home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------*/
- /* (c) 1993, 1994 Larry Morley / Enlightened Computer Solutions */
- /*----------------------------------------------------------------------------*/
- /* module: classlib.cpp created_on: 1 May 1993 by: LJM */
- /* desc : Main framework class lib source file */
- /* complr: icc /Fi /Fd /c /Ss /Sp1 /Gm+ /G4 /Kb+ [/Ti+ intrnl, /Ti- rel] */
- /* lnkr : link386 /a:4 [/deb intrnl,rel=<none> /base:65536 /noe */
- /* rc $*.res */
- /* etc : rc -r $*.rc */
- /* mkfile: makefile */
- /* depend: (see makefile) */
- /* mhist : LJM 02 May 1993 Added functionality to Menu class */
- /*----------------------------------------------------------------------------*/
-
- #define INCL_WIN
- #define INCL_DOS
- #define INCL_GPI
- #include <os2.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "cppapp.hpp"
- #include "classlib.hpp"
-
- /*----------------------------------------------------------------------------*/
- // Class names
-
- CHAR szClientClass[] = "C++ClientWindow";
- CHAR szFrameClass[] = "C++FrameWindow";
- CHAR szStatLineClass[] = "C++StatusWindow";
-
- CHAR szStatLineText[256];
-
- // Standard style flags
- ULONG ulFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
- FCF_SIZEBORDER | FCF_MINMAX |
- FCF_SHELLPOSITION | FCF_TASKLIST |
- FCF_MENU | FCF_ICON ;
-
- HAB hab;
- HMQ hmq;
- QMSG qmsg;
-
- PFNWP pfnOrigFrameProc;
- USHORT cbFrameExtra;
-
- /*----------------------------------------------------------------------------*/
- // These are all pretty straightforward -
- // start by creating an App,
- // create windows or whatever else is needed,
- // and run the App (App->Run()).
-
- // Sets up the message queue
- App :: App()
- {
-
- hab = WinInitialize((USHORT)0);
- hmq = WinCreateMsgQueue(hab,(SHORT)0);
-
- }
-
- /*----------------------------------------------------------------------------*/
- // The message loop
-
- void App :: Run()
- {
- while (WinGetMsg(hab,&qmsg,(HWND)0,(USHORT)0,(USHORT)0))
- WinDispatchMsg(hab,&qmsg);
- }
-
- /*----------------------------------------------------------------------------*/
- // Cleanup
-
- App :: ~App()
- {
- WinDestroyMsgQueue(hmq);
- WinTerminate(hab);
- }
-
- /*----------------------------------------------------------------------------*/
- // Cleanup
-
- Window :: ~Window()
- {
- WinDestroyWindow(hwndFrame);
- }
-
- /*----------------------------------------------------------------------------*/
- // These methods all apply to the hwndMenu member of the window -
- // I won't describe them in detail, since they're pretty much
- // straightforward.
-
- void Menu :: DisableItem(Window *pWindow,USHORT idItem)
- {
- WinSendMsg(
- pWindow->hwndMenu,
- MM_SETITEMATTR,
- MPFROM2SHORT(
- idItem,
- TRUE),
- MPFROM2SHORT(
- MIA_DISABLED,
- MIA_DISABLED));
- }
-
- /*----------------------------------------------------------------------------*/
-
- void Menu :: EnableItem(Window *pWindow,USHORT idItem)
- {
- WinSendMsg(
- pWindow->hwndMenu,
- MM_SETITEMATTR,
- MPFROM2SHORT(
- idItem,
- TRUE),
- MPFROM2SHORT(
- MIA_DISABLED,
- FALSE));
- }
-
- /*----------------------------------------------------------------------------*/
-
- void Menu :: CheckItem(Window *pWindow,USHORT idItem)
- {
- WinSendMsg(
- pWindow->hwndMenu,
- MM_SETITEMATTR,
- MPFROM2SHORT(
- idItem,
- TRUE),
- MPFROM2SHORT(
- MIA_CHECKED,
- MIA_CHECKED));
- }
-
- /*----------------------------------------------------------------------------*/
-
- void Menu :: UnCheckItem(Window *pWindow,USHORT idItem)
- {
- WinSendMsg(
- pWindow->hwndMenu,
- MM_SETITEMATTR,
- MPFROM2SHORT(
- idItem,
- TRUE),
- MPFROM2SHORT(
- MIA_CHECKED,
- FALSE));
- }
-
- /*----------------------------------------------------------------------------*/
- // Create a frame window with a status bar / message bar at the bottom
-
- BOOL Window :: Create()
- {
- // Take an existing class (WC_FRAME), get its
- // window proc, add extra room (window words)
- // and re-register it under my own classname.
- CLASSINFO ci;
- WinQueryClassInfo(hab,WC_FRAME,&ci);
- pfnOrigFrameProc = ci.pfnWindowProc;
- cbFrameExtra = ci.cbWindowData;
-
- // Try to re-register; return FALSE if
- // attempt fails
- if (!WinRegisterClass(
- hab,
- szFrameClass,
- FrameWndProc,
- ci.flClassStyle & (~CS_PUBLIC),
- ci.cbWindowData+sizeof(this)))
- return FALSE;
-
- // Register the client window class
- // (I should probably check here)
- WinRegisterClass(
- hab,
- szClientClass,
- ClientWndProc,
- CS_SIZEREDRAW,
- sizeof(this));
-
- // Register the status window class
- // (should probably check here too)
- WinRegisterClass(
- hab,
- szStatLineClass,
- StatLineWndProc,
- CS_SIZEREDRAW,
- sizeof(this));
-
- // Start creating windows: I don't use WinCreateStdWindow(),
- // create each piece individually. That gives me the
- // flexibility of being able to put a pointer to "this" in
- // the components of the window.
- // To do it this way, start with the frame:
- hwndFrame = WinCreateWindow(
- HWND_DESKTOP, /* parent */
- szFrameClass, /* class */
- "Main Window", /* title */
- 0L, /* style */
- 0, /* x */
- 0, /* y */
- 0, /* cx */
- 0, /* cy */
- (HWND)0, /* owner */
- HWND_TOP, /* z-order */
- ID_RESOURCE, /* window id */
- this, /* control parms */
- (PVOID)0); /* pres parms */
-
- if (!hwndFrame)
- return FALSE;
-
- // Then, create the client with an id
- // of FID_CLIENT (very important)
- hwndClient = WinCreateWindow(
- hwndFrame,
- szClientClass,
- (PSZ)0,
- 0L,
- 0,
- 0,
- 0,
- 0,
- hwndFrame,
- HWND_TOP,
- FID_CLIENT,
- (PVOID)this,
- (PVOID)0);
-
- if (!hwndClient)
- return FALSE;
-
- // And lastly, I create the status
- // bar window
- hwndStatus = WinCreateWindow(
- hwndFrame,
- szStatLineClass,
- (PSZ)0,
- 0L,
- 0,
- 0,
- 0,
- 0,
- hwndFrame,
- HWND_TOP,
- FID_STATUS,
- (PVOID)this,
- (PVOID)0);
-
- if (!hwndStatus)
- return FALSE;
-
- // Set the window's text and show it
- WinSetWindowText(hwndFrame,"C++ PM Application by Larry Morley");
- WinShowWindow(hwndFrame,TRUE);
-
- return TRUE;
-
- }
-
- /*----------------------------------------------------------------------------*/
- // Event handler for WM_PAINT
-
- MRESULT Window :: PaintEventHandler(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- HPS hPS;
- RECTL rcl;
-
- hPS = WinBeginPaint(hwnd,(HPS)0,&rcl);
- GpiErase(hPS);
- WinEndPaint(hPS);
-
- return (MRESULT)0;
- }
-
- /*----------------------------------------------------------------------------*/
- // Event handler for WM_MENUSELECT
-
- MRESULT Window :: MenuSelectEventHandler
- (HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- return WinDefWindowProc(hwnd,msg,mp1,mp2);
- }
-
- /*----------------------------------------------------------------------------*/
- // Event handler for WM_COMMAND (mostly for menu)
-
- MRESULT Window :: CommandEventHandler(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- return WinDefWindowProc(hwnd,msg,mp1,mp2);
- }
-
- /*----------------------------------------------------------------------------*/
- // This is how I make room for the status bar window at the bottom, and
- // actually make it an integral part of the frame.
-
- MRESULT Window :: FormatFrameEventHandler
- (HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- int origCount;
- // The original proc returns the number of items in the frame window
- origCount = (int)((*pfnOrigFrameProc)(hwnd,msg,mp1,mp2));
- // Enumerate them and look for FID_CLIENT
- if (origCount)
- {
- int i;
- for (i=0;i<origCount;i++)
- {
- if (WinQueryWindowUShort(((PSWP)mp1)[i].hwnd,QWS_ID)
- == FID_CLIENT)
- {
- HWND hwndTemp;
-
- // Position the status / message / whatever bar
- hwndTemp=WinWindowFromID(hwnd,FID_STATUS);
-
- if (hwndTemp)
- WinSetWindowPos(hwndTemp,
- HWND_TOP,
- ((PSWP)mp1)[i].x,
- ((PSWP)mp1)[i].y,
- ((PSWP)mp1)[i].cx,
- 25,
- ((PSWP)mp1)[i].fl);
-
- // And adjust the size of the client
- // area accordingly (it's fixed at 25
- // right now; you could base it on
- // pretty much anything you wish)
- ((PSWP)mp1)[i].y += 25;
- ((PSWP)mp1)[i].cy -= 25;
-
- }
- }
- }
- // Tell PM how many parts are in the frame
- return (MRESULT)origCount;
- }
-
- /*----------------------------------------------------------------------------*/
-
- MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
-
- Window *w;
- MRESULT rc;
-
- // See if the window contains a pointer to
- // a Window object.
- w = (Window *)WinQueryWindowPtr(hwnd,0);
-
- switch (msg)
- {
- // WM_CREATE is called directly, not sent; when you
- // call WinCreateWindow() the function calls the window
- // proc with WM_CREATE. That's why it's safe to set
- // the pointer to the owner object here - I'm guaranteed
- // that nothing else will happen in the meantime.
- case WM_CREATE:
-
- WinSetWindowPtr(hwnd,0,(PVOID)mp1);
-
- ((Window *)mp1)->hwndMenu =
- WinWindowFromID(
- WinQueryWindow(hwnd,QW_PARENT),FID_MENU);
-
- break;
-
- // The rest of the code just dispatches messages
- // to the appropriate event handlers.
- case WM_PAINT:
-
- rc = w->PaintEventHandler(hwnd,msg,mp1,mp2);
- return rc;
-
- case WM_COMMAND:
-
- rc = w->CommandEventHandler(hwnd,msg,mp1,mp2);
- return rc;
-
- case WM_MENUSELECT:
-
- rc = w->MenuSelectEventHandler(hwnd,msg,mp1,mp2);
- return rc;
-
- }
-
- return WinDefWindowProc(hwnd,msg,mp1,mp2);
-
- }
-
- /*----------------------------------------------------------------------------*/
- // This is my "replacement" frame window procedure -
- // I get the information I want, then pass the rest along
- // to the default procedure. It's also where I catch the
- // WM_FORMATFRAME message.
-
- MRESULT EXPENTRY FrameWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- switch (msg)
- {
- case WM_CREATE:
- // mp1 is a pointer to "this" -
- // set it up here for the same
- // reasons as for the client window.
- WinSetWindowPtr(hwnd,cbFrameExtra,(PVOID)mp1);
-
- // Alter the frame data that I want
- // to change...
- FRAMECDATA fcdata;
- fcdata.cb = sizeof(fcdata);
- fcdata.flCreateFlags = ulFrameFlags;
- fcdata.hmodResources = (HMODULE)0L;
- fcdata.idResources = ID_RESOURCE;
- return (*pfnOrigFrameProc)(hwnd,msg,(MPARAM)&fcdata,mp2);
-
- case WM_FORMATFRAME:
- // Invoke Window::FormatFrameEventHandler()
- Window *w;
- MRESULT rc;
- w = (Window *)WinQueryWindowPtr(hwnd,cbFrameExtra);
- rc = w->FormatFrameEventHandler(hwnd,msg,mp1,mp2);
- return rc;
-
- case WM_MENUSELECT:
- // This case is nescessary in the frame window proc
- // because that's where the system menu MENUSELECTS
- // are sent.
- w = (Window *)WinQueryWindowPtr(hwnd,cbFrameExtra);
- rc = w->MenuSelectEventHandler(hwnd,msg,mp1,mp2);
- return rc;
-
- default:
- break;
-
- }
-
- // Can't use WinDefWindowProc(); have to use the default
- // WC_FRAME window proc.
- return (*pfnOrigFrameProc)(hwnd,msg,mp1,mp2);
-
- }
-
- /*----------------------------------------------------------------------------*/
- // This is a pretty straightforward window procedure; it's the window proc
- // for the status / message / whatever area.
-
- MRESULT EXPENTRY StatLineWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- HPS hPS;
- RECTL rcl;
- POINTL ptl;
- LONG lColor;
-
- static SHORT cxClient;
- static SHORT cyClient;
- static int cyChar;
- static int cyDesc;
- static int cxChar;
- static int cxCaps;
-
- switch (msg)
- {
- case WM_CREATE:
-
- FONTMETRICS fm;
- hPS = WinGetPS(hwnd);
- GpiQueryFontMetrics(hPS,(LONG)sizeof(fm),&fm);
- cyChar = (int)fm.lMaxBaselineExt;
- cyDesc = (int)fm.lMaxDescender;
- cxChar = (int)fm.lEmInc;
- cxCaps = (int)fm.lAveCharWidth;
- WinReleasePS(hPS);
-
- strcpy(szStatLineText,"Ready.");
-
- break;
-
- case WM_SIZE:
-
- cxClient = SHORT1FROMMP(mp2);
- cyClient = SHORT2FROMMP(mp2);
-
- break;
-
- case WM_PAINT:
-
- hPS = WinBeginPaint(hwnd,(HPS)0,&rcl);
- WinFillRect(hPS,&rcl,CLR_PALEGRAY);
-
- lColor = GpiQueryColor(hPS);
- GpiSetColor(hPS,CLR_DARKGRAY);
-
- ptl.x = 0;
- ptl.y = cyClient-1;
- GpiMove(hPS,&ptl);
- ptl.x = cxClient-1;
- ptl.y = cyClient-1;
- GpiLine(hPS,&ptl);
- ptl.x = cxClient-1;
- ptl.y = 0;
- GpiLine(hPS,&ptl);
-
- GpiSetColor(hPS,lColor);
-
- ptl.x = 2;
- ptl.y = cyClient-cyChar-1;
- GpiCharStringAt(hPS,&ptl,strlen(szStatLineText),szStatLineText);
-
- WinEndPaint(hPS);
-
- break;
-
- default:
-
- return WinDefWindowProc(hwnd,msg,mp1,mp2);
-
- }
- return (MRESULT)0L;
- }
-
- /*----------------------------------------------------------------------------*/