金山卫士开源软件之旅(二) 简单教程:如何创建一个基于金山卫士界面库的工程

完整解决方案代码压缩包: test_full.zip (267.59 KB)

参考:

http://bbs.code.ijinshan.com/thread-1391-1-1.html

为了让更多的朋友能够让自己的程序使用上金山卫士界面库,现将创建界面库的过程用文字说明,希望可以帮助到各位。如果觉得过程麻烦,也可以直接下载创建后的完整代码


基本要求:安装WTL下载地址http://wtl.sourceforge.net/。下载解压后,到解压目录的AppWiz子目录下运行setup80.js(对应VS2005)即可安装完毕。

       这是补充:要告诉VS2005编译器WTL下的头文件的位置。

      工具->选项->VC++目录 在包含中加入    D:\WTL80_7161_Final\include

第一步、复制卫士界面库必要的文件

在VS2005中,单击菜单“文件”->“新建”->“项目”,在新建对话框中选择项目类型为“WTL”,模版只有一个“ATL/WTL Application Wizard”,选中它并在下方的编辑框中输入项目名和项目位置,这里假设创建后的目录为H:\MyProject\test。单击“确定”,在出现的向导中选择“下一步”,选择“Dialog Based”,并单击“Finish”按钮。

下载 (98.64 KB)
2011-9-30 17:27


H:\MyProject\test\test下创建publish文件夹,然后到http://code.ijinshan.com下载金山卫士源代码,将其解压到某个目录,打开其子目录pcmanager\src\publish,将其下的bkresbkwintinyxmlwtlhelper复制到H:\MyProject\test\test\publish下。

下载 (111.41 KB)
2011-9-30 17:29


第二步、添加包含目录

VS2005“解决方案资源管理器”中,右键点击test项目(注意是项目而不是解决方案),选择属性。

下载 (25.54 KB)
2011-9-30 17:31


在出现的“test属性页”对话框中,选择左边的“配置属性”->C/C++->“常规”项,在右边的“附加包含目录”中输入publish,点击“确定”保存设置。

下载 (109.83 KB)
2011-9-30 17:38


第三步、将BkresTinyXML加入项目中

在“解决方案资源管理器”中,右键点击“Resource Files”,选择“添加”->“现有项”,定位到publish\bkres目录下,将bkres.rc添加进项目。

下载 (19.21 KB)
2011-9-30 17:39


然后再在test项目上点击右键,选择“添加” -> “新建筛选器”,创建名为 publish 的筛选器,再在 publish 下创建 TinyXML 筛选器(创建筛选器只是为了分类方便,这一步可以略过,文件添加到任何一个筛选器中)。接下来用和以上相同的添加现有项的方法将 publish\tinyxml 下的所有文件添加到 TinyXML 筛选器下。

下载 (27.18 KB)
2011-9-30 17:39


第四步、去除TinyXML预编译头设置

展开publish\TinyXML筛选器,右键点击一个cpp文件,选择属性。

下载 (21.34 KB)
2011-9-30 17:40


点击左边的“配置属性”->“ C/C++ -> “预编译头”,将右边的“创建 / 使用预编译头”选项设置为“不使用预编译头”,点击“确定”。

下载 (75.72 KB)
2011-9-30 17:40


TinyXML筛选器下所有cpp文件都执行这一步。


第五步,添加必要的代码

主要是替换默认生成的WTL基本对话框的代码,转而使用调用卫士界面库的代码,并且加入卫士界面库必需的定义XML相关文件和图片资源。此处为了方便起见,将代码打包,各位可以直接从附件中下载,将文件替换掉原先创建项目时自动生成的代码,然后将新增的bkwinres.h以及bkwinres.rc2添加到项目中即可。

这里可以看到_tMain函数中的 

CMainDlg dlgMain;
 dlgMain.DoModal();


而构建CMainDlg的方法是:

class CMainDlg  : public CBkDialogImpl
				, public CWHRoundRectFrameHelper
{
public:
	CMainDlg():CBkDialogImpl(IDR_BK_MAIN_DIALOG)
	{
	}

	BK_NOTIFY_MAP(IDC_RICHVIEW_WIN)
		BK_NOTIFY_ID_COMMAND(IDC_BTN_CLOSE, OnBtnClose)
		BK_NOTIFY_ID_COMMAND(IDC_BTN_MIN, OnMinBtnClick)
	BK_NOTIFY_MAP_END()

	BEGIN_MSG_MAP(CMainDlg)
		MSG_BK_NOTIFY(IDC_RICHVIEW_WIN)
		CHAIN_MSG_MAP(CBkDialogImpl)
		CHAIN_MSG_MAP(CWHRoundRectFrameHelper)
		MSG_WM_SYSCOMMAND(OnCommand)
		MSG_WM_INITDIALOG(OnInitDialog)
	END_MSG_MAP()

protected:
	LRESULT OnCommand(UINT wParam, CPoint point);
	BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
	void OnBtnClose();
	void OnMinBtnClick();
};


CBkDialogImpl  CWHRoundRectFrameHelper是金山开源软件中自定义的类,我们在看它们的实现.

template 
class CWHRoundRectFrameHelper
{
protected:

    SIZE m_sizeWnd;

    void OnSize(UINT nType, CSize size)
    {
        T *pT = static_cast(this);

        if (nType == SIZE_MINIMIZED)
            return;

        if (size == m_sizeWnd)
            return;

        CRect rcWindow, rcClient;
        CRgn rgnWindow, rgnMinus, rgnAdd;

        pT->GetWindowRect(rcWindow);
        pT->GetClientRect(rcClient);
        pT->ClientToScreen(rcClient);

        rcClient.OffsetRect(- rcWindow.TopLeft());

        rgnWindow.CreateRectRgn(rcClient.left, rcClient.top + 2, rcClient.right, rcClient.bottom - 2);
        rgnAdd.CreateRectRgn(rcClient.left + 2, rcClient.top, rcClient.right - 2, rcClient.top + 1);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
        rgnAdd.OffsetRgn(0, rcClient.Height() - 1);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
        rgnAdd.SetRectRgn(rcClient.left + 1, rcClient.top + 1, rcClient.right - 1, rcClient.top + 2);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
        rgnAdd.OffsetRgn(0, rcClient.Height() - 3);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
//         rgnAdd.OffsetRgn(0, rcClient.Height());
//         rgnWindow.CombineRgn(rgnAdd, RGN_OR);

//         rgnMinus.CreateRectRgn(rcClient.left, rcClient.top, rcClient.left + 2, rcClient.top + 1);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
//         rgnMinus.OffsetRgn(rcClient.Width() - 2, 0);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
//         rgnMinus.OffsetRgn(0, rcClient.Height() - 1);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
//         rgnMinus.OffsetRgn(3 - rcClient.Width(), 0);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
// 
//         rgnMinus.SetRectRgn(rcClient.left, rcClient.top, rcClient.left + 1, rcClient.top + 2);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
//         rgnMinus.OffsetRgn(rcClient.Width() - 1, 0);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
//         rgnMinus.OffsetRgn(0, rcClient.Height() - 2);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);
//         rgnMinus.OffsetRgn(1 - rcClient.Width(), 0);
//         rgnWindow.CombineRgn(rgnMinus, RGN_DIFF);

        pT->SetWindowRgn(rgnWindow);

        m_sizeWnd = size;
    }

public:

    BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0)
    {
        BOOL bHandled = TRUE;

        switch(dwMsgMapID)
        {
        case 0:
            if (uMsg == WM_SIZE)
            {
                OnSize((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
                lResult = 0;
            }
            break;
        }
        return FALSE;
    }
};


 

//
// CBkDialogImpl

template 
class ATL_NO_VTABLE CBkDialogImpl : public CWindowImpl
{
public:

    static BOOL IsWinXPAndLater()
    {
        DWORD dwVersion = GetVersion();
        DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
        DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));

        if (dwMajorVersion > 5)         // Vista and later
            return TRUE;
        else if (dwMajorVersion < 5)    // 98/NT4 and before
            return FALSE;
        else if (dwMinorVersion > 0)    // XP and 2003
            return TRUE;
        else                            // 2000
            return FALSE;
    }

    static ATL::CWndClassInfo& GetWndClassInfo()
    {
        static ATL::CWndClassInfo wc = {
                { sizeof(WNDCLASSEX), 
                CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | (IsWinXPAndLater() ? CS_DROPSHADOW : 0), 
                  StartWindowProc, 0, 0, NULL, NULL, NULL, 
                  (HBRUSH)(COLOR_WINDOW + 1), NULL, NULL, NULL },
                NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
            };
        return wc;
    }

