|
-
Dec 27th, 2015, 10:54 AM
#11
Re: CommonControls (Replacement of the MS common controls)
With high DPI, specifically non-whole number VB DPI (1440 / DPI), there are 2 separate issues. Internal resizing from the UC and external reszing from the UC's host. For simplicity, we will assume no non-client borders, i.e., no WS_BORDER, etc. And also, for simplicity, we'll say the host & UC are in the same scalemode. One last caveat, the stuff below pertains to VB being the host for the UC. The Extender object's Width,Height properties are not guaranteed to be supported in any non-VB host, i.e., Access, IE, Word, etc.
First. At 200% DPI, VB runs internally at 214% DPI. But if the UC and host sizes were in sync, this wouldn't be an issue. 214% DPI is equivalent to: (1440 / 7) / 96. At 200% DPI the system's twips per pixel would be 7.5 but VB uses 7.
Second. UC dimensions are saved as twips by VB within the project files.
Internally: ScaleWidth,ScaleHeight cannot be trusted. It can be less than what the host reports. If UC is designed with a width of 200 pixels, 3000 twips, in 96 DPI and shown in 200% DPI, then at 200% DPI, you would expect the host to report the UC as 400 pixels, twice as large at twice the original DPI. But not so. The host still reports the UC as 3000 twips as expected, but the size in pixels would be 3000 / 7 = 428.571. If your UC's scalemode were pixels, you'd expect its ScaleWidth to report 428.571. However, the UC's scalewidth in twips is 2800 and in pixels: 400, 28.571 pixels smaller than the host.The difference in VB and System twips per pixel can be used to show that difference: 3000 * 7 / 7.5 = 2800
For hWnd controls, SetWindowPos,MoveWindow can be used. However, GetClientRect or GetWindowRect is not useful, as is. Why? Well, you are getting pixel size from one API and supplying it to another API, no change in data. The UC, internally, should rescale itself during the resize event. The pixels returned from the API should be first scaled by the Extender property, using vbContainerSize, before sending to MoveWindow,SetWindowPos.
For Windowless controls, the reported size by the UC width,height or scalewidth,scaleheight are not really important. When the UC's Paint event is called, the size reported by the host is passed via the clipping rectangle in the passed hDC. But to know the real size, there are a few ways to get to it, with the Extender property being the easiest.
Externally: Simply changing the UC dimensions from the host, does not rescale the UC correctly in all cases. The code posted in #870 can be used without need for APIs, though slight modifications are needed if the UC can be Top/Bottom aligned.
Bottom line. ScaleWidth,ScaleHeight and Width,Height cannot be trusted. They will NOT report the same dimensions as the host in some DPIs
Above being said. Yes, an API window can be sized exactly to the UC scalewidth,scaleheight. However, that scalewidth,scaleheight may not be correctly scaled relative to the actual width/height. What happens is that your control on the form appears smaller, when drawn, than it should be when compared to other non-UCs. From a professional point of view: yuck. This can be easily proven and visualized with a simple test.
1. At 96 DPI, start new project. Add a picturebox & set properties: BackColor=Red, Borderless, not-3D
2. Add a new UC to the project and set it's backcolor to white
3. Place an instance of the UC inside the picturebox. Sizing UC doesn't matter right now
4. Add a button and behind the button, add this code:
UserControl1.Move 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight 5. Save the project and change your system to 200% DPI
6. Disable DPI virtualization: VB6.exe properties compatibility tab. Check "Disable display scaling on high DPI settings"
7. Run the test project and click the button. You should see the UC did not 'fill up' the picturebox when drawn, though the picturebox & uc sizes are identical from the host's point of view
Tip: You'll know if VB is not running in virtual DPI, at all DPIs other than 96, if the Screen.TwipsPerPixelX returns something other than 15.
Edited: If your O/S doesn't have that compatibility tab option, you may need to disable DPI virtualization by creating an external manifest for vb6.exe saying that VB is DPI-aware.
Last edited by LaVolpe; Dec 27th, 2015 at 11:35 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|