Jump to content

draw on picture in GUI


Recommended Posts

Hey guys

Even after searching, maybe wrongly, I cant figure out how to draw a circle ontop of my picture embeded in the GUI so it is relative to the GUI's coordinates. SetPixel wont work as if the GUI is moved around, the pixels don't move with it. Is there a way how draw a little circle on on the picture, that stays there if event one and is removed if event two?

Thanks a lot,

Adi

Link to comment
Share on other sites

hm I dont understand what to do with it, sry

To avoid the whole problem i thought i could just load another image ontop of the other one and remove it again like that:

#include <GUIConstants.au3>


$Form1 = GUICreate("Form1", 625, 445, 193, 125)
$Label1 = GUICtrlCreateLabel("Label1", 48, 32, 36, 17)
$Input1 = GUICtrlCreateInput("Input1", 232, 40, 121, 21)
$Pic1 = GUICtrlCreatePic("D:\1.jpg", 56, 96, 548, 212, BitOR($SS_NOTIFY,$WS_GROUP,$WS_CLIPSIBLINGS))

$Button1 = GUICtrlCreateButton("Show", 56, 352, 75, 25, 0)
$Button2 = GUICtrlCreateButton("Hide", 160, 352, 75, 25, 0)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Select 
        Case $nMsg = $Button1
            $Pic2 = GUICtrlCreatePic("D:\2.jpg", 120, 56, 100, 100, BitOR($SS_NOTIFY,$WS_GROUP,$WS_CLIPSIBLINGS))
        Case $nMsg = $Button2
            GUICtrlSetState ( $Pic2, $GUI_HIDE )

    EndSelect
   If $nmsg = $GUI_EVENT_CLOSE Then Exit
WEnd

The only problem is that the image appears behind the other main image, is there a way to make it apear on top of it? Or is there an example somewhere on the drawing approach?

Thanks a lot,

Adrian

Edited by crazycrash
Link to comment
Share on other sites

Hi, I didn't know if you wanted to keep every circle in the image per click or for one circle to move every click.

I opted for the one circle to move every click. I was using autoit v3.2.10.0 on XP sp2 when I wrote this.

Right Click gui to load image.

#include <GUIConstants.au3>
#include <GDIPlus.au3>

Global $pTmp = @ScriptDir & "\pTmp.bmp", $CurImage, $state

$Gui = GUICreate("", 200, 200, -1, -1)
$Context0 = GUICtrlCreateContextMenu()
$Context1 = GUICtrlCreateMenuItem("Load picture", $Context0)
$Pic = GUICtrlCreatePic("", 0, 0, 0, 0)
GUISetState(@SW_SHOW, $Gui)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            If FileExists($pTmp) Then FileDelete($pTmp)
            Exit
        Case $Context1
            Local $FOD = FileOpenDialog("Browse for image", "", "Image (*.bmp;*.jpg)", 3)
            If Not @error Then 
                Local $GWH = GetWH($FOD)
                WinMove($Gui, "", (@DesktopWidth - $GWH[0])/ 2, (@DesktopHeight - $GWH[1])/ 2, $GWH[0], $GWH[1])
                GUICtrlSetImage($Pic, $FOD)
                $CurImage = $FOD
                $state = 1
            EndIf   
        Case $Pic
            If $state Then
                DrawCircle()
            EndIf
    EndSwitch       
WEnd

Func GetWH($iPath)
    Local $hImage1, $aRet[2]
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($iPath)
    $aRet[0] = _GDIPlus_ImageGetWidth($hImage)
    $aRet[1] = _GDIPlus_ImageGetHeight($hImage)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    Return $aRet
EndFunc 

