Sign in to follow this  
Followers 0
myspacee

Magnify alternatively 2 desktop area

10 posts in this topic

Hello to all,

find nice script that allow to zoom portion of screen.

http://www.autoitscript.com/forum/index.php?showtopic=24154&st=20

Modify to zoom desktop area where run an DS emulator:

Posted Image

Post modified code to obtain above result

;http://www.autoitscript.com/forum/index.php?showtopic=24154&st=20
#include <GUIConstants.au3>

$MagWidth = 382     
$MagHeight = 288    
$MagZoom = 2        

Global $SRCCOPY = 0x00CC0020
Global $dll[3], $DeskHDC, $GUIHDC

$dll[1] = DllOpen ( "user32.dll")
$dll[2] = DllOpen ( "gdi32.dll")

Global $GUI = GUICreate ("Zoomx2", $MagWidth * $MagZoom, $MagHeight * $MagZoom, @DesktopWidth - ($MagWidth*2), 0)

GUISetState(@SW_SHOW)

Global $LastPos[2] = [0,0]

While 1
    MAG()

    
    Sleep(10)
WEnd

Func MAG()
    $DeskHDC = DLLCall("user32.dll","int","GetDC","hwnd",0)
    $GUIHDC = DLLCall("user32.dll","int","GetDC","hwnd",$GUI)
    
    If Not @error Then
        DLLCall("gdi32.dll", "int", "StretchBlt", "int", $GUIHDC[0], "int", _
            0, "int", 0, "int", $MagWidth * $MagZoom, "int", $MagHeight * $MagZoom, "int", $DeskHDC[0], "int", _
            0+8, "int", 0+30, "int", $MagWidth ,"int", $MagHeight, _
            "long", $SRCCOPY)


        DLLCall("user32.dll","int","ReleaseDC","int",$DeskHDC[0],"hwnd",0)
        DLLCall("user32.dll","int","ReleaseDC","int",$GUIHDC[0],"hwnd",$GUI)
    EndIf
EndFunc

Func OnAutoItExit()
    DllClose ( $dll[1] )
    DllClose ( $dll[2] )
EndFunc

Ask for :

- Define 2 zoom area and show 1 alternatively to other (switch between them)

- How I can show mouse in zoom gui ?

Thank you all for any info,

m.

Share this post


Link to post
Share on other sites



Are you using gdi for this? Sounds a little insane when Windows 7 comes with a magnification tool.

http://windows.microsoft.com/en-US/windows7/Make-items-on-the-screen-appear-bigger-Magnifier

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

weaponx thank you for reply,

AI script give full control to this task and GDI open doors also for XP user.

Scripting this allow me to move gui/load/start/magnify/add macro and do a big

amount of thing.

I use NDS emulator on my TV with XP PC connected. Play using a wiimote

that feel like a NDS stylus. Gaming is pretty nice, but often word are

too small to read.

