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 */
34 #include "wine/winbase16.h"
35 #include "wine/winuser16.h"
39 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
46 /* Chose Color PRIVATE Structure:
48 * This is a duplicate of the 32bit code with
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 */
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 */
71 /***********************************************************************
72 * CC_WMInitDialog16 [internal]
74 static LONG
CC_WMInitDialog16( HWND hDlg
, WPARAM wParam
, LPARAM lParam
)
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
);
94 ch32
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CHOOSECOLORW
) );
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
);
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
);
124 /* FIXME: Draw_a_focus_rect & set_init_values */
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
);
156 CC_SwitchToFullSize(hDlg
, lpp
->lpcc
->rgbResult
, NULL
);
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
);
190 /***********************************************************************
191 * CC_WMCommand16 [internal]
193 static LRESULT
CC_WMCommand16( HWND hDlg
, WPARAM wParam
, LPARAM lParam
, WORD notifyCode
, HWND hwndCtl
)
199 LCCPRIV lpp
= (LCCPRIV
)GetWindowLongPtrW(hDlg
, DWLP_USER
);
200 TRACE("CC_WMCommand wParam=%lx lParam=%lx\n", wParam
, lParam
);
203 case 0x2c2: /* edit notify RGB */
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
);
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
);
233 case 0x2bf: /* edit notify HSL */
236 if (notifyCode
== EN_UPDATE
&& !lpp
->updating
)
238 i
= CC_CheckDigitsInEdit(hwndCtl
, wParam
== 0x2bf ? 239:240);
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
);
261 CC_SwitchToFullSize(hDlg
, lpp
->lpcc
->rgbResult
, &lpp
->fullsize
);
262 SetFocus( GetDlgItem(hDlg
, 0x2bf));
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
);
273 case 0x2c9: /* resulting color */
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
);
290 case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */
291 i
= RegisterWindowMessageA(HELPMSGSTRINGA
);
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
);
304 cokmsg
= RegisterWindowMessageA(COLOROKSTRINGA
);
307 if (lpp
->lpcc
->hwndOwner
)
308 if (SendMessageA(lpp
->lpcc
->hwndOwner
, cokmsg
, 0, (LPARAM
)lpp
->lpcc16
))
309 break; /* do NOT close */
313 BYTE
*ptr
= MapSL(lpp
->lpcc16
->lpCustColors
);
314 memcpy(ptr
, lpp
->lpcc
->lpCustColors
, sizeof(COLORREF
)*16);
315 lpp
->lpcc16
->rgbResult
= lpp
->lpcc
->rgbResult
;
328 /***********************************************************************
329 * ColorDlgProc (COMMDLG.8)
331 BOOL16 CALLBACK
ColorDlgProc16( HWND16 hDlg16
, UINT16 message
,
332 WPARAM16 wParam
, LONG lParam
)
335 HWND hDlg
= HWND_32(hDlg16
);
337 LCCPRIV lpp
= (LCCPRIV
)GetWindowLongPtrW(hDlg
, DWLP_USER
);
338 if (message
!= WM_INITDIALOG
)
343 if (CC_HookCallChk(lpp
->lpcc
))
344 res
= CallWindowProc16( (WNDPROC16
)lpp
->lpcc16
->lpfnHook
, hDlg16
, message
, wParam
, lParam
);
349 /* FIXME: SetRGB message
350 if (message && message == msetrgb)
351 return HandleSetRGB(hDlg, lParam);
357 return CC_WMInitDialog16(hDlg
, wParam
, lParam
);
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 */
366 if (CC_WMCommand16(hDlg
, wParam
, lParam
,
367 HIWORD(lParam
), HWND_32(LOWORD(lParam
))))
371 if (CC_WMPaint(hDlg
, wParam
, lParam
))
374 case WM_LBUTTONDBLCLK
:
375 if (CC_MouseCheckResultWindow(hDlg
,lParam
))
379 if (CC_WMMouseMove(hDlg
, lParam
))
382 case WM_LBUTTONUP
: /* FIXME: ClipCursor off (if in color graph)*/
383 if (CC_WMLButtonUp(hDlg
, wParam
, lParam
))
386 case WM_LBUTTONDOWN
:/* FIXME: ClipCursor on (if in color graph)*/
387 if (CC_WMLButtonDown(hDlg
, wParam
, lParam
))
394 /***********************************************************************
395 * ChooseColor (COMMDLG.5)
397 BOOL16 WINAPI
ChooseColor16( LPCHOOSECOLOR16 lpChCol
)
400 HANDLE16 hDlgTmpl16
= 0, hResource16
= 0;
401 HGLOBAL16 hGlobal16
= 0;
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
)
414 if (!(hResInfo
= FindResource16(lpChCol
->hInstance
,
415 MapSL(lpChCol
->lpTemplateName
),
418 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
421 if (!(hDlgTmpl16
= LoadResource16(lpChCol
->hInstance
, hResInfo
)))
423 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
426 hResource16
= hDlgTmpl16
;
434 if (!(hResInfo
= FindResourceA(COMDLG32_hInstance
, "CHOOSE_COLOR", (LPSTR
)RT_DIALOG
)))
436 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
439 if (!(hDlgTmpl32
= LoadResource(COMDLG32_hInstance
, hResInfo
)) ||
440 !(template32
= LockResource(hDlgTmpl32
)))
442 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
445 size
= SizeofResource(COMDLG32_hInstance
, hResInfo
);
446 hGlobal16
= GlobalAlloc16(0, size
);
449 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE
);
450 ERR("alloc failure for %d bytes\n", size
);
453 template = GlobalLock16(hGlobal16
);
456 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE
);
457 ERR("global lock failure for %x handle\n", hDlgTmpl16
);
458 GlobalFree16(hGlobal16
);
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
);
472 GlobalUnlock16(hGlobal16
);
473 GlobalFree16(hGlobal16
);