5) Finally, after all of my controls were complete, I coded up a simple Resource Editor, a program that allows someone to graphically place controls and layout dialog boxes. The resource editor took me a good month to do, but I highly suggest doing it (instead of just using text files to position stuff) - it’s much easier to create dialog boxes graphically, and it was a good exercise: during development I uncovered several bugs in my controls’ code, things that would have proven very difficult to catch in the actual game.
I toyed, for a very long time, with the idea of creating a program that would convert an MSVC++ resource (.RC) file into a custom resource file useable by my GUI. In the end, I decided such a program would be more trouble than what it would be worth. The whole reason I was writing a GUI was to get away from the confines of Windows, and to truly do that, I needed my own editor, tied to my own resource file format and my own way of doing things. I decided to implement a WYSIWYG Resource Editor in MFC from the ground up. My needs, my decision; your needs may be different. If anyone out there tries to write a converter, I’d love to hear about it.
So… let’s start with step one: basic window management functions.
The Implementation
Here we go. Here’s a good start for our base-class window definition:
class gui_window {
public:
gui_window(); // boring
virtual ~gui_window(); // boring
virtual void init(void); // boring
gui_window *getparent(void) { return(m_pParent); }
/////////////
// section I: window management controls
/////////////
int addwindow(gui_window *w);
int removewindow(gui_window *w);
void show(void) { m_bIsShown = true; }
void hide(void) { m_bIsShown = false; }
bool isshown(void) { return(m_bIsShown); }
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;