|
-
Dec 30th, 2011, 12:36 PM
#1
DPI Awareness and VB6
DPI AWARENESS AND YOUR VB6 APPLICATION
moved to the Utility Bank - Tutorials
Last edited by LaVolpe; Dec 20th, 2015 at 09:40 AM.
-
Dec 1st, 2014, 10:51 PM
#2
Frenzied Member
Re: DPI Awareness and VB6
Do you have further planning to improve your AlphaImage Control with dpi awareness? Schmidt,dilettante and many others all concerned dpi problem.
-
Dec 14th, 2014, 02:31 PM
#3
New Member
Re: DPI Awareness and VB6
Hello guys
My first post on this forum So welcome!
I am not VB expert and I need help with this piece of code:
Code:
'Screen Capture Demo by Tanner Helland (published 2008, updated 2012)
' http://www.tannerhelland.com
'If you like VB game and graphics code, be sure to subscribe to my RSS feed at
' http://www.tannerhelland.com/feed/
'The required API calls are:
'This call gives us the hWnd (window handle) of the screen
Private Declare Function GetDesktopWindow Lib "user32" () As Long
'This call assigns an hDC (handle of device context) from an hWnd
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
'BitBlt lets us draw an image from a hDC to another hDC (in our case, from an hDC of the screen capture
' to the hDC of a VB picture box)
Private Declare Function BitBlt Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, _
ByVal ySrc As Long, ByVal opCode As Long) As Long
'ReleaseDC will be used to release the screen's hDC once the screen capture is complete.
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
'This sample project copies the screen when the form loads; you could also place this code in
' a command button (or any other input)
Private Sub Form_Load()
'First, minimize this window
Me.WindowState = vbMinimized
'Get the hWnd of the screen
Dim scrHwnd As Long
scrHwnd = GetDesktopWindow
'Now, assign an hDC to the hWnd we generated
Dim shDC As Long
shDC = GetDC(scrHwnd)
'Determine the size of the screen
Dim screenWidth As Long, screenHeight As Long
screenWidth = Screen.Width \ Screen.TwipsPerPixelX
screenHeight = Screen.Height \ Screen.TwipsPerPixelY
'Copy the data from the screen hDC to this VB form
BitBlt FormScreenCapture.hDC, 0, 0, screenWidth, screenHeight, shDC, 0, 0, vbSrcCopy
'Release our hold on the screen's hDC
ReleaseDC scrHwnd, shDC
'Set the picture of the form to equal its image
FormScreenCapture.Picture = FormScreenCapture.Image
'Restore the window
Me.WindowState = vbNormal
End Sub
It can be downloaded from here: http://www.tannerhelland.com/44/screen-capture-vb6/
I used it for many years but it has problems with Windows 7 when user has larger DPI (ie. 125% or 150%).
Screenshot that is made then shows only a part of whole desktop.
Can you tell me please what should I change to make it work properly?
I have searched gogle for many days, but did not found straight solution and simple example.
-
Dec 17th, 2014, 08:59 PM
#4
Re: DPI Awareness and VB6
 Originally Posted by Jonney
Do you have further planning to improve your AlphaImage Control with dpi awareness? Schmidt,dilettante and many others all concerned dpi problem.
Yep, I have rewritten the base of the control (all actions that are not related to drawing). Still have lots of work to do. I will be making it DPI aware, ICM (color management) aware, container scalemode aware, offer more control over custom painting, and adding more options/enhancements.
Edited. Actually, the DPI awareness is written already and tested pretty well moving up & down to different DPIs. Scaling seems flawless. The only thing I won't be able to mess with is "per monitor DPI awareness" available on Win8.1. That requires subclassing so that a new message can be trapped. After I kick out the new version of the control, I'll go back and re-look at that. May just add a runtime property that allows the user to set the DPI the control should be using & then the user is responsible for trapping the message & forwarding the appropriate DPI to the control. Just a thought.
Regarding color management. I have the code written for that and am pretty happy with it. I still have not decided how I want to implement it. Probably going with a property setting to allow the user to use it or not. Just not sure what default I want: On or Off. Turning it on, may require parsing image formats for the ICM info, which means longer image load times. Still playing with that.
Container scalemode awareness was easy & is done. The current version of the control worked only in pixels. The new version's settings will be in container scalemode, like most other controls in VB.
Some additional options the user will have are:
- Custom hit testing on the control. If chosen, the control will allow the user to define whether or not the mouse is over the image. This can be useful if the control is used for something other than images, like a mapping tool
- More control over custom painting. Now the user will be able to monitor, intercept, abort all painting actions by the control. They can paint before or after the control paints, tell the control not to paint, tell the control to paint elsewhere, like maybe an offscreen bitmap
- Scaling options added to scale image to a size that allows rotating it fully 360 degrees without resizing the control. Before the control had to be sized for the image, now the image can be sized for the control
- Adding some built in GDI+ brushes for backstyle options. 61 hatch brushes
This will be a new control and not compatible with the current version. Like I said, still lots of work to do.
Last edited by LaVolpe; Dec 17th, 2014 at 10:27 PM.
-
Dec 17th, 2014, 09:06 PM
#5
Re: DPI Awareness and VB6
 Originally Posted by zastawka
I have searched gogle for many days, but did not found straight solution and simple example.
Your question should have been posted in the VB6 area of the forums, not the test area.
Anyway, I believe your problem is that because your VB app/project does not have a manifest that says it is DPI aware, Win 7 is running the app in 96 DPI and scaling/stretching the GUI to the larger DPI. At 125%, DPI is 120 and at 150%, DPI is 144. So, at 120 DPI your image was probably only about 80% the actual size, correct? And at 144 DPI, the image was only about 65% the actual size?
So... this line of code is DPI dependent: screenWidth = Screen.Width \ Screen.TwipsPerPixelX
What I believe is happening is that your screenWidth variable will not report the actual pixel width of the monitor (which is the size you want your bitmap). Instead, it is reporting what Win7 said the screen size is and that was probably scaled back to 96 DPI.
You should be able to see this with this line of code:
Code:
MsgBox 1440 / Screen.TwipsPerPixelX & " DPI & vbNewLine & Screen.Width \ Screen.TwipsPerPixelX
That line of code may say 96 DPI, which explains why only a part of the desktop was captured in your bitmap. I believe you will need to use APIs to get the true size of the desktop, not what Win7 is telling VB: GetDeviceCaps API. And if not wanting to do that, you'll have to turn off DPI Virtualization for your app or supply a manifest saying your app is DPI-aware.
Please do not respond here. Post your code in the appropriate part of the forums. I offered my thoughts as a courtesy. Will not continue to reply in this thread & won't mind replying to your questions when posted in the right part of the forum
Last edited by LaVolpe; Dec 17th, 2014 at 10:08 PM.
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
|