|
|
1.1 root 1: #define INCL_DOS
2: #define INCL_WIN
3: #define INCL_GPI
4: #include "os2.h"
5: #include "pmbind1.h"
6:
7:
8: /*********************************************************************/
9: /* PM Code for Shared Code System */
10: /* */
11: /* (c) Copyright Microsoft Corp. 1987,1988 - All Rights Reserved */
12: /*********************************************************************/
13:
14:
15: /*********************************************************************/
16: /* Many of the Windows functions can be mapped into equivalent */
17: /* PM functions through the use of defines. This file is for those */
18: /* functions which can't. */
19: /* */
20: /* For some Windows functions, such as ChangeMenu or SendMessage, */
21: /* it is necessary to require the user to examine these on a case */
22: /* by case basis in the application sources. */
23: /* */
24: /* Other functions, such as OpenFile, DlgDirList, and */
25: /* DlgDirSelect, are used commonly used but have no PM equivalent. */
26: /* These functions are implemented in this file. */
27: /* */
28: /* Functions Implemented: */
29: /* CheckScrollBars - In PM, scroll bars don't disappear when */
30: /* the high and low ends of the range are the same. This */
31: /* function utilizes features of frame and control windows */
32: /* to allow the bar to be shown or hidden. This is called */
33: /* from the pmbind.h file. */
34: /* */
35: /* DlgDirList - In PM, this useful function is not present. */
36: /* This function accepts the same parameters as the Windows */
37: /* version, so calls to it in the source may remain unchanged. */
38: /* */
39: /* DlgDirSelect - This function doesn't exist in PM and is the */
40: /* companion function to DlgDirList. */
41: /* */
42: /* OpenFile - This function doesn't exist in PM. In Windows, */
43: /* OpenFile handles a variety of operations, including */
44: /* creating, opening, and deleting files, and parsing */
45: /* filenames. The type OFSTRUCT is defined in one of the */
46: /* h files, so calls to OpenFile in the source code don't */
47: /* have to be modified. */
48: /* */
49: /* */
50: /* Additionally, a few utility functions are present for use in */
51: /* the binding functions: */
52: /* lstrcpy */
53: /* lstrlen */
54: /* lstrcat */
55: /* lmemcpy */
56: /* */
57: /* These functions are not called by the application, only by the */
58: /* binding system. */
59: /*********************************************************************/
60:
61:
62: /*********************************************************************/
63: /* Internal variables used by binding system. */
64: /*********************************************************************/
65:
66: HAB hAB; /* Holds the anchor block handle */
67: HMQ hMQ; /* Holds the message queue handle */
68: int temp; /* Temp Var, used for many mappings */
69: POINTL Point; /* Temp Var, used for many mappings */
70: WPOINT pt; /* Temp Var, used for many mappings */
71: HHEAP hLocalHeap; /* Holds the cardfile's local heap */
72: int WinHeight = 0; /* Holds the current translate value */
73: int b_CharHeight = 0; /* Character height, default is 0 */
74: WRECT TempRect; /* Temp Var, used for many mappings */
75: PWRECT lTempRect = &TempRect; /* Temp Var, used for many mappings */
76: HWND hwndTemp; /* Temp Var, used for many mappings */
77: POINTL PointArray[2]; /* Temp Var, used for many mappings */
78:
79:
80: /*********************************************************************/
81: /* In order resolve type conflicts warnings with the use of the */
82: /* MPARAM type, make a define to convert all WinSendMsg's. */
83: /*********************************************************************/
84:
85: #define NewSendMsg( a, b, c, d ) \
86: LONGFROMMR( WinSendMsg( a, b, MPFROMLONG(c), MPFROMLONG(d) ))
87:
88: #define NewSendDlgItemMsg( a, b, c, d, e ) \
89: LONGFROMMR(WinSendDlgItemMsg( a, b, c, \
90: MPFROMLONG(d), MPFROMLONG(e) ))
91:
92: /*********************************************************************/
93: /* Binding system functions */
94: /*********************************************************************/
95:
96: int CheckScrollBars( HWND, unsigned, int );
97: int FAR PASCAL lstrlen( PSZ );
98: PSZ FAR PASCAL lstrcpy( PSZ, PSZ );
99: PSZ FAR PASCAL lstrcat( PSZ, PSZ );
100: void FAR PASCAL lmemcpy( PSZ, PSZ, unsigned );
101:
102: /*********************************************************************/
103: /* Internal functions */
104: /*********************************************************************/
105:
106: int FillListBox( HWND, unsigned, PSZ );
107: PSZ ParseFile( PSZ, PSZ, BOOL );
108: PSZ GetFileFromPath( PSZ );
109:
110: /*********************************************************************/
111: /* Functions to be called from source */
112: /*********************************************************************/
113:
114: int DlgDirList( HWND, PSZ, unsigned, unsigned, unsigned );
115: unsigned DlgDirSelect( HWND, PSZ, unsigned );
116: int OpenFile( PSZ, LPOFSTRUCT, WORD );
117:
118:
119: /*********************************************************************/
120: /* Defines */
121: /*********************************************************************/
122:
123:
124:
125: /* Note: This bit must not be the same as a bit in the frame id's */
126: /* for scroll bars! (FID_HORZSCROLL | FID_VERTSCROLL) */
127:
128: #define HIDE_BIT 0x0800 /* Bit to hide scroll bar */
129: #define HIDE_MASK ~HIDE_BIT /* Mask for bit */
130:
131:
132: #define MAX_PATH_LEN 100 /* Max. length of path + filename */
133: #define DIR_ATTRIBUTE 0x10 /* Attribute to search for dir's */
134:
135:
136:
137: /*********************************************************************/
138: /* Binding System Variables: */
139: /* */
140: /* Because this is the only C file in the binding system, all */
141: /* variables used in the binding system are allocated here. None of */
142: /* these variables are used in this file. */
143: /*********************************************************************/
144:
145:
146:
147:
148: /*********************************************************************/
149: /* lstrlen - standard */
150: /*********************************************************************/
151:
152: int FAR PASCAL lstrlen( pStr )
153: PSZ pStr;
154: {
155: int j;
156:
157: for (j = 0; *(pStr++); j++);
158:
159: return j;
160: }
161:
162: /*********************************************************************/
163: /* lstrcpy - standard */
164: /*********************************************************************/
165:
166: PSZ FAR PASCAL lstrcpy( pDest, pSrc )
167: PSZ pDest, pSrc;
168: {
169: PSZ pTemp = pDest;
170:
171: do {
172: *(pDest++) = *(pSrc);
173: } while ( *(pSrc++) );
174:
175: return( pTemp );
176: }
177:
178: /*********************************************************************/
179: /* lstrcat - standard */
180: /*********************************************************************/
181:
182: PSZ FAR PASCAL lstrcat( pDest, pSrc )
183: PSZ pDest, pSrc;
184: {
185: PSZ pTemp = pDest;
186:
187: while (*(pDest++));
188:
189: pDest--;
190: do {
191: *(pDest++) = *(pSrc);
192: } while ( *(pSrc++) );
193:
194: return( pTemp );
195: }
196:
197: /*********************************************************************/
198: /* lmemcpy - standard */
199: /*********************************************************************/
200:
201: void FAR PASCAL lmemcpy( pDest, pSrc, wCount )
202: PSZ pDest, pSrc;
203: unsigned wCount;
204: {
205: for ( ; wCount--; *(pDest++) = *(pSrc++) );
206: }
207:
208: /*********************************************************************/
209: /* CheckScrollBars - */
210: /* This routine shows or hides a scroll bar. */
211: /* */
212: /* Input: Accepts handle to frame window, id of scroll bar, */
213: /* boolean indicating whether to show scroll bar. */
214: /* */
215: /* Return: Whether scroll bar shown. */
216: /* */
217: /* Notes: This routine utilizes the fact that the frame window */
218: /* recognizes control windows only through the id of the */
219: /* control window. In order to hide a scroll window, all that */
220: /* has to be done is to change the id of the scroll window, */
221: /* disable the window for input, and repaint the frame. This */
222: /* is much easier (and faster) than creating and destroying */
223: /* control windows. */
224: /*********************************************************************/
225:
226: int CheckScrollBars( hFrame, wScrollId, fShow )
227: HWND hFrame;
228: unsigned wScrollId;
229: int fShow;
230: {
231: HWND hScroll;
232:
233: /* Attempt to get existing scroll Window */
234: hScroll = WinWindowFromID( hFrame, wScrollId );
235:
236: /* If scroll bar already the in desired state, return fShow */
237: if ((fShow && hScroll) || (!fShow && !hScroll))
238: return( fShow );
239:
240: if (fShow) {
241: /* If want to show scroll bar, get hidden one */
242: hScroll = WinWindowFromID( hFrame, wScrollId | HIDE_BIT );
243:
244: /* Mask off hidden bit */
245: WinSetWindowUShort( hScroll, QWS_ID, wScrollId & HIDE_MASK );
246: }
247: else
248: /* Otherwise hide existing bar by changing id */
249: WinSetWindowUShort( hScroll, QWS_ID, wScrollId | HIDE_BIT );
250:
251: /* Turn [on|off] mouse clicks to scroll bar, [hide|show] on screen */
252: WinEnableWindow( hScroll, fShow );
253: WinShowWindow( hScroll, fShow );
254:
255: /* Finally, send update frame message to let frame know something's up */
256: NewSendMsg( hFrame, WM_UPDATEFRAME,
257: wScrollId == FID_HORZSCROLL ? FCF_HORZSCROLL : FCF_VERTSCROLL,
258: 0L );
259:
260: return( fShow );
261: }
262:
263:
264: /*********************************************************************/
265: /* DlgDirSelect - */
266: /* This routine gets current selection from a dialog box. */
267: /* */
268: /* Input: Handle to dialog box, string to return selection in, */
269: /* id of listbox. */
270: /* */
271: /* Return: Whether selection was a directory. (TRUE) */
272: /*********************************************************************/
273:
274: unsigned DlgDirSelect( hDlg, pString, nID )
275: HWND hDlg;
276: PSZ pString;
277: unsigned nID;
278: {
279: HWND hList;
280: unsigned j;
281:
282: /* Get handle to the listbox */
283: hList = WinWindowFromID( hDlg, nID );
284:
285: /* Get current selection in j; read selection from listbox */
286: j = (unsigned) NewSendMsg( hList, LM_QUERYSELECTION, 0L, 0L );
287: NewSendMsg( hList, LM_QUERYITEMTEXT,
288: MAKELONG( j, 64 ), (long) pString );
289:
290: /* Directories are enclosed in brackets */
291: if (*pString == '[') {
292: /* If directory, strip brackets, return TRUE */
293: j = lstrlen( pString );
294: lmemcpy( pString, pString + 1, j );
295: pString[j - 2] = '\\';
296: pString[j - 1] = 0;
297: return( TRUE );
298: }
299: else
300: /* Normal file, return FALSE */
301: return( FALSE );
302: }
303:
304: /*********************************************************************/
305: /* DlgDirList - */
306: /* This routine fills a list box with file names matching the */
307: /* specification and possibly updates a static text field. */
308: /* */
309: /* Input: Dialog box handle, file specification string, Id of */
310: /* list box, id of static text field (maybe 0), and */
311: /* attrib indicating type of files to list. */
312: /* */
313: /* Return: fSuccess. */
314: /* */
315: /* Notes: Currently, this function has doesn't have the full */
316: /* functionality of its Windows namesake. If the path is too */
317: /* long to fit in the static text field, it should be abbreviated */
318: /* with '...'. Also, disk drives aren't listed. */
319: /*********************************************************************/
320:
321: int DlgDirList( hDlg, pInitPath, wListId, wIdStatic, wAttrib )
322: HWND hDlg;
323: PSZ pInitPath;
324: unsigned wListId;
325: unsigned wIdStatic;
326: unsigned wAttrib;
327: {
328: char npTempBuf[MAX_PATH_LEN]; /* Temp location to hold path */
329: char PathStr[MAX_PATH_LEN]; /* Used to build path */
330: PSZ pPathStr = PathStr; /* Pointer to path */
331: PSZ pFileName; /* Pointer to File Name */
332: HWND hList; /* Handle to list box */
333:
334: /* Copy string into Temp Buffer, this allows parsing routines */
335: /* to modify the string passed in. */
336: if (pInitPath == NULL)
337: npTempBuf[0] = 0;
338: else
339: lstrcpy( (PSZ) npTempBuf, pInitPath );
340:
341: /* Ensure path is legal and expand to full search path */
342: /* Stores full path in pPathStr */
343: pFileName = ParseFile( (PSZ) npTempBuf, pPathStr, FALSE );
344: if (pFileName == NULL)
345: return( FALSE );
346:
347: /* set current drive and path */
348: DosSelectDisk( *pPathStr - 'A' + 1 );
349: DosChdir( pPathStr, 0L );
350:
351: /* If static field, set text to be path */
352: /* Note: path should be abbreviated here! */
353: if (wIdStatic)
354: WinSetWindowText( WinWindowFromID( hDlg, wIdStatic ),
355: pPathStr );
356:
357: if (wListId) {
358: /* If list box present, get window */
359: hList = WinWindowFromID( hDlg, wListId );
360:
361: /* Empty list boxes of any old entries */
362: NewSendMsg( hList, LM_DELETEALL, 0L, 0L );
363:
364: /* Fill them up with new entries */
365: return( FillListBox( hList, wAttrib, pFileName ) );
366: }
367: else
368: return( FALSE );
369: }
370:
371:
372: /*********************************************************************/
373: /* FillListBox - */
374: /* This routine fills a list box with file names matching the */
375: /* specification. */
376: /* */
377: /* Input: List box handle, file attribute, file wildcard */
378: /* specification. */
379: /* */
380: /* Return: fSuccess. */
381: /* */
382: /* Notes: This function should list disk drives. When this funciton */
383: /* is called, the current drive and directory should be correct. */
384: /*********************************************************************/
385:
386: int FillListBox( hList, wAttrib, pFileSpec )
387: HWND hList;
388: unsigned wAttrib;
389: PSZ pFileSpec;
390: {
391: char npTemp[30];
392: PSZ pTemp = npTemp;
393: unsigned wDir;
394: FILEFINDBUF ffb;
395: int cFiles;
396:
397: /* Put files that match search spec in file listbox */
398: /* This is the standard list files loop */
399: cFiles = 1;
400: wDir = 0xffff;
401: if (!DosFindFirst( pFileSpec, (PHDIR) &wDir, wAttrib & 0x0f, &ffb,
402: sizeof ffb, &cFiles, 0L )) {
403: do {
404: NewSendMsg( hList, LM_INSERTITEM,
405: MAKELONG( 0, LIT_SORTASCENDING ),
406: (long) (PSZ) ffb.achName );
407: cFiles = 1;
408: } while (!DosFindNext( wDir, &ffb, sizeof ffb, &cFiles ));
409: }
410:
411: DosFindClose( wDir );
412:
413: /* Put directories in file listbox */
414: /* Standard list files loop with a twist - surround in brackets */
415: cFiles = 1;
416: wDir = 0xffff;
417: if (!DosFindFirst( "*", (PHDIR) &wDir, DIR_ATTRIBUTE, &ffb,
418: sizeof ffb, &cFiles, 0L )) {
419: do {
420: if (ffb.attrFile & DIR_ATTRIBUTE) {
421: /* Surround in brackets */
422: pTemp[0] = '[';
423: lmemcpy( pTemp + 1, (PSZ) &(ffb.achName[0]), ffb.cchName );
424: pTemp[ffb.cchName + 1] = ']';
425: pTemp[ffb.cchName + 2] = 0;
426:
427: NewSendMsg( hList, LM_INSERTITEM,
428: MAKELONG( 0, LIT_SORTASCENDING ), (long) pTemp );
429: }
430: cFiles = 1;
431: } while (!DosFindNext( wDir, &ffb, sizeof ffb, &cFiles ));
432: }
433:
434: DosFindClose( wDir );
435:
436: return TRUE;
437: }
438:
439:
440: /*********************************************************************/
441: /* ParseFile - */
442: /* This routine parses a path/file specification obtaining a */
443: /* complete path specifcation. */
444: /* */
445: /* Input: Initial Path specification, Buffer to output path */
446: /* path spec, Flag indicating whether to append file name */
447: /* to path spec. */
448: /* */
449: /* Return: Pointer to file name, NULL if couldn't parse. */
450: /* */
451: /* Notes: This function modifies the Initial path spec directly. */
452: /* If there is a possibility that a calling function may receive */
453: /* a constant string, it should copy the string constant to a */
454: /* temp buffer before calling this routine. */
455: /*********************************************************************/
456:
457: PSZ ParseFile( pSpec, pPath, fAppend )
458: PSZ pSpec;
459: PSZ pPath;
460: BOOL fAppend;
461: {
462: char TempChar;
463: PSZ pBuf, pFile;
464:
465: /* Go past any path spec to first char in file name */
466: pFile = GetFileFromPath( pSpec );
467:
468: /* If path specification ends in '\' or ':', treat as if '*' was */
469: /* specified as the file name */
470: if (*pFile == 0) {
471: pFile++;
472: *pFile = '*';
473: *(pFile + 1) = 0;
474: }
475:
476: /* Save first char of file name, terminate path */
477: TempChar = *pFile;
478: *pFile = 0;
479:
480: /* If filename is path, i.e. no path was specified, use '.' as */
481: /* path, otherwise use current path specification */
482: if (pFile == pSpec)
483: pBuf = ".";
484: else
485: pBuf = pSpec;
486:
487: /* Call DosSearchPath. This forms a complete path specification */
488: /* in addition to verifying the path */
489: if (DosSearchPath( 0, pBuf, (PSZ) "*", pPath, MAX_PATH_LEN )) {
490: *pPath = 0;
491: *pFile = TempChar;
492: return( NULL );
493: }
494:
495: /* DosSearchPath adds wildcard extensions after valid path. Find */
496: /* first wildcard char, and end path there */
497: while (*pPath) {
498: if ((*pPath == '?') || (*pPath == '*')) {
499: *pPath = 0;
500: break;
501: }
502: pPath++;
503: }
504:
505: /* Restore first character in file name. */
506: *pFile = TempChar;
507:
508: /* Check if should append file name to path */
509: if (fAppend)
510: lstrcpy( pPath, pFile );
511: else {
512: /* If shouldn't then make sure path doesn't end in '\'. The */
513: /* only case where this is ok is for the root directory. This */
514: /* insures that DosChdir may be called on the returned path */
515: pPath--;
516: if ((*pPath == '\\') && (*(pPath-1) != ':'))
517: *pPath = 0;
518: }
519:
520: return( pFile );
521: }
522:
523:
524: /*********************************************************************/
525: /* GetFileFromPath - */
526: /* This routine finds the beginning of the file name in a path.
527: /* */
528: /* Input: Path specification.
529: /* */
530: /* Return: Pointer to file name.
531: /*********************************************************************/
532:
533: PSZ GetFileFromPath( pPath )
534: PSZ pPath;
535: {
536: int j;
537:
538: j = lstrlen( pPath );
539:
540: /* Search backwards until find '\', ':' */
541: while (j--)
542: if (pPath[j] == '\\') {
543: /* Make sure path doesn't end in '\' */
544: pPath[j] = 0;
545: return( pPath + j + 1 );
546: }
547: else if (pPath[j] == ':')
548: return( pPath + j + 1 );
549:
550: return( pPath );
551: }
552:
553:
554: /*********************************************************************/
555: /* OpenFile - */
556: /* This routine opens, closes, deletes files; parses filename. */
557: /* */
558: /* Input: File specification, Open File structure, Flags */
559: /* indicating what to do and where information is. */
560: /* */
561: /* Return: File handle (0 if OF_PARSE) or -1 if error */
562: /*********************************************************************/
563:
564:
565: /* These are constants used to specify the action taken in DosOpen */
566: #define OPEN_CALL 0x0001
567: #define CREATE_CALL 0x0012
568:
569: int OpenFile( pFileName, lpStruct, wCommand )
570: PSZ pFileName;
571: LPOFSTRUCT lpStruct;
572: WORD wCommand;
573: {
574: char npTempBuf[MAX_PATH_LEN];
575: PSZ pFile = (PSZ) npTempBuf;
576: int wOpenCode, wHandle, wAction;
577:
578: /* Copy file name to temp buf., may need to modify */
579: lstrcpy( pFile, pFileName );
580:
581: /* If OF_REOPEN, then assume that file name in buffer is correct */
582: /* Otherwise, parse from pFileName to structure and return -1 */
583: /* if error. */
584: if (! (wCommand & OF_REOPEN))
585: if (!ParseFile( pFile, (PSZ) (lpStruct->szPathName), TRUE ))
586: return( -1 );
587:
588: /* If OF_PARSE, all done! */
589: if (wCommand & OF_PARSE)
590: return( 0 );
591:
592: /* Set code indicating whether file should be opened or created */
593: wOpenCode = wCommand & OF_CREATE ? CREATE_CALL : OPEN_CALL;
594:
595: /* Either open or create file - even in the card of OF_DELETE, do */
596: /* this to verify that file is accessible */
597: pFile = (PSZ) (lpStruct->szPathName);
598: if (DosOpen( pFile, (PHFILE) &wHandle, &wAction, 1L, 0, wOpenCode,
599: 0xc2, 0L ) )
600: return( -1 );
601:
602: /* If OF_EXIST or OF_DELETE, don't keep file open */
603: if (wCommand & (OF_EXIST | OF_DELETE)) {
604: DosClose( wHandle );
605: wHandle = 0;
606: }
607:
608: /* If OF_DELETE, get rid of file. There shouldn't be an error if */
609: /* this file was opened correctly */
610: if (wCommand & OF_DELETE)
611: DosDelete( pFile, 0L );
612:
613: return( wHandle );
614: }
615:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.