You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无标题栏C++ Win32窗口无法触发Windows 11停靠面板求助

解决方案

问题根源在于Windows 11的停靠(Snap)功能依赖窗口具备WS_MAXIMIZEBOX样式——系统会认为没有该样式的窗口不支持最大化类操作,因此不会触发顶部停靠的弹窗。要在保留自定义标题栏且窗口不可调整大小的前提下解决问题,可按以下步骤操作:

步骤1:保留WS_MAXIMIZEBOX样式

修改窗口创建时的样式参数,保留WS_MAXIMIZEBOX,移除WS_SIZEBOX(如果不需要窗口可调整大小):

HWND hWnd = CreateWindowW(
    L"minimal_example_window", L"",
    WS_VISIBLE | WS_POPUP | WS_MAXIMIZEBOX,  // 保留WS_MAXIMIZEBOX,移除WS_SIZEBOX
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    1200,
    800,
    NULL,NULL,
    hInstance,
    NULL
);

步骤2:隐藏最大化按钮

由于我们不需要显示最大化按钮,可通过DWM API隐藏它。需要引入dwmapi.h并链接dwmapi.lib:

#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")  // 链接DWM库

在窗口创建完成后,调用DwmSetWindowAttribute设置隐藏最大化按钮:

// 启用DWM非客户区渲染
DWMNCRENDERINGPOLICY render_policy = DWMNCRP_ENABLED;
DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, &render_policy, sizeof(render_policy));

// 隐藏最大化按钮
DWORD button_mask = DWMNCA_HIDEMAXBUTTON;
DwmSetWindowAttribute(hWnd, DWMWA_NCAP_BUTTONS, &button_mask, sizeof(button_mask));

步骤3:保持原有拖动逻辑

你的WM_NCHITTEST处理逻辑无需修改,依然可以让整个客户区作为标题栏拖动:

LRESULT CALLBACK window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_NCHITTEST) {
        LRESULT hit = DefWindowProc(hWnd, uMsg, wParam, lParam);
        if (hit == HTCLIENT) hit = HTCAPTION;
        return hit;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

完整修改后的代码

#include <windows.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")

LRESULT CALLBACK window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_NCHITTEST) {
        LRESULT hit = DefWindowProc(hWnd, uMsg, wParam, lParam);
        if (hit == HTCLIENT) hit = HTCAPTION;
        return hit;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
    WNDCLASSW window_class = {
        NULL, window_proc, NULL,NULL, hInstance,
        NULL, LoadCursor(NULL, IDC_ARROW),
        NULL, NULL, L"minimal_example_window"
    }; 
    RegisterClassW(&window_class);
    
    HWND hWnd = CreateWindowW(
        L"minimal_example_window", L"",
        WS_VISIBLE | WS_POPUP | WS_MAXIMIZEBOX,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        1200,
        800,
        NULL,NULL,
        hInstance,
        NULL
    );

    // 配置DWM属性隐藏最大化按钮
    DWMNCRENDERINGPOLICY render_policy = DWMNCRP_ENABLED;
    DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, &render_policy, sizeof(render_policy));
    
    DWORD button_mask = DWMNCA_HIDEMAXBUTTON;
    DwmSetWindowAttribute(hWnd, DWMWA_NCAP_BUTTONS, &button_mask, sizeof(button_mask));

    MSG msg; 
    while (GetMessageW(&msg, NULL, 0, 0) > 0)
    { 
        TranslateMessage(&msg); 
        DispatchMessageW(&msg); 
    }
    
    return 0;
}

这样修改后,窗口既可以通过客户区任意拖动,又能触发Windows 11的顶部停靠弹窗,同时不会显示最大化按钮,也无法调整窗口大小。

内容的提问来源于stack exchange,提问作者Barnabás

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:54:53