2024年3月6日发(作者:)

3.3控件集成实现

控件的基本用法和通信机制熟悉之后, 我们需要做的是把控件集成实现。由于游戏工具开发既要考虑实用性,也要考虑规范性和美观性。游戏工具的开发侧重于内容的实现,对于界面和界面上的控件集成,不需要花费太多的时间和精力。本书的控件集成实现采用业界流行的界面库来讲解,这样既能做出美观的界面。由能减少很多的编码工作量提高制作游戏工具的效率。

界面库一般都是由C/C++这种中低级语言编码,因为在Windows下的界面库实现技术大都以直接操作控制Windows的消息和调用Windows的API为主。这些基础的知识我们在以前的章节中都讲解过。所以如果大家有兴趣书写自己的界面库,可以借鉴开源的界面库进行编写。 无论何种界面库,最为根本的原理就是获得或者截获窗口的某些消息,按照自己的需要处理这些消息,绘制出自己需要的界面。

按照Windows下的界面库的使用方法来分类,可以分为两种:

1、 通过派生、继承界面库中的类来使用库。这类界面库现在是占绝大多数。这类界面库通常可以对同种类型的控件、窗口自己控制显示风格。这种类型的界面库典型的代表就是GuiToolkit、ProfUIS。

2、 通过Link头文件,使用DLL来使用的界面库。这类界面库一般都是商业化的界面库。这类界面库一般对于同种类型的控件、窗口都是显示统一的风格。这种类型的界面库的典型代表是Skin++、AppFace。

下面介绍几种常见的界面库

ClassXP(个人写的开源,不是很完善)

/?26

ProfUIS(部分开源,商用,效果不错)

/docking/prod_

GuiToolkit(开源,类似VS风格)

/

GardenUI(免费,界面效果不错,用配置文件做分离处理使用方便)

/

CJLib(开源,免费,是xtreme toolkit的前生,但xtreme toolkit收费了)

/

LibUIDK(部分免费,不开源,专业MFC界面库)

/

BCGControlBar(商用收费,界面不错)

SKin++(收费,界面非常精美)

/

SkinMagic(收费,使用方便,界面效果不错)

/html/

SYGUI(收费, 功能齐全)

/

CJ60Lib(免费,6.09版本以后商用(收费) mfc扩展库很实用)

/kstowell/

以上是常用的界面库的说明和链接,大家可以根据自己的需求和爱好选择自己喜欢的界面库。下面介绍几个功能强大的界面库的用法。

CJ60Lib是原来的库(MFCXLib)已经更名后的名称,这是为了与那些使用旧库的程序区别开来。本库与旧的库具有同样的功能。但是,针对Visual C++ 6.0作了几个扩展,这个扩展库是几位高手共同完成的是开源免费的。6.09版本是其最终的一个版本,其后的版本将走入商业化了。这里介绍CJ60Lib这库的目的是为喜欢Visual C++ 6.0开发的程序员提供一种界面制作的方法。虽然现在用的主要是Microsoft Visual Studio 2003,2005,但是Visual C++ 6.0的”粉丝”还是相当的多。

下面是关于CJ60Lib类的一些基本的介绍:

CCJButton - ( and CJButton.h )

MFC中CButton类的改进。 这个类是为了处理在CCJControlBar类中的最小化和关闭按钮。能处理扁平按钮。

CCJComboBox - ( and CJComboBox.h )

MFC中CComboBox类的改进。这个类是为了处理扁平外观的组合框,就象在微软的Office系列产品中看到的一样。它很容易使用,只要将所有有CComboBox的地方替换为CCJComboBox即可。

CCJControlBar - ( and CJControlBar.h )

MFC中CControlBar类的改进。 这个类是基于CristiPosea写的CSizingControlBar类基础之上的。 添加了更多的外观给这个控件,包括最小和最大化按钮、把手、按钮浮动提示、弹出菜单支持和垂直及水平sizebar指针。

