-
October 11th, 2013, 05:37 PM
#1
Receiving a Windows Message in a Console Application
Hello,
I'm trying to write a program that passes Windows messages back and forth from another program that controls a laboratory instrument. I'm in a bit over my head but with the help of the manual I was able to write a program that successfully passes instructions, as evidenced by the instrument doing what I tell it. However, I am having trouble getting a return status from the instrument. The manual instructs the following:
// demo code, etc.
// send message to the instrument operating software here...
SendMessage(hwnd, WM_COPYDATA, tag, (LPARAM) &cd)
Either a completion message or return data is returned. Remote commands ReturnStatus,
ReturnTiming, and ReturnData return data. In either case, data is received through an
asynchronous windows message inside Win32 COPYDATASTRUCT type data packet.
For example, a typical OnCopyData window callback is shown below, where the string
data retrieved is finally stored into a Microsoft CString object. Note the use of variable
replyTag, discussed above, which is used to isolate the correct windows message returned.
BOOL CUserDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* cd)
{
….
if (cd->dwData == replyTag)
{
/* String pointing to status */
CString retStatus = (char*) cd->lpData;
}
….
}
I can't tell if my problem is in generating the replyTag, getting the HWND to my own console window, or the actual receiving part of the code.
When setting the replyTag, the manual instructs: UINT replyTag = RegisterWindowMessage(“SOFTMaxProReplyMsg”);. However, I have to put an "L" in front of the string or I get a data type error (can't convert const char* to LPCWSTR).
When setting a HWND for myself, the manual instructs: HWND MyWnd = GetSafeHwnd().
That produces an error because GetSafeHwnd is a function of the Cwnd class, and I don't have a Cwnd. I have replaced it with HWND MyWnd = GetConsoleWindow();
When listening for the reply message, the manual instructs what I quoted above. However, I again don't have a Cwnd. I therefore simply used
if (cd.dwData == replyTag)
{
CString retStatus = (char*) cd.lpData;
}
The above if statement always evaluates false, and the cd.lpdata contains the message that I had sent out instead of a reply message. If anyone could help me figure out how to get a reply using my console application, I would really appreciate it. Here is the full code of my function:
Code:
#include "stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<afxwin.h>
using namespace std;
void SendCommand(string command)
{
// Get tags to identify the receiving and sending messages
UINT tag = RegisterWindowMessage(L"SOFTMaxProMsg");
UINT replyTag = RegisterWindowMessage(L"SOFTMaxProReplyMsg");
// Get the window handles for the receiving software and my program
HWND hwnd = FindWindowA("SOFTMaxProMainWnd", "SoftMax Pro");
HWND MyWnd = GetConsoleWindow();
// convert the function's parameter appropriately for a COPYDATASTRUCT
char *cmdStr = (char*) command.c_str();
char *msgStr = _strdup(cmdStr);
// Generate the COPYDATASTRUCT to send
COPYDATASTRUCT cd;
cd.dwData = (DWORD) MyWnd;
cd.cbData = strlen(msgStr)+1;
cd.lpData = msgStr;
// Send message to the receving software
SendMessage(hwnd, WM_COPYDATA, tag, (LPARAM) &cd);
// Message gets successfully sent.
// Attempt to receive message (not successful and don't know why).
if (cd.dwData == replyTag)
{
cout << "here" << endl;
// String pointing to status //
CString retStatus = (char*) cd.lpData;
cout << retStatus << endl;
}
else
{
cout << "else" << endl;
cout << (char*) cd.lpData;
}
}
-
October 11th, 2013, 06:07 PM
#2
Re: Receiving a Windows Message in a Console Application
To receive messages, the program is going to have a message pump. By default, a console application does not have a message pump. What you can do is to create a second worker thread inside the console app, and pump messages within this thread. Of course you will need to synchronize any data that is shared between the main console app thread and the worker thread.
-
October 14th, 2013, 01:17 AM
#3
Re: Receiving a Windows Message in a Console Application
Originally Posted by Arjay
To receive messages, the program is going to have a message pump. By default, a console application does not have a message pump. What you can do is to create a second worker thread inside the console app, and pump messages within this thread. Of course you will need to synchronize any data that is shared between the main console app thread and the worker thread.
Thanks for your help! I tried the multithreading and that was too tough for me but I read a few Win32 tutorials over the weekend and was just able to construct a simple program to send and receive messages from the spec. Thanks for putting me on the message pump trail!
-
October 14th, 2013, 07:48 AM
#4
Re: Receiving a Windows Message in a Console Application
There's a big difference in how a console program typically works, and how a GUI program works.
console programs tend to be "linear", the program does stuff in specific order. Any output is "forgotten" as far as the program is concerned (the console manager will handle display) and any input is typically synchronous (the program stops and waits until the necessary input has been given).
GUI programs or any program needing to handle windows messages are "event driven". You don't know what wil happen in what order (although there are some guarantees of course). ANd the application is expected to promptly service each incoming message and return appropriately within a very short timeframe or the application will appear to 'hang' (=not responsive). Again, for a console app, it's the console manager that takes care of all this.
You will need to somehow integrate these different approaches, and as Arjay pointed out, a worker thread is the most Obvious way out. It'll require the "console" end of your app to synchronise with the workerthread to "wait" for the data from the windows message.
Getting this to work properly is tricky.
It might be easier to look into changing your app to be a simple GUI based program.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|