Sign in to follow this  
Followers 0
ptrex

Printing Controls in AU3

7 posts in this topic

#1 ·  Posted (edited)

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.

Print_Control.au3

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.

#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
1 person likes this

Share this post


Link to post
Share on other sites



Hi,

#Include <PrintWinAPI.au3>

is missing.

Mega


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee 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

Share this post


Link to post
Share on other sites

@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

Share this post


Link to post
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
Sign in to follow this  
Followers 0