Sign in to follow this  
Followers 0

Color Under Mouse -- Reborn [02/03/2014 D]

23 posts in this topic

#1 ·  Posted (edited)

Years back JamesBrooks posted this thread: ColourUnderMouse.  I was interested in it because I was looking for a way to get started in AutoIt and so I latched onto this script.  Believe it or not after all this time I still find ways to modify the script!  Something about it intrigues me.  Here is the latest version.

Changelog:

[02/03/2014] -- New feature to display the checksum of the zoom rectangle surrounding the mouse!  Also, many optimizations to speed the script up considerably.  The zoom window is no longer a separate window.

Edit B: Now the checksum isn't calculated with every mouse move.  Press F4 or hold down shift plus an arrow key to get the checksum.

Edit C:  The checksum wasn't accurate when using shift + arrow keys.

Edit D: OOPS.  I get so excited I release way too early.

[02/01/2014] -- Now you have to hold down shift to activate the zoom feature.  Also, while holding down shift the arrow keys will move the mouse one pixel at a time.  This is to allow for picking out an exact pixel.  Try it out!

[01/06/2014] -- I finally got around to integrating UEZ's >zoom window code from 2011!  Totally awesome!  Check it out.  Scroll the mouse wheel to zoom in and out.

[08/25/2013] -- I have once again found a way to update this script.  Now the script uses a low level mouse procedure to watch for mouse movement.  I believe this translates to a higher resolution.  Requires latest beta (3.3.9.19).  Tested on Windows7 x64.

Removed until furthur notice.

downloads:101

Note: credit goes to JamesBrooks for the original.  Also credit to UEZ for the Zoom Window code.  Thanks.

Edited by jaberwacky

Share this post


Link to post
Share on other sites



#2 ·  Posted

Great Script!

Another idea for enhancement: Output the hex RGB values in decimal for the three colours. If I want to set a custom colour in MS Word I have to input the RGB values in decimal e.g. #99CCFF needs to be 153 204 255.


My UDFs and Tutorials:

