-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathVolumer.vb
219 lines (181 loc) Β· 8.78 KB
/
Volumer.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
ο»Ώ
Imports System.Runtime.InteropServices
Public Class VolumerForm
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Dim ControlTimer As New Timer
Dim TaskbarIcon As New NotifyIcon
Dim Context As New ContextMenu
Dim cursorOnTaskbar As Boolean
Dim CropRects As New ArrayList
Dim screens As New Dictionary(Of String, List(Of Rectangle))
Private Sub Add(location As String, CropRect As Rectangle)
If CropRect.Width > 0 And CropRect.Height > 0 Then
' Console.WriteLine("(" + location + ") Adding Taskbar: " + CropRect.ToString())
CropRects.Add(CropRect)
End If
End Sub
Private Sub UpdateScreens()
screens = New Dictionary(Of String, List(Of Rectangle))
For Each OneScreen In Screen.AllScreens
screens.Add(OneScreen.DeviceName, New List(Of Rectangle)(New Rectangle() {OneScreen.Bounds, OneScreen.WorkingArea}))
Dim TaskBarRect As Rectangle = Rectangle.Intersect(OneScreen.WorkingArea, OneScreen.Bounds)
' Checking where is your taskbak
' If it's width equals to your screen's width, it's horizontal
' If it's height equals to your screen's height, it's vertical
If TaskBarRect.Width = OneScreen.Bounds.Width Then
' If it's y position is not 0, it's on top
' If not, it's on bottom
If TaskBarRect.Y <> OneScreen.Bounds.Y Then
Add("Top", New Rectangle(OneScreen.Bounds.X, OneScreen.Bounds.Y, TaskBarRect.Width, TaskBarRect.Y - OneScreen.Bounds.Y))
Else
Add("Bottom", New Rectangle(OneScreen.Bounds.X, TaskBarRect.Height + OneScreen.Bounds.Y, TaskBarRect.Width, OneScreen.Bounds.Height - OneScreen.WorkingArea.Height))
End If
ElseIf TaskBarRect.Height = OneScreen.Bounds.Height Then
' If it's x position is not 0, it's on left
' If not, it's on right
If TaskBarRect.X <> OneScreen.Bounds.X Then
Add("Left", New Rectangle(OneScreen.Bounds.X, OneScreen.Bounds.Y, TaskBarRect.X - OneScreen.Bounds.X, TaskBarRect.Height))
Else
Add("Right", New Rectangle(TaskBarRect.Width + OneScreen.Bounds.X, OneScreen.Bounds.Y, OneScreen.Bounds.Width, TaskBarRect.Height))
End If
End If
Next
End Sub
Private Sub VolumerForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
UpdateScreens()
If CropRects.Count = 0 Then
' No taskbar found.
Application.Exit()
End If
' Set timer & start
AddHandler ControlTimer.Tick, AddressOf ControlTimer_Tick
ControlTimer.Interval = 1
ControlTimer.Enabled = True
' Set reload button
Dim ReloadButton As New MenuItem
ReloadButton.Index = 0
ReloadButton.Text = "&Reload"
AddHandler ReloadButton.Click, AddressOf UpdateScreens
' Set exit button
Dim ExitButton As New MenuItem
ExitButton.Index = 1
ExitButton.Text = "E&xit"
AddHandler ExitButton.Click, AddressOf ExitApplication
' Set taskbar icon
TaskbarIcon.Icon = My.Resources.VolumerIcon
TaskbarIcon.Text = "Volumer"
TaskbarIcon.Visible = True
' Add context menu
Context.MenuItems.Add(ReloadButton)
Context.MenuItems.Add(ExitButton)
TaskbarIcon.ContextMenu = Context
' Start global mouse hook
MouseHook.Start()
AddHandler MouseHook.MouseWheel, AddressOf Mouse_Wheel
End Sub
Private Sub VolumerForm_Closing(sender As Object, e As EventArgs) Handles Me.FormClosing
MouseHook.Stop()
End Sub
Private Sub Mouse_Wheel(ByVal sender As Object, ByVal e As EventArgs)
If (cursorOnTaskbar) Then
If (CInt(MouseHook.MouseWheelInfo.ToString) > 0) Then
SendMessage(Handle, &H319, &H30292, &HA * &H10000) ' Volume Up
Else
SendMessage(Handle, &H319, &H30292, &H9 * &H10000) ' Volume Down
End If
End If
End Sub
Private Sub ExitApplication(sender As Object, e As EventArgs)
Application.Exit()
End Sub
Private Sub ControlTimer_Tick(sender As Object, e As EventArgs)
Dim posx = Cursor.Position.X
Dim posy = Cursor.Position.Y
' Hide form
If Me.Visible Then
Me.Hide()
End If
' MAJOR PROBLEM: POSSIBLE MEMORY LEAK.
' Check resolution
'For Each OneScreen In Screen.AllScreens
' Dim i = OneScreen.DeviceName
' If Not (OneScreen.Bounds.X = screens(i).Item(0).X And OneScreen.Bounds.Y = screens(i).Item(0).Y And
' OneScreen.Bounds.Width = screens(i).Item(0).Width And OneScreen.Bounds.Height = screens(i).Item(0).Height And
' OneScreen.WorkingArea.X = screens(i).Item(1).X And OneScreen.WorkingArea.Y = screens(i).Item(0).Y And
' OneScreen.WorkingArea.Width = screens(i).Item(1).Width And OneScreen.WorkingArea.Height = screens(i).Item(0).Height) Then
' ' Console.WriteLine("Updating screens...")
' UpdateScreens()
' End If
'Next
cursorOnTaskbar = False
For Each CropRect In CropRects
' Check if cursor is on taskbar
If posx >= CropRect.X And posx <= CropRect.X + CropRect.Width And posy >= CropRect.Y And posy <= CropRect.Y + CropRect.Height Then
cursorOnTaskbar = True
End If
Next
End Sub
End Class
Public NotInheritable Class MouseHook
Public Shared Event MouseWheel As EventHandler
Public Shared MouseWheelInfo As String
Public Shared Sub Start()
_hookID = SetHook(_proc)
End Sub
Public Shared Sub [Stop]()
UnhookWindowsHookEx(_hookID)
End Sub
Private Shared _proc As LowLevelMouseProc = AddressOf HookCallback
Private Shared _hookID As IntPtr = IntPtr.Zero
Private Shared Function SetHook(ByVal proc As LowLevelMouseProc) As IntPtr
Using curProcess As Process = Process.GetCurrentProcess()
Using curModule As ProcessModule = curProcess.MainModule
Dim hook As IntPtr = SetWindowsHookEx(14, proc, GetModuleHandle("user32"), 0)
If hook = IntPtr.Zero Then
Throw New System.ComponentModel.Win32Exception()
End If
Return hook
End Using
End Using
End Function
Private Delegate Function LowLevelMouseProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Private Shared Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
If nCode >= 0 AndAlso MouseMessages.WM_MOUSEWHEEL = CType(wParam, MouseMessages) Then
Dim hookStruct As MSLLHOOKSTRUCT = CType(Marshal.PtrToStructure(lParam, GetType(MSLLHOOKSTRUCT)), MSLLHOOKSTRUCT)
Dim v As Integer = CInt((hookStruct.mouseData And &HFFFF0000) >> 16)
If v > SystemInformation.MouseWheelScrollDelta Then v = v - (UShort.MaxValue + 1)
MouseWheelInfo = v.ToString
RaiseEvent MouseWheel(Nothing, New EventArgs())
End If
Return CallNextHookEx(_hookID, nCode, wParam, lParam)
End Function
Private Enum MouseMessages
WM_MOUSEWHEEL = &H20A
End Enum
<StructLayout(LayoutKind.Sequential)>
Private Structure POINT
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Structure MSLLHOOKSTRUCT
Public pt As POINT
Public mouseData As UInteger
Public flags As UInteger
Public time As UInteger
Public dwExtraInfo As IntPtr
End Structure
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As LowLevelMouseProc, ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
End Function
End Class