关于DUILIB的遮罩,控件穿透以及其应用的分析实践

14 篇文章 1 订阅

本文对Duilib的遮罩层以及及穿透进行相关的讨论,原理很简单,除了讨论实现外,在本文也讨论如何利用这些特性、原理来实现需求,欢迎讨论。 

1.       遮罩层的实现

在软件的UI显示中,我们经常会需要遮罩住整个窗口或者是窗口的一部分,以避免客户操作相应的UI,等待特定的操作完成之后才解除锁定。

 

其实这个在Duilib中,是非常容易实现的,好像还有不少人不太清楚,咱们这里就先来讨论一下这个。

Duilib绘制各个控件、响应控件的事件都是按层次从前往后进行处理的[可以简单的理解为XML节点的先后顺序],也就是说位置越靠后的在UI显示层次越高;那么,我们如果在足够靠后的位置放置一个float的控件,控制好他的位置,将需要遮罩的区域覆盖住的话,是不是就能够实现遮罩了呢?

答案是肯定的。

Duilib中的TestApp为例,我们在其XML而已文件的最外层的Layout最后,添加如下代码【这是为了遮罩整个窗口,如果只要遮罩部分,调整一下即可】:

<span style="font-size:14px;"><Control float="true"bkcolor="#66000000" name="cover"pos="0,0,1000,1000" /></span>

其中这个bkcolor表示是黑色,以及一定的透明度,就这样我们就完成了一个遮罩层了,在程序中,只要适当的控制好此控件的显示隐藏以及位置大小即可。

看看效果【只遮挡上半部分】:

 

 

2.       控件的穿透

还有另外一种需求,就是当有两个控件有重叠的时候,我想鼠标操作时,直接操作下面的那个控件,而不要被上面的控件把事件给拦截了,这就引出了控件的穿透问题。

 

为什么会有这样的需求呢?

举一个简单的例子,QQ的图片查看器,在通过鼠标滚轮滚动时,能调整它的显示比例,同时会有一个比例大小的显示,如下图:

但当鼠标在120%这个位置点击拖动时,与它没有显示时一样;如果我想用Duilib来实现的话,这就是一种穿透了【当然有别的实现方法,比如我们自己在此处绘制相应的图片和文字,但我们现在讨论的是如何利用Duilib来实现】。

 

如果觉得这个需求没什么意义,咱们讨论点有意思的看看:

1)      假如你在做一个图书阅读的软件,天晚了,如果可以降低阅读的软件亮度,又不影响对软件的操作,是不是比较贴心?

2)      如果可以给一个文本输入框增加一个前景半透明的图片,且不影响文字输入,是不是比加个背景色更显高大上?

3)      如果你做的是一个比较煊的界面,上面在放着鞭炮,软件双可以继续操作,是不是比较酷?

4)      更多的特效,在功能上支持后,就可以任意发挥你的想象力了,可以在评论里回复。

 

说了这么多,咱们还是来讨论如何实现控件的穿透吧,其实很简单,在强大的Duilib下,我们只需要给CControlUI增加一个属性,然后再增加一个判断就搞定了。

步骤:

1)      CControlUI增加一个成员变量:m_bEnableEvent,表示是否支持事件,为否则表示穿透,这里需要在构造函数中将其默认为true,否则你的窗口将不能被操作了。

2)      CPaintManagerUI::__FindControlFromPoint函数中,如果当前控件的m_bEnableEventfalse,则直接返回NULL即可,代码如下:

 


CControlUI* CALLBACKCPaintManagerUI::__FindControlFromPoint(CControlUI* pThis, LPVOID pData)

{

    if (!pThis->m_bEnableEvent)

    {

        return NULL;

    }

    LPPOINTpPoint = static_cast<LPPOINT>(pData);

    return ::PtInRect(&pThis->GetPos(), *pPoint)? pThis : NULL;

}

 

3)      如果想要哪个控件可以穿透,直接将其m_bEnableEvent设置为false即可。以下在OnPrepare中将遮罩层及一个按钮设置为穿透:

m_pm.FindControl(_T("cover"))->m_bEnableEvent = false;

m_pm.FindControl(_T("insertimagebtn"))->m_bEnableEvent = false;

 

进一步处理的话,在XML中增加这个属性,并且在解析XML的地方增加对此属性的解析与赋值,就更加灵活了。

 

实现效果如下[可以点击遮罩层下的任意区域,输入信息]

 

代码下载:

http://download.csdn.net/detail/tragicguy/8950067

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Duilib是一个基于C++的开源UI库,它提供了丰富的控件和功能,可以用于快速开发Windows桌面应用程序。在Duilib中,你可以自定义控件来满足特定的需求。 下面是一个示例,演示如何在Duilib中创建一个自定义控件: ```cpp // 自定义控件的头文件 CustomControl.h #pragma once #include "UIlib.h" class CCustomControl : public DuiLib::CControlUI { public: CCustomControl(); virtual ~CCustomControl(); LPCTSTR GetClass() const; LPVOID GetInterface(LPCTSTR pstrName); void DoEvent(DuiLib::TEventUI& event); void PaintStatusImage(HDC hDC); protected: bool m_bMouseHover; bool m_bMousePressed; }; // 自定义控件的实现文件 CustomControl.cpp #include "CustomControl.h" CCustomControl::CCustomControl() : m_bMouseHover(false) , m_bMousePressed(false) { } CCustomControl::~CCustomControl() { } LPCTSTR CCustomControl::GetClass() const { return _T("CustomControl"); } LPVOID CCustomControl::GetInterface(LPCTSTR pstrName) { if (_tcscmp(pstrName, _T("CustomControl")) == 0) return static_cast<CCustomControl*>(this); return CControlUI::GetInterface(pstrName); } void CCustomControl::DoEvent(DuiLib::TEventUI& event) { if (event.Type == DuiLib::UIEVENT_MOUSEENTER) { m_bMouseHover = true; Invalidate(); } else if (event.Type == DuiLib::UIEVENT_MOUSELEAVE) { m_bMouseHover = false; Invalidate(); } else if (event.Type == DuiLib::UIEVENT_BUTTONDOWN) { m_bMousePressed = true; Invalidate(); } else if (event.Type == DuiLib::UIEVENT_BUTTONUP) { m_bMousePressed = false; Invalidate(); } CControlUI::DoEvent(event); } void CCustomControl::PaintStatusImage(HDC hDC) { if (m_bMousePressed) { // 绘制按下状态的控件外观 } else if (m_bMouseHover) { // 绘制鼠标悬停状态的控件外观 } else { // 绘制正常状态的控件外观 } } ``` 在上面的示例中,我们创建了一个名为`CCustomControl`的自定义控件类,继承自`DuiLib::CControlUI`。在这个类中,我们重写了一些方法来处理控件的事件和绘制外观。你可以根据自己的需求来实现这些方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值