zoukankan      html  css  js  c++  java
  • win32- 使用WM_NCPAINT在非客户区域绘制边框

    #pragma comment(lib, "UxTheme")
    #include <windows.h>
    #include <uxtheme.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.hIcon = NULL;
        wcex.hCursor = (HICON)LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = CreateSolidBrush(RGB(0, 128, 0));
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = L"window";
        wcex.hIconSm = NULL;
    
        RegisterClassEx(&wcex);
    
        HWND hWnd = CreateWindowEx(
            NULL,
            L"window",
            NULL,
            WS_OVERLAPPEDWINDOW,
            100,
            100,
            600,
            400,
            NULL,
            NULL,
            hInstance,
            NULL);
    
        ShowWindow(hWnd, nCmdShow);
    
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return static_cast<int>(msg.wParam);
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg) {
        case WM_CREATE:
            SetWindowTheme(hWnd, L"", L"");
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_NCCALCSIZE:
        {
            LPNCCALCSIZE_PARAMS ncParams = (LPNCCALCSIZE_PARAMS)lParam;
            ncParams->rgrc[0].top += 4;
            ncParams->rgrc[0].left += 4;
            ncParams->rgrc[0].bottom -= 4;
            ncParams->rgrc[0].right -= 4;
            return 0;
        }
        case WM_NCPAINT:
        {
            RECT rect;
            GetWindowRect(hWnd, &rect);
            HRGN region = NULL;
            if (wParam == NULLREGION) {
                region = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
            }
            else {
                HRGN copy = CreateRectRgn(0, 0, 0, 0);
                if (CombineRgn(copy, (HRGN)wParam, NULL, RGN_COPY)) {
                    region = copy;
                }
                else {
                    DeleteObject(copy);
                }
            }
            HDC dc = GetDCEx(hWnd, region, DCX_WINDOW | DCX_CACHE | DCX_INTERSECTRGN | DCX_LOCKWINDOWUPDATE);
            if (!dc && region) {
                DeleteObject(region);
            }
            HPEN pen = CreatePen(PS_INSIDEFRAME, 4, RGB(255, 0, 0));
            HGDIOBJ old = SelectObject(dc, pen);
            int width = rect.right - rect.left;
            int height = rect.bottom - rect.top;
            Rectangle(dc, 0, 0, width, height);
            SelectObject(dc, old);
            ReleaseDC(hWnd, dc);
            DeleteObject(pen);
            return 0;
        }
        case WM_NCACTIVATE:
            RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW);
            return 0;
            break;
        }
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

     或者将WM_NCPAINT内的内容替换成下面的代码,效果一样

    #ifndef DCX_USESTYLE
    #define DCX_USESTYLE 0x00010000
    #endif
    
    case WM_NCPAINT:
        {
            HDC hdc = ::GetDCEx(hWnd, 0, DCX_WINDOW | DCX_USESTYLE);
            if (hdc) {
                RECT rcclient;
                ::GetClientRect(hWnd, &rcclient);
                RECT rcwin;
                ::GetWindowRect(hWnd, &rcwin);
                POINT ptupleft;
                ptupleft.x = rcwin.left;
                ptupleft.y = rcwin.top;
                ::MapWindowPoints(0, hWnd, (LPPOINT)&rcwin, (sizeof(RECT) / sizeof(POINT)));
                ::OffsetRect(&rcclient, -rcwin.left, -rcwin.top);
                ::OffsetRect(&rcwin, -rcwin.left, -rcwin.top);
    
                HRGN rgntemp = NULL;
                if (wParam == NULLREGION || wParam == ERROR) {
                    ::ExcludeClipRect(hdc, rcclient.left, rcclient.top, rcclient.right, rcclient.bottom);
                }
                else {
                    rgntemp = ::CreateRectRgn(rcclient.left + ptupleft.x, rcclient.top + ptupleft.y, rcclient.right + ptupleft.x, rcclient.bottom + ptupleft.y);
                    if (::CombineRgn(rgntemp, (HRGN)wParam, rgntemp, RGN_DIFF) == NULLREGION) {
                        // nothing to paint
                    }
                    ::OffsetRgn(rgntemp, -ptupleft.x, -ptupleft.y);
                    ::ExtSelectClipRgn(hdc, rgntemp, RGN_AND);
                }
    
                HBRUSH hbrush = ::CreateSolidBrush(RGB(255, 0, 0));
                ::FillRect(hdc, &rcwin, hbrush);
                ::DeleteObject(hbrush);
    
                ::ReleaseDC(hWnd, hdc);
                if (rgntemp != 0) {
                    ::DeleteObject(rgntemp);
                }
            }
            return 0;
        }
  • 相关阅读:
    C#日期加减
    c#的预编译指令
    IHttpModule与IHttpHandler的区别整理
    ASP.NET提供程序
    在所有页面共享通用行为
    5.Oracle中的数据表
    asp.net跳转页面的三种方法比较(转)
    C#实现经典排序算法
    ASP.NET用户登录模块代码
    http错误锦集
  • 原文地址:https://www.cnblogs.com/strive-sun/p/12923397.html
Copyright © 2011-2022 走看看