Develop GUI - Resource Editor and Other C and DirectX
Welcome to the fourth part of "Developing the C and DX Development GUI". Then we've the subject (how do I develop GUI-Quaternion for my future game, this article will pay attention to all the details of the game GUI.
4.1 Saving Window Window Serialization (Storage and Load Window) may not be important for your project. If your game GUI is very simple, you can fully rely on the program to implement the window in the game. But if your GUI is relatively complicated, or as the process of development often changes, you will want to write the program to save a window (and all its sub-windows) to the file, and then load it. For beginners, window serialization code allows you to change the GUI of the game without recompilation, and it is also beneficial for multiplayer coordination. My plan is to start from the primary dialog window, and then traverse all the sub-windows, save each one on the disk. If I use the C language to write a program, I tell my first sentence "Ok, if I have to save these windows, I need a byte to tell me what window it is, so that I can load it correctly. For example, 1 is button, 2 is a list box, 3 is chart, and so on. "This problem is C RTTI (running type identification) care. RTTI provides two stuff, type_info classes, and typeid () functions, which allow me to query the class name name of an object, such as GUI_Window, Gui_Button, and more. I didn't use enumeration and id, but simply call Typid (), and "Write" window name names for each window to be saved. I noticed the use of the RTTI object identification function to help save the two small disadvantages of the window. First, the RTTI ID is a string instead of integer, which means that they will occupy more spaces on the disk (in the PASCAL mode memory string will be the length of the first 4 bytes representing the string, next is the string Bible data). Second, if you change the name of a window class, you will destroy all of the stored window files. For these reasons, you may not use RTTI like this. After all, it is not technically necessary to use it. However, I found that RTTI is a lifeguard for my code. To get more information about RTTI and these two functions, please find it in your online help documentation. Also, if you decide to use RTTI in VC , make sure you open it in the C / C column of the engineering property and the C language option.
4.2 Loading Windows Load Window is more difficult to store them, this is mainly because you have to create a new (New) per window, load, and delete when it no longer needs. This is a recursive function, and if the PDL is expressed 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 the window from the disk as you think. First, to process the base class window: read his properties. Then, read the number of all sub-windows of the base class window. For each sub-window, read the ID byte, create a window according to the ID, then let the new window load yourself (low to it). When all the wording ports are loaded, it is over. Of course, your file structure is also very important. Make sure your storage code stores information in order you want to load. 4.3, resource editor wants to really make your GUI big light color, you must have a resource editor. Of course, you don't need to be gorgeous and powerful as the resource editor provided by the development environment, but you can at least have a basic program to complete the join, edit, delete, arrange, exempt your control for each control you dialog box. The trouble of coordinate position. Writing a resource editor of a functionally, what you get (Wysiwyg) is beyond the scope of this article, but I can give you some tips to help you complete this feat:
Share your code. In particular, let your resource editor share the same rendering code together with your game. In this way, you have got ready to support, and eliminate the trouble of developing two sets of GUI code, I assure you to adjust your DirectX code to render it to a GDI surface rather than a double buffer system will be developed A new set of new drawing code is simple. After a while, your GUI system may change, you wanted to rewrite the code often in two different places.
Do not try to imitate the appearance and feeling of the development environment. In other words, do not charge the time to imitate the details of the development environment (for example, the property page, and preview window). If your editor is relatively ugly, don't be frustrated; it is indeed that the efficiency of the group is directly proportional to the effect of the tool he use, but at the same time, people outside the group cannot use your resource editing. If you don't use it to develop a complete GUI program; you just do a few dialogs. You don't need environmental text help (CONTEXT SENSITIVE HELP). You don't need the environmental text menu, unless you think this simplifies a specific complicated operation. If your resource editor is not so beautiful, it doesn't matter, as long as it can complete the work.
Emphasize data intact rather than speed. The resource editor is a data integrator, not a high-performance program, nothing more than a hit, is more annoyed due to the program error. When you write your GUI, saving the data is your highest goal. It takes some time to do automatic storage, release buffers, etc., Don't see optimization is so important. 4.4 Generated Subclass, those who are familiar with the Win32 processing window may already know the meaning of "subclass". If you don't know, when you "Subclass", you "Derive" a new window type, then embed the new window type to the place where you want to use. Let me explain more detailed. For example, we need a super list box. We already have an ordinary list of boxes, but because of some reason it is not suitable; our game requires a super list box. So we derive a super list box class from the ordinary list box class. That's it. But how do we place this super-list box in our game dialog? Since the super list box is specially made for our program, we cannot add a function to our resource editor to support it. But at the same time, how do we inform the GUI system for this special instance (our game), let all the list boxes are super-list boxes? This is what the generated subclass (Subclass) is going to do. This is not a precise technical definition, but it has expressed enough information. The method I want to tell here is called "Subclassing At Load Time". To understand it, let us start from the basic load code described in the previous section. We have a load function that completes the creation, load, and adds a window. Here we use the PDL to express 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 what id // ... // next Child
To complete the generated subclass, I let my window load 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 ... // r c i d / // Give Application a chance to create a window of this type // i 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 give this opportunity through a function pointer. If the program needs to generate a subclass for a window, fill in the address of your own function in the function pointer. When the window is loaded, call this function to pass to the window ID you want to create. If the program wants to generate a subclass according to the ID, create a new appropriate object and returns the new pointer to the window. If the program does not need this ID, return null, the window function creates an appropriate default object according to the return value. This method allows the program "Pre-filtered" introduced window ID information and overloads the default function for a particular window type. Too perfect (translator: This paragraph I have really said that it is perfect. Instead, it is simply unknown. Here you put the original text, please take care of 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 appropriate object and returns the new pointer back to the window. If the app does not 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 Use this method to give me a lot of freedom when you create a custom control. I add code to my resource editor so that I can change the ID for each stored window. Then, when I need a customization, I just use the resource editor to change the byte of the window ID. Save on the disk is the ID and all other base class properties for the custom control. Soon? There are other ways to do the same thing, this is how the method is used when the STL needs to create an object. STL uses a specific "Allocator" class, which is a bit like "Factories", and they will create classes according to the needs of customers. You can use this method to create a window. The working principle of this method is as follows: Create a class and call it "gui_window_allocator". Write a virtual function called CREATEWINDOWOFTYPE, which accepts a given window ID and transmits a new pointer to the window. Now you get a simple assignment class, your window load code will use it to create a needed window. Now, when your program needs to overload the "new" operator for the window, derive a new, program-related GUI_WINDOW_ALLOCATOR class, and tell your window to load code to use this assignment, not the default. This method is like providing a function pointer, only one C .
4.5, accelerated GUI rendering has a small tip that can help you accelerate the GUI rendering. The key concept is, just like the optimization of other drawing functions, don't draw something you don't need. Default, GUI spends a lot of time to draw a portion where there is no change. However, you can do some optimizations by telling the GUI to draw changes in Windows That Are Dirty. When the appearance of the window needs to change, the window sets their Dirty flags, clearing their dirty flags when drawing. Since our GUI control may be transparent, when a control is marked as Dirty, its parent window must be marked as Dirty. This way, when it is drawn, the background has not changed because the parent window has just been reddled. 4.6, summary: Meet in XGDC call, a long four articles, but we still miss a lot. I am going to tell the GUI on the upcoming ArmageDon XGDC (EXTreme Game Developer's Conference). I will try my best to make my statement, now you have already seen all the articles, if you have any problems that need to be extended, or what miss it, please write let me know. I wish you a happy game.
-------------------------------------------------- ------------------------------
About the author: Mr. Mason McCuskey is the leader of Spin Studio (a great game known as Quaternion). He is looking forward to your suggestions and comments, his email is (Mason@spin-studios.com) .
Translator's hand: Finally ended a long translation process, which is the longest difficulty in Rick translation. There must be a lot of mistakes and missions, if you find these questions, please let me tell me (rick_yinhua@sina.com). Thank you for your support.