7 votes

win32 (fullscreen) fenêtre sans bordures chevauchant la barre des tâches

J'essaie de créer une fenêtre sans bordure qui chevauche potentiellement la barre des tâches en plein écran (sans utiliser la fonction ChangeDisplaySettings(&settings, CDS_FULLSCREEN); ) et je n'arrive pas à comprendre comment faire. J'ai essayé à peu près tous les CreateWindowEx sans succès.

L'objectif est d'obtenir un rendu dans une application fenêtrée sans bordure utilisant opengl/directx, tout en permettant de quitter l'application par la touche alt-tabbing tout en continuant le rendu en arrière-plan. C'est ce que font de nombreux jeux tels que wow et dota2 ( windowed fullscreen ) ainsi que des applications telles que le gestionnaire de tâches de windows7 (j'ai fait deux captures d'écran dans une vm pour prouver l'idée) (windows8 n'a pas ce comportement).

Le gestionnaire de tâches n'est pas focalisé :

Gestionnaire de tâches axé sur les tâches :

Il s'agit d'un code minimal que j'utilise pour tester facilement certaines idées que j'ai eues, mais aucune n'a vraiment abouti. Il ne crée qu'une fenêtre sans bordure avec des tailles de largeur d'écran 20 et de hauteur d'écran 20.

#include <windows.h>

static bool quit = false;

static LRESULT CALLBACK message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
    switch(umsg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        case WM_CLOSE:
            quit = true;
        break;
    }

    return DefWindowProc(hwnd, umsg, wparam, lparam);
}

int main()
{
    WNDCLASSEX wc;
    HMODULE hInstance;
    HWND hwnd;
    MSG msg;

    ZeroMemory(&msg, sizeof(MSG));
    hInstance = GetModuleHandle(NULL);

    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc      = message_handler;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra       = 0;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);
    wc.hIconSm          = wc.hIcon;
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground    = (HBRUSH)COLOR_WINDOWFRAME;
    wc.lpszMenuName     = NULL;
    wc.lpszClassName    = "test";
    wc.cbSize           = (unsigned int)sizeof(WNDCLASSEX);

    RegisterClassEx(&wc);

    hwnd = CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 10, 10, (int)GetSystemMetrics(SM_CXSCREEN)-20, (int)GetSystemMetrics(SM_CYSCREEN)-20, NULL, NULL, hInstance, NULL);
    //hwnd = CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 0, 0, (int)GetSystemMetrics(SM_CXSCREEN), (int)GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, SW_SHOW);
    SetForegroundWindow(hwnd);
    SetFocus(hwnd);

    while (!quit)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 0;
}

Utilisation

CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 0, 0, (int)GetSystemMetrics(SM_CXSCREEN), (int)GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

chevauche la barre des tâches mais a un comportement bizarre lorsque opengl rend sur elle (clignotement de l'écran, par exemple lorsque le mode vidéo change). Les mêmes effets ont été rencontrés par quelqu'un sur ce forum d'une sorte de bibliothèque qui permet de créer des Windows multiplateformes pour le rendu et d'autres choses. Quelqu'un a également posté dans ce fil de discussion une vidéo (attention, musique forte) qui montre exactement ce que j'essaie de faire).

J'ai téléchargé cette bibliothèque opensource et j'ai essayé de comprendre ce qui se passe, mais je n'ai rien trouvé de spécial dans la façon dont elle crée la fenêtre.

Utilisation g++ (Built by MinGW-builds project) 4.8.0 20121225 (experimental) sur Windows8.

9voto

Adrian McCarthy Points 17018

Raymond Chen a expliqué comment passer en mode plein écran et en sortir plutôt qu'en changeant le style de la fenêtre avec SetWindowLong(Ptr) , en utilisant Placement des fenêtres pour redimensionner la fenêtre, et SetWindowPos pour s'assurer que le cadre se redessine.

La barre des tâches détecte lorsqu'une fenêtre tente de s'afficher en plein écran et se retire automatiquement.

4voto

Mark Ransom Points 132545

Utiliser le SetWindowPos fonction pour régler votre fenêtre sur TOPMOST. Lorsque vous recevez un message indiquant que vous avez perdu le focus, redonnez-lui la priorité afin que l'autre fenêtre vers laquelle vous avez basculé puisse apparaître.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X