- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我一直在关注 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 按钮发光和工具提示,单击按钮会执行各自的操作(因此我可以关闭此窗口)。但没有别的工作:我不能用边缘移动或调整窗口大小,而且边框不绘制,而是绘制白色:
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_NCHITTEST
和 WM_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 中的结果:
赢 7:
关于c++ - 为什么我的 DwmExtendFrameIntoClientArea() 窗口没有绘制 DWM 边框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41106347/
我对WTL很陌生这是我的主对话框的 onCreate 代码 int Cwin32_mfcDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (C
正如我们所知,一些现代应用程序(IE9、Firefox 4、Chrome、Paint.NET 等)使用 DwmExtendFrameIntoClientArea 来实现 Aero 玻璃效果。 不过,您
在窗口上调用 DwmExtendFrameIntoClientArea 后,如何在保持 Aero 模式的同时再次关闭它? 我尝试调用 DwmExtendFrameIntoClientArea 并将所有
我在使用 DwmExtendFrameIntoClientArea 扩展窗框时遇到了一些麻烦在 Windows 10 上。下图显示了我得到的行为: 白色标题栏颜色从顶部延伸,而从侧面和底部延伸到窗口的
在启用 Aero Glass 的情况下使用 DwmExtendFrameIntoClientArea API 调用效果很好。但是,我希望它在禁用 Aero Glass 时也能正常工作,就像它在 Win
我一直在关注 MSDN's guide to using the DWM API to extend the frame into the client area ,但重做了,这样我就可以在我有一些工
我是一名优秀的程序员,十分优秀!