FeiQ项目

一.映射表

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.心跳机制:定期发送消息

点击关闭按钮,窗口还存在?

posted @ 2018-03-19 11:42  Lune-Qiu  阅读(214)  评论(0编辑  收藏  举报