Sync with trunk head (part 1 or 2)
[reactos.git] / base / applications / mplay32 / mplay32.c
1 /*
2 * PROJECT: ReactOS Multimedia Player
3 * FILE: base\applications\mplay32\mplay32.c
4 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
5 */
6
7 #include "mplay32.h"
8
9 #define MAIN_WINDOW_HEIGHT 125
10 #define MAIN_WINDOW_MIN_WIDTH 250
11
12 HINSTANCE hInstance = NULL;
13 HWND hTrackBar = NULL;
14 HWND hToolBar = NULL;
15 TCHAR szAppTitle[256] = _T("");
16 TCHAR szPrevFile[MAX_PATH] = _T("\0");
17 WORD wDeviceId;
18 BOOL bIsOpened = FALSE;
19 BOOL bIsPaused = FALSE;
20 UINT MaxFilePos = 0;
21
22 /* Known types table */
23 static const TYPEBYEXT ExtTypes[] =
24 {
25 { _T(".wav"), WAVE_FILE },
26 { _T(".wave"), WAVE_FILE },
27 { _T(".mid"), MIDI_FILE },
28 { _T(".midi"), MIDI_FILE },
29 { _T(".cda"), AUDIOCD_FILE },
30 { _T(".avi"), AVI_FILE },
31 { _T("\0"), 0 }
32 };
33
34 /* ToolBar Buttons */
35 static const TBBUTTON Buttons[] =
36 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
37 {TBICON_PLAY, IDC_PLAY, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
38 {TBICON_STOP, IDC_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
39 {TBICON_EJECT, IDC_EJECT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
40 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},
41 {TBICON_BACKWARD, IDC_BACKWARD, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
42 {TBICON_SEEKBACK, IDC_SEEKBACK, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
43 {TBICON_SEEKFORW, IDC_SEEKFORW, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
44 {TBICON_FORWARD, IDC_FORWARD, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}
45 };
46
47 static VOID
48 SetImageList(HWND hwnd)
49 {
50 HIMAGELIST hImageList;
51
52 hImageList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR24, 1, 1);
53
54 if (!hImageList)
55 {
56 MessageBox(hwnd, _T("ImageList it is not created!"), NULL, MB_OK);
57 return;
58 }
59
60 ImageList_AddMasked(hImageList,
61 LoadImage(hInstance, MAKEINTRESOURCE(IDB_PLAYICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
62 RGB(255, 255, 255));
63
64 ImageList_AddMasked(hImageList,
65 LoadImage(hInstance, MAKEINTRESOURCE(IDB_STOPICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
66 RGB(255, 255, 255));
67
68 ImageList_AddMasked(hImageList,
69 LoadImage(hInstance, MAKEINTRESOURCE(IDB_EJECTICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
70 RGB(255, 255, 255));
71
72 ImageList_AddMasked(hImageList,
73 LoadImage(hInstance, MAKEINTRESOURCE(IDB_BACKWARDICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
74 RGB(255, 255, 255));
75
76 ImageList_AddMasked(hImageList,
77 LoadImage(hInstance, MAKEINTRESOURCE(IDB_SEEKBACKICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
78 RGB(255, 255, 255));
79
80 ImageList_AddMasked(hImageList,
81 LoadImage(hInstance, MAKEINTRESOURCE(IDB_SEEKFORWICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
82 RGB(255, 255, 255));
83
84 ImageList_AddMasked(hImageList,
85 LoadImage(hInstance, MAKEINTRESOURCE(IDB_FORWARDICON), IMAGE_BITMAP, 16, 16, LR_DEFAULTCOLOR),
86 RGB(255, 255, 255));
87
88 ImageList_Destroy((HIMAGELIST)SendMessage(hToolBar,
89 TB_SETIMAGELIST,
90 0,
91 (LPARAM)hImageList));
92 }
93
94 static VOID
95 InitControls(HWND hwnd)
96 {
97 INT NumButtons = sizeof(Buttons) / sizeof(Buttons[0]);
98
99 InitCommonControls();
100
101 /* Create trackbar */
102 hTrackBar = CreateWindowEx(0,
103 TRACKBAR_CLASS,
104 NULL,
105 TBS_ENABLESELRANGE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS,
106 0,
107 0,
108 340,
109 20,
110 hwnd,
111 NULL,
112 hInstance,
113 NULL);
114 if (!hTrackBar)
115 {
116 MessageBox(hwnd, _T("TrackBar it is not created!"), NULL, MB_OK);
117 return;
118 }
119
120 /* Create toolbar */
121 hToolBar = CreateWindowEx(0,
122 TOOLBARCLASSNAME,
123 NULL,
124 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS |
125 TBSTYLE_FLAT | CCS_BOTTOM | TBSTYLE_TOOLTIPS,
126 0,
127 40,
128 340,
129 30,
130 hwnd,
131 NULL,
132 hInstance,
133 NULL);
134 if (!hToolBar)
135 {
136 MessageBox(hwnd, _T("ToolBar it is not created!"), NULL, MB_OK);
137 return;
138 }
139
140 SetImageList(hwnd);
141 SendMessage(hToolBar, TB_ADDBUTTONS, NumButtons, (LPARAM)Buttons);
142 }
143
144 static UINT
145 IsSupportedFileExtension(LPTSTR lpFileName)
146 {
147 TCHAR szExt[MAX_PATH];
148 INT DotPos = 0, i, j;
149
150 for (i = _tcslen(lpFileName); i >= 0; --i)
151 {
152 if (lpFileName[i] == '.')
153 {
154 DotPos = _tcslen(lpFileName) - i;
155 break;
156 }
157 }
158
159 if (!DotPos) return UNSUPPORTED_FILE;
160
161 szExt[DotPos + 1] = _T('\0');
162 for (i = _tcslen(lpFileName), j = DotPos; j >= 0; --i, --j)
163 {
164 szExt[j] = lpFileName[i];
165 }
166
167 for (i = 0; ; i++)
168 {
169 if (ExtTypes[i].uType == UNSUPPORTED_FILE)
170 {
171 return UNSUPPORTED_FILE;
172 }
173
174 if (_tcscmp(ExtTypes[i].szExt, szExt) == 0)
175 {
176 return ExtTypes[i].uType;
177 }
178 }
179
180 return UNSUPPORTED_FILE;
181 }
182
183 static DWORD
184 CloseMciDevice(VOID)
185 {
186 MCI_GENERIC_PARMS mciGeneric;
187 DWORD dwError;
188
189 if (bIsOpened)
190 {
191 dwError = mciSendCommand(wDeviceId, MCI_CLOSE, MCI_WAIT, (DWORD_PTR)&mciGeneric);
192 if (dwError) return dwError;
193 bIsOpened = FALSE;
194 }
195
196 return TRUE;
197 }
198
199 static DWORD
200 OpenMciDevice(HWND hwnd, LPTSTR lpType, LPTSTR lpFileName)
201 {
202 MCI_STATUS_PARMS mciStatus;
203 MCI_OPEN_PARMS mciOpen;
204 TCHAR szNewTitle[MAX_PATH];
205 DWORD dwError;
206
207 if (bIsOpened)
208 {
209 CloseMciDevice();
210 }
211
212 mciOpen.lpstrDeviceType = lpType;
213 mciOpen.lpstrElementName = lpFileName;
214 mciOpen.dwCallback = 0;
215 mciOpen.wDeviceID = 0;
216 mciOpen.lpstrAlias = NULL;
217
218 dwError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT | MCI_WAIT, (DWORD_PTR)&mciOpen);
219 if (dwError != 0)
220 {
221 MessageBox(0, _T("Can't open device! (1)"), NULL, MB_OK);
222 return dwError;
223 }
224
225 mciStatus.dwItem = MCI_STATUS_LENGTH;
226
227 dwError = mciSendCommand(mciOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&mciStatus);
228 if (dwError != 0)
229 {
230 MessageBox(0, _T("Can't open device! (2)"), NULL, MB_OK);
231 return dwError;
232 }
233
234 SendMessage(hTrackBar, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(1, mciStatus.dwReturn));
235 SendMessage(hTrackBar, TBM_SETPAGESIZE, 0, 10);
236 SendMessage(hTrackBar, TBM_SETLINESIZE, 0, 1);
237 SendMessage(hTrackBar, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) 1);
238
239 if (mciStatus.dwReturn < 10000)
240 {
241 SendMessage(hTrackBar, TBM_SETTICFREQ, (WPARAM) 100, (LPARAM) 0);
242 }
243 else if (mciStatus.dwReturn < 100000)
244 {
245 SendMessage(hTrackBar, TBM_SETTICFREQ, (WPARAM) 1000, (LPARAM) 0);
246 }
247 else if (mciStatus.dwReturn < 1000000)
248 {
249 SendMessage(hTrackBar, TBM_SETTICFREQ, (WPARAM) 10000, (LPARAM) 0);
250 }
251 else
252 {
253 SendMessage(hTrackBar, TBM_SETTICFREQ, (WPARAM) 100000, (LPARAM) 0);
254 }
255
256 _stprintf(szNewTitle, _T("%s - %s"), szAppTitle, lpFileName);
257 SetWindowText(hwnd, szNewTitle);
258
259 MaxFilePos = mciStatus.dwReturn;
260 wDeviceId = mciOpen.wDeviceID;
261 bIsOpened = TRUE;
262 _tcscpy(szPrevFile, lpFileName);
263 return TRUE;
264 }
265
266 static VOID
267 StopPlayback(HWND hwnd)
268 {
269 if (bIsOpened)
270 {
271 SendMessage(hTrackBar, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) 1);
272 KillTimer(hwnd, IDT_PLAYTIMER);
273 CloseMciDevice();
274 }
275 }
276
277 static VOID
278 SeekPlayback(HWND hwnd, DWORD dwNewPos)
279 {
280 MCI_SEEK_PARMS mciSeek;
281 MCI_PLAY_PARMS mciPlay;
282 DWORD dwError;
283
284 if (bIsOpened)
285 {
286 mciSeek.dwTo = (DWORD_PTR)dwNewPos;
287 dwError = mciSendCommand(wDeviceId, MCI_SEEK, MCI_WAIT | MCI_TO, (DWORD_PTR)&mciSeek);
288 if (dwError != 0)
289 {
290 MessageBox(hwnd, _T("SeekPlayback: Can't seek!"), NULL, MB_OK);
291 }
292
293 mciPlay.dwCallback = (DWORD_PTR)hwnd;
294 dwError = mciSendCommand(wDeviceId, MCI_PLAY, MCI_NOTIFY, (DWORD_PTR)&mciPlay);
295 if (dwError != 0)
296 {
297 MessageBox(hwnd, _T("SeekPlayback: Can't play!"), NULL, MB_OK);
298 }
299 }
300 }
301
302 static VOID
303 SeekBackPlayback(HWND hwnd)
304 {
305 MCI_STATUS_PARMS mciStatus;
306 DWORD dwNewPos;
307
308 if (!bIsOpened) return;
309
310 mciStatus.dwItem = MCI_STATUS_POSITION;
311 mciSendCommand(wDeviceId, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&mciStatus);
312
313 dwNewPos = mciStatus.dwReturn - 1;
314
315 if((UINT)dwNewPos <= 1)
316 {
317 StopPlayback(hwnd);
318 }
319 else
320 {
321 SeekPlayback(hwnd, dwNewPos);
322 }
323 }
324
325 static VOID
326 SeekForwPlayback(HWND hwnd)
327 {
328 MCI_STATUS_PARMS mciStatus;
329 DWORD dwNewPos;
330
331 if (!bIsOpened) return;
332
333 mciStatus.dwItem = MCI_STATUS_POSITION;
334 mciSendCommand(wDeviceId, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&mciStatus);
335
336 dwNewPos = mciStatus.dwReturn + 1;
337
338 if((UINT)dwNewPos >= MaxFilePos)
339 {
340 StopPlayback(hwnd);
341 }
342 else
343 {
344 SeekPlayback(hwnd, dwNewPos);
345 }
346 }
347
348 static VOID
349 PausePlayback(HWND hwnd)
350 {
351 MCI_GENERIC_PARMS mciGeneric;
352 DWORD dwError;
353
354 if (bIsOpened)
355 {
356 dwError = mciSendCommand(wDeviceId, MCI_PAUSE, MCI_WAIT, (DWORD_PTR)&mciGeneric);
357 if (dwError != 0)
358 {
359 MessageBox(hwnd, _T("Can't pause!"), NULL, MB_OK);
360 }
361 bIsPaused = TRUE;
362 }
363 }
364
365 static VOID
366 ResumePlayback(HWND hwnd)
367 {
368 MCI_GENERIC_PARMS mciGeneric;
369 DWORD dwError;
370
371 if (bIsPaused)
372 {
373 dwError = mciSendCommand(wDeviceId, MCI_RESUME, MCI_WAIT, (DWORD_PTR)&mciGeneric);
374 if (dwError != 0)
375 {
376 MessageBox(hwnd, _T("Can't resume!"), NULL, MB_OK);
377 }
378 bIsPaused = FALSE;
379 }
380 }
381
382 VOID CALLBACK
383 PlayTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
384 {
385 MCI_STATUS_PARMS mciStatus;
386 DWORD dwPos;
387
388 if (!bIsOpened) KillTimer(hwnd, IDT_PLAYTIMER);
389
390 mciStatus.dwItem = MCI_STATUS_POSITION;
391 mciSendCommand(wDeviceId, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&mciStatus);
392 dwPos = mciStatus.dwReturn;
393
394 if((UINT)dwPos >= MaxFilePos)
395 {
396 StopPlayback(hwnd);
397 }
398 else
399 {
400 SendMessage(hTrackBar, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) dwPos);
401 }
402 }
403
404 static VOID
405 PlayFile(HWND hwnd, LPTSTR lpFileName)
406 {
407 MCI_PLAY_PARMS mciPlay;
408 TCHAR szLocalFileName[MAX_PATH];
409 UINT FileType;
410 DWORD dwError;
411
412 if (lpFileName == NULL)
413 {
414 if (szPrevFile[0] == _T('\0'))
415 return;
416
417 _tcscpy(szLocalFileName, szPrevFile);
418 }
419 else
420 {
421 _tcscpy(szLocalFileName, lpFileName);
422 }
423
424 if (GetFileAttributes(szLocalFileName) == INVALID_FILE_ATTRIBUTES)
425 {
426 return;
427 }
428
429 FileType = IsSupportedFileExtension(szLocalFileName);
430
431 switch (FileType)
432 {
433 case UNSUPPORTED_FILE:
434 MessageBox(hwnd, _T("Unsupported format!"), NULL, MB_OK);
435 return;
436 case WAVE_FILE:
437 OpenMciDevice(hwnd, _T("waveaudio"), szLocalFileName);
438 break;
439 case MIDI_FILE:
440 OpenMciDevice(hwnd, _T("sequencer"), szLocalFileName);
441 break;
442 case AUDIOCD_FILE:
443 OpenMciDevice(hwnd, _T("cdaudio"), szLocalFileName);
444 break;
445 case AVI_FILE:
446 OpenMciDevice(hwnd, _T("avivideo"), szLocalFileName);
447 break;
448 }
449
450 SetTimer(hwnd, IDT_PLAYTIMER, 100, (TIMERPROC) PlayTimerProc);
451
452 dwError = mciSendCommand(wDeviceId, MCI_SEEK, MCI_WAIT | MCI_SEEK_TO_START, 0);
453
454 mciPlay.dwCallback = (DWORD_PTR)hwnd;
455 mciPlay.dwFrom = 0;
456 mciPlay.dwTo = MaxFilePos;
457
458 dwError = mciSendCommand(wDeviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)&mciPlay);
459 if (dwError != 0)
460 {
461 MessageBox(hwnd, _T("Can't play!"), NULL, MB_OK);
462 }
463 }
464
465 static VOID
466 OpenFileDialog(HWND hwnd)
467 {
468 OPENFILENAME OpenFileName;
469 TCHAR szFile[MAX_PATH + 1] = _T("\0");
470 TCHAR szFilter[MAX_PATH], szCurrentDir[MAX_PATH];
471
472 ZeroMemory(&OpenFileName, sizeof(OpenFileName));
473
474 LoadString(hInstance, IDS_ALL_TYPES_FILTER, szFilter, sizeof(szFilter) / sizeof(TCHAR));
475
476 if (!GetCurrentDirectory(sizeof(szCurrentDir) / sizeof(TCHAR), szCurrentDir))
477 {
478 _tcscpy(szCurrentDir, _T("c:\\"));
479 }
480
481 OpenFileName.lStructSize = sizeof(OpenFileName);
482 OpenFileName.hwndOwner = hwnd;
483 OpenFileName.hInstance = hInstance;
484 OpenFileName.lpstrFilter = szFilter;
485 OpenFileName.lpstrFile = szFile;
486 OpenFileName.nMaxFile = sizeof(szFile) / sizeof((szFile)[0]);
487 OpenFileName.lpstrInitialDir = szCurrentDir;
488 OpenFileName.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_SHAREAWARE;
489 OpenFileName.lpstrDefExt = _T("\0");
490
491 if (GetOpenFileName(&OpenFileName))
492 {
493 PlayFile(hwnd, OpenFileName.lpstrFile);
494 }
495 }
496
497 LRESULT CALLBACK
498 MainWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
499 {
500 switch (Message)
501 {
502 case WM_CREATE:
503 InitControls(hwnd);
504 break;
505
506 case WM_NOTIFY:
507 {
508 LPNMHDR pnmhdr = (LPNMHDR)lParam;
509
510 switch (pnmhdr->code)
511 {
512 case TTN_GETDISPINFO:
513 {
514 LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)lParam;
515 UINT idButton = (UINT)lpttt->hdr.idFrom;
516
517 switch (idButton)
518 {
519 case IDC_PLAY:
520 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PLAY);
521 break;
522 case IDC_STOP:
523 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP);
524 break;
525 case IDC_EJECT:
526 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EJECT);
527 break;
528 case IDC_BACKWARD:
529 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_BACKWARD);
530 break;
531 case IDC_SEEKBACK:
532 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_SEEKBACK);
533 break;
534 case IDC_SEEKFORW:
535 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_SEEKFORW);
536 break;
537 case IDC_FORWARD:
538 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_FORWARD);
539 break;
540 }
541 break;
542 }
543 }
544 }
545 break;
546
547 case WM_SIZING:
548 {
549 LPRECT pRect = (LPRECT)lParam;
550
551 if (pRect->right - pRect->left < MAIN_WINDOW_MIN_WIDTH)
552 pRect->right = pRect->left + MAIN_WINDOW_MIN_WIDTH;
553
554 if (pRect->bottom - pRect->top != MAIN_WINDOW_HEIGHT)
555 pRect->bottom = pRect->top + MAIN_WINDOW_HEIGHT;
556
557 return TRUE;
558 }
559
560 case WM_SIZE:
561 {
562 RECT Rect;
563 UINT Size;
564
565 if (hToolBar && hTrackBar)
566 {
567 SendMessage(hToolBar, TB_AUTOSIZE, 0, 0);
568 SendMessage(hToolBar, TB_GETITEMRECT, 1, (LPARAM)&Rect);
569
570 Size = GetSystemMetrics(SM_CYMENU) + Rect.bottom;
571 MoveWindow(hTrackBar, 0, 0, LOWORD(lParam), HIWORD(lParam) - Size, TRUE);
572 }
573 return 0L;
574 }
575
576 case WM_HSCROLL:
577 {
578 if (hTrackBar == (HWND) lParam)
579 {
580 if (bIsOpened)
581 {
582 DWORD dwNewPos = (DWORD) SendMessage(hTrackBar, TBM_GETPOS, 0, 0);
583 SeekPlayback(hwnd, dwNewPos);
584 }
585 else
586 {
587 SendMessage(hTrackBar, TBM_SETPOS, TRUE, 0);
588 }
589 }
590 }
591 break;
592
593 case WM_COMMAND:
594 switch (LOWORD(wParam))
595 {
596 case IDC_PLAY:
597 if (bIsOpened)
598 {
599 if (bIsPaused)
600 ResumePlayback(hwnd);
601 else
602 PausePlayback(hwnd);
603 }
604 else
605 {
606 if (szPrevFile[0] == _T('\0'))
607 OpenFileDialog(hwnd);
608 else
609 PlayFile(hwnd, NULL);
610 }
611 break;
612
613 case IDC_STOP:
614 StopPlayback(hwnd);
615 break;
616
617 case IDC_EJECT:
618 break;
619
620 case IDC_BACKWARD:
621 break;
622
623 case IDC_SEEKBACK:
624 SeekBackPlayback(hwnd);
625 break;
626
627 case IDC_SEEKFORW:
628 SeekForwPlayback(hwnd);
629 break;
630
631 case IDC_FORWARD:
632 break;
633
634 case IDM_OPEN_FILE:
635 OpenFileDialog(hwnd);
636 return 0;
637
638 case IDM_CLOSE_FILE:
639 StopPlayback(hwnd);
640 _tcscpy(szPrevFile, _T("\0"));
641 break;
642
643 case IDM_ABOUT:
644 {
645 HICON mplayIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN));
646 ShellAbout(hwnd, szAppTitle, 0, mplayIcon);
647 DeleteObject(mplayIcon);
648 break;
649 }
650 case IDM_EXIT:
651 PostMessage(hwnd, WM_CLOSE, 0, 0);
652 return 0;
653 }
654 break;
655
656 case WM_DESTROY:
657 StopPlayback(hwnd);
658 PostQuitMessage(0);
659 return 0;
660 }
661
662 return DefWindowProc(hwnd, Message, wParam, lParam);
663 }
664
665 INT WINAPI
666 _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
667 {
668 WNDCLASSEX WndClass = {0};
669 TCHAR szClassName[] = _T("ROSMPLAY32");
670 HWND hwnd;
671 MSG msg;
672
673 hInstance = hInst;
674
675 LoadString(hInstance, IDS_APPTITLE, szAppTitle, sizeof(szAppTitle) / sizeof(TCHAR));
676
677 WndClass.cbSize = sizeof(WNDCLASSEX);
678 WndClass.lpszClassName = szClassName;
679 WndClass.lpfnWndProc = MainWndProc;
680 WndClass.hInstance = hInstance;
681 WndClass.style = CS_HREDRAW | CS_VREDRAW;
682 WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN));
683 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
684 WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
685 WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
686
687 RegisterClassEx(&WndClass);
688
689 hwnd = CreateWindow(szClassName,
690 szAppTitle,
691 WS_SYSMENU | WS_MINIMIZEBOX | WS_THICKFRAME | WS_OVERLAPPED | WS_CAPTION | WS_CLIPCHILDREN,
692 CW_USEDEFAULT,
693 CW_USEDEFAULT,
694 350,
695 MAIN_WINDOW_HEIGHT,
696 NULL,
697 NULL,
698 hInstance,
699 NULL);
700
701 /* Show it */
702 ShowWindow(hwnd, SW_SHOW);
703 UpdateWindow(hwnd);
704
705 PlayFile(hwnd, lpCmdLine);
706
707 /* Message Loop */
708 while (GetMessage(&msg, NULL, 0, 0))
709 {
710 TranslateMessage(&msg);
711 DispatchMessage(&msg);
712 }
713
714 return 0;
715 }