Jump to content

Looking for a way to draw an outline around my GDI+ Shape


Go to solution Solved by Sidley,

Recommended Posts

I read up on PathAddArc - I thought I could work it out. I can do 4 shapes but my shape is 9 ellipses, and I just want to be able to draw a border around it.

I set out just creating the ellipses I'd need to define a path, turns out its not as simple as I thought.

Then I thought if i could combine the shapes I could draw a border around it.

I couldn't find anything about combining shapes (although I suspect it can be done) and my attempt at converting the ellipses to a path brought several issues to light - my straight forward math approach didn't give me results I could make sense of - and I didn't factor in the width of the line so where it touches the box its flat / clipped. 

I'm looking for suggestions for best way to get from here to there.

Please

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


$main = GUICreate(" ", 300, 300, -1, -1)
    GUICtrlCreatePic("", 15, 15, 256, 256)
        CreateBG(-1, 250, 0XFFFF9000)
        GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState(@SW_SHOW)


;Main Process Loop ======================================================================================
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

;== Graphic Functions ======================================

Func CreateBG($control, $gw, $color)
_GDIPlus_Startup()

    Local $ghandle = _GDIPlus_GraphicsCreateFromHWND($main)
    Local $hImage = _GDIPlus_BitmapCreateFromGraphics($gw, $gw, $ghandle)
    Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
        _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 5)
    Local $hBrush = _GDIPlus_BrushCreateSolid($color)
;~  Local $hPath = _GDIPlus_PathCreate()
;~      _GDIPlus_PathAddArc($hPath, 0, ($gw/8), ($gw/4), ($gw*0.75), 105, 160)
;~      _GDIPlus_PathAddArc($hPath,($gw/18), ($gw/18), ($gw*0.375), ($gw*0.375), 265, 50)
;~      _GDIPlus_PathAddArc($hPath, ($gw/8), 0, ($gw*0.75), ($gw/4), 185, 130)
;~      _GDIPlus_PathAddArc($hPath, ($gw-($gw/4)), ($gw/8), ($gw/4), ($gw*0.75), 270, 180 )
;~      _GDIPlus_PathAddArc($hPath, ($gw/8), ($gw-($gw/4)), ($gw*0.75), ($gw/4), 0, 180)

        _GDIPlus_GraphicsFillEllipse($hGraphic, 0, ($gw/8), ($gw/4), ($gw*0.75), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw/8), 0, ($gw*0.75), ($gw/4), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw-($gw/4)), ($gw/8), ($gw/4), ($gw*0.75), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw/8), ($gw-($gw/4)), ($gw*0.75), ($gw/4), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw/18), ($gw/18), ($gw*0.375), ($gw*0.375), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw-($gw*0.43)), ($gw/18), ($gw*0.375), ($gw*0.375), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw-($gw*0.43)), ($gw-($gw*0.43)), ($gw*0.375), ($gw*0.375), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw/18), ($gw-($gw*0.43)), ($gw*0.375), ($gw*0.375), $hBrush)
        _GDIPlus_GraphicsFillEllipse($hGraphic, ($gw/8), ($gw/8), ($gw*.75), ($gw*.75), $hBrush)


;~     _GDIPlus_PathCloseFigure($hPath)
;~     _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush)
;~ $hPen = _GDIPlus_PenCreate(0XFFB0B0B0, 3)
;~ _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen)

    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($control, $STM_SETIMAGE, $IMAGE_BITMAP, $hbitmap))

    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_BrushDispose($hBrush)
;~  _GDIPlus_PenDispose($hPen)
;~  _GDIPlus_PathDispose($hPath)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
Endfunc

 

Link to post
Share on other sites
  • Solution

Give this a go.

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


$main = GUICreate(" ", 300, 300, -1, -1)
    GUICtrlCreatePic("", 15, 15, 256, 256)
        CreateBG(-1, 250, 0XFFFF9000)
        GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState(@SW_SHOW)


;Main Process Loop ======================================================================================
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

;== Graphic Functions ======================================

