4

I'm writing a .NET wrapper around an old MFC-based library we have. It's based around a class that sends notifications using window messages; it has a function that lets the user pass in a handle to a window, and that window will receive the messages.

I could just require the users of my wrapper to subclass Control and pass their control's handle in order to receive messages, but that's horrible. I want my wrapper class to have events which fire whenever the old library sends a message, and then I can do the decoding of the message into something sensible. But, I don't want my wrapper class to have to be a control.

Is there a way for me to create a 'dummy' window handle, and receive the messages sent to that handle, without creating a window?

Simon
  • 25,468
  • 44
  • 152
  • 266

4 Answers4

10

There is a concept of MessageOnly Windows which can help you. You may create an internal message only window in your wrapper class and pass this handle to the old library.

Samuel Jack
  • 32,712
  • 16
  • 118
  • 155
Canopus
  • 7,351
  • 11
  • 46
  • 57
0

You could try creating a thread with a message pump and sending your messages to that. The thread then raises any necessary events that you want to handle in your C# code.

ChrisBD
  • 9,104
  • 3
  • 22
  • 35
-1

You can't create a window handle without having a window, since the window handle is the window as far Windows is concerned, but you can make a window without the WS_VISIBLE flag set, and use it for message relaying only. I use that technique sometimes to do cross-thread communication in MFC-only applications (don't tell anyone ;) ). You could derive a (c++) class from CWnd, let it process the messages, and call functions or emit signals for every message that is received. I guess that would make it work with your C# code although I don't have experience with that.

Roel
  • 19,338
  • 6
  • 61
  • 90
-3

To create a window that does not display, but receives messages, use the following code.

The header file:

#pragma once
#include <afxwin.h>

#define ID_NOTHING_MGS WM_USER + 1001

class control : public CWnd
{
public:
    control();
    LRESULT control::nothing(WPARAM wp, LPARAM lp);
    DECLARE_MESSAGE_MAP()
};

Function implementation in header file.

#include "control.h"

BEGIN_MESSAGE_MAP(control, CWnd)
    ON_MESSAGE(ID_NOTHING_MGS, nothing)
END_MESSAGE_MAP()

control::control()
{
    // ref1:https://codeantenna.com/a/s6NmJb6YD8
    // ref2:https://www.cnblogs.com/greatverve/archive/2012/11/04/mfc-message.html
    this->CreateEx(WS_EX_NOACTIVATE, AfxRegisterWndClass(0), _T("windowName"),
        WS_CAPTION | WS_OVERLAPPEDWINDOW | WS_EX_NOPARENTNOTIFY,//  | WS_VISIBLE,
        0, 0, 400, 350, NULL, NULL, NULL);
}

LRESULT control::nothing(WPARAM wp, LPARAM lp)
{
    MessageBox(TEXT("control receive message"));
    return 0;
}

Since control inherit from the CWnd class, it can receive messages。CreateEx function,creates the specified window and appends it to the CWnd object. If you do not call CreateEx, the window handle value of the created Control object is 0.

No 'WS_VISIBLE' is used, so the window is not visible.

童宗振
  • 1
  • 2