Jump to content

Recommended Posts

This is an easy question in any other language ... but for the life of me I can't seem to figure this out. 
This is what I want to do ... (please don't post some huge example that isn't doing just what I'm asking)

In an easy short and sweet code ... I want to be able to do two things.
A. Open a window, "plot" down a colored pixel by whatever color I wish.
B. Read the open window pixel by pixel telling me the color of the pixels there.
 
Short set up ...

Global $MUI=(GUICreate("Test     ",187,155,-1,-1,-1,BitOR(768,8,256)))
GUISetBkColor(0x0000000)
GUISetState(@SW_SHOW)

;code <-- good luck this is harder than you may think

While 1
    $nMsg = GUIGetMsg()
    If $nMsg<>0 Then
       Switch $nMsg
            Case -3
                Exit
       EndSwitch
    EndIf
WEnd



Set it up to "plot" down a few different colored pixels starting from 0,0 and going to the right ...
Have it read back the colors one by one till it hits a black pixel (0x0000000)

I want to be able to save the window as a picture then be able to load up one of the pictures and read it like stated.
Think I know how to do that part. It's just the no plot function that is killing me. No I do not want to plot to the desktop.

 

Edited by Comatose

Share this post


Link to post
Share on other sites

First result: https://www.autoitscript.com/forum/topic/92784-gdi-draw-line/

 

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

Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client
Opt('MustDeclareVars', 1)
Global $sPos
_Main()

Func _Main()
    Local $hGUI, $hWnd, $hGraphic, $hPen, $msg

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300, -1, -1)
    $hWnd = WinGetHandle("GDI+")
    GUISetState()

    ; Draw line
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $hPen = _GDIPlus_PenCreate(0xFF609900, 2)
    ;;_AntiAlias($hGraphic)

    ; Loop until user exits
    do
        $msg = GUIGetMsg()
        if $msg = $GUI_EVENT_MOUSEMOVE Then
            _WinAPI_RedrawWindow($hGUI, "", "", BitOR(0, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ;;$WM_ERASEBKGND
            _GDIPlus_GraphicsDrawLine($hGraphic, 10, 150, MouseGetPos(0), MouseGetPos(1), $hPen)
        EndIf

    until $msg = $GUI_EVENT_CLOSE
    ; Clean up resources
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

EndFunc   ;==>_Main

#cs
Func _AntiAlias($hGraphics)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_AntiAlias
#ce

 

Edited by Bilgus

Share this post


Link to post
Share on other sites

Thanks for the reply but ... Exactly what I asked not to post.
Yep you can draw lines. Not what I asked. I've seen 100 demos like that.
That is not what I'm looking for here ...

This is as close as I've come ... just trying to set down 1 pixel then read it back.

#include <WinAPIGdi.au3>
; only needed for _WinAPI_GetPixel if used ...

Global $MUI=(GUICreate("Test     ",187,155,-1,-1,-1,BitOR(768,8,256)))
GUISetBkColor(0x000000)
GUISetState(@SW_SHOW)

$hdc = DllCall("user32.dll","int","GetDC","hwnd",$MUI)
$x = 100
$y = 100
DllCall("gdi32.dll","int","SetPixel","int",$hdc[0],"int",$x,"int",$y,"int",0xFFFFFF)

$pix=_WinAPI_GetPixel ($hdc, $x , $y)
; Don't work ???
MsgBox(4096,"",$pix,0)

$pix= DllCall("gdi32.dll","int","GetPixel","int",$hdc[0],"int",$x,"int",$y)
;  why don't this work? It looks correctly setup ...
; https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getpixel
MsgBox(4096,"",$pix,0)

DllCall("user32.dll","int","ReleaseDC","hwnd",0,"int",$hdc[0])
While 1
    $nMsg = GUIGetMsg()
    If $nMsg<>0 Then
       Switch $nMsg
            Case -3
                Exit
       EndSwitch
    EndIf
WEnd

 

Edited by Comatose

Share this post


Link to post
Share on other sites
#include <WinAPIGdi.au3>

Global $MUI=(GUICreate("Test     ",187,155,-1,-1,-1,BitOR(768,8,256)))
GUISetBkColor(0x000000)
GUISetState(@SW_SHOW)

$hdc = _WinAPI_GetDC($MUI)
$x = 100
$y = 100

_WinAPI_SetPixel($hdc, $x, $y, 0xFF0000)
$pix=_WinAPI_GetPixel($hdc, $x , $y)
MsgBox(4096,"",Hex($pix,6))

_WinAPI_SetPixel($hdc, $x, $y, 0x0000FF)
$pix=_WinAPI_GetPixel($hdc, $x , $y)
MsgBox(4096,"",Hex($pix,6))

_WinAPI_ReleaseDC($MUI, $hdc)

While 1
    $nMsg = GUIGetMsg()
    If $nMsg<>0 Then
       Switch $nMsg
            Case -3
                Exit
       EndSwitch
    EndIf
WEnd

 

Share this post


Link to post
Share on other sites

Oh man I was so close to that with my continued testing  ... grrr. Now that's how you answer a question.
Used my code and made it work correctly.  Short and sweet. Exactly what I asked for.
Many many thanks InnI, you sir are a pro!

$hdc = _WinAPI_GetDC($MUI)  ;<- drr, how did I miss that!

You ever figure out why the $pix= DllCall("gdi32.dll","int","GetPixel","int",$hdc[0],"int",$x,"int",$y)
didn't work ... I mean I'm happy but loose ends bother me. That should have worked.
I was getting someplace with using Opt("PixelCoordMode",2) .. but everything was a weird kind of backwards.
I think the DllCall version may in the end be faster when used over a large area. 

Edited by Comatose

Share this post


Link to post
Share on other sites

You are pretty opinionated about how one should answer your questions, aren't you? ;) 

1 hour ago, Comatose said:

You ever figure out why the $pix= DllCall("gdi32.dll","int","GetPixel","int",$hdc[0],"int",$x,"int",$y)
didn't work

When you check the _WinAPI_GetPixel() you see it uses:

DllCall('gdi32.dll', 'dword', 'GetPixel', 'handle', $hDC, 'int', $iX, 'int', $iY)

So my guess would be the second parameter shouldn't be int but handle, but also the first parameter in your case is signed in stead of an unsigned dword.

Jos

Share this post


Link to post
Share on other sites

I honestly don't mean to be rude ... It's just seems every time you ask a question someone posts the 1st thing they find on google.
Like I don't know how to use google ... Clearly I didn't find a answer that way so ...

Share this post


Link to post
Share on other sites

Yea, which is likely due to the fact you are one of the exceptions to the rule. Many just dump their question assuming others will do the work. ;) 

Anyway, which of the 2 parameters of the DllCall() was the issue or was it both?

Jos

Share this post


Link to post
Share on other sites

Tried it a few ways still can't get it to work. 

Global $MUI=(GUICreate("Test     ",187,155,-1,-1,-1,BitOR(768,8,256)))
GUISetBkColor(0x000000)
GUISetState(@SW_SHOW)

$hdc = DllCall("user32.dll","int","GetDC","hwnd",$MUI)
$x = 100
$y = 100
DllCall("gdi32.dll","int","SetPixel","int",$hdc[0],"int",$x,"int",$y,"int",0xFFFFFF)

Sleep(100)


;$pix= DllCall('gdi32.dll', 'int', 'GetPixel', 'handle', $hdc[0],"int", $x, "int", $y)
$pix= DllCall('gdi32.dll', 'dword', 'GetPixel', 'handle', $hdc[0],"int", $x, "int", $y)

MsgBox(4096,"",$pix,0)

DllCall("user32.dll","int","ReleaseDC","hwnd",0,"int",$hdc[0])
While 1
    $nMsg = GUIGetMsg()
    If $nMsg<>0 Then
       Switch $nMsg
            Case -3
                Exit
       EndSwitch
    EndIf
WEnd

 

Edited by Comatose

Share this post


Link to post
Share on other sites

I've been working on this project for as long as I can remember. .au3 is a bear! ...
Anyways I got everything done but this part. As a last resort I came here. 
I am very versed in AutoIt been programming with it for over 10 years now.
I am a life long programmer and know 30+ languages. I started in Assembler. 
Always liked .au3 but got to admit it can be a bear sometimes (lol).
This is the one I've never been able to figure out ...

I also need to make that into a picture and save it
Then I need to be able to load up the picture (having problems with this part) and read the pixels. 

Edited by Comatose

Share this post


Link to post
Share on other sites

You have some mistakes in the code: what about this version of getpixel:

$pix= DllCall("gdi32.dll","dword","GetPixel","handle",$hdc[0],"int",$x,"int",$y)
;  why don't this work? It looks correctly setup ...
; https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getpixel
MsgBox(4096,"",hex($pix[0]),0)

Jos

Share this post


Link to post
Share on other sites
3 minutes ago, Jos said:

You have some mistakes in the code: what about this version of getpixel:

$pix= DllCall("gdi32.dll","dword","GetPixel","handle",$hdc[0],"int",$x,"int",$y)
;  why don't this work? It looks correctly setup ...
; https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getpixel
MsgBox(4096,"",hex($pix[0]),0)

Jos

That's the one i just posted ... it seems to come up with a blank. no 0, just a blank.

Share this post


Link to post
Share on other sites
7 minutes ago, Comatose said:

That's the one i just posted ..

It is a corrected version... just have a closer look. ;) 

