?
Solved

RegisterShellHookWindow to find handle of newly opened dialog.

Posted on 2009-05-14
6
Medium Priority
?
1,547 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
[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 39

Expert Comment

by:abel
ID: 24390418
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 2000 total points
ID: 24390460
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
ID: 24395357
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
Independent Software Vendors: 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!

 
LVL 26

Author Comment

by:Pber
ID: 24435599
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
ID: 31581709
Thanks again.
0
 
LVL 39

Expert Comment

by:abel
ID: 24436655
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 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

I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
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…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses
Course of the Month14 days, 2 hours left to enroll

800 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