AfxGetApp->GetMainWnd()与AfxGetMainWnd

转自:http://hi.baidu.com/magic_james/item/1298e9c486a7f26bf7c95d89

前台线程与后台线程,AfxGetApp->GetMainWnd()与AfxGetMainWnd的不同  

  顾名思义,前台指看得见,既然看得见自然要有窗口,而后台是看不见,看不见可以理解为没有窗口,既然没有窗口,那么用AfxGetMainWnd()取得其窗口句柄,未免有些搞笑,为什么呢?聪明的你想必早已明白,如果你曾经跟踪过AfxGetMainWnd()的调用,会发现它取得的是AFX_MODULE_THREAD_STATE线程模块中保存的活动线程的窗口句柄,而后台线程既然没有窗口,那你又从何而言取得窗口句柄呢,(也许有人对后台的理解是不显示窗口,就算有窗口,只要不显示就是后台线程,严格的说不是这样,窗口主要用来与用户交互,有窗口就难免阻塞,而后台线程往往用来进行一些后面的运算或处理,是通过前台传递的信息或数据进行相应运做的,如果窗口隐藏谈何信息传递呢?况又不能像其它线程那样进行后台运做.不过你如此理解也无防 ,关键是明白有什么区别,及怎么用.)
AfxGetApp()->GetMainWnd()取得的是主窗口句柄,无论在那个线程里调用都是没有问题的,因为它先取得主线程句柄,再取得主线程的活动窗口(如视图切换可能导致的替代,这种情况我也不大清楚),如果没有活动窗口则取主窗口,任何程序总要有一个主窗口,所以它的调用不会出现问题,如果想取得程序的主窗口建议用AfxGetApp()->GetMainWnd().

  要注意的是控制台程序没有窗口,其窗口句柄始终为0.其次后台线程其实就是一个控制台式的程序,只不过不是主线程罢了.还有就是用API Createthread之类的函数创建的线程无法生成CWinThread对象.所以如果想使用CWinThread对象里的函数,以及一些全局函数进行操作,如上面的AfxGetMainWnd(),就必须用CWinThread对象的CreateThread函数,或用AfxBeginThread()函数创建线程,否则很可能出现错误,因为MFC对线程的管理是通过CWinThread对象来完成的,通过下面的跟踪代码你不难看出.  记得当初有一位前辈曾提到过这个问题,只是不知它是否理解这其中的原因

以下是跟踪代码:

_AFXWIN_INLINE CWnd* AFXAPI AfxGetMainWnd()
{ CWinThread* pThread = AfxGetThread();
        return pThread != NULL ? pThread->GetMainWnd() : NULL; }


CWinThread* AFXAPI AfxGetThread()
{
// check for current thread in module thread state
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
CWinThread* pThread = pState->m_pCurrentWinThread;

// if no CWinThread for the module, then use the global app
if (pThread == NULL)
        pThread = AfxGetApp();

return pThread;
}

可以看出当取得的线程句柄为空时,则返回主线程句柄,所以在主线程里调用AfxGetMainWnd()是一定没问题的,(控制台程序除外)

_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
{ return afxCurrentWinApp; }


CWnd* CWinThread::GetMainWnd()
{
if (m_pActiveWnd != NULL)
        return m_pActiveWnd;          // probably in-place active

// when not inplace active, just return main window
if (m_pMainWnd != NULL)
        return m_pMainWnd;

return CWnd::GetActiveWindow();
}

那个afxCurrentWinApp就不用说了吧.

