前面已經釋出了分離後的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)