一.映射表
UDPMeditor.h中:
typedef void (UDPMeditor::*pFunc)(char*,long);struct ProtocolMap{ PackdefType pack;//协议 pFunc func;//函数地址};
UDPMeditor.cpp中:
static const ProtocolMap g_protocolmapentries[]={ {_DEF_PROTOCOL_ONLINE_RQ , &UDPMeditor::Online_Rq}, {_DEF_PROTOCOL_ONLINE_RS , &UDPMeditor::Online_Rs}, {_DEF_PROTOCOL_OFFLINE_RQ , &UDPMeditor::Offline_Rq}, {_DEF_PROTOCOL_DATAINFO_RQ , &UDPMeditor::Datainfo_Rq}, { 0,0}};
DealMessage函数:当收到一个消息,遍历数组,找出是哪个种类的消息,调用对应的处理函数
bool UDPMeditor::DealMessage(char* buf , long recvIp){ //处理数据 //判断这个包的类型 PackdefType *pType = (PackdefType *)buf; int i = 0; while(1) { if(g_protocolmapentries[i].pack == *pType ) { (this->*(g_protocolmapentries[i].func))(pType,recvIp); break; } else if(g_protocolmapentries[i].pack == 0 && g_protocolmapentries[i].func == 0 ) break; i++; } return true;}
二 . 按回车程序就退出的问题:
1.可能为按键消息
在Dlg类中添加Key Down消息
void CfeiQDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){ if(nChar == 13) return; CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);}
没效果
2.重写预处理函数
BOOL CfeiQDlg::PreTranslateMessage(MSG* pMsg){ // TODO: 在此添加专用代码和/或调用基类 if(pMsg->message == WM_KEYDOWN && pMsg->wParam == 13) { return FALSE; } return CDialogEx::PreTranslateMessage(pMsg);}
有效果
3.钩子(全局钩子和局部钩子)
局部钩子钩的是当前本线程的消息
全局钩子钩的是运行在操作系统上所有线程的消息
钩子列表
在初始化函数中
//初始化钩子
m_KeyHook = SetWindowsHookEx(WH_KEYBOARD ,KeyboardProc,NULL,GetCurrentThreadId());钩子函数的实现KeyboardProc
LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam){ if(wParam == 0xd) return 1; return CallNextHookEx(CfeiQDlg::m_KeyHook,code,wParam,lParam);}
在类中声明钩子为static,并进行初始化, HHOOK CfeiQDlg::m_KeyHook = NULL;
在销毁函数中释放:
if(m_KeyHook)
{ UnhookWindowsHookEx(m_KeyHook); m_KeyHook = NULL; }三 . 双击弹出窗口,进行对话
1.资源中添加一个Dlg,并创建类,
2.在feiQDlg中双击消息实现中非模态创建并显示(可以随意移动,SW_SHOW)
3.弹出窗口名称为IP, 且一个IP对应一个窗口(Map),当存在窗口时,将其位置显示在最上面(SetWindowPos)
4.在Destroy中删除创建的Dlg
双击消息实现:map<CString , MyDlgChat*> m_iptodlg;//使用map一定要加
void CfeiQDlg::OnLbnSelchangeList1(){ CString str; int index = m_listbox.GetCurSel(); if(index == -1) return; m_listbox.GetText(index,str); //判断窗口是否存在 MyDlgChat* pCMydlgChat = m_iptodlg[str]; if(!pCMydlgChat)//窗口不存在 { pCMydlgChat = new MyDlgChat; pCMydlgChat->Create(IDD_DIALOG1); pCMydlgChat->ShowWindow(SW_SHOW); pCMydlgChat->SetWindowText(str); m_iptodlg[str] = pCMydlgChat; } pCMydlgChat->SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE );}
非模态窗口×不能销毁窗口,只是关闭
非正常退出,不发送下线消息?
答:1.维护一个上线的好友列表,没有则添加。2.心跳机制:定期发送消息
点击关闭按钮,窗口还存在?