嘿嘿,一切完毕,如果你的程序存在类似上面的问题可一定要改回来噢.

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VC 6.0 定时执行任务编写实例,程序运行时显示托盘图标和右键菜单,请设置好时间和需要执行的外部文件路径及文件名,默认情况下是执行外部任务,可选择执行关机、重启、注销等任务,然后启动定时程序,在仅剩1分钟时,程序会显示自动重启警告:计算机将于1分钟内重启,是否取消重启?按"是"则取消自动重启.若允许自动关闭,请保存尚未关闭的程序!"。   本定时程序时间的设置可精确到日期、时间、秒,编写步骤:   ①设置任务执行的日期时间.   ②选择关机,注销,重启,任务模式.   ③选择了任务模式,需要设置任务路径.   ④按下"启动定时"按钮.   ⑤关机前1分钟不段提示是否关机或重启,如果用户一直未取消,电脑将于1分钟内关机或重启.有如下代码可参考:   if(shutTime < CTime::GetCurrentTime())   {    MessageBox("设置的时间不能早于当前系统时间!");   }   else   {    CString bb;    cButton->GetWindowText(bb);    if(bb == "启动定时")    {    if(radio == 1)    {    MessageBox("定时关机已启动!","定时关机已启动");    }    else if(radio == 2)    {    MessageBox("定时注销已启动!","定时注销已启动");    }    else if(radio == 3)    {    MessageBox("定时重启已启动!","定时重启已启动");    }else if(radio == 4)    {    CString command = "";    GetDlgItemText(IDC_EDIT2,command);    if(command == "")    {    MessageBox("请选择要执行的文件!");    return ;    }else    {    MessageBox("定时任务已启动!","定时任务已启动");    }    }    SetTimer(1,1000,0);    AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE);       //cButton->SetButtonStyle(WS_DISABLED);    cButton->SetWindowText("停止定时");    }else    {    KillTimer(1);    cButton->SetWindowText("启动定时");    }   }
这段代码是一个命令处理程序,主要作用是对图像进行增强处理,并在新窗口中显示处理后的图像。下面是对代码的解释: ```c++ CDIPFrameworkDoc* pDoc = GetDocument(); ImgCenterDib* pDib = pDoc->GetPDib(); ``` 首先获取当前文档的指针和图像数据块的指针。 ```c++ Histogram hist(pDib->GetDimensions(), pDib->m_nBitCount, pDib->m_lpColorTable, pDib->m_pImgData); ``` 创建一个直方图对象,用于计算图像的直方图。传入图像的尺寸、位深、颜色表和像素数据。 ```c++ if (pDib->m_nBitCount == 8) { hist.computeHistGray(); } else hist.computeHistBrightness(); ``` 如果图像是灰度图像,就计算灰度直方图;否则计算亮度直方图。 ```c++ CImgEnhance imgenhance(pDib->GetDimensions(), pDib->m_nBitCount, pDib->m_lpColorTable, pDib->m_pImgData); ``` 创建一个图像增强对象,传入图像的尺寸、位深、颜色表和像素数据。 ```c++ //添加噪声 imgenhance.AddPepperSaltNoise(); ``` 对图像添加椒盐噪声,增加图像的噪声。 ```c++ //梯度锐化 imgenhance.GradSharp(30); ``` 对图像进行梯度锐化,增强图像的边缘信息。 ```c++ //创建新窗口,打印图像 CMainFrame* pFrame = (CMainFrame*)(AfxGetApp()->m_pMainWnd); pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW); CDIPFrameworkView* pView = (CDIPFrameworkView*)pFrame->MDIGetActive()->GetActiveView(); CDIPFrameworkDoc* pDocNew = pView->GetDocument(); ImgCenterDib* dibNew = pDocNew->GetPDib(); dibNew->ReplaceDib(imgenhance.GetDimensions(), imgenhance.m_nBitCountOut, imgenhance.m_lpColorTableOut, imgenhance.m_pImgDataOut); pView->OnInitialUpdate(); pDocNew->SetModifiedFlag(TRUE); pDocNew->UpdateAllViews(pView); ``` 创建一个新窗口,将处理后的图像显示在新窗口中。具体操作为:发送新建文件命令,获取新窗口视图和文档的指针,将处理后的图像数据替换原有的图像数据,更新视图和文档状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值