How to provide a HWND to DirectSound SetCooperativeLevel in a console program?
Asked Answered
M

2

6

I'm writing a console program that uses DirectSound API to render some audio data. I stumbled on a curious problem when following the DirectSound Programming Guide (from Microsoft). According to the documentation :

After creating a device object, you must set the cooperative level for the device by using the IDirectSound8::SetCooperativeLevel method. Unless you do this, no sounds will be heard.

The problem is that I'm writing a console program, and SetCooperativeLevel requires a HWND as a first argument. I don't have any HWND to deal with in the console program. I tried providing a null pointer but it failed with a DSERR_INVALIDPARAM error code.

What HWND value should be provided to IDirectSound8::SetCooperativeLevel in a console program ? The audio part of the program is planned to be built as a shared library, so it has little to no knowledge of the "outside" program.

Thanks for any advice !

Note : I know that there is a somewhat better solution for simply rendering audio, like using SDL, OpenAL, SFML (based on OpenAL), but for my current project DirectSound is enforced.


Edit : I found a message from a Microsoft engineer that removes doubts about using the desktop window or the console window as a HWND for SetCooperativeLevel when creating GLOBAL_FOCUS buffers.

Mail answered 15/7, 2011 at 23:11 Comment(0)
M
3

Although I have not tested this myself, you may have some success creating a hidden window and passing its HWND to the SetCooperativeLevel method. SetCooperativeLevel uses this hwnd to determine when your application has input focus; therefore, if you select a cooperative level where the input focus doesn't matter (eg, DSSCL_NORMAL), a hidden window (which will never receive input focus) should be fine.

Mcmillian answered 15/7, 2011 at 23:35 Comment(6)
As you said, the input focus should not interfere when rendering audio. I innocently tested providing the HWND returned by GetDesktopWindow() to SetCooperativeLevel, and it seems to work. However, I don't know if it has any drawbacks compared to using a hidden window handle ...Mail
Passing a HWND you don't control seems like a very bad idea. It's one of those things that'll probably work just fine - until the day your code ends up being dissected at dailywtf or "the old new thing".Dalt
@overcoder, I'd be worried about what happens if another program decides to do the same thing...Mcmillian
@snemarch, @Mcmillian : You're right. I prefer writing it properly, as described by bdonlan. Murphy's law come to mind : 'Anything that can possibly go wrong, does' ...Mail
It's perfectly fine to pass another app's HWND to DirectSound. Not a great design, but it works. This is how certain gamer voice-comm app's like RogerWilco and Battlecom used to do it before DSSCL_EXCLUSIVE mode was deprecated (and all the games used that mode). The game could remain in the foreground with it's own HWND, yet the voice-comm app could play audio in the background. As a matter of fact, you don't even have to pass in a valid HWND at all if you're using coop mode that doesn't care about app focus. You could pass in anything non-zero.Schrock
@Schrock : Thanks for your reply. I previously found that using some nonzero HWND works fine, but the doubt is still present without an explicit reference or documentation. I (heavily) googled to find one from a microsoft engineer : groups.google.com/group/…Mail
M
2

you can use this ::GetDesktopWindow().

Mattins answered 23/8, 2012 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.