Func DrawCircle()
    Local $hImage1, $hGraphic, $hPen, $GMP
    
    $GMP = _WinAPI_GetMousePos(True, $Gui)
    
    _GDIPlus_Startup()
    
    $hImage = _GDIPlus_ImageLoadFromFile($CurImage)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)   
    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
    
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, DllStructGetData($GMP, "X") - 10, DllStructGetData($GMP, "Y") -10, 20, 20, $hPen)
    
    _GDIPlus_ImageSaveToFile($hImage, $pTmp)
    
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    
    GUICtrlSetImage($Pic, $pTmp)
EndFunc

Cheers

Link to comment
Share on other sites

thats exactly what i was looking for! thanks so much. I have one last problem that i can't figure out. After merging it with my idea of gui, when i click on the top left corner of the image, it is quite exact, but the further down/right i click, the circle apears further away from the cursor, any idea why? Drawing a circle on a specific coordinates works already very well =)

#include <GUIConstants.au3>
#include <GDIPlus.au3>

Global $pTmp = @ScriptDir & "\pTmp.bmp", $CurImage, $state

$Gui = GUICreate("Form1", 800, 600, 100, 100) 
$ImgGuitarFretboard = @ScriptDir & "\GuitarFretBoard.jpg"
$Pic = GUICtrlCreatePic( "", 50, 50, 634, 370)
GUICtrlSetImage($Pic, $ImgGuitarFretboard)
$CurImage = $ImgGuitarFretboard
$Button1 = GUICtrlCreateButton("Circle on F", 100, 500, 75, 25, 0)
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            If FileExists($pTmp) Then FileDelete($pTmp)
            Exit
        Case $Pic
            DrawCircle()
        Case $Button1
            Global $FretboardCoordinates[2]
            $FretboardCoordinates[0] = 82
            $FretboardCoordinates[1] = 222
            MarkFret($FretboardCoordinates)
    EndSwitch
WEnd

Func GetWH($iPath)
    Local $hImage1, $aRet[2]
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($iPath)
    $aRet[0] = _GDIPlus_ImageGetWidth($hImage)
    $aRet[1] = _GDIPlus_ImageGetHeight($hImage)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    Return $aRet
EndFunc 

Func MarkFret($FretboardCoordinates)
    Local $hImage1, $hGraphic, $hPen
   
    _GDIPlus_Startup()
   
    $hImage = _GDIPlus_ImageLoadFromFile($CurImage)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)   
    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
   
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, $FretboardCoordinates[0] - 10, $FretboardCoordinates[1] - 10, 20, 20, $hPen)
   
    _GDIPlus_ImageSaveToFile($hImage, $pTmp)
   
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
   
    GUICtrlSetImage($Pic, $pTmp)
EndFunc

Func DrawCircle()
    Local $hImage1, $hGraphic, $hPen, $GMP
   
    $GMP = _WinAPI_GetMousePos(True, $Gui)
   
    _GDIPlus_Startup()
   
    $hImage = _GDIPlus_ImageLoadFromFile($CurImage)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)   
    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
   
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, DllStructGetData($GMP, "X") - 60, DllStructGetData($GMP, "Y") -60, 20, 20, $hPen)
   
    _GDIPlus_ImageSaveToFile($hImage, $pTmp)
   
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
   
    GUICtrlSetImage($Pic, $pTmp)
EndFunc

cheers

Edited by crazycrash
Link to comment
Share on other sites

You'll have to make sure the GuitarFretBoard.jpg you use is the same dimensions as the Pic control.

Going by your script the size of the GuitarFretBoard.jpg image would need to be width of 634 and a height of 370.

Then replace the DrawCircle() function with this..

Func DrawCircle($CircleSize)
    Local $hImage1, $hGraphic, $hPen, $GMP, $CGP, $pX, $pY
    $GMP = _WinAPI_GetMousePos(True, $Gui)
    $CGP = ControlGetPos($Gui, "", $Pic)
    $pX = DllStructGetData($GMP, "X") - ($CGP[0] + ($CircleSize/2))
    $pY = DllStructGetData($GMP, "Y") - ($CGP[1] + ($CircleSize/2))
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($CurImage)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)   
    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, $pX, $pY, $CircleSize, $CircleSize, $hPen)
    _GDIPlus_ImageSaveToFile($hImage, $pTmp)
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    GUICtrlSetImage($Pic, $pTmp)
EndFunc
The $CircleSize parameter is for what size you want the circle.

