1*c2c66affSColin Finck //
2*c2c66affSColin Finck //    CardLib - CardWindow class
3*c2c66affSColin Finck //
4*c2c66affSColin Finck //    Freeware
5*c2c66affSColin Finck //    Copyright J Brown 2001
6*c2c66affSColin Finck //
7*c2c66affSColin Finck 
8*c2c66affSColin Finck #include "cardlib.h"
9*c2c66affSColin Finck 
10*c2c66affSColin Finck #include <tchar.h>
11*c2c66affSColin Finck 
12*c2c66affSColin Finck extern HPALETTE __holdplacepal;
13*c2c66affSColin Finck 
UseNicePalette(HDC hdc,HPALETTE hPalette)14*c2c66affSColin Finck HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette)
15*c2c66affSColin Finck {
16*c2c66affSColin Finck     HPALETTE hOld;
17*c2c66affSColin Finck 
18*c2c66affSColin Finck     hOld = SelectPalette(hdc, hPalette, FALSE);
19*c2c66affSColin Finck     RealizePalette(hdc);
20*c2c66affSColin Finck 
21*c2c66affSColin Finck     return hOld;
22*c2c66affSColin Finck }
23*c2c66affSColin Finck 
RestorePalette(HDC hdc,HPALETTE hOldPal)24*c2c66affSColin Finck void RestorePalette(HDC hdc, HPALETTE hOldPal)
25*c2c66affSColin Finck {
26*c2c66affSColin Finck     SelectPalette(hdc, hOldPal, TRUE);
27*c2c66affSColin Finck }
28*c2c66affSColin Finck 
29*c2c66affSColin Finck HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours);
30*c2c66affSColin Finck void     PaintRect(HDC hdc, RECT *rect, COLORREF colour);
31*c2c66affSColin Finck HBITMAP  CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height);
32*c2c66affSColin Finck void     GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2);
33*c2c66affSColin Finck 
34*c2c66affSColin Finck void     LoadCardBitmaps();
35*c2c66affSColin Finck void     FreeCardBitmaps();
36*c2c66affSColin Finck 
37*c2c66affSColin Finck static TCHAR szCardName[]   = _T("CardWnd32");
38*c2c66affSColin Finck static bool  fRegistered    = false;
39*c2c66affSColin Finck static LONG  uCardBitmapRef = 0;
40*c2c66affSColin Finck 
41*c2c66affSColin Finck 
RegisterCardWindow()42*c2c66affSColin Finck void RegisterCardWindow()
43*c2c66affSColin Finck {
44*c2c66affSColin Finck     WNDCLASSEX wc;
45*c2c66affSColin Finck 
46*c2c66affSColin Finck     //Window class for the main application parent window
47*c2c66affSColin Finck     wc.cbSize            = sizeof(wc);
48*c2c66affSColin Finck     wc.style            = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
49*c2c66affSColin Finck     wc.lpfnWndProc        = CardWindow::CardWndProc;
50*c2c66affSColin Finck     wc.cbClsExtra        = 0;
51*c2c66affSColin Finck     wc.cbWndExtra        = sizeof(CardWindow *);
52*c2c66affSColin Finck     wc.hInstance        = GetModuleHandle(0);
53*c2c66affSColin Finck     wc.hIcon            = 0;
54*c2c66affSColin Finck     wc.hCursor            = LoadCursor (NULL, IDC_ARROW);
55*c2c66affSColin Finck     wc.hbrBackground    = 0;
56*c2c66affSColin Finck     wc.lpszMenuName        = 0;
57*c2c66affSColin Finck     wc.lpszClassName    = szCardName;
58*c2c66affSColin Finck     wc.hIconSm            = 0;
59*c2c66affSColin Finck 
60*c2c66affSColin Finck     RegisterClassEx(&wc);
61*c2c66affSColin Finck }
62*c2c66affSColin Finck 
CardWindow()63*c2c66affSColin Finck CardWindow::CardWindow() : m_hWnd(0)
64*c2c66affSColin Finck {
65*c2c66affSColin Finck     HDC hdc = GetDC(0);
66*c2c66affSColin Finck 
67*c2c66affSColin Finck     nNumButtons       = 0;
68*c2c66affSColin Finck     nNumCardRegions   = 0;
69*c2c66affSColin Finck     nNumDropZones     = 0;
70*c2c66affSColin Finck     nBackCardIdx      = 53;
71*c2c66affSColin Finck 
72*c2c66affSColin Finck     ResizeWndCallback = 0;
73*c2c66affSColin Finck     hbmBackImage      = 0;
74*c2c66affSColin Finck     hdcBackImage      = 0;
75*c2c66affSColin Finck 
76*c2c66affSColin Finck     srand((unsigned)GetTickCount());
77*c2c66affSColin Finck 
78*c2c66affSColin Finck     //All colours (buttons, highlights, decks)
79*c2c66affSColin Finck     //are calculated off this single base colour
80*c2c66affSColin Finck     crBackgnd = PALETTERGB(0,80,0);//PALETTERGB(0,64,100);
81*c2c66affSColin Finck 
82*c2c66affSColin Finck     // If uCardBitmapRef was previously zero, then
83*c2c66affSColin Finck     // load the card bitmaps
84*c2c66affSColin Finck     if(1 == InterlockedIncrement(&uCardBitmapRef))
85*c2c66affSColin Finck     {
86*c2c66affSColin Finck         LoadCardBitmaps();
87*c2c66affSColin Finck 
88*c2c66affSColin Finck         __hPalette  = CreateCardPalette();
89*c2c66affSColin Finck 
90*c2c66affSColin Finck         __hdcPlaceHolder  = CreateCompatibleDC(hdc);
91*c2c66affSColin Finck 
92*c2c66affSColin Finck         __holdplacepal  = UseNicePalette(__hdcPlaceHolder, __hPalette);
93*c2c66affSColin Finck 
94*c2c66affSColin Finck         __hbmPlaceHolder  = CreateSinkBmp(hdc, __hdcPlaceHolder, crBackgnd, __cardwidth, __cardheight);
95*c2c66affSColin Finck 
96*c2c66affSColin Finck     }
97*c2c66affSColin Finck 
98*c2c66affSColin Finck     ReleaseDC(0, hdc);
99*c2c66affSColin Finck 
100*c2c66affSColin Finck     //register the window class if necessary
101*c2c66affSColin Finck     if(!fRegistered)
102*c2c66affSColin Finck     {
103*c2c66affSColin Finck         fRegistered = true;
104*c2c66affSColin Finck         RegisterCardWindow();
105*c2c66affSColin Finck     }
106*c2c66affSColin Finck 
107*c2c66affSColin Finck }
108*c2c66affSColin Finck 
Create(HWND hwndParent,DWORD dwExStyle,DWORD dwStyle,int x,int y,int width,int height)109*c2c66affSColin Finck BOOL CardWindow::Create(HWND hwndParent, DWORD dwExStyle, DWORD dwStyle, int x, int y, int width, int height)
110*c2c66affSColin Finck {
111*c2c66affSColin Finck     if(m_hWnd)
112*c2c66affSColin Finck         return FALSE;
113*c2c66affSColin Finck 
114*c2c66affSColin Finck     //Create the window associated with this object
115*c2c66affSColin Finck     m_hWnd = CreateWindowEx(dwExStyle, szCardName, NULL,
116*c2c66affSColin Finck                             dwStyle,
117*c2c66affSColin Finck                             x, y, width, height,
118*c2c66affSColin Finck                             hwndParent, NULL, GetModuleHandle(NULL), this);
119*c2c66affSColin Finck 
120*c2c66affSColin Finck     return TRUE;
121*c2c66affSColin Finck }
122*c2c66affSColin Finck 
Destroy()123*c2c66affSColin Finck BOOL CardWindow::Destroy()
124*c2c66affSColin Finck {
125*c2c66affSColin Finck     DestroyWindow(m_hWnd);
126*c2c66affSColin Finck     m_hWnd = 0;
127*c2c66affSColin Finck 
128*c2c66affSColin Finck     return TRUE;
129*c2c66affSColin Finck }
130*c2c66affSColin Finck 
~CardWindow()131*c2c66affSColin Finck CardWindow::~CardWindow()
132*c2c66affSColin Finck {
133*c2c66affSColin Finck     if(m_hWnd)
134*c2c66affSColin Finck         DestroyWindow(m_hWnd);
135*c2c66affSColin Finck 
136*c2c66affSColin Finck     DeleteAll();
137*c2c66affSColin Finck 
138*c2c66affSColin Finck     if(0 == InterlockedDecrement(&uCardBitmapRef))
139*c2c66affSColin Finck     {
140*c2c66affSColin Finck         FreeCardBitmaps();
141*c2c66affSColin Finck 
142*c2c66affSColin Finck         DeleteObject(__hbmPlaceHolder);
143*c2c66affSColin Finck         DeleteDC    (__hdcPlaceHolder);
144*c2c66affSColin Finck 
145*c2c66affSColin Finck         RestorePalette(__hdcPlaceHolder, __holdplacepal);
146*c2c66affSColin Finck 
147*c2c66affSColin Finck         if(__hPalette)
148*c2c66affSColin Finck             DeleteObject(__hPalette);
149*c2c66affSColin Finck     }
150*c2c66affSColin Finck }
151*c2c66affSColin Finck 
DeleteAll()152*c2c66affSColin Finck bool CardWindow::DeleteAll()
153*c2c66affSColin Finck {
154*c2c66affSColin Finck     int i;
155*c2c66affSColin Finck 
156*c2c66affSColin Finck     for(i = 0; i < nNumCardRegions; i++)
157*c2c66affSColin Finck     {
158*c2c66affSColin Finck         delete Regions[i];
159*c2c66affSColin Finck     }
160*c2c66affSColin Finck 
161*c2c66affSColin Finck     for(i = 0; i < nNumButtons; i++)
162*c2c66affSColin Finck     {
163*c2c66affSColin Finck         delete Buttons[i];
164*c2c66affSColin Finck     }
165*c2c66affSColin Finck 
166*c2c66affSColin Finck     for(i = 0; i < nNumDropZones; i++)
167*c2c66affSColin Finck     {
168*c2c66affSColin Finck         delete dropzone[i];
169*c2c66affSColin Finck     }
170*c2c66affSColin Finck 
171*c2c66affSColin Finck     nNumCardRegions = nNumButtons = nNumDropZones = 0;
172*c2c66affSColin Finck 
173*c2c66affSColin Finck     return true;
174*c2c66affSColin Finck }
175*c2c66affSColin Finck 
SetBackColor(COLORREF cr)176*c2c66affSColin Finck void CardWindow::SetBackColor(COLORREF cr)
177*c2c66affSColin Finck {
178*c2c66affSColin Finck     crBackgnd = cr;
179*c2c66affSColin Finck     int i;
180*c2c66affSColin Finck 
181*c2c66affSColin Finck     //
182*c2c66affSColin Finck     // Create the exact palette we need to render the buttons/stacks
183*c2c66affSColin Finck     //
184*c2c66affSColin Finck     RestorePalette(__hdcPlaceHolder, __holdplacepal);
185*c2c66affSColin Finck 
186*c2c66affSColin Finck     if(__hPalette)
187*c2c66affSColin Finck         DeleteObject(__hPalette);
188*c2c66affSColin Finck 
189*c2c66affSColin Finck     __hPalette = CreateCardPalette();
190*c2c66affSColin Finck 
191*c2c66affSColin Finck     //
192*c2c66affSColin Finck     // re-create the place-holder!
193*c2c66affSColin Finck     HDC hdc = GetDC(m_hWnd);
194*c2c66affSColin Finck 
195*c2c66affSColin Finck     DeleteObject(__hbmPlaceHolder);
196*c2c66affSColin Finck 
197*c2c66affSColin Finck     __holdplacepal = UseNicePalette(__hdcPlaceHolder, __hPalette);
198*c2c66affSColin Finck 
199*c2c66affSColin Finck     __hbmPlaceHolder = CreateSinkBmp(hdc, __hdcPlaceHolder, crBackgnd, __cardwidth, __cardheight);
200*c2c66affSColin Finck     //SelectObject(__hdcPlaceHolder, __hbmPlaceHolder);
201*c2c66affSColin Finck 
202*c2c66affSColin Finck     //reset all buttons to same colour
203*c2c66affSColin Finck     for(i = 0; i < nNumButtons; i++)
204*c2c66affSColin Finck     {
205*c2c66affSColin Finck         if(Buttons[i]->GetStyle() & CB_PUSHBUTTON)
206*c2c66affSColin Finck         {
207*c2c66affSColin Finck             Buttons[i]->SetBackColor(ColorScaleRGB(crBackgnd, RGB(255,255,255), 0.1));
208*c2c66affSColin Finck         }
209*c2c66affSColin Finck         else
210*c2c66affSColin Finck         {
211*c2c66affSColin Finck             Buttons[i]->SetBackColor(crBackgnd);
212*c2c66affSColin Finck         }
213*c2c66affSColin Finck     }
214*c2c66affSColin Finck 
215*c2c66affSColin Finck     for(i = 0; i < nNumCardRegions; i++)
216*c2c66affSColin Finck     {
217*c2c66affSColin Finck         Regions[i]->SetBackColor(crBackgnd);
218*c2c66affSColin Finck     }
219*c2c66affSColin Finck 
220*c2c66affSColin Finck 
221*c2c66affSColin Finck     ReleaseDC(m_hWnd, hdc);
222*c2c66affSColin Finck }
223*c2c66affSColin Finck 
GetBackColor()224*c2c66affSColin Finck COLORREF CardWindow::GetBackColor()
225*c2c66affSColin Finck {
226*c2c66affSColin Finck     return crBackgnd;
227*c2c66affSColin Finck }
228*c2c66affSColin Finck 
CardButtonFromPoint(int x,int y)229*c2c66affSColin Finck CardButton* CardWindow::CardButtonFromPoint(int x, int y)
230*c2c66affSColin Finck {
231*c2c66affSColin Finck     CardButton *bptr = 0;
232*c2c66affSColin Finck 
233*c2c66affSColin Finck     POINT pt;
234*c2c66affSColin Finck     pt.x = x;
235*c2c66affSColin Finck     pt.y = y;
236*c2c66affSColin Finck 
237*c2c66affSColin Finck     //Search BACKWARDS...to reflect the implicit Z-order that
238*c2c66affSColin Finck     //the button creation provided
239*c2c66affSColin Finck     for(int i = nNumButtons - 1; i >= 0; i--)
240*c2c66affSColin Finck     {
241*c2c66affSColin Finck         bptr = Buttons[i];
242*c2c66affSColin Finck         if(PtInRect(&bptr->rect, pt) && bptr->fVisible)
243*c2c66affSColin Finck             return bptr;
244*c2c66affSColin Finck     }
245*c2c66affSColin Finck 
246*c2c66affSColin Finck     return 0;
247*c2c66affSColin Finck }
248*c2c66affSColin Finck 
CardRegionFromPoint(int x,int y)249*c2c66affSColin Finck CardRegion* CardWindow::CardRegionFromPoint(int x, int y)
250*c2c66affSColin Finck {
251*c2c66affSColin Finck     POINT pt;
252*c2c66affSColin Finck     pt.x = x;
253*c2c66affSColin Finck     pt.y = y;
254*c2c66affSColin Finck 
255*c2c66affSColin Finck     //Search BACKWARDS...to reflect the implicit Z-order that
256*c2c66affSColin Finck     //the stack creation provided
257*c2c66affSColin Finck     for(int i = nNumCardRegions - 1; i >= 0; i--)
258*c2c66affSColin Finck     {
259*c2c66affSColin Finck         if(Regions[i]->IsPointInStack(x, y))
260*c2c66affSColin Finck             return Regions[i];
261*c2c66affSColin Finck     }
262*c2c66affSColin Finck 
263*c2c66affSColin Finck     return 0;
264*c2c66affSColin Finck }
265*c2c66affSColin Finck 
266*c2c66affSColin Finck //
267*c2c66affSColin Finck //    Forward all window messages onto the appropriate
268*c2c66affSColin Finck //  class instance
269*c2c66affSColin Finck //
CardWndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)270*c2c66affSColin Finck LRESULT CALLBACK CardWindow::CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
271*c2c66affSColin Finck {
272*c2c66affSColin Finck     CardWindow *cw = (CardWindow *)GetWindowLongPtr(hwnd, 0);
273*c2c66affSColin Finck     return cw->WndProc(hwnd, iMsg, wParam, lParam);
274*c2c66affSColin Finck }
275*c2c66affSColin Finck 
Paint(HDC hdc)276*c2c66affSColin Finck void CardWindow::Paint(HDC hdc)
277*c2c66affSColin Finck {
278*c2c66affSColin Finck     int i;
279*c2c66affSColin Finck     RECT rect;
280*c2c66affSColin Finck     HPALETTE hOldPal;
281*c2c66affSColin Finck 
282*c2c66affSColin Finck     hOldPal = UseNicePalette(hdc, __hPalette);
283*c2c66affSColin Finck 
284*c2c66affSColin Finck     //
285*c2c66affSColin Finck     //    Clip the card stacks so that they won't
286*c2c66affSColin Finck     //    get painted over
287*c2c66affSColin Finck     //
288*c2c66affSColin Finck     for(i = 0; i < nNumCardRegions; i++)
289*c2c66affSColin Finck     {
290*c2c66affSColin Finck         Regions[i]->Clip(hdc);
291*c2c66affSColin Finck     }
292*c2c66affSColin Finck 
293*c2c66affSColin Finck     //
294*c2c66affSColin Finck     //    Clip the buttons
295*c2c66affSColin Finck     //
296*c2c66affSColin Finck     for(i = 0; i < nNumButtons; i++)
297*c2c66affSColin Finck     {
298*c2c66affSColin Finck         Buttons[i]->Clip(hdc);
299*c2c66affSColin Finck     }
300*c2c66affSColin Finck 
301*c2c66affSColin Finck 
302*c2c66affSColin Finck     //    Now paint the whole screen with background colour,
303*c2c66affSColin Finck     //
304*c2c66affSColin Finck     GetClientRect(m_hWnd, &rect);
305*c2c66affSColin Finck 
306*c2c66affSColin Finck     //PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
307*c2c66affSColin Finck     PaintCardRgn(hdc, 0, 0, rect.right, rect.bottom, 0, 0);
308*c2c66affSColin Finck     SelectClipRgn(hdc, NULL);
309*c2c66affSColin Finck 
310*c2c66affSColin Finck     //    Don't let cards draw over buttons, so clip buttons again
311*c2c66affSColin Finck     //
312*c2c66affSColin Finck     for(i = 0; i < nNumButtons; i++)
313*c2c66affSColin Finck     {
314*c2c66affSColin Finck         Buttons[i]->Clip(hdc);
315*c2c66affSColin Finck     }
316*c2c66affSColin Finck 
317*c2c66affSColin Finck     //    Paint each card stack in turn
318*c2c66affSColin Finck     //
319*c2c66affSColin Finck     for(i = 0; i < nNumCardRegions; i++)
320*c2c66affSColin Finck     {
321*c2c66affSColin Finck         Regions[i]->Render(hdc);
322*c2c66affSColin Finck     }
323*c2c66affSColin Finck 
324*c2c66affSColin Finck     //    Paint each button now
325*c2c66affSColin Finck     //
326*c2c66affSColin Finck     SelectClipRgn(hdc, NULL);
327*c2c66affSColin Finck 
328*c2c66affSColin Finck     for(i = 0; i < nNumButtons; i++)
329*c2c66affSColin Finck     {
330*c2c66affSColin Finck         Buttons[i]->Redraw();
331*c2c66affSColin Finck     }
332*c2c66affSColin Finck 
333*c2c66affSColin Finck     RestorePalette(hdc, hOldPal);
334*c2c66affSColin Finck }
335*c2c66affSColin Finck 
336*c2c66affSColin Finck 
337*c2c66affSColin Finck 
338*c2c66affSColin Finck 
WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)339*c2c66affSColin Finck LRESULT CALLBACK CardWindow::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
340*c2c66affSColin Finck {
341*c2c66affSColin Finck     HDC hdc;
342*c2c66affSColin Finck     PAINTSTRUCT ps;
343*c2c66affSColin Finck 
344*c2c66affSColin Finck     CREATESTRUCT *cs;
345*c2c66affSColin Finck 
346*c2c66affSColin Finck     static CardButton *buttonptr   = 0;
347*c2c66affSColin Finck     static CardRegion *stackptr    = 0;
348*c2c66affSColin Finck 
349*c2c66affSColin Finck     int x, y, i;
350*c2c66affSColin Finck 
351*c2c66affSColin Finck     switch(iMsg)
352*c2c66affSColin Finck     {
353*c2c66affSColin Finck     case WM_NCCREATE:
354*c2c66affSColin Finck 
355*c2c66affSColin Finck         // When we created this window, we passed in the
356*c2c66affSColin Finck         // pointer to the class object (CardWindow *) in the
357*c2c66affSColin Finck         // call to CreateWindow.
358*c2c66affSColin Finck         cs = (CREATESTRUCT *)lParam;
359*c2c66affSColin Finck 
360*c2c66affSColin Finck         //
361*c2c66affSColin Finck         // associate this class with the window
362*c2c66affSColin Finck         //
363*c2c66affSColin Finck         SetWindowLongPtr(hwnd, 0, (LONG_PTR)cs->lpCreateParams);
364*c2c66affSColin Finck 
365*c2c66affSColin Finck         return 1;
366*c2c66affSColin Finck 
367*c2c66affSColin Finck     case WM_NCDESTROY:
368*c2c66affSColin Finck         // Don't delete anything here..
369*c2c66affSColin Finck         break;
370*c2c66affSColin Finck 
371*c2c66affSColin Finck     case WM_SIZE:
372*c2c66affSColin Finck         nWidth = LOWORD(lParam);
373*c2c66affSColin Finck         nHeight = HIWORD(lParam);
374*c2c66affSColin Finck 
375*c2c66affSColin Finck         //
376*c2c66affSColin Finck         // reposition all the stacks and buttons
377*c2c66affSColin Finck         // in case any of them are centered, right-justified etc
378*c2c66affSColin Finck         //
379*c2c66affSColin Finck         for(i = 0; i < nNumCardRegions; i++)
380*c2c66affSColin Finck         {
381*c2c66affSColin Finck             Regions[i]->AdjustPosition(nWidth, nHeight);
382*c2c66affSColin Finck         }
383*c2c66affSColin Finck 
384*c2c66affSColin Finck         for(i = 0; i < nNumButtons; i++)
385*c2c66affSColin Finck         {
386*c2c66affSColin Finck             Buttons[i]->AdjustPosition(nWidth, nHeight);
387*c2c66affSColin Finck         }
388*c2c66affSColin Finck 
389*c2c66affSColin Finck         //
390*c2c66affSColin Finck         // Call the user-defined resize proc AFTER all the stacks
391*c2c66affSColin Finck         // have been positioned
392*c2c66affSColin Finck         //
393*c2c66affSColin Finck         if(ResizeWndCallback)
394*c2c66affSColin Finck             ResizeWndCallback(nWidth, nHeight);
395*c2c66affSColin Finck 
396*c2c66affSColin Finck         return 0;
397*c2c66affSColin Finck 
398*c2c66affSColin Finck     case WM_PAINT:
399*c2c66affSColin Finck 
400*c2c66affSColin Finck         hdc = BeginPaint(hwnd, &ps);
401*c2c66affSColin Finck 
402*c2c66affSColin Finck         Paint(hdc);
403*c2c66affSColin Finck 
404*c2c66affSColin Finck         EndPaint(hwnd, &ps);
405*c2c66affSColin Finck         return 0;
406*c2c66affSColin Finck 
407*c2c66affSColin Finck     case WM_TIMER:
408*c2c66affSColin Finck 
409*c2c66affSColin Finck         //find the timer object in the registered funcs
410*c2c66affSColin Finck         /*if(wParam >= 0x10000)
411*c2c66affSColin Finck         {
412*c2c66affSColin Finck             for(i = 0; i < nRegFuncs; i++)
413*c2c66affSColin Finck             {
414*c2c66affSColin Finck                 if(RegFuncs[i].id == wParam)
415*c2c66affSColin Finck                 {
416*c2c66affSColin Finck                     KillTimer(hwnd, wParam);
417*c2c66affSColin Finck 
418*c2c66affSColin Finck                     //call the registered function!!
419*c2c66affSColin Finck                     RegFuncs[i].func(RegFuncs[i].dwParam);
420*c2c66affSColin Finck 
421*c2c66affSColin Finck                     RegFuncs[i] = RegFuncs[nRegFuncs-1];
422*c2c66affSColin Finck                     nRegFuncs--;
423*c2c66affSColin Finck                 }
424*c2c66affSColin Finck             }
425*c2c66affSColin Finck         }
426*c2c66affSColin Finck         else*/
427*c2c66affSColin Finck         {
428*c2c66affSColin Finck             //find the cardstack
429*c2c66affSColin Finck             CardRegion *stackobj = (CardRegion *)wParam;//CardStackFromId(wParam);
430*c2c66affSColin Finck             stackobj->DoFlash();
431*c2c66affSColin Finck         }
432*c2c66affSColin Finck 
433*c2c66affSColin Finck         return 0;
434*c2c66affSColin Finck 
435*c2c66affSColin Finck     case WM_LBUTTONDBLCLK:
436*c2c66affSColin Finck 
437*c2c66affSColin Finck         x = (short)LOWORD(lParam);
438*c2c66affSColin Finck         y = (short)HIWORD(lParam);
439*c2c66affSColin Finck 
440*c2c66affSColin Finck         if((buttonptr = CardButtonFromPoint(x, y)) != 0)
441*c2c66affSColin Finck         {
442*c2c66affSColin Finck             buttonptr->OnLButtonDown(hwnd, x, y);
443*c2c66affSColin Finck             return 0;
444*c2c66affSColin Finck         }
445*c2c66affSColin Finck 
446*c2c66affSColin Finck         if((stackptr = CardRegionFromPoint(x, y)) != 0)
447*c2c66affSColin Finck         {
448*c2c66affSColin Finck             stackptr->OnLButtonDblClk(x, y);
449*c2c66affSColin Finck             stackptr = 0;
450*c2c66affSColin Finck         }
451*c2c66affSColin Finck 
452*c2c66affSColin Finck         return 0;
453*c2c66affSColin Finck 
454*c2c66affSColin Finck     case WM_LBUTTONDOWN:
455*c2c66affSColin Finck 
456*c2c66affSColin Finck         x = (short)LOWORD(lParam);
457*c2c66affSColin Finck         y = (short)HIWORD(lParam);
458*c2c66affSColin Finck 
459*c2c66affSColin Finck         //if clicked on a button
460*c2c66affSColin Finck         if((buttonptr = CardButtonFromPoint(x, y)) != 0)
461*c2c66affSColin Finck         {
462*c2c66affSColin Finck             if(buttonptr->OnLButtonDown(hwnd, x, y) == 0)
463*c2c66affSColin Finck                 buttonptr = 0;
464*c2c66affSColin Finck 
465*c2c66affSColin Finck             return 0;
466*c2c66affSColin Finck         }
467*c2c66affSColin Finck 
468*c2c66affSColin Finck         if((stackptr = CardRegionFromPoint(x, y)) != 0)
469*c2c66affSColin Finck         {
470*c2c66affSColin Finck             if(!stackptr->OnLButtonDown(x, y))
471*c2c66affSColin Finck                 stackptr = 0;
472*c2c66affSColin Finck         }
473*c2c66affSColin Finck 
474*c2c66affSColin Finck         return 0;
475*c2c66affSColin Finck 
476*c2c66affSColin Finck     case WM_LBUTTONUP:
477*c2c66affSColin Finck 
478*c2c66affSColin Finck         x = (short)LOWORD(lParam);
479*c2c66affSColin Finck         y = (short)HIWORD(lParam);
480*c2c66affSColin Finck 
481*c2c66affSColin Finck         //
482*c2c66affSColin Finck         // if we were clicking a button
483*c2c66affSColin Finck         //
484*c2c66affSColin Finck         if(buttonptr != 0)
485*c2c66affSColin Finck         {
486*c2c66affSColin Finck             buttonptr->OnLButtonUp(hwnd, x, y);
487*c2c66affSColin Finck             buttonptr = 0;
488*c2c66affSColin Finck             return 0;
489*c2c66affSColin Finck         }
490*c2c66affSColin Finck 
491*c2c66affSColin Finck         if(stackptr != 0)
492*c2c66affSColin Finck         {
493*c2c66affSColin Finck             stackptr->OnLButtonUp(x, y);
494*c2c66affSColin Finck             stackptr = 0;
495*c2c66affSColin Finck             return 0;
496*c2c66affSColin Finck         }
497*c2c66affSColin Finck 
498*c2c66affSColin Finck         if ((stackptr = CardRegionFromPoint(x, y)) != 0)
499*c2c66affSColin Finck         {
500*c2c66affSColin Finck             stackptr->ClickRelease(x, y);
501*c2c66affSColin Finck             stackptr = 0;
502*c2c66affSColin Finck         }
503*c2c66affSColin Finck 
504*c2c66affSColin Finck         return 0;
505*c2c66affSColin Finck 
506*c2c66affSColin Finck     case WM_MOUSEMOVE:
507*c2c66affSColin Finck 
508*c2c66affSColin Finck         x = (short)LOWORD(lParam);
509*c2c66affSColin Finck         y = (short)HIWORD(lParam);
510*c2c66affSColin Finck 
511*c2c66affSColin Finck         // if we were clicking a button
512*c2c66affSColin Finck         if(buttonptr != 0)
513*c2c66affSColin Finck         {
514*c2c66affSColin Finck             buttonptr->OnMouseMove(hwnd, x, y);
515*c2c66affSColin Finck             return 0;
516*c2c66affSColin Finck         }
517*c2c66affSColin Finck 
518*c2c66affSColin Finck         if(stackptr != 0)
519*c2c66affSColin Finck         {
520*c2c66affSColin Finck             return stackptr->OnMouseMove(x, y);
521*c2c66affSColin Finck         }
522*c2c66affSColin Finck 
523*c2c66affSColin Finck         return 0;
524*c2c66affSColin Finck 
525*c2c66affSColin Finck     }
526*c2c66affSColin Finck 
527*c2c66affSColin Finck       return DefWindowProc (hwnd, iMsg, wParam, lParam);
528*c2c66affSColin Finck }
529*c2c66affSColin Finck 
530*c2c66affSColin Finck 
CardRegionFromId(int id)531*c2c66affSColin Finck CardRegion* CardWindow::CardRegionFromId(int id)
532*c2c66affSColin Finck {
533*c2c66affSColin Finck     for(int i = 0; i < nNumCardRegions; i++)
534*c2c66affSColin Finck     {
535*c2c66affSColin Finck         if(Regions[i]->id == id)
536*c2c66affSColin Finck             return Regions[i];
537*c2c66affSColin Finck     }
538*c2c66affSColin Finck 
539*c2c66affSColin Finck     return 0;
540*c2c66affSColin Finck }
541*c2c66affSColin Finck 
CardButtonFromId(int id)542*c2c66affSColin Finck CardButton* CardWindow::CardButtonFromId(int id)
543*c2c66affSColin Finck {
544*c2c66affSColin Finck     for(int i = 0; i < nNumButtons; i++)
545*c2c66affSColin Finck     {
546*c2c66affSColin Finck         if(Buttons[i]->id == id)
547*c2c66affSColin Finck             return Buttons[i];
548*c2c66affSColin Finck     }
549*c2c66affSColin Finck 
550*c2c66affSColin Finck     return 0;
551*c2c66affSColin Finck }
552*c2c66affSColin Finck 
Redraw()553*c2c66affSColin Finck void CardWindow::Redraw()
554*c2c66affSColin Finck {
555*c2c66affSColin Finck     InvalidateRect(m_hWnd, 0, 0);
556*c2c66affSColin Finck     UpdateWindow(m_hWnd);
557*c2c66affSColin Finck }
558*c2c66affSColin Finck 
DeleteButton(CardButton * pButton)559*c2c66affSColin Finck bool CardWindow::DeleteButton(CardButton *pButton)
560*c2c66affSColin Finck {
561*c2c66affSColin Finck     for(int i = 0; i < nNumButtons; i++)
562*c2c66affSColin Finck     {
563*c2c66affSColin Finck         if(Buttons[i] == pButton)
564*c2c66affSColin Finck         {
565*c2c66affSColin Finck             CardButton *cb = Buttons[i];
566*c2c66affSColin Finck 
567*c2c66affSColin Finck             //shift any after this one backwards
568*c2c66affSColin Finck             for(int j = i; j < nNumButtons - 1; j++)
569*c2c66affSColin Finck             {
570*c2c66affSColin Finck                 Buttons[j] = Buttons[j + 1];
571*c2c66affSColin Finck             }
572*c2c66affSColin Finck 
573*c2c66affSColin Finck             delete cb;
574*c2c66affSColin Finck             nNumButtons--;
575*c2c66affSColin Finck 
576*c2c66affSColin Finck             return true;
577*c2c66affSColin Finck         }
578*c2c66affSColin Finck     }
579*c2c66affSColin Finck 
580*c2c66affSColin Finck     return false;
581*c2c66affSColin Finck }
582*c2c66affSColin Finck 
DeleteRegion(CardRegion * pRegion)583*c2c66affSColin Finck bool CardWindow::DeleteRegion(CardRegion *pRegion)
584*c2c66affSColin Finck {
585*c2c66affSColin Finck     for(int i = 0; i < nNumCardRegions; i++)
586*c2c66affSColin Finck     {
587*c2c66affSColin Finck         if(Regions[i] == pRegion)
588*c2c66affSColin Finck         {
589*c2c66affSColin Finck             CardRegion *cr = Regions[i];
590*c2c66affSColin Finck 
591*c2c66affSColin Finck             //shift any after this one backwards
592*c2c66affSColin Finck             for(int j = i; j < nNumCardRegions - 1; j++)
593*c2c66affSColin Finck             {
594*c2c66affSColin Finck                 Regions[j] = Regions[j + 1];
595*c2c66affSColin Finck             }
596*c2c66affSColin Finck 
597*c2c66affSColin Finck             delete cr;
598*c2c66affSColin Finck             nNumCardRegions--;
599*c2c66affSColin Finck 
600*c2c66affSColin Finck             return true;
601*c2c66affSColin Finck         }
602*c2c66affSColin Finck     }
603*c2c66affSColin Finck 
604*c2c66affSColin Finck     return false;
605*c2c66affSColin Finck }
606*c2c66affSColin Finck 
EmptyStacks(void)607*c2c66affSColin Finck void CardWindow::EmptyStacks(void)
608*c2c66affSColin Finck {
609*c2c66affSColin Finck     for(int i = 0; i < nNumCardRegions; i++)
610*c2c66affSColin Finck     {
611*c2c66affSColin Finck         Regions[i]->Clear();
612*c2c66affSColin Finck         Regions[i]->Update();
613*c2c66affSColin Finck     }
614*c2c66affSColin Finck 
615*c2c66affSColin Finck     Redraw();
616*c2c66affSColin Finck }
617*c2c66affSColin Finck 
DistributeStacks(int nIdFrom,int nNumStacks,UINT xJustify,int xSpacing,int nStartX)618*c2c66affSColin Finck bool CardWindow::DistributeStacks(int nIdFrom, int nNumStacks, UINT xJustify, int xSpacing, int nStartX)
619*c2c66affSColin Finck {
620*c2c66affSColin Finck     int numvisiblestacks = 0;
621*c2c66affSColin Finck     int curx = nStartX;
622*c2c66affSColin Finck     int startindex = -1;
623*c2c66affSColin Finck     int i;
624*c2c66affSColin Finck 
625*c2c66affSColin Finck     //find the stack which starts with our ID
626*c2c66affSColin Finck     for(i = 0; i < nNumCardRegions; i++)
627*c2c66affSColin Finck     {
628*c2c66affSColin Finck         if(Regions[i]->Id() == nIdFrom)
629*c2c66affSColin Finck         {
630*c2c66affSColin Finck             startindex = i;
631*c2c66affSColin Finck             break;
632*c2c66affSColin Finck         }
633*c2c66affSColin Finck     }
634*c2c66affSColin Finck 
635*c2c66affSColin Finck     //if didn't find, return
636*c2c66affSColin Finck     if(i == nNumCardRegions) return false;
637*c2c66affSColin Finck 
638*c2c66affSColin Finck     //count the stacks that are visible
639*c2c66affSColin Finck     for(i = startindex; i < startindex + nNumStacks; i++)
640*c2c66affSColin Finck     {
641*c2c66affSColin Finck         if(Regions[i]->IsVisible())
642*c2c66affSColin Finck             numvisiblestacks++;
643*c2c66affSColin Finck     }
644*c2c66affSColin Finck 
645*c2c66affSColin Finck     if(xJustify == CS_XJUST_CENTER)
646*c2c66affSColin Finck     {
647*c2c66affSColin Finck         //startx -= ((numvisiblestacks + spacing) * cardwidth - spacing) / 2;
648*c2c66affSColin Finck         int viswidth;
649*c2c66affSColin Finck         viswidth = numvisiblestacks * __cardwidth;
650*c2c66affSColin Finck         viswidth += xSpacing * (numvisiblestacks - 1);
651*c2c66affSColin Finck         curx = -(viswidth  - __cardwidth) / 2;
652*c2c66affSColin Finck 
653*c2c66affSColin Finck         for(i = startindex; i < startindex + nNumStacks; i++)
654*c2c66affSColin Finck         {
655*c2c66affSColin Finck             if(Regions[i]->IsVisible())
656*c2c66affSColin Finck             {
657*c2c66affSColin Finck                 Regions[i]->xadjust = curx;
658*c2c66affSColin Finck                 Regions[i]->xjustify = CS_XJUST_CENTER;
659*c2c66affSColin Finck                 curx += Regions[i]->width + xSpacing;
660*c2c66affSColin Finck             }
661*c2c66affSColin Finck 
662*c2c66affSColin Finck         }
663*c2c66affSColin Finck     }
664*c2c66affSColin Finck 
665*c2c66affSColin Finck     if(xJustify == CS_XJUST_RIGHT)
666*c2c66affSColin Finck     {
667*c2c66affSColin Finck         nStartX -= ((numvisiblestacks + xSpacing) * __cardwidth - xSpacing);
668*c2c66affSColin Finck     }
669*c2c66affSColin Finck 
670*c2c66affSColin Finck     if(xJustify == CS_XJUST_NONE)
671*c2c66affSColin Finck     {
672*c2c66affSColin Finck         for(i = startindex; i < startindex + nNumStacks; i++)
673*c2c66affSColin Finck         {
674*c2c66affSColin Finck             if(Regions[i]->IsVisible())
675*c2c66affSColin Finck             {
676*c2c66affSColin Finck                 Regions[i]->xpos = curx;
677*c2c66affSColin Finck                 curx += Regions[i]->width + xSpacing;
678*c2c66affSColin Finck                 Regions[i]->UpdateSize();
679*c2c66affSColin Finck             }
680*c2c66affSColin Finck 
681*c2c66affSColin Finck         }
682*c2c66affSColin Finck     }
683*c2c66affSColin Finck 
684*c2c66affSColin Finck     return 0;
685*c2c66affSColin Finck }
686*c2c66affSColin Finck 
Update()687*c2c66affSColin Finck void CardWindow::Update()
688*c2c66affSColin Finck {
689*c2c66affSColin Finck     for(int i = 0; i < nNumCardRegions; i++)
690*c2c66affSColin Finck     {
691*c2c66affSColin Finck         Regions[i]->AdjustPosition(nWidth, nHeight);
692*c2c66affSColin Finck     }
693*c2c66affSColin Finck }
694*c2c66affSColin Finck 
695*c2c66affSColin Finck 
SetResizeProc(pResizeWndProc proc)696*c2c66affSColin Finck void CardWindow::SetResizeProc(pResizeWndProc proc)
697*c2c66affSColin Finck {
698*c2c66affSColin Finck     ResizeWndCallback = proc;
699*c2c66affSColin Finck }
700*c2c66affSColin Finck 
701*c2c66affSColin Finck 
CreateCardPalette()702*c2c66affSColin Finck HPALETTE CardWindow::CreateCardPalette()
703*c2c66affSColin Finck {
704*c2c66affSColin Finck     COLORREF cols[10];
705*c2c66affSColin Finck     int nNumCols;
706*c2c66affSColin Finck 
707*c2c66affSColin Finck 
708*c2c66affSColin Finck     //include button text colours
709*c2c66affSColin Finck     cols[0] = RGB(0, 0, 0);
710*c2c66affSColin Finck     cols[1] = RGB(255, 255, 255);
711*c2c66affSColin Finck 
712*c2c66affSColin Finck     //include the base background colour
713*c2c66affSColin Finck     cols[2] = crBackgnd;
714*c2c66affSColin Finck 
715*c2c66affSColin Finck     //include the standard button colours...
716*c2c66affSColin Finck     cols[3] = CardButton::GetHighlight(crBackgnd);
717*c2c66affSColin Finck     cols[4] = CardButton::GetShadow(crBackgnd);
718*c2c66affSColin Finck     cols[5] = CardButton::GetFace(crBackgnd);
719*c2c66affSColin Finck 
720*c2c66affSColin Finck     //include the sunken image bitmap colours...
721*c2c66affSColin Finck     GetSinkCols(crBackgnd, &cols[6], &cols[7], &cols[8], &cols[9]);
722*c2c66affSColin Finck 
723*c2c66affSColin Finck     nNumCols = 10;
724*c2c66affSColin Finck 
725*c2c66affSColin Finck     return MakePaletteFromCols(cols, nNumCols);
726*c2c66affSColin Finck }
727*c2c66affSColin Finck 
SetBackCardIdx(UINT uBackIdx)728*c2c66affSColin Finck void CardWindow::SetBackCardIdx(UINT uBackIdx)
729*c2c66affSColin Finck {
730*c2c66affSColin Finck     if(uBackIdx >= 52 && uBackIdx <= 68)
731*c2c66affSColin Finck         nBackCardIdx = uBackIdx;
732*c2c66affSColin Finck 
733*c2c66affSColin Finck     for(int i = 0; i < nNumCardRegions; i++)
734*c2c66affSColin Finck         Regions[i]->SetBackCardIdx(uBackIdx);
735*c2c66affSColin Finck 
736*c2c66affSColin Finck }
737*c2c66affSColin Finck 
GetBackCardIdx()738*c2c66affSColin Finck UINT CardWindow::GetBackCardIdx()
739*c2c66affSColin Finck {
740*c2c66affSColin Finck     return nBackCardIdx;
741*c2c66affSColin Finck }
742*c2c66affSColin Finck 
PaintCardRgn(HDC hdc,int dx,int dy,int width,int height,int sx,int sy)743*c2c66affSColin Finck void CardWindow::PaintCardRgn(HDC hdc, int dx, int dy, int width, int height, int sx, int sy)
744*c2c66affSColin Finck {
745*c2c66affSColin Finck     RECT rect;
746*c2c66affSColin Finck 
747*c2c66affSColin Finck     //if just a solid background colour
748*c2c66affSColin Finck     if(hbmBackImage == 0)
749*c2c66affSColin Finck     {
750*c2c66affSColin Finck         SetRect(&rect, dx, dy, dx+width, dy+height);
751*c2c66affSColin Finck 
752*c2c66affSColin Finck         /*if(GetVersion() < 0x80000000)
753*c2c66affSColin Finck         {
754*c2c66affSColin Finck             PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
755*c2c66affSColin Finck         }
756*c2c66affSColin Finck         else*/
757*c2c66affSColin Finck         {
758*c2c66affSColin Finck             HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBackgnd));
759*c2c66affSColin Finck             FillRect(hdc, &rect, hbr);
760*c2c66affSColin Finck             DeleteObject(hbr);
761*c2c66affSColin Finck         }
762*c2c66affSColin Finck     }
763*c2c66affSColin Finck     //otherwise, paint using the bitmap
764*c2c66affSColin Finck     else
765*c2c66affSColin Finck     {
766*c2c66affSColin Finck         // Draw whatever part of background we can
767*c2c66affSColin Finck         BitBlt(hdc, dx, dy, width, height, hdcBackImage, sx, sy, SRCCOPY);
768*c2c66affSColin Finck 
769*c2c66affSColin Finck         // Now we need to paint any area outside the bitmap,
770*c2c66affSColin Finck         // just in case the bitmap is too small to fill whole window
771*c2c66affSColin Finck         if(0)//sx + width > bm.bmWidth || sy + height > bm.bmHeight)
772*c2c66affSColin Finck         {
773*c2c66affSColin Finck             // Find out size of bitmap
774*c2c66affSColin Finck             BITMAP bm;
775*c2c66affSColin Finck             GetObject(hbmBackImage, sizeof(bm), &bm);
776*c2c66affSColin Finck 
777*c2c66affSColin Finck             HRGN hr1 = CreateRectRgn(sx, sy, sx+width, sy+height);
778*c2c66affSColin Finck             HRGN hr2 = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);
779*c2c66affSColin Finck             HRGN hr3 = CreateRectRgn(0,0, 1, 1);
780*c2c66affSColin Finck             HRGN hr4 = CreateRectRgn(0,0, 1, 1);
781*c2c66affSColin Finck 
782*c2c66affSColin Finck             CombineRgn(hr3, hr1, hr2, RGN_DIFF);
783*c2c66affSColin Finck 
784*c2c66affSColin Finck             GetClipRgn(hdc, hr4);
785*c2c66affSColin Finck 
786*c2c66affSColin Finck             CombineRgn(hr3, hr4, hr3, RGN_AND);
787*c2c66affSColin Finck             SelectClipRgn(hdc, hr3);
788*c2c66affSColin Finck 
789*c2c66affSColin Finck             // Fill remaining space not filled with bitmap
790*c2c66affSColin Finck             HBRUSH hbr = CreateSolidBrush(crBackgnd);
791*c2c66affSColin Finck             FillRgn(hdc, hr3, hbr);
792*c2c66affSColin Finck             DeleteObject(hbr);
793*c2c66affSColin Finck 
794*c2c66affSColin Finck             // Clean up
795*c2c66affSColin Finck             SelectClipRgn(hdc, hr4);
796*c2c66affSColin Finck 
797*c2c66affSColin Finck             DeleteObject(hr1);
798*c2c66affSColin Finck             DeleteObject(hr2);
799*c2c66affSColin Finck             DeleteObject(hr3);
800*c2c66affSColin Finck             DeleteObject(hr4);
801*c2c66affSColin Finck         }
802*c2c66affSColin Finck     }
803*c2c66affSColin Finck }
804*c2c66affSColin Finck 
SetBackImage(HBITMAP hBitmap)805*c2c66affSColin Finck void CardWindow::SetBackImage(HBITMAP hBitmap)
806*c2c66affSColin Finck {
807*c2c66affSColin Finck     //delete current image?? NO!
808*c2c66affSColin Finck     if(hdcBackImage == 0)
809*c2c66affSColin Finck     {
810*c2c66affSColin Finck         hdcBackImage = CreateCompatibleDC(0);
811*c2c66affSColin Finck     }
812*c2c66affSColin Finck 
813*c2c66affSColin Finck     hbmBackImage = hBitmap;
814*c2c66affSColin Finck 
815*c2c66affSColin Finck     if(hBitmap)
816*c2c66affSColin Finck         SelectObject(hdcBackImage, hBitmap);
817*c2c66affSColin Finck }
818