Jump to content

Scrolling Window Capture?


 Share

Recommended Posts

This is my first attempt at scripting. I am trying to create a standalone program that does not require installing, or relying on any additional ddl's, other than those that install with Windows by default.

My script creates a report, consisting of both text and graphics, and then is required to print this report. Everything is in place. I can screen capture the report to output to the printer, but my problem comes should the application be used on a laptop for example, with different, smaller screen dimensions. The report form becomes smaller, with scrolling controlls, and therefore the screen capture cannot access the whole report.

I am printing the report using:

Func _PrintImage($hDC, $filename, $centered = true, $fitToPage = false)
Local $tInput = DllStructCreate("int Version;int Callback;int NoThread;int NoCodecs")
Local $tToken = DllStructCreate("int Data")
DllStructSetData($tInput, "Version", 1)

Local $image = $filename
Local $imageheight = _GDIPlus_ImageGetHeight($image)
Local $imagewidth = _GDIPlus_ImageGetWidth($image)
Local $go = _GDIPlus_GraphicsCreateFromHDC($hDC)


If $fitToPage OR $centered Then

$tempWin = GUICreate("Test", 200, 200)
$screenHDC = _WinAPI_GetDC($tempWin)

;get monitor pixels per inch
$ppiHeight = _WinAPI_GetDeviceCaps($screenHDC, $__WINAPCONSTANT_LOGPIXELSY) 
$ppiWidth = _WinAPI_GetDeviceCaps($screenHDC, $__WINAPCONSTANT_LOGPIXELSX) 

;get printer dots per inch
$dpiHeight = _WinAPI_GetDeviceCaps($hDC, $__WINAPCONSTANT_LOGPIXELSY) 
$dpiWidth = _WinAPI_GetDeviceCaps($hDC, $__WINAPCONSTANT_LOGPIXELSX) 

;get printer page width and height in dots
$dotsHeight = _WinAPI_GetDeviceCaps($hDC, $VERTRES)
$dotsWidth = _WinAPI_GetDeviceCaps($hDC, $HORZRES)

;get printer page width and height in pixels
$height = $dotsHeight * $ppiHeight / $dpiHeight 
$width = $dotsWidth * $ppiWidth / $dpiWidth

DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $tempWin, "int", $screenHDC)
GUIDelete($tempWin)

If $fitToPage Then

If ($height/$imageHeight) < ($width/$imageWidth) Then
Local $ratio = $height/$imageHeight 
Else
Local $ratio = $width/$imageWidth
EndIf

Local $x = Abs($width - $ratio * $imageWidth)/2
Local $y = Abs($height - $ratio * $imageHeight)/2


_GDIPlus_GraphicsDrawImageRect($go, $image, $x, $y, Round($ratio * $imageWidth), Round($ratio * $imageHeight))
Else
Local $xPos = Abs($width - $imagewidth)/2
Local $yPos = Abs($height - $imageHeight)/2

_GDIPlus_GraphicsDrawImageRect($go, $image, $xPos, $yPos, $imagewidth, $imageheight)
EndIf

Else

_GDIPlus_GraphicsDrawImageRect($go, $image, 0, 0, $imagewidth, $imageheight)
EndIf
_GDIPlus_GraphicsDispose($go)
_GDIPlus_BitmapDispose($image)
_GDIPlus_Shutdown()

EndFunc

which is a modified verision of Tobias7's script, which is an addition to GRS's PrintWinAPI.au3

I have been able to capture and stitch together the scrolled screen based on junkew's code:

#include <WinAPI.au3>
#include <ScreenCapture.au3>
#include <GDIPlus.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <misc.au3>

