File:  [OS/2 SDKs] / pmsdk / samples / within / within.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1988, HEAD
Microsoft OS/2 SDK PM 08-08-1988

/*--------------------- file identification ------------------------*/

/*
 *	within.c
 *
 *	worlds within worlds
 *
 *
 *	Created by Microsoft Corp., 1988
 */


/*---------------------- include files -----------------------------*/

/* os2 pm stuff */
#define INCL_WIN
#include <os2.h>

/* ansi c stuff */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* within stuff */
#include "within.h"


/*------------------------------ main ------------------------------*/

/* main program block */
SHORT cdecl main ()
    {
    /* local variables */
    ULONG afInitFlags ;

    /* try to initialize */
    if (initialize(& afInitFlags))

	/* initialized successfully, so run main message loop*/
	messageLoop() ;

    /* clean up */
    cleanUp(afInitFlags) ;

    /* so long */
    return (0) ;
    }


/*--------------------------- initialize ---------------------------*/

/* initialization procedure */

/* returns true if successful, false if not */

/* sets bits in a longword to indicate
 * success of various initialization activities
 */

BOOL initialize (ULONG * pafInitFlags)
    {
    /* local constants */
    #define    DEFAULT_QUEUE_SIZE   0

    /* init the result flags */
    *pafInitFlags = 0L ;

    /* try to initialize this application thread's use of the PM */
    if (habAnchorBlock = WinInitialize (0))
	*pafInitFlags |= GOT_ANCHOR_BLOCK ;
    else
	return FALSE ;

    /* try to create a message queue */
    if (hmqMessageQueue =
	    WinCreateMsgQueue(habAnchorBlock, DEFAULT_QUEUE_SIZE))
	*pafInitFlags |= GOT_MESSAGE_QUEUE ;
    else
	return FALSE ;

    /* try to register our client window class */
    if (WinRegisterClass ( habAnchorBlock,
		       szOurNameClient,
		       ChildClientWndProc,
		       0L,
		       sizeof (winbytz) ))
	*pafInitFlags |= GOT_CLIENT_CLASS ;
    else
	return FALSE ;

    /* try to create a top-level frame window */
    if (createNewChildStdFrame(
	    & hwndTopFrame, & hwndTopClient, HWND_DESKTOP))
	*pafInitFlags |= GOT_TOP_FRAME_WINDOW ;
    else
	return FALSE ;

    /* made it */
    return TRUE ;

    /* kill local constants */
    #undef    DEFAULT_QUEUE_SIZE
    }


/*---------------------createNewChildStdFrame ----------------------*/

