6eca4023c718fa993ee5805da69c55f914f7d7b8
[reactos.git] / base / applications / games / solitaire / solitaire.cpp
1 #include "solitaire.h"
2
3 #include <winreg.h>
4 #include <commctrl.h>
5 #include <tchar.h>
6
7 #include "resource.h"
8
9 TCHAR szHelpPath[MAX_PATH];
10
11 DWORD dwAppStartTime;
12 HWND hwndMain;
13 HWND hwndStatus;
14 HINSTANCE hInstance;
15
16 TCHAR szAppName[128];
17 TCHAR szScore[64];
18 TCHAR szTime[64];
19 TCHAR MsgQuit[128];
20 TCHAR MsgAbout[128];
21 TCHAR MsgWin[128];
22 TCHAR MsgDeal[128];
23 DWORD dwOptions = OPTION_THREE_CARDS;
24
25 DWORD dwTime;
26 DWORD dwWasteCount;
27 DWORD dwWasteTreshold;
28 DWORD dwPrevMode;
29 long lScore;
30 UINT_PTR PlayTimer = 0;
31
32 CardWindow SolWnd;
33
34 typedef struct _CardBack
35 {
36 HWND hSelf;
37 WNDPROC hOldProc;
38 INT hdcNum;
39 INT imgNum;
40 BOOL bSelected;
41 } CARDBACK, *PCARDBACK;
42
43 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
44
45 void MakePath(TCHAR *szDest, UINT nDestLen, const TCHAR *szExt)
46 {
47 TCHAR *ptr;
48
49 ptr = szDest + GetModuleFileName(GetModuleHandle(0), szDest, nDestLen) - 1;
50 while(*ptr-- != '.');
51 lstrcpy(ptr + 1, szExt);
52 }
53
54 VOID LoadSettings(VOID)
55 {
56 DWORD dwDisposition;
57 DWORD dwSize;
58 DWORD dwBack;
59 HKEY hKey;
60
61 if (RegCreateKeyEx(HKEY_CURRENT_USER,
62 _T("Software\\ReactOS\\Solitaire"),
63 0,
64 NULL,
65 REG_OPTION_NON_VOLATILE,
66 KEY_READ,
67 NULL,
68 &hKey,
69 &dwDisposition))
70 return;
71
72 dwSize = sizeof(DWORD);
73 RegQueryValueEx(hKey,
74 _T("Options"),
75 NULL,
76 NULL,
77 (LPBYTE)&dwOptions,
78 &dwSize);
79
80 dwSize = sizeof(DWORD);
81 RegQueryValueEx(hKey,
82 _T("Back"),
83 NULL,
84 NULL,
85 (LPBYTE)&dwBack,
86 &dwSize);
87 SolWnd.SetBackCardIdx(dwBack);
88
89 RegCloseKey(hKey);
90 }
91
92 VOID SaveSettings(VOID)
93 {
94 DWORD dwDisposition;
95 DWORD dwBack;
96 HKEY hKey;
97
98 if (RegCreateKeyEx(HKEY_CURRENT_USER,
99 _T("Software\\ReactOS\\Solitaire"),
100 0,
101 NULL,
102 REG_OPTION_NON_VOLATILE,
103 KEY_WRITE,
104 NULL,
105 &hKey,
106 &dwDisposition))
107 return;
108
109 RegSetValueEx(hKey,
110 _T("Options"),
111 0,
112 REG_DWORD,
113 (CONST BYTE *)&dwOptions,
114 sizeof(DWORD));
115
116 dwBack = SolWnd.GetBackCardIdx();
117 RegSetValueEx(hKey,
118 _T("Back"),
119 0,
120 REG_DWORD,
121 (CONST BYTE *)&dwBack,
122 sizeof(DWORD));
123
124 RegCloseKey(hKey);
125 }
126
127 // Returns 0 for no points, 1 for Standard and 2 for Vegas
128 int GetScoreMode(void)
129 {
130 if ((dwOptions & OPTION_SCORE_STD) && (dwOptions & OPTION_SCORE_VEGAS))
131 {
132 return SCORE_NONE;
133 }
134
135 if (dwOptions & OPTION_SCORE_STD)
136 {
137 return SCORE_STD;
138 }
139
140 if (dwOptions & OPTION_SCORE_VEGAS)
141 {
142 return SCORE_VEGAS;
143 }
144
145 return 0;
146 }
147
148 void UpdateStatusBar(void)
149 {
150 TCHAR szStatusText[128];
151 TCHAR szTempText[64];
152
153 ZeroMemory(szStatusText, sizeof(szStatusText));
154
155 if (GetScoreMode() != SCORE_NONE)
156 {
157 _stprintf(szStatusText, szScore, lScore);
158 _tcscat(szStatusText, _T(" "));
159 }
160
161 if (dwOptions & OPTION_SHOW_TIME)
162 {
163 _stprintf(szTempText, szTime, dwTime);
164 _tcscat(szStatusText, szTempText);
165 }
166
167 SendMessage(hwndStatus, SB_SETTEXT, 0 | SBT_NOBORDERS, (LPARAM)(LPTSTR)szStatusText);
168 }
169
170 void SetPlayTimer(void)
171 {
172 if (dwOptions & OPTION_SHOW_TIME)
173 {
174 if (!PlayTimer)
175 {
176 PlayTimer = SetTimer(hwndMain, IDT_PLAYTIMER, 1000, NULL);
177 }
178 }
179 }
180
181 //
182 // Main entry point
183 //
184 int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int iCmdShow)
185 {
186 HWND hwnd;
187 MSG msg;
188 WNDCLASS wndclass;
189 INITCOMMONCONTROLSEX ice;
190 HACCEL hAccelTable;
191
192 hInstance = hInst;
193
194 // Load application title
195 LoadString(hInst, IDS_SOL_NAME, szAppName, sizeof(szAppName) / sizeof(szAppName[0]));
196 // Load MsgBox() texts here to avoid loading them many times later
197 LoadString(hInst, IDS_SOL_ABOUT, MsgAbout, sizeof(MsgAbout) / sizeof(MsgAbout[0]));
198 LoadString(hInst, IDS_SOL_QUIT, MsgQuit, sizeof(MsgQuit) / sizeof(MsgQuit[0]));
199 LoadString(hInst, IDS_SOL_WIN, MsgWin, sizeof(MsgWin) / sizeof(MsgWin[0]));
200 LoadString(hInst, IDS_SOL_DEAL, MsgDeal, sizeof(MsgDeal) / sizeof(MsgDeal[0]));
201
202 LoadString(hInst, IDS_SOL_SCORE, szScore, sizeof(szScore) / sizeof(TCHAR));
203 LoadString(hInst, IDS_SOL_TIME, szTime, sizeof(szTime) / sizeof(TCHAR));
204
205 //Window class for the main application parent window
206 wndclass.style = 0;//CS_HREDRAW | CS_VREDRAW;
207 wndclass.lpfnWndProc = WndProc;
208 wndclass.cbClsExtra = 0;
209 wndclass.cbWndExtra = 0;
210 wndclass.hInstance = hInst;
211 wndclass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_SOLITAIRE));
212 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
213 wndclass.hbrBackground = (HBRUSH)NULL;
214 wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
215 wndclass.lpszClassName = szAppName;
216
217 RegisterClass(&wndclass);
218
219 ice.dwSize = sizeof(ice);
220 ice.dwICC = ICC_BAR_CLASSES;
221 InitCommonControlsEx(&ice);
222
223 srand((unsigned)GetTickCount());//timeGetTime());
224
225 // InitCardLib();
226
227 LoadSettings();
228
229 dwPrevMode = GetScoreMode();
230
231 //Construct the path to our help file
232 MakePath(szHelpPath, MAX_PATH, _T(".hlp"));
233
234 hwnd = CreateWindow(szAppName, // window class name
235 szAppName, // window caption
236 WS_OVERLAPPEDWINDOW
237 ,//|WS_CLIPCHILDREN, // window style
238 CW_USEDEFAULT, // initial x position
239 CW_USEDEFAULT, // initial y position
240 0, // The real size will be computed in WndProc through WM_GETMINMAXINFO
241 0, // The real size will be computed in WndProc through WM_GETMINMAXINFO
242 NULL, // parent window handle
243 NULL, // use window class menu
244 hInst, // program instance handle
245 NULL); // creation parameters
246 if (hwnd == NULL)
247 return 1;
248
249 hwndMain = hwnd;
250
251 UpdateStatusBar();
252
253 ShowWindow(hwnd, iCmdShow);
254 UpdateWindow(hwnd);
255
256 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
257
258 while(GetMessage(&msg, NULL,0,0))
259 {
260 if(!TranslateAccelerator(hwnd, hAccelTable, &msg))
261 {
262 TranslateMessage(&msg);
263 DispatchMessage(&msg);
264 }
265 }
266
267 SaveSettings();
268
269 return msg.wParam;
270 }
271
272
273 INT_PTR CALLBACK OptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
274 {
275 HWND hCtrl;
276
277 switch (uMsg)
278 {
279 case WM_INITDIALOG:
280 CheckRadioButton(hDlg, IDC_OPT_DRAWONE, IDC_OPT_DRAWTHREE,
281 (dwOptions & OPTION_THREE_CARDS) ? IDC_OPT_DRAWTHREE : IDC_OPT_DRAWONE);
282
283 CheckDlgButton(hDlg,
284 IDC_OPT_STATUSBAR,
285 (dwOptions & OPTION_SHOW_STATUS) ? BST_CHECKED : BST_UNCHECKED);
286
287 CheckDlgButton(hDlg,
288 IDC_OPT_SHOWTIME,
289 (dwOptions & OPTION_SHOW_TIME) ? BST_CHECKED : BST_UNCHECKED);
290
291 CheckDlgButton(hDlg,
292 IDC_OPT_KEEPSCORE,
293 (dwOptions & OPTION_KEEP_SCORE) ? BST_CHECKED : BST_UNCHECKED);
294
295 hCtrl = GetDlgItem(hDlg, IDC_OPT_KEEPSCORE);
296
297 if (GetScoreMode() == SCORE_NONE)
298 {
299 CheckRadioButton(hDlg, IDC_OPT_STANDARD, IDC_OPT_NOSCORE, IDC_OPT_NOSCORE);
300 EnableWindow(hCtrl, FALSE);
301 }
302 else if (GetScoreMode() == SCORE_STD)
303 {
304 CheckRadioButton(hDlg, IDC_OPT_STANDARD, IDC_OPT_NOSCORE, IDC_OPT_STANDARD);
305 EnableWindow(hCtrl, FALSE);
306 }
307 else if (GetScoreMode() == SCORE_VEGAS)
308 {
309 CheckRadioButton(hDlg, IDC_OPT_STANDARD, IDC_OPT_NOSCORE, IDC_OPT_VEGAS);
310 EnableWindow(hCtrl, TRUE);
311 }
312 return TRUE;
313
314 case WM_COMMAND:
315 switch(LOWORD(wParam))
316 {
317 case IDC_OPT_NOSCORE:
318 case IDC_OPT_STANDARD:
319 case IDC_OPT_VEGAS:
320 hCtrl = GetDlgItem(hDlg, IDC_OPT_KEEPSCORE);
321 if (wParam == IDC_OPT_VEGAS)
322 EnableWindow(hCtrl, TRUE);
323 else
324 EnableWindow(hCtrl, FALSE);
325 return TRUE;
326
327 case IDOK:
328 dwOptions &= ~OPTION_THREE_CARDS;
329 if (IsDlgButtonChecked(hDlg, IDC_OPT_DRAWTHREE) == BST_CHECKED)
330 dwOptions |= OPTION_THREE_CARDS;
331
332 if (IsDlgButtonChecked(hDlg, IDC_OPT_STATUSBAR) == BST_CHECKED)
333 dwOptions |= OPTION_SHOW_STATUS;
334 else
335 dwOptions &= ~OPTION_SHOW_STATUS;
336
337 if (IsDlgButtonChecked(hDlg, IDC_OPT_SHOWTIME) == BST_CHECKED)
338 dwOptions |= OPTION_SHOW_TIME;
339 else
340 dwOptions &= ~OPTION_SHOW_TIME;
341
342 if (IsDlgButtonChecked(hDlg, IDC_OPT_KEEPSCORE) == BST_CHECKED)
343 dwOptions |= OPTION_KEEP_SCORE;
344 else
345 dwOptions &= ~OPTION_KEEP_SCORE;
346
347 if (IsDlgButtonChecked(hDlg, IDC_OPT_STANDARD) == BST_CHECKED)
348 {
349 dwOptions |= OPTION_SCORE_STD;
350 dwOptions &= ~OPTION_SCORE_VEGAS;
351 }
352 else if (IsDlgButtonChecked(hDlg, IDC_OPT_VEGAS) == BST_CHECKED)
353 {
354 dwOptions |= OPTION_SCORE_VEGAS;
355 dwOptions &= ~OPTION_SCORE_STD;
356 }
357 else if (IsDlgButtonChecked(hDlg, IDC_OPT_NOSCORE) == BST_CHECKED)
358 {
359 dwOptions |= OPTION_SCORE_VEGAS;
360 dwOptions |= OPTION_SCORE_STD;
361 }
362
363 UpdateStatusBar();
364
365 EndDialog(hDlg, TRUE);
366 return TRUE;
367
368 case IDCANCEL:
369 EndDialog(hDlg, FALSE);
370 return TRUE;
371 }
372 break;
373 }
374 return FALSE;
375 }
376
377 VOID ShowGameOptionsDlg(HWND hwnd)
378 {
379 DWORD dwOldOptions = dwOptions;
380 RECT rcMain, rcStatus;
381
382 int iOldScoreMode = GetScoreMode();
383
384 if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsDlgProc))
385 {
386 if (((dwOldOptions & OPTION_THREE_CARDS) != (dwOptions & OPTION_THREE_CARDS)) ||
387 ((dwOldOptions & OPTION_SHOW_TIME) != (dwOptions & OPTION_SHOW_TIME)) ||
388 (iOldScoreMode != GetScoreMode()))
389 NewGame();
390
391 if ((dwOldOptions & OPTION_SHOW_STATUS) != (dwOptions & OPTION_SHOW_STATUS))
392 {
393 int nWidth, nHeight, nStatusHeight;
394
395 GetClientRect(hwndMain, &rcMain);
396 nHeight = rcMain.bottom - rcMain.top;
397 nWidth = rcMain.right - rcMain.left;
398
399 if (dwOptions & OPTION_SHOW_STATUS)
400 {
401 RECT rc;
402
403 ShowWindow(hwndStatus, SW_SHOW);
404 GetWindowRect(hwndStatus, &rcStatus);
405 nStatusHeight = rcStatus.bottom - rcStatus.top;
406 MoveWindow(SolWnd, 0, 0, nWidth, nHeight-nStatusHeight, TRUE);
407 MoveWindow(hwndStatus, 0, nHeight-nStatusHeight, nWidth, nHeight, TRUE);
408
409 // Force the window to process WM_GETMINMAXINFO again
410 GetWindowRect(hwndMain, &rc);
411 SetWindowPos(hwndMain, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER);
412 }
413 else
414 {
415 ShowWindow(hwndStatus, SW_HIDE);
416 MoveWindow(SolWnd, 0, 0, nWidth, nHeight, TRUE);
417 }
418 }
419 }
420 }
421
422
423 LRESULT CALLBACK
424 CardImageWndProc(HWND hwnd,
425 UINT msg,
426 WPARAM wParam,
427 LPARAM lParam)
428 {
429 PCARDBACK pCardBack = (PCARDBACK)GetWindowLongPtr(hwnd,
430 GWL_USERDATA);
431 static WNDPROC hOldProc = NULL;
432
433 if (!hOldProc && pCardBack)
434 hOldProc = pCardBack->hOldProc;
435
436 switch (msg)
437 {
438 case WM_PAINT:
439 {
440 HDC hdc;
441 PAINTSTRUCT ps;
442 HPEN hPen, hOldPen;
443 HBRUSH hBrush, hOldBrush;
444 RECT rc;
445
446 hdc = BeginPaint(hwnd, &ps);
447
448 if (pCardBack->bSelected)
449 {
450 hPen = CreatePen(PS_SOLID, 2, RGB(0,0,0));
451 }
452 else
453 {
454 DWORD Face = GetSysColor(COLOR_3DFACE);
455 hPen = CreatePen(PS_SOLID, 2, Face);
456 }
457
458 GetClientRect(hwnd, &rc);
459 hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
460 hOldPen = (HPEN)SelectObject(hdc, hPen);
461 hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
462
463 Rectangle(hdc,
464 rc.left+1,
465 rc.top+1,
466 rc.right,
467 rc.bottom);
468
469 StretchBlt(hdc,
470 2,
471 2,
472 CARDBACK_OPTIONS_WIDTH,
473 CARDBACK_OPTIONS_HEIGHT,
474 __hdcCardBitmaps,
475 pCardBack->hdcNum * __cardwidth,
476 0,
477 __cardwidth,
478 __cardheight,
479 SRCCOPY);
480
481 SelectObject(hdc, hOldPen);
482 SelectObject(hdc, hOldBrush);
483
484 EndPaint(hwnd, &ps);
485
486 break;
487 }
488
489 case WM_LBUTTONDOWN:
490 pCardBack->bSelected = pCardBack->bSelected ? FALSE : TRUE;
491 break;
492 }
493
494 return CallWindowProc(hOldProc,
495 hwnd,
496 msg,
497 wParam,
498 lParam);
499 }
500
501
502 INT_PTR CALLBACK CardBackDlgProc(HWND hDlg,
503 UINT uMsg,
504 WPARAM wParam,
505 LPARAM lParam)
506 {
507 static PCARDBACK pCardBacks = NULL;
508
509 switch (uMsg)
510 {
511 case WM_INITDIALOG:
512 {
513 INT i, c;
514 SIZE_T size = sizeof(CARDBACK) * NUM_CARDBACKS;
515
516 pCardBacks = (PCARDBACK)HeapAlloc(GetProcessHeap(),
517 0,
518 size);
519
520 for (i = 0, c = CARDBACK_START; c <= CARDBACK_END; i++, c++)
521 {
522 pCardBacks[i].hSelf = GetDlgItem(hDlg, c);
523 pCardBacks[i].bSelected = FALSE;
524 pCardBacks[i].hdcNum = CARDBACK_RES_START + i;
525 pCardBacks[i].imgNum = i + 1;
526 pCardBacks[i].hOldProc = (WNDPROC)SetWindowLongPtr(pCardBacks[i].hSelf,
527 GWLP_WNDPROC,
528 (LONG_PTR)CardImageWndProc);
529
530 SetWindowLongPtr(pCardBacks[i].hSelf,
531 GWL_USERDATA,
532 (LONG_PTR)&pCardBacks[i]);
533 }
534
535 return TRUE;
536 }
537
538 case WM_COMMAND:
539 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
540 {
541 INT i, num = 0;
542 for (i = 0; i < NUM_CARDBACKS; i++)
543 {
544 if (pCardBacks[i].bSelected)
545 {
546 num = pCardBacks[i].imgNum;
547 }
548 }
549
550 EndDialog(hDlg, LOWORD(wParam) == IDOK ? num : FALSE);
551 HeapFree(GetProcessHeap(), 0, pCardBacks);
552 return TRUE;
553 }
554
555 if (HIWORD(wParam) == STN_CLICKED)
556 {
557 INT i;
558 RECT rc;
559 for (i = 0; i < NUM_CARDBACKS; i++)
560 {
561 if (pCardBacks[i].hSelf == (HWND)lParam)
562 {
563 pCardBacks[i].bSelected = TRUE;
564 }
565 else
566 pCardBacks[i].bSelected = FALSE;
567
568 GetClientRect(pCardBacks[i].hSelf, &rc);
569 InvalidateRect(pCardBacks[i].hSelf, &rc, TRUE);
570 }
571
572 break;
573 }
574 }
575
576 return FALSE;
577 }
578
579
580 VOID ShowDeckOptionsDlg(HWND hwnd)
581 {
582 INT cardBack;
583
584 if ((cardBack = DialogBox(hInstance,
585 MAKEINTRESOURCE(IDD_CARDBACK),
586 hwnd,
587 CardBackDlgProc)))
588 {
589 SolWnd.SetBackCardIdx(CARDBACK_RES_START + (cardBack - 1));
590 SolWnd.Redraw();
591 }
592 }
593
594 //-----------------------------------------------------------------------------
595 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
596 {
597 static int nWidth, nHeight, nStatusHeight;
598
599 switch(iMsg)
600 {
601 case WM_CREATE:
602 {
603 int parts[] = { 150, -1 };
604 RECT rcStatus;
605
606 hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, _T("Ready"), hwnd, 0);
607
608 //SendMessage(hwndStatus, SB_SIMPLE, (WPARAM)TRUE, 0);
609
610 SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
611 SendMessage(hwndStatus, SB_SETTEXT, 0 | SBT_NOBORDERS, (LPARAM)"");
612
613 SolWnd.Create(hwnd, 0, WS_CHILD | WS_VISIBLE, 0, 0, 100, 100);
614
615 CreateSol();
616
617 // The status bar height is fixed and needed later in WM_SIZE and WM_GETMINMAXINFO
618 // Force the window to process WM_GETMINMAXINFO again
619 GetWindowRect(hwndStatus, &rcStatus);
620 nStatusHeight = rcStatus.bottom - rcStatus.top;
621
622 // Hide status bar if options say so
623 if (!(dwOptions & OPTION_SHOW_STATUS))
624 {
625 ShowWindow(hwndStatus, SW_HIDE);
626 }
627
628 SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOZORDER);
629
630 NewGame();
631
632 dwAppStartTime = GetTickCount();
633
634 return 0;
635 }
636
637 case WM_DESTROY:
638 PostQuitMessage(0);
639 return 0;
640
641 case WM_TIMER:
642 if (!fGameStarted)
643 {
644 KillTimer(hwndMain, IDT_PLAYTIMER);
645 PlayTimer = 0;
646 }
647 else if (dwOptions & OPTION_SHOW_TIME)
648 {
649 if (((dwTime + 1) % 10 == 0) && (GetScoreMode() == SCORE_STD))
650 {
651 lScore = lScore >= 2 ? lScore - 2 : 0;
652 }
653
654 dwTime++;
655 }
656
657 UpdateStatusBar();
658 return 0;
659
660 case WM_SIZE:
661 nWidth = LOWORD(lParam);
662 nHeight = HIWORD(lParam);
663
664 if (dwOptions & OPTION_SHOW_STATUS)
665 {
666 MoveWindow(SolWnd, 0, 0, nWidth, nHeight - nStatusHeight, TRUE);
667 MoveWindow(hwndStatus, 0, nHeight - nStatusHeight, nWidth, nStatusHeight, TRUE);
668 }
669 else
670 {
671 MoveWindow(SolWnd, 0, 0, nWidth, nHeight, TRUE);
672 }
673 //parts[0] = nWidth - 256;
674 //SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
675 return 0;
676
677 case WM_GETMINMAXINFO:
678 {
679 MINMAXINFO *mmi;
680
681 mmi = (MINMAXINFO *)lParam;
682 mmi->ptMinTrackSize.x = X_BORDER + NUM_ROW_STACKS * (__cardwidth + X_ROWSTACK_BORDER) + X_BORDER;
683 mmi->ptMinTrackSize.y = GetSystemMetrics(SM_CYCAPTION) +
684 GetSystemMetrics(SM_CYMENU) +
685 Y_BORDER +
686 __cardheight +
687 Y_ROWSTACK_BORDER +
688 6 * yRowStackCardOffset +
689 __cardheight +
690 Y_BORDER +
691 (dwOptions & OPTION_SHOW_STATUS ? nStatusHeight : 0);
692 return 0;
693 }
694
695 case WM_COMMAND:
696 switch(LOWORD(wParam))
697 {
698 case IDM_GAME_NEW:
699 //simulate a button click on the new button..
700 NewGame();
701 return 0;
702
703 case IDM_GAME_DECK:
704 ShowDeckOptionsDlg(hwnd);
705 return 0;
706
707 case IDM_GAME_OPTIONS:
708 ShowGameOptionsDlg(hwnd);
709 return 0;
710
711 case IDM_HELP_CONTENTS:
712 WinHelp(hwnd, szHelpPath, HELP_CONTENTS, 0);//HELP_KEY, (DWORD)"How to play");
713 return 0;
714
715 case IDM_HELP_ABOUT:
716 MessageBox(hwnd, MsgAbout, szAppName, MB_OK|MB_ICONINFORMATION);
717 return 0;
718
719 case IDM_GAME_EXIT:
720 PostMessage(hwnd, WM_CLOSE, 0, 0);
721 return 0;
722 }
723
724 return 0;
725
726 case WM_CLOSE:
727 if (fGameStarted == false)
728 {
729 DestroyWindow(hwnd);
730 return 0;
731 }
732 else
733 {
734 int ret;
735
736 ret = MessageBox(hwnd, MsgQuit, szAppName, MB_YESNO|MB_ICONQUESTION);
737 if (ret == IDYES)
738 {
739 WinHelp(hwnd, szHelpPath, HELP_QUIT, 0);
740 DestroyWindow(hwnd);
741 }
742 }
743 return 0;
744 }
745
746 return DefWindowProc (hwnd, iMsg, wParam, lParam);
747 }
748
749
750