WinAPI + Cmake + Aero

88 Views Asked by At

I have a CMake project with an executable and a static library (linked to the exe). The library is responsible for implementing the creation of the window (using WinAPI for Windows OS), and the executable contains the main entry point (in this case a simple int main(...) function).

I've been googling for a day but cannot find a way to create a window with Aero support (can maximize by dropping to the top, the title bar is a little bit transparent, etc). I've read the Enabling Visual Styles MSDN article but I'm not sure how I should handle this with CMake. Especially that the window implementation is hidden to the client (since it's implemented in the library).

The windowing code is really basic right now for simplicity. Some of the code will be refactored, the point is not that right now. Here is the (almost) full code for creating the window.

bool WindowsWindow::create(const WindowCreateInfo& info)
{
    // register custom window class
    {
        WNDCLASSEX wnd = { 0 };
        wnd.cbSize = sizeof(wnd);
        wnd.lpszClassName = CLASS_NAME;
        wnd.hInstance = GetModuleHandle(nullptr);
        wnd.lpfnWndProc = wndProc;
        wnd.style = CS_OWNDC;
        wnd.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW);
        wnd.hCursor = LoadCursor(NULL, IDC_ARROW);

        if (RegisterClassEx(&wnd) == 0) {
            return false;
        }

        hInstance = wnd.hInstance;
    }

    HMONITOR monitor = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
    MONITORINFO monitorInfo;
    monitorInfo.cbSize = sizeof(MONITORINFO);
    GetMonitorInfo(monitor, &monitorInfo);

    LONG style = 0;
    LONG exStyle = WS_EX_APPWINDOW;
    int x = CW_USEDEFAULT;
    int y = CW_USEDEFAULT;
    int width = info.width;
    int height = info.height;

    if (info.isWindowed) {
        style = WS_OVERLAPPED | WS_BORDER | WS_CAPTION;

        if (info.hasSysMenu) {
            style |= WS_SYSMENU;
        }
        if (info.allowMinimize) {
            style |= WS_MINIMIZEBOX;
        }
        if (info.allowMaximize) {
            style |= WS_MAXIMIZEBOX;
        }

        // ... positioning, adjusting size, etc.

    } else {
        style = WS_POPUP;
        x = monitorInfo.rcMonitor.left;
        y = monitorInfo.rcMonitor.top;
        width = monitorInfo.rcMonitor.right - x;
        height = monitorInfo.rcMonitor.bottom - y;
    }

    handle = CreateWindowEx(
        exStyle,
        CLASS_NAME,
        info.title,
        style,
        x,
        y,
        width,
        height,
        HWND_DESKTOP,
        nullptr,
        hInstance,
        nullptr
    );

    if (!handle) {
        return false;
    }

    running = true;
    ShowWindow(handle, SW_SHOW);

    return true;
}

The loop is the standard Peek-Translate-Dispatch trio and the WndProc only handles the WM_CLOSE message, otherwise returns with DefWindowProc.

  • How could I enable the Aero support in this kind of setup?
  • If the proper manifest file would be the solution, how should I handle it correctly? I mean the client (the executable) should not care that the underlying library is using WinAPI or not
  • A CMake example would be really helpful

Current solution

I was able to find an example (actually from a Vulkan SDK) that pointed out that I need the WS_THICKFRAME style (a resize border) in order to my window become modern looking (Aero-like).

0

There are 0 best solutions below