六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

基于 CDialog 的應(yīng)用程序一開始便被隱藏的方法

[摘要]作者: Solomon ([email protected])   要使一個基于 CDialog 的應(yīng)用程序一開始便被隱藏的方法有好多種。大多數(shù)方法在相關(guān)文章(http://www.csdn.net...
作者: Solomon ([email protected])

  要使一個基于 CDialog 的應(yīng)用程序一開始便被隱藏的方法有好多種。大多數(shù)方法在相關(guān)文章(http://www.csdn.net/develop/article/11/11634.shtm)中已經(jīng)提及。本人之所以要寫這篇文章,主要是通過分析MFC 調(diào)用模式對話框的方法向大家展示一種簡單,合理,完滿的解決方案。

  首先,用MFC 生成的一個基于對話框的應(yīng)用程序框架,然后修改對話框資源的Visible屬性使之成為不可見(在屬性頁的MoreStyle中),接著按下F5 來運(yùn)行這個程序,我們會發(fā)現(xiàn),它并不象我們期望的那樣一開始就被隱藏。而是被顯示了出來。那么為什么會這樣呢?特別是精通SDK的朋友們,會對此百思不得其解。

  其實(shí),MFC框架為了顯示對話框很多工作,它并不簡簡單單地調(diào)用 DialogBox 顯示對話框,而是使用了相對復(fù)雜的方法�,F(xiàn)在,我就來引導(dǎo)大家對此探個究竟。

  在生成的應(yīng)用程序框架中(名稱為Test),你會看到CTestApp和CTestDlg 兩個類,在 CTestApp 的 InitInstance 方法中有如下語句:

     CTestDlg dlg;
     m_pMainWnd = &dlg;
     int nResponse = dlg.DoModal();        // 此處將創(chuàng)建并顯示對話框

DoModal 是一個虛函數(shù),MFC允許用戶編寫自己的調(diào)用對話框方式來替代原來的方式。但是,MS 實(shí)在令人失望。如果,你打開 DlgCore.Cpp (MFC Source 目錄下)并復(fù)制 DoModal  的代碼到你自己的類中,你會發(fā)現(xiàn)無法編譯成功。原因在于MS在 DoModal 中使用了兩個非輸出函數(shù) AfxHookWindowCreate 和 AfxUnhookWindowCreate。(這兩個函數(shù)的作用超出了本文所討論的范圍,因此不作詳細(xì)論述。)由于無法編譯,所以 MS  要求用戶的 DoModal 必須調(diào)用 CDialog 的 DoModal 來顯示對話框。這樣,控制隱藏就無法通過重載 DoModal 實(shí)現(xiàn)了。那么 MS 在 DoModal 中干了什么呢?下面就是一部分代碼。

int CDialog::DoModal()
{
  ...... 讀入資源,并作一些設(shè)置
  if (CreateDlgIndirect(lpDialogTemplate,
            CWnd::FromHandle(hWndParent), hInst))  //創(chuàng)建無模式對話框
    {
      if (m_nFlags & WF_CONTINUEMODAL)
      {
        // enter modal loop
        DWORD dwFlags = MLF_SHOWONIDLE;  //罪魁禍?zhǔn)拙褪撬?br>        if (GetStyle() & DS_NOIDLEMSG)
          dwFlags = MLF_NOIDLEMSG;
        VERIFY(RunModalLoop(dwFlags) == m_nModalResult); //進(jìn)入消息循環(huán)
      }

  .......
    }
  }
  ...... 釋放資源等
}

原來,DoModal 并不使用 DialogBox 直接調(diào)出對話框,而是通過創(chuàng)建無模式對話框并維護(hù)消息循環(huán)的方式(RunModalLoop)來模擬模式對話框的效果。(看起來好像有點(diǎn)像DialogBox 的內(nèi)部作業(yè)方式)MLF_SHOWONIDLE 是什么?看英文的意思是在Idle 的時候ShowWindow。那么是不是這樣呢?好吧,為了探個究竟,讓我們進(jìn)入RunModalLoop。RunModalLoop在WinCore.CPP中定義。打開WinCore.CPP 并找到 RunModalLoop, 會看到以下的語句

BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);

