导读
<p>Windows客户端开发的一项重要工作就是用户界面的开发。</p>
<p>不管客户端应用实际包含的逻辑多么复杂、多么优秀,如果这个应用没有提供友好的图形用户界面,也将很难吸引最终用户。相反,如果为应用程序提供了友好的图形用户界面,最终用户通过鼠标点点就可以操作整个应用,这个应用程序就会受欢迎得多。</p>
<p>作为一个程序开发者,必须优先考虑用户的感受,一定要让用户感到爽,我们的程序才会被需要、被使用,这样的程序才有价值。</p>
<p>从趋势上看,用户对Windows客户端界面的要求会越来越高,对Windows界面开发人才的需求也越来越大。对于大部分Windows客户端来说,新增功能50%以上的开发量来自于界面开发,后期迭代70%以上的工作量同样来自界面开发。</p>
<p>虽然界面开发的工作量越来越大,但是MFC、WTL等传统界面库开发效率低下,实现动画、换肤等高级需求困难,同时卡顿、闪烁等一系列问题难以彻底解决,已经无法满足互联网时代多变的需求。</p>
<p>SkinUI是采用DirectUI思想设计和开发的界面库,可广泛用于研发企业级产品的Windows客户端,致力于做最好用的Windows客户端界面库,是现阶段界面开发的不二选择。</p>
<p>SkinUI提供了大量功能丰富的UI组件,开发者只需要按一定的规律把这些UI组件组合起来,就像小朋友“搭积木”一样,把这些UI组件按一定规律搭建在一起就可以开发出优秀的图形用户界面。</p>
<p>SkinUI推荐使用XML文件,而不是C++代码来定义用户界面。实际上,不管使用哪种方式,它们控制SkinUI用户界面行为的本质是一样的。大部分时候,控制UI视图的XML属性都有对应的方法。</p>
<h2>1 使用XML布局文件</h2>
<p>使用XML布局文件来控制视图,不仅简单明了,而且可以将应用的视图控制逻辑从C++代码中分离出来,放入XML文件中控制,从而更好的体现逻辑与界面分离的原则。</p>
<ul>
<li>XML文件:</li>
</ul>
<pre><code class="language-xml"><Dialog DefaultWidth="460" DefaultHeight="251" SysButton="CLOSE" Icon="128" Caption="IDS_ABOUT" Animation="CenterExpand">
<TextView Width="WrapContent" Height="WrapContent" AlignParentHorzCenter="0" AlignParentVertCenter="0" Text="IDS_CONFIG"/>
</Dialog></code></pre>
<ul>
<li>示例代码:</li>
</ul>
<pre><code class="language-c">//作为模态对话框的布局文件
CDialog dlg(_T("TestDialog.xml"));
dlg.DoModal(m_hWnd);</code></pre>
<pre><code class="language-c">//作为非模态对话框的布局文件
CDialog* pDialog = new CDialog(_T("TestDialog.xml"));
if(pDialog)
{
if(!pDialog->Create(m_hWnd))
{
delete pDialog;
}
else
{
pDialog->ShowWindow(SW_SHOW);
}
}</code></pre>
<h2>2 使用C++代码</h2>
<p>虽然SkinUI推荐使用XML布局文件来控制UI界面,但是如果开发者愿意,SkinUI允许开发者完全抛弃XML布局文件,完全在C++代码中控制UI界面。</p>
<p>如果希望在代码中控制UI界面,那么所有的UI组件都将通过new关键字创建出来,然后以合适的方式搭建在一起即可。</p>
<ul>
<li>XML文件:</li>
</ul>
<pre><code class="language-xml"><Dialog DefaultWidth="460" DefaultHeight="251" SysButton="CLOSE" Icon="128" Caption="IDS_ABOUT" Animation="CenterExpand">
</Dialog></code></pre>
<ul>
<li>示例代码</li>
</ul>
<pre><code class="language-c">class CTestDialog : public CDialog
{
public:
CTestDialog();
public:
virtual void OnBuildFinish();
};</code></pre>
<pre><code class="language-c">#include "stdafx.h"
#include "TestDialog.h"
CTestDialog::CTestDialog()
: CDialog(_T("TestDialog.xml"))
{
}
void CTestDialog::OnBuildFinish()
{
CDialog::OnBuildFinish();
CTextView* pTextView = new CTextView(this);
if(pTextView)
{
pTextView->SetWidth(WRAP_CONTENT);
pTextView->SetHeight(WRAP_CONTENT);
pTextView->SetAlignParentHorzCenter(0);
pTextView->SetAlignParentVertCenter(0);
pTextView->SetText(SkinUI::GetString(_T("IDS_CONFIG")));
}
}</code></pre>
<h2>3 XML布局文件和C++代码混合</h2>
<p>完全使用C++代码来控制UI界面不仅繁琐,而且不利于解耦。而完全使用XML布局文件来控制UI界面虽然方便、便捷,但难免有失灵活。因此,有些时候可能需要混合使用XML布局文件和代码来控制UI界面。</p>
<p>当混合使用XML布局文件和代码来控制UI界面时,习惯上把变化小、行为比较固定的组件放在XML布局文件中管理,而那些控制比较复杂的组件则交给C++代码来管理。</p>
<p>例如下面的应用,我们先在布局文件中定义一个简单的树控件, 然后在程序中获取该树控件,并往该树控件添加子节点。</p>
<ul>
<li>XML文件:</li>
</ul>
<pre><code class="language-xml"><Dialog DefaultWidth="460" DefaultHeight="251" SysButton="CLOSE" Icon="128" Caption="IDS_ABOUT" Animation="CenterExpand">
<TreeView Id="1000" Width="MatchParent" AlignParentTop="40" AlignParentBottom="0"/>
</Dialog></code></pre>
<ul>
<li>示例代码:</li>
</ul>
<pre><code class="language-c">void CListDialog::OnBuildFinish()
{
CDialog::OnInitDialog();
CTreeView* pTreeView = dynamic_cast<CTreeView*>(GetChildById(IDC_TREEVIEW));
if(pTreeView)
{
for(int nIndex = 0; nIndex < 10; ++nIndex)
{
CTreeItem* pTreeItem = new CTreeItem(pTreeView);
if(pTreeItem)
{
pTreeItem->SetBackground(_T("ListItem.png"));
pTreeItem->SetLayout(_T("TreeItem.xml"));
pTreeItem->SetHeight(ITEM_HEIGHT_40);
pTreeItem->SetChildText(ID_TEXTVIEW, SkinUI::Format(_T("树节点%d"), nIndex));
pTreeView->InsertItem(NULL, pTreeItem);
}
}
}
}</code></pre>