UDFs:
Active Directory (NEW 2015-08-07 - Version 1.2.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2014-07-27 - Version 1.0.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (NEW 2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

Share this post


Link to post
Share on other sites

#3 ·  Posted

Cool script!

Using BlockInput() in the While/WEnd loop is a bit annoying because the mouse becomes stumbeling.

Greets,

-supersonic.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Another idea for enhancement: Output the hex RGB values in decimal for the three colours. If I want to set a custom colour in MS Word I have to input the RGB values in decimal e.g. #99CCFF needs to be 153 204 255.

Please see if the latest version does what you asked.

Edit: I realized that it wouldn't and so I corrected it.

Using BlockInput() in the While/WEnd loop is a bit annoying because the mouse becomes stumbeling.

Removed.

Edited by LaCastiglione

Share this post


Link to post
Share on other sites

#5 ·  Posted

Please see if the latest version does what you asked.

Perfect! This version does exactly what I need!

Thanks a lot for sharing!


My UDFs and Tutorials:

UDFs:
Active Directory (NEW 2015-08-07 - Version 1.2.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2014-07-27 - Version 1.0.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (NEW 2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
Tutorials:
ADO - Wiki

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

A zoom window would be great to pick detailed pixel color.

Something like that:

;coded by UEZ
#include <GDIPlus.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)
Opt("GUICloseOnESC", 0)
TraySetState (2)

Global $zx = 0, $zy = 0, $up = 1
Global $zoom_level = 6, $zoom_min = 0.5, $zoom_max = 30
Global $esc

$zoom_level = 6
$esc = False
Zoom()
Exit

Func Zoom()
    Local $w, $h, $mpos = MouseGetPos(), $pixel_color
    Local $hGUI_Dot = GUICreate("", 1, 1, 18, 18, BitOR($WS_POPUP, $WS_CLIPSIBLINGS), $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
    GUISetBkColor(0, $hGUI_Dot)
    GUISetState(@SW_SHOW, $hGUI_Dot)
    HotKeySet("{ESC}", "_Exit_CSR")

    Local Const $zw = 256
    Local Const $zh = 256
    Local Const $lW = 40
    Local Const $lH = 40
    Local Const $dist_x = 24, $dist_y = 24, $radius = 160
    Local $dirx = 1, $drx = 0, $diry = 1, $dry = 0, $lower_border, $right_border
    Local $zoomW = Int($zw / $zoom_level)
    Local $zoomH = Int($zh / $zoom_level)
    Local $hGUI_Zoom = GUICreate("Zoom", $zw, $zh, $zx, $zx, BitOR($WS_POPUP,$DS_MODALFRAME), BitOR($WS_EX_OVERLAPPEDWINDOW,$WS_EX_TOPMOST,$WS_EX_WINDOWEDGE), WinGetHandle(AutoItWinGetTitle()))
    GUISetState(@SW_SHOW, $hGUI_Zoom)
    Local $hDC_Zoom = _WinAPI_GetDC(0)
    Local $hGUI_ZoomDC = _WinAPI_GetDC($hGUI_Zoom)
    _WinAPI_SetBkMode($hGUI_ZoomDC, $TRANSPARENT)

    GUIRegisterMsg(0x020A, "WM_MOUSEWHEEL")
    Local $aLastPos[2]

    Do
        If $esc Then ExitLoop
        $mpos = MouseGetPos()
        GUISetState(@SW_SHOW, $hGUI_Zoom)
        If $mpos[0] <> $aLastPos[0] Or $mpos[1] <> $aLastPos[1] Then
            $pixel_color = Hex(PixelGetColor($mpos[0], $mpos[1]), 6)
            WinMove($hGUI_Dot, "", $mpos[0], $mpos[1])
            ToolTip("ESC to abort"& @CRLF & @CRLF & _
                          "Position: " & $mpos[0] & "," & $mpos[1] & @CRLF & _
                          "Pixel Color: 0x" & $pixel_color, $drx + $mpos[0] + $dirx * ($dist_x + $zoomW / 3) , $dry + $mpos[1] + $diry * ($dist_y + $zoomH / 3))
            $aLastPos = $mpos

            $right_border = Pixel_Distance($mpos[0], $mpos[1], @DesktopWidth, $mpos[1])
            If $right_border < $radius Then
                $dirx = -1
                $drx = -$radius
            Else
                $dirx = 1
                $drx = 0
            EndIf
            $lower_border = Pixel_Distance($mpos[0], $mpos[1], $mpos[0], @DesktopHeight)
            If $lower_border < $radius Then
                $diry = -1
                $dry = -$radius
            Else
                $diry = 1
                $dry = 0
            EndIf
        EndIf

        If CheckRectCollision($zx - $lW, $zy - $lH , $zx + $zw + $lW, $zy + $zh + $lH, $mpos[0], $mpos[1]) Then
            $up *= -1
            If $up = -1 Then
                $zx = @DesktopWidth - $zw - 4
                WinMove($hGUI_Zoom, "", $zx, $zy)
            Else
                $zx = 0
                WinMove($hGUI_Zoom, "", $zx, $zy)
            EndIf
        EndIf
        _WinAPI_StretchBlt($hGUI_ZoomDC, 0, 0, $zw, $zh, $hDC_Zoom, $mpos[0] - $zoomW / 2, $mpos[1] - $zoomH / 2, $zoomW, $zoomH, $SRCCOPY)
        $zoomW = Int($zw / $zoom_level)
        $zoomH = Int($zh / $zoom_level)

        Sleep(20)
    Until 0
    ToolTip("")
    _WinAPI_ReleaseDC($hGUI_Zoom, $hGUI_ZoomDC)
    _WinAPI_ReleaseDC(0, $hDC_Zoom)
    _WinAPI_DeleteDC($hGUI_ZoomDC)
    _WinAPI_DeleteDC($hDC_Zoom)
    GUIDelete($hGUI_Dot)
    GUIDelete($hGUI_Zoom)
EndFunc

Func _Exit_CSR()
    $esc = True
    Return
EndFunc

Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
    Local $wheel_Dir = _WinAPI_HiWord($wParam)
    If $wheel_Dir > 0 Then
        If $zoom_level < $zoom_max Then
            $zoom_level += 0.25
        EndIf
    Else
        If $zoom_level  > $zoom_min Then
            $zoom_level  -= 0.25
        EndIf
    EndIf
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_MOUSEWHEEL

Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidthDest, $iHeightDest, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iRop)
    Local $Ret  = DllCall('gdi32.dll', 'int', 'StretchBlt', 'hwnd', $hDestDC, 'int', $iXDest, 'int', $iYDest, 'int', $iWidthDest, 'int', $iHeightDest, 'hwnd', $hSrcDC, 'int', $iXSrc, 'int', $iYSrc, 'int', $iWidthSrc, 'int', $iHeightSrc, 'dword', $iRop)
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_WinAPI_StretchBlt

Func CheckRectCollision($iLeft, $iTop, $iRight, $iBottom, $iX, $iY )
    Local $tagRECT = "int Left;int Top;int Right;int Bottom"
    Local $tRECT = DllStructCreate($tagRECT)
    DllStructSetData($tRECT, 1, $iLeft)
    DllStructSetData($tRECT, 2, $iTop)
    DllStructSetData($tRECT, 3, $iRight)
    DllStructSetData($tRECT, 4, $iBottom)
    Local $aResult = DllCall("User32.dll", "int", "PtInRect", "ptr", DllStructGetPtr($tRECT), "int", $iX, "int", $iY)
    Return $aResult[0] <> 0
EndFunc

Func Pixel_Distance($x1, $y1, $x2, $y2) ;Pythagoras theorem
    Local $a, $b
    If $x2 = $x1 And $y2 = $y1 Then Return 0
    $a = $y2 - $y1
    $b = $x2 - $x1
    Return Sqrt($a * $a + $b * $b)
EndFunc   ;==>Pixel_Distance

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#7 ·  Posted

both scripts are awesome! i get an error when running the zoom one after i hit ESC i get

_WinAPI_DeleteDC: The operation completed successfully.

How to I stop this from displaying?

Share this post


Link to post
Share on other sites

#8 ·  Posted

Hey,

im trying to make a colorpicker, zoom and screenshot script.

I figured out that GDI+ is the best way (but not the easiest) to draw rectangles on the desktop.

So i modified that great example from Malkey () to have a Zoom GUI

But i have a problem: drawn rectangles wont show up in the zoomed window.

I bet there is a window flag you have to set to get that included, but for that special case i cant find any information and im not a GDI+ expert.

Here is the Script (press and hold Ctrl to drag a rectangle)

#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
; Modified from http://www.autoitscript.com/forum/index....=&showtopic=97126&view=findpos
;~ Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
$GDIdll = DllOpen("gdi32.dll")
$ZoomSizeX = 256
$ZoomSizeY = 256
$ZoomGUI = GUICreate("Zoom", $ZoomSizeX, $ZoomSizeY, 400, 200, BitOR($WS_SIZEBOX,$WS_THICKFRAME, $WS_SYSMENU, $WS_BORDER, $WS_CAPTION), $WS_EX_TOPMOST)
WinSetTrans($ZoomGUI, "", 255); I dont know why but this excludes the ZoomGUI from being drawn with StretchBlt, neat!

GUISetBkColor(0xEEEEEE)
GUISetOnEvent($GUI_EVENT_CLOSE, "ExitF")
GUISetState()
Main()
Func Main()
    Local $hBitmap, $hGui, $hGraphic, $hImage2, $GuiSizeX = @DesktopWidth, $GuiSizeY = @DesktopHeight
    Local $GuiSize = 70, $hWnd, $hDC, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    Local $iX1 = 0, $iY1 = 0, $tPoint, $pPoint, $hBMPBuff, $hGraphicGUI, $hPen, $aMPosNew
    Local $iOpacity = 255, $dll = DllOpen("user32.dll")
Local $aMPos = -1
    $hGui = GUICreate("L1", $GuiSizeX, $GuiSizeY, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST + $WS_EX_TRANSPARENT))
    GUISetState()
    _GDIPlus_Startup()
    $hWnd = _WinAPI_GetDC(0)
    $hDC = _WinAPI_CreateCompatibleDC($hWnd)
    $hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSizeX, $GuiSizeY)
    _WinAPI_SelectObject($hDC, $hBitmap)
    $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC)
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphic)
    $hGraphicGUI = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)
    _GDIPlus_GraphicsClear($hGraphic); Add ,0x01000000) to disable underling desktop
    $hPen = _GDIPlus_PenCreate(0xffff0000, 10)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", $GuiSizeX);$iWidth )
    DllStructSetData($tSize, "Y", $GuiSizeY);$iHeight)
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    $tPoint = DllStructCreate($tagPOINT); Create point destination structure here
    $pPoint = DllStructGetPtr($tPoint); Create pointer to this dll data structure, $pPTDest parameter
    DllStructSetData($tPoint, "X", $iX1)
    DllStructSetData($tPoint, "Y", $iY1)
    _WinAPI_UpdateLayeredWindow($hGui, $hWnd, $pPoint, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    Do
 
  $ZoomDC = _WinAPI_GetDC($ZoomGUI)
  $DeskDC = _WinAPI_GetDC(0)
 
        Select
            Case _IsPressed("11", $dll); Ctrl to start drag rect
                Do

     $aMPosNew = MouseGetPos()
     If $aMPos = -1 Then ; Drag Start
      $aMPos = $aMPosNew
     EndIf
     _GDIPlus_GraphicsClear($hGraphic)
    
     ; I used _Iif() from Misc.au3 instead using of _Min() from Math.au3.
     $RectStartX = _Iif($aMPos[0] < $aMPosNew[0], $aMPos[0], $aMPosNew[0])
     $RectStartY = _Iif($aMPos[1] < $aMPosNew[1], $aMPos[1], $aMPosNew[1])
     _GDIPlus_GraphicsDrawRect($hGraphic, $RectStartX, $RectStartY, Abs($aMPosNew[0] - $aMPos[0]), Abs($aMPosNew[1] - $aMPos[1]), $hPen)
    
     _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA)

                    Sleep(10)
                Until Not _IsPressed("11", $dll)
    $aMPos = -1 ; Drag End
              
            Case _IsPressed("04", $dll) Or _IsPressed("11", $dll) ; Middle mouse button 0r Ctrl key <=======  Clear screen of rectangles.
                _GDIPlus_GraphicsClear($hGraphic)
                _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
   Case Else
   
    $aMPosNew = MouseGetPos()
    _WinAPI_StretchBlt($ZoomDC, 0, 0, $ZoomSizeX, $ZoomSizeY, $DeskDC, $aMPosNew[0], $aMPosNew[1], 256/2, 256/2, $MERGECOPY) ; 256/2 = Double Zoom
   
  EndSelect
 
  _WinAPI_ReleaseDC(0, $DeskDC)
  _WinAPI_ReleaseDC($ZoomGUI, $ZoomDC)
    
        Sleep(10)
    Until _IsPressed("1B", $dll); ESC key
    DllClose($dll)
