Eejit Posted April 13, 2009 Share Posted April 13, 2009 (edited) 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: expandcollapse popupFunc _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: expandcollapse popup#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 April 13, 2009 by Eejit Link to comment Share on other sites More sharing options...
PsaltyDS Posted April 14, 2009 Share Posted April 14, 2009 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? 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 More sharing options...
Eejit Posted April 14, 2009 Author Share Posted April 14, 2009 (edited) 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? 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 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 April 14, 2009 by Eejit Link to comment Share on other sites More sharing options...
martin Posted April 14, 2009 Share Posted April 14, 2009 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 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 More sharing options...
Eejit Posted April 15, 2009 Author Share Posted April 15, 2009 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 More sharing options...
PsaltyDS Posted April 16, 2009 Share Posted April 16, 2009 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 More sharing options...
Eejit Posted April 16, 2009 Author Share Posted April 16, 2009 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now