Prevent wrapping of background bitmap of property page on Windows XP with enabled visual styles

When I create a property page in a property sheet or a tab control on Windows XP and the visual styles (themes) are enabled, the background is a bitmap displaying a gradient. This works very well. However when the property page gets too big (height >600 pixels, width doesn't matter), the size of the according Windows XP background bitmap seems to be too small and the gradient wraps over. So after a dark area a light one is attached below (see attached screenshot). This looks ugly.
I think Windows XP takes this background bitmap from the file C:\WINDOWS\Resources\Themes\Luna\luna.msstyles (resource "BLUE_TABBACKGROUND_BMP" or "HOMESTEAD_TABBACKGROUND_BMP" or "METALLIC_TABBACKGROUND_BMP") which has the height of 600 pixels.
As I have a lot of overlying dialogs and controls just painting something on my own in the background is no solution. How can I prevent the wrapping? Can I force stretching the bitmap instead of wrapping it or can I replace the bitmap by a larger one for my whole process?
// just a MFC example - one way of many how to do this
CPropertySheet sheet(_T("Test"));
CPropertyPage page(IDD_PROPPAGE_VERY_LARGE);
 
sheet.AddPage(&page);
sheet.DoModal();

Open in new window

Screenshot.png
LVL 2
VolkerBeckAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

itsmeandnobodyelseCommented:
>>>>> just painting something on my own in the background is no solution.

Hmmm. I never used XP visual themes myself so I actually can't tell whether the following suggestions will work. But it may be worth a try:

1. derive from CPropertySheet and handle the WM_PAINT message

You would need to check the CPropertySheet::OnPaint in the MFC sources to find out whether you could call the baseclass function before or after your changes or if you need to replace the code completely by your override.

2. Handle the WM_CTLCOLOR of your CPropertyPage classes

(you also could create a common baseclass for all of your classes) .
In the YourPage::OnCtlColor handler you could change the background color of the pages so that it is equal to that of the CPropertySheet.

BTW, why didn't the property pages (all) have the same size and cover all of the background sheet?

3. If you are right that XP uses one of the xxx_TABBACKGROUND_BMP resources you could spot the bitmap files and enlarge them, e. g. by using the resource editor.
0
VolkerBeckAuthor Commented:
Thanks itsmeandnobodyelse, however, it's not quite what I'm searching for...

About 3.: It's an original file of Microsoft Windows XP that contains the resource. I don't dare changing it as it would a) influence other applications b) the next Microsoft patch could reverse the change c) customers wouldn't accept changes like this on their OS.
So I would prefer changing it in my applications memory space at runtime in case this is possible somehow.

About 1+2: It's not just a simple background color, it's a gradient painted by Windows XP (not by the application) and all the controls are painted transparently or use DrawThemeParentBackground - this is a mechanism invented by Windows XP, the application normally has nothing to do with it as long as it just uses comctl32.dll version 6 via a manifest file/resource. UxTheme.dll has a lot to do with it, but the exact mechanism is quite confusing for me. You can use EnableThemeDialogTexture(hWnd, ETDT_ENABLETAB) to force using the XP background bitmap - with the wrapping effect described here.
Maybe SetWindowTheme could help somehow. Does anybody know if you can use it to replace the bitmap?
Additionally I have several hundred dialog classes scattered over several DLLs - a lot of child dialogs. In the end, I guess there are at least 8 hierarchy levels of windows overlying each other. It's not a classical property sheet - just think of it like a Firefox/Opera/IE with tabs for changing the pages that can contain a lot of stuff.

By the way, on Windows Vista I don't have this problem as it doesn't use a gradient - or just a very light one.

> BTW, why didn't the property pages (all) have the same size and cover all of the background sheet?

It's resizable and very often the user resizes/maximizes it to cover the whole screen (see comparison with browsers above). Limiting this to 600 pixels wouldn't be a solution.

I know this is thing isn't simple - the solution however could be, at least I think so. Other people seem to have the same problem. I saw discussions about it in other forums, but no solution so far. I hope somebody knows a simple solution here. Thanks.
0
DanRollinsCommented:
It looks like it might be possible to disable the drawing of the background
   EnableThemeDialogTexture
   http://msdn.microsoft.com/en-us/library/bb773320(VS.85).aspx
You can do some additional diagnostic research -- find out if the problem is the bitmap:
   GetThemeBitmap
    http://msdn.microsoft.com/en-us/library/bb773388(VS.85).aspx
(iPartId might be TABP_BODY)
0
VolkerBeckAuthor Commented:
Hello DanRollins,

thank you for these suggestions. Unfortunately they don't really help me. When I disable the bitmap, I have the effect you can see when opening the Windows XP task manager. The tab is white and the page background is gray (standard dialog background color). This is even worse than the wrapping and a lot of people try to get rid of that and get the gradient I already have (e.g. http://www.devmaster.net/forums/archive/index.php/t-5668.html).
GetThemeBitmap is interesting, but only available on Windows Vista, not on XP (see link of DanRollins' post).
0
VolkerBeckAuthor Commented:
I've found a way to get the bitmap handle: Send WM_CTLCOLORSTATIC to the page, use GetObject on the returned brush to get a LOGBRUSH. The lbHatch field is the handle to the bitmap. I've even managed to change the bitmap. Unfortunately I also found out that this affects all applications, so the bitmap seems to be shared accross all applications. Now I try a different approach which is not as simple as changing a bitmap. What a pity.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.