DllClose($GDIdll)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_ReleaseDC(0, $hWnd)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hDC)
    _GDIPlus_Shutdown()
EndFunc   ;==>Main

Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iROP)
;~   Local $aResult = _WinAPI_BitBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iROP)
    Local $aResult = DllCall($GDIdll, "int", "StretchBlt", "hwnd", $hDestDC, "int", $iXDest, "int", $iYDest, "int", $iWidth, "int", $iHeight, _
            "hwnd", $hSrcDC, "int", $iXSrc, "int", $iYSrc, "int", $iWidthSrc, "int", $iHeightSrc, "int", $iROP)
    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc   ;==>_WinAPI_StretchBlt

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

#10 ·  Posted

From davidkim's post by adding a BitBlt to the _WinAPI_StretchBlt function, a layered window is able to be captured.

#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>

;Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
Local $f = 0, $GDIdll = DllOpen("gdi32.dll")
Local $ZoomSizeX = 256
Local $ZoomSizeY = 256
Local $ZoomGUI = GUICreate("Zoom", $ZoomSizeX, $ZoomSizeY, 400, 200, BitOR($WS_SIZEBOX, $WS_THICKFRAME, $WS_SYSMENU, $WS_BORDER, $WS_CAPTION), $WS_EX_TOPMOST)
WinSetTrans($ZoomGUI, "", 255)
GUISetBkColor(0xEEEEEE)
GUISetOnEvent($GUI_EVENT_CLOSE, "ExitF")
GUISetState()
Main()