BOOL createNewChildStdFrame (PHWND phwndFrame, PHWND phwndClient,
			     HWND hwndParent)

    {
    /* local variables */
    ULONG   bflWindowStyles ;
    RECTL   rclParentRect ;
    SHORT   sFrameWidth ;
    SHORT   sFrameHeight ;
    SHORT   sBLCx ;
    SHORT   sBLCy ;
    USHORT  usChildNumber ;
    USHORT  usGeneration ;
    CHAR    szOurTitle[80] ;
    CHAR    szPathString[256] ;

    /* prepare style bits for our window creation attempt */
    bflWindowStyles = FCF_SYSMENU    | FCF_TITLEBAR |
		      FCF_SIZEBORDER | FCF_MINMAX   |
		      FCF_MENU	 ;

    /* special case on first window */
    if (hwndParent != HWND_DESKTOP)
	{
	/* not the first window */

	/* get a child number for the child */
	/* all windows except the first go here */
	usChildNumber = WinQueryWindowUShort (hwndParent,
					      US_NUM_CHILDREN) ;

	/* get a generation for the child */
	usGeneration = WinQueryWindowUShort (hwndParent,
			   US_GENERATION) + 1 ;
	}
    else
	{
	/* first window */

	/* get a child number for the child */
	usChildNumber = 0 ;

	/* get a generation for the child */
	usGeneration = 0 ;
	}

    /* initialize the window's path string */
    sprintf (szPathString, "%i", usChildNumber) ;

     if (hwndParent != HWND_DESKTOP)
	/* figure the window's path string */
	getPathString (hwndParent, szPathString) ;


    /* adjust the window title to suit the generation and level */
    sprintf (szOurTitle, "%s %s",
	     szOurNameTitle, szPathString) ;

    /* try to create a standard frame window */
    if (! (*phwndFrame = WinCreateStdWindow (hwndParent,
			      FS_ICON, & bflWindowStyles,
			      szOurNameClient, szOurTitle,
			      WS_VISIBLE, NULL, RSRC_ID_within,
			      phwndClient)))
	return FALSE ;

    /* for first window, record desktop window's handle */
    if (hwndParent == HWND_DESKTOP)
	hwndDeskTop = WinQueryWindow (*phwndFrame, QW_PARENT, FALSE) ;

    /* get the parent window's size */
    WinQueryWindowRect (hwndParent, & rclParentRect) ;

    /* let's make our new window a simple
     * fraction of that size, centered
     */
    sFrameWidth  = (SHORT) ((rclParentRect.xRight -
			rclParentRect.xLeft) * 19 / 20) ;
    sFrameHeight = (SHORT) ((rclParentRect.yTop -
			rclParentRect.yBottom) * 19 / 20) ;
    sBLCx = (SHORT) (sFrameWidth  / 40) ;
    sBLCy = (SHORT) (sFrameHeight / 40) ;

    /* move, size, and show the window */
    WinSetWindowPos (*phwndFrame,
                     HWND_TOP,
                     sBLCx, sBLCy,
		     sFrameWidth, sFrameHeight,
                     SWP_SIZE | SWP_MOVE |
                     SWP_SHOW | SWP_ACTIVATE) ;

    /* tell the parent a child's been born by upping its # of children */
    if (hwndParent != HWND_DESKTOP)
	WinSetWindowUShort(hwndParent, US_NUM_CHILDREN, usChildNumber + 1) ;

    /* set this window's child id  */
    WinSetWindowUShort(*phwndClient, US_CHILD_ID, usChildNumber) ;

    /* store a generation number in the window */
    WinSetWindowUShort(*phwndClient, US_GENERATION, usGeneration) ;

    /* made it; return signalling success */
    return TRUE ;

}


/*------------------------- getPathString --------------------------*/

VOID getPathString (HWND hwndGrandParent, CHAR * szPathString)
    {
    /* stop recursing when we hit the desktop */
    if (hwndGrandParent == HWND_DESKTOP || hwndGrandParent == hwndDeskTop)
	{
	reverseString (szPathString) ;
	return ;
	}

    /* add child number of grandparent to path string */
    sprintf(szPathString, "%s%s%i", szPathString,"-",
	    WinQueryWindowUShort (hwndGrandParent, US_CHILD_ID)) ;

    /* figure out grandparent's parent */
    hwndGrandParent = WinQueryWindow (hwndGrandParent, QW_PARENT, FALSE) ;
    hwndGrandParent = WinQueryWindow (hwndGrandParent, QW_PARENT, FALSE) ;

    /* recurse on grandparent's grandparent */
    getPathString(hwndGrandParent, szPathString) ;
     }


/*--------------------------- reverseString ------------------------*/

/* reverses a string of characters in place */

VOID reverseString (CHAR szSomeString[])
    {
    CHAR   chHoldingCell ;
    USHORT usIndexFromLeft ;
    USHORT usIndexFromRight ;

    for (usIndexFromLeft = 0, usIndexFromRight = strlen (szSomeString) - 1 ;
	 usIndexFromLeft < usIndexFromRight;
	 usIndexFromLeft++, usIndexFromRight--)
	{
	chHoldingCell =szSomeString[usIndexFromLeft] ;
	szSomeString[usIndexFromLeft] = szSomeString[usIndexFromRight] ;
	szSomeString[usIndexFromRight] = chHoldingCell ;
	}
    }

/*---------------------------- messageLoop -------------------------*/

/* main message loop */

VOID messageLoop ()
    {
    /* local variables */
    QMSG    qmsgTheMessage ;

    /* until it's time to quit, fetch a message ... */
    /* we go until there's the top window's done */
    while (WinGetMsg (habAnchorBlock, & qmsgTheMessage, NULL, 0, 0))
	    /* ... send the message off to get handled */
	    WinDispatchMsg (habAnchorBlock, &qmsgTheMessage) ;
    }

/*-------------------------- cleanUp -------------------------------*/

/* carefully mop the floor from our muddy little feet */

