问题描述
I'm having some trouble extending the window frames using DwmExtendFrameIntoClientArea
on Windows 10. The images below show the behaviour I'm getting:
白色标题栏颜色从顶部延伸,而从侧面和底部开始延伸窗口的彩色边缘.
The white titlebar colour is extended from the top, while from the sides and the bottom it extends the coloured edge of the window.
如果我将所有页边距全部设置为-1
以扩展帧的范围,则该窗口将被填充为白色,并且完全失去其彩色边缘:
If I set the margins all to -1
to extend the frames all the way, the window is filled with white and loses its coloured edge altogether:
此结果非常不一致,我期望白色在窗口的所有侧面扩展,类似于在Windows 8中扩展彩色框架的方式,或在Windows 7和Vista中扩展玻璃的方式.
This result is very inconsistent, I was expecting the white colour to be extended on all sides of the window, similar to the way the coloured frame is extended in Windows 8, or the glass is extended in Windows 7 and Vista.
我尝试过在线搜索,但是找不到任何类似的问题.
I've tried searching online, but I haven't been able to find any similar issues.
这是我正在使用的代码:
Here is the code I'm using:
#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);
}
我做错什么了吗,或者这仅仅是Windows 10的问题?预先感谢您的帮助!
Am I doing something wrong or is this just an issue with Windows 10? Thanks in advance for any help!
编辑:我发布的代码与Aero Lite和Windows 10上的高对比度主题都可以完美配合,但不适用于默认的Windows 10主题.
The code I posted works perfectly with both Aero Lite and the high contrast themes on Windows 10, but not with the default Windows 10 theme.
推荐答案
将框架扩展到工作区后,您需要确保工作区的绘制过程在任何地方绘制纯 black glass 应该是.
When the frame has been extended into the client area, you need to make sure that your client area paint procedure draws pure black anywhere the glass should be.
来自 MSDN :
编辑:我试图尽可能地重现您的草稿程序:
Edit: I tried to reproduce your scratch program as closely as possible:
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.
它对我有用:
无论问题出在哪里,代码在概念上都没有错.
Whatever the problem is, the code doesn't look conceptually wrong.
可能会调用约定,或者发生您不期望的约定(例如,RegisterClass
,或者在传递给WinMain
的实例句柄上使用GetModuleHandle
,或者即使是在表单时也调用DwmExtendFrameIntoClientArea
正在停用).
Perhaps calling conventions, or a failure where you don't expect it (RegisterClass
for example, or the use of GetModuleHandle
over the instance handle passed to WinMain
, or calling DwmExtendFrameIntoClientArea
even when the form is being deactivated).
这篇关于DwmExtendFrameIntoClientArea在Windows 10上的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!