windows API 的 C++封装

// windows API 的 C++封装
//
// WndProc 是静态函数,可以被子类隐藏。
// 调用取决于创建窗口的注册结构。CXMDIView 进行了重定义隐藏。
// CXMDIFrame 使用CWnd的create创建窗口,因此无需定义WndProc函数,但是消息处理虚函数是需要的,
// 因为默认消息处理函数是不同的。
//
// 在WndProc中处理消息映射表,有三种,DefWindowProc; DefFrameProc;DefMDIChildProc;
//
// create 是虚函数,无论对象指针类是谁,创建的窗口是子类。
//
// 消息映射链表中的消息响应函数:基类函数,子类同名函数,虚函数等。
// 对这些函数的查询从子类向基类方向遍历,查到了就执行并返回。
// 实际上子类消息响应同名函数,要执行就必须加进消息映射表,否则消息向基类查询,执行基类的函数,
// 如果消息响应函数是虚函数,在子类中即使不加到消息映射表也是执行子类函数。
//
// this指针是窗口创建时传入的,CXWnd 和 CXMDIView 的传入方式有一点区别。
// 需要this调用成员函数。this是指向子类的基类指针,消息处理函数是虚函数。调用的函数取决于消息映射表。
//
// 宏在使用上比较方便,但是调试非常麻烦,最好把代码展开来调试。
//


程序运行的效果如下图:

 

 主要的封装代码:

CXWnd 为窗口基类,派生出框架窗口,子窗口,主要功能是创建窗口,消息响应函数

XWnd.h

//    windows API 的 C++封装 
//
//    WndProc 是静态函数,可以被子类隐藏。
//       调用取决于创建窗口的注册结构。CXMDIView 进行了重定义隐藏。
//       CXMDIFrame 使用CWnd的create创建窗口,因此无需定义WndProc函数,但是消息处理虚函数是需要的,
//       因为默认消息处理函数是不同的。
//
//    在WndProc中处理消息映射表,有三种,DefWindowProc; DefFrameProc;DefMDIChildProc; 
//
//    create 是虚函数,无论对象指针类是谁,创建的窗口是子类。
//
//    消息映射链表中的消息响应函数:基类函数,子类同名函数,虚函数等。
//    对这些函数的查询从子类向基类方向遍历,查到了就执行并返回。
//    实际上子类消息响应同名函数,要执行就必须加进消息映射表,否则消息向基类查询,执行基类的函数,
//    如果消息响应函数是虚函数,在子类中即使不加到消息映射表也是执行子类函数。
//    
//    this指针是窗口创建时传入的,CXWnd 和 CXMDIView 的传入方式有一点区别。  
//    需要this调用成员函数。this是指向子类的基类指针,消息处理函数是虚函数。调用的函数取决于消息映射表。
//    
//     宏在使用上比较方便,但是调试非常麻烦,最好把代码展开来调试。
//
//

#pragma once
#include "xobj.h"
#include "resource.h"

extern int XSprintfMsg(char *fmt, ...);

class CXWnd; 

typedef int (CXWnd::*X_PMSG)(HWND, UINT, WPARAM, LPARAM);

#define  dim(x)  (sizeof(x)/sizeof(x[0]))

enum XSig
{
    XSig_end = 0,     // [marks end of message map]
    XSig_lwl,     // LRESULT (WPARAM, LPARAM)
    XSig_vv,      // void (void)
};

struct X_MSGMAP_ENTRY
{
    UINT nMessage;   // windows message
    UINT nCode;      // control code or WM_NOTIFY code
    UINT nID;        // control ID (or 0 for windows messages)
    UINT nLastID;    // used for entries specifying a range of control id's
    UINT nSig;       // signature type (action) or pointer to message #
    X_PMSG pfn;    // routine to call (or special value)
};

// the struct quote itself
struct X_MSGMAP{
    X_MSGMAP* pBaseMsgMap;
    X_MSGMAP_ENTRY* lpEntries;
};

#define XDECLARE_MESSAGE_MAP() \
    static X_MSGMAP_ENTRY _xmessageEntries[]; \
    static X_MSGMAP xmessageMap; \
    virtual X_MSGMAP* XGetMessageMap() const;

