Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Designing a Cross-Platform GUI


April 1995/Designing a Cross-Platform GUI/Listing 1

Listing 1 gui.h — Platform-independent header file for class library

gui.h

#ifndef _GUI_
#define _GUI_

#include <stdarg.h>

// platform specific includes and defines

#ifdef WIN_NT
   #include <windows.h>

   typedef HWND NativeWindow;
   typedef HDC GraphicsHandle;
   #define EXP1
   #define EXP2 _declspec(dllexport)
   #define NATIVE_PART_OF_GUI_APPLICATION HINSTANCE hInstance
   #define NATIVE_PART_OF_GUI_WINDOW
   #define NATIVE_FRIEND_OF_GUI_WINDOW   friend LRESULT CALLBACK \
          GuiWindowProc(HWND hWnd, UINT message, \
                      WPARAM uParam, LPARAM lParam)
   #define main  ApplicationMain
#endif

#ifdef OS2
   #define INCL_WIN
   #define INCL_GPI
   #include <os2.h>

   typedef HWND  NativeWindow;
   typedef HPS   GraphicsHandle;
   #define EXP1  _export
   #define EXP2
   #define NATIVE_PART_OF_GUI_APPLICATION HAB Hab; \
                                   HMQ Hmq
   #define NATIVE_PART_OF_GUI_WINDOW      NativeWindow frame
   #define NATIVE_FRIEND_OF_GUI_WINDOW    friend MRESULT \
          EXPENTRY GuiWindowProc(HWND hwnd, USHORT msg, \
                             MPARAM mp1, MPARAM mp2)
#endif

#ifdef X_WINDOWS
   #include <X11/Intrinsic.h>

   typedef Widget NativeWindow;
   typedef GC     GraphicsHandle;
   #define EXP1
   #define EXP2
   #define NATIVE_PART_OF_GUI_APPLICATION int dontQuit
   #define NATIVE_PART_OF_GUI_WINDOW      NativeWindow frame; \
                                   char          szGeometry[100]
   #define NATIVE_FRIEND_OF_GUI_WINDOW    \
       friend void ExposeCallback(Widget w, XtPointer client_data, \
                                  XtPointer call_data); \
       friend void ResizeCallback(Widget w, XtPointer client_data, \
                                  XtPointer call_data)
#endif

// coordinate system definition

#define MAX_X              10000
#define MAX_Y              10000

#define MAX_WINDOW         100 // max. windows in an application
#define MAX_CHILDREN       100 // max. children of a window

// VGA colors

#define COLOR_WHITE        0
#define COLOR_BLACK        1
#define COLOR_BLUE         2
#define COLOR_RED          3
#define COLOR_PINK         4
#define COLOR_GREEN        5
#define COLOR_CYAN         6
#define COLOR_YELLOW       7
#define COLOR_NEUTRAL      8
#define COLOR_DARKGRAY     9
#define COLOR_DARKBLUE     10
#define COLOR_DARKRED      11
#define COLOR_DARKPINK     12
#define COL0R_DARKGREEN    13
#define COLOR_DARKCYAN     14
#define COLOR_BROWN        15

// object types returned by GetType()

#define TYPE_LINE          1
#define TYPE_ELLIPSE       2
#define TYPE_TEXT          3
#define TYPE_BUTTON        4
#define TYPE_ENTRY         5
#define TYPE_WINDOW        6

// the only global function: logs into a file
EXP2 void EXP1 Log(char* fmt, ...);

// forward declaration of classes GUI_WINDOW and GUI_OBJECT
class GUI_WINDOW;
class GUI_OBJECT;

typedef struct _GUI_WINDOW_ELEM { // typedef for linked list of windows
   GUI_WINDOW*              pWindow;
   struct _GUI_WINDOW_ELEM* pNext;
} GUI_WINDOW_ELEM;

class EXP1 GUI_APPLICATION {
   private:
      NATIVE_PART_OF_GUI_APPLICATION;

