views:

246

answers:

2

We are writing a plugin for an existing VB6 application (via COM interop), and we are requiring some functionality that they do not support. We could easily get the required functionality if we could somehow receive an event for when a particular control's text on their window changes.

We can already grab their existing window handle of the control with FindWindow and get the text with GetWindowText.

Is there any unmanaged/pinvoke method to receive an event when the text on a window is changed?

We do not want to poll with a while loop--we may want to do this on several of their controls in the future.

PS - I know there are ways to intercept p/invoke calls (google EasyHook), but we do not want to intercept every call to SetWindowText. We just want to receive it for one control, and using something like EasyHook is probably adding unnecessary complexity.

+1  A: 

There is no such event for general windows. If the control is an Edit control, it may send EN_CHANGE via WM_NOTIFY to its parent, however you can not inject managed code to another process to intercept the notification. I suggest you to contact the author of the VB6 app to add a COM event for you, or give up the notification requirement.

Sheng Jiang 蒋晟
Sadly, the application is old and the original developers do not (or maybe cannot) add any changes. I would like to comment that we are actually in the same process, their application is loading our C# assembly as an ActiveX control and placing it on their form, does this open anything up?
Jonathan.Peppers
Depends, what is the window's window class?
Sheng Jiang 蒋晟
+2  A: 

You could try creating a new class in c# that derives from NativeWindow.

Override the WndProc function, and if the message if of type WM SETWINDOWTEXT add your functionality - ignore all other messages and call the base class implementation

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM SETWINDOWTEXT:
            // Custom code here
            break;
    }
    base.WndProc(ref m);
}

Create an instance of this C# class and call the AssignHandle function with the hWnd for the control that you got with FindWindow.

See this link for further details and a more in depth explanation: Overriding WndProc in the NativeWindow class

John Sibly
This looks extremely promising. I will try it and let you know my results.
Jonathan.Peppers
Worked great. _
Jonathan.Peppers
Great stuff. It's the .NET equivalent to sub-classing a window using MFC or the Win32 API
John Sibly
@John - what if the window belongs to another process?
Giorgi
@Giorgi not sure how easy it would be to get to work in .NET, but take a look at the documentation for SetWindowsHookEx which would be the C++ was of intercepting a WndProc for another process http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspxAlso this article might be a good starting point: http://www.codeproject.com/KB/dotnet/HookingInMicrosoftDotNET.aspx
John Sibly