Jump to content



Photo

Printing Controls in AU3


  • Please log in to reply
6 replies to this topic

#1 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 20 August 2008 - 10:03 PM

Printing Controls in AU3

Native printing in AU3 has always been an issue, untill GRS came up with PrintWinAPI.au3

Thanks to Martin, ProgAndy and Zedna for their enlightning examples.
I was able to mix all of those together in this example.

Attached File  Print_Control.au3   7.81K   604 downloads

Needs : PrintWinAPI.au3

It still needs cleaning up, but it will give you all a start.

I finished what Zedna started using the WM_PRINT message instead of _WinAPI_BitBlt.
The result is the same but the approach is different.

When to use which approach ?

The normal way of capturing the contents of a window into a bitmap is creating a memory device context (CreateCompatibleDC), creating a device-dependent bitmap (CreateCompatibleBitmap) or a DIB section (CreateDIBSection), selecting the bitmap into the memory DC (SelectObject), and then bitblt from the window's device context (GetWindowDC) into the memory DC (Bitblt). After that, a copy of the contents of the window as it appears on the screen is stored in the bitmap.

But what if the window is hidden, or partially blocked with other windows ? When a window is hidden or partially blocked, the non-visible part of the window will be clipped in the device context returned from GetWindowDC. In other words, that part of the window can't be captured using a simple BitBlt.

To capture any window, completely visible, partially visible, or complete invisible, Win32 API provides two special messages, WM_PRINT and WM_PRINTCLIENT. Both these messages take a device context handle as a parameter, and the window handling these messages is supposed to draw itself or its client area into the device context provided.

AutoIt         
#include <ClipBoard.au3> #include <SendMessage.au3> #include <GDIPlus.au3> #Include <WinAPI.au3> #include <GUIStatusBar.au3> #include <GUIConstantsEx.au3> Const $WM_PAINT = 0x000F Const $WM_PRINT = 0x317 Const $WM_PRINTCLIENT = 0x318 Const $PRF_CHECKVISIBLE = 0x1; Draws the window only if it is visible Const $PRF_ERASEBKGND = 0x8 ; Erases the background before drawing the window Const $PRF_CLIENT = 0x4 ; Draw the window's client area. Const $PRF_NONCLIENT = 0x2 ; Draw the window's Title area. Const $PRF_CHILDREN = 0x10; Draw all visible child windows. Const $PRF_OWNED = 0x20 ; Draw all owned windows. $Form1 = GUICreate("Form1", 593, 453, 193, 115) $StatusBar1 = _GUICtrlStatusBar_Create($Form1) _GUICtrlStatusBar_SetSimple($StatusBar1) _GUICtrlStatusBar_SetText($StatusBar1, "This is the status bar text ...") $MyButton1 = GUICtrlCreateButton("Get Status as image", 224, 176, 140, 30, 0) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $MyButton1 GetStatusImage() EndSwitch WEnd Func GetStatusImage() $hWnd = ControlGetHandle("Form1","","msctls_statusbar321") ; WinGetHandle("Form1") $pos = ControlGetPos("Form1","","msctls_statusbar321") ; WinGetPos("Form1")                                     If Not IsArray($pos) Then MsgBox(0,"Error","No Control found") Return EndIf                                     _GDIPlus_StartUp() $Width = $pos[2] $Height = $pos[3] $hDC = _WinAPI_GetDC($hWnd) $memDC = _WinAPI_CreateCompatibleDC($hDC) $memBmp = _WinAPI_CreateCompatibleBitmap($hDC, $Width, $Height) _WinAPI_SelectObject ($memDC, $memBmp) ; Use the WM_PRINT message instead of _WinAPI_BitBlt ;_WinAPI_BitBlt($memDC, 0, 0, $Width, $Height, $hDC, 0, 0, $SRCCOPY) $Ret = _SendMessage($hWnd, $WM_PAINT, $memDC, 0) $Ret = _SendMessage($hWnd, $WM_PRINT, $memDC, BitOR($PRF_CHILDREN , $PRF_CLIENT, $PRF_OWNED, $PRF_NONCLIENT, $PRF_ERASEBKGND)) $hImage = _GDIPlus_BitmapCreateFromHBITMAP ($memBmp) _ClipBoard_SetData($memBmp,$CF_BITMAP) _GDIPlus_ImageSaveToFile($hImage, 'status.jpg') ;.BMP _GDIPlus_ImageDispose ($hImage) _WinAPI_ReleaseDC($hWnd, $hDC) _WinAPI_DeleteDC($memDC) _WinAPI_DeleteObject ($memBmp) _GDIPlus_ShutDown() _WinAPI_GetLastError() EndFunc

Enjoy !!

Regards,

ptrex

Edited by ptrex, 14 September 2012 - 09:41 AM.








#2 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 21 August 2008 - 02:03 PM

@All

Updated the Example script.

(See first post.)

Regards

ptrex

#3 Xenobiologist

Xenobiologist

    Xx Code~Mega xX

  • MVPs
  • 4,729 posts

Posted 22 August 2008 - 07:45 AM

Hi,

#Include <PrintWinAPI.au3>

is missing.

Mega
Scripts & functions Organize Includes Let Scite organize the include files *newYahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication)_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

#4 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 24 August 2008 - 08:42 PM

@Xenobiologist

Thanks for mentioning it !!

Thought everyone would already have downloaded it ;)

Updated first post.

Regards,

ptrex

#5 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 27 August 2008 - 08:52 PM

@all

Updated first post.

Added an example to use the $WM_PRINT Sendmessage approach.

Regards,

ptrex

#6 Zedna

Zedna

    AutoIt rulez!

  • MVPs
  • 8,315 posts

Posted 27 August 2008 - 09:39 PM

@all

Updated first post.
Added an example to use the $WM_PRINT Sendmessage approach.

Regards,
ptrex

WM_PAUNT is not neccessary
_SendMessage($hWnd, $WM_PAINT, $memDC,  0)


#7 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 28 August 2008 - 05:41 PM

@Zedna

$WM_PAINT is not needed in this example.
But it is needed in the case where you use a graphic on the GUI.
When minimizing and maximizing the GUI, WM_PAINT is needed to redraw the graphic.

So as a best practice it is, best to use the WM_PAINT in any case.
Doesn't harm anything.

regards,

ptrex




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users