      GUI_WINDOW_ELEM WindowElemList[MAX_WINDOW], *pUsed, *pFree;
      int             AddWindow(GUI_WINDOW *pWindow);
      int             DelWindow(GUI_WINDOW *pWindow);
   public:
      EXP2 GUI_APPLICATION(int* pArgc, char** argv, char* logFile);
      EXP2 virtual     ~GUI_APPLICATION(void);
      EXP2 void        MainLoop(void);
      EXP2 void        Terminate(void);
      EXP2 GUI_WINDOW* FindWindow(NativeWindow window);
      EXP2 GUI_OBJECT* FindChild(NativeWindow window);

   friend class GUI_WINDOW;
};

class EXP1 CALLABLE_OBJECT {
   public:
      EXP2 virtual int Activate(void) { return(1); }
      EXP2 virtual int LeftClick(void) { return(1); }
      EXP2 virtual int RightClick(void) { return(1); }
      EXP2 virtual int LeftDoubleClick(void) { return(1); }
      EXP2 virtual int RightDoubleClick(void) { return(1); }
};

class EXP1 GUI_OBJECT: public CALLABLE_OBJECT { // abstract class
   protected:
      GUI_WINDOW* pParent;
      int         id, x, y, width, height;
   public:
      EXP2 GUI_OBJECT(GUI_WINDOW* pParent, int id, int x=0, int y=0,
                      int width=MAX_X, int height=MAX_Y);
      EXP2 virtual              ~GUI_OBJECT(void);
      EXP2 virtual int          GetType(void)=0;
      EXP2 virtual void         Paint(GraphicsHandle gh) { }
      EXP2 virtual NativeWindow GetNativeWindow(void) { return(0); }
      EXP2 GUI_WINDOW*          GetParent(void) { return(pParent); }
      EXP2 int                  GetId(void) { return(id); }
      EXP2 int                  GetX(void) { return(x); }
      EXP2 int                  GetY(void) { return(y); }
      EXP2 int                  GetWidth(void) { return(width); }
      EXP2 int                  GetHeight(void) { return(height); }
};

class EXP1 GUI_GRAPHICS_OBJECT: public GUI_OBJECT { // abstract class
   protected:
      int color, lineWidth;
   public:
      EXP2 GUI_GRAPHICS_OBJECT(GUI_WINDOW* pParent, int id, int x=0,
                       int y=0,int width=MAX_X, int height=MAX_Y,
                       int color=COLOR_BLACK, int lineWidth=1);
      EXP2 virtual ~GUI_GRAPHICS_OBJECT(void);
};

class EXP1 GUI_LINE: public GUI_GRAPHICS_OBJECT {
   public:
      EXP2 GUI_LINE(GUI_WINDOW* pParent, int id, int x1=0, int y1=0,
             int x2=MAX_X, int y2=MAX_Y,
             int color=COLOR_BLACK, int lineWidth=1);
      EXP2 virtual     ~GUI_LINE(void);
      EXP2 virtual int GetType(void) { return(TYPE_LINE); }
      EXP2 virtual void Paint(GraphicsHandle gh);
};

// fill types

#define FILL_OUTER       0 // draw just the otline
#define FILL_SOLID       1 // draw and fill the shape

class EXP1 GUI_ELLIPSE: public GUI_GRAPHICS_OBJECT { // abstract class
   protected:
      int fillType;
   public:
      EXP2 GUI_ELLIPSE(GUI_WINDOW* pParent, int id, int x=0, int y=0,
             int width=MAX_X/2,  int height=MAX_Y/2,
             int color=COLOR_BLACK,  int fillType=FILL_OUTER,
             int lineWidth=1);
      EXP2 virtual     ~GUI_ELLIPSE(void);
      EXP2 virtual int GetType(void) { return(TYPE_ELLIPSE); }
      EXP2 virtual void Paint(GraphicsHandle gh);
};

class EXP1 GUI_WINDOW_OBJECT: public GUI_OBJECT { // abstract class
   protected:
      NativeWindow window;
   public:
      EXP2 GUI_WINDOW_OBJECT(GUI_WINDOW* pParent, int id, int x=0,
                     int y=0, int width=MAX_X, int height=MAX_Y);
      EXP2 virtual      ~GUI_WINDOW_OBJECT(void);
      EXP2 NativeWindow GetNativeWindow(void) { return(window); }
      EXP2 virtual void GetRealCoordinates(int *pRx, int *pRy,
                                 int *pRw, int *pRh);
      EXP2 virtual int  GetText(char *buffer, int bufferLength);
      EXP2 virtual int  SetText(char *text="");
};