Cheers

Link to comment
Share on other sites

Your welcome,

I had a play with it a bit more and did away with the temp image.

This makes it less cpu intensive and it also doesn't matter if the GuitarFretBoard.jpg isn't the same size as the Pic control.

I got the idea from this recent thread in the example section Here.

#include <GUIConstants.au3>
#include <GDIPlus.au3>

Global $Fretboard = @ScriptDir & "\GuitarFretBoard.jpg"
Global $hPic, $hGraphic, $cX, $cY, $cDiam, $hPen

$Gui = GUICreate("Test", 800, 600, 100, 100)
$Pic = GUICtrlCreatePic($Fretboard, 50, 50, 634, 370)
$hPic = GUICtrlGetHandle($Pic)
$Button1 = GUICtrlCreateButton("Circle on F", 100, 500, 75, 25, 0)
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hPic)

GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _GDIPlus_PenDispose($hPen)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_Shutdown()
            Exit
        Case $Pic
            SetCircleCenter(25)
            DrawCircle($cX , $cY, $cDiam, "0x00FF00", 3)
        Case $Button1
            DrawCircle(82 , 222, 25, "0x0000FF", 3)
    EndSwitch
WEnd

; SetCircleCenter($cSize)
; $cSize = Diameter of the circle
Func SetCircleCenter($cSize)
    Local $GMP, $CGP
    $cDiam = $cSize
    $GMP = _WinAPI_GetMousePos(True, $Gui)
    $CGP = ControlGetPos($Gui, "", $Pic)
    $cX = DllStructGetData($GMP, "X") - ($CGP[0] + ($cDiam/2))
    $cY = DllStructGetData($GMP, "Y") - ($CGP[1] + ($cDiam/2))  
EndFunc

; DrawCircle($posX, $posY, $cSize, $pColor, $pThick)
; $posX = X position of the circle
; $posX = Y position of the circle
; $cSize = Diameter of the circle
; $pColor = RGB color of the line that draws the circle
; $pThick = Thicknes of the line that draws the circle

Func DrawCircle($posX, $posY, $cSize, $pColor, $pThick)
    If $hPen <> 0 Then _GDIPlus_PenDispose($hPen)
    $hPen = _GDIPlus_PenCreate(StringReplace($pColor, "0x", "0xFF"), $pThick)
    $cDiam = $cSize
    $cX = $posX
    $cY = $posY
    _WinAPI_InvalidateRect($hPic)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $cX, $cY, $cDiam, $cDiam, $hPen)
EndFunc

Func MY_WM_PAINT($hWnd, $Msg)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_UPDATENOW)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $cX, $cY, $cDiam, $cDiam, $hPen)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_VALIDATE)
    Return $GUI_RUNDEFMSG
EndFunc

Cheers

Link to comment
Share on other sites

cool that is even better, much faster, awsome =)

hopefully the last question i have on this topic, is there a way how to have the circle drawn like in the example, and in adition to that, 20 pixels to the left of the circle the picture E.g. "note.png" added to it? (using the same method of editing the original picture?) Thanks!

Edited by crazycrash
Link to comment
Share on other sites

Hey

Uploaded 2 example pictures:

post-18937-1209655627_thumb.jpg

I will draw the fretboard in photoshop in the end, but that should do for the time being =)

damn just had so many ideas of what i could do if i could use png files (partially transparent like the one i uploaded) and blend it onto the main picture, i could make the whole thing so arty! (currently drawing a fretboard using photoshop =)) praying you find a way =)

Cheers,

Adrian

Edited by crazycrash
Link to comment
Share on other sites

