子线程或业务类调用主对话框的GetDlgItem(IDC_XXX)

时间:2022-08-28 05:48:30
子线程或其他类中是调用主对话框控件的 GetDlgItem( IDC_XXX)功能是非常不安全的,但是同时又想要在子线程或其他类中调用此函数来设置主对话框中某个控件的内容,该怎么处理呢?
根据MVC设计模式来看:
    ~M = Modle(模型)保存和维护数据,提供接口让外部修改数据,通知表现需要刷新
    ~V  = View (表现) 从模型获取数据,根据数据画出表现
    ~C =  Contrl(控制) 从用户得到输入,根据输入调整数据
子线程或其他类可以看做业务类或业务线程,作为Modle。主对话框界面作为View,负责展示用户交互界面。最好是View要和M分离才好。
如何实现业务数据和用户界面的分离呢?
可以利用windows的消息机制来实现这种方法。
函数原型
BOOL WINAPI PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
参数说明
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
HWND_BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、 被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口
NULL:此函数的操作和调用参数dwThread设置为当前线程的 标识符 PostThreadMessage函数一样
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
LParam:指定附加的消息特定的信息。
返回值:如果 函数调用成功,返回非零,否则函数调用返回值为零

以MFC对话框应用程序为例, 具体实现过程如下:

1、首先定义消息响应ID
# define UM_MASSAGEEDIT2 WM_USER+201

2、在主对话框类实现文件(.cpp)中的 BEGIN_MESSAGE_MAP下增加消息处理函数入口:
ON_MESSAGE( UM_MASSAGEEDIT2, & CTEST2Dlg:: OnPossMessageToEdit2)
子线程或业务类调用主对话框的GetDlgItem(IDC_XXX)
前两步要注意,后面不要习惯性的加分号“;“
3、定义消息处理函数并实现
在主对话框类头文件(.h)中声明
LRESULT OnPossMessageToEdit2( WPARAM mParam, LPARAM lParam);
在类实现文件中来实现功能
LRESULT CTEST2Dlg:: OnPossMessageToEdit2( WPARAM mParam, LPARAM lParam)
{
GetDlgItem( IDC_EDIT1)-> SetWindowText(( LPCTSTR)mParam);
return 0;
}

4、万事俱备,只欠东风,最后一步,就是在子线程或业务类中发送消息给主对话框类了
void CTestPossMessage:: ShowXXOnEdit2()
{
:: PostMessageA(m_pTestDlg->m_hWnd, UM_MASSAGEEDIT2,( WPARAM)( LPCSTR)_T( "多线程发送消息测试"),( LPARAM)( LPCSTR)_T( "消息"));
}