DuiLib实现简易GUI

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lluozh2015/article/details/50441482

在使用inspect或者UiSpy元素识别工具识别Remote界面元素时,该界面内的元素并不能被识别。后来又碰到关于EB界面交互实现的问题,决定弄一个简易的Demo学习学习。

Remote和EB都是使用开源 的directui 界面库DuiLib,现在很多公司都采用DuiLib做为界面库,比如金山快盘、爱奇艺视频、百度卫士等等。
可以在https://code.google.com/p/duilib/downloads/list下载DuiLib开源代码

新建一个空的Win32项目,新建一个main.cpp文件

#include <windows.h>
#include <tchar.h>

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    ::MessageBox(NULL, _T("Hello World !"), NULL, NULL);
    return 0;
}

运行后即可看到如下结果:
这里写图片描述
这是一个win32的程序,但是DuiLib就是一个基于 win32的UI库。
下面看看DuiLib实现的Hello World:

class CDuiFrameWnd : public CWindowWnd, public INotifyUI
{
public:
    virtual LPCTSTR GetWindowClassName() const { return _T("DUIMainFrame"); }
    virtual void    Notify(TNotifyUI& msg) {}

    virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        LRESULT lRes = 0;

        if( uMsg == WM_CREATE ) 
        {
            CControlUI *pWnd = new CButtonUI;
            pWnd->SetText(_T("Hello World"));   // 设置文字
            pWnd->SetBkColor(0xFF00FF00);       // 设置背景色

            m_PaintManager.Init(m_hWnd);
            m_PaintManager.AttachDialog(pWnd);
            return lRes;
        }

        if( m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes) ) 
        {
            return lRes;
        }

        return __super::HandleMessage(uMsg, wParam, lParam);
    }

protected:
    CPaintManagerUI m_PaintManager;
};

具体实现的效果为:
这里写图片描述

在写DuiLib的界面时,可用DuiLib的UI设计器DuiDesigner或者自己使用XML实现,但是DuiDesigner不完善,容易停止运行。
现在看看使用XML界面的实现:
1. 把if( uMsg == WM_CREATE ) 里面的代码改为:

if( uMsg == WM_CREATE ) 
        {
            m_PaintManager.Init(m_hWnd);

            CDialogBuilder builder;
            CControlUI* pRoot = builder.Create(_T("duilib.xml"), (UINT)0, NULL, &m_PaintManager);   // duilib.xml需要放到exe目录下
            ASSERT(pRoot && "Failed to parse XML");

            m_PaintManager.AttachDialog(pRoot);
            m_PaintManager.AddNotifier(this);   // 添加控件等消息响应,这样消息就会传达到duilib的消息循环,我们可以在Notify函数里做消息处理
            return lRes;
        }
  1. 设置XML的路径:
    在CPaintManagerUI::SetInstance(hInstance); 下面调用SetResourcePath函数:
  2. 在exe目录下建立一个文件名为duilib.xml的文件
    下面看看一个简易使用xml的实现,xml代码如下:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="500,220" caption="0,0,0,32" mininfo="442,381" maxinfo="442,381" roundcorner="5,5">
    <Font name="微软雅黑" size="16" bold="false" italic="false"/>
    <Font name="SimSun" size="20" bold="false" italic="false" default="true"/>
    <Font name="微软雅黑" size="12" bold="false" italic="false"/>
    <VerticalLayout name="MainDialog" bordersize="2" width="442" height="381" bkcolor="#FFFFFFFF" bordercolor="#00C0C0C0">
       <HorizontalLayout  height="32" bkcolor="#FFA0A0A4" bkcolor2="#00C0C0C0">
         <VerticalLayout width="77">
           <Button name="closebtn" float="true" pos="44,5,0,0" width="28" height="19" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
         </VerticalLayout>
       </HorizontalLayout>
    <Label text="DuiLibDemo" float="true" pos="200,0,0,0" width="99" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="0"/>
    <Label text="Please input IPAddress:" float="true" pos="10,50,0,0" width="200" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="0"/>
    <Button name="btnYes" text="yes" textcolor="#00C0C0C0" bordersize="1" float="true" pos="153,141,0,0" width="67" height="25" bkcolor="#FFFF0000"   bordercolor="#00808080" disabledtextcolor=" #000000" font="0" align="center"/>
    <Button name="btnNo"  text="no" textcolor="#00C0C0C0" bordersize="1" float="true" pos="253,141,0,0" width="67" height="25"  bkcolor="#FF0000FF"/>


    </VerticalLayout>
