_WINDOWS MEETS C++_ by Scott Robert Ladd [LISTING ONE] // WINDOWS CLASSES // winclass.h -- Class definitions for Windows programming // Copyright 1991 by Scott Robert Ladd. All Rights Reserved. #if !defined(__WINCLASS_H) #define __WINCLASS_H #include "windows.h" // macro resolving to size of this pointer #define SIZEOF_THIS (sizeof(void *)) // macro resolving to number of extra bytes required by this window #define PTR_BYTES (SIZEOF_THIS) // macros used to store and extract class pointer from extra window bytes #if sizeof(void *) == 4 #define SetWindowPtr(wdw,ptr) SetWindowLong((wdw),0,(DWORD)(ptr)) #define GetWindowPtr(wdw) (Window *)GetWindowLong(wdw,0) #else #define SetWindowPtr(wdw,ptr) SetWindowWord((wdw),0,(WORD)(ptr)) #define GetWindowPtr(wdw) (Window *)GetWindowWord(wdw,0) #endif // callback function types typedef long (_far _pascal * WinCallBack)(HWND,WORD,WORD,DWORD); typedef int (_far _pascal * DlgCallBack)(HWND,WORD,WORD,DWORD); //------------- CLASS WinApp ------------- class WinApp { public: static int Dispatcher(); static void SetInstance(HANDLE inst); static HANDLE GetInstance(); private: static HANDLE Instance; }; // set instance handle inline void WinApp::SetInstance(HANDLE inst) { if (Instance == NULL) Instance = inst; } // get instance handle inline HANDLE WinApp::GetInstance() { return Instance; } //------------------ CLASS WindowClass ------------------ class WindowClass : public WinApp { public: WindowClass(); // constructor BOOL Register(); // register BOOL Unregister(); // unregister const char * GetName() const; // get class name string protected: WNDCLASS ClassData; }; //------------------ CLASS BasicWindow ------------------ class BasicWindow : private WinApp { public: HWND GetHandle() const; HANDLE GetInstance() const; DWORD GetStyle() const; void Show(int cmdShow = SW_SHOW); void Update(); void SetText(char * text); void GetText(char * buffer, int n) const; void Disable(); void Enable(); void GetExtents(int * x, int * y, int * width, int * height) const; void Move(int x, int y, int width, int height); protected: BasicWindow(const char * cname); HWND Handle; HANDLE Instance; DWORD Style; char ClassName[32]; }; inline HWND BasicWindow::GetHandle() const { return Handle; } inline HANDLE BasicWindow::GetInstance() const { return Instance; } inline DWORD BasicWindow::GetStyle() const { return Style; } inline void BasicWindow::Show(int cmdShow) { ShowWindow(Handle,cmdShow); } inline void BasicWindow::Update() { UpdateWindow(Handle); } inline void BasicWindow::SetText(char * text) { SetWindowText(Handle,text); } inline void BasicWindow::GetText(char * buffer, int n) const { GetWindowText(Handle,buffer,n); } inline void BasicWindow::Disable() { EnableWindow(Handle,FALSE); } inline void BasicWindow::Enable() { EnableWindow(Handle,TRUE); } inline void BasicWindow::GetExtents(int * x, int * y, int * width, int * height) const { RECT r; GetWindowRect(Handle,&r); *x = r.left; *y = r.top; *width = r.right - r.left + 1; *height = r.bottom - r.top + 1; } inline void BasicWindow::Move(int x, int y, int width, int height) { MoveWindow(Handle,x,y,width,height,TRUE); } //------------- CLASS Window ------------- class Window : public BasicWindow { public: Window(const char * cname); BOOL Actualize(const char * title, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int width = CW_USEDEFAULT, int height = CW_USEDEFAULT); HDC OpenDC(); void CloseDC(HDC dc); protected: virtual void Create(HWND wdw, CREATESTRUCT _far * cs); virtual void Close(HWND wdw); virtual void Paint(HDC dc); virtual void Command(HWND wdw, WORD wParam, DWORD lParam); virtual long AuxMsgHandler(HWND wdw, WORD message, WORD wParam, DWORD lParam); private: static long _far _pascal _export MessageHandler(HWND wdw, WORD message, WORD wParam, DWORD lParam); }; inline HDC Window::OpenDC() { return GetDC(Handle); } inline void Window::CloseDC(HDC dc) { ReleaseDC(Handle,dc); } //-------------- CLASS Control -------------- class Control : public BasicWindow { public: BOOL Actualize(const Window & parent, const char * text, WORD id, int x, int y, int width, int height); WORD GetID() const; WinCallBack SubClass(WinCallBack newHandler); protected: Control(const char * cname); }; inline WORD Control::GetID() const { return GetWindowWord(Handle,GWW_ID); } inline WinCallBack Control::SubClass(WinCallBack newHandler) { return (WinCallBack)SetWindowLong(Handle,GWL_WNDPROC,(DWORD)newHandler); } inline Control::Control(const char * cname) : BasicWindow(cname) { // does nothing else } //----------------- CLASS StaticLeft ----------------- class StaticLeft : public Control { public: StaticLeft(); }; //----------------- CLASS PushButton ----------------- class PushButton : public Control { public: PushButton(); }; #endif // __WINCLASS_H [LISTING TWO] // WINDOWS CLASSES // winclass.cpp -- Windows class implementations. // Copyright 1991 by Scott Robert Ladd. All Rights Reserved. #include "winclass.h" #include "string.h" //------------- CLASS WinApp ------------- // define values for static member of WinApp class HANDLE WinApp::Instance = NULL; // message dispatcher int WinApp::Dispatcher() { if (Instance == NULL) return !0; MSG msg; while (GetMessage(&msg, NULL, NULL, NULL)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //------------------ CLASS WindowClass ------------------ WindowClass::WindowClass() { #if defined(__BCPLUSPLUS__) ClassData.lpfnWndProc = DefWindowProc; #else ClassData.lpfnWndProc = (long (_far _pascal *)())DefWindowProc; #endif ClassData.hInstance = WinApp::GetInstance(); ClassData.style = 0; ClassData.cbClsExtra = 0; ClassData.cbWndExtra = PTR_BYTES; ClassData.hIcon = NULL; ClassData.hCursor = LoadCursor(NULL,IDC_ARROW); ClassData.hbrBackground = GetStockObject(WHITE_BRUSH); ClassData.lpszMenuName = NULL; ClassData.lpszClassName = "DefaultWindowClass"; } BOOL WindowClass::Register() { if (!RegisterClass((WNDCLASS _far *)&ClassData)) return FALSE; else return TRUE; } BOOL WindowClass::Unregister() { if (!UnregisterClass(ClassData.lpszClassName,ClassData.hInstance)) return FALSE; else return TRUE; } const char * WindowClass::GetName() const { return (const char *)ClassData.lpszClassName; } //------------------ CLASS BasicWindow ------------------ BasicWindow::BasicWindow(const char * cname) { Handle = NULL; Instance = WinApp::GetInstance(); Style = 0UL; if (cname != NULL) strncpy(ClassName,cname,32); else ClassName[0] = 0; // blank class name } //------------- CLASS Window ------------- Window::Window(const char * cname) : BasicWindow(cname) { Style = WS_OVERLAPPEDWINDOW; } BOOL Window::Actualize(const char * title, int x, int y, int width, int height) { Handle = CreateWindow(ClassName, (char *)title, Style, x, y, width, height, NULL, NULL, Instance, 0L); if (Handle == NULL) return FALSE; FARPROC fp = MakeProcInstance((FARPROC)((DWORD)(Window::MessageHandler)), Instance); SetWindowLong(Handle,GWL_WNDPROC,(DWORD)fp); SetWindowPtr(Handle,this); SendMessage(Handle,WM_CREATE,0,0L); return TRUE; } void Window::Create(HWND wdw, CREATESTRUCT _far * cs) { // by default, does NOTHING! } void Window::Close(HWND wdw) { // by default, does NOTHING! } void Window::Paint(HDC dc) { // by default, does NOTHING! } void Window::Command(HWND wdw, WORD wParam, DWORD lParam) { // by default, does NOTHING! } long Window::AuxMsgHandler(HWND wdw, WORD message, WORD wParam, DWORD lParam) { return DefWindowProc(wdw,message,wParam,lParam); } long _far _pascal _export Window::MessageHandler(HWND wdw, WORD message, WORD wParam, DWORD lParam) { HDC dc; PAINTSTRUCT ps; Window * wptr; wptr = GetWindowPtr(wdw); switch (message) { case WM_CREATE: wptr->Create(wdw, (CREATESTRUCT _far *)lParam); break; case WM_CLOSE: wptr->Close(wdw); break; case WM_PAINT: dc = BeginPaint(wdw,&ps); wptr->Paint(dc); EndPaint(wdw,&ps); break; case WM_COMMAND: wptr->Command(wdw,wParam,lParam); break; default: return wptr->AuxMsgHandler(wdw,message,wParam,lParam); } return 0L; } //-------------- CLASS Control -------------- BOOL Control::Actualize(const Window & parent, const char * text, WORD id, int x, int y, int width, int height) { Handle = CreateWindow(ClassName, (char *)text, Style, x,y,width,height, parent.GetHandle(), id, parent.GetInstance(), 0L); if (Handle == NULL) return FALSE; return TRUE; } //----------------- CLASS StaticLeft ----------------- StaticLeft::StaticLeft() : Control("STATIC") { Style = WS_CHILD | SS_LEFT | SS_NOPREFIX | WS_BORDER; } //----------------- CLASS PushButton ----------------- PushButton::PushButton() : Control("BUTTON") { Style = WS_CHILD | BS_PUSHBUTTON; } [LISTING THREE] // WINDOWS CLASSES // woop.cpp -- A program to test basic windows classes. // Copyright 1991 by Scott Robert Ladd. All Rights Reserved. #include "winclass.h" #include "woop.h" #define IDC_BUTTON 1000 //---------------------- CLASS MainWindowClass ---------------------- class WOOPWindowClass : public WindowClass { public: WOOPWindowClass(); }; WOOPWindowClass::WOOPWindowClass() : WindowClass() { ClassData.hIcon = LoadIcon(WinApp::GetInstance(),"WOOPIcon"); ClassData.hbrBackground = GetStockObject(LTGRAY_BRUSH); ClassData.lpszMenuName = "WOOPMenu"; ClassData.lpszClassName = "MainWindowClass"; } //----------------- CLASS WOOPWindow ----------------- class WOOPWindow : public Window { public: WOOPWindow(const char * cname); virtual BOOL Actualize(); protected: virtual void Close(HWND wdw); virtual void Command(HWND wdw, WORD wParam, DWORD lParam); StaticLeft SCtl; PushButton BCtl; }; WOOPWindow::WOOPWindow(const char * cname) : Window(cname) { } BOOL WOOPWindow::Actualize() { BOOL res; res = Window::Actualize("WOOP Window"); // call base class member if (res == FALSE) return FALSE; res = SCtl.Actualize(*this,"Static control",0,100,10,120,16); if (res == FALSE) return FALSE; SCtl.Show(); SCtl.Update(); res = BCtl.Actualize(*this,"Button",IDC_BUTTON,100,50,60,40); if (res == FALSE) return FALSE; BCtl.Show(); BCtl.Update(); return TRUE; } void WOOPWindow::Close(HWND wdw) { PostQuitMessage(0); } void WOOPWindow::Command(HWND wdw, WORD wParam, DWORD lParam) { switch (wParam) { case IDM_EXIT: PostQuitMessage(0); break; case IDM_ABOUT: MessageBox(GetFocus(),"WOOP version 1.00","About...",MB_OK); break; case IDM_SET: SCtl.SetText("Set!"); break; case IDM_RESET: SCtl.SetText("Reset!"); break; case IDC_BUTTON: MessageBeep(0); MessageBeep(0); } } //----------------- FUNCTION WinMain ----------------- int _pascal WinMain(HANDLE instance,HANDLE prevInst,LPSTR cmdLine,int cmdShow) { WinApp::SetInstance(instance); WOOPWindowClass wc; if (prevInst == NULL) wc.Register(); WOOPWindow wdw(wc.GetName()); wdw.Actualize(); wdw.Show(cmdShow); wdw.Update(); return WinApp::Dispatcher(); }; [LISTING FOUR] #include "windows.h" #include "woop.h" WOOPIcon ICON WOOP.ICO WOOPMenu MENU BEGIN POPUP "&Menu" BEGIN MENUITEM "Set", IDM_SET MENUITEM "Reset", IDM_RESET MENUITEM SEPARATOR MENUITEM "&About...", IDM_ABOUT MENUITEM SEPARATOR MENUITEM "E&xit", IDM_EXIT END END [LISTING FIVE] #define IDM_SET 100 #define IDM_RESET 101 #define IDM_ABOUT 102 #define IDM_EXIT 103 [LISTING SIX] NAME OOPAPP DESCRIPTION 'OPP Windows App' EXETYPE WINDOWS STUB 'WINSTUB.EXE' CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE MULTIPLE HEAPSIZE 4096 STACKSIZE 4096 [MAKE FILE] windows = y woop.exe : woop.obj winclass.obj woop.res woop.def woop.obj : woop.cpp winclass.h woop.h winclass.obj : winclass.cpp winclass.h woop.res : woop.rc woop.h woop.ico