#define XBEGIN_MESSAGE_MAP(theClass, baseClass) \
    X_MSGMAP* theClass::XGetMessageMap() const \
{ return &theClass::xmessageMap; } \
    X_MSGMAP theClass::xmessageMap = \
{ &(baseClass::xmessageMap), \
    (X_MSGMAP_ENTRY*) &(theClass::_xmessageEntries) }; \
    X_MSGMAP_ENTRY theClass::_xmessageEntries[]= \
{

#define XON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, XSig_lwl, (X_PMSG)&memberFxn },

#define XON_COMMAND(id, memberFxn) \
{ WM_COMMAND, 0, (WORD)id, (WORD)id, XSig_vv, (X_PMSG)&memberFxn },

#define XEND_MESSAGE_MAP() \
{0, 0,0,0, XSig_end, (X_PMSG) 0 } \
};


class CXWnd :
    public CXObj
{
public:
    CXWnd(void);
    ~CXWnd(void);

    XDECLARE_DYNCREATE(CXWnd)

    TCHAR szWindowClass[256];                        // The title bar text
    TCHAR szTitle[256];                            // The title bar text

    HINSTANCE m_hInst;
    HINSTANCE m_hPrevInstance;
    HWND m_hWnd;
    //    HWND m_hWndClient;
    HMENU m_hMenu, m_hMenuWindow;

    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    virtual BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
        LPCTSTR lpszWindowName, DWORD dwStyle,
        int x, int y, int nWidth, int nHeight,
        HWND hWndParent, HMENU nIDorHMenu, HINSTANCE hInstance, LPVOID lpParam);
    
    virtual BOOL PreCreateWindow(WNDCLASSEX &cs); 
    virtual LRESULT Create(HINSTANCE hInstance, HINSTANCE Phinstance, LPTSTR lpstr, int nCmdShow); //frame
    virtual LRESULT Create(HINSTANCE hInstance, HWND hParent, int nCmdShow);  // plane
    virtual LRESULT Create(HINSTANCE hInstance, HWND hParent);  //child 

    static LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

    //======WM================ 
    virtual int HandleMessage(HWND, UINT, WPARAM, LPARAM);
    virtual int OnCommand(HWND, UINT, WPARAM, LPARAM);
    virtual int OnNotify(HWND, UINT, WPARAM, LPARAM);

    int OnDestroy(HWND, UINT, WPARAM, LPARAM);    
    int OnSize(HWND, UINT, WPARAM, LPARAM);

    virtual int OnHookMessage(HWND, UINT, WPARAM, LPARAM);

    XDECLARE_MESSAGE_MAP()
};

XWnd.cpp

#include "StdAfx.h"
#include "XWnd.h"

X_MSGMAP* CXWnd::XGetMessageMap() const 
{
    return &CXWnd::xmessageMap; 
}

X_MSGMAP CXWnd::xmessageMap = 
{ 
    NULL, 
    (X_MSGMAP_ENTRY*) &(CXWnd::_xmessageEntries) 
}; 

X_MSGMAP_ENTRY CXWnd::_xmessageEntries[]= 
{

    //    { message, 0, 0, 0, XSig_lwl, (X_PMSG)&memberFxn },
    XON_MESSAGE(WM_SIZE, OnSize) 
    XON_MESSAGE(WM_DESTROY, OnDestroy)

XEND_MESSAGE_MAP()

CXWnd::CXWnd(void)
{
    m_hMenu = NULL;
    m_hMenuWindow = NULL;
}

CXWnd::~CXWnd(void)
{

}

XIMPLEMENT_DYNCREATE(CXWnd, CXObj)

BOOL CXWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
    LPCTSTR lpszWindowName, DWORD dwStyle,
    int x, int y, int nWidth, int nHeight,
    HWND hWndParent, HMENU nIDorHMenu, HINSTANCE hInstance, LPVOID lpParam)
{
    // allow modification of several common create parameters
    CREATESTRUCT cs;
    cs.dwExStyle = dwExStyle;
    cs.lpszClass = lpszClassName;
    cs.lpszName = lpszWindowName;
    cs.style = dwStyle;
    cs.x = x;
    cs.y = y;
    cs.cx = nWidth;
    cs.cy = nHeight;
    cs.hwndParent = hWndParent;
    cs.hMenu = nIDorHMenu;
    cs.hInstance = hInstance; //xgz
    cs.lpCreateParams = lpParam;

    if (!PreCreateWindow(cs))
    {
        return FALSE;
    }

    HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
            cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
            cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);

    if (hWnd == NULL)
        return FALSE;

    m_hWnd = hWnd; //xgz

    return TRUE;
}

