DuiVision开发教程(2)-如何写一个简单的界面程序

来源:互联网 发布:红衣主教 知乎 编辑:程序博客网 时间:2024/06/05 15:56

基于DuiVision界面库开发的界面程序主要包括如下几部分内容:
1、资源定义,包括图片资源、各个窗口界面的xml定义文件
2、事件处理类代码,用于处理界面响应消息
3、其他业务逻辑代码
下面举例说明如何写一个简单的界面程序。

第一步:使用VC向导创建一个有两个tab页面的DuiVision工程
duivision_tutor_2-1
duivision_tutor_2-2
duivision_tutor_2-3
向导生成的解决方案文件如下:
duivision_tutor_2-4
默认有两个工程,分别是DuiVision库和应用程序工程。自动生成的代码目录中bin目录下的内容那个如下,bkimg目录存放窗口背景图片,skins目录存放图片资源,xml目录存放字符串定义文件、菜单定义文件、窗口定义文件。
duivision_tutor_2-5

第二步:写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 onceclass 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"//////////////////////////////////////////////////////////////// CDuiHandlerControlCDuiHandlerControl::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// CDuiVisionTutorial1AppBEGIN_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"//////////////////////////////////////////////////////////////// CDuiHandlerMainCDuiHandlerMain::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;}

第四步:编译运行,界面效果如下
duivision_tutor_2-6
duivision_tutor_2-7


DuiVision开源代码下载地址(github):https://github.com/blueantst/DuiVision
蓝蚂蚁工作室主页:http://www.blueantstudio.net
DuiVision QQ群:325880743
微信公众号:blueantstudio 或搜索 蓝蚂蚁工作室

2 1