Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

win32 (fullscreen) borderless window overlapping taskbar

I'm trying to create a borderless window that overlaps the taskbar potentially in fullscreen (without using ChangeDisplaySettings(&settings, CDS_FULLSCREEN);) and I can't quite figure out how to do it. I have tried pretty much every possible CreateWindowEx style combination with no success.

The purpose of it is to be rendered on in a windowed borderless application using opengl/directx while allowing alt-tabbing out while continuing rendering in the background. This is done by many games such as wow and dota2 (windowed fullscreen option) as well as applications such as windows7 task manager (took two screenshots of this in a vm to prove the idea) (windows8 doesn't have this behaviour).

Task manager not focused:

Task manager focused:

This is some minimal code I'm using for easily testing some ideas I had, but none really quite did it. It only creates a borderless window with sizes of screenwidth-20 and screenheight-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;
}

Using

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

does overlap the taskbar but it has some weird behaviour when opengl renders on it (flashes/flickers the screen such as when the video mode changes. Same effects were encountered by someone on this forum of some sort of a library that makes cross platform windows for rendering and other stuff. Someone also posted in that thread a video (careful, loud music) which shows exactly what I'm trying to achieve).

I have downloaded that opensource library and tried to figure out what is doing but I couldn't find anything special about the way it creates the window.

Using g++ (Built by MinGW-builds project) 4.8.0 20121225 (experimental) on Windows8.

like image 552
Edward A Avatar asked Mar 06 '13 17:03

Edward A


2 Answers

Raymond Chen explained how to switch in and out of full screen mode rather simply by changing the window style with SetWindowLong(Ptr), using SetWindowPlacement to resize the window, and SetWindowPos to make sure the frame redraws.

The Task Bar detects when a window is trying to be full screen and automatically gets out of the way.

like image 133
Adrian McCarthy Avatar answered Nov 10 '22 01:11

Adrian McCarthy


Use the SetWindowPos function to set your window TOPMOST. When you get a message saying you lost the focus, make it non-topmost again so the other window you switched to can appear.

like image 33
Mark Ransom Avatar answered Nov 09 '22 23:11

Mark Ransom