CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    MFC Thread: How to access UI elements from a thread in MFC?

    Q: How to access UI elements from a thread in MFC?

    A: Since the MFC is not thread-safe at object level (only at class level) one have to be careful when UI elements (like edit controls, listboxes etc.) should be accessed from inside the thread. The safest way is to pass a windows object handle and uses this inside the thread to post messages to the object.

    The following sample shows this technique assuming that the created dialog contains a static text control named 'IDC_THREAD_TEXT'. The object handle of the dialog will be passed to the thread. Inside the thread this handle will be used to post ten messages to the dialog causing it to update the static control.

    Code:
    // 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;
    }
    Last edited by Andreas Masur; July 25th, 2005 at 12:43 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured