Changing window styles on the fly

by Kent Reisdorph

The VCL does a good job of insulating the C++Builder programmer from the Windows API. Sometimes, however, you need to use the API if you want to accomplish some goal that isn’t provided for by the VCL. Take window styles, for example. Every window has a set of style bits that determine how the window should look. These style bits are or’d together to get the desired behavior for the window. Most VCL components surface window styles as properties. In some cases, though, the VCL does not provide properties for a particular style. Let’s say, for example, that you want a progress bar that has no border. If you drop a TProgressBar component on a form you will find that there is no way to turn off the control’s border. In that case you’ll have to go to the Windows API in order to remove the progress bar’s border.

Style types

Windows defines three style types. The first set of style types has to do with basic window styles. This includes styles that indicate whether the window has a title bar, whether it is a child window, and so on. The second group of styles consists of extended style types. You might consider these styles as “Win32 styles,” since many of them refer to window styles that didn’t exist in Windows 3.x. The third type of style consists of styles specific to a particular type of window. For example, the Win32 tree view control has a style called TVS_DISABLEDRAGDROP. This style indicates whether the tree view can accept dropped files.

You can find out about the basic window styles by looking at the CreateWindow() function in the Win32 help file. For extended styles, see the CreateWindowEx() function in the help file. For styles specific to a particular control, see the help for that control.

Changing styles at run time

Changing styles at runtime requires just a few lines of code. First you get the current window style. Next you add or remove style bits as needed. Finally, you reset the window style to the new style bits. Here’s how the code looks:

long style = GetWindowLong(
  ProgressBar1->Handle, GWL_EXSTYLE);
style &= ~WS_EX_STATICEDGE;
SetWindowLong(ProgressBar1->Handle, 
  GWL_EXSTYLE, style);

This code removes the WS_EX_STATICEDGE style from the progress bar. To add this style back you would use code like this:

long style = GetWindowLong(
  ProgressBar1->Handle, GWL_EXSTYLE);
style |= WS_EX_STATICEDGE;
SetWindowLong(ProgressBar1->Handle,
  GWL_EXSTYLE, style);

Typically you will place this code in your form’s constructor or on OnCreate event handler.

The great debate?

Recently I had a rather spirited discussion on this topic with a fellow TeamB member. His position is that using SetWindowLong() is a hack and shouldn’t be used in a VCL application. Instead, he said, you should create a new component and set the window style in an overridden CreateParams(). His reasoning was due to the fact that the VCL will, in some extreme cases, destroy and recreate a window. By setting the style bits in CreateParams() the component will always have the correct window styles regardless of what the VCL does.

My position on the subject is simple: Creating a component for such a simple task is extreme overkill. Imagine what your Component Palette would look like if you created a new component for every simple programming task! While the previous position is the absolute safest route to take, it simply isn’t necessary in most cases. Ultimately you can decide which way to go.

Conclusion

Changing window styles at runtime (or through a component) is a simple and effective way of getting the correct window appearance and behavior for your components. This technique should be in your bag of Windows programming tricks.