如何像github应用程序一样创建没有边框和阴影的窗口?
问题描述:
如何创建没有边框但行为与边框类似的窗口.像 git-hub 应用程序窗口一样,它也有阴影效果.如何创建这样的窗口.
谢谢你.使用 win 32 c++.
how to create window which does't have border but it has behaves like with border . like git-hub app window, it has shadow effect also.how to create window like this.
thank you. using win 32 c++.
我曾尝试处理 wm_Ncpaint 调用,但没有用.
i had tried by handling wm_Ncpaint call but no use.
#include "stdafx.h"
#include "CustomWindow.h"
LONG_PTR g_lpCustomWindowptr = NULL;
BOOL g_bStateofWindow = TRUE;
// creating window
CreateWindowEx(WS_EX_ACCEPTFILES,
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,
NULL, hInstance, NULL);
void CustomWindow::CreateCustomWindow(HWND hwnd)
{
// To set border and handling Doc with default cases
LONG_PTR lpStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
lpStyle &= ~(WS_CAPTION | WS_ACTIVECAPTION );
//lpStyle |= WS_THICKFRAME;
SetWindowLongPtr(hwnd, GWL_STYLE, lpStyle);
//set the customized proc.
g_lpCustomWindowptr = SetWindowLongPtr(hwnd,
GWLP_WNDPROC,
(LONG_PTR)CustonWindow_WndProc);
}
LRESULT CALLBACK CustomWindow::CustonWindow_WndProc(IN HWND hwnd,
IN UINT message,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
if (SIZE_MAXIMIZED == wParam)
{
HMONITOR hmon= MonitorFromWindow(hwnd,
MONITOR_DEFAULTTONEAREST);
MONITORINFO moninfo = {0};
moninfo.cbSize= sizeof(moninfo);
GetMonitorInfo(hmon, &moninfo);
SetWindowPos(hwnd,
HWND_TOP,
moninfo.rcWork.left,
moninfo.rcWork.top,
moninfo.rcWork.right,
moninfo.rcWork.bottom,
SWP_FRAMECHANGED |
SWP_NOREDRAW);
}
}
break;
case WM_NCACTIVATE :
{
if (TRUE == wParam)
{
SendMessage(hwnd,WM_NCPAINT,wParam,0);
}
else if(FALSE == wParam )
{
SendMessage(hwnd,WM_NCPAINT,wParam,0);
}
return true;
}
case WM_NCCALCSIZE:
{
return 0;
}
break;
case WM_NCPAINT:
{
HDC hDC;
hDC = GetWindowDC(hwnd);
HPEN hPen = CreatePen(PS_SOLID, 5, RGB(0,0,255));;
SelectObject(hDC, hPen);
RECT rcClientRect = {0};
GetClientRect(hwnd,&rcClientRect);
if(FALSE == wParam)
{
MoveToEx(hDC,rcClientRect.left,rcClientRect.top,NULL);
LineTo(hDC,rcClientRect.right - 1,rcClientRect.top );
LineTo(hDC,rcClientRect.right - 1,rcClientRect.bottom - 1 );
LineTo(hDC,rcClientRect.left,rcClientRect.bottom - 1);
LineTo(hDC,rcClientRect.left,rcClientRect.top);
}
else
{
HPEN hPen1 = CreatePen(PS_SOLID, 5, RGB(255,0,0));;
SelectObject(hDC, hPen1);
MoveToEx(hDC,rcClientRect.left,rcClientRect.top,NULL);
LineTo(hDC,rcClientRect.right - 1,rcClientRect.top );
LineTo(hDC,rcClientRect.right - 1,rcClientRect.bottom - 1 );
LineTo(hDC,rcClientRect.left,rcClientRect.bottom - 1);
LineTo(hDC,rcClientRect.left,rcClientRect.top);
}
ReleaseDC(hwnd, hDC);
}
}
break;
}
return CallWindowProc((WNDPROC)g_lpCustomWindowptr,
hwnd,
message,
wParam,
lParam);
}
答
要创建没有边框、系统菜单和标题栏但带有 Aero 阴影的窗口,您需要执行以下操作:
To create window without border, system menu and titlebar but with Aero shadow you need to do the following:
- 使用
WS_CAPTION
样式创建窗口 - 调用
DwmExtendFrameIntoClientArea
WDM API 传递 1 像素上边距 - 处理
WM_NCCALCSIZE
消息,处理此消息时不将调用转发到DefWindowProc
,而只返回0
- Create window with
WS_CAPTION
style - Call
DwmExtendFrameIntoClientArea
WDM API passing 1 pixel top margin - Handle
WM_NCCALCSIZE
message, do not forward call toDefWindowProc
while processing this message, but just return0
这是一个使用 Delphi 编写的干净的 Windows API 创建此类窗口的简单示例:
Here is a simple example that creates such window using clean Windows API written in Delphi:
program BorderlessWindow;
uses
DwmApi,
Winapi.UxTheme,
Windows, SysUtils, Messages;
{$R *.res}
var
Msg : TMSG;
LWndClass : TWndClass;
hMainHandle: HWND;
lMargins: TMargins;
procedure ReleaseResources;
begin
PostQuitMessage(0);
end;
function WindowProc(hWnd,Msg:Longint; wParam : WPARAM; lParam: LPARAM):Longint; stdcall;
begin
case Msg of
WM_DESTROY: ReleaseResources;
WM_NCHITTEST: Exit(HTCAPTION); // This is needed only to move window with mouse
WM_NCCALCSIZE: Exit(0); // This line will hide default window border and caption
end;
Result:=DefWindowProc(hWnd,Msg,wParam,lParam);
end;
begin
//create the window
LWndClass.hInstance := hInstance;
with LWndClass do
begin
lpszClassName := 'MyWinApiWnd';
Style := 0;//CS_PARENTDC or CS_BYTEALIGNCLIENT;
hIcon := LoadIcon(hInstance,'MAINICON');
lpfnWndProc := @WindowProc;
hbrBackground := COLOR_BTNFACE+1;
hCursor := LoadCursor(0,IDC_ARROW);
end;
RegisterClass(LWndClass);
hMainHandle := CreateWindow(LWndClass.lpszClassName,nil,
WS_CAPTION or WS_VISIBLE,
(GetSystemMetrics(SM_CXSCREEN) div 2)-190,
(GetSystemMetrics(SM_CYSCREEN) div 2)-170, 386,200,0,0,hInstance,nil);
if DwmCompositionEnabled then
begin
// This API call adds aero shadow
lMargins.cyTopHeight := 1;
DwmExtendFrameIntoClientArea(hMainHandle, lMargins);
end;
//message loop
while GetMessage(Msg,0,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.