Note: This isn't a post about Finobe. Sorry.

So while I was working on the updater for 2012, I came across an issue that absolutely stumped me: garbled window titles, almost like mojibake.

The Finobe 2012 updater uses task dialogs, a feature introduced in Windows Vista. It's invoked by passing a struct TASKDIALOGCONFIG into the method TaskDialogIndirect. The title is a field within the struct called pszWindowTitle.

So, clearly, one should do this to set a title for the task dialog:

// ...
c.pszWindowTitle = L"Hello world";
// ...

This works fine for constant titles. That isn't any good for me though - my application has localization to torture people who can't read Chinese!

Interestingly enough, pszWindowTitle is actually a PCWSTR. So, I thought, "no big deal! I'll just pass it a LPCWSTR by calling c_str() on a std::wstring" (note: this is a Unicode application).

So, then my code looked similar to this:

// ...
c.pszWindowTitle = std::wstring(L"Hello world").c_str();
// ...

After running it... well, Win32PropSheetPageHost isn't Hello world.

"So the string is getting corrupted automagically, so why don't I just use SetWindowText?" I thought.

Somewhere in the task dialog callback:

SetWindowText(hWnd, std::wstring(L"Hello world").c_str());

It works! Or did it?

It seemed to work until I asked people on Windows 7 to show me the title. "ă…“inobe Updater," it said. Heck.

After a bit of searching I came across this Chinese post on a site called CSDN. Someone said "use a CString".

CString title(std::wstring(L"Hello world").c_str());
SetWindowText(hWnd, title);

Okay, that works. For real, this time. Problem solved.

Lessons learned:

  • Win32 sucks
  • Lucky coincidences are more likely when you're running Windows 10, apparently
  • gg Windows 7
  • Chinese people have been through it all, just ask them

I can only guess that this is related to a "memory alignment" issue or rather a difference of where something in memory is, but I don't care enough to look into it. This satisfies me.