Maybe instead of using a png you could just draw the note beside the circle using GDIPlus. (Excuse my notes as they are just an example of maybe how to accomplish what your after. I really have no clue to guitar notes and cords and stuff.)

Global $Fretboard = @ScriptDir & "\FretBoard.bmp", $Note[72][2]
Global $hPic, $hGraphic, $cX, $cY, $cDiam, $hPen
Global $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo[3], $Text
Global $Notes[73][2] 
Global $Ord = StringSplit("60,75,85,F|150,75,80,|236,74,75,G|317,74,70,|394,73,68,A|467,72,64,|" & _
                            "536,72,60,B|602,71,55,C|663,71,54,|722,70,50,D|777,70,46,|829,69,44,E|" & _
                            "60,96,85,C|150,96,80,|236,95,75,D|317,95,70,|394,95,68,E|467,95,64,F|" & _
                            "536,95,60,|602,94,55,G|663,94,54,|722,94,50,A|777,94,46,|829,94,44,B|" & _
                            "60,117,85,|150,117,80,A|236,118,75,|317,118,70,B|394,118,68,C|467,118,64,|" & _
                            "536,118,60,D|602,118,55,|663,118,54,E|722,118,50,F|777,118,46,|829,118,44,G|" & _
                            "60,139,85,|150,139,80,E|236,140,75,F|317,140,70,|394,141,68,G|467,141,64,|" & _
                            "536,142,60,A|602,142,55,|663,143,54,B|722,143,50,C|777,143,46,|829,143,44,D|" & _
                            "60,159,85,|150,160,80,B|236,161,75,C|317,162,70,|394,163,68,D|467,164,64,|" & _
                            "536,164,60,E|602,165,55,F|663,165,54,|722,166,50,G|777,166,46,|829,167,44,A|" & _
                            "60,180,85,F|150,182,80,|236,183,75,G|317,184,70,|394,185,68,A|467,186,64,|" & _
                            "536,187,60,B|602,188,55,C|663,189,54,|722,190,50,D|777,191,46,|829,192,44,E", "|")
$Notes[0][0] = $Ord[0]

$Gui = GUICreate("Test", 900, 300, 100, 100)
$Pic = GUICtrlCreatePic($Fretboard, 20, 50, 859, 162)
GUICtrlSetCursor(-1, 3)
$hPic = GUICtrlGetHandle($Pic)

For $i = 1 To $Notes[0][0]
    Local $SO = StringSplit($Ord[$i], ",")
    $Notes[$i][0] = GUICtrlCreateLabel("", $SO[1], $SO[2], $SO[3], 4, $WS_CLIPSIBLINGS)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $Notes[$i][1] = $SO[4]
Next
$Ord = 0
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hPic)

GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            DisposeText()
            _GDIPlus_PenDispose($hPen)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_Shutdown()
            Exit
        Case $Pic
            Local $GGCI = GUIGetCursorInfo($Gui)
            Local $CurNote = FindNote($GGCI[4])
            If $GGCI[4] = $CurNote[0] Then 
                SetCircleCenter(16)
                DrawCircle($cX, $cY, $cDiam, "0x00FF00", 2)
                DrawText($cX, $cY, $CurNote[1], "Arial", 24, 1, "0xFFFF00")
            Else
                SetCircleCenter(16)
                DrawCircle($cX, $cY, $cDiam, "0xFF0000", 2)
            EndIf
    EndSwitch
WEnd

Func FindNote($cID)
    Local $aRet[2]
    For $i = 1 To $Notes[0][0]
        If $Notes[$i][0] = $cID Then 
            $aRet[0] = $Notes[$i][0]
            $aRet[1] = $Notes[$i][1]
            Return $aRet
        EndIf
    Next
    $aRet[0] = "N"
    Return $aRet
EndFunc

