GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
Go Back  Xtreme Visual Basic Talk > > > GDI+ Region hit test returns Object Busy


Reply
 
Thread Tools Display Modes
  #1  
Old 08-15-2012, 04:26 PM
starrynighter starrynighter is offline
Newcomer
 
Join Date: Jul 2012
Location: Auckland, New Zealand
Posts: 3
Default GDI+ Region hit test returns Object Busy


In Access 2003 I have successfully used GDI+ DLL functions to draw anti-aliased Bezier curve onto an Access 2003 Image using the Lebans GDI32-based pictureBox. (see here )

I have tested the status return value and each call returns OK=0.

I have created a GDI+ region based on the curve (but with a slightly wider pen).
I have drawn the outline of this region and also brush-filled the region to verify the region as much as possible and it seems to be good.
(see drawBezierCurve() and computeRegion())


However when I try to hit test with the function GdipIsVisibleRegionPoint(), the return value is always 4=OBJECTBUSY.
(refer Public Function HitTest())


I get the same return value when calling GdipGetRegionScansCount() as a precursor to fetching the rectangles myself to do the hit test manually.

I have tried disposing any and all of the underlying GDI+ objects, and hunted around for other possible anomalies but to no avail.

I cannot see that I would be running more than one thread.

Can anyone shed light on this?

Here is the class:
Code:
Option Compare Database
Option Explicit

Const pModuleName = "ConnectorBezier."

' synchronises all parts of a Bezier connector Curve


Private pInitDone As Boolean


Private pPathRegion As Long
Private pPenPathRegion As Long
Private pPenRegionOutline As Long
Private pHitTestRegion As Long

Private pBrush As Long


' gdip variables ----------------------------------------------
Private gpToken As Long
Private gpStartupInput As GdiplusStartupInput

Private gdipStatus As gpStatus

Private pImageColour As Long

Private pGraphics As Long
Private pPenBCT As Long
Private pPenBezier As Long
Private pPenBezierThickness As Long
Private pPathBezier As Long
Private pPathBCT As Long




' The Form controls for the {src,dst} X {node,BCP}
Private WithEvents ctlSrcNode As CommandButton
Private WithEvents ctlDstNode As CommandButton
Private WithEvents ctlSrcBCP As Rectangle
Private WithEvents ctlDstBCP As Rectangle

Private testParentForm As Access.Form

Private picbox As clsPictureBox

Private BCPSrc As BezierControlPointHandler
Private BCPDst As BezierControlPointHandler

Private Sub Class_Initialize()
On Error GoTo ErrorLabel

Exit Sub

ErrorLabel:
reportErr err, pModuleName + "Class_Initialize"

End Sub

Private Sub Class_Terminate()
On Error GoTo ErrorLabel

Exit Sub

ErrorLabel:
reportErr err, pModuleName + "Class_Terminate"

End Sub

Public Function Init( _
  parmPicBox As clsPictureBox _
  ) _
                                           As Boolean
 ' parmLsLink As LsLink,

On Error GoTo ErrorLabel

Set picbox = parmPicBox


' from invoking class:---------------
Set testParentForm = Form_frmBezierMGBwithClass

Set ctlSrcNode = testParentForm.BtnSrc
Set ctlDstNode = testParentForm.BtnDst
Set ctlSrcBCP = testParentForm.BtnSrcControl
Set ctlDstBCP = testParentForm.BtnDstControl
'                       -----------------

' gdi+ initialization.---------------------------
'^^ to be moved into greater program
gpStartupInput.GdiplusVersion = 1
gdipStatus = GdiplusStartup(gpToken, gpStartupInput, 0)

gdipStatus = GdipCreateFromHDC(picbox.hdc, pGraphics)

gdipStatus = GdipSetSmoothingMode( _
  pGraphics, SmoothingModeHighQuality)

