AfxGetApp()->GetMainWnd()和AfxGetMainWnd()的区别

本文探讨了AfxGetMainWnd()函数在不同线程中的应用,并通过实例对比了其与AfxGetApp()->GetMainWnd()->GetSafeHwnd()的区别。详细解释了为何在一个未创建窗口的线程中直接调用AfxGetMainWnd()会导致错误。

1. 获取的是主线程的窗口句柄。

2. AfxGetMainWnd()获取的是所在线程的窗口句柄。

在单线程下他们获得是同一个窗口,多线程下则不是。

 

下面是一个线程函数:

void /*Cthread1Dlg::*/threadFunc()
{
 CTime time;
 CString strTime;
 g_bRun = true;

 while(g_bRun)
 {
  time = CTime::GetCurrentTime();
  strTime = time.Format("%H:%M:%S");

   //HWND hw = AfxGetMainWnd()->m_hWnd;      //(1)
   //HWND hw =AfxGetApp()->GetMainWnd()->GetSafeHwnd(); //(2)


   ::SetDlgItemText(hw, IDC_TIME, strTime);

  Sleep(1000);
 }
}

上面注掉的代码中,有一个是错的,到底是哪一个?为什么?

答案是(1),因为该线程并没有创建窗口,而试图访问为赋值的变量。

而(2)是没问题的,访问的主窗口的穿够句柄!

在 MFC 应用程序中,获取特定 Windows 应用程序主窗口指针并进行类型转换时,必须注意类型匹配对象继承结构。`AfxGetApp()->GetMainWnd()` 返回的是主窗口的指针,其类型为 `CWnd*`,而非应用程序对象指针 `CWinApp*`。将 `CWnd*` 强制转换为 `CYSXF_ComportApp*` 类型是不正确的,因为 `CYSXF_ComportApp` 是从 `CWinApp` 派生的类,与 `CWnd` 是不同的类层次结构,直接转换会导致未定义行为 [^1]。 ### 获取主窗口指针并进行类型转换的正确方法 若需访问主窗口并将其转换为特定派生类(如 `CYSXF_ComportApp` 的主窗口类),应使用 `AfxGetApp()->GetMainWnd()` 获取 `CWnd*` 指针,并将其动态转换为实际主窗口类(如 `CMainFrame*` 或自定义的主窗口类)[^1]。例如: ```cpp CWnd* pMainWnd = AfxGetApp()->GetMainWnd(); if (pMainWnd != nullptr) { CMainFrame* pFrame = dynamic_cast<CMainFrame*>(pMainWnd); if (pFrame != nullptr) { // 成功获取主框架窗口指针 } } ``` 若 `CYSXF_ComportApp` 是应用程序类,而不是窗口类,则不能通过 `GetMainWnd()` 转换为 `CYSXF_ComportApp*`,因为 `GetMainWnd()` 返回的是窗口对象指针,而非应用程序对象指针 [^1]。正确的获取应用程序对象的方式如下: ```cpp CYSXF_ComportApp* pApp = dynamic_cast<CYSXF_ComportApp*>(AfxGetApp()); if (pApp != nullptr) { // 成功获取应用程序对象 } ``` ### 注意事项与调试建议 - 确保 `CYSXF_ComportApp` 类继承自 `CWinApp`,并在全局作用域中定义了该类的唯一实例。 - 启用运行时类型信息(RTTI),即编译器选项 `/GR` 必须启用,以支持 `dynamic_cast`。 - 避免在 `InitInstance` 方法执行前调用 `AfxGetApp()`,否则可能导致指针尚未初始化。 - 若应用程序为 DLL 项目,确保 MFC 被设置为“在共享 DLL 中使用”,以避免 EXE DLL 使用不同的 MFC 实例。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值