Func Main()
    Local $hBitmap, $hGui, $hGraphic, $hImage2, $GuiSizeX = @DesktopWidth, $GuiSizeY = @DesktopHeight
    Local $GuiSize = 70, $hWnd, $hDC, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend, $ZoomDC, $DeskDC, $RectStartX, $RectStartY
    Local $iX1 = 0, $iY1 = 0, $tPoint, $pPoint, $hBMPBuff, $hGraphicGUI, $hPen, $aMPosNew
    Local $iOpacity = 255, $dll = DllOpen("user32.dll")
    Local $aMPos = -1
    $hGui = GUICreate("L1", $GuiSizeX, $GuiSizeY, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST + $WS_EX_TRANSPARENT))
    GUISetState()
    _GDIPlus_Startup()
    $hWnd = _WinAPI_GetDC(0)
    $hDC = _WinAPI_CreateCompatibleDC($hWnd)
    $hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSizeX, $GuiSizeY)
    _WinAPI_SelectObject($hDC, $hBitmap)
    $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC)
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphic)
    $hGraphicGUI = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)
    _GDIPlus_GraphicsClear($hGraphic); Add ,0x01000000) to disable underling desktop
    $hPen = _GDIPlus_PenCreate(0xffff0000, 10)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", $GuiSizeX);$iWidth )
    DllStructSetData($tSize, "Y", $GuiSizeY);$iHeight)
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    $tPoint = DllStructCreate($tagPOINT); Create point destination structure here
    $pPoint = DllStructGetPtr($tPoint); Create pointer to this dll data structure, $pPTDest parameter
    DllStructSetData($tPoint, "X", $iX1)
    DllStructSetData($tPoint, "Y", $iY1)
    _WinAPI_UpdateLayeredWindow($hGui, $hWnd, $pPoint, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    $ZoomDC = _WinAPI_GetDC($ZoomGUI)
    $DeskDC = _WinAPI_GetDC(0)
    Do
        Select
            Case _IsPressed("11", $dll); Ctrl to start drag rect
                Do
                    $aMPosNew = MouseGetPos()
                    If $aMPos = -1 Then ; Drag Start
                        $aMPos = $aMPosNew
                    EndIf
                    _GDIPlus_GraphicsClear($hGraphic)
                    ; I used _Iif() from Misc.au3 instead using of _Min() from Math.au3.
                    $RectStartX = _Iif($aMPos[0] < $aMPosNew[0], $aMPos[0], $aMPosNew[0])
                    $RectStartY = _Iif($aMPos[1] < $aMPosNew[1], $aMPos[1], $aMPosNew[1])
                    _GDIPlus_GraphicsDrawRect($hGraphic, $RectStartX, $RectStartY, Abs($aMPosNew[0] - $aMPos[0]), Abs($aMPosNew[1] - $aMPos[1]), $hPen)
                    _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
                    Sleep(10)
                Until Not _IsPressed("11", $dll)
                $aMPos = -1 ; Drag End
            Case _IsPressed("04", $dll) Or _IsPressed("11", $dll) ; Middle mouse button 0r Ctrl key <=======  Clear screen of rectangles.
                _GDIPlus_GraphicsClear($hGraphic)
                _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
            Case Else
                $aMPosNew = MouseGetPos()
                _WinAPI_StretchBlt($ZoomDC, 0, 0, $ZoomSizeX, $ZoomSizeY, $DeskDC, $aMPosNew[0], $aMPosNew[1], 256 / 2, 256 / 2, $MERGECOPY)
        EndSelect

        If _IsPressed("1B", $dll) Then $f = 1; ESC key
        Sleep(50)
    Until $f
    _WinAPI_ReleaseDC(0, $DeskDC)
    _WinAPI_ReleaseDC($ZoomGUI, $ZoomDC)
    DllClose($dll)
    DllClose($GDIdll)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_ReleaseDC(0, $hWnd)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hDC)
    _GDIPlus_Shutdown()
