C++ WM_弹出窗口,用于调整绘制边框的切割大小
我有一个窗口,我试图在我自己画一切,包括标题栏,边框 我的问题是,当我从右下角拖动窗口以调整其大小时 当我把窗口变小时,我的右/下边框被切掉了,当我把它拉大时,它似乎工作得很好 如果我删除CS|HREDRAW | CS|VREDRAW,它只会弄乱边界,从我拖动的地方它就会变成黑色。(我在某处看到,最好不要使用这些样式来停止闪烁) 我不确定我是否在我的窗口中使用了正确的样式来实现我的目标。我的最终目标是绘制窗口中的所有内容,包括标题栏、边框、按钮和所有控件C++ WM_弹出窗口,用于调整绘制边框的切割大小,c++,winapi,C++,Winapi,我有一个窗口,我试图在我自己画一切,包括标题栏,边框 我的问题是,当我从右下角拖动窗口以调整其大小时 当我把窗口变小时,我的右/下边框被切掉了,当我把它拉大时,它似乎工作得很好 如果我删除CS|HREDRAW | CS|VREDRAW,它只会弄乱边界,从我拖动的地方它就会变成黑色。(我在某处看到,最好不要使用这些样式来停止闪烁) 我不确定我是否在我的窗口中使用了正确的样式来实现我的目标。我的最终目标是绘制窗口中的所有内容,包括标题栏、边框、按钮和所有控件 bool Window::Create(
bool Window::Create(const wchar_t *title, Vector2D size)
{
HINSTANCE instanceHandle = GetModuleHandle(NULL);
if (this->RegisterWindowClass())
{
m_handle = (HWND)CreateWindowEx(0, VERSION, L"", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, size.m_x, size.m_y, NULL, NULL, instanceHandle, this);
if (m_handle)
{
::ShowWindow(m_handle, SW_SHOW);
}
}
return m_handle != 0;
}
bool Window::RegisterWindowClass(const wchar_t *title)
{
static bool registered = false;
if (!registered)
{
HINSTANCE instanceHandle = GetModuleHandle(NULL);
WNDCLASSEX windowClass;
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = (WNDPROC)Window::WindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = instanceHandle;
windowClass.hIcon = NULL;
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(60, 60, 60)));//set back color to window
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = title;
windowClass.hIconSm = NULL;
if (RegisterClassEx(&windowClass))
registered = true;
}
return registered;
}
void Draw_LeftRightBottom_Rectangles(HDC hdc, HBRUSH brush, RECT rect, int TaskbarHeight)
{
RECT leftrect, rightrect, bottomrect;
leftrect.left = 0;
leftrect.top = TaskbarHeight;
leftrect.right = 2;
leftrect.bottom = rect.bottom;
//fill left rect of window for border
FillRect(hdc, &leftrect, brush);
rightrect.left = rect.right - 2;
rightrect.top = TaskbarHeight;
rightrect.right = rect.right;
rightrect.bottom = rect.bottom;
//fill right rect of window
FillRect(hdc, &rightrect, brush);
bottomrect.left = 0;
bottomrect.top = rect.bottom - 2;
bottomrect.right = rect.right;
bottomrect.bottom = rect.bottom;
//fill bottom rect of window
FillRect(hdc, &bottomrect, brush);
}
LRESULT Window::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static int X, Y;
Window* pThis;
if (uMsg == WM_NCCREATE)
{
pThis = static_cast<Window*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis));
}
else
pThis = reinterpret_cast<Window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (pThis != 0)
{
switch (uMsg)
{
case WM_PAINT:
{
RECT clientArea;
GetClientRect(hwnd, &clientArea);
PAINTSTRUCT ps;
if (BeginPaint(hwnd, &ps))
{
//Creating double buffer
HDC hdcMem = CreateCompatibleDC(ps.hdc);
int ndcmem = SaveDC(hdcMem);
HBITMAP hbmMem = CreateCompatibleBitmap(ps.hdc, X, Y);
SelectObject(hdcMem, hbmMem);
//-------------------------------------------------------
// Copy background bitmap into double buffer
BitBlt(hdcMem, 0, 0, clientArea.right, clientArea.bottom, ps.hdc, 0, 0, SRCCOPY);
//---------------------------------------------------------
RECT rect;
rect.bottom = 25;
rect.right = clientArea.right;
HBRUSH brush = CreateSolidBrush(RGB(0, 0, 0));
// Draw Titlebar
FillRect(hdcMem, &rect, brush);
Draw_LeftRightBottom_Rectangles(hdcMem, brush, clientArea, 25);
DeleteObject(brush);
//-----------------------------------------------------------------------------
// Copy double buffer to screen
BitBlt(ps.hdc, 0, 0, X, Y, hdcMem, 0, 0, SRCCOPY);
//--------------------------------------------------
// Clean up
RestoreDC(hdcMem, ndcmem);
DeleteObject(hbmMem);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
//--------------------
}
return 0;;
}
case WM_SIZE:
{
X = LOWORD(lParam);
Y = HIWORD(lParam);
break;
}
case WM_NCHITTEST:
{
POINT pt;
RECT rc;
GetClientRect(hwnd, &rc);
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ScreenToClient(hwnd, &pt);
if (pt.y > (rc.bottom - BORDERWIDTH))
{
if (pt.x>(rc.right - BORDERWIDTH))
{
return HTBOTTOMRIGHT;
}
}
if (pt.y < 25)
{
return HTCAPTION;
}
break;
}
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
bool窗口::创建(常量wchar\u t*标题,矢量2D大小)
{
HINSTANCE instanceHandle=GetModuleHandle(NULL);
如果(此->RegisterWindowClass())
{
m_handle=(HWND)CreateWindowEx(0,版本,L“”,WS_弹出窗口,CW_USEDEFAULT,CW_USEDEFAULT,size.m_x,size.m_y,NULL,NULL,instanceHandle,this);
if(m_句柄)
{
:显示窗口(m_手柄、SW_显示);
}
}
返回m_句柄!=0;
}
bool窗口::RegisterWindowClass(常量wchar\u t*title)
{
静态bool注册=假;
如果(!已注册)
{
HINSTANCE instanceHandle=GetModuleHandle(NULL);
WNDCLASSEX窗口类;
windowClass.cbSize=sizeof(WNDCLASSEX);
windowClass.style=CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc=(WNDPROC)Window::WindowProc;
windowClass.cbClsExtra=0;
windowClass.cbWndExtra=0;
windowClass.hInstance=instanceHandle;
windowClass.hIcon=NULL;
windowClass.hCursor=LoadCursor(空,IDC_箭头);
windowClass.hbrBackground=(HBRUSH)(CreateSolidBrush(RGB(60,60,60));//将颜色设置回窗口
windowClass.lpszMenuName=NULL;
windowClass.lpszClassName=标题;
windowClass.hIconSm=NULL;
if(注册表类(&windowClass))
注册=真实;
}
注册报税表;
}
void Draw_LeftRightBottom_矩形(HDC HDC、HBRUSH笔刷、RECT RECT、int TaskbarHeight)
{
RECT leftrect,righrect,bottomrect;
leftrect.left=0;
leftrect.top=TaskbarHeight;
leftrect.right=2;
leftrect.bottom=rect.bottom;
//为边框填充窗口的左矩形
FillRect(hdc和leftrect、笔刷);
righrect.left=rect.right-2;
rightrect.top=TaskbarHeight;
righrect.right=rect.right;
righrect.bottom=rect.bottom;
//填充窗口的右矩形
FillRect(hdc和rightrect、笔刷);
bottomrect.left=0;
bottomrect.top=rect.bottom-2;
bottomrect.right=rect.right;
bottomrect.bottom=rect.bottom;
//填充窗口的底部矩形
FillRect(hdc和bottomrect、笔刷);
}
LRESULT窗口::WindowProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
静态int X,Y;
窗口*p这;
if(uMsg==wmnccreate)
{
pThis=静态转换(重新解释转换(lParam)->lpCreateParams);
SetWindowLongPtr(hwnd、GWLP_用户数据、重新解释(pThis));
}
其他的
pThis=reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA));
如果(pThis!=0)
{
开关(uMsg)
{
案例WM_油漆:
{
直阴蒂区;
GetClientRect(hwnd和clientArea);
PAINTSTRUCT-ps;
if(开始喷漆(hwnd和ps))
{
//创建双缓冲区
HDC hdcMem=CreateCompatibleDC(ps.HDC);
int ndcmem=SaveDC(hdcMem);
HBITMAP hbmMem=CreateCompatibleBitmap(ps.hdc,X,Y);
选择对象(hdcMem、hbmMem);
//-------------------------------------------------------
//将背景位图复制到双缓冲区
BitBlt(hdcMem,0,0,clientrea.right,clientrea.bottom,ps.hdc,0,0,srcopy);
//---------------------------------------------------------
RECT-RECT;
rect.bottom=25;
rect.right=clientrea.right;
HBRUSH笔刷=CreateSolidBrush(RGB(0,0,0));
//画标题栏
FillRect(hdcMem和rect、笔刷);
绘制左右下矩形(hdcMem、画笔、clientArea、25);
删除对象(画笔);
//-----------------------------------------------------------------------------
//将双缓冲区复制到屏幕
BitBlt(ps.hdc,0,0,X,Y,hdcMem,0,0,srcopy);
//--------------------------------------------------
//清理
恢复的(hdcMem、ndcmem);
删除对象(hbmMem);
DeleteDC(hdcMem);
端漆(hwnd和ps);
//--------------------
}
返回0;;
}
案例WM_大小:
{
X=低ORD(lParam);
Y=HIWORD(lParam);
打破
}
案例WM_NCHITTEST:
{
点pt;
RECT-rc;
GetClientRect(hwnd和rc);
pt.x=低ORD(LPRAM);
pt.y=HIWORD(lParam);
屏幕客户端(硬件、硬件和pt);
如果(第y部分>(rc.底部-边框宽度))
{
如果(第x部分>(右栏-边框宽度))
{
回归权;
}
}
如果(第y部分<25)
{
返回标题;
}
打破
}
}
}
返回DefWindowProc(hwnd、uMsg、wParam、lParam);
}
在WM_PAINT中调用GetClientRect()
时,为什么要使用静态变量X
和Y
(应称为width
和height
)。然后在某些调用中不一致地使用X
和Y