首页 > REDM基础教程 > REDM基础教程13-手工增加控件
2016十一月13

REDM基础教程13-手工增加控件

[隐藏]

 修改前的MyRes+Test下载–>

MyRes1.zip

Test.zip

  修改后的MyRes+Test下载–>

Test.zip

MyRes.zip

完整的MyTest工程(带响应list中的关闭事件)

MyTest.zip

1.手工增加控件

  

结合 REDM基础教程11-控件的XML属性规则 的方式,我们能得到任意一个控件使用的XML结点名,支持的所有属性名,这次我们来手工构造一个新加的控件comboboxex

  

首先,我们要找到登陆窗口对应的XML,所有的XML文件如前一节所看到的,位于layout\dmindex.xml中:

<?xml version="1.0"?>
<resource>
	<global>
		<file name="global" path="layout\xml\global.xml" />
	</global>
	<layout>
		<file name="main" path="layout\xml\main.xml" />
	</layout>
</resource>

  

结合Test.cpp中的创建窗口代码使用的窗口name为main

pMainWnd->DM_CreateWindow(L"main",0,0,0,0,NULL,false);

我们能确认主窗口的xml为MyRes\layout\xml\main.xml,当然,如果使用了设计器加载MyRes,则可以按以下方式打开main.xml

5.png或者6.png

<?xml version="1.0"?>
<dm initsize="430,330" minsize="200,200" bresize="0" btranslucent="1">
	<root clrbg="pbgra(f9,f2,eb,ff)">
		<gif pos="0,0,@430,@180" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" badjust="0" gifskin="gif:qqbg" bdrag="1">
			<Button name="closebtn" pos="-30,0,@30,@27" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="png:close" />
			<Button name="minibtn" pos="-60,0,@30,@27" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="png:mini" />
			<Static pos="150,65,@130,@60" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQlogin" />
		</gif>
		<Static pos="42,190,@80,@80" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQ" />
		<Button pos="6,-30,@24,@24" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQleft" />
		<Button pos="-30,-30,@22,@22" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQright" />
		<Window pos="134,190,@194,@59" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQcbxbg" />
		<checkbox pos="133,256,@66,@20" text="记住密码" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,00)" checkskin="QQcheckbox" align="left" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" clrtext="pbgra(80,80,80,ff)" />
		<checkbox pos="261,256,@66,@20" text="自动登陆" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,00)" checkskin="QQcheckbox" align="left" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" clrtext="pbgra(80,80,80,ff)" />
		<Button pos="334,190,@90,@20" text="注册帐号" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,00)" align="left" clrtext="pbgra(ff,80,80,ff)" clrtexthover="pbgra(c0,80,00,ff)" clrtextpush="pbgra(ff,80,00,ff)" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" />
		<Button pos="335,220,@90,@20" text="找回密码" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,00)" align="left" clrtext="pbgra(ff,80,80,ff)" clrtexthover="pbgra(c0,80,00,ff)" clrtextpush="pbgra(ff,80,00,ff)" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" />
		<Button pos="134,-44,@194,@30" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQbtn" />
	</root>
</dm>

  

1.主窗口都是以<dm>为根结点,<dm>结点记录了主窗口的实际窗口属性,如上面,指定了初始大小(宽430,高330),最小大小(宽200,高200),不可拖动(bresize="0"),分层窗口(btranslucent="1"),分层窗口意为可以使用不规则的背景图.

  

2.第二层总是<root>结点,它表示主窗口的DUI属性,主窗口也是一个DUIWindow窗口.

  

3.从第二层后,展示的是锚点坐标系,当然DM也支持流式布局(类似duilib),两种布局可以互用

  

4.锚点坐标系理解起来比较简单:如<gif>,它的父窗口为<root>,它有三个子控件<Button><Button><Static>,pos表示坐标,锚点坐标系是以父窗口为参考的

  

我们已经用设计器把中间的区域底图拖拉出来了:

<Window pos="134,190,@194,@59" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQcbxbg" />

  

我们在它的中间加入comboboxex子控件(帐号下拉框)以及密码框:(font看起来有点长,其实这部分是我从设计器里拖拉好的,这里就直接使用了)

		<Window pos="134,190,@194,@59" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="QQcbxbg">
			<comboxex pos="10,3,@183,@23" bhideedit="0" skin="QQPW">
				<subshow>
					<edit pos="0,0,-30,-0" surfacetext="QQ号码/手机/邮箱" surfacetextclr="pbgra(7f,7f,7f,ff)" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-16,face:宋体" clrtext="rgba(00,00,00,ff)" bautosel="1" surfacefont="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" />
				</subshow>
			<sublistboxex itemheight="38" bswapline="0" ncmargin="1,1,1,1" clrnc="pbgra(d5,9b,0,ff)" clrbg="pbgra(ff,ff,ff,ff)">
				<item cursor="hand">
					<static pos="10,0,-30,-0" clrtext="pbgra(00,00,00,ff)" align="left" text="80718901" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-14,face:宋体" cursor="cross" />
					<Button name="closebtn" pos="-30,5,@30,@27" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="png:close" />
				</item>
				<item ncmargin="0,1,0,2" cursor="hand">
					<static pos="10,0,-30,-0" clrtext="pbgra(00,00,00,ff)" align="left" text="12345678" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-14,face:宋体" cursor="cross" />
					<Button name="closebtn" pos="-30,5,@30,@27" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="png:close" />
				</item>
			</sublistboxex>
			</comboxex>
			<edit pos="10,32,@153,@23" surfacetext="密码" surfacetextclr="pbgra(7f,7f,7f,ff)" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-16,face:宋体" clrtext="rgba(00,00,00,ff)" bautosel="1" surfacefont="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" bpassword="1" />
		</Window>

  

下面是解释:

