commoncontrol.hpp

来自「一个WinCE6。0下的IP phone的源代码」· HPP 代码 · 共 296 行

HPP
296
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#pragma once

#ifndef __COMMONCONTROL_HPP__
#define __COMMONCONTROL_HPP__

#include <windows.h>

template <class Impl, class T>
class CommonControlImpl_t :
    public T
{
    //To use this control template you must define the following (or generate a compiler error)

    //  SuperWindowClassName() - static const WCHAR* - Used to determine if the class we are subclassing (if any)
    //  use the macro's at the end of the file to help with this

    //  ControlWindowProc: Personal WndProc.
    //  Returns lresult to be returned to message-passer unless the Handled value is set to false
    //  LRESULT ControlWindowProc(
    //      UINT Message,       //WndProc message
    //      WPARAM wParam,      //Standard WPARAM
    //      LPARAM lParam,      //Standard LPARAM
    //      bool& Handled       //Was this message handled? If not, DefWndProc will be
    //                          //called and the return value from this function ignored.
    //      );

public:
    CommonControlImpl_t()
    {
        m_DefaultWindowProc = ::DefWindowProc;
    }

    static
    const UINT
    GetWindowClassStyle(
        void
        )
    {
        return 0;
    }

    //register the wnd class of this control
    static
    bool
    Register(
        void
        )
    {
        WNDCLASS WindowClass = {0};

        WindowClass.hInstance = GlobalData_t::s_ModuleInstance;
        WindowClass.lpszClassName = T::GetWindowClassName();
        WindowClass.lpfnWndProc = s_WindowProc;
        WindowClass.style = Impl::GetWindowClassStyle();

        //add extra room for our 'this' pointer
        WindowClass.cbWndExtra = sizeof(CommonControlImpl_t<Impl, T> *);

        if ((RegisterClass(&WindowClass) == 0) &&
            (GetLastError() != ERROR_CLASS_ALREADY_EXISTS))
        {
            return false;
        }

        return true;
    }

    //public wnd proc for this class
    static
    LRESULT
    WINAPI
    s_WindowProc(
        HWND hwnd,
        UINT Message,
        WPARAM wParam,
        LPARAM lParam
        )
    {
        Impl* pThis = NULL;
        LRESULT ReturnValue = 0;

        if (Message == WM_CREATE)
        {
            pThis = new Impl();
            if (! pThis)
            {
                return (LRESULT)-1;
            }

            //reset the last error to detect whether SetWindowLong succeeds or fails
            SetLastError(0);

            if ((SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<LONG>(pThis)) == 0) &&
                (GetLastError() != 0))
            {
                //failure! - delete the object if necessary
                delete pThis;
                return (LRESULT)-1;
            }

            //set the hwnd parameter of this window
            pThis->m_hwnd = hwnd;

            //setup the defwindowproc if we are subclassing another window
            if (Impl::SuperWindowClassName())
            {
                WNDCLASS SuperClass = {0};
                bool FailedToCreateSuperClass = true;

                if (GetClassInfo(NULL, Impl::SuperWindowClassName(), &SuperClass) &&
                    SuperClass.lpfnWndProc)
                {
                    pThis->m_DefaultWindowProc = SuperClass.lpfnWndProc;

                    //create messages MUST reach the superclass first!
                    if (-1 != CallWindowProc(pThis->m_DefaultWindowProc, hwnd, Message, wParam, lParam))
                    {
                        FailedToCreateSuperClass = false;
                    }
                }

                if (FailedToCreateSuperClass)
                {
                    //failure! - cannot use superclass
                    ReturnValue = (LRESULT)-1;
                    goto DeleteThisObject;
                }
            }
        }
        else
        {
            //otherwise, get the control from the window
            pThis = reinterpret_cast<Impl*>(::GetWindowLong(hwnd, GWL_USERDATA));
        }

        bool Handled = false;

        //give the derived class a first crack at this message
        if (pThis)
        {
            ReturnValue = pThis->ControlWindowProc(Message, wParam, lParam, Handled);
            if ((Message == WM_CREATE) && Impl::SuperWindowClassName())
            {
                Handled = true;
            }
        }
        else
        {
            return ::DefWindowProc(hwnd, Message, wParam, lParam);
        }

        //if the derived class didn't handle the message or the message is DESTROY
        //then invoke the defwndproc
        if (! Handled || Message == WM_DESTROY)
        {
            //control didn't want to handle this message - use the defwindowproc
            ReturnValue = CallWindowProc(pThis->m_DefaultWindowProc, hwnd, Message, wParam, lParam);
        }

        //if the window has been destroyed, we need to delete the instance
        if (Message == WM_DESTROY)
        {
        DeleteThisObject:
            if (pThis)
            {
                delete pThis;
            }

            //clear the pointer out of the window
            SetWindowLong(hwnd, GWL_USERDATA, 0);
        }

        return ReturnValue;
    }

    LRESULT
    DefWindowProc(
        UINT Message,
        WPARAM wParam,
        LPARAM lParam
        )
    {
        ASSERT(m_DefaultWindowProc);

        return CallWindowProc(m_DefaultWindowProc, m_hwnd, Message, wParam, lParam);
    }

    bool
    ForwardEraseBackground(
        HDC hdc,
        __in_opt LRESULT* pResult = NULL
        )
    {
        HWND hwndParent;
        LRESULT Result = 0;
        bool Success = false;

        hwndParent = GetParent(m_hwnd);
        if (hwndParent != NULL)
        {
            POINT MappedOrigin = {0,0};
            POINT OldOrigin;

            // Map to parent's coordinates
            // NOTE: We should be using OffsetWindowOrgEx (not available)
            MapWindowPoints(m_hwnd, hwndParent, &MappedOrigin, 1);

            GetWindowOrgEx(hdc, &OldOrigin);
            SetWindowOrgEx(
                hdc,
                OldOrigin.x + MappedOrigin.x,
                OldOrigin.y + MappedOrigin.y,
                NULL
                );

            Result = SendMessage(hwndParent, WM_ERASEBKGND, (WPARAM) hdc, 1);

            SetWindowOrgEx(hdc, OldOrigin.x, OldOrigin.y, NULL);
            Success = true;
        }

        if (pResult)
        {
            *pResult = Result;
        }

        return Success;
    }

    bool
    ForwardMessageToParent(
        UINT Message,
        WPARAM wParam,
        LPARAM lParam,
        __in_opt LRESULT* pResult = NULL
        )
    {
        HWND hwndParent;
        LRESULT Result = 0;
        bool Success = false;

        hwndParent = GetParent(m_hwnd);
        if (hwndParent != NULL)
        {
            // Forward the message to the parent window
            Result = SendMessage(hwndParent, Message, wParam, lParam);
            Success = true;
        }

        if (pResult)
        {
            *pResult = Result;
        }

        return Success;
    }

    LRESULT
    NotifyParent(
        DWORD Code // NM_ code
        )
    {
        NMHDR Header = {0};
        Header.hwndFrom = m_hwnd;
        Header.code = Code;

        return SendMessage(
            GetParent(m_hwnd),
            WM_NOTIFY,
            GetWindowLong(m_hwnd, GWL_ID),
            reinterpret_cast<LPARAM>(&Header)
            );
    }

private:
    WNDPROC     m_DefaultWindowProc;
};

//Macros to help other classes define their superclass
#define DECLARE_NO_SUPERCLASS()  static const WCHAR*   SuperWindowClassName() { return NULL  ; }
#define DECLARE_SUPERCLASS(name) static const WCHAR*   SuperWindowClassName() { return (name); }

#endif //!defined __COMMONCONTROL_HPP__

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?