Programming In C + Win API: How To Get Windows 7 Look For Controls?

15.5k Views Asked by At

I am programming strictly in C and WinAPI, no C++ or C#. I am a beginner and just learning to draw controls etc. The thing is that when I create Windows or other controls like Command Buttons, they have Windows Native look. Take a look at this:

This is look I am getting!

But in Windows 7, the command buttons look like this:

enter image description here

Now, how do I get command buttons in my program to look like that. Is it even possible? I am following this tutorial, for reference: http://zetcode.com/gui/winapi/

Thanks.

3

There are 3 best solutions below

1
On BEST ANSWER

You enable visual styles for your app by providing an XML manifest, either as a separate file or as an embedded resource. See Enabling Visual Styles for details.

2
On

That's how the controls looked back in the 1990s, before themes (visual styles) were invented. As you've noticed, modern buttons are now painted all fancy-pants with gradients and throbbing and all that. But for backwards-compatibility reasons, you have to specifically request that your controls get that treatment, or they'll fall back to the legacy style.

You do that by specifying a manifest. You can either add one in plain text format to your application's root directory, or you can have Visual Studio (2005 and later) automatically embed one in your EXE.

The second route is the way I'd go. Add the following code to your stdafx.h file to inform the compiler that you want it to add the manifest automatically upon building your project:

#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

This MSDN article has more information on visual styles than you could ever want.


And if you really want your application to look native, you need to change the background brush used for the main window. By default, it's set to use the same color as a textbox's background (white).

You want to use the color used to paint 3D controls, instead. Modify the hbrBackground member of your WNDCLASS (or WNDCLASSEX) structure as shown here:

wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

Why do you have to add 1? For backwards-compatibility reasons, again. The details are boring. :-)

0
On

You probably remember when Windows XP arrived with that fresh new look, and you could revert it back to Windows 95/2000 classic appearance, or you could change the color theme. That was called visual styles, which brought to Windows a better theming support.

Classic, Luna, Aero and Metro

Visual styles remained as a feature since then. Windows Vista and 7 introduced Aero, but they still allowed using the classic theme. Windows 8 has removed both Aero and the classic theme, and added the Metro theme. High-contrast themes are now part of visual styles and do not have the classic appearance anymore.

Thus, a classic themed application in Windows 7 when it was expected an Aero style, is an issue with the visual style of the application. I'm not sure why but Microsoft did not leave the old classic theme optional while migrating the API to the new look.

So, how do I apply the modern style?

enter image description here

Either way this MSDN article explains how to enable visual styles for your application. I have seen people saying that enabling Unicode (defining UNICODE) would make it, but it is not required. Basically, you just need to write a manifest file specifying version 6 of the common controls DLL as requirement, then embed it as a resource or place under appname.exe.manifest in the executable's directory. A sample manifest would look like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="1.0.0.0" processorArchitecture="*"
        name="CompanyName.ProductName.YourApplication" type="win32"/>
    <description>Your application description here.</description>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity name="Microsoft.Windows.Common-Controls"
                version="6.0.0.0" type="win32" processorArchitecture="*"
                publicKeyToken="6595b64144ccf1df" language="*"/>
        </dependentAssembly>
    </dependency>
</assembly>

If you go for the embed option, don't forget to have winuser.h included in your resource file. You may also want to initialize the common controls DLL in your WinMain, according to this MinGW guide:

I’ve seen this step missed in some examples, and it can cause some odd behaviors under certain operating system versions and certain conditions, such as buttons being invisible, or dialogs failing to be created.

INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icc);