2 * PROJECT: ReactOS Multimedia Player
3 * FILE: base/applications/mplay32/mplay32.c
4 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
9 #define IDT_PLAYTIMER 1000
11 #define MAIN_WINDOW_HEIGHT 125
12 #define MAIN_WINDOW_MIN_WIDTH 250
13 #define MAX_MCISTR 256
15 HINSTANCE hInstance
= NULL
;
16 HWND hTrackBar
= NULL
;
18 HWND hTimeDisplay
= NULL
;
19 HMENU hMainMenu
= NULL
;
21 TCHAR szAppTitle
[256] = _T("");
22 TCHAR szDefaultFilter
[MAX_PATH
] = _T("");
23 TCHAR szCurrentFile
[MAX_PATH
] = _T("");
24 LPTSTR szFilter
= NULL
;
28 BOOL bIsSingleWindow
= FALSE
;
32 static DWORD
GetDeviceMode(HWND hwnd
);
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 // {TBICON_PAUSE, IDC_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}
48 void EnableMenuItems(HWND hwnd
)
51 MCI_GENERIC_PARMS mciGeneric
;
52 MCI_DGV_RECT_PARMS mciVideoRect
;
53 MCI_DGV_WINDOW_PARMSW mciVideoWindow
;
55 EnableMenuItem(hMainMenu
, IDM_CLOSE_FILE
, MF_BYCOMMAND
| MF_ENABLED
);
57 mciError
= mciSendCommand(wDeviceId
, MCI_CONFIGURE
, MCI_TEST
, (DWORD_PTR
)&mciGeneric
);
60 EnableMenuItem(hMainMenu
, IDM_DEVPROPS
, MF_BYCOMMAND
| MF_ENABLED
);
63 mciVideoWindow
.hWnd
= hwnd
;
65 mciError
= mciSendCommand(wDeviceId
, MCI_WINDOW
, MCI_DGV_WINDOW_HWND
| MCI_TEST
, (DWORD_PTR
)&mciVideoWindow
);
68 mciError
= mciSendCommand(wDeviceId
, MCI_WHERE
, MCI_DGV_WHERE_SOURCE
| MCI_TEST
, (DWORD_PTR
)&mciVideoRect
);
71 EnableMenuItem(hMainMenu
, IDM_SWITCHVIEW
, MF_BYCOMMAND
| MF_ENABLED
);
76 void DisableMenuItems(void)
78 EnableMenuItem(hMainMenu
, IDM_CLOSE_FILE
, MF_BYCOMMAND
| MF_GRAYED
);
79 EnableMenuItem(hMainMenu
, IDM_DEVPROPS
, MF_BYCOMMAND
| MF_GRAYED
);
80 EnableMenuItem(hMainMenu
, IDM_SWITCHVIEW
, MF_BYCOMMAND
| MF_GRAYED
);
83 void ResizeClientArea(HWND hwnd
, int nWidth
, int nHeight
)
89 GetClientRect(hwnd
, &rcClientRect
);
90 GetWindowRect(hwnd
, &rcWindowRect
);
91 ptDifference
.x
= (rcWindowRect
.right
- rcWindowRect
.left
) - rcClientRect
.right
;
92 ptDifference
.y
= (rcWindowRect
.bottom
- rcWindowRect
.top
) - rcClientRect
.bottom
;
93 MoveWindow(hwnd
, rcWindowRect
.left
, rcWindowRect
.top
, nWidth
+ ptDifference
.x
, nHeight
+ ptDifference
.y
, TRUE
);
96 void UpdateWindowCaption(HWND hwnd
)
98 TCHAR szNewTitle
[MAX_PATH
+ 3 + 256];
103 SetWindowText(hwnd
, szAppTitle
);
107 switch (GetDeviceMode(hwnd
))
111 LoadString(hInstance
, IDS_MODE_PAUSE
, szStatus
, ARRAYSIZE(szStatus
));
117 LoadString(hInstance
, IDS_MODE_STOP
, szStatus
, ARRAYSIZE(szStatus
));
123 LoadString(hInstance
, IDS_MODE_PLAY
, szStatus
, ARRAYSIZE(szStatus
));
129 LoadString(hInstance
, IDS_MODE_OPEN
, szStatus
, ARRAYSIZE(szStatus
));
133 case MCI_MODE_RECORD
:
135 LoadString(hInstance
, IDS_MODE_RECORD
, szStatus
, ARRAYSIZE(szStatus
));
141 LoadString(hInstance
, IDS_MODE_SEEK
, szStatus
, ARRAYSIZE(szStatus
));
145 case MCI_MODE_NOT_READY
:
147 LoadString(hInstance
, IDS_MODE_NOT_READY
, szStatus
, ARRAYSIZE(szStatus
));
153 LoadString(hInstance
, IDS_MODE_UNKNOWN
, szStatus
, ARRAYSIZE(szStatus
));
157 StringCbPrintf(szNewTitle
, sizeof(szNewTitle
), _T("%s - %s (%s)"), szAppTitle
, szCurrentFile
, szStatus
);
158 SetWindowText(hwnd
, szNewTitle
);
161 void UpdateTimeDisplay(HWND hwnd
)
163 MCI_STATUS_PARMS mciStatus
;
164 TCHAR szTime
[MAX_MCISTR
];
169 SetWindowText(hwnd
, _T(""));
173 mciStatus
.dwItem
= MCI_STATUS_TIME_FORMAT
;
174 mciStatus
.dwReturn
= 0;
175 mciSendCommand(wDeviceId
, MCI_STATUS
, MCI_STATUS_ITEM
, (DWORD_PTR
)&mciStatus
);
176 dwTimeFormat
= mciStatus
.dwReturn
;
178 mciStatus
.dwItem
= MCI_STATUS_POSITION
;
179 mciStatus
.dwReturn
= 0;
180 mciSendCommand(wDeviceId
, MCI_STATUS
, MCI_STATUS_ITEM
, (DWORD_PTR
)&mciStatus
);
184 case MCI_FORMAT_MILLISECONDS
:
188 s
= (mciStatus
.dwReturn
/ 1000) % 60;
189 m
= ((mciStatus
.dwReturn
/ (1000*60)) % 60);
190 h
= ((mciStatus
.dwReturn
/ (1000*60*60)) % 24);
191 StringCbPrintf(szTime
, sizeof(szTime
), _T("%02lu:%02lu:%02lu"), h
, m
, s
);
195 /* The time format is unknown, so use the returned position as is */
198 StringCbPrintf(szTime
, sizeof(szTime
), _T("%lu"), mciStatus
.dwReturn
);
203 SetWindowText(hwnd
, szTime
);
207 ShowLastWin32Error(HWND hwnd
)
209 LPTSTR lpMessageBuffer
;
210 DWORD dwError
= GetLastError();
212 if (dwError
== ERROR_SUCCESS
)
215 if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
216 FORMAT_MESSAGE_FROM_SYSTEM
|
217 FORMAT_MESSAGE_IGNORE_INSERTS
,
221 (LPTSTR
)&lpMessageBuffer
,
227 MessageBox(hwnd
, lpMessageBuffer
, szAppTitle
, MB_OK
| MB_ICONERROR
);
228 LocalFree(lpMessageBuffer
);
232 SetImageList(HWND hwnd
)
234 HIMAGELIST hImageList
;
236 hImageList
= ImageList_Create(16, 16, ILC_MASK
| ILC_COLOR24
, 1, 1);
239 ShowLastWin32Error(hwnd
);
243 ImageList_AddMasked(hImageList
,
244 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_PLAYICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
247 ImageList_AddMasked(hImageList
,
248 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_STOPICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
251 ImageList_AddMasked(hImageList
,
252 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_EJECTICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
255 ImageList_AddMasked(hImageList
,
256 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_BACKWARDICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
259 ImageList_AddMasked(hImageList
,
260 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_SEEKBACKICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
263 ImageList_AddMasked(hImageList
,
264 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_SEEKFORWICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
267 ImageList_AddMasked(hImageList
,
268 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_FORWARDICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
271 ImageList_AddMasked(hImageList
,
272 LoadImage(hInstance
, MAKEINTRESOURCE(IDB_PAUSEICON
), IMAGE_BITMAP
, 16, 16, LR_DEFAULTCOLOR
),
275 ImageList_Destroy((HIMAGELIST
)SendMessage(hToolBar
,
278 (LPARAM
)hImageList
));
282 ShowMCIError(HWND hwnd
, MCIERROR mciError
)
284 TCHAR szErrorMessage
[MAX_MCISTR
];
285 TCHAR szTempMessage
[MAX_MCISTR
+ 44];
287 if (mciGetErrorString(mciError
, szErrorMessage
, ARRAYSIZE(szErrorMessage
)) == FALSE
)
289 LoadString(hInstance
, IDS_DEFAULTMCIERRMSG
, szErrorMessage
, ARRAYSIZE(szErrorMessage
));
292 StringCbPrintf(szTempMessage
, sizeof(szTempMessage
), _T("MMSYS%lu: %s"), mciError
, szErrorMessage
);
293 MessageBox(hwnd
, szTempMessage
, szAppTitle
, MB_OK
| MB_ICONEXCLAMATION
);
297 InitControls(HWND hwnd
)
299 INT NumButtons
= ARRAYSIZE(Buttons
);
301 InitCommonControls();
303 /* Create trackbar */
304 hTrackBar
= CreateWindowEx(0,
307 TBS_ENABLESELRANGE
| WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_CLIPSIBLINGS
,
318 ShowLastWin32Error(hwnd
);
323 hToolBar
= CreateWindowEx(0,
326 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_CLIPSIBLINGS
|
327 TBSTYLE_FLAT
| CCS_BOTTOM
| TBSTYLE_TOOLTIPS
,
338 ShowLastWin32Error(hwnd
);
342 hTimeDisplay
= CreateWindowEx(0,
345 WS_CHILD
| WS_VISIBLE
| SS_CENTER
| SS_SUNKEN
,
356 ShowLastWin32Error(hwnd
);
361 SendMessage(hToolBar
, TB_ADDBUTTONS
, NumButtons
, (LPARAM
)Buttons
);
365 SwitchViewMode(HWND hwnd
)
368 MCI_DGV_RECT_PARMS mciVideoRect
;
369 MCI_DGV_WINDOW_PARMSW mciVideoWindow
;
373 mciVideoWindow
.hWnd
= hwnd
;
375 mciError
= mciSendCommand(wDeviceId
, MCI_WINDOW
, MCI_DGV_WINDOW_HWND
| MCI_TEST
, (DWORD_PTR
)&mciVideoWindow
);
379 mciError
= mciSendCommand(wDeviceId
, MCI_WHERE
, MCI_DGV_WHERE_SOURCE
| MCI_TEST
, (DWORD_PTR
)&mciVideoRect
);
383 if (!bIsSingleWindow
)
385 GetWindowRect(hwnd
, &PrevWindowPos
);
387 SetParent(hTrackBar
, hToolBar
);
389 mciError
= mciSendCommand(wDeviceId
, MCI_WHERE
, MCI_DGV_WHERE_SOURCE
, (DWORD_PTR
)&mciVideoRect
);
392 ShowMCIError(hwnd
, mciError
);
396 GetWindowRect(hToolBar
, &rcToolbarRect
);
397 ResizeClientArea(hwnd
, mciVideoRect
.rc
.right
, mciVideoRect
.rc
.bottom
+ (rcToolbarRect
.bottom
- rcToolbarRect
.top
));
399 mciError
= mciSendCommand(wDeviceId
, MCI_WINDOW
, MCI_DGV_WINDOW_HWND
, (DWORD_PTR
)&mciVideoWindow
);
402 ShowMCIError(hwnd
, mciError
);
406 GetWindowRect(hToolBar
, &rcTempRect
);
407 MoveWindow(hTrackBar
, 180, 0, rcTempRect
.right
- rcTempRect
.left
- 322, 25, TRUE
);
408 MoveWindow(hTimeDisplay
, rcTempRect
.right
- rcTempRect
.left
- 140, 4, 135, 18, TRUE
);
410 CheckMenuItem(hMainMenu
, IDM_SWITCHVIEW
, MF_BYCOMMAND
| MF_CHECKED
);
411 bIsSingleWindow
= TRUE
;
415 bIsSingleWindow
= FALSE
;
416 CheckMenuItem(hMainMenu
, IDM_SWITCHVIEW
, MF_BYCOMMAND
| MF_UNCHECKED
);
418 mciVideoWindow
.hWnd
= MCI_DGV_WINDOW_DEFAULT
;
419 mciError
= mciSendCommand(wDeviceId
, MCI_WINDOW
, MCI_DGV_WINDOW_HWND
, (DWORD_PTR
)&mciVideoWindow
);
422 ShowMCIError(hwnd
, mciError
);
426 SetParent(hTrackBar
, hwnd
);
428 MoveWindow(hwnd
, PrevWindowPos
.left
, PrevWindowPos
.top
, PrevWindowPos
.right
- PrevWindowPos
.left
, PrevWindowPos
.bottom
- PrevWindowPos
.top
, TRUE
);
435 MCI_SYSINFO_PARMS mciSysInfo
;
436 DWORD dwNumDevices
= 0;
438 mciSysInfo
.dwCallback
= 0;
439 mciSysInfo
.lpstrReturn
= (LPTSTR
)&dwNumDevices
;
440 mciSysInfo
.dwRetSize
= sizeof(dwNumDevices
);
441 mciSysInfo
.dwNumber
= 0;
442 mciSysInfo
.wDeviceType
= MCI_ALL_DEVICE_ID
;
444 mciSendCommand(MCI_ALL_DEVICE_ID
, MCI_SYSINFO
, MCI_SYSINFO_QUANTITY
, (DWORD_PTR
)&mciSysInfo
);
446 return *(DWORD
*)mciSysInfo
.lpstrReturn
;
450 GetDeviceName(DWORD dwDeviceIndex
, LPTSTR lpDeviceName
, DWORD dwDeviceNameSize
)
452 MCI_SYSINFO_PARMS mciSysInfo
;
454 mciSysInfo
.dwCallback
= 0;
455 mciSysInfo
.lpstrReturn
= lpDeviceName
;
456 mciSysInfo
.dwRetSize
= dwDeviceNameSize
;
457 mciSysInfo
.dwNumber
= dwDeviceIndex
;
458 mciSysInfo
.wDeviceType
= MCI_DEVTYPE_WAVEFORM_AUDIO
;
460 return mciSendCommand(MCI_ALL_DEVICE_ID
, MCI_SYSINFO
, MCI_SYSINFO_NAME
, (DWORD_PTR
)&mciSysInfo
);
464 GetDeviceFriendlyName(LPTSTR lpDeviceName
, LPTSTR lpFriendlyName
, DWORD dwFriendlyNameSize
)
467 MCI_OPEN_PARMS mciOpen
;
468 MCI_INFO_PARMS mciInfo
;
469 MCI_GENERIC_PARMS mciGeneric
;
471 mciOpen
.dwCallback
= 0;
472 mciOpen
.wDeviceID
= 0;
473 mciOpen
.lpstrDeviceType
= lpDeviceName
;
474 mciOpen
.lpstrElementName
= NULL
;
475 mciOpen
.lpstrAlias
= NULL
;
477 mciError
= mciSendCommand(0, MCI_OPEN
, MCI_OPEN_TYPE
| MCI_WAIT
, (DWORD_PTR
)&mciOpen
);
481 mciInfo
.dwCallback
= 0;
482 mciInfo
.lpstrReturn
= lpFriendlyName
;
483 mciInfo
.dwRetSize
= dwFriendlyNameSize
;
485 mciError
= mciSendCommand(mciOpen
.wDeviceID
, MCI_INFO
, MCI_INFO_PRODUCT
, (DWORD_PTR
)&mciInfo
);
487 mciGeneric
.dwCallback
= 0;
488 mciSendCommand(mciOpen
.wDeviceID
, MCI_CLOSE
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
494 DeviceUsesFiles(LPTSTR lpDeviceName
)
497 MCI_OPEN_PARMS mciOpen
;
498 MCI_GETDEVCAPS_PARMS mciDevCaps
;
499 MCI_GENERIC_PARMS mciGeneric
;
501 mciOpen
.dwCallback
= 0;
502 mciOpen
.wDeviceID
= 0;
503 mciOpen
.lpstrDeviceType
= lpDeviceName
;
504 mciOpen
.lpstrElementName
= NULL
;
505 mciOpen
.lpstrAlias
= NULL
;
507 mciError
= mciSendCommand(0, MCI_OPEN
, MCI_OPEN_TYPE
| MCI_WAIT
, (DWORD_PTR
)&mciOpen
);
511 mciDevCaps
.dwCallback
= 0;
512 mciDevCaps
.dwReturn
= 0;
513 mciDevCaps
.dwItem
= MCI_GETDEVCAPS_USES_FILES
;
515 mciError
= mciSendCommand(mciOpen
.wDeviceID
, MCI_GETDEVCAPS
, MCI_WAIT
| MCI_GETDEVCAPS_ITEM
, (DWORD_PTR
)&mciDevCaps
);
519 mciGeneric
.dwCallback
= 0;
520 mciSendCommand(mciOpen
.wDeviceID
, MCI_CLOSE
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
522 return (BOOL
)mciDevCaps
.dwReturn
;
529 MCI_GENERIC_PARMS mciGeneric
;
533 mciError
= mciSendCommand(wDeviceId
, MCI_CLOSE
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
534 if (mciError
!= 0) return mciError
;
538 UpdateTimeDisplay(hTimeDisplay
);
546 OpenMciDevice(HWND hwnd
, LPTSTR lpType
, LPTSTR lpFileName
)
549 MCI_STATUS_PARMS mciStatus
;
550 MCI_OPEN_PARMS mciOpen
;
551 DWORD dwFlags
= MCI_WAIT
;
557 mciOpen
.lpstrDeviceType
= lpType
;
558 mciOpen
.lpstrElementName
= lpFileName
;
559 mciOpen
.dwCallback
= 0;
560 mciOpen
.wDeviceID
= 0;
561 mciOpen
.lpstrAlias
= NULL
;
564 dwFlags
|= MCI_OPEN_TYPE
;
567 dwFlags
|= MCI_OPEN_ELEMENT
;
569 mciError
= mciSendCommand(0, MCI_OPEN
, dwFlags
, (DWORD_PTR
)&mciOpen
);
573 mciStatus
.dwItem
= MCI_STATUS_LENGTH
;
575 mciError
= mciSendCommand(mciOpen
.wDeviceID
, MCI_STATUS
, MCI_STATUS_ITEM
| MCI_WAIT
, (DWORD_PTR
)&mciStatus
);
579 SendMessage(hTrackBar
, TBM_SETRANGEMIN
, (WPARAM
)TRUE
, (LPARAM
)1);
580 SendMessage(hTrackBar
, TBM_SETRANGEMAX
, (WPARAM
)TRUE
, (LPARAM
)mciStatus
.dwReturn
);
581 SendMessage(hTrackBar
, TBM_SETPAGESIZE
, 0, 10);
582 SendMessage(hTrackBar
, TBM_SETLINESIZE
, 0, 1);
583 SendMessage(hTrackBar
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)1);
585 if (mciStatus
.dwReturn
< 10000)
587 SendMessage(hTrackBar
, TBM_SETTICFREQ
, (WPARAM
)100, (LPARAM
)0);
589 else if (mciStatus
.dwReturn
< 100000)
591 SendMessage(hTrackBar
, TBM_SETTICFREQ
, (WPARAM
)1000, (LPARAM
)0);
593 else if (mciStatus
.dwReturn
< 1000000)
595 SendMessage(hTrackBar
, TBM_SETTICFREQ
, (WPARAM
)10000, (LPARAM
)0);
599 SendMessage(hTrackBar
, TBM_SETTICFREQ
, (WPARAM
)100000, (LPARAM
)0);
602 MaxFilePos
= mciStatus
.dwReturn
;
603 wDeviceId
= mciOpen
.wDeviceID
;
605 /* NOTE: Everything above this line may be done instead in OpenMediaFile() */
609 lpStr
= _tcsrchr(lpFileName
, _T('\\'));
610 if (lpStr
) // Get only the file name (skip the last path separator)
618 StringCbCopy(szCurrentFile
, sizeof(szCurrentFile
), lpStr
);
620 EnableMenuItems(hwnd
);
622 UpdateTimeDisplay(hTimeDisplay
);
623 UpdateWindowCaption(hwnd
);
629 GetDeviceMode(HWND hwnd
)
632 MCI_STATUS_PARMS mciStatus
;
634 mciStatus
.dwItem
= MCI_STATUS_MODE
;
635 mciError
= mciSendCommand(wDeviceId
, MCI_STATUS
, MCI_WAIT
| MCI_STATUS_ITEM
, (DWORD_PTR
)&mciStatus
);
638 ShowMCIError(hwnd
, mciError
);
639 return MCI_MODE_NOT_READY
;
642 return mciStatus
.dwReturn
;
646 StopPlayback(HWND hwnd
)
649 MCI_GENERIC_PARMS mciGeneric
;
650 MCI_SEEK_PARMS mciSeek
;
652 if (wDeviceId
== 0) return;
654 KillTimer(hwnd
, IDT_PLAYTIMER
);
655 SendMessage(hTrackBar
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)1);
657 mciGeneric
.dwCallback
= (DWORD_PTR
)hwnd
;
658 mciError
= mciSendCommand(wDeviceId
, MCI_STOP
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
661 ShowMCIError(hwnd
, mciError
);
665 mciSendCommand(wDeviceId
, MCI_SEEK
, MCI_WAIT
| MCI_SEEK_TO_START
, (DWORD_PTR
)&mciSeek
);
667 UpdateTimeDisplay(hTimeDisplay
);
668 UpdateWindowCaption(hwnd
);
670 SendMessage(hToolBar
,
674 SendMessage(hToolBar
,
677 IDB_PLAYICON
- IDB_PLAYICON
);
681 SeekPlayback(HWND hwnd
, DWORD dwNewPos
)
684 MCI_SEEK_PARMS mciSeek
;
685 MCI_PLAY_PARMS mciPlay
;
687 if (wDeviceId
== 0) return;
689 mciSeek
.dwTo
= (DWORD_PTR
)dwNewPos
;
690 mciError
= mciSendCommand(wDeviceId
, MCI_SEEK
, MCI_WAIT
| MCI_TO
, (DWORD_PTR
)&mciSeek
);
693 ShowMCIError(hwnd
, mciError
);
696 mciPlay
.dwCallback
= (DWORD_PTR
)hwnd
;
697 mciError
= mciSendCommand(wDeviceId
, MCI_PLAY
, MCI_NOTIFY
, (DWORD_PTR
)&mciPlay
);
700 ShowMCIError(hwnd
, mciError
);
705 SeekBackPlayback(HWND hwnd
)
707 MCI_STATUS_PARMS mciStatus
;
710 if (wDeviceId
== 0) return;
712 mciStatus
.dwItem
= MCI_STATUS_POSITION
;
713 mciSendCommand(wDeviceId
, MCI_STATUS
, MCI_STATUS_ITEM
, (DWORD_PTR
)&mciStatus
);
715 dwNewPos
= mciStatus
.dwReturn
- 1;
717 if ((UINT
)dwNewPos
<= 1)
723 SeekPlayback(hwnd
, dwNewPos
);
728 SeekForwPlayback(HWND hwnd
)
730 MCI_STATUS_PARMS mciStatus
;
733 if (wDeviceId
== 0) return;
735 mciStatus
.dwItem
= MCI_STATUS_POSITION
;
736 mciSendCommand(wDeviceId
, MCI_STATUS
, MCI_STATUS_ITEM
, (DWORD_PTR
)&mciStatus
);
738 dwNewPos
= mciStatus
.dwReturn
+ 1;
740 if ((UINT
)dwNewPos
>= MaxFilePos
)
746 SeekPlayback(hwnd
, dwNewPos
);
751 PlayTimerProc(HWND hwnd
, UINT uMsg
, UINT_PTR idEvent
, DWORD dwTime
)
753 MCI_STATUS_PARMS mciStatus
;
756 if (wDeviceId
== 0) KillTimer(hwnd
, IDT_PLAYTIMER
);
758 mciStatus
.dwItem
= MCI_STATUS_POSITION
;
759 mciSendCommand(wDeviceId
, MCI_STATUS
, MCI_STATUS_ITEM
, (DWORD_PTR
)&mciStatus
);
760 dwPos
= mciStatus
.dwReturn
;
762 SendMessage(hTrackBar
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)dwPos
);
763 UpdateTimeDisplay(hTimeDisplay
);
767 StartPlayback(HWND hwnd
)
770 MCI_PLAY_PARMS mciPlay
;
771 MCI_SEEK_PARMS mciSeek
;
773 SetTimer(hwnd
, IDT_PLAYTIMER
, 100, (TIMERPROC
)PlayTimerProc
);
775 mciSendCommand(wDeviceId
, MCI_SEEK
, MCI_WAIT
| MCI_SEEK_TO_START
, (DWORD_PTR
)&mciSeek
);
777 mciPlay
.dwCallback
= (DWORD_PTR
)hwnd
;
779 mciPlay
.dwTo
= MaxFilePos
;
781 mciError
= mciSendCommand(wDeviceId
, MCI_PLAY
, MCI_NOTIFY
| MCI_FROM
/*| MCI_TO*/, (DWORD_PTR
)&mciPlay
);
784 ShowMCIError(hwnd
, mciError
);
788 UpdateWindowCaption(hwnd
);
790 SendMessage(hToolBar
,
794 SendMessage(hToolBar
,
797 IDB_PAUSEICON
- IDB_PLAYICON
);
801 TogglePlaybackState(HWND hwnd
)
804 MCI_GENERIC_PARMS mciGeneric
;
805 ULONG idBmp
= IDB_PLAYICON
;
806 ULONG idCmd
= IDC_PLAY
;
808 if (wDeviceId
== 0) return;
810 switch (GetDeviceMode(hwnd
))
821 mciGeneric
.dwCallback
= (DWORD_PTR
)hwnd
;
822 mciError
= mciSendCommand(wDeviceId
, MCI_PAUSE
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
823 idBmp
= IDB_PLAYICON
;
830 mciGeneric
.dwCallback
= (DWORD_PTR
)hwnd
;
831 mciError
= mciSendCommand(wDeviceId
, MCI_RESUME
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
832 idBmp
= IDB_PAUSEICON
;
845 ShowMCIError(hwnd
, mciError
);
849 UpdateWindowCaption(hwnd
);
851 SendMessage(hToolBar
,
855 SendMessage(hToolBar
,
858 idBmp
- IDB_PLAYICON
);
862 ShowDeviceProperties(HWND hwnd
)
865 MCI_GENERIC_PARMS mciGeneric
;
867 mciError
= mciSendCommand(wDeviceId
, MCI_CONFIGURE
, MCI_WAIT
, (DWORD_PTR
)&mciGeneric
);
870 ShowMCIError(hwnd
, mciError
);
875 CloseMediaFile(HWND hwnd
)
880 SwitchViewMode(hwnd
);
883 UpdateWindowCaption(hwnd
);
887 OpenMediaFile(HWND hwnd
, LPTSTR lpFileName
, LPTSTR lpType
)
891 if (GetFileAttributes(lpFileName
) == INVALID_FILE_ATTRIBUTES
)
895 CloseMediaFile(hwnd
);
897 mciError
= OpenMciDevice(hwnd
, lpType
, lpFileName
);
900 ShowMCIError(hwnd
, mciError
);
908 InsertDeviceMenuItem(HMENU hMenu
, UINT uItem
, BOOL fByPosition
, UINT uItemID
, DWORD dwDeviceIndex
)
912 TCHAR szDeviceName
[MAX_MCISTR
];
913 TCHAR szFriendlyName
[MAX_MCISTR
];
915 mciError
= GetDeviceName(dwDeviceIndex
, szDeviceName
, sizeof(szDeviceName
));
921 mciError
= GetDeviceFriendlyName(szDeviceName
, szFriendlyName
, sizeof(szFriendlyName
));
927 if (DeviceUsesFiles(szDeviceName
))
929 StringCbCat(szFriendlyName
, sizeof(szFriendlyName
), _T("..."));
932 ZeroMemory(&lpmii
, sizeof(MENUITEMINFO
));
933 lpmii
.cbSize
= sizeof(lpmii
);
934 lpmii
.fMask
= MIIM_DATA
| MIIM_TYPE
| MIIM_ID
;
936 lpmii
.fType
= MF_STRING
;
937 lpmii
.dwTypeData
= szFriendlyName
;
938 lpmii
.dwItemData
= dwDeviceIndex
;
939 InsertMenuItem(hMenu
, uItem
, fByPosition
, &lpmii
);
945 BuildFileFilterAndDeviceMenu(VOID
)
947 TCHAR szDeviceName
[MAX_MCISTR
];
948 TCHAR szFriendlyName
[MAX_MCISTR
];
949 TCHAR
*szDevice
= NULL
;
950 static TCHAR szDefaultExtension
[] = _T("*.*");
951 TCHAR
*szExtensionList
= NULL
;
952 TCHAR
*szExtension
= NULL
;
957 DWORD dwValueNameLen
;
958 DWORD dwValueDataSize
;
962 DWORD dwExtensionLen
;
963 DWORD dwPosition
= 0;
970 /* Always load the default (all files) filter */
971 LoadString(hInstance
, IDS_ALL_TYPES_FILTER
, szDefaultFilter
, ARRAYSIZE(szDefaultFilter
));
973 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\MCI Extensions"), 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
978 if (RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &dwNumValues
, &dwValueNameLen
, &dwValueDataSize
, NULL
, NULL
) != ERROR_SUCCESS
)
983 dwMaskLen
= ((dwValueNameLen
+ 3) * dwNumValues
) + 1;
985 szExtensionList
= malloc(dwMaskLen
* sizeof(TCHAR
));
986 if (!szExtensionList
)
989 dwNumDevices
= GetNumDevices();
991 /* Allocate space for every pair of Device and Extension Filter */
992 dwFilterSize
= (MAX_MCISTR
+ (dwMaskLen
* 2) + 5) * dwNumDevices
;
994 /* Add space for the "All supported" entry */
995 dwFilterSize
= (dwFilterSize
+ (dwMaskLen
* 2) + 7) * sizeof(TCHAR
) + sizeof(szDefaultFilter
);
997 szFilter
= malloc(dwFilterSize
);
1001 szExtension
= malloc((dwValueNameLen
+ 1) * sizeof(TCHAR
));
1005 szDevice
= malloc(dwValueDataSize
+ sizeof(TCHAR
));
1009 ZeroMemory(szFilter
, dwFilterSize
);
1011 uSizeRemain
= dwFilterSize
;
1014 for (j
= 1; j
<= dwNumDevices
; j
++)
1016 if (GetDeviceName(j
, szDeviceName
, sizeof(szDeviceName
)))
1021 if (GetDeviceFriendlyName(szDeviceName
, szFriendlyName
, sizeof(szFriendlyName
)))
1026 /* Insert a menu item under the "Device" menu for every found MCI device */
1027 InsertDeviceMenuItem(GetSubMenu(hMainMenu
, 3), dwPosition
, TRUE
, IDM_DEVICE_FIRST
+ dwPosition
, j
);
1030 /* Copy the default extension list, that may be overwritten after... */
1031 StringCbCopy(szExtensionList
, dwMaskLen
* sizeof(TCHAR
), szDefaultExtension
);
1033 /* Try to determine the real extension list */
1034 uMaskRemain
= dwMaskLen
* sizeof(TCHAR
);
1035 d
= szExtensionList
;
1037 for (i
= 0; i
< dwNumValues
; i
++)
1039 dwExtensionLen
= dwValueNameLen
+ 1;
1040 dwDeviceSize
= dwValueDataSize
+ sizeof(TCHAR
);
1042 ZeroMemory(szDevice
, dwDeviceSize
);
1044 if (RegEnumValue(hKey
, i
, szExtension
, &dwExtensionLen
, NULL
, NULL
, (LPBYTE
)szDevice
, &dwDeviceSize
) == ERROR_SUCCESS
)
1046 CharLowerBuff(szDevice
, dwDeviceSize
/ sizeof(TCHAR
));
1047 CharLowerBuff(szDeviceName
, ARRAYSIZE(szDeviceName
));
1048 if (_tcscmp(szDeviceName
, szDevice
) == 0)
1050 CharLowerBuff(szExtension
, dwExtensionLen
);
1051 StringCbPrintfEx(d
, uMaskRemain
, &d
, &uMaskRemain
, 0, _T("%s%s%s"), _T("*."), szExtension
, _T(";"));
1056 /* Remove the last separator */
1058 uSizeRemain
+= sizeof(*d
);
1061 /* Add the description */
1062 StringCbPrintfEx(c
, uSizeRemain
, &c
, &uSizeRemain
, 0, _T("%s (%s)"), szFriendlyName
, szExtensionList
);
1064 /* Skip one char to separate the description from the filter mask */
1066 uSizeRemain
-= sizeof(*c
);
1068 /* Append the filter mask */
1069 StringCbCopyEx(c
, uSizeRemain
, szExtensionList
, &c
, &uSizeRemain
, 0);
1071 /* Skip another char to separate the elements of the filter mask */
1073 uSizeRemain
-= sizeof(*c
);
1076 /* Build the full list of supported extensions */
1077 uMaskRemain
= dwMaskLen
* sizeof(TCHAR
);
1078 d
= szExtensionList
;
1080 for (i
= 0; i
< dwNumValues
; i
++)
1082 dwExtensionLen
= dwValueNameLen
+ 1;
1084 if (RegEnumValue(hKey
, i
, szExtension
, &dwExtensionLen
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1086 CharLowerBuff(szExtension
, dwExtensionLen
);
1087 StringCbPrintfEx(d
, uMaskRemain
, &d
, &uMaskRemain
, 0, _T("%s%s%s"), _T("*."), szExtension
, _T(";"));
1091 /* Remove the last separator */
1093 uSizeRemain
+= sizeof(*d
);
1096 /* Add the default (all files) description */
1097 StringCbPrintfEx(c
, uSizeRemain
, &c
, &uSizeRemain
, 0, _T("%s (%s)"), szDefaultFilter
, szExtensionList
);
1099 /* Skip one char to separate the description from the filter mask */
1101 uSizeRemain
-= sizeof(*c
);
1103 /* Append the filter mask */
1104 StringCbCopyEx(c
, uSizeRemain
, szExtensionList
, &c
, &uSizeRemain
, 0);
1107 if (szExtensionList
) free(szExtensionList
);
1108 if (szExtension
) free(szExtension
);
1109 if (szDevice
) free(szDevice
);
1115 /* We failed at retrieving the supported files, so use the default filter */
1116 if (szFilter
) free(szFilter
);
1117 szFilter
= szDefaultFilter
;
1119 uSizeRemain
= sizeof(szDefaultFilter
);
1122 /* Add the default (all files) description */
1123 StringCbPrintfEx(c
, uSizeRemain
, &c
, &uSizeRemain
, 0, _T("%s (%s)"), szDefaultFilter
, szDefaultExtension
);
1125 /* Skip one char to separate the description from the filter mask */
1127 uSizeRemain
-= sizeof(*c
);
1129 /* Append the filter mask */
1130 StringCbCopyEx(c
, uSizeRemain
, szDefaultExtension
, &c
, &uSizeRemain
, 0);
1136 CleanupFileFilter(VOID
)
1138 if (szFilter
&& szFilter
!= szDefaultFilter
) free(szFilter
);
1142 OpenFileDialog(HWND hwnd
, DWORD dwFilterIndex
, LPTSTR lpType
)
1144 OPENFILENAME OpenFileName
;
1145 TCHAR szFile
[MAX_PATH
+ 1] = _T("");
1146 TCHAR szCurrentDir
[MAX_PATH
];
1148 ZeroMemory(&OpenFileName
, sizeof(OpenFileName
));
1150 if (!GetCurrentDirectory(ARRAYSIZE(szCurrentDir
), szCurrentDir
))
1152 StringCbCopy(szCurrentDir
, sizeof(szCurrentDir
), _T("c:\\"));
1155 OpenFileName
.lStructSize
= sizeof(OpenFileName
);
1156 OpenFileName
.hwndOwner
= hwnd
;
1157 OpenFileName
.hInstance
= hInstance
;
1158 OpenFileName
.lpstrFilter
= szFilter
;
1159 OpenFileName
.lpstrFile
= szFile
;
1160 OpenFileName
.nMaxFile
= ARRAYSIZE(szFile
);
1161 OpenFileName
.lpstrInitialDir
= szCurrentDir
;
1162 OpenFileName
.Flags
= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
| OFN_SHAREAWARE
;
1163 OpenFileName
.lpstrDefExt
= _T("\0");
1164 OpenFileName
.nFilterIndex
= dwFilterIndex
;
1166 if (!GetOpenFileName(&OpenFileName
))
1169 OpenMediaFile(hwnd
, OpenFileName
.lpstrFile
, lpType
);
1173 HandleDeviceMenuItem(HWND hwnd
, UINT uItem
)
1176 TCHAR szDeviceName
[MAX_MCISTR
];
1179 ZeroMemory(&lpmii
, sizeof(MENUITEMINFO
));
1180 lpmii
.cbSize
= sizeof(lpmii
);
1181 lpmii
.fMask
= MIIM_DATA
;
1182 GetMenuItemInfo(hMainMenu
, uItem
, FALSE
, &lpmii
);
1184 mciError
= GetDeviceName(lpmii
.dwItemData
, szDeviceName
, sizeof(szDeviceName
));
1187 ShowMCIError(hwnd
, mciError
);
1191 if (DeviceUsesFiles(szDeviceName
))
1193 OpenFileDialog(hwnd
, uItem
- IDM_DEVICE_FIRST
+ 1, szDeviceName
);
1197 mciError
= OpenMciDevice(hwnd
, szDeviceName
, NULL
);
1200 ShowMCIError(hwnd
, mciError
);
1207 MainWndProc(HWND hwnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
1214 hMainMenu
= GetMenu(hwnd
);
1221 TCHAR droppedfile
[MAX_PATH
];
1223 drophandle
= (HDROP
)wParam
;
1224 DragQueryFile(drophandle
, 0, droppedfile
, ARRAYSIZE(droppedfile
));
1225 DragFinish(drophandle
);
1226 OpenMediaFile(hwnd
, droppedfile
, NULL
);
1232 if (wParam
== MCI_NOTIFY_SUCCESSFUL
)
1237 StartPlayback(hwnd
);
1245 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
1247 switch (pnmhdr
->code
)
1249 case TTN_GETDISPINFO
:
1251 LPTOOLTIPTEXT lpttt
= (LPTOOLTIPTEXT
)lParam
;
1252 UINT idButton
= (UINT
)lpttt
->hdr
.idFrom
;
1257 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PLAY
);
1260 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_STOP
);
1263 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EJECT
);
1266 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_BACKWARD
);
1269 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_SEEKBACK
);
1272 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_SEEKFORW
);
1275 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_FORWARD
);
1278 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE
);
1289 LPRECT pRect
= (LPRECT
)lParam
;
1291 if (!bIsSingleWindow
)
1293 if (pRect
->right
- pRect
->left
< MAIN_WINDOW_MIN_WIDTH
)
1294 pRect
->right
= pRect
->left
+ MAIN_WINDOW_MIN_WIDTH
;
1296 if (pRect
->bottom
- pRect
->top
!= MAIN_WINDOW_HEIGHT
)
1297 pRect
->bottom
= pRect
->top
+ MAIN_WINDOW_HEIGHT
;
1306 if (hToolBar
&& hTrackBar
)
1308 SendMessage(hToolBar
, TB_AUTOSIZE
, 0, 0);
1309 SendMessage(hToolBar
, TB_GETITEMRECT
, 1, (LPARAM
)&Rect
);
1310 MoveWindow(hTimeDisplay
, LOWORD(lParam
) - 140, 4, 135, 18, TRUE
);
1312 if (!bIsSingleWindow
)
1314 UINT Size
= GetSystemMetrics(SM_CYMENU
) + Rect
.bottom
;
1315 MoveWindow(hTrackBar
, 0, 0, LOWORD(lParam
), HIWORD(lParam
) - Size
, TRUE
);
1320 MCI_DGV_PUT_PARMS mciPut
;
1322 MoveWindow(hTrackBar
, 180, 0, LOWORD(lParam
) - 322, 25, TRUE
);
1324 GetClientRect(hwnd
, &Rect
);
1325 GetClientRect(hToolBar
, &ToolbarRect
);
1329 mciPut
.rc
.right
= Rect
.right
;
1330 mciPut
.rc
.bottom
= Rect
.bottom
- (ToolbarRect
.bottom
- ToolbarRect
.top
) - 2;
1332 mciSendCommand(wDeviceId
, MCI_PUT
, MCI_DGV_PUT_DESTINATION
| MCI_DGV_RECT
| MCI_WAIT
, (DWORD_PTR
)&mciPut
);
1340 if (hTrackBar
== (HWND
)lParam
)
1344 DWORD dwNewPos
= (DWORD
)SendMessage(hTrackBar
, TBM_GETPOS
, 0, 0);
1345 SeekPlayback(hwnd
, dwNewPos
);
1349 SendMessage(hTrackBar
, TBM_SETPOS
, TRUE
, 0);
1355 case WM_NCLBUTTONDBLCLK
:
1357 if (wParam
== HTCAPTION
)
1359 SwitchViewMode(hwnd
);
1366 if (LOWORD(wParam
) >= IDM_DEVICE_FIRST
)
1368 HandleDeviceMenuItem(hwnd
, LOWORD(wParam
));
1372 switch (LOWORD(wParam
))
1378 TogglePlaybackState(hwnd
);
1380 OpenFileDialog(hwnd
, 1, NULL
);
1396 SeekBackPlayback(hwnd
);
1400 SeekForwPlayback(hwnd
);
1407 OpenFileDialog(hwnd
, 1, NULL
);
1410 case IDM_CLOSE_FILE
:
1411 CloseMediaFile(hwnd
);
1418 CheckMenuItem(hMainMenu
, IDM_REPEAT
, MF_BYCOMMAND
| MF_CHECKED
);
1423 CheckMenuItem(hMainMenu
, IDM_REPEAT
, MF_BYCOMMAND
| MF_UNCHECKED
);
1429 case IDM_SWITCHVIEW
:
1430 SwitchViewMode(hwnd
);
1434 ShowDeviceProperties(hwnd
);
1438 ShellExecute(hwnd
, NULL
, _T("SNDVOL32.EXE"), NULL
, NULL
, SW_SHOWNORMAL
);
1443 HICON mplayIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_MAIN
));
1444 ShellAbout(hwnd
, szAppTitle
, 0, mplayIcon
);
1445 DeleteObject(mplayIcon
);
1450 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
1457 CloseMediaFile(hwnd
);
1462 return DefWindowProc(hwnd
, Message
, wParam
, lParam
);
1466 _tWinMain(HINSTANCE hInst
, HINSTANCE hPrevInst
, LPTSTR lpCmdLine
, INT nCmdShow
)
1468 WNDCLASSEX WndClass
= {0};
1469 TCHAR szClassName
[] = _T("ROSMPLAY32");
1477 LoadString(hInstance
, IDS_APPTITLE
, szAppTitle
, ARRAYSIZE(szAppTitle
));
1479 WndClass
.cbSize
= sizeof(WndClass
);
1480 WndClass
.lpszClassName
= szClassName
;
1481 WndClass
.lpfnWndProc
= MainWndProc
;
1482 WndClass
.hInstance
= hInstance
;
1483 WndClass
.style
= CS_HREDRAW
| CS_VREDRAW
;
1484 WndClass
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_MAIN
));
1485 WndClass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
1486 WndClass
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1487 WndClass
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
1489 if (!RegisterClassEx(&WndClass
))
1491 ShowLastWin32Error(NULL
);
1495 hwnd
= CreateWindow(szClassName
,
1497 WS_SYSMENU
| WS_MINIMIZEBOX
| WS_THICKFRAME
| WS_OVERLAPPED
| WS_CAPTION
| WS_CLIPCHILDREN
,
1508 ShowLastWin32Error(NULL
);
1512 hAccel
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(ID_ACCELERATORS
));
1514 BuildFileFilterAndDeviceMenu();
1516 DragAcceptFiles(hwnd
, TRUE
);
1520 dwError
= SearchPath(NULL
, _T("SNDVOL32.EXE"), NULL
, 0, NULL
, NULL
);
1523 EnableMenuItem(hMainMenu
, IDM_VOLUMECTL
, MF_BYCOMMAND
| MF_GRAYED
);
1527 ShowWindow(hwnd
, SW_SHOW
);
1530 OpenMediaFile(hwnd
, lpCmdLine
, NULL
);
1533 while (GetMessage(&msg
, NULL
, 0, 0))
1535 if (!TranslateAccelerator(hwnd
, hAccel
, &msg
))
1537 TranslateMessage(&msg
);
1538 DispatchMessage(&msg
);
1542 CleanupFileFilter();
1544 DestroyAcceleratorTable(hAccel
);
1546 return (INT
)msg
.wParam
;