Hooking the #WM_COMMAND message
Posted: Tue Sep 25, 2007 1:00 am
I'm trying to create a utility to put apps in the system tray when minimized by hooking the #WM_SYSCOMMAND message with an #SC_MINIMIZE wParam. Every bit of literature I've found so far indicates that this message should be sent when the user either clicks Minimize in the system menu OR click the minimize button on the titlebar. For some reason, though, I'm not catching the minimize message unless it's selected from the system menu - it doesn't seem to fire when the titlebar button is pressed. Here's a minimal version of the code I'm using; maybe someone can put me on the right path, or at least prove to me that it's just my system that's screwing this up.
Code: Select all
;Hook procedure
;compile this To a Shared library called "minimizehook.dll"
#WM_MYEVENT = #WM_USER + 1
ProcedureDLL MinimizeProc(code.l, wParam.l, *lParam.MSG)
If code < 0
ProcedureReturn CallNextHookEx_(@MinimizeProc(), code, wParam, lParam)
EndIf
If *lParam\message & $FFFF = #WM_SYSCOMMAND
If (*lParam\wParam & $FFFF) = #SC_MINIMIZE
hwnd = FindWindow_(0, "Minimize Hook Test")
If hwnd
SendMessage_(hwnd, #WM_MYEVENT, 0, 0)
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(@MinimizeProc(), code, wParam, lParam)
EndProcedureCode: Select all
;Test app
;Either save this in the folder where "minimizehook.dll" was built,
;or change the path to the dll in the OpenLibrary() call, then execute.
;The hook is global, so any window that's minimized while this is
;running should case a message to be displayed in the hook test window.
#WM_MYEVENT = #WM_USER + 1
Enumeration
#MainWindow
#MessageText
#MessageTimer
EndEnumeration
Global timer_start.l, hook_dll.l, hook.l
Procedure WndProc(hwnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_MYEVENT
SetGadgetText(#MessageText, "A window has been minimized")
timer_start = ElapsedMilliseconds()
EndSelect
ProcedureReturn result
EndProcedure
hook_dll = OpenLibrary(0, "minimizehook.dll")
If Not hook_dll
MessageRequester("Error", "Could not load minimizehook.dll")
End
EndIf
If OpenWindow(#MainWindow, 0, 0, 320, 240, "Minimize Hook Test", #PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget)
If CreateGadgetList(WindowID(#MainWindow))
SetWindowCallback(@WndProc())
SetWindowPos_(WindowID(#MainWindow), #HWND_TOPMOST, 0, 0, 0, 0, #SWP_NOMOVE|#SWP_NOSIZE)
TextGadget(#MessageText, 10, 10, 300, 15, "")
hook = SetWindowsHookEx_(#WH_GETMESSAGE, GetProcAddress_(hook_dll, "MinimizeProc"), hook_dll, 0)
If Not hook
MessageRequester("Error", "Unable to install message hook")
CloseLibrary(0)
End
EndIf
Repeat
event = WindowEvent()
If timer_start And (ElapsedMilliseconds() - timer_start) > 2000
SetGadgetText(#MessageText, "")
timer_start = 0
EndIf
Delay(1)
Until event = #PB_Event_CloseWindow
EndIf
EndIf
UnhookWindowsHookEx_(hook)
CloseLibrary(0)
End