duilib DirectUI库里面的一个简单的例子ListDemo
来源:互联网 发布:adobe xd mac 编辑:程序博客网 时间:2024/06/04 01:28
1、从WinMain说起
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow){ ListMainForm* pFrame = new ListMainForm(); pFrame->Create(NULL, _T("ListDemo"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW , 0, 0, 600, 320); pFrame->CenterWindow(); ::ShowWindow(*pFrame, SW_SHOW); CPaintManagerUI::MessageLoop();return 0;}
这里面也没啥看的,因为是ui,所以消息很重要,来看看
INotifyUI: void Notify(TNotifyUI& msg) { if( msg.sType == _T("windowinit") ) OnPrepare(msg); else if( msg.sType == _T("click") ) { else if( msg.pSender == m_pMinBtn ) { SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); return; } else if(msg.pSender == m_pSearch) { OnSearch(); } } else if( msg.sType == _T("itemactivate") ) { int iIndex = msg.pSender->GetTag(); CDuiString sMessage = _T("Click: ");; sMessage += domain[iIndex].c_str(); ::MessageBox(NULL, sMessage.GetData(), _T("提示(by tojen)"), MB_OK); } else if(msg.sType == _T("menu")) { if( msg.pSender->GetName() != _T("domainlist") ) return; CMenuWnd* pMenu = new CMenuWnd(); if( pMenu == NULL ) { return; } POINT pt = {msg.ptMouse.x, msg.ptMouse.y}; ::ClientToScreen(*this, &pt); pMenu->Init(msg.pSender, pt); } else if( msg.sType == _T("menu_Delete") ) { CListUI* pList = static_cast<CListUI*>(msg.pSender); int nSel = pList->GetCurSel(); if( nSel < 0 ) return; pList->RemoveAt(nSel); domain.erase(domain.begin() + nSel); desc.erase(desc.begin() + nSel); } }
一步一步来看这里显示
一开始是
if( msg.sType == _T("windowinit") ) OnPrepare(msg);
OnPrepare函数没有做什么事情,所以忽略
其他的消息我们在后面继续看=============
在继承了CWindowWnd之后可以通过覆盖LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)的实现,添加自己的消息响应
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = 0; BOOL bHandled = TRUE; switch( uMsg ) { case WM_ADDLISTITEM: lRes = OnAddListItem(uMsg, wParam, lParam, bHandled); break; case WM_CREATE: lRes = OnCreate(uMsg, wParam, lParam, bHandled); break; case WM_CLOSE: lRes = OnClose(uMsg, wParam, lParam, bHandled); break; case WM_DESTROY: lRes = OnDestroy(uMsg, wParam, lParam, bHandled); break; case WM_NCACTIVATE: lRes = OnNcActivate(uMsg, wParam, lParam, bHandled); break; case WM_NCCALCSIZE: lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled); break; case WM_NCPAINT: lRes = OnNcPaint(uMsg, wParam, lParam, bHandled); break; case WM_NCHITTEST: lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled); break; case WM_SIZE: lRes = OnSize(uMsg, wParam, lParam, bHandled); break; case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled); break; case WM_SYSCOMMAND: lRes = OnSysCommand(uMsg, wParam, lParam, bHandled); break; default: bHandled = FALSE; } if( bHandled ) return lRes; if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes; return CWindowWnd::HandleMessage(uMsg, wParam, lParam); }
2、下面的WM消息,一起来看看
a、首先发出的是WM_NCACTIVATE消息
======当客户区将要显示激活或者非激活时,WM_NCACTIVATE消息就会发送给窗口。一个窗口通过它的WindowProc函数来获取该消息。
LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if( ::IsIconic(*this) ) bHandled = FALSE; return (wParam == 0) ? TRUE : FALSE; }
判断一下窗体是否是最小化,如果是则设置标志bHandled,然后返回wParam
b、下来发出的是WM_CREATE消息:
======窗口创建CreateWindow时,系统给消息处理程序发送的消息,每次窗口创建,有且只有1个WM_CREATE消息
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LONG styleValue = ::GetWindowLong(*this, GWL_STYLE); styleValue &= ~WS_CAPTION; ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); Init(); }
这里是创建一个窗口并执行Init的操作:
void Init() { m_pCloseBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("closebtn"))); m_pMaxBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("maxbtn"))); m_pRestoreBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("restorebtn"))); m_pMinBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("minbtn"))); m_pSearch = static_cast<CButtonUI*>(m_pm.FindControl(_T("btn"))); }
Init是找到对应的控件
Create完毕之后,窗口就起来了
记得我们在void Notify(TNotifyUI& msg)中绑定了一个消息,消息类型为:
if( msg.sType == _T("click") ) { else if(msg.pSender == m_pSearch) { OnSearch(); }}
主要是这个OnSearch(),当点击了页面上面的Search按钮,那么相对应的消息便会发出来,m_pSearch在Init的时候和UI上的Search按钮绑定(在这里再判断一下消息的发送者),如果对应 则执行了OnSearch()
void OnSearch(){ struct Prama *prama = new Prama; CListUI* pList = static_cast<CListUI*>(m_pm.FindControl(_T("domainlist"))); CEditUI* pEdit = static_cast<CEditUI*>(m_pm.FindControl(_T("input"))); pEdit->SetEnabled(false); CDuiString input = pEdit->GetText(); m_pSearch->SetEnabled(false); pList->RemoveAll(); domain.empty(); domain.resize(0); desc.empty(); desc.resize(0); DWORD dwThreadID = 0; pList->SetTextCallback(this);//[1] prama->hWnd = GetHWND(); prama->pList = pList; prama->pSearch = m_pSearch; prama->tDomain = input; HANDLE hThread = CreateThread(NULL,0,&ListMainForm::Search, (LPVOID)prama, 0,&dwThreadID);}
Prama是定义的一个结构体,因为在最底下需要开辟线程去执行Add的操作,所以通过这个结构体把所以需要到的东西都传过去。
pList为对应的List列表,pEdit为最上面的文本框
在ListMainForm::Search中(也就是线程的回调方法):
static DWORD WINAPI Search(LPVOID lpParameter) { try { struct Prama* prama = (struct Prama *)lpParameter; CListUI* pList = prama->pList; CButtonUI* pSearch = prama->pSearch; CDuiString tDomain = prama->tDomain; //------------------------------------- /* * 添加数据循环 */ for(int i=0; i<100; i++) { std::stringstream ss; ss << "www." << i << ".com"; domain.push_back(ss.str()); ss.clear(); ss << "it's " << i; desc.push_back(ss.str()); CListTextElementUI* pListElement = new CListTextElementUI; pListElement->SetTag(i); if (pListElement != NULL) { ::PostMessage(prama->hWnd, WM_ADDLISTITEM, 0L, (LPARAM)pListElement); } /* *Sleep 为了展示添加的动态效果,故放慢了添加速度,同时可以看到添加过程中界面仍然可以响应 */ ::Sleep(100); } //------------------------------------------ delete prama; pSearch->SetEnabled(true); return 0; } }
取出上面的参数,发送WM_ADDLIST消息往里边加入Item:
::PostMessage(prama->hWnd, WM_ADDLISTITEM, 0L, (LPARAM)pListElement);
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){ switch( uMsg ) { case WM_ADDLISTITEM: lRes = OnAddListItem(uMsg, wParam, lParam, bHandled); break;}
对应的OnAddListItem就是往List添加Item的
LRESULT OnAddListItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){ CListTextElementUI* pListElement = (CListTextElementUI*)lParam; CListUI* pList = static_cast<CListUI*>(m_pm.FindControl(_T("domainlist"))); if( pList ) pList->Add(pListElement); return 0;}
在回头看看void Notify(TNotifyUI& msg)里面:
双击每一个Item则会发出消息itemactivate
else if( msg.sType == _T("itemactivate") ) { int iIndex = msg.pSender->GetTag(); CDuiString sMessage = _T("Click: ");;sMessage += domain[iIndex].c_str(); ::MessageBox(NULL, sMessage.GetData(), _T("提示(by tojen)"), MB_OK);}
msg.pSender->GetTag()获取当前List的Index
对着List右键,则会发出消息menu
else if(msg.sType == _T("menu")) { if( msg.pSender->GetName() != _T("domainlist") ) return; CMenuWnd* pMenu = new CMenuWnd(); if( pMenu == NULL ) { return; } POINT pt = {msg.ptMouse.x, msg.ptMouse.y}; ::ClientToScreen(*this, &pt); pMenu->Init(msg.pSender, pt);}
menu里边有个delete,对应的消息是menu_Delete:
else if( msg.sType == _T("menu_Delete") ) { CListUI* pList = static_cast<CListUI*>(msg.pSender); int nSel = pList->GetCurSel(); if( nSel < 0 ) return; pList->RemoveAt(nSel); domain.erase(domain.begin() + nSel); desc.erase(desc.begin() + nSel); }}
好了 这个例子就看完了
这个例子中还有两外一个文件MenuWnd.h他其实是对的CMenuWnd描述,也是一个class CMenuWnd : public CWindowWnd, public INotifyUI窗口,他的分析和上面说的差不多。
最后,来看看这里:
else if(msg.sType == _T("menu")) {if( msg.pSender->GetName() != _T("domainlist") ) return;CMenuWnd* pMenu = new CMenuWnd();if( pMenu == NULL ) { return; }POINT pt = {msg.ptMouse.x, msg.ptMouse.y};::ClientToScreen(*this, &pt);pMenu->Init(msg.pSender, pt);}
==========最后delete this==========
- duilib DirectUI库里面的一个简单的例子ListDemo
- duilib DirectUI库里面的一个简单的例子RichListDemo
- directui界面库 Duilib是开源的
- DirectUI开源库 - DuiLib 的使用
- 一个简单的Duilib程序
- 用gnuplot画图,扔latex里面。一个简单的例子。
- 一个简单的开源DIRECTUI界面框架
- 【VC】各种免费、开源的directui库,duilib,REDUI,UiFeature,sharpui等
- 开源的DirectUI界面开发库DUILIB试用demo (Win32程序)
- 一个简单的例子
- 提供一个免费的directui界面库(已开源)
- 一个简单的java反射例子(获得javabean里面的字段)
- java se tutorials 里面的一个很简单的例子,高手请指点一下
- 推荐一个directui介绍的文章
- 【个人收藏】Direct UI 与一个简单的开源DIRECTUI界面框架
- CImg库的一个简单例子
- duilib个简单的文档
- UIPro 一个DirectUI库
- 使用sql*loader和外部表
- [leetcode] Sort Colors
- 坚持写blog啦!!!
- 黑马程序员—Java实例化类
- LeetCode-Unique Binary Search Trees II
- duilib DirectUI库里面的一个简单的例子ListDemo
- HDU1290---献给杭电五十周年校庆的礼物 HDU(106)
- Linux 初始化过程
- Spring抛出错误无效的字段:
- C++一些注意点之异常处理
- Android上传文件至服务器
- 错误:java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.String
- Qt调用VS第三方库
- 1 Spring MVC View层与Controller层的衔接