VOID cleanUp (ULONG afInitFlags)
    {
    /* if we were able to build a child frame window and it's
     * still alive  ... */
    #ifdef fred
	if (afInitFlags & GOT_CHILD_FRAME_WINDOW)
	/* ... destroy it */
	WinDestroyWindow (hChildFrame) ;
	#endif

    /* if we were able to build a top-level frame window ... */
    if (afInitFlags & GOT_TOP_FRAME_WINDOW)
	/* ... destroy it */
	WinDestroyWindow (hwndTopFrame) ;

    /* if we were able to get a message queue ... */
    if (afInitFlags & GOT_MESSAGE_QUEUE)
	/* ... destroy it */
	WinDestroyMsgQueue (hmqMessageQueue) ;

    /* if we were able to get an anchor block ... */
    if (afInitFlags & GOT_ANCHOR_BLOCK)
	/* ... destroy it */
	WinTerminate (habAnchorBlock) ;
    }


/*-------------------------- ChildFrameWndProc -----------------------*/

MRESULT APIENTRY ChildFrameWndProc(hwnd, msg, mp1, mp2)
HWND  hwnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
    switch (msg) {
 
    case WM_SYSCOMMAND:
        /* MDI:  close window explicitly to avoid posting WM_QUIT */
        if (SHORT1FROMMP(mp1) == SC_CLOSE) {
	    WinDestroyWindow(hwnd);
            return TRUE;
	    }
        break;
 
 
        /* send to DefWindowProc instead of original frame procedure */
        return WinDefWindowProc(hwnd, msg, mp1, mp2);
        break;
    }
    return (*pfnwpRegFrameWndProc)(hwnd, msg, mp1, mp2);
}
 

/*------------------------- ChildClientWndProc --------------------------*/

MRESULT EXPENTRY ChildClientWndProc( HWND hwnd, USHORT usMessage,
				MPARAM mp1, MPARAM mp2 )
    {
    /* local variables */
    HPS   hpsPS ;
    RECTL rclUpdateRect ;
    USHORT usChildID ;
    USHORT usGeneration ;
    CHAR   szPathString [80] ;
    CHAR   szLittleMessage [80] ;
    HWND  hwndGrandParent ;

    /* case out on the message, dudes and dudesses */
    switch (usMessage)
	{
	case WM_COMMAND:
            switch (LOUSHORT (mp1))
                {
		case WINDOW_NEW:
		    /* try to create a child standard frame window */
		    createNewChildStdFrame(
			    & hwndChildFrame[0], & hwndChildClient[0], hwnd) ;

		    /* subclass the child frame window so we can
		     * intercept system menu quit messages
		     */
		    pfnwpRegFrameWndProc = WinSubclassWindow (
					       hwndChildFrame[0],
					       ChildFrameWndProc);


		    break ;

		 default:
		    break ;
		 }
	    return FALSE ;

	case WM_PAINT:
	    /* try to start painting */
	    if (hpsPS = WinBeginPaint (hwnd, NULL, & rclUpdateRect))
		{
		/* got a PS */
		/* get the generation number */
		usGeneration = WinQueryWindowUShort (hwnd, US_GENERATION) ;

		/* get the child number */
		usChildID = WinQueryWindowUShort (hwnd, US_CHILD_ID) ;

		/* initialize the window's path string */
		sprintf (szPathString, "%i", usChildID) ;

		/* build the path */
		 if (usGeneration)
		    {
    hwndGrandParent = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
    hwndGrandParent = WinQueryWindow (hwndGrandParent, QW_PARENT, FALSE) ;

		    /* figure the window's path string */
		    getPathString (hwndGrandParent, szPathString) ;
		}
		/* compose a little message */
		sprintf (szLittleMessage, "%s %s ",
			 "window", szPathString) ;

		/* fill the invalid rectangle with a color */
		WinFillRect (hpsPS, & rclUpdateRect,
			     CLR_BLACK) ;

		/* print a little message */
		fillWindowWithMessage (
		    hpsPS, hwnd, & rclUpdateRect,
		    szLittleMessage,
		    apaclrChildColorArrays[usChildID],
		    asChildColorArraySizes[usChildID]) ;

		/* close down painting operation */
		WinEndPaint (hpsPS) ;

		/* message taken care of */
		return MESSAGE_HANDLED ;
		}
	}
    /* go to default for unhandled messages and
     * handled messages that want continued processing
     */
    return (WinDefWindowProc (hwnd, usMessage, mp1, mp2));
    }


