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 7.81K
604 downloadsNeeds : 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, 14 September 2012 - 09:41 AM.




