所以我成功地将我的学习困难设法制作了一些基于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),我认为这很好。我不知道它让我头疼。任何帮助将不胜感激,一个小小的注意事项是我必须在我的小应用程序访问工作线程控件。上面的例子是唯一一个我没有理解和开始工作的人。