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.
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.
you can use this ::GetDesktopWindow().
Related
Win32 programs generally have a message loop that loops calling GetMessage or PeekMessage, and then calls DispatchMessage to dispatch the message to the window proceedure of the relevant window.
But is there any need to actually do this? Can I instead just look in the MSG object directly in the message loop and perform the actions needed there without calling DispatchMessage? I'm talking about cases where I have one single window with no other window controls, for example if the window is only used as a direct3d display window, so messages will always be directed at the only window.
Mostly I'm just curious but also it might lead to certain aspects of my code being cleaner too.
You call DispatchMessage to have the message delivered to proper window, to its "window proc". You think you have one window only, but is it really the only one? COM will create helper windows, other subsystems might create helper hidden windows as well, who is going to deliver messages posted to shared message queue and addressed to those windows. Without having to think a lot about these details you have API to dispatch them. And you have to do it because those subsystems are relying on presence of message pump.
Spy++ Windows SDK tool might help you with seeing how many windows you really have.
Still if you indeed have the only window, it does not make much of a difference whether you handler is called from DispatchMessage internals, or directly by your message pump.
If an Win32 app has its UI designed using sigc and glibmm,
how does it implement its message loops?
does it still use win32 API such as GetMessage, DispatchMessage, TranslateMessage, etc?
or they use other functions to finish this?
And the default WinProc is still there?
sigc+glibmm is the C++ level on top of the GTK C Framework callbacks/main loop which is on top of the native callback/main loop (NSRunLoop for MacOSX and GetMessage on Windows).
GetMessage must be called by every GUI application on Windows to get the absolute basics like a window handle, key presses and mouse movements.
TranslateMessage is not required because accelerator keys are handled with GTK's own implementation.
SendMessage is used very rare, most calls that require SendMessage are calls to a client control like a button or text field widget. In GTK they are implemented as GtkButton and GtkEntry and GTK can directly use the C implementation without going through the windows message dispatching.
All Windows GUI apps have to run a message pump based on GetMessage, TranslateMessage, DispatchMessage. Frameworks typically shield you from the implementation details, but somewhere in the framework will be a message pump.
The same is true for window procedures. Although you may never have to write one or interact with one, the framework will have to provide window procedures for top-level windows, and possibly for child windows depending on how the framework is implemented.
Is it possible to use Windows Raw Input API without a window (ie from a console application)?
I've tried using RegisterRawInputDevices but my message loops doesn't seem to get any events from GetMessage and hence just 'hangs' there.
That way I did it (not sure it is the most comfortable way...):
I have started a thread (for the task of filling my input buffer).
In this thread I have created a message-only window (its hidden, and can get input datas) with an appropriate window-class.
Then registered the raw input devices.
This thread has its own message handler loop.
In the WindowProc of the window-class I've handled the inputs.
(For buffer, You can use boost:circular_buffer, it ROCKS! :D)
In this solution You did need have a window, but it looks like You don't. :)
I hope this can help.
Do you mean RegisterRawInputDevices?
Since the RAWINPUTDEVICE structure requires you to specify an HWND to receive the WM_INPUT messages, no it's not possible to do this without a window.
Console applications can create windows, and the window probably can receive WM_INPUT while hidden, but you do need a window.
I'm currently working on a Win32 program which requires a main window containing many child window controls - buttons, listviews and so on. I believe the standard way to build such a window is to first call CreateWindow for the main window, then again for each of the controls.
As an easier option, I'm considering designing the main window using the resource editor's dialog box designer, then using CreateDialog to build the main window in one go.
By using a CLASS statement in the dialog box template, I should be able to get the main window to use a custom window class (and hence a custom window procedure) and thus avoid the window having any dialog-like behaviour. An example of this technique can be found in Charles Petzold's "Programming Windows": the HEXCALC program in chapter 11.
Are there any downsides to creating my main window in this way? If so, what are they? If not, why is this approach rarely used?
You don't get control of your main window message loop - the dialog manager handles it for you. On the other hand, the dialog manager handles keyboard accelerators, tab ordering and a number of other effects.
You'd be surprised what you can do with a standard dialog box - the windows volume control is implemented with about four different dialog boxes - it has a frame dialog box which in turn host hosts a tray window which in turn holds volume control dialog boxes, one for each app volume.
The only downside of CreateDialog I know of (as compared to repeated CreateWindow, not talking about some heavyweight framework, just Win32 vs Win32) is that dialog resources position child windows using dialog units. So the layout is dependent not only on DPI, but also on the user's theme settings (choice and size of font).
If any of your controls need to have fixed sizes in terms of pixels, you won't be happy with the dialog-provided positioning and will need to go through and move all the child windows after the fact.
So yes, you can use CreateDialog as a shortcut for creating a bunch of windows with specified classes and styles. But no, you can't do your layout in the dialog editor.
OTOH, you could store the DLU <-> pixel conversion used on your design machine, and then learn enough about parsing the DIALOG resource internal format to pull out the positioning information, then convert to pixels and correct the positioning in more automated fashion.
You will be able to have the full control over your window, even if it was created with CreateDialog.
Normally, when you create your own window (of your class), the window procedure used is the one that you registered with the class. OTOH windows created via CreateDialog will have the dialog standard window procedure (DefDlgProc), which will mostly invoke your supplied "dialog handler".
If you want to have full control of all the messages you may replace the window proc of the newly created window right after its creation. Just call SetWindowLongPtr with GWLP_WNDPROC parameter. Still, you may do the auto processing of some dialog-specific things by calling IsDialogMessage within your procedure.
There is no downside whatsoever.
Why is it rarely used? Because:
People normally use DialogBox instead, since that is easier for simpler cases.
For more complex cases, people use things like MFC or ATL (or some external library like GTk or Qt), and don't bother with native Win32 graphics.
There are no downsides using the Windows SDK, internally libraries like MFC use the Windows SDK .
People tend to use libraries like MFC over Windows SDK, as libaries have the readymade stuff. However Windows SDK calls are faster than library calls, so in some situations developers call Windows SDK directly .
CButton btnOk ;
btnOK.Create(_T("Press Me"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(100,100,300,300), pParentWnd, 1);
is similar to the following code ,
HWND hWnd = CreateWindow("BUTTON","Press Me",WS_CHILD|WS_POPUP|BS_DEFPUSHBUTTON,100,100,300,300,NULL,NULL,GetModuleHandle(NULL),NULL);
ShowWindow(hWnd,SW_SHOW);
Using WinXP. What I need to do (pref in VB or c#) is to detect when another (closed source) program displays a notification balloon in the tray - and grab the details. Any help would be appreciated. Thanks
In similar situations, I have used the Microsoft tool Spy++ to grab the window information and then uses pinvoke calls to FindWindow to detect when the window is present.
I've not tried with a notification balloon, but I imagine that a pinvoke call to GetText would retrieve the contents.
I think you'll need to use pinvoke to do this from a .net language.
On the system I'm using now (Vista Business SP2), balloon windows always seem to have window class #32769 (reserved for desktop windows) and the windows style bit TTS_BALLOON set.
The following might work: Determine the parent window for all notification balloons by creating a temporary one, getting its hWnd, and calling GetParent() before deleting it. You could then periodically poll the children of this parent hwnd (using EnumWindows() or FindWindowEx()) looking for windows with the required class and style.
This seems highly non-portable to me, and likely to require a lot of testing on a variety of platforms.
pinvoke.net and spy++ might be useful.
Good luck!
You will definitely need to use Win API calls to achieve this. If this is the only thing you're trying to do, you'd be better off using straight C or C++ so you don't have to do a bunch of platform invoke for C# or VB.
Since andyjohnson identified that the window class for all notification balloons is #32769, and that they have the TTS_BALLOON style set, you could use a CBT hook (if you're not familiar with Win32 hooks, you might want to read up on them), to get a callback whenever a window is created, and check for windows of that class and with that style.
I'm not sure, though, if a new balloon window is created for second and subsequent popups or if the same one is just hidden and reshown. If this is the case, you might need a CallWndProc hook, to get WM_SHOWWINDOW messages.
Edit:
I should mention that the hooks that I've mentioned cannot be implemented in .NET. Except for the low-level keyboard and mouse hooks, global system hooks must be implemented in a native (unmanaged) DLL. Windows will load this DLL into other processes, and if a managed DLL gets loaded into a process that doesn't have the .NET CLR loaded, it will crash that process. (Even if the CLR is loaded, it might be at a different address, also causing a crash.)
So you must build your hooks in a native (unmanaged) DLL. It's possible to interface from here to a managed application, such as Michael Kennedy has done on Code Project, but to do it properly, and handle the hook types I've mentioned above, you'd need to use interprocess communication, a step that Michael Kennedy left out. All in all, for the purpose you've described, it would probably be easier to just build the whole thing in native code.