65.9K
CodeProject 正在变化。 阅读更多。
Home

CustomUI: C# 快速入门指南

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.29/5 (7投票s)

2005 年 8 月 1 日

CPOL

5分钟阅读

viewsIcon

49275

DirectX SDK 中的 C# CustomUI 示例快速指南。

引言

因此,您决定编写下一个大型游戏。您已经成功运行了一个不错的虚拟世界和玩家模型。然后现实来了,您没有用户界面!几个小时后,您最终看到了 DirectX SDK 中的 CustomUI 示例。现实再次来临,这个示例几乎没有文档!

弄懂 CustomUI 示例的最佳方法是尝试使用它。我写这篇指南是为了快速介绍我在自己摸索过程中发现的一些内容。这或许能帮助您开始自己的摸索之旅。

CustomUI 项目可能是 DirectX SDK 中最有趣且最有用的示例,因为几乎所有游戏都需要某种用户界面。我花了一些时间阅读和分析该示例的 C# 版本,并在这里分享我学到的知识。

设计

设计人员基本上是模仿 Windows 控件对其进行建模。有一个 Dialog 类,可以容纳一组控件。初始化对话框后,您可以使用 Dialog 类提供的几种方法将其添加到其中。

Sample screenshot

图 1 – 图显示您可以同时拥有多个对话框。对话框 A 有两个控件,对话框 B 有三个控件。请注意,控件不能存在于对话框之外。

该示例使用 sampleFramework,这是一个执行 DirectX 应用程序所有基本操作的类。实际上,使用它来启动游戏是个不错的方法。sampleFramework 拥有许多方法来执行各种任务,这些超出了本指南的范围。但是,有两个回调函数您应该了解:OneFrameMoveOnFrameRenderOnFrameMove 应包含更改屏幕状态但不绘制它的代码,例如处理游戏事件。OnFrameRender 应包含实际绘制场景的代码。

向对话框添加控件

查看第 394 行的以下代码

Checkbox clearEdit = sampleUi.AddCheckBox(ClearEditControl, 
  "This checkbox controls whether the edit control " + 
  "text is cleared when Enter is pressed.", 
  150, 460, 430, 24, false);

这会将一个复选框控件添加到 sampleUi 对话框中,并返回添加的复选框。第一个参数是 ID(ClearEditControl 是在第 59 行声明的静态 int),第二个是复选框旁边的文本描述。第四、五、六、七个参数是控件的位置和大小,最后一个参数用于设置控件是否为对话框的默认控件。

控件的位置相对于对话框。例如,如果对话框位于位置 (50,100),而对话框内的控件位于 (10,10),则控件的屏幕位置将是 (60, 110)。

另一件需要注意的事情是,sampleUiAddCheckBox 方法只是一个包装器,它调用 AddControls 来设置复选框并将其添加到对话框中。对于其他控件也有类似的包装方法。

控件渲染

对于您添加的每个对话框,都需要在 OnFrameRender 回调函数中调用其 OnRender 方法。这样,对话框就会被绘制,并且对话框内所有控件的 OnRender 方法都会根据需要被调用。控件的 OnRender 是绘制实际控件的地方。

DXUTControls.dds 文件包含用于绘制某些控件的纹理。它在对话框初始化时加载,并加载到 DialogResourceManager 中。DialogResourceManager 确保所有对话框使用的资产只有一份副本,以节省内存。

控件以图层形式绘制。例如,按钮控件有一个绘制按钮形状的图层,还有一个绘制按钮文本的图层。每个图层都有一个 Element 对象,用于定义绘制时要使用的纹理或字体。InitializeDefaultElements 方法定义了每个图层的默认设置。

控件创建

有一个基类 Control,所有控件都从中派生。该基类包含所有控件共有的基本属性。控件在 dxmutgui.cs 中创建,必须继承基类 Control。应使用自定义代码重写 OnRender 方法来绘制控件。

绘图

控件可以通过控件的 Parent 属性访问其父对话框。Dialog 包含所有绘图功能,包括 DrawTextDrawSpriteDrawTextDrawRectangle。它们都将 Element 类作为参数。

Element 类包含有关要使用的纹理或字体的索引等信息,但它本身不包含实际的纹理或字体。实际的纹理和字体存储在 DialogResourceManager 类中。这确保了同一纹理或字体始终只有一个加载副本。

要编写文本,您需要调用对话框的 DrawText 方法,传入文本、Element 以及指定位置(相对于对话框)的矩形。DrawText 将使用传入的 Element 来确定要用于渲染的字体。

同样,要绘制纹理,您需要调用对话框的 DrawSprite 方法,传入一个 Element(其中包含纹理的索引)和一个包含位置信息的矩形。

用户输入处理

您可能知道,Windows 使用消息在内部通信。sampleFrameworkMessageProc 可以截获这些消息。然后,您可以调用对话框的 MessageProc 方法,该方法会将其转发给控件的 MsgProc 方法。消息被分解并处理,然后调用 HandleKeyboardHandleMouse。派生控件可以重写 HandleKeyboardHandleMouse 方法来添加键盘和鼠标处理。

因此,当您添加自己的对话框时,您需要添加一个条目来调用对话框的 MessageProc。这是来自第 340 行的一个示例

// Give the dialog a chance to handle the message first
noFurtherProcessing = hud.MessageProc(hWnd, msg, wParam, lParam);

if (noFurtherProcessing)
    return IntPtr.Zero;

处理控件的事件

处理控件事件非常简单。您只需创建一个方法来处理事件,并使用 EventHandler 将其绑定到控件的事件。例如

edit.Changed += new EventHandler(OnEditChanged);

edit 是一个文本框。当其文本更改时,将调用 OnEditChanged。事件绑定应在将控件添加到对话框后调用。

© . All rights reserved.