PureBasic Forumhttp://forums.purebasic.com/english/ Window hooking?http://forums.purebasic.com/english/viewtopic.php?f=13&t=13850 Page 1 of 2

 Author: PB [ Sun Jan 30, 2005 8:39 am ] Post subject: Window hooking? Anyone know how to perform window hooking so I know when a third-party window is opening? I'd like to make the Windows Calculator always open in the center of the Desktop, but not move it after it's opened.

 Author: Heis Spiter [ Sun Jan 30, 2005 10:00 am ] Post subject: Try there : http://www.codeproject.com/system/hooksys.asp

 Author: PB [ Sun Jan 30, 2005 12:27 pm ] Post subject: Re: Window hooking? Thanks Heis, but I'm still confused over this. If you look at http://tinyurl.com/5dzq7 there's an example of how to position a MessageBox before it's displayed (click the "Listing 1" link in the article); however I've not been successful in converting it to PureBasic. Anyone able to offer any advice? Thanks.

 Author: Heis Spiter [ Sun Jan 30, 2005 2:08 pm ] Post subject: I'll try to convert Listing 1. But, I'm not sure I'll managed to...

 Author: freak [ Sun Jan 30, 2005 3:52 pm ] Post subject: This code should get you started: Hook dll: Code:; This is the hook procedure. It must be compiled to a dll.; Every process on which this hook is installed will load; this dll and execute the procedure.;; Even though you also load this dll from the program that installes; the hook, you have to keep in mind that this code is mostly excecuted; inside a foreign process, not the one of your program.;; For this example, all the code does is catch a #WM_CREATE message; and broadcast our own message, so the original program can read; it. Usually, whatever task needs to be done can be done right here; inside the procedure, so that extra message is not needed.;Global CreateMessage.lProcedureDLL AttachProcess(Instance)  CreateMessage = RegisterWindowMessage_("MyHook_Window_Created")EndProcedure; This is the hook procedure; The parameters depend on what type of hook you install.; This is a hook which is called before the window procedure of the; process is called.;ProcedureDLL MyHookProcedure(nCode.l, wParam.l, *lParam.CWPSTRUCT)  ; Just catch this one message.  If *lParam\message = #WM_CREATE    PostMessage_(#HWND_BROADCAST, CreateMessage, *lParam\hwnd, 0)  EndIf  ; This is very important to allow multiple hooks to work side by side.  ProcedureReturn CallNextHookEx_(@MyHookProcedure(), nCode, wParam, *lParam)EndProcedureProgram:Code:; This is the program that installes the hook.; Note: it also needs to load the hook dll, even if it itself is not hooked.; little gui stuffEnumeration  #GADGET_List  #GADGET_Start  #GADGET_StopEndEnumeration#Hook_Path = "b:\test.dll" ; the hook dll#LIBRARY_Hook = 0          ; PB id for our dll.If OpenWindow(0, 0, 0, 400, 400, #PB_Window_SystemMenu|#PB_Window_Screencentered, "Hook example")  If CreateGadgetList(WindowID())    ListViewGadget(#GADGET_List, 5, 5, 390, 365)    ButtonGadget(#GADGET_Start, 5, 375, 120, 20, "Install Hook")    ButtonGadget(#GADGET_Stop, 130, 375, 120, 20, "Remove Hook")      EndIf    DisableGadget(#GADGET_Stop, 1)  CreateMessage = RegisterWindowMessage_("MyHook_Window_Created")    Repeat    Event = WaitWindowEvent()        ; here we received our create message..    ;    If Event = CreateMessage      hwnd = EventwParam()      Name$= Space(500) GetWindowText_(hwnd, @Name$, 500)      AddGadgetItem(#GADGET_List, -1, "WM_CREATE: "+RSet(Hex(hwnd), 8, "0")+" -> "+Name$) SetGadgetState(#GADGET_List, CountGadgetItems(#GADGET_List)-1) ElseIf Event = #PB_EventCloseWindow Quit = 1 ElseIf Event = #PB_EventGadget Select EventGadgetID() Case #GADGET_Start ; This code installes the hook. If OpenLibrary(#LIBRARY_Hook, #Hook_Path) dllInstance = LibraryID(#LIBRARY_Hook) dllFunction = IsFunction(#LIBRARY_Hook, "MyHookProcedure") ; If you set the last parameter to a threadid, only this thread will get ; hooked. Like this, every thread is hooked. HookID = SetWindowsHookEx_(#WH_CALLWNDPROC, dllFunction, dllInstance, #NULL) If HookID DisableGadget(#GADGET_Start, 1) DisableGadget(#GADGET_Stop, 0) AddGadgetItem(#GADGET_List, -1, "=====> Hook installed") SetGadgetState(#GADGET_List, CountGadgetItems(#GADGET_List)-1) EndIf EndIf Case #GADGET_Stop ; This removes the hook.. quite simple. If HookID UnhookWindowsHookEx_(HookID) CloseLibrary(#LIBRARY_Hook) DisableGadget(#GADGET_Start, 0) DisableGadget(#GADGET_Stop, 1) AddGadgetItem(#GADGET_List, -1, "=====> Hook removed") SetGadgetState(#GADGET_List, CountGadgetItems(#GADGET_List)-1) HookID = 0 EndIf EndSelect EndIf Until Quit EndIf; unhook if not allready done.If HookID UnhookWindowsHookEx_(HookID) CloseLibrary(#LIBRARY_Hook)EndIfEnd For your calculator problem, this should work well, because #WM_CREATE is send after the window is created, but before it is displayed. So if you move it from inside the hook procedure, it should work, and also look good  Author: PB [ Sun Jan 30, 2005 8:29 pm ] Post subject: Thanks Freak, I'll have a play later on... but I thought it would be a lot simpler than using a DLL? I'd prefer a standalone exe solution, like that Visual Basic example uses... if VB can do it, surely PureBasic can? Here's what I've been testing, but it fails and even crashes my PC sometimes: Code:; WARNING: Running this *might* crash your PC!Procedure WindowHook(uMsg,wParam,lParam) If uMsg=#HCBT_ACTIVATE AddGadgetItem(0,-1,Str(wParam)) ; Show window handle that just opened? UnhookWindowsHookEx_(hHook) EndIf ProcedureReturn #FALSEEndProcedureIf OpenWindow(1,300,250,400,200,#PB_Window_SystemMenu,"test") CreateGadgetList(WindowID()) ListViewGadget(0,0,0,400,200) hHook=SetWindowsHookEx_(#WH_CBT,@WindowHook(),GetModuleHandle_(0),GetCurrentThreadId_()) Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindowEndIf  Author: freak [ Sun Jan 30, 2005 8:44 pm ] Post subject: Well, according to the documentation, you need to have the code located in a dll if you want the hook to be system wide or on a thread which is not your own. And since you want it to work on the calculator, it won't help to hook your own process. btw, in your example, you should set the 3rd parameter to 0 instead of GetModuleHandle_(0). This should only be a instance handle if the code IS inside a dll, otheweise it should be 0.  Author: PB [ Sun Jan 30, 2005 8:46 pm ] Post subject: > according to the documentation, you need to have the code located > in a dll if you want the hook to be system wide Ah, I see. No wonder you used a DLL then! I'll play with your code then. Many thanks for your help on this. Hopefully I can get it doing what I want.  Author: PB [ Mon Jan 31, 2005 8:36 pm ] Post subject: Hi Freak... Unfortunately I can't get it doing what I want. I've been watching for the opening of calc.exe but by the time the DLL sees it, it's already drawn. Do you have any suggestions?  Author: freak [ Mon Jan 31, 2005 11:57 pm ] Post subject: Hum, it seems to work fine here. Did you put the code to move the window in the dll or the main app? If you put it in the app, the window is of course allready drawn by the time that the communication from dll to app is done. But you don't need to do it from the app, this was only for my example, you should do it from the dll. Here's the code: Code:ProcedureDLL MyHookProcedure(nCode.l, wParam.l, *lParam.CWPSTRUCT) ; Just catch this one message. If *lParam\message = #WM_CREATE ; only check toplevel windows If GetWindowLong_(*lParam\hwnd, #GWL_STYLE) & #WS_CHILD = 0 Name$ = Space(1000)            ; since this dll is executed by the hooked programm, this call will      ; return the calculator executable name      ;      GetModuleFileName_(0, @Name$, 1000) If LCase(GetFilePart(Name$)) = "calc.exe"               ; get the window size and move it.         GetWindowRect_(*lParam\hwnd, @Size.RECT)        w = Size\right - Size\left        h = Size\bottom - Size\top        x = (GetSystemMetrics_(#SM_CXSCREEN)-w)/2        y = (GetSystemMetrics_(#SM_CYSCREEN)-h)/2        MoveWindow_(*lParam\hwnd, x, y, w, h, #False)              EndIf    EndIf      EndIf  ; This is very important to allow multiple hooks to work side by side.  ProcedureReturn CallNextHookEx_(@MyHookProcedure(), nCode, wParam, *lParam)EndProcedure Compile it to a dll and use the above app code to set/remove the hook. Works fine here.

 Author: PB [ Tue Feb 01, 2005 11:54 am ] Post subject: > Did you put the code to move the window in the dll or the main app? The main app. Thanks for your new code, I'll study it well.

 Author: Lane [ Fri Feb 04, 2005 4:49 am ] Post subject: Enumeration?? Enumeration does not appear to be a valid command. It's not listed in the online command index either. I'm running 3.10 - Ebay special

 Author: PB [ Fri Feb 04, 2005 5:15 am ] Post subject: Re: Enumeration?? > Enumeration does not appear to be a valid command It was introduced in v3.80: http://www.purebasic.com/news36.php3 > It's not listed in the online command index either See: http://www.purebasic.com/documentation/ ... tions.html I'm running 3.10 - Ebay special There's your problem. E-mail support@purebasic.com and talk to them.

 Author: Lane [ Fri Feb 04, 2005 5:30 am ] Post subject: correct sir! Ok thanks.

 Author: Julien [ Sat May 21, 2005 7:41 pm ] Post subject: How to change this code for Work with KEYBOARD ? Thank

 Page 1 of 2 All times are UTC + 1 hour Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Grouphttp://www.phpbb.com/