Click here to Skip to main content
15,885,875 members
Articles / Programming Languages / eVC

Sub-classing a C# window in a DLL created using eMbedded VC++

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
24 Jun 2007CPOL2 min read 22.7K   9  
How to trap a C# application window message in an eMbedded VC++ created DLL.

Introduction

One of the requirements for a PDA (Personal Digital Assistance) application I was developing was to subclass a window created by a C# application, in an eMbedded VC++ created DLL. The C# application loads the eMbedded VC++ created DLL to perform the recording functionality.

Solution

The GUI for the same was developed using C# (.NET Compact framework), and for the recording functionality, we have a DLL created using eMbedded VC++. Now, the waveform-audio input device sends a notification message to the specified window, but the question was how to get a window handle which is created in C# application so that it can be passed as a parameter for the waveInOpen function? We need to somehow pass the window handle to the DLL so that the DLL can subclass the window and the messages can be processed in the DLL itself.

Here is an attempt to solve the above mentioned issue.

First of all, the functions implemented in the DLL are called using DllImport in the C# application. You need to write the following code to access the functions exported from this DLL (Recorder.dll). I have put all these functions in a class named Wrapper.

C#
public class Wrapper 
{

    [DllImport("Recorder.dll", EntryPoint="StartRecording")] 
    static extern public bool StartRecording (); 

    [DllImport("Recorder.dll", EntryPoint="StopRecording")] 
    static extern public bool StopRecording (); 

    [DllImport("Recorder.dll", EntryPoint="StartPlaying")] 
    static extern public bool StartPlaying(string sFile); 

    [DllImport("Recorder.dll", EntryPoint="StopPlaying")] 
    static extern public bool StopPlaying ();

    //Other functions

}

I added one more function in the DLL which will accept the window handle of a C# window. I imported the same in the C# application.

C#
[DllImport ("Recrdr.dll", EntryPoint="SetParentWnd")] 
static extern public bool SetParentWnd (UInt32 hWnd);

Now, I need to pass the window's handle to this function (Please note that this.Handle is not supported in the .NET Compact framework). Then, how do we do this? Well, again, we need to call a Windows API for getting the window handle. For that, you need to import the Windows DLL, coredll.dll, which implements the GetForegroundWindow function.

This is how you do this.

C#
[DllImport ("coredll.dll", EntryPoint="GetForegroundWindow")] 
static extern public UInt32 GetForegroundWindow();

This is again added to the Wrapper class which I mentioned earlier.

Call this function from your C# application's form load function to get the foreground window, and call the SetParentWnd function of the Recrdr.dll by passing this handle.

C#
UInt32 unHandle = Wrapper.GetForegroundWindow (); 

Wrapper.SetParentWnd (unHandle);

Now, in your eMbedded VC++ code, add the following lines of code to trap the message:

C++
LRESULT CALLBACK RecorderWndProc ( HWND hWnd, UINT unMessage, WPARAM wParam, LONG lParam ) 
{ 
    switch (unMessage) 
    { 
        case <message>: 
            break; 
        default:

        break; 
    }
    
    return CallWindowProc ( g_lpfnWndProc, hWnd, unMessage, wParam, lParam );
    // Call original window procedure 

}

This is your new window procedure in which you can trap any message coming to your C# window.

Do the subclassing whenever the SetWindowHandle function is called. Here is the code for the same:

bool CRecorder::SetWindowHandle(HWND hWnd)
{
    if ( hWnd == NULL )
            return false;

    m_hParentWnd = hWnd;
    // Do an instance subclassing so that you can trap messages here

    // and leave rest of the messages to the main window

    g_lpfnWndProc = (WNDPROC) SetWindowLong ( m_hParentWnd, 
                              GWL_WNDPROC, (LONG) RecorderWndProc );

    if ( g_lpfnWndProc == NULL )
        return false;

    return true;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
A Software Engineer working on C++, VC++, MFC and .Net Compact Framework.

Comments and Discussions

 
-- There are no messages in this forum --