pImageColour = Colors.White '''''And &HFFFFFF
gdipStatus = GdipGraphicsClear(pGraphics, pImageColour)
picbox.DIBtoPictureData

gdipStatus = GdipCreatePen1(Colors.Green, 2, UnitPixel, pPenBCT)
gdipStatus = GdipSetPenDashStyle(pPenBCT, DashStyleDash)

pPenBezierThickness = 15

gdipStatus = _
  GdipCreatePen1(Colors.DarkBlue, _
                        pPenBezierThickness, UnitPixel, pPenBezier)
gdipStatus = GdipSetPenEndCap(pPenBezier, LineCapArrowAnchor)
gdipStatus = GdipSetPenStartCap(pPenBezier, LineCapArrowAnchor)

'-----------------------------------------------

Set BCPSrc = New BezierControlPointHandler
Set BCPDst = New BezierControlPointHandler

BCPSrc.Init Me, ctlSrcNode, ctlSrcBCP
BCPDst.Init Me, ctlDstNode, ctlDstBCP

drawBezierCurve

' :-) let the fun begin...

pInitDone = True
Init = True
Exit Function

ErrorLabel:
Init = False
reportErr err, pModuleName + "init"

End Function


Public Sub drawBezierCurve()
On Error GoTo ErrorLabel

gdipStatus = GdipGraphicsClear(pGraphics, pImageColour)

drawBCT BCPSrc
drawBCT BCPDst

gdipStatus = GdipCreatePath(FillModeAlternate, pPathBezier)

gdipStatus = GdipAddPathBezier(pPathBezier, _
  BCPSrc.EndPosition.X / 15, BCPSrc.EndPosition.Y / 15, _
  BCPSrc.BCPPosition.X / 15, BCPSrc.BCPPosition.Y / 15, _
  BCPDst.BCPPosition.X / 15, BCPDst.BCPPosition.Y / 15, _
  BCPDst.EndPosition.X / 15, BCPDst.EndPosition.Y / 15 _
  )
  
gdipStatus = GdipDrawPath(pGraphics, pPenBezier, pPathBezier)

computeRegion

picbox.DIBtoPictureData

Exit Sub

ErrorLabel:
reportErr err, pModuleName + "drawBezierCurve"

End Sub


Private Sub drawBCT(BCP As BezierControlPointHandler)

On Error GoTo ErrorLabel

gdipStatus = GdipCreatePath(FillModeAlternate, pPathBCT)

gdipStatus = GdipAddPathLine(pPathBCT, _
  BCP.EndPosition.X / 15, BCP.EndPosition.Y / 15, _
  BCP.BCPPosition.X / 15, BCP.BCPPosition.Y / 15 _
  )
    
gdipStatus = GdipDrawPath(pGraphics, pPenBCT, pPathBCT)

Exit Sub

ErrorLabel:
reportErr err, pModuleName + "drawSrcBCPLine"

End Sub

Public Sub computeRegion()
' form a region for this curve path by widening with a no-frills pen.
On Error GoTo ErrorLabel

'no-frills pen:
gdipStatus = _
  GdipCreatePen1(Colors.Green, pPenBezierThickness + 4, _
    UnitPixel, pPenPathRegion)

'' region outline pen:
gdipStatus = _
  GdipCreatePen1(Colors.DarkGreen, 1, UnitPixel, pPenRegionOutline)


'gdipStatus = _
'  GdipClonePath(pPathBezier, pPathRegion)

' create again instead of Clone:
gdipStatus = GdipCreatePath(FillModeAlternate, pPathRegion)

gdipStatus = GdipAddPathBezier(pPathRegion, _
  BCPSrc.EndPosition.X / 15, BCPSrc.EndPosition.Y / 15, _
  BCPSrc.BCPPosition.X / 15, BCPSrc.BCPPosition.Y / 15, _
  BCPDst.BCPPosition.X / 15, BCPDst.BCPPosition.Y / 15, _
  BCPDst.EndPosition.X / 15, BCPDst.EndPosition.Y / 15 _
  )
  

gdipStatus = _
  GdipWidenPath(pPathRegion, pPenPathRegion, 0, 1#)

gdipStatus = _
  GdipCreateRegionPath(pPathRegion, pHitTestRegion)
  '^ becomes:
  'Public Sub New(ByVal path As System.Drawing.Drawing2D.GraphicsPath)
'    Member of System.Drawing.Region

gdipStatus = _
  GdipDrawPath(pGraphics, pPenRegionOutline, pPathRegion)


'''TESTseekPoints
''' hStatus = GdipFillRegion(pGraphics, pSolidBrush, pPathRegion)
'^ try release  the path to free the region:
gdipStatus = _
  GdipDeletePath(pPathRegion)

gdipStatus = _
  GdipDeletePen(pPenPathRegion)


'' fill region with brush:
'gdipStatus = _
'  GdipCreateSolidFill(Colors.Beige, pBrush)
'
'gdipStatus = _
'  GdipFillRegion(pGraphics, pBrush, pHitTestRegion)

''gdipStatus = _
''  GdipDeleteGraphics(pGraphics)


Exit Sub

ErrorLabel:
reportErr err, pModuleName + "HitTest"
End Sub


Public Function HitTest(ByVal X As Single, ByVal Y As Single) _
                                       As Boolean
' Not using GeomPoint since this usually called from mouse event.
On Error GoTo ErrorLabel
Dim result As Long

gdipStatus = GdipIsVisibleRegionPoint( _
  pPathRegion, X, Y, pGraphics, result)
numberedDebug "gdipStatus=" + CStr(gdipStatus)
HitTest = result


Dim RectCount As Long
gdipStatus = GdipGetRegionScansCount(pPathRegion, RectCount, 0)
numberedDebug _
  "GdipGetRegionScansCount - gdipStatus=" + CStr(gdipStatus) _
  + "  RectCount=" + CStr(RectCount)



Exit Function

ErrorLabel:
reportErr err, pModuleName + "HitTest"
End Function

Public Property Get PathRegion() As Long
PathRegion = pPathRegion
End Property

Last edited by Flyguy; 08-16-2012 at 03:12 AM.
Reply With Quote
  #2  
Old 08-16-2012, 04:59 AM
starrynighter starrynighter is offline
Newcomer
 
Join Date: Jul 2012
Location: Auckland, New Zealand
Posts: 3
Default

Solved: I had the wrong 1st argument to GdipIsVisibleRegionPoint() in HitTest().

I will roll the necessary gdip() functions into dotNET-like classes to eliminate this and other errors in the future (or find where someone else may have done so).
Reply With Quote
Reply

Tags
gdi32, gdiplus, vba access 2003


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
 
GDI+ Region hit test returns Object Busy
GDI+ Region hit test returns Object Busy
 
-->