Mason McCuskey - Developing a GUI in C++ and DirectX

Здесь есть возможность читать онлайн «Mason McCuskey - Developing a GUI in C++ and DirectX» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Developing a GUI in C++ and DirectX: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Developing a GUI in C++ and DirectX»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

At first glance, it may seem like I’m reinventing the wheel; Windows already comes with a very complex, very functional GUI. Unfortunately, while the Windows GUI is great for office apps, quite frequently, it’s not suited for many games. Games tend to want a more precise control over the GUI than Windows can provide (for example, games may want to use alpha-blending to implement partially transparent windows - easy if you’ve written your own GUI, but next to impossible using the Windows GUI).
This article will walk you though how to create a GUI using C++ and DirectX. The series is divided into several parts, each dealing with a specific aspect of GUI programming:
Part I: The Basics, and the Mouse
Part II: Windows
Part III: Controls
Part IV: Resource Editors and Other Madness
NOTE: This document was originally four separate articles on www.gamedev.net. I’ve concatenated all four into one for the XGDC, but they remain otherwise unchanged. - Mason

Developing a GUI in C++ and DirectX — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Developing a GUI in C++ and DirectX», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

void bringtotop(void);

bool isactive(void);

/////////////

// Section II: coordinates

/////////////

void setpos(coord x1, coord y1); // boring

void setsize(coord width, coord height); // boring

void screentoclient(coord& x, coord& y);

int virtxtopixels(coord virtx); // convert GUI units to actual pixels

int virtytopixels(coord virty); // ditto

virtual gui_window *findchildatcoord(coord x, coord y, int flags = 0);

/////////////

// Section III: Drawing Code

/////////////

// renders this window + all children recursively

int renderall(coord x, coord y, int drawme = 1);

gui_wincolor& getcurrentcolorset(void) { return(isactive() ? m_activecolors : m_inactivecolors); }

/////////////

// Messaging stuff to be discussed in later Parts

/////////////

int calcall(void);

virtual int wm_paint(coord x, coord y);

virtual int wm_rendermouse(coord x, coord y);

virtual int wm_lbuttondown(coord x, coord y);

virtual int wm_lbuttonup(coord x, coord y);

virtual int wm_ldrag(coord x, coord y);

virtual int wm_lclick(coord x, coord y);

virtual int wm_keydown(int key);

virtual int wm_command(gui_window *win, int cmd, int param) { return(0); };

virtual int wm_cansize(coord x, coord y);

virtual int wm_size(coord x, coord y, int cansize);

virtual int wm_sizechanged(void) { return(0); }

virtual int wm_update(int msdelta) { return(0); }

protected:

virtual void copy(gui_window& r); // deep copies one window to another

gui_window *m_pParent;

uti_pointerarray m_subwins;

uti_rectangle m_position;

// active and inactive colorsets

gui_wincolor m_activecolor;

gui_wincolor m_inactivecolor;

// window caption

uti_string m_caption;

};

First of all, notice the virtual destructor on the window class. This may not seem like it’s needed just yet, but we’ll eventually be deriving controls from this class, so it’s important that it have a virtual destructor.

As you peruse the functions we’ll be talking about, keep in mind that recursion is everywhere. For example, our game will be drawing the entireGUI system by making a call to the renderall() method of the root window, which will in turn call the renderall() methods of its subwindows, which will call renderall() for their subwindows, and so on. Most of the functions follow this recursive pattern.

The whole GUI system will be contained within one global static variable - the root window. To be on the safe side, I encapsulated this variable within a global GetDesktop() function.

Also, notice that the class definition is rife with virtual keywords. This is where C++’s polymorphism is working for us. Need to change how certain types of windows (or controls - say, buttons) deal with a “left mouse button has just been pushed down” event? Simple, derive a class from the base window and override its wm_lbuttondown() method. The system will automaticallycall the derived class’s method where appropriate; behold the power of C++.

Now that we’ve got the header, let’s start filling in some functions, starting with the Window Management code…

Window Management Code

/****************************************************************************

addwindow: adds a window to this window's subwin array

****************************************************************************/

int gui_window::addwindow(gui_window *w) {

if (!w) return(-1);

// only add it if it isn't already in our window list.

if (m_subwins.find(w) == -1) m_subwins.add(w);

w-›setparent(this);

return(0);

}

/****************************************************************************

removewindow: removes a window from this window's subwin array

****************************************************************************/

int gui_window::removewindow(gui_window *w) {

w-›setparent(NULL);

return (m_subwins.findandremove(w));

}

/****************************************************************************

bringtotop: bring this window to the top of the z-order. the top of the

z-order is the HIGHEST index in the subwin array.

****************************************************************************/

void gui_window::bringtotop(void) {

if (m_parent) {

// we gotta save the old parent so we know who to add back to

gui_window *p = m_parent;

p-›removewindow(this);

p-›addwindow(this);

}

}

/****************************************************************************

isactive: returns true if this window is the active one (the one with input focus).

****************************************************************************/

bool gui_window::isactive(void) {

if (!m_parent) return(1);

if (!m_parent-›isactive()) return(0);

return(this == m_parent-›m_subwins.getat(m_parent-›m_subwins.getsize()-1));

}

This set of functions deals with what I call window management; adding windows, deleting them, showing/hiding them, and changing their z-order. All of these are really just array operations; this is where your array class gets a workout.

The only thing interesting in the add / remove window functions is the question, “who is responsible for the window pointer?” This is always a good question to ask yourself in C++. Addwindow and removewindow both take pointers to a window class. This means that to create a new window, your code news it, then passes the pointer to the parent (desktop) window through addwindow(). So who’s responsible for deleting the pointer you newed?

My answer was “the GUI doesn’t own the window pointers; the game itself is responsible for adding them.” This is consistent with the C++ rule of thumb that says “those who new things also delete them.”

The alternative to the method I chose was to say “the parent window is responsible for the pointers of all his child windows.” That would mean that to prevent memory leaks, each window must, in it’s (virtual) destructor (remember, there’s derived classes), loop through its m_subwindows array and delete all of the windows contained within it.

If you decide to implement a GUI-owns-pointer system, be aware of an important trade-off - all of your windows must be dynamically allocated (newed). A quick way to crash a system like that is to pass in the address of a variable on the stack, i.e. say something like “addwindow(&mywindow)”, where mywindow is declared as a local variable on the stack. Things will work until mywindow goes out of scope, or until the destructor for the parent window is called, whereupon it’ll try to delete that address and all hell will break loose. The lesson is “be extra careful with pointers.”

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Developing a GUI in C++ and DirectX»

Представляем Вашему вниманию похожие книги на «Developing a GUI in C++ and DirectX» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Developing a GUI in C++ and DirectX»

Обсуждение, отзывы о книге «Developing a GUI in C++ and DirectX» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x