一.映射表
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.心跳机制:定期发送消息
点击关闭按钮,窗口还存在?