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