Solved

Using SetWindowsHookEx to notify when Calculator is lauched or closed.

Posted on 2004-09-17
6
674 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
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

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

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

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
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…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses
Course of the Month10 days, 17 hours left to enroll

632 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