kernel32/tests: Fix some test failures on Win9x and WinME.
[wine/hacks.git] / dlls / comdlg32 / colordlg16.c
blobadbcf9862a7f2be5fd8de362692fb24bee92faab
1 /*
2 * COMMDLG - Color Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 /* BUGS : still seems to not refresh correctly
23 sometimes, especially when 2 instances of the
24 dialog are loaded at the same time */
26 #include <ctype.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include "windef.h"
32 #include "winbase.h"
33 #include "wingdi.h"
34 #include "wine/winbase16.h"
35 #include "wine/winuser16.h"
36 #include "winuser.h"
37 #include "commdlg.h"
38 #include "dlgs.h"
39 #include "wine/debug.h"
40 #include "cderr.h"
41 #include "cdlg.h"
42 #include "cdlg16.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
46 /* Chose Color PRIVATE Structure:
48 * This is a duplicate of the 32bit code with
49 * an extra member
51 typedef struct CCPRIVATE
53 LPCHOOSECOLORW lpcc; /* points to public known data structure */
54 LPCHOOSECOLOR16 lpcc16; /* save the 16 bits pointer */
55 int nextuserdef; /* next free place in user defined color array */
56 HDC hdcMem; /* color graph used for BitBlt() */
57 HBITMAP hbmMem; /* color graph bitmap */
58 RECT fullsize; /* original dialog window size */
59 UINT msetrgb; /* # of SETRGBSTRING message (today not used) */
60 RECT old3angle; /* last position of l-marker */
61 RECT oldcross; /* last position of color/saturation marker */
62 BOOL updating; /* to prevent recursive WM_COMMAND/EN_UPDATE processing */
63 int h;
64 int s;
65 int l; /* for temporary storing of hue,sat,lum */
66 int capturedGraph; /* control mouse captured */
67 RECT focusRect; /* rectangle last focused item */
68 HWND hwndFocus; /* handle last focused item */
69 } *LCCPRIV;
71 /***********************************************************************
72 * CC_WMInitDialog16 [internal]
74 static LONG CC_WMInitDialog16( HWND hDlg, WPARAM wParam, LPARAM lParam )
76 int i, res;
77 int r, g, b;
78 HWND hwnd;
79 RECT rect;
80 POINT point;
81 LCCPRIV lpp;
82 CHOOSECOLORW *ch32;
83 CHOOSECOLOR16 *ch16 = (CHOOSECOLOR16 *) lParam;
85 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
86 lpp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct CCPRIVATE) );
88 if (ch16->lStructSize != sizeof(CHOOSECOLOR16) )
90 HeapFree(GetProcessHeap(), 0, lpp);
91 EndDialog (hDlg, 0) ;
92 return FALSE;
94 ch32 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CHOOSECOLORW) );
95 lpp->lpcc = ch32;
96 lpp->lpcc16 = ch16;
97 ch32->lStructSize = sizeof(CHOOSECOLORW);
98 ch32->hwndOwner = HWND_32(ch16->hwndOwner);
99 /* Should be an HINSTANCE but MS made a typo */
100 ch32->hInstance = HWND_32(ch16->hInstance);
101 ch32->lpCustColors = MapSL(ch16->lpCustColors);
102 ch32->lpfnHook = (LPCCHOOKPROC) ch16->lpfnHook; /* only used as flag */
103 ch32->Flags = ch16->Flags;
105 SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)lpp);
107 if (!(lpp->lpcc->Flags & CC_SHOWHELP))
108 ShowWindow( GetDlgItem(hDlg,0x40e), SW_HIDE);
109 lpp->msetrgb = RegisterWindowMessageA(SETRGBSTRINGA);
111 #if 0
112 cpos = MAKELONG(5,7); /* init */
113 if (lpp->lpcc->Flags & CC_RGBINIT)
115 for (i = 0; i < 6; i++)
116 for (j = 0; j < 8; j++)
117 if (predefcolors[i][j] == lpp->lpcc->rgbResult)
119 cpos = MAKELONG(i,j);
120 goto found;
123 found:
124 /* FIXME: Draw_a_focus_rect & set_init_values */
125 #endif
127 GetWindowRect(hDlg, &lpp->fullsize);
128 if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
130 hwnd = GetDlgItem(hDlg, 0x2cf);
131 EnableWindow(hwnd, FALSE);
133 if (!(lpp->lpcc->Flags & CC_FULLOPEN ) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
135 rect = lpp->fullsize;
136 res = rect.bottom - rect.top;
137 hwnd = GetDlgItem(hDlg, 0x2c6); /* cut at left border */
138 point.x = point.y = 0;
139 ClientToScreen(hwnd, &point);
140 ScreenToClient(hDlg,&point);
141 GetClientRect(hDlg, &rect);
142 point.x += GetSystemMetrics(SM_CXDLGFRAME);
143 SetWindowPos(hDlg, 0, 0, 0, point.x, res, SWP_NOMOVE|SWP_NOZORDER);
145 for (i = 0x2bf; i < 0x2c5; i++)
146 ShowWindow( GetDlgItem(hDlg, i), SW_HIDE);
147 for (i = 0x2d3; i < 0x2d9; i++)
148 ShowWindow( GetDlgItem(hDlg, i), SW_HIDE);
149 ShowWindow( GetDlgItem(hDlg, 0x2c9), SW_HIDE);
150 ShowWindow( GetDlgItem(hDlg, 0x2c8), SW_HIDE);
151 ShowWindow( GetDlgItem(hDlg, 0x2c6), SW_HIDE);
152 ShowWindow( GetDlgItem(hDlg, 0x2c5), SW_HIDE);
153 ShowWindow( GetDlgItem(hDlg, 1090 ), SW_HIDE);
155 else
156 CC_SwitchToFullSize(hDlg, lpp->lpcc->rgbResult, NULL);
157 res = TRUE;
158 for (i = 0x2bf; i < 0x2c5; i++)
159 SendMessageA( GetDlgItem(hDlg, i), EM_LIMITTEXT, 3, 0); /* max 3 digits: xyz */
160 if (CC_HookCallChk(lpp->lpcc))
162 res = CallWindowProc16( (WNDPROC16)lpp->lpcc16->lpfnHook,
163 HWND_16(hDlg), WM_INITDIALOG, wParam, lParam);
166 /* Set the initial values of the color chooser dialog */
167 r = GetRValue(lpp->lpcc->rgbResult);
168 g = GetGValue(lpp->lpcc->rgbResult);
169 b = GetBValue(lpp->lpcc->rgbResult);
171 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
172 lpp->h = CC_RGBtoHSL('H', r, g, b);
173 lpp->s = CC_RGBtoHSL('S', r, g, b);
174 lpp->l = CC_RGBtoHSL('L', r, g, b);
176 /* Doing it the long way because CC_EditSetRGB/HSL doesn't seem to work */
177 SetDlgItemInt(hDlg, 703, lpp->h, TRUE);
178 SetDlgItemInt(hDlg, 704, lpp->s, TRUE);
179 SetDlgItemInt(hDlg, 705, lpp->l, TRUE);
180 SetDlgItemInt(hDlg, 706, r, TRUE);
181 SetDlgItemInt(hDlg, 707, g, TRUE);
182 SetDlgItemInt(hDlg, 708, b, TRUE);
184 CC_PaintCross(hDlg, lpp->h, lpp->s);
185 CC_PaintTriangle(hDlg, lpp->l);
187 return res;
190 /***********************************************************************
191 * CC_WMCommand16 [internal]
193 static LRESULT CC_WMCommand16( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode, HWND hwndCtl )
195 int r, g, b, i, xx;
196 UINT cokmsg;
197 HDC hdc;
198 COLORREF *cr;
199 LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);
200 TRACE("CC_WMCommand wParam=%lx lParam=%lx\n", wParam, lParam);
201 switch (wParam)
203 case 0x2c2: /* edit notify RGB */
204 case 0x2c3:
205 case 0x2c4:
206 if (notifyCode == EN_UPDATE && !lpp->updating)
208 i = CC_CheckDigitsInEdit(hwndCtl, 255);
209 r = GetRValue(lpp->lpcc->rgbResult);
210 g = GetGValue(lpp->lpcc->rgbResult);
211 b= GetBValue(lpp->lpcc->rgbResult);
212 xx = 0;
213 switch (wParam)
215 case 0x2c2: if ((xx = (i != r))) r = i; break;
216 case 0x2c3: if ((xx = (i != g))) g = i; break;
217 case 0x2c4: if ((xx = (i != b))) b = i; break;
219 if (xx) /* something has changed */
221 lpp->lpcc->rgbResult = RGB(r, g, b);
222 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
223 lpp->h = CC_RGBtoHSL('H', r, g, b);
224 lpp->s = CC_RGBtoHSL('S', r, g, b);
225 lpp->l = CC_RGBtoHSL('L', r, g, b);
226 CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l);
227 CC_PaintCross(hDlg, lpp->h, lpp->s);
228 CC_PaintTriangle(hDlg, lpp->l);
231 break;
233 case 0x2bf: /* edit notify HSL */
234 case 0x2c0:
235 case 0x2c1:
236 if (notifyCode == EN_UPDATE && !lpp->updating)
238 i = CC_CheckDigitsInEdit(hwndCtl , wParam == 0x2bf ? 239:240);
239 xx = 0;
240 switch (wParam)
242 case 0x2bf: if ((xx = ( i != lpp->h))) lpp->h = i; break;
243 case 0x2c0: if ((xx = ( i != lpp->s))) lpp->s = i; break;
244 case 0x2c1: if ((xx = ( i != lpp->l))) lpp->l = i; break;
246 if (xx) /* something has changed */
248 r = CC_HSLtoRGB('R', lpp->h, lpp->s, lpp->l);
249 g = CC_HSLtoRGB('G', lpp->h, lpp->s, lpp->l);
250 b = CC_HSLtoRGB('B', lpp->h, lpp->s, lpp->l);
251 lpp->lpcc->rgbResult = RGB(r, g, b);
252 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
253 CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult);
254 CC_PaintCross(hDlg, lpp->h, lpp->s);
255 CC_PaintTriangle(hDlg, lpp->l);
258 break;
260 case 0x2cf:
261 CC_SwitchToFullSize(hDlg, lpp->lpcc->rgbResult, &lpp->fullsize);
262 SetFocus( GetDlgItem(hDlg, 0x2bf));
263 break;
265 case 0x2c8: /* add colors ... column by column */
266 cr = lpp->lpcc->lpCustColors;
267 cr[(lpp->nextuserdef % 2) * 8 + lpp->nextuserdef / 2] = lpp->lpcc->rgbResult;
268 if (++lpp->nextuserdef == 16)
269 lpp->nextuserdef = 0;
270 CC_PaintUserColorArray(hDlg, 2, 8, lpp->lpcc->lpCustColors);
271 break;
273 case 0x2c9: /* resulting color */
274 hdc = GetDC(hDlg);
275 lpp->lpcc->rgbResult = GetNearestColor(hdc, lpp->lpcc->rgbResult);
276 ReleaseDC(hDlg, hdc);
277 CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult);
278 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
279 r = GetRValue(lpp->lpcc->rgbResult);
280 g = GetGValue(lpp->lpcc->rgbResult);
281 b = GetBValue(lpp->lpcc->rgbResult);
282 lpp->h = CC_RGBtoHSL('H', r, g, b);
283 lpp->s = CC_RGBtoHSL('S', r, g, b);
284 lpp->l = CC_RGBtoHSL('L', r, g, b);
285 CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l);
286 CC_PaintCross(hDlg, lpp->h, lpp->s);
287 CC_PaintTriangle(hDlg, lpp->l);
288 break;
290 case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */
291 i = RegisterWindowMessageA(HELPMSGSTRINGA);
292 if (lpp->lpcc16)
294 if (lpp->lpcc->hwndOwner)
295 SendMessageA(lpp->lpcc->hwndOwner, i, 0, (LPARAM)lpp->lpcc16);
296 if ( CC_HookCallChk(lpp->lpcc))
297 CallWindowProc16( (WNDPROC16) lpp->lpcc16->lpfnHook,
298 HWND_16(hDlg), WM_COMMAND, psh15,
299 (LPARAM)lpp->lpcc16);
301 break;
303 case IDOK :
304 cokmsg = RegisterWindowMessageA(COLOROKSTRINGA);
305 if (lpp->lpcc16)
307 if (lpp->lpcc->hwndOwner)
308 if (SendMessageA(lpp->lpcc->hwndOwner, cokmsg, 0, (LPARAM)lpp->lpcc16))
309 break; /* do NOT close */
311 if (lpp->lpcc16)
313 BYTE *ptr = MapSL(lpp->lpcc16->lpCustColors);
314 memcpy(ptr, lpp->lpcc->lpCustColors, sizeof(COLORREF)*16);
315 lpp->lpcc16->rgbResult = lpp->lpcc->rgbResult;
317 EndDialog(hDlg, 1) ;
318 return TRUE ;
320 case IDCANCEL :
321 EndDialog(hDlg, 0) ;
322 return TRUE ;
325 return FALSE;
328 /***********************************************************************
329 * ColorDlgProc (COMMDLG.8)
331 BOOL16 CALLBACK ColorDlgProc16( HWND16 hDlg16, UINT16 message,
332 WPARAM16 wParam, LONG lParam )
334 BOOL16 res;
335 HWND hDlg = HWND_32(hDlg16);
337 LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);
338 if (message != WM_INITDIALOG)
340 if (!lpp)
341 return FALSE;
342 res=0;
343 if (CC_HookCallChk(lpp->lpcc))
344 res = CallWindowProc16( (WNDPROC16)lpp->lpcc16->lpfnHook, hDlg16, message, wParam, lParam);
345 if (res)
346 return res;
349 /* FIXME: SetRGB message
350 if (message && message == msetrgb)
351 return HandleSetRGB(hDlg, lParam);
354 switch (message)
356 case WM_INITDIALOG:
357 return CC_WMInitDialog16(hDlg, wParam, lParam);
358 case WM_NCDESTROY:
359 DeleteDC(lpp->hdcMem);
360 DeleteObject(lpp->hbmMem);
361 HeapFree(GetProcessHeap(), 0, lpp->lpcc);
362 HeapFree(GetProcessHeap(), 0, lpp);
363 SetWindowLongPtrW(hDlg, DWLP_USER, 0); /* we don't need it anymore */
364 break;
365 case WM_COMMAND:
366 if (CC_WMCommand16(hDlg, wParam, lParam,
367 HIWORD(lParam), HWND_32(LOWORD(lParam))))
368 return TRUE;
369 break;
370 case WM_PAINT:
371 if (CC_WMPaint(hDlg, wParam, lParam))
372 return TRUE;
373 break;
374 case WM_LBUTTONDBLCLK:
375 if (CC_MouseCheckResultWindow(hDlg,lParam))
376 return TRUE;
377 break;
378 case WM_MOUSEMOVE:
379 if (CC_WMMouseMove(hDlg, lParam))
380 return TRUE;
381 break;
382 case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/
383 if (CC_WMLButtonUp(hDlg, wParam, lParam))
384 return TRUE;
385 break;
386 case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/
387 if (CC_WMLButtonDown(hDlg, wParam, lParam))
388 return TRUE;
389 break;
391 return FALSE ;
394 /***********************************************************************
395 * ChooseColor (COMMDLG.5)
397 BOOL16 WINAPI ChooseColor16( LPCHOOSECOLOR16 lpChCol )
399 HINSTANCE16 hInst;
400 HANDLE16 hDlgTmpl16 = 0, hResource16 = 0;
401 HGLOBAL16 hGlobal16 = 0;
402 BOOL16 bRet = FALSE;
403 LPVOID template;
404 FARPROC16 ptr;
406 TRACE("ChooseColor\n");
407 if (!lpChCol) return FALSE;
409 if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE)
410 hDlgTmpl16 = lpChCol->hInstance;
411 else if (lpChCol->Flags & CC_ENABLETEMPLATE)
413 HANDLE16 hResInfo;
414 if (!(hResInfo = FindResource16(lpChCol->hInstance,
415 MapSL(lpChCol->lpTemplateName),
416 (LPSTR)RT_DIALOG)))
418 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
419 return FALSE;
421 if (!(hDlgTmpl16 = LoadResource16(lpChCol->hInstance, hResInfo)))
423 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
424 return FALSE;
426 hResource16 = hDlgTmpl16;
428 else
430 HRSRC hResInfo;
431 HGLOBAL hDlgTmpl32;
432 LPCVOID template32;
433 DWORD size;
434 if (!(hResInfo = FindResourceA(COMDLG32_hInstance, "CHOOSE_COLOR", (LPSTR)RT_DIALOG)))
436 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
437 return FALSE;
439 if (!(hDlgTmpl32 = LoadResource(COMDLG32_hInstance, hResInfo)) ||
440 !(template32 = LockResource(hDlgTmpl32)))
442 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
443 return FALSE;
445 size = SizeofResource(COMDLG32_hInstance, hResInfo);
446 hGlobal16 = GlobalAlloc16(0, size);
447 if (!hGlobal16)
449 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
450 ERR("alloc failure for %d bytes\n", size);
451 return FALSE;
453 template = GlobalLock16(hGlobal16);
454 if (!template)
456 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
457 ERR("global lock failure for %x handle\n", hDlgTmpl16);
458 GlobalFree16(hGlobal16);
459 return FALSE;
461 ConvertDialog32To16(template32, size, template);
462 hDlgTmpl16 = hGlobal16;
465 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 8);
466 hInst = GetWindowLongPtrA(HWND_32(lpChCol->hwndOwner), GWLP_HINSTANCE);
467 bRet = DialogBoxIndirectParam16(hInst, hDlgTmpl16, lpChCol->hwndOwner,
468 (DLGPROC16) ptr, (DWORD)lpChCol);
469 if (hResource16) FreeResource16(hDlgTmpl16);
470 if (hGlobal16)
472 GlobalUnlock16(hGlobal16);
473 GlobalFree16(hGlobal16);
475 return bRet;