home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
TOOLKIT
/
OS2
/
VMM
/
VMM_MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
27KB
|
627 lines
/*static char *SCCSID = "@(#)vmm_main.c 6.19 92/02/18";*/
/*==============================================================*\
* VMM_MAIN.C - Sample PM application *
* *
* (C) Copyright IBM Corporation 1992 *
* *
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is*
* sample code created by IBM Corporation. This sample code is*
* not part of any standard IBM product and is provided to you*
* solely forthe purpose of assisting you in the development *
* of your applications. The code is provided "AS IS", *
* without warranty of any kind. No IBM shall be liable for *
* any damages arising out of your use of the sample code, *
* even if they have been advised of the possibility of *
* such damages. *
* *
*--------------------------------------------------------------*
* *
* This application serves two distinct purposes. First, it *
* demonstrates the standard menus and dialogs that most PM *
* applications will contain. The Demo menu calls dialog *
* boxes that demonstrate all of the controls available for *
* use in a dialog box. There is also a dialog box which *
* demonstrates the setting and removing of control *
* Presentation Parameters. Finally, the demo menu also has *
* menu items that demonstrate the various types of message *
* boxes that the system supports. *
* *
* This application also serves as a template that can be *
* easily modified by an application developer. The source *
* files are organized so that the overhead code that should *
* be in all applications is located in the same files so *
* that these files do not need to be modified. The routines *
* that deal with application specific code are also located *
* in their own modules. An application developer need only *
* change these files in order to modify this template for *
* his application. *
* *
*--------------------------------------------------------------*
* *
* This source file contains the following functions: *
* *
* main() - main routine *
* MainWndProc(hwnd, msg, mp1, mp2) - main window procedure*
* MainCommand(mp1, mp2) - WM_COMMAND processing of Main *
* MessageBox(hwnd nId, pszMsg, fsStyle, bBeep) *
* DisplayPage(hps, pptl, ulPageIndex) *
* EnableMenuItem(hwnd, sMenuItem, fEnable) *
* *
\*==============================================================*/
/*--------------------------------------------------------------*\
* Include files, macros, defined constants, and externs *
\*--------------------------------------------------------------*/
#include "vmm.h"
/****************************************************************\
* Main routine *
*--------------------------------------------------------------*
* *
* Name: main() *
* *
* Purpose: Initializes the PM environment, calls the *
* initialization routine, creates the main *
* window, and polls the message queue *
* *
* Usage: *
* *
* Method: -obtains anchor block handle and creates message *
* queue *
* -calls the initialization routine *
* -creates the main frame window which creates the *
* main client window *
* -polls the message queue via Get/Dispatch Msg loop *
* -upon exiting the loop, exits *
* *
* Returns: 1 - if sucessful execution completed *
* 0 - if error *
\****************************************************************/
INT main(VOID)
{
QMSG qmsg; /* message structure */
ULONG ctlData; /* frame control data */
EXCEPTIONREGISTRATIONRECORD ExceptionStruct;
ulFreePage = 0L;
strcpy(szWindowText,"VMM Sample");
hab = WinInitialize(0);
if(!hab)
{
DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
DosExit(EXIT_PROCESS, RETURN_ERROR);
}
/* find a define for this v */
hmq = WinCreateMsgQueue(hab, 0);
if(!hmq)
{
DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
WinTerminate(hab);
DosExit(EXIT_PROCESS, RETURN_ERROR);
}
if(!Init())
{
MessageBox(HWND_DESKTOP, IDMSG_INITFAILED, "Error !",
MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
DosExit(EXIT_PROCESS, RETURN_ERROR);
}
/* create the main window */
ctlData = FCF_STANDARD | FCF_VERTSCROLL;
hwndMainFrame = WinCreateStdWindow(HWND_DESKTOP,
WS_VISIBLE,
(PVOID)&ctlData,
(PSZ)szAppName,
(PSZ)NULL,
WS_VISIBLE,
(HMODULE)NULL,
IDR_RESOURCE,
(PHWND)&hwndMain);
if(!hwndMainFrame)
{
MessageBox(HWND_DESKTOP, IDMSG_MAINWINCREATEFAILED, "Error !",
MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
DosExit(EXIT_PROCESS, RETURN_ERROR);
}
InitHelp();
/* Invoke exception management, and direction user
exception handling function to GPFHandler() */
ExceptionStruct.ExceptionHandler = (_ERR *)&GPFHandler;
DosSetExceptionHandler(&ExceptionStruct) ;
/* Get/Dispatch Message loop */
while(WinGetMsg(hab, (PQMSG)&qmsg, 0L, 0L, 0L))
WinDispatchMsg(hab, (PQMSG)&qmsg);
/* Release exception managerment */
DosUnsetExceptionHandler(&ExceptionStruct) ;
DestroyHelpInstance(); /* destroy the help instance */
#ifdef VER630
/* will normally be put in ExitProc */
WinDestroyWindow(hwndMainFrame);
/*--------------------------------------------------*\
* Any other system resources used *
* (e.g. memory or files) should be freed here *
\*--------------------------------------------------*/
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
#endif
DosExit(EXIT_PROCESS, RETURN_SUCCESS);
return 0L;
} /* main() */
/****************************************************************\
* Main client window procedure *
*--------------------------------------------------------------*
* *
* Name: MainWndProc(hwnd, msg, mp1, mp2) *
* *
* Purpose: Processes the messages sent to the main client *
* window. This routine processes the basic messages *
* all client windows should process and passes all *
* others onto UserWndProc where the developer can *
* process any others. *
* *
* Usage: Called for each message placed in the main *
* window's message queue *
* *
* Method: a switch statement branches to the routines to be *
* performed for each message processed. Any messages *
* not specifically process are passed to the user's *
* message processing procedure UserWndProc(). *
* *
* Returns: Return values are determined by each message *
* *
\****************************************************************/
MRESULT EXPENTRY MainWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
static LONG sVscrollMax;
MRESULT sRC;
switch(msg)
{
case WM_CREATE:
sVscrollMax = MAXPAGES*(BOX_HEIGHT+VERT_SPACING);
hwndVscroll = WinWindowFromID(
WinQueryWindow(hwnd, QW_PARENT),
FID_VERTSCROLL);
WinSendMsg(hwndVscroll, SBM_SETSCROLLBAR,
MPFROM2SHORT(sVscrollPos, 0),
MPFROM2SHORT(0, sVscrollMax) );
break;
case WM_VSCROLL:
switch (SHORT2FROMMP(mp2))
{
case SB_LINEUP:
sVscrollPos -= SMALL_BOX_HEIGHT;
break;
case SB_LINEDOWN:
sVscrollPos += SMALL_BOX_HEIGHT;
break;
case SB_PAGEUP:
sVscrollPos -= BOX_HEIGHT+VERT_SPACING;
break;
case SB_PAGEDOWN:
sVscrollPos += BOX_HEIGHT+VERT_SPACING;
break;
case SB_SLIDERTRACK:
case SB_SLIDERPOSITION:
sVscrollPos = SHORT1FROMMP(mp2);
break;
}
sVscrollPos = max(0, min(sVscrollPos, sVscrollMax) );
if(sVscrollPos != SHORT1FROMMR(WinSendMsg(hwndVscroll,
SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL)))
{
WinSendMsg(hwndVscroll, SBM_SETPOS,
MPFROMSHORT(sVscrollPos), NULL);
WinInvalidateRect(hwnd, NULL, FALSE);
}
break;
case WM_CHAR:
switch (SHORT2FROMMP(mp2))
{
case VK_LEFT:
case VK_UP:
sVscrollPos -= SMALL_BOX_HEIGHT;
break;
case VK_DOWN:
case VK_RIGHT:
sVscrollPos += SMALL_BOX_HEIGHT;
break;
case VK_PAGEUP:
sVscrollPos -= BOX_HEIGHT+VERT_SPACING;
break;
case VK_PAGEDOWN:
sVscrollPos += BOX_HEIGHT+VERT_SPACING;
break;
}
sVscrollPos = max(0, min(sVscrollPos, sVscrollMax) );
if(sVscrollPos != SHORT1FROMMR(WinSendMsg(hwndVscroll,
SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL)))
{
WinSendMsg(hwndVscroll, SBM_SETPOS,
MPFROMSHORT(sVscrollPos), NULL);
WinInvalidateRect(hwnd, NULL, FALSE);
}
break;
case WM_PAINT:
MainPaint(hwnd);
break;
case WM_COMMAND:
MainCommand(mp1, mp2);
break;
/*--------------------------------------------------*\
* Any messages not processed are passed on *
* to the user's window proc. It is *
* responsible for passing any messages it *
* doesn't handle onto WinDefWindowProc() *
\*--------------------------------------------------*/
case HM_QUERY_KEYS_HELP:
return ((MRESULT)PANEL_KEYSHELP);
default:
sRC = WinDefWindowProc(hwnd, msg, mp1, mp2);
return sRC;
}
return ((MRESULT)0L); /* window procedures should return 0 as a default */
} /* MainWndProc() */
/****************************************************************\
* Main client painting routine *
*--------------------------------------------------------------*
* *
* Name: MainPaint(hwnd) *
* *
* Purpose: Paints the main client window. *
* *
* Usage: Routine is called whenver the client window *
* procedure receives a WM_PAINT message *
* *
* Method: -begins painting by calling WinBeginPaint *
* and retriving the HPS for the window *
* -paint page info boxes *
* *
* -ends painting by calling WinEndPaint *
* *
* Returns: VOID *
* *
\****************************************************************/
VOID MainPaint(HWND hwnd)
{
HPS hps;
USHORT i;
POINTL ptl;
RECTL rect;
SIZEL sizl;
char szBuff[BUFF_SIZE];
sizl.cx = 0L;
sizl.cy = 0L;
hps = WinBeginPaint(hwnd, 0L, 0L);
GpiSetPS(hps, &sizl, PU_LOMETRIC);
WinQueryWindowRect(hwnd, &rect);
WinFillRect(hps, (PRECTL)&rect, CLR_BACKGROUND);
/* convert the coords of the window to world coords */
GpiConvert(hps, CVTC_DEVICE, CVTC_WORLD, 2L, (PPOINTL) &rect);
ptl.x = HORZ_INDENT*3;
ptl.y = rect.yTop - (BOX_HEIGHT+VERT_SPACING) + sVscrollPos;
GpiMove(hps, &ptl);
ptl.x += BOX_WIDTH;
ptl.y += BOX_HEIGHT;
GpiSetColor(hps, CLR_GREEN);
GpiBox(hps, DRO_OUTLINE, &ptl, 0L, 0L);
ptl.x = HORZ_INDENT*3 + HORZ_SPACING*3 + BOX_WIDTH;
ptl.y = rect.yTop - (BOX_HEIGHT+VERT_SPACING) + sVscrollPos;
GpiMove(hps, &ptl);
ptl.x += BOX_WIDTH;
ptl.y += BOX_HEIGHT;
GpiSetColor(hps, CLR_RED);
GpiBox(hps, DRO_OUTLINE, &ptl, 0L, 0L);
GpiSetColor(hps, CLR_BLACK);
ptl.x = HORZ_INDENT*3+30;
ptl.y = rect.yTop - (VERT_SPACING+SMALL_BOX_HEIGHT) + 30 + sVscrollPos;
strcpy(szBuff,"Committed");
GpiCharStringAt(hps, &ptl, (LONG) strlen(szBuff), szBuff);
ptl.y -= SMALL_BOX_HEIGHT;
strcpy(szBuff,"page");
GpiCharStringAt(hps, &ptl, (LONG) strlen(szBuff), szBuff);
ptl.x = HORZ_INDENT*3+30 + HORZ_SPACING*3 + BOX_WIDTH ;
ptl.y = rect.yTop - (VERT_SPACING+SMALL_BOX_HEIGHT) + 30 + sVscrollPos;
strcpy(szBuff,"Non-Committed");
GpiCharStringAt(hps, &ptl, (LONG) strlen(szBuff), szBuff);
ptl.y -= SMALL_BOX_HEIGHT;
strcpy(szBuff,"page");
GpiCharStringAt(hps, &ptl, (LONG) strlen(szBuff), szBuff);
ptl.x = HORZ_INDENT; /* 1'st page location */
ptl.y = rect.yTop - 2*(BOX_HEIGHT+VERT_SPACING) + sVscrollPos;
for (i=0;((ULONG) i)<ulFreePage; i++)
{
DisplayPage(hps, &ptl, i); /* Redisplay alloc status */
ptl.x += BOX_WIDTH+HORZ_SPACING;
if (ptl.x+BOX_WIDTH > rect.xRight)
{ /* If next page over window, move to next line */
ptl.x = HORZ_INDENT+BOX_WIDTH+HORZ_SPACING;
ptl.y -= (BOX_HEIGHT+VERT_SPACING);
}
/* If the next page is a base page, display it on a new line for clarity */
if (apgentry[i+1].fBaseAddr)
{
ptl.x = HORZ_INDENT;
ptl.y -= (BOX_HEIGHT+VERT_SPACING);
}
}
WinEndPaint(hps);
return;
} /* MainPaint() */
/****************************************************************\
* Main window WM_COMMAND processing procedure *
*--------------------------------------------------------------*
* *
* Name: MainCommand(mp1, mp2) *
* *
* Purpose:Calls the appropriate procedures that deal with *
* the selected menu item. *
* *
* Usage: Routine is called whenever a WM_COMMAND message *
* is posted to the main window. *
* *
* Method: a switch statement branches on the id of the *
* menu item that posted the message and the *
* appropriate action for that item is taken. Any *
* menu ids that are not part of the standard menu *
* set are passed onto the user defined WM_COMMAND *
* processing procedure. *
* *
* Returns: *
* *
\****************************************************************/
VOID MainCommand(MPARAM mp1, MPARAM mp2)
{
switch(SHORT1FROMMP(mp1))
{
case IDM_GENERALHELP:
HelpExtended(mp2);
return;
case IDM_USINGHELP:
HelpHelpForHelp(mp2);
return;
case IDM_TUTORIAL:
HelpKeys(mp2);
return;
case IDM_HELPINDEX:
HelpIndex(mp2);
return;
case IDM_HELPPRODUCTINFO:
HelpAbout(mp2);
return;
/*--------------------------------------------------*\
* User command processing routine is called *
* here so any ids not procecessed here can be *
* processed *
\*--------------------------------------------------*/
default:
UserCommand(mp1, mp2);
break;
}
return;
} /* MainCommand() */
/****************************************************************\
* Exit routine *
*--------------------------------------------------------------*
* *
* Name: DisplayPage(hps, pptl, ulPageIndex) *
* *
* Purpose: Processes the VMM menu's Exit item. *
* *
* Usage: called whenever Exit from the VMM menu is *
* selected *
* *
* Method: Routine posts a WM_CLOSE message to the main *
* application window. *
* *
* Returns: VOID *
* *
\****************************************************************/
VOID DisplayPage(HPS hps, PPOINTL pptl, ULONG ulPageIndex)
{
POINTL ptl;
MATRIXLF matrix;
ULONG ulAccess=0;
ULONG ulRegionSize;
PVOID pMem;
char szBuff[BUFF_SIZE];
pMem = apgentry[ulPageIndex].pvAddress;
/* We don't check the return code here since we assume that the array
contains good addresses since we verified them when we put them in
the array. */ /* Get memory size & attributes */
DosQueryMem(pMem, &ulRegionSize, &ulAccess);
matrix.fxM11 = MAKEFIXED(1,0);
matrix.fxM12 = 0L;
matrix.lM13 = 0L;
matrix.fxM21 = 0L;
matrix.fxM22 = MAKEFIXED(1,0);
matrix.lM23 = 0L;
matrix.lM31 = pptl->x; /* x translation */
matrix.lM32 = pptl->y; /* y translation */
matrix.lM33 = 1L;
GpiSetDefaultViewMatrix(hps, 9L, &matrix,TRANSFORM_REPLACE);
ptl.x = 0L;
ptl.y = 0L;
GpiMove(hps, &ptl);
ptl.x = BOX_WIDTH;
ptl.y = BOX_HEIGHT;
/* set outline color to CLR_RED for uncommitted, CLR_GREEN for committed */
if (ulAccess & PAG_COMMIT)
{
GpiSetColor(hps, CLR_GREEN);
}
else
GpiSetColor(hps, CLR_RED);
GpiBox(hps, DRO_OUTLINE, &ptl, 0L, 0L);
/* should query sys values in case the default is not black ? */
GpiSetColor(hps, CLR_BLACK);
szBuff[0]='\000';
if (ulAccess & PAG_READ)
strcat(szBuff, "R");
if (ulAccess & PAG_WRITE)
strcat(szBuff, "W");
if (ulAccess & PAG_EXECUTE)
strcat(szBuff, "E");
if (ulAccess & PAG_GUARD)
strcat(szBuff, "G");
if (ulAccess & PAG_DEFAULT)
strcat(szBuff, "Def");
if (ulAccess & PAG_BASE)
strcat(szBuff, "Base");
ptl.x = HORZ_INDENT;
ptl.y = VERT_INDENT;
GpiCharStringAt(hps, &ptl, (LONG) strlen(szBuff), szBuff);
ptl.x = 0;
ptl.y = SMALL_BOX_HEIGHT;
GpiMove(hps, &ptl);
ptl.x = BOX_WIDTH;
ptl.y = SMALL_BOX_HEIGHT;
GpiLine(hps, &ptl);
/* Get base address of current page */
sprintf(szBuff, "0x%p", pMem);
ptl.x = HORZ_INDENT;
ptl.y = SMALL_BOX_HEIGHT+VERT_INDENT;
GpiCharStringAt(hps, &ptl, (LONG) strlen(szBuff), szBuff);
return;
}
/****************************************************************\
* Message Box procedure *
*--------------------------------------------------------------*
* *
* Name: MessageBox(hwndOwner, nIdMsg,pszMsg,fsStyle, bBeep)*
* *
* Purpose: Displays the warning message box with the message *
* given in nIdMsg retrived from the message table *
* *
* Usage: Called whever an error occurs and a message wishes *
* to be displayed to the user *
* *
* Method: - Message string is loaded from the process' *
* message table *
* - Alarm beep is sounded if desired *
* - Message box with the message is displayed *
* *
* Returns: *
* *
\****************************************************************/
VOID MessageBox(HWND hwndOwner, LONG nIdMsg, PSZ pszMsg, LONG fsStyle,
BOOL bBeep)
{
CHAR szText[MESSAGELEN];
if(!WinLoadMessage(hab, (HMODULE)NULL, nIdMsg, MESSAGELEN, (PSZ)szText))
{
WinAlarm(HWND_DESKTOP, WA_ERROR);
return;
}
if(bBeep)
WinAlarm(HWND_DESKTOP, WA_ERROR);
WinMessageBox(HWND_DESKTOP,
hwndOwner,
szText,
(PSZ)pszMsg,
IDM_MSGBOX,
fsStyle);
return;
} /* MessageBox() */
/****************************************************************\
* EnableMenuItem procedure *
*--------------------------------------------------------------*
* *
* Name: EnableMenuItem(hwnd, sMenuItem, fEnable) *
* *
* Purpose: This routine handles enabling/disabling of menu *
* items. This is done by getting Parent and Menu hwnd *
* handles then sending the appropriate message. * *
* *
* Usage: Routine is called when enable or disable one item *
* from menu. *
* *
* Method: *
* *
* Returns: VOID *
* *
\****************************************************************/
VOID EnableMenuItem(HWND hwnd, LONG sMenuItem, BOOL fEnable)
{
HWND hwndParent = WinQueryWindow(hwnd, QW_PARENT);
HWND hwndMenu = WinWindowFromID(hwndParent,FID_MENU);
WinSendMsg(hwndMenu, MM_SETITEMATTR,
MPFROM2SHORT(sMenuItem, TRUE),
MPFROM2SHORT(MIA_DISABLED, fEnable ? 0 : MIA_DISABLED));
return;
}