It is currently Sat Nov 23, 2019 3:31 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Window hooking?
PostPosted: Sun Jan 30, 2005 8:39 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
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.

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 30, 2005 10:00 am 
Offline
User
User
User avatar

Joined: Fri Aug 22, 2003 7:10 pm
Posts: 41
Location: 76 (FRANCE)
Try there : http://www.codeproject.com/system/hooksys.asp


Top
 Profile  
Reply with quote  
 Post subject: Re: Window hooking?
PostPosted: Sun Jan 30, 2005 12:27 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
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.

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 30, 2005 2:08 pm 
Offline
User
User
User avatar

Joined: Fri Aug 22, 2003 7:10 pm
Posts: 41
Location: 76 (FRANCE)
I'll try to convert Listing 1. But, I'm not sure I'll managed to... :?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 30, 2005 3:52 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5783
Location: Germany
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.l

ProcedureDLL 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)
EndProcedure


Program:
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 stuff
Enumeration
  #GADGET_List
  #GADGET_Start
  #GADGET_Stop
EndEnumeration

#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)
EndIf
End


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 :)

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 30, 2005 8:29 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
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 #FALSE
EndProcedure

If 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_CloseWindow
EndIf

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Last edited by PB on Sun Jan 30, 2005 8:45 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 30, 2005 8:44 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5783
Location: Germany
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.

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 30, 2005 8:46 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
> 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.

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jan 31, 2005 8:36 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
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?

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jan 31, 2005 11:57 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5783
Location: Germany
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.

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Feb 01, 2005 11:54 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
> Did you put the code to move the window in the dll or the main app?

The main app. :oops: Thanks for your new code, I'll study it well. :)

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Top
 Profile  
Reply with quote  
 Post subject: Enumeration??
PostPosted: Fri Feb 04, 2005 4:49 am 
Offline
New User
New User

Joined: Thu Sep 11, 2003 6:17 pm
Posts: 5
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


Top
 Profile  
Reply with quote  
 Post subject: Re: Enumeration??
PostPosted: Fri Feb 04, 2005 5:15 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Fri Apr 25, 2003 5:24 pm
Posts: 7581
> 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.

_________________
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.


Top
 Profile  
Reply with quote  
 Post subject: correct sir!
PostPosted: Fri Feb 04, 2005 5:30 am 
Offline
New User
New User

Joined: Thu Sep 11, 2003 6:17 pm
Posts: 5
Ok thanks.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat May 21, 2005 7:41 pm 
Offline
User
User

Joined: Fri Apr 25, 2003 6:08 pm
Posts: 17
Location: France
How to change this code for Work with KEYBOARD ?

Thank


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye