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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 /***********************************************************************
47 * CC_WMInitDialog16 [internal]
49 LONG
CC_WMInitDialog16( HWND hDlg
, WPARAM wParam
, LPARAM lParam
)
58 CHOOSECOLOR16
*ch16
= (CHOOSECOLOR16
*) lParam
;
60 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam
);
61 lpp
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct CCPRIVATE
) );
63 if (ch16
->lStructSize
!= sizeof(CHOOSECOLOR16
) )
65 HeapFree(GetProcessHeap(), 0, lpp
);
69 ch32
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CHOOSECOLORW
) );
72 ch32
->lStructSize
= sizeof(CHOOSECOLORW
);
73 ch32
->hwndOwner
= HWND_32(ch16
->hwndOwner
);
74 /* Should be an HINSTANCE but MS made a typo */
75 ch32
->hInstance
= HWND_32(ch16
->hInstance
);
76 ch32
->lpCustColors
= MapSL(ch16
->lpCustColors
);
77 ch32
->lpfnHook
= (LPCCHOOKPROC
) ch16
->lpfnHook
; /* only used as flag */
78 ch32
->Flags
= ch16
->Flags
;
80 SetWindowLongA(hDlg
, DWL_USER
, (LONG
)lpp
);
82 if (!(lpp
->lpcc
->Flags
& CC_SHOWHELP
))
83 ShowWindow( GetDlgItem(hDlg
,0x40e), SW_HIDE
);
84 lpp
->msetrgb
= RegisterWindowMessageA(SETRGBSTRINGA
);
87 cpos
= MAKELONG(5,7); /* init */
88 if (lpp
->lpcc
->Flags
& CC_RGBINIT
)
90 for (i
= 0; i
< 6; i
++)
91 for (j
= 0; j
< 8; j
++)
92 if (predefcolors
[i
][j
] == lpp
->lpcc
->rgbResult
)
99 /* FIXME: Draw_a_focus_rect & set_init_values */
102 GetWindowRect(hDlg
, &lpp
->fullsize
);
103 if (lpp
->lpcc
->Flags
& CC_FULLOPEN
|| lpp
->lpcc
->Flags
& CC_PREVENTFULLOPEN
)
105 hwnd
= GetDlgItem(hDlg
, 0x2cf);
106 EnableWindow(hwnd
, FALSE
);
108 if (!(lpp
->lpcc
->Flags
& CC_FULLOPEN
) || lpp
->lpcc
->Flags
& CC_PREVENTFULLOPEN
)
110 rect
= lpp
->fullsize
;
111 res
= rect
.bottom
- rect
.top
;
112 hwnd
= GetDlgItem(hDlg
, 0x2c6); /* cut at left border */
113 point
.x
= point
.y
= 0;
114 ClientToScreen(hwnd
, &point
);
115 ScreenToClient(hDlg
,&point
);
116 GetClientRect(hDlg
, &rect
);
117 point
.x
+= GetSystemMetrics(SM_CXDLGFRAME
);
118 SetWindowPos(hDlg
, 0, 0, 0, point
.x
, res
, SWP_NOMOVE
|SWP_NOZORDER
);
120 for (i
= 0x2bf; i
< 0x2c5; i
++)
121 ShowWindow( GetDlgItem(hDlg
, i
), SW_HIDE
);
122 for (i
= 0x2d3; i
< 0x2d9; i
++)
123 ShowWindow( GetDlgItem(hDlg
, i
), SW_HIDE
);
124 ShowWindow( GetDlgItem(hDlg
, 0x2c9), SW_HIDE
);
125 ShowWindow( GetDlgItem(hDlg
, 0x2c8), SW_HIDE
);
126 ShowWindow( GetDlgItem(hDlg
, 0x2c6), SW_HIDE
);
127 ShowWindow( GetDlgItem(hDlg
, 0x2c5), SW_HIDE
);
128 ShowWindow( GetDlgItem(hDlg
, 1090 ), SW_HIDE
);
131 CC_SwitchToFullSize(hDlg
, lpp
->lpcc
->rgbResult
, NULL
);
133 for (i
= 0x2bf; i
< 0x2c5; i
++)
134 SendMessageA( GetDlgItem(hDlg
, i
), EM_LIMITTEXT
, 3, 0); /* max 3 digits: xyz */
135 if (CC_HookCallChk(lpp
->lpcc
))
137 res
= CallWindowProc16( (WNDPROC16
)lpp
->lpcc16
->lpfnHook
,
138 HWND_16(hDlg
), WM_INITDIALOG
, wParam
, lParam
);
141 /* Set the initial values of the color chooser dialog */
142 r
= GetRValue(lpp
->lpcc
->rgbResult
);
143 g
= GetGValue(lpp
->lpcc
->rgbResult
);
144 b
= GetBValue(lpp
->lpcc
->rgbResult
);
146 CC_PaintSelectedColor(hDlg
, lpp
->lpcc
->rgbResult
);
147 lpp
->h
= CC_RGBtoHSL('H', r
, g
, b
);
148 lpp
->s
= CC_RGBtoHSL('S', r
, g
, b
);
149 lpp
->l
= CC_RGBtoHSL('L', r
, g
, b
);
151 /* Doing it the long way because CC_EditSetRGB/HSL doesn't seem to work */
152 SetDlgItemInt(hDlg
, 703, lpp
->h
, TRUE
);
153 SetDlgItemInt(hDlg
, 704, lpp
->s
, TRUE
);
154 SetDlgItemInt(hDlg
, 705, lpp
->l
, TRUE
);
155 SetDlgItemInt(hDlg
, 706, r
, TRUE
);
156 SetDlgItemInt(hDlg
, 707, g
, TRUE
);
157 SetDlgItemInt(hDlg
, 708, b
, TRUE
);
159 CC_PaintCross(hDlg
, lpp
->h
, lpp
->s
);
160 CC_PaintTriangle(hDlg
, lpp
->l
);
165 /***********************************************************************
166 * CC_WMCommand16 [internal]
168 LRESULT
CC_WMCommand16( HWND hDlg
, WPARAM wParam
, LPARAM lParam
, WORD notifyCode
, HWND hwndCtl
)
174 LCCPRIV lpp
= (LCCPRIV
)GetWindowLongA(hDlg
, DWL_USER
);
175 TRACE("CC_WMCommand wParam=%x lParam=%lx\n", wParam
, lParam
);
178 case 0x2c2: /* edit notify RGB */
181 if (notifyCode
== EN_UPDATE
&& !lpp
->updating
)
183 i
= CC_CheckDigitsInEdit(hwndCtl
, 255);
184 r
= GetRValue(lpp
->lpcc
->rgbResult
);
185 g
= GetGValue(lpp
->lpcc
->rgbResult
);
186 b
= GetBValue(lpp
->lpcc
->rgbResult
);
190 case 0x2c2: if ((xx
= (i
!= r
))) r
= i
; break;
191 case 0x2c3: if ((xx
= (i
!= g
))) g
= i
; break;
192 case 0x2c4: if ((xx
= (i
!= b
))) b
= i
; break;
194 if (xx
) /* something has changed */
196 lpp
->lpcc
->rgbResult
= RGB(r
, g
, b
);
197 CC_PaintSelectedColor(hDlg
, lpp
->lpcc
->rgbResult
);
198 lpp
->h
= CC_RGBtoHSL('H', r
, g
, b
);
199 lpp
->s
= CC_RGBtoHSL('S', r
, g
, b
);
200 lpp
->l
= CC_RGBtoHSL('L', r
, g
, b
);
201 CC_EditSetHSL(hDlg
, lpp
->h
, lpp
->s
, lpp
->l
);
202 CC_PaintCross(hDlg
, lpp
->h
, lpp
->s
);
203 CC_PaintTriangle(hDlg
, lpp
->l
);
208 case 0x2bf: /* edit notify HSL */
211 if (notifyCode
== EN_UPDATE
&& !lpp
->updating
)
213 i
= CC_CheckDigitsInEdit(hwndCtl
, wParam
== 0x2bf ? 239:240);
217 case 0x2bf: if ((xx
= ( i
!= lpp
->h
))) lpp
->h
= i
; break;
218 case 0x2c0: if ((xx
= ( i
!= lpp
->s
))) lpp
->s
= i
; break;
219 case 0x2c1: if ((xx
= ( i
!= lpp
->l
))) lpp
->l
= i
; break;
221 if (xx
) /* something has changed */
223 r
= CC_HSLtoRGB('R', lpp
->h
, lpp
->s
, lpp
->l
);
224 g
= CC_HSLtoRGB('G', lpp
->h
, lpp
->s
, lpp
->l
);
225 b
= CC_HSLtoRGB('B', lpp
->h
, lpp
->s
, lpp
->l
);
226 lpp
->lpcc
->rgbResult
= RGB(r
, g
, b
);
227 CC_PaintSelectedColor(hDlg
, lpp
->lpcc
->rgbResult
);
228 CC_EditSetRGB(hDlg
, lpp
->lpcc
->rgbResult
);
229 CC_PaintCross(hDlg
, lpp
->h
, lpp
->s
);
230 CC_PaintTriangle(hDlg
, lpp
->l
);
236 CC_SwitchToFullSize(hDlg
, lpp
->lpcc
->rgbResult
, &lpp
->fullsize
);
237 SetFocus( GetDlgItem(hDlg
, 0x2bf));
240 case 0x2c8: /* add colors ... column by column */
241 cr
= lpp
->lpcc
->lpCustColors
;
242 cr
[(lpp
->nextuserdef
% 2) * 8 + lpp
->nextuserdef
/ 2] = lpp
->lpcc
->rgbResult
;
243 if (++lpp
->nextuserdef
== 16)
244 lpp
->nextuserdef
= 0;
245 CC_PaintUserColorArray(hDlg
, 2, 8, lpp
->lpcc
->lpCustColors
);
248 case 0x2c9: /* resulting color */
250 lpp
->lpcc
->rgbResult
= GetNearestColor(hdc
, lpp
->lpcc
->rgbResult
);
251 ReleaseDC(hDlg
, hdc
);
252 CC_EditSetRGB(hDlg
, lpp
->lpcc
->rgbResult
);
253 CC_PaintSelectedColor(hDlg
, lpp
->lpcc
->rgbResult
);
254 r
= GetRValue(lpp
->lpcc
->rgbResult
);
255 g
= GetGValue(lpp
->lpcc
->rgbResult
);
256 b
= GetBValue(lpp
->lpcc
->rgbResult
);
257 lpp
->h
= CC_RGBtoHSL('H', r
, g
, b
);
258 lpp
->s
= CC_RGBtoHSL('S', r
, g
, b
);
259 lpp
->l
= CC_RGBtoHSL('L', r
, g
, b
);
260 CC_EditSetHSL(hDlg
, lpp
->h
, lpp
->s
, lpp
->l
);
261 CC_PaintCross(hDlg
, lpp
->h
, lpp
->s
);
262 CC_PaintTriangle(hDlg
, lpp
->l
);
265 case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */
266 i
= RegisterWindowMessageA(HELPMSGSTRINGA
);
269 if (lpp
->lpcc
->hwndOwner
)
270 SendMessageA(lpp
->lpcc
->hwndOwner
, i
, 0, (LPARAM
)lpp
->lpcc16
);
271 if ( CC_HookCallChk(lpp
->lpcc
))
272 CallWindowProc16( (WNDPROC16
) lpp
->lpcc16
->lpfnHook
,
273 HWND_16(hDlg
), WM_COMMAND
, psh15
,
274 (LPARAM
)lpp
->lpcc16
);
279 cokmsg
= RegisterWindowMessageA(COLOROKSTRINGA
);
282 if (lpp
->lpcc
->hwndOwner
)
283 if (SendMessageA(lpp
->lpcc
->hwndOwner
, cokmsg
, 0, (LPARAM
)lpp
->lpcc16
))
284 break; /* do NOT close */
288 BYTE
*ptr
= MapSL(lpp
->lpcc16
->lpCustColors
);
289 memcpy(ptr
, lpp
->lpcc
->lpCustColors
, sizeof(COLORREF
)*16);
290 lpp
->lpcc16
->rgbResult
= lpp
->lpcc
->rgbResult
;
303 /***********************************************************************
304 * ColorDlgProc (COMMDLG.8)
306 BOOL16 CALLBACK
ColorDlgProc16( HWND16 hDlg16
, UINT16 message
,
307 WPARAM16 wParam
, LONG lParam
)
310 HWND hDlg
= HWND_32(hDlg16
);
312 LCCPRIV lpp
= (LCCPRIV
)GetWindowLongA(hDlg
, DWL_USER
);
313 if (message
!= WM_INITDIALOG
)
318 if (CC_HookCallChk(lpp
->lpcc
))
319 res
= CallWindowProc16( (WNDPROC16
)lpp
->lpcc16
->lpfnHook
, hDlg16
, message
, wParam
, lParam
);
324 /* FIXME: SetRGB message
325 if (message && message == msetrgb)
326 return HandleSetRGB(hDlg, lParam);
332 return CC_WMInitDialog16(hDlg
, wParam
, lParam
);
334 DeleteDC(lpp
->hdcMem
);
335 DeleteObject(lpp
->hbmMem
);
336 HeapFree(GetProcessHeap(), 0, lpp
->lpcc
);
337 HeapFree(GetProcessHeap(), 0, lpp
);
338 SetWindowLongA(hDlg
, DWL_USER
, 0L); /* we don't need it anymore */
341 if (CC_WMCommand16(hDlg
, wParam
, lParam
,
342 HIWORD(lParam
), HWND_32(LOWORD(lParam
))))
346 if (CC_WMPaint(hDlg
, wParam
, lParam
))
349 case WM_LBUTTONDBLCLK
:
350 if (CC_MouseCheckResultWindow(hDlg
,lParam
))
354 if (CC_WMMouseMove(hDlg
, lParam
))
357 case WM_LBUTTONUP
: /* FIXME: ClipCursor off (if in color graph)*/
358 if (CC_WMLButtonUp(hDlg
, wParam
, lParam
))
361 case WM_LBUTTONDOWN
:/* FIXME: ClipCursor on (if in color graph)*/
362 if (CC_WMLButtonDown(hDlg
, wParam
, lParam
))
369 /***********************************************************************
370 * ChooseColor (COMMDLG.5)
372 BOOL16 WINAPI
ChooseColor16( LPCHOOSECOLOR16 lpChCol
)
375 HANDLE16 hDlgTmpl16
= 0, hResource16
= 0;
376 HGLOBAL16 hGlobal16
= 0;
381 TRACE("ChooseColor\n");
382 if (!lpChCol
) return FALSE
;
384 if (lpChCol
->Flags
& CC_ENABLETEMPLATEHANDLE
)
385 hDlgTmpl16
= lpChCol
->hInstance
;
386 else if (lpChCol
->Flags
& CC_ENABLETEMPLATE
)
389 if (!(hResInfo
= FindResource16(lpChCol
->hInstance
,
390 MapSL(lpChCol
->lpTemplateName
),
393 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
396 if (!(hDlgTmpl16
= LoadResource16(lpChCol
->hInstance
, hResInfo
)))
398 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
401 hResource16
= hDlgTmpl16
;
409 if (!(hResInfo
= FindResourceA(COMDLG32_hInstance
, "CHOOSE_COLOR", (LPSTR
)RT_DIALOG
)))
411 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
414 if (!(hDlgTmpl32
= LoadResource(COMDLG32_hInstance
, hResInfo
)) ||
415 !(template32
= LockResource(hDlgTmpl32
)))
417 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
420 size
= SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo
);
421 hGlobal16
= GlobalAlloc16(0, size
);
424 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE
);
425 ERR("alloc failure for %ld bytes\n", size
);
428 template = GlobalLock16(hGlobal16
);
431 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE
);
432 ERR("global lock failure for %x handle\n", hDlgTmpl16
);
433 GlobalFree16(hGlobal16
);
436 ConvertDialog32To16((LPVOID
)template32
, size
, (LPVOID
)template);
437 hDlgTmpl16
= hGlobal16
;
440 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 8);
441 hInst
= GetWindowLongA(HWND_32(lpChCol
->hwndOwner
), GWL_HINSTANCE
);
442 bRet
= DialogBoxIndirectParam16(hInst
, hDlgTmpl16
, lpChCol
->hwndOwner
,
443 (DLGPROC16
) ptr
, (DWORD
)lpChCol
);
444 if (hResource16
) FreeResource16(hDlgTmpl16
);
447 GlobalUnlock16(hGlobal16
);
448 GlobalFree16(hGlobal16
);