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