File:  [OS/2 SDKs] / pmsdk / samples / newcard / pmbind.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

#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 );
}


unix.superglobalmegacorp.com

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