• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1603
  • Last Modified:

RegisterShellHookWindow to find handle of newly opened dialog.

I have an app that is essentially using the same code as in the refernce question

I've used both: HSHELL_WINDOWACTIVATED and HSHELL_WINDOWCREATED to attempt to detect when a new window is created.  It works but only seems to detect main applications threads and not any dialog windows that may be created.  How would I go about modifying this to display the dialog windows or child windows of the main thread?
This behaviour can be duplicated by opening outlook and then opening messages or new message windows.  They always display the same handle.  I also made my own vb.net app, that just spawns new forms and the WINDOWCREATED event doesn't even get detected.
Imports System.Runtime.InteropServices
 
Public Class Form1
    Inherits System.Windows.Forms.Form
 
    Public Enum ShellEvents
        HSHELL_WINDOWCREATED = 1
        HSHELL_WINDOWDESTROYED = 2
        HSHELL_ACTIVATESHELLWINDOW = 3
        HSHELL_WINDOWACTIVATED = 4
        HSHELL_GETMINRECT = 5
        HSHELL_REDRAW = 6
        HSHELL_TASKMAN = 7
        HSHELL_LANGUAGE = 8
        HSHELL_ACCESSIBILITYSTATE = 11
    End Enum
 
    Public Declare Function RegisterWindowMessage Lib "user32.dll" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Integer
    Public Declare Function DeregisterShellHookWindow Lib "user32" (ByVal hWnd As IntPtr) As Integer
    Public Declare Function RegisterShellHookWindow Lib "user32" (ByVal hWnd As IntPtr) As Integer
    Public Declare Function GetForegroundWindow Lib "user32" () As IntPtr
    Public Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hWnd As IntPtr) As Integer
 
    Private uMsgNotify As Integer
    Private lastWindow As IntPtr
 
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        uMsgNotify = RegisterWindowMessage("SHELLHOOK")
        RegisterShellHookWindow(Me.Handle)
    End Sub
 
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = uMsgNotify Then
            Select Case m.WParam.ToInt32
                Case ShellEvents.HSHELL_WINDOWCREATED
                    Dim curWindow As IntPtr = GetForegroundWindow()
                    Debug.WriteLine("Window Created: " & curWindow.ToString)
            End Select
        End If
        MyBase.WndProc(m)
    End Sub
 
    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        DeregisterShellHookWindow(Me.Handle)
    End Sub
 
End Class

Open in new window

0
Pber
Asked:
Pber
  • 3
  • 3
1 Solution
 
abelCommented:
Well, that seems correct. Reading up on this shows (ms documentation aboutRegisterShellHookWindow):

The event messages received are only those sent to the Shell window associated  with the specified window's desktop.
which means: only the main windows, because they become children of the shell window (desktop). What you need instead is the SetWindowsHookEx function, which you can set the moment the main window is created. Here's an example of using that function as a keyboard hook to illustrate the process, but the idea is the same, you need WH_CALLWNDPROC I think: http://www.pinvoke.net/default.aspx/user32/SetWindowsHookEx.html


0
 
abelCommented:
Yes, that appears to be right. And then you need to filter for WM_CREATE. So, the procedure becomes as follows:

- your current hook
- whenever a main window is created, you cal SetWindowsHookEx
- you monitor (first param) for WH_CALLWNDPROC (messages before they arrive in the window proc)
- you react on any WM_CREATE. The rest you leave
- always call CallNextHookEx

0
 
PberSolutions ArchitectAuthor Commented:
Thanks for the reply, I have a load of meetings today, so I'll poke at this when I have some free time.  I'm not that experienced with windows hooking, so I'll see how it going.
Ultimately what I'm trying to do is create a systray application that will monitor window creation (in this case, dialogs from other apps) and if specific dialog pops up (based on the WindowText) I reposition the window to a certain location on the screen.  I have everything else working, I just want a way of making it happen on window creation.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
PberSolutions ArchitectAuthor Commented:
Sorry 4 not getting back sooner.  Turns out "we" don't feel comfortable enough with the stability of our 3rd party application and the hook chain involved in this solution.  
Anyhow, thanks for the solution.  I will likely put it to use on other projects of mine.
(:
 
0
 
PberSolutions ArchitectAuthor Commented:
Thanks again.
0
 
abelCommented:
Ok, that's understandable, I may not have gone for it myself either if I had the choice. Tx for the points :)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now