// for child windows
BOOL CXWnd::PreCreateWindow(CREATESTRUCT& cs)
{
    if (cs.lpszClass == NULL)
    {
        // make sure the default window class is registered
        cs.lpszClass = _T("X_defaultWnd");
    }
    return TRUE;
}

BOOL CXWnd::PreCreateWindow(WNDCLASSEX& wcex)
{
    return TRUE;
}

LRESULT CXWnd::Create(HINSTANCE hInstance, HINSTANCE Phinstance, LPTSTR lpstr, int nCmdShow) 
{
    WNDCLASSEX wcex;

    m_hInst = hInstance;

    wcex.cbSize = sizeof(WNDCLASSEX); 

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)(CXWnd::WndProc);
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, (LPCTSTR)IDI_XT);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    //wcex.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE+1);
    wcex.lpszMenuName    = NULL; 
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    PreCreateWindow(wcex);  

    RegisterClassEx(&wcex);

    m_hWnd = CreateWindow(szWindowClass, szTitle, 
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 
        NULL, m_hMenu, hInstance, 
        this);
    
    if (!m_hWnd)
    {
        return FALSE;
    }

    ShowWindow(m_hWnd, nCmdShow);
    UpdateWindow(m_hWnd);

    return 0;
}

LRESULT CXWnd::Create(HINSTANCE hInstance, HWND hParent) 
{
    WNDCLASSEX wcex;

    m_hInst = hInstance;

    wcex.cbSize = sizeof(WNDCLASSEX); 

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)(CXWnd::WndProc);
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, (LPCTSTR)IDI_XT);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
//    wcex.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE+1);
    wcex.lpszMenuName    = NULL; 
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    PreCreateWindow(wcex);

    RegisterClassEx(&wcex);

     m_hWnd = CreateWindow(szWindowClass, szTitle, 
        WS_CHILD|WS_BORDER|WS_VISIBLE|WS_THICKFRAME,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 
        hParent, m_hMenu, hInstance, 
        this);
    
    if (!m_hWnd)
    {
        return FALSE;
    }
  
    return 0;
}

LRESULT CXWnd::Create(HINSTANCE hInstance, HWND hParent, int nCmdShow) 
{
    WNDCLASSEX wcex;

    m_hInst = hInstance;

    wcex.cbSize = sizeof(WNDCLASSEX); 

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)(CXWnd::WndProc);
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, (LPCTSTR)IDI_XT);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
//    wcex.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE+1);
    wcex.lpszMenuName    = NULL; 
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    PreCreateWindow(wcex);

    RegisterClassEx(&wcex);

    m_hWnd = CreateWindow(szWindowClass, szTitle, 
        WS_CHILD|WS_BORDER|WS_VISIBLE|WS_THICKFRAME, //WS_CHILD|WS_BORDER|WS_VISIBLE|WS_THICKFRAME,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 
        hParent, m_hMenu, hInstance, 
        this);
    
    if (!m_hWnd)
    {
        return FALSE;
    }

    ::ShowWindow(m_hWnd, nCmdShow);
    ::UpdateWindow(m_hWnd);

    return 0;
}

//return ::DefWindowProc(hWnd, message, wParam, lParam);              // for normal windows
//return ::DefFrameProc(hWnd, m_hWndClient, message, wParam, lParam); // for MDIFrame
//return ::DefMDIChildProc(hWnd,  message, wParam, lParam);           // for MDIChild
LRESULT CALLBACK CXWnd::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    CXWnd* pThis = NULL;
  
    if( message == WM_NCCREATE ) {
        LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
        pThis = static_cast<CXWnd*>(lpcs->lpCreateParams);
        pThis->m_hWnd = hWnd;
        SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LPARAM>(pThis));
    } 
    else {
        pThis = reinterpret_cast<CXWnd*>(GetWindowLong(hWnd, GWL_USERDATA));
        if( message == WM_NCDESTROY && pThis != NULL ) {
          
            return 0;
        }
    }
    if( pThis != NULL ) {
        return pThis->HandleMessage(hWnd, message, wParam, lParam);
    } 
    else {
        return ::DefWindowProc(hWnd, message, wParam, lParam);
    }

   return 0;
}