This litte script can make happy a lot of NDS emulator user :(

m.

Edited by myspacee

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

tricky with GUIs:

;http://www.autoitscript.com/forum/index.php?showtopic=24154&st=20
#include <GUIConstants.au3>

$MagWidth = 382     
$MagHeight = 288    
$MagZoom = 2        


HotKeySet("{UP}", "_UP")
HotKeySet("{down}", "_DOWN")
HotKeySet("{ESC}", "_terminate")


Global $SRCCOPY = 0x00CC0020
Global $dll[3], $DeskHDC, $GUIHDC_UP

$dll[1] = DllOpen ( "user32.dll")
$dll[2] = DllOpen ( "gdi32.dll")

Global $GUI_UP = GUICreate ("UP", $MagWidth * $MagZoom, $MagHeight * $MagZoom, @DesktopWidth - ($MagWidth*2), 0)
Global $GUI_DOWN = GUICreate ("DOWN", $MagWidth * $MagZoom, $MagHeight * $MagZoom, @DesktopWidth - ($MagWidth*2), 0)


GUISetState(@SW_SHOW, $GUI_UP)
GUISetState(@SW_hide, $GUI_down)



;//////////////////////////////////////////////////////////////
;                       MAIN
;//////////////////////////////////////////////////////////////
While 1
    MAG()
    MAG_down()  
    
    Sleep(10)
WEnd

;//////////////////////////////////////////////////////////////
;                       FUNC
;//////////////////////////////////////////////////////////////
Func _UP()
    GUISetState(@SW_hide, $GUI_down)
    GUISetState(@SW_SHOW, $GUI_UP)

EndFunc

Func _down()
    GUISetState(@SW_hide, $GUI_UP)
    GUISetState(@SW_SHOW, $GUI_down)
EndFunc


Func MAG()
    $DeskHDC = DLLCall("user32.dll","int","GetDC","hwnd",0)
    $GUIHDC_UP = DLLCall("user32.dll","int","GetDC","hwnd",$GUI_UP)
    
    If Not @error Then
        DLLCall("gdi32.dll", "int", "StretchBlt", "int", $GUIHDC_UP[0], "int", _
            0, "int", 0, "int", $MagWidth * $MagZoom, "int", $MagHeight * $MagZoom, "int", $DeskHDC[0], "int", _
            0+8, "int", 0+30, "int", $MagWidth ,"int", $MagHeight, _
            "long", $SRCCOPY)


        DLLCall("user32.dll","int","ReleaseDC","int",$DeskHDC[0],"hwnd",0)
        DLLCall("user32.dll","int","ReleaseDC","int",$GUIHDC_UP[0],"hwnd",$GUI_UP)
    EndIf
EndFunc


Func MAG_down()
    $DeskHDC = DLLCall("user32.dll","int","GetDC","hwnd",0)
    $GUIHDC_DOWN = DLLCall("user32.dll","int","GetDC","hwnd",$GUI_DOWN)
    
    If Not @error Then
        DLLCall("gdi32.dll", "int", "StretchBlt", "int", $GUIHDC_DOWN[0], "int", _
            0, "int", 0, "int", $MagWidth * $MagZoom, "int", $MagHeight * $MagZoom, "int", $DeskHDC[0], "int", _
            0+8, "int", 0+320, "int", $MagWidth ,"int", $MagHeight, _
            "long", $SRCCOPY)


        DLLCall("user32.dll","int","ReleaseDC","int",$DeskHDC[0],"hwnd",0)
        DLLCall("user32.dll","int","ReleaseDC","int",$GUIHDC_DOWN[0],"hwnd",$GUI_DOWN)
    EndIf
EndFunc


Func _Terminate()
    DllClose ( $dll[1] )
    DllClose ( $dll[2] )
    Exit 0
EndFunc

Func OnAutoItExit()
    DllClose ( $dll[1] )
    DllClose ( $dll[2] )
EndFunc

make 2 GUI, when push UP and DOWN arrow key hide first and show second, and viceversa.

Did job ok, but high MEMORY usage, and not mouse pointer yet, anyone can help understand gdi DLLCall please ?

thank you,

m.

Edited by myspacee

Share this post


Link to post
Share on other sites

Stop using DLLCALL reduce mem usage.

Now using GDI directly with AI function.

Adjustable CPU usage but now usable:

; ====================================================================================================
; Description ...: Shows how to magnify an image [mod]
; Author ........: Paul Campbell (PaulIA)
; Notes .........:
; ====================================================================================================
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>

HotKeySet("{UP}", "_UP")
HotKeySet("{down}", "_DOWN")
HotKeySet("{ESC}", "_terminate")

; ====================================================================================================

; Global variables
; ====================================================================================================

Global $hBMP, $hGUI1, $hGUI2, $hBitmap, $hGraphic1, $hGraphic2
Global $f_show_gui = 1
dim $MagWidth = 382, $MagHeight = 288, $MagZoom = 2

; ====================================================================================================
; Main
; ====================================================================================================
; Create a GUI for the zoomed image
$hGUI2 = GUICreate ("Zoomer", $MagWidth * $MagZoom, $MagHeight * $MagZoom, @DesktopWidth - ($MagWidth*2), 0)
GUISetState()

_GDIPlus_Startup()

; Loop until user exits
do
    if $f_show_gui = 1 Then
            
        ; Capture top left corner of the screen
        $hBMP = _ScreenCapture_Capture("", 8, 30, -1, -1, True)
        
        ; Initialize GDI+ library and load image
        $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
        
        ; Draw 2x zoomed image
        $hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($hGUI2)
        _GDIPlus_GraphicsDrawImageRectRect($hGraphic2, $hBitmap, 8, 10, $MagWidth, $MagHeight, 0, 0, $MagWidth*$MagZoom, $MagHeight*$MagZoom)

    elseif $f_show_gui = 2 Then

        ; Capture top left corner of the screen
        $hBMP = _ScreenCapture_Capture("", 8, 300, -1, -1, True)
        
        ; Initialize GDI+ library and load image
        $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
        
        ; Draw 2x zoomed image
        $hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($hGUI2)
        _GDIPlus_GraphicsDrawImageRectRect($hGraphic2, $hBitmap, 8, 75, $MagWidth, $MagHeight, 0, 0, $MagWidth*$MagZoom, $MagHeight*$MagZoom)

    EndIf
    
    
    ; Release resources
    _GDIPlus_GraphicsDispose($hGraphic2)
    _GDIPlus_ImageDispose($hBitmap)
    _WinAPI_DeleteObject($hBmp)

    sleep(50)



until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_Shutdown()

;//////////////////////////////////////////////////////////////
;                       FUNC
;//////////////////////////////////////////////////////////////
Func _UP()
    $f_show_gui = 1
EndFunc

Func _down()
    $f_show_gui = 2
EndFunc

Func _Terminate()
    Exit 0
EndFunc

Now adding .ini to allow setting windows star/stop points.

Nice exercise,

m.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I've been using the dllcall script in the original posting and it works wonderfully! I've been trying to use it to magnify a webpage with a flash game, so I can see it on my TV. Is there a way to "hide" the flash game and only see the magnified version using the dllcall script? I tried using the GDI version from the prior post and found the video to be choppy, whereas the dllcalls made it more fluid and playable.

Edited by buymeapc

Share this post


Link to post
Share on other sites

myspacee,

Here is my take. The mouse is only represented by a small block GUI, but that could be easily changed. I have run this to magnify streaming video and it seems pretty lagless - it uses about 7% CPU at most on my machine: :blink:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Opt("GUICloseOnESC", 0)

HotKeySet("{ESC}", "On_Exit")
HotKeySet("{PAUSE}", "On_Switch") ; to switch areas to be magnified

; Set coordinates for areas to magnify
Global $aCoords_1[2] = [750, 500], $aCoords_2[2] = [1000, 500]
; Set size of magnifier GUI
Global $iWidth = 500, $iHeight = 500
Global $hMag_Win, $hMagDC, $hDeskDC, $hPen, $oObj, $iShow = 1

; Create mouse GUI
$hMouse_GUI = GUICreate("Mouse", 5, 5, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
GUISetBkColor(0, $hMouse_GUI)
GUISetState(@SW_SHOW)

; Create Magnifier GUI
$hMag_GUI = GUICreate("Test", $iWidth, $iHeight, 0, 0, $WS_POPUP)
GUISetState(@SW_SHOW)

; Get device context for Mag GUI
$hMagDC = _WinAPI_GetDC($hMag_GUI)
If @error Then Exit
; Get device context for desktop
$hDeskDC = _WinAPI_GetDC(0)
If @error Then
    _WinAPI_ReleaseDC($hMag_GUI, $hMagDC)
    Exit
EndIf

While 1
    Sleep(10)

    ; Show the correct area
    Switch $iShow
        Case 1
            Magnify($aCoords_1)
            MouseCheck($aCoords_1)
        Case 2
            Magnify($aCoords_2)
            MouseCheck($aCoords_2)
    EndSwitch

WEnd

; Move the mouse GUI to follow the real mouse
Func MouseCheck($aCoords)

    Local $aMousePos = MouseGetPos()
    If  $aMousePos[0] > $aCoords[0] And $aMousePos[0] < $aCoords[0] + 250 And _
        $aMousePos[1] > $aCoords[1] And $aMousePos[1] < $aCoords[1] + 250 Then

        Local $iX = ($aMousePos[0] - $aCoords[0]) * 2
        Local $iY = ($aMousePos[1] - $aCoords[1]) * 2
        WinMove($hMouse_GUI, "", $iX, $iY)

    Else
        ; Hide mouse GUI if not required
        WinMove($hMouse_GUI, "", -20, -20)
    EndIf

EndFunc

Func On_Exit()

    ; Clear up
    _WinAPI_ReleaseDC(0, $hDeskDC)
    _WinAPI_ReleaseDC($hMag_GUI, $hMagDC)
    Exit

EndFunc   ;==>On_Exit

Func On_Switch()

    Switch $iShow
        Case 1
            $iShow = 2
        Case 2
            $iShow = 1
    EndSwitch

EndFunc

Func Magnify($aCoords)

    ; Fill Mag GUI with 2x expanded contents of desktop area as set in $aCoords
    DllCall("gdi32.dll", "int", "StretchBlt", _
        "int", $hMagDC,  "int", 0,                   "int", 0,   "int", $iWidth,     "int", $iHeight, _
        "int", $hDeskDC, "int", $aCoords[0], "int", $aCoords[1], "int", $iWidth / 2, "int", $iWidth / 2, _
        "long", $SRCCOPY)

EndFunc   ;==>Magnify

I hope all the comments are clear - but do not expect too much more explanation, I am not very good with GDI. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Stop using DLLCALL reduce mem usage.

Now using GDI directly with AI function.

I hate to break it to you, but _GDIPlus* functions all use DLLCall's. Additionally, GDIPlus.dll is basically a wrapper for gdi32.dll, though with some extra features like support for different graphics file formats. For probably 90% of posted code that uses _GDIPlus* calls, the same can be done using different gdi32.dll calls (and faster). Additionally, gdi32.dll is already loaded for all processes in the system, so you don't have to 'load' the DLL again. And lastly, since GDIPlus calls gdi32.dll for most of its functions, there is unnecessary additional overhead (both memory and time-wise).

All of this makes me wonder why people prefer to use _GDIPlus in situations where loading/saving different file formats isn't an issue. My guess would be because its a bundled UDF. Would be cool if someone did a GDI32 UDF.. (although I bet Yashied probably has most of the functions in his WinAPIEx UDF..)

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

This I'd love to see you prove, because in my experience - gdi32.dll has ALWAYS been faster.

By the way, take a look by the way at the imports on gdiplus.dll. Over 150 functions are Imported from gdi32.dll. In other words, you call gdiplus.dll, it call gdi32.dll for most of its work. (Need an import viewer - check my sig :blink: )

*edit: also, with the user32.dll imports for many of the graphics functions, thats nearly 200 functions it wraps. And both user32.dll and gdi32.dll are permanent 'fixtures' in memory.

Edited by Ascend4nt

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