2010-03-04 22 views
22

I tiene una ventana, que I SetWindowPos(window, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);Win32: de pantalla completa y ocultar barra de tareas

cubre toda la pantalla, bien, pero se necesita un tiempo (0,5 sec) para cubrir la barra de tareas también.

¿Hay alguna manera de acceder a la barra de tareas inmediatamente? Descubrí que la configuración HWND_TOPMOST lo hace de inmediato, pero se mantiene por encima de todas las otras ventanas, incluso si cambio la aplicación; esto es algo que no quiero. Además, si primero oculto la ventana y luego la muestro, de alguna manera fuerza a la ventana a volver a dibujar y cubre la barra de tareas inmediatamente, pero parpadea (debido a la ocultación). ¿Hay otra manera?

Respuesta

34

Editar 2.Incluso hay una mejor manera para hacer de pantalla completa, la forma de cromo, fuente tomada de aquí:

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

Editar. Probablemente es mejor para crear una ventana de pantalla completa como BrendanMcK lo señaló en un comentario a esta respuesta, consulte este enlace: http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx ("¿Cómo cubrir la barra de tareas con una ventana de pantalla completa?")

El nuevo código usando el enlace anterior sería:

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); 
} 

respuesta Antiguo abajo - no lo utilice, se queda solamente para el registro de cómo nO hacer esto.

Tienes que ocultar la barra de tareas y la barra de menú para ver la pantalla completa inmediatamente.

Aquí está el código (utiliza WTL), llame SetFullScreen (verdadero) para entrar en modo de pantalla completa:

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); 
     }  
    } 
}; 

También hay que añadir algo de código para WM_CLOSE mensaje:

case WM_CLOSE: 
    ShowTaskBar(true); 

Hay una advertencia con esta solución: si su aplicación falla o se destruye a través del administrador de tareas, ¡el usuario pierde la barra de tareas en su sistema de forma permanente! (a menos que ejecute su aplicación nuevamente, entre en pantalla completa y salga, entonces verá la barra de tareas nuevamente).

Al principio de mi respuesta Señalé "atlwince.h", pero que la función trabajaban sólo en Windows CE, el Pegué anterior funciona bien con XP, Vista y 7.

+2

-1 porque no debería estar jugando con la barra de tareas; no es necesario en primer lugar; vea el blog de Raymond Chen sobre esto aquí: [¿Cómo cubro la barra de tareas con una ventana de pantalla completa?] (http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/4/4999.aspx) – BrendanMcK

+0

@ BrendanMcK: he editado mi respuesta. Tenga un buen día. –

+0

Increíble, -1 convertido a +1. (En realidad, era un poco demasiado rápido con ese -1 en primer lugar, debería haber dejado el comentario primero. Creo que me volví demasiado sensible a los ataques de Windows a lo largo de los años:!) – BrendanMcK

-3
  1. Haga clic derecho sobre la barra de tareas
  2. elegir Propiedades
  3. desmarque la casilla de verificación que dice "Mantener la barra de tareas en la parte superior de otras ventanas".

La barra de tareas pertenece al usuario , Depende de ellos que se preocupan por tener que tomar 1/2 segundo para ocultar automáticamente cuando se va aplicación de pantalla completa. Si quieren cambiar ese comportamiento, entonces pueden cambiarlo.

Si está trabajando en un sistema integrado, es posible que tenga un motivo legítimo para ocultar la barra de tareas. Pero en ese caso, no hay razón para no configurar simplemente la barra de tareas para que no siempre esté en la parte superior. También puede echarle un vistazo al SystemParametersInfo si desea cambiar algunas de estas configuraciones en su código.

+0

OK, y cada vez que inicias un juego, ¿quieres hacer estos tres pasos antes, y luego restaurar el estado anterior? De Verdad? – user2328447

+0

user2328447, ¿estás haciendo trolling? El estado de la barra de tareas se ignora cuando un juego va a pantalla completa, por lo que sería estúpido y roto para que los juegos entren en la barra de tareas, pero seguramente ya lo has notado ... –

+0

En la pantalla completa con ventana, la barra de tareas es NO ignorado Que es exactamente lo que pidió el cartel original. Varios juegos usan esto. – user2328447

1

Creo que la barra de tareas se saldrá del camino cuando su gancho de shell le dice acerca de una "aplicación grosera", esto podría tomar un poco de tiempo.

¿Qué sucede si comienzas con la ventana HWND_TOPMOST y la haces no más alta después de 1 segundo?

13

Sí, HWND_TOPMOST lo hace por mí. Aquí es una sección de código que hace bien el trabajo de pantalla completa (y rápido) para mí:


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; 
} 

Tenga en cuenta que esto va a cambiar la resolución si le dice que la configuración incorrecta. Esto es lo que yo quiero por lo general, pero si no te gusta eso, se puede averiguar su resolución mediante el uso de (donde mainWindow se devuelve desde algo así como CreateWindow() o CreateWindowEx()):


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

cuando se quiere salir de pantalla completa haces algo como esto:


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; 
} 

puse mi código para cambiar entre pantalla completa y modo de ventana usando una tecla de acceso directo, y guardo las variables de modo de ventana como global, de manera que cuando se cambia a de ventana modo, se mantiene.

Este código también tiene la ventaja de funcionar en el equivalente de "modo exclusivo" (estoy usando XP, y no lo he probado en las versiones más nuevas de Windows), lo que significa que será mucho, mucho Más rápido. Avíseme si cometí algún error al condensar el código (de mi código mucho más grande).

+0

Gracias por la respuesta. Creo que la razón por la que funciona es que cambia el tamaño de la ventana al menos dos veces "SetWindowPos() y ShowWindow()" (no sé que "ChangeDisplaySettings()"). El problema es, ¿qué sucede si ya estoy en "SW_MAXIMIZE" y qué debo hacer a pantalla completa? –

+0

Leí en alguna parte que hay una especie de "caché" del administrador de ventanas. Así que esperaba que haya una forma de forzarlo a actualizar o de otra manera decirle que debería volver a pintar la barra de tareas debajo. –

+0

En otras palabras, me parece que "SW_MAXIMIZE" hace algo además del cambio de tamaño y me gustaría saber qué ... –

Cuestiones relacionadas