Jump to content

Print window and then display it in a static control


Kip
 Share

Recommended Posts

Hi,

I'm trying to print a window using PrintWindow(), and then show the window in a static control.

I've made it quite far, but something is not right here and I don't know what.

The static control doesn't contain a picture or anything.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <WinAPI.au3>
#include <Constants.au3>
#Include <GDIPlus.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>

_GDIPlus_Startup ()

Global Const $STM_SETIMAGE = 0x0172



$Gui = GUICreate("sdsd", 700,500)

GUISetState()


$hImage = _WinApi_CreateWindowEx(0, "Static", "", $WS_VISIBLE+$WS_CHILD+$SS_NOTIFY+0xE, 0, 0, 700, 500, $Gui); 0xE = $SS_BITMAP
    
    $hWindow = WinGetHandle("AutoIt Help")
    
    $HBITMAP = _WinCapture($hWindow)
    
    $hOldBitmap = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hImage, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
    If $hOldBitmap[0] <> 0 Then _WinAPI_DeleteObject($hOldBitmap[0])
    
    _WinAPI_DeleteObject($HBITMAP)
    
    ToolTip($HBITMAP)


While 1
    
WEnd




Func _WinCapture($hWnd, $iWidth=-1, $iHeight=-1)
    
    Local $iH, $iW, $hDDC, $hCDC, $hBMP

    if $iWidth = -1 Then $iWidth = _WinAPI_GetWindowWidth($hWnd)
    if $iHeight = -1 Then $iHeight = _WinAPI_GetWindowHeight($hWnd)
    
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    
    DllCall("User32.dll","int","PrintWindow","hwnd",$hWnd,"hwnd",$hCDC,"int",0)
    
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    
    Return $hBMP
    
EndFunc

Edit: I see that it does resize the control, but just doesn't display anything

Edited by Kip
Link to comment
Share on other sites

No, it displays but window is probably not big enough to see what is displayed.

I guess the problem is what is displayed. Why would non-client area be displayed if you are using _WinAPI_GetDC() function?

Assistance of someone with better understanding of used functions is needed. Something is obviously missing or not done right.

I chenged some things to reduce the amount of variables.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>

;_GDIPlus_Startup ()

Global Const $STM_SETIMAGE = 0x0172

$Gui = GUICreate("sdsd", 400, 300)
$hPic = GUICtrlCreatePic("", 0, 0)

GUISetState()

$hWindow = $Gui;WinGetHandle("AutoIt Help")

_WinCaptureAndDraw($hWindow)

While 1
    If GUIGetMsg() = -3 Then Exit
WEnd


Func _WinCaptureAndDraw($hWnd, $iWidth = -1, $iHeight = -1)

    Local $iH, $iW, $hDDC, $hCDC, $hBMP

    If $iWidth = -1 Then $iWidth = _WinAPI_GetWindowWidth($hWnd)
    If $iHeight = -1 Then $iHeight = _WinAPI_GetWindowHeight($hWnd)

    $hDDC = _WinAPI_GetDC($hWnd)

    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)

    _WinAPI_SelectObject($hCDC, $hBMP)

    $aCall = DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0)

    _WinAPI_DeleteDC($hCDC)
    _WinAPI_ReleaseDC($hWnd, $hDDC)


    GUICtrlSetPos($hPic, 0, 0, $iWidth, $iHeight)
    GUICtrlSendMsg($hPic, $STM_SETIMAGE, 0, $hBMP)

    _WinAPI_DeleteObject($hBMP)

EndFunc

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

don't know what to do for GDI only but this works with GDI+

#Include <GDIPlus.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>


_GDIPlus_Startup ()

Global Const $STM_SETIMAGE = 0x0172

$Gui = GUICreate("sdsd", 1024,768)


    $hPic = _WinApi_CreateWindowEx(0, "Static", "", $WS_VISIBLE+$WS_CHILD+$SS_NOTIFY+0xE, 0, 0, 1024,768, $Gui); 0xE = $SS_BITMAP
    
    $hWindow = WinGetHandle("AutoIt Help")
    $hBMP = _WinCapture($hWindow)
    
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    _WinAPI_DeleteObject($hBMP)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _GDIPlus_ImageDispose($hImage)
    
    $hOldBitmap = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hPic, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "hwnd", $hBitmap)
    If $hOldBitmap[0] <> 0 Then _WinAPI_DeleteObject($hOldBitmap[0])
    
    Local $iFlags = BitOR($SWP_NOZORDER, $SWP_NOREDRAW, $SWP_NOACTIVATE)
    _WinAPI_SetWindowPos($hPic, $HWND_TOP, 0, 0, 1024,768, $iFlags)
    GUISetState()
    
    _WinAPI_DeleteObject ($hBitmap)
    _GDIPlus_Shutdown()

   ;ToolTip($HBITMAP)


While 1
    If GUIGetMsg() = -3 Then Exit
WEnd


Func _WinCapture($hWnd, $iWidth=-1, $iHeight=-1)
    
    Local $iH, $iW, $hDDC, $hCDC, $hBMP

    if $iWidth = -1 Then $iWidth = _WinAPI_GetWindowWidth($hWnd)
    if $iHeight = -1 Then $iHeight = _WinAPI_GetWindowHeight($hWnd)
    
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    
    DllCall("User32.dll","int","PrintWindow","hwnd",$hWnd,"hwnd",$hCDC,"int",0)
    
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    
    Return $hBMP
    
