Magnify Area under Mouse Coordinates

  • Thread starter Thread starter Henry Wu
  • Start date Start date
H

Henry Wu

Hi, I see examples of Magnifying an area under mouse coordinates to a
form or picturebox using VB6 and VC6, does anyone know how to do it
under VB.NET? Its nice to use the new GDI+ for it.

Thanks,
Henry
 
* (e-mail address removed) (Henry Wu) scripsit:
Hi, I see examples of Magnifying an area under mouse coordinates to a
form or picturebox using VB6 and VC6, does anyone know how to do it
under VB.NET? Its nice to use the new GDI+ for it.

You can use 'Cursor.Position' to determine the position of the mouse.
Then you can take a screenshot of the area of the desktop and draw it
onto the form in magnified size ('Graphics.DrawImage').

<URL:http://dotnet.mvps.org/dotnet/samples/windowsandforms/downloads/Screenshot.zip>
 
Hi Herfried,
Thanks for the reply, that's exactly what I did, but instead of using
Graphics.DrawImage I use the StretchBlt Api. It is working now, I
place the "zooming code" at one of my TabPage's Paint Event, and a
Timer set at 50milliseconds, to zoom in and out, a Vertical Scrollbar
is used.

However, could you kindly help me remove the flickering? In any
Interval I use at the Timer, there is still some amount of flickering.
Even if I use Graphics.DrawImage. I just wanted it to be the same as
Microsoft's Magnifier, it doesen't flicker at all :(

Thanks,
Henry


Private Sub tbpPatternMovement_Paint(ByVal sender As Object, ByVal e
As System.Windows.Forms.PaintEventArgs) Handles
tbpPatternMovement.Paint
'Mouse Coordiantes To Statusbar
Me.stbVideoPatternControl.Text = "X = " &
Cursor.Current.Position.X & ", Y = " & Cursor.Current.Position.Y

'Get Handle Of Desktop
Dim hdc As IntPtr = GetDC(IntPtr.Zero)

'Get Screen Dimensions
Dim hr As Integer = Screen.PrimaryScreen.Bounds.Width
Dim vr As Integer = Screen.PrimaryScreen.Bounds.Height

Dim percent As Single = Me.vsbVideoPatternControl.Value / 100
Dim lengthX As Single = (Me.tbpPatternMovement.Width -
Me.vsbVideoPatternControl.Width) * percent
Dim lengthY As Single = (Me.tbpPatternMovement.Height -
Me.stbVideoPatternControl.Height) * percent

'Center image around the mouse
Dim offsetX As Single = lengthX \ 2
Dim offsetY As Single = lengthY \ 2

'Actual area to blit to
Dim blitAreaX As Integer = Me.tbpPatternMovement.Width -
Me.vsbVideoPatternControl.Width
Dim blitAreaY As Integer = Me.tbpPatternMovement.Height -
Me.stbVideoPatternControl.Height

Dim ret As Integer = StretchBlt(e.Graphics.GetHdc.ToInt32, 0,
0, blitAreaX, blitAreaY, hdc.ToInt32, Cursor.Current.Position.X -
offsetX, Cursor.Current.Position.Y - offsetY, lengthX, lengthY,
SRCCOPY)

Dim dsHWND As Integer = GetDesktopWindow()

'Free Memory
e.Graphics.ReleaseHdc(hdc)
e.Dispose()
ReleaseDC(dsHWND, hdc.ToInt32)
End Sub

Private Sub tmrVideoPatternControl_Tick(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
tmrVideoPatternControl.Tick
Me.tbpPatternMovement.Invalidate()
End Sub
 
Hi again, I stumble yet to another problem, I tried the VisualBasic
Sample ScreenShot program you gave, and both that and my program fails
to solve my new found problem.

Have you ever tried creating a form with the ff:
FormBorderStyle = None
BackColor = White
TransparencyKey = White

Then at the form's paint event, draw a simple Cirle like the ff:
e.Graphics.DrawEllipse(New Pen(Color.Black, 10), 0, 0, 100, 100)
e.Dispose()

It draws a thick black circle, with its underlying form "invisible"

Now trying to capture screen on both the sample program, and my code
didn't capture the "thick black circle".

HOWEVER, the strange thing is, when you hit the "PrtScn" or
PrintScreen key at your keyboard, and paste is at MS Paint for
example, you can see that it actually captures the "thick black
circle" correctly.

Why is this? I was wondering if the API or function or underlying code
of the PrintScreen key differs a lot from the sample Screenshot
program/s with APIs?

Thanks so much,
Henry
 
Hi Herfried,
After continous tries to capture Transparent Forms, I discovered
several things.

In your sample CaptureScreen Project, if you add CAPTUREBLT to the
StretchBlt function having a defintion of Public Const CAPTUREBLT As
Integer = &H40000000
you will be able to Capture Transparent Forms without any problems.

I modified your code below and just added an OR CAPTUREBLT to capture
Transparent Forms.

' Zeichnen des Inhalts des Desktop-DCs in den DC der Bitmap.
StretchBlt( _
hdc, _
0, _
0, _
Width, _
Height, _
hdcWindow, _
rct.Left, _
rct.Top, _
Width, _
Height, _
SRCCOPY Or CAPTUREBLT _
)


Your sample CaptureScreen project stores the captured screen into a
BMP variable and you sets it into a PictureBox.

However, what I am trying to do is to draw directly to the form and
not into a BMP or Picturebox. So what I tried is to add the CAPTUREBLT
to my code, but apperntly it does not work! Why is that if it is saved
to a BMP variable and loaded to a PictureBox or saved into a Bitmap
File, you can see the Transparent Form w/o any problems, BUT if you
try to draw the capture screen w/ transparent forms directly to the
form itself, you CANNOT see the transparent form??

Below is my code I modified from my previous post:

Notes: stbVideoPatternControl is a StatusBar docked to the bottom, and
vsbVideoPatternControl is a VerticalScrollBar docked to the right.

-------------------------------------------------
Paint Event of the Form
-------------------------------------------------

Private Sub tbpPatternMovement_Paint(ByVal sender As Object, ByVal e
As System.Windows.Forms.PaintEventArgs) Handles
tbpPatternMovement.Paint
'Mouse Coordiantes To Statusbar
Me.stbVideoPatternControl.Text = "X = " &
Cursor.Current.Position.X & ", Y = " & Cursor.Current.Position.Y

'Get Handle Of Desktop
Dim hdc As IntPtr = GetDC(IntPtr.Zero)

'Get Screen Dimensions
Dim hr As Integer = Screen.PrimaryScreen.Bounds.Width
Dim vr As Integer = Screen.PrimaryScreen.Bounds.Height

Dim percent As Single = Me.vsbVideoPatternControl.Value / 100
Dim lengthX As Single = (Me.tbpPatternMovement.Width -
Me.vsbVideoPatternControl.Width) * percent
Dim lengthY As Single = (Me.tbpPatternMovement.Height -
Me.stbVideoPatternControl.Height) * percent

'Center image around the mouse
Dim offsetX As Single = lengthX \ 2
Dim offsetY As Single = lengthY \ 2

'Actual area to blit to
Dim blitAreaX As Integer = Me.tbpPatternMovement.Width -
Me.vsbVideoPatternControl.Width
Dim blitAreaY As Integer = Me.tbpPatternMovement.Height -
Me.stbVideoPatternControl.Height

e.Graphics.CompositingQuality =
Drawing2D.CompositingQuality.HighSpeed
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed

Dim ret As Integer = StretchBlt(e.Graphics.GetHdc.ToInt32, 0,
0, blitAreaX, blitAreaY, hdc.ToInt32, Cursor.Current.Position.X -
offsetX, Cursor.Current.Position.Y - offsetY, lengthX, lengthY,
SRCCOPY Or CAPTUREBLT)

'Free Memory
e.Graphics.ReleaseHdc(hdc)
e.Dispose()
ReleaseDC(GetDesktopWindow(), hdc.ToInt32)
End Sub

-------------------------------------------------
Timer Event of the Form
-------------------------------------------------

Private Sub tmrVideoPatternControl_Tick(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
tmrVideoPatternControl.Tick
Me.tbpPatternMovement.Invalidate()
End Sub




The only codes I added from my previous post are:

For Flickering Issue:
=====================
e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed

For Transparent Form Issue:
===========================
CAPTUREBLT

I tried to make the flickering stop, but to no avail, it still
flickers. I really wonder how did Microsoft create the Magnifier
program that has no flickers and could see transparent forms.

Oh by da way, since I know that saving to a bitmap variable would make
transparent forms appear, I tried to do a e.Graphics.DrawImage from a
bitmap variable, and yes I could now see the transparent form drawn
directly to the form, however this method is Super Slow for a
magnifier program.


Any help to draw directly to the form which could see transparent
forms will be very much appreciated!


Thanks,
Henry
 
* (e-mail address removed) (Henry Wu) scripsit:
In your sample CaptureScreen Project, if you add CAPTUREBLT to the
StretchBlt function having a defintion of Public Const CAPTUREBLT As
Integer = &H40000000
you will be able to Capture Transparent Forms without any problems.

I modified your code below and just added an OR CAPTUREBLT to capture
Transparent Forms.

' Zeichnen des Inhalts des Desktop-DCs in den DC der Bitmap.
StretchBlt( _
hdc, _
0, _
0, _
Width, _
Height, _
hdcWindow, _
rct.Left, _
rct.Top, _
Width, _
Height, _
SRCCOPY Or CAPTUREBLT _
)


Your sample CaptureScreen project stores the captured screen into a
BMP variable and you sets it into a PictureBox.

However, what I am trying to do is to draw directly to the form and
not into a BMP or Picturebox.

So, why not draw the image onto the form using 'DrawImage' in the form's
'Paint' event?
 
oh by the way,.. the max value of the scrollbar is 100, the min value
of the scrollbar is 1, and lastly the default value or value of the
scrollbar is 50.

I just wrote this down if someone wants to try to duplicate the
scenario.

Thanks,
Henry

Contants/Declartions Used:

Public Const SRCCOPY As Integer = &HCC0020
Public Const CAPTUREBLT As Integer = &H40000000
Public Declare Function GetDesktopWindow Lib "user32" () As Integer
Public Declare Function GetDC Lib "user32.dll" (ByVal hWnd As IntPtr)
As IntPtr
Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Integer,
ByVal hdc As Integer) As Integer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top