How do I disable windowless control support in dialog boxes?


A customer wanted to know how to disable windowless control support in dialog boxes. "The customer has a CommandButton ActiveX control on his dialog box, and using Get­Dlg­Item to get the window handle of the command button succeeded with VC 6.0, but when compiled with VC 9.0, it does not create a window. I'm guessing that this is caused by Dialog­Box's support for windowless controls. Is it possible to disable support for windowless controls?"

The question on its face is somewhat puzzling, because dialog boxes don't "support" or "not support" windowless controls. It's like asking, "I want rice that doesn't support meat. My customer is a vegetarian and cannot eat meat." Rice doesn't support meat, and it doesn't not-support meat. If you don't want meat, then don't add meat. And if you don't want windowless controls on your dialog box, then don't create windowless controls.

I was also not sure what the customer meant by CommandButton, because Win32 command buttons are not ActiveX controls. The customer must be referring to something else also called Command­Button, in which case the customer should also consult the documentation for that something else to see if there's a way to control its windowed/windowless behavior.

The customer liaison gave some more details: "My customer uses Get­Dlg­Item to get the handle of a specific window. This method worked in VC 6.0 since VC 6.0 doesn't support windowless controls. But VC 9.0 added support for windowless controls in dialog boxes, which breaks my customer's code. Is there a way to disable support for windowless controls in dialog boxes?"

It took a few more questions, but eventually we figured out that the customer was not using raw Win32 dialog boxes (as Dialog­Box suggested in the original question) but rather MFC dialog boxes, and the CommandButton in question is a Microsoft Forms 2.0 CommandButton control.

"The customer simply wants to continue using his code without modification. He is already using the Microsoft Forms 2.0 CommandButton control, and he is already using Get­Dlg­Item to obtain its handle, but that technique no longer works."

The pieces started to fall into place, and somebody from the Visual Studio team provided an explanation: The version of MFC which comes with Visual Studio 2000 added support for hosting windowless ActiveX controls. By default, the MFC hosting code permits controls to be added as windowless controls if the control requests it. To force all controls to be windowed, you need to provide a custom class which derives from COle­Control­Site and overrides IOle­In­Place­Site­Windowless::Can­Windowless­Activate to return S_FALSE. Then override the dialog's CWnd::Create­Control­Site method to return an instance of this class instead of the default control site.

I haven't actually tested this to see if it works, but the customer didn't come back, so either it worked, or they decided that we were jerks and didn't want to waste their time with us any more.

Comments (12)
  1. # says:

    "Visual Studio 2000"…2008?

  2. Joshua says:

    What a mess.

    Two things I hate: non-standard compilers and code that breaks because you upgraded the compiler. I'm not sure which is worse.

  3. Timothy Byrd says:

    Joshua: Um, MFC isn't a compiler, it's a class library. And I thought Microsoft Forms was another library meant for VBA. And they were never meant to play together. So could you explain what you mean here?

  4. JW says:

    @Joshua:

    You did notice it isn't the compiler upgrade that broke it, right? It's the framework that got a version bump, and had an new setting of which the default is incompatible in this particular case. Throw the old MFC version into the new compiler, and it is quite likely to work. (Then again, those old sources may or may not have relied on features/bugs that were changed in more recent revisions of the compiler and/or C++ standards.)

    Besides, as it is, Microsoft probably released some kind of changes/upgrade document somewhere, but this customer would have had to find the right document for the right version-upgrade that introduced the change. After all, it is unlikely Microsoft would release VC6->VC9 transition documents. The only problem is finding it in the mess that is MSDN. :)

  5. AsmGuru62 says:

    Ahhh… sweet MFC' *** pain!

    Always with changes!..

  6. Joshua says:

    (Then again, those old sources may or may not have relied on features/bugs that were changed in more recent revisions of the compiler and/or C++ standards.)

    Exactly! I know MFC sources were shipped but what a pain (oh and now you have to private install them as your new build makes them incompatible with stock).

  7. Anonymous Coward says:

    Lesson learnt: never put to much weight on everything that follows ‘I'm guessing’.

  8. tobi says:

    This blog has many lessions in communication and methodology. I read this blog although I have little understanding for the particular subject (Win32).

  9. Neil says:

    Sadly we never found out why they felt the need to resort to manipulating an ActiveX control via a window handle in the first place…

  10. @Neil: Or why they were using a control designed for VBA in a dialog box in C++?

  11. SimonRev says:

    @immibis

    I can take a reasonable guess:  The original author of the code was a VB developer recently come to VC++.  The VB versions of the standard controls had a number of nice convenience properties such as foreground/background color properties.

    I suspect that he needed something like a custom foreground and found it easier to use the VB controls via ActiveX than to figure out WM_CTLCOLOR.

  12. 640k says:

    VC 9.0 = VS 2008. Not "Visual Studio 2000", that doesn't exist.

Comments are closed.