stitchbitmap("Scrolled Form", c:\temp\test.bmp")

While GUIGetMsg() <> -3
    Sleep(10)
WEnd
Exit

; Just stitching 2 bitmaps of screen
Func StitchBitmap($hWnd1, $sFileName = "")
    Local $hWnd, $hDDC   
    Local $HDDC1, $hCDC1, $hBMP1
    Local $iW = 650;Size of bitmap width to capture from screen
    Local $iH = 500;Size of bitmap height to capture from screen
    
    $hWnd = WinGetHandle($hWnd1)
    $hDDC = _WinAPI_GetDC($hWnd)  ; Devicecontext to capture from
    
; Part 1 to show it on the screen
;   Create GUI for stitched bump
    $GUIHandle = GUICreate("Stitched", $iW, $iH * 2, 300, 300)
    GUISetState()   
    
    $hDDC1 = _WinAPI_GetDC($GUIHandle)
    $hCDC1 = _WinAPI_CreateCompatibleDC($hDDC1)
    $hBMP1 = _WinAPI_CreateCompatibleBitmap($hDDC1, $iW, $iH * 2)
    _WinAPI_SelectObject($hCDC1, $hBMP1)
    
;Show 2 parts of a screencapture on screen, capturing in upper left corner of screen
;BOOL BitBlt(  HDC hdcDest, // handle to destination DC
;  int nXDest,  // x-coord of destination upper-left corner
;  int nYDest,  // y-coord of destination upper-left corner
;  int nWidth,  // width of destination rectangle
;  int nHeight, // height of destination rectangle
;  HDC hdcSrc,  // handle to source DC
;  int nXSrc,   // x-coordinate of source upper-left corner
;  int nYSrc,   // y-coordinate of source upper-left corner
;  DWORD dwRop  // raster operation code
;);
    _WinAPI_BitBlt($hDDC1, 0, 0, $iW, $iH, $hDDC, 0, 0, $SRCCOPY) ; Direct copy first capture
    _WinAPI_BitBlt($hDDC1, 0, $iH, $iW, $iH, $hDDC, 0, 0, $SRCCOPY); Direct copy second capture

    _GUIScrollBars_ScrollWindow($hWnd1 , 0, -500)

; Part 2 the actual stitching
    _WinAPI_BitBlt($hCDC1, 0, 0, $iW, $iH, $hDDC, 0, 0, $SRCCOPY) ; Direct copy first capture
    _WinAPI_BitBlt($hCDC1, 0, $iH, $iW, $iH, $hDDC, 0, 0, $SRCCOPY); Direct copy second capture

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_ReleaseDC($GUIHandle, $hDCD1)
    _WinAPI_DeleteDC($hCDC1)

     If $sFileName = "" Then Return $hBMP1
     _ScreenCapture_SaveImage($sFileName, $hBMP1)   
    _WinAPI_DeleteObject($hBMP1)
    
EndFunc;==>Bitmap Stitching

As I understand it, the

_WinAPI_BitBlt($hCDC1, 0, $iH, $iW, $iH, $hDDC, 0, 0, $SRCCOPY); Direct copy second capture

is a memory DC which will hold my joined image. the question is how do I print it?

I know I can print the saved file, and then delete it, but I would rather not have to do that.

Your thoughts and suggestions are much appreciated

Edited by Eejit
Link to comment
Share on other sites

I don't get it. If your script is the one creating the content, then why do you have screen-scape the data off your own program? Write the report to a file. If you want to embed graphics, save the report as HTML with the images in separate files referenced by image tags, etc. You already have all the data and imagery when you create the report, so why retrieve it again from the screen?

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I don't get it. If your script is the one creating the content, then why do you have screen-scape the data off your own program? Write the report to a file. If you want to embed graphics, save the report as HTML with the images in separate files referenced by image tags, etc. You already have all the data and imagery when you create the report, so why retrieve it again from the screen?

:D

Thanks for your reply.

As I said, I'm aware that I can save the report to a file and then print it out. I would rather not do that if possible. Oh, and I've no idea about HTML :o

The reason for the screen scrape is that if the report is used on a PC with a smaller resolution, I can't print the whole thing out due to elements hidden by the scrolled window. (Does that make sense?)

If it is possible to print the report as is, then I'm not sure how. One of the reasons I've gone this way is that I can centre and 'fit to page' the screen scrape. Again, this is my first attempt at scripting and I've learnt alot from the forums. but have become stuck at this point.

Edited by Eejit
Link to comment
Share on other sites

Thanks for your reply.

As I said, I'm aware that I can save the report to a file and then print it out. I would rather not do that if possible. Oh, and I've no idea about HTML :D

The reason for the screen scrape is that if the report is used on a PC with a smaller resolution, I can't print the whole thing out due to elements hidden by the scrolled window. (Does that make sense?)

If it is possible to print the report as is, then I'm not sure how. One of the reasons I've gone this way is that I can centre and 'fit to page' the screen scrape. Again, this is my first attempt at scripting and I've learnt alot from the forums. but have become stuck at this point.

This doesn't make sense to me but perhaps there is something you haven't told us or I have misunderstood something.

If your script produces the report which consists of text and graphics, then why can't you create that report on the DC for the printer and print it out and not worry about what is seen on the screen?

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

This doesn't make sense to me but perhaps there is something you haven't told us or I have misunderstood something.

If your script produces the report which consists of text and graphics, then why can't you create that report on the DC for the printer and print it out and not worry about what is seen on the screen?

Thanks for your reply martin,

The simple answer is 'because I haven't figured out how to do that' ;)

As mentioned earlier, this is my first attempt at scripting and everything I've done so far is by trial and error and pouring over the forums. The reason I want my app to be totaly self sufficiant is that it will run on PC's that are completely locked down and unable to install anything.

What I've done so far is create the report by using GUICreate("Data Controls", 830, 550, -1, -1, $frm_main) and then populating the form with elements such as GUICtrlCreateLabel, GUICtrlSetData, GUICtrlSetBkColor etc.

I haven't figured out how to get this information to a printer directly. This was one of the reasons for using a screen scrape. Then I discovered that if my app was run on say a laptop with a smaller screen resolution, then the screen scrape wouldn't get the full report. The window would have scroll bars. Hence the use of stitching, but getting the stitched image from the memory DC to the printer is my next problem.

I'm beginning to think I'm trying to go about this the wrong/complicated way. I would post my script, but it is an absolute mess. Not modular at all ^_^ and even I find it difficult to follow at times due to lack of comments. I must learn to do better.

I hope I've made myself a little clearer in my aims, and what/why I've done what I've done so far, and that you can point me in the right direction. I've no problem in rewriting code as it's the only way to learn. I just wish the help file had a more 'idiot's guide' with respect to some explanations.

_WinAPI_SelectObject

Selects an object into the specified device context

is an example of the somtimes cryptic descriptions to an eejit like myself :-)
Link to comment
Share on other sites

