gpt4 book ai didi

c++ - 为什么我的 DwmExtendFrameIntoClientArea() 窗口没有绘制 DWM 边框?

转载 作者:搜寻专家 更新时间:2023-10-31 00:55:51 26 4
gpt4 key购买 nike

我一直在关注 MSDN's guide to using the DWM API to extend the frame into the client area ,但重做了,这样我就可以在我有一些工作时进行试验。

但是,当我在 Visual Studio 2013 x64 Native Tools 命令行中使用 cl wincompositiontest.cpp 构建它时,程序不会绘制窗口边框。标准窗口按钮确实有效:我可以看到 Windows 7 按钮发光和工具提示,单击按钮会执行各自的操作(因此我可以关闭此窗口)。但没有别的工作:我不能用边缘移动或调整窗口大小,而且边框不绘制,而是绘制白色:

Window

DwmExtendFrameIntoClientArea() 返回 S_OK

这是怎么回事?这是在 VirtualBox 中运行的 Windows 7 x64 上;我把代码给了一个也在真实硬件上运行 Windows 7 的 friend ,他们得到了相同的结果。谢谢。

// 12 december 2016
#define UNICODE
#define _UNICODE
#define STRICT
#define STRICT_TYPED_ITEMIDS
// get Windows version right; right now Windows Vista
// unless otherwise stated, all values from Microsoft's sdkddkver.h
// TODO is all of this necessary? how is NTDDI_VERSION used?
// TODO plaform update sp2
#define WINVER 0x0600 /* from Microsoft's winnls.h */
#define _WIN32_WINNT 0x0600
#define _WIN32_WINDOWS 0x0600 /* from Microsoft's pdh.h */
#define _WIN32_IE 0x0700
#define NTDDI_VERSION 0x06000000
#include <windows.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <windowsx.h>
#include <shobjidl.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include <usp10.h>
#include <msctf.h>
#include <textstor.h>
#include <olectl.h>
#include <shlwapi.h>
#include <dwmapi.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <inttypes.h>
#include <vector>
#include <map>
#include <string>

#pragma comment(linker, \
"\"/manifestdependency:type='Win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='*' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "uxtheme.lib")
#pragma comment(lib, "dwmapi.lib")

#define HR(call) printf("%s -> 0x%I32X\n", #call, call)

LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RECT r;
MARGINS margins;
BOOL dwmHandled;
LRESULT lResult;

dwmHandled = DwmDefWindowProc(hwnd, uMsg, wParam, lParam, &lResult);
switch (uMsg) {
case WM_CREATE:
GetWindowRect(hwnd, &r);
SetWindowPos(hwnd, NULL,
r.left, r.top,
r.right - r.left, r.bottom - r.top,
SWP_FRAMECHANGED);
// TODO if we pass SWP_NOOWNERZORDER || SWP_NOZORDER, the default frame is not correctly inhibited
break;
case WM_ACTIVATE:
margins.cxLeftWidth = 8;
margins.cxRightWidth = 8;
margins.cyBottomHeight = 20;
margins.cyTopHeight = 27;
HR(DwmExtendFrameIntoClientArea(hwnd, &margins));
break;
case WM_NCCALCSIZE:
if (wParam != (WPARAM) FALSE)
return 0;
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
}
if (dwmHandled)
return lResult;
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