Share this post


Link to post
Share on other sites

This worked .. it was returning an array.

Global $MUI=(GUICreate("Test     ",187,155,-1,-1,+BitOR(-2147483648, 144),-1))
GUISetBkColor(0x000000)
GUISetState(@SW_SHOW)

$hdc = DllCall("user32.dll","int","GetDC","hwnd",$MUI)
$x = 100
$y = 100
DllCall("gdi32.dll","int","SetPixel","handle",$hdc[0],"int",$x,"int",$y,"int",0xFDFFFF)

Sleep(100)

$pix= DllCall("gdi32.dll","int","GetPixel","handle",$hdc[0],"int",$x,"int",$y)

MsgBox(4096,"",hex($pix[0]),0)

DllCall("user32.dll","int","ReleaseDC","hwnd",0,"int",$hdc[0])

While 1
    $nMsg = GUIGetMsg()
    If $nMsg<>0 Then
       Switch $nMsg
            Case -3
                Exit
        EndSwitch
    Else
     Sleep(100)
    EndIf
WEnd

 

Edited by Comatose

Share this post


Link to post
Share on other sites

Everything works but the last part ... :(
Not to sure how to load a picture to my window correctly ...

#include <ScreenCapture.au3>
Global $MUI=(GUICreate("Test     ",187,155,-1,-1,+BitOR(-2147483648, 144),-1))
;Global $MUI=(GUICreate("Test     ",187,155,-1,-1,BitOR(768,8,256)))
GUISetBkColor(0x000000)
GUISetState(@SW_SHOW)

$hdc = DllCall("user32.dll","int","GetDC","hwnd",$MUI)
$x = 100
$y = 100

$mode=1

if($mode=(1))Then
 DllCall("gdi32.dll","int","SetPixel","handle",$hdc[0],"int",$x,"int",$y,"int",0xFDFFFF)
 Sleep(100)
 $pix= DllCall("gdi32.dll","int","GetPixel","handle",$hdc[0],"int",$x,"int",$y)
 MsgBox(4096,"",hex($pix[0]),0)

 $pic=_ScreenCapture_CaptureWnd (@WorkingDir&"\Pic.bmp",$MUI,0,0,-1,-1,false)
 _WinAPI_DeleteObject($pic)
else

 $pic=(GUICtrlCreatePic(@WorkingDir&"\Pic.bmp",0,0,-1,-1,14,-1))
 Sleep(100)
 $pix= DllCall("gdi32.dll","int","GetPixel","handle",$hdc[0],"int",$x,"int",$y)
 MsgBox(4096,"",hex($pix[0]),0)

Endif
DllCall("user32.dll","int","ReleaseDC","hwnd",0,"int",$hdc[0])

While 1
    $nMsg = GUIGetMsg()
    If $nMsg<>0 Then
       Switch $nMsg
            Case -3
                Exit
        EndSwitch
    Else
     Sleep(100)
    EndIf
WEnd

 

Edited by Comatose
added codebox

Share this post


Link to post
Share on other sites

The not 1 mode ... load the pic and read the pixel
Run it as mode 1 first to get the picture ...
Then try mode not 1 ... mode 2
I know your part worked so it has to be how I loaded the pic.

(I like the code box thing)

Edited by Comatose

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

×
×
  • Create New...