I have an application which utilises two version of projects one is MFC based and other is win32 based project. For communicating between these two projects I am using SendMessage() with only one input in LPARAM. Is there any way I can send multiple input or array of inputs/object in LPARAM of SendMessage().
I will write the code if required
Use WM_COPYDATA. The documentation also contains a sample.
Related
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.
ive recently started to work with the win32 api and im trying to do a couple of things.
I have a project that is gonna use about 4-5 windows. I want to seperate each of these into a different cpp file where each has its own message Loop. How do i pass information from window to window?(is there some sort of entry point?) at the moment im creating all windows during case WM_CREATE: and I am showing them as required.
I am trying to have a nice OOP design but having trouble with that, my main issue is the communication between windows. I have a fair amount of experience in C# and C++ and other than this the win32 api is not being a problem.
Thanks for your help!
I don't think you want a per-window message loop, unless you want each window in its own thread. You probably need a window procedure instead.
Each window class has its own window procedure, which you register by setting lpfnWndProc field of WNDCLASS structure before passing it to the RegisterClass. Once you've done that, you can use that class when creating a new window with CreateWindow.
In your case, you'll probably want to implement the window procedure so it accepts custom messages (WM_APP + x), and then pass custom messages between windows using PostMessage (for asynchronous communication) or SendMessage (for synchronous communication). If necessary, you can create separate window classes and window procedures for your different windows. A single message loop is capable of pumping messages to all these procedures.
The classic way of inter-window communication is sending / posting messages:
SendMessage
PostMessage
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.
Short version:
How can I receive input messages in Windows with C++/C when the window is not active?
Background information:
I'm currently working on an Input System that should not depend on any window, so it can e.g. be used in the console as well.
My idea is to create an invisible window only receiving messages, which is possible using HWND_MESSAGE as hWndParent. It only receives input messages when it's active though, and I don't want this. It should always receive input (unless the application requests it no longer does so, e.g. because it lost focus).
I know this is possible somehow, many applications support global shortcuts (e.g. media players (playback control) or instant messengers (opening the contact list)), I just don't know how. Do you know?
Options:
RegisterHotKey if you need to register just one or a few hotkeys
SetWindowsHookEx with WH_KEYBOARD / WH_KEYBOARD_LL. Use when you need to filter many or all keyboard events. However, the hook code needs to be implemented in a DLL (which is loaded into other processes). You need separate 32 bit and 64 bit versions of the DLL
You need to setup windows keyboard input hook. Here is an example how to do it; it is even easier to do in C++
There are few things I'm not sure of :
When you create a basic SDI using MFC app wizard (let's call it TestMfc) you get :
4 major classes :
CTestMfcApp
CTestMfcView
CTestMfcDoc
CMainFrame
What I noticed is that CTestMfcApp has those declaration
ON_COMMAND(ID_APP_ABOUT, &CTestMfcApp::OnAppAbout)
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
while CTestMfcView has these :
BEGIN_MESSAGE_MAP(CTestMfcView, CEditView)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, &CEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CEditView::OnFilePrintPreview)
END_MESSAGE_MAP()
What I don't understand is why does MFC create that separation?
I can't see why the app class needs to declare functions for handling events... isn't that the view's job? If for exmaple there are few windows it's even becoming more clear.
Second, how those events get called? I know there's supposed to be WINPROC function who's supposed to get the MSG and call the right handler. is the ON_COMMAND the macro who sets some kind of pointer function who is later available to the the WINPROC function.
And why doesn't the ON_COMMAND get a WINDOWS handle... if for example there is another WINDOW in the program with the same ID ?
Third and last, let's say I want to change some window's threads to an alert state.
To do that I want to change the main loop (which keeps calling getmessage/dispatchmessage
etc.. and insert the waitformultibleonject function. where is the winmain function? I can't find it when the appwizard is doing all the job for me.
Thanks!!
In MFC, messages "bubble up" until they find a handler. IIRC it's View -> Document -> Document Template -> MainFrame -> App. This allows to handle view-specific events in the view, document-specific events in the document etc.
Usually, global handlers end up in the mainframe class. However, you can use multiple mainframe windows - even with different behavior - where the distinction between "MainFrame" and "App class" becomes important.
Control-specific handlers do belong in the view class, though. I'd put only WM_COMMAND handlers into higher-up classes.
for your third question: I wouldn't do that. While MFC avoids a few common modal loops, you can't avoid them all. OnIdle is a good place to implement defered updates.
[update] MFC uses one global WNDPROC to handle all messages. It uses a HWND to CWnd mapping to locate the MFC object. When the WNDPROC sees a WM_COMMAND message, it will first check the message map of the receiver window if it contains a handler for that message. If there is none, it will do a variety of checks, e.g. "Is this not just a CWnd, but a CView?" Yes --> get the document and see if the documents message map has a handler for this particular command.
Introduction to the MFC architecture
The Microsoft Foundation Class library framework does a reasonable job of providing the basics of an MVC design pattern using messages of various sort to provide the communication between the various parts. However like any framework it provides a structure which can provide lots of functionality you do not have to write as well as quite a bit of restrictions and constraints if your approach is not congruent with the framework.
The framework uses messages between cooperating entities, extending the idea of Windows messages and using the message infrastructure of the Windows operating system. Some of these cooperating entities have their own Windows message pump (modal dialogs and threads) while the rest use the application message pump serviced by the main or UI thread.
Messages sent to the application's main window such as keyboard or mouse events or posted messages using PostMessage() are pulled off the Windows message queue by the main window thread, also known as the main UI thread, servicing the message pump and then forwarded to the entity that it belongs to by the MFC framework. This is why actions that pause or wait the main UI thread make the application unresponsive. The main UI thread must continually run to pull Windows messages from the Windows message queue and then distribute them to the rest of the application.
The MFC framework forwards messages by looking through a list of message maps in order to find which entity or MFC class instance is expecting the message and if one is found, calling the C++ function specified in the message map entry with the arguments the MFC specification requires. The expectation is that any message processing function will either complete the action quickly and return back to the MFC framework's message dispatch functionality or will use a thread to perform any action that requires some time and then return.
The MVC design pattern views the application as made up of three cooperating entities, the Model entity containing the data, the View entity which presents a view of the Model and its data, and the Controller entity which is the affordance the user manipulates to change what is viewed as well as the model and its data.
The MFC framework architecture starts with a couple of base classes which are then specialized through inheritance. For instance there is a general view class which provides the message infrastructure for a general display then subclasses extend and specialize the general view class. For instance the CView class is specialized with the CScrollView class.
Main types of MFC UI classes
In general the document class will handle messages that involve changes to the document content and the view class will handle messages that involve the presentation of the document content. The document class is responsible for serializing all of the data or content to or from the document object from or to a file.
The document class uses the Observer design pattern to allow views to know when an update is needed. The document class has a list of view instances so that when a change is made to the document or model or data, all of the registered views are sent a message indicating a change and need to update.
The view class is responsible for displaying a view of the document data to a device such as a window on the screen or a printer. So it would be normal for a CView class to have a function that would handle a print request sent via a message with a message Id of ID_FILE_PRINT or ID_FILE_PRINT_PREVIEW.
When data within the document changes, a message can be sent to all of the views registered with the document informing those views of the data change so that the views can decide whether to make changes to the view or not.
The third main class of the framework, the CWinApp or application class is a container and manager for the document and view classes. Within the app object, which is the entry point for the application (a construct which is also used for an MFC DLL as well to provide for the DLL load and unload entry points), is the hooks for the main message pump. The purpose of the app class is to set up the initial environment and to then allow the programmer to hook their particular document and view objects into the MFC framework of the app class.
Since the CWinApp class is a container for the application, it would be normal for it to handle such events as ID_FILE_NEW or ID_FILE_OPEN as it would cause the document class to close out the current document and reinitialize the application to start with a new document and its associated views.
My opinion is that the About dialog handling and Help handling was put into the CWinApp class since it was the easiest place to put it. Typically an About is a dialog with a basic description of the application. And both Help and About may be things you want to access without having to start a document or view first.
The MFC framework has other, supporting classes for the main UI functionality. There are also other additional libraries that have been added since MFC was first introduced in the early 1990s.
A few details about messages
Windows messages have a message Id indicating the type of message. There are various ranges of message Id values that are allocated to different purposes. One range is the WM_USER range that an application can use without concern of using a message Id assigned to a Windows message such as a keyboard message. Part of this range is allocated to MFC messages (see WM_USER vs WM_APP as well as Sending and receiving Windows messages as well as How to handle a posted, registered windows message within a VCL application? ).
These messages are standard Windows messages using PostMessage() or SendMessage() with the standard Windows format of handle of the target window, a message identifier, and the two parameters which are used to provide additional information. The MFC framework has lots of different C Preprocessor defines for various message identifiers. If you follow the class derivation hierarchy you will find that document classes, CDocument, end up being derived from CCmdTarget classes just as the view classes, CView or derivations of CView, are as well. CCmdTarget in turn derives from the most basic MFC class, CObject.
Much of the message map functionality seems to come from the functionality of the CCmdTarget class which uses a method of accepting a message, checking to see if the message identifier is in the CCmdTarget message list for the specific object and if not passing it on to the next CCmdTarget object in the chain. So the MFC framework uses a kind of Strategy Design Pattern so that a message is passed along a chain of components until an object that can handle the message is found.
Due to the age of the MFC framework, quite a bit of the exposed pieces use the C Preprocessor and macros. You can inspect the macros to see what they are doing and how they are implemented using the Visual Studio IDE. And those parts of the MFC framework that are implemented as templates are also easily available through the Visual Studio IDE to read. Both macros and templates are in the MFC include files.
However to read the code in the actual classes you will need to find a copy of the MFC source body. Using the MFC Source Files from the Microsoft web site provides a starting point including where to find the source from your installation of Visual Studio.
The Microsoft Foundation Class (MFC) Library supplies full source
code. Header files (.h) are in the \atlmfc\include directory;
implementation files (.cpp) are in the \atlmfc\src\mfc directory.
I would not recommend forking this with your own changes.
Your third question is about threads and the approach you describe does not make sense within the MFC framework. With MFC you would normally create a thread using the AfxBeginThread() or AfxBeginThreadEx() functions. There are two kinds of threads, one with a user interface and one without.
It does not make sense that a multi-threaded MFC application would need to modify the message pump. You would instead send messages to the thread once you have created it using something like PostThreadMessage(). The thread can receive messages by calling either the GetMessage() or PeekMessage() functions. Each MFC thread has a message pump and message queue that is set up "when the thread makes its first call to one of the User or GDI functions" (see PostThreadMessageW function).
References
Is MFC is based on any design pattern,if so which design pattern?
Windows Messages
SendMessage/PostMessage to a derived CView class not working for MFC application
MFC - How to post a message to all views that were derived from CView class?
Is the 'C' in MVC really necessary?
This article, Threads with MFC, in code project provides an overview and source example.
Print is normally handled in the view because in win32 you print by calling the OnPaint event to a printer rather than the screen. Also for any events that involve getting the mouse position it's easier to do it in the view.
You can easily get the current doc form the view but it's more effort to get the view form the doc.