duilib相关
局部静态变量初始化失败的问题
- 描述
- 调试一个实现了
exe和dll双形态的程序时发现,duilib一些局部的static变量new出来是空的
- 调试一个实现了
|
1 2 3 4 5 6 7 |
// .cpp文件 /*CControlFactory* CControlFactory::GetInstance() { static CControlFactory* pInstance = new CControlFactory; return pInstance; }*/ |
-
原因
- 可能是
exe和dll对于全局变量、静态变量的初始化时机不一样
- 可能是
-
解决
- 把实现放到头文件里面
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// .h文件 class UILIB_API CControlFactory { public: CControlUI* CreateControl(CDuiString strClassName); void RegistControl(CDuiString strClassName, CreateClass pFunc); static CControlFactory* GetInstance() { static CControlFactory* pInstance = new CControlFactory; return pInstance; } void Release(); private: // ... } |
dui里面FindResource失败
|
1 2 3 4 5 |
HRSRC hRes = ::FindResource(CPaintManagerUI::GetResourceDll(), L"IDR_ZIPRES1", L"ZIPRES"); // ↓ HRSRC hRes = ::FindResource(CPaintManagerUI::GetResourceDll(), MAKEINTRESOURCE(IDR_ZIPRES1), L"ZIPRES"); |
dui的资源初始化
- 初始化
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
void init_res() { #ifdef _DEBUG CPaintManagerUI::SetResourceType(UILIB_FILE); #else CPaintManagerUI::SetResourceType(UILIB_ZIPRESOURCE); #endif CDuiString str_res_path = CPaintManagerUI::GetInstancePath(); switch (CPaintManagerUI::GetResourceType()) { case UILIB_FILE: { str_res_path += L"skin"; CPaintManagerUI::SetResourcePath(str_res_path.GetData()); CResourceManager::GetInstance()->LoadResource(L"install.xml", NULL); break; } case UILIB_ZIPRESOURCE: { str_res_path += L"skin"; CPaintManagerUI::SetResourcePath(str_res_path.GetData()); HRSRC hRes = ::FindResource(CPaintManagerUI::GetResourceDll(), MAKEINTRESOURCE(IDR_ZIPRES1), L"ZIPRES"); if (hRes != NULL) { DWORD dwSize = 0; HGLOBAL hGlobal = ::LoadResource(CPaintManagerUI::GetResourceDll(), hRes); if (hGlobal != NULL) { dwSize = ::SizeofResource(CPaintManagerUI::GetResourceDll(), hRes); if (dwSize > 0) { CPaintManagerUI::SetResourceZip((LPBYTE)::LockResource(hGlobal), dwSize); CResourceManager::GetInstance()->LoadResource(L"install.xml", NULL); } } if (hGlobal != NULL) { ::FreeResource(hGlobal); } } break; } default: break; } } |
-
UILIB_FILE- 上面选择在
debug模式下使用文件
- 上面选择在
-
UILIB_ZIPRESOURCErelease模式下,上面的做法是,把skin文件夹里面的资源内容达成一个zip包,然后把这个包作为自定义资源类型ZIPRES,资源ID为IDR_ZIPRES1,打入了exerc自定义资源见下节
dui关于程序运行时大小图标
- 直接使用
LoadIcon来设置 - 使用
dui的CWindowWnd类的SetIcon函数发现,小图标设置不成功
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
CUnInstallWnd mainWnd; if (mainWnd.Create(NULL, _T("Win清理优化卸载程序"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 400) == NULL) { return 0; } if (!CCommandParser::GetInstance()->IsSilent()) { HICON hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); if (hIcon) { ::SendMessage(mainWnd.GetHWND(), WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); ::SendMessage(mainWnd.GetHWND(), WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); } mainWnd.CenterWindow(); mainWnd.ShowWindow(TRUE); } else { mainWnd.ShowWindow(FALSE); } |
dui实现一个消息派发UI窗口
- 头文件
- 不需要特意加消息循环
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#pragma once #include "dui_define.h" #include "simple_bind.h" void RunAsUIThread( ISimpleBind * pSimpleBind ); void AsyncToUIThread( ISimpleBind * pSimpleBind ); #define WM_SWITCH_TO_UI_THREAD (WM_USER + 1978) #define WM_ASYNC_TO_UI_THREAD (WM_USER + 1979) class CUIThreadWindow : public CWindowWnd { public: CUIThreadWindow(void); virtual ~CUIThreadWindow(void); static BOOL InitUIThreadWindow(void); static CUIThreadWindow * GetUIThreadWindow(void); static void DestroyUIThreadWindow(); virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override; protected: virtual CDuiString GetSkinFile() { return L""; } virtual LPCTSTR GetWindowClassName(void) const { return L"ui_thread_wnd"; } private: LRESULT OnSwitchToUIThreadMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled ); LRESULT OnAsyncToUIThreadMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled ); private: static CUIThreadWindow * m_pUIThreadWindow; }; |
- 源文件
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
#include "UIThreadWindow.h" CUIThreadWindow * CUIThreadWindow::m_pUIThreadWindow = NULL; CUIThreadWindow::CUIThreadWindow(void){ } CUIThreadWindow::~CUIThreadWindow(void) { } CUIThreadWindow * CUIThreadWindow::GetUIThreadWindow( void ) { return m_pUIThreadWindow; } LRESULT CUIThreadWindow::OnSwitchToUIThreadMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled ) { ISimpleBind * pBind = reinterpret_cast<ISimpleBind *>(wParam); if(pBind == NULL) return FALSE; pBind->SimpleInvolk(); return TRUE; } LRESULT CUIThreadWindow::OnAsyncToUIThreadMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled ) { ISimpleBind * pBind = reinterpret_cast<ISimpleBind *>(wParam); if(pBind == NULL) return FALSE; pBind->SimpleInvolk(); delete pBind; pBind = NULL; return TRUE; } BOOL CUIThreadWindow::InitUIThreadWindow( void ) { if (m_pUIThreadWindow) return TRUE; m_pUIThreadWindow = new CUIThreadWindow; if(m_pUIThreadWindow == NULL) return NULL; HWND hWnd = m_pUIThreadWindow->Create(NULL, NULL, WS_POPUP, NULL); return hWnd != NULL; } void CUIThreadWindow::DestroyUIThreadWindow() { if (m_pUIThreadWindow) { m_pUIThreadWindow->Close(); m_pUIThreadWindow = NULL; } } void RunAsUIThread( ISimpleBind * pSimpleBind ) { CUIThreadWindow * pWnd = CUIThreadWindow::GetUIThreadWindow(); if(pWnd == NULL) return; pWnd->SendMessage(WM_SWITCH_TO_UI_THREAD, (WPARAM)pSimpleBind); } void AsyncToUIThread( ISimpleBind * pSimpleBind ) { CUIThreadWindow * pWnd = CUIThreadWindow::GetUIThreadWindow(); if(pWnd == NULL) return; pWnd->PostMessage(WM_ASYNC_TO_UI_THREAD, (WPARAM)pSimpleBind); } LRESULT CUIThreadWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = __super::HandleMessage(uMsg, wParam, lParam); BOOL bHandled = 0; switch (uMsg) { case WM_SWITCH_TO_UI_THREAD: lRes = OnSwitchToUIThreadMessage(uMsg, wParam, lParam, bHandled); break; case WM_ASYNC_TO_UI_THREAD: lRes = OnAsyncToUIThreadMessage(uMsg, wParam, lParam, bHandled); break; default: break; } return lRes; } |
- 使用
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void RunAsUIThread( ISimpleBind * pSimpleBind ) { CUIThreadWindow * pWnd = CUIThreadWindow::GetUIThreadWindow(); if(pWnd == NULL) return; pWnd->SendMessage(WM_SWITCH_TO_UI_THREAD, (WPARAM)pSimpleBind); } void AsyncToUIThread( ISimpleBind * pSimpleBind ) { CUIThreadWindow * pWnd = CUIThreadWindow::GetUIThreadWindow(); if(pWnd == NULL) return; pWnd->PostMessage(WM_ASYNC_TO_UI_THREAD, (WPARAM)pSimpleBind); } auto bind = simple_bind(&CInstaller::OnInstallStartOnUI, this); RunAsUIThread(&bind); |
- 解析
CUIThreadWindow这个窗口类不会显示出来,在其他非主线程的线程上,可以把一些UI相关的任务通过消息的方式在这个CUIThreadWindow派发窗口上去执行
vs相关
关于byte和std::byte二义性问题
- 描述
- 处理上述双形态功能时遇到了这个问题
- 原因
Windows的sdk对byte有一个定义,而std里面对byte也有一个定义- 当引入了
Windows的一些头文件,且直接或间接引入了<cstddef>时,可能会导致这个问题
- 解决
- 在代码中搜索
using namespace std,注释掉,并修改相应部位
- 在代码中搜索
|
1 2 3 4 5 |
string test(); // ↓ std::string test(); |
rc自定义资源
- 资源视图里面,选择某个工程的
rc打开,添加资源,自定义,ZIPRES - 确定后,同时会生成一个默认的
IDR_ZIPRES1 - 解决方案资源管理器里面,找到要保存资源的筛选器,如资源文件
- 右键,添加,资源,选择
ZIPRES,导入 - 这样会生成资源
ID为IDR_ZIPRES2 - 删掉
IDR_ZIPRES1 - 重命名
IDR_ZIPRES2为IDR_ZIPRES1 - 打开
Resource.h删掉重复的资源id,比如此时IDR_ZIPRES1和IDR_ZIPRES2的值都为130,只留IDR_ZIPRES1
- 右键,添加,资源,选择
- 右键,
rc文件,编译
声明:本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Duilib_概念&&标签05/22
- ♥ Duilib切换界面区域布局11/04
- ♥ Macos进入Recovery界面关闭SIP09/19
- ♥ Make&&Makefile03/23
- ♥ C++_多线程相关03/12
- ♥ STL_priority_queue08/26