Share via


(SDK root)\Samples\Managed\Direct3D\CustomUI

This sample is a simple demonstration of the user interface (UI) subsystem implemented by the Microsoft DirectX 9.0 for Managed Code sample framework. The sample framework provides code and infrastructure common to most DirectX 9.0 for Managed Code applications. One area of the framework is user interface support. The sample framework contains commonly used control objects, such as buttons and check boxes, that both windowed and full screen Microsoft Direct3D applications can use to implement their user interfaces.

CustomUI sample

Supported Languages

  • C#

Path

Source: (SDK root)\Samples\Managed\Direct3D\CustomUI
Executable: (SDK root)\Samples\Managed\Direct3D\Bin\x86\csCustomUI.exe

How the Sample Works

This sample demonstrates how an application that uses the DirectX 9.0 for Managed Code sample framework can take advantage of the framework's UI support. The sample framework supports the following control types:

Control type Class that implements it
Statics Microsoft.Samples.DirectX.UtilityToolkit.StaticText
Buttons Microsoft.Samples.DirectX.UtilityToolkit.Button
Radio buttons Microsoft.Samples.DirectX.UtilityToolkit.RadioButton
Check boxes Microsoft.Samples.DirectX.UtilityToolkit.Checkbox
Combo boxes Microsoft.Samples.DirectX.UtilityToolkit.ComboBox
List boxes Microsoft.Samples.DirectX.UtilityToolkit.ListBox
Sliders Microsoft.Samples.DirectX.UtilityToolkit.Slider
Scrollbars Microsoft.Samples.DirectX.UtilityToolkit.Scrollbar
Edit boxes Microsoft.Samples.DirectX.UtilityToolkit.EditBox

All of the sample framework controls work similarly to Microsoft Windows controls. They are implemented entirely from scratch and with the exception of the EditBox do not use any Windows control underneath. They are also rendered with Direct3D, and therefore can be used by both windowed and full screen Direct3D applications.

This sample starts by defining two Dialog objects: hud and sampleUi. A Dialog serves as a container that encapsulates one or more controls. It sits between the application and the controls, so that the application can pass messages and rendering calls to Dialog, and Dialog will ensure that all of its controls receive the messages and get rendered properly. The controls themselves are designed to be used with a Dialog, not stand-alone. Applications are not limited to one Dialog object. They can use more at once, as this sample does.

As the user interacts with the UI controls, the controls can notify the sample about important events, so that it can respond accordingly. At this time the sample also initializes additional fonts that it will need. This is done with the SetFont method.

The next step that the sample has to do is create the controls it needs. This is achieved by calling the Dialog's AddXXX methods, such as AddButton. In the sample, hud contains 3 buttons that provide standard functionalities that Direct3D samples have: toggle between Hardware and Reference devices, and changing 3D device settings. sampleUi contains the rest of the controls, which are sample-specific. After a control is added, its appearance can be modified. This is demonstrated in the sample as it modifies the appearance of the static controls as well as the combo box. At creation the appropriate events are hooked for each control and responded to in the event handler methods.

Next, in OnResetDevice, are a number of calls to the Dialog's and controls' SetSize and SetLocation methods. This is because when the user resizes the application window, some dialogs and controls need to be resized and repositioned as well. It is worth noting that the Dialog's location is relative to the application window, while a control's location is relative to the Dialog it belongs.

To render the user interface, the sample calls the OnRender method of the two Dialog objects in its OnFrameRender function. Dialog will render the controls it contains in the correct order.

The final step required to make the UI work is passing messages to the controls. This lets them receive keyboard and mouse events from the user. In MsgProc, the sample calls Dialog's MsgProc method to pass down the messages. It is very important that if Dialog's MsgProc returns true indicating that the message has been handled, the sample sets the noFurtherProcessing parameter to true and returns immediately. Failure to do so will cause a message to be processed more than once.

Events

Certain events happen as the user interacts with the UI controls, such as checking or unchecking a check box, selecting a new item in a combo box, selecting a new item in a radio button group, etc. The application may be interested in such events, and it can be notified with controls events. In the sample, a series of event handler functions are defined and hooked as the controls are created. As a result, these functions will get called whenever the user performs an interesting action with a UI control. The actions that can trigger a callback are:

  • Clicking a button (Button)
  • Selecting a new item in a combo box (ComboBox)
  • Selecting a new item in a radio button group (RadioButton)
  • Changing the check state of a check box (CheckBox)
  • Changing the value of a slider (Slider)
  • Pressing Enter in an edit box (EditBox and EditBox)

In the event handlers, the control that fired the event and any necessary extra data are available to the application. The sample responds to the events by retrieving content of the firing control and displaying it on screen.