EndFunc   ;==>Main

Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iROP)
;~   Local $aResult = _WinAPI_BitBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iROP)
    Local $srcDC = _WinAPI_GetDC(0)
    Local $trgDC = _WinAPI_CreateCompatibleDC($srcDC)
    Local $hBitmap = _WinAPI_CreateCompatibleBitmap($srcDC, @DesktopWidth, @DesktopHeight)
    Local $old = _WinAPI_SelectObject($trgDC, $hBitmap)
    ;select area copy
    _WinAPI_BitBlt($trgDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $srcDC, $iXSrc - $iWidthSrc / 2, $iYSrc - $iHeightSrc / 2, BitOR($SRCCOPY, 0x40000000))

    Local $aResult = DllCall($GDIdll, "int", "StretchBlt", _
            "hwnd", $hDestDC, "int", $iXDest, "int", $iYDest, "int", $iWidth, "int", $iHeight, _
            "hwnd", $trgDC, "int", $iXSrc, "int", $iYSrc, "int", $iWidthSrc, "int", $iHeightSrc, "int", $iROP)
    If @error Then Return SetError(@error, 0, False)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($trgDC)
    _WinAPI_ReleaseDC(0, $srcDC)
    Return $aResult[0] <> 0
EndFunc   ;==>_WinAPI_StretchBlt

Func ExitF()
    $f = 1
EndFunc   ;==>ExitF

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Malkey thats cool, i learned quite something today :)

You use BitOR($SRCCOPY, 0x40000000) for the raster operation code with BitBlt, which is $CAPTUREBLT (which is exactly what i needed).

But the thing is: you also can use it directly with StretchBlt since it has the same $iROP parameter.

So my code works if i just replace $MERGECOPY with BitOR($SRCCOPY, $CAPTUREBLT)

But then i noticed that the zoom window is being visible again in the zoomed view, which is kind of one step further, one step back.

Then i thought it must be possible to take a bitmap of the original Desktop (without layered windows) and additionally merge in the bitmap of the layered rectangle window.

Your code was very helpful in the process of doing that ;)

Here is the script:

#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
; Modified from http://www.autoitscript.com/forum/index....=&showtopic=97126&view=findpos
;~ Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client
Local $f = 0, $GDIdll = DllOpen("gdi32.dll")

Local $hBitmap, $hGui, $hGraphic, $hImage2, $GuiSizeX = @DesktopWidth, $GuiSizeY = @DesktopHeight
Local $GuiSize = 70, $hWnd, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
Local $iX1 = 0, $iY1 = 0, $tPoint, $pPoint, $hBMPBuff, $hGraphicGUI, $hPen, $aMPosNew
Local $iOpacity = 255, $dll = DllOpen("user32.dll")
Local $aMPos = -1
$hGui = GUICreate("L1", $GuiSizeX, $GuiSizeY, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST + $WS_EX_TRANSPARENT))
GUISetState()

$ZoomSizeX = 256
$ZoomSizeY = 256
$ZoomGUI = GUICreate("Zoom", $ZoomSizeX, $ZoomSizeY, 400, 200, BitOR($WS_SIZEBOX, $WS_THICKFRAME, $WS_SYSMENU, $WS_BORDER, $WS_CAPTION), $WS_EX_TOPMOST)
WinSetTrans($ZoomGUI, "", 255); I dont know why but this excludes the ZoomGUI from being drawn with StretchBlt, neat!

GUISetBkColor(0xEEEEEE)
GUISetOnEvent($GUI_EVENT_CLOSE, "ExitF")
GUISetState()

