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