C++ WM_弹出窗口,用于调整绘制边框的切割大小

C++ WM_弹出窗口,用于调整绘制边框的切割大小,c++,winapi,C++,Winapi,我有一个窗口,我试图在我自己画一切,包括标题栏,边框 我的问题是,当我从右下角拖动窗口以调整其大小时 当我把窗口变小时,我的右/下边框被切掉了,当我把它拉大时,它似乎工作得很好 如果我删除CS|HREDRAW | CS|VREDRAW,它只会弄乱边界,从我拖动的地方它就会变成黑色。(我在某处看到,最好不要使用这些样式来停止闪烁) 我不确定我是否在我的窗口中使用了正确的样式来实现我的目标。我的最终目标是绘制窗口中的所有内容,包括标题栏、边框、按钮和所有控件 bool Window::Create(

我有一个窗口,我试图在我自己画一切,包括标题栏,边框

我的问题是,当我从右下角拖动窗口以调整其大小时

当我把窗口变小时,我的右/下边框被切掉了,当我把它拉大时,它似乎工作得很好

如果我删除CS|HREDRAW | CS|VREDRAW,它只会弄乱边界,从我拖动的地方它就会变成黑色。(我在某处看到,最好不要使用这些样式来停止闪烁)

我不确定我是否在我的窗口中使用了正确的样式来实现我的目标。我的最终目标是绘制窗口中的所有内容,包括标题栏、边框、按钮和所有控件

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