_GDIPlus_Startup()
$hWnd = _WinAPI_GetDC(0)
$L1hDC = _WinAPI_CreateCompatibleDC($hWnd)
$hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSizeX, $GuiSizeY)
_WinAPI_SelectObject($L1hDC, $hBitmap)
$hGraphic = _GDIPlus_GraphicsCreateFromHDC($L1hDC)
$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphic)
$hGraphicGUI = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)
_GDIPlus_GraphicsClear($hGraphic); Add ,0x01000000) to disable underling desktop
$hPen = _GDIPlus_PenCreate(0xffff0000, 10)
;~     $hBrush = _GDIPlus_BrushCreateSolid(0xffff0000)
$tSize = DllStructCreate($tagSIZE)
$pSize = DllStructGetPtr($tSize)
DllStructSetData($tSize, "X", $GuiSizeX);$iWidth )
DllStructSetData($tSize, "Y", $GuiSizeY);$iHeight)
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
$tBlend = DllStructCreate($tagBLENDFUNCTION)
$pBlend = DllStructGetPtr($tBlend)
DllStructSetData($tBlend, "Alpha", $iOpacity)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT); Create point destination structure here
$pPoint = DllStructGetPtr($tPoint); Create pointer to this dll data structure, $pPTDest parameter
DllStructSetData($tPoint, "X", $iX1)
DllStructSetData($tPoint, "Y", $iY1)
_WinAPI_UpdateLayeredWindow($hGui, $hWnd, $pPoint, $pSize, $L1hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
$ZoomDC = _WinAPI_GetDC($ZoomGUI)
Global $DeskDC = _WinAPI_GetDC(0)

Do
    Select
        Case _IsPressed("11", $dll); Ctrl to start drag rect
            Do
                $aMPosNew = MouseGetPos()
                If $aMPos = -1 Then ; Drag Start
                    $aMPos = $aMPosNew
                EndIf
                _GDIPlus_GraphicsClear($hGraphic)
                ; I used _Iif() from Misc.au3 instead using of _Min() from Math.au3.
                $RectStartX = _Iif($aMPos[0] < $aMPosNew[0], $aMPos[0], $aMPosNew[0])
                $RectStartY = _Iif($aMPos[1] < $aMPosNew[1], $aMPos[1], $aMPosNew[1])
                _GDIPlus_GraphicsDrawRect($hGraphic, $RectStartX, $RectStartY, Abs($aMPosNew[0] - $aMPos[0]), Abs($aMPosNew[1] - $aMPos[1]), $hPen)
                _WinAPI_StretchBltNOTLayCombine($ZoomDC, 0, 0, $ZoomSizeX, $ZoomSizeY, $DeskDC, $aMPosNew[0] - 64, $aMPosNew[1] - 64, 256 / 2, 256 / 2, $SRCCOPY, $L1hDC) ; 256/2 = Double Zoom
;~                 _WinAPI_StretchBlt($ZoomDC, 0, 0, $ZoomSizeX, $ZoomSizeY, $DeskDC, $aMPosNew[0]-64, $aMPosNew[1]-64, 256 / 2, 256 / 2, $SRCCOPY) ; less CPU

                _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $L1hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
                Sleep(10)
            Until Not _IsPressed("11", $dll)
            $aMPos = -1 ; Drag End
        Case _IsPressed("04", $dll) Or _IsPressed("11", $dll) ; Middle mouse button 0r Ctrl key <=======  Clear screen of rectangles.
            _GDIPlus_GraphicsClear($hGraphic)
            _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $L1hDC, $pSource, 0, $pBlend, $ULW_ALPHA)
        Case Else
            $aMPosNew = MouseGetPos()
            _WinAPI_StretchBltNOTLayCombine($ZoomDC, 0, 0, $ZoomSizeX, $ZoomSizeY, $DeskDC, $aMPosNew[0] - 64, $aMPosNew[1] - 64, 256 / 2, 256 / 2, $SRCCOPY, $L1hDC) ; 256/2 = Double Zoom
;~             _WinAPI_StretchBlt($ZoomDC, 0, 0, $ZoomSizeX, $ZoomSizeY, $DeskDC, $aMPosNew[0]-64, $aMPosNew[1]-64, 256 / 2, 256 / 2, $SRCCOPY) ; less CPU
    EndSelect
    Sleep(10)
Until $f

_WinAPI_ReleaseDC(0, $DeskDC)
_WinAPI_ReleaseDC($ZoomGUI, $ZoomDC)
DllClose($dll)
DllClose($GDIdll)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphicGUI)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_ReleaseDC(0, $hWnd)
_WinAPI_DeleteObject($hBitmap)
_WinAPI_DeleteDC($L1hDC)
_GDIPlus_Shutdown()