int CXWnd::OnCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;
    
    X_MSGMAP* pMap = this->XGetMessageMap();
    
    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(LOWORD(wParam) == (pMap->lpEntries+i)->nID)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }
        
    return ::DefWindowProc(hWnd,  message, wParam, lParam);
}

int CXWnd::OnNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;
    
    X_MSGMAP* pMap = this->XGetMessageMap();
    
    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(LOWORD(wParam) == (pMap->lpEntries+i)->nID)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }
    return ::DefWindowProc(hWnd,  message, wParam, lParam);
}

int CXWnd::OnHookMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//    PRINT("CXWnd::OnHookProc %d, %d, %d, %d\r\n", hWnd,  message,  wParam,  lParam); 
    return 0;
}

int CXWnd::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;

    OnHookMessage( hWnd,  message,  wParam,  lParam);

    if(WM_COMMAND == message) 
        return OnCommand(hWnd,  message,  wParam,  lParam);    // command table is same as WM table

    if(WM_NOTIFY == message)
        return OnNotify(hWnd,  message,  wParam,  lParam);    // command table is same as WM table
    
    X_MSGMAP* pMap = this->XGetMessageMap();
    
    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(message == (pMap->lpEntries+i)->nMessage)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            } 
        }
    }
    return ::DefWindowProc(hWnd,  message, wParam, lParam);
}

int CXWnd::OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc(hWnd, message, wParam, lParam);
}


int CXWnd::OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//    PostQuitMessage(0);  //the default not quite.
    return 0;
}

 

CXMDIFrame 框架窗口,主要是是创建客户窗口,复写消息处理,另外还有框架的基本消息响应。

XMDIFrame.h

#pragma once
#include "xwnd.h"

#include "stdio.h"

#define IDM_FIRSTCHILD  50000     //larger than other menu id. it is child windows dynamic menu id

class CXMDIFrame :
    public CXWnd
{
public:
    CXMDIFrame(void);
    ~CXMDIFrame(void);

    XDECLARE_DYNCREATE(CXMDIFrame)

public:

    HWND        m_hWndClient;
    
    virtual BOOL  PreCreateWindow(WNDCLASSEX &wcex);
    static BOOL CALLBACK CloseEnumProc(HWND hWnd, LPARAM lParam);

    //======WM================ 
    virtual int HandleMessage(HWND, UINT, WPARAM, LPARAM);
    virtual int OnCommand(HWND, UINT, WPARAM, LPARAM);
    virtual int OnNotify(HWND, UINT, WPARAM, LPARAM);

    int OnQueryEndSession(HWND, UINT, WPARAM, LPARAM);
    int OnClose(HWND, UINT, WPARAM, LPARAM);
    int OnDestroy(HWND, UINT, WPARAM, LPARAM);

    int OnCreate(HWND, UINT, WPARAM, LPARAM);
    int OnSize(HWND, UINT, WPARAM, LPARAM);

    virtual int Init(void);

    //========command========
    int OnNew(HWND, UINT, WPARAM, LPARAM);
    
    int OnAppExit(HWND, UINT, WPARAM, LPARAM);
    int OnFileClose(HWND, UINT, WPARAM, LPARAM);

    int OnCascade(HWND, UINT, WPARAM, LPARAM);
    int OnArrange(HWND, UINT, WPARAM, LPARAM);
    int OnTile(HWND, UINT, WPARAM, LPARAM);
    int OnCloseAll(HWND, UINT, WPARAM, LPARAM);
    virtual int OnAbout(HWND, UINT, WPARAM, LPARAM);
    XDECLARE_MESSAGE_MAP()

};

XMDIFrame.cpp

