• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1632
  • 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_REDRAW = 6
        HSHELL_TASKMAN = 7
    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")
    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
    End Sub
    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
    End Sub
End Class

Open in new window

  • 3
  • 3
1 Solution
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

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

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.
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

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

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.
PberSolutions ArchitectAuthor Commented:
Thanks again.
Ok, that's understandable, I may not have gone for it myself either if I had the choice. Tx for the points :)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

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