公司不知道从哪里搞来的源代码,有个库是没有代码的,导师让我把它重写。这个库的的类是一个中间类,被应用程序用作收发消息,被通信模块也用作收发消息。
消息模式是COPYSTRUCT
大概的过程如下:
应用模块收集设备的信息,比如设备状态,设备耗材等,通过这个中间类,发送给通信模块,通信模块接收到后,再发送主机。然后主机进行处理,主机应答后,再发回给
通信模块。通信模块收集到主机的指令后,通过这个中间类,再发送给应用模块,让应用模块继续处理或者完成。
该类接口是
class __declspec(dllexport) CIPC
{
public:
CIPC();
virtual ~CIPC();
bool Create(CString csTitle);
void Release();
int Send(CString csRevWndTile, DWORD dwCode, LPVOID pData, DWORD dwSize);
virtual int OnReceive(CString csSendWndTile, DWORD dwCode, LPVOID pData, DWORD dwSize) = 0;
private:
classCManager *m_pManager;
};
class CManager
{
public:
CManager(CIPC* pIPC);
virtual ~CManager();
//创建一个隐藏窗口,用于收发WINDOWS消息
bool Create(CString csTitle);
//释放窗口资源
void Release();
//发送消息函数
//csRevWndTile 接受窗口名
//dwCode 消息码,触发窗口的函数动作
//pData 传递的数据
//dwSize 数据大小S
int Send(CString csRevWndTile, DWORD dwCode, LPVOID pData, DWORD dwSize);
private:
bool RegisterWindow(); //注册窗口函数
//void CreateWindow();
private:
HWND m_hHandle;
};
Create函数用来创建一个隐藏的窗口,处理WINDOWS消息。实现方法为:
bool CManager::Create(CString csTitle)
{
/*
bool bRes = false;
m_csSendWndTile = csTitle;
CString strMyClass;
try
{
strMyClass = AfxRegisterWndClass(0);
TRACE("WindowName: %s\n", strMyClass);
}
catch (CResourceException* pEx)
{
AfxMessageBox( _T("Couldn't register class! (Already registered?)"));
pEx->Delete();
}
if (!(bRes = m_hCreateWnd.CreateEx(0, AfxRegisterWndClass(0), \
_T(csTitle), \
WS_POPUP | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, 0)?true:false))
{
TRACE0("Warning: unable to create window!\n");
AfxThrowResourceException();
}
m_hCreateWnd.ShowWindow(SW_HIDE);
m_hCreateWnd.UpdateWindow();
*/
if (!RegisterWindow())
{
TRACE("register ipc window failed");
return false;
}
m_hHandle = CreateWindow(AfxGetAppName(),
TEXT(csTitle),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
AfxGetInstanceHandle(),
NULL);
if (m_hHandle == NULL)
{
TRACE("create ipc window failed");
return false;
}
m_csSendWndTile = csTitle;
ShowWindow(m_hHandle,SW_HIDE);
UpdateWindow(m_hHandle);
return true;
}
创建窗口的时候需要注册窗口类,窗口类中有个注册函数,也就是回调函数,用来处理接收的消息,也就是该回调函数需要调用OnReceive接口。
该回调函数实现方法是
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COPYDATA:
COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
if ((cds!=NULL)&&(m_ipc!=NULL))
{
//m_ipc为CIPC的类对象,
m_ipc->OnReceive(m_csSendWndTile,cds->dwData,cds->lpData,cds->cbData);
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
send函数用来向接收窗口发送消息,实现方法为
HWND hRecvWnd = NULL;
HWND hSendWnd = NULL;
// Get target Window handle
for(int ix = 0; ix < 3; ix++)
{
::Sleep(10);
//hRecvWnd = ::FindWindow(NULL,gcsATMCWndTitle);
hRecvWnd = ::FindWindow(NULL,csRevWndTile);
if(NULL == hRecvWnd)
{
continue;
}
hSendWnd = ::FindWindow(NULL,m_csSendWndTile);
if(hSendWnd != NULL)
{
break;
}
}
if(NULL == hRecvWnd || NULL == hSendWnd)
{
TRACE("IPCSendMsg: NULL window handle\n");
TRACE("GetLastError returned %u\n",GetLastError());
//theLog.Write(LOG_ERROR,"IPC: can not find %s.",( NULL == hRecvWnd ? gcsATMCWndTitle : gcsPacketWndTitle ) );
return -1; // Window not found
}
inti = 0;
DWORDdwResult;
LRESULTret;
COPYDATASTRUCTcds;
do{
TRACE("Sent: Message Code = %d\n", dwCode);
cds.dwData = dwCode;
cds.cbData = dwSize;
cds.lpData = pData;
ret = ::SendMessageTimeout(hRecvWnd,// handle to window
WM_COPYDATA, // message type
(WPARAM)hSendWnd,// first message parameter
(LPARAM)&cds,// second message parameter
SMTO_BLOCK,// send options
3000,// time-out duration
&dwResult);// return value for synchronous call
if(0 == ret)
{
TRACE("%d Send Message Fail,GetLastError returned %u\n",(i+1),GetLastError());
// Re Get target Window handle
hRecvWnd = ::FindWindow(NULL,csRevWndTile);
}
}while ((ret == 0) && (++i < 3));
if (3 == i)
{
TRACE("Send Message Time-Out\n");
return -2; // Time Out
}
//AfxMessageBox("Send Message ok\n");
return 0;
RegisterWindow窗口实现方法为:
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = AfxGetInstanceHandle();
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = AfxGetAppName();
if (!RegisterClass(&wndclass))
{
return false;
}
return true;