Func _WinAPI_StretchBltNOTLayCombine($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iROP, $hAddDC); $hAddDC = DC to a bitmap to mix in with black transparency

    ; create a Memory Bitmap to combine the Desktop DC(without any layered Windows) with the DC of the layered rectangle window (fullscreen)
    Local $MashDC = _WinAPI_CreateCompatibleDC($DeskDC)
    Local $hMashBitmap = _WinAPI_CreateCompatibleBitmap($DeskDC, @DesktopWidth, @DesktopHeight)
    Local $old = _WinAPI_SelectObject($MashDC, $hMashBitmap)

    ; copy whole Desktop Bitmap to memory (without layered windows)
    _WinAPI_BitBlt($MashDC, 0, 0, @DesktopWidth, @DesktopHeight, $DeskDC, 0, 0, $iROP)

    ; copy additional bitmap with black color made transparent (only red rectangles visible)
    Local $aResult = DllCall($GDIdll, "int", "GdiTransparentBlt", "hwnd", $MashDC, "int", 0, "int", 0, "int", @DesktopWidth, "int", @DesktopHeight, _
            "hwnd", $hAddDC, "int", 0, "int", 0, "int", @DesktopWidth, "int", @DesktopHeight, "uint", 0x000000); make black color transparent (BGR format)

    ; copy merged bitmap from memory to Desktop
    _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $MashDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iROP)

    _WinAPI_DeleteObject($hMashBitmap)
    _WinAPI_DeleteDC($MashDC)

    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc   ;==>_WinAPI_StretchBltNOTLayCombine

Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iROP)
;~   Local $aResult = _WinAPI_BitBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iROP)
    Local $aResult = DllCall($GDIdll, "int", "StretchBlt", "hwnd", $hDestDC, "int", $iXDest, "int", $iYDest, "int", $iWidth, "int", $iHeight, _
            "hwnd", $hSrcDC, "int", $iXSrc, "int", $iYSrc, "int", $iWidthSrc, "int", $iHeightSrc, "int", $iROP)
    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc   ;==>_WinAPI_StretchBlt

Func ExitF()
    $f = 1
EndFunc   ;==>ExitF

But this way is much more CPU intensive than simply use StretchBlt, is there another way to make it more slim?

The rectangles show up for me. WIndows 7 x64

Yeah i have the same, but it has to do with Aero. I have turned it off and therefore BitBlt will behave different. Edited by qsek

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Add these changes to toggle the dot in UEZ's excellent code above Posted 04 November 2011 - 08:00 AM

Local $aLastPos[2]
    Local $begin = TimerInit()
    Local $color = 0
    Do
        If $esc Then ExitLoop
        $mpos = MouseGetPos()

        ;toggle dot color
        If TimerDiff($begin) &gt; 250 Then  ;1/4 second
            $begin = TimerInit()    ;reset timer
            if $color = 0 Then      ;toggle color
                $color = 0xffffff   ;white
            Else
                $color = 0          ;black
            EndIf
        EndIf

        GUISetState(@SW_SHOW, $hGUI_Zoom)
... rest of UEZ's code
Edited by ahha

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

@LaCastiglione script very good and very useful, congratulations.

@UEZ, zoom option also execelente

Edited by Belini

Share this post


Link to post
Share on other sites

#15 ·  Posted

I added "color to clip board" to UEZ's Code which makes this very useful to me.

;coded by UEZ
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Opt("MustDeclareVars", 1)
Opt("GUICloseOnESC", 0)
TraySetState(2)

Global $zx = 0, $zy = 0, $up = 1
Global $zoom_level = 6, $zoom_min = 0.5, $zoom_max = 30
Global $esc, $pixel_color, $Copy
HotKeySet("!x", "CaptureColor")

$zoom_level = 7 ;5 ;6
$esc = False
Zoom()
Exit