#include "StdAfx.h"
#include "XMDIFrame.h"

#include "XMDIView.h"


XIMPLEMENT_DYNCREATE(CXMDIFrame, CXWnd)

XBEGIN_MESSAGE_MAP(CXMDIFrame, CXWnd)

    XON_MESSAGE(WM_CREATE, OnCreate)
    XON_MESSAGE(WM_SIZE, OnSize)
    XON_MESSAGE(WM_DESTROY, OnDestroy)
    XON_MESSAGE(WM_COMMAND, OnCommand)
    XON_MESSAGE(WM_QUERYENDSESSION, OnQueryEndSession)
    XON_MESSAGE(WM_CLOSE, OnClose)

    XON_COMMAND(IDM_ABOUT,  OnAbout)
    XON_COMMAND(IDM_FILE_NEWHELLO,  OnNew)
    XON_COMMAND(IDM_FILE_CLOSE,  OnFileClose)
    XON_COMMAND(IDM_WINDOW_CASCADE,  OnCascade)
    XON_COMMAND(IDM_WINDOW_ARRANGE,  OnArrange)
    XON_COMMAND(IDM_WINDOW_TILE,  OnTile)
    XON_COMMAND(IDM_WINDOW_CLOSEALL,  OnCloseAll)
    XON_COMMAND(IDM_APP_EXIT,  OnAppExit)

XEND_MESSAGE_MAP()

CXMDIFrame::CXMDIFrame(void)
{
    wcscpy_s(szWindowClass,_T("MT_FrameWnd"));                                // The title bar text
    wcscpy_s(szTitle,_T("XT"));                                // The title bar text
    m_hWnd = NULL;
    m_hWndClient = NULL;   //xgz  important for msg loop

}

CXMDIFrame::~CXMDIFrame(void)
{

}

BOOL CXMDIFrame::PreCreateWindow(WNDCLASSEX &wcex) //cs
{
    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)(CXWnd::WndProc);
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = m_hInst;
    wcex.hIcon            = LoadIcon(m_hInst, (LPCTSTR)IDI_XT);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    //wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE+1);
    wcex.lpszMenuName    = NULL; 
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    return TRUE;
}

int CXMDIFrame::OnCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;

    PRINT(_T("CXFrame::OnCommand %d, %d, %d, %d\r\n"), hWnd,  message,  wParam,  lParam); 
    
    X_MSGMAP* pMap = this->XGetMessageMap();
    
    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(LOWORD(wParam) == (pMap->lpEntries+i)->nID)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }
    
    HWND hwndChild = (HWND) SendMessage(m_hWndClient, WM_MDIGETACTIVE,0,0);
    
    if(IsWindow(hwndChild))
        SendMessage(hwndChild, WM_COMMAND, wParam, lParam);  // some menu ID is for child window.
    
    return ::DefFrameProc(hWnd, m_hWndClient, message, wParam, lParam);
}

int CXMDIFrame::OnNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;
    
    X_MSGMAP* pMap = this->XGetMessageMap();
    
    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(LOWORD(wParam) == (pMap->lpEntries+i)->nID)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }

    return ::DefFrameProc(hWnd, m_hWndClient, message, wParam, lParam);
}


int CXMDIFrame::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    int i;

    if(WM_COMMAND == message) 
        return OnCommand(hWnd,  message,  wParam,  lParam);    // command table is same as WM table

    if(WM_NOTIFY == message)
        return OnNotify(hWnd,  message,  wParam,  lParam);    // command table is same as WM table
    
    X_MSGMAP* pMap = this->XGetMessageMap();
    
    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(message == (pMap->lpEntries+i)->nMessage)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }
    
    return ::DefFrameProc(hWnd, m_hWndClient, message, wParam, lParam);
}
 

int CXMDIFrame::OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    CLIENTCREATESTRUCT    clientcreate;

    clientcreate.hWindowMenu = m_hMenuWindow;
    clientcreate.idFirstChild = IDM_FIRSTCHILD;

    m_hWndClient = CreateWindow(TEXT("MDICLIENT"), NULL,
        WS_CHILD|WS_CLIPCHILDREN |WS_VISIBLE,
        0,0,0,0,
        m_hWnd, (HMENU) 1, m_hInst, 
        (PSTR) &clientcreate);
        
    Init();
    return 0;
}

