zoukankan      html  css  js  c++  java
  • MFC用PostMessage传递消息

    1.自定义消息ID。

    #define WM_MY_MESSAGE (WM_USER+100)         WM_USER为windows系统为非系统消息保留的ID,这里至少要用100,因为其它控件的消息会占用一部分。

    2. 定义消息处理函数。

    消息处理函数为消息目标类的成员函数。首先应该在.h 文件中声明。这里以主窗口类为例,主窗口类名 CMainDialog,则首先在CMainDialog.h声明消息处理函数。

    protected: 

    afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); 

    3.在CMainDialog.cpp中实现消息处理函数

    LPESULT CMainDialog::OnMyMessage(WPARAM wParam, LPARAM lParam) 

    // TODO: 处理用户自定义消息 
    ... 
    return 0; 
    }

    4.在CMainDialog.cpp中映射消息ID和消息处理函数

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) 
    ON_WM_CREATE() 
    ON_WM_TIMER() 
    ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage) 
    //}}AFX_MSG_MAP 
    END_MESSAGE_MAP()

    在创建线程的时候将主窗口句柄作为参数传入线程,就可以用 PostMessage传递消息了。

    SendMessage函数功能描述:将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口过程,直到窗口过程处理完消息后才返回。

    Postmessage函数则是将消息放入消息队列里,并立即返回。

    常见问题

    1)使用SendMessage来实现剪切、复制和粘贴

    1 SendMessage(hwnd, WM_COPY, 0, 0);
    2 SendMessage(hwnd, WM_CUT, 0, 0);
    3 SendMessage(hwnd, WM_PASTE, 0, 0);

    2)SendMessage与PostMessage的区别

    PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回。

    3)SendMessage发送WM_COPYDATA消息在进程间传送数据

    WM_COPYDATA消息主要目的是允许在进程间传递少量只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。

    例如:

    1 std:string strData = "VC知识库 VCKBASE.COM";
    2 COPYDATASTRUCT cds;
    3 cds.dwData = 0;
    4 cds.cbData = strData.Length();
    5 cds.lpData = strData.c_str();
    6 ::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cds);

    3、PostThreadMessage有时会失败,报1444错误(Invalid thread identifier. ),其实这不一定是线程不存在的原因,也有可能是线程不存在消息队列(message queue)造成的。事实上,并不是每个thread都有message queue,那如何让thread具有呢? 答案是,至少调用message相关的function一次,比如GetMessage,PeekMessage。

    4、如果是postthreadmessage动态分配的memory给另外一个thread,要注意内存的正确释放。并且PostThreadMessage不能够post WM_COPYDATE之类的同步消息,否则会报错!

    5、最好不要使用PostThreadMessage post message给一个窗口,使用PostMessage替代。

    1    #include <windows.h>
    2    #include <cstdio>
    3    #include <process.h>
    4    #define MY_MSG WM_USER+100
    5    const int MAX_INFO_SIZE = 20;
    6    HANDLE hStartEvent; // thread start event
    7    // thread function
    8    unsigned __stdcall fun(void *param)
    9    {
    10        printf("thread fun start
    11    
    12    
    13    
    ");
    14        MSG msg;
    15        PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
    16        if(!SetEvent(hStartEvent)) //set thread start event 
    17        {
    18            printf("set start event failed,errno:%d
    ",::GetLastError());
    19            return 1;
    20        }
    21        
    22        while(true)
    23        {
    24            if(GetMessage(&msg,0,0,0)) //get msg from message queue
    25            {
    26                switch(msg.message)
    27                {
    28                case MY_MSG:
    29                    char * pInfo = (char *)msg.wParam;
    30                    printf("recv %s
    ",pInfo);
    31                    delete[] pInfo;
    32                    break;
    33                }
    34            }
    35        };
    36        return 0;
    37    }
    38    int main()
    39    {
    40        HANDLE hThread;
    41        unsigned nThreadID;
    42        hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event
    43        if(hStartEvent == 0)
    44        {
    45            printf("create start event failed,errno:%d
    ",::GetLastError());
    46            return 1;
    47        }
    48        //start thread
    49        hThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );
    50        if(hThread == 0)
    51        {
    52            printf("start thread failed,errno:%d
    ",::GetLastError());
    53            CloseHandle(hStartEvent);
    54            return 1;
    55        }
    56        //wait thread start event to avoid PostThreadMessage return errno:1444
    57        ::WaitForSingleObject(hStartEvent,INFINITE);
    58        CloseHandle(hStartEvent);
    59        int count = 0;
    60        while(true)
    61        {
    62            char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
    63            sprintf(pInfo,"msg_%d",++count);
    64            if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg
    65            {
    66                printf("post message failed,errno:%d
    ",::GetLastError());
    67                delete[] pInfo;
    68            }
    69            ::Sleep(1000);
    70        }
    71        CloseHandle(hThread);
    72        return 0;
    73    }
  • 相关阅读:
    2020牛客暑期多校第三场B-Classical String Problem(字符串移动思维)
    2020牛客暑期多校第四场B-Basic Gcd Problem(思维+数论)
    2020牛客暑期多校第三场E-Two Matchings(规律DP)
    2020牛客暑期多校第三场C-Operation Love(计算几何-顺逆时针的判断)
    odoo高级物流应用:跨厂区生产
    Odoo车辆管理
    安装odoo 9实录
    Odoo 养猪
    【转】结转本年利润的有关分录
    Odoo POS
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/5729539.html
Copyright © 2011-2022 走看看