在使用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界面的实现:
- 把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;
}
- 设置XML的路径:
在CPaintManagerUI::SetInstance(hInstance); 下面调用SetResourcePath函数: - 在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='D:\1.jpeg' " hotimage=" file='D:\2.jpg' " pushedimage=" file='D:\3.jpg' " focusedimage=" file='D:\4.jpg' " />
其中: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