通过线程传递消息

今天讲一下线程如何向对话框传递消息,步骤如下:

  1. 创建消息数,在xxDlg.h: #define WM_RESPONSE WM_USER+1 
  2. 声明消息函数成员函数xxDlg.h: afx_msg LRESULT winMessageFun(WPARAM wParam, LPARAM lParam); (注意返回值类型为LRESULT,在VC里可以是void 类,但在vs内会提示不兼容,只能用LRESULT)
  3. 添加消息映像xxDlg.cpp: ON_MESSAGE(WM_RESPONSE,winMessageFun) 
  4. 定义消息响应函数xxxDlg.cpp:
    LRESULT CMFCApplicationThresdDlg::winMessageFun(WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(wParam);
        UNREFERENCED_PARAMETER(lParam);
        WORD value = lParam;
        CString str;
        str.Format(_T("%d\r\n"), value);
        m_edit1 += str;
        UpdateData(FALSE);
        return 0;
    }

     

  5. 定义线程传递参数结构体
    1 struct ThreadParam
    2 {
    3     HWND ThreadID;
    4     WORD ThreadVal;
    5 };

     

  6. 创建线程,在点击按键后启动线程:
    1 void CMFCApplicationThresdDlg::Btn_Clicked_Start()
    2 {
    3     // TODO: Add your control notification handler code here
    4     ThreadParam *pRecvParam = new ThreadParam;
    5     pRecvParam->ThreadVal = 0;
    6     pRecvParam->ThreadID = m_hWnd;
    7     //create thread
    8     HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)pRecvParam, 0, NULL);
    9 }

     

  7. 声明线程函数xxDlg.h: 
    1 private:
    2     static DWORD WINAPI ThreadProc(LPVOID lpParameter);
  8. 定义线程函数:
     1 DWORD CMFCApplicationThresdDlg::ThreadProc(LPVOID lpParameter)
     2 {
     3     WORD value = ((ThreadParam*)lpParameter)->ThreadVal;
     4     HWND hwnd = ((ThreadParam*)lpParameter)->ThreadID;
     5     while (1)
     6     {
     7         value++;
     8         ::PostMessage(hwnd, WM_RESPONSE, 0, (LPARAM)value);
     9         Sleep(1000);
    10     }
    11     return 0;
    12 }

     

  9. 源码:
      1 // MFCApplicationThresdDlg.cpp : implementation file
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "MFCApplicationThresd.h"
      6 #include "MFCApplicationThresdDlg.h"
      7 #include "afxdialogex.h"
      8 
      9 #ifdef _DEBUG
     10 #define new DEBUG_NEW
     11 #endif
     12 
     13 
     14 // CAboutDlg dialog used for App About
     15 
     16 class CAboutDlg : public CDialogEx
     17 {
     18 public:
     19     CAboutDlg();
     20 
     21 // Dialog Data
     22     enum { IDD = IDD_ABOUTBOX };
     23 
     24     protected:
     25     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
     26 
     27 // Implementation
     28 protected:
     29     DECLARE_MESSAGE_MAP()
     30 };
     31 
     32 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
     33 {
     34 }
     35 
     36 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
     37 {
     38     CDialogEx::DoDataExchange(pDX);
     39 }
     40 
     41 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
     42 END_MESSAGE_MAP()
     43 
     44 
     45 // CMFCApplicationThresdDlg dialog
     46 
     47 
     48 
     49 CMFCApplicationThresdDlg::CMFCApplicationThresdDlg(CWnd* pParent /*=NULL*/)
     50     : CDialogEx(CMFCApplicationThresdDlg::IDD, pParent)
     51     , m_edit1(_T(""))
     52 {
     53     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
     54 }
     55 
     56 void CMFCApplicationThresdDlg::DoDataExchange(CDataExchange* pDX)
     57 {
     58     CDialogEx::DoDataExchange(pDX);
     59     DDX_Text(pDX, IDC_EDIT1, m_edit1);
     60 }
     61 
     62 BEGIN_MESSAGE_MAP(CMFCApplicationThresdDlg, CDialogEx)
     63     ON_WM_SYSCOMMAND()
     64     ON_WM_PAINT()
     65     ON_WM_QUERYDRAGICON()
     66     ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplicationThresdDlg::Btn_Clicked_Start)
     67     ON_MESSAGE(WM_RESPONSE,winMessageFun)
     68 END_MESSAGE_MAP()
     69 
     70 
     71 // CMFCApplicationThresdDlg message handlers
     72 
     73 BOOL CMFCApplicationThresdDlg::OnInitDialog()
     74 {
     75     CDialogEx::OnInitDialog();
     76 
     77     // Add "About..." menu item to system menu.
     78 
     79     // IDM_ABOUTBOX must be in the system command range.
     80     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     81     ASSERT(IDM_ABOUTBOX < 0xF000);
     82 
     83     CMenu* pSysMenu = GetSystemMenu(FALSE);
     84     if (pSysMenu != NULL)
     85     {
     86         BOOL bNameValid;
     87         CString strAboutMenu;
     88         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
     89         ASSERT(bNameValid);
     90         if (!strAboutMenu.IsEmpty())
     91         {
     92             pSysMenu->AppendMenu(MF_SEPARATOR);
     93             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
     94         }
     95     }
     96 
     97     // Set the icon for this dialog.  The framework does this automatically
     98     //  when the application's main window is not a dialog
     99     SetIcon(m_hIcon, TRUE);            // Set big icon
    100     SetIcon(m_hIcon, FALSE);        // Set small icon
    101 
    102     // TODO: Add extra initialization here
    103 
    104     return TRUE;  // return TRUE  unless you set the focus to a control
    105 }
    106 
    107 void CMFCApplicationThresdDlg::OnSysCommand(UINT nID, LPARAM lParam)
    108 {
    109     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    110     {
    111         CAboutDlg dlgAbout;
    112         dlgAbout.DoModal();
    113     }
    114     else
    115     {
    116         CDialogEx::OnSysCommand(nID, lParam);
    117     }
    118 }
    119 
    120 // If you add a minimize button to your dialog, you will need the code below
    121 //  to draw the icon.  For MFC applications using the document/view model,
    122 //  this is automatically done for you by the framework.
    123 
    124 void CMFCApplicationThresdDlg::OnPaint()
    125 {
    126     if (IsIconic())
    127     {
    128         CPaintDC dc(this); // device context for painting
    129 
    130         SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
    131 
    132         // Center icon in client rectangle
    133         int cxIcon = GetSystemMetrics(SM_CXICON);
    134         int cyIcon = GetSystemMetrics(SM_CYICON);
    135         CRect rect;
    136         GetClientRect(&rect);
    137         int x = (rect.Width() - cxIcon + 1) / 2;
    138         int y = (rect.Height() - cyIcon + 1) / 2;
    139 
    140         // Draw the icon
    141         dc.DrawIcon(x, y, m_hIcon);
    142     }
    143     else
    144     {
    145         CDialogEx::OnPaint();
    146     }
    147 }
    148 
    149 // The system calls this function to obtain the cursor to display while the user drags
    150 //  the minimized window.
    151 HCURSOR CMFCApplicationThresdDlg::OnQueryDragIcon()
    152 {
    153     return static_cast(m_hIcon);
    154 }
    155 
    156 
    157 
    158 void CMFCApplicationThresdDlg::Btn_Clicked_Start()
    159 {
    160     // TODO: Add your control notification handler code here
    161     ThreadParam *pRecvParam = new ThreadParam;
    162     pRecvParam->ThreadVal = 0;
    163     pRecvParam->ThreadID = m_hWnd;
    164     //create thread
    165     HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)pRecvParam, 0, NULL);
    166 }
    167 DWORD CMFCApplicationThresdDlg::ThreadProc(LPVOID lpParameter)
    168 {
    169     WORD value = ((ThreadParam*)lpParameter)->ThreadVal;
    170     HWND hwnd = ((ThreadParam*)lpParameter)->ThreadID;
    171     while (1)
    172     {
    173         value++;
    174         ::PostMessage(hwnd, WM_RESPONSE, 0, (LPARAM)value);
    175         Sleep(1000);
    176     }
    177     return 0;
    178 }
    179 LRESULT CMFCApplicationThresdDlg::winMessageFun(WPARAM wParam, LPARAM lParam)
    180 {
    181     UNREFERENCED_PARAMETER(wParam);
    182     UNREFERENCED_PARAMETER(lParam);
    183     WORD value = lParam;
    184     CString str;
    185     str.Format(_T("%d\r\n"), value);
    186     m_edit1 += str;
    187     UpdateData(FALSE);
    188     return 0;
    189 }
    CMFCApplicationThresdDlg.cpp
     1 // MFCApplicationThresdDlg.h : header file
     2 //
     3 
     4 #pragma once
     5 
     6 
     7 // CMFCApplicationThresdDlg dialog
     8 #define WM_RESPONSE    WM_USER+1
     9 struct ThreadParam
    10 {
    11     HWND ThreadID;
    12     WORD ThreadVal;
    13 };
    14 class CMFCApplicationThresdDlg : public CDialogEx
    15 {
    16 // Construction
    17 public:
    18     CMFCApplicationThresdDlg(CWnd* pParent = NULL);    // standard constructor
    19 
    20 // Dialog Data
    21     enum { IDD = IDD_MFCAPPLICATIONTHRESD_DIALOG };
    22 private:
    23     static DWORD WINAPI ThreadProc(LPVOID lpParameter);
    24 
    25     protected:
    26     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    27 
    28 
    29 // Implementation
    30 protected:
    31     HICON m_hIcon;
    32 
    33     // Generated message map functions
    34     virtual BOOL OnInitDialog();
    35     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    36     afx_msg void OnPaint();
    37     afx_msg HCURSOR OnQueryDragIcon();
    38     afx_msg LRESULT winMessageFun(WPARAM wParam, LPARAM lParam);
    39     DECLARE_MESSAGE_MAP()
    40 public:
    41     CString m_edit1;
    42     afx_msg void Btn_Clicked_Start();
    43 };
    CMFCApplicationThresdDlg.h

     

谢谢!

End.

 

你可能感兴趣的:(通过线程传递消息)