Results 1 to 4 of 4

Thread: VB6 ucVTab - a Vertical TabStrip-Control

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,255

    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.

  2. #2
    gibra
    Guest

    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

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,255

    Re: VB6 ucVTab - a Vertical TabStrip-Control

    Quote Originally Posted by gibra View Post
    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

  4. #4
    gibra
    Guest

    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
  •  



Click Here to Expand Forum to Full Width