; SetCircleCenter($cSize)
; $cSize = Diameter of the circle
Func SetCircleCenter($cSize)
    Local $GMP, $CGP
    $cDiam = $cSize
    $GMP = _WinAPI_GetMousePos(True, $Gui)
    $CGP = ControlGetPos($Gui, "", $Pic)
    $cX = DllStructGetData($GMP, "X") - ($CGP[0] + ($cDiam/2))
    $cY = DllStructGetData($GMP, "Y") - ($CGP[1] + ($cDiam/2))  
EndFunc

; DrawCircle($posX, $posY, $cSize, $pColor, $pThick)
; $posX = X position of the circle
; $posX = Y position of the circle
; $cSize = Diameter of the circle
; $pColor = RGB color of the line that draws the circle
; $pThick = Thicknes of the line that draws the circle
Func DrawCircle($posX, $posY, $cSize, $pColor, $pThick)
    If $hPen <> 0 Then _GDIPlus_PenDispose($hPen)
    $hPen = _GDIPlus_PenCreate(StringReplace($pColor, "0x", "0xFF"), $pThick)
    $cDiam = $cSize
    $cX = $posX
    $cY = $posY
    _WinAPI_InvalidateRect($hPic)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $cX, $cY, $cDiam, $cDiam, $hPen)
EndFunc

; DrawText($fX, $fY, $fText, $fName, $fSize , $fStyle, $fColor)
; $fX = X position of the text
; $fY = Y position of the text
; $fText = String of text to draw
; $fName = Font to use
; $fSize =  Size of font
; $fStyle = (0 = None, 1 = Bold, 2 = Italic, 4 = Underline, 8 = Strikethrough)
; $fColor = RGB color of the text
Func DrawText($fX, $fY, $fText, $fName = "Arial", $fSize = 12, $fStyle = 0, $fColor = "0x000000")
    If $hFont <> 0 Then DisposeText()
    $Text = $fText
    $hBrush = _GDIPlus_BrushCreateSolid (StringReplace($fColor, "0x", "0xFF"))
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ($fName)
    $hFont = _GDIPlus_FontCreate ($hFamily, $fSize, $fStyle)
    $tLayout = _GDIPlus_RectFCreate ($fX, $fY, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $Text, $hFont, $tLayout, $hFormat)
    DllStructSetData($aInfo[0], "X", $fX - DllStructGetData($aInfo[0], "Width"))
    DllStructSetData($aInfo[0], "Y", $fY - ((DllStructGetData($aInfo[0], "Height") - $cDiam)/2))
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $Text, $hFont, $aInfo[0], $hFormat, $hBrush)
EndFunc

Func DisposeText()
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
EndFunc

Func MY_WM_PAINT($hWnd, $Msg)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_UPDATENOW)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $cX, $cY, $cDiam, $cDiam, $hPen)
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $Text, $hFont, $aInfo[0], $hFormat, $hBrush)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_VALIDATE)
    Return $GUI_RUNDEFMSG
EndFunc
Here's the fretboard.jpg that you'll need to use with the above example.

Cheers

Edit: and yes you can use a png and add it to the original image, but if all your notes are just a letter with an under score then using gdiplus to draw the letter with an under score would save having a few dozen png files to load accompanying your script.

Edited by smashly
Link to comment
Share on other sites

This is so brilliant, now I know how to make the script recognise which note it is in such a simple way =D, I have been fiddling around with this for a couple of days haha lol

If its still possible with having a png image added ontop of a specific location, can always be the same location, do you mind giving me an example? (does it really work with being transparent?)

I could do the whole thing really arty, everything blending and stuff, dont mind if its a bit slower =)

Cheers,

Adrian

Link to comment
Share on other sites

Here ya go.

This is using the note.png you posted earlier.

I haven't gone to any effort on this addition (barely allowed for positioning), it's just an example to load the png with trans using gdiplus

#include <GUIConstants.au3>
#include <GDIPlus.au3>

