Is there a sane way to implement GdiplusStartup/GdiplusShutdown sequence w/o risking stepping on our toes?
As far as I can tell if developer A and developer B separately implement reference counting on GDI+ usage they still can blow thing up by calling [tt]GdiplusShutdown[/t] out of order like this:
token1 = GdiplusStartup
.. work 1
token2 = GdiplusStartup
... work 2
GdiplusShutdown token1
... work 3
... this completely fails as GdiplusShutdown has done the damage
GdiplusShutdown token2
... mosty some access violation will be reached before this point
So is there something that I'm unable to find in the docs? How are we suppoed to initialize GDI+ in a compatible way, w/o support from the VB runtime?
My proposal for all fellow devs is to completely abandon shutting GDI+ down for any of our processes and to use a one-time initializer -- a simple code like this:
thinBasic Code:
Option Explicit
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GdiplusStartup Lib "gdiplus" (hToken As Long, pInputBuf As Any, Optional ByVal pOutputBuf As Long = 0) As Long
Private Sub Class_Initialize()
Dim aInput(0 To 3) As Long
If GetModuleHandle("gdiplus") = 0 Then
aInput(0) = 1
Call GdiplusStartup(0, aInput(0))
End If
'--- more init follows
'...
End Sub
Ignore the returned token, GDI+ is never to be unloaded.
I'm not seeing any such issue, but perhaps I have misinterpreted your scenario?
Code:
Private Sub Form_Load()
Dim AP1 As AlphaPic
Dim AP2 As AlphaPic
Set AP1 = New AlphaPic
Set AP2 = New AlphaPic
AP1.LoadBitmap "Drink.png"
AP2.LoadBitmap "GhostFace.png"
AutoRedraw = True
AP1.Render Me, (ScaleX(ScaleWidth, ScaleMode, vbPixels) - AP1.Width) \ 2
Set AP1 = Nothing
AP2.Render Me
AP2.Render Me, ScaleX(ScaleWidth, ScaleMode, vbPixels) - AP2.Width
AutoRedraw = False
Set AP2 = Nothing
End Sub
Weird and it works on XP apparently. I was reading some threads on the internet w/o doing my own testing. Most of the horror stories are related to calling startup/shutdown from DllMain.
As far as I understand there is a background thread involved but it's not clear which Gdip functions actually spawn it. Overlapped nesting could be problematic in this case, more testing needed.