Game UI Design (2.1) - Package of the Father CXWND

xiaoxiao2021-03-06  92

Parent CxWnd of Window

[http://blog.9cbs.net/mythma]

The dialog boxes, buttons, edit boxes, etc. in the general program are all windows. In the MFC, class CWnd is based on the base class of the window class, abstract their common features, and thereby derive a number of subclasses. In a normal Windows program, we can easily use the MFC for our package (CDIALOG, CBUTTON, CEDIT, etc.), and in the game program, due to the need to combine with DX / OpenGL and efficiency, it is not directly Use them, this requires us to package it. How many controls can be packaged? We may also wish to all the windows, the control abstract base class, just call her cxwnd. Then let us start from cxwnd, step by step to realize our true UI.

Let's first open the DX specific drawing window, look at the window, what is common characteristics, and how to implement it in cxwnd.

1, the size and position of the window

The window is a rectangular area, so it can be represented by two variables (width: m_wdith, height: m_height).

The location of the window can also be represented by two variables (X coordinate: m_xpos, y coordinate: m_ypos). But these two variables indicate the absolute coordinates of the window (with respect to the upper left corner of the screen) or the relative coordinate (relative to the parent window)?

From the user's perspective (ie the creation window), use the relative coordinates for convenientness;

From the perspective of the program (ie, the drawing window), use the absolute coordinates.

Our package of CXWND is to use, so it is to start from the user's perspective, ie M_XPOS and M_YPOS represent the relative coordinates of the window. When the window is drawn, we need to get the absolute coordinates of the window, so you need to provide a member function to translate --getabsolutePos (Float & X, Float & Y).

(The picture doesn't have to draw, :))

2, the connection between the window

In order to be more representative, I want to (not painted) a window hierarchy with a property page, with its related window has a parent window (excluding grandfather), several sub-windows (various controls ), As well as a number of episodes, there is a need to have a pointer to its parent window (cxwnd * m_wndparent), a pointer to its sub-window linked list (cxwnd * m_wndchild, m_wndchild points to the first window of the window linked list, this The window z preface is minimal in the sub-window, which is displayed in the forefront, plus the pointer between the same level window (cxWnd * m_WndnextSibling points to the next class window; cxwnd * m_wndprevioussibling points to the forward single window). Such a multi-window is linked with these four pointers, and the draw is a window relationship tree. Why do you need two pointers in the same level window? You can find the answer in the message loop.

What do you need for these pointers?

In addition to basic GET *** WND () and set *** wnd (), it is also required:

Add a sub-window AddChildWnd (WNDCHILD: CXWND *)

Delete a child window deletechildWnd (WNDCHILD: CXWND *)

Delete all sub-winding deleteAllChildWnd () to release memory. Get sub-window number getChildcount ()

These are all basic operations for one-way linkers.

3, message loop

From the classic message function WNDPROC (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARM LPARAM), after the message, the main window needs to pass, so cxwnd has a similar function --PostMessage (Uint MSG, WPARAM WPARAM, LPARAM LPARAM, VOID * DATA); wherein the message is classified.

1) Mouse message

Mouse message processing, of course, as follows (but do not need to implement them in cxwnd, just declaring as a pure virtual function, because the mouse processing function of each control is not the same)

Virtual Void OnMouseDown (int button, int x, int y) = null;

Virtual void onmousemove (int x, int y) = null;

Virtual Void OnMouseup (int button, int x, int y) = null;

How do I know which window gets the mouse message? Then you need to search for all windows, see which window of the current coordinates (note is absolute coordinates). Therefore, add the function CURSORINTERSECT (FLOAT X, FLOAT Y) to complete this feature.

How is the mouse message passed in the window tree? The scope is definitely from big to small scan, that is, see if it is on a window. If you see whether it is on the sub-window of the window ..., finally find the most upstanding window, then the child window will first handle the mouse message. That is, the most last sub-window has priority to handling mouse messages. Therefore, the transmission of the message is from top to bottom, it is called the positive order message --PostMsgtochildren (...) is responsible for transmitting the message positive sequence to each sub-window.

2) Keyboard message

Like the mouse message, the processing of keyboard messages has the following two pure virtual member functions:

Virtual Void onkeyDown (WPARAM Key, Lparam Extended) = NULL;

Virtual Void onkeyup (WPARAM Key, Lparam Extended) = NULL;

The special point of the processing of keyboard messages is to process its window (control) needs to get focus (whose reason is very simple), so each form requires a pointer member variable (cxwnd * m_wndfocus) that stores its acquired sub-form (cxwnd * m_wndfocus) and A BOOL member variable (BOOL M_BFOCUS) that judges it to obtain focus, there is a setFocusWnd (...) and getFocus () member functions.

The transfer of keyboard messages is the same as the transfer of mouse messages.

3) Window drawing message

The drawing of the window is related to the specific window object, so it is not implemented in cxwnd, but the message drawn by the window is to pass, how is the message passed?

Each window has its own z preface. At the end, you must draw it first. The front is to draw (if you want to be done), the corresponding and window tree is, the parent window must draw first, then the next child window Draw, the last is the top one. Therefore, the lower window has the priority of processing the window to draw messages. The topmost sub-window is placed in the forefront of the sub-window linked list, so the message requires an inverse order to pass forward. Therefore, it is necessary to dedicate member functions of the message --PostMsgtochildrenreverse (...). The z-order of the window is not fixed, so a function is needed to change their Z-order --movetofront (...).

At this point, the principal function of CXWND has been completed, see it, it is a member:

转载请注明原文地址:https://www.9cbs.com/read-106271.html

New Post(0)