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