Sign in to follow this  
Followers 0
ahha

set pixel color

11 posts in this topic

Okay I seem to be stuck. I've found all sorts of GDI screen capture and then pixel color set operations like BitmapSetPixel. What I can't seem to find, but what is alluded to, is some sort of DLL call to set the pixel color on a screen. I was trying to write a simple program that merrily marched across the screen inverting pixels. Please point me in the correct direction.

screen color invert v1a.au3

screen color invert v1a.au3

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Thanks. It uses GDI32.dll. Where can I find a list of GDI32.dll functions? (I searched the web but must be going to the wrong areas. http://source.winehq.org/WineAPI/gdi32.html shows LineTo as not documented :( ) I need to see if LineTo in GDI32.dll will accept a single pixel start and stop location. I'm kind of surprised that there is not another way of doing this. (I miss the old days of memory-mapped displays.)

Okay just found some info here: http://msdn.microsoft.com/en-us/library/dd145203%28v=VS.85%29.aspx

Edited by ahha

Share this post


Link to post
Share on other sites

Since that script was written a udf has been added to autoit for gdi funtions, look in the helpfile user defined function reference > GDIPlus management.


GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.

Share this post


Link to post
Share on other sites

Thanks. Actually saw some of these, however, the closest seemed to be _GDIPlus_DrawImagePoints which handles an area and needs an image file and _GDIPlus_BitmapLockBits which looks like you can write to bits, however there's no example of writing - Ugh.

Share this post


Link to post
Share on other sites

ook in the helpfile user defined function reference > GDIPlus management.

Example to paint "at the screen" from AutoIt-Help:LINK

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

This will allow you to set pixels on the primary screen. I have code to set pixels on any monitor, but this should get you started:

Func _PixelSetColor($iX,$iY,$iColor,$hWnd=0)
    Local $aRet,$iErr,$hDC
    If $hWnd And Not IsHWnd($hWnd) Then Return SetError(1,@error,False)

    $hDC=_WinAPI_GetWindowDC($hWnd)     ; 0 = DC of entire (primary) screen (desktop)
    If Not $hDC Then Return SetError(2,@error,False)

    ; Do the RGB->BGR conversion ('+' could have been used in place of BitOR)
    $iColor=BitOR(BitShift(BitAND($iColor,0xFF0000),16),BitShift(BitAND($iColor,0xFF),-16),BitAND($iColor,0xFF00))

    $aRet=DllCall ("gdi32.dll","dword","SetPixel","handle",$hDC,"int",$iX,"int",$iY,"dword",$iColor)
    If @error Then $iErr=@error

 _WinAPI_ReleaseDC($hWnd,$hDC)

 If $iErr Then Return SetError(2,$iErr,False)

 $iColor=$aRet[0]
    ; Do the BGR->RGB conversion ('+' could have been used in place of BitOR)
    $iColor=BitOR(BitShift(BitAND($iColor,0xFF0000),16),BitShift(BitAND($iColor,0xFF),-16),BitAND($iColor,0xFF00))

 Return SetError(0,$iColor,True)
 EndFunc
Edited by Ascend4nt

Share this post


Link to post
Share on other sites

Ascend4nt,

Thanks will give it a try. Meanwhile I came up the attached code. Problem is that GDIPlus does not seem to be working correctly. Program attached tries to place a single pixel below some marker lines (so you can see single pixel placement). GDI works, but GDIPlus does not seem to work. See line 29 for problem. What am I doing wrong?

ahha_GDIPlus_GraphicsDrawLine.au3

Share this post


Link to post
Share on other sites

Sorry, haven't messed with GDI+ yet. From what I understand, GDI+ is like a wrapper for GDI32, so basically there's some overhead in using GDI+ vs GDI32. Of course, there's added functionality in GDI+, but a lot of what people do with it is possible using GDI32 calls. (selecting pens, drawing pixels, lines, text, boxes, grabbing/manipulating bitmaps in native formats, etc). Just do what's simplest for what you need. In this case, I think I gave you that.

Share this post


Link to post
Share on other sites

Ascend4nt,

I confirm it works. Thanks.

Share this post


Link to post
Share on other sites

Here is an example with a magnification window added.

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled

Global $GuiSizeX = 500, $GuiSizeY = 500

$hGui = GUICreate("GDIPlus Example", $GuiSizeX, $GuiSizeY)
GUISetOnEvent(-3, "_Quit")
GUISetState()

;=== For _MAG() === 1 of 3
Global $hGUI2, $Width = 400, $Height = 300, $ZoomFactor = 10;0.4
$hGUI2 = GUICreate("Magnification x" & $ZoomFactor, $Width, $Height, 0, 400, $WS_OVERLAPPED)
GUISetState()
;===================

_GDIPlus_Startup()

$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) ; Graphics of GUI
$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) ; Memory bitmap
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ; Graphics of memory bitmap


;Graphics here

_GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8)
$hPen = _GDIPlus_PenCreate(0xFFFF0000)
_GDIPlus_GraphicsDrawLine($hGraphic, 90, 200, 100, 200, $hPen)
_GDIPlus_GraphicsDrawLine($hGraphic, 102, 200, 112, 200, $hPen)

DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBMPBuff, "int", 101, "int", 201, "dword", 0xFF0000FF) ; 0xAARRGGBB


;End of graphics

GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize.
_GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ; Draw memory bitmap to graphics of GUI


While 1
    ;=== For _MAG() === 2 of 3
    Local $aMousePos = MouseGetPos()
    _MAG($hGUI2, $aMousePos[0] - ($Width / $ZoomFactor) / 2, $aMousePos[1] - ($Height / $ZoomFactor) / 2)
    ;===================
    Sleep(20)
WEnd

;Func to redraw on PAINT MSG
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    ; Check, if the GUI with the Graphic should be repainted
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN
    Return $GUI_RUNDEFMSG
EndFunc ;==>MY_PAINT

Func _Quit()
    ;_GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _WinAPI_DeleteObject($hBMPBuff)
    _GDIPlus_Shutdown()
    Exit
EndFunc ;==>_Quit

;3 of 3
; Modified from http://www.autoitscript.com/forum/index.php?s=&showtopic=53471&view=findpost&p=405045
Func _MAG($MyhWnd, $l, $t)
    Local $MyHDC = DllCall("user32.dll", "int", "GetDC", "hwnd", $MyhWnd); $MyHDC = _WinAPI_GetDC ($MyhWnd)
    If @error Then Return
    Local $DeskHDC = DllCall("user32.dll", "int", "GetDC", "hwnd", 0) ; $DeskHDC = _WinAPI_GetDC (0)
    If Not @error Then
        DllCall("gdi32.dll", "int", "StretchBlt", "int", $MyHDC[0], "int", 0, "int", 0, "int", $Width, "int", $Height, "int", _
                $DeskHDC[0], "int", $l, "int", $t, "int", $Width / $ZoomFactor, "int", $Height / $ZoomFactor, "long", $SRCCOPY)
        DllCall("user32.dll", "int", "ReleaseDC", "int", $DeskHDC[0], "hwnd", 0); _WinAPI_ReleaseDC ($DeskHDC, 0)
    EndIf
    DllCall("user32.dll", "int", "ReleaseDC", "int", $MyHDC[0], "hwnd", $MyhWnd); _WinAPI_ReleaseDC ($MyhWnd, $MyHDC)
EndFunc ;==>_MAG

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