Use C ++ and DirectX to develop Gui-resource editor and other

Source: Internet
Author: User

welcome back to part 4 of "using C ++ and DX for GUI development. Next we will focus on all the details about the game gui (How do I develop a GUI for my future games-quaternion.

4.1. Save window
window serialization (storage and loading window) it may not be important for your project. If your game GUI is simple, you can use the Program to implement the window in the game. However, if your GUI is relatively complex or changes frequently as the development process changes, you may want to write a program to save a window (and all its subwindows) to a file, then load it. For beginners, window serialization Code allows you to change the game's Gui without re-compilation. It is also helpful for multi-person coordination.
my plan is to start from the main dialog window, traverse all its subwindows, and save each of them to the disk. If I write a program in C language, the first sentence I tell myself is "Okay, if I have to save these windows, I need a byte for each window to tell me what kind of window it is, so that I can load it correctly. For example, 1 is a button, 2 is a list box, 3 is a chart, and so on ."
this problem is a concern of C ++'s rtti (runtime type identification. Rtti provides two functions: the type_info class and the typeid () function. The two allow me to query the class names of an object, such as gui_window and gui_button. Instead of enumeration and ID, I simply call typid () for each window to be saved and "Write down" the Class Name of the window.
I have noticed two disadvantages of using the rtti object recognition function to help save the window. First, rtti IDs are strings rather than integers, which means they will occupy more space on the disk (the strings stored in Pascal mode will be the first four bytes representing the string length, next is the data of the string itself ). Second, if you change the name of a window class, you will destroy all the existing window files.
you may not use rtti for these reasons. After all, you must use it without technology. However, I found that rtti is a lifeguard for my code. For more information about rtti and these two functions, see your online help document.
In addition, if you decide to use rtti in VC ++, make sure that you open it in the C/C ++ column of the Project attribute and the C ++ language option.

4.2 loading window
Loading windows is a little harder than storing them, mainly because you have to create (new) each window, load it, and delete it when it is no longer needed.
This is a recursive function, expressed in PDL as follows:

Void gui_window: load (INT filehandle)
{
// Read window properties (colorsets, etc .)
// Read Total number of children for this window
// For each child?
// Read window ID from disk
// New A gui_window derivative based on that ID
// Tell the newly created window to load itself (recurse !)
// Next child
}

In other words, you have to load windows from the disk as you think. First, you need to process the base class window: read its properties. Then, read the number of all subwindows of the base class window. Read the ID byte for each subwindow, create a window based on the ID, and load the new window into itself (down to it ). When all the word windows are loaded, it is over.
Of course, it is also important that your file structure is consistent. Make sure that your stored code stores information in the order you want to load.

4.3. resource editor
To make your GUI shine, you must have a resource editor. Of course, you don't need to be as gorgeous and powerful as the resource editor provided by the development environment, but you have to have at least a basic program to complete addition, editing, deletion, and arrangement, this frees you from the trouble of calculating virtual coordinates for each control in the dialog box.
Writing a fully functional WYSIWYG resource editor is beyond the scope of this article, but I can give you some tips to help you accomplish this feat:

Share your code. In particular, let your resource editor share the same rendering code with your game. In this way, you get what you see is what you get, and you don't have to worry about developing two sets of GUI code. I promise you, adjust your DirectX Code to make it render a GDI surface, instead of a dual-buffer system, which makes it easier to develop a new set of drawing code. Remember that after a while your GUI system may change and you do not want to rewrite the code in two different places.

Do not try to imitate the appearance and feeling of the development environment. In other words, do not spend time imitating the details of the development environment (for example, property pages and preview windows ). If your editor is relatively ugly, don't be frustrated. Indeed, the efficiency of the group is directly proportional to the efficiency of the tool he uses, but at the same time, people outside the Group cannot use your resource editor, and you won't use it to develop a complete GUI program. You just need to make a few dialogs. You do not need context sensitive help ). You do not need context menus unless you think this will simplify a specific complex operation. It doesn't matter if your resource editor is not so beautiful, as long as it can complete the work.