Func CreateBG($control, $gw, $color)
    _GDIPlus_Startup()

    Local $ghandle = _GDIPlus_GraphicsCreateFromHWND($main)
    Local $hImage = _GDIPlus_BitmapCreateFromGraphics($gw, $gw, $ghandle)
    Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
    Local $hBrush = _GDIPlus_BrushCreateSolid($color)
    Local $hBrush2 = _GDIPlus_BrushCreateSolid(0xFFFF0000)
    Local $hPath = _GDIPlus_PathCreate()
    Local $nOffset = 4
    $gw -= $nOffset*2   ;Offset to allow for scaling
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 5)

    ;Path used instead of Graphic
    _GDIPlus_PathAddEllipse($hPath, 0+$nOffset, ($gw/8)+$nOffset, ($gw/4), ($gw*0.75))
    _GDIPlus_PathAddEllipse($hPath, ($gw/8)+$nOffset, 0+$nOffset, ($gw*0.75), ($gw/4))
    _GDIPlus_PathAddEllipse($hPath, ($gw-($gw/4))+$nOffset, ($gw/8)+$nOffset, ($gw/4), ($gw*0.75))
    _GDIPlus_PathAddEllipse($hPath, ($gw/8)+$nOffset, ($gw-($gw/4))+$nOffset, ($gw*0.75), ($gw/4))
    _GDIPlus_PathAddEllipse($hPath, ($gw/18)+$nOffset, ($gw/18)+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw-($gw*0.43))+$nOffset, ($gw/18)+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw-($gw*0.43))+$nOffset, ($gw-($gw*0.43))+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw/18)+$nOffset, ($gw-($gw*0.43))+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw/8)+$nOffset, ($gw/8)+$nOffset, ($gw*.75), ($gw*.75))
    _GDIPlus_PathCloseFigure($hPath)

    _GDIPlus_PathSetFillMode($hPath, 1) ;Set fill mode to union

    Local $hPath2 = _GDIPlus_PathClone($hPath)  ;Clone the first path
    Local $hPen_Widen = _GDIPlus_PenCreate(0, $nOffset)
    _GDIPlus_PenSetLineJoin($hPen_Widen, $GDIP_PENSETLINEJOIN_ROUND)
    _GDIPlus_PathWiden($hPath2, $hPen_Widen)    ;Widen second path
    _GDIPlus_GraphicsFillPath($hGraphic, $hPath2, $hBrush2) ; IMPORTANT Fill second path to graphic first
    _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush)   ; Then first path on top

    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($control, $STM_SETIMAGE, $IMAGE_BITMAP, $hbitmap))

    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BrushDispose($hBrush2)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PathDispose($hPath2)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
Endfunc

 

Link to post
Share on other sites

That's brilliant!   Thank you!

I have to admit if you hadn't called it "Union" mode this wouldn't make sense

Quote

Path fill mode:
    0 - The areas are filled according to the even-odd parity rule
    1 - The areas are filled according to the nonzero winding rule

I don't know these rules but I'll look them up

 

Thx again

 

Link to post
Share on other sites

I couldn't leave it alone 😀 There was a bug that caused different offsets to change the overall size of the image, this fixes that.

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


$main = GUICreate(" ", 300, 300, -1, -1)
    GUICtrlCreatePic("", 15, 15, 256, 256)
        CreateBG(-1, 250, 0XFFFF9000)
        GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState(@SW_SHOW)


;Main Process Loop ======================================================================================
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

;== Graphic Functions ======================================

Func CreateBG($control, $gw, $color)
    _GDIPlus_Startup()

    Local $ghandle = _GDIPlus_GraphicsCreateFromHWND($main)
    Local $hImage = _GDIPlus_BitmapCreateFromGraphics($gw, $gw, $ghandle)
    Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
    Local $hBrush = _GDIPlus_BrushCreateSolid($color)
    Local $hBrush2 = _GDIPlus_BrushCreateSolid(0xFF000000)
    Local $hPath = _GDIPlus_PathCreate()
    Local $nBorderSize = 100
    $gw -= $nBorderSize;    ;Offset to allow for scaling
    Local $nOffset = $nBorderSize/2
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 5)

    ;Path used instead of Graphic
    _GDIPlus_PathAddEllipse($hPath, 0+$nOffset, ($gw/8)+$nOffset, ($gw/4), ($gw*0.75))
    _GDIPlus_PathAddEllipse($hPath, ($gw/8)+$nOffset, 0+$nOffset, ($gw*0.75), ($gw/4))
    _GDIPlus_PathAddEllipse($hPath, ($gw-($gw/4))+$nOffset, ($gw/8)+$nOffset, ($gw/4), ($gw*0.75))
    _GDIPlus_PathAddEllipse($hPath, ($gw/8)+$nOffset, ($gw-($gw/4))+$nOffset, ($gw*0.75), ($gw/4))
    _GDIPlus_PathAddEllipse($hPath, ($gw/18)+$nOffset, ($gw/18)+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw-($gw*0.43))+$nOffset, ($gw/18)+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw-($gw*0.43))+$nOffset, ($gw-($gw*0.43))+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw/18)+$nOffset, ($gw-($gw*0.43))+$nOffset, ($gw*0.375), ($gw*0.375))
    _GDIPlus_PathAddEllipse($hPath, ($gw/8)+$nOffset, ($gw/8)+$nOffset, ($gw*.75), ($gw*.75))
    _GDIPlus_PathCloseFigure($hPath)

    _GDIPlus_PathSetFillMode($hPath, 1) ;Set fill mode to union

    Local $hPath2 = _GDIPlus_PathClone($hPath)  ;Clone the first path
    Local $hPen_Widen = _GDIPlus_PenCreate(0, $nBorderSize)
    _GDIPlus_PenSetLineJoin($hPen_Widen, $GDIP_PENSETLINEJOIN_ROUND)
    _GDIPlus_PathWiden($hPath2, $hPen_Widen)    ;Widen second path
    _GDIPlus_GraphicsFillPath($hGraphic, $hPath2, $hBrush2) ; IMPORTANT Fill second path to graphic first
    _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush)   ; Then first path on top

    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($control, $STM_SETIMAGE, $IMAGE_BITMAP, $hbitmap))

    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BrushDispose($hBrush2)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PathDispose($hPath2)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
Endfunc

 

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...