|
|
Microsoft OS/2 SDK PM 08-08-1988
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#include "os2.h"
#include "pmbind1.h"
/*********************************************************************/
/* PM Code for Shared Code System */
/* */
/* (c) Copyright Microsoft Corp. 1987,1988 - All Rights Reserved */
/*********************************************************************/
/*********************************************************************/
/* Many of the Windows functions can be mapped into equivalent */
/* PM functions through the use of defines. This file is for those */
/* functions which can't. */
/* */
/* For some Windows functions, such as ChangeMenu or SendMessage, */
/* it is necessary to require the user to examine these on a case */
/* by case basis in the application sources. */
/* */
/* Other functions, such as OpenFile, DlgDirList, and */
/* DlgDirSelect, are used commonly used but have no PM equivalent. */
/* These functions are implemented in this file. */
/* */
/* Functions Implemented: */
/* CheckScrollBars - In PM, scroll bars don't disappear when */
/* the high and low ends of the range are the same. This */
/* function utilizes features of frame and control windows */
/* to allow the bar to be shown or hidden. This is called */
/* from the pmbind.h file. */
/* */
/* DlgDirList - In PM, this useful function is not present. */
/* This function accepts the same parameters as the Windows */
/* version, so calls to it in the source may remain unchanged. */
/* */
/* DlgDirSelect - This function doesn't exist in PM and is the */
/* companion function to DlgDirList. */
/* */
/* OpenFile - This function doesn't exist in PM. In Windows, */
/* OpenFile handles a variety of operations, including */
/* creating, opening, and deleting files, and parsing */
/* filenames. The type OFSTRUCT is defined in one of the */
/* h files, so calls to OpenFile in the source code don't */
/* have to be modified. */
/* */
/* */
/* Additionally, a few utility functions are present for use in */
/* the binding functions: */
/* lstrcpy */
/* lstrlen */
/* lstrcat */
/* lmemcpy */
/* */
/* These functions are not called by the application, only by the */
/* binding system. */
/*********************************************************************/
/*********************************************************************/
/* Internal variables used by binding system. */
/*********************************************************************/
HAB hAB; /* Holds the anchor block handle */
HMQ hMQ; /* Holds the message queue handle */
int temp; /* Temp Var, used for many mappings */
POINTL Point; /* Temp Var, used for many mappings */
WPOINT pt; /* Temp Var, used for many mappings */
HHEAP hLocalHeap; /* Holds the cardfile's local heap */
int WinHeight = 0; /* Holds the current translate value */
int b_CharHeight = 0; /* Character height, default is 0 */
WRECT TempRect; /* Temp Var, used for many mappings */
PWRECT lTempRect = &TempRect; /* Temp Var, used for many mappings */
HWND hwndTemp; /* Temp Var, used for many mappings */
POINTL PointArray[2]; /* Temp Var, used for many mappings */
/*********************************************************************/
/* In order resolve type conflicts warnings with the use of the */
/* MPARAM type, make a define to convert all WinSendMsg's. */
/*********************************************************************/
#define NewSendMsg( a, b, c, d ) \
LONGFROMMR( WinSendMsg( a, b, MPFROMLONG(c), MPFROMLONG(d) ))
#define NewSendDlgItemMsg( a, b, c, d, e ) \
LONGFROMMR(WinSendDlgItemMsg( a, b, c, \
MPFROMLONG(d), MPFROMLONG(e) ))
/*********************************************************************/
/* Binding system functions */
/*********************************************************************/
int CheckScrollBars( HWND, unsigned, int );
int FAR PASCAL lstrlen( PSZ );
PSZ FAR PASCAL lstrcpy( PSZ, PSZ );
PSZ FAR PASCAL lstrcat( PSZ, PSZ );
void FAR PASCAL lmemcpy( PSZ, PSZ, unsigned );
/*********************************************************************/
/* Internal functions */
/*********************************************************************/
int FillListBox( HWND, unsigned, PSZ );
PSZ ParseFile( PSZ, PSZ, BOOL );
PSZ GetFileFromPath( PSZ );
/*********************************************************************/
/* Functions to be called from source */
/*********************************************************************/
int DlgDirList( HWND, PSZ, unsigned, unsigned, unsigned );
unsigned DlgDirSelect( HWND, PSZ, unsigned );
int OpenFile( PSZ, LPOFSTRUCT, WORD );
/*********************************************************************/
/* Defines */
/*********************************************************************/
/* Note: This bit must not be the same as a bit in the frame id's */
/* for scroll bars! (FID_HORZSCROLL | FID_VERTSCROLL) */
#define HIDE_BIT 0x0800 /* Bit to hide scroll bar */
#define HIDE_MASK ~HIDE_BIT /* Mask for bit */
#define MAX_PATH_LEN 100 /* Max. length of path + filename */
#define DIR_ATTRIBUTE 0x10 /* Attribute to search for dir's */
/*********************************************************************/
/* Binding System Variables: */
/* */
/* Because this is the only C file in the binding system, all */
/* variables used in the binding system are allocated here. None of */
/* these variables are used in this file. */
/*********************************************************************/
/*********************************************************************/
/* lstrlen - standard */
/*********************************************************************/
int FAR PASCAL lstrlen( pStr )
PSZ pStr;
{
int j;
for (j = 0; *(pStr++); j++);
return j;
}
/*********************************************************************/
/* lstrcpy - standard */
/*********************************************************************/
PSZ FAR PASCAL lstrcpy( pDest, pSrc )
PSZ pDest, pSrc;
{
PSZ pTemp = pDest;
do {
*(pDest++) = *(pSrc);
} while ( *(pSrc++) );
return( pTemp );
}
/*********************************************************************/
/* lstrcat - standard */
/*********************************************************************/
PSZ FAR PASCAL lstrcat( pDest, pSrc )
PSZ pDest, pSrc;
{
PSZ pTemp = pDest;
while (*(pDest++));
pDest--;
do {
*(pDest++) = *(pSrc);
} while ( *(pSrc++) );
return( pTemp );
}
/*********************************************************************/
/* lmemcpy - standard */
/*********************************************************************/
void FAR PASCAL lmemcpy( pDest, pSrc, wCount )
PSZ pDest, pSrc;
unsigned wCount;
{
for ( ; wCount--; *(pDest++) = *(pSrc++) );
}
/*********************************************************************/
/* CheckScrollBars - */
/* This routine shows or hides a scroll bar. */
/* */
/* Input: Accepts handle to frame window, id of scroll bar, */
/* boolean indicating whether to show scroll bar. */
/* */
/* Return: Whether scroll bar shown. */
/* */
/* Notes: This routine utilizes the fact that the frame window */
/* recognizes control windows only through the id of the */
/* control window. In order to hide a scroll window, all that */
/* has to be done is to change the id of the scroll window, */
/* disable the window for input, and repaint the frame. This */
/* is much easier (and faster) than creating and destroying */
/* control windows. */
/*********************************************************************/
int CheckScrollBars( hFrame, wScrollId, fShow )
HWND hFrame;
unsigned wScrollId;
int fShow;
{
HWND hScroll;
/* Attempt to get existing scroll Window */
hScroll = WinWindowFromID( hFrame, wScrollId );
/* If scroll bar already the in desired state, return fShow */
if ((fShow && hScroll) || (!fShow && !hScroll))
return( fShow );
if (fShow) {
/* If want to show scroll bar, get hidden one */
hScroll = WinWindowFromID( hFrame, wScrollId | HIDE_BIT );
/* Mask off hidden bit */
WinSetWindowUShort( hScroll, QWS_ID, wScrollId & HIDE_MASK );
}
else
/* Otherwise hide existing bar by changing id */
WinSetWindowUShort( hScroll, QWS_ID, wScrollId | HIDE_BIT );
/* Turn [on|off] mouse clicks to scroll bar, [hide|show] on screen */
WinEnableWindow( hScroll, fShow );
WinShowWindow( hScroll, fShow );
/* Finally, send update frame message to let frame know something's up */
NewSendMsg( hFrame, WM_UPDATEFRAME,
wScrollId == FID_HORZSCROLL ? FCF_HORZSCROLL : FCF_VERTSCROLL,
0L );
return( fShow );
}
/*********************************************************************/
/* DlgDirSelect - */
/* This routine gets current selection from a dialog box. */
/* */
/* Input: Handle to dialog box, string to return selection in, */
/* id of listbox. */
/* */
/* Return: Whether selection was a directory. (TRUE) */
/*********************************************************************/
unsigned DlgDirSelect( hDlg, pString, nID )
HWND hDlg;
PSZ pString;
unsigned nID;
{
HWND hList;
unsigned j;
/* Get handle to the listbox */
hList = WinWindowFromID( hDlg, nID );
/* Get current selection in j; read selection from listbox */
j = (unsigned) NewSendMsg( hList, LM_QUERYSELECTION, 0L, 0L );
NewSendMsg( hList, LM_QUERYITEMTEXT,
MAKELONG( j, 64 ), (long) pString );
/* Directories are enclosed in brackets */
if (*pString == '[') {
/* If directory, strip brackets, return TRUE */
j = lstrlen( pString );
lmemcpy( pString, pString + 1, j );
pString[j - 2] = '\\';
pString[j - 1] = 0;
return( TRUE );
}
else
/* Normal file, return FALSE */
return( FALSE );
}
/*********************************************************************/
/* DlgDirList - */
/* This routine fills a list box with file names matching the */
/* specification and possibly updates a static text field. */
/* */
/* Input: Dialog box handle, file specification string, Id of */
/* list box, id of static text field (maybe 0), and */
/* attrib indicating type of files to list. */
/* */
/* Return: fSuccess. */
/* */
/* Notes: Currently, this function has doesn't have the full */
/* functionality of its Windows namesake. If the path is too */
/* long to fit in the static text field, it should be abbreviated */
/* with '...'. Also, disk drives aren't listed. */
/*********************************************************************/
int DlgDirList( hDlg, pInitPath, wListId, wIdStatic, wAttrib )
HWND hDlg;
PSZ pInitPath;
unsigned wListId;
unsigned wIdStatic;
unsigned wAttrib;
{
char npTempBuf[MAX_PATH_LEN]; /* Temp location to hold path */
char PathStr[MAX_PATH_LEN]; /* Used to build path */
PSZ pPathStr = PathStr; /* Pointer to path */
PSZ pFileName; /* Pointer to File Name */
HWND hList; /* Handle to list box */
/* Copy string into Temp Buffer, this allows parsing routines */
/* to modify the string passed in. */
if (pInitPath == NULL)
npTempBuf[0] = 0;
else
lstrcpy( (PSZ) npTempBuf, pInitPath );
/* Ensure path is legal and expand to full search path */
/* Stores full path in pPathStr */
pFileName = ParseFile( (PSZ) npTempBuf, pPathStr, FALSE );
if (pFileName == NULL)
return( FALSE );
/* set current drive and path */
DosSelectDisk( *pPathStr - 'A' + 1 );
DosChdir( pPathStr, 0L );
/* If static field, set text to be path */
/* Note: path should be abbreviated here! */
if (wIdStatic)
WinSetWindowText( WinWindowFromID( hDlg, wIdStatic ),
pPathStr );
if (wListId) {
/* If list box present, get window */
hList = WinWindowFromID( hDlg, wListId );
/* Empty list boxes of any old entries */
NewSendMsg( hList, LM_DELETEALL, 0L, 0L );
/* Fill them up with new entries */
return( FillListBox( hList, wAttrib, pFileName ) );
}
else
return( FALSE );
}
/*********************************************************************/
/* FillListBox - */
/* This routine fills a list box with file names matching the */
/* specification. */
/* */
/* Input: List box handle, file attribute, file wildcard */
/* specification. */
/* */
/* Return: fSuccess. */
/* */
/* Notes: This function should list disk drives. When this funciton */
/* is called, the current drive and directory should be correct. */
/*********************************************************************/
int FillListBox( hList, wAttrib, pFileSpec )
HWND hList;
unsigned wAttrib;
PSZ pFileSpec;
{
char npTemp[30];
PSZ pTemp = npTemp;
unsigned wDir;
FILEFINDBUF ffb;
int cFiles;
/* Put files that match search spec in file listbox */
/* This is the standard list files loop */
cFiles = 1;
wDir = 0xffff;
if (!DosFindFirst( pFileSpec, (PHDIR) &wDir, wAttrib & 0x0f, &ffb,
sizeof ffb, &cFiles, 0L )) {
do {
NewSendMsg( hList, LM_INSERTITEM,
MAKELONG( 0, LIT_SORTASCENDING ),
(long) (PSZ) ffb.achName );
cFiles = 1;
} while (!DosFindNext( wDir, &ffb, sizeof ffb, &cFiles ));
}
DosFindClose( wDir );
/* Put directories in file listbox */
/* Standard list files loop with a twist - surround in brackets */
cFiles = 1;
wDir = 0xffff;
if (!DosFindFirst( "*", (PHDIR) &wDir, DIR_ATTRIBUTE, &ffb,
sizeof ffb, &cFiles, 0L )) {
do {
if (ffb.attrFile & DIR_ATTRIBUTE) {
/* Surround in brackets */
pTemp[0] = '[';
lmemcpy( pTemp + 1, (PSZ) &(ffb.achName[0]), ffb.cchName );
pTemp[ffb.cchName + 1] = ']';
pTemp[ffb.cchName + 2] = 0;
NewSendMsg( hList, LM_INSERTITEM,
MAKELONG( 0, LIT_SORTASCENDING ), (long) pTemp );
}
cFiles = 1;
} while (!DosFindNext( wDir, &ffb, sizeof ffb, &cFiles ));
}
DosFindClose( wDir );
return TRUE;
}
/*********************************************************************/
/* ParseFile - */
/* This routine parses a path/file specification obtaining a */
/* complete path specifcation. */
/* */
/* Input: Initial Path specification, Buffer to output path */
/* path spec, Flag indicating whether to append file name */
/* to path spec. */
/* */
/* Return: Pointer to file name, NULL if couldn't parse. */
/* */
/* Notes: This function modifies the Initial path spec directly. */
/* If there is a possibility that a calling function may receive */
/* a constant string, it should copy the string constant to a */
/* temp buffer before calling this routine. */
/*********************************************************************/
PSZ ParseFile( pSpec, pPath, fAppend )
PSZ pSpec;
PSZ pPath;
BOOL fAppend;
{
char TempChar;
PSZ pBuf, pFile;
/* Go past any path spec to first char in file name */
pFile = GetFileFromPath( pSpec );
/* If path specification ends in '\' or ':', treat as if '*' was */
/* specified as the file name */
if (*pFile == 0) {
pFile++;
*pFile = '*';
*(pFile + 1) = 0;
}
/* Save first char of file name, terminate path */
TempChar = *pFile;
*pFile = 0;
/* If filename is path, i.e. no path was specified, use '.' as */
/* path, otherwise use current path specification */
if (pFile == pSpec)
pBuf = ".";
else
pBuf = pSpec;
/* Call DosSearchPath. This forms a complete path specification */
/* in addition to verifying the path */
if (DosSearchPath( 0, pBuf, (PSZ) "*", pPath, MAX_PATH_LEN )) {
*pPath = 0;
*pFile = TempChar;
return( NULL );
}
/* DosSearchPath adds wildcard extensions after valid path. Find */
/* first wildcard char, and end path there */
while (*pPath) {
if ((*pPath == '?') || (*pPath == '*')) {
*pPath = 0;
break;
}
pPath++;
}
/* Restore first character in file name. */
*pFile = TempChar;
/* Check if should append file name to path */
if (fAppend)
lstrcpy( pPath, pFile );
else {
/* If shouldn't then make sure path doesn't end in '\'. The */
/* only case where this is ok is for the root directory. This */
/* insures that DosChdir may be called on the returned path */
pPath--;
if ((*pPath == '\\') && (*(pPath-1) != ':'))
*pPath = 0;
}
return( pFile );
}
/*********************************************************************/
/* GetFileFromPath - */
/* This routine finds the beginning of the file name in a path.
/* */
/* Input: Path specification.
/* */
/* Return: Pointer to file name.
/*********************************************************************/
PSZ GetFileFromPath( pPath )
PSZ pPath;
{
int j;
j = lstrlen( pPath );
/* Search backwards until find '\', ':' */
while (j--)
if (pPath[j] == '\\') {
/* Make sure path doesn't end in '\' */
pPath[j] = 0;
return( pPath + j + 1 );
}
else if (pPath[j] == ':')
return( pPath + j + 1 );
return( pPath );
}
/*********************************************************************/
/* OpenFile - */
/* This routine opens, closes, deletes files; parses filename. */
/* */
/* Input: File specification, Open File structure, Flags */
/* indicating what to do and where information is. */
/* */
/* Return: File handle (0 if OF_PARSE) or -1 if error */
/*********************************************************************/
/* These are constants used to specify the action taken in DosOpen */
#define OPEN_CALL 0x0001
#define CREATE_CALL 0x0012
int OpenFile( pFileName, lpStruct, wCommand )
PSZ pFileName;
LPOFSTRUCT lpStruct;
WORD wCommand;
{
char npTempBuf[MAX_PATH_LEN];
PSZ pFile = (PSZ) npTempBuf;
int wOpenCode, wHandle, wAction;
/* Copy file name to temp buf., may need to modify */
lstrcpy( pFile, pFileName );
/* If OF_REOPEN, then assume that file name in buffer is correct */
/* Otherwise, parse from pFileName to structure and return -1 */
/* if error. */
if (! (wCommand & OF_REOPEN))
if (!ParseFile( pFile, (PSZ) (lpStruct->szPathName), TRUE ))
return( -1 );
/* If OF_PARSE, all done! */
if (wCommand & OF_PARSE)
return( 0 );
/* Set code indicating whether file should be opened or created */
wOpenCode = wCommand & OF_CREATE ? CREATE_CALL : OPEN_CALL;
/* Either open or create file - even in the card of OF_DELETE, do */
/* this to verify that file is accessible */
pFile = (PSZ) (lpStruct->szPathName);
if (DosOpen( pFile, (PHFILE) &wHandle, &wAction, 1L, 0, wOpenCode,
0xc2, 0L ) )
return( -1 );
/* If OF_EXIST or OF_DELETE, don't keep file open */
if (wCommand & (OF_EXIST | OF_DELETE)) {
DosClose( wHandle );
wHandle = 0;
}
/* If OF_DELETE, get rid of file. There shouldn't be an error if */
/* this file was opened correctly */
if (wCommand & OF_DELETE)
DosDelete( pFile, 0L );
return( wHandle );
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.