• windows窗口子类化图解


    windows中的static控件的背景色不好改变,因为一般的做法是依赖他的父窗口来给他传入背景画刷才能实现,也就是说需要依赖父窗口。这种方式在duilib中会导致主窗口逻辑会混入子窗口的逻辑,控件也不能复用。

    windows提供了一种机制,子类化窗口。可以实现对窗口的功能进行扩展。

    参考资料:https://docs.microsoft.com/en-us/windows/win32/controls/subclassing-overview

    总结来说子类化窗口是对窗口消息的重定向。

    先来看下正常的窗口消息的处理过程。

    消息循环把消息队列中的消息取出来后,派发到不同的窗口,各个窗口都有自己的窗口过程,用来处理派发过来的消息。

    如果我们需要定制我们特有的功能,就需要能自己处理这些消息,完成定制的逻辑。这个就可以通过子类化窗口来实现。

    下面来看下子类化窗口之后的窗口消息处理过程。

     

     

    消息循环把窗口B的消息派发给窗口B后,消息并没有直接交给窗口B的窗口过程,而是交给了我们自定义的窗口过程,在这里,我们可以做我们想做的事情,来实现定制的功能。

    然后根据需要是再次调用原来的窗口过程(Case 1),还是认为消息已经处理完毕了(Case 2)。

     

     

    子类化窗口API

    目前有两种方式来实现:

    使用SetWindowLong设置新的窗口过程。

    使用SetWindowSubclass来设置子类化窗口过程。

     

     
    (1)使用SetWindowLong设置新的窗口过程
    1. 创建窗口CreateWindowExW

    2. 通过SetWindowLong设置新的窗口过程

    3. 在窗口过程中处理自己感兴趣的消息

     

        WNDPROC OldProc = NULL;

        HWND hwnd = ::CreateWindowExW(dwStyleEx, L"Static", NULL, dwStyle, left, top, width, height,

            hParentWnd, NULL, hInstance, NULL);

        OldProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)StaticControlProc);

     

        LRESULT CALLBACK StaticControlProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

        {

            if (msg == WM_PAINT)

            {

                PAINTSTRUCT ps = { 0 };

                HDC hdc = BeginPaint(hWnd, &ps);


                RECT rect;

                ::GetClientRect(hWnd, &rect);

                DWORD dwColor = RGB(255, 0, 0);

                HBRUSH hBrush = ::CreateSolidBrush(dwColor);

                HPEN hPen = ::CreatePen(PS_SOLID, 1, dwColor);

                HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hBrush);

                HPEN hOldPen = (HPEN)::SelectObject(hdc, hPen);


                ::Rectangle(hdc, 0, 0, rect.right, rect.bottom);


                ::SelectObject(hdc, hOldBrush);

                ::SelectObject(hdc, hOldPen);

                ::DeleteObject(hBrush);

                ::DeleteObject(hPen);


                EndPaint(hWnd, &ps);

                return 0;

            }

            else

            {

                return ::CallWindowProc(OldProc, hWnd, msg, wParam, lParam);

            }

        }


     
    (2)使用SetWindowSubclass来设置子类化窗口过程


    1. 创建窗口CreateWindowExW

    2. 通过SetWindowSubclass设置新的窗口过程

    3. 在窗口过程中处理自己感兴趣的消息

     

        HWND hwnd = ::CreateWindowExW(dwStyleEx, L"Static", NULL, dwStyle, left, top, width, height,

            hParentWnd, NULL, hInstance, NULL);

    SetWindowSubclass(hwnd, StaticControlProc, 0, 0);

    LRESULT CALLBACK StaticControlProc(HWND hWnd, UINT uMsg, WPARAM wParam,

    LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)

    {

    if (uMsg == WM_PAINT)

    {

                        // ...

    return 0;

    }

    else

    {

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);

    }

    }

    参考资料:

    https://www.cnblogs.com/kekec/p/3210696.html

    https://blog.csdn.net/bjbz_cxy/article/details/80762692

  • 相关阅读:
    [SAP ABAP开发技术总结]OLE
    [SAP ABAP开发技术总结]ABAP读写、解析XML文件
    [SAP ABAP开发技术总结]FTP到文件服务器,服务器上文件读写
    [SAP ABAP开发技术总结]Function远程、同步、异步调用
    [SAP ABAP开发技术总结]采购、销售、生产简单业务流程
    [SAP ABAP开发技术总结]IDoc
    [SAP ABAP开发技术总结]BAPI调用
    [SAP ABAP开发技术总结]业务对象和BAPI
    [SAP ABAP开发技术总结]增强Enhancement
    [SAP ABAP开发技术总结]SD销售订单定价过程
  • 原文地址:https://www.cnblogs.com/1yzq/p/12939791.html
Copyright © 2020-2023  润新知