class EXP1 GUI_TEXT: public GUI_WINDOW_OBJECT {
   public:
      EXP2 GUI_TEXT(GUI_WINDOW* pParent, int id, int x=0, int y=0,
             int width=MAX_X, int height=0,
             char *text="");
      EXP2 virtual int GetType(void) { return(TYPE_TEXT); }
};

class EXP1 GUI_BUTTON: public GUI_WINDOW_OBJECT {
   public:
      EXP2 GUI_BUTTON(GUI_WINDOW* pParent, int id, int x=0, int y=0,
                      int width=MAX_X, int height=0, char* text="");
      EXP2 virtual int  GetType(void) { return(TYPE_BUTTON; }
};

class EXP1 GUI_ENTRY: public GUI_WINDOW_OBJECT {
   protected:
      int length;
   public:
      EXP2 GUI_ENTRY(GUI_WINDOW* pParent, int id, int x=0, int y=0,
                     int width=MAX_X, int height=0,
                     char* text="", int maxTextLength=10);
      EXP2 virtual int GetType(void) { return(TYPE_ENTRY); }
#ifdef X_WINDOWS // if not under X_WINDOWS these are inherited from
                            // GUI_WINDOW_OBJECT
      EXP2 virtual int  GetText(char *buffer, int bufferLength);
      EXP2 virtual int  SetText(char *text="");
#endif
};

// frame styles

#define FRAME_THIN        1
#define FRAME_SIZEABLE    2
#define FRAME_TITLE       4
#define FRAME_MIN_BUTTON  8
#define FRAME_MAX_BUTTON  16
#define FRAME_DEFAULT     (FRAME_THIN | FRAME_TITLE)

typedef struct _GUI_OBJECT_ELEM { // typedef for linked list of children
   GUI_OBJECT*              pObject;
   struct _GUI_OBJECT_ELEM* pNext;
} GUI_OBJECT_ELEM;

class EXP1 GUI_WINDOW: public GUI_WINDOW_OBJECT {
   private:
      NATIVE_PART_OF_GUI_WINDOW;

      GUI_APPLICATION* pApplication;
      GraphicsHandle   gh;
      int              frameStyle, backgroundColor;
      GUI_OBJECT_ELEM  Children[MAX_CHILDREN], *pUsed, *pFree;
   protected:
      EXP2 void             SizeChildren(void);
      EXP2 int              AddChild(GUI_OBJECT* pChild);
      EXP2 int              DeleteChild(GUI_OBJECT* pChild);
   public:
      EXP2 GUI_WINDOW(GUI_APPLICATION* pApplication, int id, int x=0,
                      int y=0, int width=MAX_X, int height=MAX_Y,
                      int backgroundColor=COLOR_WHITE, char* title= "",
                      int frameStyle=FRAME_DEFAULT);
      EXP2 virtual        ~GUI_WINDOW(void);
      EXP2 virtual int    GetType(void) { return(TYPE_WINDOW); }
      EXP2 virtual void   Paint(GraphicsHandle gh);
      EXP2 virtual void   Show(void);
      EXP2 int            GetBackground(void) {return(backgroundColor); }
      EXP2 GraphicsHandle GetGraphicsHandle(void) { return(gh); }
      EXP2 GUI_OBJECT*    GetChildFromId(int id);
      EXP2 GUI_OBJECT*    GetChildFromWindow(NativeWindow window);
#ifndef WIN_NT // if under Windows these are inherited from GUI_WINDOW_OBJECT
      EXP2 virtual int    GetText(char *buffer, int bufferLength);
      EXP2 virtual int    SetText(char *text="");
#endif
      EXP2 virtual void   Message(char *title, char *text);
      // return value 0=OK, 1=Cancel
      EXP2 virtual int    Question(char *title, char *text);

   friend class GUI_APPLICATION;
   friend class GUI_OBJECT;
   NATIVE_FRIEND_OF_GUI_WINDOW;
};

#endif // #ifndef _GUI_

/* End of File */

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.