DuiLib : 复杂ListHeaderItem的拖动
来源:互联网 发布:vb 资源管理器侧边栏 编辑:程序博客网 时间:2024/06/07 00:52
我们使用 ListHeaderItem 时,为了实现复杂的题头样式, 会选择Container作为容器,放一些控件的组合.
这时,使用原生的DuiLibV391无法用鼠标拖动2个ListHeaderItem的结合部.
我这几天研究了这个问题
写了一个Demo验证了修改后的效果
工程下载点: srcListUiHeaderItemEx_2014_1006_2029.rar
效果图:
大家手头的DuiLib修改版本都不同,拿Diff工具比较不出来.
大家拿着我这版本,用起来会很不爽(重构了一些代码), 我说修改思路, 供需要的同学参考.
我先追 WM_SETCURSOR
case WM_SETCURSOR: { if( LOWORD(lParam) != HTCLIENT ) break; if( m_bMouseCapture ) return true; POINT pt = { 0 }; ::GetCursorPos(&pt); ::ScreenToClient(m_hWndPaint, &pt); CControlUI* pControl = FindControl(pt); if( pControl == NULL ) break; if( (pControl->GetControlFlags() & UIFLAG_SETCURSOR) == 0 ) break;
发现复杂题头的Container不接受WM_SETCURSOR消息.
我将Container的GetControlFlags改成只要不禁止,就返回UIFLAG_SETCURSOR.
UINT CContainerUI::GetControlFlags() const { if (IsEnabled()) return UIFLAG_SETCURSOR; else return 0; }
然后执行 CContainerUI 的 pControl->Event(event);
BOOL CContainerUI::DoEvent(TEventUI& event){ std::wstring strParentClassName = L""; CControlUI* pParentCtrl = NULL;if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {if( m_pParent != NULL ) m_pParent->DoEvent(event);else CControlUI::DoEvent(event); return TRUE;} if( event.Type == UIEVENT_SETCURSOR ) { pParentCtrl = GetParent(); if ((NULL != pParentCtrl) && (pParentCtrl->GetSepWidth() > 0)) { POINT pt = { 0 }; ::GetCursorPos(&pt); // ::ScreenToClient(m_pPaintManager->GetPaintWindow(), &pt); event.ptMouse = pt; if (!pParentCtrl->DoEvent(event)) ///< 让父窗口决定是否显示光标 { ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); } } else { ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); return FALSE; } }
我让父窗口来决定是否要变换光标(其他样式变成拖动光标).
我写的xml文件如下: (以一个题头字段ListHeaderItem 为例)
<ListHeaderItem name="HeadItem_id" text="ID" width="104" height="30" textcolor="#FF6c6c6c" disabledtextcolor="#FFA7A6AA" align="center" font="1" normalimage="headerctrl_n.png" hotimage="headerctrl_h.png" pushedimage="headerctrl_d.png" sepimage="header_Item_boundary.png" sepwidth="1" > <Container > <HorizontalLayout sepwidth="1" > <Container /> <!-- 拖动时需要, 可以使容器包裹的控件在宽度方向成比例移动 --> <Container width="80" height="32"> </Container> <Container width="16" height="30"> <Button name="btn_sort_id" float="true" pos="0,7,16,16" width="16" height="16" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="sort_no.png" hotimage="sort_no.png" pushedimage="sort_no.png" /> </Container> <Container width="4" /> <!-- 拖动时需要, 和右边界保持一定距离, 拖动时,拖动光标的判断不会落在控件上 --> <Container width="1" bkimage="header_Item_boundary.png" /> </HorizontalLayout> </Container> </ListHeaderItem>
当 HorizontalLayout sepwidth="1" 时, HorizontalLayout会进入光标的判断(原生版本,就有这个判断逻辑)
我将虚函数 DoEvent 由void 返回值,变成BOOL返回值, 这样就可以利用父窗口的判断,如果返回FALSE, 我们就在Container中就将光标设置成箭头.
如果父窗口已经处理了光标(已经设置成拖动光标或别的), 在Container中就不处理光标.
CHorizontalLayoutUI中的光标处理如下, 没有改动, 和原生版本相同
BOOL CHorizontalLayoutUI::DoEvent(TEventUI& event)
...
if( event.Type == UIEVENT_SETCURSOR ){RECT rcSeparator = GetThumbRect(false); if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动 { rcSeparator.left -= 4; rcSeparator.right += 4; } else rcSeparator.right+=4; // ::ScreenToClient(m_pPaintManager->GetPaintWindow(), &pt); POINT pt; pt.x = rcSeparator.left; pt.y = rcSeparator.top; ClientToScreen(m_pPaintManager->GetPaintWindow(), &pt); rcSeparator.left = pt.x; rcSeparator.top = pt.y; pt.x = rcSeparator.right; pt.y = rcSeparator.bottom; ClientToScreen(m_pPaintManager->GetPaintWindow(), &pt); rcSeparator.right = pt.x; rcSeparator.bottom = pt.y; if( IsEnabled() && ::PtInRect(&rcSeparator, event.ptMouse) ) { HCURSOR hCursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)); _ASSERT(NULL != hCursor);::SetCursor(hCursor);return TRUE;} else { return FALSE; }}
我记得就改了这些, 剩下的就是调整一下xml文件就搞定这个显示效果.
0 0
- DuiLib : 复杂ListHeaderItem的拖动
- duilib进阶教程 改进窗口的拖动
- duilib : 窗口拖动
- duilib 无标题窗口拖动
- 嵌套多层的复杂拖动效果
- duilib创建可拖动窗口
- mfc使用duilib 支持拖动
- DuiLib : 在Title区隐藏控件和拖动控件隐藏的区域
- duilib中list拖动表头大小内容大小跟随变化的一个示例
- duilib进阶教程 -- 改进窗口拖动 (12)
- DuiLib界面库滚动条拖动注意事项
- duilib 滚动条不能拖动 问题处理
- 教你如何用duilib实现控件可拖动,可拖拽
- duilib标题栏有文字不能拖动处理方法
- 自定义View-6-拖动按钮复杂版
- 关于duilib的理解
- Duilib的一些资料
- DuiLib的源码分析
- java继承、子类和父类之间转换
- ArchLinux系统安装使用截屏工具
- 看<Headfirst Python>,学习过程中阅读的博客文
- HDU 3105 Fred's Lotto Tickets(数学题)
- HDU 3102 Lawrence of Arabia(dp)
- DuiLib : 复杂ListHeaderItem的拖动
- VRPN学习笔记(一) 用CMake配置和编译VRPN
- 简单的手机页面触屏滚动
- Xcode6:The file couldn’t be opened because you don’t have permission to view it
- Java 向Hbase表插入数据报(org.apache.hadoop.hbase.client.HTablePool$PooledHTable cannot be cast to org.apac
- Keil5创建STM32工程
- Java客户端连接HBase报错:Not a host:port pair
- 可编程图形硬件发展历史,以及CPU VS CPU
- Hadoop+HBase 安装配置