Func Zoom()
    Local $w, $h, $mpos = MouseGetPos(), $pixel_color
    Local $hGUI_Dot = GUICreate("", 1, 1, 18, 18, BitOR($WS_POPUP, $WS_CLIPSIBLINGS), $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
    GUISetBkColor(0, $hGUI_Dot)
    GUISetState(@SW_SHOW, $hGUI_Dot)
    HotKeySet("{ESC}", "_Exit_CSR")

    Local Const $zw = 256
    Local Const $zh = 256
    Local Const $lW = 40
    Local Const $lH = 40
    Local Const $dist_x = 24, $dist_y = 24, $radius = 160
    Local $dirx = 1, $drx = 0, $diry = 1, $dry = 0, $lower_border, $right_border
    Local $zoomW = Int($zw / $zoom_level)
    Local $zoomH = Int($zh / $zoom_level)
    Local $hGUI_Zoom = GUICreate("Zoom", $zw, $zh, $zx, $zx, BitOR($WS_POPUP, $DS_MODALFRAME), BitOR($WS_EX_OVERLAPPEDWINDOW, $WS_EX_TOPMOST, $WS_EX_WINDOWEDGE), WinGetHandle(AutoItWinGetTitle()))
    GUISetState(@SW_SHOW, $hGUI_Zoom)
    Local $hDC_Zoom = _WinAPI_GetDC(0)
    Local $hGUI_ZoomDC = _WinAPI_GetDC($hGUI_Zoom)
    _WinAPI_SetBkMode($hGUI_ZoomDC, $TRANSPARENT)

    GUIRegisterMsg(0x020A, "WM_MOUSEWHEEL")
    Local $aLastPos[2]

    Do
        If $esc Then ExitLoop
        $mpos = MouseGetPos()
        GUISetState(@SW_SHOW, $hGUI_Zoom)
        If $mpos[0] <> $aLastPos[0] Or $mpos[1] <> $aLastPos[1] Then
            $pixel_color = Hex(PixelGetColor($mpos[0], $mpos[1]), 6)
            $Copy = $pixel_color
            WinMove($hGUI_Dot, "", $mpos[0], $mpos[1])
            ToolTip("ESC to abort" & @CRLF & @CRLF & _
                    "ALT + x = Capture " & @CRLF & _
                    "Color to clip board" & @CRLF & @CRLF & _
                    "Position: " & $mpos[0] & "," & $mpos[1] & @CRLF & _
                    "Pixel Color: 0x" & $pixel_color, $drx + $mpos[0] + $dirx * ($dist_x + $zoomW / 3), $dry + $mpos[1] + $diry * ($dist_y + $zoomH / 3))
            $aLastPos = $mpos

            $right_border = Pixel_Distance($mpos[0], $mpos[1], @DesktopWidth, $mpos[1])
            If $right_border < $radius Then
                $dirx = -1
                $drx = -$radius
            Else
                $dirx = 1
                $drx = 0
            EndIf
            $lower_border = Pixel_Distance($mpos[0], $mpos[1], $mpos[0], @DesktopHeight)
            If $lower_border < $radius Then
                $diry = -1
                $dry = -$radius
            Else
                $diry = 1
                $dry = 0
            EndIf
        EndIf

        If CheckRectCollision($zx - $lW, $zy - $lH, $zx + $zw + $lW, $zy + $zh + $lH, $mpos[0], $mpos[1]) Then
            $up *= -1
            If $up = -1 Then
                $zx = @DesktopWidth - $zw - 4
                WinMove($hGUI_Zoom, "", $zx, $zy)
            Else
                $zx = 0
                WinMove($hGUI_Zoom, "", $zx, $zy)
            EndIf
        EndIf
        _WinAPI_StretchBlt($hGUI_ZoomDC, 0, 0, $zw, $zh, $hDC_Zoom, $mpos[0] - $zoomW / 2, $mpos[1] - $zoomH / 2, $zoomW, $zoomH, $SRCCOPY)
        $zoomW = Int($zw / $zoom_level)
        $zoomH = Int($zh / $zoom_level)

        Sleep(20)
    Until 0
    ToolTip("")
    _WinAPI_ReleaseDC($hGUI_Zoom, $hGUI_ZoomDC)
    _WinAPI_ReleaseDC(0, $hDC_Zoom)
    _WinAPI_DeleteDC($hGUI_ZoomDC)
    _WinAPI_DeleteDC($hDC_Zoom)
    GUIDelete($hGUI_Dot)
    GUIDelete($hGUI_Zoom)
EndFunc   ;==>Zoom

Func _Exit_CSR()
    $esc = True
    Return
EndFunc   ;==>_Exit_CSR

Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
    Local $wheel_Dir = _WinAPI_HiWord($wParam)
    If $wheel_Dir > 0 Then
        If $zoom_level < $zoom_max Then
            $zoom_level += 0.25
        EndIf
    Else
        If $zoom_level > $zoom_min Then
            $zoom_level -= 0.25
        EndIf
    EndIf
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_MOUSEWHEEL

Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidthDest, $iHeightDest, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iRop)
    Local $Ret = DllCall('gdi32.dll', 'int', 'StretchBlt', 'hwnd', $hDestDC, 'int', $iXDest, 'int', $iYDest, 'int', $iWidthDest, 'int', $iHeightDest, 'hwnd', $hSrcDC, 'int', $iXSrc, 'int', $iYSrc, 'int', $iWidthSrc, 'int', $iHeightSrc, 'dword', $iRop)
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_WinAPI_StretchBlt

Func CheckRectCollision($iLeft, $iTop, $iRight, $iBottom, $iX, $iY)
    Local $tagRECT = "int Left;int Top;int Right;int Bottom"
    Local $tRECT = DllStructCreate($tagRECT)
    DllStructSetData($tRECT, 1, $iLeft)
    DllStructSetData($tRECT, 2, $iTop)
    DllStructSetData($tRECT, 3, $iRight)
    DllStructSetData($tRECT, 4, $iBottom)
    Local $aResult = DllCall("User32.dll", "int", "PtInRect", "ptr", DllStructGetPtr($tRECT), "int", $iX, "int", $iY)
    Return $aResult[0] <> 0
EndFunc   ;==>CheckRectCollision

Func Pixel_Distance($x1, $y1, $x2, $y2) ;Pythagoras theorem
    Local $a, $b
    If $x2 = $x1 And $y2 = $y1 Then Return 0
    $a = $y2 - $y1
    $b = $x2 - $x1
    Return Sqrt($a * $a + $b * $b)
EndFunc   ;==>Pixel_Distance

Func CaptureColor()
;~  MsgBox(0,"","HERE")
    ClipPut("0x" & $Copy)
EndFunc   ;==>CaptureColor

MEASURE TWICE - CUT ONCE

Share this post


Link to post
Share on other sites

#20 ·  Posted

@jaberwacky

Hello sir, I'm in dear need of a script like this and it would be great if you can send me the script :0. THank you very much

Updated!  See the changelog in the OP for details.

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