The Old New Thing

Practical development throughout the evolution of Windows.

Latest posts

Sep 29, 2014
Post comments count 0
Post likes count 1

Simulating media controller buttons like Play and Pause

Raymond Chen

Today's Little Program simulates pressing the Play/Pause button on your fancy keyboard. This might be useful if you want to write a program that converts some other input (say, gesture detection) into media controller events. One way of doing this is to take advantage of the function, since the default behavior for the message is to pass the message up the parent chain, and if it still can't find a handler, it hands the message to the shell for global processing. Remember, don't fumble around. If you want to send a message to a window, then send a message to a window. Don't broadcast a message to every wi...

Sep 26, 2014
Post comments count 0
Post likes count 1

Marshaling won't get in your way if it isn't needed

Raymond Chen

I left an exercise at the end of last week's article: "Why is the error raised only sometimes?" COM subscribes to the principle that if no marshaling is needed, then an interface pointer points directly at the object with no COM code in between. If the current thread is running in a single-threaded apartment, and it creates a COM object with thread affinity (also known as an "apartment-model object"; yes, the name is confusing), then the thread gets a pointer directly to the object. When you call , you are calling directly into the implementation provided by the object. This principle has its pluses and mi...

Sep 25, 2014
Post comments count 0
Post likes count 1

If a process crashes while holding a mutex, why is its ownership magically transferred to another process?

Raymond Chen

A customer was observing strange mutex ownership behavior. They had two processes that used a mutex to coordinate access to some shared resource. When the first process crashed while owning the mutex, they found that the second process somehow magically gained ownership of that mutex. Specifically, when the first process crashed, the second process could take the mutex, but when it released the mutex, the mutex was still not released. They discovered that in order to release the mutex, the second process had to call twice. It's as if the claim on the mutex from the crashed process was secretly transferred to th...

Sep 24, 2014
Post comments count 0
Post likes count 1

What is the story of the mysterious DS_RECURSE dialog style?

Raymond Chen

There are a few references to the dialog style scattered throughout MSDN, and they are all of the form "Don't use it." But if you look in your copy of , there is no sign of anywhere. This obviously makes it trivial to avoid using it because you couldn't use it even if you wanted it, seeing as it doesn't exist. "Do not push the red button on the control panel!" — There is no red button on the control panel. "Well, that makes it easy not to push it." As with many of these types of stories, the answer is rather mundane. When nested dialogs were added to Windows 95, the flag to indicate that a dial...

Sep 23, 2014
Post comments count 0
Post likes count 3

The grand ambition of giving your project the code name Highlander

Raymond Chen

There can be only one, but will it be you?

Sep 22, 2014
Post comments count 0
Post likes count 1

Receiving a notification any time the selection changes in an Explorer window

Raymond Chen

Today's Little Program merely prints a message whenever the user changes the selection on the desktop. I chose the desktop for expediency, since it saves me the trouble of coming up with a way for the user to specify which Explorer window they want to track. Also, all I do is print a message saying "Selection changed!"; actually getting the selection was covered earlier in both C++ and script. Remember that Little Programs do little to no error checking. Our simply prints the message whenever it receives a event. Sure, this program isn't useful on its own, but you can incorporate into a program that ...

Sep 19, 2014
Post comments count 0
Post likes count 2

I marked my parameter as [optional], so why do I get an RPC error when I pass NULL?

Raymond Chen

Not that kind of optional.

Sep 18, 2014
Post comments count 0
Post likes count 1

The stream pointer position in IDataObject::GetData and IDataObject::GetDataHere is significant

Raymond Chen

An oft-overlooked detail of the and methods is the position of the stream pointer when the result is a stream. These rules are buried in the documentation, so I'm going to call them out louder. Let's look at first. If returns a stream, then the stream pointer must be positioned at the end of the stream before the stream is returned. In other words, the last thing you do before returning the stream is seek it to the end. The contents of the data object are assumed to extend from the start of the stream to the stream's position as returned by . (And no, I don't know why this rule exists.) I messed this ...

Sep 17, 2014
Post comments count 0
Post likes count 1

The citizenship test is pass/fail; there’s no blue ribbon for acing it

Raymond Chen

Six out of ten is all you need.