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 // For now, the Help dialog item is disabled because of lacking of HTML Help support 281 EnableMenuItem(GetMenu(hDlg), IDM_HELP_CONTENTS, MF_BYCOMMAND | MF_GRAYED); 282 283 CheckRadioButton(hDlg, IDC_OPT_DRAWONE, IDC_OPT_DRAWTHREE, 284 (dwOptions & OPTION_THREE_CARDS) ? IDC_OPT_DRAWTHREE : IDC_OPT_DRAWONE); 285 286 CheckDlgButton(hDlg, 287 IDC_OPT_STATUSBAR, 288 (dwOptions & OPTION_SHOW_STATUS) ? BST_CHECKED : BST_UNCHECKED); 289 290 CheckDlgButton(hDlg, 291 IDC_OPT_SHOWTIME, 292 (dwOptions & OPTION_SHOW_TIME) ? BST_CHECKED : BST_UNCHECKED); 293 294 CheckDlgButton(hDlg, 295 IDC_OPT_KEEPSCORE, 296 (dwOptions & OPTION_KEEP_SCORE) ? BST_CHECKED : BST_UNCHECKED); 297 298 hCtrl = GetDlgItem(hDlg, IDC_OPT_KEEPSCORE); 299 300 if (GetScoreMode() == SCORE_NONE) 301 { 302 CheckRadioButton(hDlg, IDC_OPT_STANDARD, IDC_OPT_NOSCORE, IDC_OPT_NOSCORE); 303 EnableWindow(hCtrl, FALSE); 304 } 305 else if (GetScoreMode() == SCORE_STD) 306 { 307 CheckRadioButton(hDlg, IDC_OPT_STANDARD, IDC_OPT_NOSCORE, IDC_OPT_STANDARD); 308 EnableWindow(hCtrl, FALSE); 309 } 310 else if (GetScoreMode() == SCORE_VEGAS) 311 { 312 CheckRadioButton(hDlg, IDC_OPT_STANDARD, IDC_OPT_NOSCORE, IDC_OPT_VEGAS); 313 EnableWindow(hCtrl, TRUE); 314 } 315 return TRUE; 316 317 case WM_COMMAND: 318 switch(LOWORD(wParam)) 319 { 320 case IDC_OPT_NOSCORE: 321 case IDC_OPT_STANDARD: 322 case IDC_OPT_VEGAS: 323 hCtrl = GetDlgItem(hDlg, IDC_OPT_KEEPSCORE); 324 if (wParam == IDC_OPT_VEGAS) 325 EnableWindow(hCtrl, TRUE); 326 else 327 EnableWindow(hCtrl, FALSE); 328 return TRUE; 329 330 case IDOK: 331 dwOptions &= ~OPTION_THREE_CARDS; 332 if (IsDlgButtonChecked(hDlg, IDC_OPT_DRAWTHREE) == BST_CHECKED) 333 dwOptions |= OPTION_THREE_CARDS; 334 335 if (IsDlgButtonChecked(hDlg, IDC_OPT_STATUSBAR) == BST_CHECKED) 336 dwOptions |= OPTION_SHOW_STATUS; 337 else 338 dwOptions &= ~OPTION_SHOW_STATUS; 339 340 if (IsDlgButtonChecked(hDlg, IDC_OPT_SHOWTIME) == BST_CHECKED) 341 dwOptions |= OPTION_SHOW_TIME; 342 else 343 dwOptions &= ~OPTION_SHOW_TIME; 344 345 if (IsDlgButtonChecked(hDlg, IDC_OPT_KEEPSCORE) == BST_CHECKED) 346 dwOptions |= OPTION_KEEP_SCORE; 347 else 348 dwOptions &= ~OPTION_KEEP_SCORE; 349 350 if (IsDlgButtonChecked(hDlg, IDC_OPT_STANDARD) == BST_CHECKED) 351 { 352 dwOptions |= OPTION_SCORE_STD; 353 dwOptions &= ~OPTION_SCORE_VEGAS; 354 } 355 else if (IsDlgButtonChecked(hDlg, IDC_OPT_VEGAS) == BST_CHECKED) 356 { 357 dwOptions |= OPTION_SCORE_VEGAS; 358 dwOptions &= ~OPTION_SCORE_STD; 359 } 360 else if (IsDlgButtonChecked(hDlg, IDC_OPT_NOSCORE) == BST_CHECKED) 361 { 362 dwOptions |= OPTION_SCORE_VEGAS; 363 dwOptions |= OPTION_SCORE_STD; 364 } 365 366 UpdateStatusBar(); 367 368 EndDialog(hDlg, TRUE); 369 return TRUE; 370 371 case IDCANCEL: 372 EndDialog(hDlg, FALSE); 373 return TRUE; 374 } 375 break; 376 } 377 return FALSE; 378 } 379 380 VOID ShowGameOptionsDlg(HWND hwnd) 381 { 382 DWORD dwOldOptions = dwOptions; 383 RECT rcMain, rcStatus; 384 385 int iOldScoreMode = GetScoreMode(); 386 387 if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsDlgProc)) 388 { 389 if (((dwOldOptions & OPTION_THREE_CARDS) != (dwOptions & OPTION_THREE_CARDS)) || 390 ((dwOldOptions & OPTION_SHOW_TIME) != (dwOptions & OPTION_SHOW_TIME)) || 391 (iOldScoreMode != GetScoreMode())) 392 NewGame(); 393 394 if ((dwOldOptions & OPTION_SHOW_STATUS) != (dwOptions & OPTION_SHOW_STATUS)) 395 { 396 int nWidth, nHeight, nStatusHeight; 397 398 GetClientRect(hwndMain, &rcMain); 399 nHeight = rcMain.bottom - rcMain.top; 400 nWidth = rcMain.right - rcMain.left; 401 402 if (dwOptions & OPTION_SHOW_STATUS) 403 { 404 RECT rc; 405 406 ShowWindow(hwndStatus, SW_SHOW); 407 GetWindowRect(hwndStatus, &rcStatus); 408 nStatusHeight = rcStatus.bottom - rcStatus.top; 409 MoveWindow(SolWnd, 0, 0, nWidth, nHeight-nStatusHeight, TRUE); 410 MoveWindow(hwndStatus, 0, nHeight-nStatusHeight, nWidth, nHeight, TRUE); 411 412 // Force the window to process WM_GETMINMAXINFO again 413 GetWindowRect(hwndMain, &rc); 414 SetWindowPos(hwndMain, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER); 415 } 416 else 417 { 418 ShowWindow(hwndStatus, SW_HIDE); 419 MoveWindow(SolWnd, 0, 0, nWidth, nHeight, TRUE); 420 } 421 } 422 } 423 } 424 425 426 LRESULT CALLBACK 427 CardImageWndProc(HWND hwnd, 428 UINT msg, 429 WPARAM wParam, 430 LPARAM lParam) 431 { 432 PCARDBACK pCardBack = (PCARDBACK)GetWindowLongPtr(hwnd, 433 GWLP_USERDATA); 434 static WNDPROC hOldProc = NULL; 435 436 if (!hOldProc && pCardBack) 437 hOldProc = pCardBack->hOldProc; 438 439 switch (msg) 440 { 441 case WM_PAINT: 442 { 443 HDC hdc; 444 PAINTSTRUCT ps; 445 HPEN hPen, hOldPen; 446 HBRUSH hBrush, hOldBrush; 447 RECT rc; 448 449 hdc = BeginPaint(hwnd, &ps); 450 451 if (pCardBack->bSelected) 452 { 453 hPen = CreatePen(PS_SOLID, 2, RGB(0,0,0)); 454 } 455 else 456 { 457 DWORD Face = GetSysColor(COLOR_3DFACE); 458 hPen = CreatePen(PS_SOLID, 2, Face); 459 } 460 461 GetClientRect(hwnd, &rc); 462 hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); 463 hOldPen = (HPEN)SelectObject(hdc, hPen); 464 hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); 465 466 Rectangle(hdc, 467 rc.left+1, 468 rc.top+1, 469 rc.right, 470 rc.bottom); 471 472 StretchBlt(hdc, 473 2, 474 2, 475 CARDBACK_OPTIONS_WIDTH, 476 CARDBACK_OPTIONS_HEIGHT, 477 __hdcCardBitmaps, 478 pCardBack->hdcNum * __cardwidth, 479 0, 480 __cardwidth, 481 __cardheight, 482 SRCCOPY); 483 484 SelectObject(hdc, hOldPen); 485 SelectObject(hdc, hOldBrush); 486 487 EndPaint(hwnd, &ps); 488 489 break; 490 } 491 492 case WM_LBUTTONDOWN: 493 pCardBack->bSelected = pCardBack->bSelected ? FALSE : TRUE; 494 break; 495 } 496 497 return CallWindowProc(hOldProc, 498 hwnd, 499 msg, 500 wParam, 501 lParam); 502 } 503 504 505 INT_PTR CALLBACK CardBackDlgProc(HWND hDlg, 506 UINT uMsg, 507 WPARAM wParam, 508 LPARAM lParam) 509 { 510 static PCARDBACK pCardBacks = NULL; 511 512 switch (uMsg) 513 { 514 case WM_INITDIALOG: 515 { 516 INT i, c; 517 SIZE_T size = sizeof(CARDBACK) * NUM_CARDBACKS; 518 519 pCardBacks = (PCARDBACK)HeapAlloc(GetProcessHeap(), 520 0, 521 size); 522 523 for (i = 0, c = CARDBACK_START; c <= CARDBACK_END; i++, c++) 524 { 525 pCardBacks[i].hSelf = GetDlgItem(hDlg, c); 526 pCardBacks[i].bSelected = FALSE; 527 pCardBacks[i].hdcNum = CARDBACK_RES_START + i; 528 pCardBacks[i].imgNum = i + 1; 529 pCardBacks[i].hOldProc = (WNDPROC)SetWindowLongPtr(pCardBacks[i].hSelf, 530 GWLP_WNDPROC, 531 (LONG_PTR)CardImageWndProc); 532 533 SetWindowLongPtr(pCardBacks[i].hSelf, 534 GWLP_USERDATA, 535 (LONG_PTR)&pCardBacks[i]); 536 } 537 538 return TRUE; 539 } 540 541 case WM_COMMAND: 542 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 543 { 544 INT i, num = 0; 545 for (i = 0; i < NUM_CARDBACKS; i++) 546 { 547 if (pCardBacks[i].bSelected) 548 { 549 num = pCardBacks[i].imgNum; 550 } 551 } 552 553 EndDialog(hDlg, LOWORD(wParam) == IDOK ? num : FALSE); 554 HeapFree(GetProcessHeap(), 0, pCardBacks); 555 return TRUE; 556 } 557 558 if (HIWORD(wParam) == STN_CLICKED) 559 { 560 INT i; 561 RECT rc; 562 for (i = 0; i < NUM_CARDBACKS; i++) 563 { 564 if (pCardBacks[i].hSelf == (HWND)lParam) 565 { 566 pCardBacks[i].bSelected = TRUE; 567 } 568 else 569 pCardBacks[i].bSelected = FALSE; 570 571 GetClientRect(pCardBacks[i].hSelf, &rc); 572 InvalidateRect(pCardBacks[i].hSelf, &rc, TRUE); 573 } 574 575 break; 576 } 577 } 578 579 return FALSE; 580 } 581 582 583 VOID ShowDeckOptionsDlg(HWND hwnd) 584 { 585 INT cardBack; 586 587 if ((cardBack = DialogBox(hInstance, 588 MAKEINTRESOURCE(IDD_CARDBACK), 589 hwnd, 590 CardBackDlgProc))) 591 { 592 SolWnd.SetBackCardIdx(CARDBACK_RES_START + (cardBack - 1)); 593 SolWnd.Redraw(); 594 } 595 } 596 597 //----------------------------------------------------------------------------- 598 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 599 { 600 static int nWidth, nHeight, nStatusHeight; 601 602 switch(iMsg) 603 { 604 case WM_CREATE: 605 { 606 int parts[] = { 150, -1 }; 607 RECT rcStatus; 608 609 // For now, the Help dialog item is disabled because of lacking of HTML Help support 610 EnableMenuItem(GetMenu(hwnd), IDM_HELP_CONTENTS, MF_BYCOMMAND | MF_GRAYED); 611 612 hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, _T("Ready"), hwnd, 0); 613 614 //SendMessage(hwndStatus, SB_SIMPLE, (WPARAM)TRUE, 0); 615 616 SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts); 617 SendMessage(hwndStatus, SB_SETTEXT, 0 | SBT_NOBORDERS, (LPARAM)""); 618 619 SolWnd.Create(hwnd, 0, WS_CHILD | WS_VISIBLE, 0, 0, 100, 100); 620 621 CreateSol(); 622 623 // The status bar height is fixed and needed later in WM_SIZE and WM_GETMINMAXINFO 624 // Force the window to process WM_GETMINMAXINFO again 625 GetWindowRect(hwndStatus, &rcStatus); 626 nStatusHeight = rcStatus.bottom - rcStatus.top; 627 628 // Hide status bar if options say so 629 if (!(dwOptions & OPTION_SHOW_STATUS)) 630 { 631 ShowWindow(hwndStatus, SW_HIDE); 632 } 633 634 SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOZORDER); 635 636 NewGame(); 637 638 dwAppStartTime = GetTickCount(); 639 640 return 0; 641 } 642 643 case WM_DESTROY: 644 PostQuitMessage(0); 645 return 0; 646 647 case WM_TIMER: 648 if (!fGameStarted) 649 { 650 KillTimer(hwndMain, IDT_PLAYTIMER); 651 PlayTimer = 0; 652 } 653 else if (dwOptions & OPTION_SHOW_TIME) 654 { 655 if (((dwTime + 1) % 10 == 0) && (GetScoreMode() == SCORE_STD)) 656 { 657 lScore = lScore >= 2 ? lScore - 2 : 0; 658 } 659 660 dwTime++; 661 } 662 663 UpdateStatusBar(); 664 return 0; 665 666 case WM_SIZE: 667 nWidth = LOWORD(lParam); 668 nHeight = HIWORD(lParam); 669 670 if (dwOptions & OPTION_SHOW_STATUS) 671 { 672 MoveWindow(SolWnd, 0, 0, nWidth, nHeight - nStatusHeight, TRUE); 673 MoveWindow(hwndStatus, 0, nHeight - nStatusHeight, nWidth, nStatusHeight, TRUE); 674 } 675 else 676 { 677 MoveWindow(SolWnd, 0, 0, nWidth, nHeight, TRUE); 678 } 679 //parts[0] = nWidth - 256; 680 //SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts); 681 return 0; 682 683 case WM_GETMINMAXINFO: 684 { 685 MINMAXINFO *mmi; 686 687 mmi = (MINMAXINFO *)lParam; 688 mmi->ptMinTrackSize.x = X_BORDER + NUM_ROW_STACKS * (__cardwidth + X_ROWSTACK_BORDER) + X_BORDER; 689 mmi->ptMinTrackSize.y = GetSystemMetrics(SM_CYCAPTION) + 690 GetSystemMetrics(SM_CYMENU) + 691 Y_BORDER + 692 __cardheight + 693 Y_ROWSTACK_BORDER + 694 6 * yRowStackCardOffset + 695 __cardheight + 696 Y_BORDER + 697 (dwOptions & OPTION_SHOW_STATUS ? nStatusHeight : 0); 698 return 0; 699 } 700 701 case WM_COMMAND: 702 switch(LOWORD(wParam)) 703 { 704 case IDM_GAME_NEW: 705 //simulate a button click on the new button.. 706 NewGame(); 707 return 0; 708 709 case IDM_GAME_DECK: 710 ShowDeckOptionsDlg(hwnd); 711 return 0; 712 713 case IDM_GAME_OPTIONS: 714 ShowGameOptionsDlg(hwnd); 715 return 0; 716 717 case IDM_HELP_CONTENTS: 718 WinHelp(hwnd, szHelpPath, HELP_CONTENTS, 0);//HELP_KEY, (DWORD)"How to play"); 719 return 0; 720 721 case IDM_HELP_ABOUT: 722 MessageBox(hwnd, MsgAbout, szAppName, MB_OK|MB_ICONINFORMATION); 723 return 0; 724 725 case IDM_GAME_EXIT: 726 PostMessage(hwnd, WM_CLOSE, 0, 0); 727 return 0; 728 } 729 730 return 0; 731 732 case WM_CLOSE: 733 if (fGameStarted == false) 734 { 735 DestroyWindow(hwnd); 736 return 0; 737 } 738 else 739 { 740 int ret; 741 742 ret = MessageBox(hwnd, MsgQuit, szAppName, MB_YESNO|MB_ICONQUESTION); 743 if (ret == IDYES) 744 { 745 WinHelp(hwnd, szHelpPath, HELP_QUIT, 0); 746 DestroyWindow(hwnd); 747 } 748 } 749 return 0; 750 } 751 752 return DefWindowProc (hwnd, iMsg, wParam, lParam); 753 } 754 755 756 757