See WIP.md for the cross-package maintenance guide.
A VB6-compatible replacement for Microsoft Common Controls 6.0 (MSCOMCTL.OCX), written on top of the Win32 ComCtl32 controls (COMCTL32.DLL / MSFTEDIT.DLL). Ships eight controls that mirror the MSCOMCTL surface name-for-name where possible. It is independent of, but co-versioned with, the VB compatibility package.
Each control is a large <Name>BaseCtl (where every event / method / property is implemented, tagged [COMCreatable(False)] + [EventsUseDispInterface]) plus a thin <Name> leaf (Inherits <Name>BaseCtl, tagged [WindowsControl("/miscellaneous/ICONS??/<Name>??.png")]). The leaf adds only a Class_BeforeFirstMethodAccess that calls [_HiddenModule].EnsureContainerIsLoaded(Me). CEF and the VB controls use the same <Name>BaseCtl / <Name> leaf split.
Eight controls (one .twin per pair):
| File | <Name>BaseCtl inherits |
Role |
|---|---|---|
DTPicker.twin |
VB.BaseControlFocusable |
Date / time picker — calendar drop-down, single-date Value, custom format strings |
ImageList.twin |
VB.BaseControlNotFocusable |
Off-screen image collection — feeds ListView / TreeView icons via Icons / ImageList properties |
ListView.twin |
VB.BaseControlFocusable |
Multi-column list — four View modes (Icon / SmallIcon / List / Report), label-edit, checkboxes |
MonthView.twin |
VB.BaseControlFocusable |
Full-month calendar grid — multi-select, bold-day callbacks, week-number / today display |
ProgressBar.twin |
VB.BaseControlNotFocusable2 |
Standard / Smooth / Marquee progress indicator with three visual states (Normal / Error / Paused) |
Slider.twin |
VB.BaseControlFocusableNoFont |
Trackbar / slider — tick marks, range selection, vertical or horizontal orientation |
TreeView.twin |
VB.BaseControlFocusable |
Hierarchical tree of Node objects — sorting, label-edit, checkboxes, image lists |
UpDown.twin |
VB.BaseControlFocusableNoFont |
Spin control (up / down arrows) — pure Increment / Min / Max / Value; no auto-buddy binding |
Every <Name>BaseCtl carries [WithDispatchForwarding] Implements Control (where Control is Private Interface in Interfaces.twin, marked [COMExtensible] — essentially an Object alias that makes the dispatch forwarding behave). They also implement VB.IWindowsControl, VB.IWindowElementEventsCommon, VB.IWindowElementEventsCommonControls, VB.IWindowElementEventsUC and VB.IWindowElementEventsAX — the VB-package event-dispatch interfaces. Do not show them in the docs. Each control also implements one private Tb<Name>Private interface (declared [ComImport(True)] inside the same .twin). The package's collection sub-objects use it to refcount and reach internal state without a strong reference. No doc page for those.
The eight leaf classes DTPicker, ImageList, ListView, MonthView, ProgressBar, Slider, TreeView, UpDown are what user code references at design time (via [WindowsControl(...)]) and at run time (Dim lv As ListView). The <Name>BaseCtl base classes are the implementation half: [COMCreatable(False)], not user-instantiable, but the entire user-visible surface is declared on them. Document on the leaf's name (ListView.md), describe the full surface, and do not show the <Name>BaseCtl split.
The package also surfaces eight sub-object classes — collection plus item:
| Class | Reached via | Notes |
|---|---|---|
ListImages |
ImageList.ListImages (Get-only) |
Enumerable; Item(Index or Key) default member; Add, Remove, Clear, Exists |
ListImage |
element of ListImages (returned from Add, indexed) |
Index (read-only), Key, Picture, Tag, plus Draw(hDC, x, y, Style) and ExtractIcon |
ListItems |
ListView.ListItems (Get-only) |
Enumerable; Item(Index or Key) default member; Add, Remove, Clear |
ListItem |
element of ListItems |
Text (default), SubItems(Index), Icon, SmallIcon, Checked, Selected, Ghosted, Bold, BackColor, ForeColor, Tag, ToolTipText, EnsureVisible, Left / Top / Width / Height, Index (RO), Key, CreateDragImage ([Unimplemented]) |
ColumnHeaders |
ListView.ColumnHeaders (Get-only) |
Same shape as ListItems; Add(Index, Key, Text, Width, Alignment, Icon) returns ColumnHeader |
ColumnHeader |
element of ColumnHeaders |
Text (default), Width, Left (RO), Alignment (typed ListColumnAlignmentConstants), Position, SubItemIndex, Icon, Index (RO), Key, Tag |
Nodes |
TreeView.Nodes (Get-only) |
Enumerable; Item(Index or Key) default; Add(Relative, Relationship, Key, Text, Image, SelectedImage) returns Node |
Node |
element of Nodes |
Text (default), Parent, Child, Next, Previous, Root, FirstSibling, LastSibling, Children (count), Expanded, Selected, Checked, Bold, BackColor, ForeColor, Image, SelectedImage, Tag, FullPath, Visible (RO), Sorted, SortOrder, SortType, EnsureVisible, Index (RO), Key |
Every sub-object is [COMCreatable(False)] — its constructor takes a <Name>BaseCtl reference, so user code never instantiates these directly. They are returned from container methods (Add, Item) and reached through container properties.
Container cross-references (typed as the <Name>BaseCtl parent, since the controls accept either the base or the leaf — but document the parameter as the leaf):
TreeView.ImageList/Let/Set— typedAs ImageListBaseCtl; the user assigns anImageList.ListView.Icons/Let/Set,ListView.SmallIcons/Let/Set,ListView.ColumnHeaderIcons/Let/Set— all three typedAs ImageListBaseCtl; the user assigns anImageList.
ListView.BorderStyle is unusually typed As TreeBorderStyleConstants (declared in TreeViewPublic, not in a ListView* module) — the enum is shared across both controls. Surface this on the BorderStyle entry without trying to rationalise it.
Points to put on each control's page that are not obvious from a flat property list:
- DTPicker — the only control where most behaviour is in the calendar drop-down, not the inline display. The
Calendar*colour properties (CalendarBackColor,CalendarForeColor,CalendarTitleBackColor,CalendarTitleForeColor,CalendarTrailingForeColor) act on the dropped-down month grid viaDTM_SETMCCOLOR.Format(DTPickerFormatConstants) chooses between long-date / short-date / time / custom; when set todtpCustom, the picker pullsCustomFormat(aGetDateFormat-style picture string). The control exposesYear/Month/Week/Day/Hour/Minute/Secondaccessors that decompose the currentValue.ValueisVariant— it can beNull(no date selected) whenCheckBox = Trueand the user unchecks the box. EventsFormat,FormatSize,CallbackKeyDownfire whenFormat = dtpCustomand the format string contains a callback token. - ImageList — purely off-screen;
Visibledoes nothing user-meaningful (it's a "store of pictures" control). TheImageWidth/ImageHeightproperties are read/write only while empty — once any image is added, the setter raises run-time error 35611 ("Property is read-only if image list contains images").ColorDepthis fixed at construction time.MaskColor+UseMaskColor = Truemakes the masked pixels transparent when rendered into a control that consumes the image list.Overlay(Key1, Key2)composes two list-images into a singleStdPicture. Bound-count tracking: anImageListcannot be modified (clear / remove) while any control has it bound asIcons/SmallIcons/ColumnHeaderIcons/ImageList, throwing error 35617. - ListView — the largest of the eight.
Viewswitches the visual mode (lvwIcon/lvwSmallIcon/lvwList/lvwReport);Arrange(lvwNone/lvwAutoLeft/lvwAutoTop) auto-flows the icon mode;Reportmode is the only one that shows theColumnHeaders.LabelEditdefaults tolvwAutomatic— F2 / click-and-wait edits a label in place;lvwManualrequiresStartLabelEdit()andlvwDisabledblocks editing.TextBackground(lvwTransparent/lvwOpaque) acts on the item text rendering:lvwOpaquedraws item text on the control'sBackColor(LVM_SETTEXTBKCOLOR),lvwTransparentsets it toCLR_NONE. Since BETA 1005BackColorandTextBackgroundboth go throughColorsChanged, and every colour property ofListView,ListItem,ProgressBarandImageListvalidates its value withVB.CommonValidateColorOrRevert: a valueOleTranslateColorrefuses (-1) raises 380 and keeps the old colour, soListItem.BackColor = -1(its default,CLR_NONE) cannot be assigned back after a colour.MultiSelect = Trueenables Ctrl+click / Shift+click range selection.CheckBoxes = Trueadds a leading checkbox per row and firesItemCheck.AllowColumnReorderonly matters in Report view.BorderStyleisTreeBorderStyleConstants(ccNone/ccFixedSingle). The control surfaceshWndandhWndHeader(the embeddedSysHeader32window) separately.Scrollis[Unimplemented]per the source.GetFirstVisible() As ListItem,SelectedItem/SelectedItemIndex— the latter is read-only (assign throughListItem.Selected = Trueinstead). - MonthView —
MonthColumns/MonthRowslay out a grid of side-by-side month panels (ResizeToFitauto-sizes the control to fit them).Day/Month/Week/Yearare the same decomposition pattern as DTPicker.MaxSelCountis the upper bound of a multi-day selection (default 7, max ≈ 366 per the Win32 control);SelStartandSelEndare the inclusive range.MinDate/MaxDatebound the navigable range.Valueis the current selection's start date (same asSelStartwhenMultiSelect = False). The control fires bothClick(any click) andDateClick(only when a date cell is hit, with the date passed as a parameter); same split forDblClick/DateDblClick.GetDayBoldis an event-driven callback — the control fires it for each visible month asking for aState()array of which days to render bold; this is the mechanism for highlighting holidays, schedule entries, etc.DayBoldis an alternative per-date setter.GetMonthRange(IncludeTrailing, StartDate, EndDate)returns the visible date span. - ProgressBar — three orthogonal axes.
Min/Max/Valueare the standard range.Step+StepIt()advances the bar byStepunits (typical loop pattern:Min = 0,Max = N, thenStepIt()per iteration).Scrolling = PrbScrollingStandard(default) animates the bar in segments;PrbScrollingSmoothis the continuous block;PrbScrollingMarqueeis the indeterminate animation (drive withMarqueeAnimation = True+MarqueeSpeed).State(PrbStateNormal/Error/Paused) tints the bar red / yellow per the OS theme.OrientationisPrbOrientation(Horizontal/Vertical). The control hasClick/DblClick/Mouse*events but noChangedespite the declaration — verify with the source if surfaced (Changeis declared in the events region but not fired by any Win32 progress-bar notification). - Slider —
Min/Max/Valuelike a scrollbar;SmallChangeis the arrow-key step,LargeChangeis the PgUp / PgDn step.SelStart+SelLengthcreate a highlighted selection range (visible whenSelectRange = True).TickFrequencycontrols how often tick marks appear;TickStyle(sldBottomRight/sldTopLeft/sldBoth/sldNoTicks) chooses which side(s) of the channel they render on.TextPosition(sldAboveLeft/sldBelowRight) is for the optional tip text.HideThumb = Trueremoves the draggable indicator.ShowTip = Trueenables the floating tooltip showing the current value during drag.OrientationisOrientationConstants(the shared horizontal / vertical enum used also byUpDown). - TreeView — the second-largest control.
Style(TreeStyleConstants, 8 values) is a composite of show / hide flags for tree-lines / plus-minus boxes / icons / text — the values name what's shown.LineStylechoosestvwRootLines(lines from root nodes) ortvwTreeLines(lines only from children).Sorted/SortOrder/SortTypeapply at the root level; eachNodehas its own per-subtreeSorted/SortOrder/SortType.LabelEditis the same gating asListView.LabelEdit(tvwAutomatic/Manual/Disabled).CheckBoxes = Trueadds per-node checkboxes;FullRowSelectextends the selection highlight across the full row width.Indentationis in twips.HitTest(x, y)returns theNodeat a point (for hover effects, drag-drop).SelectedItem(Get/Let/Set) andDropHighlight(Get/Let/Set) are bothNode-typed.StartLabelEdit()forManualmode.GetVisibleCount()returns how many full nodes the visible area shows.Scrollevent new to tB. - UpDown — pure spin control:
Min/Max/Value/Increment.OrientationisOrientationConstants(horizontal pair of arrows or vertical, the more common). Events areChange(any timeValuechanges),UpClick,DownClick. There is no auto-buddy / partner-control facility in this version (the Win32UDS_AUTOBUDDYflag is in the source enums but not exposed) — user code wiresUpClick/DownClickto update the partner control manually.
Common surface across every control: Public Opacity As Double = 100 (with the "REQUIRES TARGET OS 6.2+ FOR CHILD CONTROLS." description), Public TransparencyKey As OLE_COLOR = -1 (same OS requirement), and (where FEATURE_OLEDRAGDROP is enabled at compile time) Public OLEDropMode As VBRUN.OLEDropConstants plus the OLECompleteDrag / OLEDragDrop / OLEDragOver / OLEGiveFeedback / OLESetData / OLEStartDrag events. Public OLEDrag() method on every control. Public Property Get Parent() As Object and Public Property Get Object() As Object on every control. The inherited surface from VB.BaseControl* includes Name, Left, Top, Width, Height, Anchors, Dock, Visible, Enabled, BackColor / ForeColor / Font (where focusable), Appearance, MousePointer / MouseIcon, ToolTipText, DragMode / DragIcon, Drag(), Refresh(), SetFocus() (focusable variants), ZOrder(), CausesValidation, TabIndex / TabStop (focusable variants), VisualStyles, hWnd, HelpContextID / WhatsThisHelpID.
These enums are declared inside each <Name>BaseCtl (Enum <Name> without Public, which still surfaces because the enclosing class is public). Following the CustomControls convention for WaynesSlider.SliderDirection, document each on its declaring control's page rather than under Enumerations/:
| Enum | Declared on | Members |
|---|---|---|
ImageListColorDepth |
ImageListBaseCtl |
ColorDepth4Bit = 4, ColorDepth8Bit = 8, ColorDepth16Bit = 16, ColorDepth24Bit = 24, ColorDepth32Bit = 32 |
ListViewConstants |
ListViewBaseCtl |
lvwIcon = 0, lvwSmallIcon = 1, lvwList = 2, lvwReport = 3 |
ListArrangeConstants |
ListViewBaseCtl |
lvwNone = 0, lvwAutoLeft = 1, lvwAutoTop = 2 |
ListTextBackgroundConstants |
ListViewBaseCtl |
lvwTransparent = 0, lvwOpaque = 1 |
ListLabelEditConstants |
ListViewBaseCtl |
lvwAutomatic = 0, lvwManual = 1, lvwDisabled = 2 |
ListColumnAlignmentConstants |
ColumnHeader |
lvwColumnLeft = 0, lvwColumnRight = 1, lvwColumnCenter = 2 |
PrbOrientation |
ProgressBarBaseCtl |
PrbOrientationHorizontal = 0, PrbOrientationVertical = 1 |
PrbScrolling |
ProgressBarBaseCtl |
PrbScrollingStandard = 0, PrbScrollingSmooth = 1, PrbScrollingMarquee = 2 |
PrbState |
ProgressBarBaseCtl |
PrbStateNormal = 1, PrbStateError = 2, PrbStatePaused = 3 |
TickStyleConstants |
SliderBaseCtl |
sldBottomRight = 0, sldTopLeft = 1, sldBoth = 2, sldNoTicks = 3 |
TextPositionConstants |
SliderBaseCtl |
sldAboveLeft = 0, sldBelowRight = 1 |
Source-side spelling note: every enum is named <Name> (no Public modifier) but the member names use the historical VB6 prefix conventions — lvw for ListView, tvw for TreeView, sld for Slider, dtp for DTPicker, Prb for ProgressBar, cc for cross-control. Mixed casing in member names (SldAboveLeft literal in the source defaults vs sldAboveLeft declaration) is a source-side issue; surface members with the declared casing.
Five <Name>Consts.twin modules in SUPPORT/ hold Win32 SDK plumbing (message IDs, notification IDs, style flags, Win32 types like NMHDR / SYSTEMTIME / LVCOLUMNW) plus a few user-facing enums. User code cannot reach the plumbing (mostly inside Private Module …Consts). The user-facing enums are in a separate Public Module (TreeView) or share an effectively public bare Module with the plumbing (the rest). Either way, document only the user-facing enums:
| Enum | Declared in / module | Members |
|---|---|---|
DTPickerFormatConstants |
DTPickerConsts.twin (module DTPickerConsts) |
dtpLongDate = 0, dtpShortDate = 1, dtpTime = 2, dtpCustom = 3 |
TreeBorderStyleConstants |
TreeViewConsts.twin (Public Module TreeViewPublic) |
ccNone = 0, ccFixedSingle = 1 |
TreeLabelEditConstants |
TreeViewConsts.twin (TreeViewPublic) |
tvwAutomatic = 0, tvwManual = 1, tvwDisabled = 2 |
TreeLineStyleConstants |
TreeViewConsts.twin (TreeViewPublic) |
tvwTreeLines = 0, tvwRootLines = 1 |
TreeStyleConstants |
TreeViewConsts.twin (TreeViewPublic) |
8 members: tvwTextOnly, tvwPictureText, tvwPlusMinusText, tvwPlusMinusPictureText, tvwTreelinesText, tvwTreelinesPictureText, tvwTreelinesPlusMinusText, tvwTreelinesPlusMinusPictureText |
TreeRelationshipConstants |
TreeViewConsts.twin (TreeViewPublic) |
tvwFirst = 0, tvwLast = 1, tvwNext = 2, tvwPrevious = 3, tvwChild = 4 |
TreeSortOrderConstants |
TreeViewConsts.twin (TreeViewPublic) |
tvwAscending = 0, tvwDescending = 1 |
TreeSortTypeConstants |
TreeViewConsts.twin (TreeViewPublic) |
tvwBinary = 0, tvwText = 1 |
OrientationConstants |
Misc.twin (Private Module Miscellaneous) |
ccOrientationHorizontal = 0, ccOrientationVertical = 1 — used by both Slider and UpDown |
ImlDrawConstants |
ImageListConsts.twin (Private Module ImageListConsts) |
ImlDrawNormal = 1, ImlDrawTransparent = 2, ImlDrawSelected = 4, ImlDrawFocus = 8, ImlDrawNoMask = 16 — flag combination; used as [TypeHint(ImlDrawConstants)] on ListImage.Draw's Style parameter |
For OrientationConstants and ImlDrawConstants (declared Public Enum inside a Private Module): user code cannot name the enclosing module, but the enum members are reachable. [TypeHint] tags them on the consuming method's parameter, and the IDE's "implicit member visibility" shows them. User code writes Slider1.Orientation = ccOrientationVertical and ListImage.Draw(hdc, 0, 0, ImlDrawTransparent Or ImlDrawSelected). Document the enum and don't worry about qualification — the user's call site never needs Module.Enum.Member form.
The remaining <Name>Consts.twin modules (ImageListConsts, ListViewConsts, ProgressBarConsts, TreeViewConsts.TreeViewConsts (the private half), UpDownConsts, SliderConsts, MonthViewConsts, DTPickerConsts non-DTPickerFormatConstants content) are package-internal — Win32 message IDs, style flags, notification structures (NMHDR, NMLISTVIEW, NMDATETIMECHANGE, …) that the controls use to talk to ComCtl32 but that the user never references. No doc pages for those; do not document LVMessages, TVMessages, MonthViewMessages, SliderMessages, UpDownMessages, DTPickerMessages and the associated *Notifications / *Styles enums.
Private Class ListViewHeaderSubclasser(inListView.twin) — subclasses the embeddedSysHeader32window to interceptHDM_LAYOUTnotifications for the column-resize handler. Implementation detail.Private Class TreeViewNodeCheckState/ListViewNodeCheckState/TreeViewNodeClick/TreeViewNodeDblClick(inTreeViewNodeCheckState.twin) — fourIScheduledCallback-implementing dispatch helpers that the controls schedule onto the message loop to fireNodeCheck/ItemCheck/NodeClick/DblClickevents at the right point in the click-handling sequence. Same role as the…Internalclasses in WinNamedPipesLib; no doc page.Class ImageListPropertyPage(inImageListPropertyPage.twin) —[FormDesignerId][PredeclaredId][COMCreatable(False)]Form class that's the IDE's design-time property editor forImageList(the "Custom Properties..." button). Invoked fromImageListBaseCtl.HandleInvokePropertyExtension. Pure design-time tooling, never appears at run-time; no doc page.Private Interface Control/IScheduledCallback/ITwinBasicDesignerExtensions(inInterfaces.twin) — internal interfaces.Controlis the empty marker interface that[WithDispatchForwarding]resolves names through. No doc pages.Private Module Miscellaneous(inMisc.twin) —StrPtrSafe,CommonTreeViewGetNodeFromHandle,SyncBorderStyle— internal helpers.OrientationConstantsdoes surface from this module (see above) but the module itself doesn't get a doc page.Private Module ImagesHelper(inImagesHelper.twin) —GetBitsPerPixelFromPic. Internal helper. No doc page.- The
…Constsmodules (private, or the bareModule DTPickerConsts/MonthViewConsts/SliderConsts/UpDownConsts, which are effectively public but Win32 plumbing only) — see Module-level enums; no per-module doc page.
[Unimplemented] and [Hidden] members to flag
- DTPicker.RightToLeft — tagged
[Unimplemented]; flag with> [!NOTE]. - MonthView.RightToLeft — same.
- ListView.Scroll event — tagged
[Unimplemented]; flag on the event entry. - ListItem.CreateDragImage — tagged
[Unimplemented]; flag with> [!NOTE]. - ListImages.ControlDefault — tagged
[Unimplemented]and[Hidden]; do not document ([Hidden]means the IDE intentionally suppresses it). - ListView.AllowColumnReorder — implemented but only takes effect in Report view; surface as a note on the property.
Layout: folder-style for ImageList/, ListView/, TreeView/ (each has 2–4 sub-object companions — ListImage + ListImages; ListItem + ListItems + ColumnHeader + ColumnHeaders; Node + Nodes — that are 1:1 with the container, same pattern as CustomControls/WaynesButton/WaynesButtonState.md). Single-file for the remaining five (DTPicker.md, MonthView.md, ProgressBar.md, Slider.md, UpDown.md). An Enumerations/ folder holds the 10 module-level / shared enums; the 11 per-control nested enums fold onto their declaring control's page.
docs/Reference/Default/VBRUN/Constants/ControlTypeConstants.mdalready lists every control'svb<Name>constant:vbProgressBar = 21,vbTreeView = 22,vbSlider = 26,vbUpDown = 27,vbDTPicker = 28,vbMonthView = 29,vbListView = 30,vbImageList = 31. Each control's reference page should link back to its constant.docs/Reference/Default/VBRUN/Constants/OLEDropConstants.mdand theOLEDragDropevents are inherited surface — link theOLEDropModeentries to the constant.