It may be desirable sometimes (for instance, for testing purposes) to send a message to a window of some application. Initially,
MessageSender was created just for sending such messages, normally
WM_USER + XXX or
WM_APP + XXX or some system messages not containing pointers. Later, I added a few more features such as context and time customization. A few messages, such as
WM_SETFONT, can also be customized. Their list is not so long though; I did it just for my favorite ones.
Settings and Operations
You can provide the handle of a window or its title and class. Alternatively, you can use a window-finding tool thanks to Lim Bio Liong and his article MS Spy++ style Window Finder. Also, you can navigate along next/previous or parent/first child windows.
Enter message code (hex) or select a message from the list, specifying their
lParam. For a few messages, you can customize their parameters in a more natural way. It is especially useful for those whose values should be pointers. See, for instance,
You can select among the
SendMessageTimeout() functions to send a message.
Some messages cannot be sent to windows from a different thread. If target window thread context is selected,
MessageSender first installs a hook on the target window, injecting msgsndr.dll to its process address space. During the first call to the hook function, a new hidden window will be created in the target thread context. This window will serve as a medium while sending messages. Namely,
MessageSender will pack an original message and send it packed using
WM_COPYDATA to that hidden window. Then the window procedure unpacks it and forwards to its target. Note that the last steps will be performed not in
MessageSender, but in the target thread context.
Normally messages will be sent once, as soon as you press the "Send it!" button. By specifying correspondent values, you can do it later or a few times in a chain.
Using the Code
I hope that the code is more or less self-explanatory. The workspace contains two projects, MessageSender (EXE) and msgsndr (injecting DLL). The main application dialog is
CMessageSenderDlg (files: MessageSenderDlg.cpp and MessageSenderDlg.h).
It is possible that you would like to add customization for more messages. To protect my code from frequent changes, I derived
CSendMessageDialog (files: SendMessageDialog.h and SendMessageDialog.cpp) from
CMessageSenderDlg. Implement accordingly some or all of its functions:
class CSendMessageDialog : public CMessageSenderDlg
virtual void AddConstantsToCombo();
virtual void MessageChanged(UINT unMessage);
virtual void CustomizeMessage(UINT unMessage);
virtual void PreSendMessage(SendingMessage*);
virtual void PrepareMessageLocal(SendingMessage*);
virtual CString DisplayMessageLocalResults(SendingMessage*);
virtual void PrepareMessageTarget(SendingMessage*);
virtual CString DisplayMessageTargetResults(SendingMessage*);
In addition, add necessary code to
InsertedDialogProc() in the DLL (file: msgsndr\msgsndr.cpp). I have marked correspondent places by
TODO comments. If you do this job, please do not forget to send me a copy!
Sending some messages may cause unpredictable results. Target applications may stop working properly and you can lose some data. It is recommended to close all applications but the one you're testing.
Sep 2, 2003
Sep 9, 2003
- "Find window" tool is now able to catch more windows, including disabled and hidden child windows.
- Navigation along next/previous or parent/first child windows was added.
- Message processing result is now available in both local (i.e.
MessageSender) and target window thread context.
Aug 23, 2004
- Information about thread / process / path to the executable file (the latter is not available under Windows NT).
- Possibility to navigate back and forth through already found windows.
- Main window is automatically reduced in size while using the "Find window" tool.
Aug 20, 2007
WM_COPYDATA message can now be customized and sent from
MessageSender thread context.