DuiLib::CTreeViewUI 的基本用法

来源:互联网 发布:数据库培训哪家好 编辑:程序博客网 时间:2024/05/01 00:09

前几天工程中使用了DuiLib::CTreeViewUI, 由于以前改原生DuiLib时, 没有考虑到DuiLib::CTreeNodeUI时的情况.

出现了DuiLib::CTreeViewUI 不显示的情况, 但是原生的DuiLib是可以的. 

找这个问题用了6天,  还好任务不是很紧, 如果是在试用期, 估计要跑路了^_^

找了6天之后, 改了1句代码. 修改的地方也是自己以前改别的效果时, 改动的.

因为工程中以前没有用到树控件, 当时要发现这个问题, 也有些困难.

void CListContainerElementUI::SetPos(RECT rc){    int i = 0;    int nCount = 0;    TListInfoUI* pInfo = NULL;    CControlUI *pHorizontalLayout = NULL;    RECT rt;    do     {        CContainerUI::SetPos(rc);        /// 以下的处理是为了调整拖动List题头后, 每行字段位置和题头宽度匹配所做的处理        if (NULL == m_pIListOwner_on_ListContainerElementUI)            break;        pInfo = m_pIListOwner_on_ListContainerElementUI->GetListInfo();        /// 这里是对 CTreeNodeUI做的处理, 防止CTreeView的节点文字显示不出来        /// 对于 CTreeNodeUI, (pInfo->nColumns == 0)为实际值        if (pInfo->nColumns <= 0)            break;        nCount = m_items.GetSize();        for (i = 0; i < nCount; i++)        {            pHorizontalLayout = static_cast<CControlUI*>(m_items[i]);            if (NULL == pHorizontalLayout)                continue;            rt = pHorizontalLayout->GetPos();            rt.left = pInfo->rcColumn[i].left;            rt.right = pInfo->rcColumn[i].right;            /// 对于 CTreeNodeUI, 不能执行这里            /// 防止 ((0 == rt.left) && (0 == rt.right)),             /// 导致CControlUI::DoPaint判断条件过不了,不继续刷新            /// 文字显示不出来.            /// RECT {上,下,左,右}            /// org rc = {0,18,10,240}            /// 对于CTreeNodeUI, 如果执行到这里,变成 rc = {0,18,0,0}            /// 导致不是一个值得刷新的区域, 如果不刷新, 文字不显示            pHorizontalLayout->SetPos(rt);        }    } while (0);}

调用链:

是WM_PAINT引发的DuiLib::CListContainerElementUI::SetPos

 dlgNotify.exe!DuiLib::CListContainerElementUI::SetPos(tagRECT rc)  Line 1881C++ dlgNotify.exe!DuiLib::CListBodyUI::SetPos(tagRECT rc)  Line 1189 + 0x3d bytesC++ dlgNotify.exe!DuiLib::CVerticalLayoutUI::SetPos(tagRECT rc)  Line 122 + 0x3d bytesC++ dlgNotify.exe!DuiLib::CListUI::SetPos(tagRECT rc)  Line 303C++ dlgNotify.exe!DuiLib::CContainerUI::SetPos(tagRECT rc)  Line 602 + 0x2b bytesC++ dlgNotify.exe!DuiLib::CVerticalLayoutUI::SetPos(tagRECT rc)  Line 122 + 0x3d bytesC++ dlgNotify.exe!DuiLib::CContainerUI::SetPos(tagRECT rc)  Line 602 + 0x2b bytesC++ dlgNotify.exe!DuiLib::CHorizontalLayoutUI::SetPos(tagRECT rc)  Line 118 + 0x3d bytesC++ dlgNotify.exe!DuiLib::CContainerUI::SetPos(tagRECT rc)  Line 602 + 0x2b bytesC++ dlgNotify.exe!DuiLib::CVerticalLayoutUI::SetPos(tagRECT rc)  Line 122 + 0x3d bytesC++ dlgNotify.exe!DuiLib::CContainerUI::SetPos(tagRECT rc)  Line 602 + 0x2b bytesC++ dlgNotify.exe!DuiLib::CTabLayoutUI::SetPos(tagRECT rc)  Line 181 + 0x2b bytesC++ dlgNotify.exe!DuiLib::CContainerUI::SetPos(tagRECT rc)  Line 602 + 0x2b bytesC++ dlgNotify.exe!DuiLib::CPaintManagerUI::SysMessageProc_Process_WM_PAINT_AlphaBackground_no(unsigned int uMsg, unsigned int wParam, long lParam, long & lRes)  Line 803 + 0x31 bytesC++>dlgNotify.exe!DuiLib::CPaintManagerUI::SysMessageProc_Process_WM_PAINT(unsigned int uMsg, unsigned int wParam, long lParam, long & lRes)  Line 906C++ dlgNotify.exe!DuiLib::CPaintManagerUI::SysMessageProc(unsigned int uMsg, unsigned int wParam, long lParam, long & lRes)  Line 946 + 0x18 bytesC++ dlgNotify.exe!DuiLib::WindowImplBase::WndMessageProc(unsigned int uMsg, unsigned int wParam, long lParam)  Line 434 + 0x1b bytesC++ dlgNotify.exe!CXmlWnd::WndMessageProc(unsigned int uMsg, unsigned int wParam, long lParam)  Line 185C++ dlgNotify.exe!CMainDlg::WndMessageProc(unsigned int uMsg, unsigned int wParam, long lParam)  Line 443 + 0x14 bytesC++ dlgNotify.exe!DuiLib::CWindowWnd::__WndProc(HWND__ * hWnd, unsigned int uMsg, unsigned int wParam, long lParam)  Line 461 + 0x1b bytesC++

BUG排查思路:

  * 写一个小Demo出来, 重现这个问题.  由于这个问题是自己改版的DuiLib库有误, 所以Bug总是重现的.

    写小Demo的目的, 减少无关控件的影响. 减少跟踪代码的复杂度, 提高可操作性.

  * 因为是显示相关的BUG, 跟进WM_PAINT处理.

  * 在经过的控件类中用GetClassNameW 和 GetName 来定位我们需要跟踪的 DuiLib::CTreeViewUI 实例.
  * 在自画过程中追吧, 看看到底在哪除了问题? 是不显示? 还是返回了没有画? 还是将size, RECT等数据结构的数据填错了.


修正后, 写了一个小Demo留念. 

工程下载点 : prj_dlg_show_tree_view.zip

DuiLib::CTreeViewUI的用法参照了新版原生DuiLib中自带的FileTree, 其它调用参照了改版的DuiLib中的代码.

效果图:


工程预览:

/// @fileMainDlg.h/// @brief主对话框的定义, 基类为CXmlWnd#ifndef __MAIN_DLG_H__#define __MAIN_DLG_H__#include "stdafx.h"#include<sstream>#include <iomanip>#include <iostream>#include <map>#include <deque>#include "XmlWnd.h"/// 扩展DuiLib控件#include "controls_ex.h"extern HWND     g_hHwndMain;extern TAG_HOOK_DATA g_KbHookData;extern TAG_HOOK_DATA g_MouseHookData;LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);LRESULT CALLBACK MouseProc(    int nCode,      // hook code    WPARAM wParam,  // message identifier    LPARAM lParam   // mouse coordinates    );enum e_view_index{    e_view_index_unknown = 0,    e_view_index_start_prog,};class CMainDlg :     public CXmlWnd{public:    CMainDlg(WCHAR * pcXmlFileName, WCHAR * pcWndClassName);    virtual ~CMainDlg(void);    /// 安装相关    DWORD m_dwMainTID;public:    void ThreadProcStart();    void ThreadProcEnd();    static UINT WINAPI ThreadProc(void* pParam);    UINT WINAPI ThreadProc();    DUI_DECLARE_MESSAGE_MAP()public:    virtual void InitWindow();    virtual LONG GetStyle();    virtual LONG GetExStyle();    virtual CControlUI* CreateUiControlByMySelf(LPCTSTR pstrClass);    virtual LRESULT     WndMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam);    virtual LRESULT     SysMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled);    virtual void        OnFinalMessage(HWND hWnd);    virtual void        Notify(TNotifyUI & msg);    virtual void        OnClick(TNotifyUI& msg);    virtual LRESULT     OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);private:    void UiInit();    void UiInit_TreeView();    void AddRootNode_TreeView(const WCHAR* pcDispData);    void InsertRow2DirTree(DuiLib::CTreeNodeUI* pNodeParent, const WCHAR* pcDirNow, const WCHAR* pcDispData, OUT DuiLib::CTreeNodeUI*& pNodeNew);    void MoveMyWindowToDesktopRightBottom();    void DataInit();    void DataUnInit();    void RunObjProg();    void switch_view(e_view_index PageIndex);private:    DuiLib::CTabLayoutUI*   m_pTabView;    DuiLib::CContainerUI*   m_pPage_StartProg;    DuiLib::CTreeViewUI* m_pTreeView; ///< 树控件    DuiLib::CTreeNodeUI* m_pTreeNode; ///< 树控件的根节点    ns_base::CThreadManager     m_ThreadManager;    BOOL m_bRunObjProgNow;};#endif // #ifndef __MAIN_DLG_H__

/// @fileMainDlg.cpp#include "stdafx.h"#include "resource.h"#include "resource.h"#include <comutil.h>#include <commdlg.h>#include <mshtml.h>#include <wininet.h>#include <sys/stat.h>#include "MainDlg.h"/// Hook键盘产生的数据, 动机 : 当焦点在Edit中时, DuiLib不传递 WM_KEYxx + VT_TAB/// 下全局钩子, 不采用DLL注入方式, 只监控本程序的键盘输入/// 当有Tab键按下时, PostMessage 到主程序中处理,/// 当此时, 登录框出现时, 就切换用户名和密码的Edit焦点TAG_HOOK_DATA g_KbHookData;TAG_HOOK_DATA g_MouseHookData;HWND g_hHwndMain = NULL;LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam){    if (nCode==0)    {        MOUSEHOOKSTRUCT* pMouseHook= (MOUSEHOOKSTRUCT*)lParam;        if ( pMouseHook->hwnd == NULL )        {        }    }    return CallNextHookEx(g_MouseHookData.hHook, nCode, wParam, lParam);}LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){    static LONG_PTR lVkCodePrev_Tab = 0;    static LONG_PTR lVkCode_Tab = 0;    static LONG_PTR lVkCode_Enter = 0;    static LONG_PTR lVkCode_Cancel = 0;    LONG_PTR        lTemp = 0;    /** when tab key press down and up    KeyboardProc : nCode = 0x0, wParam = 0x9, lParam = 0xF0001    KeyboardProc : nCode = 0x0, wParam = 0x9, lParam = 0xC00F0001    */    if (0 == nCode)    {        switch (wParam)        {        case VK_TAB:            {                lVkCode_Tab = (LONG_PTR)lParam;                lTemp = lVkCode_Tab & 0xFFF00000;                if (0 == lTemp)                {                    // tab key press down                    lVkCodePrev_Tab = lVkCode_Tab;                }                else                {                    // tab key press up                    if (lVkCode_Tab != lVkCodePrev_Tab)                    {                        lVkCodePrev_Tab = lVkCode_Tab;                        if (NULL != g_hHwndMain)                        {                            ::PostMessageW(g_hHwndMain, WM_TAB_KEY_PRESS, 0, 0);                        }                    }                }            }            break;        case VK_RETURN:            {                lVkCode_Enter = (LONG_PTR)lParam;                lTemp = lVkCode_Enter & 0xFFF00000;                if (lTemp > 0)                {                    // key press up                    if (NULL != g_hHwndMain)                    {                        ::PostMessageW(g_hHwndMain, WM_ENTER_KEY_PRESS, 0, 0);                    }                }            }            break;        case VK_UP:            {                lVkCode_Enter = (LONG_PTR)lParam;                lTemp = lVkCode_Enter & 0xFFF00000;                if (lTemp>0)                {                    POINT pt;                    GetCursorPos(&pt);                    ::PostMessageW(g_hHwndMain,WM_UP_KEY_PRESS,pt.x,pt.y);                }            }            break;        case VK_DOWN:            {                lVkCode_Enter = (LONG_PTR)lParam;                lTemp = lVkCode_Enter & 0xFFF00000;                if (lTemp>0)                {                    ::PostMessageW(g_hHwndMain,WM_DOWN_KEY_PRESS,0,0);                }            }            break;        case VK_ESCAPE:            {                lVkCode_Cancel = (LONG_PTR)lParam;                lTemp = lVkCode_Cancel & 0xFFF00000;                if (0 == lTemp)                {                    // key press down                    if (NULL != g_hHwndMain)                    {                        ::PostMessageW(g_hHwndMain, WM_CANCEL_KEY_PRESS, 0, 0);                    }                }            }            break;        default:            break;        }    }    return CallNextHookEx(g_KbHookData.hHook, nCode, wParam, lParam);}CMainDlg::CMainDlg(WCHAR * pcXmlFileName, WCHAR * pcWndClassName)    : CXmlWnd(pcXmlFileName, pcWndClassName){    DataInit();}CMainDlg::~CMainDlg(void){    DataUnInit();}DUI_BEGIN_MESSAGE_MAP(CMainDlg, CXmlWnd)    DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK, OnClick)DUI_END_MESSAGE_MAP()void CMainDlg::UiInit_TreeView(){    if (NULL == m_pTreeView)    {        m_pTreeView = (CTreeViewUI*)m_PaintManager.FindControl(L"tree_view_for_test");        _ASSERT(NULL != m_pTreeView);        m_pTreeView->EnableScrollBar(true, true);    }}void CMainDlg::AddRootNode_TreeView(const WCHAR* pcDispData){    do     {        if ((NULL == m_pTreeView)            || (NULL != m_pTreeNode))        {            break;        }        /// 设置第1层文件夹        m_pTreeNode = new CTreeNodeUI;        _ASSERT(NULL != m_pTreeNode);        /// 高度要设置的和文件夹图标一样高        m_pTreeNode->SetAttribute(L"height", L"17");        m_pTreeNode->SetAttribute(L"width", L"200");        /// 设置文件夹图标(17x19), dir.png        m_pTreeNode->GetFolderButton()->SetAttribute(L"width", L"17");        m_pTreeNode->GetFolderButton()->SetAttribute(L"height", L"19");        m_pTreeNode->GetFolderButton()->SetAttribute(L"normalimage", L"dir.png");        m_pTreeNode->GetFolderButton()->SetAttribute(L"hotimage", L"dir.png");        m_pTreeNode->GetFolderButton()->SetAttribute(L"pushedimage", L"dir.png");        m_pTreeNode->GetFolderButton()->SetAttribute(L"selectedimage", L"dir.png");        m_pTreeNode->SetName(L"root_dir");        m_pTreeNode->SetUserData(L"/");        m_pTreeNode->SetItemText((NULL != pcDispData) ? pcDispData : L"root dir");        m_pTreeNode->SetTag(1000);        m_pTreeNode->GetItemButton()->SetAttribute(L"align", L"left");        /// 设置padding, 让文字看起来Y方向居中        m_pTreeNode->GetItemButton()->SetAttribute(L"padding", L"4,-2,0,0");        m_pTreeNode->GetItemButton()->SetAttribute(L"font", L"6"); ///< 这里font6 是14ppx        m_pTreeNode->SetItemTextColor(RGB(0x7f,0x7f,0x7f));        /// 在文件夹图标和文字内容中间的是CheckBox        /// 我们不需要        m_pTreeNode->SetVisibleCheckBtn(false);        m_pTreeView->Add(m_pTreeNode);        m_pTreeNode->Select(true);    } while (0);}void CMainDlg::InsertRow2DirTree(    DuiLib::CTreeNodeUI* pNodeParent,     const WCHAR* pcDirNow,     const WCHAR* pcDispData,     OUT DuiLib::CTreeNodeUI*& pNodeNew){    std::wstring strDirNow = (NULL != pcDirNow) ? pcDirNow : L"";    std::wstring strPathNameFindData = L"";    std::wstring strItemText = L"";    std::wstring::size_type nPos = std::wstring::npos;    do     {        if (NULL == pNodeParent)        {            break;        }        strPathNameFindData = (NULL != pcDispData) ? pcDispData : L"invalid data";        strDirNow = (NULL != pcDirNow) ? pcDirNow : L"invalid dir";        /// 建立新节点        pNodeNew = new CTreeNodeUI;        _ASSERT(NULL != pNodeNew);        /// 高度要设置的和文件夹图标一样高        pNodeNew->SetAttribute(L"height", L"18");        pNodeNew->SetAttribute(L"width", L"200");        /// 设置文件夹图标(17x19), dir.png        pNodeNew->GetFolderButton()->SetAttribute(L"width", L"17");        pNodeNew->GetFolderButton()->SetAttribute(L"height", L"19");        pNodeNew->GetFolderButton()->SetAttribute(L"normalimage", L"dir.png");        pNodeNew->GetFolderButton()->SetAttribute(L"hotimage", L"dir.png");        pNodeNew->GetFolderButton()->SetAttribute(L"pushedimage", L"dir.png");        pNodeNew->GetFolderButton()->SetAttribute(L"selectedimage", L"dir.png");        pNodeNew->SetName(strPathNameFindData.c_str());        strItemText = strPathNameFindData.c_str();        nPos = strItemText.rfind(L'/');        if (std::wstring::npos != nPos)        {            strItemText = strItemText.substr(nPos + 1, -1);        }        pNodeNew->SetItemText(strItemText.c_str());        pNodeNew->SetUserData(strDirNow.c_str());        // pNodeNew->SetTag(1000 + 1);        pNodeNew->GetItemButton()->SetAttribute(L"align", L"left");        /// 设置padding, 让文字看起来Y方向居中        pNodeNew->GetItemButton()->SetAttribute(L"padding", L"4,-2,0,0");        pNodeNew->GetItemButton()->SetAttribute(L"font", L"6"); ///< 这里font6 是14ppx        pNodeNew->SetItemTextColor(RGB(0x7f, 0x7f, 0x7f));        /// 在文件夹图标和文字内容中间的是CheckBox        /// 我们不需要        pNodeNew->SetVisibleCheckBtn(false);        pNodeParent->AddAt(pNodeNew, 0);    } while (0);}void CMainDlg::UiInit(){    CContainerUI* pContainer = NULL;    DuiLib::CTreeNodeUI* pNodeNew = NULL;    DuiLib::CTreeNodeUI* pSubNodeNew = NULL;    do     {        m_dwMainTID = ::GetCurrentThreadId();        WriteLogEx(L"m_dwMainTID = 0x%x or %d", m_dwMainTID, m_dwMainTID);        m_pTabView = (DuiLib::CTabLayoutUI*)m_PaintManager.FindControl(L"TabLayout_setup_now");        if (NULL == m_pTabView)            break;        m_pPage_StartProg = (DuiLib::CContainerUI*)m_pTabView->FindSubControl(L"Container_page_install_over");        if (NULL == m_pPage_StartProg)            break;        UiInit_TreeView();        AddRootNode_TreeView(L"根目录");        /// 在根节点上加2个子节点        InsertRow2DirTree(m_pTreeNode, L"/tmp", L"临时目录", pNodeNew);        InsertRow2DirTree(m_pTreeNode, L"/cache", L"缓存目录", pNodeNew);        /// 在子节点上增加一个子子节点        InsertRow2DirTree(pNodeNew, L"/cache/log", L"日志目录", pNodeNew);        switch_view(e_view_index_start_prog);        /// 将窗体放到桌面右下角        MoveMyWindowToDesktopRightBottom();        ThreadProcStart();    } while (0);}void CMainDlg::MoveMyWindowToDesktopRightBottom(){    ASSERT(::IsWindow(m_hWnd));    ASSERT((GetWindowStyle(m_hWnd)&WS_CHILD)==0);    RECT rcDlg = { 0 };    ::GetWindowRect(m_hWnd, &rcDlg);    RECT rcArea = { 0 };    RECT rcCenter = { 0 };    HWND hWnd=*this;    HWND hWndParent = ::GetParent(m_hWnd);    HWND hWndCenter = ::GetWindowOwner(m_hWnd);    if (hWndCenter!=NULL)        hWnd=hWndCenter;    // 处理多显示器模式下屏幕居中    MONITORINFO oMonitor = {};    oMonitor.cbSize = sizeof(oMonitor);    ::GetMonitorInfo(::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &oMonitor);    rcArea = oMonitor.rcWork;    if( hWndCenter == NULL )        rcCenter = rcArea;    else        ::GetWindowRect(hWndCenter, &rcCenter);    int DlgWidth = rcDlg.right - rcDlg.left;    int DlgHeight = rcDlg.bottom - rcDlg.top;    // Find dialog's upper left based on rcCenter    int xLeft = rcCenter.right - DlgWidth;    int yTop = rcCenter.bottom - DlgHeight;    // The dialog is outside the screen, move it inside    if( xLeft < rcArea.left )        xLeft = rcArea.left;    else if( xLeft + DlgWidth > rcArea.right )         xLeft = rcArea.right - DlgWidth;    if( yTop < rcArea.top )        yTop = rcArea.top;    else if( yTop + DlgHeight > rcArea.bottom )         yTop = rcArea.bottom - DlgHeight;    ::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);}void CMainDlg::DataInit(){    m_pTreeView = NULL;    m_pTreeNode = NULL;    m_bRunObjProgNow = FALSE;    m_dwMainTID = 0;    m_pTabView = NULL;    m_pPage_StartProg = NULL;}void CMainDlg::DataUnInit(){}LONG CMainDlg::GetStyle(){    long dwStyle = __super::GetStyle();    dwStyle &= ~WS_MAXIMIZEBOX;    return dwStyle;}/**LRESULT WindowImplBase::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){LONG styleValue = 0;styleValue = GetStyle();::SetWindowLong(*this, GWL_STYLE, styleValue);styleValue = GetExStyle();::SetWindowLong(*this, GWL_EXSTYLE, styleValue);*//// CMainDlg::GetExStyle 是虚函数, 在WindowImplBase::OnCreate中被调用, 用来设置扩展窗口风格LONG CMainDlg::GetExStyle(){    long dwStyle = __super::GetExStyle();    /// 禁止接受文件拖拽    dwStyle &= ~WS_EX_ACCEPTFILES;    /// 禁止产生任务栏图标    dwStyle |= WS_EX_TOOLWINDOW;    dwStyle &= ~(WS_EX_APPWINDOW);    return dwStyle;}LRESULT CMainDlg::WndMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam){    BOOL    bNeedDefaultProcess = FALSE;    do     {        switch (uMsg)        {        /// 如果窗口的扩展风格 WS_EX_ACCEPTFILES 被禁止, 是接受不到 WM_DROPFILES 消息的        /// 同时, 拖动文件到CMainDlg时, 图标是禁止样式的图标        case WM_DROPFILES:            OutputDebugStringW(L"");            break;        case WM_CREATE:            bNeedDefaultProcess = TRUE;            break;        case WM_SWITCH_VIEW:            switch_view((e_view_index)wParam);            break;        case WM_CLOSE:            EntryUiDestory(TRUE);            ThreadProcEnd();            bNeedDefaultProcess = TRUE;            break;        default:            bNeedDefaultProcess = TRUE;            break;        }        if (bNeedDefaultProcess)            return __super::WndMessageProc(uMsg, wParam, lParam);        else            return S_OK;    } while (0);    return S_OK;}void CMainDlg::InitWindow(){    BOOL bRc = FALSE;    DWORD dwStyle = 0;    UiInit();}CControlUI* CMainDlg::CreateUiControlByMySelf(LPCTSTR pstrClass){    if (0 == _tcscmp(pstrClass,_T("ButtonGif")))        return new CButtonGifUI;    return NULL;}LRESULT CMainDlg::SysMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled){    return __super::SysMessageProc(uMsg, wParam, lParam, bHandled);}void CMainDlg::OnFinalMessage(HWND hWnd){    m_PaintManager.FreeResourceZip(); ///< !    __super::OnFinalMessage(hWnd);}void CMainDlg::Notify(TNotifyUI & msg){    return __super::Notify(msg);}void CMainDlg::OnClick(TNotifyUI& msg){    BOOL            bNeedDefaultProcess = FALSE;    std::wstring    strName = L"";    if (NULL != msg.pSender)    {        strName = msg.pSender->GetName().GetData();    }    if (strName == L"btn_close_ui5")    {        ::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);    }    else if (strName == L"btn_run_now")    {        m_bRunObjProgNow = TRUE;    }    else    {        bNeedDefaultProcess = TRUE;    }    if (bNeedDefaultProcess)        __super::OnClick(msg);}LRESULT CMainDlg::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){    return __super::OnNcHitTest(uMsg, wParam, lParam, bHandled);}void CMainDlg::switch_view(e_view_index PageIndex){    static int     iWidth = 0;    static int     iHeight = 0;    do     {        if (::GetCurrentThreadId() != m_dwMainTID)        {            ::PostMessageW(this->GetHWND(), WM_SWITCH_VIEW, PageIndex, 0);            break;        }        if (NULL == m_pTabView)            break;        iWidth = m_pTabView->GetFixedWidth();        iHeight = m_pTabView->GetFixedHeight();        switch (PageIndex)        {        case e_view_index_start_prog:            {                if (NULL != m_pPage_StartProg)                {                    m_pTabView->SelectItem(m_pPage_StartProg);                }            }            break;        default:            break;        }    } while (0);}void CMainDlg::ThreadProcStart(){    if (!m_ThreadManager.IsNeedQuitThread()        && !m_ThreadManager.IsThreadRunning())    {        m_ThreadManager.SetThreadHandle((HANDLE)_beginthreadex(NULL, 0, &CMainDlg::ThreadProc, (void*)this, 0, NULL));    }}void CMainDlg::ThreadProcEnd(){    m_ThreadManager.StopThread(TRUE, L"m_ThreadManager");}UINT WINAPI CMainDlg::ThreadProc(void* pParam){    UINT    uRc = S_FALSE;    do     {        if (NULL == pParam)            break;        uRc = ((CMainDlg*)pParam)->ThreadProc();    } while (0);    return uRc;}UINT WINAPI CMainDlg::ThreadProc(){    do     {        ::Sleep(20);        if (m_ThreadManager.IsNeedQuitThread())            break;        if (ns_base::IsMutextExist(PE_INSTANCE_NAME_CMD_LET_DLG_NOTIFY_QUIT))        {            ::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);            break;        }        if (m_bRunObjProgNow)        {            m_bRunObjProgNow = FALSE;            RunObjProg();            ::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);            break;        }    } while (1);    return S_OK;}void CMainDlg::RunObjProg(){    ns_base::CreateProcessEx(L"C:\\Windows\\System32\\notepad.exe", L"", FALSE, TRUE);}


 

  


0 0
原创粉丝点击