/*---------------------- fillWindowWithMessage ---------------------*/

/* fills a window with a message */

VOID fillWindowWithMessage (HPS hpsPS, HWND hwnd,
			    PRECTL prclInvalidRect,
			    CHAR szSomeMessage [],
			    ULONG aclrColors [],
			    SHORT sNumColors)
    {
    /* local variables */
    RECTL rclWindowRect, rclTextRect, rclDrawRect ;
    SHORT sWindowWidth, sWindowHeight ;
    SHORT sTextWidth, sTextHeight ;
    SHORT sRow, sColumn ;
    SHORT sNumColumns ;
    SHORT sColorIndex ;
    SHORT sStartRow, sEndRow, sStartColumn, sEndColumn ;

    /* figure size of window */
    WinQueryWindowRect (hwnd, & rclWindowRect) ;

    /* figure rectangle text will fit in */
    WinDrawText (hpsPS, -1, szSomeMessage,
		 &rclTextRect, SYSCLR_WINDOWTEXT,
		 SYSCLR_WINDOW, DT_QUERYEXTENT | DT_LEFT | DT_TOP) ;

    /* figure out window's width and height */
    sWindowWidth = (SHORT) rclWindowRect.xRight ;
    sWindowHeight = (SHORT) rclWindowRect.yTop ;

    /* figure out text's width and height */
    sTextWidth = (SHORT) (rclTextRect.xRight - rclTextRect.xLeft) ;
    sTextHeight = (SHORT) (rclTextRect.yTop - rclTextRect.yBottom) ;

    /* figure out number of columns */
    sNumColumns = (sWindowWidth / sTextWidth) + 1 ;

    /* figure out which rows and columns contain the update area */
    /* figure out row for top of invalid rect */
    sStartRow = (sWindowHeight - (SHORT) prclInvalidRect->yTop)
		 / sTextHeight ;

    /* figure out row for bottom of invalid rect */
    sEndRow = (sWindowHeight - (SHORT) prclInvalidRect->yBottom)
	       / sTextHeight ;

    /* figure out column for left of invalid rect */
    sStartColumn = (SHORT) prclInvalidRect->xLeft / sTextWidth ;

    /* figure out column for right of invalid rect */
    sEndColumn = (SHORT) prclInvalidRect->xRight / sTextWidth ;

    /* draw those rows and columns */

    /* move text rect to initial row and column */
    rclTextRect.xLeft = sStartColumn * sTextWidth ;
    rclTextRect.xRight = rclTextRect.xLeft + sTextWidth ;
    rclTextRect.yTop = rclWindowRect.yTop -
		       (sStartRow * sTextHeight) ;
    rclTextRect.yBottom = rclTextRect.yTop - sTextHeight ;

    /* initialize the vertical parts of the drawing rectangle */
    rclDrawRect.yTop = rclTextRect.yTop ;
    rclDrawRect.yBottom = rclTextRect.yBottom ;

    /* for each row to be drawn ... */
    for (sRow = sStartRow ;
	 sRow <= sEndRow ;
	 sRow ++)
	{
	/* adjust drawing rectangle for first column in a row */
	rclDrawRect.xLeft = rclTextRect.xLeft ;
	rclDrawRect.xRight = rclTextRect.xRight ;

	/* initialize a coloring index */
	sColorIndex = (sRow * sNumColumns + sStartColumn)
		      % sNumColors ;

	/* for each column in the row ... */
	for (sColumn = sStartColumn ;
	     sColumn <= sEndColumn ;
	     sColumn ++)
	    {
	    /* draw the column's text */
	    WinDrawText (hpsPS, -1, szSomeMessage,
			 &rclDrawRect, aclrColors [sColorIndex],
			 SYSCLR_WINDOW, DT_LEFT | DT_TOP) ;

	    /* adjust color for next column */
	    if (++sColorIndex == sNumColors)
		sColorIndex = 0 ;

	    /* adjust drawing rectangle for next column */
	    rclDrawRect.xLeft += sTextWidth ;
	    rclDrawRect.xRight += sTextWidth ;
	    }

	/* adjust drawing rectangle for next row */
	rclDrawRect.yTop -= (LONG) sTextHeight ;
	rclDrawRect.yBottom -= (LONG) sTextHeight ;
	}
    }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.