Solved

RegisterShellHookWindow to find handle of newly opened dialog.

Posted on 2009-05-14
6
1,423 Views
Last Modified: 2012-05-07
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
Comment
Question by:Pber
  • 3
  • 3
6 Comments
 
LVL 39

Expert Comment

by:abel
Comment Utility
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
 
LVL 39

Accepted Solution

by:
abel earned 500 total points
Comment Utility
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
 
LVL 26

Author Comment

by:Pber
Comment Utility
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 Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 26

Author Comment

by:Pber
Comment Utility
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
 
LVL 26

Author Closing Comment

by:Pber
Comment Utility
Thanks again.
0
 
LVL 39

Expert Comment

by:abel
Comment Utility
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
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…

743 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now