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 GWLP_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 GWLP_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 751