Release 960225
[wine.git] / misc / commdlg.c
blob9e76ac0bf3f9e74d8543710b71bdbb9b73f9459b
1 /*
2 * COMMDLG functions
4 * Copyright 1994 Martin Ayotte
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "win.h"
11 #include "user.h"
12 #include "message.h"
13 #include "commdlg.h"
14 #include "dlgs.h"
15 #include "selectors.h"
16 #include "resource.h"
17 #include "dos_fs.h"
18 #include "drive.h"
19 #include "stackframe.h"
20 #include "stddebug.h"
21 #include "debug.h"
23 static DWORD CommDlgLastError = 0;
25 static HBITMAP hFolder = 0;
26 static HBITMAP hFolder2 = 0;
27 static HBITMAP hFloppy = 0;
28 static HBITMAP hHDisk = 0;
29 static HBITMAP hCDRom = 0;
31 /***********************************************************************
32 * FileDlg_Init [internal]
34 static BOOL FileDlg_Init()
36 static BOOL initialized = 0;
38 if (!initialized) {
39 if (!hFolder) hFolder = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER));
40 if (!hFolder2) hFolder2 = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER2));
41 if (!hFloppy) hFloppy = LoadBitmap(0, MAKEINTRESOURCE(OBM_FLOPPY));
42 if (!hHDisk) hHDisk = LoadBitmap(0, MAKEINTRESOURCE(OBM_HDISK));
43 if (!hCDRom) hCDRom = LoadBitmap(0, MAKEINTRESOURCE(OBM_CDROM));
44 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
45 hHDisk == 0 || hCDRom == 0)
47 fprintf(stderr, "FileDlg_Init // Error loading bitmaps !");
48 return FALSE;
50 initialized = TRUE;
52 return TRUE;
55 /***********************************************************************
56 * GetOpenFileName (COMMDLG.1)
58 BOOL GetOpenFileName(LPOPENFILENAME lpofn)
60 HINSTANCE hInst;
61 HANDLE hDlgTmpl, hResInfo;
62 BOOL bRet;
64 if (!lpofn || !FileDlg_Init()) return FALSE;
66 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) hDlgTmpl = lpofn->hInstance;
67 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
69 if (!(hResInfo = FindResource( lpofn->hInstance,
70 lpofn->lpTemplateName, RT_DIALOG)))
72 CommDlgLastError = CDERR_FINDRESFAILURE;
73 return FALSE;
75 hDlgTmpl = LoadResource( lpofn->hInstance, hResInfo );
77 else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_OPEN_FILE );
78 if (!hDlgTmpl)
80 CommDlgLastError = CDERR_LOADRESFAILURE;
81 return FALSE;
84 hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
85 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner,
86 GetWndProcEntry16("FileOpenDlgProc"),
87 (DWORD)lpofn );
89 if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
91 if (lpofn->Flags & OFN_ENABLETEMPLATE) FreeResource( hDlgTmpl );
92 else SYSRES_FreeResource( hDlgTmpl );
95 dprintf_commdlg(stddeb,"GetOpenFileName // return lpstrFile='%s' !\n",
96 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
97 return bRet;
101 /***********************************************************************
102 * GetSaveFileName (COMMDLG.2)
104 BOOL GetSaveFileName(LPOPENFILENAME lpofn)
106 HINSTANCE hInst;
107 HANDLE hDlgTmpl, hResInfo;
108 BOOL bRet;
110 if (!lpofn || !FileDlg_Init()) return FALSE;
112 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) hDlgTmpl = lpofn->hInstance;
113 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
115 hInst = lpofn->hInstance;
116 if (!(hResInfo = FindResource( lpofn->hInstance,
117 lpofn->lpTemplateName, RT_DIALOG )))
119 CommDlgLastError = CDERR_FINDRESFAILURE;
120 return FALSE;
122 hDlgTmpl = LoadResource( lpofn->hInstance, hResInfo );
124 else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_SAVE_FILE );
126 hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
127 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner,
128 GetWndProcEntry16("FileSaveDlgProc"),
129 (DWORD)lpofn);
130 if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
132 if (lpofn->Flags & OFN_ENABLETEMPLATE) FreeResource( hDlgTmpl );
133 else SYSRES_FreeResource( hDlgTmpl );
136 dprintf_commdlg(stddeb, "GetSaveFileName // return lpstrFile='%s' !\n",
137 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
138 return bRet;
141 /***********************************************************************
142 * FILEDLG_StripEditControl [internal]
143 * Strip pathnames off the contents of the edit control.
145 static void FILEDLG_StripEditControl(HWND hwnd)
147 char temp[512], *cp;
149 SendDlgItemMessage(hwnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(temp));
150 cp = strrchr(temp, '\\');
151 if (cp != NULL) {
152 strcpy(temp, cp+1);
154 cp = strrchr(temp, ':');
155 if (cp != NULL) {
156 strcpy(temp, cp+1);
160 /***********************************************************************
161 * FILEDLG_ScanDir [internal]
163 static BOOL FILEDLG_ScanDir(HWND hWnd, LPSTR newPath)
165 char str[512],str2[512];
167 strncpy(str,newPath,511); str[511]=0;
168 SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(str2));
169 strncat(str,str2,511-strlen(str)); str[511]=0;
170 if (!DlgDirList(hWnd, MAKE_SEGPTR(str), lst1, 0, 0x0000)) return FALSE;
171 strcpy( str, "*.*" );
172 DlgDirList(hWnd, MAKE_SEGPTR(str), lst2, stc1, 0x8010);
173 return TRUE;
176 /***********************************************************************
177 * FILEDLG_GetFileType [internal]
180 static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
182 int n, i;
183 i = 0;
184 if (cfptr)
185 for ( ;(n = strlen(cfptr)) != 0; i++)
187 cfptr += n + 1;
188 if (i == index)
189 return cfptr;
190 cfptr += strlen(cfptr) + 1;
192 if (fptr)
193 for ( ;(n = strlen(fptr)) != 0; i++)
195 fptr += n + 1;
196 if (i == index)
197 return fptr;
198 fptr += strlen(fptr) + 1;
200 return NULL;
203 /***********************************************************************
204 * FILEDLG_WMDrawItem [internal]
206 static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
208 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
209 char str[512];
210 HBRUSH hBrush;
211 HBITMAP hBitmap, hPrevBitmap;
212 BITMAP bm;
213 HDC hMemDC;
215 str[0]=0;
216 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) {
217 hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
218 SelectObject(lpdis->hDC, hBrush);
219 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
220 SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
221 (LPARAM)MAKE_SEGPTR(str));
222 TextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
223 str, strlen(str));
224 if (lpdis->itemState != 0) {
225 InvertRect(lpdis->hDC, &lpdis->rcItem);
227 return TRUE;
230 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) {
231 hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
232 SelectObject(lpdis->hDC, hBrush);
233 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
234 SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
235 (LPARAM)MAKE_SEGPTR(str));
237 hBitmap = hFolder;
238 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
239 TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
240 lpdis->rcItem.top, str, strlen(str));
241 hMemDC = CreateCompatibleDC(lpdis->hDC);
242 hPrevBitmap = SelectObject(hMemDC, hBitmap);
243 BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
244 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
245 SelectObject(hMemDC, hPrevBitmap);
246 DeleteDC(hMemDC);
247 if (lpdis->itemState != 0) {
248 InvertRect(lpdis->hDC, &lpdis->rcItem);
250 return TRUE;
252 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) {
253 hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
254 SelectObject(lpdis->hDC, hBrush);
255 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
256 SendMessage(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID,
257 (LPARAM)MAKE_SEGPTR(str));
258 switch(DRIVE_GetType( str[2] - 'a' ))
260 case TYPE_FLOPPY: hBitmap = hFloppy; break;
261 case TYPE_CDROM: hBitmap = hCDRom; break;
262 case TYPE_HD:
263 case TYPE_NETWORK:
264 default: hBitmap = hHDisk; break;
266 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
267 TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
268 lpdis->rcItem.top, str, strlen(str));
269 hMemDC = CreateCompatibleDC(lpdis->hDC);
270 hPrevBitmap = SelectObject(hMemDC, hBitmap);
271 BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
272 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
273 SelectObject(hMemDC, hPrevBitmap);
274 DeleteDC(hMemDC);
275 if (lpdis->itemState != 0) {
276 InvertRect(lpdis->hDC, &lpdis->rcItem);
278 return TRUE;
280 return FALSE;
283 /***********************************************************************
284 * FILEDLG_WMMeasureItem [internal]
286 static LONG FILEDLG_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
288 BITMAP bm;
289 LPMEASUREITEMSTRUCT lpmeasure;
291 GetObject(hFolder2, sizeof(BITMAP), (LPSTR)&bm);
292 lpmeasure = (LPMEASUREITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
293 lpmeasure->itemHeight = bm.bmHeight;
294 return TRUE;
297 /***********************************************************************
298 * FILEDLG_WMInitDialog [internal]
301 static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
303 int n;
304 int i;
305 LPOPENFILENAME lpofn;
306 char tmpstr[512];
307 LPSTR pstr;
308 SetWindowLong(hWnd, DWL_USER, lParam);
309 lpofn = (LPOPENFILENAME)lParam;
310 /* read custom filter information */
311 if (lpofn->lpstrCustomFilter)
313 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
314 dprintf_commdlg(stddeb,"lpstrCustomFilter = %p\n", pstr);
315 while(*pstr)
317 n = strlen(pstr);
318 strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
319 dprintf_commdlg(stddeb,"lpstrCustomFilter // add tmpstr='%s' ", tmpstr);
320 i = SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
321 pstr += n + 1;
322 n = strlen(pstr);
323 dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
324 SendDlgItemMessage(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
325 pstr += n + 1;
328 /* read filter information */
329 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
330 while(*pstr)
332 n = strlen(pstr);
333 strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
334 dprintf_commdlg(stddeb,"lpstrFilter // add tmpstr='%s' ", tmpstr);
335 i = SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
336 pstr += n + 1;
337 n = strlen(pstr);
338 dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
339 SendDlgItemMessage(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
340 pstr += n + 1;
342 /* set default filter */
343 if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
344 lpofn->nFilterIndex = 1;
345 SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL, lpofn->nFilterIndex - 1, 0);
346 strncpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
347 PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),511);
348 tmpstr[511]=0;
349 dprintf_commdlg(stddeb,"nFilterIndex = %ld // SetText of edt1 to '%s'\n",
350 lpofn->nFilterIndex, tmpstr);
351 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
352 /* get drive list */
353 *tmpstr = 0;
354 DlgDirListComboBox(hWnd, MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
355 /* read initial directory */
356 if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL)
358 strncpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 510);
359 tmpstr[510]=0;
360 if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\'
361 && tmpstr[strlen(tmpstr)-1] != ':')
362 strcat(tmpstr,"\\");
364 else
365 *tmpstr = 0;
366 if (!FILEDLG_ScanDir(hWnd, tmpstr))
367 fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
368 /* select current drive in combo 2 */
369 n = DRIVE_GetCurrentDrive();
370 SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n, 0);
371 if (!(lpofn->Flags & OFN_SHOWHELP))
372 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
373 if (lpofn->Flags & OFN_HIDEREADONLY)
374 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
375 return TRUE;
378 /***********************************************************************
379 * FILEDLG_WMCommand [internal]
381 static LRESULT FILEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
383 LONG lRet;
384 LPOPENFILENAME lpofn;
385 char tmpstr[512], tmpstr2[512];
386 LPSTR pstr, pstr2;
387 UINT control,notification;
389 /* Notifications are packaged differently in Win32 */
390 #ifdef WINELIB32
391 control = LOWORD(wParam);
392 notification = HIWORD(wParam);
393 #else
394 control = wParam;
395 notification = HIWORD(lParam);
396 #endif
398 lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
399 switch (control)
401 case lst1: /* file list */
402 FILEDLG_StripEditControl(hWnd);
403 if (notification == LBN_DBLCLK)
404 goto almost_ok;
405 lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
406 if (lRet == LB_ERR) return TRUE;
407 SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
408 (LPARAM)MAKE_SEGPTR(tmpstr));
409 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
410 return TRUE;
411 case lst2: /* directory list */
412 FILEDLG_StripEditControl(hWnd);
413 if (notification == LBN_DBLCLK)
415 lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0);
416 if (lRet == LB_ERR) return TRUE;
417 SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet,
418 (LPARAM)MAKE_SEGPTR(tmpstr));
419 if (tmpstr[0] == '[')
421 tmpstr[strlen(tmpstr) - 1] = 0;
422 strcpy(tmpstr,tmpstr+1);
424 strcat(tmpstr, "\\");
425 goto reset_scan;
427 return TRUE;
428 case cmb1: /* file type drop list */
429 if (notification == CBN_SELCHANGE)
431 *tmpstr = 0;
432 goto reset_scan;
434 return TRUE;
435 case cmb2: /* disk drop list */
436 FILEDLG_StripEditControl(hWnd);
437 lRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
438 if (lRet == LB_ERR) return 0;
439 SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, lRet, (LPARAM)MAKE_SEGPTR(tmpstr));
440 sprintf(tmpstr, "%c:", tmpstr[2]);
441 reset_scan:
442 lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
443 if (lRet == LB_ERR)
444 return TRUE;
445 pstr = (LPSTR)SendDlgItemMessage(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
446 dprintf_commdlg(stddeb,"Selected filter : %s\n", pstr);
447 strncpy(tmpstr2, pstr, 511); tmpstr2[511]=0;
448 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
449 FILEDLG_ScanDir(hWnd, tmpstr);
450 return TRUE;
451 case chx1:
452 return TRUE;
453 case pshHelp:
454 return TRUE;
455 case IDOK:
456 almost_ok:
457 SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(tmpstr));
458 pstr = strrchr(tmpstr, '\\');
459 if (pstr == NULL)
460 pstr = strrchr(tmpstr, ':');
461 if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
463 /* edit control contains wildcards */
464 if (pstr != NULL)
466 strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
467 *(pstr+1) = 0;
469 else
471 strcpy(tmpstr2, tmpstr);
472 *tmpstr=0;
474 dprintf_commdlg(stddeb,"commdlg: %s, %s\n", tmpstr, tmpstr2);
475 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
476 FILEDLG_ScanDir(hWnd, tmpstr);
477 return TRUE;
479 /* no wildcards, we might have a directory or a filename */
480 /* try appending a wildcard and reading the directory */
481 pstr2 = tmpstr + strlen(tmpstr);
482 if (pstr == NULL || *(pstr+1) != 0)
483 strcat(tmpstr, "\\");
484 lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
485 if (lRet == LB_ERR) return TRUE;
486 lpofn->nFilterIndex = lRet + 1;
487 dprintf_commdlg(stddeb,"commdlg: lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
488 strncpy(tmpstr2,
489 FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
490 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
491 lRet), 511);
492 tmpstr2[511]=0;
493 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
494 /* if ScanDir succeeds, we have changed the directory */
495 if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
496 /* if not, this must be a filename */
497 *pstr2 = 0;
498 if (pstr != NULL)
500 /* strip off the pathname */
501 *pstr = 0;
502 strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
503 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
504 /* Should we MessageBox() if this fails? */
505 if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
506 strcpy(tmpstr, tmpstr2);
508 else
509 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
510 ShowWindow(hWnd, SW_HIDE);
512 int drive = DRIVE_GetCurrentDrive();
513 tmpstr2[0] = 'A'+ drive;
514 tmpstr2[1] = ':';
515 tmpstr2[2] = '\\';
516 strncpy(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507); tmpstr2[510]=0;
517 if (strlen(tmpstr2) > 3)
518 strcat(tmpstr2, "\\");
519 strncat(tmpstr2, tmpstr, 511-strlen(tmpstr2)); tmpstr2[511]=0;
520 strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2);
522 lpofn->nFileOffset = 0;
523 lpofn->nFileExtension = 0;
524 while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
525 lpofn->nFileExtension++;
526 if (lpofn->nFileExtension == '\0')
527 lpofn->nFileExtension = 0;
528 else
529 lpofn->nFileExtension++;
530 if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL)
532 lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
533 SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
534 (LPARAM)MAKE_SEGPTR(tmpstr));
535 dprintf_commdlg(stddeb,"strcpy'ing '%s'\n",tmpstr); fflush(stdout);
536 strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
538 EndDialog(hWnd, TRUE);
539 return TRUE;
540 case IDCANCEL:
541 EndDialog(hWnd, FALSE);
542 return TRUE;
544 return FALSE;
548 /***********************************************************************
549 * FileOpenDlgProc (COMMDLG.6)
551 LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
553 switch (wMsg)
555 case WM_INITDIALOG:
556 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
557 case WM_MEASUREITEM:
558 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
559 case WM_DRAWITEM:
560 return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
561 case WM_COMMAND:
562 return FILEDLG_WMCommand(hWnd, wParam, lParam);
563 #if 0
564 case WM_CTLCOLOR:
565 SetBkColor((HDC)wParam, 0x00C0C0C0);
566 switch (HIWORD(lParam))
568 case CTLCOLOR_BTN:
569 SetTextColor((HDC)wParam, 0x00000000);
570 return hGRAYBrush;
571 case CTLCOLOR_STATIC:
572 SetTextColor((HDC)wParam, 0x00000000);
573 return hGRAYBrush;
575 break;
576 #endif
578 return FALSE;
582 /***********************************************************************
583 * FileSaveDlgProc (COMMDLG.7)
585 LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
587 switch (wMsg) {
588 case WM_INITDIALOG:
589 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
591 case WM_MEASUREITEM:
592 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
594 case WM_DRAWITEM:
595 return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
597 case WM_COMMAND:
598 return FILEDLG_WMCommand(hWnd, wParam, lParam);
602 case WM_CTLCOLOR:
603 SetBkColor((HDC)wParam, 0x00C0C0C0);
604 switch (HIWORD(lParam))
606 case CTLCOLOR_BTN:
607 SetTextColor((HDC)wParam, 0x00000000);
608 return hGRAYBrush;
609 case CTLCOLOR_STATIC:
610 SetTextColor((HDC)wParam, 0x00000000);
611 return hGRAYBrush;
613 return FALSE;
616 return FALSE;
620 /***********************************************************************
621 * ChooseColor (COMMDLG.5)
623 BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
625 HANDLE hInst, hDlgTmpl;
626 BOOL bRet;
628 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_COLOR );
629 hInst = WIN_GetWindowInstance( lpChCol->hwndOwner );
630 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChCol->hwndOwner,
631 GetWndProcEntry16("ColorDlgProc"),
632 (DWORD)lpChCol );
633 SYSRES_FreeResource( hDlgTmpl );
634 return bRet;
638 /***********************************************************************
639 * ColorDlgProc (COMMDLG.8)
641 LRESULT ColorDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
643 switch (wMsg)
645 case WM_INITDIALOG:
646 dprintf_commdlg(stddeb,"ColorDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
647 ShowWindow(hWnd, SW_SHOWNORMAL);
648 return (TRUE);
649 case WM_COMMAND:
650 switch (wParam)
652 case IDOK:
653 EndDialog(hWnd, TRUE);
654 return(TRUE);
655 case IDCANCEL:
656 EndDialog(hWnd, FALSE);
657 return(TRUE);
659 return(FALSE);
661 return FALSE;
665 /***********************************************************************
666 * FindTextDlg (COMMDLG.11)
668 BOOL FindText(LPFINDREPLACE lpFind)
670 HANDLE hInst, hDlgTmpl;
671 BOOL bRet;
672 SEGPTR ptr;
675 * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
676 * For now, only the standard dialog works.
679 * FIXME : We should do error checking on the lpFind structure here
680 * and make CommDlgExtendedError() return the error condition.
682 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_FIND_TEXT );
683 hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
684 if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1;
685 bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
686 GetWndProcEntry16("FindTextDlgProc"),
687 (DWORD)lpFind );
688 GlobalUnlock( hDlgTmpl );
689 SYSRES_FreeResource( hDlgTmpl );
690 return bRet;
694 /***********************************************************************
695 * ReplaceTextDlg (COMMDLG.12)
697 BOOL ReplaceText(LPFINDREPLACE lpFind)
699 HANDLE hInst, hDlgTmpl;
700 BOOL bRet;
701 SEGPTR ptr;
704 * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
705 * For now, only the standard dialog works.
708 * FIXME : We should do error checking on the lpFind structure here
709 * and make CommDlgExtendedError() return the error condition.
711 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_REPLACE_TEXT );
712 hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
713 if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1;
714 bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
715 GetWndProcEntry16("ReplaceTextDlgProc"),
716 (DWORD)lpFind );
717 GlobalUnlock( hDlgTmpl );
718 SYSRES_FreeResource( hDlgTmpl );
719 return bRet;
723 /***********************************************************************
724 * FINDDLG_WMInitDialog [internal]
726 static LRESULT FINDDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
728 LPFINDREPLACE lpfr;
730 SetWindowLong(hWnd, DWL_USER, lParam);
731 lpfr = (LPFINDREPLACE)lParam;
732 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
734 * FIXME : If the initial FindWhat string is empty, we should disable the
735 * FindNext (IDOK) button. Only after typing some text, the button should be
736 * enabled.
738 SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
739 CheckRadioButton(hWnd, rad1, rad2, (lpfr->Flags & FR_DOWN) ? rad2 : rad1);
740 if (lpfr->Flags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
741 EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
742 EnableWindow(GetDlgItem(hWnd, rad2), FALSE);
744 if (lpfr->Flags & FR_HIDEUPDOWN) {
745 ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE);
746 ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE);
747 ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE);
749 CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
750 if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
751 EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
752 if (lpfr->Flags & FR_HIDEWHOLEWORD)
753 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
754 CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
755 if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
756 EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
757 if (lpfr->Flags & FR_HIDEMATCHCASE)
758 ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
759 if (!(lpfr->Flags & FR_SHOWHELP)) {
760 EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
761 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
763 ShowWindow(hWnd, SW_SHOWNORMAL);
764 return TRUE;
768 /***********************************************************************
769 * FINDDLG_WMCommand [internal]
771 static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
773 LPFINDREPLACE lpfr;
774 int uFindReplaceMessage = RegisterWindowMessage(MAKE_SEGPTR(FINDMSGSTRING));
775 int uHelpMessage = RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
777 lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
778 switch (wParam) {
779 case IDOK:
780 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
781 if (IsDlgButtonChecked(hWnd, rad2))
782 lpfr->Flags |= FR_DOWN;
783 else lpfr->Flags &= ~FR_DOWN;
784 if (IsDlgButtonChecked(hWnd, chx1))
785 lpfr->Flags |= FR_WHOLEWORD;
786 else lpfr->Flags &= ~FR_WHOLEWORD;
787 if (IsDlgButtonChecked(hWnd, chx2))
788 lpfr->Flags |= FR_MATCHCASE;
789 else lpfr->Flags &= ~FR_MATCHCASE;
790 lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
791 lpfr->Flags |= FR_FINDNEXT;
792 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
793 return TRUE;
794 case IDCANCEL:
795 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
796 lpfr->Flags |= FR_DIALOGTERM;
797 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
798 DestroyWindow(hWnd);
799 return TRUE;
800 case pshHelp:
801 /* FIXME : should lpfr structure be passed as an argument ??? */
802 SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
803 return TRUE;
805 return FALSE;
809 /***********************************************************************
810 * FindTextDlgProc (COMMDLG.13)
812 LRESULT FindTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
814 switch (wMsg) {
815 case WM_INITDIALOG:
816 return FINDDLG_WMInitDialog(hWnd, wParam, lParam);
817 case WM_COMMAND:
818 return FINDDLG_WMCommand(hWnd, wParam, lParam);
820 return FALSE;
824 /***********************************************************************
825 * REPLACEDLG_WMInitDialog [internal]
827 static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
829 LPFINDREPLACE lpfr;
831 SetWindowLong(hWnd, DWL_USER, lParam);
832 lpfr = (LPFINDREPLACE)lParam;
833 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
835 * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
836 * Replace / ReplaceAll buttons. Only after typing some text, the buttons should be
837 * enabled.
839 SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
840 SetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith);
841 CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
842 if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
843 EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
844 if (lpfr->Flags & FR_HIDEWHOLEWORD)
845 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
846 CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
847 if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
848 EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
849 if (lpfr->Flags & FR_HIDEMATCHCASE)
850 ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
851 if (!(lpfr->Flags & FR_SHOWHELP)) {
852 EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
853 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
855 ShowWindow(hWnd, SW_SHOWNORMAL);
856 return TRUE;
860 /***********************************************************************
861 * REPLACEDLG_WMCommand [internal]
863 static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
865 LPFINDREPLACE lpfr;
866 int uFindReplaceMessage = RegisterWindowMessage(MAKE_SEGPTR(FINDMSGSTRING));
867 int uHelpMessage = RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
869 lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
870 switch (wParam) {
871 case IDOK:
872 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
873 GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
874 if (IsDlgButtonChecked(hWnd, chx1))
875 lpfr->Flags |= FR_WHOLEWORD;
876 else lpfr->Flags &= ~FR_WHOLEWORD;
877 if (IsDlgButtonChecked(hWnd, chx2))
878 lpfr->Flags |= FR_MATCHCASE;
879 else lpfr->Flags &= ~FR_MATCHCASE;
880 lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
881 lpfr->Flags |= FR_FINDNEXT;
882 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
883 return TRUE;
884 case IDCANCEL:
885 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
886 lpfr->Flags |= FR_DIALOGTERM;
887 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
888 DestroyWindow(hWnd);
889 return TRUE;
890 case psh1:
891 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
892 GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
893 if (IsDlgButtonChecked(hWnd, chx1))
894 lpfr->Flags |= FR_WHOLEWORD;
895 else lpfr->Flags &= ~FR_WHOLEWORD;
896 if (IsDlgButtonChecked(hWnd, chx2))
897 lpfr->Flags |= FR_MATCHCASE;
898 else lpfr->Flags &= ~FR_MATCHCASE;
899 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
900 lpfr->Flags |= FR_REPLACE;
901 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
902 return TRUE;
903 case psh2:
904 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
905 GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
906 if (IsDlgButtonChecked(hWnd, chx1))
907 lpfr->Flags |= FR_WHOLEWORD;
908 else lpfr->Flags &= ~FR_WHOLEWORD;
909 if (IsDlgButtonChecked(hWnd, chx2))
910 lpfr->Flags |= FR_MATCHCASE;
911 else lpfr->Flags &= ~FR_MATCHCASE;
912 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
913 lpfr->Flags |= FR_REPLACEALL;
914 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
915 return TRUE;
916 case pshHelp:
917 /* FIXME : should lpfr structure be passed as an argument ??? */
918 SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
919 return TRUE;
921 return FALSE;
925 /***********************************************************************
926 * ReplaceTextDlgProc (COMMDLG.14)
928 LRESULT ReplaceTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
930 switch (wMsg) {
931 case WM_INITDIALOG:
932 return REPLACEDLG_WMInitDialog(hWnd, wParam, lParam);
933 case WM_COMMAND:
934 return REPLACEDLG_WMCommand(hWnd, wParam, lParam);
936 return FALSE;
940 /***********************************************************************
941 * PrintDlg (COMMDLG.20)
943 BOOL PrintDlg(LPPRINTDLG lpPrint)
945 HANDLE hInst, hDlgTmpl;
946 BOOL bRet;
948 dprintf_commdlg(stddeb,"PrintDlg(%p) // Flags=%08lX\n", lpPrint, lpPrint->Flags );
950 if (lpPrint->Flags & PD_RETURNDEFAULT)
951 /* FIXME: should fill lpPrint->hDevMode and lpPrint->hDevNames here */
952 return TRUE;
954 if (lpPrint->Flags & PD_PRINTSETUP)
955 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT_SETUP );
956 else
957 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT );
959 hInst = WIN_GetWindowInstance( lpPrint->hwndOwner );
960 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpPrint->hwndOwner,
961 (lpPrint->Flags & PD_PRINTSETUP) ?
962 GetWndProcEntry16("PrintSetupDlgProc") :
963 GetWndProcEntry16("PrintDlgProc"),
964 (DWORD)lpPrint );
965 SYSRES_FreeResource( hDlgTmpl );
966 return bRet;
970 /***********************************************************************
971 * PrintDlgProc (COMMDLG.21)
973 LRESULT PrintDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
975 switch (wMsg)
977 case WM_INITDIALOG:
978 dprintf_commdlg(stddeb,"PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
979 ShowWindow(hWnd, SW_SHOWNORMAL);
980 return (TRUE);
981 case WM_COMMAND:
982 switch (wParam)
984 case IDOK:
985 EndDialog(hWnd, TRUE);
986 return(TRUE);
987 case IDCANCEL:
988 EndDialog(hWnd, FALSE);
989 return(TRUE);
991 return(FALSE);
993 return FALSE;
997 /***********************************************************************
998 * PrintSetupDlgProc (COMMDLG.22)
1000 LRESULT PrintSetupDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
1002 switch (wMsg)
1004 case WM_INITDIALOG:
1005 dprintf_commdlg(stddeb,"PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
1006 ShowWindow(hWnd, SW_SHOWNORMAL);
1007 return (TRUE);
1008 case WM_COMMAND:
1009 switch (wParam) {
1010 case IDOK:
1011 EndDialog(hWnd, TRUE);
1012 return(TRUE);
1013 case IDCANCEL:
1014 EndDialog(hWnd, FALSE);
1015 return(TRUE);
1017 return(FALSE);
1019 return FALSE;
1023 /***********************************************************************
1024 * CommDlgExtendedError (COMMDLG.26)
1026 DWORD CommDlgExtendedError(void)
1028 return CommDlgLastError;
1032 /***********************************************************************
1033 * GetFileTitle (COMMDLG.27)
1035 short GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf)
1037 int i, len;
1038 dprintf_commdlg(stddeb,"GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
1039 if (lpFile == NULL || lpTitle == NULL)
1040 return -1;
1041 len = strlen(lpFile);
1042 if (len == 0)
1043 return -1;
1044 if (strpbrk(lpFile, "*[]"))
1045 return -1;
1046 len--;
1047 if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
1048 return -1;
1049 for (i = len; i >= 0; i--)
1050 if (lpFile[i] == '/' || lpFile[i] == '\\' || lpFile[i] == ':')
1052 i++;
1053 break;
1055 dprintf_commdlg(stddeb,"\n---> '%s' ", &lpFile[i]);
1057 len = strlen(lpFile+i)+1;
1058 if (cbBuf < len)
1059 return len;
1061 strncpy(lpTitle, &lpFile[i], len);
1062 return 0;