2010-03-04 3 views
22

У меня есть окно, которое я SetWindowPos(window, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);Win32: полный экран и скрытие панели задач

Она охватывает весь экран, хорошо, но это занимает некоторое время (0,5 сек), чтобы покрыть панель задач, а также.

Есть ли способ сразу перейти на панель задач? Я обнаружил, что настройка HWND_TOPMOST делает это немедленно, но она остается выше всех остальных окон, даже если я переключу приложение - этого я не хочу. Кроме того, если я сначала скрою окно, а затем покажу его, он каким-то образом заставит окно перерисовать и сразу же закрывает панель задач, но она мерцает (из-за скрытия). Есть ли другой способ?

ответ

34

Редактировать 2.Существует даже лучший способ для этого в полноэкранном режиме, то, как хром, источник взято отсюда:

http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=markup

Редактировать. Это, вероятно, лучше создать полноэкранное окно, как BrendanMcK указал на это в комментарии к этому ответу, эта ссылка: http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx («Как покрыть панель задач с полноэкранным окном?»)

Новый код с помощью выше ссылка будет:

HWND CreateFullscreenWindow(HWND hwnd) 
{ 
HMONITOR hmon = MonitorFromWindow(hwnd, 
            MONITOR_DEFAULTTONEAREST); 
MONITORINFO mi = { sizeof(mi) }; 
if (!GetMonitorInfo(hmon, &mi)) return NULL; 
return CreateWindow(TEXT("static"), 
     TEXT("something interesting might go here"), 
     WS_POPUP | WS_VISIBLE, 
     mi.rcMonitor.left, 
     mi.rcMonitor.top, 
     mi.rcMonitor.right - mi.rcMonitor.left, 
     mi.rcMonitor.bottom - mi.rcMonitor.top, 
     hwnd, NULL, g_hinst, 0); 
} 

Старый ответ ниже - не использовать его, остается только для записи о том, как не делать этого.

Вам нужно скрыть панель задач и меню, чтобы сразу увидеть полноэкранный режим.

Вот код (использует WTL), вызовите SetFullScreen (истина), чтобы перейти в полноэкранный режим:

template <class T, bool t_bHasSip = true> 
class CFullScreenFrame 
{ 
public: 
    bool m_fullscreen; 
    LONG m_windowstyles; 
    WINDOWPLACEMENT m_windowplacement; 

    CFullScreenFrame() 
     : 
     m_fullscreen(false), 
     m_windowstyles(0) 
    { } 

    void SetFullScreen(bool fullscreen) 
    { 
     ShowTaskBar(!fullscreen); 

     T* pT = static_cast<T*>(this); 

     if (fullscreen) { 
      if (!m_fullscreen) { 
       m_windowstyles = pT->GetWindowLongW(GWL_STYLE); 
       pT->GetWindowPlacement(&m_windowplacement); 
      } 

     } 

     // SM_CXSCREEN gives primary monitor, for multiple monitors use SM_CXVIRTUALSCREEN. 
     RECT fullrect = { 0 };    
     SetRect(&fullrect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); 

     WINDOWPLACEMENT newplacement = m_windowplacement; 
     newplacement.showCmd = SW_SHOWNORMAL; 
     newplacement.rcNormalPosition = fullrect; 

     if (fullscreen) { 
      pT->SetWindowPlacement(&newplacement); 
      pT->SetWindowLongW(GWL_STYLE, WS_VISIBLE); 
      pT->UpdateWindow(); 
     } else { 
      if (m_fullscreen) { 
       pT->SetWindowPlacement(&m_windowplacement); 
       pT->SetWindowLongW(GWL_STYLE, m_windowstyles); 
       pT->UpdateWindow(); 
      } 
     } 

     m_fullscreen = fullscreen; 
    } 

    void ShowTaskBar(bool show) 
    { 
     HWND taskbar = FindWindow(_T("Shell_TrayWnd"), NULL); 
     HWND start = FindWindow(_T("Button"), NULL); 

     if (taskbar != NULL) { 
      ShowWindow(taskbar, show ? SW_SHOW : SW_HIDE); 
      UpdateWindow(taskbar); 
     } 
     if (start != NULL) { 
      // Vista 
      ShowWindow(start, show ? SW_SHOW : SW_HIDE); 
      UpdateWindow(start); 
     }  
    } 
}; 

Вы также должны добавить код WM_CLOSE сообщение:

case WM_CLOSE: 
    ShowTaskBar(true); 

Существует одно предостережение с этим решением, если ваше приложение аварийно завершает работу или убивается через диспетчер задач, а затем панель задач пользователя на своей системе постоянно! (если он снова не запустит ваше приложение, не войдет в полноэкранный режим и не выйдет, то он снова увидит панель задач).

Ранее в моем ответе я указал на «atlwince.h», но эта функция работала только на Windows CE, который я вставил выше отлично работает с XP, Vista и 7.

+2

-1, потому что вы не должны возиться с панелью задач; он не нужен в первую очередь; см. блог Раймонда Чена об этом здесь: [Как покрыть панель задач полноэкранным окном?] (http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx) – BrendanMcK

+0

@ BrendanMcK: Я отредактировал свой ответ. Хорошего дня. –

+0

Awesome, -1 преобразован в +1. (На самом деле, я был слишком быстр с этим -1, в первую очередь, мне следовало только что оставить комментарий. Я думаю, что на протяжении многих лет я стал слишком чувствительным к просмотру оконных хаков!) – BrendanMcK

