-
Mar 17th, 2019, 12:25 PM
#1
VB6 ucVTab - a Vertical TabStrip-Control
Another small Control, which demonstrates the advantages of a "virtual Control"
(requiring your own User-Code in an OwnerDraw-Event, to decide what's rendered concretely).
Maybe I should start with a ScreenShot first:
The OwerDrawn-Vertical-Tabentries are currently in a Style which kind of matches a "modern side-bar".
Here's the (Drawing-)UserCode one has to write for this kind of Tab-Entry-Rendering (in the appropriate Event the ucVTab raises).
Code:
Private Sub ucVTab1_RenderTab(ByVal Index As Long, TabEntry As PictureBox)
TabRs.AbsolutePosition = Index + 1 'synchronize the Tab-Index to our external Rs
With TabEntry
.BackColor = IIf(Index = ucVTab1.TabIdx, vbHighlightText, IIf(Index = ucVTab1.HotIdx, vbInactiveBorder, vbButtonFace))
TabEntry.Line (0, .Height - 1)-(.Width, .Height - 1), vbButtonShadow 'a single Line at the Bottom
If Index = ucVTab1.TabIdx Then TabEntry.Line (0, 0)-(2, .Height), IIf(ucVTab1.Focused, vbHighlight, vbButtonShadow), BF
'PNG-Icon-Rendering from our global GDIPlus-CacheInstance
GC.AlphaRenderTo .hDC, TabRs!ImgKey.Value, 8, 4, .Height - 8, .Height - 8
'and finally the Text-Rendering (only a single Caption-Line is printed, but multiple Lines of TextOutput are easily possible this way)
.FontName = "Arial": .FontSize = 10: .FontBold = CBool(Index = ucVTab1.TabIdx)
.CurrentX = 30: .CurrentY = (.Height - .TextHeight("")) / 2
TabEntry.Print TabRs!Caption
End With
End Sub
So instead of preparing a Control via countless Properties for "special cases" (implementing and documenting them),
then in turn also requiring the User to "study all these Prop-Settings and their Effects on the Render-Output" -
one can simply leave them out of the Ctl-Implementation - and raise an OwnerDraw-Event instead -
where the User now has to place a handful of render-calls himself, to achieve exactly the render-output he wants.
That shifts a Users learning-efforts" from "studying and applying a Controls Property-Settings" to "learning how to Draw on a certain Canvas- or DrawingContext-Object"
(in our case here, the Canvas is a normal VB6-PicBox - and the Drawing-Context is the GDI-hDC of said PictureBox-Canvas.
I'd consider "knowing how to draw stuff on certain canvases and context" a skill which is in most cases already there.
So these kind of virtual/ownerdrawn Controls have (from my point of view) only advantages (for the implementor - as well as for the end-user).
The ucVTab-Ctl contains only about 70 lines of code.
Also with regards to "best-practice" (code-engineering-wise) there is no disadvantage, because these kind of Controls will require you,
to "keep Control-Context-Data on the outside" (as it should be IMO)...
So in the case of this Demo here, the Context-Data for the TabEntries is not "gathered inside the Control" (e.g. in a Tabs-Collection) -
no - instead it is sitting on the outside (in the hosting VB-Form - in a ADO-Rs-Private-Variable).
This kind of "simple and relatively loose" DataBinding-approach (which requires the Control, to know only the "external Count of entries")
should be common best practice - but sadly it is not.
Well, now the whole thing starts sounding like a rant (which I guess it is) -
but maybe when you study the example (I mean, really study it - damnit),
you'll begin to see, how powerful, flexible and clean these "pure ownerdrawn approaches" can be.
Here is the Code-Zip of the Demo: ucVTab.zip
Have fun,
Olaf
Last edited by Schmidt; Mar 17th, 2019 at 01:34 PM.
-
Jul 13th, 2019, 10:46 AM
#2
Re: VB6 ucVTab - a Vertical TabStrip-Control
Great!
I not find Backcolor property for ucVTab1.
How can I set the Backcolor of the user control? Example:
Code:
ucVTab1.BackColor = vbBlue
-
Jul 13th, 2019, 03:30 PM
#3
Re: VB6 ucVTab - a Vertical TabStrip-Control
Originally Posted by gibra
Great!
I not find Backcolor property for ucVTab1.
How can I set the Backcolor of the user control? Example:
Code:
ucVTab1.BackColor = vbBlue
Either add your own Public Property Get/Let for the BackColor within the UserControl,
or (according to the "everything is ownerdrawn"-philosophy), you could simply add the following:
First an additional Event-Definition (below the already existing two in the declaration-section of the Control):
Code:
Event Click()
Event RenderTab(ByVal Index As Long, TabEntry As PictureBox)
Event RenderBackGround(ucCanvas As Object, ByVal PxlW As Long, ByVal PxlH As Long)
And at the end of the Control-Code-Module, add and enhance:
Code:
Public Sub Refresh()
PC.Move 0, 0, ScaleWidth, mHeight
UserControl.Cls
RaiseEvent RenderBackGround(GetUC(UserControl), UserControl.ScaleWidth, UserControl.ScaleHeight)
Dim i As Long
For i = 0 To mCount - 1
PC.Cls
RaiseEvent RenderTab(i, PC)
UserControl.PaintPicture PC.Image, 0, i * mHeight
Next
UserControl.Refresh
End Sub
Private Function GetUC(ByVal UC As Variant) 'a workaround via Variants, to be able to pass the UC to the outside
Set GetUC = UC
End Function
Now you can render any background you want in your Form-Code by making use of that new Event...
Either via a solid color-rectangle - by using the VB-Line-method on the passed ucCanvas-Object as shown below:
Code:
Private Sub ucVTab1_RenderBackGround(ucCanvas As Object, ByVal PxlW As Long, ByVal PxlH As Long)
ucCanvas.Line (0, 0)-(PxlW, PxlH), vbRed, BF
End Sub
And since the passed ucCanvas is a normal (albeit LateBound) VB-Canvas-Object, you can of course also use:
- ucCanvas.PaintPicture (to render arbitrary ImageContent as the BackGround)
- or use the ucCanvas.hDC, to render your BackGround via GDI or GDIPlus-APIs
HTH
Olaf
-
Jul 13th, 2019, 04:56 PM
#4
Re: VB6 ucVTab - a Vertical TabStrip-Control
Good sample.
I chose to add the RenderBackGround event
Thank Olaf!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|