Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
2dfd3e90
Commit
2dfd3e90
authored
Nov 10, 2009
by
Jörg Höhle
Committed by
Alexandre Julliard
Nov 11, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mciwave: Rework MCI notification system.
parent
2ac86feb
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
84 additions
and
41 deletions
+84
-41
mciwave.c
dlls/mciwave/mciwave.c
+76
-34
mci.c
dlls/winmm/tests/mci.c
+8
-7
No files found.
dlls/mciwave/mciwave.c
View file @
2dfd3e90
...
...
@@ -4,6 +4,7 @@
* Copyright 1994 Martin Ayotte
* 1999,2000,2005 Eric Pouech
* 2000 Francois Jacques
* 2009 Jörg Höhle
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -40,6 +41,7 @@ typedef struct {
int
nUseCount
;
/* Incremented for each shared open */
HMMIO
hFile
;
/* mmio file handle open as Element */
MCI_WAVE_OPEN_PARMSW
openParms
;
HANDLE
hCallback
;
/* Callback handle for pending notification */
WAVEFORMATEX
wfxRef
;
LPWAVEFORMATEX
lpWaveFormat
;
/* Points to wfxRef until set by OPEN or RECORD */
BOOL
fInput
;
/* FALSE = Output, TRUE = Input */
...
...
@@ -199,6 +201,21 @@ static WINE_MCIWAVE *WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
}
/**************************************************************************
* WAVE_mciNotify [internal]
*
* Notifications in MCI work like a 1-element queue.
* Each new notification request supersedes the previous one.
* This affects Play and Record; other commands are immediate.
*/
static
void
WAVE_mciNotify
(
DWORD_PTR
hWndCallBack
,
WINE_MCIWAVE
*
wmw
,
UINT
wStatus
)
{
MCIDEVICEID
wDevID
=
wmw
->
openParms
.
wDeviceID
;
HANDLE
old
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
NULL
);
if
(
old
)
mciDriverNotify
(
old
,
wDevID
,
MCI_NOTIFY_SUPERSEDED
);
mciDriverNotify
(
HWND_32
(
LOWORD
(
hWndCallBack
)),
wDevID
,
wStatus
);
}
/**************************************************************************
* WAVE_ConvertByteToTimeFormat [internal]
*/
static
DWORD
WAVE_ConvertByteToTimeFormat
(
WINE_MCIWAVE
*
wmw
,
DWORD
val
,
LPDWORD
lpRet
)
...
...
@@ -509,6 +526,7 @@ static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_P
memcpy
(
&
wmw
->
openParms
,
lpOpenParms
,
sizeof
(
MCI_WAVE_OPEN_PARMSA
));
/* will be set by WAVE_mciOpenFile */
wmw
->
openParms
.
lpstrElementName
=
NULL
;
wmw
->
hCallback
=
NULL
;
WAVE_mciDefaultFmt
(
wmw
);
TRACE
(
"wDevID=%04X (lpParams->wDeviceID=%08X)
\n
"
,
wDevID
,
lpOpenParms
->
wDeviceID
);
...
...
@@ -529,6 +547,9 @@ static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_P
wmw
->
dwPosition
=
0
;
wmw
->
dwStatus
=
MCI_MODE_STOP
;
if
(
dwFlags
&
MCI_NOTIFY
)
WAVE_mciNotify
(
lpOpenParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
}
else
{
wmw
->
nUseCount
--
;
if
(
wmw
->
hFile
!=
0
)
...
...
@@ -595,6 +616,11 @@ static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS
if
(
wmw
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
wmw
->
dwStatus
!=
MCI_MODE_STOP
)
{
HANDLE
old
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
NULL
);
if
(
old
)
mciDriverNotify
(
old
,
wDevID
,
MCI_NOTIFY_ABORTED
);
}
/* wait for playback thread (if any) to exit before processing further */
switch
(
wmw
->
dwStatus
)
{
case
MCI_MODE_PAUSE
:
...
...
@@ -614,10 +640,8 @@ static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS
/* sanity resets */
wmw
->
dwStatus
=
MCI_MODE_STOP
;
if
((
dwFlags
&
MCI_NOTIFY
)
&&
lpParms
)
{
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
if
((
dwFlags
&
MCI_NOTIFY
)
&&
lpParms
&&
MMSYSERR_NOERROR
==
dwRet
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
dwRet
;
}
...
...
@@ -635,6 +659,7 @@ static DWORD WAVE_mciClose(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARM
if
(
wmw
==
NULL
)
return
MCIERR_INVALID_DEVICE_ID
;
if
(
wmw
->
dwStatus
!=
MCI_MODE_STOP
)
{
/* mciStop handles MCI_NOTIFY_ABORTED */
dwRet
=
WAVE_mciStop
(
wDevID
,
MCI_WAIT
,
lpParms
);
}
...
...
@@ -654,9 +679,8 @@ static DWORD WAVE_mciClose(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARM
wmw
->
openParms
.
lpstrElementName
=
NULL
;
if
((
dwFlags
&
MCI_NOTIFY
)
&&
lpParms
)
{
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
(
dwRet
==
0
)
?
MCI_NOTIFY_SUCCESSFUL
:
MCI_NOTIFY_FAILURE
);
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
(
dwRet
==
0
)
?
MCI_NOTIFY_SUCCESSFUL
:
MCI_NOTIFY_FAILURE
);
}
return
0
;
...
...
@@ -712,6 +736,7 @@ static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt,
DWORD
dwRet
;
LPWAVEHDR
waveHdr
=
NULL
;
WINE_MCIWAVE
*
wmw
=
WAVE_mciGetOpenDev
(
wDevID
);
HANDLE
oldcb
;
int
whidx
;
TRACE
(
"(%u, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
...
...
@@ -779,6 +804,11 @@ static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt,
TRACE
(
"Playing from byte=%u to byte=%u
\n
"
,
wmw
->
dwPosition
,
end
);
oldcb
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
(
dwFlags
&
MCI_NOTIFY
)
?
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
))
:
NULL
);
if
(
oldcb
)
mciDriverNotify
(
oldcb
,
wDevID
,
MCI_NOTIFY_ABORTED
);
oldcb
=
NULL
;
if
(
end
<=
wmw
->
dwPosition
)
return
MMSYSERR_NOERROR
;
...
...
@@ -870,6 +900,9 @@ static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt,
dwRet
=
0
;
cleanUp:
if
(
dwFlags
&
MCI_NOTIFY
)
oldcb
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
NULL
);
HeapFree
(
GetProcessHeap
(),
0
,
waveHdr
);
if
(
wmw
->
hWave
)
{
...
...
@@ -880,11 +913,9 @@ cleanUp:
wmw
->
dwStatus
=
MCI_MODE_STOP
;
if
(
lpParms
&&
(
dwFlags
&
MCI_NOTIFY
))
{
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
dwRet
?
MCI_NOTIFY_FAILURE
:
MCI_NOTIFY_SUCCESSFUL
);
}
/* Let the potentically asynchronous commands support FAILURE notification. */
if
(
oldcb
)
mciDriverNotify
(
oldcb
,
wDevID
,
dwRet
?
MCI_NOTIFY_FAILURE
:
MCI_NOTIFY_SUCCESSFUL
);
return
dwRet
;
}
...
...
@@ -959,6 +990,7 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt
LONG
bufsize
;
LPWAVEHDR
waveHdr
=
NULL
;
WINE_MCIWAVE
*
wmw
=
WAVE_mciGetOpenDev
(
wDevID
);
HANDLE
oldcb
;
TRACE
(
"(%u, %08lX, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
...
...
@@ -1013,6 +1045,11 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt
TRACE
(
"Recording from byte=%u to byte=%u
\n
"
,
wmw
->
dwPosition
,
end
);
oldcb
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
(
dwFlags
&
MCI_NOTIFY
)
?
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
))
:
NULL
);
if
(
oldcb
)
mciDriverNotify
(
oldcb
,
wDevID
,
MCI_NOTIFY_ABORTED
);
oldcb
=
NULL
;
if
(
end
<=
wmw
->
dwPosition
)
{
return
MMSYSERR_NOERROR
;
...
...
@@ -1081,7 +1118,11 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt
while
(
wmw
->
dwPosition
<
end
&&
wmw
->
dwStatus
!=
MCI_MODE_STOP
&&
wmw
->
dwStatus
!=
MCI_MODE_NOT_READY
)
{
WAVE_mciRecordWaitDone
(
wmw
);
}
/* Grab callback before another thread kicks in after we change dwStatus. */
if
(
dwFlags
&
MCI_NOTIFY
)
{
oldcb
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
NULL
);
dwFlags
&=
~
MCI_NOTIFY
;
}
/* needed so that the callback above won't add again the buffers returned by the reset */
wmw
->
dwStatus
=
MCI_MODE_STOP
;
...
...
@@ -1093,6 +1134,9 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt
dwRet
=
0
;
cleanUp:
if
(
dwFlags
&
MCI_NOTIFY
)
oldcb
=
InterlockedExchangePointer
(
&
wmw
->
hCallback
,
NULL
);
HeapFree
(
GetProcessHeap
(),
0
,
waveHdr
);
if
(
wmw
->
hWave
)
{
...
...
@@ -1103,11 +1147,8 @@ cleanUp:
wmw
->
dwStatus
=
MCI_MODE_STOP
;
if
(
lpParms
&&
(
dwFlags
&
MCI_NOTIFY
))
{
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
dwRet
?
MCI_NOTIFY_FAILURE
:
MCI_NOTIFY_SUCCESSFUL
);
}
if
(
oldcb
)
mciDriverNotify
(
oldcb
,
wDevID
,
dwRet
?
MCI_NOTIFY_FAILURE
:
MCI_NOTIFY_SUCCESSFUL
);
return
dwRet
;
...
...
@@ -1148,6 +1189,8 @@ static DWORD WAVE_mciPause(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARM
default:
dwRet
=
MCIERR_NONAPPLICABLE_FUNCTION
;
}
if
(
MMSYSERR_NOERROR
==
dwRet
&&
(
dwFlags
&
MCI_NOTIFY
)
&&
lpParms
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
dwRet
;
}
...
...
@@ -1189,6 +1232,8 @@ static DWORD WAVE_mciResume(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PAR
default:
dwRet
=
MCIERR_NONAPPLICABLE_FUNCTION
;
}
if
(
MMSYSERR_NOERROR
==
dwRet
&&
(
dwFlags
&
MCI_NOTIFY
)
&&
lpParms
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
dwRet
;
}
...
...
@@ -1219,10 +1264,9 @@ static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lp
TRACE
(
"Seeking to position=%u bytes
\n
"
,
wmw
->
dwPosition
);
if
(
dwFlags
&
MCI_NOTIFY
)
{
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
if
(
dwFlags
&
MCI_NOTIFY
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
MMSYSERR_NOERROR
;
}
...
...
@@ -1327,6 +1371,8 @@ static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpPa
wmw
->
wfxRef
.
nSamplesPerSec
=
((
LPMCI_WAVE_SET_PARMS
)
lpParms
)
->
nSamplesPerSec
;
TRACE
(
"MCI_WAVE_SET_SAMPLESPERSEC = %d
\n
"
,
wmw
->
wfxRef
.
nSamplesPerSec
);
}
if
(
dwFlags
&
MCI_NOTIFY
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
0
;
}
...
...
@@ -1337,7 +1383,6 @@ static DWORD WAVE_mciSave(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW l
{
WINE_MCIWAVE
*
wmw
=
WAVE_mciGetOpenDev
(
wDevID
);
DWORD
ret
=
MCIERR_FILE_NOT_SAVED
,
tmpRet
;
WPARAM
wparam
=
MCI_NOTIFY_FAILURE
;
TRACE
(
"%d, %08X, %p);
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
if
(
lpParms
==
NULL
)
return
MCIERR_NULL_PARAMETER_BLOCK
;
...
...
@@ -1372,12 +1417,8 @@ static DWORD WAVE_mciSave(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW l
ret
=
MMSYSERR_NOERROR
;
}
if
(
dwFlags
&
MCI_NOTIFY
)
{
if
(
ret
==
MMSYSERR_NOERROR
)
wparam
=
MCI_NOTIFY_SUCCESSFUL
;
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
wparam
);
}
if
(
MMSYSERR_NOERROR
==
ret
&&
(
dwFlags
&
MCI_NOTIFY
))
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
if
(
ret
==
MMSYSERR_NOERROR
)
ret
=
WAVE_mciOpenFile
(
wmw
,
lpParms
->
lpfilename
);
...
...
@@ -1502,10 +1543,8 @@ static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARM
return
MCIERR_UNRECOGNIZED_COMMAND
;
}
}
if
(
dwFlags
&
MCI_NOTIFY
)
{
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wmw
->
openParms
.
wDeviceID
,
MCI_NOTIFY_SUCCESSFUL
);
}
if
((
dwFlags
&
MCI_NOTIFY
)
&&
HRESULT_CODE
(
ret
)
==
0
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
ret
;
}
...
...
@@ -1575,6 +1614,8 @@ static DWORD WAVE_mciGetDevCaps(MCIDEVICEID wDevID, DWORD dwFlags,
WARN
(
"No GetDevCaps-Item !
\n
"
);
return
MCIERR_UNRECOGNIZED_COMMAND
;
}
if
((
dwFlags
&
MCI_NOTIFY
)
&&
HRESULT_CODE
(
ret
)
==
0
)
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
ret
;
}
...
...
@@ -1620,7 +1661,8 @@ static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW l
}
else
{
lpParms
->
lpstrReturn
[
0
]
=
0
;
}
if
(
MMSYSERR_NOERROR
==
ret
&&
(
dwFlags
&
MCI_NOTIFY
))
WAVE_mciNotify
(
lpParms
->
dwCallback
,
wmw
,
MCI_NOTIFY_SUCCESSFUL
);
return
ret
;
}
...
...
dlls/winmm/tests/mci.c
View file @
2dfd3e90
...
...
@@ -416,8 +416,8 @@ static void test_asyncWAVE(HWND hwnd)
err
=
mciSendString
(
"status mysound mode notify"
,
buf
,
sizeof
(
buf
),
hwnd
);
ok
(
!
err
,
"mci status mode returned error: %d
\n
"
,
err
);
if
(
!
err
)
ok
(
!
strcmp
(
buf
,
"paused"
),
"mci status mode: %s
\n
"
,
buf
);
t
odo_wine
test_notification1
(
hwnd
,
"play"
,
MCI_NOTIFY_SUPERSEDED
);
t
odo_wine
test_notification1
(
hwnd
,
"status"
,
MCI_NOTIFY_SUCCESSFUL
);
t
est_notification
(
hwnd
,
"play"
,
MCI_NOTIFY_SUPERSEDED
);
t
est_notification
(
hwnd
,
"status"
,
MCI_NOTIFY_SUCCESSFUL
);
buf
[
0
]
=
0
;
err
=
mciSendString
(
"status mysound position"
,
buf
,
sizeof
(
buf
),
hwnd
);
...
...
@@ -430,13 +430,14 @@ static void test_asyncWAVE(HWND hwnd)
ok
(
!
err
,
"mci stop returned error: %s
\n
"
,
dbg_mcierr
(
err
));
buf
[
0
]
=
0
;
err
=
mciSendString
(
"info mysound file
"
,
buf
,
sizeof
(
buf
),
NULL
);
err
=
mciSendString
(
"info mysound file
notify"
,
buf
,
sizeof
(
buf
),
hwnd
);
ok
(
!
err
,
"mci info file returned error: %d
\n
"
,
err
);
if
(
!
err
)
{
/* fully qualified name */
int
len
=
strlen
(
buf
);
todo_wine
ok
(
len
>
2
&&
buf
[
1
]
==
':'
,
"Expected full pathname from info file: %s
\n
"
,
buf
);
ok
(
len
>=
12
&&
!
strcmp
(
&
buf
[
len
-
12
],
"tempfile.wav"
),
"info file returned: %s
\n
"
,
buf
);
}
test_notification
(
hwnd
,
"info file"
,
MCI_NOTIFY_SUCCESSFUL
);
buf
[
0
]
=
0
;
err
=
mciSendString
(
"status mysound mode"
,
buf
,
sizeof
(
buf
),
hwnd
);
...
...
@@ -473,8 +474,8 @@ static void test_asyncWAVE(HWND hwnd)
err
=
mciSendString
(
"pause mysound notify"
,
NULL
,
0
,
NULL
);
/* notify no callback */
ok
(
!
err
,
"mci pause notify returned error: %s
\n
"
,
dbg_mcierr
(
err
));
/* Supersede even though pause cannot not
not
ify given no callback */
t
odo_wine
test_notification1
(
hwnd
,
"pause aborted play #1 notification"
,
MCI_NOTIFY_SUPERSEDED
);
/* Supersede even though pause cannot notify given no callback */
t
est_notification
(
hwnd
,
"pause aborted play #1 notification"
,
MCI_NOTIFY_SUPERSEDED
);
test_notification
(
hwnd
,
"impossible pause notification"
,
0
);
/* Seek or even Stop used to hang Wine on MacOS. */
...
...
@@ -490,7 +491,7 @@ static void test_asyncWAVE(HWND hwnd)
err
=
mciSendString
(
"pause mysound wait"
,
NULL
,
0
,
NULL
);
ok
(
!
err
,
"mci pause wait returned error: %d
\n
"
,
err
);
/* Unlike sequencer and cdaudio, waveaudio's pause does not abort. */
t
odo_wine
test_notification1
(
hwnd
,
"pause aborted play #2 notification"
,
0
);
t
est_notification
(
hwnd
,
"pause aborted play #2 notification"
,
0
);
err
=
mciSendString
(
"resume mysound wait"
,
NULL
,
0
,
NULL
);
ok
(
!
err
,
"mci resume wait returned error: %d
\n
"
,
err
);
...
...
@@ -518,7 +519,7 @@ static void test_asyncWAVE(HWND hwnd)
err
=
mciSendString
(
"close mysound wait"
,
NULL
,
0
,
NULL
);
ok
(
!
err
,
"mci close wait returned error: %d
\n
"
,
err
);
t
odo_wine
test_notification1
(
hwnd
,
"play (aborted by close)"
,
MCI_NOTIFY_ABORTED
);
t
est_notification
(
hwnd
,
"play (aborted by close)"
,
MCI_NOTIFY_ABORTED
);
}
static
void
test_AutoOpenWAVE
(
HWND
hwnd
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment