DuiVision开发教程(2)-如何写一个简单的界面程序
基于DuiVision界面库开发的界面程序主要包括如下几部分内容:
1、资源定义,包括图片资源、各个窗口界面的xml定义文件
2、事件处理类代码,用于处理界面响应消息
3、其他业务逻辑代码
下面举例说明如何写一个简单的界面程序。
第一步:使用VC向导创建一个有两个tab页面的DuiVision工程
向导生成的解决方案文件如下:
默认有两个工程,分别是DuiVision库和应用程序工程。自动生成的代码目录中bin目录下的内容那个如下,bkimg目录存放窗口背景图片,skins目录存放图片资源,xml目录存放字符串定义文件、菜单定义文件、窗口定义文件。
第二步:写tab页的xml定义文件
Tab_Home.xml是首页的xml定义文件,写入如下内容(一些图片和文字控件):
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<div pos="0,75,-0,-0" >
<img pos="20,50" width="128" height="128" image="skins\dui.png"
mode="extrude" framesize="1" tip="DuiVision LOGO" />
<text pos="170,50,600,80" crtext="000000" crmark="904000" font="bigbig" title="DUI界面库开发教程" mask="DUI" />
<text crtext="808080" pos="170,90,-30,110"
title="DuiVision开发教程(1)-创建DuiVision工程" />
<text crtext="808080" pos="170,110,-30,130"
title="DuiVision开发教程(2)-如何写一个完整的界面程序" />
</div>
Tab_Control.xml是第二个页面的xml定义文件,写入如下内容(定义一个按钮控件):
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<div pos="0,75,-0,-0" >
<button name="button.about" pos="100,100,200,200" skin="IDB_BT_DEFAULT" img-btn="skins\image\icon_info.png" cursor="hand"
title="图片按钮" tip="图片按钮-显示关于对话框" animate="0" maxindex="4" />
</div>
Xml文件和相关的资源定义在resource.xml文件中:
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--系统配置-->
<res type="cfg" name="defaultStyle" value="" />
<res type="cfg" name="logfile" value="DuiVisionTutorial1.log" />
<res type="cfg" name="loglevel" value="1" />
<res type="cfg" name="appMutex" value="MUTEX_DUIVISION_DuiVisionTutorial1" />
<res type="cfg" name="enableDragFile" value="1" />
<res type="cfg" name="trayDbClickMsg" value="0" />
<!--风格设置-->
<res type="style" name="default" value="" />
<res type="style" name="qq" value="qq" />
<!--XML资源-->
<res type="res" lang="zh-cn" file="xml\def_string_zh-cn.xml" />
<res type="res" lang="en-us" file="xml\def_string_en-us.xml" />
<!--XML资源-默认风格-->
<res type="xml" name="dlg_main" file="xml\duivision\dlg_main.xml" />
<res type="xml" name="dlg_skin" file="xml\dlg_skin.xml" />
<res type="xml" name="dlg_notifymsg" file="xml\dlg_notifymsg.xml" />
<res type="xml" name="dlg_msgbox" file="xml\dlg_msgbox.xml" />
<res type="xml" name="dlg_about" file="xml\duivision\dlg_about.xml" />
<res type="xml" name="dlg_login" file="xml\duivision\dlg_login.xml" />
<res type="xml" name="tab_Home" file="xml\app\tab_Home.xml" />
<res type="xml" name="tab_Control" file="xml\app\tab_Control.xml" />
<res type="xml" name="menu_main" file="xml\duivision\menu_main.xml" />
<res type="xml" name="menu_tray" file="xml\duivision\menu_tray.xml" />
<!--字体资源-->
<res type="font" lang="zh-cn" name="default" font="微软雅黑" size="12" bold="false" />
<res type="font" lang="zh-cn" name="default" font="Tahoma" size="11" bold="false" os="winxp" />
<res type="font" lang="zh-cn" name="bold" font="微软雅黑" size="12" bold="true" />
<res type="font" lang="zh-cn" name="bold" font="Tahoma" size="11" bold="true" os="winxp" />
<res type="font" lang="zh-cn" name="big" font="微软雅黑" size="14" bold="true" italic="false" underline="false" strikeout="false" />
<res type="font" lang="zh-cn" name="big" font="Tahoma" size="12" bold="true" italic="false" underline="false" strikeout="false" os="winxp" />
<res type="font" lang="zh-cn" name="bigbig" font="微软雅黑" size="18" />
<res type="font" lang="zh-cn" name="bigbig" font="Tahoma" size="17" os="winxp" />
<!--图片资源-默认风格-->
<res type="img" name="IDB_TRAY_ICON" file="dui.ico" />
<res type="img" name="IDB_MAIN_FRAME" file="skins\default\WindowsBack.png" />
<res type="img" name="IDB_BT_CLOSE" file="skins\default\BT_CLOSE.png" />
<res type="img" name="IDB_BT_MIN" file="skins\default\BT_MIN.png" />
<res type="img" name="IDB_BT_MENU" file="skins\default\BT_MENU.png" />
<res type="img" name="IDB_BT_SKIN" file="skins\default\BT_SKIN.png" />
<res type="img" name="IDB_BT_SETUP" file="skins\default\BT_SETUP.png" />
<res type="img" name="IDB_BT_DEFAULT" file="skins\default\BT_DEFAULT.png" />
<res type="img" name="IDB_BT_ICON" file="skins\default\BT_ICON.png" />
<res type="img" name="IDB_BT_GREEN" file="skins\default\BT_GREEN.png" />
<res type="img" name="IDB_BT_CANCEL" file="skins\default\BT_CANCEL.png" />
<res type="img" name="IDB_CHECK_BOX" file="skins\default\CHECK_BOX.png" />
<res type="img" name="IDB_RADIO_BUTTON" file="skins\default\RADIO_BUTTON.png" />
<res type="img" name="IDB_EDIT" file="skins\default\EDIT.png" />
<res type="img" name="IDB_COMBO_ITEM" file="skins\default\COMBO_ITEM.png" />
<res type="img" name="IDB_COMBO_ITEM_CLOSE" file="skins\default\COMBO_ITEM_CLOSE.png" />
<res type="img" name="IDB_PROGRESS" file="skins\default\Progress.png" />
<res type="img" name="IDB_PROGRESS_GREEN_BACK" file="skins\default\progress_background_icon.png" />
<res type="img" name="IDB_PROGRESS_GREEN_FORE" file="skins\default\progress_foreground_icon.png" />
<res type="img" name="IDB_SCROLL_V" file="skins\default\SCROLL_V.png" />
<res type="img" name="IDB_BT_SCROLL_UP" file="skins\default\BT_SCROLL_UP.png" />
<res type="img" name="IDB_BT_SCROLL_DOWN" file="skins\default\BT_SCROLL_DOWN.png" />
<res type="img" name="IDB_TAB_SEPERATOR" file="skins\default\Tab_seperator.png" />
<res type="img" name="IDB_TAB_ITEM" file="skins\default\tab.png" />
<res type="img" name="IDB_TAB_BACK" file="skins\default\tab_background.png" />
<res type="img" name="IDB_TAB_HOVER" file="skins\default\toolbar_hover.png" />
<res type="img" name="IDB_LIST_IMG" file="skins\default\list_img.png" />
<res type="img" name="IDB_MSGDLG_BK" file="skins\default\msgdlg_bk.png" />
<res type="img" name="IDB_TREE_COLLAPSE" file="skins\default\tree_collapse.png" />
<res type="img" name="IDB_TREE_TOGGLE" file="skins\default\tree_toggle.png" />
<res type="img" name="IDB_TREE_CHECKBOX" file="skins\default\tree_checkbox.png" />
<res type="img" name="IDB_TREE_ICON" file="skins\default\tree_icon.png" />
<res type="img" name="IDB_BT_SKIN_CUSTOMIZE" file="skins\default\BT_SKIN_CUSTOMIZE.png" />
<res type="img" name="IDB_BT_SKIN_IMAGE" file="skins\default\BT_SKIN_IMAGE.png" />
<res type="img" name="IDB_BT_SKIN_COLOR" file="skins\default\BT_SKIN_COLOR.png" />
<res type="img" name="IDB_SKIN_PUSHED_BKG" file="skins\default\SkinPushedBkg.png" />
<res type="img" name="IDB_SKIN_BKG" file="skins\default\SkinBkg.png" />
<res type="img" name="IDB_DROP_DOWN" file="skins\default\BT_DROP_DOWN.png" />
<res type="img" name="IDB_KEY_BOARD" file="skins\default\BT_KEY_BOARD.png" />
<res type="img" name="IDB_EDIT_USER" file="skins\simage\edit_user.png" />
<res type="img" name="IDB_COMPUTER" file="skins\simage\computer.png" />
<res type="img" name="IDB_EDIT_PWD" file="skins\simage\password.png" />
<res type="img" name="IDB_LINE_RP" file="skins\default\rp_line.png" />
<res type="img" name="IDB_MENU_BACK" file="skins\menu\menu_bkg.png" />
<res type="img" name="IDB_MENU_SEP" file="skins\menu\menu_sep.png" />
<res type="img" name="IDB_MENU_ARROW" file="skins\menu\menu_arrow.png" />
<res type="img" name="SKIN_PIC_0" file="bkimg\SKIN_PIC_0.png" />
<res type="img" name="SKIN_PIC_1" file="bkimg\SKIN_PIC_1.png" />
<res type="img" name="SKIN_PIC_2" file="bkimg\SKIN_PIC_2.png" />
<res type="img" name="SKIN_PIC_3" file="bkimg\SKIN_PIC_3.png" />
<res type="img" name="SKIN_PIC_4" file="bkimg\SKIN_PIC_4.png" />
<res type="img" name="SKIN_PIC_5" file="bkimg\SKIN_PIC_5.png" />
<res type="img" name="SKIN_PIC_6" file="bkimg\SKIN_PIC_6.png" />
<res type="img" name="SKIN_PIC_7" file="bkimg\SKIN_PIC_7.png" />
<res type="img" name="SKIN_PIC_8" file="bkimg\SKIN_PIC_8.png" />
<res type="img" name="IDB_ICON_CHECK" file="skins\image\icon_check.png" />
<res type="img" name="IDB_ICON_INFO" file="skins\image\icon_info.png" />
<res type="img" name="IDB_ICON_QUESTION" file="skins\image\icon_question.png" />
<res type="img" name="IDB_ICON_WARN" file="skins\image\icon_warning.png" />
<res type="img" name="IDB_ICON_ERROR" file="skins\image\icon_error.png" />
<res type="img" name="IDB_MENU_UPDATE" file="skins\menu\MENU_UPDATE.png" />
<res type="img" name="IDB_MENU_AUTH" file="skins\menu\MENU_AUTH.png" />
<res type="img" name="IDB_MENU_HELP" file="skins\menu\MENU_HELP.png" />
<res type="img" name="IDB_MENU_SETUP" file="skins\menu\MENU_SETUP.png" />
<res type="img" name="IDB_SCAN_ANIMATE" file="skins\default\scan_animate.png" />
<!--图片资源-360风格-->
<!--字符串资源-->
<res type="str" lang="zh-cn" name="APP_NAME" value="DuiVision Tutorial 1" />
<res type="str" lang="zh-cn" name="APP_VER" value="1.0.0.1" />
<res type="str" lang="zh-cn" name="APP_COPYRIGHT" value="蓝蚂蚁工作室" />
<res type="str" lang="zh-cn" name="OK" value="确定" />
<res type="str" lang="zh-cn" name="CANCEL" value="放弃" />
<res type="str" lang="zh-cn" name="YES" value="是" />
<res type="str" lang="zh-cn" name="NO" value="否" />
<res type="str" lang="zh-cn" name="LOGIN" value="登录" />
</root>
第三步:写事件处理类代码
首页界面只显示一些静态内容,不需要处理事件,按照默认生成的代码就可以,第二个页面定义了一个按钮控件,需要写一个按钮的点击事件处理函数,在按钮点击之后打开关于对话框,事件处理类的代码如下:
DuiHandlerControl.h
// DuiVision message handler base class
#pragma once
class CDuiObject;
// DUI事件处理类
class CDuiHandlerControl : public CDuiHandler
{
public:
CDuiHandlerControl(void);
virtual ~CDuiHandlerControl(void);
virtual void OnInit();
LRESULT OnDuiBtnShowAbout(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam);
virtual void OnTimer(UINT uTimerID, CString strTimerName);
UINT m_uTimerAni; // 动画定时器
int m_nAniIndex; // 动画索引
// 消息处理定义
DUI_DECLARE_MESSAGE_BEGIN(CDuiHandlerControl)
DUI_CONTROL_NAMEMSG_MESSAGE(L"button.about", MSG_BUTTON_UP, OnDuiBtnShowAbout)
DUI_DECLARE_MESSAGE_END()
};
DuiHandlerControl.cpp
#include "StdAfx.h"
#include "DuiHandlerControl.h"
//////////////////////////////////////////////////////////////
// CDuiHandlerControl
CDuiHandlerControl::CDuiHandlerControl(void) : CDuiHandler()
{
m_uTimerAni = 0;
m_nAniIndex = 0;
}
CDuiHandlerControl::~CDuiHandlerControl(void)
{
}
// 初始化
void CDuiHandlerControl::OnInit()
{
}
// DUI定时器事件处理
void CDuiHandlerControl::OnTimer(UINT uTimerID, CString strTimerName)
{
if(uTimerID == m_uTimerAni)
{
}
}
// 按钮button.about的消息处理
LRESULT CDuiHandlerControl::OnDuiBtnShowAbout(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam)
{
CDlgBase* pDlg = DuiSystem::CreateDuiDialog(_T("dlg_about"), NULL, _T(""), TRUE, 0, TRUE);
if(pDlg == NULL)
{
return FALSE;
}
int nResponse = pDlg->DoModal();
DuiSystem::Instance()->RemoveDuiDialog(pDlg);
return TRUE;
}
向导自动生成的主程序cpp代码(DuiVisionTutorial1.cpp)如下:
// DuiVisionTutorial1.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "DuiVisionTutorial1.h"
#include "DuiHandlerMain.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CDuiVisionTutorial1App
BEGIN_MESSAGE_MAP(CDuiVisionTutorial1App, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CDuiVisionTutorial1App 构造
CDuiVisionTutorial1App::CDuiVisionTutorial1App()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CDuiVisionTutorial1App 对象
CDuiVisionTutorial1App theApp;
// CDuiVisionTutorial1App 初始化
BOOL CDuiVisionTutorial1App::InitInstance()
{
CWinApp::InitInstance();
AfxEnableControlContainer();
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("DuiVisionTutorial1"));
// 初始化DuiVision界面库,可以指定语言,dwLangID为0表示自动判断当前语言
// 11160是应用程序ID,每个DUI应用程序应该使用不同的ID,ID主要用于进程间通信传递命令行时候区分应用
DWORD dwLangID = 0;
new DuiSystem(m_hInstance, dwLangID, _T("DuiVisionTutorial1.ui"), 11160, IDD_DUIVISIONAPP_DIALOG, _T(""));
// 检查是否已经有进程在运行
CString strAppMutex = DuiSystem::Instance()->GetConfig(_T("appMutex")); // 从配置文件中获取互斥量名字
if(!strAppMutex.IsEmpty())
{
::CreateMutex(NULL,TRUE, _T("Global\\") + strAppMutex);
if(ERROR_ALREADY_EXISTS == GetLastError() || ERROR_ACCESS_DENIED == GetLastError())
{
// 读取命令行参数,如果不需要处理命令行可以直接退出
CString strCmd = L"";
if(__argc > 0)
{
strCmd = __targv[0];
DuiSystem::LogEvent(LOG_LEVEL_DEBUG, L"Command line:%s", strCmd);
}
// 发送进程间消息(lParam为1表示不显示界面,appMutex作为应用名,信息参数传递命令行参数)
CString strAppName = DuiSystem::Instance()->GetConfig(_T("appMutex"));
DuiSystem::Instance()->SendInterprocessMessage(0, DuiSystem::Instance()->GetAppID(), 1, strAppName, strCmd);
return FALSE; // Here we quit this application
}
}
// 创建主窗口
CDlgBase* pMainDlg = DuiSystem::CreateDuiDialog(_T("dlg_main"), NULL, _T(""), TRUE);
// 给主窗口注册事件处理对象
CDuiHandlerMain* pHandler = new CDuiHandlerMain();
pHandler->SetDialog(pMainDlg);
DuiSystem::RegisterHandler(pMainDlg, pHandler);
// 初始化提示信息窗口
DuiSystem::Instance()->CreateNotifyMsgBox(_T("dlg_notifymsg"));
// 按照非模式对话框创建主窗口,可以默认隐藏
pMainDlg->Create(pMainDlg->GetIDTemplate(), NULL);
//pMainDlg->ShowWindow(SW_HIDE);
INT_PTR nResponse = pMainDlg->RunModalLoop();
// 如果是按照模式对话框运行主窗口,只要改为如下代码就可以
//INT_PTR nResponse = pMainDlg->DoModal();
// 释放DuiVision界面库的资源
DuiSystem::Release();
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
自动生成的主事件处理类(DuiHandlerMain.cpp)代码如下,在此事件处理类的初始化函数中会创建两个tab页对应的事件处理对象:
#include "StdAfx.h"
#include "DuiHandlerMain.h"
#include "registry.h"
#include "DuiHandlerHome.h"
#include "DuiHandlerControl.h"
//////////////////////////////////////////////////////////////
// CDuiHandlerMain
CDuiHandlerMain::CDuiHandlerMain(void) : CDuiHandler()
{
m_pDlg = NULL;
m_uTimerAni = 0;
m_nAniIndex = 0;
}
CDuiHandlerMain::~CDuiHandlerMain(void)
{
}
// 初始化
void CDuiHandlerMain::OnInit()
{
// 初始化托盘图标
DuiSystem::Instance()->InitTray();
// 将tab页‘首页‘注册事件处理对象
CDuiHandlerHome* pDuiHandlerHome = new CDuiHandlerHome();
DuiSystem::RegisterHandler(m_pDlg, pDuiHandlerHome, _T("tab.Home"));
pDuiHandlerHome->OnInit();
// 将tab页‘控件‘注册事件处理对象
CDuiHandlerControl* pDuiHandlerControl = new CDuiHandlerControl();
DuiSystem::RegisterHandler(m_pDlg, pDuiHandlerControl, _T("tab.Control"));
pDuiHandlerControl->OnInit();
// 启动动画定时器
m_uTimerAni = DuiSystem::AddDuiTimer(500);
}
// 皮肤消息处理(实现皮肤的保存和获取)
LRESULT CDuiHandlerMain::OnDuiMsgSkin(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if(Msg == MSG_GET_SKIN_TYPE) // 获取Skin类型
{
CRegistryUtil reg(HKEY_CURRENT_USER);
int nBkType = reg.GetDWordValue(NULL, REG_CONFIG_SUBKEY, REG_CONFIG_BKTYPE);
*(int*)wParam = nBkType;
return TRUE;
}else
if(Msg == MSG_GET_SKIN_VALUE) // 获取Skin值
{
CRegistryUtil reg(HKEY_CURRENT_USER);
if(wParam == BKTYPE_IMAGE_RESOURCE)
{
*(int*)lParam = reg.GetDWordValue(NULL, REG_CONFIG_SUBKEY, REG_CONFIG_BKPIC_RES);
return TRUE;
}else
if(wParam == BKTYPE_COLOR)
{
*(COLORREF*)lParam = reg.GetDWordValue(NULL, REG_CONFIG_SUBKEY, REG_CONFIG_BKCOLOR);
return TRUE;
}else
if(wParam == BKTYPE_IMAGE_FILE)
{
*(CString*)lParam = reg.GetStringValue(NULL, REG_CONFIG_SUBKEY, REG_CONFIG_BKPIC_FILE);
return TRUE;
}
}else
if(Msg == MSG_SET_SKIN_VALUE) // 设置Skin值
{
CRegistryUtil reg(HKEY_CURRENT_USER);
reg.SetDWordValue(HKEY_CURRENT_USER, REG_CONFIG_SUBKEY, REG_CONFIG_BKTYPE, wParam);
if(wParam == BKTYPE_IMAGE_RESOURCE)
{
reg.SetDWordValue(HKEY_CURRENT_USER, REG_CONFIG_SUBKEY, REG_CONFIG_BKPIC_RES, lParam);
}else
if(wParam == BKTYPE_COLOR)
{
reg.SetDWordValue(HKEY_CURRENT_USER, REG_CONFIG_SUBKEY, REG_CONFIG_BKCOLOR, lParam);
}else
if(wParam == BKTYPE_IMAGE_FILE)
{
CString* pstrImgFile = (CString*)lParam;
reg.SetStringValue(HKEY_CURRENT_USER, REG_CONFIG_SUBKEY, REG_CONFIG_BKPIC_FILE, *pstrImgFile);
}
return TRUE;
}
return FALSE;
}
// 托盘双击消息处理
LRESULT CDuiHandlerMain::OnDuiMsgTrayIconDClick(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam)
{
DuiSystem::ShowDuiDialog(_T("dlg_login"), NULL);
return TRUE;
}
// DUI定时器事件处理
void CDuiHandlerMain::OnTimer(UINT uTimerID, CString strTimerName)
{
if(uTimerID == m_uTimerAni)
{
}
}
// 进程间消息处理
LRESULT CDuiHandlerMain::OnDuiMsgInterprocess(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam)
{
// 命令行参数,可以对命令行参数进行处理,也可以直接显示主窗口
DUI_INTERPROCESS_MSG* pInterMsg = (DUI_INTERPROCESS_MSG*)lParam;
CString strCmd = pInterMsg->wInfo;
if(!strCmd.IsEmpty())
{
DuiSystem::DuiMessageBox(NULL, L"执行了命令行参数:" + strCmd);
}else
{
CDlgBase* pDlg = DuiSystem::Instance()->GetDuiDialog(L"dlg_main");
if(pDlg)
{
pDlg->SetForegroundWindow();
pDlg->ShowWindow(SW_NORMAL);
pDlg->ShowWindow(SW_SHOW);
pDlg->BringWindowToTop();
}
}
return TRUE;
}
第四步:编译运行,界面效果如下
文章来自:http://blog.csdn.net/oceanheart/article/details/45776075