Thanks for your reply martin,

The simple answer is 'because I haven't figured out how to do that' :(

As mentioned earlier, this is my first attempt at scripting and everything I've done so far is by trial and error and pouring over the forums. The reason I want my app to be totaly self sufficiant is that it will run on PC's that are completely locked down and unable to install anything.

What I've done so far is create the report by using GUICreate("Data Controls", 830, 550, -1, -1, $frm_main) and then populating the form with elements such as GUICtrlCreateLabel, GUICtrlSetData, GUICtrlSetBkColor etc.

I haven't figured out how to get this information to a printer directly. This was one of the reasons for using a screen scrape. Then I discovered that if my app was run on say a laptop with a smaller screen resolution, then the screen scrape wouldn't get the full report. The window would have scroll bars. Hence the use of stitching, but getting the stitched image from the memory DC to the printer is my next problem.

I'm beginning to think I'm trying to go about this the wrong/complicated way. I would post my script, but it is an absolute mess. Not modular at all ;) and even I find it difficult to follow at times due to lack of comments. I must learn to do better.

I hope I've made myself a little clearer in my aims, and what/why I've done what I've done so far, and that you can point me in the right direction. I've no problem in rewriting code as it's the only way to learn. I just wish the help file had a more 'idiot's guide' with respect to some explanations. is an example of the somtimes cryptic descriptions to an eejit like myself :-)

You have to walk before you can run. Trying to do the Calculus without wanting to bother with learning to multiply and divide first would be analogous.

Most would not call creating a GUI the same as creating a report. Most would say a report was a separate file of useful information that could exist, and be transmitted and used when the reporting program isn't even running.

Assuming you still want to produce a true report, and the GUI was only a means to the end: Are there really graphical elements that have to be included in the report, or was that only a consequence of miss-using a GUI to create it? If there are no actual graphical elements then it's just a text file. And if there are graphical elements required, use something intended to store such things, like and HTML file.

Learning a little HTML will be easier than complex screen-scraping techniques.

^_^

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

You have to walk before you can run. Trying to do the Calculus without wanting to bother with learning to multiply and divide first would be analogous.

Most would not call creating a GUI the same as creating a report. Most would say a report was a separate file of useful information that could exist, and be transmitted and used when the reporting program isn't even running.

Assuming you still want to produce a true report, and the GUI was only a means to the end: Are there really graphical elements that have to be included in the report, or was that only a consequence of miss-using a GUI to create it? If there are no actual graphical elements then it's just a text file. And if there are graphical elements required, use something intended to store such things, like and HTML file.

Learning a little HTML will be easier than complex screen-scraping techniques.

^_^

I hated Calculus and Math was my strongest subject ;) It would appear I also need to get my terminology right. The GUI is indeed a means to an end and by your description, there are no REAL graphics included, unless you call borders around Labels as graphics. Learning HTML seems to be a bit overkill for what I'm wanting at this juncture. I've already have an idea on screen scraping and have been able to join two seperate scrapes. It's now how to handle this image? handle? The terminology still hasn't quite sunk in.

If it's possible to direct my GUICtrlCreateLabel, GUICtrlSetData, GUICtrlSetBkColor etc. directly to a printer, then that would appear to be the simplest approach. Failing that, a complete re-think of my strategy. (I really don't want to go down the route of an Excel spreadsheet :( )

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...