public:
    CBkDialogImpl(UINT uResID = 0)
        : m_uResID(uResID)
        , m_bShowWindow(TRUE)
        , m_bExitModalLoop(FALSE)
    {
    }
    virtual ~CBkDialogImpl()
    {

    }

protected:
    typedef CBkDialogImpl __thisClass;

    UINT m_uResID;
    UINT m_uRetCode;

    TBkView m_richView;

    BOOL m_bShowWindow;

    void ResizeClient(SIZE sizeClient, BOOL bRedraw)
    {
        ResizeClient(sizeClient.cx, sizeClient.cy, bRedraw);
    }

    void ResizeClient(int cx, int cy, BOOL bRedraw)
    {
        CRect rcWindow, rcClient;
        CPoint ptWindow;

        GetWindowRect(rcWindow);
        GetClientRect(rcClient);

        ptWindow = rcWindow.TopLeft();

        rcWindow.MoveToXY(0, 0);

        rcWindow -= rcClient;
        rcClient.SetRect(0, 0, cx, cy);
        rcWindow += rcClient;

        rcWindow.MoveToXY(ptWindow);

        MoveWindow(rcWindow, bRedraw);
    }

    void OnSize(UINT nType, CSize size)
    {
        CRect rcClient;

        GetClientRect(rcClient);

        if (SIZE_MINIMIZED != nType)
        {
            if (m_richView.m_hWnd)
                m_richView.MoveWindow(rcClient);

        }

        SetMsgHandled(FALSE);
    }

    BOOL OnEraseBkgnd(CDCHandle dc)
    {
        return TRUE;
    }

    LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
    {
        if (bCalcValidRects)
        {
            CRect rcWindow;

            GetWindowRect(rcWindow);

            LPNCCALCSIZE_PARAMS pParam = (LPNCCALCSIZE_PARAMS)lParam;

            if (SWP_NOSIZE == (SWP_NOSIZE & pParam->lppos->flags))
                return 0;

            if (0 == (SWP_NOMOVE & pParam->lppos->flags))
            {
                rcWindow.left = pParam->lppos->x;
                rcWindow.top = pParam->lppos->y;
            }

            rcWindow.right = rcWindow.left + pParam->lppos->cx;
            rcWindow.bottom = rcWindow.top + pParam->lppos->cy;
            pParam->rgrc[0] = rcWindow;
            pParam->rgrc[1] = pParam->rgrc[0];
        }

        return 0;
    }

    void OnGetMinMaxInfo(LPMINMAXINFO lpMMI)
    {
        HMONITOR hMonitor = ::MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONULL);

        if (hMonitor)
        {
            MONITORINFO mi = {sizeof(MONITORINFO)};
            ::GetMonitorInfo(hMonitor, &mi);

            CRect rcWork = mi.rcWork, rcMonitor = mi.rcMonitor;
            lpMMI->ptMaxPosition.x = abs(rcWork.left - rcMonitor.left) - 1;
            lpMMI->ptMaxPosition.y = abs(rcWork.top - rcMonitor.top) - 1;
            lpMMI->ptMaxSize.x = abs(rcWork.Width()) + 2;
            lpMMI->ptMaxSize.y = abs(rcWork.Height()) + 2;
            lpMMI->ptMaxTrackSize.x = abs(rcWork.Width()) + 2;
            lpMMI->ptMaxTrackSize.y = abs(rcWork.Height()) + 2;
        }
    }

    BOOL OnNcActivate(BOOL bActive)
    {
        return TRUE;
    }

