|
|
1.1 root 1: /*******************************************************************************
2: * *
3: * MODULE : DLGOPEN.C *
4: * *
5: * DESCRIPTION : Routines to display a standard File/Open and File/Save *
6: * dialog boxes. *
7: * *
8: * FUNCTIONS : DlgOpenFile() - Displays a dialog box for opening or saving a*
9: * file. *
10: * *
11: * DlgfnOpen() - Dialog function for the above dialog. *
12: * *
13: * AddExt() - Adds an extension to a filename if not *
14: * already present. *
15: * *
16: * FSearchSpec() - Checks if given string contains a wildcard *
17: * character. *
18: * *
19: * FillListBox() - Fills listbox with files that match specs. *
20: * *
21: * DlgCheckOkEnable() - Enables <OK> button iff there's text in *
22: * the edit control. *
23: * *
24: * NOTE : These routines require that the app. be running *
25: * SS = DS since they use near pointers into the stack. *
26: * *
27: *******************************************************************************/
28: #include <windows.h>
29: #include <string.h>
30: #include "showdib.h"
31:
32: static PSTR szExt;
33: static PSTR szFileName;
34: static PSTR szTitle;
35: static DWORD flags;
36: static WORD fOpt;
37:
38: /* Forward declarations of helper functions */
39:
40: static VOID NEAR DlgCheckOkEnable(HWND hwnd, INT idEdit, UINT message);
41: static CHAR *NEAR FillListBox (HWND,CHAR*, UINT);
42: static BOOL NEAR FSearchSpec (CHAR*);
43: static VOID NEAR AddExt (CHAR*,CHAR*);
44:
45: #define DLGOPEN_UNUSED 0
46:
47: /* Mask to eliminate bogus style and bitcount combinations ...
48: * RLE formats, if chosen should be matched with the bitcounts:
49: * RLE4 scheme should be used only for 4 bitcount DIBs.
50: * RLE8 " " " " " " 8 " "
51: *
52: * BITCOUNTMASK is indexed by DLGOPEN_RLE4 >> 4, DLGOPEN_RLE8 >> 4
53: * and DLGOPEN_RLE8 >> 4
54: */
55:
56: static WORD BITCOUNTMASK[] = { DLGOPEN_UNUSED,
57: DLGOPEN_1BPP | DLGOPEN_8BPP | DLGOPEN_24BPP,
58: DLGOPEN_1BPP | DLGOPEN_4BPP | DLGOPEN_24BPP,
59: DLGOPEN_UNUSED,
60: 0 };
61:
62:
63: LPSTR AnsiUpper(LPSTR);
64: /*******************************************************************************
65: * *
66: * FUNCTION :DlgOpen(LPSTR szFile) *
67: * *
68: * PURPOSE :Display dialog box for opening files. Allow user to interact *
69: * with dialogbox, change directories as necessary, and try to *
70: * open file if user selects one. Automatically append *
71: * extension to filename if necessary. *
72: * This routine correctly parses filenames containing KANJI *
73: * characters. *
74: * *
75: * RETURNS : - Handle to the opened file if legal filename. *
76: * - 0 if user presses <cancel> *
77: * - 1 if filename entered is illegal *
78: * *
79: *******************************************************************************/
80: HFILE APIENTRY DlgOpenFile (
81: HWND hwndParent,
82: CHAR *szTitleIn,
83: DWORD flagsIn,
84: CHAR *szExtIn,
85: CHAR *szFileNameIn,
86: WORD *pfOpt)
87: {
88: INT fh;
89: FARPROC lpProc;
90: CHAR achFile[128];
91: CHAR achExt[128];
92: HANDLE hInstance;
93: WORD w;
94:
95: if (pfOpt == NULL)
96: pfOpt = &w;
97:
98: flags = flagsIn;
99: fOpt = *pfOpt;
100:
101: lstrcpy (szFileName = achFile, szFileNameIn);
102: lstrcpy (szExt = achExt, szExtIn);
103: szTitle = szTitleIn;
104:
105: hInstance = (HANDLE)GetWindowLong (hwndParent, GWL_HINSTANCE);
106:
107: /* Show the dialog box */
108: lpProc = MakeProcInstance ((FARPROC)DlgfnOpen, hInstance);
1.1.1.2 ! root 109: fh = DialogBox (hInstance, "DlgOpenBox", hwndParent, lpProc);
1.1 root 110: FreeProcInstance (lpProc);
111:
112: if (fh != 0){
113: lstrcpy (szFileNameIn, szFileName);
114: *pfOpt = fOpt;
115: }
116: return fh;
117: }
118:
119: /****************************************************************************
120: * *
121: * FUNCTION :DlgfnOpen (hwnd, msg, wParam, lParam) *
122: * *
123: * PURPOSE :Dialog function for File/Open dialog. *
124: * *
125: ****************************************************************************/
126: LONG APIENTRY DlgfnOpen (
127: HWND hwnd,
128: UINT msg,
129: UINT wParam,
130: LONG lParam)
131: {
132: INT result = -1; /* Assume illegal filename initially */
133: int w;
134: CHAR c;
135: WORD f;
136: OFSTRUCT of;
137: RECT rc, rcCtl;
138: HWND hwndT;
139: BOOL fEnable;
140:
141: switch (msg) {
142: case WM_INITDIALOG:
143: if (szTitle && *szTitle)
144: SetWindowText (hwnd, szTitle);
145:
146: /* Set text on <OK> button according to mode (File/Open or File/Save) */
147: if (flags & OF_SAVE)
148: SetDlgItemText (hwnd, IDOK, "&Save");
149: if (flags & OF_OPEN)
150: SetDlgItemText (hwnd, IDOK, "&Open");
151:
152: if ((flags & OF_NOOPTIONS) &&
153: (hwndT = GetDlgItem(hwnd,DLGOPEN_FOLDOUT)))
154: EnableWindow (hwndT,FALSE);
155:
156: if (hwndT = GetDlgItem (hwnd, DLGOPEN_SMALL)) {
157: GetWindowRect (hwnd,&rc);
158: GetWindowRect (GetDlgItem(hwnd,DLGOPEN_SMALL),&rcCtl);
159:
160: SetWindowPos (hwnd,
161: NULL,
162: 0,
163: 0,
164: rcCtl.left - rc.left,
165: rc.bottom - rc.top,
166: SWP_NOZORDER | SWP_NOMOVE);
167: }
168: /* fill list box with filenames that match specifications, and
169: * fill static field with path name.
170: */
171: FillListBox(hwnd,szExt, WM_INITDIALOG);
172:
173: /* If in Save mode, set the edit control with default (current)
174: * file name,and select the corresponding entry in the listbox.
175: */
176: if ((flags & OF_SAVE) && *szFileName) {
177: SetDlgItemText (hwnd, DLGOPEN_EDIT, szFileName);
178: SendDlgItemMessage (hwnd,
179: DLGOPEN_FILE_LISTBOX,
180: LB_SELECTSTRING,
181: 0,
182: (LONG)(LPSTR)szFileName);
183: }
184: else {
185: /* Set the edit field with the default extensions... */
186: if (flags & OF_NOSHOWSPEC)
187: SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
188: else
189: SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
190: }
191: /* ...and select all text in the edit field */
192: /* JAP added HWND cast*/
193: SendMessage((HWND)GetDlgItem(hwnd, DLGOPEN_EDIT), EM_SETSEL, GET_EM_SETSEL_MPS(0, 0x7fff));
194:
195: /* check all options that are set */
196: for ( f = DLGOPEN_1BPP; f; f<<=1)
197: CheckDlgButton(hwnd, (INT)FID(f), (WORD) (fOpt & f));
198:
199: break;
200:
201: case WM_COMMAND:
202: w = LOWORD(wParam);
203: switch (w) {
204: case IDOK:
205: if (IsWindowEnabled (GetDlgItem(hwnd, IDOK))) {
206: /* Get contents of edit field and add search spec. if it
207: * does not contain one.
208: */
209: GetDlgItemText (hwnd, DLGOPEN_EDIT, (LPSTR)szFileName, 128);
210:
211: w = lstrlen(szFileName)-1;
212: c = szFileName[w];
213: switch (c) {
214: case '\\':
215: case '/':
216: szFileName[w] = 0;
217: break;
218: }
219: if (SetCurrentDirectory ((LPSTR)szFileName))
220: lstrcpy (szFileName,szExt);
221:
222: /* Try to open path. If successful, fill listbox with
223: * contents of new directory. Otherwise, open datafile.
224: */
225: if (FSearchSpec(szFileName)) {
226: lstrcpy (szExt, FillListBox (hwnd, szFileName, WM_COMMAND));
227: if (flags & OF_NOSHOWSPEC) {
228: SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
229: } else {
230: SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
231: }
232: break;
233: }
234:
235: /* Make filename upper case and if it's a legal DOS
236: * name, try to open the file.
237: */
238: AnsiUpper(szFileName);
239: AddExt(szFileName,szExt);
240: result = (INT)OpenFile(szFileName, &of, (WORD)flags);
241:
242: if (result != -1) {
243: lstrcpy(szFileName,of.szPathName);
244: }
245: else if (flags & OF_MUSTEXIST) {
246: MessageBeep(0);
247: return 0L;
248: }
249:
250: /* Get the state of all checked options */
251: for (f = DLGOPEN_1BPP; f; f <<= 1){
252: if (IsDlgButtonChecked (hwnd, FID (f)))
253: fOpt |= f;
254: else
255: fOpt &= ~f;
256: }
257:
258: EndDialog (hwnd, result);
259: }
260: break;
261:
262: case DLGOPEN_OPTION + DLGOPEN_RLE4:
263: case DLGOPEN_OPTION + DLGOPEN_RLE8:
264: case DLGOPEN_OPTION + DLGOPEN_RGB:
265: /* Mask out incompatible bitcount options and gray the
266: * appropriate radiobuttons.
267: */
268: for (f = DLGOPEN_1BPP; f <= DLGOPEN_24BPP; f <<= 1){
269: fEnable = !(f & BITCOUNTMASK [IDF(w) >> 4 ]);
270: EnableWindow (GetDlgItem (hwnd, FID(f)), fEnable);
271:
272: /* If the radiobutton is being grayed, uncheck it and
273: * and check an "allowed" option so the bitcount group
274: * is still accessible via the keyboard
275: */
276: if (!fEnable && IsDlgButtonChecked (hwnd, FID (f))){
277: CheckDlgButton(hwnd, FID(f), FALSE);
278: CheckDlgButton(hwnd, FID(IDF(w) >> 3), TRUE);
279: }
280: }
281: break;
282:
283: case IDCANCEL:
284: /* User pressed cancel. Just take down dialog box. */
285: EndDialog (hwnd, 0);
286: break;
287:
288: /* User single clicked or doubled clicked in listbox -
289: * Single click means fill edit box with selection.
290: * Double click means go ahead and open the selection.
291: */
292: case DLGOPEN_FILE_LISTBOX:
293: case DLGOPEN_DIR_LISTBOX:
294: switch (GET_WM_COMMAND_CMD(wParam, lParam)) {
295: /* Single click case */
296: case LBN_SELCHANGE:
297: /* Get selection, which may be either a prefix to a
298: * new search path or a filename. DlgDirSelectEx parses
299: * selection, and appends a backslash if selection
300: * is a prefix
301: */
302: DlgDirSelectEx(hwnd, szFileName, 128, LOWORD(wParam));
303: w = lstrlen(szFileName)-1;
304: c = szFileName[w];
305: switch (c) {
306: case ':':
307: lstrcat (szFileName,".");
308: break;
309: case '\\':
310: case '/':
311: szFileName[w] = 0;
312: break;
313: }
314: SetDlgItemText(hwnd, DLGOPEN_EDIT, szFileName);
315: break;
316: /* Double click case - first click has already been
317: * processed as single click
318: */
319: case LBN_DBLCLK:
320: PostMessage (hwnd,WM_COMMAND,IDOK,0L);
321: break;
322: }
323: break;
324:
325: case DLGOPEN_EDIT:
326: DlgCheckOkEnable(hwnd, DLGOPEN_EDIT, HIWORD(lParam));
327: break;
328:
329: case DLGOPEN_FOLDOUT:
330: GetWindowRect(hwnd,&rc);
331: GetWindowRect(GetDlgItem(hwnd,DLGOPEN_BIG),&rcCtl);
332:
333: if ((rcCtl.left <= rc.right) && (rcCtl.top <= rc.bottom))
334: GetWindowRect (GetDlgItem (hwnd, DLGOPEN_SMALL), &rcCtl);
335:
336: SetWindowPos (hwnd,
337: NULL,
338: 0,
339: 0,
340: rcCtl.left - rc.left,
341: rc.bottom - rc.top,
342: SWP_NOZORDER | SWP_NOMOVE);
343: break;
344: }
345: default:
346: return FALSE;
347: }
348: return TRUE;
349: }
350:
351: /****************************************************************************
352: * *
353: * FUNCTION : static void NEAR DlgCheckOkEnable(hwnd, idEdit, message) *
354: * *
355: * PURPOSE : Enables the <OK> button in a dialog box iff the edit item *
356: * contains text. *
357: * *
358: ****************************************************************************/
359: static VOID NEAR DlgCheckOkEnable(
360: HWND hwnd,
361: INT idEdit,
362: UINT message)
363: {
364: if (message == EN_CHANGE) {
365: EnableWindow ( GetDlgItem (hwnd, IDOK),
366: (BOOL)SendMessage (GetDlgItem (hwnd, idEdit),
367: WM_GETTEXTLENGTH,
368: 0, 0L));
369: }
370: }
371:
372: /****************************************************************************
373: * *
374: * FUNCTION : AddExt (pch, ext) *
375: * *
376: * PURPOSE : Add an extension to a filename if none is already specified*
377: * *
378: ****************************************************************************/
379: static VOID NEAR AddExt (
380: CHAR *pch, /* File name */
381: CHAR *ext) /* Extension to add */
382: {
383: CHAR acExt[20];
384: CHAR *pext = acExt;
385:
386: while (*ext && *ext != '.')
387: ext++;
388: while (*ext && *ext != ';')
389: *pext++ = *ext++;
390: *pext = 0;
391: pext = acExt;
392:
393: while (*pch == '.') {
394: pch++;
395: if ((*pch == '.') && pch[1] == '\\')
396: pch += 2; /* ..\ */
397: if (*pch == '\\')
398: pch++; /* .\ */
399: }
400: while (*pch != '\0')
401: if (*pch++ == '.')
402: return;
403:
404: // *pch++ = '.';
405: do
406: *pch++ = *pext;
407: while (*pext++ != '\0');
408: }
409: /****************************************************************************
410: * *
411: * FUNCTION : FSearchSpec (sz) *
412: * *
413: * PURPOSE : Checks to see if NULL-terminated strings contains a "*" or *
414: * a "?". *
415: * *
416: * RETURNS : TRUE - if the above characters are found in the string *
417: * FALSE - otherwise. *
418: * *
419: ****************************************************************************/
420: static BOOL NEAR FSearchSpec(CHAR *sz)
421: {
422: for (; *sz ;sz++) {
423: if (*sz == '*' || *sz == '?')
424: return TRUE;
425: }
426: return FALSE;
427: }
428:
429: /****************************************************************************
430: * *
431: * FUNCTION : static char * NEAR FillListBox (hDlg,pFile, cmd) *
432: * *
433: * PURPOSE : Fill list box with filenames that match specifications, and*
434: * fills the static field with the path name. *
435: * *
436: * RETURNS : A pointer to the pathname. *
437: * *
438: ****************************************************************************/
439: static CHAR * NEAR FillListBox (
440: HWND hDlg,
441: CHAR *pFile, /* [path]{list of file wild cards, separated by ';'} */
442: UINT cmd) /* if initdialog, or WM_COMMAND*/
443: {
444: CHAR ach[128];
445: CHAR *pch;
446: CHAR *pDir; /* Directory name or path */
447: CHAR pCurDir[256];
448:
449: pch = pFile;
450: pDir = ach;
451: if(cmd == WM_INITDIALOG){
452: while (*pch && *pch != ';')
453: pch++;
454: while ((pch > pFile) && (*pch != '/') && (*pch != '\\'))
455: pch--;
456: if (pch > pFile) {
457: *pch = 0;
458: lstrcpy (pDir, pFile);
459: pFile = pch + 1;
460: }
461: else {
462: lstrcpy (pDir,".");
463: }
464: }
465: else{
466: /* since SetCurrentDirectory was called already, I'll use GetCurrentDirectory*/
467: /* to get pDir*/
468: GetCurrentDirectory(256, pCurDir);
469: strcpy(pDir, pCurDir);
470: }
471: DlgDirList (hDlg, pDir, (INT)DLGOPEN_DIR_LISTBOX, (INT)DLGOPEN_PATH,(WORD)ATTRDIRLIST);
472: SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, LB_RESETCONTENT, 0, 0L);
473: SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, FALSE, 0L);
474: pDir = pFile; /* save pFile to return */
475: while (*pFile) {
476: pch = ach;
477: while (*pFile==' ')
478: pFile++;
479: while (*pFile && *pFile != ';')
480: *pch++ = *pFile++;
481: *pch = 0;
482: if (*pFile)
483: pFile++;
484: SendDlgItemMessage (hDlg,
485: DLGOPEN_FILE_LISTBOX,
486: LB_DIR,ATTRFILELIST,
487: (LONG)(LPSTR)ach);
488: }
489: SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, TRUE, 0L);
490: InvalidateRect (GetDlgItem (hDlg, DLGOPEN_FILE_LISTBOX), NULL, TRUE);
491:
492: return pDir;
493: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.