int CXMDIFrame::OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefFrameProc(hWnd, m_hWndClient, message, wParam, lParam);
}

int CXMDIFrame::OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PostQuitMessage(0);  //frame 退出则程序退出
    return 0;
}

int CXMDIFrame::OnNew(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    CXMDIView* WndView = new CXMDIView();
    if (WndView == NULL)return 0;
    
    WndView->Create(m_hInst, m_hWndClient);
    
    return 0;
}

int CXMDIFrame::OnFileClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

     HWND hwndChild =(HWND) SendMessage(m_hWndClient, WM_MDIGETACTIVE, 0,0);  //SendMessage is call proc

    if(SendMessage(hwndChild, WM_QUERYENDSESSION,0,0)) // The command did not come from the target app, so need confirm
       SendMessage(m_hWndClient,WM_MDIDESTROY, (WPARAM) hwndChild,0);

    return 0;
}

int CXMDIFrame::OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    SendMessage(hWnd, WM_COMMAND, IDM_WINDOW_CLOSEALL,0);
    if(NULL != GetWindow(m_hWndClient,GW_CHILD))
        return 0;
        
    return DefFrameProc(hWnd, m_hWndClient, message, wParam, lParam);;
}

int CXMDIFrame::OnQueryEndSession(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        
    return OnClose(hWnd, message, wParam, lParam);;
}

BOOL CALLBACK CXMDIFrame::CloseEnumProc(HWND hWnd, LPARAM lParam)
{
    if(GetWindow(hWnd,GW_OWNER))   // it is not for minimized win. never return. mybe for ctrl wnd. eg, Edit,Button.  
        return TRUE;
    SendMessage(GetParent(hWnd), WM_MDIRESTORE, (WPARAM)hWnd, 0);
    if(!SendMessage(hWnd, WM_QUERYENDSESSION,0,0))   // this child can not close, will block here until ready close, Sendmessage return == case return from child wnd
        return TRUE;
    SendMessage(GetParent(hWnd), WM_MDIDESTROY, (WPARAM)hWnd, 0);
    return TRUE;
}

int CXMDIFrame::OnCloseAll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    EnumChildWindows(m_hWndClient, CloseEnumProc, 0);  // return after enumerated or  func return false
    return 0;
}


int CXMDIFrame::OnAppExit(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    SendMessage(hWnd, WM_CLOSE, 0,0);

    return 0;
}

int CXMDIFrame::OnCascade(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    SendMessage(m_hWndClient, WM_MDICASCADE,0,0);
    return 0;
}
                
int CXMDIFrame::OnArrange(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    SendMessage(m_hWndClient, WM_MDIICONARRANGE,0,0);
                    //ArrangeIconicWindows(hwndClient);
    return 0;
}
int CXMDIFrame::OnTile(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    SendMessage(m_hWndClient, WM_MDITILE,0,0);
    return 0;
}

int CXMDIFrame::Init(void)
{
    return 0;
}

int CXMDIFrame::OnAbout(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    MessageBox(hWnd, _T("Frame"),_T("About"),MB_OK);

    return 0;
}
//===============================================


CXMDIView 为子窗口

XMDIView.h

#pragma once
#include "xwnd.h"

#include "stdio.h"

class CXMDIView :
    public CXWnd
{
public:
    CXMDIView(void);
    ~CXMDIView(void);

    XDECLARE_DYNCREATE(CXMDIView)

public:

    virtual LRESULT Create(HINSTANCE hInstance, HWND hWndParent); 

    HMENU        m_hMenuMDIInit, m_hMenuMDIInitWindow;  // When View closed

    HWND        m_hWndClient, m_hWndFrame; 

    virtual BOOL PreCreateWindow(WNDCLASSEX &cs);
    virtual BOOL PreCreateWindow(MDICREATESTRUCT &mdicreate); 

    static LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

    virtual int HandleMessage(HWND, UINT, WPARAM, LPARAM);
    virtual int OnCommand(HWND, UINT, WPARAM, LPARAM);
    virtual int OnNotify(HWND, UINT, WPARAM, LPARAM);

    int OnCreate(HWND, UINT, WPARAM, LPARAM);
    int OnPaint(HWND, UINT, WPARAM, LPARAM);
    int OnSize(HWND, UINT, WPARAM, LPARAM);
    int OnChar(HWND, UINT, WPARAM, LPARAM);
    int OnClose(HWND, UINT, WPARAM, LPARAM);
    int OnDestroy(HWND, UINT, WPARAM, LPARAM);
    int OnMdiActive(HWND, UINT, WPARAM, LPARAM);
    int OnExit(HWND, UINT, WPARAM, LPARAM);

        
    XDECLARE_MESSAGE_MAP()
};