</Window>

运行后的界面为:
这里写图片描述
主要是一个主窗口、2个button按钮和text文本组成。在属性的设置中pos=”0,0,0,0”设置按钮和文本所在窗口的位置,name设置控件名称唯一标识,bkcolor设置控件背景颜色等等(对各个控件的属性列表可查看在开源代码文件的属性列表.xml文件)
另对于控件可以使用图片文件做为UI,如添加一个Button控件

  <Button name="Uibtn" float="true" pos="0,0,0,0" width="67" height="25" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage=" file=&apos;D:\1.jpeg&apos; " hotimage=" file=&apos;D:\2.jpg&apos;  " pushedimage=" file=&apos;D:\3.jpg&apos;  " focusedimage=" file=&apos;D:\4.jpg&apos;  " />

其中:normalimage为焦点不在该控件下时显示D:\1.jpeg图片;hotimage为鼠标移动到该位置时显示D:\2.jpg图片;pushedimage为鼠标按下时显示D:\3.jpg图片;focusedimage为焦点在该控件上时显示D:\4.jpg图片
运行后焦点不在该控件时的界面:
这里写图片描述

现在想要实现的是点击button按钮可触发一个弹窗。
如何响应按钮的点击消息,需要:
1.调用AddNotifier函数将消息加入duilib的消息循环
2.给按钮设置一个唯一的控件ID
3.在Notify函数里处理按钮消息
实现的代码模块为:

class CDuiFrameWnd : public CWindowWnd, public INotifyUI
{
public:
    virtual LPCTSTR GetWindowClassName() const { return _T("DUIMainFrame"); }
    virtual void    Notify(TNotifyUI& msg)
    {
        if (msg.sType == _T("click"))
        {
            if (msg.pSender->GetName() == _T("btnYes"))
            {
                ::MessageBox(NULL, _T("我是按钮"), _T("点击了yes按钮"), NULL);
            }
        }
    }

    virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        LRESULT lRes = 0;

        if (uMsg == WM_CREATE)
        {
            m_PaintManager.Init(m_hWnd);
            CDialogBuilder builder;
            CControlUI* pRoot = builder.Create(_T("duilib.xml"), (UINT)0, NULL, &m_PaintManager);   // duilib.xml需要放到exe目录下
            ASSERT(pRoot && "Failed to parse XML");
            m_PaintManager.AttachDialog(pRoot);
            m_PaintManager.AddNotifier(this);   // 添加控件等消息响应,这样消息就会传达到duilib的消息循环,我们可以在Notify函数里做消息处理
            return lRes;
        }
        // 以下3个消息WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT用于屏蔽系统标题栏
        else if (uMsg == WM_NCACTIVATE)
        {
            if (!::IsIconic(m_hWnd))
            {
                return (wParam == 0) ? TRUE : FALSE;
            }
        }
        else if (uMsg == WM_NCCALCSIZE)
        {
            return 0;
        }
        else if (uMsg == WM_NCPAINT)
        {
            return 0;
        }
        if (m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes))
        {
            return lRes;
        }
        return __super::HandleMessage(uMsg, wParam, lParam);
    }
protected:
    CPaintManagerUI m_PaintManager;
};

在界面中点击yes按钮后具体效果为:
这里写图片描述
即在点击yes按钮后,可以触发一个自定义用户提示弹窗。我们可以实现点击该Button后在一定时间内弹出用户提示弹窗,也可以在点击该Button后监听某事件直到响应时弹出用户提示弹窗

EB的客户端窗口是无法进行拖动操作的,上面实现的简易窗口界面也是无法进行拖动操作的,但是如果我们继承的是工具基类WindowImplBase那就不用自己处理,因为这个基类已经帮处理WM_NCHITTEST消息。

/Alberl/p/3341956.html

展开阅读全文

没有更多推荐了,返回首页