CCJFrameWnd - ( and CJFrameWnd.h )

CCJMDIFrameWnd - ( and CJMDIFrameWnd.h )

CCJDockBar - ( and CJDockBar.h )

这些类重载了缺省的主框架布局,以增加3D效果到工具条。为了使用这些类,仅将

CFrameWnd 改为 CCJFrameWnd,其中,CMainFrame 包含在 Mainfrm.h文件中,(对于MDI,采用CCJMDIFrameWnd)。

CCJOutlookBar - ( and CJOutlookBar.h )

新增类,用于实现Outlook中的工具条。

CCJPagerCtrl - ( and CJPagerCtrl.h )

新增类,用于设置标签视或者对话框。

CCJTabCtrlBar - ( and CJTabCtrlBar.h )

新增类。

CCJToolBar - ( and CJToolBar.h )

MFC中CToolBar类的改进。

CCoolMenuManager -( , and CoolMenu.h )

CSubclassWnd -( and Subclass.h )

新增类,用于改进已有的菜单。

CFlatToolBar - ( and FlatBar.h )

Obsolete with VC 6.0

CModuleVersion - ( and ModulVer.h )

这是CCJToolBar的基类。

CCoolBar, CRebarInfo - ( and CoolBar.h )

Obsolete with VC 6.0 新增类,用于实现Internet Explorer 4风格的工具条。

CHyperLink - ( and HyperLink.h )

超链接控件。

图3-22 CJ60Lib类继承图

CJ60Lib类库的使用方法和IDE环境的设置

在【Project Settings】中选择【General】标签,【Microsoft Foundation Class】设置为 Use MFC in a shared DLL。

在【Project Settings】中选择【Link】标签,设置【Category】为Input,增加../Lib到Additional Library Path。

在【Link】标签中,改变Category为General,Output Name (所有配置)设置为../Lib。

选择【C/C++】标签,改变Category为Preprocessor,增加../Include到Additional

Include Directories.

最后一步是添加下面两行代码到StdAfx.h头文件中:

#define MFCX_PROJ

#include

为了能静态链接到CJ60Lib,需要做下面修改:

在【project settings】对话框中,选择【General】标签,确保【Microsoft Foundation

Class】设置为Use MFC in a static library。

添加下面代码到StdAfx.h 头文件,其将使库静态链接到应用程序:

#define MFCXLIB_STATIC

#define MFCX_PROJ

#include

图3-23 界面效果

GuiLib1.6是另一套Windows界面库,它是国外人写的一个免费的基于MFC界面库。功能非常强大,可以制作出类似PowerPoint, Outlook, Visual Studio 2005等各种界面。既美观又实用。GuiLib1.6的版本可以针对Visual Studio 2005进行界面开发。由于GuiLib是基于MFC的扩展库,所以在普遍采用MFC做游戏开发工具的游戏业界来说,使用它既方便又实用。

要使用前首先下载GuiLib1.6。由于GuiLib1.6是免费开源的。所以我们可以下载到它的源代码。进行编译以便生成我们需要的lib和dll库文件。

编译之前需要注意要把GuiADODB.h头文件中的如下语句

#import "C:Program FilesFichiers " rename_namespace("ADOCG")

rename("EOF", "EndOfFile")

改为:

#import "C:Program FilesCommon " rename_namespace("ADOCG")

rename("EOF", "EndOfFile")

这样编译链接才不会出现问题。

如果想利用GuiLib1.6进行自己的界面开发需要加入GuiLib1.6的include和Lib这样保证将来再程序的编译和运行时候不会出现错误。运行时候需要提供,,,这四个动态链接库保证程序能在Debug或Release模式都能运行。具体操作如下图所示:

图3-24 包含目录的添加

图3-24 lib库的添加

由于GuiLib1.6是基于MFC的扩展库,所以在使用的过程中,我们可以直接采用MFC的的方式新建项目。然后在项目的基础进行改装。例如:先新建一个基于单视图的MFC的应用程序。