public:

    BOOL Load(UINT uResID)
    {
        CStringA strXml;

        BOOL bRet = BkResManager::LoadResource(uResID, strXml);

        if (!bRet)
            return FALSE;

        return SetXml(strXml);
    }

    BOOL SetXml(LPCSTR lpszXml)
    {
        return m_richView.SetXml(lpszXml);
    }

    HWND GetViewHWND()
    {
        return m_richView.m_hWnd;
    }

    BOOL SetPanelXml(UINT uItemID, UINT uResID)
    {
        return m_richView.SetPanelXml(uItemID, uResID);
    }

    BOOL SetPanelXml(UINT uItemID, LPCSTR lpszXml)
    {
        return m_richView.SetPanelXml(uItemID, lpszXml);
    }

    BOOL SetRichText(UINT uItemID, UINT uResID)
    {
        return m_richView.SetRichText(uItemID, uResID);
    }

    BOOL FormatRichText(UINT uItemID, LPCTSTR lpszFormat, ...)
    {
        va_list args;
        CString strText;

        va_start(args, lpszFormat);

        strText.FormatV(lpszFormat, args);

        return m_richView.SetRichText(uItemID, strText);
    }

    BOOL SetRichText(UINT uItemID, LPCWSTR lpszXml)
    {
        return m_richView.SetRichText(uItemID, lpszXml);
    }

    BOOL SetRichText(UINT uItemID, LPCSTR lpszXml)
    {
        return m_richView.SetRichText(uItemID, lpszXml);
    }

    BOOL SetItemText(UINT uItemID, LPCTSTR lpszText)
    {
        return m_richView.SetItemText(uItemID, lpszText);
    }

	CString GetItemText(UINT uItemID)
	{
		return m_richView.GetItemText(uItemID);
	}

    BOOL FormatItemText(UINT uItemID, LPCTSTR lpszFormat, ...)
    {
        va_list args;
        CString strText;

        va_start(args, lpszFormat);

        strText.FormatV(lpszFormat, args);

        return m_richView.SetItemText(uItemID, strText);
    }

    BOOL SetItemAttribute(UINT uItemID, LPCSTR lpszAttrib, LPCSTR lpszValue)
    {
        return m_richView.SetItemAttribute(uItemID, lpszAttrib, lpszValue);
    }

    BOOL GetItemRect(UINT uItemID, RECT &rcItem)
    {
        return m_richView.GetItemRect(uItemID, rcItem);
    }

    BOOL SetItemStringAttribute(UINT uItemID, LPCSTR lpszAttrib, LPCTSTR lpszValue)
    {
        return m_richView.SetItemStringAttribute(uItemID, lpszAttrib, lpszValue);
    }

    BOOL SetItemIntAttribute(UINT uItemID, LPCSTR lpszAttrib, int nValue)
    {
        return m_richView.SetItemIntAttribute(uItemID, lpszAttrib, nValue);
    }

    BOOL SetItemDWordAttribute(UINT uItemID, LPCSTR lpszAttrib, DWORD dwValue)
    {
        return m_richView.SetItemDWordAttribute(uItemID, lpszAttrib, dwValue);
    }

    BOOL SetItemColorAttribute(UINT uItemID, LPCSTR lpszAttrib, COLORREF crValue)
    {
        return m_richView.SetItemColorAttribute(uItemID, lpszAttrib, crValue);
    }

    BOOL GetItemCheck(UINT uItemID)
    {
        return m_richView.GetItemCheck(uItemID);
    }

    BOOL SetItemCheck(UINT uItemID, BOOL bCheck)
    {
        return m_richView.SetItemCheck(uItemID, bCheck);
    }

    BOOL IsItemEnable(UINT uItemID, BOOL bCheckParent = FALSE)
    {
        return m_richView.IsItemEnable(uItemID, bCheckParent);
    }

    BOOL EnableItem(UINT uItemID, BOOL bEnable)
    {
        return m_richView.EnableItem(uItemID, bEnable);
    }

    BOOL IsItemVisible(UINT uItemID, BOOL bCheckParent = FALSE)
    {
        return m_richView.IsItemVisible(uItemID, bCheckParent);
    }

    BOOL SetItemVisible(UINT uItemID, BOOL bVisible)
    {
        return m_richView.SetItemVisible(uItemID, bVisible);
    }

    BOOL SetTabCurSel(UINT uItemID, int nPage)
    {
        return m_richView.SetTabCurSel(uItemID, nPage);
    }

    int GetTabCurSel(UINT uItemID)
    {
        return m_richView.GetTabCurSel(uItemID);
    }

    BOOL SetTabTitle(UINT uItemID, int nPage, LPCTSTR lpszTitle)
    {
        return m_richView.SetTabTitle(uItemID, nPage, lpszTitle);
    }

    BOOL IsTabPageVisible(UINT uItemID, int nPage)
    {
        return m_richView.IsTabPageVisible(uItemID, nPage);
    }

    BOOL SetTabPageVisible(UINT uItemID, int nPage, BOOL bVisible)
    {
        return m_richView.SetTabPageVisible(uItemID, nPage, bVisible);
    }

    BOOL SetItemIconHandle(UINT uItemID, HICON hIcon)
    {
        return m_richView.SetItemIconHandle(uItemID, hIcon);
    }

	BOOL SetItemPaintHook(UINT uItemID, IBkWindowPaintHook* lpPaintHook)
	{
		return m_richView.SetItemPaintHook(uItemID, lpPaintHook);
	}

    void SetWindowCaption(LPCTSTR lpszCaption)
    {
        m_richView.SetWindowCaption(lpszCaption);
    }

    // Call at WM_INITDIALOG
    void DontShowWindow()
    {
        m_bShowWindow = FALSE;
    }

    HWND Create(HWND hWndParent = ::GetActiveWindow(), LPRECT rect = NULL)
    {
        if (!m_richView.XmlLoaded())
        {
            if (0 == m_uResID || !Load(m_uResID))// 载入XML文件
            {
                return NULL;
            }
        }

        CRect rcWnd(0, 0, 0, 0);
        LPCTSTR lpszCaption = m_richView.GetWindowCaption();

        if (_T('\0') == lpszCaption[0])   // 加载标题
            lpszCaption = NULL;

        if (rect)
            rcWnd = rect;

        HWND hWnd = __super::Create(hWndParent, rcWnd, lpszCaption, m_richView.GetDlgStyle(), m_richView.GetDlgExStyle());
        if (!hWnd)
            return NULL;

        BkWinThemeFunc::SetWindowTheme(hWnd, L"", L"");

        if (rect)
        {
            rcWnd.MoveToXY(0, 0);
            m_richView.Create(m_hWnd, rcWnd, 0, 0, IDC_RICHVIEW_WIN);
        }
        else
            m_richView.Create(m_hWnd, NULL, 0, 0, IDC_RICHVIEW_WIN);

        m_bShowWindow = TRUE;

        SendMessage(WM_INITDIALOG, (WPARAM)hWnd);

        m_richView.ShowAllRealWindows(TRUE);

        if (m_hWnd == hWnd)
        {
            SIZE sizeDefault = m_richView.GetDefaultSize();
            if (sizeDefault.cx && sizeDefault.cy)
            {
                ResizeClient(sizeDefault, FALSE);
            }
        }
        else
            hWnd = m_hWnd;

        return hWnd;
    }

    UINT_PTR DoModal(HWND hWndParent = NULL, LPRECT rect = NULL)
    {
        BOOL bEnableParent = FALSE;

        if (NULL == hWndParent)
        {
            hWndParent = BkWinManager::GetActive();
            if (NULL == hWndParent)
                hWndParent = ::GetActiveWindow();
        }

        if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))
        {
            ::EnableWindow(hWndParent, FALSE);
            bEnableParent = TRUE;
        }

        m_bExitModalLoop = FALSE;

        HWND hWnd = Create(hWndParent, rect);
        if (!hWnd)
        {
            ::EnableWindow(hWndParent, TRUE);
            return 0;
        }

        HWND hWndLastActive = BkWinManager::SetActive(hWnd);

        if (!rect)
            CenterWindow();

        if (m_bShowWindow)
        {
            
            ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
        }

        _ModalMessageLoop();

        m_bExitModalLoop = FALSE;

        // From MFC
        // hide the window before enabling the parent, etc.

		if ( IsWindow() )
		{
			SetWindowPos(
            NULL, 0, 0, 0, 0, 
            SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
		}

        if (bEnableParent)
        {
            ::EnableWindow(hWndParent, TRUE);
        }

        if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
            ::SetActiveWindow(hWndParent);

        BkWinManager::SetActive(hWndLastActive);

		if ( IsWindow() )
	        DestroyWindow();

        return m_uRetCode;
    }

    void OnClose()
    {
        SendMessage(WM_COMMAND, MAKELONG(IDCANCEL, 0), NULL);
    }

    void EndDialog(UINT uRetCode)
    {
        m_uRetCode = uRetCode;

        m_bExitModalLoop = TRUE;

        // DestroyWindow里面直接Send了WM_DESTROY,所以不会跑到DoModal的消息循环里,所以有了下面那行代码
        // DestroyWindow();

        // 这句非常重要,可以让DoModal消息循环再跑一次,防止卡死在GetMessage,泪奔~~~~~~~
        ::PostThreadMessage(::GetCurrentThreadId(), WM_NULL, 0, 0);
    }

    void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
        if (IsWindowEnabled())
        {
            if (::GetKeyState(VK_CONTROL) >= 0)
            {
                if (VK_ESCAPE == nChar)
                {
                    SendMessage(WM_COMMAND, MAKELONG(IDCANCEL, 0), NULL);
                }
                else if (VK_RETURN == nChar)
                {
                    SendMessage(WM_COMMAND, MAKELONG(IDOK, 0), NULL);
                }
            }

            SetMsgHandled(FALSE);
        }
    }

    void OnOK(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
    {
        BKNMCOMMAND nms;
        nms.hdr.code = BKNM_COMMAND;
        nms.hdr.hwndFrom = m_hWnd;
        nms.hdr.idFrom = IDC_RICHVIEW_WIN;
        nms.uItemID = IDOK;
        nms.szItemClass = "";

        LRESULT lRet = ::SendMessage(m_hWnd, WM_NOTIFY, (LPARAM)nms.hdr.idFrom, (WPARAM)&nms);
    }

    void OnCancel(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
    {
        BKNMCOMMAND nms;
        nms.hdr.code = BKNM_COMMAND;
        nms.hdr.hwndFrom = m_hWnd;
        nms.hdr.idFrom = IDC_RICHVIEW_WIN;
        nms.uItemID = IDCANCEL;
        nms.szItemClass = "";

        LRESULT lRet = ::SendMessage(m_hWnd, WM_NOTIFY, (LPARAM)nms.hdr.idFrom, (WPARAM)&nms);
    }

public:
	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		return FALSE;
	}

protected:

    BOOL m_bExitModalLoop;

    void _ModalMessageLoop()
    {
        BOOL bRet;
        MSG msg;

        for(;;)
        {
            if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
            {
                if (WM_QUIT == msg.message)
                    break;
            }

            if (m_bExitModalLoop || NULL == m_hWnd || !::IsWindow(m_hWnd))
                break;

            bRet = ::GetMessage(&msg, NULL, 0, 0);

            if (bRet == -1)
            {
                continue;   // error, don't process
            }
            else if (!bRet)
            {
                ATLTRACE(L"Why Receive WM_QUIT here?\r\n");
                break;   // WM_QUIT, exit message loop
            }
			
			if ( !PreTranslateMessage(&msg) )
			{
				::TranslateMessage(&msg);
				::DispatchMessage(&msg);
			}
        }
    }

	BEGIN_MSG_MAP_EX(CBkDialogImpl)
        MSG_WM_NCACTIVATE(OnNcActivate)
        MSG_WM_ERASEBKGND(OnEraseBkgnd)
        MSG_WM_NCCALCSIZE(OnNcCalcSize)
        MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
        MSG_WM_SIZE(OnSize)
        MSG_WM_KEYDOWN(OnKeyDown)
        MSG_WM_CLOSE(OnClose)
        COMMAND_ID_HANDLER_EX(IDOK, OnOK)
        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
	END_MSG_MAP()
};


  在参考了文章《初步分析整理了xml文件与类之间的关联。分享给大家。》后

http://bbs.code.ijinshan.com/thread-1584-1-1.html

得到下图,希望对大家有帮助:


你可能感兴趣的:(平时总结,开源软件(金山,Nginx,Gual)/设计模式)