2017-03-05 16 views
0

所以我想爲我的遊戲寫一個切換全屏功能。禁用窗口消息(沒有WNDPROC調用)

它工作..有點問題是第一個SetWindowLongPtr()調用導致WM_SIZE消息排隊併發送到我的WNDPROC(在MSDN我讀取窗口樣式的更改只緩存,必須使用SetWindowPos ()雖然)。

SetWindowLongPtr(m_hWnd, GWL_STYLE, dwStyle); 
SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, dwExStyle); 
SetWindowPos(m_hWnd, NULL, fullscreen ? 0 : window.left, fullscreen ? 0 : window.top, window.right, window.bottom, SWP_NOZORDER | SWP_FRAMECHANGED); 
ShowWindow(m_hWnd, SW_SHOW); 

當從窗到全屏模式下的客戶區被調整到窗口矩形和更新這樣的改變(所以現在「包含」酒吧等)。 除了導致我的程序兩次銷燬Vulkan上下文之外,這使得我保存錯誤的窗口維度以便稍後恢復爲窗口模式(這是在WM_SIZE發生時以及遊戲處於全屏模式時完成的)。

之後,它通過SetWindowPos()調整到正確的尺寸。

我的意思是,我當然可以在布爾中破解WM_SIZE消息,但它應該是,但我正在尋找一個更好,也許不太順便的方式。 是否有暫時禁用窗口消息或僅用戶def WNDPROC的功能?

+1

不必禁用Windows消息,但正確處理它 – RbMm

+0

我只是做到這一點,它的工作原理: SetWindowLongPtr(m_hWnd,GWLP_WNDPROC,(LONG_PTR)DefWindowProc函數); SetWindowLongPtr(m_hWnd,GWL_STYLE,dwStyle); SetWindowLongPtr(m_hWnd,GWL_EXSTYLE,dwExStyle); SetWindowLongPtr(m_hWnd,GWLP_WNDPROC,(LONG_PTR)StdWndProc); – AxMedia

+0

這當然不應該成爲問題。水晶球說,你只是忘了*還*存儲窗口狀態。這是必需的,因爲它告訴你如何在開始備份時重新創建窗口,假設你想以全屏模式重新開始。 –

回答

0

這是我用來切換全屏開啓和關閉的功能。 我從Raymond Chen得到了這個功能。 我不知道它是否與Vulkan混淆,但它可以與OpenGL一起使用。

WINDOWPLACEMENT GlobalWindowPosition = {sizeof(GlobalWindowPosition)}; 
void ToggleFullscreen(HWND WindowHandle) 
{ 
    DWORD Style = GetWindowLong(WindowHandle, GWL_STYLE); 
    if(Style & WS_OVERLAPPEDWINDOW) 
    { 
     MONITORINFO MonitorInfo = {sizeof(MonitorInfo)}; 
     if(GetWindowPlacement(WindowHandle, &GlobalWindowPosition) && 
      GetMonitorInfo(MonitorFromWindow(WindowHandle, MONITOR_DEFAULTTOPRIMARY), 
          &MonitorInfo)) 
     { 
      SetWindowLong(WindowHandle, GWL_STYLE, 
          Style & ~WS_OVERLAPPEDWINDOW); 
      SetWindowPos(WindowHandle, HWND_TOP, 
         MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top, 
         MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left, 
         MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top, 
         SWP_NOOWNERZORDER | SWP_FRAMECHANGED); 
     } 
    } 
    else 
    { 
     SetWindowLong(WindowHandle, GWL_STYLE, Style | WS_OVERLAPPEDWINDOW); 
     SetWindowPlacement(WindowHandle, &GlobalWindowPosition); 
     SetWindowPos(WindowHandle, NULL, 0, 0, 0, 0, 
        SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | 
        SWP_NOOWNERZORDER | SWP_FRAMECHANGED); 
    } 
} 
+0

「if(Style&WS_OVERLAPPEDWINDOW)」 - 肯定是壞主意,請參閱WS_OVERLAPPEDWINDOW的定義。 – KonstantinL

+1

@KonstantinL:你用'WS_OVERLAPPED'混淆了樣式。那個被定義爲'0x0'。 'WS_OVERLAPPEDWINDOW'不是。這是一個罕見的場合,當雷蒙德錯了。 – IInspectable

+0

@Indoseable,不,我知道區別。我的意思是應該是如果((Style&WS_OVERLAPPEDWINDOW)== WS_OVERLAPPEDWINDOW)。 – KonstantinL