VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)-VBForums
Results 1 to 20 of 20

Thread: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    The small Demo shows a lightweight Implementation of GDI+ based Png-Handling,
    encapsulated in two small and resource-friendly windowless Controls...

    It's a variation (with some improvements) from my other CodeBank-post here:
    http://www.vbforums.com/showthread.p...ely-per-WIA%29

    One is for (Moveable) Images or Sprites -> ucPngPicture.ctl - the other is to handle
    "4-State-Png-Image"-based Buttons (Normal, Hovered, Pressed, Disabled) -> ucPngButton.ctl.

    Here's a ScreenShot, what the combined 4-State-Button-Pngs look like:


    The Button-States-PngResources could also be adjusted to work with 5 States (e.g. when
    you want to introduce also a "Focused" State - its just about enhancing the Png-Resource
    about the new "State-Area" - and adding a few lines of code, which ensure the correct
    Offset within the Controls "Refresh-Drawings"-routine.

    To incorporate it into your existing Projects, you will have to include the 4 Files:
    • modPngCache.bas <- only contains a global Definition of PngCache As cPngCacheGDIp
    • cPngCacheGDIp.cls <- the GDI+ Handling (APIs and conversion into a 32Bit VB-StdPicture-DIB)
    • ucPngPicture.ctl <- the Png-Image- or Png-Sprite-Control
    • ucPngButton.ctl <- the (currently) 4-State-Png-Button-Implementation


    Here's the Download-Link:
    http://vbRichClient.com/Downloads/Pn...AndButtons.zip

    The Source-Code within the Form is quite small (BTW, also demonstrating the
    usage of VBs Usercontrols built-in HitTest-capabilities):

    Code:
    Option Explicit
    
    Private Sub Form_Initialize() '<- early loading of all Png-Resources under their Keys (before Main-Form_Load)
    
      'here we add true Alpha-Channel-Png-Images to the cache (with 4 Button-States per Image)
      PngCache.AddImage "Home", App.Path & "\Res\Home.png"
      PngCache.AddImage "Seven", App.Path & "\Res\Seven.png"
    
      'now we cache another Alpha-Png, which will be rendered in a moveable Control
      PngCache.AddImage "Tucan", App.Path & "\Res\Tucan.png"
    End Sub
    
    Private Sub Form_Load()
      'just VBs normal LoadPicture-Function, providing the Forms BackGround-Img from a *.jpg
      Set Picture = LoadPicture(App.Path & "\Res\Checker.jpg")
    End Sub
    
    Private Sub Form_Resize() 'this adjusts the two Btns, which share the "Seven"-Key at the LeftBottom-Form-Edge
      ucPngButton(3).Move 7, ScaleHeight - ucPngButton(3).Height
      ucPngButton(4).Move 54, ScaleHeight - ucPngButton(4).Height
    End Sub
    
    Private Sub Form_Paint() '<- now that's iportant here for flickerfree rendering
      'to receive Form_Paint-Events, the Form needs to remain at the default (AutoRedraw = False)
      'then we need to ensure, that each and every Png-Usercontrol we use on this Form, gets refreshed
      
      '...starting with the Z-ordering "Bottom-Up" (the first refr. ucPng-Ctl is "bottom-most", a.s.o.)
      ucPngPicture1.Refresh
      
      Dim i As Long 'after the movable Png-Picture-Ctl above, we follow up with our 4 Png-Buttons below
      For i = 1 To 4: ucPngButton(i).Refresh: Next
    End Sub
    
    Private Sub ucPngButton_Click(Index As Integer)
      Caption = "ucPngButton " & Index & " -> " & ucPngButton(Index).Key
    End Sub
    
    'just a demonstration of the HitTest-Event (which by default, when not explicitely handled - would
    'detect a Hit on the current *rectangular* Ctl-Region) - here we adjust the Hit-Detection with the
    '"circle-formula" -> R = Sqr(x^2 + y^2), to the circular region of the round Buttons, so when you move
    'the Mouse diagonally across the Button-"edges", it should give a hit only when you cross the circumference
    Private Sub ucPngButton_HitTest(Index As Integer, X As Single, Y As Single, HitResult As HitResultConstants)
      Const R = 20 '<- we define a Radius of 20 Pixels for our userdefined HitTest
      Dim cx: cx = ucPngButton(Index).Width / 2
      Dim cy: cy = ucPngButton(Index).Height / 2
    
      HitResult = IIf(Sqr((X - cx) ^ 2 + (Y - cy) ^ 2) < R, vbHitResultHit, vbHitResultOutside)
    End Sub
    And the appropriate ScreenShot of the small Demo-App:


    Have fun with it...

    Olaf
    Last edited by Schmidt; Feb 28th, 2014 at 05:22 PM.

  2. #2
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,057

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Quote Originally Posted by Schmidt View Post
    To incorporate it into your existing Projects, you will have to include the 4 Files:
    • modPngCache.bas <- only contains a global Definition of PngCache As cPngCacheGDIp
    Wouldn't setting cPngCacheGDIp.cls'

    Code:
    Attribute VB_PredeclaredId = False
    to True achieve the same effect as

    Code:
    Public PngCache As New cPngCacheGDIP 'let's have it declared here for global usage (we only need one of it for the whole App)
    ? (thus no more need for a standard module)

    I just had to rename your demo project's cPngCacheGDIP class to PngCache in order to maintain compatibility with the existing PngCache references in your code.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Ah - good catch Bonnie.

    Didn't thought about the Flag... (which is the same one, you can set in the IDE in an ActiveX-dll project per: [Instancing] Property to [6-GlobalMultiUse]).

    In a normal StdExe-Project, the VB-IDE doesn't provide this Flag in its visible Interface - so one would have to resort to manually editing the *.cls-File, to achieve the desired effect.

    Thanks for the hint.

    Olaf

  4. #4
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Howdy.
    Download the file "http://vbRichClient.com/Downloads/Pn...AndButtons.zip" and got the following error:

    Invalid procedure call or argument

    Here:

    Public Property Get Picture(Key As String) As StdPicture
    Set Picture = Images(Key)
    End Property

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    In case this was with the original, unchanged source - then "on what system do you use that" (Win98 might be a problem with regards to the GDI+ libs).

    If you changed code in the Demo, I'd like to see (all) your changes (or better yet - an uploaded project with your code).

    Olaf

  6. #6
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Olaf,

    Thanks for your reply.
    I am running XP.
    Did not make any changes at all.
    Simply downloaded and tried to run.

    I then tried this:


    It's a variation (with some improvements) from my other CodeBank-post here:
    http://www.vbforums.com/showthread.p...ely-per-WIA%29


    It runs.
    I spent about an hour trying to figure out how to use it.
    I am stuck with the following:

    I try to use this:

    PngCache.AddImage "Spider", App.Path & "\Spider.png"
    Set Button1 = New cButton: Button2.InitOn Me, "Spider", 100, 100


    The image appears fine but when I hover the mouse over the image, the image disappears.
    Could you perhaps provide an example with a standard PNG that only has 1 state?
    i.e. what needs to be changed just to put a single PNG on the form ?

    Danke!

    David

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Quote Originally Posted by kembreg View Post
    Olaf,

    Thanks for your reply.
    I am running XP.
    Did not make any changes at all.
    Simply downloaded and tried to run.

    I then tried this:


    It's a variation (with some improvements) from my other CodeBank-post here:
    http://www.vbforums.com/showthread.p...ely-per-WIA%29


    It runs.

    Then the other application should run as well IMO, because the cPngCacheGDIp.cls is to 99%
    the same as in the other project (there's only some slight changes with an additional
    Stretch-Parameter).

    So I'd rather find out what went wrong with this Demo here on your XP-machine, because
    I think that it's the more intuitive one to use in "normal scenarios".

    When you write, that an error happens "here":

    Public Property Get Picture(Key As String) As StdPicture
    Set Picture = Images(Key)
    End Property

    In what line exactly - and since you're in a breakpoint then - could you please check,
    if there's content at all in the Images-Collection?
    e.g. by using:
    ?Images.Count, "should give 3"
    or
    ?Images("Home") Is Nothing, "should give False"
    or
    ?Images("Seven") Is Nothing, "should give False"
    or
    ?Images("Tucan") Is Nothing, "should give False"

    all in the DirectWindow, whilst you are at the breakpoint...

    Maybe there's something different on XP - but if the other, earlier Demo works,
    then we should be able to make this (easier to use) one work too.

    Olaf

  8. #8
    Fanatic Member
    Join Date
    Apr 2012
    Posts
    873

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    If it helps, Olaf, I just tested the demo concerned on XP SP3 and no errors...
    If you don't know where you're going, any road will take you there...

    My VB6 love-children: Vee-Hive and Vee-Launcher

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Thanks for the feedback Colin - good to know - so I'm not going to undertake any further investigations at the moment...

  10. #10
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Name:  invalid-procedure-error.jpg
Views: 984
Size:  40.4 KB

    Olaf,

    Downloaded again, unzipped, ran -> same error.
    the variable "Key" has the value "Key"

    David

  11. #11
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Olaf,

    Looked a bit. The key is coming from label1.caption
    Could not see this control nor could I see how it gets the value "Key"

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Ah ...

    so you're perhaps trying to assign a Png-image to the picture-prop in the Form-Designer?
    That's currently not supported on this "lightweight-version" of the control(s).

    You will have to assign your Png-Images to the Cache-Instance instead (once - either in Sub Main or in Form-Initialize -
    as shown in the Demo, where those images are loaded as resources).

    This way you can share the same Cached-Key among several instances of such a Control.

    Olaf

  13. #13
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Quote Originally Posted by Schmidt View Post
    Ah ...

    so you're perhaps trying to assign a Png-image to the picture-prop in the Form-Designer?
    That's currently not supported on this "lightweight-version" of the control(s).

    You will have to assign your Png-Images to the Cache-Instance instead (once - either in Sub Main or in Form-Initialize -
    as shown in the Demo, where those images are loaded as resources).

    This way you can share the same Cached-Key among several instances of such a Control.

    Olaf
    ------------------------------
    I have not made any changes at all to your code.
    Download, unzip, run.

    David

  14. #14
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Olaf,

    When the X or Y coordinates is too high, the image will not render.
    Any ideas?
    Attached Images Attached Images  
    Last edited by kembreg; Apr 15th, 2014 at 06:41 AM. Reason: Fixed by myself

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Quote Originally Posted by kembreg View Post
    Olaf,

    When the X or Y coordinates is too high, the image will not render.
    Any ideas?
    I don't know which version you currently use - and would like very much,
    that you upload a simple version of your own adaptions, which shows the
    behaviour you mentioned (in a small zip-file).

    That way it would be most painless for all and a solution could be found very fast.

    Olaf

  16. #16
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Quote Originally Posted by Schmidt View Post
    I don't know which version you currently use - and would like very much,
    that you upload a simple version of your own adaptions, which shows the
    behaviour you mentioned (in a small zip-file).

    That way it would be most painless for all and a solution could be found very fast.

    Olaf
    Olaf, könntest du mir bitte eine email schicken: kembreg yahoo COMunity

    Ich schicke dir dann den Code.

    Danke.

  17. #17

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    My public E-Mail should already be exposed somewhere in my "user-info-page" here.

    Though I don't understand, what's so complicated in making a small example in a fresh,
    new Std-Exe-project... Even if your "real App" is much larger, you should be able to
    reproduce the behaviour you see also in a small Mockup-Demo, which only contains
    the source of my uploaded controls ... + the few lines (and a few "unimportant images")
    of your own.

    Creating something like that - checking if the error is reproducable - then uploading in a zip ...
    all that should take up only 10-15 minutes.

    I can ensure you, that I invested more time whilst writing this demo for the benefit of all -
    why not try a bit, to save some time on my end "in return"...

    If it's not the time (or your intellectual property) you're concerned about, but potential
    "code-quality issues" - (fearing that others will mock you about it) - that's not happening
    here IMO - there's occasional criticism, but that's a normal thing - and needed to get better
    with something...

    I'd just repost the Zip with my corrections and a few comments - you will see no ridiculing
    from my end - but errors need to be pointed out to others - of course also my own ones
    (in case it was me, who was responsible for the misbehaviour you encountered).

    Olaf

  18. #18
    Member
    Join Date
    May 2006
    Posts
    60

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Olaf,

    I figuret it out.
    I was rendering the images in the form "load" event event.

    At design time, if the form is not big enough, the methods will not paint the images even through the "windowstate" is set to max.
    During the load event, the windowstate is always "normal" regardless of what it is actually set too.

    David

  19. #19

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,105

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    Quote Originally Posted by kembreg View Post
    I figuret it out.
    I was rendering the images in the form "load" event event.

    At design time, if the form is not big enough, the methods will not paint the images even through the "windowstate" is set to max.
    During the load event, the windowstate is always "normal" regardless of what it is actually set too.
    Not sure, what version of the Png-Rendering you're using now (the "older one" from the other Link, or this one here),
    but if it works for you now, then fine...

    For an even better (and easier to code) Png-Rendering-support you could also consider using vbRichClient5
    (there's Demos for that here in the CodeBank, but also in the large Cairo-Tutorial on vbRichClient.com.

    Olaf

  20. #20
    Member Black_Storm's Avatar
    Join Date
    Sep 2007
    Posts
    49

    Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)

    i fixed #4 error with this way :

    Code:
    in ucPngButton.ctl
    
    Public Sub Refresh()
    
      If Ambient.UserMode Then ScaleMode = vbPixels Else Exit Sub
      If Shape1.Visible Then Shape1.Visible = False
      If Label1.Visible Then Label1.Visible = False
      With Extender
        If .Container.AutoRedraw Then .Container.AutoRedraw = False
        If .Container.ScaleMode <> vbPixels Then .Container.ScaleMode = vbPixels
    
    If Key = "Key" Then
    Exit Sub
    End If
    
        .Move .Left, .Top, PngCache.Width(Key), PngCache.Height(Key) \ PngCache.Height(Key) / PngCache.Width(Key)
        PngCache.AlphaRenderTo .Container.HDc, Key, .Left, .Top, .Width, .Height, 0, .Height * State
      End With
    End Sub
    
    
    
    
    in cPngCacheGDIP.cls
    
    Public Property Get Picture(Key As String) As StdPicture
    If Key = "Key" Then
    Exit Sub
    End If
    
      Set Picture = Images(Key)
    End Property
    
    
    
    Public Property Get Width(Key As String) As Long
    If Key = "Key" Then
    Exit Sub
    End If
      Width = Picture(Key).Width / Screen.TwipsPerPixelX * 0.566929133858268
    End Property
    
    Public Property Get Height(Key As String) As Long
    If Key = "Key" Then
    Exit Sub
    End If
      Height = Picture(Key).Height / Screen.TwipsPerPixelY * 0.566929133858268
    End Property
    
    
    Public Sub AlphaRenderTo(ByVal HDc As Long, Key As String, Optional ByVal X As Long, Optional ByVal Y As Long, _
                                                               Optional ByVal dX As Long, Optional ByVal dY As Long, _
                                                               Optional ByVal XSrc As Long, Optional ByVal YSrc As Long, _
                                                               Optional ByVal Stretch As Boolean, Optional ByVal GlobalAlpha As Double = 1)
      If dX = 0 Then dX = Width(Key)
      If dY = 0 Then dY = Height(Key)
          If Key = "Key" Then
                Exit Sub
          End If
    
      If Picture(Key).Handle Then OldBM = SelectObject(mhDC, Picture(Key).Handle)
      If Stretch Then
        GdiAlphaBlend HDc, X, Y, dX, dY, mhDC, XSrc, YSrc, Width(Key), Height(Key), 2 ^ 24 + &HFF0000 * GlobalAlpha
      Else
        GdiAlphaBlend HDc, X, Y, dX, dY, mhDC, XSrc, YSrc, dX, dY, 2 ^ 24 + &HFF0000 * GlobalAlpha
      End If
      If OldBM Then SelectObject mhDC, OldBM
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.