-
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:
http://vbRichClient.com/Downloads/Png-Resources.png
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:
http://vbRichClient.com/Downloads/Png-Controls.jpg
Have fun with it...
Olaf
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Quote:
Originally Posted by
Schmidt
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.
-
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
-
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
-
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
-
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
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Quote:
Originally Posted by
kembreg
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
-
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...
-
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...
-
1 Attachment(s)
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Attachment 112879
Olaf,
Downloaded again, unzipped, ran -> same error.
the variable "Key" has the value "Key"
David
-
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"
-
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
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Quote:
Originally Posted by
Schmidt
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
-
1 Attachment(s)
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?
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Quote:
Originally Posted by
kembreg
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
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Quote:
Originally Posted by
Schmidt
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.
-
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
-
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
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Quote:
Originally Posted by
kembreg
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
-
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
-
3 Attachment(s)
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
Attachment 164599
这种长方形的按钮如何显示?How is this rectangular button displayed?
Attachment 164601
Attachment 164603
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
I have written one of my life's largest VB6 control project, PNG transparent button.I don't know if I did it wrong, because once the control is transparent, it can't be placed on top of other images or webbrowers.
So my idea is to use a non-transparent control, if I place the custom control on a button or a table control, my practice is to copy the elements behind the control as images into my custom control.
If I want to put this custom control above the playing video, it will not be truly transparent.The above content is used translation software, attached to the original Chinese.
我曾经写过一个我人生中最大的vb6 控件工程,png透明按钮。我不知道我是不是做错了,因为一旦控件透明,他就没办法放置在其他图像或者网页控件webbrower上面。
所以我的想法是用非透明的控件,如果我这个自定义控件放置在一个按钮或者表格控件上面,我的做法是先把控件后面的元素以图片方式复制到我的自定义控件里面。
如果要把我这个自定义控件放置在正在播放的视频上面,它就没办法做到真正的透明。以上内容是用翻译软件,附上原来的中文。
-
Re: VB6 lightweight PNG-Controls (4-State-PngButtons and a moveable Png-Image/Sprite)
When DPI is enabled, PngButtons and Png-Image cannot display images when the system display size is 175%.
Can anyone fix it?