在MainFrm.h中把CMainFrame的基类CFrameWnd改写成CGuiFrameWnd,CGuiFrameWnd是GuiLib集成好的框架基类比CFrameWnd功能更强大。可以在框架上集成我们想要的各种功能。代码如下:

#if !defined(AFX_MAINFRM_H__57C35901_B6A0_45DC_9229_2697767F4931__INCLUDED_)

#define AFX_MAINFRM_H__57C35901_B6A0_45DC_9229_2697767F4931__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "GuiFrameWnd.h"

class CMainFrame : public CGuiFrameWnd

{

protected: // create from serialization only

CMainFrame();

DECLARE_DYNCREATE(CMainFrame)

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

//}}AFX_VIRTUAL

public:

// Implementation

public:

// Generated message map functions

protected:

};

#endif // !defined(AFX_MAINFRM_H__57C35901_B6A0_45DC_9229_2697767F4931__INCLUDED_)

//{{AFX_MSG(CMainFrame)

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code!

virtual ~CMainFrame();

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#ifdef _DEBUG

#endif

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

下面添加一个做工具条控制的类CGuiFolderVisio具体如下:

#include "GuiControlBar.h"

#include "GuiContainer.h"

#include "GuiVisioFolder.h"

class CGuiFolderVisio : public CGuiControlBar

{

protected:

};

CGuiVisioFolder m_fv;

CGuiContainer m_ctServer;

CTreeCtrl m_tree;

CGuiFolderVisio();

virtual ~CGuiFolderVisio();

DECLARE_MESSAGE_MAP()

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

public:

#include "stdafx.h"

#include "GuiVisioDemo.h"

#include "GuiFolderVisio.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

CGuiFolderVisio::CGuiFolderVisio()

{

}

CGuiFolderVisio::~CGuiFolderVisio()

{

}

BEGIN_MESSAGE_MAP(CGuiFolderVisio, CGuiControlBar)

ON_WM_CREATE()

END_MESSAGE_MAP()

int CGuiFolderVisio::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CGuiControlBar::OnCreate(lpCreateStruct) == -1)

return -1;

return -1;

if (!m_(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),this,124))

// TODO: Add your specialized creation code here

if (!m_(WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), &m_ctServer, 125))

return -1;

m_ponen(&m_fv);

m_geList(IDB_BITMAP1,16,3,RGB(255,0,0));

}

m_(WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT |

m_der(&m_tree,"ToolBox1",0);

return 0;

TVS_HASBUTTONS,CRect(0,0,0,0),&m_fv,126);

然后再框架类(CMainFrame)中加入两个私有成员用来创建控件。

protected: // control bar embedded members

CGuiComboBoxExt m_combMenu;

CGuiFolderVisio m_OutNormal;

在OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加如下代码:

m_Style(m_Style() |

CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

// TODO: Delete these three lines if you don't want the toolbar to

// be dockable

EnableDocking(CBRS_ALIGN_ANY);

m_Docking(CBRS_ALIGN_ANY);

m_eHistory("HistoryVisio",TRUE);

m_Combo(&m_combMenu,IDC_COMBOMENU,150);

DockControlBar(&m_wndMenuBar,m_dockTop);

DockControlBar(&m_wndToolBar,m_dockTop);

m_Docking(CBRS_ALIGN_ANY);

DockControlBar(&m_OutNormal, AFX_IDW_DOCKBAR_LEFT);

m_Docking(CBRS_ALIGN_ANY);

实现的效果如下:

图3-25 GuiLib实现的效果

下面是利用GuiLib编写的其他界面的效果具体代码可以参照给定的例子。

图3-26 GuiLib实现OutLook 效果

图3-27 GuiLib实现Office 效果

图3-28 GuiLib实现PowerPoint效果

图3-29 GuiLib实现VS