c++ clistui duilibtextelementui 怎么让每行加载前暂停一秒

最近遇到要在一个DuiLib::CListUI中显示动态数据的子任务.
在使用我改版的DuiLib中发现如下问题, 真杯具.
* 如果反复添加删除CListContainerElementUI, 会引起CListUI所在的Dialog退出时挂掉的问题.
& e.g. 在CListUI中增加2000条数据, 在CListUI中删掉2000条数据, 如此反复20次. &再退出该CListUI所在的Dialog, UI就挂掉了.
&现象是WM_PAINT陷入了一个循环(这个正常), 但是UI显示不出来了.
& 这个问题我回避了, 搞不定. &采用妥协的方法, 使CListUI只固定一个行数(e.g. 20行), &根据要显示的内容计算List的UI可见部分应该写什么数据.
& 这样, 只在建立ListUI时, 插入了新的行. 以后都是更新行上的内容. 就不存在退出时UI挂掉的问题.
* 当CListUI一次添加太多数据时(e.g. 一次添加2000行), 当滚动时, List反应特别的迟钝, 有时还会导致UI卡死.
&&这个问题我同样回避了, 搞不定. &采用妥协的方法, 使CListUI只固定一个行数(e.g. 20行), &根据要显示的内容计算List的UI可见部分应该写什么数据.
& 这样, 只在建立ListUI时, 插入了新的行. 以后都是更新行上的内容. 就不存在滚动List自带竖向滚动条时, 引起的机率性UI卡死.
这个问题让我做了5天实验, 才想到折中的解决方法.
我采用的方法是:
* 隐藏CListUI实例自带的竖向滚动条控件, 每次只显示一页的数据
* 在CListUI实例右边的Container中自己摆一个&CScrollBarUI, 用户点击滚动条时, 记录点击的位置, 发送自定义消息, 去刷新CListUI中的显示.
实验过了, 准备20W条数据, 在CListUI中显示, 也是蛮快的, 和数据多少无关, 花费的操作和显示时间都是常量.
这个折中的方法, 让我感到很欣慰.&
数据的容器使用std::vector, 而不能是std::deque, 防止数据释放时, 时间太长. 20W条数据时, std::deque释放的不是一般的慢, 和构造数据的速度比较, 慢了100倍.
使用std::vector时, 构造数据和释放数据的时间是基本相同的. 在20W条数据的条件下做过实验了.
运行效果图:
工程下载点 :&
/// @file MainDlg.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
extern TAG_HOOK_DATA g_KbHookD
extern TAG_HOOK_DATA g_MouseHookD
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,
typedef struct _INFO_LIST_ITEM_DATA
_INFO_LIST_ITEM_DATA()
::ZeroMemory(cFileType, sizeof(cFileType));
::ZeroMemory(cCreationTime, sizeof(cCreationTime));
::ZeroMemory(cLastWriteTime, sizeof(cLastWriteTime));
::ZeroMemory(cFilePath, sizeof(cFilePath));
::ZeroMemory(cFileSize, sizeof(cFileSize));
char cFileType[MAX_PATH]; ///& type_dir 目录, 其它 文件
char cCreationTime[MAX_PATH];
char cLastWriteTime[MAX_PATH];
char cFilePath[MAX_PATH + 1];
char cFileSize[MAX_PATH];
}INFO_LIST_ITEM_DATA, *PINFO_LIST_ITEM_DATA;
typedef enum _eDispWParam {
DISP_REFRESH_CUR_TREE_NODE_FILES_INFO_REMOVE_ALL, ///& 移除List的当前页面内容
DISP_REFRESH_CUR_TREE_NODE_FILES_INFO, ///& 刷新当前用户选择节点的文件信息
DISP_MSG, ///& 显示消息
class CMainDlg :
public CXmlWnd
CMainDlg(WCHAR * pcXmlFileName, WCHAR * pcWndClassName);
virtual ~CMainDlg(void);
/// 安装相关
DWORD m_dwMainTID;
void ThreadProcStart();
BOOL ThreadProcEnd(BOOL bStopNow);
static UINT WINAPI ThreadProc(void* pParam);
UINT WINAPI ThreadProc();
DUI_DECLARE_MESSAGE_MAP()
virtual void InitWindow();
virtual LONG GetStyle();
virtual LONG GetExStyle();
virtual CControlUI* CreateUiControlByMySelf(LPCTSTR pstrClass);
virtual LRESULT
WndMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT WndMessageProc_WM_DISP_REFRESH(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);
void UiInit();
void UiInit_List();
void clearFindData();
void PrepareData();
void ShowMsg(const WCHAR* pcMsg);
void InsertRow2FileList_RemoveAll();
void ClearRow2FileList(CListContainerElementUI* pListItem);
void fn_ShowCurTreeNodeFilesInfo();
void InsertRow2FileList(std::vector&INFO_LIST_ITEM_DATA*&& deqFindData);
void InsertRow2FileList(INFO_LIST_ITEM_DATA*& FindData, CListContainerElementUI*& pListItem);
void MoveMyWindowToDesktopRightBottom();
void DataInit();
void DataUnInit();
void RunObjProg();
void switch_view(e_view_index PageIndex);
DuiLib::CTabLayoutUI*
DuiLib::CContainerUI*
m_pPage_StartP
CListUI* m_pListF ///& 显示文件信息集合的List
CScrollBarUI* m_pVScrollBarForFilesL ///& List右边的竖向滚动条
CContainerUI* m_pContainerForVScrollBarForFilesL ///& List右边竖向滚动条的容器
DuiLib::CLabelUI* m_pStatusM
std::wstring m_strTipM ///& 提示消息
std::wstring m_strTipMsgP ///& 提示消息(最后一次), 为了提高效率
ns_shaoyuan::CCriticalSection m_Locker_MainUI;
int m_iCntFilesListRowM ///& List一页最多显示几行
int m_iDataSoruceRecordC ///& 要操作的数据集合总条目数量, 暂定为20W条数据
std::vector&INFO_LIST_ITEM_DATA*& m_deqFindD ///& 要显示的数据, 假设有6W条数据
ns_shaoyuan::CCriticalSection m_Locker_DispI
ns_base::CThreadManager
BOOL m_bRunObjProgN
BOOL m_bMsgProcessOver_RefreshFilesInfo_RemoveA
BOOL m_bMsgProcessOver_RefreshFilesI
#endif // #ifndef __MAIN_DLG_H__
/// @file MainDlg.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_KbHookD
TAG_HOOK_DATA g_MouseHookD
HWND g_hHwndMain = NULL;
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
if (nCode==0)
MOUSEHOOKSTRUCT* pMouseHook= (MOUSEHOOKSTRUCT*)lP
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;
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)lP
lTemp = lVkCode_Tab & 0xFFF00000;
if (0 == lTemp)
// tab key press down
lVkCodePrev_Tab = lVkCode_T
// tab key press up
if (lVkCode_Tab != lVkCodePrev_Tab)
lVkCodePrev_Tab = lVkCode_T
if (NULL != g_hHwndMain)
::PostMessageW(g_hHwndMain, WM_TAB_KEY_PRESS, 0, 0);
case VK_RETURN:
lVkCode_Enter = (LONG_PTR)lP
lTemp = lVkCode_Enter & 0xFFF00000;
if (lTemp & 0)
// key press up
if (NULL != g_hHwndMain)
::PostMessageW(g_hHwndMain, WM_ENTER_KEY_PRESS, 0, 0);
case VK_UP:
lVkCode_Enter = (LONG_PTR)lP
lTemp = lVkCode_Enter & 0xFFF00000;
if (lTemp&0)
GetCursorPos(&pt);
::PostMessageW(g_hHwndMain,WM_UP_KEY_PRESS,pt.x,pt.y);
case VK_DOWN:
lVkCode_Enter = (LONG_PTR)lP
lTemp = lVkCode_Enter & 0xFFF00000;
if (lTemp&0)
::PostMessageW(g_hHwndMain,WM_DOWN_KEY_PRESS,0,0);
case VK_ESCAPE:
lVkCode_Cancel = (LONG_PTR)lP
lTemp = lVkCode_Cancel & 0xFFF00000;
if (0 == lTemp)
// key press down
if (NULL != g_hHwndMain)
::PostMessageW(g_hHwndMain, WM_CANCEL_KEY_PRESS, 0, 0);
return CallNextHookEx(g_KbHookData.hHook, nCode, wParam, lParam);
CMainDlg::CMainDlg(WCHAR * pcXmlFileName, WCHAR * pcWndClassName)
: CXmlWnd(pcXmlFileName, pcWndClassName),
m_iCntFilesListRowMax(4),
m_iDataSoruceRecordCnt(200000)
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()
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)
m_pPage_StartProg = (DuiLib::CContainerUI*)m_pTabView-&FindSubControl(L&Container_page_install_over&);
if (NULL == m_pPage_StartProg)
UiInit_List();
switch_view(e_view_index_start_prog);
/// 将窗体放到桌面右下角
MoveMyWindowToDesktopRightBottom();
ThreadProcStart();
} while (0);
void CMainDlg::UiInit_List()
int iWidth = 0;
LPCTSTR pcDefaultAttributes = NULL;
if (NULL == m_pListFiles)
m_pStatusMsg = (CLabelUI*)m_PaintManager.FindControl(L&Label_UI_MSG&);
_ASSERT(NULL != m_pStatusMsg);
m_pContainerForVScrollBarForFilesList = (CContainerUI*)m_PaintManager.FindControl(L&container_for_v_scrollbar_for_list&);
_ASSERT(NULL != m_pContainerForVScrollBarForFilesList);
m_pVScrollBarForFilesList = (CScrollBarUI*)m_PaintManager.FindControl(L&scrollbar_for_files_list&);
_ASSERT(NULL != m_pVScrollBarForFilesList);
m_pVScrollBarForFilesList-&SetOwner(NULL);
m_pVScrollBarForFilesList-&SetManager(&m_PaintManager, NULL, false);
pcDefaultAttributes = m_PaintManager.GetDefaultAttributeList(_T(&VScrollBar&));
if (NULL != pcDefaultAttributes)
m_pVScrollBarForFilesList-&ApplyAttributeList(pcDefaultAttributes);
/// 为了让滚动时,List中的内容可以衔接的观看
m_pVScrollBarForFilesList-&SetLineSize((m_iCntFilesListRowMax & 3) ? (m_iCntFilesListRowMax - 1) : 1);
/// 重新安装滚动条配置, 设置合适的滚动条宽度
iWidth = m_pVScrollBarForFilesList-&GetFixedWidth();
m_pContainerForVScrollBarForFilesList-&SetFixedWidth(iWidth);
m_pListFiles = (CListUI*)m_PaintManager.FindControl(L&list_files&);
_ASSERT(NULL != m_pListFiles);
m_pListFiles-&SetAttribute(L&bkcolor&, L&#FFFFFFFF&);
m_pListFiles-&SetAttribute(_T(&itemaltbk&),_T(&true&));
m_pListFiles-&SetAttribute(_T(&itembkcolor&),_T(&#fff8f8f8&));
m_pListFiles-&SetAttribute(_T(&itemhotbkcolor&), _T(&#FFE4E4E4&));
m_pListFiles-&SetAttribute(_T(&itemselectedbkcolor&), _T(&#FFD9E1EE&));
m_pListFiles-&EnableScrollBar(false, true);
m_pListFiles-&GetHeader()-&SetMinWidth(100);
} while (0);
void CMainDlg::clearFindData()
int iIndex = 0;
float fProcessPercent = 0;
float fProcessPercentPerv = 0;
DWORD dwTickBegin = 0;
DWORD dwTickEnd = 0;
std::wstring strTmp = L&&;
INFO_LIST_ITEM_DATA* pData = NULL;
std::vector&INFO_LIST_ITEM_DATA*&::
dwTickBegin = GetTickCount();
it = m_deqFindData.begin();
if (it == m_deqFindData.end())
if (NULL != *it)
pData = m_deqFindData.front();
if (NULL != pData)
SAFE_DELETE(pData);
m_deqFindData.erase(m_deqFindData.begin());
dwTickEnd = GetTickCount();
if ((dwTickEnd - dwTickBegin) & 500)
fProcessPercent = (1.0f * iIndex / m_iDataSoruceRecordCnt) * 100;
if ((fProcessPercentPerv != fProcessPercent)
&& ((fProcessPercent - 0.001f) & fProcessPercentPerv)) {
fProcessPercentPerv = fProcessP
dwTickBegin = GetTickCount();
strTmp = ns_base::StringFormatV(
L&程序正在退出, 资源释放进度%.2f%%, 请稍候...&,
fProcessPercent);
ShowMsg(strTmp.c_str());
m_deqFindData.resize(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=*
HWND hWndParent = ::GetParent(m_hWnd);
HWND hWndCenter = ::GetWindowOwner(m_hWnd);
if (hWndCenter!=NULL)
hWnd=hWndC
// 处理多显示器模式下屏幕居中
MONITORINFO oMonitor = {};
oMonitor.cbSize = sizeof(oMonitor);
::GetMonitorInfo(::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &oMonitor);
rcArea = oMonitor.rcW
if( hWndCenter == NULL )
rcCenter = rcA
::GetWindowRect(hWndCenter, &rcCenter);
int DlgWidth = rcDlg.right - rcDlg.
int DlgHeight = rcDlg.bottom - rcDlg.
// Find dialog's upper left based on rcCenter
int xLeft = rcCenter.right - DlgW
int yTop = rcCenter.bottom - DlgH
// The dialog is outside the screen, move it inside
if( xLeft & rcArea.left )
xLeft = rcArea.
else if( xLeft + DlgWidth & rcArea.right )
xLeft = rcArea.right - DlgW
if( yTop & rcArea.top )
yTop = rcArea.
else if( yTop + DlgHeight & rcArea.bottom )
yTop = rcArea.bottom - DlgH
::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
void CMainDlg::DataInit()
m_strTipMsg = L&&;
m_strTipMsgPerv = L&&;
m_bMsgProcessOver_RefreshFilesInfo_RemoveAll = FALSE;
m_bMsgProcessOver_RefreshFilesInfo = FALSE;
m_pStatusMsg = NULL;
m_pListFiles = NULL;
m_pVScrollBarForFilesList = NULL;
m_pContainerForVScrollBarForFilesList = 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 dwS
/// CMainDlg::GetExStyle 是虚函数, 在WindowImplBase::OnCreate中被调用, 用来设置扩展窗口风格
LONG CMainDlg::GetExStyle()
long dwStyle = __super::GetExStyle();
/// 禁止接受文件拖拽
dwStyle &= ~WS_EX_ACCEPTFILES;
/// 禁止产生任务栏图标
dwStyle |= WS_EX_TOOLWINDOW;
dwStyle &= ~(WS_EX_APPWINDOW);
return dwS
void CMainDlg::InsertRow2FileList_RemoveAll()
int iCnt = 0;
int iIndex = 0;
CControlUI* pCtrl = NULL;
CListContainerElementUI* pListItem = NULL;
/// 填充之前, 都是重新填充, 将旧的丢掉
/// 反复删除再插入会导致UI挂死, 这里临时做的处理为, 将行内容全部清除和隐藏
iCnt = m_pListFiles-&GetCount();
for (iIndex = 0; iIndex & iC iIndex++)
pListItem = (CListContainerElementUI*)m_pListFiles-&GetItemAt(iIndex);
ClearRow2FileList(pListItem);
} while (0);
void CMainDlg::ClearRow2FileList(CListContainerElementUI* pListItem)
CButtonUI* pCtrlIcon = NULL;
CLabelUI* pCtrlFileName = NULL;
CLabelUI* pCtrlFileSize = NULL;
CLabelUI* pCtrlFileTime = NULL;
CLabelUI* pCtrlFileType = NULL;
if (NULL == pListItem)
pCtrlIcon = (CButtonUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_FILE_ICON);
if (NULL != pCtrlIcon)
pCtrlIcon-&SetNormalImage(L&&);
pCtrlFileName = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_FILE_NAME);
if (NULL != pCtrlFileName)
pCtrlFileName-&SetText(L&&);
pCtrlFileSize = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_SIZE);
if (NULL != pCtrlFileSize)
pCtrlFileSize-&SetText(L&&);
pCtrlFileTime = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_TIME);
if (NULL != pCtrlFileTime)
pCtrlFileTime-&SetText(L&&);
pCtrlFileType = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_TYPE);
if (NULL != pCtrlFileType)
pCtrlFileType-&SetText(L&&);
} while (0);
void CMainDlg::fn_ShowCurTreeNodeFilesInfo()
InsertRow2FileList(m_deqFindData);
void CMainDlg::InsertRow2FileList(std::vector&INFO_LIST_ITEM_DATA*&& deqFindData)
std::deque&INFO_LIST_ITEM_DATA*&::
int iCnt = 0;
int iIndex = 0;
int iScrollPos = 0;
int iLastScrollPos = 0;
int iScrollRange = 0;
int iDataIndex = 0;
int iDataBeginIndex = 0;
int iDataEndIndex = 0;
CListContainerElementUI* pListItem = NULL;
iCnt = deqFindData.size();
if (iCnt &= m_iCntFilesListRowMax)
iDataBeginIndex = 0;
iDataEndIndex = (iCnt & 0) ? (iCnt - 1) : 0;
iScrollPos = m_pVScrollBarForFilesList-&GetScrollPos();
iLastScrollPos = m_pVScrollBarForFilesList-&GetLastScrollPos();
iScrollRange = m_pVScrollBarForFilesList-&GetScrollRange();
iDataBeginIndex = (int)((1.0f * iScrollPos / iScrollRange) * iCnt);
/// @todo 从最下面开始向上移动的一次, 不会显示新的内容
if (iScrollPos &= iLastScrollPos)
if (iLastScrollPos == (iCnt - 1))
OutputDebugStringW(L&&);
/// 向下移动
if ((iDataBeginIndex + m_iCntFilesListRowMax) &= iCnt)
iDataEndIndex = iCnt - 1;
iDataBeginIndex = iDataEndIndex - (m_iCntFilesListRowMax - 1);
iDataEndIndex = iDataBeginIndex + (m_iCntFilesListRowMax - 1);
/// 向上移动
if ((iDataBeginIndex + m_iCntFilesListRowMax) &= iCnt)
iDataEndIndex = iDataBeginI
iDataBeginIndex = iDataEndIndex - (m_iCntFilesListRowMax - 1);
iDataBeginIndex = 0;
iDataEndIndex = m_iCntFilesListRowMax - 1;
iCnt = m_pListFiles-&GetCount();
for (iDataIndex = iDataBeginIndex, iIndex = 0;
iDataIndex &= iDataEndI
iDataIndex++, iIndex++)
if (iIndex & iCnt)
pListItem = (CListContainerElementUI*)m_pListFiles-&GetItemAt(iIndex);
pListItem = NULL;
if (deqFindData.size() & 0)
/// 插入或更新行
InsertRow2FileList(deqFindData.at(iDataIndex), pListItem);
/// 清除行
ClearRow2FileList(pListItem);
m_pListFiles-&Invalidate();
} while (0);
void CMainDlg::InsertRow2FileList(INFO_LIST_ITEM_DATA*& FindData, CListContainerElementUI*& pListItem)
_ASSERT(NULL != FindData);
int iTmp = 0;
LONGLONG llTime = 0;
std::wstring strPicFileType = L&&;
std::wstring strFileType = L&&;
BOOL bObjIsDir = FALSE;
std::wstring::size_type nPos = std::wstring::
std::wstring strFileName = ns_base::A2Wex(ns_base::UTF8ToMB(FindData-&cFilePath).c_str()).c_str();
std::wstring strFileSize = ns_base::Size2SizeString(atol(FindData-&cFileSize), FALSE).c_str();
std::wstring strFileTime = L&&;
SYSTEMTIME
CButtonUI* pCtrlIcon = NULL;
CLabelUI* pCtrlFileName = NULL;
CLabelUI* pCtrlFileSize = NULL;
CLabelUI* pCtrlFileTime = NULL;
CLabelUI* pCtrlFileType = NULL;
if (NULL == m_pListFiles)
iTmp = m_pListFiles-&GetCount();
/// @todo ls 快了8个小时, 要转成本地时间
llTime = ns_base::string2longlong(FindData-&cLastWriteTime);
if (ns_base::php_time_2_systemtime((long)llTime, &st))
strFileTime = ns_base::StringFormatV(L&%d-%d-%d %d:%d:%d&,
st.wMonth,
st.wMinute,
st.wSecond);
if (0 == stricmp(FindData-&cFileType, &type_dir&))
strPicFileType = L&dir.png&;
strFileType = L&目录&;
bObjIsDir = TRUE;
strPicFileType = L&file.png&;
strFileType = L&文件&;
bObjIsDir = FALSE;
/// 如果(NULL != pListItem), 就是更新了
if (NULL == pListItem)
/// 插入一个文件夹或者文件
CreateListContainerElementUI(
&m_PaintManager,
pListItem,
L&ListItem_File.xml&,
/// 将目录排前面, 文件放后面
m_pListFiles-&AddAt(
pListItem,
0 /*bObjIsDir ? 0 : m_pListFiles-&GetCount()*/);
pCtrlIcon = (CButtonUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_FILE_ICON);
if (NULL != pCtrlIcon)
pCtrlIcon-&SetNormalImage(strPicFileType.c_str());
pCtrlFileName = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_FILE_NAME);
if (NULL != pCtrlFileName)
nPos = strFileName.rfind(L'/');
if (std::wstring::npos != nPos)
strFileName = strFileName.substr(nPos + 1, -1);
pCtrlFileName-&SetText(strFileName.c_str());
pCtrlFileSize = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_SIZE);
if (NULL != pCtrlFileSize)
pCtrlFileSize-&SetText(strFileSize.c_str());
pCtrlFileTime = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_TIME);
if (NULL != pCtrlFileTime)
pCtrlFileTime-&SetText(strFileTime.c_str());
pCtrlFileType = (CLabelUI*)pListItem-&FindSubControl(LIST_ROW_ELEMENT_NAME_TYPE);
if (NULL != pCtrlFileType)
pCtrlFileType-&SetText(strFileType.c_str());
} while (0);
LRESULT CMainDlg::WndMessageProc_WM_DISP_REFRESH(UINT uMsg, WPARAM wParam, LPARAM lParam)
if (WM_DISP_REFRESH == uMsg)
switch (wParam)
case DISP_REFRESH_CUR_TREE_NODE_FILES_INFO_REMOVE_ALL:
InsertRow2FileList_RemoveAll();
m_bMsgProcessOver_RefreshFilesInfo_RemoveAll = TRUE;
case DISP_REFRESH_CUR_TREE_NODE_FILES_INFO:
fn_ShowCurTreeNodeFilesInfo();
m_bMsgProcessOver_RefreshFilesInfo = TRUE;
case DISP_MSG:
ShowMsg(m_strTipMsg.c_str());
return S_OK;
void CMainDlg::ShowMsg(const WCHAR* pcMsg)
/// 防止显示重复数据时, 由于要加锁判断, 使显示效率降低
if (0 == pare((NULL != pcMsg) ? pcMsg : L&&))
m_Locker_MainUI.enter();
m_strTipMsg = (NULL != pcMsg) ? pcMsg : L&&;
m_Locker_MainUI.leave();
if (GetCurrentThreadId() != m_dwMainTID)
::PostMessageW(this-&GetHWND(), WM_DISP_REFRESH, DISP_MSG, 0);
m_Locker_MainUI.enter();
m_pStatusMsg-&SetText(m_strTipMsg.c_str());
m_Locker_MainUI.leave();
} while (0);
LRESULT CMainDlg::WndMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
bNeedDefaultProcess = FALSE;
switch (uMsg)
case WM_DISP_REFRESH:
WndMessageProc_WM_DISP_REFRESH(uMsg, wParam, lParam);
/// 如果窗口的扩展风格 WS_EX_ACCEPTFILES 被禁止, 是接受不到 WM_DROPFILES 消息的
/// 同时, 拖动文件到CMainDlg时, 图标是禁止样式的图标
case WM_DROPFILES:
OutputDebugStringW(L&&);
case WM_CREATE:
bNeedDefaultProcess = TRUE;
case WM_SWITCH_VIEW:
switch_view((e_view_index)wParam);
case WM_CLOSE:
EntryUiDestory(TRUE);
bNeedDefaultProcess = ThreadProcEnd(FALSE);
bNeedDefaultProcess = TRUE;
if (bNeedDefaultProcess)
return __super::WndMessageProc(uMsg, wParam, lParam);
} while (0);
return S_OK;
void CMainDlg::InitWindow()
BOOL bRc = FALSE;
DWORD dwStyle = 0;
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)
std::wstring strName = L&&;
if (NULL == msg.pSender)
strName = msg.pSender-&GetName().GetData();
if (msg.sType == DUI_MSGTYPE_SCROLL)
if (msg.pSender == m_pVScrollBarForFilesList)
::PostMessage(this-&GetHWND(), WM_DISP_REFRESH, DISP_REFRESH_CUR_TREE_NODE_FILES_INFO, 0);
} while (0);
return __super::Notify(msg);
void CMainDlg::OnClick(TNotifyUI& msg)
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;
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;
if (::GetCurrentThreadId() != m_dwMainTID)
::PostMessageW(this-&GetHWND(), WM_SWITCH_VIEW, PageIndex, 0);
if (NULL == m_pTabView)
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);
} 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));
BOOL CMainDlg::ThreadProcEnd(BOOL bStopNow)
BOOL bThreadWasStop = FALSE;
m_ThreadManager.StopThread(bStopNow, L&m_ThreadManager&);
bThreadWasStop = !m_ThreadManager.IsThreadRunning();
} while (0);
return bThreadWasS
UINT WINAPI CMainDlg::ThreadProc(void* pParam)
uRc = S_FALSE;
if (NULL == pParam)
uRc = ((CMainDlg*)pParam)-&ThreadProc();
} while (0);
return uRc;
UINT WINAPI CMainDlg::ThreadProc()
BOOL bScrollBarEnable = FALSE;
int iCntData = 0;
std::wstring strMsg = L&&;
int iTest = 0;
int iTestPrev = 0x7
while (++iTest & 0)
iTestPrev = iT
iTestPrev 0x7fffffff int
iTestPrev /= 1000000; ///& 百万级
// iTestPrev = 2147
ShowMsg(L&正在准备数据, 请稍后...&);
PrepareData();
/// 现在采用只填充一个7行的List, 具体填充的内容由ScorllBar来决定
iCntData = m_deqFindData.size();
bScrollBarEnable = iCntData & m_iCntFilesListRowM
m_pVScrollBarForFilesList-&SetVisible(TRUE == bScrollBarEnable);
m_pVScrollBarForFilesList-&SetEnabled(TRUE == bScrollBarEnable);
if (bScrollBarEnable)
m_pVScrollBarForFilesList-&SetScrollPos(0);
m_pVScrollBarForFilesList-&SetScrollRange((iCntData & 0) ? iCntData : 1);
m_pContainerForVScrollBarForFilesList-&SetFixedWidth(bScrollBarEnable ? m_pVScrollBarForFilesList-&GetFixedWidth() : 1);
m_pContainerForVScrollBarForFilesList-&Invalidate();
ShowMsg(L&数据准备完成&);
/// 进行首次UI刷新, 让List显示数据
/// 移除files
m_bMsgProcessOver_RefreshFilesInfo_RemoveAll = FALSE;
::PostMessage(this-&GetHWND(), WM_DISP_REFRESH, DISP_REFRESH_CUR_TREE_NODE_FILES_INFO_REMOVE_ALL, 0);
while (!m_bMsgProcessOver_RefreshFilesInfo_RemoveAll)
if (IsEntryUiDestory())
::Sleep(10);
if (IsEntryUiDestory())
/// 刷新files
m_bMsgProcessOver_RefreshFilesInfo = FALSE;
::PostMessage(this-&GetHWND(), WM_DISP_REFRESH, DISP_REFRESH_CUR_TREE_NODE_FILES_INFO, 0);
while (!m_bMsgProcessOver_RefreshFilesInfo)
if (IsEntryUiDestory())
::Sleep(10);
} while (0);
::Sleep(20);
if (IsEntryUiDestory())
if (m_ThreadManager.IsNeedQuitThread())
if (ns_base::IsMutextExist(PE_INSTANCE_NAME_CMD_LET_DLG_NOTIFY_QUIT))
::PostMessageW(this-&GetHWND(), WM_CLOSE, 0, 0);
if (m_bRunObjProgNow)
m_bRunObjProgNow = FALSE;
RunObjProg();
::PostMessageW(this-&GetHWND(), WM_CLOSE, 0, 0);
} while (1);
clearFindData();
::PostMessageW(this-&GetHWND(), WM_CLOSE, 0, 0);
return S_OK;
void CMainDlg::PrepareData()
int iTmp = 0;
DWORD dwTickBegin = 0;
DWORD dwTickEnd = 0;
std::wstring strTmp = L&&;
int iIndex = 0;
INFO_LIST_ITEM_DATA* pData = NULL;
UINT uTimeVal = 0;
srand((UINT)time(NULL));
dwTickBegin = GetTickCount();
for (iIndex = 0; iIndex & m_iDataSoruceRecordC iIndex++)
dwTickEnd = GetTickCount();
if ((dwTickEnd - dwTickBegin) & 500)
dwTickBegin = GetTickCount();
strTmp = ns_base::StringFormatV(L&数据准备进度%.2f%%&, (1.0f * iIndex / m_iDataSoruceRecordCnt) * 100);
ShowMsg(strTmp.c_str());
pData = new INFO_LIST_ITEM_DATA;
_ASSERT(NULL != pData);
::ZeroMemory(pData, sizeof(INFO_LIST_ITEM_DATA));
uTimeVal = (UINT)time(NULL);
uTimeVal += ns_base::RandRange(-10, 10);
strcpy_s(pData-&cCreationTime, ns_base::StringFormatVA(&%u&, uTimeVal).c_str());
strcpy_s(pData-&cFileSize, ns_base::StringFormatVA(&%d&, ns_base::RandRange(100, 1000)).c_str());
iTmp = ns_base::RandRange(1, 2);
strcpy_s(pData-&cFileType,
ns_base::StringFormatVA(&type_%s&, (1 == iTmp) ? &dir& : &file&).c_str());
if (1 == iTmp)
strcpy_s(pData-&cFilePath, ns_base::StringFormatVA(&TestDir_%d&, iIndex).c_str());
strcpy_s(pData-&cFilePath, ns_base::StringFormatVA(&TestFile_%d.txt&, iIndex).c_str());
strcpy_s(pData-&cLastWriteTime, ns_base::StringFormatVA(&%u&, uTimeVal + ns_base::RandRange(1, 10)).c_str());
m_deqFindData.push_back(pData);
void CMainDlg::RunObjProg()
ns_base::CreateProcessEx(L&C:\\Windows\\System32\\notepad.exe&, L&&, FALSE, TRUE);
&!-- dlgNotify_MainDlg.xml --&
&?xml version=&1.0& encoding=&utf-8& standalone=&yes& ?&
&Window size=&595,412&&
&Font name=&微软雅黑& size=&11& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&12& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&13& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&14& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&15& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&16& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&14& bold=&true& italic=&false& /&
&Default name=&VScrollBar& value=&button1normalimage=&file='scrollbar.bmp' source='0,90,16,106' mask='#FFFF00FF'& button1hotimage=&file='scrollbar.bmp' source='18,90,34,106' mask='#FFFF00FF'& button1pushedimage=&file='scrollbar.bmp' source='36,90,52,106' mask='#FFFF00FF'& button1disabledimage=&file='scrollbar.bmp' source='54,90,70,106' mask='#FFFF00FF'& button2normalimage=&file='scrollbar.bmp' source='0,108,16,124' mask='#FFFF00FF'& button2hotimage=&file='scrollbar.bmp' source='18,108,34,124' mask='#FFFF00FF'& button2pushedimage=&file='scrollbar.bmp' source='36,108,52,124' mask='#FFFF00FF'& button2disabledimage=&file='scrollbar.bmp' source='54,108,70,124' mask='#FFFF00FF'& thumbnormalimage=&file='scrollbar.bmp' source='0,126,16,142' corner='2,2,2,2' mask='#FFFF00FF'& thumbhotimage=&file='scrollbar.bmp' source='18,126,34,142' corner='2,2,2,2' mask='#FFFF00FF'& thumbpushedimage=&file='scrollbar.bmp' source='36,126,52,142' corner='2,2,2,2' mask='#FFFF00FF'& thumbdisabledimage=&file='scrollbar.bmp' source='54,126,70,142' corner='2,2,2,2' mask='#FFFF00FF'& railnormalimage=&file='scrollbar.bmp' source='0,144,16,160' corner='2,2,2,2' mask='#FFFF00FF'& railhotimage=&file='scrollbar.bmp' source='18,144,34,160' corner='2,2,2,2' mask='#FFFF00FF'& railpushedimage=&file='scrollbar.bmp' source='36,144,52,160' corner='2,2,2,2' mask='#FFFF00FF'& raildisabledimage=&file='scrollbar.bmp' source='54,144,70,160' corner='2,2,2,2' mask='#FFFF00FF'& bknormalimage=&file='scrollbar.bmp' source='0,162,16,178' corner='2,2,2,2' mask='#FFFF00FF'& bkhotimage=&file='scrollbar.bmp' source='18,162,34,178' corner='2,2,2,2' mask='#FFFF00FF'& bkpushedimage=&file='scrollbar.bmp' source='36,162,52,178' corner='2,2,2,2' mask='#FFFF00FF'& bkdisabledimage=&file='scrollbar.bmp' source='54,162,70,178' corner='2,2,2,2' mask='#FFFF00FF'& & /&
&Default name=&HScrollBar& value=&button1normalimage=&file='scrollbar.bmp' source='0,0,16,16' mask='#FFFF00FF'& button1hotimage=&file='scrollbar.bmp' source='18,0,34,16' mask='#FFFF00FF'& button1pushedimage=&file='scrollbar.bmp' source='36,0,52,16' mask='#FFFF00FF'& button1disabledimage=&file='scrollbar.bmp' source='54,0,70,16' mask='#FFFF00FF'& button2normalimage=&file='scrollbar.bmp' source='0,18,16,34' mask='#FFFF00FF'& button2hotimage=&file='scrollbar.bmp' source='18,18,34,34' mask='#FFFF00FF'& button2pushedimage=&file='scrollbar.bmp' source='36,18,52,34' mask='#FFFF00FF'& button2disabledimage=&file='scrollbar.bmp' source='54,18,70,34' mask='#FFFF00FF'& thumbnormalimage=&file='scrollbar.bmp' source='0,36,16,52' corner='2,2,2,2' mask='#FFFF00FF'& thumbhotimage=&file='scrollbar.bmp' source='18,36,34,52' corner='2,2,2,2' mask='#FFFF00FF'& thumbpushedimage=&file='scrollbar.bmp' source='36,36,52,52' corner='2,2,2,2' mask='#FFFF00FF'& thumbdisabledimage=&file='scrollbar.bmp' source='54,36,70,52' corner='2,2,2,2' mask='#FFFF00FF'& railnormalimage=&file='scrollbar.bmp' source='0,54,16,70' corner='2,2,2,2' mask='#FFFF00FF'& railhotimage=&file='scrollbar.bmp' source='18,54,34,70' corner='2,2,2,2' mask='#FFFF00FF'& railpushedimage=&file='scrollbar.bmp' source='36,54,52,70' corner='2,2,2,2' mask='#FFFF00FF'& raildisabledimage=&file='scrollbar.bmp' source='54,54,70,70' corner='2,2,2,2' mask='#FFFF00FF'& bknormalimage=&file='scrollbar.bmp' source='0,72,16,88' corner='2,2,2,2' mask='#FFFF00FF'& bkhotimage=&file='scrollbar.bmp' source='18,72,34,88' corner='2,2,2,2' mask='#FFFF00FF'& bkpushedimage=&file='scrollbar.bmp' source='36,72,52,88' corner='2,2,2,2' mask='#FFFF00FF'& bkdisabledimage=&file='scrollbar.bmp' source='54,72,70,88' corner='2,2,2,2' mask='#FFFF00FF'& & /&
&Container float=&true& pos=&0,0,0,0& width=&595& height=&412&&
&TabLayout name=&TabLayout_setup_now& width=&581& height=&380&&
&Container name=&Container_page_install_over& bkimage=&bg_setup_now.png&&
&VerticalLayout&
&Container width=&595& height=&40&&
&Button name=&btn_close_ui5& float=&true& pos=&554,0,0,0& width=&40& height=&39& textcolor=&#FF000000& disabledtextcolor=&#FFA7A6AA& align=&center& normalimage=&btn_close_n.png& hotimage=&btn_close_h.png& pushedimage=&btn_close_d.png& /&
&/Container&
&Container&
&HorizontalLayout&
&Container width=&10& /&
&Container&
&HorizontalLayout&
&Container name=&Container_UI_for_tree_view& &
&List name=&list_files& width=&660& height=&527& bordersize=&1& bkcolor=&#FFC0C0C0& itemtextcolor=&#FF000000& itemselectedtextcolor=&#FF000000& itemselectedbkcolor=&#FFC1E3FF& itemhottextcolor=&#FF000000& itemhotbkcolor=&#FFE9F5FF& itemdisabledtextcolor=&#FFCCCCCC& itemdisabledbkcolor=&#FFFFFFFF& vscrollbar=&true& hscrollbar=&true&&
&ListHeader&
&ListHeaderItem name=&HeadItem_file_name& text=&名称& width=&258& height=&31& textcolor=&#FF6c6c6c& disabledtextcolor=&#FFA7A6AA& align=&center& font=&1& normalimage=&headerctrl_normal.png& hotimage=&headerctrl_hot.png& pushedimage=&headerctrl_down.png& sepimage=&header_Item_boundary.png& sepwidth=&1& &
&Container&
&HorizontalLayout sepwidth=&1& &
&Container /&
&Container width=&1& bkimage=&header_Item_boundary.png& /&
&/HorizontalLayout&
&/Container&
&/ListHeaderItem&
&ListHeaderItem name=&HeadItem_file_size& text=&大小& width=&73& height=&31& textcolor=&#FF6c6c6c& disabledtextcolor=&#FFA7A6AA& align=&center& font=&1& normalimage=&headerctrl_normal.png& hotimage=&headerctrl_hot.png& pushedimage=&headerctrl_down.png& sepimage=&header_Item_boundary.png& sepwidth=&1& &
&Container&
&HorizontalLayout sepwidth=&1& &
&Container /&
&Container width=&1& bkimage=&header_Item_boundary.png& /&
&/HorizontalLayout&
&/Container&
&/ListHeaderItem&
&ListHeaderItem name=&HeadItem_file_type& text=&类型& width=&73& height=&31& textcolor=&#FF6c6c6c& disabledtextcolor=&#FFA7A6AA& align=&center& font=&1& normalimage=&headerctrl_normal.png& hotimage=&headerctrl_hot.png& pushedimage=&headerctrl_down.png& sepimage=&header_Item_boundary.png& sepwidth=&1& &
&Container&
&HorizontalLayout sepwidth=&1& &
&Container /&
&Container width=&1& bkimage=&header_Item_boundary.png& /&
&/HorizontalLayout&
&/Container&
&/ListHeaderItem&
&ListHeaderItem name=&HeadItem_file_time& text=&时间& width=&170& height=&31& textcolor=&#FF6c6c6c& disabledtextcolor=&#FFA7A6AA& align=&center& font=&1& normalimage=&headerctrl_normal.png& hotimage=&headerctrl_hot.png& pushedimage=&headerctrl_down.png& sepimage=&header_Item_boundary.png& sepwidth=&1& &
&Container&
&HorizontalLayout sepwidth=&1& &
&Container /&
&Container width=&1& bkimage=&header_Item_boundary.png& /&
&/HorizontalLayout&
&/Container&
&/ListHeaderItem&
&ListHeaderItem name=&HeadItemhave5& text=&& width=&660& height=&31& textcolor=&#FF6c6c6c& disabledtextcolor=&#FFA7A6AA& align=&center& font=&1& normalimage=&headerctrl_normal.png& hotimage=&headerctrl_hot.png& pushedimage=&headerctrl_down.png& /&
&/ListHeader&
&/Container&
&Container name=&container_for_v_scrollbar_for_list& width=&20&& &!-- 这里不用设置准确的滚动条宽度,程序里会自动设置 --&
&ScrollBar name=&scrollbar_for_files_list& /&
&/Container&
&/HorizontalLayout&
&/Container&
&Container width=&10& /&
&/HorizontalLayout&
&/Container&
&Container height=&80&&
&Button name=&btn_run_now& float=&true& pos=&390,11,0,0& width=&197& height=&59& textcolor=&#FF000000& disabledtextcolor=&#FFA7A6AA& align=&center& normalimage=&btn_run_now_n.png& hotimage=&btn_run_now_h.png& pushedimage=&btn_run_now_d.png& /&
&Label name=&Label_UI_MSG& float=&true& pos=&6,11,0,0& width=&374& height=&59& textcolor=&#FF000000& disabledtextcolor=&#FFA7A6AA& /&
&/Container&
&/VerticalLayout&
&/Container&
&/TabLayout&
&/Container&
&!-- ListItem_Files.xml --&
&?xml version=&1.0& encoding=&utf-8& standalone=&yes& ?&
&Window size=&666,61& &
&Font name=&微软雅黑& size=&10& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&11& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&12& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&13& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&14& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&15& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&16& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&17& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&18& bold=&false& italic=&false& /&
&Font name=&微软雅黑& size=&19& bold=&false& italic=&false& /&
&ListContainerElement name=&Container_file_list_item& width=&660& height=&61&&
&Container name=&Container_1& width=&258&&
&HorizontalLayout&
&Container&
&Button name=&btn_row_file_icon& float=&true& pos=&11,6,0,0& width=&48& height=&48& textcolor=&#FF000000& disabledtextcolor=&#FFA7A6AA& align=&center& normalimage=&& hotimage=&& pushedimage=&& /&
&Label name=&label_row_file_name& float=&true& endellipsis=&false& text=&名称& textpadding=&0,0,0,18& pos=&66,0,0,0& width=&600& height=&61& textcolor=&#FF2C2C2C& disabledtextcolor=&#FFA7A6AA& font=&1& align=&wrap& /&
&/Container&
&/HorizontalLayout&
&/Container&
&Container name=&Container_2& width=&73&&
&HorizontalLayout&
&Container&
&Label name=&label_row_size& endellipsis=&false& text=&大小& float=&true& pos=&0,0,0,0& width=&73& height=&61& textcolor=&#FF656565& disabledtextcolor=&#FFA7A6AA& font=&1& align=&center& /&
&/Container&
&/HorizontalLayout&
&/Container&
&Container name=&Container_3& width=&73&&
&HorizontalLayout&
&Container&
&Label name=&label_row_type& endellipsis=&false& text=&类型& float=&true& pos=&0,0,0,0& width=&73& height=&61& textcolor=&#FF656565& disabledtextcolor=&#FFA7A6AA& font=&1& align=&center& /&
&/Container&
&/HorizontalLayout&
&/Container&
&Container name=&Container_4& width=&170& &
&HorizontalLayout&
&Container&
&Label name=&label_row_time& endellipsis=&false& text=&时间& float=&true& pos=&0,0,0,0& width=&170& height=&61& textcolor=&#FF656565& disabledtextcolor=&#FFA7A6AA& font=&1& align=&center& /&
&/Container&
&/HorizontalLayout&
&/Container&
&/ListContainerElement&
本文已收录于以下专栏:
相关文章推荐
以下是duilib demo加自己的改动
struct NodeData
int level_;//层数
bool child_visible...
今天在做一个程序的界面时,需要在一个列表中显示除文字以外的其他控件,如:Edit、Button、Combo等;我做界面使用的是duilib,其自带的CListUI并不能满足此向功能,需要进行扩展,在此...
网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。
在项目中遇到一个 CListUI的显示问题.
* 先建立一个CListUI, 因为暂时符合显示条件,不允许显示, 先隐藏.
/// create dlg have a LitUI
经常有人问list数据量上万的时候,更新效率很低的问题
事实上,对任何界面库,数据量大到一定程度,优化都是必须的
有人提出了虚拟窗口的方法,就是list只维护少数item,滚动的时候根据显示范围调...
在tojen同学的努力下,Duilib官网()终于上线了。论坛地址在,欢迎大家访问。
Duilib确实很强大,而且源码开放,有些不满足的需求,可以通过阅读源码,Debug跟代码,来改进,废话不过说,开看看要改那些东西。
前情提要:Duilib源码中的ListDemo,给我们提供了一个...
今天在做一个程序的界面时,需要在一个列表中显示除文字以外的其他控件,如:Edit、Button、Combo等;我做界面使用的是duilib,其自带的CListUI并不能满足此项功能,需要进行扩展,在此...
前两天项目要用duilib重构。苦于网上几乎没有duilib的文档和教程,郁闷之极。那份简单文档上的代码都基本看懂了,就是不知道怎么配置,代码跑不起来! 网络上也几乎没有告诉第一次配置duilib的文...
他的最新文章
讲师:王渊命
讲师:蔡栋
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 weui 滚动加载 的文章

 

随机推荐