Release 960414
[wine.git] / misc / commdlg.c
blob089019b2cd12b146b79d95649eb0a81310efaca3
1 /*
2 * COMMDLG functions
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "win.h"
12 #include "user.h"
13 #include "message.h"
14 #include "commdlg.h"
15 #include "dlgs.h"
16 #include "module.h"
17 #include "resource.h"
18 #include "dos_fs.h"
19 #include "drive.h"
20 #include "stackframe.h"
21 #include "stddebug.h"
22 #include "debug.h"
24 static DWORD CommDlgLastError = 0;
26 static HBITMAP hFolder = 0;
27 static HBITMAP hFolder2 = 0;
28 static HBITMAP hFloppy = 0;
29 static HBITMAP hHDisk = 0;
30 static HBITMAP hCDRom = 0;
32 /***********************************************************************
33 * FileDlg_Init [internal]
35 static BOOL FileDlg_Init()
37 static BOOL initialized = 0;
39 if (!initialized) {
40 if (!hFolder) hFolder = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER));
41 if (!hFolder2) hFolder2 = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER2));
42 if (!hFloppy) hFloppy = LoadBitmap(0, MAKEINTRESOURCE(OBM_FLOPPY));
43 if (!hHDisk) hHDisk = LoadBitmap(0, MAKEINTRESOURCE(OBM_HDISK));
44 if (!hCDRom) hCDRom = LoadBitmap(0, MAKEINTRESOURCE(OBM_CDROM));
45 if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
46 hHDisk == 0 || hCDRom == 0)
48 fprintf(stderr, "FileDlg_Init // Error loading bitmaps !");
49 return FALSE;
51 initialized = TRUE;
53 return TRUE;
56 /***********************************************************************
57 * GetOpenFileName (COMMDLG.1)
59 BOOL GetOpenFileName(LPOPENFILENAME lpofn)
61 HINSTANCE hInst;
62 HANDLE hDlgTmpl, hResInfo;
63 BOOL bRet;
65 if (!lpofn || !FileDlg_Init()) return FALSE;
67 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) hDlgTmpl = lpofn->hInstance;
68 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
70 if (!(hResInfo = FindResource( lpofn->hInstance,
71 lpofn->lpTemplateName, RT_DIALOG)))
73 CommDlgLastError = CDERR_FINDRESFAILURE;
74 return FALSE;
76 hDlgTmpl = LoadResource( lpofn->hInstance, hResInfo );
78 else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_OPEN_FILE );
79 if (!hDlgTmpl)
81 CommDlgLastError = CDERR_LOADRESFAILURE;
82 return FALSE;
85 hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
86 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner,
87 MODULE_GetWndProcEntry16("FileOpenDlgProc"),
88 (DWORD)lpofn );
90 if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
92 if (lpofn->Flags & OFN_ENABLETEMPLATE) FreeResource( hDlgTmpl );
93 else SYSRES_FreeResource( hDlgTmpl );
96 dprintf_commdlg(stddeb,"GetOpenFileName // return lpstrFile='%s' !\n",
97 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
98 return bRet;
102 /***********************************************************************
103 * GetSaveFileName (COMMDLG.2)
105 BOOL GetSaveFileName(LPOPENFILENAME lpofn)
107 HINSTANCE hInst;
108 HANDLE hDlgTmpl, hResInfo;
109 BOOL bRet;
111 if (!lpofn || !FileDlg_Init()) return FALSE;
113 if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) hDlgTmpl = lpofn->hInstance;
114 else if (lpofn->Flags & OFN_ENABLETEMPLATE)
116 hInst = lpofn->hInstance;
117 if (!(hResInfo = FindResource( lpofn->hInstance,
118 lpofn->lpTemplateName, RT_DIALOG )))
120 CommDlgLastError = CDERR_FINDRESFAILURE;
121 return FALSE;
123 hDlgTmpl = LoadResource( lpofn->hInstance, hResInfo );
125 else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_SAVE_FILE );
127 hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
128 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner,
129 MODULE_GetWndProcEntry16("FileSaveDlgProc"),
130 (DWORD)lpofn);
131 if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
133 if (lpofn->Flags & OFN_ENABLETEMPLATE) FreeResource( hDlgTmpl );
134 else SYSRES_FreeResource( hDlgTmpl );
137 dprintf_commdlg(stddeb, "GetSaveFileName // return lpstrFile='%s' !\n",
138 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
139 return bRet;
142 /***********************************************************************
143 * FILEDLG_StripEditControl [internal]
144 * Strip pathnames off the contents of the edit control.
146 static void FILEDLG_StripEditControl(HWND hwnd)
148 char temp[512], *cp;
150 SendDlgItemMessage(hwnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(temp));
151 cp = strrchr(temp, '\\');
152 if (cp != NULL) {
153 strcpy(temp, cp+1);
155 cp = strrchr(temp, ':');
156 if (cp != NULL) {
157 strcpy(temp, cp+1);
161 /***********************************************************************
162 * FILEDLG_ScanDir [internal]
164 static BOOL FILEDLG_ScanDir(HWND hWnd, LPSTR newPath)
166 char str[512],str2[512];
168 strncpy(str,newPath,511); str[511]=0;
169 SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(str2));
170 strncat(str,str2,511-strlen(str)); str[511]=0;
171 if (!DlgDirList(hWnd, MAKE_SEGPTR(str), lst1, 0, 0x0000)) return FALSE;
172 strcpy( str, "*.*" );
173 DlgDirList(hWnd, MAKE_SEGPTR(str), lst2, stc1, 0x8010);
174 return TRUE;
177 /***********************************************************************
178 * FILEDLG_GetFileType [internal]
181 static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
183 int n, i;
184 i = 0;
185 if (cfptr)
186 for ( ;(n = strlen(cfptr)) != 0; i++)
188 cfptr += n + 1;
189 if (i == index)
190 return cfptr;
191 cfptr += strlen(cfptr) + 1;
193 if (fptr)
194 for ( ;(n = strlen(fptr)) != 0; i++)
196 fptr += n + 1;
197 if (i == index)
198 return fptr;
199 fptr += strlen(fptr) + 1;
201 return NULL;
204 /***********************************************************************
205 * FILEDLG_WMDrawItem [internal]
207 static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
209 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
210 char str[512];
211 HBRUSH hBrush;
212 HBITMAP hBitmap, hPrevBitmap;
213 BITMAP bm;
214 HDC hMemDC;
216 str[0]=0;
217 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) {
218 hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
219 SelectObject(lpdis->hDC, hBrush);
220 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
221 SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
222 (LPARAM)MAKE_SEGPTR(str));
223 TextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
224 str, strlen(str));
225 if (lpdis->itemState != 0) {
226 InvertRect(lpdis->hDC, &lpdis->rcItem);
228 return TRUE;
231 if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) {
232 hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
233 SelectObject(lpdis->hDC, hBrush);
234 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
235 SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,
236 (LPARAM)MAKE_SEGPTR(str));
238 hBitmap = hFolder;
239 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
240 TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
241 lpdis->rcItem.top, str, strlen(str));
242 hMemDC = CreateCompatibleDC(lpdis->hDC);
243 hPrevBitmap = SelectObject(hMemDC, hBitmap);
244 BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
245 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
246 SelectObject(hMemDC, hPrevBitmap);
247 DeleteDC(hMemDC);
248 if (lpdis->itemState != 0) {
249 InvertRect(lpdis->hDC, &lpdis->rcItem);
251 return TRUE;
253 if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) {
254 hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
255 SelectObject(lpdis->hDC, hBrush);
256 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
257 SendMessage(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID,
258 (LPARAM)MAKE_SEGPTR(str));
259 switch(DRIVE_GetType( str[2] - 'a' ))
261 case TYPE_FLOPPY: hBitmap = hFloppy; break;
262 case TYPE_CDROM: hBitmap = hCDRom; break;
263 case TYPE_HD:
264 case TYPE_NETWORK:
265 default: hBitmap = hHDisk; break;
267 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
268 TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
269 lpdis->rcItem.top, str, strlen(str));
270 hMemDC = CreateCompatibleDC(lpdis->hDC);
271 hPrevBitmap = SelectObject(hMemDC, hBitmap);
272 BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
273 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
274 SelectObject(hMemDC, hPrevBitmap);
275 DeleteDC(hMemDC);
276 if (lpdis->itemState != 0) {
277 InvertRect(lpdis->hDC, &lpdis->rcItem);
279 return TRUE;
281 return FALSE;
284 /***********************************************************************
285 * FILEDLG_WMMeasureItem [internal]
287 static LONG FILEDLG_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
289 BITMAP bm;
290 LPMEASUREITEMSTRUCT lpmeasure;
292 GetObject(hFolder2, sizeof(BITMAP), (LPSTR)&bm);
293 lpmeasure = (LPMEASUREITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
294 lpmeasure->itemHeight = bm.bmHeight;
295 return TRUE;
298 /***********************************************************************
299 * FILEDLG_HookCallChk [internal]
301 static int FILEDLG_HookCallChk(LPOPENFILENAME lpofn)
303 if (lpofn)
304 if (lpofn->Flags & OFN_ENABLEHOOK)
305 if (lpofn->lpfnHook)
306 return 1;
307 return 0;
310 /***********************************************************************
311 * FILEDLG_WMInitDialog [internal]
314 static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
316 int n;
317 int i;
318 LPOPENFILENAME lpofn;
319 char tmpstr[512];
320 LPSTR pstr;
321 SetWindowLong(hWnd, DWL_USER, lParam);
322 lpofn = (LPOPENFILENAME)lParam;
323 /* read custom filter information */
324 if (lpofn->lpstrCustomFilter)
326 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
327 dprintf_commdlg(stddeb,"lpstrCustomFilter = %p\n", pstr);
328 while(*pstr)
330 n = strlen(pstr);
331 strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
332 dprintf_commdlg(stddeb,"lpstrCustomFilter // add tmpstr='%s' ", tmpstr);
333 i = SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
334 pstr += n + 1;
335 n = strlen(pstr);
336 dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
337 SendDlgItemMessage(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
338 pstr += n + 1;
341 /* read filter information */
342 pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
343 while(*pstr)
345 n = strlen(pstr);
346 strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
347 dprintf_commdlg(stddeb,"lpstrFilter // add tmpstr='%s' ", tmpstr);
348 i = SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
349 pstr += n + 1;
350 n = strlen(pstr);
351 dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
352 SendDlgItemMessage(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
353 pstr += n + 1;
355 /* set default filter */
356 if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
357 lpofn->nFilterIndex = 1;
358 SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL, lpofn->nFilterIndex - 1, 0);
359 strncpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
360 PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),511);
361 tmpstr[511]=0;
362 dprintf_commdlg(stddeb,"nFilterIndex = %ld // SetText of edt1 to '%s'\n",
363 lpofn->nFilterIndex, tmpstr);
364 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
365 /* get drive list */
366 *tmpstr = 0;
367 DlgDirListComboBox(hWnd, MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
368 /* read initial directory */
369 if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL)
371 strncpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 510);
372 tmpstr[510]=0;
373 if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\'
374 && tmpstr[strlen(tmpstr)-1] != ':')
375 strcat(tmpstr,"\\");
377 else
378 *tmpstr = 0;
379 if (!FILEDLG_ScanDir(hWnd, tmpstr))
380 fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
381 /* select current drive in combo 2 */
382 n = DRIVE_GetCurrentDrive();
383 SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n, 0);
384 if (!(lpofn->Flags & OFN_SHOWHELP))
385 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
386 if (lpofn->Flags & OFN_HIDEREADONLY)
387 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
388 if (FILEDLG_HookCallChk(lpofn))
389 return (BOOL)CallWindowProc(lpofn->lpfnHook,
390 hWnd, WM_INITDIALOG, wParam,(LPARAM)MAKE_SEGPTR(lpofn));
391 else
392 return TRUE;
395 /***********************************************************************
396 * FILEDLG_WMCommand [internal]
398 static LRESULT FILEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
400 LONG lRet;
401 LPOPENFILENAME lpofn;
402 OPENFILENAME ofn2;
403 char tmpstr[512], tmpstr2[512];
404 LPSTR pstr, pstr2;
405 UINT control,notification;
407 /* Notifications are packaged differently in Win32 */
408 #ifdef WINELIB32
409 control = LOWORD(wParam);
410 notification = HIWORD(wParam);
411 #else
412 control = wParam;
413 notification = HIWORD(lParam);
414 #endif
416 lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
417 switch (control)
419 case lst1: /* file list */
420 FILEDLG_StripEditControl(hWnd);
421 if (notification == LBN_DBLCLK)
422 goto almost_ok;
423 lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
424 if (lRet == LB_ERR) return TRUE;
425 SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
426 (LPARAM)MAKE_SEGPTR(tmpstr));
427 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
429 if (FILEDLG_HookCallChk(lpofn))
430 CallWindowProc (lpofn->lpfnHook, hWnd,
431 RegisterWindowMessage(MAKE_SEGPTR(LBSELCHSTRING)),
432 control, MAKELONG(lRet,CD_LBSELCHANGE));
433 /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */
434 return TRUE;
435 case lst2: /* directory list */
436 FILEDLG_StripEditControl(hWnd);
437 if (notification == LBN_DBLCLK)
439 lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0);
440 if (lRet == LB_ERR) return TRUE;
441 SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet,
442 (LPARAM)MAKE_SEGPTR(tmpstr));
443 if (tmpstr[0] == '[')
445 tmpstr[strlen(tmpstr) - 1] = 0;
446 strcpy(tmpstr,tmpstr+1);
448 strcat(tmpstr, "\\");
449 goto reset_scan;
451 return TRUE;
452 case cmb1: /* file type drop list */
453 if (notification == CBN_SELCHANGE)
455 *tmpstr = 0;
456 goto reset_scan;
458 return TRUE;
459 case cmb2: /* disk drop list */
460 FILEDLG_StripEditControl(hWnd);
461 lRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
462 if (lRet == LB_ERR) return 0;
463 SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, lRet, (LPARAM)MAKE_SEGPTR(tmpstr));
464 sprintf(tmpstr, "%c:", tmpstr[2]);
465 reset_scan:
466 lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
467 if (lRet == LB_ERR)
468 return TRUE;
469 pstr = (LPSTR)SendDlgItemMessage(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
470 dprintf_commdlg(stddeb,"Selected filter : %s\n", pstr);
471 strncpy(tmpstr2, pstr, 511); tmpstr2[511]=0;
472 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
473 FILEDLG_ScanDir(hWnd, tmpstr);
474 return TRUE;
475 case chx1:
476 return TRUE;
477 case pshHelp:
478 return TRUE;
479 case IDOK:
480 almost_ok:
481 ofn2=*lpofn; /* for later restoring */
482 SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(tmpstr));
483 pstr = strrchr(tmpstr, '\\');
484 if (pstr == NULL)
485 pstr = strrchr(tmpstr, ':');
486 if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
488 /* edit control contains wildcards */
489 if (pstr != NULL)
491 strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
492 *(pstr+1) = 0;
494 else
496 strcpy(tmpstr2, tmpstr);
497 *tmpstr=0;
499 dprintf_commdlg(stddeb,"commdlg: %s, %s\n", tmpstr, tmpstr2);
500 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
501 FILEDLG_ScanDir(hWnd, tmpstr);
502 return TRUE;
504 /* no wildcards, we might have a directory or a filename */
505 /* try appending a wildcard and reading the directory */
506 pstr2 = tmpstr + strlen(tmpstr);
507 if (pstr == NULL || *(pstr+1) != 0)
508 strcat(tmpstr, "\\");
509 lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
510 if (lRet == LB_ERR) return TRUE;
511 lpofn->nFilterIndex = lRet + 1;
512 dprintf_commdlg(stddeb,"commdlg: lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
513 strncpy(tmpstr2,
514 FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
515 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
516 lRet), 511);
517 tmpstr2[511]=0;
518 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
519 /* if ScanDir succeeds, we have changed the directory */
520 if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
521 /* if not, this must be a filename */
522 *pstr2 = 0;
523 if (pstr != NULL)
525 /* strip off the pathname */
526 *pstr = 0;
527 strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
528 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
529 /* Should we MessageBox() if this fails? */
530 if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
531 strcpy(tmpstr, tmpstr2);
533 else
534 SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
535 #if 0
536 ShowWindow(hWnd, SW_HIDE); /* this should not be necessary ?! (%%%) */
537 #endif
539 int drive = DRIVE_GetCurrentDrive();
540 tmpstr2[0] = 'A'+ drive;
541 tmpstr2[1] = ':';
542 tmpstr2[2] = '\\';
543 strncpy(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507); tmpstr2[510]=0;
544 if (strlen(tmpstr2) > 3)
545 strcat(tmpstr2, "\\");
546 strncat(tmpstr2, tmpstr, 511-strlen(tmpstr2)); tmpstr2[511]=0;
547 strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2);
549 lpofn->nFileOffset = 0;
550 lpofn->nFileExtension = 0;
551 while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
552 lpofn->nFileExtension++;
553 if (lpofn->nFileExtension == '\0')
554 lpofn->nFileExtension = 0;
555 else
556 lpofn->nFileExtension++;
557 if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL)
559 lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
560 SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
561 (LPARAM)MAKE_SEGPTR(tmpstr));
562 dprintf_commdlg(stddeb,"strcpy'ing '%s'\n",tmpstr); fflush(stdout);
563 strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
565 if (FILEDLG_HookCallChk(lpofn))
567 lRet= (BOOL)CallWindowProc (lpofn->lpfnHook,
568 hWnd, RegisterWindowMessage(MAKE_SEGPTR(FILEOKSTRING)),
569 0, (LPARAM)MAKE_SEGPTR(lpofn));
570 if (lRet)
572 *lpofn=ofn2; /* restore old state */
573 #if 0
574 ShowWindow(hWnd, SW_SHOW); /* only if above (%%%) SW_HIDE used */
575 #endif
576 break;
579 EndDialog(hWnd, TRUE);
580 return TRUE;
581 case IDCANCEL:
582 EndDialog(hWnd, FALSE);
583 return TRUE;
585 return FALSE;
589 /***********************************************************************
590 * FileOpenDlgProc (COMMDLG.6)
592 LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
594 LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
596 if (wMsg!=WM_INITDIALOG)
597 if (FILEDLG_HookCallChk(lpofn))
599 LRESULT lRet=(BOOL)CallWindowProc(lpofn->lpfnHook, hWnd, wMsg, wParam, lParam);
600 if (lRet)
601 return lRet; /* else continue message processing */
603 switch (wMsg)
605 case WM_INITDIALOG:
606 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
607 case WM_MEASUREITEM:
608 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
609 case WM_DRAWITEM:
610 return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
611 case WM_COMMAND:
612 return FILEDLG_WMCommand(hWnd, wParam, lParam);
613 #if 0
614 case WM_CTLCOLOR:
615 SetBkColor((HDC)wParam, 0x00C0C0C0);
616 switch (HIWORD(lParam))
618 case CTLCOLOR_BTN:
619 SetTextColor((HDC)wParam, 0x00000000);
620 return hGRAYBrush;
621 case CTLCOLOR_STATIC:
622 SetTextColor((HDC)wParam, 0x00000000);
623 return hGRAYBrush;
625 break;
626 #endif
628 return FALSE;
632 /***********************************************************************
633 * FileSaveDlgProc (COMMDLG.7)
635 LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
637 LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
639 if (wMsg!=WM_INITDIALOG)
640 if (FILEDLG_HookCallChk(lpofn))
642 LRESULT lRet=(BOOL)CallWindowProc(lpofn->lpfnHook, hWnd, wMsg, wParam, lParam);
643 if (lRet)
644 return lRet; /* else continue message processing */
646 switch (wMsg) {
647 case WM_INITDIALOG:
648 return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
650 case WM_MEASUREITEM:
651 return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
653 case WM_DRAWITEM:
654 return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
656 case WM_COMMAND:
657 return FILEDLG_WMCommand(hWnd, wParam, lParam);
661 case WM_CTLCOLOR:
662 SetBkColor((HDC)wParam, 0x00C0C0C0);
663 switch (HIWORD(lParam))
665 case CTLCOLOR_BTN:
666 SetTextColor((HDC)wParam, 0x00000000);
667 return hGRAYBrush;
668 case CTLCOLOR_STATIC:
669 SetTextColor((HDC)wParam, 0x00000000);
670 return hGRAYBrush;
672 return FALSE;
675 return FALSE;
679 /***********************************************************************
680 * ChooseColor (COMMDLG.5)
682 BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
684 HANDLE hInst, hDlgTmpl;
685 BOOL bRet;
687 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_COLOR );
688 hInst = WIN_GetWindowInstance( lpChCol->hwndOwner );
689 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChCol->hwndOwner,
690 MODULE_GetWndProcEntry16("ColorDlgProc"),
691 (DWORD)lpChCol );
692 SYSRES_FreeResource( hDlgTmpl );
693 return bRet;
697 /***********************************************************************
698 * FindTextDlg (COMMDLG.11)
700 BOOL FindText(LPFINDREPLACE lpFind)
702 HANDLE hInst, hDlgTmpl;
703 BOOL bRet;
704 SEGPTR ptr;
707 * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
708 * For now, only the standard dialog works.
711 * FIXME : We should do error checking on the lpFind structure here
712 * and make CommDlgExtendedError() return the error condition.
714 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_FIND_TEXT );
715 hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
716 if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1;
717 bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
718 MODULE_GetWndProcEntry16("FindTextDlgProc"),
719 (DWORD)lpFind );
720 GlobalUnlock( hDlgTmpl );
721 SYSRES_FreeResource( hDlgTmpl );
722 return bRet;
726 /***********************************************************************
727 * ReplaceTextDlg (COMMDLG.12)
729 BOOL ReplaceText(LPFINDREPLACE lpFind)
731 HANDLE hInst, hDlgTmpl;
732 BOOL bRet;
733 SEGPTR ptr;
736 * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
737 * For now, only the standard dialog works.
740 * FIXME : We should do error checking on the lpFind structure here
741 * and make CommDlgExtendedError() return the error condition.
743 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_REPLACE_TEXT );
744 hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
745 if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1;
746 bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
747 MODULE_GetWndProcEntry16("ReplaceTextDlgProc"),
748 (DWORD)lpFind );
749 GlobalUnlock( hDlgTmpl );
750 SYSRES_FreeResource( hDlgTmpl );
751 return bRet;
755 /***********************************************************************
756 * FINDDLG_WMInitDialog [internal]
758 static LRESULT FINDDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
760 LPFINDREPLACE lpfr;
762 SetWindowLong(hWnd, DWL_USER, lParam);
763 lpfr = (LPFINDREPLACE)lParam;
764 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
766 * FIXME : If the initial FindWhat string is empty, we should disable the
767 * FindNext (IDOK) button. Only after typing some text, the button should be
768 * enabled.
770 SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
771 CheckRadioButton(hWnd, rad1, rad2, (lpfr->Flags & FR_DOWN) ? rad2 : rad1);
772 if (lpfr->Flags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
773 EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
774 EnableWindow(GetDlgItem(hWnd, rad2), FALSE);
776 if (lpfr->Flags & FR_HIDEUPDOWN) {
777 ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE);
778 ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE);
779 ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE);
781 CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
782 if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
783 EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
784 if (lpfr->Flags & FR_HIDEWHOLEWORD)
785 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
786 CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
787 if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
788 EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
789 if (lpfr->Flags & FR_HIDEMATCHCASE)
790 ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
791 if (!(lpfr->Flags & FR_SHOWHELP)) {
792 EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
793 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
795 ShowWindow(hWnd, SW_SHOWNORMAL);
796 return TRUE;
800 /***********************************************************************
801 * FINDDLG_WMCommand [internal]
803 static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
805 LPFINDREPLACE lpfr;
806 int uFindReplaceMessage = RegisterWindowMessage(MAKE_SEGPTR(FINDMSGSTRING));
807 int uHelpMessage = RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
809 lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
810 switch (wParam) {
811 case IDOK:
812 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
813 if (IsDlgButtonChecked(hWnd, rad2))
814 lpfr->Flags |= FR_DOWN;
815 else lpfr->Flags &= ~FR_DOWN;
816 if (IsDlgButtonChecked(hWnd, chx1))
817 lpfr->Flags |= FR_WHOLEWORD;
818 else lpfr->Flags &= ~FR_WHOLEWORD;
819 if (IsDlgButtonChecked(hWnd, chx2))
820 lpfr->Flags |= FR_MATCHCASE;
821 else lpfr->Flags &= ~FR_MATCHCASE;
822 lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
823 lpfr->Flags |= FR_FINDNEXT;
824 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
825 return TRUE;
826 case IDCANCEL:
827 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
828 lpfr->Flags |= FR_DIALOGTERM;
829 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
830 DestroyWindow(hWnd);
831 return TRUE;
832 case pshHelp:
833 /* FIXME : should lpfr structure be passed as an argument ??? */
834 SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
835 return TRUE;
837 return FALSE;
841 /***********************************************************************
842 * FindTextDlgProc (COMMDLG.13)
844 LRESULT FindTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
846 switch (wMsg) {
847 case WM_INITDIALOG:
848 return FINDDLG_WMInitDialog(hWnd, wParam, lParam);
849 case WM_COMMAND:
850 return FINDDLG_WMCommand(hWnd, wParam, lParam);
852 return FALSE;
856 /***********************************************************************
857 * REPLACEDLG_WMInitDialog [internal]
859 static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
861 LPFINDREPLACE lpfr;
863 SetWindowLong(hWnd, DWL_USER, lParam);
864 lpfr = (LPFINDREPLACE)lParam;
865 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
867 * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
868 * Replace / ReplaceAll buttons. Only after typing some text, the buttons should be
869 * enabled.
871 SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
872 SetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith);
873 CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
874 if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
875 EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
876 if (lpfr->Flags & FR_HIDEWHOLEWORD)
877 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
878 CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
879 if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
880 EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
881 if (lpfr->Flags & FR_HIDEMATCHCASE)
882 ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
883 if (!(lpfr->Flags & FR_SHOWHELP)) {
884 EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
885 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
887 ShowWindow(hWnd, SW_SHOWNORMAL);
888 return TRUE;
892 /***********************************************************************
893 * REPLACEDLG_WMCommand [internal]
895 static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
897 LPFINDREPLACE lpfr;
898 int uFindReplaceMessage = RegisterWindowMessage(MAKE_SEGPTR(FINDMSGSTRING));
899 int uHelpMessage = RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
901 lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
902 switch (wParam) {
903 case IDOK:
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_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
913 lpfr->Flags |= FR_FINDNEXT;
914 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
915 return TRUE;
916 case IDCANCEL:
917 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
918 lpfr->Flags |= FR_DIALOGTERM;
919 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
920 DestroyWindow(hWnd);
921 return TRUE;
922 case psh1:
923 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
924 GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
925 if (IsDlgButtonChecked(hWnd, chx1))
926 lpfr->Flags |= FR_WHOLEWORD;
927 else lpfr->Flags &= ~FR_WHOLEWORD;
928 if (IsDlgButtonChecked(hWnd, chx2))
929 lpfr->Flags |= FR_MATCHCASE;
930 else lpfr->Flags &= ~FR_MATCHCASE;
931 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
932 lpfr->Flags |= FR_REPLACE;
933 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
934 return TRUE;
935 case psh2:
936 GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
937 GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
938 if (IsDlgButtonChecked(hWnd, chx1))
939 lpfr->Flags |= FR_WHOLEWORD;
940 else lpfr->Flags &= ~FR_WHOLEWORD;
941 if (IsDlgButtonChecked(hWnd, chx2))
942 lpfr->Flags |= FR_MATCHCASE;
943 else lpfr->Flags &= ~FR_MATCHCASE;
944 lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
945 lpfr->Flags |= FR_REPLACEALL;
946 SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
947 return TRUE;
948 case pshHelp:
949 /* FIXME : should lpfr structure be passed as an argument ??? */
950 SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
951 return TRUE;
953 return FALSE;
957 /***********************************************************************
958 * ReplaceTextDlgProc (COMMDLG.14)
960 LRESULT ReplaceTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
962 switch (wMsg) {
963 case WM_INITDIALOG:
964 return REPLACEDLG_WMInitDialog(hWnd, wParam, lParam);
965 case WM_COMMAND:
966 return REPLACEDLG_WMCommand(hWnd, wParam, lParam);
968 return FALSE;
972 /***********************************************************************
973 * PrintDlg (COMMDLG.20)
975 BOOL PrintDlg(LPPRINTDLG lpPrint)
977 HANDLE hInst, hDlgTmpl;
978 BOOL bRet;
980 dprintf_commdlg(stddeb,"PrintDlg(%p) // Flags=%08lX\n", lpPrint, lpPrint->Flags );
982 if (lpPrint->Flags & PD_RETURNDEFAULT)
983 /* FIXME: should fill lpPrint->hDevMode and lpPrint->hDevNames here */
984 return TRUE;
986 if (lpPrint->Flags & PD_PRINTSETUP)
987 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT_SETUP );
988 else
989 hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT );
991 hInst = WIN_GetWindowInstance( lpPrint->hwndOwner );
992 bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpPrint->hwndOwner,
993 (lpPrint->Flags & PD_PRINTSETUP) ?
994 MODULE_GetWndProcEntry16("PrintSetupDlgProc") :
995 MODULE_GetWndProcEntry16("PrintDlgProc"),
996 (DWORD)lpPrint );
997 SYSRES_FreeResource( hDlgTmpl );
998 return bRet;
1002 /***********************************************************************
1003 * PrintDlgProc (COMMDLG.21)
1005 LRESULT PrintDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
1007 switch (wMsg)
1009 case WM_INITDIALOG:
1010 dprintf_commdlg(stddeb,"PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
1011 ShowWindow(hWnd, SW_SHOWNORMAL);
1012 return (TRUE);
1013 case WM_COMMAND:
1014 switch (wParam)
1016 case IDOK:
1017 EndDialog(hWnd, TRUE);
1018 return(TRUE);
1019 case IDCANCEL:
1020 EndDialog(hWnd, FALSE);
1021 return(TRUE);
1023 return(FALSE);
1025 return FALSE;
1029 /***********************************************************************
1030 * PrintSetupDlgProc (COMMDLG.22)
1032 LRESULT PrintSetupDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
1034 switch (wMsg)
1036 case WM_INITDIALOG:
1037 dprintf_commdlg(stddeb,"PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
1038 ShowWindow(hWnd, SW_SHOWNORMAL);
1039 return (TRUE);
1040 case WM_COMMAND:
1041 switch (wParam) {
1042 case IDOK:
1043 EndDialog(hWnd, TRUE);
1044 return(TRUE);
1045 case IDCANCEL:
1046 EndDialog(hWnd, FALSE);
1047 return(TRUE);
1049 return(FALSE);
1051 return FALSE;
1055 /***********************************************************************
1056 * CommDlgExtendedError (COMMDLG.26)
1058 DWORD CommDlgExtendedError(void)
1060 return CommDlgLastError;
1064 /***********************************************************************
1065 * GetFileTitle (COMMDLG.27)
1067 short GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf)
1069 int i, len;
1070 dprintf_commdlg(stddeb,"GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
1071 if (lpFile == NULL || lpTitle == NULL)
1072 return -1;
1073 len = strlen(lpFile);
1074 if (len == 0)
1075 return -1;
1076 if (strpbrk(lpFile, "*[]"))
1077 return -1;
1078 len--;
1079 if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
1080 return -1;
1081 for (i = len; i >= 0; i--)
1082 if (lpFile[i] == '/' || lpFile[i] == '\\' || lpFile[i] == ':')
1084 i++;
1085 break;
1087 dprintf_commdlg(stddeb,"\n---> '%s' ", &lpFile[i]);
1089 len = strlen(lpFile+i)+1;
1090 if (cbBuf < len)
1091 return len;
1093 strncpy(lpTitle, &lpFile[i], len);
1094 return 0;
1098 /* --------------------------- Choose Color Dialog ------------------------------ */
1100 static const COLORREF predefcolors[6][8]=
1102 { 0x008080FFL, 0x0080FFFFL, 0x0080FF80L, 0x0080FF00L,
1103 0x00FFFF80L, 0x00FF8000L, 0x00C080FFL, 0x00FF80FFL },
1104 { 0x000000FFL, 0x0000FFFFL, 0x0000FF80L, 0x0040FF00L,
1105 0x00FFFF00L, 0x00C08000L, 0x00C08080L, 0x00FF00FFL },
1107 { 0x00404080L, 0x004080FFL, 0x0000FF00L, 0x00808000L,
1108 0x00804000L, 0x00FF8080L, 0x00400080L, 0x008000FFL },
1109 { 0x00000080L, 0x000080FFL, 0x00008000L, 0x00408000L,
1110 0x00FF0000L, 0x00A00000L, 0x00800080L, 0x00FF0080L },
1112 { 0x00000040L, 0x00004080L, 0x00004000L, 0x00404000L,
1113 0x00800000L, 0x00400000L, 0x00400040L, 0x00800040L },
1114 { 0x00000000L, 0x00008080L, 0x00408080L, 0x00808080L,
1115 0x00808040L, 0x00C0C0C0L, 0x00400040L, 0x00FFFFFFL },
1118 struct CCPRIVATE
1120 LPCHOOSECOLOR lpcc; /* points to public known data structure */
1121 int nextuserdef; /* next free place in user defined color array */
1122 HDC hdcMem; /* color graph used for BitBlt() */
1123 RECT fullsize; /* original dialog window size */
1124 UINT msetrgb; /* # of SETRGBSTRING message (today not used) */
1125 RECT old3angle; /* last position of l-marker */
1126 RECT oldcross; /* last position of color/satuation marker */
1127 int h;
1128 int s;
1129 int l; /* for temporary storing of hue,sat,lum */
1132 /***********************************************************************
1133 * CC_HSLtoRGB [internal]
1135 static int CC_HSLtoRGB(char c,int hue,int sat,int lum)
1137 int res=0,maxrgb;
1139 /* hue */
1140 switch(c)
1142 case 'R':if (hue>80) hue-=80; else hue+=160; break;
1143 case 'G':if (hue>160) hue-=160; else hue+=80; break;
1144 case 'B':break;
1147 /* l below 120 */
1148 maxrgb=(256*MIN(120,lum))/120; /* 0 .. 256 */
1149 if (hue< 80)
1150 res=0;
1151 else
1152 if (hue< 120)
1154 res=(hue-80)* maxrgb; /* 0...10240 */
1155 res/=40; /* 0...256 */
1157 else
1158 if (hue< 200)
1159 res=maxrgb;
1160 else
1162 res=(240-hue)* maxrgb;
1163 res/=40;
1165 res=res-maxrgb/2; /* -128...128 */
1167 /* saturation */
1168 res=maxrgb/2 + (sat*res) /240; /* 0..256 */
1170 /* lum above 120 */
1171 if (lum>120 && res<256)
1172 res+=((lum-120) * (256-res))/120;
1174 return MIN(res,255);
1177 /***********************************************************************
1178 * CC_RGBtoHSL [internal]
1180 static int CC_RGBtoHSL(char c,int r,int g,int b)
1182 WORD maxi,mini,mmsum,mmdif,result=0;
1183 int iresult=0;
1185 maxi=MAX(r,b);
1186 maxi=MAX(maxi,g);
1187 mini=MIN(r,b);
1188 mini=MIN(mini,g);
1190 mmsum=maxi+mini;
1191 mmdif=maxi-mini;
1193 switch(c)
1195 /* lum */
1196 case 'L':mmsum*=120; /* 0...61200=(255+255)*120 */
1197 result=mmsum/255; /* 0...240 */
1198 break;
1199 /* saturation */
1200 case 'S':if (!mmsum)
1201 result=0;
1202 else
1203 if (!mini || maxi==255)
1204 result=240;
1205 else
1207 result=mmdif*240; /* 0...61200=255*240 */
1208 result/= (mmsum>255 ? mmsum=510-mmsum : mmsum); /* 0..255 */
1210 break;
1211 /* hue */
1212 case 'H':if (!mmdif)
1213 result=160;
1214 else
1216 if (maxi==r)
1218 iresult=40*(g-b); /* -10200 ... 10200 */
1219 iresult/=(int)mmdif; /* -40 .. 40 */
1220 if (iresult<0)
1221 iresult+=240; /* 0..40 and 200..240 */
1223 else
1224 if (maxi==g)
1226 iresult=40*(b-r);
1227 iresult/=(int)mmdif;
1228 iresult+=80; /* 40 .. 120 */
1230 else
1231 if (maxi==b)
1233 iresult=40*(r-g);
1234 iresult/=(int)mmdif;
1235 iresult+=160; /* 120 .. 200 */
1237 result=iresult;
1239 break;
1241 return result; /* is this integer arithmetic precise enough ? */
1244 #define DISTANCE 4
1246 /***********************************************************************
1247 * CC_MouseCheckPredefColorArray [internal]
1249 static int CC_MouseCheckPredefColorArray(HWND hDlg,int dlgitem,int rows,int cols,
1250 LPARAM lParam,COLORREF *cr)
1252 HWND hwnd;
1253 POINT point;
1254 RECT rect;
1255 int dx,dy,x,y;
1257 point.x=LOWORD(lParam);
1258 point.y=HIWORD(lParam);
1259 ClientToScreen(hDlg,&point);
1261 hwnd=GetDlgItem(hDlg,dlgitem);
1262 GetWindowRect(hwnd,&rect);
1263 if (PtInRect(&rect,point))
1265 dx=(rect.right-rect.left)/cols;
1266 dy=(rect.bottom-rect.top)/rows;
1267 ScreenToClient(hwnd,&point);
1269 if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
1271 x=point.x/dx;
1272 y=point.y/dy;
1273 *cr=predefcolors[y][x];
1274 /* FIXME: Draw_a_Focus_Rect() */
1275 return 1;
1278 return 0;
1281 /***********************************************************************
1282 * CC_MouseCheckUserColorArray [internal]
1284 static int CC_MouseCheckUserColorArray(HWND hDlg,int dlgitem,int rows,int cols,
1285 LPARAM lParam,COLORREF *cr,COLORREF*crarr)
1287 HWND hwnd;
1288 POINT point;
1289 RECT rect;
1290 int dx,dy,x,y;
1292 point.x=LOWORD(lParam);
1293 point.y=HIWORD(lParam);
1294 ClientToScreen(hDlg,&point);
1296 hwnd=GetDlgItem(hDlg,dlgitem);
1297 GetWindowRect(hwnd,&rect);
1298 if (PtInRect(&rect,point))
1300 dx=(rect.right-rect.left)/cols;
1301 dy=(rect.bottom-rect.top)/rows;
1302 ScreenToClient(hwnd,&point);
1304 if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
1306 x=point.x/dx;
1307 y=point.y/dy;
1308 *cr=crarr[x+cols*y];
1309 /* FIXME: Draw_a_Focus_Rect() */
1310 return 1;
1313 return 0;
1316 #define MAXVERT 240
1317 #define MAXHORI 239
1319 /* 240 ^...... ^^ 240
1320 | . ||
1321 SAT | . || LUM
1322 | . ||
1323 +-----> 239 ----
1326 /***********************************************************************
1327 * CC_MouseCheckColorGraph [internal]
1329 static int CC_MouseCheckColorGraph(HWND hDlg,int dlgitem,int *hori,int *vert,LPARAM lParam)
1331 HWND hwnd;
1332 POINT point;
1333 RECT rect;
1334 long x,y;
1336 point.x=LOWORD(lParam);
1337 point.y=HIWORD(lParam);
1338 ClientToScreen(hDlg,&point);
1339 hwnd=GetDlgItem(hDlg,dlgitem);
1340 GetWindowRect(hwnd,&rect);
1341 if (PtInRect(&rect,point))
1343 GetClientRect(hwnd,&rect);
1344 ScreenToClient(hwnd,&point);
1346 x=(long)point.x*MAXHORI;
1347 x/=rect.right;
1348 y=(long)(rect.bottom-point.y)*MAXVERT;
1349 y/=rect.bottom;
1351 if (hori)
1352 *hori=x;
1353 if (vert)
1354 *vert=y;
1355 return 1;
1357 else
1358 return 0;
1360 /***********************************************************************
1361 * CC_MouseCheckResultWindow [internal]
1363 static int CC_MouseCheckResultWindow(HWND hDlg,LPARAM lParam)
1365 HWND hwnd;
1366 POINT point;
1367 RECT rect;
1368 point.x=LOWORD(lParam);
1369 point.y=HIWORD(lParam);
1370 ClientToScreen(hDlg,&point);
1371 hwnd=GetDlgItem(hDlg,0x2c5);
1372 GetWindowRect(hwnd,&rect);
1373 if (PtInRect(&rect,point))
1375 PostMessage(hDlg,WM_COMMAND,0x2c9,0);
1376 return 1;
1378 return 0;
1381 /***********************************************************************
1382 * CC_CheckDigitsInEdit [internal]
1384 static int CC_CheckDigitsInEdit(HWND hwnd,int maxval)
1386 int i,k,m,result,value;
1387 long editpos;
1388 char buffer[30];
1389 GetWindowText(hwnd,buffer,30-1);
1390 m=lstrlen(buffer);
1391 result=0;
1393 for (i=0;i<m;i++)
1394 if (buffer[i]<'0' || buffer[i]>'9')
1396 for (k=i+1;k<=m;k++) /* delete bad character */
1398 buffer[i]=buffer[k];
1399 m--;
1401 buffer[m]=0;
1402 result=1;
1405 value=atoi(buffer);
1406 if (value>maxval) /* build a new string */
1408 sprintf(buffer,"%d",maxval);
1409 result=2;
1411 if (result)
1413 editpos=SendMessage(hwnd,EM_GETSEL,0,0);
1414 SetWindowText(hwnd,buffer);
1415 SendMessage(hwnd,EM_SETSEL,0,editpos);
1417 return value;
1422 /***********************************************************************
1423 * CC_PaintSelectedColor [internal]
1425 static void CC_PaintSelectedColor(HWND hDlg,COLORREF cr)
1427 RECT rect;
1428 HDC hdc;
1429 HBRUSH hBrush;
1430 HWND hwnd=GetDlgItem(hDlg,0x2c5);
1431 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
1433 hdc=GetDC(hwnd);
1434 GetClientRect (hwnd, &rect) ;
1435 hBrush = CreateSolidBrush(cr);
1436 if (hBrush)
1438 hBrush = SelectObject (hdc, hBrush) ;
1439 Rectangle (hdc, rect.left,rect.top,rect.right/2,rect.bottom);
1440 DeleteObject (SelectObject (hdc,hBrush)) ;
1441 hBrush=CreateSolidBrush(GetNearestColor(hdc,cr));
1442 if (hBrush)
1444 hBrush= SelectObject (hdc, hBrush) ;
1445 Rectangle (hdc, rect.right/2-1,rect.top,rect.right,rect.bottom);
1446 DeleteObject (SelectObject (hdc, hBrush)) ;
1449 ReleaseDC(hwnd,hdc);
1453 /***********************************************************************
1454 * CC_PaintTriangle [internal]
1456 static void CC_PaintTriangle(HWND hDlg,int y)
1458 HDC hDC;
1459 long temp;
1460 int w=GetDialogBaseUnits();
1461 POINT points[3];
1462 int height;
1463 int oben;
1464 RECT rect;
1465 HWND hwnd=GetDlgItem(hDlg,0x2be);
1466 struct CCPRIVATE *lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
1468 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
1470 GetClientRect(hwnd,&rect);
1471 height=rect.bottom;
1472 hDC=GetDC(hDlg);
1474 points[0].y=rect.top;
1475 points[0].x=rect.right; /* | /| */
1476 ClientToScreen(hwnd,points); /* | / | */
1477 ScreenToClient(hDlg,points); /* |< | */
1478 oben=points[0].y; /* | \ | */
1479 /* | \| */
1480 temp=(long)height*(long)y;
1481 points[0].y=oben+height -temp/(long)MAXVERT;
1482 points[1].y=points[0].y+w;
1483 points[2].y=points[0].y-w;
1484 points[2].x=points[1].x=points[0].x + w;
1486 if (lpp->old3angle.left)
1487 FillRect(hDC,&lpp->old3angle,GetStockObject(WHITE_BRUSH));
1488 lpp->old3angle.left =points[0].x;
1489 lpp->old3angle.right =points[1].x+1;
1490 lpp->old3angle.top =points[2].y-1;
1491 lpp->old3angle.bottom=points[1].y+1;
1492 Polygon(hDC,points,3);
1493 ReleaseDC(hDlg,hDC);
1498 /***********************************************************************
1499 * CC_PaintCross [internal]
1501 static void CC_PaintCross(HWND hDlg,int x,int y)
1503 HDC hDC;
1504 long temp;
1505 int w=GetDialogBaseUnits();
1506 HWND hwnd=GetDlgItem(hDlg,0x2c6);
1507 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
1508 RECT rect;
1509 POINT point;
1510 HPEN hPen;
1512 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
1514 GetClientRect(hwnd,&rect);
1516 hDC=GetDC(hwnd);
1517 hPen=CreatePen(PS_SOLID,2,0);
1518 hPen=SelectObject(hDC,hPen);
1520 temp=(long)rect.right*(long)x;
1521 point.x=temp/(long)MAXHORI;
1522 temp=(long)rect.bottom*(long)y;
1523 point.y=rect.bottom-temp/(long)MAXVERT;
1525 if (lpp->oldcross.left!=lpp->oldcross.right)
1526 BitBlt(hDC,lpp->oldcross.left,lpp->oldcross.top,
1527 lpp->oldcross.right-lpp->oldcross.left,
1528 lpp->oldcross.bottom-lpp->oldcross.top,
1529 lpp->hdcMem,lpp->oldcross.left,lpp->oldcross.top,SRCCOPY);
1531 lpp->oldcross.left =point.x-w-1;
1532 lpp->oldcross.right =point.x+w+1;
1533 lpp->oldcross.top =point.y-w-1;
1534 lpp->oldcross.bottom=point.y+w+1;
1536 if (point.y+w/2<rect.bottom-3) /* perhaps better via SelectClipRgn() */
1538 MoveTo(hDC,point.x,MIN(point.y+w/2,rect.bottom));
1539 LineTo(hDC,point.x,MIN(point.y+w,rect.bottom-2));
1541 if (point.y-w/2>3)
1543 MoveTo(hDC,point.x,point.y-w/2);
1544 LineTo(hDC,point.x,MAX(2,point.y-w ));
1546 if (point.x+w/2<rect.right-3)
1548 MoveTo(hDC,point.x+w/2,point.y);
1549 LineTo(hDC,MIN(rect.right,point.x+w), point.y);
1551 if ((point.x-w/2)>3)
1553 MoveTo(hDC,point.x-w/2,point.y);
1554 LineTo(hDC,MAX(2,point.x-w), point.y);
1557 DeleteObject(SelectObject(hDC,hPen));
1558 ReleaseDC(hwnd,hDC);
1563 #define XSTEPS 36
1564 #define YSTEPS 48
1567 /***********************************************************************
1568 * CC_PrepareColorGraph [internal]
1570 static void CC_PrepareColorGraph(HWND hDlg)
1572 int sdif,hdif,xdif,ydif,r,g,b,hue,sat;
1573 HWND hwnd=GetDlgItem(hDlg,0x2c6);
1574 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
1575 HBRUSH hbrush;
1576 HDC hdc ;
1577 RECT rect,client;
1578 HBITMAP hbmMem;
1579 HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT));
1581 GetClientRect(hwnd,&client);
1582 hdc=GetDC(hwnd);
1583 lpp->hdcMem = CreateCompatibleDC(hdc);
1584 hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
1585 SelectObject(lpp->hdcMem,hbmMem);
1587 xdif=client.right /XSTEPS;
1588 ydif=client.bottom/YSTEPS+1;
1589 hdif=239/XSTEPS;
1590 sdif=240/YSTEPS;
1591 for(rect.left=hue=0;hue<239+hdif;hue+=hdif)
1593 rect.right=rect.left+xdif;
1594 rect.bottom=client.bottom;
1595 for(sat=0;sat<240+sdif;sat+=sdif)
1597 rect.top=rect.bottom-ydif;
1598 r=CC_HSLtoRGB('R',hue,sat,120);
1599 g=CC_HSLtoRGB('G',hue,sat,120);
1600 b=CC_HSLtoRGB('B',hue,sat,120);
1601 hbrush=CreateSolidBrush(RGB(r,g,b));
1602 FillRect(lpp->hdcMem,&rect,hbrush);
1603 DeleteObject(hbrush);
1604 rect.bottom=rect.top;
1606 rect.left=rect.right;
1608 ReleaseDC(hwnd,hdc);
1609 SetCursor(hcursor);
1610 /* FIXME perhaps we should do it only ONCE for all, like hCDRom,.... ? */
1613 /***********************************************************************
1614 * CC_PaintColorGraph [internal]
1616 static void CC_PaintColorGraph(HWND hDlg)
1618 HWND hwnd=GetDlgItem(hDlg,0x2c6);
1619 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
1620 HDC hDC;
1621 RECT rect;
1622 if (IsWindowVisible(hwnd)) /* if full size */
1624 if (!lpp->hdcMem)
1625 CC_PrepareColorGraph(hDlg); /* should not be necessary */
1627 hDC=GetDC(hwnd);
1628 GetClientRect(hwnd,&rect);
1629 if (lpp->hdcMem)
1630 BitBlt(hDC,0,0,rect.right,rect.bottom,lpp->hdcMem,0,0,SRCCOPY);
1631 else
1632 fprintf(stderr,"choose color: hdcMem is not defined\n");
1633 ReleaseDC(hwnd,hDC);
1636 /***********************************************************************
1637 * CC_PaintLumBar [internal]
1639 static void CC_PaintLumBar(HWND hDlg,int hue,int sat)
1641 HWND hwnd=GetDlgItem(hDlg,0x2be);
1642 RECT rect,client;
1643 int lum,ldif,ydif,r,g,b;
1644 HBRUSH hbrush;
1645 HDC hDC;
1647 if (IsWindowVisible(hwnd))
1649 hDC=GetDC(hwnd);
1650 GetClientRect(hwnd,&client);
1651 rect=client;
1653 ldif=240/YSTEPS;
1654 ydif=client.bottom/YSTEPS+1;
1655 for(lum=0;lum<240+ldif;lum+=ldif)
1657 rect.top=MAX(0,rect.bottom-ydif);
1658 r=CC_HSLtoRGB('R',hue,sat,lum);
1659 g=CC_HSLtoRGB('G',hue,sat,lum);
1660 b=CC_HSLtoRGB('B',hue,sat,lum);
1661 hbrush=CreateSolidBrush(RGB(r,g,b));
1662 FillRect(hDC,&rect,hbrush);
1663 DeleteObject(hbrush);
1664 rect.bottom=rect.top;
1666 GetClientRect(hwnd,&rect);
1667 FrameRect(hDC,&rect,GetStockObject(BLACK_BRUSH));
1668 ReleaseDC(hwnd,hDC);
1672 /***********************************************************************
1673 * CC_EditSetRGB [internal]
1675 static void CC_EditSetRGB(HWND hDlg,COLORREF cr)
1677 char buffer[10];
1678 int r=GetRValue(cr);
1679 int g=GetGValue(cr);
1680 int b=GetBValue(cr);
1681 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
1683 sprintf(buffer,"%d",r);
1684 SetWindowText(GetDlgItem(hDlg,0x2c2),buffer);
1685 sprintf(buffer,"%d",g);
1686 SetWindowText(GetDlgItem(hDlg,0x2c3),buffer);
1687 sprintf(buffer,"%d",b);
1688 SetWindowText(GetDlgItem(hDlg,0x2c4),buffer);
1692 /***********************************************************************
1693 * CC_EditSetHSL [internal]
1695 static void CC_EditSetHSL(HWND hDlg,int h,int s,int l)
1697 char buffer[10];
1698 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
1700 sprintf(buffer,"%d",h);
1701 SetWindowText(GetDlgItem(hDlg,0x2bf),buffer);
1702 sprintf(buffer,"%d",s);
1703 SetWindowText(GetDlgItem(hDlg,0x2c0),buffer);
1704 sprintf(buffer,"%d",l);
1705 SetWindowText(GetDlgItem(hDlg,0x2c1),buffer);
1707 CC_PaintLumBar(hDlg,h,s);
1710 /***********************************************************************
1711 * CC_SwitchToFullSize [internal]
1713 static void CC_SwitchToFullSize(HWND hDlg,COLORREF result,LPRECT lprect)
1715 int i;
1716 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
1718 EnableWindow(GetDlgItem(hDlg,0x2cf),FALSE);
1719 CC_PrepareColorGraph(hDlg);
1720 for (i=0x2bf;i<0x2c5;i++)
1721 EnableWindow(GetDlgItem(hDlg,i),TRUE);
1722 for (i=0x2d3;i<0x2d9;i++)
1723 EnableWindow(GetDlgItem(hDlg,i),TRUE);
1724 EnableWindow(GetDlgItem(hDlg,0x2c9),TRUE);
1725 EnableWindow(GetDlgItem(hDlg,0x2c8),TRUE);
1727 if (lprect)
1728 SetWindowPos(hDlg,NULL,0,0,lprect->right-lprect->left,
1729 lprect->bottom-lprect->top, SWP_NOMOVE|SWP_NOZORDER);
1731 ShowWindow(GetDlgItem(hDlg,0x2c6),SW_SHOW);
1732 ShowWindow(GetDlgItem(hDlg,0x2be),SW_SHOW);
1733 ShowWindow(GetDlgItem(hDlg,0x2c5),SW_SHOW);
1735 CC_EditSetRGB(hDlg,result);
1736 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1739 /***********************************************************************
1740 * CC_PaintPredefColorArray [internal]
1742 static void CC_PaintPredefColorArray(HWND hDlg,int rows,int cols)
1744 HWND hwnd=GetDlgItem(hDlg,0x2d0);
1745 RECT rect;
1746 HDC hdc;
1747 HBRUSH hBrush;
1748 int dx,dy,i,j,k;
1750 GetClientRect(hwnd,&rect);
1751 dx=rect.right/cols;
1752 dy=rect.bottom/rows;
1753 k=rect.left;
1755 hdc=GetDC(hwnd);
1756 GetClientRect (hwnd, &rect) ;
1758 for (j=0;j<rows;j++)
1760 for (i=0;i<cols;i++)
1762 hBrush = CreateSolidBrush(predefcolors[j][i]);
1763 if (hBrush)
1765 hBrush = SelectObject (hdc, hBrush) ;
1766 Rectangle (hdc, rect.left, rect.top,
1767 rect.left+dx-DISTANCE,rect.top+dy-DISTANCE);
1768 rect.left=rect.left+dx;
1769 DeleteObject (SelectObject (hdc, hBrush)) ;
1772 rect.top=rect.top+dy;
1773 rect.left=k;
1775 ReleaseDC(hwnd,hdc);
1776 /* FIXME: draw_a_focus_rect */
1778 /***********************************************************************
1779 * CC_PaintUserColorArray [internal]
1781 static void CC_PaintUserColorArray(HWND hDlg,int rows,int cols,COLORREF* lpcr)
1783 HWND hwnd=GetDlgItem(hDlg,0x2d1);
1784 RECT rect;
1785 HDC hdc;
1786 HBRUSH hBrush;
1787 int dx,dy,i,j,k;
1789 GetClientRect(hwnd,&rect);
1791 dx=rect.right/cols;
1792 dy=rect.bottom/rows;
1793 k=rect.left;
1795 hdc=GetDC(hwnd);
1796 if (hdc)
1798 for (j=0;j<rows;j++)
1800 for (i=0;i<cols;i++)
1802 hBrush = CreateSolidBrush(lpcr[i+j*cols]);
1803 if (hBrush)
1805 hBrush = SelectObject (hdc, hBrush) ;
1806 Rectangle (hdc, rect.left, rect.top,
1807 rect.left+dx-DISTANCE,rect.top+dy-DISTANCE);
1808 rect.left=rect.left+dx;
1809 DeleteObject (SelectObject (hdc, hBrush)) ;
1812 rect.top=rect.top+dy;
1813 rect.left=k;
1815 ReleaseDC(hwnd,hdc);
1817 /* FIXME: draw_a_focus_rect */
1822 /***********************************************************************
1823 * CC_HookCallChk [internal]
1825 static BOOL CC_HookCallChk(LPCHOOSECOLOR lpcc)
1827 if (lpcc)
1828 if(lpcc->Flags & CC_ENABLEHOOK)
1829 if (lpcc->lpfnHook)
1830 return TRUE;
1831 return FALSE;
1834 /***********************************************************************
1835 * CC_WMInitDialog [internal]
1837 static LONG CC_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
1839 int i,res;
1840 HWND hwnd;
1841 RECT rect;
1842 POINT point;
1843 struct CCPRIVATE * lpp;
1845 dprintf_commdlg(stddeb,"ColorDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
1846 lpp=calloc(1,sizeof(struct CCPRIVATE));
1847 lpp->lpcc=(LPCHOOSECOLOR)lParam;
1848 if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLOR))
1850 EndDialog (hDlg, 0) ;
1851 return FALSE;
1853 SetWindowLong(hDlg, DWL_USER, (LONG)lpp);
1855 if (!(lpp->lpcc->Flags & CC_SHOWHELP))
1856 ShowWindow(GetDlgItem(hDlg,0x40e),SW_HIDE);
1857 lpp->msetrgb=RegisterWindowMessage(MAKE_SEGPTR(SETRGBSTRING));
1858 #if 0
1859 cpos=MAKELONG(5,7); /* init */
1860 if (lpp->lpcc->Flags & CC_RGBINIT)
1862 for (i=0;i<6;i++)
1863 for (j=0;j<8;j++)
1864 if (predefcolors[i][j]==lpp->lpcc->rgbResult)
1866 cpos=MAKELONG(i,j);
1867 goto found;
1870 found:
1871 /* FIXME: Draw_a_focus_rect & set_init_values */
1872 #endif
1873 GetWindowRect(hDlg,&lpp->fullsize);
1874 if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
1876 hwnd=GetDlgItem(hDlg,0x2cf);
1877 EnableWindow(hwnd,FALSE);
1879 if (!(lpp->lpcc->Flags & CC_FULLOPEN) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
1881 rect=lpp->fullsize;
1882 res=rect.bottom-rect.top;
1883 hwnd=GetDlgItem(hDlg,0x2c6); /* cut at left border */
1884 point.x=point.y=0;
1885 ClientToScreen(hwnd,&point);
1886 ScreenToClient(hDlg,&point);
1887 GetClientRect(hDlg,&rect);
1888 point.x+=GetSystemMetrics(SM_CXDLGFRAME);
1889 SetWindowPos(hDlg,NULL,0,0,point.x,res,SWP_NOMOVE|SWP_NOZORDER);
1891 ShowWindow(GetDlgItem(hDlg,0x2c6),SW_HIDE);
1892 ShowWindow(GetDlgItem(hDlg,0x2c5),SW_HIDE);
1894 else
1895 CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,NULL);
1896 res=TRUE;
1897 for (i=0x2bf;i<0x2c5;i++)
1898 SendMessage(GetDlgItem(hDlg,i),EM_LIMITTEXT,3,0); /* max 3 digits: xyz */
1899 if (CC_HookCallChk(lpp->lpcc))
1900 res=CallWindowProc((FARPROC)lpp->lpcc->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1901 return res;
1904 /***********************************************************************
1905 * CC_WMCommand [internal]
1907 static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
1909 int r,g,b,i,xx;
1910 UINT cokmsg;
1911 HDC hdc;
1912 COLORREF *cr;
1913 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
1914 switch (wParam)
1916 case 0x2c2: /* edit notify RGB */
1917 case 0x2c3:
1918 case 0x2c4:
1919 if (HIWORD(lParam)==EN_UPDATE)
1921 i=CC_CheckDigitsInEdit(LOWORD(lParam),255);
1922 r=GetRValue(lpp->lpcc->rgbResult);
1923 g=GetGValue(lpp->lpcc->rgbResult);
1924 b=GetBValue(lpp->lpcc->rgbResult);
1925 xx=0;
1926 switch (wParam)
1928 case 0x2c2:if ((xx=(i!=r))) r=i;break;
1929 case 0x2c3:if ((xx=(i!=g))) g=i;break;
1930 case 0x2c4:if ((xx=(i!=b))) b=i;break;
1932 if (xx) /* something has changed */
1934 lpp->lpcc->rgbResult=RGB(r,g,b);
1935 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1936 lpp->h=CC_RGBtoHSL('H',r,g,b);
1937 lpp->s=CC_RGBtoHSL('S',r,g,b);
1938 lpp->l=CC_RGBtoHSL('L',r,g,b);
1939 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1940 CC_PaintCross(hDlg,lpp->h,lpp->s);
1941 CC_PaintTriangle(hDlg,lpp->l);
1944 break;
1946 case 0x2bf: /* edit notify HSL */
1947 case 0x2c0:
1948 case 0x2c1:
1949 if (HIWORD(lParam)==EN_UPDATE)
1951 i=CC_CheckDigitsInEdit(LOWORD(lParam),wParam==0x2bf?239:240);
1952 xx=0;
1953 switch (wParam)
1955 case 0x2bf:if ((xx=(i!=lpp->h))) lpp->h=i;break;
1956 case 0x2c0:if ((xx=(i!=lpp->s))) lpp->s=i;break;
1957 case 0x2c1:if ((xx=(i!=lpp->l))) lpp->l=i;break;
1959 if (xx) /* something has changed */
1961 r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
1962 g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
1963 b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
1964 lpp->lpcc->rgbResult=RGB(r,g,b);
1965 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1966 CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
1967 CC_PaintCross(hDlg,lpp->h,lpp->s);
1968 CC_PaintTriangle(hDlg,lpp->l);
1971 break;
1973 case 0x2cf:
1974 CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,&lpp->fullsize);
1975 InvalidateRect(hDlg,NULL,NULL);
1976 SetFocus(GetDlgItem(hDlg,0x2bf));
1977 break;
1979 case 0x2c8: /* add colors ... column by column */
1980 cr=PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors);
1981 cr[(lpp->nextuserdef%2)*8 + lpp->nextuserdef/2]=lpp->lpcc->rgbResult;
1982 if (++lpp->nextuserdef==16)
1983 lpp->nextuserdef=0;
1984 CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
1985 break;
1987 case 0x2c9: /* resulting color */
1988 hdc=GetDC(hDlg);
1989 lpp->lpcc->rgbResult=GetNearestColor(hdc,lpp->lpcc->rgbResult);
1990 ReleaseDC(hDlg,hdc);
1991 CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
1992 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1993 r=GetRValue(lpp->lpcc->rgbResult);
1994 g=GetGValue(lpp->lpcc->rgbResult);
1995 b=GetBValue(lpp->lpcc->rgbResult);
1996 lpp->h=CC_RGBtoHSL('H',r,g,b);
1997 lpp->s=CC_RGBtoHSL('S',r,g,b);
1998 lpp->l=CC_RGBtoHSL('L',r,g,b);
1999 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
2000 CC_PaintCross(hDlg,lpp->h,lpp->s);
2001 CC_PaintTriangle(hDlg,lpp->l);
2002 break;
2004 case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */
2005 i=RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
2006 if (lpp->lpcc->hwndOwner)
2007 SendMessage(lpp->lpcc->hwndOwner,i,0,(LPARAM)lpp->lpcc);
2008 if (CC_HookCallChk(lpp->lpcc))
2009 CallWindowProc((FARPROC)lpp->lpcc->lpfnHook,hDlg,
2010 WM_COMMAND,psh15,(LPARAM)lpp->lpcc);
2011 break;
2013 case IDOK :
2014 cokmsg=RegisterWindowMessage(MAKE_SEGPTR(COLOROKSTRING));
2015 if (lpp->lpcc->hwndOwner)
2016 if (SendMessage(lpp->lpcc->hwndOwner,cokmsg,0,(LPARAM)lpp->lpcc))
2017 break; /* do NOT close */
2019 EndDialog (hDlg, 1) ;
2020 return TRUE ;
2022 case IDCANCEL :
2023 EndDialog (hDlg, 0) ;
2024 return TRUE ;
2027 return FALSE;
2030 /***********************************************************************
2031 * CC_WMPaint [internal]
2033 static LRESULT CC_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam)
2035 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
2036 /* we have to paint dialog children except text and buttons */
2038 CC_PaintPredefColorArray(hDlg,6,8);
2039 CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
2040 CC_PaintColorGraph(hDlg);
2041 CC_PaintLumBar(hDlg,lpp->h,lpp->s);
2042 CC_PaintCross(hDlg,lpp->h,lpp->s);
2043 CC_PaintTriangle(hDlg,lpp->l);
2044 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
2046 /* special necessary for Wine */
2047 ValidateRect(GetDlgItem(hDlg,0x2d0),NULL);
2048 ValidateRect(GetDlgItem(hDlg,0x2d1),NULL);
2049 ValidateRect(GetDlgItem(hDlg,0x2c6),NULL);
2050 ValidateRect(GetDlgItem(hDlg,0x2be),NULL);
2051 ValidateRect(GetDlgItem(hDlg,0x2c5),NULL);
2052 /* hope we can remove it later -->FIXME */
2053 return 0;
2057 /***********************************************************************
2058 * CC_WMLButtonDown [internal]
2060 static LRESULT CC_WMLButtonDown(HWND hDlg, WPARAM wParam, LPARAM lParam)
2062 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
2063 int r,g,b,i;
2064 i=0;
2065 if (CC_MouseCheckPredefColorArray(hDlg,0x2d0,6,8,lParam,&lpp->lpcc->rgbResult))
2066 i=1;
2067 else
2068 if (CC_MouseCheckUserColorArray(hDlg,0x2d1,2,8,lParam,&lpp->lpcc->rgbResult,
2069 PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors)))
2070 i=1;
2071 else
2072 if (CC_MouseCheckColorGraph(hDlg,0x2c6,&lpp->h,&lpp->s,lParam))
2073 i=2;
2074 else
2075 if (CC_MouseCheckColorGraph(hDlg,0x2be,NULL,&lpp->l,lParam))
2076 i=2;
2077 if (i==2)
2079 r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
2080 g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
2081 b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
2082 lpp->lpcc->rgbResult=RGB(r,g,b);
2084 if (i==1)
2086 r=GetRValue(lpp->lpcc->rgbResult);
2087 g=GetGValue(lpp->lpcc->rgbResult);
2088 b=GetBValue(lpp->lpcc->rgbResult);
2089 lpp->h=CC_RGBtoHSL('H',r,g,b);
2090 lpp->s=CC_RGBtoHSL('S',r,g,b);
2091 lpp->l=CC_RGBtoHSL('L',r,g,b);
2093 if (i)
2095 CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
2096 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
2097 CC_PaintCross(hDlg,lpp->h,lpp->s);
2098 CC_PaintTriangle(hDlg,lpp->l);
2099 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
2100 return TRUE;
2102 return FALSE;
2105 /***********************************************************************
2106 * ColorDlgProc (COMMDLG.8)
2108 LRESULT ColorDlgProc(HWND hDlg, UINT message,
2109 UINT wParam, LONG lParam)
2111 int res;
2112 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
2113 if (message!=WM_INITDIALOG)
2115 if (!lpp)
2116 return FALSE;
2117 res=0;
2118 if (CC_HookCallChk(lpp->lpcc))
2119 res=CallWindowProc((FARPROC)lpp->lpcc->lpfnHook,hDlg,message,wParam,lParam);
2120 if (res)
2121 return res;
2124 /* FIXME: SetRGB message
2125 if (message && message==msetrgb)
2126 return HandleSetRGB(hDlg,lParam);
2129 switch (message)
2131 case WM_INITDIALOG:
2132 return CC_WMInitDialog(hDlg,wParam,lParam);
2133 case WM_NCDESTROY:
2134 /* FIXME: what about lpp->hdcMem ? */
2135 free(lpp);
2136 SetWindowLong(hDlg, DWL_USER, 0L); /* we don't need it anymore */
2137 break;
2138 case WM_COMMAND:
2139 if (CC_WMCommand(hDlg, wParam, lParam))
2140 return TRUE;
2141 break;
2142 case WM_PAINT:
2143 CC_WMPaint(hDlg, wParam, lParam);
2144 break;
2145 case WM_LBUTTONDBLCLK:
2146 if (CC_MouseCheckResultWindow(hDlg,lParam))
2147 return TRUE;
2148 break;
2149 case WM_MOUSEMOVE: /* FIXME: calculate new hue,sat,lum (if in color graph) */
2150 break;
2151 case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/
2152 break;
2153 case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/
2154 if (CC_WMLButtonDown(hDlg, wParam, lParam))
2155 return TRUE;
2156 break;
2158 return FALSE ;