XMDIView.cpp

#include "StdAfx.h"
#include "XMDIView.h"

XIMPLEMENT_DYNCREATE(CXMDIView, CXWnd)

    XBEGIN_MESSAGE_MAP(CXMDIView, CXWnd)

    XON_MESSAGE(WM_CREATE, OnCreate)
    XON_MESSAGE(WM_SIZE, OnSize)
    XON_MESSAGE(WM_DESTROY, OnDestroy)
    XON_MESSAGE(WM_COMMAND, OnCommand)
    XON_MESSAGE(WM_PAINT, OnPaint)
    XON_MESSAGE(WM_CHAR, OnChar)
    XON_MESSAGE(WM_CLOSE, OnClose)
    XON_MESSAGE(WM_MDIACTIVATE, OnMdiActive)

XEND_MESSAGE_MAP()

CXMDIView::CXMDIView(void)
{
    wcscpy_s(szWindowClass,_T("XMDIView"));                                // The title bar text
    wcscpy_s(szTitle,_T("XMDIView"));
    m_hWnd = NULL;
}

CXMDIView::~CXMDIView(void)
{

}
BOOL CXMDIView::PreCreateWindow(WNDCLASSEX &cs) 
{
    return TRUE;
}

BOOL CXMDIView::PreCreateWindow(MDICREATESTRUCT &mdicreate) 
{
    return TRUE;
}

LRESULT CXMDIView::Create(HINSTANCE hInstance, HWND hWndParent) 
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX); 
    
    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc        = (WNDPROC)(CXMDIView::WndProc); //(WNDPROC)(CXWnd::WndProc);//
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = sizeof(HANDLE);  //XGZ????
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, (LPCTSTR)IDI_XT);
    wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    //wcex.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE+1);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    RegisterClassEx(&wcex);

    MDICREATESTRUCT        mdicreate;

    mdicreate.szClass    = szWindowClass;
    mdicreate.szTitle    = szTitle;
    mdicreate.hOwner        = hInstance;
    mdicreate.x            = CW_USEDEFAULT;
    mdicreate.y            = CW_USEDEFAULT;
    mdicreate.cx            = CW_USEDEFAULT;
    mdicreate.cy            = CW_USEDEFAULT;
    
    mdicreate.style        = 0;
    mdicreate.lParam        = (LPARAM)this;  // xgz

    m_hInst = hInstance;
    m_hWndClient = hWndParent;
    m_hWndFrame = GetParent(m_hWndClient); 
    
    PreCreateWindow(mdicreate);

    m_hWnd = (HWND) SendMessage(m_hWndClient,
        WM_MDICREATE,0,
        (LPARAM)(LPMDICREATESTRUCT) &mdicreate);

    return 0;
}

LRESULT CALLBACK CXMDIView::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    CXMDIView* pThis = NULL;

    if( message == WM_NCCREATE ) {
        LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
        LPMDICREATESTRUCT lpms = reinterpret_cast<LPMDICREATESTRUCT>(lpcs->lpCreateParams);
        //pThis = static_cast<CXMDIView*>(lpcs->lpCreateParams);
        pThis = reinterpret_cast<CXMDIView*>(lpms->lParam);
        pThis->m_hWnd = hWnd;
        SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LPARAM>(pThis));
    } 
    else {
        pThis = reinterpret_cast<CXMDIView*>(GetWindowLong(hWnd, GWL_USERDATA));
        if( message == WM_NCDESTROY && pThis != NULL ) {

            return 0;
        }
    }
    if( pThis != NULL ) {
        return pThis->HandleMessage(hWnd, message, wParam, lParam);
    } 
    else
    {
        //return ::DefWindowProc(hWnd, message, wParam, lParam);
        return ::DefMDIChildProc(hWnd,  message, wParam, lParam);
    }

    return 0;
}