-3
  1. правой кнопкой мыши на панели задач
  2. выберите Свойства
  3. снимите флажок с надписью «Держите панель задач поверх остальных окон».

панель задачи принадлежит пользователю, это до них, чтобы заботиться о том, что взять 1/2 секунды до автоматического скрытия, когда вы приложение идут полный экран. Если они хотят изменить это поведение, они могут изменить его.

Если вы работаете во встроенной системе, у вас может быть законная причина скрывать панель задач. Но в этом случае нет причин не просто настраивать панель задач не всегда на вершине. Вы также можете посмотреть SystemParametersInfo, если вы хотите изменить некоторые из этих параметров в своем коде.

+0

ОК, и каждый раз, когда вы начинаете игру, вы хотите сделать эти три шага раньше, а затем восстановить старое состояние? В самом деле? – user2328447

+0

user2328447, ты троллинг? Состояние панели задач игнорируется при игре в полноэкранном режиме - так что это было бы и глупо и сломано для игр, чтобы возиться с панелью задач - но, конечно же, вы уже это заметили ... –

+0

В оконном полноэкранном режиме панель задач НЕ игнорируется. Именно это и требовал первоначальный плакат. Несколько игр используют это. – user2328447

1

Я верю, что панель задач будет сбиваться с пути, когда ее крючок оболочки сообщает об «грубом приложении», это может занять некоторое время.

Что делать, если вы начинаете с окна HWND_TOPMOST и делаете его не самым большим после 1 секунды?

13

Yup, HWND_TOPMOST делает это для меня. Вот фрагмент кода, который делает полноэкранное работу хорошо (и быстро) для меня:


bool enterFullscreen(HWND hwnd, int fullscreenWidth, int fullscreenHeight, int colourBits, int refreshRate) { 
    DEVMODE fullscreenSettings; 
    bool isChangeSuccessful; 
    RECT windowBoundary; 

    EnumDisplaySettings(NULL, 0, &fullscreenSettings); 
    fullscreenSettings.dmPelsWidth  = fullscreenWidth; 
    fullscreenSettings.dmPelsHeight  = fullscreenHeight; 
    fullscreenSettings.dmBitsPerPel  = colourBits; 
    fullscreenSettings.dmDisplayFrequency = refreshRate; 
    fullscreenSettings.dmFields   = DM_PELSWIDTH | 
              DM_PELSHEIGHT | 
              DM_BITSPERPEL | 
              DM_DISPLAYFREQUENCY; 

    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST); 
    SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); 
    SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fullscreenWidth, fullscreenHeight, SWP_SHOWWINDOW); 
    isChangeSuccessful = ChangeDisplaySettings(&fullscreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL; 
    ShowWindow(hwnd, SW_MAXIMIZE); 

    return isChangeSuccessful; 
} 

Обратите внимание, что это изменит решение, если вы скажете ему неправильные настройки. Это то, что я обычно хочу, но если вам не нравится, что вы можете найти свое разрешение, используя (где mainWindow возвращается из чего-то вроде CreateWindow() или CreateWindowEx()):


windowHDC = GetDC(mainWindow); 
fullscreenWidth = GetDeviceCaps(windowHDC, HORZRES); 
fullscreenHeight = GetDeviceCaps(windowHDC, VERTRES); 
colourBits  = GetDeviceCaps(windowHDC, BITSPIXEL); 
refreshRate  = GetDeviceCaps(windowHDC, VREFRESH); 

Если вы хотите, чтобы выйти полного экрана вы делаете что-то вроде этого:


bool exitFullscreen(HWND hwnd, int windowW, int windowY, int windowedWidth, int windowedHeight, int windowedPaddingX, int windowedPaddingY) { 
    bool isChangeSuccessful; 

    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_LEFT); 
    SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE); 
    isChangeSuccessful = ChangeDisplaySettings(NULL, CDS_RESET) == DISP_CHANGE_SUCCESSFUL; 
    SetWindowPos(hwnd, HWND_NOTOPMOST, windowX, windowY, windowedWidth + windowedPaddingX, windowedHeight + windowedPaddingY, SWP_SHOWWINDOW); 
    ShowWindow(hwnd, SW_RESTORE); 

    return isChangeSuccessful; 
} 

Я установил свой код для переключения между полноэкранным и оконным режимом с помощью горячих клавиш, и я держать оконный переменные режим, как глобальные, так что при переходе на оконном режим, он остается включенным.

Этот код имеет то преимущество, что работает в эквиваленте «эксклюзивного режима» (я использую XP и не пробовал его в новых версиях окон), что означает, что это будет много, Быстрее. Дайте мне знать, если я сделал какие-либо ошибки от сжатия кода (из моего гораздо большего кода).

+0

Спасибо за ответ. Я думаю, что причина, по которой это работает, заключается в том, что вы изменяете размер окна как минимум дважды «SetWindowPos() и ShowWindow()» (я не знаю, что «ChangeDisplaySettings()»). Проблема в том, что произойдет, если я уже в «SW_MAXIMIZE» и что делать в полноэкранном режиме? –

+0

Я где-то читал, что есть «кеш» оконного менеджера. Поэтому я надеялся, что есть способ заставить его обновиться или сказать другим, что он должен перерисовать панель задач внизу. –

+0

Другими словами, мне кажется, что «SW_MAXIMIZE» делает что-то помимо изменения размера, и я хотел бы знать, что ... –

Смежные вопросы