Emphasize data integrity rather than speed. Resource editor is a data integrator, not a high-performance program. There is nothing more annoying than what you spent an hour designing is lost due to program errors. When writing your GUI, saving data is your highest goal. Take some time for Automatic Storage, release the buffer (autosaves, undo buffers), and so on. Don't take optimization as important.
4.4 generate a subclass (subclass)
Those familiar with the Win32 processing window may already know the meaning of the term "subclass. If you do not know, When you "subclass" a window, you will "derive (derive)" a new window type, then, embed the new window type into the place where the old window will be used.
Let me explain it in more detail. For example, we need a super list box. We already have a common ListBox class, but it is not suitable for some reason; our games require a super ListBox. Therefore, a super list box class is derived from the common list box class. That's it.
But how do we place this super list box in our game dialog box? Since the super list box is specially designed for our program, we cannot add functions to our resource editor to support it. But at the same time, how do we notify the GUI system for this special instance (our game) so that all the list boxes are super lists? This is what subclass is to do. This is not a precise technical definition, but it expresses enough information.
The method I want to talk about here is called "subclassing at load time )". To understand it, let's start with the basic load code described in the previous section. We have a loading function that completes creation, loading, and adding a window. Here we use PDL to describe the following:

// Read Total number of children for this window
// For each child...
// Read window ID from disk
// New A gui_window derivative based on that ID
//...
// Next child

To complete subclass generation, I asked my window to load the function "give the program a chance to create this type of window", like this:

// Read Total number of children for this window
// For each child...
// Read window ID from disk
// Give application a chance to create a window of this type
// If the application didn't create a window,
// Then new A gui_window derivative Based on the ID
// Else, use the application's created window
//...
// Next child

I use a function pointer to give the program the opportunity. If the program needs to generate a subclass for a window, fill in the address of your function in the function pointer. When a window is loaded, call this function to input the ID of the window to be created. If the program wants to generate a subclass for a window based on the ID, create an appropriate object and return the new pointer to the window. If the program does not need this ID, null is returned. The window function creates an appropriate default object based on the returned value. This method allows the program to "pre-filter" The introduced window ID information, and reload the default function for a specific window type. It's so perfect (Translator: I can't say this translation is perfect. On the contrary, it's just yunyun. I will post the original article here. Please consider it yourself ).
Specifically, I give the application this chance by way of a function pointer. if the application needs to subclass a window, it fills in the function pointer with the address of its own function. when the windows are loading, they call this application function, passing in the ID of the window they want to create. if the application wants to subclass A window from this ID, it news up the appropria Te object and returns the new pointer back to the window. if the app doesn' t want to do anything special for this ID, it returns NULL, and the window function senses this and news up the appropriate default object. this method allows the app to "pre-filter" the incoming window ID bytes, And to override the default behavior for certain window types. perfect!

Using this method gives me a lot of freedom when creating a custom control. I added code for my resource editor so that I could change the ID for each stored window. Then, when I need to customize the control room, I just need to use the resource editor to change the byte that saves the window ID. The ID and all other basic attributes of the custom control are saved on the disk.
Soon? There are other ways to do the same thing, which is used to imitate the methods that STL needs to create objects. STL uses a specific "Allocator" class, which is a bit like a "factories". They create classes based on what customers tell them. You can use this method to create a window.
This method works as follows: Create a class and call it "gui_window_allocator ". Write a virtual function called createwindowoftype. It accepts a given window ID and sends a new pointer to the window. Now you get a simple assignment class, and your window Loading Code will use it to create the required window.
Now, when your program needs to reload the "new" operator for the window, derive a new program-related gui_window_allocator class, and tell your window Loading Code to use this alignator, instead of the default one. This method is like providing a function pointer and only using a little c ++.

4.5. Accelerate GUI Rendering
There is also a small tip that can help you accelerate GUI rendering.
The key concept is not to draw things you don't need, just like optimization of other plotting functions. By default, the GUI takes a lot of time to plot the unchanged part. However, you can make some optimizations by telling the GUI to draw a changed window (Windows that are dirty. When the appearance of the window needs to be changed, the window sets their dirty flag and clears their dirty flag during painting.
Since our GUI control may be transparent, when a control is marked as dirty, its parent window must also be marked as dirty. In this way, when it is drawn, the background is not changed because the parent window has just been re-painted.

4.6. Conclusion: xgdc
Call, long 4 articlesArticleHowever, we have missed a lot.
I'm going to describe the GUI on the upcoming Armageddon xgdc (extreme game developer's Conference. I will try my best to make my speech useful. Now you have read all the articles. If you have any questions about expansion or any omissions, please write me a letter to let me know. Have a good time playing the game.

--------------------------------------------------------------------------------

Author profile:
Mr. Mason mccuskey is the leader in spin studio, a production team that is making a great game named Quaternion. He looks forward to your suggestions and comments. His email is (Mason@spin-studios.com).

Translator's note:
Finally, the long translation process has ended. This is the longest and most difficult technical article that Rick has translated. There must be a lot of errors and omissions. If you find these problems, please send me a letter (Rick_yinhua@sina.com). Thank you for your support.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.