Global $Fretboard = @ScriptDir & "\fretboard.jpg", $PNG = @ScriptDir & "\note.png", $Note[72][2]
Global $hPic, $hGraphic, $cX, $cY, $cDiam, $hPen
Global $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo[3], $Text
Global $hImagePNG ; Added
Global $Notes[73][2] 
Global $Ord = StringSplit("60,75,85,F|150,75,80,|236,74,75,G|317,74,70,|394,73,68,A|467,72,64,|" & _
                            "536,72,60,B|602,71,55,C|663,71,54,|722,70,50,D|777,70,46,|829,69,44,E|" & _
                            "60,96,85,C|150,96,80,|236,95,75,D|317,95,70,|394,95,68,E|467,95,64,F|" & _
                            "536,95,60,|602,94,55,G|663,94,54,|722,94,50,A|777,94,46,|829,94,44,B|" & _
                            "60,117,85,|150,117,80,A|236,118,75,|317,118,70,B|394,118,68,C|467,118,64,|" & _
                            "536,118,60,D|602,118,55,|663,118,54,E|722,118,50,F|777,118,46,|829,118,44,G|" & _
                            "60,139,85,|150,139,80,E|236,140,75,F|317,140,70,|394,141,68,G|467,141,64,|" & _
                            "536,142,60,A|602,142,55,|663,143,54,B|722,143,50,C|777,143,46,|829,143,44,D|" & _
                            "60,159,85,|150,160,80,B|236,161,75,C|317,162,70,|394,163,68,D|467,164,64,|" & _
                            "536,164,60,E|602,165,55,F|663,165,54,|722,166,50,G|777,166,46,|829,167,44,A|" & _
                            "60,180,85,F|150,182,80,|236,183,75,G|317,184,70,|394,185,68,A|467,186,64,|" & _
                            "536,187,60,B|602,188,55,C|663,189,54,|722,190,50,D|777,191,46,|829,192,44,E", "|")
$Notes[0][0] = $Ord[0]

$Gui = GUICreate("Test", 900, 300, 100, 100)
$Pic = GUICtrlCreatePic($Fretboard, 20, 50, 859, 162)
GUICtrlSetCursor(-1, 3)
$hPic = GUICtrlGetHandle($Pic)

For $i = 1 To $Notes[0][0]
    Local $SO = StringSplit($Ord[$i], ",")
    $Notes[$i][0] = GUICtrlCreateLabel("", $SO[1], $SO[2], $SO[3], 4, $WS_CLIPSIBLINGS)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $Notes[$i][1] = $SO[4]
Next
$Ord = 0
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hPic)

GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            DisposeText()
            _GDIPlus_ImageDispose($hImagePNG)
            _GDIPlus_PenDispose($hPen)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_Shutdown()
            Exit
        Case $Pic
            Local $GGCI = GUIGetCursorInfo($Gui)
            Local $CurNote = FindNote($GGCI[4])
            If $GGCI[4] = $CurNote[0] Then 
                SetCircleCenter(16)
                DrawCircle($cX, $cY, $cDiam, "0x00FF00", 2)
                DrawPNG($PNG, $cX, $cY, 100, 141); Added
                DrawText($cX, $cY, $CurNote[1], "Arial", 24, 1, "0xFFFF00")
            Else
                SetCircleCenter(16)
                DrawCircle($cX, $cY, $cDiam, "0xFF0000", 2)
            EndIf
    EndSwitch
WEnd

Func DrawPNG($pPath, $pX, $pY, $pW, $pH) ; added
    If Not FileExists($pPath) Then Return
    $hImagePNG = _GDIPlus_ImageLoadFromFile($pPath)
    _GDIPLus_GraphicsDrawImageRectI($hGraphic, $hImagePNG, $pX + $cDiam, $pY, $pW, $pH)
EndFunc 

Func _GDIPLus_GraphicsDrawImageRectI($hGraphics, $hImage, $iX, $iY, $iW, $iH) ; added
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectI", "hwnd", $hGraphics, "hwnd", $hImage, _
                                                        "int", $iX, "int", $iY, "int", $iW, "int", $iH)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

