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
© 2021 jiaocheng.bubufx.com  联系我们
ICP备案:鲁ICP备09046678号-3