天天看點

金山衛士界面源碼解讀及界面庫分離(2)

前面已經釋出了分離後的Kui代碼,我們繼續,下面來解釋該代碼庫的使用.

首先要說下Kui架構的一些基礎概念:

 一、

金山界面庫不使用Windows的視窗布局,隻是使用Windows的視窗作為一個載體,整個視窗都隻是作為一個繪制面,

而Kui對視窗實行重新布局,取消了原視窗非客戶區和客戶區的概念.而自己對視窗劃分為上中下三個部分.

上部分為Header,一般作為視窗标題欄,可以放置縮小,最大化,關閉按鈕,

中部分為Body,是視窗主要功能操作區域,

下部分為Footer,一般作為狀态顯示.

這部分說明主要是為了以後寫XML時使用. 

 二、

Kui将使用到的諸如圖檔,布局定義xml等檔案使用zip打包,并按資源名"kuires.dat",資源類别為"SKIN",儲存到運作程式的資源裡

 三、

Kui庫使用xml格式定義控件及資源的布局,這也是通常DirectUI的做法(xml布局,腳本控制[Kui裡面沒使用],windowless)。

有了以上的概念就可以使用Kui來進行界面開發了。

同學們可以參考第一個樣例程式----該程式在客戶區顯示經典的hello world.并且對視窗外框進行了美化。

一、建立工程

首先使用向導建立一個Win32程式,對!是Win32程式,選擇了Kui,你将不能使用MFC程式設計了,因為沒有了MFC的視窗概念。

你将應用微軟的另一個庫進行程式開發----WTL。

好處就是開發出來的程式不會那麼臃腫了,缺點嘛,就是沒有MFC那麼友善了。

不過習慣了也沒什麼的。都是同一家公司的技術,是以肯定各有好處。

二、編寫入口程式

首先當然是包含庫檔案,在stdafx.h中定義

// 界面庫

#include "../../include/KUILib.h"

然後寫入口函數

WTL的程式都有一個程式執行個體,與MFC的CWinApp對應,但Kui對它進行了繼承以完成了一些初始化操作,你可以直接使用該類來定義執行個體。如Sample1所示:

HINSTANCE g_hInstance; // 定義執行個體句柄,必須的。

CKuiApp<CMainWnd> _Module;//用Kui的預設類,其中CMainWnd是模版參數,是使用的主視窗類,後面會解釋,定義一個執行個體,你也可以繼承新的類。

CAppModule* _ModulePtr = &_Module;// 定義執行個體指針,必須的。

完整代碼:

#include "stdafx.h"

#include "./mainwnd.h"

//

HINSTANCE g_hInstance;

//

CKuiApp<CMainWnd> _Module;

CAppModule* _ModulePtr = &_Module;

//

//

int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

g_hInstance = hInstance;

_Module.Init( hInstance );

_Module.Main();

_Module.UnInit();

return 0;

}

三、視窗函數定義

下面接着要編寫主視窗類了

其中頭檔案MainWnd.h如下:

#pragma once

#include "stdafx.h"

class CMainWnd : public CKuiDialogImpl<CMainWnd>

, public CWHRoundRectFrameHelper<CMainWnd>

{

public:

CMainWnd(void);

virtual ~CMainWnd(void);

void OnDestroy();

void OnBkBtnClose();

void OnBkBtnMax();

void OnBkBtnMin();

KUI_NOTIFY_MAP(IDC_RICHVIEW_WIN)

KUI_NOTIFY_ID_COMMAND(60001, OnBkBtnClose)

KUI_NOTIFY_ID_COMMAND(60002, OnBkBtnMax)

KUI_NOTIFY_ID_COMMAND(60003, OnBkBtnMin)

//KUI_NOTIFY_TAB_SELCHANGE(IDC_TAB_MAIN, OnBkTabMainSelChange)

KUI_NOTIFY_MAP_END()

BEGIN_MSG_MAP_EX(CMainWnd)

MSG_KUI_NOTIFY(IDC_RICHVIEW_WIN)

CHAIN_MSG_MAP(CKuiDialogImpl<CMainWnd>)

CHAIN_MSG_MAP(CWHRoundRectFrameHelper<CMainWnd>)

//MSG_WM_INITDIALOG(OnInitDialog)

//MSG_WM_SYSCOMMAND(OnSysCommand)

MSG_WM_DESTROY(OnDestroy)

REFLECT_NOTIFICATIONS_EX()

END_MSG_MAP()

};

實作檔案MainWnd.cpp如下:

#include "stdafx.h"

#include "./mainwnd.h"

CMainWnd::CMainWnd(void) : CKuiDialogImpl<CMainWnd>( "IDR_DLG_MAIN" )

{

}

CMainWnd::~CMainWnd(void)

{

}

void CMainWnd::OnDestroy()

{

PostQuitMessage(0);

}

void CMainWnd::OnBkBtnMax()

{

if (WS_MAXIMIZE == (GetStyle() & WS_MAXIMIZE))

{

SendMessage(WM_SYSCOMMAND, SC_RESTORE | HTCAPTION, 0);

}

else

{

SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE | HTCAPTION, 0);

}

}

void CMainWnd::OnBkBtnMin()

{

SendMessage(WM_SYSCOMMAND, SC_MINIMIZE | HTCAPTION, 0);

}

void CMainWnd::OnBkBtnClose()

{

DestroyWindow();

}

下面對代碼關鍵部分進行說明:

主視窗繼承自兩個類

CKuiDialogImpl<CMainWnd> 是對話框視窗實作模版,主視窗繼承自該類,沒有接觸模版的同學可能對該寫法有些奇怪,看看模版介紹就可以了。

CWHRoundRectFrameHelper<CMainWnd> 是一個異型視窗輔助,實作了圓角視窗。

KUI_NOTIFY_MAP(IDC_RICHVIEW_WIN)

KUI_NOTIFY_ID_COMMAND(60001, OnBkBtnClose)

KUI_NOTIFY_ID_COMMAND(60002, OnBkBtnMax)

KUI_NOTIFY_ID_COMMAND(60003, OnBkBtnMin)

KUI_NOTIFY_MAP_END()

上面這些宏映射了控件通知到相應的函數

BEGIN_MSG_MAP_EX(CMainWnd)

MSG_KUI_NOTIFY(IDC_RICHVIEW_WIN)

CHAIN_MSG_MAP(CKuiDialogImpl<CMainWnd>)

CHAIN_MSG_MAP(CWHRoundRectFrameHelper<CMainWnd>)

//MSG_WM_INITDIALOG(OnInitDialog)

//MSG_WM_SYSCOMMAND(OnSysCommand)

MSG_WM_DESTROY(OnDestroy)

REFLECT_NOTIFICATIONS_EX()

END_MSG_MAP()

上面這些宏映射了視窗消息到對應函數。

這些代碼作用跟MFC的消息映射作用是一樣的,但實作手法有些差異。其實WTL的更原始。

實作部分的代碼就比較簡單了。

四、最後就是資源的添加了。

可以參考Sample1.rc檔案,直接在相應位置添加一行

kuires.dat    SKIN     "res//sample1.kui"

至此Kui庫整個使用過程就是如此簡單。

你需要做的就是定義主視窗的消息處理及函數而已。

本項目已經在GOOGLE的開源項目裡建立了工程,如果你有興趣加入可以聯系我。

svn https://openkui.googlecode.com/svn/trunk

本程式代碼可以在第一篇裡下載下傳

金山衛士界面源碼解讀及界面庫分離(1)