LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

send char array from CVI to VC window

My language is VC++ 6.0.I want to receive a char array from CVI in my MainFrame window.

My code in cvi:
//------------------------------------------------------------------------------------------------//
// the global window message that will be received by vc++ //
#define RESULT_MSG "{FE4EE340-6192-11d5-9B48-9BA90ACC8C0F}"
char TestMsg[100];
int PassFlag;

idResultMsg= RegisterWindowMessage(RESULT_MSG);
SendMessage(frmHandle,idResultMsg,PassFlag,(LPARAM)(LPCTSTR)TestMsg);
//---------------------------------------------------------------------------------------------------//

My code in VC:
//--------------------------------------------------------------------------------------------------/
/
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
//}}AFX_MSG_MAP
ON_REGISTERED_MESSAGE(idResultMsg,OnResultMsg)
END_MESSAGE_MAP()

LRESULT CMainFrame::OnResultMsg(WPARAM wParam/*PassFlag*/,LPARAM lParam/*TestMsg*/)
{
LPCTSTR str = (LPCTSTR)lParam;
return 0;
}
//----------------------------------------------------------------------------------------------------//

frmHandle is my MainFrame window handle,PassFlag is an integer,and received correctly.But TestMsg cannot.Why?

Any help be appreciated!
0 Kudos
Message 1 of 4
(3,680 Views)
Actually, this may be something obvious to point out, but you never set the contents of the TestMsg array in the sample code you gave. So it seems like you will have to give everyone more information about your program if you want any help on this.

Like, what exactly do you mean by "But TestMsg cannot."? Are you getting some pointer errors or is just the data in it unreadable? If you haven't already try assigining a string to the TestMsg array and see if it works then. Also are you sure you are using the message the way you want to (i.e. is the value you specified for the message significant or did you just make it up?), because you could try just using the message value to send the string with. Then again we do need more info.

Jason F.
Applications Engineer
Nation
al Instruments
www.ni.com/ask
0 Kudos
Message 2 of 4
(3,680 Views)
Hi!Jason F.,
Thanks for you instruction!
And here are some more detailed infomation:

My code in cvi:
//***---------------------------------------------------------------------------------------***//
//*** the global window message that will be received by vc++ *** //

#define RESULT_MSG "{FE4EE340-6192-11d5-9B48-9BA90ACC8C0F}"
char TestMsg[100];
int PassFlag;

//*** I've already got frmHandle----handle of MainFrame in VC *** //

Fmt(TestMsg,"There is an error occurs!\r\n");
PassFlag =1;
idResultMsg= RegisterWindowMessage(RESULT_MSG);
SendMessage(frmHandle,idResultMsg,PassFlag,(LPARAM)(LPCTSTR)TestMsg);

//** I set a breakpoint here.The Variables window shows:
//** TestMsg 00D572C0 "There is an error occurs!\r\n" char *

//** At this time,in VC,wParam/*PassFlag*/ is 1,that's right.And
//** lParam/*TestMsg*/ is
//** 00D572C0,does this mean I've received the correct array address?(But when I
//** see with VC Memory tool,this address has no character)If so,how to get the
//** contents?
//** I've tried with
//** LPCTSTR str = (LPCTSTR)lParam;
//** but error occurs "CXX0030:Error:expression cannot be evaluated..".
//---------------------------------------------------------------------------------------------------//

//** Whst's more..
//** If I use
//** SendMessage(frmHandle,WM_SETTEXT,0,(LPARAM)(LPCTSTR)TestMsg),
//** then in VC,
//** CString MsgString;
//** GetWindowText(MsgString);
//** can get the correct TestMsg.That is MsgString is "There is an error occurs!\r\n".

//** Then what shall I do to get a char array from cvi?

Thanks & Regards,
Lily
0 Kudos
Message 3 of 4
(3,680 Views)
Lily,

I have the same needs and have come to the unfortunate conclusion that sending character strings To CVI From VC++ is not supported by the Windows Messaging hooks provided by National Instruments. {Note that it IS possible to send character strings in the From CVI To VC++ using the SendMessage() function supported by the SDK tools (see an example below). The 'why' is associated with how Windows itself passes messages (WM_COPYDATA works in Windows by actually making a temporary copy of a data structure and making that available to the receiving process - at which point the temporary data is deleted from the Windows Message memory space. All other messages of type (HNDL, MSG, WPARAM, LPARAM) won't support passing pointers to strings, you can pass integers all day long - but not pointers to arrays of data.


We are pursuing a completely different approach (using DCOM) to implement the same need. Another approach (ugly but doable) would be to send all messages via File I/O, or by using TCP messaging - The Windows Messaging approach is a dead-end for bi-directional character message passing (unless NI provides a library update to support WM_COPYDATA messages.

Example on how to send strings From CVI To VC:
===================================================
First: A Comment on how to establish a 'unique' communication link between
your CVI and VC processes:

Step 1. I have both processes establish a Unique Message Id using the Windows SDK function "RegisterWindowMessage()" (you must put "#include " in your CVI File.

In CVI and VC it would look like:
" ui32UniqueMessage = RegisterWindowMessage((LPCSTR) ("MyConnectStr"));"

You can forgoe the call above in CVI and use the following (which you will need anyway - see Step 3);

" ui32UniqueMessage = RegisterWinMsgCallback (EstablishLinkCALLBACK,
"MyConnectStr",
"MyConnectStr", /* This string will be passed to the callback */
i32size, /* can be zero , or strlen("MyConnectStr") */
ui32MsgCallbackID, /* Needed later to unregister the callback */
TRUE);


Step 2. Set up an 'ON_REGISTERED_MESSAGE' procedure in VC to capture the Broadcast Message

Example;

" ON_REGISTERED_MESSAGE(ui32UniqueMessage ,OnCVIPageMsg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
"

Note: When I send the Broadcast Message from CVI I include CVI's window handle in the WPARAM field (I obtain this using "mhThisHndl = (HWND) GetCVIWindowHandle();")

Step 3. Setup the EstablishLinkCALLBACK in CVI to capture messages sent by VC - In this callback I 'expect' to find VC's window handle provided in the WPARAM field. I use this handle in all subsequent calls to the VC process to avoid using BROADCAST.

Step 4. In CVI - Send BROADCAST Windows Message using ui32UniqueMessage as your message {put mhThisHndl in the Wparam field}

From this point on - both processes/threads 'know' each others window handle and can just send messages to the applicable window.


===================================================
Sending Strings to VC from CVI:
===================================================
INT32 SendWinMessage(char *message)
{
INT32 i32Err = 0, i32Status = 0;
WIN_MSG_STRUCT *ptMsgStruct = NULL;
COPYDATASTRUCT *ptData = NULL;

ptData = malloc(sizeof(COPYDATASTRUCT));
ptData->dwData = (DWORD) mhThisHndl;/* CVI's window handle */;
ptData->cbData = strlen(message);
ptData->lpData = message;

i32Status = SendMessage((HWND) tSimHandle /* Window Handle of VC process */,
WM_COPYDATA,
(WPARAM) ATE_COMMAND_MSG /* you define */
(LPARAM) ptData );


free(ptData);

return i32Err;
}
=============================================================
D.Barbour
drbarbour@certtech.com

I hope this helps!
Message 4 of 4
(3,680 Views)