YmF*_*TY0 7 winapi dwm windows-10
我在使用DwmExtendFrameIntoClientAreaWindows 10 扩展窗口框架时遇到了一些麻烦.下面的图片显示了我得到的行为:
白色标题栏颜色从顶部延伸,而从侧面和底部延伸窗口的彩色边缘.
如果我将边距全部设置-1为将框架一直延伸,则窗口将填充白色并完全丢失其彩色边缘:
这个结果非常不一致,我希望在窗口的所有侧面都能延伸白色,类似于Windows 8中彩色框架的扩展方式,或者在Windows 7和Vista中扩展了玻璃.
我试过在线搜索,但我找不到任何类似的问题.
这是我正在使用的代码:
#include <windows.h>
#include <dwmapi.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int main(int argc, char **argv)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
MSG msg;
HWND hwnd;
WNDCLASSW wc;
int message;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassW(&wc);
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 350, 250, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
while(1) {
message = GetMessageW(&msg, NULL, 0, 0);
if(message == -1)
{
char x[100];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), x, 100, NULL);
puts(x);
abort();
}
else if(message == 0) break;
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_ACTIVATE:
{
MARGINS m = {50, 50, 50, 50};
HRESULT hr = DwmExtendFrameIntoClientArea(hwnd, &m);
if(!SUCCEEDED(hr))
{
char x[100];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), x, 100, NULL);
puts(x);
abort();
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
我做错了什么或者这只是Windows 10的一个问题?在此先感谢您的帮助!
编辑:我发布的代码与Windows 10上的Aero Lite和高对比度主题完美配合,但与默认的Windows 10主题无关.
当框架延伸到客户区域时,您需要确保客户区域绘制程序在玻璃应该在的任何地方绘制纯黑色。
来自MSDN:
确保扩展帧可见的最简单方法是将整个客户区域涂成黑色。要实现此目的,请将WNDCLASS或WNDCLASSEX结构的hbrBackground成员初始化为库存 BLACK_BRUSH 的句柄。下图显示了前面所示的相同标准框架(左)和扩展框架(右)。然而,这一次,hbrBackground被设置为从GetStockObject函数获得的BLACK_BRUSH句柄。
编辑:我尝试尽可能地重现您的临时程序:
program ScratchProgram;
uses
Windows,
Messages,
DwmApi,
UxTheme;
{ Window Procedure }
function WndProc(hWnd: HWND; uiMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
m: TMargins;
begin
case uiMsg of
WM_ACTIVATE:
begin
m.cxLeftWidth := 50;
m.cxRightWidth := 50;
m.cyTopHeight := 50;
m.cyBottomHeight := 50;
DwmExtendFrameIntoClientArea(hWnd, m);
end;
WM_DESTROY:
begin
PostQuitMessage(0);
Result := 0;
Exit;
end;
end;
Result := DefWindowProc(hWnd, uiMsg, wParam, lParam);
end;
function WinMain(hInstance: HINST; hPrevInstance: HINST; lpCmdLine: PChar; nShowCmd: Integer): Integer; stdcall;
var
wc: WNDCLASS;
msg: TMSG;
hWindow: HWND;
instance: HINST;
begin
instance := GetModuleHandle(nil);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.lpszClassName := 'Window';
wc.hInstance := instance;
wc.hbrBackground := GetStockObject(BLACK_BRUSH);
wc.lpszMenuName := nil;
wc.lpfnWndProc := @WndProc;
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hIcon := LoadIcon(0, IDI_APPLICATION);
RegisterClass(wc);
hWindow := CreateWindow(
wc.lpszClassName, // Class Name
'Window', // Title
WS_OVERLAPPEDWINDOW or WS_VISIBLE, // Style
100, 100, // Position
350, 250, // Size
0, // Parent
0, // No menu
instance, // Instance
nil); // No special parameters
ShowWindow(hWindow, SW_SHOW);
while (GetMessage(msg, 0, 0, 0)) do
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
Result := 0;
end;
begin
WinMain(hInstance, hPrevInst, CmdLine, CmdShow);
end.
Run Code Online (Sandbox Code Playgroud)
它对我有用:
无论问题是什么,代码在概念上看起来都没有错误。
也许是调用约定,或者在您不期望的情况下失败(RegisterClass例如,使用GetModuleHandle传递给 的实例句柄WinMain,或者DwmExtendFrameIntoClientArea即使在表单被停用时也进行调用)。