Moved error codes to cderr.h.
[wine/gsoc_dplay.git] / dlls / commdlg / colordlg.c
blob565e4e7621aed36f7dc68b20dd26de0e91ac4933
1 /*
2 * COMMDLG - File Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1999 Klaas van Gend
7 */
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "winbase.h"
13 #include "wine/winbase16.h"
14 #include "wine/winuser16.h"
15 #include "win.h"
16 #include "heap.h"
17 #include "message.h"
18 #include "commdlg.h"
19 #include "resource.h"
20 #include "dialog.h"
21 #include "dlgs.h"
22 #include "module.h"
23 #include "drive.h"
24 #include "debug.h"
25 #include "font.h"
26 #include "winproc.h"
27 #include "cderr.h"
29 extern DWORD CommDlgLastError;
31 /***********************************************************************
32 * ChooseColor (COMMDLG.5)
34 BOOL16 WINAPI ChooseColor16(LPCHOOSECOLOR16 lpChCol)
36 HINSTANCE16 hInst;
37 HANDLE16 hDlgTmpl = 0;
38 BOOL16 bRet = FALSE, win32Format = FALSE;
39 LPCVOID template;
40 HWND hwndDialog;
42 TRACE(commdlg,"ChooseColor\n");
43 if (!lpChCol) return FALSE;
45 if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE)
47 if (!(template = LockResource16( lpChCol->hInstance )))
49 CommDlgLastError = CDERR_LOADRESFAILURE;
50 return FALSE;
53 else if (lpChCol->Flags & CC_ENABLETEMPLATE)
55 HANDLE16 hResInfo;
56 if (!(hResInfo = FindResource16(lpChCol->hInstance,
57 lpChCol->lpTemplateName,
58 RT_DIALOG16)))
60 CommDlgLastError = CDERR_FINDRESFAILURE;
61 return FALSE;
63 if (!(hDlgTmpl = LoadResource16( lpChCol->hInstance, hResInfo )) ||
64 !(template = LockResource16( hDlgTmpl )))
66 CommDlgLastError = CDERR_LOADRESFAILURE;
67 return FALSE;
70 else
72 template = SYSRES_GetResPtr( SYSRES_DIALOG_CHOOSE_COLOR );
73 win32Format = TRUE;
76 hInst = WIN_GetWindowInstance( lpChCol->hwndOwner );
77 hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
78 lpChCol->hwndOwner,
79 (DLGPROC16)MODULE_GetWndProcEntry16("ColorDlgProc"),
80 (DWORD)lpChCol, WIN_PROC_16 );
81 if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpChCol->hwndOwner);
82 if (hDlgTmpl) FreeResource16( hDlgTmpl );
84 return bRet;
88 static const COLORREF predefcolors[6][8]=
90 { 0x008080FFL, 0x0080FFFFL, 0x0080FF80L, 0x0080FF00L,
91 0x00FFFF80L, 0x00FF8000L, 0x00C080FFL, 0x00FF80FFL },
92 { 0x000000FFL, 0x0000FFFFL, 0x0000FF80L, 0x0040FF00L,
93 0x00FFFF00L, 0x00C08000L, 0x00C08080L, 0x00FF00FFL },
95 { 0x00404080L, 0x004080FFL, 0x0000FF00L, 0x00808000L,
96 0x00804000L, 0x00FF8080L, 0x00400080L, 0x008000FFL },
97 { 0x00000080L, 0x000080FFL, 0x00008000L, 0x00408000L,
98 0x00FF0000L, 0x00A00000L, 0x00800080L, 0x00FF0080L },
100 { 0x00000040L, 0x00004080L, 0x00004000L, 0x00404000L,
101 0x00800000L, 0x00400000L, 0x00400040L, 0x00800040L },
102 { 0x00000000L, 0x00008080L, 0x00408080L, 0x00808080L,
103 0x00808040L, 0x00C0C0C0L, 0x00400040L, 0x00FFFFFFL },
106 struct CCPRIVATE
108 LPCHOOSECOLOR16 lpcc; /* points to public known data structure */
109 int nextuserdef; /* next free place in user defined color array */
110 HDC16 hdcMem; /* color graph used for BitBlt() */
111 HBITMAP16 hbmMem; /* color graph bitmap */
112 RECT16 fullsize; /* original dialog window size */
113 UINT16 msetrgb; /* # of SETRGBSTRING message (today not used) */
114 RECT16 old3angle; /* last position of l-marker */
115 RECT16 oldcross; /* last position of color/satuation marker */
116 BOOL updating; /* to prevent recursive WM_COMMAND/EN_UPDATE procesing */
117 int h;
118 int s;
119 int l; /* for temporary storing of hue,sat,lum */
122 /***********************************************************************
123 * CC_HSLtoRGB [internal]
125 static int CC_HSLtoRGB(char c,int hue,int sat,int lum)
127 int res=0,maxrgb;
129 /* hue */
130 switch(c)
132 case 'R':if (hue>80) hue-=80; else hue+=160; break;
133 case 'G':if (hue>160) hue-=160; else hue+=80; break;
134 case 'B':break;
137 /* l below 120 */
138 maxrgb=(256*MIN(120,lum))/120; /* 0 .. 256 */
139 if (hue< 80)
140 res=0;
141 else
142 if (hue< 120)
144 res=(hue-80)* maxrgb; /* 0...10240 */
145 res/=40; /* 0...256 */
147 else
148 if (hue< 200)
149 res=maxrgb;
150 else
152 res=(240-hue)* maxrgb;
153 res/=40;
155 res=res-maxrgb/2; /* -128...128 */
157 /* saturation */
158 res=maxrgb/2 + (sat*res) /240; /* 0..256 */
160 /* lum above 120 */
161 if (lum>120 && res<256)
162 res+=((lum-120) * (256-res))/120;
164 return MIN(res,255);
167 /***********************************************************************
168 * CC_RGBtoHSL [internal]
170 static int CC_RGBtoHSL(char c,int r,int g,int b)
172 WORD maxi,mini,mmsum,mmdif,result=0;
173 int iresult=0;
175 maxi=MAX(r,b);
176 maxi=MAX(maxi,g);
177 mini=MIN(r,b);
178 mini=MIN(mini,g);
180 mmsum=maxi+mini;
181 mmdif=maxi-mini;
183 switch(c)
185 /* lum */
186 case 'L':mmsum*=120; /* 0...61200=(255+255)*120 */
187 result=mmsum/255; /* 0...240 */
188 break;
189 /* saturation */
190 case 'S':if (!mmsum)
191 result=0;
192 else
193 if (!mini || maxi==255)
194 result=240;
195 else
197 result=mmdif*240; /* 0...61200=255*240 */
198 result/= (mmsum>255 ? mmsum=510-mmsum : mmsum); /* 0..255 */
200 break;
201 /* hue */
202 case 'H':if (!mmdif)
203 result=160;
204 else
206 if (maxi==r)
208 iresult=40*(g-b); /* -10200 ... 10200 */
209 iresult/=(int)mmdif; /* -40 .. 40 */
210 if (iresult<0)
211 iresult+=240; /* 0..40 and 200..240 */
213 else
214 if (maxi==g)
216 iresult=40*(b-r);
217 iresult/=(int)mmdif;
218 iresult+=80; /* 40 .. 120 */
220 else
221 if (maxi==b)
223 iresult=40*(r-g);
224 iresult/=(int)mmdif;
225 iresult+=160; /* 120 .. 200 */
227 result=iresult;
229 break;
231 return result; /* is this integer arithmetic precise enough ? */
234 #define DISTANCE 4
236 /***********************************************************************
237 * CC_MouseCheckPredefColorArray [internal]
239 static int CC_MouseCheckPredefColorArray(HWND16 hDlg,int dlgitem,int rows,int cols,
240 LPARAM lParam,COLORREF *cr)
242 HWND16 hwnd;
243 POINT16 point = MAKEPOINT16(lParam);
244 RECT16 rect;
245 int dx,dy,x,y;
247 ClientToScreen16(hDlg,&point);
248 hwnd=GetDlgItem(hDlg,dlgitem);
249 GetWindowRect16(hwnd,&rect);
250 if (PtInRect16(&rect,point))
252 dx=(rect.right-rect.left)/cols;
253 dy=(rect.bottom-rect.top)/rows;
254 ScreenToClient16(hwnd,&point);
256 if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
258 x=point.x/dx;
259 y=point.y/dy;
260 *cr=predefcolors[y][x];
261 /* FIXME: Draw_a_Focus_Rect() */
262 return 1;
265 return 0;
268 /***********************************************************************
269 * CC_MouseCheckUserColorArray [internal]
271 static int CC_MouseCheckUserColorArray(HWND16 hDlg,int dlgitem,int rows,int cols,
272 LPARAM lParam,COLORREF *cr,COLORREF*crarr)
274 HWND16 hwnd;
275 POINT16 point = MAKEPOINT16(lParam);
276 RECT16 rect;
277 int dx,dy,x,y;
279 ClientToScreen16(hDlg,&point);
280 hwnd=GetDlgItem(hDlg,dlgitem);
281 GetWindowRect16(hwnd,&rect);
282 if (PtInRect16(&rect,point))
284 dx=(rect.right-rect.left)/cols;
285 dy=(rect.bottom-rect.top)/rows;
286 ScreenToClient16(hwnd,&point);
288 if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
290 x=point.x/dx;
291 y=point.y/dy;
292 *cr=crarr[x+cols*y];
293 /* FIXME: Draw_a_Focus_Rect() */
294 return 1;
297 return 0;
300 #define MAXVERT 240
301 #define MAXHORI 239
303 /* 240 ^...... ^^ 240
304 | . ||
305 SAT | . || LUM
306 | . ||
307 +-----> 239 ----
310 /***********************************************************************
311 * CC_MouseCheckColorGraph [internal]
313 static int CC_MouseCheckColorGraph(HWND16 hDlg,int dlgitem,int *hori,int *vert,LPARAM lParam)
315 HWND hwnd;
316 POINT16 point = MAKEPOINT16(lParam);
317 RECT16 rect;
318 long x,y;
320 ClientToScreen16(hDlg,&point);
321 hwnd=GetDlgItem(hDlg,dlgitem);
322 GetWindowRect16(hwnd,&rect);
323 if (PtInRect16(&rect,point))
325 GetClientRect16(hwnd,&rect);
326 ScreenToClient16(hwnd,&point);
328 x=(long)point.x*MAXHORI;
329 x/=rect.right;
330 y=(long)(rect.bottom-point.y)*MAXVERT;
331 y/=rect.bottom;
333 if (hori)
334 *hori=x;
335 if (vert)
336 *vert=y;
337 return 1;
339 else
340 return 0;
342 /***********************************************************************
343 * CC_MouseCheckResultWindow [internal]
345 static int CC_MouseCheckResultWindow(HWND16 hDlg,LPARAM lParam)
347 HWND16 hwnd;
348 POINT16 point = MAKEPOINT16(lParam);
349 RECT16 rect;
351 ClientToScreen16(hDlg,&point);
352 hwnd=GetDlgItem(hDlg,0x2c5);
353 GetWindowRect16(hwnd,&rect);
354 if (PtInRect16(&rect,point))
356 PostMessage16(hDlg,WM_COMMAND,0x2c9,0);
357 return 1;
359 return 0;
362 /***********************************************************************
363 * CC_CheckDigitsInEdit [internal]
365 static int CC_CheckDigitsInEdit(HWND16 hwnd,int maxval)
367 int i,k,m,result,value;
368 long editpos;
369 char buffer[30];
370 GetWindowTextA(hwnd,buffer,sizeof(buffer));
371 m=strlen(buffer);
372 result=0;
374 for (i=0;i<m;i++)
375 if (buffer[i]<'0' || buffer[i]>'9')
377 for (k=i+1;k<=m;k++) /* delete bad character */
379 buffer[i]=buffer[k];
380 m--;
382 buffer[m]=0;
383 result=1;
386 value=atoi(buffer);
387 if (value>maxval) /* build a new string */
389 sprintf(buffer,"%d",maxval);
390 result=2;
392 if (result)
394 editpos=SendMessage16(hwnd,EM_GETSEL16,0,0);
395 SetWindowTextA(hwnd,buffer);
396 SendMessage16(hwnd,EM_SETSEL16,0,editpos);
398 return value;
403 /***********************************************************************
404 * CC_PaintSelectedColor [internal]
406 static void CC_PaintSelectedColor(HWND16 hDlg,COLORREF cr)
408 RECT16 rect;
409 HDC hdc;
410 HBRUSH hBrush;
411 HWND hwnd=GetDlgItem(hDlg,0x2c5);
412 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
414 hdc=GetDC(hwnd);
415 GetClientRect16 (hwnd, &rect) ;
416 hBrush = CreateSolidBrush(cr);
417 if (hBrush)
419 hBrush = SelectObject (hdc, hBrush) ;
420 Rectangle(hdc, rect.left,rect.top,rect.right/2,rect.bottom);
421 DeleteObject (SelectObject (hdc,hBrush)) ;
422 hBrush=CreateSolidBrush(GetNearestColor(hdc,cr));
423 if (hBrush)
425 hBrush= SelectObject (hdc, hBrush) ;
426 Rectangle( hdc, rect.right/2-1,rect.top,rect.right,rect.bottom);
427 DeleteObject( SelectObject (hdc, hBrush)) ;
430 ReleaseDC(hwnd,hdc);
434 /***********************************************************************
435 * CC_PaintTriangle [internal]
437 static void CC_PaintTriangle(HWND16 hDlg,int y)
439 HDC hDC;
440 long temp;
441 int w=GetDialogBaseUnits();
442 POINT16 points[3];
443 int height;
444 int oben;
445 RECT16 rect;
446 HWND16 hwnd=GetDlgItem(hDlg,0x2be);
447 struct CCPRIVATE *lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
449 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
451 GetClientRect16(hwnd,&rect);
452 height=rect.bottom;
453 hDC=GetDC(hDlg);
455 points[0].y=rect.top;
456 points[0].x=rect.right; /* | /| */
457 ClientToScreen16(hwnd,points); /* | / | */
458 ScreenToClient16(hDlg,points); /* |< | */
459 oben=points[0].y; /* | \ | */
460 /* | \| */
461 temp=(long)height*(long)y;
462 points[0].y=oben+height -temp/(long)MAXVERT;
463 points[1].y=points[0].y+w;
464 points[2].y=points[0].y-w;
465 points[2].x=points[1].x=points[0].x + w;
467 if (lpp->old3angle.left)
468 FillRect16(hDC,&lpp->old3angle,GetStockObject(WHITE_BRUSH));
469 lpp->old3angle.left =points[0].x;
470 lpp->old3angle.right =points[1].x+1;
471 lpp->old3angle.top =points[2].y-1;
472 lpp->old3angle.bottom=points[1].y+1;
473 Polygon16(hDC,points,3);
474 ReleaseDC(hDlg,hDC);
479 /***********************************************************************
480 * CC_PaintCross [internal]
482 static void CC_PaintCross(HWND16 hDlg,int x,int y)
484 HDC hDC;
485 int w=GetDialogBaseUnits();
486 HWND16 hwnd=GetDlgItem(hDlg,0x2c6);
487 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
488 RECT16 rect;
489 POINT16 point;
490 HPEN hPen;
492 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
494 GetClientRect16(hwnd,&rect);
495 hDC=GetDC(hwnd);
496 SelectClipRgn(hDC,CreateRectRgnIndirect16(&rect));
497 hPen=CreatePen(PS_SOLID,2,0);
498 hPen=SelectObject(hDC,hPen);
499 point.x=((long)rect.right*(long)x)/(long)MAXHORI;
500 point.y=rect.bottom-((long)rect.bottom*(long)y)/(long)MAXVERT;
501 if (lpp->oldcross.left!=lpp->oldcross.right)
502 BitBlt(hDC,lpp->oldcross.left,lpp->oldcross.top,
503 lpp->oldcross.right-lpp->oldcross.left,
504 lpp->oldcross.bottom-lpp->oldcross.top,
505 lpp->hdcMem,lpp->oldcross.left,lpp->oldcross.top,SRCCOPY);
506 lpp->oldcross.left =point.x-w-1;
507 lpp->oldcross.right =point.x+w+1;
508 lpp->oldcross.top =point.y-w-1;
509 lpp->oldcross.bottom=point.y+w+1;
511 MoveTo16(hDC,point.x-w,point.y);
512 LineTo(hDC,point.x+w,point.y);
513 MoveTo16(hDC,point.x,point.y-w);
514 LineTo(hDC,point.x,point.y+w);
515 DeleteObject(SelectObject(hDC,hPen));
516 ReleaseDC(hwnd,hDC);
521 #define XSTEPS 48
522 #define YSTEPS 24
525 /***********************************************************************
526 * CC_PrepareColorGraph [internal]
528 static void CC_PrepareColorGraph(HWND16 hDlg)
530 int sdif,hdif,xdif,ydif,r,g,b,hue,sat;
531 HWND hwnd=GetDlgItem(hDlg,0x2c6);
532 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
533 HBRUSH hbrush;
534 HDC hdc ;
535 RECT16 rect,client;
536 HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT16));
538 GetClientRect16(hwnd,&client);
539 hdc=GetDC(hwnd);
540 lpp->hdcMem = CreateCompatibleDC(hdc);
541 lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
542 SelectObject(lpp->hdcMem,lpp->hbmMem);
544 xdif=client.right /XSTEPS;
545 ydif=client.bottom/YSTEPS+1;
546 hdif=239/XSTEPS;
547 sdif=240/YSTEPS;
548 for(rect.left=hue=0;hue<239+hdif;hue+=hdif)
550 rect.right=rect.left+xdif;
551 rect.bottom=client.bottom;
552 for(sat=0;sat<240+sdif;sat+=sdif)
554 rect.top=rect.bottom-ydif;
555 r=CC_HSLtoRGB('R',hue,sat,120);
556 g=CC_HSLtoRGB('G',hue,sat,120);
557 b=CC_HSLtoRGB('B',hue,sat,120);
558 hbrush=CreateSolidBrush(RGB(r,g,b));
559 FillRect16(lpp->hdcMem,&rect,hbrush);
560 DeleteObject(hbrush);
561 rect.bottom=rect.top;
563 rect.left=rect.right;
565 ReleaseDC(hwnd,hdc);
566 SetCursor16(hcursor);
569 /***********************************************************************
570 * CC_PaintColorGraph [internal]
572 static void CC_PaintColorGraph(HWND16 hDlg)
574 HWND hwnd=GetDlgItem(hDlg,0x2c6);
575 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
576 HDC hDC;
577 RECT16 rect;
578 if (IsWindowVisible(hwnd)) /* if full size */
580 if (!lpp->hdcMem)
581 CC_PrepareColorGraph(hDlg); /* should not be necessary */
583 hDC=GetDC(hwnd);
584 GetClientRect16(hwnd,&rect);
585 if (lpp->hdcMem)
586 BitBlt(hDC,0,0,rect.right,rect.bottom,lpp->hdcMem,0,0,SRCCOPY);
587 else
588 WARN(commdlg,"choose color: hdcMem is not defined\n");
589 ReleaseDC(hwnd,hDC);
592 /***********************************************************************
593 * CC_PaintLumBar [internal]
595 static void CC_PaintLumBar(HWND16 hDlg,int hue,int sat)
597 HWND hwnd=GetDlgItem(hDlg,0x2be);
598 RECT16 rect,client;
599 int lum,ldif,ydif,r,g,b;
600 HBRUSH hbrush;
601 HDC hDC;
603 if (IsWindowVisible(hwnd))
605 hDC=GetDC(hwnd);
606 GetClientRect16(hwnd,&client);
607 rect=client;
609 ldif=240/YSTEPS;
610 ydif=client.bottom/YSTEPS+1;
611 for(lum=0;lum<240+ldif;lum+=ldif)
613 rect.top=MAX(0,rect.bottom-ydif);
614 r=CC_HSLtoRGB('R',hue,sat,lum);
615 g=CC_HSLtoRGB('G',hue,sat,lum);
616 b=CC_HSLtoRGB('B',hue,sat,lum);
617 hbrush=CreateSolidBrush(RGB(r,g,b));
618 FillRect16(hDC,&rect,hbrush);
619 DeleteObject(hbrush);
620 rect.bottom=rect.top;
622 GetClientRect16(hwnd,&rect);
623 FrameRect16(hDC,&rect,GetStockObject(BLACK_BRUSH));
624 ReleaseDC(hwnd,hDC);
628 /***********************************************************************
629 * CC_EditSetRGB [internal]
631 static void CC_EditSetRGB(HWND16 hDlg,COLORREF cr)
633 char buffer[10];
634 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
635 int r=GetRValue(cr);
636 int g=GetGValue(cr);
637 int b=GetBValue(cr);
638 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
640 lpp->updating=TRUE;
641 sprintf(buffer,"%d",r);
642 SetWindowTextA(GetDlgItem(hDlg,0x2c2),buffer);
643 sprintf(buffer,"%d",g);
644 SetWindowTextA(GetDlgItem(hDlg,0x2c3),buffer);
645 sprintf(buffer,"%d",b);
646 SetWindowTextA(GetDlgItem(hDlg,0x2c4),buffer);
647 lpp->updating=FALSE;
651 /***********************************************************************
652 * CC_EditSetHSL [internal]
654 static void CC_EditSetHSL(HWND16 hDlg,int h,int s,int l)
656 char buffer[10];
657 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
658 lpp->updating=TRUE;
659 if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
661 lpp->updating=TRUE;
662 sprintf(buffer,"%d",h);
663 SetWindowTextA(GetDlgItem(hDlg,0x2bf),buffer);
664 sprintf(buffer,"%d",s);
665 SetWindowTextA(GetDlgItem(hDlg,0x2c0),buffer);
666 sprintf(buffer,"%d",l);
667 SetWindowTextA(GetDlgItem(hDlg,0x2c1),buffer);
668 lpp->updating=FALSE;
670 CC_PaintLumBar(hDlg,h,s);
673 /***********************************************************************
674 * CC_SwitchToFullSize [internal]
676 static void CC_SwitchToFullSize(HWND16 hDlg,COLORREF result,LPRECT16 lprect)
678 int i;
679 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
681 EnableWindow(GetDlgItem(hDlg,0x2cf),FALSE);
682 CC_PrepareColorGraph(hDlg);
683 for (i=0x2bf;i<0x2c5;i++)
684 EnableWindow(GetDlgItem(hDlg,i),TRUE);
685 for (i=0x2d3;i<0x2d9;i++)
686 EnableWindow(GetDlgItem(hDlg,i),TRUE);
687 EnableWindow(GetDlgItem(hDlg,0x2c9),TRUE);
688 EnableWindow(GetDlgItem(hDlg,0x2c8),TRUE);
690 if (lprect)
691 SetWindowPos(hDlg,0,0,0,lprect->right-lprect->left,
692 lprect->bottom-lprect->top, SWP_NOMOVE|SWP_NOZORDER);
694 ShowWindow(GetDlgItem(hDlg,0x2c6),SW_SHOW);
695 ShowWindow(GetDlgItem(hDlg,0x2be),SW_SHOW);
696 ShowWindow(GetDlgItem(hDlg,0x2c5),SW_SHOW);
698 CC_EditSetRGB(hDlg,result);
699 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
702 /***********************************************************************
703 * CC_PaintPredefColorArray [internal]
705 static void CC_PaintPredefColorArray(HWND16 hDlg,int rows,int cols)
707 HWND hwnd=GetDlgItem(hDlg,0x2d0);
708 RECT16 rect;
709 HDC hdc;
710 HBRUSH hBrush;
711 int dx,dy,i,j,k;
713 GetClientRect16(hwnd,&rect);
714 dx=rect.right/cols;
715 dy=rect.bottom/rows;
716 k=rect.left;
718 hdc=GetDC(hwnd);
719 GetClientRect16 (hwnd, &rect) ;
721 for (j=0;j<rows;j++)
723 for (i=0;i<cols;i++)
725 hBrush = CreateSolidBrush(predefcolors[j][i]);
726 if (hBrush)
728 hBrush = SelectObject (hdc, hBrush) ;
729 Rectangle(hdc, rect.left, rect.top,
730 rect.left+dx-DISTANCE, rect.top+dy-DISTANCE);
731 rect.left=rect.left+dx;
732 DeleteObject( SelectObject (hdc, hBrush)) ;
735 rect.top=rect.top+dy;
736 rect.left=k;
738 ReleaseDC(hwnd,hdc);
739 /* FIXME: draw_a_focus_rect */
741 /***********************************************************************
742 * CC_PaintUserColorArray [internal]
744 static void CC_PaintUserColorArray(HWND16 hDlg,int rows,int cols,COLORREF* lpcr)
746 HWND hwnd=GetDlgItem(hDlg,0x2d1);
747 RECT16 rect;
748 HDC hdc;
749 HBRUSH hBrush;
750 int dx,dy,i,j,k;
752 GetClientRect16(hwnd,&rect);
754 dx=rect.right/cols;
755 dy=rect.bottom/rows;
756 k=rect.left;
758 hdc=GetDC(hwnd);
759 if (hdc)
761 for (j=0;j<rows;j++)
763 for (i=0;i<cols;i++)
765 hBrush = CreateSolidBrush(lpcr[i+j*cols]);
766 if (hBrush)
768 hBrush = SelectObject (hdc, hBrush) ;
769 Rectangle( hdc, rect.left, rect.top,
770 rect.left+dx-DISTANCE, rect.top+dy-DISTANCE);
771 rect.left=rect.left+dx;
772 DeleteObject( SelectObject (hdc, hBrush)) ;
775 rect.top=rect.top+dy;
776 rect.left=k;
778 ReleaseDC(hwnd,hdc);
780 /* FIXME: draw_a_focus_rect */
785 /***********************************************************************
786 * CC_HookCallChk [internal]
788 static BOOL CC_HookCallChk(LPCHOOSECOLOR16 lpcc)
790 if (lpcc)
791 if(lpcc->Flags & CC_ENABLEHOOK)
792 if (lpcc->lpfnHook)
793 return TRUE;
794 return FALSE;
797 /***********************************************************************
798 * CC_WMInitDialog [internal]
800 static LONG CC_WMInitDialog(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam)
802 int i,res;
803 int r, g, b;
804 HWND16 hwnd;
805 RECT16 rect;
806 POINT16 point;
807 struct CCPRIVATE * lpp;
809 TRACE(commdlg,"WM_INITDIALOG lParam=%08lX\n", lParam);
810 lpp=calloc(1,sizeof(struct CCPRIVATE));
811 lpp->lpcc=(LPCHOOSECOLOR16)lParam;
813 if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLOR16))
815 EndDialog (hDlg, 0) ;
816 return FALSE;
818 SetWindowLongA(hDlg, DWL_USER, (LONG)lpp);
820 if (!(lpp->lpcc->Flags & CC_SHOWHELP))
821 ShowWindow(GetDlgItem(hDlg,0x40e),SW_HIDE);
822 lpp->msetrgb=RegisterWindowMessageA( SETRGBSTRING );
824 #if 0
825 cpos=MAKELONG(5,7); /* init */
826 if (lpp->lpcc->Flags & CC_RGBINIT)
828 for (i=0;i<6;i++)
829 for (j=0;j<8;j++)
830 if (predefcolors[i][j]==lpp->lpcc->rgbResult)
832 cpos=MAKELONG(i,j);
833 goto found;
836 found:
837 /* FIXME: Draw_a_focus_rect & set_init_values */
838 #endif
840 GetWindowRect16(hDlg,&lpp->fullsize);
841 if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
843 hwnd=GetDlgItem(hDlg,0x2cf);
844 EnableWindow(hwnd,FALSE);
846 if (!(lpp->lpcc->Flags & CC_FULLOPEN) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
848 rect=lpp->fullsize;
849 res=rect.bottom-rect.top;
850 hwnd=GetDlgItem(hDlg,0x2c6); /* cut at left border */
851 point.x=point.y=0;
852 ClientToScreen16(hwnd,&point);
853 ScreenToClient16(hDlg,&point);
854 GetClientRect16(hDlg,&rect);
855 point.x+=GetSystemMetrics(SM_CXDLGFRAME);
856 SetWindowPos(hDlg,0,0,0,point.x,res,SWP_NOMOVE|SWP_NOZORDER);
858 ShowWindow(GetDlgItem(hDlg,0x2c6),SW_HIDE);
859 ShowWindow(GetDlgItem(hDlg,0x2c5),SW_HIDE);
861 else
862 CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,NULL);
863 res=TRUE;
864 for (i=0x2bf;i<0x2c5;i++)
865 SendMessage16(GetDlgItem(hDlg,i),EM_LIMITTEXT16,3,0); /* max 3 digits: xyz */
866 if (CC_HookCallChk(lpp->lpcc))
867 res=CallWindowProc16(lpp->lpcc->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
870 /* Set the initial values of the color chooser dialog */
871 r = GetRValue(lpp->lpcc->rgbResult);
872 g = GetGValue(lpp->lpcc->rgbResult);
873 b = GetBValue(lpp->lpcc->rgbResult);
875 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
876 lpp->h=CC_RGBtoHSL('H',r,g,b);
877 lpp->s=CC_RGBtoHSL('S',r,g,b);
878 lpp->l=CC_RGBtoHSL('L',r,g,b);
880 /* Doing it the long way becaus CC_EditSetRGB/HSL doesn'nt seem to work */
881 SetDlgItemInt(hDlg, 703, lpp->h, TRUE);
882 SetDlgItemInt(hDlg, 704, lpp->s, TRUE);
883 SetDlgItemInt(hDlg, 705, lpp->l, TRUE);
884 SetDlgItemInt(hDlg, 706, r, TRUE);
885 SetDlgItemInt(hDlg, 707, g, TRUE);
886 SetDlgItemInt(hDlg, 708, b, TRUE);
888 CC_PaintCross(hDlg,lpp->h,lpp->s);
889 CC_PaintTriangle(hDlg,lpp->l);
891 return res;
894 /***********************************************************************
895 * CC_WMCommand [internal]
897 static LRESULT CC_WMCommand(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam)
899 int r,g,b,i,xx;
900 UINT16 cokmsg;
901 HDC hdc;
902 COLORREF *cr;
903 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
904 TRACE(commdlg,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
905 switch (wParam)
907 case 0x2c2: /* edit notify RGB */
908 case 0x2c3:
909 case 0x2c4:
910 if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
912 i=CC_CheckDigitsInEdit(LOWORD(lParam),255);
913 r=GetRValue(lpp->lpcc->rgbResult);
914 g=GetGValue(lpp->lpcc->rgbResult);
915 b=GetBValue(lpp->lpcc->rgbResult);
916 xx=0;
917 switch (wParam)
919 case 0x2c2:if ((xx=(i!=r))) r=i;break;
920 case 0x2c3:if ((xx=(i!=g))) g=i;break;
921 case 0x2c4:if ((xx=(i!=b))) b=i;break;
923 if (xx) /* something has changed */
925 lpp->lpcc->rgbResult=RGB(r,g,b);
926 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
927 lpp->h=CC_RGBtoHSL('H',r,g,b);
928 lpp->s=CC_RGBtoHSL('S',r,g,b);
929 lpp->l=CC_RGBtoHSL('L',r,g,b);
930 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
931 CC_PaintCross(hDlg,lpp->h,lpp->s);
932 CC_PaintTriangle(hDlg,lpp->l);
935 break;
937 case 0x2bf: /* edit notify HSL */
938 case 0x2c0:
939 case 0x2c1:
940 if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
942 i=CC_CheckDigitsInEdit(LOWORD(lParam),wParam==0x2bf?239:240);
943 xx=0;
944 switch (wParam)
946 case 0x2bf:if ((xx=(i!=lpp->h))) lpp->h=i;break;
947 case 0x2c0:if ((xx=(i!=lpp->s))) lpp->s=i;break;
948 case 0x2c1:if ((xx=(i!=lpp->l))) lpp->l=i;break;
950 if (xx) /* something has changed */
952 r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
953 g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
954 b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
955 lpp->lpcc->rgbResult=RGB(r,g,b);
956 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
957 CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
958 CC_PaintCross(hDlg,lpp->h,lpp->s);
959 CC_PaintTriangle(hDlg,lpp->l);
962 break;
964 case 0x2cf:
965 CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,&lpp->fullsize);
966 InvalidateRect( hDlg, NULL, TRUE );
967 SetFocus(GetDlgItem(hDlg,0x2bf));
968 break;
970 case 0x2c8: /* add colors ... column by column */
971 cr=PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors);
972 cr[(lpp->nextuserdef%2)*8 + lpp->nextuserdef/2]=lpp->lpcc->rgbResult;
973 if (++lpp->nextuserdef==16)
974 lpp->nextuserdef=0;
975 CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
976 break;
978 case 0x2c9: /* resulting color */
979 hdc=GetDC(hDlg);
980 lpp->lpcc->rgbResult=GetNearestColor(hdc,lpp->lpcc->rgbResult);
981 ReleaseDC(hDlg,hdc);
982 CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
983 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
984 r=GetRValue(lpp->lpcc->rgbResult);
985 g=GetGValue(lpp->lpcc->rgbResult);
986 b=GetBValue(lpp->lpcc->rgbResult);
987 lpp->h=CC_RGBtoHSL('H',r,g,b);
988 lpp->s=CC_RGBtoHSL('S',r,g,b);
989 lpp->l=CC_RGBtoHSL('L',r,g,b);
990 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
991 CC_PaintCross(hDlg,lpp->h,lpp->s);
992 CC_PaintTriangle(hDlg,lpp->l);
993 break;
995 case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */
996 i=RegisterWindowMessageA( HELPMSGSTRING );
997 if (lpp->lpcc->hwndOwner)
998 SendMessage16(lpp->lpcc->hwndOwner,i,0,(LPARAM)lpp->lpcc);
999 if (CC_HookCallChk(lpp->lpcc))
1000 CallWindowProc16(lpp->lpcc->lpfnHook,hDlg,
1001 WM_COMMAND,psh15,(LPARAM)lpp->lpcc);
1002 break;
1004 case IDOK :
1005 cokmsg=RegisterWindowMessageA( COLOROKSTRING );
1006 if (lpp->lpcc->hwndOwner)
1007 if (SendMessage16(lpp->lpcc->hwndOwner,cokmsg,0,(LPARAM)lpp->lpcc))
1008 break; /* do NOT close */
1010 EndDialog (hDlg, 1) ;
1011 return TRUE ;
1013 case IDCANCEL :
1014 EndDialog (hDlg, 0) ;
1015 return TRUE ;
1018 return FALSE;
1021 /***********************************************************************
1022 * CC_WMPaint [internal]
1024 static LRESULT CC_WMPaint(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam)
1026 HDC hdc;
1027 PAINTSTRUCT ps;
1028 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1030 hdc=BeginPaint(hDlg,&ps);
1031 EndPaint(hDlg,&ps);
1032 /* we have to paint dialog children except text and buttons */
1034 CC_PaintPredefColorArray(hDlg,6,8);
1035 CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
1036 CC_PaintColorGraph(hDlg);
1037 CC_PaintLumBar(hDlg,lpp->h,lpp->s);
1038 CC_PaintCross(hDlg,lpp->h,lpp->s);
1039 CC_PaintTriangle(hDlg,lpp->l);
1040 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1042 /* special necessary for Wine */
1043 ValidateRect(GetDlgItem(hDlg,0x2d0),NULL);
1044 ValidateRect(GetDlgItem(hDlg,0x2d1),NULL);
1045 ValidateRect(GetDlgItem(hDlg,0x2c6),NULL);
1046 ValidateRect(GetDlgItem(hDlg,0x2be),NULL);
1047 ValidateRect(GetDlgItem(hDlg,0x2c5),NULL);
1048 /* hope we can remove it later -->FIXME */
1049 return TRUE;
1053 /***********************************************************************
1054 * CC_WMLButtonDown [internal]
1056 static LRESULT CC_WMLButtonDown(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam)
1058 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1059 int r,g,b,i;
1060 i=0;
1061 if (CC_MouseCheckPredefColorArray(hDlg,0x2d0,6,8,lParam,&lpp->lpcc->rgbResult))
1062 i=1;
1063 else
1064 if (CC_MouseCheckUserColorArray(hDlg,0x2d1,2,8,lParam,&lpp->lpcc->rgbResult,
1065 PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors)))
1066 i=1;
1067 else
1068 if (CC_MouseCheckColorGraph(hDlg,0x2c6,&lpp->h,&lpp->s,lParam))
1069 i=2;
1070 else
1071 if (CC_MouseCheckColorGraph(hDlg,0x2be,NULL,&lpp->l,lParam))
1072 i=2;
1073 if (i==2)
1075 r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
1076 g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
1077 b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
1078 lpp->lpcc->rgbResult=RGB(r,g,b);
1080 if (i==1)
1082 r=GetRValue(lpp->lpcc->rgbResult);
1083 g=GetGValue(lpp->lpcc->rgbResult);
1084 b=GetBValue(lpp->lpcc->rgbResult);
1085 lpp->h=CC_RGBtoHSL('H',r,g,b);
1086 lpp->s=CC_RGBtoHSL('S',r,g,b);
1087 lpp->l=CC_RGBtoHSL('L',r,g,b);
1089 if (i)
1091 CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
1092 CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1093 CC_PaintCross(hDlg,lpp->h,lpp->s);
1094 CC_PaintTriangle(hDlg,lpp->l);
1095 CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1096 return TRUE;
1098 return FALSE;
1101 /***********************************************************************
1102 * ColorDlgProc (COMMDLG.8)
1104 LRESULT WINAPI ColorDlgProc16(HWND16 hDlg, UINT16 message,
1105 WPARAM16 wParam, LONG lParam)
1107 int res;
1108 struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1109 if (message!=WM_INITDIALOG)
1111 if (!lpp)
1112 return FALSE;
1113 res=0;
1114 if (CC_HookCallChk(lpp->lpcc))
1115 res=CallWindowProc16(lpp->lpcc->lpfnHook,hDlg,message,wParam,lParam);
1116 if (res)
1117 return res;
1120 /* FIXME: SetRGB message
1121 if (message && message==msetrgb)
1122 return HandleSetRGB(hDlg,lParam);
1125 switch (message)
1127 case WM_INITDIALOG:
1128 return CC_WMInitDialog(hDlg,wParam,lParam);
1129 case WM_NCDESTROY:
1130 DeleteDC(lpp->hdcMem);
1131 DeleteObject(lpp->hbmMem);
1132 free(lpp);
1133 SetWindowLongA(hDlg, DWL_USER, 0L); /* we don't need it anymore */
1134 break;
1135 case WM_COMMAND:
1136 if (CC_WMCommand(hDlg, wParam, lParam))
1137 return TRUE;
1138 break;
1139 case WM_PAINT:
1140 if (CC_WMPaint(hDlg, wParam, lParam))
1141 return TRUE;
1142 break;
1143 case WM_LBUTTONDBLCLK:
1144 if (CC_MouseCheckResultWindow(hDlg,lParam))
1145 return TRUE;
1146 break;
1147 case WM_MOUSEMOVE: /* FIXME: calculate new hue,sat,lum (if in color graph) */
1148 break;
1149 case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/
1150 break;
1151 case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/
1152 if (CC_WMLButtonDown(hDlg, wParam, lParam))
1153 return TRUE;
1154 break;
1156 return FALSE ;
1160 /***********************************************************************
1161 * ChooseColorA (COMDLG32.1)
1163 BOOL WINAPI ChooseColorA(LPCHOOSECOLORA lpChCol )
1166 BOOL16 ret;
1167 char *str = NULL;
1168 COLORREF* ccref=SEGPTR_ALLOC(64);
1169 LPCHOOSECOLOR16 lpcc16=SEGPTR_ALLOC(sizeof(CHOOSECOLOR16));
1171 memset(lpcc16,'\0',sizeof(*lpcc16));
1172 lpcc16->lStructSize=sizeof(*lpcc16);
1173 lpcc16->hwndOwner=lpChCol->hwndOwner;
1174 lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance);
1175 lpcc16->rgbResult=lpChCol->rgbResult;
1176 memcpy(ccref,lpChCol->lpCustColors,64);
1177 lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
1178 lpcc16->Flags=lpChCol->Flags;
1179 lpcc16->lCustData=lpChCol->lCustData;
1180 lpcc16->lpfnHook=(WNDPROC16)lpChCol->lpfnHook;
1181 if (lpChCol->lpTemplateName)
1182 str = SEGPTR_STRDUP(lpChCol->lpTemplateName );
1183 lpcc16->lpTemplateName=SEGPTR_GET(str);
1185 ret = ChooseColor16(lpcc16);
1187 if(ret)
1188 lpChCol->rgbResult = lpcc16->rgbResult;
1190 if(str)
1191 SEGPTR_FREE(str);
1192 memcpy(lpChCol->lpCustColors,ccref,64);
1193 SEGPTR_FREE(ccref);
1194 SEGPTR_FREE(lpcc16);
1195 return (BOOL)ret;
1198 /***********************************************************************
1199 * ChooseColorW (COMDLG32.2)
1201 BOOL WINAPI ChooseColorW(LPCHOOSECOLORW lpChCol )
1204 BOOL16 ret;
1205 char *str = NULL;
1206 COLORREF* ccref=SEGPTR_ALLOC(64);
1207 LPCHOOSECOLOR16 lpcc16=SEGPTR_ALLOC(sizeof(CHOOSECOLOR16));
1209 memset(lpcc16,'\0',sizeof(*lpcc16));
1210 lpcc16->lStructSize=sizeof(*lpcc16);
1211 lpcc16->hwndOwner=lpChCol->hwndOwner;
1212 lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance);
1213 lpcc16->rgbResult=lpChCol->rgbResult;
1214 memcpy(ccref,lpChCol->lpCustColors,64);
1215 lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
1216 lpcc16->Flags=lpChCol->Flags;
1217 lpcc16->lCustData=lpChCol->lCustData;
1218 lpcc16->lpfnHook=(WNDPROC16)lpChCol->lpfnHook;
1219 if (lpChCol->lpTemplateName)
1220 str = SEGPTR_STRDUP_WtoA(lpChCol->lpTemplateName );
1221 lpcc16->lpTemplateName=SEGPTR_GET(str);
1223 ret = ChooseColor16(lpcc16);
1225 if(ret)
1226 lpChCol->rgbResult = lpcc16->rgbResult;
1228 if(str)
1229 SEGPTR_FREE(str);
1230 memcpy(lpChCol->lpCustColors,ccref,64);
1231 SEGPTR_FREE(ccref);
1232 SEGPTR_FREE(lpcc16);
1233 return (BOOL)ret;