int main(void)
{
WNDCLASSW wc;
HWND mainwin;
MSG msg;

ZeroMemory(&wc, sizeof (WNDCLASSW));
wc.lpszClassName = L"mainwin";
wc.lpfnWndProc = wndproc;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIconW(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
RegisterClassW(&wc);

mainwin = CreateWindowExW(0,
L"mainwin", L"Main Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
400, 400,
NULL, NULL, GetModuleHandle(NULL), NULL);

ShowWindow(mainwin, SW_SHOWDEFAULT);
UpdateWindow(mainwin);

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

最佳答案

为了与 Windows 10 兼容,左/右/下边距应为零。

通常你只需要改变标题栏区域。因此,只需更改 margins.cyTopHeight

的值

使用 AdjustWindowRectEx 计算给定窗口样式的默认边框宽度,并将这些值传递给 WM_NCCALCSIZE,这将显示默认边框。

DwmDefWindowProc 是响应 WM_NCHITTESTWM_NCMOUSELEAVE 所必需的(但也许您设置它的方式对于将来的兼容性更好)

您还必须处理 WM_PAINT 以使系统按钮正确显示。隐藏系统按钮并绘制您自己的按钮可能更容易,因此标题栏是完全自定义的,具有自己的背景颜色。

下面是 Windows 10 的示例,它应该适用于 Windows 7。应用程序应该知道 DPI,否则会出现带边框的小显示问题。

void paint_caption(HWND hWnd, HDC hdc, int caption_height)
{
RECT rc;
GetClientRect(hWnd, &rc);
rc.bottom = caption_height;

HDC memdc = CreateCompatibleDC(hdc);
BITMAPINFOHEADER bmpInfoHdr =
{ sizeof(BITMAPINFOHEADER), rc.right, -rc.bottom, 1, 32 };
HBITMAP hbitmap =
CreateDIBSection(memdc, (BITMAPINFO*)(&bmpInfoHdr), DIB_RGB_COLORS, 0, 0, 0);
HGDIOBJ oldbitmap = SelectObject(memdc, hbitmap);

//Note, GDI functions don't support alpha channel, they can't be used here
//Use GDI+, BufferedPaint, or DrawThemeXXX functions

BitBlt(hdc, 0, 0, rc.right, caption_height, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, oldbitmap);
DeleteObject(hbitmap);
DeleteDC(memdc);
}

LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//static MARGINS margins = { -1,-1,100,-1 };
static MARGINS margins = { 0,0,100,0 };
static RECT border_thickness = { 0 };

switch(uMsg)
{
case WM_CREATE:
if(GetWindowLongPtr(hwnd, GWL_STYLE) & WS_THICKFRAME)
{
AdjustWindowRectEx(&border_thickness,
GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
border_thickness.left *= -1;
border_thickness.top *= -1;
}
else if(GetWindowLongPtr(hwnd, GWL_STYLE) & WS_BORDER)
{
border_thickness = { 1,1,1,1 };
}

DwmExtendFrameIntoClientArea(hwnd, &margins);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);

break;

case WM_NCCALCSIZE:
if(lParam)
{
NCCALCSIZE_PARAMS* sz = (NCCALCSIZE_PARAMS*)lParam;
sz->rgrc[0].left += border_thickness.left;
sz->rgrc[0].right -= border_thickness.right;
sz->rgrc[0].bottom -= border_thickness.bottom;
return 0;
}
break;

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);

//paint caption area
paint_caption(hwnd, hdc, margins.cyTopHeight);

EndPaint(hwnd, &ps);
return 0;
}

case WM_NCHITTEST:
{
//handle close/minimize/maximize/help button
LRESULT lResult;
if (DwmDefWindowProc(hwnd, uMsg, wParam, lParam, &lResult))
return lResult;

//do default processing, except change the result for caption area
lResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
if(lResult == HTCLIENT)
{
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
ScreenToClient(hwnd, &pt);
if(pt.y < border_thickness.top) return HTTOP;
if(pt.y < margins.cyTopHeight) return HTCAPTION;
}

return lResult;
}

case WM_NCMOUSELEAVE:
{
LRESULT lResult;
if(DwmDefWindowProc(hwnd, uMsg, wParam, lParam, &lResult))
return lResult;
break;
}

case WM_CLOSE:
PostQuitMessage(0);
break;
}

return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

Windows 10 中的结果:

enter image description here

赢 7:

enter image description here

关于c++ - 为什么我的 DwmExtendFrameIntoClientArea() 窗口没有绘制 DWM 边框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41106347/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com