2013-04-25 45 views
1

WM_GETMINMAXINFO在最大化操作即將開始時生成,當最大化操作完成時生成WM_SIZE檢測窗口恢復操作即將開始

WM_SIZE也會在還原操作完成時生成。

但是如何檢測窗口恢復操作即將開始?


我需要檢測確切時刻,當窗口即將恢復,但不是此刻已經恢復時。我正在開發多線程DirectX應用程序。我在專用的輔助線程中渲染。當窗口即將開始最大化或恢復時,我需要更改回顯緩衝區大小(DirectX DeviceReset)。我只能從主線程調整緩衝區大小,所以我使用Critical Sections與渲染線程同步。問題是我無法在渲染線程中中斷Present操作,並且當最大化或恢復操作即將開始時,我等待直到當前Present操作完成,然後纔開始調整大小(最大化/恢復)。如果您改變後臺緩衝區大小太晚(當最大化/恢復操作完成時(WM_SIZE消息),您可以注意到舊框架繪製的大小錯誤(圖像被拉伸)

回答

2

嗯,很高興看到有人這些小東西,如調整大小時的一秒圖像拉伸,區分專業外觀的應用程序和臥室編碼的應用程序第一件事是你可以檢查WM_SYSCOMMAND

 case WM_SYSCOMMAND: 
      { 
       switch (wParam) 
       { 
       case SC_MAXIMIZE: 
        std::cout << "Going to MAXIMIZE: " << std::endl; 
        break; 

       case SC_MINIMIZE: 
        std::cout << "Going to MINIMIZE: " << std::endl; 

        break; 

       case SC_RESTORE: 
        std::cout << "Going to RESTORE: " << std::endl; 
        break; 


       default: 
        break; 
       } 
       return DefWindowProc(m_hWnd, msg, wParam, lParam); 
      } 

但問題是,當用戶雙擊標題欄時,它不捕獲最大化/恢復事件。

所以我發現了一個小竅門,當解析WM_WINDOWPOSCHANGING

首先我們來做一個有趣的研究。我們閱讀文檔herehere,我們發現:

WM_WINDOWPOSCHANGING消息發送到一個窗口的大小,位置,或發生在Z順序是即將改變

因爲它幾乎是無法在通用調試器中調試事件(如何測試調試器是否經常更改窗口的z順序?),所以出於測試目的,我們將製作一個小型控制檯應用程序int main(),其中我們像往常一樣初始化窗口(我們可以獲得HINSTANCE從GetModuleHandle(0);)。所以我們同時有一個控制檯和一個窗口。在窗口過程中,我們趕上WM_WINDOWPOSCHANGING和打印信息,它會告訴我們,安慰:

 case WM_WINDOWPOSCHANGING: 
     { 
      WINDOWPOS* wp = ((WINDOWPOS*)lParam); 

      // We checking current state which is saved in member (or global) bools 
      // Set them checking WM_SIZE before 
      if (m_bMaximized) 
      { 
       std::cout << "Currently MAXIMIZED: "; 
      } 
      else if (m_bMinimized) 
      { 
       std::cout << "Currently MINIMIZED: "; 
      } 
      else 
      { 
       std::cout << "Currently NORMAL: "; 
      } 

      dbgPrintPositionCurrent(); 

      std::cout << "Going to change to: "; 
      dbgPrintPosition(wp->x, wp->y, wp->cx, wp->cy, wp->flags); 
      std::cout << std::endl << std::endl; 

      return DefWindowProc(m_hWnd, msg, wParam, lParam); 
     } 

見效用函數here

當我們發揮不夠,我們現在可以把它有用:

   bool bFrameChanged = ((wp->flags) & SWP_FRAMECHANGED) > 0; 
      bool bNoCopyBits = ((wp->flags) & SWP_NOCOPYBITS) > 0; 
      bool bNormal = (!m_bMaximized) && (!m_bMinimized); 

      // from maximized 
      if(m_bMaximized && bFrameChanged && !bNoCopyBits) 
      { 
       std::cout << " MAXIMIZED -> NORMAL " << std::endl; 
      } 
      if (m_bMaximized && bFrameChanged && bNoCopyBits) 
      { 
       std::cout << " MAXIMIZED -> MINIMIZED " << std::endl; 
      } 

      // from normal states 
      if (bNormal && bFrameChanged && !bNoCopyBits) 
      { 
       std::cout << " NORMAL -> MAXIMIZED " << std::endl; 
      } 
      if (bNormal && bFrameChanged && bNoCopyBits) 
      { 
       std::cout << " NORMAL -> MINIMIZED" << std::endl; 
      } 

      // from minimized 
      if(m_bMinimized && bFrameChanged) 
      { 
       std::cout << " MINIMIZED -> MAXIMIZED " << std::endl; 
      } 
      if(m_bMinimized && m_bMaximized && bFrameChanged) 
      { 
       std::cout << " MINIMIZED -> MAXIMIZED " << std::endl; 
      } 


      return DefWindowProc(m_hWnd, msg, wParam, lParam); 

我真的不知道這是不是一個簡單的,甚至是它這樣做正確的方式。但它現在=) 此外,我認爲你的應用程序不關心什麼恰好發生:最大化,恢復或調整大小。它只是在乎,如果大小已更改,所以你需要調整您的緩衝區/重新創建交換鏈等...

希望它有幫助!快樂的編碼!