Our investigation of why the CF_ clipboard format is not being created from CF_ via AnsiÂToÂOem led us to the realization that the Windows clipboard automatic text conversion diagram is non-commutative. And the conversion we’re observing is consistent with Windows deciding not to do the direct conversion of CF_ to CF_, but rather converting from CF_ to CF_, and from there to CF_.
It took a day before I realized what was going on. Let’s look at the graph again.
| CF_TEXT | ||||
| (CF_LOCALE) | ⇅ | ↑ | (LOCALE_ | |
| CF_UNICODETEXT | | | USER_ | ||
| ↖↘ | ↓ | DEFAULT) | ||
| (CF_LOCALE) | CF_OEMTEXT | |||
If we start with CF_ and somebody asks for CF_, it will be converted via the CF_ clipboard format to Unicode (which for Windows means UTF-16LE). And then if we ask for CF_, the diagram above shows that Windows will prefer to convert from CF_, so the string ends up being converted through CF_ after all.
The fact that the conversion diagram is path-dependent means that what you get is now influenced by what other applications read from the clipboard. After our test program copied text to the clipboard in ANSI format, the fact that another program requested CF_ influences what a future CF_ request will produce.
And it’s not like the interloper program can do anything about it. There is no way to ask, “Hey, like, I know that you say that you have CF_, but do you really have it? Or are you just pretending to have it?”
And how do these interloper programs know when you changed the clipboard? Because they have registered clipboard format listeners. But what program do I have that has registered a clipboard format listener?
And then it occurred to me: I have Clipboard History enabled.
Clipboard History is waking up when the first test program copies ANSI text to the clipboard and reading out CF_ to add to the clipboard history. This triggers the conversion CF_, and the result is cached back onto the clipboard. This means that when you ask for CF_, the clipboard sees that it has a choice of CF_ and CF_, and from the diagram we see that it prefers converting from CF_.
I turned off Clipboard History, and the query for CF_ started behaving as expected: The OEM text was generated by applying AnsiÂToÂOem to the CF_ contents.
So I came to two conclusions.
First, if you care about OEM text, then you should set your CF_ to LOCALE_ to avoid path-dependent conversions.
Second, pretty much nobody cares about OEM text.
Next time, we’ll look at another consequence of the above diagram.
0 comments
Be the first to start the discussion.