Capture windows messages generated by an MFC app in plain C++ dll - c++

First of all: Is this even possible?
I have a third party dll that interfaces some hardware. It's written in MFC. I received (from the dll vendors) a sample Visual Studio 2010 solution which has only one project: An MFC application (.exe) which calls the third party dll in question. It works fine.
When I try to use the third party dll from my dll (which is plain C++, no MFC, no .NET), I can call its functions fine, but there's a catch: the sample MFC app seems to "override" MessageProc in order to capture certain messages that the third party dll generates. And though the dll has a function called "RegisterFuncCallback" and I use it, my callback never gets called.
So here's the problem: How can I capture those messages without creating an MFC app? (Is it even possible?)

Alright, I made it. Here's how:
Create a class which inherits from CWnd
Declare a message map associating the desired messages and their handlers
When creating the Window, use the CreateEx function (I did it in my class's constructor), and pass it the HWND_MESSAGE flag in the last but one parameter. This will create the window as a "Message Window", that is, invisible.
Once I'm done initializing the window and the MFC dll, I call RunModalLoop on my hidden window, in a separate thread, since it's blocking. This fires up the message pump, and starts receiving the MFC dll's messages.
Edit: I could finally do it using just Win32 API. Here's my story, code included:
Programate Algo Blog. Don't worry, it's in English.

If the DLL works with Win32 messages you won't get around them. But you do not neccessarily need MFC for that, a simple WinAPI solution would suffice. MFC just wraps the Win32 API. If those messages aren't Win32 messages, you do not need a Win32 application.

Related

Is it possible to create window using C++/WinRT from a console application?

When using Win32 API, it's not really necessary to have a winmain entry point in order to create a window, because we can still call RegisterClassExW and CreateWindowExW, etc. I wonder if it's possible to do so as well in creating a C++/WinRT window, since almost every example on the Internet is using template projects.
I tried to create a struct which inherits implements<App, IFrameworkView, IFrameworkViewSource> with all necessary functions (Initialize, Uninitialize, Load, SetWindow, Run, etc.), then call CoreApplication::Run(winrt::make<App>()) inside int main(), but WinRT either complains about not having run init_apartment() beforehand, or shows a weird error as WinRT originate error - 0x80070057 : 'serverName' and that HRESULT is E_INVALIDARG, and that a hresult_invalid_argument(take_ownership_from_abi) is thrown. Plus, the source file created with template project doesn't even have to run init_apartment() first, which I couldn't really understand why.
Is it possible to create a C++/WinRT window from a console application? Thanks.
No.
UWP console apps may not create a window. They cannot use MessageBox(), or Location(), or any other API that may create a window for any reason, such as user consent prompts.
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/console-uwp

Asserts when using an extension dll in MFC

I am trying to create a new frame window with toolbars inside a dll.
I was able to create the frame and the toolbars but however the messages do not work properly in the CToolbar. Particularly the ON_UPDATE_COMMAND_UI messages are never called in the DLL.
After some research I came to know that this is because
PreTranslateMessage(MSG* pMsg)
and
OnIdle(LONG lCount)
need to be called.
But my calling application is Delphi based and this cannot be done.
After research I came to know that this is best possible from an Extension dll.
Since MFC extension dlls can only be called from an MFC application. I thought of the following solution.
Delphi calls an regular MFC dll
The MFC dll calls the Extension dll.
But I have run into problems because of asserts in in MFC AfxGetResourceHandle() and AfxGetInstanceHandle().
But I am also aware that AFX_MANAGE_STATE(AfxGetStaticModuleState()); cannot be called from an extension dll.
Does anybody have a solution for this problem?
The ON_UPDATE_COMMAND_UI messages are created by the MFC message loop. You don't have one. You will have to build your own ON_UPDATE_COMMAND_UI translator or something equivalent. It all starts with this in your frame window message map:
ON_WM_INITMENUPOPUP()
Your OnInitMenuPopup handler will be called when the user selects a menu, before the menu is displayed.

ON_REGISTERED_MESSAGE Win32 equivalent

I'm using Windows Hooks on my Win32 Application, I found ON_REGISTERED_MESSAGE in MFC Application that is uses for handle posted messages, but how can I use this method in Win32 without MFC classes?
You use RegisterWindowMessage() to get a message ID. That you then use in Post/SendMessage() calls. The code that processes the message also calls RegisterWindowMessage, using the exact same string. And gets the exact same message ID. And checks for a match in the window procedure with an if() statement.
The ON_REGISTERED_MESSAGE macro doesn't do much of anything, it just hides that if() statement.

Loading DLL and child dll calling parent class

I have an ActiveX dll that loads a child dll (NPAPI plugin). My child plugin creates multiple threads and they need to communicate back to the web page. In my ActiveX (parent dll) I have connection points to fire an event for javascript to provide updates. The problem I am having is that I do not know how the child can call the parent DLL.
What I have tried:
1: Passing a function pointer to the child dll of a function that is not within the class and used a global variable that is a pointer to the ActiveX class (this), but the connection point fails when Invoke with E_UNEXPECTED
2: Passing the child dll a pointer to my class function, and get the same results.
Im still learning C++ and COM at the same time, sorry for my ignorance. Thank you.
COM has ways to set things up so that you can call COM methods from other threads, but the easiest way for you to do this would be to make all calls back to the activex control on the main thread. One way to do this is to create a Message Window and post a windows message to it with the LPARAM being a pointer to a data structure containing the parameters needed to make the call; you create the structure and fill it out, then post the message and free the memory after your WINPROC has made the call.
FireBreath uses this approach and it works quite well. Speaking of which, have you considered implementing your NPAPI plugin as a FireBreath plugin so that it works in both activex and npapi?
Here are some code samples that may help:
WinMessageWindow (.cpp, .h) - this is a class FireBreath uses for creating message windows; pay particular attention to the DefaultWinProc which is used as part of an async (often cross thread) function call
NpapiBrowserHostAsyncWin (.cpp, .h) - this is a class used on some browsers for the npapi plugin to work around NPN_PluginThreadAsyncCall not working. It utilizes WinMessageWindow to make cross thread calls in _scheduleAsyncCall
Hope that helps

Handling Messages in Console Apps/DLLs in C++ Win32

I would like to have the ability to process Win32 messages in a console app and/or inside a standalone DLL.
I have been able to do it in .NET with the following article and it works great in C# inside a console app and standalone DLL
http://msdn.microsoft.com/en-us/magazine/cc163417.aspx
Is there a way to do the equivalent with C/C++ Win32 APIs? I have tried doing RegisterClassEx(...) and CreateWindow(...) even passing in HWND_MESSAGE to hWndParent but the trouble is that after the "invisible" window is created messages are not being processed probably due to the lack of a message pump.
Where would the message pump go if you had a DLL entry point? I have tried creating another thread in a DLL and put while(GetMesage(..)) there but that did not work either.
Any ideas?
You need a message pump yes. The window also has thread affinity so it needs to be created on the same thread that you're running the message pump on. The basic approach is sound, if you include more code it may become clear what the problem is.
In addition to what Logan Capaldo said, you also have the problem that, as a DLL, you don't know at compile time what kind of process is going to be loading you at runtime.
If you are being loaded by a console application (/SUBSYSTEM:CONSOLE), then creating a hidden window of your own and setting up a message pump on that same thread will work fine (as long as you are the first window created).
If you are being loaded by a windows app (/SUBSYSTEM:WINDOWS) then you might run into problems getting messages. They will be sent to the top-level window in the hierarchy, which you didn't create. You'll need to get the hWnd of the main process and subclass it (if you aren't already).
If you are being loaded by a service, then you aren't going to get window messages at all. You instead need to use the RegisterServiceCtrlHandlerEx Function