
Custom DPI settings mess up Statusbar, Coolbar, and other ActiveX controls
Hi,
I've been trying to make sure a VB app works properly no matter the
user's DPI setting (96, 120, custom), but I've run into a snag. It
seems that for all custom settings (106 DPI for example), many controls
do not receive the correct .width and .height from VB. Pictureboxes,
Labels, and other basics are FINE. Statusbars, coolbars, tabbed
controls, and custom ActiveX controls are getting the wrong numbers.
And in the case of statusbars aligned to the bottom, the grabber shangle
thing resizes the statusbar itself, not the form, which is odd.
I first noticed this when the coolbar I was using did not fill the width
of the form despite its width being set to the form's ScaleWidth in
Form_Resize. It works fine in 96 or 120 DPI (15 and 12 twips per pixel
respectively).
Further, I've written a custom ActiveX control in MSVC++ that has
allowed me to confirm that VB is sending the wrong width and height and
causes the control to be thinner and shorter than it should be.
The problem, it seems, is that the official TwipsPerPixel is 13 (for 106
DPI), but it is using 13.58208 for conversion purposes. For example, I
have my custom control sitting in a picturebox set to ScaleMode=pixel
(changing this does nothing, it only helps to illustrate the
difference). The custom control's width is set to 484 in VB. In the
control's OnDraw method, the CRect rcBounds is given width 463!
The difference is always proportional and one can work out that 6292
twips / 13.58208 twips per pixel = 463 pixels, the number given to the
custom ActiveX control. One can also "fix" it by multiplying by
13.5820/13 = 1.0447 to get the 484 pixels that it SHOULD be.
Anyone know a good workaround? The only thing I can think of is to use
my custom control to figure out this percentage on startup and then
multiply the widths by it. This doesn't help statusbars since you can't
set their .width property (when they are set to vbAlignBottom).
Want to try it yourself? Set your DPI setting by going to Display
Properties -> Settings -> Advanced -> General -> DPI setting -> Custom
-> 110%. Note that you WILL have to reboot (even in XP) even though the
fonts will be noticeably larger already. Now create a new VB project
and add a statusbar or coolbar. In Form_Resize do:
CoolBar1.left = 0
CoolBar1.Width = Me.ScaleWidth
Run it, and notice that it doesn't fill the form as it would in 96 or
120 DPI.
Now change it to:
CoolBar1.Width = CDbl(Me.ScaleWidth) * 1.04477
And notice that it works.
Any ideas?
Thanks,
Carl