條件 dwFlags & MLF_SHOWONIDLE 始終為TRUE。 而 !(GetStyle() & WS_VISIBLE)只有在WS_VISIBLE屬性沒有設(shè)置的時候才會為 TRUE。這樣,當(dāng)我們?nèi)サ鬡isible 屬性后 bShowIdle 就為 TRUE 了。再往下,就會看到以下的調(diào)用

  while (bIdle &&
   !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
  {
   ASSERT(ContinueModal());

   // show the dialog when the message queue goes idle
   if (bShowIdle)              // 找到了
   {
    ShowWindow(SW_SHOWNORMAL);
    UpdateWindow();
    bShowIdle = FALSE;  // 指示下一次Idle 時不用顯示對話框了
   }
While 里的條件是消息隊(duì)列里再也沒有任何消息了。此時,由于 bShowIdle 為 TRUE ,就會調(diào)用 ShowWindow 來顯示對話框。由于 ShowWindow 只執(zhí)行一次,所以如果能截獲第一次WM_SHOWWINDOW消息, 就能控制了隱藏了。

是的。在 CTestDlg 處理 WM_SHOWWINDOW 并添上以下代碼

void CTestDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{

if( GetStyle() & WS_VISIBLE ) {
  CDialog::OnShowWindow(bShow, nStatus);
} else {
  long Style = ::GetWindowLong(*this, GWL_STYLE);
  ::SetWindowLong(*this, GWL_STYLE, Style WS_VISIBLE);
  CDialog::OnShowWindow(SW_HIDE, nStatus);
}
}
再運(yùn)行一下,哈哈,對話框不見了,連閃都不閃一下。細(xì)心的讀者也許會問為什么使用SetWindowLong,而不是 ModifyStyle, 其實(shí)是為了加快速度,因?yàn)椤odifyStyle 內(nèi)部還要調(diào)用 GetWindowLong 和 SetWindowPos。到此為止,一個簡單,完滿的解決方法已經(jīng)展現(xiàn)在大家面前了。

其實(shí),本來 MS 可以做的更好,比如把 GetStyle() 聲明為虛函數(shù),使得我們能返回WS_VISIBLE 來控制 bShowIdle 成為 FALSE, 或者把

        DWORD dwFlags = MLF_SHOWONIDLE;

改成

  DWORD dwFlags =  ShowOnIdle();  // 聲明為虛函數(shù)


希望MS能在以后的版本中考慮這個問題。

這是本人在CSDN上的第一個作品,希望大家能多提寶貴意見。


主站蜘蛛池模板: 日本国产在线观看 | 日韩大片免费看 | 欧美亚洲国产成人不卡 | 天天天天做夜夜夜做 | 日本最新免费二区三区 | 亚洲日韩中文第一精品 | 野草影院手机在线观看免费6 | 中文字幕在线看视频一区二区三区 | 午夜国产精品久久久久 | 青久在线 | 青娱乐99| 欧美坐爱视频 | 亚洲第一黄色 | 亚色91| 亚州1区2区3区4区产品乱码2021 | 天天干夜啪 | 亚洲资源站| 亚色国产| 午夜影院亚洲 | 青青青免费网站在线观看 | 青青草97国产精品免费观看 | 日韩欧美一区黑人vs日本人 | 午夜不卡福利 | 热热涩热热狠狠色香蕉综合 | 最新中文字幕一区 | 青草影院在线 | 青草青青视频在线观看 | 亚洲国产最新在线一区二区 | 天天射日日干 | 欧美视频在线免费看 | 亚洲日韩中文字幕在线播放 | 亚洲一级大黄大色毛片 | 青青草国产精品 | 欧美在线日韩在线 | 日本亚欧乱色视频在线系列 | 四虎影院最新网址 | 亚洲三级在线观看 | 亚洲婷婷在线 | 在线免费观看日本 | 色聚网久久综合 | 亚洲国产精品久久久久666 |