Solved

Using SetWindowsHookEx to notify when Calculator is lauched or closed.

Posted on 2004-09-17
6
648 Views
Last Modified: 2008-02-01
I'm looking for the "calculator" window when it is launched and closed how can I get a msgbox with the HWND when this event takes place using "SetWindowsHookEx"?




FORM
'********************************************

      Private Sub Command1_Click()
      Dim hInst As Long
      Dim Thread As Long

         'Set up the CBT hook
         hInst = GetWindowLong(Me.hwnd, GWL_HINSTANCE)
         Thread = GetCurrentThreadId()
         hHook = SetWindowsHookEx(WH_CBT, AddressOf WinProc1, hInst, _
                                  Thread)
           
         'Display the message box
         MsgBox "This message box has been positioned at (0,0)."
         
      End Sub

MODULE
'*************************************************

      Public Declare Function UnhookWindowsHookEx Lib "user32" ( _
         ByVal hHook As Long) As Long
      Public Declare Function GetWindowLong Lib "user32" Alias _
         "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) _
         As Long
      Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long
      Public Declare Function SetWindowsHookEx Lib "user32" Alias _
         "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, _
         ByVal hmod As Long, ByVal dwThreadId As Long) As Long
      Public Declare Function SetWindowPos Lib "user32" ( _
         ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
         ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
         ByVal cy As Long, ByVal wFlags As Long) As Long
      Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd _
         As Long, lpRect As RECT) As Long


      Public Const GWL_HINSTANCE = (-6)
      Public Const SWP_NOSIZE = &H1
      Public Const SWP_NOZORDER = &H4
      Public Const SWP_NOACTIVATE = &H10
      Public Const HCBT_ACTIVATE = 5
      Public Const WH_CBT = 5

      Public hHook As Long

      Function WinProc1(ByVal lMsg As Long, ByVal wParam As Long, _
         ByVal lParam As Long) As Long

         If lMsg = HCBT_ACTIVATE Then
            'Show the MsgBox at a fixed location (0,0)
            SetWindowPos wParam, 0, 0, 0, 0, 0, _
                         SWP_NOSIZE Or SWP_NOZORDER Or SWP_NOACTIVATE
             'Release the CBT hook
            UnhookWindowsHookEx hHook

         End If
         WinProc1 = False

      End Function
0
Comment
Question by:ampapa
  • 3
  • 3
6 Comments
 
LVL 8

Expert Comment

by:mladenovicz
ID: 12091053
I am not sure, if I understodd what do you want, but maybe you can use FindWindow API

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Const gcClassnameMSWord = "OpusApp"
Const gcClassnameMSExcel = "XLMAIN"
Const gcClassnameMSIExplorer = "IEFrame"
Const gcClassnameMSVBasic = "wndclass_desked_gsk"
Const gcClassnameNotePad = "Notepad"
Const gcClassnameMyVBApp = "ThunderForm"
Private Sub Form_Load()
    'KPD-Team 1998
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
    'Ask for a Window title
    Ret = InputBox("Enter the exact window title:" + Chr$(13) + Chr$(10) + "Note: must be an exact match")
    'Search the window
    WinWnd = FindWindow(vbNullString, Ret)
    If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
    'Show the window
    ShowWindow WinWnd, SW_SHOWNORMAL
    'Create a buffer
    lpClassName = Space(256)
    'retrieve the class name
    RetVal = GetClassName(WinWnd, lpClassName, 256)
    'Show the classname
    MsgBox "Classname: " + Left$(lpClassName, RetVal)
    'Post a message to the window to close itself
    PostMessage WinWnd, WM_CLOSE, 0&, 0&
End Sub
0
 
LVL 8

Author Comment

by:ampapa
ID: 12091234
I need to find the window before it is created by hooking into the windows messaging system - "SetWindowsHookEx". I want to change the caption on the window as an example.
0
 
LVL 8

Expert Comment

by:mladenovicz
ID: 12091285
I am not sure that you can find window before it is created. Here is the code that will set window caption. You can chekc if winddow exists on timer and then change it's caption

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Const gcClassnameMSWord = "OpusApp"
Const gcClassnameMSExcel = "XLMAIN"
Const gcClassnameMSIExplorer = "IEFrame"
Const gcClassnameMSVBasic = "wndclass_desked_gsk"
Const gcClassnameNotePad = "Notepad"
Const gcClassnameMyVBApp = "ThunderForm"
Private Sub Form_Load()
    'KPD-Team 1998
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim WinWnd As Long, Ret As String, RetVal As Long
    'Ask for a Window title
    Ret = InputBox("Enter the exact window title:" + Chr$(13) + Chr$(10) + "Note: must be an exact match")
    'Search the window
    WinWnd = FindWindow(vbNullString, Ret)
    If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
    'Show the window
    ShowWindow WinWnd, SW_SHOWNORMAL
   
    SetWindowText WinWnd, "My Caption"
   
End Sub
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 8

Author Comment

by:ampapa
ID: 12091408
My problem is that I need to get the HWND of a(any) window when it is created on the desktop. The source code at the top is from microsoft (http://support.microsoft.com/default.aspx?scid=kb;EN-US;q180936) recieving notification when windows are created and destroyed. It's exactly what I'm looking for except I am confused about how to modify it, as usual. I've modified the source a bit mostly removed the second example.

I also have another question open "http://experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_21132319.html" which is where we were heading but I'm running out of time, but it might give some insight.

My API programming is extremely week but I'm learning. From what I can understand by creating this CBT hook it will be able to recieive windows messages and can Identify the activate message to a window by using"HCBT_ACTIVATE". This then allows you to modify that window or at the very least get the HWND to it, that's what I need.

FindWindow won't work in this instance because the window(s) I am trying to get the HWND have the same 'Caption' and therefore even though it gets the window it get's the wrong one.

So, it's got to be set to listen for all windows being created, identify the caption and the HWND if the caption of the window matches a text string "calculator" then I'm golden....
0
 
LVL 8

Accepted Solution

by:
mladenovicz earned 500 total points
ID: 12091474
I take a look on MS code you started from and I think (I am not quite sure) that you can not do this, because that sample uses current thread

        Thread = GetCurrentThreadId()
         hHook = SetWindowsHookEx(WH_CBT, AddressOf WinProc1, hInst, _
                                  Thread)

So you can track windows within your application, not outside it
0
 
LVL 8

Author Comment

by:ampapa
ID: 12092114
I think my bubble just burst... I believe you are correct from what I just read, in order to do a system wide hook I'll need some type of DLL and that the process can't be done from within VB.

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question