1.<combobox>为xml节名,坐标为距离父dui控件左上角(10,3),宽186,高23(pos="10,3,@183,@23"

  

2.它有两个属性(bhideedit="0" skin="QQPW"),这从它的Attr类继承关系可以找到,表示comboxex是可编缉的,背景皮肤是QQPW(上一节我们加入的)

class DUIComboBoxExAttr:public DUIComboBoxBaseAttr

------>
class DUIComboBoxBaseAttr:public DUIWindowAttr
	{
	public:
		static wchar_t* bool_bhideedit;                                               ///< 是否不显示edit,示例:bhideedit="1"
		...
	}	
--->所有dui控件都会包含DUIStyleAttr属性
class DUIStyleAttr
	{
	public:
	        static wchar_t* SKIN_skin;											///< 窗口的style背景图,示例:skin="checkbox"
	        ...

  

3.它有两个子项subshowsublistboxexITEM_开头的表示为控件的子项,在不同控件中意思是不同的,在这里subshow表示了在comboxex中显示的初始绘制,sublistboxex指定下拉框的初始内容

class DUIComboBoxExAttr:public DUIComboBoxBaseAttr
	{
	public:
		static wchar_t* ITEM_subshow;													///< 初始显示的XML标识
		static wchar_t* ITEM_sublistboxex;                                              ///< 子控件listbox的XML标识
	};

  

4.很明显,comboxex的初始绘制为一个edit,它的坐标为左上角(0,0),其右边:相对于父控件右边左移30(-30), 其下边:相对于父控件下边上移0(-0), 父控件即comboxex,(pos="0,0,-30,-0"),它的表层文字为QQ号码/手机/邮箱(surfacetext="QQ号码/手机/邮箱"),在edit没有内容时出现的文字叫表层文字(当光标点击时,会自动消失),当光标点击时,会自动全选(bautosel="1")

<subshow>
	<edit pos="0,0,-30,-0" surfacetext="QQ号码/手机/邮箱" surfacetextclr="pbgra(7f,7f,7f,ff)" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-16,face:宋体" clrtext="rgba(00,00,00,ff)" bautosel="1" surfacefont="weight:400,charset:0,underline:0,italic:0,strike:0,size:-12,face:新宋体" />
</subshow>
class DUIEditAttr:public DUIRichEditAttr
	{
	public:
		static wchar_t* SKIN_surfaceskin;                               ///< 表层背景皮肤,示例:surfaceskin="editskin"
		static wchar_t* STRING_surfacetext;                             ///< 表层文字,当真实文字为空时,表层文字出现,示例:surfacetext="this is edit"
		static wchar_t* COLOR_surfacetextclr;                           ///< 表层文字背景,示例:surfacetextclr="pbgra(00,00,ff,ff)"  
		static wchar_t* FONT_surfacefont;                               ///< 表层文字字体,示例:surfacefont="face:宋体,size:0,weight:400
		
---->
	class DUIRichEditAttr:public DUIScrollBaseAttr
	{
	public:
	....
	static wchar_t* bool_bautosel;									///< 每次进入,默认选中所有内容,示例:bautosel="1"

  

5.comboxex的下拉框为一个列表框扩展,即我们的listboxex

<sublistboxex itemheight="38" bswapline="0" ncmargin="1,1,1,1" clrnc="pbgra(d5,9b,0,ff)" clrbg="pbgra(ff,ff,ff,ff)">
	<item cursor="hand">
		<static pos="10,0,-30,-0" clrtext="pbgra(00,00,00,ff)" align="left" text="80718901" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-14,face:宋体" cursor="cross" />
		<Button name="closebtn" pos="-30,5,@30,@27" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="png:close" />
	</item>
	<item ncmargin="0,1,0,2" cursor="hand">
		<static pos="10,0,-30,-0" clrtext="pbgra(00,00,00,ff)" align="left" text="12345678" font="weight:400,charset:0,underline:0,italic:0,strike:0,size:-14,face:宋体" cursor="cross" />
		<Button name="closebtn" pos="-30,5,@30,@27" text="" clrnc="pbgra(00,00,00,ff)" clrbg="pbgra(dd,dd,dd,ff)" skin="png:close" />
	</item>
</sublistboxex>

对于列表框扩展来说,每一项的结点为<item>,所以上面只有两项(两个item)

每个item默认是占了列表框控件的全部宽度,它们的高度可以由自己来指定,如果没有,就使用列表框指定的(itemheight="38"),每个item其实就是一个duiwindow控件,所以它的下面也可以包含任意多的子控件,这里是包含了两个<Static>+<Button>

大家可能有点疑问,应该是<listboxex>,但现在使用的是<sublistboxex>,这个可以在代码中找到答案,创建子控件列表的函数为DV_CreateChildWnds(DV_开头表示它是个虚函数)

DMCode ComboboxEx::DV_CreateChildWnds(DMXmlNode &XmlNode)
{
	// todo.初始显示信息,这里按显示大区和延迟两个子控件处理
	do 
	{    
		DMXmlNode XmlShowStyle = XmlNode.FirstChild(DMAttr::DUIComboBoxExAttr::ITEM_subshow);
		DUIWindow::DV_CreateChildWnds(XmlShowStyle);

		CreateListBox(XmlNode);// 创建List
	} while (false);

	return DM_ECODE_OK;
}
--->
bool ComboboxEx::CreateListBox(DMXmlNode &XmlNode)
{
	bool bRet = false;
	do 
	{
		if (!XmlNode.IsValid())
		{
			break;
		}
		g_pDMApp->CreateRegObj((void**)&m_pListBox, ListBoxEx::GetClassName(),DMREG_Window);// 使用了listboxex创建子控件
		....
		DMCode dwCode =	m_pListBox->InitDMData(XmlNode.FirstChild(DMAttr::DUIComboBoxExAttr::ITEM_sublistboxex));// 子控件加载xml属性

可以看出,实际上代码内部是使用了ListBoxEx来创建一个子控件,但使用sublistboxex对应的xml节点来初始化

同时,像这种扩展控件,每个<item>同时也是一个容器面板, 它们内部的所有事件消息都是通过DMEVT_OFPANEL这个面板消息来转发的,如果你要接收面板里的子控件消息,需要响应DMEVT_OFPANEL这个事件消息,并在内部取得原始消息,在CTGPMainWnd::OnListBoxEx或WidgetAttr::s_DMHandleEvent都有相关的参考,这个后续介绍吧

DV_CreateChildWnds这个函数是非常有用的,所有的创建子控件列表均通过它来控制,它是个虚函数,可以重载来实现子控件的多样化

  

6.comboxex下接着的edit表示一个密码输入框,它多了一个属性,使用密码方式输入(bpassword="1")

 

7.保存main.xml,MyTest运行:

19.gif

  

8.基本形象出来了,但好像下拉框的左右位置不对啊!,在代码中做一下调整:CalcPopupRect用于调整实际的弹出大小,我们让它左边增大10吧,为什么呢,因为:

<comboxex pos="10,3,@183,@23"// 相对于父控件的左边为10偏移,但弹出框是和父控件保持左对齐,所以移回去
bool ComboboxEx::CalcPopupRect( int nHeight,CRect& rcPopup )
{
	bool bRet = DUIComboBoxBase::CalcPopupRect(nHeight,rcPopup);
	rcPopup.left -=10;// 
	return bRet;
}

效果如下:

20.gif

      

    下一节教程:REDM设计器教程11-显示自定义控件

    

   

文章作者:hgy413
本文地址:http://hgy413.com/3760.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!

14 Responses to “REDM基础教程13-手工增加控件”

  1. #1 minecraft 回复 | 引用 Post:2018-10-04 07:57

    It’s very trouble-free to find out any matter on web as compared
    to books, as I found this piece of writing at this
    web site.

  2. #2 minecraft 回复 | 引用 Post:2018-10-07 02:45

    My brother recommended I might like this blog.
    He used to be entirely right. This publish actually made my day.
    You can not consider simply how so much time I had spent for this info!
    Thank you!

  3. Hey there! Would you mind if I share your blog
    with my myspace group? There’s a lot of folks that I think would really appreciate
    your content. Please let me know. Thank you

  4. I’m really impressed with your writing skills as well as with the
    layout on your weblog. Is this a paid theme or did you modify it yourself?
    Anyway keep up the nice quality writing, it’s rare to see
    a nice blog like this one today.

  5. Do you have a spam issue on this website; I also am a blogger, and I was curious about your situation; we have developed
    some nice practices and we are looking to exchange
    strategies with others, be sure to shoot me an email if interested.

  6. #6 Benefits of Coconut Oil 回复 | 引用 Post:2018-10-21 09:11

    Howdy! I know this is kind of off topic but I was wondering if you knew where I
    could find a captcha plugin for my comment form? I’m using the same blog platform as yours
    and I’m having difficulty finding one? Thanks a lot!

  7. #7 Benefits of Coconut Oil 回复 | 引用 Post:2018-10-27 06:04

    Hi there friends, how is everything, and what you wish for to say concerning this post, in my view its genuinely amazing in support of me.

  8. #8 Benefits of Coconut Oil 回复 | 引用 Post:2018-10-29 23:34

    Inspiring quest there. What happened after? Take care!

  9. #9 descargar facebook 回复 | 引用 Post:2018-11-02 07:22

    I do believe all the concepts you have offered in your post.
    They are very convincing and will definitely work. Still, the posts are very brief for newbies.
    Could you please lengthen them a little from next time?
    Thank you for the post.

  10. #10 quest bars cheap 回复 | 引用 Post:2018-11-04 17:25

    Quest bars cheap fitnesstipsnew1 quest bars cheap 516999410492780544 quest bars
    cheap
    Hello! I just wanted to ask if you ever have any problems with hackers?
    My last blog (wordpress) was hacked and I ended
    up losing several weeks of hard work due to
    no backup. Do you have any solutions to protect against hackers?
    Quest bars cheap fitnesstipsnew1 quest bars cheap 516999410492780544 quest bars
    cheap

  11. #11 Quest Protein Bars 回复 | 引用 Post:2018-11-06 07:34

    I blog often and I seriously thank you for your information. This great article has truly peaked my interest.

    I will bookmark your website and keep checking for new
    information about once a week. I subscribed to your Feed too.

  12. #12 Quest Bars Cheap 回复 | 引用 Post:2018-11-08 19:29

    Wow, this article is good, my sister is analyzing such things, so I am going to convey her.

  13. Hi colleagues, good article and good arguments commented here, I am actually enjoying by these.

  14. I am genuinely thankful to the owner of this web page who has
    shared this enormous paragraph at here.

发表评论