Dovberman
asked on
How to capture a rectangular area of a window
I know the handle of a window. I also know the coordinates of the rectangular region of the window that I would like to capture. Once the region is captured, I would like to create a bitmap in memory of the captured region.
Here is where I am:
hObjectDC = CreateRectRgn(270, 188, 285, 224) 'Handle to caputred region
hCaptureDC = CreateCompatibleDC(hObject DC)
hCaptureBitmap = CreateCompatibleBitmap(hCa ptureDC, 15, 36)
This code fails because the captured region is not a window
IsWindow (hObjectDC) returns false
I then need to store the bitmap bits into an array.
Could you point me to an example where a common window like calc.exe is used.
Perhaps the example could show how to capture a region of the calculator window.
(Not a specific button or object)
Thanks,
Dovberman
Here is where I am:
hObjectDC = CreateRectRgn(270, 188, 285, 224) 'Handle to caputred region
hCaptureDC = CreateCompatibleDC(hObject
hCaptureBitmap = CreateCompatibleBitmap(hCa
This code fails because the captured region is not a window
IsWindow (hObjectDC) returns false
I then need to store the bitmap bits into an array.
Could you point me to an example where a common window like calc.exe is used.
Perhaps the example could show how to capture a region of the calculator window.
(Not a specific button or object)
Thanks,
Dovberman
ASKER
<<Here is where I am:
hObjectDC = CreateRectRgn(270, 188, 285, 224) 'Handle to caputred region
hCaptureDC = CreateCompatibleDC(hObject DC)
hCaptureBitmap = CreateCompatibleBitmap(hCa ptureDC, 15, 36)
This code fails because the captured region is not a window
IsWindow (hObjectDC) returns false>>
I have already reviewed the article you referenced.
The article does not use CreateRectRgn which captures a specific rectanglular segment of the window. It is CreateRectRgn which returns a handle, but does not recognize the region as a window.
I need an example that specifically addresses the CreateRectRgn function.
Thanks,
Dovberman
hObjectDC = CreateRectRgn(270, 188, 285, 224) 'Handle to caputred region
hCaptureDC = CreateCompatibleDC(hObject
hCaptureBitmap = CreateCompatibleBitmap(hCa
This code fails because the captured region is not a window
IsWindow (hObjectDC) returns false>>
I have already reviewed the article you referenced.
The article does not use CreateRectRgn which captures a specific rectanglular segment of the window. It is CreateRectRgn which returns a handle, but does not recognize the region as a window.
I need an example that specifically addresses the CreateRectRgn function.
Thanks,
Dovberman
Dovberman,
What is the end goal here? Do you really need CreateRectRgn() to capture a specific region of a window? (The link gecko has given demonstrates that you don't.) Do you really need the bitmap bits in an array or will a Picture object do? There may be other ways of going about this!
Give us a bigger picture and tell us more about what you are doing...
~IM
What is the end goal here? Do you really need CreateRectRgn() to capture a specific region of a window? (The link gecko has given demonstrates that you don't.) Do you really need the bitmap bits in an array or will a Picture object do? There may be other ways of going about this!
Give us a bigger picture and tell us more about what you are doing...
~IM
CreateRectRgn returns a handle to a region.
CreateCompatibleDC can only use the handle to a device context.
You cannot use CreateRectRgn with CreateCompatibleDC to get a screen capture.
CreateCompatibleDC can only use the handle to a device context.
You cannot use CreateRectRgn with CreateCompatibleDC to get a screen capture.
Thank you Erick37 for that clarification. I was pretty sure the approach being taken wasn't quite right but I'm no GDI expert! Hence the roundabout wording in my questions above...
=)
=)
ASKER
OK, here is the overview. I have developed an application that lists odds of drawing to specific hands when playing hold'em at an on line gaming site. The gaming site displays a table on which card images appear to represent cards that are dealt as community cards.
I need to capture the card images as memory bitmaps. Once this is done, I can compare the captured images to a catalog of 52 images. This will tell me which card has been dealt.
I know the x,y coordinates to the top left corner of each card image on the gaming table. I know the handle of the game window. I also know the card image length and width.
I thought that each card image was defined as a rectangular area. If this is true , then I assumed that CreateRectRgn would define each card.
Anyway, given this background, how do I capture each card image. I have picture controls on my application form to hold the captured images.
Thanks,
Dovberman
I need to capture the card images as memory bitmaps. Once this is done, I can compare the captured images to a catalog of 52 images. This will tell me which card has been dealt.
I know the x,y coordinates to the top left corner of each card image on the gaming table. I know the handle of the game window. I also know the card image length and width.
I thought that each card image was defined as a rectangular area. If this is true , then I assumed that CreateRectRgn would define each card.
Anyway, given this background, how do I capture each card image. I have picture controls on my application form to hold the captured images.
Thanks,
Dovberman
The easiest way I can think of is to BitBlt right from the screen to your picturebox. Like any screen capture, this will work only if the area you are blitting from is currently visible on the screen.
Simple example omitting the API declarations:
Dim hWndCalculator As Long
Dim hDCScreen As Long
Dim pt As POINTAPI
hWndCalculator = FindWindow(vbNullString, "Calculator")
If hWndCalculator <> 0 Then
'get the screen DC
hDCScreen = GetDC(0)
'get the upper left coordinate of calculator as a reference point
Call ClientToScreen(hWndCalcula tor, pt)
'blit the image to your Picturebox
'pt.x and pt.y is the upper left of the client area... add offsets as needed
Call BitBlt(Picture1.hDC, 0, 0, 50, 50, hDCScreen, pt.x, pt.y, vbSrcCopy)
End If
Simple example omitting the API declarations:
Dim hWndCalculator As Long
Dim hDCScreen As Long
Dim pt As POINTAPI
hWndCalculator = FindWindow(vbNullString, "Calculator")
If hWndCalculator <> 0 Then
'get the screen DC
hDCScreen = GetDC(0)
'get the upper left coordinate of calculator as a reference point
Call ClientToScreen(hWndCalcula
'blit the image to your Picturebox
'pt.x and pt.y is the upper left of the client area... add offsets as needed
Call BitBlt(Picture1.hDC, 0, 0, 50, 50, hDCScreen, pt.x, pt.y, vbSrcCopy)
End If
ASKER
Sounds like a winner.
I was unaware of the API call that returns the upper left corner coordinates of the window that contains the region I want to capture.
<<'get the upper left coordinate of calculator as a reference point
Call ClientToScreen(hWndCalcula tor, pt)>>
I will try this.
Thanks,
Dovberman
I was unaware of the API call that returns the upper left corner coordinates of the window that contains the region I want to capture.
<<'get the upper left coordinate of calculator as a reference point
Call ClientToScreen(hWndCalcula
I will try this.
Thanks,
Dovberman
ASKER
I believe we are almost there.
I get no errors. However the picture box control remains empty
The pictureBox has an HDC
I am not clear on the coordinate representation.
Here is my code:
===============
Private Sub cmdCapture_Click()
Dim hwndSelected As Long
Dim strWindowName As String
Dim hdcCapture As Long
Dim hdcScreen As Long
Dim StartPoint As POINTAPI
Dim lngStartPoint As Long
Dim lngBitBltRet As Long
hwndSelected = CLng(lstDeskTop.SelectedIt em.SubItem s(1))
If hwndSelected <> 0 Then
'get the screen DC
hdcScreen = GetDC(0)
'get the upper left coordinate of calculator as a reference point
StartPoint.x = 0
StartPoint.y = 0
lngStartPoint = ClientToScreen(hwndSelecte d, StartPoint)
'blit the image to your Picturebox
'pt.x and pt.y is the upper left of the client area... add offsets as needed
lngBitBltRet = BitBlt(picCapture.hdc, 0, 0, 50, 50, hdcScreen, StartPoint.x, StartPoint.y, vbSrcCopy)
End If
'From API_Guide 3.7
'· nWidth
'Specifies the logical width of the source and destination rectangles.
'· nHeight
'Specifies the logical height of the source and the destination rectangles.
'· hdcSrc
'Identifies the source device context.
'· nXSrc
'Specifies the logical x-coordinate of the upper-left corner of the source rectangle.
'· nYSrc
'Specifies the logical y-coordinate of the upper-left corner of the source rectangle.
End Sub
========================
Do I need expressions to get the logical coordinates and dimensions ?
What is meant by the term 'logical' in this context?
I get no errors. However the picture box control remains empty
The pictureBox has an HDC
I am not clear on the coordinate representation.
Here is my code:
===============
Private Sub cmdCapture_Click()
Dim hwndSelected As Long
Dim strWindowName As String
Dim hdcCapture As Long
Dim hdcScreen As Long
Dim StartPoint As POINTAPI
Dim lngStartPoint As Long
Dim lngBitBltRet As Long
hwndSelected = CLng(lstDeskTop.SelectedIt
If hwndSelected <> 0 Then
'get the screen DC
hdcScreen = GetDC(0)
'get the upper left coordinate of calculator as a reference point
StartPoint.x = 0
StartPoint.y = 0
lngStartPoint = ClientToScreen(hwndSelecte
'blit the image to your Picturebox
'pt.x and pt.y is the upper left of the client area... add offsets as needed
lngBitBltRet = BitBlt(picCapture.hdc, 0, 0, 50, 50, hdcScreen, StartPoint.x, StartPoint.y, vbSrcCopy)
End If
'From API_Guide 3.7
'· nWidth
'Specifies the logical width of the source and destination rectangles.
'· nHeight
'Specifies the logical height of the source and the destination rectangles.
'· hdcSrc
'Identifies the source device context.
'· nXSrc
'Specifies the logical x-coordinate of the upper-left corner of the source rectangle.
'· nYSrc
'Specifies the logical y-coordinate of the upper-left corner of the source rectangle.
End Sub
========================
Do I need expressions to get the logical coordinates and dimensions ?
What is meant by the term 'logical' in this context?
Logical units are the unit of measure for a device context. In VB, the default is twips. In the API functions the default unit is pixels. Any time you use API functions, use pixels.
Try setting the Autoredraw property of the picturebox = True.
Then refresh the picturebox after the bitblt.
picCapture.Autoredraw = True
Call BitBlt(picCapture.hDC, ...
picCapture.Refresh
Try setting the Autoredraw property of the picturebox = True.
Then refresh the picturebox after the bitblt.
picCapture.Autoredraw = True
Call BitBlt(picCapture.hDC, ...
picCapture.Refresh
ASKER
It is working. The autoredraw and Refresh methods were not the issue. However, this is good management code.
The region to be captured was covered by a different window.
Which API call places the source window on top ?
Thanks,
Dovberman
The region to be captured was covered by a different window.
Which API call places the source window on top ?
Thanks,
Dovberman
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This brings the desired window to the top.
Module constants:
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_SHOWWINDOW = &H40
Public Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
'Bring source window to top
'hwndSelected- handle of the window you wish to force to the top
SetWindowPos hwndSelected, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or _ SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
Thanks,
Dovberman
Module constants:
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_SHOWWINDOW = &H40
Public Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
'Bring source window to top
'hwndSelected- handle of the window you wish to force to the top
SetWindowPos hwndSelected, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or _ SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
Thanks,
Dovberman
http://support.microsoft.com/kb/q161299/
If you still need help post back :)