Func FindNote($cID)
    Local $aRet[2]
    For $i = 1 To $Notes[0][0]
        If $Notes[$i][0] = $cID Then 
            $aRet[0] = $Notes[$i][0]
            $aRet[1] = $Notes[$i][1]
            Return $aRet
        EndIf
    Next
    $aRet[0] = "N"
    Return $aRet
EndFunc

; SetCircleCenter($cSize)
; $cSize = Diameter of the circle
Func SetCircleCenter($cSize)
    Local $GMP, $CGP
    $cDiam = $cSize
    $GMP = _WinAPI_GetMousePos(True, $Gui)
    $CGP = ControlGetPos($Gui, "", $Pic)
    $cX = DllStructGetData($GMP, "X") - ($CGP[0] + ($cDiam/2))
    $cY = DllStructGetData($GMP, "Y") - ($CGP[1] + ($cDiam/2))  
EndFunc

; DrawCircle($posX, $posY, $cSize, $pColor, $pThick)
; $posX = X position of the circle
; $posX = Y position of the circle
; $cSize = Diameter of the circle
; $pColor = RGB color of the line that draws the circle
; $pThick = Thicknes of the line that draws the circle
Func DrawCircle($posX, $posY, $cSize, $pColor, $pThick)
    If $hPen <> 0 Then _GDIPlus_PenDispose($hPen)
    $hPen = _GDIPlus_PenCreate(StringReplace($pColor, "0x", "0xFF"), $pThick)
    $cDiam = $cSize
    $cX = $posX
    $cY = $posY
    _WinAPI_InvalidateRect($hPic)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $cX, $cY, $cDiam, $cDiam, $hPen)
EndFunc

; DrawText($fX, $fY, $fText, $fName, $fSize , $fStyle, $fColor)
; $fX = X position of the text
; $fY = Y position of the text
; $fText = String of text to draw
; $fName = Font to use
; $fSize =  Size of font
; $fStyle = (0 = None, 1 = Bold, 2 = Italic, 4 = Underline, 8 = Strikethrough)
; $fColor = RGB color of the text
Func DrawText($fX, $fY, $fText, $fName = "Arial", $fSize = 12, $fStyle = 0, $fColor = "0x000000")
    If $hFont <> 0 Then DisposeText()
    $Text = $fText
    $hBrush = _GDIPlus_BrushCreateSolid (StringReplace($fColor, "0x", "0xFF"))
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ($fName)
    $hFont = _GDIPlus_FontCreate ($hFamily, $fSize, $fStyle)
    $tLayout = _GDIPlus_RectFCreate ($fX, $fY, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $Text, $hFont, $tLayout, $hFormat)
    DllStructSetData($aInfo[0], "X", $fX - DllStructGetData($aInfo[0], "Width"))
    DllStructSetData($aInfo[0], "Y", $fY - ((DllStructGetData($aInfo[0], "Height") - $cDiam)/2))
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $Text, $hFont, $aInfo[0], $hFormat, $hBrush)
EndFunc

Func DisposeText()
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
EndFunc

Func MY_WM_PAINT($hWnd, $Msg)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_UPDATENOW)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $cX, $cY, $cDiam, $cDiam, $hPen)
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $Text, $hFont, $aInfo[0], $hFormat, $hBrush)
    _GDIPLus_GraphicsDrawImageRectI($hGraphic, $hImagePNG, $cX + $cDiam, $cY, 100, 141) ; Added
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_VALIDATE)
    Return $GUI_RUNDEFMSG
EndFunc

Cheers

Edited by smashly
Link to comment
Share on other sites

  • 2 weeks later...

Heyhey

This is the fretboard like im using it in my app (letters are just for reference so I dont forget lol). I plan to have it in its original size but maybe also had the function to resize it if the screenresolution of the user too low for that size...

Thanks!

Adrian

post-18937-1210941818_thumb.jpg

Edited by crazycrash
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...