EndFunc

I see fascists...

Link to comment
Share on other sites

Hi,

I'm trying to print a window using PrintWindow(), and then show the window in a static control.

I've made it quite far, but something is not right here and I don't know what.

The static control doesn't contain a picture or anything.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <WinAPI.au3>
#include <Constants.au3>
#Include <GDIPlus.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>

_GDIPlus_Startup ()

Global Const $STM_SETIMAGE = 0x0172



$Gui = GUICreate("sdsd", 700,500)

GUISetState()


$hImage = _WinApi_CreateWindowEx(0, "Static", "", $WS_VISIBLE+$WS_CHILD+$SS_NOTIFY+0xE, 0, 0, 700, 500, $Gui); 0xE = $SS_BITMAP
    
    $hWindow = WinGetHandle("AutoIt Help")
    
    $HBITMAP = _WinCapture($hWindow)
    
    $hOldBitmap = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hImage, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
    If $hOldBitmap[0] <> 0 Then _WinAPI_DeleteObject($hOldBitmap[0])
    
    _WinAPI_DeleteObject($HBITMAP)
    
    ToolTip($HBITMAP)


While 1
    
WEnd




Func _WinCapture($hWnd, $iWidth=-1, $iHeight=-1)
    
    Local $iH, $iW, $hDDC, $hCDC, $hBMP

    if $iWidth = -1 Then $iWidth = _WinAPI_GetWindowWidth($hWnd)
    if $iHeight = -1 Then $iHeight = _WinAPI_GetWindowHeight($hWnd)
    
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    
    DllCall("User32.dll","int","PrintWindow","hwnd",$hWnd,"hwnd",$hCDC,"int",0)
    
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    
    Return $hBMP
    
EndFunc

Edit: I see that it does resize the control, but just doesn't display anything

You code seems to work for me.

I made a couple of small changes.

I commented out the _WinAPI_DeleteObject($HBITMAP) because if you do that the window can't redraw itself.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>



Global Const $STM_SETIMAGE = 0x0172



$hWindow = WinGetHandle("AutoIt Help")
If @error = 1 Then
    MsgBox(262144, "ERROR", "Autoit help Window not found")
    Exit
EndIf
$Gui = GUICreate("sdsd", _WinAPI_GetWindowWidth($hWindow), _WinAPI_GetWindowHeight($hWindow))

GUISetState()
$hImage = _WinAPI_CreateWindowEx(0, "Static", "", $WS_VISIBLE + $WS_CHILD + $SS_NOTIFY + 0xE, 0, 0, 700, 500, $Gui); 0xE = $SS_BITMAP

$HBITMAP = _WinCapture($hWindow)
$hOldBitmap = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hImage, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $HBITMAP)
If $hOldBitmap[0] <> 0 Then _WinAPI_DeleteObject($hOldBitmap[0])

;_WinAPI_DeleteObject($HBITMAP)

ToolTip($HBITMAP)


While GUIGetMsg() <> -3

WEnd




Func _WinCapture($hWnd, $iWidth = -1, $iHeight = -1)

    Local $iH, $iW, $hDDC, $hCDC, $hBMP

    If $iWidth = -1 Then $iWidth = _WinAPI_GetWindowWidth($hWnd)
    If $iHeight = -1 Then $iHeight = _WinAPI_GetWindowHeight($hWnd)

    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)

    DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0)

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)

    Return $hBMP

EndFunc  ;==>_WinCapture
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

@Martin: If I run your script, the only thing that it displays is the white X from the close button of the window :)

I guess the problem is what is displayed. Why would non-client area be displayed if you are using _WinAPI_GetDC() function?

Because I'm not using the DC of the window to get the image, but PrintWindow()
Link to comment
Share on other sites

Because I'm not using the DC of the window to get the image, but PrintWindow()

How to capture only the client area, rectangle, then?

Black border is probably because captured window is (was) maximized and in that case there is no resizing border of a window.

Maybe moving (or whatever) pic to the left _WinAPI_GetSystemMetrics($SM_CXSIZEFRAME) and up _WinAPI_GetSystemMetrics($SM_CYSIZEFRAME) would solve that for that kind of window styles.

nice post rover

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

@Martin: If I run your script, the only thing that it displays is the white X from the close button of the window :)

Because I'm not using the DC of the window to get the image, but PrintWindow()

My version uses PrintWindow, it's only slightly different to your first post which also worked for me. Are you using Vista? I'm using XP and latest versions of AutoIt.
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

Ok thanks, but why is there a black border around it?

@Kip

it's the PrintWindow API

doesn't work properly with GetDC and the PW_CLIENTONLY flag either ($PW_CLIENTONLY = 0x1)

image shifted down about height of titlebar and to the right.

whole window is displayed, not client area

found one example in another language where same behaviour was reported.

the previous examples in this thread returned a faint white 'AutoIt Help' at top left and no image

creating the compatible bitmap was only thing that worked for me.

Hi Rasim

I see fascists...

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...