MFC工作线程

时间:2015-05-09 11:31:07

标签: windows multithreading visual-c++ mfc

所以我成功地将我的学习困难设法制作了一些基于MFC的小应用程序,但现在我更难以理解如何在线程内部访问编辑控件。好吧,首先让我说我发现了一个很好的例子,通过一些修补我设法让它在我的测试应用程序中正常运行。问题是,它现在不像一个线程,它就像在线程之外一样挂起。

我的测试应用程序每x秒向另一个应用程序发送一条消息,在这种情况下每20秒发送一次消息.20秒后它发送另一条消息,然后在20之后再次显示第一条消息,并且每20秒重复一次,直到应用程序关闭。

以下是我用来帮助我了解如何使用线程的示例代码,以及如何访问MFC控件。

    // StdAfx.h
#define WM_UPDATE_CONTROL    WM_APP + 0x10

// MyDialog.h
class CMyDialog : public CDialog
{
public:
  CMyDialog(CWnd* pParent = NULL);

private:
  CWinThread *m_pThread;

  LRESULT OnUpdateControl(WPARAM wParam, LPARAM lParam);            
  static UINT ThreadFunc(LPVOID pvParam);
};

// MyDialog.cpp
CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
  : CDialog(CMyDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CMyDialog)
//}}AFX_DATA_INIT

  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

  m_pThread = 0;
}

BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
  //{{AFX_MSG_MAP(CMyDialog)
  ON_WM_SYSCOMMAND()
  ON_WM_PAINT()
  ON_WM_QUERYDRAGICON()
  //}}AFX_MSG_MAP
  ON_MESSAGE(WM_UPDATE_CONTROL, OnUpdateControl)
END_MESSAGE_MAP()

BOOL CMyDialog::OnInitDialog()
{
  CDialog::OnInitDialog();
  //...

  // Set object handle for thread
  HWND *phObjectHandle = new HWND;

  *phObjectHandle = GetSafeHwnd();

  // Create thread
  m_pThread = AfxBeginThread(ThreadFunc, phObjectHandle);
  if(!m_pThread)
  {
    // Could not create thread
    EndDialog(IDCANCEL);
  }
  return TRUE;
}

LRESULT CMyDialog::OnUpdateControl(WPARAM wParam, LPARAM lParam)
{
  static int iCounter = 0;
  CString    strText;

  strText.Format("Message %d", ++iCounter);
  GetDlgItem(IDC_THREAD_TEXT)->SetWindowText(strText);

  return 0;
}

UINT CMyDialog::ThreadFunc(LPVOID pvParam)
{
  HWND *phObjectHandle = static_cast<HWND *>(pvParam);

  for(int iCnt = 0; iCnt < 10; ++iCnt)
  {
    ::PostMessage(*phObjectHandle, WM_UPDATE_CONTROL, 0, 0);
    ::Sleep(2000);
  }

  // Release memory
  delete phObjectHandle;

  return 0;
}

不包含所有其他必要的代码,即stdax.h,这里是我遇到问题的代码。我知道这很糟糕,但是我已经发现它是目前我能想到的最好的。

LRESULT MyDlg::OnUpdateControl(WPARAM wParam, LPARAM lParam)
{
        CString    sWnd1;
        CString    sWnd2;
        HWND       hWnd;

        sWnd1.Format(_T("%p"), &hWnd);
        GetDlgItemText(IDC_APPWINDOW1, sWnd1);
        GetDlgItemText(IDC_APPWINDOW2, sWnd2);
        swscanf_s(sWnd1, _T("%p"), &hWnd);
        ::SendMessage(hWnd, WM_SETTEXT,0, (LPARAM)L"hello test");
        Sleep(20000);
        ::SendMessage(hWnd, WM_SETTEXT,0, (LPARAM)L"goodbye test");
        Sleep(20000);
        return 0;
}

UINT MyDlg::ThreadFunc(LPVOID pvParam)
{
        HWND *phObjectHandle = static_cast<HWND *>(pvParam);

        for(;;)
        {
            ::PostMessage(*phObjectHandle, WM_UPDATE_CONTROL, 0, 0);
        }

        delete phObjectHandle;

        return 0;
}

APPWINDOW1和APPWINDOW2是我从其他程序0x000000等输入窗口句柄的编辑控件,我打算以某种方式自动执行此操作而不必每次都使用winspy,但是现在我唯一关心的是线程问题。一切都运行良好,除了它挂起。在未经修改的代码中,它运行得很完美,只要我尝试将命令重复发送到同一窗口或使用Sleep(x),我认为这很好。我不知道它让我头疼。任何帮助将不胜感激,一个小小的注意事项是我必须在我的小应用程序访问工作线程控件。上面的例子是唯一一个我没有理解和开始工作的人。

0 个答案:

没有答案