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