int CXMDIView::OnCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;

    //    PRINT("CXMDIView::OnCommand %d, %d, %d, %d\r\n", hWnd,  message,  wParam,  lParam); 

    X_MSGMAP* pMap = this->XGetMessageMap();

    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(LOWORD(wParam) == (pMap->lpEntries+i)->nID)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }

    return ::DefMDIChildProc(hWnd,  message, wParam, lParam);
}


int CXMDIView::OnNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;

    //    PRINT("CXMDIView::OnNotify %d, %d, %d, %d\r\n", hWnd,  message,  wParam,  lParam); 

    X_MSGMAP* pMap = this->XGetMessageMap();

    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            //    if(LOWORD(wParam) == (pMap->lpEntries+i)->nID)
            if(message == (pMap->lpEntries+i)->nMessage)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }

    return ::DefMDIChildProc(hWnd,  message, wParam, lParam);
}

int CXMDIView::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;

    OnHookMessage( hWnd,  message,  wParam,  lParam);
    //    PRINT("CXMDIView::HandleMessage %d, %d, %d, %d\r\n", hWnd,  message,  wParam,  lParam); 

    if(WM_COMMAND == message) 
        return OnCommand(hWnd,  message,  wParam,  lParam);    // command table is same as WM table

    if(WM_NOTIFY == message) 
        return OnNotify(hWnd,  message,  wParam,  lParam);    // command table is same as WM table

    X_MSGMAP* pMap = this->XGetMessageMap();

    for(; pMap != NULL; pMap = pMap->pBaseMsgMap)
    {
        for(i=0; (pMap->lpEntries+i)->nSig != XSig_end; i++)
        {
            if(message == (pMap->lpEntries+i)->nMessage)
            {
                return (this->*((pMap->lpEntries+i)->pfn))( hWnd,  message,  wParam,  lParam);
            }
        }
    }
    //return ::DefWindowProc(hWnd, message, wParam, lParam);
    //return ::DefFrameProc(hWnd, m_hwndClient, message, wParam, lParam);
    return ::DefMDIChildProc(hWnd,  message, wParam, lParam);
}

int CXMDIView::OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return 0;
}

int CXMDIView::OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    HDC hdc;
    PAINTSTRUCT ps;

    hdc = BeginPaint(hWnd, &ps);
    // TODO: Add any drawing code here...
    RECT rt;
    GetClientRect(hWnd, &rt);
    DrawText(hdc, _T("CXMDIView"), wcslen(_T("CXMDIView")), &rt, DT_CENTER);
    EndPaint(hWnd, &ps);

    return 0;
}

int CXMDIView::OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefMDIChildProc(hWnd, message, wParam, lParam);
}

int CXMDIView::OnChar(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefMDIChildProc(hWnd, message, wParam, lParam);
}

int CXMDIView::OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    m_hWnd = NULL;
    //    PostQuitMessage(0);
    return 0;
}

int CXMDIView::OnExit(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    DestroyWindow(hWnd);
    return 0;
}

int CXMDIView::OnMdiActive(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    //wParam is deactivated Handle,    lParam is activated Handle
        
    //PRINT(_("\r\nCXMDIView::OnActive"));

    if(lParam == (LPARAM) hWnd)                     //active
    {
        SendMessage(m_hWndClient, WM_MDISETMENU,    (WPARAM)m_hMenu, (LPARAM) m_hMenuWindow);
    }
    else
    {
        SendMessage(m_hWndClient, WM_MDISETMENU, (WPARAM) m_hMenuMDIInit, (LPARAM)m_hMenuMDIInitWindow);
    }
    DrawMenuBar(m_hWndFrame);

    return 0;
}

int CXMDIView::OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefMDIChildProc(hWnd, message, wParam, lParam);
}

 

posted @ 2022-04-30 13:29  XGZ21  阅读(533)  评论(0编辑  收藏  举报