home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
TOOLKIT
/
CREXX
/
PMREXX
/
PMRXSUBS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
58KB
|
966 lines
/* static char *SCCSID = "@(#)pmrxsubs.c 12.7 89/10/13"; */
/********************* START OF SPECIFICATIONS ******************************/
/* */
/* SOURCE FILE NAME: pmrxsubs.c */
/* */
/* DESCRIPTIVE NAME: Miscellaneous subroutines to support the PMREXX */
/* program. */
/* */
/* COPYRIGHT: IBM Corporation 1989 */
/* */
/* STATUS: Version 1.20 */
/* */
/* FUNCTION: */
/* This module provides several support subroutines used by the */
/* PMREXX program. The routines included are listed below. */
/* */
/* */
/* NOTES: */
/* DEPENDENCIES: */
/* This function has dependencies on the following */
/* files for compilation. */
/* pmrexx.h - Definitions necessary for the resource */
/* file compilation. */
/* rhdtatyp.h - Macros, structures, typedefs and defines */
/* local to and necessary for this program. */
/* The C runtime multi-threaded header files */
/* See README.C in \TOOLKT12\C for a list and description of the */
/* system files that are needed. */
/* */
/* */
/* PROCEDURES: */
/* */
/* Add_Q_Element: Add an element to a queue */
/* getfixedfont: Get a fixed font for the default display */
/* getstring: Retrieve a string resource */
/* makepipe: Create a pipe with specific read & write handles */
/* Remove_Q_Element: Remove a queue element, wait if none there */
/* RestoreWindow: Restore the window from the user profile */
/* RHWinErrorBox: Pops up a message box with PM error info */
/* SaveWindow: Save the window position to the user profile */
/* SetCheckMark: Check/uncheck a menu item */
/* setinherit: Set the inheritance flags for a file handle. */
/* SetOptions: Enable/disable menu options */
/* SysErrorBox: Pops up an error box with the system error text */
/* SysErrorBoxM: SysErrorBox with added user control */
/* */
/*********************** END OF SPECIFICATIONS ******************************/
/******************************************************************************/
/* Include relevant sections of the PM header file. */
/******************************************************************************/
#define INCL_WINERRORS /* Error code definitions */
#define INCL_GPILCIDS /* Physical and logical fonts with */
/* lcids */
#define INCL_WINFRAMEMGR /* Frame manager */
#define INCL_WINMENUS /* Menu controls */
#define INCL_WINSHELLDATA /* Profile calls */
#define INCL_WINWINDOWMGR
#define INCL_DOSSEMAPHORES /* OS/2 semaphore support */
#define INCL_WINSTDFONT /* Standard Font dialog */
#define INCL_WINCOUNTRY /* Code page support */
#define INCL_DOSNLS /* NLS (code page) support */
/******************************************************************************/
/* Include relevant sections of the BSE header file. */
/******************************************************************************/
#define INCL_DOSMISC /* Miscellaneous doscalls */
#define INCL_DOSERRORS /* OS/2 errors */
#define INCL_DOSQUEUES /* Queues */
#define INCL_DOSPROCESS /* Process and thread support */
#define INCL_RXSYSEXIT /* REXX system exits */
#include <os2.h>
#include <rexxsaa.h>
/******************************************************************************/
/* Include the multi-threaded C header files needed. */
/******************************************************************************/
#include <ctype.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/******************************************************************************/
/* Include application header files */
/******************************************************************************/
#include "rhdtatyp.h"
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: RHWinErrorBox */
/* */
/* DESCRIPTIVE NAME: */
/* Display information about the last PM error in a message */
/* box. */
/* */
/* FUNCTION: */
/* When a PM error occurs, this routine can be called to */
/* obtain the text of the error information from PM and place */
/* it into a message box for display to the user. */
/* NOTES: */
/* The code that is commented out allows the error box to contain */
/* additional information returned from WinGetErrorInfo. However, */
/* this information is of a technical nature, and not of use to */
/* the average user. */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* ULONG RHWinErrorBox(HAB hab, HWND hwnd, HMODULE, handle, */
/* ULONG title, ULONG style) */
/* */
/* INPUT: */
/* hwnd - The handle of the window that received the error */
/* title - The resource ID of a string to use as a title for */
/* the message box. */
/* style - The style bits to use on the message box. */
/* */
/* EXIT-NORMAL: */
/* returns the value returned from the WinMessageBox call. */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* getstring - To obtain the title bar name and window name. */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* WinFreeErrorInfo */
/* WinGetErrorInfo */
/* WinMessageBox */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
ULONG RHWinErrorBox(HAB hab, HWND hwnd, HMODULE handle, ULONG title,
ULONG style)
{
ULONG rc = 0; /* return code */
PUCHAR header; /* Holds message box title */
/* Obtain the message box title. */
header = getstring(hab, handle, title);
/* Now, display the message, save the button press for a return code */
rc = WinMessageBox(HWND_DESKTOP, hwnd, header, NULL, (USHORT)0, style);
free(header); /* get rid of header */
return rc;
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: getstring */
/* */
/* DESCRIPTIVE NAME: */
/* Allocate memory for, and obtain a string resource. */
/* */
/* FUNCTION: */
/* This function gets a string resource from the */
/* program file. It accepts as input, the resource ID */
/* of the string to get, and returns a far pointer to */
/* the string in allocated storage. The caller should */
/* free the storage (via free()) when done with the */
/* string. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: getstring(HAB hab, HMODULE handle, ULONG string_name) */
/* */
/* INPUT: */
/* string_name - The resource ID that identifies the string in the */
/* resource file. */
/* */
/* EXIT-NORMAL: */
/* Returns a pointer to the string. */
/* */
/* EXIT-ERROR: */
/* Returns a null pointer. Use WinGetLastError to find the cause. */
/* */
/* EFFECTS: */
/* Assumptions made include: */
/* The maximum width string to be obtained is MAXWIDTH-1 characters. */
/* MAXWIDTH is defined in file RHDTATYP.H. */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* WinLoadString */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
PUCHAR getstring(HAB hab, HMODULE handle, ULONG string_name)
{
UCHAR buffer[MAXWIDTH];
ULONG chars;
buffer[0] = '\0';
/* Get the message into our local buffer, then make a copy to return. */
chars = WinLoadString(hab, (HMODULE)handle,
(ULONG)string_name, MAXWIDTH, buffer);
return strdup(buffer);
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: getfixedfont */
/* */
/* DESCRIPTIVE NAME: */
/* Attempt to get a fixed width font for display in the MLE */
/* output window. */
/* */
/* FUNCTION: */
/* This routine will attempt to get a fixed width font for */
/* display in the output window. This is necessary to so */
/* that VIO type commands (like DIR) look normal. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: PFATTRS getfixedfont(HWND hwnd) */
/* */
/* INPUT: */
/* hwnd - A window handle to use to obtain a presentation */
/* space with which the font calls to PM may be made. */
/* */
/* EXIT-NORMAL: */
/* Returns a pointer to the FATTRS structure identifying the fixed width */
/* font. This pointer is then passed to the MLE to tell it what font to */
/* use. */
/* */
/* EXIT-ERROR: */
/* A null pointer is returned. */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* DevQueryCaps PrfQueryProfileData */
/* GpiCreateLogFont WinGetPS */
/* GpiQueryDevice WinReleasePS */
/* GpiQueryFonts */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
void getfixedfont(HWND hwnd, PFATTRS fat)
{
HPS hps = WinGetPS(hwnd); /* Presentation space handle */
HDC hdc = GpiQueryDevice(hps); /* Device context handle */
PFONTMETRICS pfm; /* struc with info on font */
LONG lHorzRes, /* Display horizontal res */
lVertRes, /* Display vertical res */
lRequestFonts, /* Number of fonts returned */
lNumberFonts; /* Number of fonts available */
LONG sIndex; /* Loop variable */
LONG alMatch = 0; /* TRUE if we found a font */
ULONG bytes; /* Byte count for Prf call */
/* Get the horizontal and vertical resolution of the display. */
DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1L, &lHorzRes);
DevQueryCaps(hdc, CAPS_VERTICAL_FONT_RES, 1L, &lVertRes);
bytes = sizeof(*fat);
/* Check the profile for any saved font information */
if (PrfQueryProfileData(HINI_USERPROFILE, "PMREXX_Interface", "UserFont",
fat, &bytes) && bytes == sizeof(*fat)) {
/* We successfully read in the saved font information */
GpiCreateLogFont(hps, NULL, 1L, fat);
}
else {
/* No profile information found, so look for a font */
lRequestFonts = 0;
memset(fat, '\0', sizeof(*fat)); /* Clear out fat struct */
/* The system is distributed with the Courier fixed width font. */
/* So ask for information about the Courier fonts available. */
if (lNumberFonts = GpiQueryFonts(hps, QF_PUBLIC, "Courier",
&lRequestFonts, 0L, NULL)) { /* If some number of fonts was */
/* indicated, make sure the info can be*/
/* contained in a single segment. */
if (lNumberFonts *sizeof(FONTMETRICS) < 65536L) {/* Allocate the space */
/* for the font info */
/* and get the information */
if (pfm = malloc((LONG )lNumberFonts *sizeof(FONTMETRICS))) {
GpiQueryFonts(hps, QF_PUBLIC, "Courier", &lNumberFonts,
(LONG)sizeof(FONTMETRICS), pfm);
/* Look through the information */
/* returned for an appropriate font. */
for (sIndex = 0; sIndex < (LONG )lNumberFonts; sIndex++) {/* Look */
/* only at fixed fonts (fsDefn & */
/* FM_TYPE_FIXED) that match the */
/* display resolution. */
if (pfm[sIndex].sXDeviceRes == (SHORT)lHorzRes &&
pfm[sIndex]. sYDeviceRes == (SHORT)lVertRes &&
(pfm[sIndex].fsDefn & FM_TYPE_FIXED) == 0) {
/* Then look for an 8 point font. */
if (pfm[sIndex].sNominalPointSize == 80) {
alMatch = pfm[sIndex].lMatch;
}
}
}
free(pfm); /* Free the information buffer, now */
/* that it is no longer needed. */
if (alMatch) { /* Obtain information for a font */
/* attribute structure. */
fat->usRecordLength = sizeof *fat;/* with the info */
fat->fsSelection = FATTR_SEL_BOLD;/* for PM to */
fat->lMatch = alMatch; /* define it. */
strcpy(fat->szFacename, "Courier");
GpiCreateLogFont(hps, NULL, 1L, fat);
}
}
}
}
}
WinReleasePS(hps);
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: SetOptions */
/* */
/* DESCRIPTIVE NAME: */
/* Enable/disable menu items. */
/* */
/* FUNCTION: */
/* This function is called to individually enable or disable a */
/* particular item in the menu structure. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void SetOptions(HWND hwndFrame, ULONG item, BOOL option ) */
/* */
/* INPUT: */
/* item - The id of the item to enable/disable */
/* option - TRUE to enable the option, FALSE to disable. */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* DosSleep */
/* WinPostMsg */
/* WinWindowFromID */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
void SetOptions(HWND hwndFrame, ULONG item, BOOL option)
{
/* This call may be issued from a non-PM thread. So we have to use Post */
/* instead of Send. If the Post fails, give the window procedure a */
/* chance to empty the message queue and try again. */
while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT((USHORT)item, TRUE),
MPFROM2SHORT(MIA_DISABLED, option?~ MIA_DISABLED:MIA_DISABLED))) {
DosSleep(0L); /* This give the window thread a chance*/
/* to run */
} /* end of while */
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: SetCheckMark */
/* */
/* DESCRIPTIVE NAME: */
/* Check/Uncheck menu items. */
/* */
/* FUNCTION: */
/* This function is called to place a check mark next to, or */
/* remove a check mark from a particular item in the menu */
/* structure. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void SetCheckMark(HWND hwndFrame, ULONG item, BOOL option ) */
/* */
/* INPUT: */
/* item - The id of the item to check/uncheck. */
/* option - TRUE to check the item, FALSE to uncheck. */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* DosSleep */
/* WinPostMsg */
/* WinWindowFromID */
/**************************** END OF SPECIFICATIONS ***************************/
void SetCheckMark(HWND hwndFrame, ULONG item, BOOL option)
{
/* This call may be issued from a non-PM thread. So we have to use Post */
/* instead of Send. If the Post fails, give the window procedure a */
/* chance to empty the message queue and try again. */
while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(item, TRUE),
MPFROM2SHORT(MIA_CHECKED, option?MIA_CHECKED:~MIA_CHECKED))) {
DosSleep(0L); /* This give the window thread a chance*/
/* to run */
} /* end of while */
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: Add_Q_Element */
/* */
/* DESCRIPTIVE NAME: */
/* Add q queue element. */
/* */
/* FUNCTION: */
/* This function adds an element to a queue. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void Add_Q_Element(PLIST q, PLIST_ENTRY q_entry) */
/* */
/* INPUT: */
/* q - queue */
/* q_entry - queue entry */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
void Add_Q_Element(PLIST q,PLIST_ENTRY q_entry)
{
PLIST_ENTRY qptr; /* Pointer to an element in the queue */
/****************************************************************************/
/* Get the q semaphore */
/****************************************************************************/
if (!DosRequestMutexSem(q->q_sem, SEM_INDEFINITE_WAIT)) {
if (qptr = q->q_1st)
/*************************************************************************/
/* There are entries in the queue */
/*************************************************************************/
{
/**********************************************************************/
/* Add entry onto end of queue */
/**********************************************************************/
while (qptr->next)
qptr = qptr->next;
qptr->next = q_entry;
}
else {
/**********************************************************************/
/* There are no entries in the queue, so put it in front */
/**********************************************************************/
q->q_1st = q_entry;
} /* endif */
q_entry->next = NULL;
DosPostEventSem(q->q_data);
DosReleaseMutexSem(q->q_sem);
}
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: Remove_Q_Element */
/* */
/* DESCRIPTIVE NAME: */
/* Remove a queue element. */
/* */
/* FUCNTION: This function removes an element from a queue and */
/* returns it to the caller. If none are available, it */
/* waits for one. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* PLIST_ENTRY Remove_Q_Element( PLIST q ) */
/* */
/* INPUT: */
/* q - queue */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* DosEnterCritSec */
/* DosExitCritSec */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
PLIST_ENTRY Remove_Q_Element(PLIST q)
{
PLIST_ENTRY qptr = NULL; /* pointer to an element in the queue */
ULONG postcount; /* number of posted events */
/****************************************************************************/
/* Wait for an element if the queue is empty */
/****************************************************************************/
while (NULL == qptr) {
/*************************************************************************/
/* Get the semaphores to update the queue (and wait for data) */
/*************************************************************************/
if (!DosWaitEventSem(q->q_data, SEM_INDEFINITE_WAIT) &&
!DosRequestMutexSem(q->q_sem, SEM_INDEFINITE_WAIT)) {
/**********************************************************************/
/* Update the queue */
/**********************************************************************/
qptr = q->q_1st;
if (NULL != qptr)
q->q_1st = qptr->next;
DosReleaseMutexSem(q->q_sem);
}
}
DosEnterCritSec();
/****************************************************************************/
/* If the queue is empty, set the data semaphore */
/****************************************************************************/
if (NULL == q->q_1st)
DosResetEventSem(q->q_data, &postcount);
DosExitCritSec();
return qptr;
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: makepipe */
/* */
/* DESCRIPTIVE NAME: */
/* Make a pipe. */
/* */
/* FUNCTION: This function creates a pipe with the read and write */
/* handles at the requested handle locations. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void makepipe(PHFILE read, HFILE rspot, */
/* PHFILE write, HFILE wspot, ULONG psize ) */
/* */
/* INPUT: */
/* read - read file ptr */
/* rspot - read handle */
/* write - write file ptr */
/* wspot - write handle */
/* psize - size of pipe buffer */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* DosClose */
/* DosDupHandle */
/* DosCreatePipe */
/* */
/**************************** END OF SPECIFICATIONS ***************************/
void makepipe(PHFILE read,HFILE rspot,PHFILE write,HFILE wspot,ULONG psize)
{
HFILE rh,wh; /* read and write handles for pipe */
HFILE newh = 0xFFFF; /* we want to get a new handle */
ULONG rc; /* holds return code */
/****************************************************************************/
/* Create the pipe */
/****************************************************************************/
if (rc = DosCreatePipe(&rh, &wh, psize)) {
/* We haven't initialized yet, so we can't display an error */
exit(rc);
}
if (rh != rspot)
/****************************************************************************/
/* We didn't get the read handle we wanted */
/****************************************************************************/
{
if (wh == rspot)
/*************************************************************************/
/* The write handle we got is the read handle we wanted */
/*************************************************************************/
{
/**********************************************************************/
/* If the read handle we got isn't the write handle requested, dup */
/* the handle received to what was requested, otherwise get a new */
/* handle. */
/**********************************************************************/
if (rh != wspot)
newh = wspot;
if (rc = DosDupHandle(wh, &newh)) {
exit(rc);
}
wh = newh;
}
/*************************************************************************/
/* Dup requested read handle to the read handle we got */
/*************************************************************************/
if (rc = DosDupHandle(rh, &rspot)) {
exit(rc);
}
/*************************************************************************/
/* Close the original read handle we received */
/*************************************************************************/
DosClose(rh);
rh = rspot;
}
if (wh != wspot)
/****************************************************************************/
/* We didn't get the write handle we wanted */
/****************************************************************************/
{
/*************************************************************************/
/* From above we are assured that we can dup to the handle we wanted */
/*************************************************************************/
if (rc = DosDupHandle(wh, &wspot)) {
exit(rc);
}
/*************************************************************************/
/* Close original write handle we received */
/*************************************************************************/
DosClose(wh);
wh = wspot;
}
*read = rh;
*write = wh;
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: setinherit */
/* */
/* DESCRIPTIVE NAME: */
/* Set the inheritance of the given file handle */
/* */
/* FUNCTION: This function will set the inheritance state of the given */
/* file handle. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void setinherit(HFILE handle, BOOL inh) */
/* */
/* INPUT: */
/* handle - handle of given file */
/* inh - inherit or not */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* DosQueryFHState */
/* DosSetFHandState */
/**************************** END OF SPECIFICATIONS ***************************/
void setinherit(HFILE handle,BOOL inh)
{
ULONG state; /* Variable to change current state of */
/* the file handle */
DosQueryFHState(handle,
&state);
if (inh) {
state |= INHERIT;
}
else {
state &= ~INHERIT;
}
DosSetFHState(handle,
state);
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: RestoreWindow */
/* */
/* DESCRIPTIVE NAME: */
/* Restore the window from the ini file */
/* */
/* FUNCTION: This routine will attempt to restore the window to its */
/* previous position saved in the user profile. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void RestoreWindow(HWND hwnd, PRHWINDATA pWinData) */
/* */
/* INPUT: */
/* hwnd - window handle */
/* pWinData - pointer to WinData structure */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* SizeWindow */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* PrfQueryProfileData */
/* PrfWriteProfileData */
/* WinSetWindowPos */
/* WinSetWindowUShort */
/**************************** END OF SPECIFICATIONS ***************************/
void RestoreWindow(HWND hwnd, PRHWINDATA pWinData)
{
SAVEDWINDOWPOS windowpos; /* structure to hold info from profile */
ULONG bytes; /* byte counter */
/* Get Window position from user profile */
bytes = sizeof(windowpos);
if (PrfQueryProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
&windowpos, &bytes) && bytes == sizeof(windowpos)) {
/* Delete the entry from the profile so if the user starts another */
/* copy of PMREXX before this one ends, it won't be right on top of us. */
PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
NULL, 0);
/* Everything was read in OK, so set window to previous position */
WinSetWindowPos(pWinData->frame,
HWND_TOP,
windowpos.x,
windowpos.y,
windowpos.cx,
windowpos.cy,
windowpos.flags);
/* If window is maximized or minimized, set the position and size to */
/* restore it to. */
if (windowpos.flags&SWP_MINIMIZE || windowpos.flags&SWP_MAXIMIZE) {
WinSetWindowUShort(pWinData->frame, QWS_CYRESTORE, windowpos.restorecy);
WinSetWindowUShort(pWinData->frame, QWS_CXRESTORE, windowpos.restorecx);
WinSetWindowUShort(pWinData->frame, QWS_YRESTORE, windowpos.restorey);
WinSetWindowUShort(pWinData->frame, QWS_XRESTORE, windowpos.restorex);
}
}
/* If the window isn't minimized, size the windows inside it */
if (!(windowpos.flags&SWP_MINIMIZE)) {
SizeWindow(hwnd, pWinData);
}
}
/************************** START OF SPECIFICATIONS ***************************/
/* */
/* SUBROUTINE NAME: SaveWindow */
/* */
/* DESCRIPTIVE NAME: */
/* Save information about the current window state. */
/* */
/* FUNCTION: This routine will save the window position and the current */
/* font in the output window to the user profile. */
/* */
/* NOTES: */
/* */
/* ENTRY POINT: */
/* LINKAGE: */
/* void SaveWindow(PRHWINDATA pWinData) */
/* */
/* INPUT: */
/* pWinData - pointer to WinData structure */
/* */
/* EXIT-NORMAL: */
/* */
/* EXIT-ERROR: */
/* */
/* EFFECTS: */
/* */
/* INTERNAL REFERENCES: */
/* ROUTINES: */
/* */
/* EXTERNAL REFERENCES: */
/* ROUTINES: */
/* PrfWriteProfileData */
/* WinQueryWindowPos */
/* WinQueryWindowUShort */
/**************************** END OF SPECIFICATIONS ***************************/
void SaveWindow(PRHWINDATA pWinData)
{
SAVEDWINDOWPOS savewindowpos; /* holds window position info */
SWP swp; /* window poition structure */
/* Don't bother saving the data to the profile if we aren't visible */
if (pWinData->visible) {
/* Save the font for the output window to the user profile */
PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "UserFont",
&(pWinData->MleFontAttrs.fAttrs), (ULONG)sizeof(FATTRS));
/* Get Window positions */
WinQueryWindowPos(pWinData->frame, &swp);
/* Set the fields in the savewindowpos structure */
savewindowpos.flags = swp.fl;
savewindowpos.cy = swp.cy;
savewindowpos.cx = swp.cx;
savewindowpos.y = swp.y;
savewindowpos.x = swp.x;
/* Get the restore positions, also */
savewindowpos.restorecy = WinQueryWindowUShort(pWinData->frame,
QWS_CYRESTORE);
savewindowpos.restorecx = WinQueryWindowUShort(pWinData->frame,
QWS_CXRESTORE);
savewindowpos.restorey = WinQueryWindowUShort(pWinData->frame,
QWS_YRESTORE);
savewindowpos.restorex = WinQueryWindowUShort(pWinData->frame,
QWS_XRESTORE);
/* Write the window data to the profile */
PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
&savewindowpos, (ULONG)sizeof(savewindowpos));
}
}