# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  CommonControls (Replacement of the MS common controls)

## Krool

This project is intended to replace the MS common controls for VB6.

The "MSCOMCTL.OCX" (respectively "COMCTL32.OCX") can be replaced completly.
The "MSCOMCT2.OCX" (respectively "COMCT232.OCX") can be replaced completly.
The "RICHTX32.OCX" can be replaced completly.
The "COMDLG32.OCX" can be replaced completly.
The "COMCT332.OCX" can be replaced completly.
The "MCIWNDX.OCX" (shipped with VB5) can be replaced completly.
The "SYSINFO.OCX" can be replaced completly.

Following controls are available at the moment:

-	Animation
-	CheckBoxW
-	ComboBoxW
-	CommandButtonW
-	CommandLink
-	CoolBar
-	CommonDialog (Class Module)
-	DTPicker
-	FontCombo
-	FrameW
-	HotKey
-	ImageCombo
-	ImageList
-	IPAddress
-	LabelW
-	LinkLabel
-	ListBoxW
-	ListView
-	MCIWnd
-	MonthView
-	OptionButtonW
-	Pager
-	ProgressBar
-	RichTextBox
-	Slider
-	SpinBox
-	StatusBar
-	SysInfo
-	TabStrip
-	TextBoxW
-	ToolBar
-	TreeView
-	UpDown
-	VirtualCombo
-	VListBox

*Unicode* is supported for all the stated controls. Also these are full *DPI-Aware*.

At design-time (IDE) there is only one dependency. (OLEGuids.tlb)
This is a modified version of the original .tlb from the vbaccelerator website.
But for the compiled .exe there are *no dependencies*, because the .tlb gets then compiled into the executable.

Everything should be self explained, because all functions and properties have a description.

The source code of the project can also be viewed on GitHub.

This Demo shows of how to make the ToolBar control accessible per shortcut key on a MDIForm.

ActiveX Control version, together with a Registration-Free (Side-by-side) solution:
Version 1.7

Thanks to MountainMan for the 
Documentation and Update/Compile Utility

*Notes:*
- When using the SetParent or MoveWindow API, pass .hWndUserControl and not .hWnd.
- When changing the "Project Name", have all forms open, else all properties are lost. Because the library to which the controls are referring to is the "Project Name" itself. Having all forms open will ensure that the .frx files will be updated with the new "Project Name".

*List of revisions:*

```
11-Jan-2023
- Unnecessary usage/variable of GetTopUserControl() removed in the ListView and SpinBox control.
10-Sep-2022
- Bugfix in the RightToLeft property in the RichTextBox control.
30-Aug-2022
- Critical bugfix in the StatusBar that the DrawState API is not allowed anymore to have lData as 0.
26-Aug-2022
- Improved the popup menu in the ToolBar to send WM_CANCELMODE upon recursive invocation.
  This is useful in the .ContainerKeyDown function to close the popup menu when it's already dropped down.
22-Aug-2022
- Minor internal improvement in the StatusBar control.
15-Aug-2022
- Exit Property for same value in the Text property of a Panel in the StatusBar control.
27-Jun-2022
- Bugfix in the internal OLEDragOver in the ListView control for report view.
22-Jun-2022
- Bugfix in the WM_NCPAINT handler for a themed RichTextBox that scrollbars are not drawn.
30-May-2022
- Support for adding an .Image object from a PictureBox to an ImageList.
  Prior to this update the .Image object needed to be peristed into the .Picture property of the PictureBox.
18-Feb-2022
- Included [_Default] property in ComboBoxW/FontCombo/VirtualCombo/ImageCombo.
- Included the GetTextRange property in the RichTextBox control.
04-Nov-2021
- FilterBar now receives focus in the ListView control on an MDI child form when the previous control was an intrinsic VB.CommandButton.
  Reason is a unknown message &H105A pending on the MDI host form which brings focus back to the ActiveControl.
26-Oct-2021
- Bugfix on LvwListItems.Remove that no error was thrown for an non-existent numeric index.
  For a string index/key an error was already thrown.
25-Oct-2021
- Internal improvements in the UpDown control.
- Included ES_AUTOHSCROLL for the edit window in the SpinBox control.
22-Oct-2021
- RichTextBox improvement when changing the RightToLeft property at run-time and when TextMode is RTF.
  It will not stream RTF out before re-create and not stream RTF in afterwards. This way the \rtlpar is properly in place.
- Default value for MaxDate property in the DTPicker/MonthView control changed to 31-Dec-9999. (instead of 01-Jan-3000)
13-Oct-2021
- Included the run-time (read-only) TextLength property for the TextBoxW and RichTextBox control.
- The RichTextBox control now uses EM_GETTEXTEX/EM_SETTEXTEX instead of EM_STREAMOUT/EM_STREAMIN for the Text property.
- Included the UseCrLf property in the RichTextBox control.
  It defaults to False (compatibility break in VBCCR) but fixes the Text to match to internal positions.
  This affects the Text and TextLength property. (GT_USECRLF/GTL_USECRLF)
07-Sep-2021
- Fixed GDI leaks for DTPickerCalendarFontHandle, LinkLabelUnderlineFontHandle and ProgressBarFontHandle.
04-Sep-2021
- Bugfix in the internal CreatePrintJob method in the RichTextBox concerning the printing margins.
10-Aug-2021
- Removal of EM_EXLIMITTEXT (Flags = SF_RTF) in internal StreamStringIn/StreamFileIn in the RichTextBox control.
  It was probably put there by error or by misunderstanding of the MSDN documentation.
05-Aug-2021
- Small bugfix in the PPCoolBarBands that child controls can be in the list that have no window handle. (e.g. Label)
  This bug occured only when there were other child controls that have a window handle.
24-Jul-2021
- DrawStyle vbSolid now only when Single BorderStyle is set, otherwise it is vbInvisible. (refer to 21-Jul-2021 and 26-Mar-2021 update)
21-Jul-2021
- Bugfix in the LabelW control that the Single BorderStyle was not drawn anymore as of 26-Mar-2021 update.
15-Jul-2021
- Bugfix in the Text property of a Panel in the StatusBar control. (no immediate update of internal DisplayText)
08-Jun-2021
- CommandButtonW/CheckBoxW/OptionButtonW (vbButtonGraphical) can now render 32bpp alpha bitmaps and icons.
04-Jun-2021
- PPCoolBarBands can be switched now between CoolBars at design-time without issues.
- PPStatusBarPanels can be switched now between StatusBars at design-time without issues.
- PPToolBarButtons can be switched now between ToolBars at design-time without issues.
29-May-2021
- PPTabStripTabs can be switched now between TabStrips at design-time without issues.
- PPImageListImages can be switched now between ImageLists at design-time without issues.
23-May-2021
- Improvement in the WM_SETCURSOR in the CoolBar control.
  This ensures the cursor handling for the child controls can walk up the chain properly.
15-May-2021
- Bugfix in the UseChevron property of a Band in the CoolBar control.
  The .CXHeader member (RBBIM_HEADERSIZE) will now be reset (= -1) whenever the property is set.
- RP_CHEVRON/RP_CHEVRONVERT now included in the 'ImplementThemedReBarFix'.
12-Apr-2021
- Internal improvement in the StatusBar control.
26-Mar-2021
- UserControl.DrawStyle set to 5 = Transparent to avoid a wasted/unused GDI pen handle.
17-Mar-2021
- Improved CreateGDIFontFromOLEFont function.
15-Mar-2021
- HotTracking property improved in the ListView control.
01-Mar-2021
- Harmonization in the ContextMenu events. The X and Y parameters are now always originated to the control's hWnd.
  Problem was in some controls which have child windows, resulted in confusing X and Y parameters.
19-Feb-2021
- Bugfix in the NodeClick/NodeDblClick event in the TreeView control.
  Prior to this update it fired whenever hItem is <> 0.
  Now it fires only when when in addition the hit-test flags are TVHT_ONITEMICON or TVHT_ONITEMLABEL. (like the MS TreeView does)
- Improved the Nodes.Clear method in the TreeView control.
  The selected item is now removed before clearing to have no unnecessary TVN_SELCHANGING/TVN_SELCHANGED notifications.
18-Feb-2021
- Bugfix in the Left/Width property (Get) of a Panel in the StatusBar control.
16-Feb-2021
- Internal improvement in the TextBoxW control.
14-Feb-2021
- Bugfix in the FrameW control related to 13-Feb-2021 update.
13-Feb-2021
- Bugfix in the FrameW control that mouse events were in pixels instead of twips.
19-Jan-2021
- TabMinWidth property can be set to -1 in the TabStrip control.
23-Sep-2020
- No crash anymore when passing a vbNullString to the .SelText property in various controls. (e.g. TextBoxW)
  Though, the fix concerns only Windows XP or below. Because as of Vista+ a NULL StrPtr() on EM_REPLACESEL does not cause harm.
18-Aug-2020
- Enhancement for the FrameW control.
  - Access key now supported.
  - TabIndex now supported. (important to be set meaningful so the access key works properly)
  - Included UseMnemonic property. (not available in a VB.Frame, thus being an advantage)
15-Aug-2020
- Some minor internal improvements.
08-Aug-2020
- Bugfix in the OLEDropMode property in the FrameW control.
  It was not possible to set it to OLEDropModeManual when windowless control(s) were contained in it.
- It is now possible for the TbrButtonMenus collection to change the key on a particular TbrButtonMenu in the ToolBar control.
06-Aug-2020
- It is now possible for the TbrButtons collection to change the key on a particular TbrButton in the ToolBar control.
29-Jul-2020
- Included new RefreshMousePointer function in Common.bas.
- All controls who receive CBN_DROPDOWN will call RefreshMousePointer function when current hCursor is NULL.
  This is a unresolved misbehavior in user32.dll ever since.
26-Jul-2020
- Internal improvement in the SelText property in the RichTextBox control.
25-Jul-2020
- It is now possible for the CbrBands collection to change the key on a particular CbrBand in the CoolBar control.
23-Jul-2020
- Internal improvement in the SysInfo control.
20-Jul-2020
- It is now possible for the SbrPanels collection to change the key on a particular SbrPanel in the StatusBar control.
- Included the 'NodeRangeSelect' event in TreeView control with a Cancel parameter.
  It fires for each node when a range of nodes is about to be selected. (like 'NodeBeforeSelect', but for shift-range selection)
16-Jul-2020
- The GetEmptyMarkup event supports now right-to-left in the ListView control.
15-Jul-2020
- Added optional 'Index' param in the .WorkAreas.Add method (to insert before index) in the ListView control.
12-Jul-2020
- Reworked the .WorkAreas property in the ListView control.
  It is not anymore a property which just returns/sets an array of coordinates.
  Instead it returns now a collection to the new 'LvwWorkAreas' class.
  The collection is not 'private' and relies fully on LVM_GETWORKAREAS/LVM_SETWORKAREAS.
  The .ListItemIndices of a 'LvwWorkArea' returns all list items that belongs to a work area.
  Also the new .WorkArea property of a 'LvwListItem' returns the work area to which a list item belongs to.
09-Jul-2020
- Included MultiSelect property in the TreeView control.
  It can be set to 'None' (Default), 'All', 'VisibleOnly', 'RestrictSiblings'.
  The new 'SelectedNodes' property returns a collection to the new 'TvwSelectedNodes' class.
  With this class the count and the selected nodes can be retrieved or enumerated.
  The most recent select node has index 1 and the oldest select node has the last index. (sorted by history)
  Included the 'AnchorItem' property which returns the node from which a multiple selection starts.
  Included the 'SelectedIndex' function in the TvwNode class. It returns the index of the associated selected nodes collection.
05-Jul-2020
- Internal improvement in the TreeView control.
01-Jul-2020
- VirtualCombo control now works on comctl version 5.8x.
- ItemBkColor now fired in a virtual ListView control.
- Internal improvement for the HighlightHot property in the ListView control.
30-Jun-2020
- Included Left/Top/Width/Height (read-only) property in the ListSubItem of the ListView control. (LVM_GETSUBITEMRECT)
- Included function 'FindNearestItem' in the ListView control. (LVFI_NEARESTXY)
28-Jun-2020
- Included CacheVirtualItems event in the ListView control. (LVN_ODCACHEHINT)
- LVN_ODSTATECHANGED processed to enhance the ItemSelect event in a virtual ListView control.
- Renamed param 'Index' to 'ItemIndex' in the GetVirtualItem event in the ListView control.
  Thus it does not clash anymore with the 'Index As Integer' param in a control array.
- ItemSelect event can now pass a ListItem 'As Nothing' in a virtual ListView control. (LVN_ITEMCHANGED, iItem = -1)
  Because a virtual list view does only inform about each selected item and not for each deselected item.
- It is now possible for the TbsTabs collection to change the key on a particular TbsTab in the TabStrip control.
27-Jun-2020
- It is now possible for the LvwGroups collection to change the key on a particular LvwGroup in the ListView control.
- It is now possible for the ImlListImages collection to change the key on a particular ImlListImage in the ImageList control.
26-Jun-2020
- Included the FontWeight property in the CommonDialog class.
23-Jun-2020
- Included the VListBox control. (virtual list box control)
  The name 'VirtualList' would confuse as this is a common word for a virtual list view.
  Thus to avoid that the name must contain 'ListBox' and to keep it short then 'VListBox'.
- TabbedTextOut API now used in a Checkbox/Option Style ListBoxW control when UseTabStops property is True.
- Bugfix in the 32-bit scrolling in a multi-column ListBoxW and when WS_EX_LEFTSCROLLBAR is set.
- Text property in ListBoxW now data-bindable to a VB.Data control.
07-Jun-2020
- Internal improvement in the OptionButtonW control.
- Bugfix in the OptionButtonW control, the default value property should be False in Read/WriteProperties.
  This change makes migration from VB.OptionButton to OptionButtonW easier at the cost of compatibility break to old OptionButtonW.
- Major internal improvement for MCIWnd as no WM_MOUSEACTIVATE overhead necessary anymore.
  This results for 'ComCtlsTopParentValidateControls' being obselete and was removed!
02-Jun-2020
- Included the BeforeUserInput/AfterUserInput event in the DTPicker control.
  The BeforeUserInput provides a hWndEdit and AfterUserInput is always fired, even when canceled.
  Existent ParseUserInput event only fires if the user did not cancel.
01-Jun-2020
- Internal improvements in the ComboBoxW/FontCombo/VirtualCombo/ImageCombo controls.
28-May-2020
- WM_UNICHAR handler now supports surrogate pairs. (UTF32 conversion)
26-May-2020
- SimpleText property now uses SBT_RTLREADING in case RightToLeft is True in the StatusBar control.
- Changed IncrementalSearch event params in the VirtualCombo control.
25-May-2020
- Behavior bugfixes in the VirtualCombo control when Style is <> DropDownList.
- Included DrawMode property in the VirtualCombo control.
  Only options are Normal and OwnerDrawFixed. (OwnerDrawVariable not possible due to LBS_NODATA restriction)
24-May-2020
- Included the VirtualCombo control. (super-classed combo box control with a no-data list box portion)
  The .ListCount property is write-able and populates the list very quickly.
  GetVirtualItem event retrieves the item strings.
  IncrementalSearch/FindVirtualItem event can also be handled to enable full functionality.
21-May-2020
- Included the DrawMode property in the Slider control.
20-May-2020
- Major internal improvement for ImageCombo as no WM_MOUSEACTIVATE overhead necessary anymore.
- Improvement for the WM_NCPAINT handler in the RichTextBox control.
- Included a WM_NCPAINT handler for the HotKey control to resolve msctls_hotkey32 class bugs. (it behaves then like an edit control)
18-May-2020
- Included SortType LvwSortTypeLogical in the ListView control.
- Bugfix related to 08-May-2020 update. (WM_PRINTCLIENT in IPAddress control)
17-May-2020
- Bugfix in the Add method of LvwColumnHeaders in the ListView control.
- Included Text property (read-only) in the HotKey control.
- BackColor property in the HotKey control works now also when Enabled = False.
- Major internal improvement for HotKey as no WM_MOUSEACTIVATE overhead necessary anymore.
09-May-2020
- UserControl.Cls added in the UserControl_Paint event in the IPAddress control.
08-May-2020
- The IPAddress control supports now the WM_PRINTCLIENT message.
  This was lost due to the rebuild from scratch as of 17-Apr-2020. (no longer use of SysIPAddress32 class)
07-May-2020
- Width property of a Panel in the StatusBar control not read-only anymore. It behaves as the MS StatusBar.
06-May-2020
- Removed the BackColor property in the DTPicker control for simplification.
  It was anyhow not possible anymore as of Vista+ ..
04-May-2020
- Included Font/Text/TextColor property in the ProgressBar control.
  Text placeholders: {0} = Value, {1} = Min, {2} = Max and {3} = Percent value between 0 and 100.
03-May-2020
- Major internal improvement for LinkLabel/MonthView/ComboBoxW/FontCombo as no WM_MOUSEACTIVATE overhead necessary anymore.
- Other minor internal improvements.
30-Apr-2020
- Internal improvement in the OptionButtonW control.
28-Apr-2020
- Property bag for the CheckBoxW/CommandButtonW/OptionButtonW/FrameW caption's property not unicode anymore. (like LabelW from beginning)
  This avoids some .frx refs as there is no property page anyway for these available to input unicode in the IDE.
  No problem occurs with existing property bags, so no compatibility break.
- Other minor internal improvements in the ListView control.
27-Apr-2020
- Bugfix in the ListView control.
  - The ItemFocus event is now able to fire at first item insertion. (Index = 1)
  - The ItemFocus event will not have an Item set as 'Nothing' anymore when clearing the list. (mis-feature)
26-Apr-2020
- Bugfix in the GetClipboardText function in Common.bas.
23-Apr-2020
- FrameW responds now to WM_SETTEXT/WM_GETTEXT/WM_GETTEXTLENGTH like the VB.Frame.
22-Apr-2020
- Bugfix that an OwnerDrawn OptionButtonW did not raise the Click event, though the value got changed.
20-Apr-2020
- Major Bugfix in the CheckBoxW/CommandButtonW/CommandLink/LinkLabel/OptionButtonW control.
  Forgot to call DeActivateIPAO method upon WM_KILLFOCUS.
- DPI-aware bugfix in the Slider control.
- Major internal improvement for SpinBox as no WM_MOUSEACTIVATE overhead necessary anymore.
19-Apr-2020
- Internal improvement in ComCtlsBase.bas.
- Improvement for Animation control.
  - No re-creation anymore when changing BackColor property.
  - Default value for AutoPlay property now False instead of True. (like in the original MS control)
  - StartPlay and IsPlaying renamed to Play and Playing in the Animation control. (like in the original MS control)
  - StartedPlay/StoppedPlay event merged into new Change event. (more VB-ish, use .Playing to determine current status)
18-Apr-2020
- Major internal improvement for ListView as no WM_MOUSEACTIVATE overhead necessary anymore.
- Renamed the Border property to 'BorderStyle' in the RichTextBox control. (like in the original MS control)
17-Apr-2020
- Major internal improvement in the IPAddress control as SysIPAddress32 class no longer used.
  Instead everything is done from scratch within the UserControl and four internal edit controls.
  The behavior and usage is 100% mimic, but looks more "VB-ish".
  - BackColor property now possible.
  - ForeColor property also effects now the three dots.
  - UserControl_Resize does not need a re-creation. (SysIPAddress32 was fixed, no MoveWindow was possible!)
  - BorderStyle property now possible. (e.g. Flat style)
  - Design time property page included.
  - Support for SysIPAddress32 IPM_* messages.
15-Apr-2020
- Modified OLEGuids.tlb as following: (compiled with same uuid)
  - included hWnd param for IOleInPlaceActiveObjectVB and IOleControlVB
  Unregister to old OLEGuids.tlb is not necessary, just overwrite the file.
- Bugfix in the various WM_CONTEXTMENU handlers. It can now also handle negative screen coordinates.
13-Apr-2020
- Behavior improvement for the LabelW control. (when AutoSize property set to True)
  It now sets a temporary NULL clipping region in that case, like the VB.Label does.
- Major internal improvement for Slider/TabStrip as no WM_MOUSEACTIVATE overhead necessary anymore.
- Minor internal improvement in the TextBoxW and RichTextBox control.
12-Apr-2020
- Major internal improvement for TreeView as no WM_MOUSEACTIVATE overhead necessary anymore.
- Bugfix in the Checkboxes property in the TreeView control.
11-Apr-2020
- Major internal improvement for TextBoxW/RichTextBox/DTPicker/ListBoxW as no WM_MOUSEACTIVATE overhead necessary anymore.
- Behavior improvement for vbOLEDragAutomatic in the TextBoxW/ListBoxW control. (OLEDragMode property)
07-Apr-2020
- Major internal improvement for CheckBoxW/CommandButtonW/OptionButtonW/CommandLink as no WM_MOUSEACTIVATE overhead necessary anymore.
06-Apr-2020
- Minor internal improvement in the TabStrip and TreeView control.
29-Mar-2020
- Included the ShowColumnTips property in the ListView control to enable tooltips on the column headers.
  Therefore ToolTipText, ToolTipTextFilterBtn and ToolTipTextDropDown property are included of a ColumnHeader in the ListView control.
- It is now possible for the LvwColumnHeaders collection to change the key on a particular LvwColumnHeader in the ListView control.

[...]

11-Nov-2012
- First release.
```


Warning: This Std-EXE version here is not really IDE-Safe as the design-time (form designer) user control subclassing (AddressOf pointer) can just become invalid when the IDE wants to. It is recommended to use the OCX version.

----------


## Hack

What is the benefit of using these over the existing controls?

Does each control have the same properties? Do they have new properties?

----------


## Krool

The benefit is that these controls are linked to the comctl32.dll, that means they support the latest API calls, functions, properties and visual styles (themes).

The existing common controls 6.0 from MS are not linked to the comctl32.dll, so they doesn't support the visual styles (themes).
Reason why: The controls of the comct32.dll are compiled directly into the common controls 6.0 from MS, but as of state of a old version of comctl32.dll

Only the common controls 5.0 from MS are linked to the comctl32.dll, but the COM hull is very old and so they have a leak of the latest functions and properties. Also controls like the DTPicker, MonthView or UpDown are not included.

----------


## Jonney

> The benefit is that these controls are linked to the comctl32.dll, that means they support the latest API calls, functions, properties and visual styles (themes).
> 
> The existing common controls 6.0 from MS are not linked to the comctl32.dll, so they doesn't support the visual styles (themes).
> Reason why: The controls of the comct32.dll are compiled directly into the common controls 6.0 from MS, but as of state of a old version of comctl32.dll
> 
> Only the common controls 5.0 from MS are linked to the comctl32.dll, but the COM hull is very old and so they have a leak of the latest functions and properties. Also controls like the DTPicker, MonthView or UpDown are not included.


Can you please change the OLEGuids.tlb to a new name to avoid conflicts with my existing OLEGuids.tlb in system32 folder?

----------


## Bonnie West

Excellent work!  :Thumb: 




> What is the benefit of using these over the existing controls?
> 
> Does each control have the same properties? Do they have new properties?


In addition to what Krool stated, some folks, myself included, prefer that their apps have no dependencies whatsoever.

The controls have most of the necessary (similarly named) properties and methods and many of them have some new ones as well (the VisualStyles property for instance).




> Can you please change the OLEGuids.tlb to a new name to avoid conflicts with my existing OLEGuids.tlb in system32 folder?


Open CommonControlsEx.vbp in any text editor and edit this line:



```
Reference=*\G{5B1EACE0-EDEB-11E1-AFF1-0800200C9A66}#1.0#0#..\..\..\..\WINDOWS\system32\OLEGuids.tlb#OLE Guid and interface definitions
```

to:



```
Reference=*\G{5B1EACE0-EDEB-11E1-AFF1-0800200C9A66}#1.0#0#OLEGuids\OLEGuids.tlb#OLE Guid and interface definitions
```

----------


## Krool

> Can you please change the OLEGuids.tlb to a new name to avoid conflicts with my existing OLEGuids.tlb in system32 folder?


You can just rename the file "OLEGuids.tlb" at your own, for example to "OLEGuids2.tlb"
That is no problem, because the uuid and library name differs from the original. They can co-exist without conflicts.
You just need to re-register it in the IDE. (Project -> References... -> Browse for file)

----------


## Jonney

> You can just rename the file "OLEGuids.tlb" at your own, for example to "OLEGuids2.tlb"
> That is no problem, because the uuid and library name differs from the original. They can co-exist without conflicts.
> You just need to re-register it in the IDE. (Project -> References... -> Browse for file)


Thanks. I understood.
If you can add Unicode support, then those control can be used on PC with whatever locale setting.
How about others control built by CreateWindowEx such as Listview/Treeview? Listview support more new features such as Grouping now.

----------


## Krool

Update released.

----------


## Bonnie West

Thanks for the update!

----------


## Krool

Update released.

All controls support now Unicode and some other minor improvements are done.

----------


## Jonney

> Update released.
> 
> All controls support now Unicode and some other minor improvements are done.


Fairly support Unicode. 
But because of nature of MS BUTTON, it doesn't an unicode compatible control.
Never mind, just leave this because it's hard to fully support Unicode for a Command button.

DrawText hDC, StrPtr(Button.Caption), -1, RectText, DT_CALCRECT Or DT_WORDBREAK
Button.Caption can never be held Unicode string, internal conversion has been done before you call DrawTextW.

----------


## Bonnie West

> Button.Caption can never be held Unicode string, internal conversion has been done before you call DrawTextW.


This function will retrieve any button's caption, even if VB displays their Unicode captions as ?????.



```
Private Declare Function DefWindowProcW Lib "user32.dll" (ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Function GetCaption(ByRef oButton As Object) As String
    Const WM_GETTEXT = &HD&, WM_GETTEXTLENGTH = &HE&
    Dim Button_hWnd As Long

    On Error GoTo 1
    Button_hWnd = oButton.hWnd
    GetCaption = Space$(DefWindowProcW(Button_hWnd, WM_GETTEXTLENGTH, 0&, 0&))
    DefWindowProcW Button_hWnd, WM_GETTEXT, Len(GetCaption) + 1&, StrPtr(GetCaption)
1   On Error GoTo 0
End Function
```

VB's Button controls (CommandButton, CheckBox or OptionButton) can actually contain Unicode captions (via DefWindowProcW + WM_SETTEXT). VB doesn't display them properly though.

----------


## Krool

Update released.

----------


## Krool

Update released.

----------


## Krool

Update released.

----------


## Bonnie West

Thanks for including the StatusBar control!

----------


## Krool

Update released.

----------


## Krool

Update released.

----------


## Krool

Update released.

----------


## Jonney

> Update released.


Thank you for consistent update.

----------


## gibra

Good Work!  :Smilie:

----------


## robi_thakur

its really an amazing work,god bless you.Bro can you add listview and treeview with displayable unicode support?
it will great achievment if it possible

----------


## Jonney

Edited: Remove my Post regarding Balloon tooltips, Win8 has fixed the problem.

----------


## Jonney

Confirmed it is OS problem. The balloon tooltips works perfect on Win8.

Edited: CommonControlsEx works On Win8.

----------


## Krool

Update released.

ListView control is added.

Groups and 'Tile' View are for the moment not included.
It can replace 100% the ListView from „MSCOMCTL.OCX". (Exception: ToolTipText of the ListSubItems)
But it has also many properties, methods and events more than the original.

----------


## Jonney

> Update released.
> 
> ListView control is added.
> 
> Groups and 'Tile' View are for the moment not included.
> It can replace 100% the ListView from „MSCOMCTL.OCX". (Exception: ToolTipText of the ListSubItems)
> But it has also many properties, methods and events more than the original.


Thank you for additional Listview.
From Vista/Win7,MS added lots of new features into Listview, such as enhanced grouping, Checkbox on Header,etc.
Please consider adding checkbox and Text Edit for subitems.

----------


## Krool

> Please consider adding checkbox and Text Edit for subitems.


The comctl32.dll does not provide the ability to edit the labels of the subitems.

----------


## Krool

Update released.

ImageList control is completly rewritten. (It is not compatible with the previous version)

It works now like the original ImageList from MS but with some improvements, for example that the Style flag of the ListImages Draw method can be combined with multiples styles. (That was not possible in the original ImageList from MS) or that the Overlay function returns an icon instead of a bitmap or that the BackColor can be turned on or off (UseBackColor property).

----------


## brandoncampbell

Awesome work! I am by far not knocking the work but asking a question.. Is the tab control text a little too far to the right?

----------


## Krool

> Is the tab control text a little too far to the right?


I noticed that too. I think that is due to the new appearance of Windows 7.

----------


## brandoncampbell

I think it has something to do with Mnemonics if you don't put the _ before the text it looks fine.

----------


## Niya

I must say I'm truly impressed. Were I still using VB6, this would have been an incredible source of knowledge. I tended to write alot of my own controls(I still do in VB.Net) and I always want to learn as much as possible about creating them. I thought I had a good handle on it it but one glance at your source code, and even what you described about them being linked to ComCtl32.Dll showed me just how little I actually knew about control authoring in VB6. I tip my hat to you sir.  :Wink:

----------


## Krool

Update released.

ImageCombo control is added.

The biggest advantage is that you can set the style property. ('DropDownCombo', 'DropDownList' or 'SimpleCombo')
That was not possible on the original ImageCombo control. (It was always as 'DropDownCombo')
Also new is the 'ItemDrag' event, similar to the one used in the ListView control.

----------


## brandoncampbell

Nice work dude

----------


## Koalf

Very, very good work. Many thanks to you. I do not like to link to Microsofts Ocx-files (Mscommctl.....). With your controls i don't need that. My exe work so without registrations on every PC. And: i can do more things. I can change the WM_PAINT - message to what i will. I can change the colors, i can add a picture, i can paint the control.  I must only change your code a little bit. Awsome.
Thank you very much!!!!!

----------


## Krool

Update released.

----------


## Krool

Update released.

----------


## Romeo91

Thank you for the work - it's a lovely change CommonControls.
I have one problem, very often crashes when you compile an application (even an example), and the exe-file is created. And sometimes crashes when you press End in the course of the program.
It would be nice if the progress bar for added display of progress on the taskbar. An example can be found here http://sourceforge.net/p/audica/code...skBarList3.cls

----------


## Romeo91

Also for the beautiful subsclassing commandbutton think it will be good to make changes if there is a caption and a picture, you have the image on the left and the caption to the left of the picture. So the picture will not be imposed on the text.



```
Private Sub DrawButton(ByVal hWnd As Long, ByVal hDC As Long, Button As Object)
.....
If Not Button.Caption = vbNullString Or Len(Button.Caption) > 0 Then
    Set ButtonFont = Button.Font
    FontOld = SelectObject(hDC, ButtonFont.hFont)
    RectText = RectClient
    DrawText hDC, StrPtr(Button.Caption), -1, RectText, DT_CALCRECT Or DT_WORDBREAK
    RectText.Right = RectClient.Right
    If ButtonPic Is Nothing Then
        RectText.Left = RectClient.Left
        RectText.Top = ((RectClient.Bottom - RectText.Bottom) / 2) + 3
        RectText.Bottom = RectText.Top + RectText.Bottom
    Else
        RectText.Left = CInt(Button.Parent.ScaleX(ButtonPic.Width, vbHimetric, vbPixels)) + 4
        'RectText.Top = RectClient.Top '(RectClient.Bottom - RectText.Bottom) + 1
        RectText.Top = (((RectClient.Bottom - RectClient.Top) - (RectText.Bottom - RectText.Top)) / 2) + RectClient.Top
        RectText.Bottom = RectClient.Bottom
    End If
    DrawThemeText Theme, hDC, 1, ButtonState, StrPtr(Button.Caption), -1, DT_CENTER Or DT_WORDBREAK, 0, RectText
    SelectObject hDC, FontOld
End If
CloseThemeData Theme
If Not ButtonPic Is Nothing Then
    W = CInt(Button.Parent.ScaleX(ButtonPic.Width, vbHimetric, vbPixels))
    H = CInt(Button.Parent.ScaleY(ButtonPic.Height, vbHimetric, vbPixels))
    If Not Button.Caption = vbNullString Or Len(Button.Caption) > 0 Then
        X = RectClient.Left
        'Y = RectClient.Top ' + ((RectClient.Bottom - RectClient.Left - H) / 2)
        Y = (((RectClient.Bottom - RectClient.Top) - H) / 2) + RectClient.Top
    Else
        RectClient.Bottom = RectText.Top
        X = RectClient.Left + ((RectClient.Right - RectClient.Left - W) / 2)
        Y = RectClient.Top + ((RectClient.Bottom - RectClient.Left - H) / 2)
    End If
    If Enabled = True Then
        If Button.UseMaskColor = True Then
            Call DrawTransparentPicture(ButtonPic, hDC, X, Y, W, H, WinColor(Button.MaskColor))
        Else
            ButtonPic.Render hDC, X, Y + H, W, -H, 0, 0, ButtonPic.Width, ButtonPic.Height, ByVal 0
        End If
    Else
        Call DrawDisabledPicture(ButtonPic, hDC, X, Y, W, H, WinColor(Button.MaskColor))
    End If
End If
```

----------


## ladoo

sleeeeeeeeeeeeeek

----------


## Bonnie West

> I have one problem, very often crashes when you compile an application (even an example), and the exe-file is created. And sometimes crashes when you press End in the course of the program.


Can you tell us how to replicate your "problem"? Can you also point out the code that you suspect is causing the problem?

----------


## Bonnie West

> Also for the beautiful subsclassing commandbutton think it will be good to make changes if there is a caption and a picture, *you have the image on the left and the caption to the left of the picture*. So the picture will not be imposed on the text.


Is that somehow related to this thread? Also, I think what you're saying, is that you want both the button icon and text to be on the left side of the button. Is this correct?

----------


## Romeo91

> Is that somehow related to this thread? Also, I think what you're saying, is that you want both the button icon and text to be on the left side of the button. Is this correct?


Well, partly it has to do with the topic. But, the project is code imposes sabsclassing on standard components.


```
Public Sub SetupVisualStyles(ByVal Form As VB.Form)
If GetComCtlVersion() >= 6 Then SendMessage Form.hWnd, WM_CHANGEUISTATE, MakeDWord(UIS_CLEAR, UISF_HIDEFOCUS Or UISF_HIDEACCEL), ByVal 0&
If EnabledVisualStyles() = False Then Exit Sub
Dim CurrControl As Control
For Each CurrControl In Form.Controls
    Select Case TypeName(CurrControl)
        Case "Frame"
            RemoveVisualStyles CurrControl.hWnd
            SetWindowSubclass CurrControl.hWnd, AddressOf RedirectFrame, ObjPtr(CurrControl), 0
        Case "CommandButton", "CheckBox", "OptionButton"
            If CurrControl.Style = vbButtonGraphical Then
                If CurrControl.Enabled = True Then SetProp CurrControl.hWnd, StrPtr("Enabled"), 1
                SetWindowSubclass CurrControl.hWnd, AddressOf RedirectButton, ObjPtr(CurrControl), ObjPtr(CurrControl)
            End If
    End Select
Next CurrControl
End Sub
```

----------


## Romeo91

> Can you tell us how to replicate your "problem"? Can you also point out the code that you suspect is causing the problem?


VB crashes after compiling the project, if you open a form MainForm in IDE
1. open CommonControls.vbp
2. MainForm.frm open in the GUI
3. compile the project
4. After compiling - Crash VB
Error occurs both on windows xp, and Windows 7.
The compiled exe with no problems

----------


## Bonnie West

OK, I can confirm that on XP, the IDE does indeed crash while compiling the exe. I believe it's due to the heavy subclassing involved, even in the IDE. I think what happens is that some controls are destroyed "abruptly" by VB6, i.e., the UserControl_Terminate() doesn't fire, giving the UserControl(s) no chance of unsubclassing properly, thus causing a crash. Of course, the simplest workaround is to close the MainForm first before compiling. BTW, crashes are to be expected when subclassing, as it's very easy to reference invalid memory addresses.  :Eek Boom:

----------


## Bonnie West

> Well, partly it has to do with the topic. But, the project is code imposes sabsclassing on standard components.


You may want your post(s) to be transferred to the Fix Visual Styles Issues (Themes) thread, as it's the more appropriate thread. Ask a moderator about it by clicking the black triangle icon on the bottom left side of your post.

----------


## Krool

If you set by the StatusBar the compile option "ImplementDesignModeSubclass" to *False* then it should not crash anymore when you compile your project with a opened form that contains a StatusBar.

----------


## Jonney

Only the latest version on 9/may has crash issue while compiling with Mainform open after you updated SubclassProc. I didn't see any crash before. Please double check where and what you have modified since last update.

----------


## Romeo91

> If you set by the StatusBar the compile option "ImplementDesignModeSubclass" to *False* then it should not crash anymore when you compile your project with a opened form that contains a StatusBar.


Thank you. This solution helped.

----------


## DougMZA

Lovely controls. I see however, that the MOUSEUP event works kinda wierd. (I am specifically referring to the listview control). When I right-click an item in the listview, the MOUSEUP event does not fire. Double-clicking (right button) does fire the event. Is this by design (different to the way the listview works in VB6) or did I miss something?

----------


## Krool

See this article from MSDN referring to the WM_RBUTTONUP message by the ListView controls.

"_Note that the control processes the corresponding WM_RBUTTONUP message, and does not dispatch it. Applications thus cannot see this message, even by subclassing the control._"

You may use the "ContextMenu" event for your purpose, as this will be fired when the right mouse button goes up. (but also when pressing SHIFT + F10, but you can filter this case out by checking if the X and Y values are not -1)

Another solution is that you split the Click() event by seperating the NM_CLICK and NM_RCLICK. So you can catch then the NM_RCLICK. Somehow like a RClick() event then.

And again a other sultion is just to handle the ItemClick() event and check if the Button value is vbRightButton, but this will only be fired when your mouse is over an item.

----------


## DougMZA

Thanks, the "ContextMenu" solution works great.

----------


## Krool

Update released.

----------


## SuperDre

Thanx to Bonnie West I noticed this great control set.. Look absolutely awesome.. I too don't like to have to link to OCX, especially after I noticed a crash (when you reorder a listview) with a specific MSCOMCTL.OCX (6.1.97.82).. And I also like to have as much control over the controls as possible, so I love this, as if you run into a problem/or missing something you like you can just add it and it's avaible to all your forms where you use the controls, now we use functions/methods located in modules to do what should be a method/property on some controls.. hehe..

With the current version (common controls demo) the problem of Vb6 crashing after compile when the form is open, is still there (windows 7 ultimate x64)..

Keep up the great work, and thanx..

----------


## RichInSoquel

This looks nice... and thanks for your efforts.  But is there a reason I can't embed your ListView implementation in a VB6 UserControl?  I need a Unicode-aware ListView in my ancient file i/o control.  I don't seem to get events when I do this--the ListView shows up, and I can add items, but not much else is working...  I'm calling 


```
    Call ComCtlsInitIDEStopProtection
    Call InitVisualStyles
```

in my UserControl_Initialize.  Is there something I'm missing?

----------


## Krool

> But is there a reason I can't embed your ListView implementation in a VB6 UserControl?


I just released an update that fixes a bug in the WM_MOUSEACTIVATE handler for this case.
I suggest you download the project again.

Then you need to add the following code to your UserControl:



```
Implements OLEGuids.IOleInPlaceActiveObjectVB

Private Sub IOleInPlaceActiveObjectVB_TranslateAccelerator(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal Shift As Long)
On Error Resume Next
Dim This As OLEGuids.IOleInPlaceActiveObjectVB
Set This = UserControl.ActiveControl.Object
This.TranslateAccelerator Handled, RetVal, wMsg, wParam, lParam, Shift
End Sub
```

This is necessary because in this case the Container (UserControl) of the embedded controls receive the TranslateAccelerator message. If the ActiveControl of the UserControl implements the IOleInPlaceActiveObjectVB interface (That are the common controls from my project), then it delegates to it and perform the TranslateAccelerator for that control.

----------


## RichInSoquel

Thanks for you suggestions.

I've downloaded the latest, and added your suggested code into my UserControl.  Now I am seeing some events.  I see one ItemSelect Event from your ListView (it arrives as I add the first item into ListView.ListItems).  None are received by my UserControl after that.  I have debug.prints in your code that report when RaiseEvents are fired by you: 

When I click on an item,
You raise                       I receive
ItemSelect                     [nothing]
ItemSelect                     [nothing]
ItemClick                       [nothing]

When I click on a column header, 
You raise                       I receive
ColumnClick                    ColumnClick

When I start to resize a column
You raise                       I receive
ColumnBeforeSize            [nothing]

When I click on a row with no item in it,
You raise                       I receive
ItemSelect                     [nothing]
MouseUp                        MouseUp

When I left double-click on a row with no item in it,
You raise                       I receive
DblClick                         DblClick
MouseUp                       MouseUp

I'm fairly sure there is something in my ancient code that is still causing trouble, because I've made an ultimately simple test bed that has a UserControl with your ListView in it that's used on a simple VB6 form, and I get most of the missing Events there. [However, there are other problems --when I add ColumnHeaders, they aren't visible.  

Obviously, I'm not asking for you to debug my code, I just hope these symptoms may suggest something...

Thanks for any help you can give.

----------


## Bonnie West

> But is there a reason I can't embed your ListView implementation *in a VB6 UserControl*? ...  I'm calling 
> 
> *    . . .*
> 
> in *my UserControl_Initialize*.





> ... and added your suggested code into *my UserControl*. ... None are received by *my UserControl* after that.  
> 
> *    . . .*
> 
> ... I've made an ultimately simple test bed that *has a UserControl with your ListView in it* that's used on a simple VB6 form, ...


Just so we're clear, are you saying that you have a User Control that has Krool's ListView User Control in it? That is, a User Control within another User Control?

----------


## RichInSoquel

Right.  I'm trying to replace the old VB6 ListView with Krool's ListView inside a big File I/O UserControl I wrote about 10 years ago.

----------


## Krool

I think it is difficult to help you more without seeing the code in your UserControl.
I have tested your scenario within a blank UserControl and everything seems to work.

----------


## RichInSoquel

I'm working on stripping as much other stuff out of my UserControl as I can.  Either I'll get to a place where it starts working, or I'll send you a reasonable-sized chunk that shows the problems.  Thanks.

----------


## RichInSoquel

I'm trying to come in from both sides.  I have a very simple test bed (as you mention), and agree that everything works fine there.  I'm several hours into cutting out other parts of the real case with no progress.  I do see something I don't quite understand: In the attached screen shot, you can see that I added an On Error Resume Next and some debug.prints in your subclassed Window proc, and you can see the results in the Immediate window...  After the line  


```
           RaiseEvent ItemClick(Me.ListItems(NMIA.iItem + 1), vbLeftButton)
```

it looks like nothing is executed.  Guess I don't really remember if On Error should work inside a subclassed WinProc... but obviously something is going wrong.

----------


## dartguru

Hi I'm new here. I've just encountered the same mscomctl.ocx problem that others have been on about for a while. Eventually that brought me here (and what a wealth of useful information I must say).
I'm sorry if I'm being monumentally thick, but I've downloaded the zip file, and compiled comctlsdemo into an exe. The thick bit ... how do I now get to use that in an existing project. I presume I need to include something to replace mscomctl.ocx.
Thanks in advance (and sorry for introducing myself and flagging up my ignorance all at the same time).

----------


## dartguru

Hi, I've recently encountered the mscomctl.ocx problem having just revisited an old VB6 project I need to upgrade.
Eventually that brought me to this form - and a wealth of knowledge and useful info I must say.
Sorry, but I'm being monumentally thick here, I've downloaded the zip file and compiled the project into an EXE. How do I now use that in my own project as a replacement for the common control that aren't working.
Thanks in advance and apologies again for introducing myself with what is probably a very simple question.

----------


## Bonnie West

> how do I now get to use that in an existing project. I presume I need to include something to replace mscomctl.ocx.





> How do I now use that in my own project as a replacement for the common control that aren't working.


Which specific common control(s) do you wish to use?

----------


## dartguru

> Which specific common control(s) do you wish to use?


It looks like just lstView and ProgressBar1

----------


## Bonnie West

> It looks like just lstView and ProgressBar1


Copy/Move the following files and folders to a new folder:


[ListView][ProgressBar]ComCtlsBase.basCommon.basVisualStyles.basVTableHandle.basEnumeration.clsISubclass.clsVTableSubclass.cls 

Finally, copy/move the OLEGuids.tlb file to the "Windows\System32\" directory and set a reference to it through the VB6 IDE's References dialog box.



*EDIT*

Of course, you'll have to import all of those files into your project (except for *.CTX files). The easiest way of doing that is to drag and drop them onto the Project Explorer window.

----------


## dartguru

Thanks for the reply.
I've included the .bas and .cls files into my project and the OLEGuids.tlb files into system32.

(I've figured out how to register it now).
Next problem is that I was expecting to be able to drag-n-drop lstView and ProgressBar1 object to my form(s) to replace the old ones.
I think I'm just not understanding how these new controls work.

----------


## Bonnie West

> Next problem is that I was expecting to be able to drag-n-drop lstView and ProgressBar1 object to my form(s) to replace the old ones.
> I think I'm just not understanding how these new controls work.


To replace your old controls, copy their names first and then delete them from the Form. You should be able to see the new User Control's icons on the Toolbox. Add them to the Form either by double-clicking or clicking and drawing them on the Form. Rename them using the names of the old controls. Every property, method and event of the old controls should continue to work as they did before. If not, then post here the issues you've encountered.

----------


## dartguru

I see. I think I've got there now. I'd missed the need to drag the contents of the Builds/ListView and Builds/ProgressBar (excluding the CTX) into my project.
The controls are now there and I've successfully replaced my old ones with them.
I've also removed mscomctl.ocx so I've definitely replaced ALL instances of the old controls.

> If not, then post here the issues you've encountered. 

When I try and compile, I get the following compilation errors using listView....

The types ListItem  and ColumnHeader do not exist for the ListView control
The column alignment constants are missing for lvwColumnLeft, lvwColumnCenter and lvwColumnRight

Also, when trying to save and exit the project, I hit the CreateSubclass debug.assert in VTableSubclass when trying to save the form with ListView on it.


I have to say, if I can get over these errors, then this is a great replacement for mscomctl. krool should geta  medal  :Smilie:

----------


## Bonnie West

> When I try and compile, I get the following compilation errors using listView....


I think we should wait for Krool to show up since I'm not familiar with that part.  :Stick Out Tongue: 




> I have to say, if I can get over these errors, then this is a great replacement for mscomctl. krool should geta  medal


Indeed!  :Thumb:

----------


## Krool

> I see. I think I've got there now. I'd missed the need to drag the contents of the Builds/ListView and Builds/ProgressBar (excluding the CTX) into my project.


You can also include the CTX file into your project. (It contains a custom toolbox bitmap for displaying a ListView symbol in the components tab)




> The types ListItem  and ColumnHeader do not exist for the ListView control
> The column alignment constants are missing for lvwColumnLeft, lvwColumnCenter and lvwColumnRight


You have to make some renamings. For instance "Dim Test As ListItem" would then be "Dim Test As LvwListItem" or "Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)" would then be "Private Sub ListView1_ColumnClick(ByVal ColumnHeader As LvwColumnHeader)"

The constants are also different. In your case you need to rename lvwColumnLeft, lvwColumnCenter and lvwColumnRight to LvwColumnHeaderAlignmentLeft, LvwColumnHeaderAlignmentRight and LvwColumnHeaderAlignmentCenter.




> Also, when trying to save and exit the project, I hit the CreateSubclass debug.assert in VTableSubclass when trying to save the form with ListView on it.


This always happens when the IDE crashed and is supposed to be.

----------


## Karim Wafi

Hi Krool nice to meet you, this is a very nice and large project, contains 33.760 lines of code. I have a tools for formatting VB6 code maybe worth for you thanks. http://www.vbforums.com/showthread.p...ode-Formatter)

----------


## dartguru

> You can also include the CTX file into your project. (It contains a custom toolbox bitmap for displaying a ListView symbol in the components tab)
> 
> 
> 
> You have to make some renamings. For instance "Dim Test As ListItem" would then be "Dim Test As LvwListItem" or "Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)" would then be "Private Sub ListView1_ColumnClick(ByVal ColumnHeader As LvwColumnHeader)"
> 
> The constants are also different. In your case you need to rename lvwColumnLeft, lvwColumnCenter and lvwColumnRight to LvwColumnHeaderAlignmentLeft, LvwColumnHeaderAlignmentRight and LvwColumnHeaderAlignmentCenter.
> 
> 
> ...


Thanks krool, I've made these changes and got everything compiling.

(It wouldn't let me drag the ctx into the project though - not important)

One final question, in debug mode I seem to hit this assert every time I run, and I have to close down VB and re-open the project to re-run in debug. Is that correct, and what would cause the IDE to crash?
This is just me running my app in debug, and closing it down at the end. The only thing I can think is that I try to compact the attached database and this fails depending on what version of Access is in use, but I've got this trapped behind "on error goto"....

        On Error GoTo CompactDBFailure
        DBEngine.CompactDatabase sDBCopyName, gDataBaseLocation
        On Error GoTo 0

Is there a problem is just commenting out the debug.assert line ?

----------


## Krool

> (It wouldn't let me drag the ctx into the project though - not important)


Don't import it. Just copy it to the same folder as the ctl file than it should work.




> One final question, in debug mode I seem to hit this assert every time I run, and I have to close down VB and re-open the project to re-run in debug. Is that correct, and what would cause the IDE to crash?


Is this also happening in the demo project?




> Is there a problem is just commenting out the debug.assert line ?


If you comment it out then the IDE is immediatly crashed. Without leting have you a chance to still save the project. (it will fire the debug.assert again when saving, but it is saved)

----------


## dartguru

Thanks krool.
The assert is hit whenever I close after failing to compact the DB. If I remove the compaction code, it doesn't occur.
It does not happen with the demo project.

----------


## Krool

Update released.

OptionButtonW control is added. (Unicode)
It can be combined with the intrinsic VB OptionButton.

----------


## vibiEn

Superb work! You really should post this in the coding contest!

----------


## Romeo91

> Update released.
> 
> OptionButtonW control is added. (Unicode)
> It can be combined with the intrinsic VB OptionButton.


Thank you for this release. OptionButton not enough options for multi-line text or wrap text by default if it is not included in the controller. Standard control VB can do

Kroll, You can extend the functionality of ProgressBar?
It would be nice if the progress bar for added display of progress on the taskbar. An example can be found here http://sourceforge.net/p/audica/code...skBarList3.cls

----------


## Bonnie West

> Kroll, You can extend the functionality of ProgressBar?
> It would be nice if the progress bar for added display of progress on the taskbar. An example can be found here http://sourceforge.net/p/audica/code...skBarList3.cls


See the DispInvokeDemo.zip linked here.

----------


## Romeo91

A Transparent property can be added to CheckboxW and OptionboxW? And to complete the set, not enough of the control LabelW, also with options wrap and transparent
At the moment I use similar control from the user Truong Van Hieu site PlanetSourceCode.

Thank you, your set can now replace many of the old well-known sets of controls.

----------


## zzap

Compiling the VBP project ends up with an error (343): object is no array (translated from german error description).
in module: Common.bas
in line 128: Index = Control.Index

Any idea?

Regards,
ZZap

----------


## Krool

> Compiling the VBP project ends up with an error (343): object is no array (translated from german error description).
> in module: Common.bas
> in line 128: Index = Control.Index
> 
> Any idea?
> 
> Regards,
> ZZap


It is correct that the "Index = Control.Index" will make a error, whenever the control is not an array.
But that is no problem as there is a "On Error Resume Next" line before the "Index = Control.Index" to prevent that the error will be raised.

----------


## Krool

Updated released.

All controls should be now truly unicode.

----------


## brandoncampbell

Anyway to fix the password in the textbox to reflect the later style password text with dots instead of asterisks?

----------


## Bonnie West

> Anyway to fix the password in the textbox to reflect the later style password text with dots instead of asterisks?


Have you embedded a visual styles manifest to your exe? Is your IDE also visual styles enabled?

----------


## brandoncampbell

> Have you embedded a visual styles manifest to your exe? Is your IDE also visual styles enabled?


Yeah it has everything in to make the ellipses but it doesn't.

----------


## Krool

> Anyway to fix the password in the textbox to reflect the later style password text with dots instead of asterisks?


That will do it: (to be done at run-time, e.g. Form_Load event)


```
TextBoxW1.PasswordChar = ChrW(&H25CF)
```

----------


## brandoncampbell

So I did notice that some of the settings don't save when you compile. For instance if you change the password char to whatever and you click build it will not have a password char in the exe. If it is set through the form like you stated above it works ok.

----------


## Krool

This demo is showing of how to make the ToolBar accessible per shortcut key when it is placed on a MDIForm.
It is a little bit more work as the MDIForm does not have a KeyDown event.

----------


## Jonney

> This demo is showing of how to make the ToolBar accessible per shortcut key when it is placed on a MDIForm.
> It is a little bit more work as the MDIForm does not have a KeyDown event.


Very useful code. Thanks.

SetupVisualStyles Me doesn't work in MDIForm?

----------


## Krool

> SetupVisualStyles Me doesn't work in MDIForm?


I forgot to include the .res file in the demo that the visual styles will work.
I have updated the demo. ToolBar control also updated with some improvements concerning the ImageList handling.

----------


## Krool

> For instance if you change the password char to whatever and you click build it will not have a password char in the exe. If it is set through the form like you stated above it works ok.


The password char for dots "ChrW(&H25CF)" cannot be set at design time. (only at run time as stated above)
I have therefore now included a "UseSystemPasswordChar" property to the TextBoxW control. When set to true then the control will be created with the style bit ES_PASSWORD and thus display asterisks or dots as password text automatically (depending on the comctl32 version) .

----------


## brandoncampbell

> The password char for dots "ChrW(&H25CF)" cannot be set at design time. (only at run time as stated above)
> I have therefore now included a "UseSystemPasswordChar" property to the TextBoxW control. When set to true then the control will be created with the style bit ES_PASSWORD and thus display asterisks or dots as password text automatically (depending on the comctl32 version) .


Awesome work as always! I still have an issue when compiling where it does not save the changed settings. If I open the project. Change the textbox at the bottom via properties to systempasschar and click compile. The progress bar goes as if it is compiling but once it reaches the end it refreshes the project and the settings don't stick. The exe does not reflect the change and the project in the ide changes back to default text.

----------


## Krool

> Change the textbox at the bottom via properties to systempasschar and click compile.


Did you try to close the Form first (WriteProperties will then run) before you compile?

----------


## brandoncampbell

> Did you try to close the Form first (WriteProperties will then run) before you compile?


Didn't know that.. it worked.. Thanks! Why does it need to be closed?

----------


## Romeo91

Dear Krool, could you add to its control (OptionButtonW and CheckBoxW, CommandButtonW) parameter Transparent, to the BackColor property itself became equal to the parent. But it is also possible for the elements of a ProgressBar and CommandButtonW fix the appearance of unpainted parts, or as a backcolor, or add an option RoundCorner, to be able to make a rectangular controls, thereby remove the unfilled elements.

----------


## brandoncampbell

Can someone tell me how to auto size columns based on items in listview?

----------


## Krool

> could you add to its control (OptionButtonW and CheckBoxW, CommandButtonW) parameter Transparent, to the BackColor property itself became equal to the parent.


You can set the BackColor property manually, so that it matches to the Parent's BackColor.
For example in Form_Load event:



```
Private Sub Form_Load()
CommandButtonW1.BackColor = Me.BackColor
CheckBoxW1.BackColor = Me.BackColor
OptionButtonW1.BackColor = Me.BackColor
End Sub
```




> Can someone tell me how to auto size columns based on items in listview?


Do following: (where _Index_ is the column you want to auto size)



```
ListView1.ColumnHeaders(Index).AutoSize LvwColumnHeaderAutoSizeToItems
```

----------


## Krool

> could you add to its control (OptionButtonW and CheckBoxW, CommandButtonW) parameter Transparent


Update released.

Transparent property included to CheckBoxW, OptionButtonW and CommandButtonW.
But it is not a real transparency. Each time when the underlying background may change you need to call .Refresh.
In the new release there is also a demonstration of how to make the transparency work when a control (for e.g. CheckBoxW) is placed on a TabStrip control.

----------


## Krool

Update released.

Remake of the FrameW control. There should be no bugs anymore.

----------


## Romeo91

I use the control jcFrames from site planet-source-code.com (http://www.planet-source-code.com/vb...64261&lngWId=1), when I add your control LabelW, and after change property BackStyle = 0 (Transpapent), I see a small graphic bug on the element jcFrames. Tell me why this might be, and you can somehow fix it?
I attach a test project where I showed this nuance

----------


## posfan12

Do you have plans on recreating the File Open/Save dialogs?

[edit]

Also, do you have plans on releasing a DLL version of the controls?

----------


## Krool

> I use the control jcFrames from site planet-source-code.com (http://www.planet-source-code.com/vb...64261&lngWId=1), when I add your control LabelW, and after change property BackStyle = 0 (Transpapent), I see a small graphic bug on the element jcFrames. Tell me why this might be, and you can somehow fix it?
> I attach a test project where I showed this nuance


You can fix that small graphic bug by including following at the end of the "PaintFrame" sub in the jcFrame control:


```
Private Sub PaintFrame()
' [...]
Set UserControl.Picture = UserControl.Image
End Sub
```




> Do you have plans on recreating the File Open/Save dialogs?


I don't think that I will make a "CommonDialog" control as it can be replaced easily by some API calls. There are enough examples out there.




> Also, do you have plans on releasing a DLL version of the controls?


Maybe I will provide some day such a converted project, as there are really some big advantages.
However, you can convert this project to an ActiveX Control for yourself.
Just ensure that you start a new ActiveX Control project from scratch instead of directly converting the CommonControls project. The classes need to be public and the enums located in the ComCtlsBase.bas need to be shifted to a public class. I have tested it and by this way I did not encounter any problems.

----------


## Romeo91

> You can fix that small graphic bug by including following at the end of the "PaintFrame" sub in the jcFrame control:


Krool, Thanks for the tip

----------


## Nightwalker83

Is it possible to do the same thing with the Microsoft Hierarchical FlexGrid and the normal FlexGrid control?

----------


## Romeo91

Control ComboBoxW for events, substitutes the previous value. For example, when you select an item from the list (Event Click), the value of the Text, is not for the selected item, and the previous item in the list.
In native controller from the MS is not

----------


## Krool

> Is it possible to do the same thing with the Microsoft Hierarchical FlexGrid and the normal FlexGrid control?


I don't think that the FlexGrid control is a "common" control located in any Windows DLL. Therefore such a control need to be created from scratch.




> Control ComboBoxW for events, substitutes the previous value. For example, when you select an item from the list (Event Click), the value of the Text, is not for the selected item, and the previous item in the list.
> In native controller from the MS is not


Fixed. Thanks!

----------


## Romeo91

Krool, you have in your kit use for string operation some slow Variant functions - Chr, ChrW, String, Mid, Left, Right, Format, Ucase, Replace, Dir and e.t.c . To increase the speed, i think it is necessary to replace them with their string equivalents function (Chr$, ChrW$, String$, Mid$, Left$, Right$, Format$, Ucase$, Replace$, Dir$). This has a positive impact on the speed of some of the elements.

----------


## JohnTurnbull

Is there any way to get your demo running in VB5 ?

----------


## Krool

> Is there any way to get your demo running in VB5 ?


I think it is not possible. For example in VB5 you cannot instantiate "new" property bags whereas this is possible in VB6 and I used that in some controls.

----------


## JohnTurnbull

OK - Guess I'll start looking for a second hand VB6 (again!)

----------


## Krool

Update released.

----------


## Romeo91

Krool, please tell me how to handle the event RichTExtBox clicking the link above.
Event found LinkEvent, but for some reason it does not work

Also, In the example RTF, there is a small error
Private Const MFS_DISABLED As Long = &H*3*

----------


## Jonney

Can you please enhance Richedit to support pictures (Insert/Resize/Delete/Positioning) and editable table?

----------


## Krool

> Event found LinkEvent, but for some reason it does not work


Are you saying the LinkEvent never fires? Ensure that the AutoURLDetect property is set to true.




> Also, In the example RTF, there is a small error
> Private Const MFS_DISABLED As Long = &H*3*


What do you mean with small error? The Const value is correctly set to &H2.




> Can you please enhance Richedit to support pictures (Insert/Resize/Delete/Positioning) and editable table?


Do you mean "Insert/Resize/Delete/Positioning" by code?

----------


## SuperDre

> What do you mean with small error? The Const value is correctly set to &H2.


Actually according to the MSDN site it should be &H3.. http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

----------


## Jonney

> Originally Posted by Jonney  View Post
> Can you please enhance Richedit to support pictures (Insert/Resize/Delete/Positioning) and editable table?





> Do you mean "Insert/Resize/Delete/Positioning" by code?


Yes,sir. How to manipulate pictures and tables in Richedit is a difficult part for ordinate VB programmer. I know my request is beyond the topic, but if you have something on hand, please make a simple demo. Thanks.

----------


## JohnTurnbull

Got Myself a copy of VB6...

Just wanted to say "Thank you soooooo much" - I've been wanting to add unicode support for years and never could!

----------


## jpbro

@Krool

First off - great work, thanks for such a comprehensive project!

Second - I have a need for a Unicode RichTextBox control, so I thought I give yours a try. Everything seems to be working pretty well except that if I host your RichTextBox control on another UserControl then the cursor keys don't seem to work any longer. Is there anything special I need to do to get them working on a UserControl, or is there a bug?

Thanks again!

----------


## jpbro

An additional note on my previous post - it appears that only the naked cursor keys don't work (vbKeyLeft, vbKeyRight, vbKeyUp, vbKeyDown). Press Shift+ or Ctrl+ a cursor key appears to work. Other naked navigation keys such as vbKeyHome, vbKeyEnd also appear to work as expected. Maybe a clue?

---
Additional note: If the Usercontrol has 2 controls (e.g. your RichTextBox and TextBoxW), then the cursor keys push the focus around between the controls. Perhaps another clue?

----------


## Krool

> I have a need for a Unicode RichTextBox control, so I thought I give yours a try. Everything seems to be working pretty well except that if I host your RichTextBox control on another UserControl then the cursor keys don't seem to work any longer. Is there anything special I need to do to get them working on a UserControl, or is there a bug?


This problem was discussed already on page 2 and there is a solution as described below.




> Then you need to add the following code to your UserControl:
> 
> 
> 
> ```
> Implements OLEGuids.IOleInPlaceActiveObjectVB
> 
> Private Sub IOleInPlaceActiveObjectVB_TranslateAccelerator(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal Shift As Long)
> On Error Resume Next
> ...


Just put the code fragment into your UserControl and everything should work.

----------


## jpbro

Hi Krool,

Sorry, I did read the other posts to see if the problem already had a solution, but I guess I misunderstood that that solution would work for this case (should have tried it anyway). Thanks for your help!

----------


## Romeo91

There are strange program hang when changing font (size and name) for the element comboboxw. Probably when they appear for the property or Font.Name Font.Size put incorrect values​​, such as an erroneous name of the font and size respectively. The greater the time used for the control of the properties, the longer hang

----------


## JohnTurnbull

Hi,

Just a quick question. I have a form with two TextBoxW controls. Lets call them A and B. No matter which control had the focus when the form loses the focus, control A has the focus when the form regain the focus. Can you suggest a reason for this and/or a way to fix it. The control A was added to the form before control B and A is single line with a maxlength set whereas B is multiline with no length limit.

----------


## Krool

> I have a form with two TextBoxW controls. Lets call them A and B. No matter which control had the focus when the form loses the focus, control A has the focus when the form regain the focus. Can you suggest a reason for this and/or a way to fix it. The control A was added to the form before control B and A is single line with a maxlength set whereas B is multiline with no length limit.


I can't reproduce your problems. In order to help you more please upload the form and tell us which OS you are using.

----------


## JohnTurnbull

Hi Krool,

Thanks for replying. The form “as is” won’t run without all sorts of things from the rest of the project so I added it to your demo to take stuff out and get it to run there. It wouldn’t load in your demo with the following error log….

===========================================
Line 104: Class GraphicM8.TextBoxW of control ClipName was not a loaded control class.
Line 567: Class GraphicM8.TextBoxW of control Text1 was not a loaded control class.
Line 110: The property name _ExtentX in ClipName is invalid.
Line 111: The property name _ExtentY in ClipName is invalid.
Line 121: The property name Text in ClipName is invalid.
Line 122: The property name MaxLength in ClipName is invalid.
Line 123: The property name CueBanner in ClipName is invalid.
Line 573: The property name _ExtentX in Text1 is invalid.
Line 574: The property name _ExtentY in Text1 is invalid.
Line 585: The property name Text in Text1 is invalid.
Line 586: The property name HideSelection in Text1 is invalid.
Line 587: The property name MultiLine in Text1 is invalid.
Line 588: The property name ScrollBars in Text1 is invalid.
Line 589: The property name CueBanner in Text1 is invalid.

GraphicM8 is my project name so I guess I screwed something up adding your controls to my project!

I get no errors in my project and it runs perfectly apart from the focus thing I described.

Does this tell you what might be wrong or should I send you the form anyway?

Thanks JT

----------


## JohnTurnbull

I suspect the problem has something to do with your note about changing the project name, but it didn’t mean much to me as I didn’t change any project name. What I did was add your code to my project. To have the LabelW, TextBoxW and Richtextbox, the parts added were…..

Modules
ComCtlsBase.bas
Common.bas
Commondialog.bas
RichTextBoxBase.bas
VisualStyals.bas
Vtablehandle.bas

Class Modules
Enumeration.cls
Isubclass.cls
VtableSubclas.cls

User Controls
LabelW.ctl
RichTextbox.ctl
TextBoxW.ctl

Property pages
PPRichtextBoxGeneral.pag
PPRichtextBoxText.pag
PPTextBoxWText.pag

----------


## JohnTurnbull

Me again!

I now have two forms with this problem. However, when I added a nice simple form with nothing on it except  the two TextBoxWs , that did not have the problem. Today I will take one of the offending forms apart till I find what causes it.

Let you know.

JT

----------


## JohnTurnbull

OK – Problem solved – My bad!

In case it happen to anyone else, this was the problem.

The forms have all their control Tabstops set to false so that I can handle the tab key. To get the form to load with the focus in the first TextBoxW, that has its Tabstop set to true but its GotFocus event turns it off. When I replaced my VB textboxes with TextBoxWs,  I left the Tabstop in the second TextBoxW on true.

Sorry to bother you and thanks again for some great code.

----------


## Romeo91

Hi Kroll, a problem with the program's freezing appears when you multiple time trying to change any of font properties on any controls.
For example here is a code, and applying the property 10-15 times, the more times apply, the longer the freeze. May be variables are not cleared?

Private Sub Command5_Click ()
ComboBoxW1.Font.Size = 10
End Sub

Private Sub Command6_Click ()
ComboBoxW1.Font.Size = 8
End Sub

P.S. Sorry for my English, in from Russia. I often use Google.Translate

----------


## Krool

> a problem with the program's freezing appears when you multiple time trying to change any of font properties on any controls.


Thanks for this bug report!
It is fixed now.

----------


## jay!

Really nice work with the unicode controls, thanks for this great work.

Could you add a PictureW control for the picturebox, which could work unicode into the Print statement?

Thank you,
JC

----------


## jpbro

> This problem was discussed already on page 2 and there is a solution as described below.
> Just put the code fragment into your UserControl and everything should work.


Just a quick note to anyone else experiencing this issue - if you have one of Krool's common controls on a UserControl, and then have your UserControl on another UserControl (and possibly even that UserControl on an additional UserControl, etc...), then you will need to add the code snippet to every UserControl all the way up the chain in order to get the expected behaviour.

----------


## Krool

> Could you add a PictureW control for the picturebox, which could work unicode into the Print statement?


You can print unicode text into the intrinsic VB PictureBox.
You just need to use an API instead of the VB "Print" command.


```
Private Declare Function TextOutW Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal lpString As Long, ByVal nCount As Long) As Long

Private Sub Command1_Click()
Dim Text As String
Text = "text unicode " & ChrW(&HFA23)
Picture1.AutoRedraw = True
TextOutW Picture1.hDC, 0, 0, StrPtr(Text), Len(Text)
Picture1.Refresh
End Sub
```

The downside is that the CurrentX and CurrentY property of the PictureBox are not meaningful.
But this can be solved by using the GetTextExtentPoint32() API.

----------


## Bonnie West

> Could you add a PictureW control for the picturebox, which could work unicode into the Print statement?


Here's an alternative approach using the DrawTextW API function. The attached project demonstrates the use of the *PrintW* subroutine which tries to emulate the native Print method.

----------


## Jonney

> Here's an alternative approach using the DrawTextW API function. The attached project demonstrates the use of the *PrintW* subroutine which tries to emulate the native Print method.


In your PrintW, Chr$ got error when typing Japanese.

----------


## Bonnie West

> In your PrintW, Chr$ got error when typing Japanese.


Well, I don't know Japanese but I think it won't work in the KeyPress event:




> Occurs when the user presses and releases an *ANSI* key.


I did mention this "limitation" in the instructions:




> *Type any ASCII character* to the Form
> or *paste any Unicode* text

----------


## spinsk

hey guys, im having a issue with the listview control, when i add to project and its all working fine with styles etc but once i close the main form of my app i get "runtime error 339", any ideas? thanks

----------


## JohnTurnbull

I have an installed font EPSON 行書体Ｍ and want to use it in textboxW

I use the choosefont dialog in which the name appears correctly



But when I retrieve the name in the variable Tr$, it comes out EPSON ???M not EPSON 行書体Ｍ and when I set the Text1.font.name (a TextboxW) to it, Text1 reversts to Arial

What am I doing wrong..... My code is below and works for all fonts except ones with unicode names....


Private Sub MnuFont_Click()
Dim fdata As ChooseFontType
Dim lData As LOGFONT
Dim Tr$
'..................
Text1.SetFocus
'..................preset log structure
Call StrToByteArray(Text1.Font.Name, lData)
lData.LFHeight = MulDiv(Text1.Font.Size, GetDeviceCaps(hDC, 90), 72)
lData.LFWeight = IIf(Text1.Font.Bold, 700, 400)
lData.LFItalic = Text1.Font.Italic
'lData.LFStrikeOut = Text1.Font.Strikethru
lData.LFUnderline = Text1.Font.Underline
'...................Preset choose font structure
fdata.lStructSize = Len(fdata)
fdata.hWndOwner = EditClip.hWnd
fdata.hDC = EditClip.hDC
fdata.lpLogFont = VarPtr(lData)
fdata.nFontType = &H1
fdata.rgbColors = 0
fdata.Flags = &H1 Or &H40 'Screenfonts/init to log
'....................................
If ChooseFont(fdata) = 0 Then GoTo Cancel
'================================================Text Label==================.....
Tr = StrConv(lData.LFFaceName, vbUnicode)
Tr = Left$(Tr, InStr(Tr, Chr$(0)) - 1)
Text1.Font.Name = Tr

----------


## Krool

> im having a issue with the listview control, when i add to project and its all working fine with styles etc but once i close the main form of my app i get "runtime error 339"


Without more details it is difficult to help. Is this occuring in the IDE only? Or does the executable also crash?
Is this error also occuring in a "blank" project?




> I have an installed font EPSON 行書体Ｍ and want to use it in textboxW
> 
> But when I retrieve the name in the variable Tr$, it comes out EPSON ???M not EPSON 行書体Ｍ 
> 
> [...]
> 
> Tr = StrConv(lData.LFFaceName, vbUnicode)
> Tr = Left$(Tr, InStr(Tr, Chr$(0)) - 1)


You are using the ANSI version of the ChooseFont API. Check whether the Alias of the API is "ChooseFontA" or "ChooseFontW".
The problem is that you are using a byte array in the LFFaceName member of the LogFont structure and using a ANSI API. Because if you would use the Unicode API then the Result would be already in Unicode and thus a StrConv would not be needed.

----------


## JohnTurnbull

Magic ! Thank you.

I been using basic nearly thirty years but I only just got into unicode and its like I know nothing!

----------


## jay!

Alright, I've been working with TextBoxW and the Richtextbox now over the course of a few projects and keep getting the same crash, which locks up the VB6 IDE completely and crashes the project.

After putting a TextBoxW control on the form and running the application, I can use it just fine and everything is great.  Then, I close the application, and in every project so far it has then gone to this line:

    Debug.Assert CBool(OldPointer <> NewPointer)

in the CreateSubclass sub.  I commented it out, and found the following occurred:

Out of stack space at:

Private Function Original_IOleIPAO_TranslateAccelerator(ByVal This As OLEGuids.IOleInPlaceActiveObject, ByRef Msg As OLEGuids.OLEACCELMSG) As Long
*VTableSubclassIPAO.SubclassEntry(VTableIndexIPAOTranslateAccelerator) = False*
Original_IOleIPAO_TranslateAccelerator = This.TranslateAccelerator(ByVal VarPtr(Msg))
VTableSubclassIPAO.SubclassEntry(VTableIndexIPAOTranslateAccelerator) = True
End Function

I commented out the switch lines for the VtableSubclassIPAO there and received the same error OUT OF STACK SPACE for the line

     Original_IOleIPAO_TranslateAccelerator = This.TranslateAccelerator(ByVal VarPtr(Msg))

Now it's a Win7 64bit machine, and I need these controls for working with some translation software type stuff.  I would be glad to share the project if it would help in debugging the problem for you.

Any suggestions?

Thanks a lot, and great work again on these controls, if this problem can be fixed they're going in my permanent toolbox.

----------


## Niya

There must be some kind of infinite recursion some where there.

----------


## Romeo91

> Then, I close the application, and in every project so far it has then gone to this line:
> 
>     Debug.Assert CBool(OldPointer <> NewPointer)
> 
> in the CreateSubclass sub.  I commented it out, and found the following occurred:
> 
> Out of stack space at:
> 
> Private Function Original_IOleIPAO_TranslateAccelerator(ByVal This As OLEGuids.IOleInPlaceActiveObject, ByRef Msg As OLEGuids.OLEACCELMSG) As Long
> ...


I also have in my project the same error, for example if i call the unload form *(Unload me*) *from the event key_down* (both IDE and the exe), but if I just close the form by pressing X, then unloading occurs normally. I also use the event Query_Unload and Unload.

----------


## spinsk

hi krool, sorry i figured the problem out, it was because i was using api timers that was causing the issue but i fixed it by saving project hwnd in a variable before sub classing init, however i do have another issue, im trying to add a progress bar to your status bar control via setparent then moving it into the panel i require, all works fine until i resize the form, if increase the width of the form the progress bar disappears and reappears once u release the mouse button from the resize event, also once you maximize the form the progress bar disappears all together and cannot get it back even with calling setparent api again, any idea's? thanks in advanced

----------


## Krool

> After putting a TextBoxW control on the form and running the application, I can use it just fine and everything is great.  Then, I close the application, and in every project so far it has then gone to this line:
> 
> Debug.Assert CBool(OldPointer <> NewPointer)


How do you close the application? if the above Debug.Assert is firing this is an indication of an "unclean" closure.




> i do have another issue, im trying to add a progress bar to your status bar control via setparent then moving it into the panel i require, all works fine until i resize the form, if increase the width of the form the progress bar disappears and reappears once u release the mouse button from the resize event, also once you maximize the form the progress bar disappears all together and cannot get it back even with calling setparent api again, any idea's?


There was indeed a problem in the StatusBar control. I have released an update. Thanks for your report.
Also keep in mind to use the .hWndUserControl and not .hWnd in the SetParent API. Like as following:



```
SetParent ProgressBar1.hWndUserControl, StatusBar1.hWndOwner
```

----------


## JohnTurnbull

> You can print unicode text into the intrinsic VB PictureBox.
> You just need to use an API instead of the VB "Print" command.


As well as printing unicode to a picturebox, I have a need to set the font of a picturebox to a font which has a unicode name. This result in "Invalid property Value" 

Problem would be solved with a PictureboxW control! 
Or is there some other way round this?

----------


## Krool

Update released.




> Then, I close the application, and in every project so far it has then gone to this line:
> 
> Debug.Assert CBool(OldPointer <> NewPointer)


This update might solve your problems.

----------


## Romeo91

> Update released.
> This update might solve your problems.


In my project, this solution did not help. The error in the same place. On my form I use ComboBoxW, CheckBoxW, LabelW, ToolTip now trying to understand what third-party control-collections (Analogs Frame control) affect this.

----------


## JohnTurnbull

Romeo,

I have about a dozen forms with Krools controls on them and had this problem for a while. It happens when you terminate your app from within the code of a form with the controls. 

Solution:-

Add a timer to a form which DOESN'T have Krools controls. The timer event unloads all the forms that have controls on them before unloading itself.

Never had the problem again!

----------


## Krool

> I have about a dozen forms with Krools controls on them and had this problem for a while. It happens when you terminate your app from within the code of a form with the controls.


I can't replicate the problem. Can you share a sample?

----------


## JohnTurnbull

I don't have the problem. Romeo does. Perhaps he can oblige.

Any chance of the PictureboxW sometime?

----------


## spinsk

Hi krool, that's for the update, I've come across another issue with the tabs control, when I set the alignment to bottom they appear upside down correctly in IDE but once u compile with manifest they are back to normal? Also is there a way to have the tabs align from the furthest point right instead of always left? Thanks in advanced.

----------


## Krool

> I've come across another issue with the tabs control, when I set the alignment to bottom they appear upside down correctly in IDE but once u compile with manifest they are back to normal?


I assume you mean the 'Placement' property. This property is ignored if the version of comctl32.dll is 6.0 or higher.

----------


## Romeo91

> Debug.Assert CBool(OldPointer <> NewPointer)


Krool, with the latest update, I've lost my mistake in the project.
Thank you very much.

----------


## Krool

Update released.

I just encountered that any control can receive the focus when pressing a "X" mouse button. Which should not be.
This brought me up to make a intensive test on each WM_MOUSEACTIVATE handler and I found some more bugs...
So in my opinion this is a quite important update.

----------


## JohnTurnbull

> Here's an alternative approach using the DrawTextW API function. The attached project demonstrates the use of the *PrintW* subroutine which tries to emulate the native Print method.


Hi Bonnie,

I've been using your PrintW to print unicode into pictureboxes with great success. However, when I try using it to the printer, although it executes without error, nothing gets printed at Printer.Enddoc. Any Ideas what I'm doing wrong?

Print routine code.....



```
Private Sub PrintIt(Landscape As Integer)
Dim Txt$, xx&, Tr$, yy&
Dim Lft&, wid&
'..............

If Text1.Text = "" Then Exit Sub
'....................
On Local Error GoTo SkipFont
Printer.FontName = Text1.Font.Name
On Local Error GoTo 0
SkipFont:
If Err > 0 Then Resume Here1
Here1:
On Local Error GoTo SkipSize
Printer.FontSize = Text1.Font.Size
On Local Error GoTo 0
SkipSize:
If Err > 0 Then Resume Here2
Here2:
On Local Error GoTo Skip3
If Landscape = 0 Then
   Printer.orientation = 1
Else
   Printer.orientation = 2
End If
On Local Error GoTo 0
Skip3:
If Err > 0 Then Resume Here3
Here3:
'====================================
Lft = 1000
On Local Error GoTo NoPrinter
wid = Printer.Width - 2000
On Local Error GoTo 0
Printer.CurrentX = Lft: Printer.CurrentY = Lft
Txt = Text1.Text
'=====================================
PrintLine:
If Printer.CurrentY > Printer.Height - 1200 Then
   Printer.NewPage
   Printer.CurrentX = Lft
   Printer.CurrentY = Lft
End If
Prt.Caption = ""
Do
   Tr = Left$(Txt, 1)
   Txt = Right$(Txt, Len(Txt) - 1)
   '..............................................Line ends
   If Tr = Chr$(13) Then
      '......................................Get rid of first Chr$(10)
      If Left$(Txt, 1) = Chr$(10) Then Txt = Right$(Txt, Len(Txt) - 1)
      '.....................................pass any extra Cr/Lfs
      Do
         If Left$(Txt, 1) <> Chr$(13) And Left$(Txt, 1) <> Chr$(10) Then Exit Do
         Tr = Left$(Txt, 1)
         Txt = Right$(Txt, Len(Txt) - 1)
         Prt.Caption = Prt.Caption + Tr
      Loop
      PrintW Printer, Prt.Caption   ' replacing next line
      'Printer.Print Prt.Caption
      If Txt = "" Then
         Exit Do
       Else
         Printer.CurrentX = Lft
         GoTo PrintLine
      End If
   Else
      Prt.Caption = Prt.Caption + Tr
   End If
   '.................................................End of print
   If Txt = "" Then
      On Local Error Resume Next 'Needed if doc printer is default
      PrintW Printer, Prt.Caption    ' replacing next line
      'Printer.Print Prt.Caption
      On Local Error GoTo 0
      Exit Do
   End If
   '.................................................Word wrap to printer width
   If Printer.TextWidth(Prt.Caption) > wid Then
      Do
         Tr = Right$(Prt.Caption, 1)
         Prt.Caption = Left$(Prt.Caption, Len(Prt.Caption) - 1)
         If Tr = Chr$(32) Then Exit Do
         Txt = Tr + Txt
      Loop
      PrintW Printer, Prt.Caption     ' replacing next line
      'Printer.Print Prt.Caption
      Printer.CurrentX = Lft
      GoTo PrintLine
   End If
Loop
Printer.EndDoc
Exit Sub
NoPrinter:
Resume Here4
Here4:
End Sub
```

----------


## byweb

TreeView won't raise "MouseUp" event if mouse is still. Why?

----------


## Romeo91

Good day.
It is impossible to correctly change the font for the Tooltip, after the form is loaded. I use a two monospaced fonts Lucida Console and Courier New. With the first type there is no problem, but the second font is correctly displayed only after loading a form, and if you try to change it after load form to another font (such as Lucida Console) and back again, the font changes, but not correctly displayed
I added to your project and two buttons Command5 Command6, and added to them the ToolTip.
ComCtlsDemo_TestTTFont.7z.zip  (The attached file is a .7z file with a .zip extension so it could be uploaded.)

P.S. Also I Tried to change other properties for LogFont Structure (such as LFQuality As Byte and LFPitchAndFamily As Byte), but the result (as the after form_load) not seen


*********************
Added later.
In windows 7 tooltip font can only be operated in a classical theme, in aero themes font remains unchanged and is likely to default

----------


## JohnTurnbull

Hi Krool,

Merry Xmass!

I have replaced all labels and textboxes throughout a large project and everything runs fine both in the IDE and compiled. However, I am finding it almost impossible to modify any form. If I add, delete or even rename a control, then either the IDE crashes completely or I get the...      _Debug.Assert CBool(OldPointer <> NewPointer)_  Line.

I Presume that "_Object has been modified while it is subclassed_." is the problem but How do I prevent the sub classing to modify the form?

----------


## Krool

> I am finding it almost impossible to modify any form. If I add, delete or even rename a control, then either the IDE crashes completely or I get the...      _Debug.Assert CBool(OldPointer <> NewPointer)_  Line.


I can't replicate your problem. Is this problem also occuring in the demo project?

----------


## jay!

Regarding the Debug.Assert CBool(OldPointer <> NewPointer) bug,

I was reading a Readme file by a fellow regarding a rather large subclassing project, and he got around the IDE crash problem in a rather unique way, which might interest Krool.

Basically, he used a global Boolean to determine whether the application is being run within the IDE environment, or as an executed application.

The programmer changes the global to true if its in the IDE, and the subclassing code will (in theory) skip that nasty Debug.Assert CBool(OldPointer <> NewPointer) type stuff.

Anyway, happy holidays.  :Smilie:

----------


## JohnTurnbull

No. Only in my project. In some forms, just changing the name of a control crashes the IDE.

----------


## JohnTurnbull

> Regarding the Debug.Assert CBool(OldPointer <> NewPointer) bug,
> 
> I was reading a Readme file by a fellow regarding a rather large subclassing project, and he got around the IDE crash problem in a rather unique way, which might interest Krool.
> 
> Basically, he used a global Boolean to determine whether the application is being run within the IDE environment, or as an executed application.
> 
> The programmer changes the global to true if its in the IDE, and the subclassing code will (in theory) skip that nasty Debug.Assert CBool(OldPointer <> NewPointer) type stuff.
> 
> Anyway, happy holidays.


That sounds interesting - I already do that with hooking the mouse wheel which also crashes the IDE. I set a global constant so that it is only hooked when compiled. I wouldn't have a clue how to do it with Krool's stuff though....

Over to you Krool!

----------


## JohnTurnbull

Hi Krool,

First of all, let me say that your controls really are great. They are the only way I could ever convert my program to unicode. I hope when they're finished you are going to charge for them. I for one would me more than happy to pay.

In the mean time, they do have problems when you integrate them into a major project. As I said before, I now have forms in which I cannot change a control name without crashing VB6.

If you spend as much time on your controls as I do on my Spartan multi clipboard, then you won't have had time to try the controls out in a major project. Yes - they work perfectly in the demo. No - they don't work in something more complicated. If you would like see how bad these problems are, let me have an email address and I'll give you a download URL for my project.

I am currently ignoring the forms problem as I'm sure you'll fix it. In doing so, I've come across another problem. When I change the background color of a labelw, the caption and border disappear and are not immediately redrawn by the refresh....

Public Sub Refresh()
UserControl.Refresh
End Sub

They do eventually refresh but not until the processor is released. In this form.....



The cells are labelw's. The cell the mouse is over is colored blue. as you move the mouse the next cell is colored blue and the previous blue cell is set back to white. When the cells were VB6 labels, the recoloring was instant. with LabelW s , moving the mouse quickly results in missing captions and borders....



The missing captions and borders do redraw when the mouse stops moving. But it looks really bad while the mouse is in motion. Adding a control.refresh after each change makes no difference.

PS - If you don't have a good multi-clipboard, let me know and I'll send you one!

----------


## Krool

Update released.




> TreeView won't raise "MouseUp" event if mouse is still. Why?


This update solves your problem.

----------


## SMC1979

Krool, I just wanted to give you a big thumbs up and thanks for your hard work.

I am from tweaking.com and every single program on the site I have done in VB6. My other programs on pcwintech.com I had to use 3rd party controls to get Unicode support. And I haven't added Unicode support for my apps on tweaking yet as I didn't want to have to replace every single control with a 3rd party one, and then go update all the code for the different controls.

Also I use manifest files to have any ocx and dll with the exe so I can do portable versions.

Thanks to your hard work, which I only found tonight as I am making a new program for the site, I will be able to do Unicode easier than ever and be able to use these controls for now on, reducing the size of the setups and portable versions thanks to not needing to have the MS ocx files. (Example, I just needed a listview in a program yet I had to have the large ocx (1.01 MB) file with it just for the one control)

From one programmer to another you have my respect. Keep up the good work.  :Smilie: 

Now time to try your controls out in the new program (And hopefully reply all the programs on the site with them). If you ever have a email list or something so I know when you make a new version you can sign me up!

Enjoy the new year :-)

-Shane

----------


## Krool

I just added a "note" on the first post about error trapping as this could be a common "problem".

In order to trap error raises via "On Error Goto ..." or "On Error Resume Next"  it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error Trapping.
The actual problem is that the option "Break in Class Module" (which is the default one on a fresh VB6) just effects class modules and not usercontrols.

Example:


```
On Error Resume Next
RichTextBox1.LoadFile "xyz"
MsgBox Err.Number
```

When the option "Break in Class Module" is selected it is not possible to trap the error in above example which results always in a crash.
But when the option "Break on Unhandled Errors" is selected the error is trapped and you can evaluate the Err.Number.

----------


## SMC1979

Would it be possible to add the .span command to the richtextbox control? It is missing and I need it for a command I am using to color key words.

----------


## Krool

Update released.




> Would it be possible to add the .span command to the richtextbox control? It is missing and I need it for a command I am using to color key words.


The .Span method is not a build-in feature of the rich edit control.
I don't know how exactly this is working and how to re-build it.
If somebody knows how, please let me know.  :Smilie:

----------


## Bonnie West

> ... However, when I try using it to the printer, although it executes without error, nothing gets printed at Printer.Enddoc. Any Ideas what I'm doing wrong?


Sorry for the delay!  :Blush:  I haven't been able to test the PrintW subroutine with a printer until now. That sub, indeed, does nothing when printing to a printer. Although the DrawTextW API returns success and Err.LastDllError returns 0, nothing ever gets sent to the printer. I really don't know why. Sorry...  :Frown:  You might want to try some other method of printing Unicode text instead.

----------


## Krool

Update released.

Important bugfix when using the RichTextBox control as the UserControl_Terminate event did not fire..

----------


## Almeida

Have just downloaded the stuff and liked it very much, but... When I click Custom property of ToolBar component Automation error occures and then all the things go wrong and eventually IDE crushes.

What could it possibly be? Is it on my side only?

----------


## Krool

> When I click Custom property of ToolBar component Automation error occures and then all the things go wrong and eventually IDE crushes.
> 
> What could it possibly be? Is it on my side only?


Did you included the property pages into the project? Which OS are you using?

----------


## Almeida

I forgot to mention that I was experiencing this problem right in the Demo Project from the original archive. The line where the error occures is the last line of the code snippet below. The module of the Sub is PPToolBarGeneral.pag



```
Private Sub PropertyPage_SelectionChanged()
Dim i As Long
FreezeChanged = True
With PropertyPage.SelectedControls(0)
CheckEnabled.Value = IIf(.Enabled = True, vbChecked, vbUnchecked)
CheckVisualStyles.Value = IIf(.VisualStyles = True, vbChecked, vbUnchecked)
CheckDoubleBuffer.Value = IIf(.DoubleBuffer = True, vbChecked, vbUnchecked)
For i = 0 To ComboMousePointer.ListCount - 1
    If ComboMousePointer.ItemData(i) = .MousePointer Then
        ComboMousePointer.ListIndex = i
        Exit For
    End If
Next i
Dim ControlEnum As Object
If ImageListEnumerated(0) = False Then
    For Each ControlEnum In .ControlsEnum
```

I have WinXP SP3. Do you think the problem may lie in one of the system files or VB6 itself? How can I make sure that all the necessary files (e.g. stdole2.tlb, etc) and VB6 with its IDE are up-to-date on my machine? Where can I see this sort of information?

Btw, same problem with CoolBar too. Yet, the page properties of some other components do open without troubles.

----------


## Krool

Is the demo running? Means that you "only" have problems with certain property pages?

----------


## Almeida

Demo runs but without XP-styles and it does it only once. Re-running it causes fatal crush of IDE with a "memory can't be read" error. Am I in a big trouble with a glitchy Windows? This OS has been serving me for years but recently it has started acting up on different occasions. I've been procrastinating on installing a new one but it seems like the time has finally come.

Adding On Error Resume Next statement allowed me to run the property page, but with empty ComboImageList and all the images lost. Surprisingly, EXE from the original CommonControls.vbp was created successfully which let me take a good look at all the components in action.

If I do install a new system, please give me your advice on how to secure the latest (or known for its stabity rather) VB6. Will following this arcticle's steps do in your opinion?
http://inthiaano.com/2013/10/07/vb6-updates/
Or could you tell me about your enviroment? Is everything stable and smooth on your maching?

----------


## Krool

It is normal that within the IDE there are no XP-Styles as you need a VB6.exe.manifest for getting this to work.
Is the EXE running without problems?
Have you tried re-installing vb6?
Maybe there is really a damage on your OS as you already assume.

----------


## Almeida

Yeah, it's a likely case. I really can't see what I can do apart from reinstalling OS or trying the projects in another "virgin" enviroment. But can't afford it at the moment. But after I do this I will report the outcome. Thank you for your support and the great work done! And yeah... EXE is working fine, I really loved the components  :Smilie:

----------


## Krool

Update released.

Quite important bugfix when using the RichTextBox control.

----------


## dr_efendi

Hello Kroll,
How to compile the source code to (for example) comctl.ocx?
Can you give us the guide?
Thank you very much.

----------


## quicken

i just want to thank you "Krool" your unicode controls really helped me
 i wish you luck

----------


## chosk

Hi Krool,

Thank you very much for your work on the Common Control Replacement.

I am trying out the DataTimePicker and may have stumbled on a bug. This is what I did.

In your VBP demo, I added a DTPicker2 and add the following code:

Private Sub DTPicker2_Change()
   MsgBox "change"
End Sub

I ran the project and clicked on DTPicker2 to pop up the Calendar.
When I clicked on any date in the calendar, the MsgBox fired and I closed it.
The MsgBox immediately fired one more time and I closed it again.
It should fire only one time.

When I clicked on the "<" button on the calendar to go to the previous month,
the MsgBox fired and I closed it. Then immediately, it fired repeatedly and
I have to go to Task Manager to kill the VB6 process.

The same happened when I clicked on the ">" button to go the next month.

----------


## quicken

hello Krool 
why when i use unicode controls in my project, the IDE crashes after first run? giving this error "CBool(OldPointer <> NewPointer)"
but in demo sample it doesn't get that error, i cant really find what is the problem..

----------


## Krool

Update released.

Included the modeless dialogs "Find" and "Replace" in the CommonDialog class.
Unlike the "Find and Replace Common Dialogs" from vbAccelerator these have no issues with the tab keys.
Also mine support multiple modeless dialogs at the same time. But only one per CommonDialog class.
Means that each "single" class can only run one modeless "Find" or "Replace" dialog at the same time.
Sample usage is demonstrated in the RichTextBox Demo.




> How to compile the source code to (for example) comctl.ocx?


You mean of how to create a ActiveX Control project?




> I am trying out the DataTimePicker and may have stumbled on a bug. This is what I did.
> 
> In your VBP demo, I added a DTPicker2 and add the following code:
> 
> Private Sub DTPicker2_Change()
>    MsgBox "change"
> End Sub
> 
> I ran the project and clicked on DTPicker2 to pop up the Calendar.
> ...


I have researched this and it seems to be by "design" that the change event (DTN_DATETIMECHANGE) does fire sometimes twice.
And also can cause a loop when for instance showing a MsgBox in the change event as the DTPicker did not receive until then a MouseUp event.
I did a little workaround to fix this and it should be the same behavior now as the original control.




> why when i use unicode controls in my project, the IDE crashes after first run? giving this error "CBool(OldPointer <> NewPointer)"
> but in demo sample it doesn't get that error, i cant really find what is the problem..


It is impossible to help you without knowing the details of your project.

----------


## quicken

thank you for your replay krool
i don't know what was the problem, but i replaced controls with updated controls (one of the modules) and my problem solved... thanks again

----------


## chosk

Hi Krool,

Thank you very much. I appreciate it.

----------


## quicken

hello krool

*I searched the internet and i fund this code :*
http://www.Planet-Source-Code.com/vb...59434&lngWId=1

i don't know have you seen this code or not but it would be grate if you do something like this in your unicode controls...

----------


## chosk

Hi Krool,

I have just replaced 16 ccrpDTP with your DTPicker.ctl and removed ccrpDTP6.ocx and ccrpUCW6.dll. I have also replaced 4 UpDown with your UpDown.ctl and removed ComCT232.ocx. I am moving on to a lot more from ComCtl32.ocx.

One question I like to ask is that to mimick the DTPs from MSComct2 and ccrpDTP that prevent the mouse wheel from changing the date, I have REM out the following in DTPicker.ctl:

Case WM_MOUSEWHEEL from Function WindowProcControl
and
Case WM_MOUSEWHEEL from Function WindowProcCalendar

Is there any side effect that I should be aware of by doing this?

----------


## Krool

> *I searched the internet and i fund this code :*
> http://www.Planet-Source-Code.com/vb...59434&lngWId=1
> 
> i don't know have you seen this code or not but it would be grate if you do something like this in your unicode controls...


Thanks. I took a look on this and it seems it works via DLL. (ActiveX DLL Project)
And the point is that I don't want this project to have a dependency on any .ocx or .dll.





> One question I like to ask is that to mimick the DTPs from MSComct2 and ccrpDTP that prevent the mouse wheel from changing the date, I have REM out the following in DTPicker.ctl:
> 
> Case WM_MOUSEWHEEL from Function WindowProcControl
> and
> Case WM_MOUSEWHEEL from Function WindowProcCalendar
> 
> Is there any side effect that I should be aware of by doing this?


You can delete the WM_MOUSEWHEEL handler if you want. No side effect.

----------


## chosk

Hi Krool,

I am moving on to ImageList and encounter "User-defined type not defined" on the following line in ImageList.ctl:

Private PropListImages As ImlListImages

----------


## chosk

Hi Krool,

Please ignore my previous post. I forgot to add the ".cls" files. Sorry.

----------


## chosk

I Krool,

May I ask whether you have plan for a replacement of the MSINET.OCX?

----------


## chosk

Hi Krool,

I am into the last 4 Listviews to replace, having already done many simple ones. For these last 4, I have already got the proper numeric sorting to work. Cell text forecolor should be easy to implement. But I can seem to get alternate ledger color to work. The one I was using utilizes subclassing but it is not working now. Since your controls use a lot of subcalssing, I thought maybe I find some other method. So I search an old source I am familiar with and found it:

http://vbnet.mvps.org/index.html?cod...l/lvledger.htm

I have changed the following in the code:

If lv.View = LvwViewReport Then (from If lv.View = lvwReport Then)
Dim itmX As lvwListItem (from Dim itmX As ListItem)

I REM out he following:
lv.Visible - because this doesn't work after ListView is passed to a Sub (lv as ListView...)

I ran the project, the text in the ListView show up as expected but the alternate ledger color does not work.
I tested with the ListView from MSCOMCTL.OCX and it works.

May I ask is there some thing I need to look at?

----------


## Krool

Update released.




> I REM out he following:
> lv.Visible - because this doesn't work after ListView is passed to a Sub (lv as ListView...)


This works now.




> I ran the project, the text in the ListView show up as expected but the alternate ledger color does not work.
> I tested with the ListView from MSCOMCTL.OCX and it works.
> 
> May I ask is there some thing I need to look at?


There was a problem that the '.Image' property of the PictureBox was directly passed to the Picture property of the ListView. But this case is now solved in the update.
Keep in mind that the Picture property requires comctl32.dll version 6.0 or higher in order to work.

But you could just use for this case the 'ItemBkColor' event. (?)
This sample will make a red background color of every second ListItem.


```
Private Sub ListView1_ItemBkColor(ByVal Item As LvwListItem, ColorRef As Long)
If Item.Index Mod 2 Then ColorRef = vbRed
End Sub
```

----------


## chosk

Hi Krool,

Thanks for the update.

.Visible now works after ListView is passed into a Sub.

Silly me. Didn't realise ItemBkColor exists in your ListView ctl. Been too used to MS's that I did not think of this. This makes it so much easier. Now I can even implement Alternate Ledger Color on ListViews where I could not. This is fantastic.

Now I am left to find ways to do stuff I did with msinet.ocx and I should be free of com registration problem that Win8 is causing a lot of pain.

----------


## chosk

I just like to update that I have replaced the use of msinet.ocx with MSXML. It is pre-installed in WinXP SP3 and later (up to Win8.1) and can be installed in WinXP SP2 with Windows Installer. The important thing for me is it has the option to use Username and Password which is what I need.

http://msdn.microsoft.com/en-us/data/bb291077.aspx

The only controls I have not replaced are those "basic" ones that come pre-installed in VB6 - label, command button, frame, check, option, combo, text. Am I right to understand that these do not require "addition" dependencies outside of the VB6 runtime and the few that are Windows system files?

----------


## Krool

> The only controls I have not replaced are those "basic" ones that come pre-installed in VB6 - label, command button, frame, check, option, combo, text. Am I right to understand that these do not require "addition" dependencies outside of the VB6 runtime and the few that are Windows system files?


Yes, you are right. No "addition" dependencies. There are included in the msvbvm60.dll.

----------


## chosk

Thanks Krool.

----------


## chosk

Hi Krool,

I have a statusbar panel that show time. When leave the windows in the same size, the time update over-write and gets garbled. Meaning time is 02:37, when it gets to 02:38, the 8 over-write the 7. When it gets to 02:40, the 4 over-write the 3. Resizing the windows will clear the garble.

No sure whether the date have the same problem. Did not have a chance to wait so long.

It will be good also if can show AM and PM.

----------


## Krool

Update released.




> I have a statusbar panel that show time. When leave the windows in the same size, the time update over-write and gets garbled. Meaning time is 02:37, when it gets to 02:38, the 8 over-write the 7. When it gets to 02:40, the 4 over-write the 3. Resizing the windows will clear the garble.


Indeed there was a updating bug, which is fixed now. Thanks

----------


## JohnTurnbull

Hi Krool,

Sorry! - another bug but easy to reproduce.



```
Tr = StrConv(Tr, vbFromUnicode)
Text1.Text = Tr
```

Tr is a unicode string containing Hebrew. Text1 is a Textw control.

If the date / time format is english...



The text displays correctly....



But if the date /time format is Hebrew...



The text is corrupt....



The same fault if Date /time is set to Russian, Greek and several other languages.

The fault only occurs with Hebrew and the only affecting factor is Date/Time format

John Turnbull
M8 Software Support
Saturday 22nd February
10.35am UK time.

----------


## Krool

> Sorry! - another bug but easy to reproduce.
> 
> 
> 
> ```
> Tr = StrConv(Tr, vbFromUnicode)
> Text1.Text = Tr
> ```
> 
> Tr is a unicode string containing Hebrew. Text1 is a Textw control.


Why do you use StrConv? That might be the reason why you loose the unicode chars.

----------


## JohnTurnbull

> Why do you use StrConv?


To convert it to chars from unicode!  Tr is retrieved from a file where it was previously saved using StrConv(Tr, vbUnicode)

There is no problem with my code! It works perfectly in English, Russian, Chinese and Arabic. It only fails in Hebrew and then only when when The Windows date format is Hebrew, Russian or Greek. The screen shots in my last post are genuine. When the date format is English, the textw displays correctly. When the date/time format is Hebrew, it does not. There are no other factors affecting the problem.

----------


## JohnTurnbull

Create a form
add a textboxw
add a command button

Add code



```
Option Explicit
Dim Tr$

Private Sub Command1_Click()
TextBoxW1.Text = StrConv(Tr, vbFromUnicode)
End Sub

Private Sub Form_Load()
Tr = "հиԷѰ꼸  е  ٰٸ  |   бܹԶڸ,   Ѽ۸- ܰѸѰڸ,   ռѰ۸- ڸ,   ռѰ۸- ްйӶڸ.   հԸռ  ԷӼѸ  Ըеܼ,   в  |   и۴   "
End Sub
```

Click command1 with English date/time - No Problem
Click command1 with Hebrew date/time - Rubbish

----------


## Schmidt

When to use StrConv...




> To convert it to chars from unicode!


StrConv is the Uni-to-ANSI (or ANSI-to-Uni) Helper-Function of VB6.

And with: StrConv(Tr, vbFromUnicode)
you definitely perform a (potentially, and locale-dependent) *lossy* conversion from Unicode-Content to ANSI.

Krool is absolutely right.

As soon as true Unicode-Controls are in use, StrConv is not needed at all anymore 
(aside from converting old Textfiles which were stored in ANSI-format in a given Locale,
to Unicode-content, using the right (matching) LCID as the second Parameter of the StrConv-function).

StrConv is for *legacy* stuff, for TextData stored in an old non-unicode-format.

As soon as you have true Unicode-Content in your VB-Strings, you can pass them 
directly into the W-capable Controls - and to persist them, you store their contents 
either in unicode-capable Databases, or in Textfiles in UTF-16-Format (directly possible 
in VB over an intermediate ByteArray) - or in UTF-8 (possible per WideCharToMultiByte-API - 
and definitely *not* per StrConv-Function).





> Tr is retrieved from a file where it was previously saved using StrConv(Tr, vbUnicode)


As just said, this is absolutely wrong, since StrConv doesn't work lossless as a Text-Encoder/Decoder,
when changes in the User-locale are involved (exactly the thing you're provocing with your change 
between Hebrew and English in the appropriate Dialogue).




> There is no problem with my code!


Maybe, but with your Unicode-Handling and usage of the Strconv-Function there are definitely problems you will encounter,
as soon as you provoce different locale-settings.

Let's maybe start-up with a correctly formatted Unicode-String, set-up per ChrW-construct.
(and let's not ask for the moment, from what datafile it was retrieved ... wherever it came from, it is correct and now sitting in a VB-String, OK?



```
Option Explicit

Dim UniHeb As String

Private Sub Form_Load()
  'different Uni-ChrW-Test-Sets on Dr-Unicodes site: http://www.cyberactivex.com/unicodetutorialvb.htm
  UniHeb = "HEB: " & ChrW(&H5D1) & ChrW(&H5E8) & ChrW(&H5D5) & ChrW(&H5DB) & ChrW(&H5D9) & ChrW(&H5DD) & _
               " " & ChrW(&H5D4) & ChrW(&H5D1) & ChrW(&H5D0) & ChrW(&H5D9) & ChrW(&H5DD)
End Sub
```

Now put that string directly (without any StrConv-functions) into the Unicode-Textbox.

I'm pretty sure that the TextBoxW1 will *always* render the correct and same result,
no matter what you change in the Dialogue you mentioned.

What now remains is, to talk about correct persisting and retrieval of this 
String-content (either as UTF-16-file of as a somewhat more efficient UTF8-File).

Olaf

----------


## JohnTurnbull

Hi Olaf,

That's all very interesting. Unfortunately, the source of Tr$ is format 13 from the Windows clipboard which is pure unicode. The Windows clipboard does not provide a UTF 8 or UTF 16 format.

John Turnbull
M8 Software Support
Sunday 23rd February
9.13am UK time.

----------


## Krool

> That's all very interesting. Unfortunately, the source of Tr$ is format 13 from the Windows clipboard which is pure unicode. The Windows clipboard does not provide a UTF 8 or UTF 16 format.


Then StrConv shouldn't be necessary?

----------


## JohnTurnbull

Hi Krool,

You're right of course. The reason for the conversion is that before I show it in the textboxw, I have to strip out leading carriage returns and trunctate it to also show in a label. This is much easier to do after scrconv.

Anyway, looks like it's my problem not yours! Just very strange that it only happens with Hebrew. I guess the answer is to keep two copies, the original unicode for showing in textboxw and the strconv for everything else.

Sorry to trouble you.

John Turnbull
M8 Software Support
Sunday 23rd February
10.00am UK time.

----------


## Krool

Yes. StrConv can cause some troubles on certain settings.

For example on japanese system there are also problems. 
The reason is due to the fact that even the ANSI strings on japanese systems are also 2-byte and not 1-byte. So when using StrConv the 2nd byte is lost.

----------


## JohnTurnbull

Thanks to Schmidt and Krool for all help. One last piece of advice please.

Before rewriting (which is a huge job) I tried adding my LCID (English United Kingdom) to all StrConv functions and that has cleared the problem! I am now testing through all other languages. If you can think of a situation where this might not work, please let me know so I can test it out.

John Turnbull
M8 Software Support
Sunday 23rd February
11.22am UK time.

----------


## Schmidt

> Unfortunately, the source of Tr$ is format 13 from the Windows clipboard which is pure unicode. The Windows clipboard does not provide a UTF 8 or UTF 16 format.


The *Windows*-Clipboard does support UTF-16 (in Write- and Read-Direction), when CF_UNICODETEXT = 13 is used...

Unfortunately the *VB*.Clipboard does not support this Format-Constant (only the ANSI-Constant CF_Text = 1 is supported).

So, to place and retrieve VBs internal W-Strings directly on and from the clipboard, you will need (in the same way as with unicode-capable Controls) a Clipboard-Class which supports Unicode (there's stuff in the CodeBank or also on PSC for that, but vbRichClient also has a cUniClipBoard-Class).

So, with Unicode-capable Controls and an Unicode-capable Clipboard you have some helpers which will allow you "to ban" VBs ANSI-conversion-functions entirely from your App...
You can place and retrieve VB-Strings directly (to and from Controls or an UnicodeClipBoard-Class) and thus "work entirely in W-Space".

As said, you only need to take care, when you pull String-Content "from elsewhere" (e.g. the FileSystem or the Web) into that "W-Space" - or when you want to "export" String-Content from your "W-Space" into the FilesSystem or into "Web-Formats" (as e.g. HTML or XML).

When you export into the FileSystem, then DBs are usually safe, because the ADO-layer already is "W-capable" - as well as the OleDB-driver-layers - and finally the DB-Backends too.
Plain-Textfiles should be written into with either UTF-16 or UTF-8 (and their appropriate BOMs to make retrieval easier for others, when such a "Hint" is contained in the first Bytes of a plain-text-file) - and for putting out VBs WStrings into XML or HTML, there's appropriate Header-Tags for either UTF-16 or UTF-8 as well...

Glad to hear, that you were able to fix your current issues by forcing the StrConv-functions to act "under guidance" of an explicitely given LCID now - but that's only a temporary fix (in my understanding) on your way to a true unicode-capable Application, since you are essentially still dealing with ANSI in your App.

If you're still unsure about things I just wrote above, then maybe post a new Thread for that in the normal Forum - maybe with a concrete problem (with concrete Text-Content) - but if you do so, try to describe exactly, where the String-Content in question really had its very origin - and what potential conversions this String-Content may already have undergone on its way into your VB.String-Variable...

To conclude again - try to ensure a "clean W-Space" in your unicode-capable App.
Working "within W-Space" (normal VB-Strings as transport-containers) is absolutely easy, when you use Unicode-capable Controls and an Unicode-capable Clipboard - you can pass String-Content directly then (without StrConv).

The only thing you need to take care of is, when the "borders to your W-Space" are passed (when you pull from Web-or XML-content or from the Filesystem).

Olaf

----------


## Krool

> Unfortunately the *VB*.Clipboard does not support this Format-Constant (only the ANSI-Constant CF_Text = 1 is supported).
> 
> So, to place and retrieve VBs internal W-Strings directly on and from the clipboard, you will need (in the same way as with unicode-capable Controls) a Clipboard-Class which supports Unicode (there's stuff in the CodeBank or also on PSC for that, but vbRichClient also has a cUniClipBoard-Class).


_I think there is no problem with VBs Clipboard function. Just pass CF_UNICODETEXT into Clipboard.GetFormat()/GetData(). It will return a byte array (Unicode) which can be casted to a string._

Edit: Scratch this... this works only with the OLE DataObject in UserControls.
So it is necessary to use the Clipboard APIs in this case.

----------


## JohnTurnbull

Hi Folks,

We're going off at a tangent here. I don't have a problem with the clipboard! I save and replace all clipboard formats using the API.

I only have a problem displaying a unicode clip to the user. To do that, I take a small extract from the clipboard data and save it as a separate file to the clip itself. This file contains one of the following - If unicode format 13 is present,the first 1000 bytes from that. If not present, the first 1000 bytes from format 1 (plain text) or a thumbnail if the clip is graphic.

This small file is necessary because the preview has to load and display a clip as fast as the user moves his mouse over the grid of clip names. The preview file is further complicated by the fact that it also contains a long representing the color to display the clip name and a smaller, 50 byte extract to display as the clip name itself. That extract has to have any leading spaces or carriage returns removed. It's length is also adjusted by length of text depending on font, as it has to be displayed in a grid of LabelWs. Both the name and preview texts are either trimmed to length if the real clip is longer or padded with spaces if shorter so that they can be saved to the file with fixed lengths for easy retrieval.

The entire system was developed without unicode support about fifteen years ago. In the last six months I have replaced textboxes and labels with Krool's controls. By using StrConv on the extractions, I can keep all the existing text processing intact. OK, it's perfectly possible to trim, pad and process unicode strings directly but that would be a massive re-write. (The find and replace to add the LCID to strconv resulted in over 100 changes!) So, obviously, If adding LCID to the strconvs works, I am going to stick with it..... So far, no problems.

John T

----------


## JohnTurnbull

Is there any way to tell if a user has selected "Right to left reading order" in a textboxW ?

----------


## Schatn

Hello Krool,

I really love the work you've done here! Been looking for something like this for some time now  :Smilie: 

I know you intended this to be integrated into the programs so one wouldn't need any dependencies, but still, is there any way you'll be releasing this an OCX version?

----------


## Romeo91

Friends, I was not the first time I've heard the request and questions regarding ocx-version. For what it is you what their applications for drag additional files? And yet, and register them in the system. Here the project with a fully open source (also very convenient directory structure of the project), and all this without any problems embedded in the code of any of its projects. Adding common modules (bas) and classes (cls), necessary for correct operation, and add the dates you control (ctl), every control lie in a separate folder.
I do not know about you, but I always disliked ocx-controls

----------


## Krool

> Is there any way to tell if a user has selected "Right to left reading order" in a textboxW ?


Check for the extended style WS_EX_RTLREADING.

----------


## JohnTurnbull

> Check for the extended style WS_EX_RTLREADING.


Thank you!

John T

----------


## Romeo91

Good day .
Very often when I look at the code of your project ( the code of the project do not change ), I get an error that has previously been mentioned repeatedly
    Debug.Assert CBool ​​(OldPointer <> NewPointer)


This occurs when the main form is opened and you open any control. And when you exit the control ( push X ) I get an error .

Ide protection enabled you default .
I understand that the control is updated , and the project is redrawn from scratch, but why there is an error , elsi nothing changed . As with many other projects of this did not occur. Maybe something is wrong in sabsclassing ?
One can get around this ?

Repeatedly pressing F5, can lead to performance of the project, or a hang or error.
When you close the project, VB reports a change of the main form and offers to save it. But does not save, and shows the same error.

----------


## Krool

> I get an error that has previously been mentioned repeatedly
>     Debug.Assert CBool ​​(OldPointer <> NewPointer)
> 
> 
> This occurs when the main form is opened and you open any control. And when you exit the control ( push X ) I get an error .


You shouldn't do that. (Opening and closing the .ctl)
Reason is because of subclassing and the .ctl gets "interrupted" when you open the .ctl while it is subclassed.

An solution is to make an .OCX out of the project. Then the .ctl are not "changeable" anymore and thus do not crash.  :Eek Boom: 

Or just be careful and don't open the .ctl.

----------


## chosk

Hi Krool,

I see in your listview example where the sort arrow is applied. I can see in your sample how you put the sort arrow in "EnumColumn.IconOnRight = True". In non-Visual Theme mode, I am getting a *big* arrow in the ColumnHeader even though I made the arrows 16x16 in the ImageList. Your sample show a small arrow. No problem when running in Visual theme as I think Windows may handle that - small arrow at centre top of columnheader. 

I have tried looking but still must be missing a setting or two somewhere and I can't seem to find out where. Appreciate if you could give me a pointer.

Thanks.

----------


## chosk

Hi Krool,

I just made my arrow 8x8 and this is much closer to yours. I think this is the trick?

----------


## Krool

> I just made my arrow 8x8 and this is much closer to yours. I think this is the trick?


Yes. Keep in mind that arrow image (custom one via image list) is needed only when version of comctl32.dll is 5 or lower. It is not dependent on whether visual styles are enabled or not.

----------


## chosk

Hi Krool,

Thanks for the confirmation.

And yes. Indeed my comctl32.dll is version 5.82.7601.17514 in my install of Win7 x86. I was looking at the ComCtlsSupportLevel function and must have gotten a "0" back (< ver 6) since the arrows were used.

Thanks.

----------


## Krool

> And yes. Indeed my comctl32.dll is version 5.82.7601.17514 in my install of Win7 x86. I was looking at the ComCtlsSupportLevel function and must have gotten a "0" back (< ver 6) since the arrows were used.
> 
> Thanks.


You have to use a manifest in order to use comctl32 version 6. Then you have not to use a custom arrow anymore.

----------


## chosk

I do use a manifest in the res to use ver 6 so that the compiled exe will run with "new/modern look" theme in XP and later. When I run the project in the VB6 IDE, the project GUI look like Win2000 and earlier, therefore the custom arrow.

(I know I can use a manifest for VB6 IDE, but the color palette in properties is one of the thing that will not work and the IDE may be slower.)

----------


## Bonnie West

> (I know I can use a manifest for VB6 IDE, but *the color palette in properties is one of the thing that will not work* and the IDE may be slower.)


You could use the Color Palette window instead:

----------


## dr_efendi

> You mean of how to create a ActiveX Control project?


I mean: how to compile your codes to be one activex control,
for example comctl.ocx.
Because I could not change your codes target to be activex control.
I wish I can create project will refer to the ocx (of your codes), not with including your file codes.
I hope you understand what I mean.
Thank you.

----------


## Krool

_Obselete_

----------


## Schmidt

Thanks for the OCX-version - also managed an ocx-compile (about half a year ago, trying to "promote" it a bit in the german forum on ActiveVB):
http://foren.activevb.de/archiv/vb-c...g-mit-Windows/

And whilst it worked for me at that time on both - my Win7-machine and within a XP-VM, there seemed to be no success on the other users system.
"Error whilst loading a Dll" (Fehler beim Laden einer Dll).

Funnywise I now can reproduce that exact error (as reported in the german forum-thread) here on a newer Win8-Notebook (running VB6/SP6 - reproducable with both versions - my older compile - and yours is not starting up as well - even in an otherwise empty, virginal VB6-StdExe-project, as soon as you want to check-out the compiled OCXes over the Component-Dialogue).

Would be great, if that could be resolved somehow, because having a binary COMponent is (IMO) always preferrable - especially with such large code-bases - and as soon as the COMponent-Classes have reached (more or less) stable interfaces. There's just easier and faster coding in the IDE - more stability (since the SubClassing-stuff now runs compiled in its own Binary) etc...

Olaf

----------


## chosk

The reason I use these non-OCX ctls is maybe the same reason you now having on Win8. My program setup created with InstallShield was not installing properly on Win8 although it had done so reliably on Win7 and earlier. After running the setup, on first launch, would get an "Application-defined or object-defined error". I know this to be related to ActiveX and OCX not properly registered into the Windows Registry. No matter how I looked at the InstallShield setup, I am unable to find the problem. I even retained the use of having the string "setup" in the setup file name (example MyProgsetup.exe) as recommended by Microsoft and it worked to overcome registration problem in Vista, but not Win8. So I went searching for non-OCX replacement and I am glad I found this.

I read through this thread and I see some requests to make this an OCX but from my reason, I would rather prefer it the way it is - just ctls and compiled into the same program exe. Now I just copy the exe into any other Windows PC, even Win8, and it just run. The VB6 runtime and other system required files are already pre-installed into Windows and I can comfortably forget about the dreaded ActiveX/OCX registration in Win8.

----------


## Schmidt

Potential problems with the deployment of OCXes (as well as their weird OCA-caching-mechanisms and their complicated siting-calls) is one reason I prefer ActiveX-Dlls over OCXes.

Though I'm still deeply convinced about the advantages of COM-*Components* vs. direct usage of huge Code-Bases in a Project (especially when those involve SubClassing).

For me it's quite important to have fast Startup-Times and a reliable debugging of the current ("clean, small and unrelated") Project-Sources I work on.

That's the Background which would make an OCX-version of Krools Sources desirable.

But preferences differ, that's for sure - and the "All-in-one-Exe"-goal seems to be some kind of "obsession" in the VBClassic-community (for no apparent reason).  :Wink: 

Olaf

----------


## chosk

> But preferences differ, that's for sure - and the "All-in-one-Exe"-goal seems to be some kind of "obsession" in the VBClassic-community (for no apparent reason).


It is not an obsession, it is survival. With Windows 8, removing ActiveX and OCX is a necessity as many will find out in time. I accepted the shock, the disappointment, found a solution and move on. I can't express how much I want to thank Krool to make this possible.

----------


## chosk

Duplicate post removed.

----------


## Schmidt

> It is not an obsession, it is survival. With Windows 8, removing ActiveX and OCX is a necessity as many will find out in time.


No, a binary Component-Technology which is class-based and offers self-describing Interfaces
(in our case this is COM and TypeLibs) is a Plus - and this technology is definitely *not* 
broken in Win 8 and Win 8.1.

COMponents are (in my opinion) far under-used in the VBClassic-community - hence my comment about 
the "obsession" to put everything but the kitchen-sink (as code-modules) into one Mega-Std-Exe-Project.
That's (especially since techniques like RegFree-COM are available for years now) just "not how it's done".

When we look at things from an engineering-perspective, then you will have (in case complexity increases) 
to split-up into more managable parts, which - when done right - are even reusable in similar scenarios
or the next project with a simple mouse-click (a check-in over the Components- or References-Dialogue).




> I accepted the shock, the disappointment, found a solution and move on. 
> I can't express how much I want to thank Krool to make this possible.


Yes, Krools-Tools offered a way out of the breakage of interfaces (not COM itself) a thing which was
caused by the *vendor* (MS), and happening the second time already (after the ADO-interface-trouble) - 
that's (for such a big vendor with a huge set of test-cases and -tools) either plain stupid - or was done
deliberately, just to spread a little more FUD among the members of the VB6/VBA community...

In either case COM (the Component-Technology) was never broken at all.
MSHFlex.ocx, MSWinsock.ocx, scrrun.dll, the MS-XML-components ... as well as ones own,
VB6-generated COMponents, all work as before also on Win8.

If a COMponent doesn't properly install on a given OS, blame the people who are responsible
for this Component (and its Typelib-Interfaces or 2nd-level-dependencies) - don't blame the 
Component-Technology itself - so far MS refrained from "fiddeling" with *that* can of worms 
(since this would break also their own Office-products and huge parts of the industry).


Olaf

----------


## chosk

> No, a binary Component-Technology which is class-based and offers self-describing Interfaces
> (in our case this is COM and TypeLibs) is a Plus - and this technology is definitely *not* 
> broken in Win 8 and Win 8.1.
> ...
> ...
> If a COMponent doesn't properly install on a given OS, blame the people who are responsible
> for this Component (and its Typelib-Interfaces or 2nd-level-dependencies) - don't blame the 
> Component-Technology itself - so far MS refrained from "fiddeling" with *that* can of worms 
> (since this would break also their own Office-products and huge parts of the industry).


Nah, I never say COM was broken in Win8/8.1. Never did. I just say InstallShield (MSI) setup have problem installing COM components in Win8/8.1 when it never had such problem with Win7 and earlier.

I was only trying to share my experience with you since you did mentioned you had problem installing (your own compiled of Krool's into OCX 6 about half a year ago and now) in Win8. I am sorry that I even tried to share.

Blaming anyone (others or myself) for COM components not properly installed is no use. Blaming will not make COM components install properly. Only a solution can. I have been looking for a solution for many months and I found it here. Thanks for your side of opinion but it really doesn't help solve the problem on Win8.

 I don't wish to dwell on it. You can have the last words if you want. I am moving on. Thanks anyway.

----------


## Krool

_Obselete_

----------


## Krool

_Obselete_

----------


## chosk

Hi Krool,

If I understand correctly,...
1) I put CCR32.OCX into a Win7x86 C:\Windows\System32 and registered it.
2) Open VB6, create a project with CCR32.OCX, put some of the controls on the form.
3) I add CCR32SideBySide.res into the project so that this file will be compiled into the exe.
4) I copy Project1.exe and CCR32.OCX to a thumbdrive and plug into my Win8x64 ASUS notebook.
5) I copy the files onto the desktop. (Same result if I just run from thumbdrive).
6) I run Project1.exe

Error:



> The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.


Windows Event Viewer:



> Activation context generation failed for "C:\User\...\Desktop\Project1.exe". Error in manifest or policy file "C:\User\...\Desktop\Project1.exe" on line 36. Invalid Xml syntax.



I did the same for CCR32SideBySideAndVisualStyles.res and same thing. This time the error in on line 41.

----------


## Krool

Ok, you are testing on Win8.
I did some research and please try following on your notebook:




> You miss a Visual C++ runtime.
> 
> Run the Command prompt with admin rights and run this command:
> 
> SxsTrace Trace -logfile:SxsTrace.etl
> Now run the programm which causes the SideBySide error.
> 
> Go back to the command prompt press ENTER to generate the SxsTrace.etl. Now type this:
> 
> ...

----------


## chosk

Copy and paste now from my Win8 notebook, D: is thumbdrive:




> =================
> Begin Activation Context Generation.
> Input Parameter:
> 	Flags = 0
> 	ProcessorArchitecture = Wow32
> 	CultureFallBacks = en-US;en
> 	ManifestPath = D:\Project1.exe
> 	AssemblyDirectory = D:\
> 	Application Config File = 
> ...


I did the same on my Win7x86 desktop, after unregistered the CCR32.OCX, similar problem.

----------


## Bonnie West

@ chosk

You may want to try dilettante's Make My Manifest tool.

----------


## chosk

I tried that before some time back, and another one I cannot remember the name. Did not work for me. Actually now I don't need this as I prefer the Krool's trouble-free non-OCX version. I am helping Krool to test out his Reg-Free OCX solution for others' preference of choice. Since I can help (in testing) since I have Win8, I will help.

----------


## Krool

> I tried that before some time back, and another one I cannot remember the name. Did not work for me. Actually now I don't need this as I prefer the Krool's trouble-free non-OCX version. I am helping Krool to test out his Reg-Free OCX solution for others' preference of choice. Since I can help (in testing) since I have Win8, I will help.


You said it also dont work on Win7...
By me its working. Can somebody else test?

----------


## jpbro

It works for me on Win7 32-Bit. I used your compiled OCX, then created a project with a component reference to it, added the .RES file and a couple of controls, compiled, and ran with the OCX and the EXE in the same folder on a different computer. No problems.

Unfortunately, I don't have Win8 to test.

----------


## chosk

Finally able to upload attachment to the forum here. Hope I am doing it right becos can't seem to find where to attach in PM. The only file nt in the zip is the OCX that I downloaded from this link:

 this CCR32.OCX compilation

----------


## Krool

> Finally able to upload attachment to the forum here. Hope I am doing it right becos can't seem to find where to attach in PM. The only file nt in the zip is the OCX that I downloaded from this link:


Ok, now it get's funny.
First, I got the same error. (Side-by-side configuration error)
But then I just recompiled the project again (build Project1.exe) and then it worked. Huh?
Recompiliation was done under WinXP SP3 (VM) and then tested on Win7. Just for info.

----------


## chosk

Same vbp, frm, res and ocx. The only diff is my compile vs your compile. Is there any required (system) file that is required for the compile not in my system but in yours? Or diff version, whatever. May never know.

I compile mine on a Win7 x86. No longer has WinXP box.

----------


## jpbro

I compiled on WinXP, and had no problems. I don't have VB6 on a non-XP computer, so I can't test after compiling under a different OS unfortunately.

Just thinking out loud here - I vaguely recall reading something about the length of a manifest needing to be a multiple of 4 bytes. Maybe this only holds true for certain OSes, and that's why we're seeing the discrepancy? For example, Krool's manifests are 5446 and 5711 bytes long, so if you add some space padding to the end to make them multiples of 4-bytes long, then try recompiling, it might make a difference (assuming Krool didn't already make the manifest lengths multiples of 4-bytes in the RES files)?

Kind of a shot in the dark, but maybe worth a try.

----------


## Krool

I compiled now on a Win7 x86 and tested on another Win7 x86 and it worked.

----------


## Schmidt

Here my two cents...

Good news:
- the regfree-approach works here (on a virginal Win 8 as well as on a Win 8.1 box) - 
- found the cause for the error which prevented loading as a normal (registered) OCX into the IDE 
..("Fehler beim Laden einer Dll" -> "Error whilst loading a Dll")

Will post the steps I undertook, which led to success with the regfree approach first - 
then in another posting, what caused the Error with normal Loading of the OCX into the VB-IDE

Update: The instructions below (for regfree-usage ) refer to the latest version VBCCR10, which now 
doesn't show the above Error: "Fehler beim Laden einer Dll" -> "Error whilst loading a Dll" ... anymore.

1) ... The approach below doesn't use the posted *.res Files, but works with the manifest-string directly:
.......(the latest one for VBCCR10, which Krool posted further below - here it comes again :Smilie: 



```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <file name="VBCCR10.OCX">
      <typelib tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" version="1.0" flags="control" helpdir="" />
      <comClass clsid="{8601688A-5AE4-4E72-A048-5B98B803FC8C}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.CommonDialog" />
      <comClass clsid="{5B319054-D9B4-4983-8C19-58335FAC0296}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{E0788311-759B-407C-A929-91B42E90E616}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.UpDown" />
      <comClass clsid="{2B5F079B-5CAD-4CFE-B1E4-0063AED55A1F}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{41BA8A4F-52EA-437C-AE89-C576D2BE37C9}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.TreeView" />
      <comClass clsid="{6F605BD6-03A1-4BF3-AB55-138C0C71F039}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ToolTip" />
      <comClass clsid="{7DF3862A-0CA7-4AF8-87DA-14BB5318086E}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{14E704AD-ADCC-4E76-9A2E-83CA38A87071}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ToolBar" />
      <comClass clsid="{F655539D-290C-488B-A471-7A7477FD610C}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{6CDFC3B6-16C1-49CA-9A38-B8D0191CF4E5}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.TextBoxW" />
      <comClass clsid="{BF54A588-7D1D-45DE-A48E-0761D4F0CDFE}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{B3BCDCAB-AE3B-4899-A2FE-FE82C3E3AD33}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{121486A6-1B27-4FA2-9D8C-E42E4F0E0FC7}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.TabStrip" />
      <comClass clsid="{92AAD9D1-5900-4731-91D7-E705BA287B9F}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{A773E4A9-C2B5-4979-89EB-F402F747ECE2}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.SysInfo" />
      <comClass clsid="{C20F53B2-057C-42C9-8A2E-D3CCA7D03F0C}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{98722513-DE25-405F-AC64-9E22C0BC92C7}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{4DD49DF3-BE23-412C-A66B-220FFF0E07CE}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.StatusBar" />
      <comClass clsid="{33EC5301-1481-4F3B-91C7-4CC86583669B}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.SpinBox" />
      <comClass clsid="{8855093C-AA41-4896-A397-4A501B2342FF}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{9B2C0845-B5C2-42D4-8896-4DF5F6126C43}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{7A606FF5-E223-4DDD-B10C-0A463F7FF34D}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.Slider" />
      <comClass clsid="{F3467CCA-E75C-4EC5-BE6A-40E486588111}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{00F78EA7-39A3-454C-8766-DC0877EAB3FD}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{1E9AC570-5A92-43CB-B0AC-BB25D1E071AD}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.RichTextBox" />
      <comClass clsid="{5462ED0C-09AA-4BAC-AC89-209C3BC135A5}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ProgressBar" />
      <comClass clsid="{E47F59C0-DB10-4FEA-8479-014543A1592A}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{84220344-EC4D-46FA-B93D-5D91A71EEBBF}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.Pager" />
      <comClass clsid="{E1D2F892-E2AB-434D-8848-7988DB01D1D7}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{78C7ACA3-1296-4B30-B0F4-C9BEF8189CF3}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.OptionButtonW" />
      <comClass clsid="{1426112E-FC90-443C-926A-A14EE3153C6A}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{EBC1EBF3-5BB7-44FA-99A0-E9B394BEEE79}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.MonthView" />
      <comClass clsid="{5A48F961-8784-49B4-A33D-EB791FF03C29}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.MCIWnd" />
      <comClass clsid="{450F0581-ED76-4FD0-80A6-EBF9C2BEED28}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{144F607D-E50F-457E-80C8-AF8FCEEBEF97}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ListView" />
      <comClass clsid="{9E3840CE-655C-4750-9B91-659DB66236C2}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{D0209DF7-7E21-4F16-9AAC-04569170D8A6}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{6715850E-C5A1-4402-834F-876B58364BFB}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ListBoxW" />
      <comClass clsid="{86457A21-B800-4093-A5F5-19B6642597CA}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.LabelW" />
      <comClass clsid="{9E7DB98B-8F1E-4FA0-9CC9-CF0CF10BAD02}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.IPAddress" />
      <comClass clsid="{4EFAA401-3A2D-49CB-AEA2-C3646D308191}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{E0FF485A-B64B-4A09-BD06-FFA31B8B86A8}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ImageList" />
      <comClass clsid="{67A86DAB-5588-4848-B07E-ECF9C3345F4E}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{9B8F26EB-0E78-4CF1-8A3F-DF14C182B7DD}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ImageCombo" />
      <comClass clsid="{ECC8AD11-6EF4-4879-BB4D-8DA679891A79}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{46CFA4F3-32FA-4748-B626-C58F419D52A0}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.HotKey" />
      <comClass clsid="{8B8D0C2A-E6F2-48F7-B906-508AE305FAB0}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.FrameW" />
      <comClass clsid="{C2DBF8B6-D42E-4D00-A649-CD8CF26D5D67}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{EA330ADD-7A77-4BBC-831A-4A026437F1CA}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.DTPicker" />
      <comClass clsid="{1B36B5A7-1155-4CCA-BF93-85E46CF3C03B}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.CoolBar" />
      <comClass clsid="{BD3F1035-9250-4D15-B110-A6054B3A9B7D}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{5AD3A4E3-C85F-4EC3-BE37-69B306BED1F6}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{6A70B990-3D4E-411A-8FE6-B6C8CC020018}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.CommandButtonW" />
      <comClass clsid="{78DBE8D4-B938-44DE-B514-B4B3558C79CE}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.ComboBoxW" />
      <comClass clsid="{76BCBCAE-6822-48E4-B6CC-50DF6128F2F0}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.CheckBoxW" />
      <comClass clsid="{5B432C6C-DF42-4370-A98A-14E82AB2EEFE}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" />
      <comClass clsid="{C59E1C4C-F305-42F8-AD0F-03F8022A171D}" tlbid="{CE08B9D4-381D-4D40-B699-E8352BA50128}" threadingModel="Apartment" progid="VBCCR10.Animation" />
   </file>
</assembly>
```

2) then make sure, you use the matching OCX-binary, downloadable here:
http://krool.dyndns.org/Data/VBCCR10/VBCCR10.OCX

3) To work around potential limitations of the VB6-Resource-Addin, I wrote a small Tool, 
... which is able to apply Plain-Text-Manifest-Files directly into a given Binary.
http://vbRichClient.com/Downloads/Manifester.zip
Just compile the small Manifester.exe from the contained sources - and after that
you can create a Link to it on your Desktop.

4) Unregister any other previous CCR-OCXes (in case you have any) on your machine - 
... and then Register the correct one you downloaded under 2)

5) Open a VB6-IDE-StdExe-project - check-in the "Common Controls Replacment"-Component 
... and drop a few of Krools Controls onto the Form - > compile the Project.

6) Close the IDE (any IDEs) which might reference a CCR-OCX.

7) Unregister the VBCCR10.OCX

8) DoubleClick (Start) your new compiled Executable which contains the few CCR-Controls.
... (this should fail now with "Component missing...", because the  VBCCR10.OCX was unregistered)
...  please make very sure at this point, that it *does* fail - otherwise the next steps will not make sense.

9) To make it work, place the compiled Executable in the same Folder as the (still unregistered) VBCCR10.OCX

10) Finally you only need to apply the Manifest-String-Content within your Executable (not the OCX)
...  using the already mentioned Manifester-Tool under 3)... just drag&drop the Executable either 
...  onto the Manifester-Link on your Dektop - or directly onto the Manifester.exe.
...  Now choose (I've already created a Textfile with the right content) the 'VBCCR10-regfree.manifest'
...  which is already contained in the Manifester Zip (or -Folder) 
...  The Manifester-Tool will give you a message, when the attempt succeeded (or failed)

11) If the above step was successfully confirmed - then the right resource is now in your Executable
...  DoubleClick it again - it should now run (remember, VBCCR10.OCX is still unregistered - 
...  you might check that from within a newly loaded VB6-IDE in the Components-Dialogue

12) To perform an opposite check, you can now remove the Manifest-Resource again from 
...  your Executable - drop it again on the Manifester, but cancel the File-Dialogue (choose no *.manifest).
...  Then answer the MsgBox which asks you if you want to remove the resource, with "Yes".

13) If you now DoubleClick again, the good old "Component missing/not registered" message should pop up.
...  (thereby proving, that there was no successful "Auto-Registering" involved, which is built-in into an 
...   upstarting VB-Executable when the matching OCX is sitting in the same Folder - though that mechanism
...   worked only up to XP - and not anymore on Vista and greater...  

Ok, hope these detailed steps work reliably also for others... as said, at least on two very new virginal 
machines (8.0 and 8.1) it made no problems (didn't test on Win7 or XP).

Olaf

----------


## Schmidt

Ok, regarding the error which prevented loading as a normal (registered) OCX into the IDE
... throwing a message like: ("Fehler beim Laden einer Dll" -> "Error whilst loading a Dll").

This should be reproducable on any machine, when you ensure the following:

- There should be only one version of CCR32.ocx registered on your machine (in only one place 
.. in the FileSystem

- Now try to find the matching CCR32.oca (if you have or find any, usually this is placed beside the *.ocx)

- Delete this typelib-cache (the *.oca-File) - and forget about it - it will be re-created automatically

- Finally (and that's the main-point) rename (temporarily) 'OLEGuids.tlb' (hopefully this is registered
. and sitting in only one single place in the FileSystem) ... e.g. to 'OLEGuids.tlb_'

Now (remember that the OCX is still registered, which normally should be the only necessity  
for a successful loading into the IDE) - start a new IDE with an empty StdExe-Project and 
try to Select the 'Common Controls Replacement' entry from the Component-Dialogue.

It should fail now.

So, that means that somewhere in the Public Interfaces of all the Public Classes or Public Ctls
(maybe even in the PropPage-Files, not sure) there's a Type exposed (in a Parameter, or a
Return-Value of a Public Procedure or Property or also in an Event) which doesn't belong there 
(because it is defined in OLEGuids.tlb, which should be used only internally, in Modules, 
Private- or Friend-Classes and not on the Public OCX-interface).

That's something of a task, to find this needle in the haystack - maybe Krool has a good idea
where to look first - or maybe some assistance from one of the better IDE-plugins (which should
be able to report, what type is used where) can shorten the time to find the culprit.


Olaf

----------


## Schmidt

> I just say InstallShield (MSI) setup have problem installing COM components in Win8/8.1...
> I was only trying to share my experience with you


Sorry, but the above statement doesn't contain much useful information...
(what issues exactly? ... and with all COM-compontens or only a few - or a single one mayhap?)

Just did a search in the official IS-forum for win8+problems and there's no bigger stuff found - 
the 3 "worst sounding issues" I have listed below, but in all cases the reason was either 
a too old version - or the user of the tool:
http://community.flexerasoftware.com...t=win8+problem
http://community.flexerasoftware.com...t=win8+problem
http://community.flexerasoftware.com...t=win8+problem





> since you did mentioned you had problem installing (your own compiled of Krool's into OCX 6 about half a year ago and now) in Win8.


No, I didn't mention that - I've compiled Krools stuff into an OCX, to help Users in a german Forum.
And the issue was not an install-problem (the registering was successful in all cases) - 
it was a Problem with loading the OCX from the Component-dialogue (or not correctly upstarting
*.vbp - which referenced the  correctly registered version, but still were reporting the same error
as when trying to load the OCX directly from the IDE-Dialogue.

No installer, no installshield - heck I'm not even using Krools Tools at all personally.




> I am sorry that I even tried to share.


You shared only a blurry information about "mysterious-install-shield-issues" - 
nothing to be sorry about.




> Blaming anyone (others or myself) for COM components not properly installed is no use. 
> Blaming will not make COM components install properly.


Now, that's not funny anymore - I've never talked about install-issues - or blamed anyone
about "improper COM-installations" - I was talking about people who (involuntarily perhaps)
disencourage COMponent-*usage* generally by promoting the "Everything in one Exe"-model.

What you wrote further above:



> ...I would rather prefer it the way it is - just ctls and compiled into the same program exe. 
> Now I just copy the exe into any other Windows PC, even Win8, and it just run. 
> The VB6 runtime and other system required files are already pre-installed into Windows 
> and I can comfortably forget about the dreaded ActiveX/OCX registration in Win8


... had this tendency - and so I made my reply as a kind of counter-weight - and IIRC
I was not getting personally whilst doing so.

Olaf

----------


## Krool

> So, that means that somewhere in the Public Interfaces of all the Public Classes or Public Ctls
> (maybe even in the PropPage-Files, not sure) there's a Type exposed (in a Parameter, or a
> Return-Value of a Public Procedure or Property or also in an Event) which doesn't belong there 
> (because it is defined in OLEGuids.tlb, which should be used only internally, in Modules, 
> Private- or Friend-Classes and not on the Public OCX-interface).


The property "GetOLEInterface" in the RichTextBox control is referring OLEGuids.tlb.
I think that is the only "Public" contact with the OLEGuids typelib.

However, there is another problem I just encountered. When using the RichTextBox control from the CCR32.OCX then the .exe will crash during unload. ("MSFTEDIT.DLL access violation")
But this is only happening on WinXP. On Win7 it works...

The "Everything in one Exe"-model works the RichTextBox without any problem. WinXP and Win7.
Also the whole thing works up in W2K.

I am getting to dislike the .OCX experiment.  :Confused:

----------


## Schmidt

> The property "GetOLEInterface" in the RichTextBox control is referring OLEGuids.tlb.
> I think that is the only "Public" contact with the OLEGuids typelib.


Then this needs to be wrapped up in a dedicated Class, and then this Class should be  
exposed as the Return-Value (if there's still an interest in the OCX-version).




> However, there is another problem I just encountered. When using the RichTextBox control from the CCR32.OCX then the .exe will crash during unload. ("MSFTEDIT.DLL access violation")
> But this is only happening on WinXP. On Win7 it works...
> 
> The "Everything in one Exe"-model works the RichTextBox without any problem. WinXP and Win7.


I'd not state it this way... 
"Works without any problem" is too strong for my taste (when it's known to crash in the OCX-Variant) 
"Works despite a problem which became apparent now" would be a better formulation.  :Wink: 




> I am getting to dislike the .OCX experiment.


I wouldn't give up that fast - the regfree deployment-approach (and test) already worked out 
quite well and is encouraging - now we only have to fix the RTBox-issues and find potential
other occurences of "exposed Typelib-Types".

Then a "Version 1" of the OCX could be made available (together with a matching manifest
for regfree deployment) ... and a release-cycle of "any half a year" or so could be introduced - 
throwing out another filename for the OCX then, which includes the version-number (to not 
collide with existing older binary versions of the OCX which could be met "out there in the wild"
(already working "well enough" for the purposes these older versions are used for in somebodys
application).

Olaf

----------


## chosk

Hi Krool,

I hit a problem. I was testing my software on Win8 x64 and the TabStrip tabs appeared garbled. I could not see the tabs although I can use the arrow keys to switch from tabs to tabs.

Then I tried to simulate the problem using with a sample project with only the TabStrip and 12 tabs with images, like how mine look like. Because I have a lot of codes and also I use quite a lot of the controls, I actually put all your controls in the sample project although I only use the TabStrip and ImageList for the sample. I remember last week I tested my software with 6 tabs and images on Win8 x64 and there was no problem.

Here is the screen capture of the problem.

----------


## chosk

I just tested my software and the above sample on Win7 x64 and no problem.

It appears that the tabs are stacked one atop another vertically in Win8 x64. From the screen shot, starting from the bottom is the body of the TabStrip (white color) and then above it is the first tab also white color (with rect selected mark) stretched to full width. Then above it are the other 11 tabs.

----------


## Krool

> I remember last week I tested my software with 6 tabs and images on Win8 x64 and there was no problem.


So you are saying with 6 tabs it is working on Win8 x64 and with 12 tabs not?




> However, there is another problem I just encountered. When using the RichTextBox control from the CCR32.OCX then the .exe will crash during unload. ("MSFTEDIT.DLL access violation")
> But this is only happening on WinXP. On Win7 it works...


I know now how to fix this problem.  :Smilie: 
Also I was able isolate the exposed OLEGuids places. (to solve the "Error whilst loading a Dll")




> I am getting to dislike the .OCX experiment.


I am now quite optimistic that soon there is a stable .OCX release.  :Smilie:

----------


## chosk

> So you are saying with 6 tabs it is working on Win8 x64 and with 12 tabs not?


Yes. This is correct.

Update:
For the benefit of forum readers, Krool PMed me simple suggestion by adding 1 or 2 line of refresh in the ctl file to fix this problem. I tested as suggested and it works now in Win8 x64.

Thanks Krool for the fast response.

----------


## chosk

Hi Krool,

A question on ListView.

In visual-theme, when a ListView column is sorted, all the rows in that column will be "highlighted" in that the background for that all rows background in that column become light gray. Whereas the other columns/rows still show the alternate ledger colors.

I believe this is Windows default. Can a this be changed somehow?

In non visual-theme, that is in Win2000 style, the sorted column is not highlighted in light gray.

----------


## Krool

> Update:
> For the benefit of forum readers, Krool PMed me simple suggestion by adding 1 or 2 line of refresh in the ctl file to fix this problem. I tested as suggested and it works now in Win8 x64.


In the next update I will publish the solution for everyone.

----------


## chosk

When I add an icon to CommandButtonW Picture and set PictureAndCaption to True, only the icon will appear not the text. Set Alignment to vbLeftAlign and pull the button longer the text won't show. Not sure what else I need to set.

----------


## Krool

> When I add an icon to CommandButtonW Picture and set PictureAndCaption to True, only the icon will appear not the text.


I just tested that and it worked by me.

----------


## Krool

_Obselete_

----------


## chosk

> I just tested that and it worked by me.


Using your demo to test. Win7 x86.

----------


## Krool

> Using your demo to test. Win7 x86.


The property needs comctl32 version 6.1 or higher and your IDE is linked (currently) to version 5. (No manifest of VB6.exe)

----------


## chosk

OK I get now.

I am aware you have a manifest in res for the compile exe so I compiled and run the exe and it works. Thanks.

----------


## Schmidt

> OK I get now.
> 
> I am aware you have a manifest in res for the compile exe so I compiled and run the exe and it works. Thanks.


And in case you want the "comctl32 version 6"-capabilities also in the IDE - you can use either a manifest 
for VB6.exe (VB6.exe.manifest) ... already known I assume ... though the method which works by placing 
the manifest-file in the same Folder was not working for me anymore for the VB6-IDE on Win8. 

What *did* work on Win8 was beaming the manifest-infos directly into the VB6.exe-File - relatively easy 
to accomplish, when you compile the Sources of the small Manifester.vbp-Tool I've posted a Link to recently.

Since the Programs-Folder has a quite tight security-behaviour - I've had to:

Make a Copy of VB6.exe into another Folder (I've placed the copy on my Desktop).

But from there one can drag the copy of the VB6.exe-File and drop it on Manifester.exe - or better:
a Link to Manifester.exe (I created a Link to it on my Desktop, along with regsvr32-Links for register
and unregsiter - all with Admin-rights-settings, earlier achieved over the Lnk-Context-Dialogue).

The dropping will cause an upcoming Dialogue -> choose the manifest-file: "CC6-minimalistic.manifest"  
as the one to incorporate into the dropped VB6.exe-File.

Maybe rename the original VB6.exe in its Programs-SubFolder to 'VB6.exe.orig' to keep it "as it was" -  
and then just move the "manifested" VB6.exe from your Desktop back into the \Programs\...\VB98-Folder.

That's it already - pretty styles shining up all over the place - Krools stuff working as it should -
and "world-peace-all-over" (Ok, until you open the ColorBox-Dropdown <g> - but Bonnie adressed 
that already in a recent post here in this Thread).

To remove the manifest, either resort back from 'VB6.exe.orig' - or use the VB6.exe-file which
contains the manifest-resource - and follow the steps as described above again - only this 
time do not choose any manifest-files - just cancel the up-popping dialogue...

Olaf

----------


## chosk

> And in case you want the "comctl32 version 6"-capabilities also in the IDE - you can use either a manifest 
> for VB6.exe (VB6.exe.manifest) ... already known I assume ... though the method which works by placing 
> the manifest-file in the same Folder was not working for me anymore for the VB6-IDE on Win8. 
> 
> ...
> ...


Also doesn't work for me anymore in Win7 too. I used to do it in WinXP (I skipped Vista). That's why in the VB6-IDE, I am not seeing the pretty styles and have to compile every time to check the conversion I make.

I will give your advice a try later when I take a break. I am converting the labels, textbox, options, checks, buttons, combo and listbox.

Yes, Bonnie did address the color palette in an earlier post.

----------


## chosk

Success! The VB6 IDE looks so sexy now! I miss it for a long time.

----------


## Krool

_Obselete_

----------


## SuperDre

> Since the Programs-Folder has a quite tight security-behaviour - I've had to:


Just install it into another folder other than 'Program Files', i even have a folder names 'Program Files (no nagging)' LOL.. Looks like a program files folder but works without all the stupid moronic behaviour of the 'Program Files' folder which was introduced with Vista.. I still never understood why MS changed it, as it was the one of those stupid decisions they made as it's so easily circumvented by just not installing in that folder...

----------


## chosk

There is this question on my mind for the last few weeks and I am not really at ease if I don't know what I should do. So I will try and ask.

For about 9 years, I have been using the following codes in my VB6 projects so that the controls get the sexy XP-theme look. As you are all aware, this sexy visual-theme continues into Vista, Win7 and now Win8. No doubt will still do for future version of Windows.

The 2 sets of codes I use are as follows:

1) Ensure your application link to Comctl32.dll 
http://www.vbaccelerator.com/home/VB...VB/article.asp

In addition to the manifest, also these codes:




> Private Type tagInitCommonControlsEx
>    lngSize As Long
>    lngICC As Long
> End Type
> Private Declare Function InitCommonControlsEx Lib "comctl32.dll" _
>    (iccex As tagInitCommonControlsEx) As Boolean
> Private Const ICC_USEREX_CLASSES = &H200
> 
> Public Function InitCommonControlsVB() As Boolean
> ...


2) Preventing crashes at shutdown
http://www.vbaccelerator.com/home/VB...wn/article.asp




> Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
> Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
>     ByVal lpLibFileName As String) As Long
> Private Declare Function FreeLibrary Lib "kernel32" ( _
>    ByVal hLibModule As Long) As Long
> 
> Private m_hMod As Long
> 
> Private Sub Form_Initialize()
> ...



So far, I have been using these codes with the comctl32.ocx and of course linked to comctl32.dll and there been no problem. Linked and no crash on exit. The questions I like to ask are:

1) With the all-in-one exe, are the codes still needed.
2) Any harm if I just leave them in there as they are?
3) Or I should remove them?

Note: I know there is a "SetupVisualStyles Me" in the Form_Load of all forms. Is it doing the same purpose? I look at it may not be but of course I am not sure.

Thanks.

----------


## Krool

> 1) Ensure your application link to Comctl32.dll


The equivalent in the "all-in-one" exe are the functions "InitVisualStyles" and "SetupVisualStyles".
The "SetupVisualStyles" also fixes some issues. Details can be found here.




> 2) Preventing crashes at shutdown


The code "LoadLibrary("shell32.dll")" is only necessary when a custom UserControl is involved in the Std-EXE.
All my Common Controls are loading this library also. See the functions "ComCtlsLoadShellMod" and "ComCtlsReleaseShellMod".




> 1) With the all-in-one exe, are the codes still needed.
> 2) Any harm if I just leave them in there as they are?
> 3) Or I should remove them?


There should be no harm when you keep yours also.
You can replace yours with the "InitVisualStyles" and "SetupVisualStyles" functions as because of the "fixes".

----------


## chosk

Hi Krool,

Thanks for your explanation.

I have converted all the controls over to your all-in-one controls. Conversion also include those basic controls like CommandButton, CheckBox, OptionButton, Frame, Label, TextBox. Those in comctl32.ocx and comct232.ocx were the first to be converted earlier. The only ones I cannot convert and there is actually no need to are the PictureBox and Image.

I have seen the functions you mentioned and I will now remove the codes I have been using since they no longer serve any purpose.

Thanks again.

----------


## chosk

Here is an update to the complied res problem I had in post #241 where I always encountered "Invalid XML Syntax" error on the 2nd last line of the manifest file:
http://www.vbforums.com/showthread.p...=1#post4626989

I wanted to include 48x48, 32x32 and 16x16 icons in both 256 and 32-bit color variant in order to give the app a "proper" icon in modern Windows:
http://www.vbaccelerator.com/home/VB...ly/article.asp

This means that I will have to re-compile the existing res file. This pose a problem since I am now always getting the "Invalid XML Syntax" every time I compile a res file. So, I did searches over the weekend on my res problem on the Internet but all in vain. The common search result was missing a Visual C++ file. Tried installing from MS website the 2005 and 2008 version no use.

Then I started looking at the manifest and the the compiled res file sizes. Up to now I am using a res compiled by rc.exe some years ago. If I were to compile again now and use it, I will get the Invalid XML syntax error. So I check the size of the old and new compiled res files. The old file is 788 bytes and new one is 792 bytes. The strange thing is both are compiled from the same unchanged manifest file so how can there be this difference. My conclusion is somehow something is padding that extra 4 bytes and this triggered the Invalid XML syntax.

So I experimented with the manifest file. I removed all formatting and put them into 5 lines each begining and ending with respective tags in one line. I make sure the manifest file size is divisible by 4 exactly. Example below, some items removed and "_and ending with_" added for clarity:




> <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
> <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="... ..." type="win32" />
> <description>........ _and ending with_ </description>
> <dependency><dependentAssembly><assemblyIdentity ... ... ...  /></dependentAssembly></dependency>_and ending with_</assembly>


Note: above line 5 <dependency> ... to ... </assembly> is 1 line only.

Compiled and viola success! Sexy-theme and no more Invalid XML syntax.

Then I added the lines:




> // Icons for this application
> AAA      ICON    MOVEABLE        PRELOAD         MyProg.ico


so that the rc file is now:




> #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
> #define RT_MANIFEST                     24
> #define CONTROL_PANEL_RESOURCE_ID       123
> 
> CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST             "MyProg.exe.manifest"
> 
> // Icons for this application
> AAA      ICON    MOVEABLE        PRELOAD         MyProg.ico


Compiled and viola success! Sexy theme and proper "bigger" 32x32 icon in the Windows task bar, not the upscale from 16x16 pixelated one.

ps: I know this is not the proper place/thread but on a by-the-way-basic, may I like to ask for confirmation from experts here whether what I done to the rc script to include icon is it the correct and proper way. Although it runs as I wanted it to, it is always better to get this vetted so that neither myself or anyone who use this will not get an expected surprise.

----------


## SuperDre

Are you sure the problem isn't with the older RC.exe maybe not supporting 32-bit icons? try loading a 32bit icon as a form icon and you also get an error in VB. Just like the later windows don't support the older iconlibraries anymore (which really is a stupid thing)..

----------


## chosk

The problem (Invalid XML syntax error) is not due to the older RC.exe although I am using the same older RC.exe that came with VB6 before and now. I use the same RC.exe to compile the re-edited rc script and resultant res now works.

The 32-bit icon is a new thing I tried now and not related to the Invalid XML syntax error. By the way, this "proper icon" trick in fact does wonder to the "professional look" of VB6 apps. I just realised that the icon at the bottom left of the Windows Explorer in Win7 shows the 48x48 icon. Previously it was the ugly pixelated upsize of the 16x16 icon.

----------


## Krool

This is the 1.0 ActiveX Control version. (End of support)

_Removed_

----------


## Romeo91

> 10-Mar-2014
> - Minor bugfix in the TextBoxW control.
> - Some component modifications. (it is recommended to replace everything)


Krool thanks for your last update. Now there is no problem in the IDE even when opening the control and not have to constantly restart VB.

----------


## chosk

Hi Krool,

I understand that min WinXP SP2 is required for the all-in-one, please correct me if I am wrong. I also understand you running the controls all okay in WinXP.

I have 3 users showing the following same issues in WinXP (one of them I know is SP3):

1a) Tabstrip showing only the first tab stretched all the way horizontally.
1b) The other 11 tabs cannot be seen.
1c) The tabstrip body is shown correctly.
1d) One is using "classic" theme, the other two using "blue" XP-theme.

2a) The one using "blue" Xp-theme, all other controls showing in sexy theme but CommandButtons showing in classic.
2b) All have CommandButton showing only the icon, no text. I understand comctl32.dll 6.1 required.

I am guessing both issues could be due to not having comctl32.dll v6.1. I tried searching the Internet on how to get this version into WinXP, either a certain Windows patch or update, but unable to find any answer.

Do you or anyone knows?

----------


## Krool

> I am guessing both issues could be due to not having comctl32.dll v6.1. I tried searching the Internet on how to get this version into WinXP, either a certain Windows patch or update, but unable to find any answer.
> 
> Do you or anyone knows?


There is no way to get comctl32.dll v6.1 on WinXP.




> 1a) Tabstrip showing only the first tab stretched all the way horizontally.
> 1b) The other 11 tabs cannot be seen.
> 2a) The one using "blue" Xp-theme, all other controls showing in sexy theme but CommandButtons showing in classic.


1a+b) Please provide a demo showing the issues as I cannot replicate them in WinXP.
2a) Is it a CommandButtonW control? If yes, then ensure that the "VisualStyles" property is set to True.

----------


## chosk

Hi Krool,

I don't have WinXP so I did a test project with the controls shown in the screenshots and sent the exe to 2 users to run and screenshot.

Beside the controls, I add all 3 modules in the Common folder and the 2 modules and 4 classes in the Build folder. VisualStyles for all controls are set to True. The only code I add is as follows and nothing else:




> Private Sub Form_Load()
>     SetupVisualStyles Me
> End Sub


Here are the screen shots I got back from 2 users of WinXP SP3.

----------


## Krool

As already mentioned the "PictureAndCaption" property needs at least Windows Vista.
For the other issues. Please upload the demo project in order to make tests on it.

----------


## chosk

Oh Windows Vista. OK I see now. Means comctl32.dll 6.1 follows the Windows versioning. 6.1 = Vista.

Attached is the test project.

----------


## Krool

> Oh Windows Vista. OK I see now. Means comctl32.dll 6.1 follows the Windows versioning. 6.1 = Vista.


No. Vista is NT 6.0. Win7 is NT 6.1.
But the comctl32.dll version on Vista is 6.1.

----------


## chosk

OK. Now I know the actual details, should not have use icons by default for all the CommandButtonW.  I will research whether I can check for comctl32.dll version and then Select Case either to or not to use the ".Picture" and ".PictureAndCaption" properties in Form_Load.

----------


## Krool

> OK. Now I know the actual details, should not have use icons by default for all the CommandButtonW.  I will research whether I can check for comctl32.dll version and then Select Case either to or not to use the ".Picture" and ".PictureAndCaption" properties in Form_Load.


You can use the "ComCtlsSupportLevel" function and if the result is equal or higher than 2, then you can use the "PictureAndCaption" property.



```
If ComCtlsSupportLevel() >= 2 Then [...]
```

----------


## chosk

Thanks. I just tested this on Win7 and it works. The CommandButtonW1 does not have a picture by default. Now it is better I fix up a WinXP box and do all the testing.



```
If ComCtlsSupportLevel() >= 2 Then
    CommandButtonW1.Picture = ImageList1.ListImages(1).Picture
    CommandButtonW1.PictureAndCaption = True
Else
    CommandButtonW1.PictureAndCaption = False
End If
```

----------


## Krool

I just tested on WinXP concerning the classic CommandButtonW appearance and it seems that if the ".Picture" property is used (in WinXP only) then the appearance is always classic. So this is not a bug, it is a "feature" in WinXP.

Concerning the "vertically stack" problem on the TabStrip control. I could not replicate it. Does a extra "Me.Refresh" or/and "DoEvents" in the CreateTabStrip sub solves this issue on the concerned machine?

----------


## chosk

> Concerning the "vertically stack" problem on the TabStrip control. I could not replicate it. Does a extra "Me.Refresh" or/and "DoEvents" in the CreateTabStrip sub solves this issue on the concerned machine?


I am not sure whether I can go back and forth with them. Just receive another one, this time from the look it is either Vista or Win7. I think I have to remove the TabStrip and use another control. Maybe I try TreeView.

----------


## Krool

> I am not sure whether I can go back and forth with them. Just receive another one, this time from the look it is either Vista or Win7. I think I have to remove the TabStrip and use another control. Maybe I try TreeView.


Please check if my suggested solution will help. Thanks

----------


## chosk

I put DoEvents in the first location and also after the Me.Refresh in second location. I sent the exe over to test and came back same problem.

----------


## chosk

The one I did not know whether Vista or Win7, it is Vista Home Premium and the test (with the DoEvents) came back Tabs stack vertically.

To retrace the issue:
1) Initially, when I tested on my Win8 with 6 tabs, no problem.
2) I increased to 12 tabs, on my Win8 they stack vertically starting from the bottom.
3) I added the Me.Refresh, problem on my Win8 solved.
4) I did not have a WinXP to test.
5) I sent out updates.
6) Problem reported on 3 WinXP (so far) and 1 Vista Home.

----------


## chosk

I am researching on the Internet on CreateWindowEx TabStrip and usually see the WS_EX_LEFT as an included parameter. I did a find for WS_EX_LEFT in the CreateTabStrip proceedure and did not find any.

What is this and what does it do?

----------


## Krool

> I am researching on the Internet on CreateWindowEx TabStrip and usually see the WS_EX_LEFT as an included parameter. I did a find for WS_EX_LEFT in the CreateTabStrip proceedure and did not find any.
> 
> What is this and what does it do?


WS_EX_LEFT is default and its value is &H0, so this can not be the reason.

----------


## chosk

I just received another feedback the same thing happen in an Atom tablet running Windows 8.1 (non RT).

----------


## Romeo91

chosk, 
Your mistake with the control TabStrip confirmed in a your test project (on my Win7). To solve your problem, I tried to replace a Ambient.UserMode to  global variable g_mbUserMode. And it happened, the compiled project looks correct.
In the wilds of the Internet I've seen that, Ambient.UserMode not always work out.

module startup prescribed definition
Public g_mbUserMode As Boolean

and assigning a value to a variable
Sub Main ()
     g_mbUserMode = True

----------


## Krool

> Your mistake with the control TabStrip confirmed in a your test project (on my Win7). To solve your problem, I tried to replace a Ambient.UserMode to  global variable g_mbUserMode. And it happened, the compiled project looks correct.
> In the wilds of the Internet I've seen that, Ambient.UserMode not always work out.
> 
> module startup prescribed definition
> Public g_mbUserMode As Boolean
> 
> and assigning a value to a variable
> Sub Main ()
>      g_mbUserMode = True


You mean the reason that the tabs are vertically stacked is due to the Ambient.UserMode property?

----------


## Romeo91

> You mean the reason that the tabs are vertically stacked is due to the Ambient.UserMode property?


Yes it is.
Depends on what I do not know, on one win7 I look normal on the second win7 tab are not just vertically, but without pictures and caption. The problem occurs only in the compiled exe.
All that i made ​​it - replaced Ambient.UserMode property, and after compiling all was well

----------


## Krool

> Yes it is.
> Depends on what I do not know, on one win7 I look normal on the second win7 tab are not just vertically, but without pictures and caption. The problem occurs only in the compiled exe.
> All that i made ​​it - replaced Ambient.UserMode property, and after compiling all was well


Can you try to isolate which call to Ambient.UserMode is causing exactly the problem?

----------


## Romeo91

> Can you try to isolate which call to Ambient.UserMode is causing exactly the problem?


I will try to identify where the problem, but it is only at home in the evening, as on all working machines I have everything works correctly (XP/7/8).

----------


## Romeo91

> I will try to identify where the problem, but it is only at home in the evening, as on all working machines I have everything works correctly (XP/7/8).


Enough to replace one parameter
Private Sub CreateTabStrip()
....
If TabStripHandle <> 0 Then
    If *Ambient.UserMode* = True Then Call ComCtlsSetSubclass(TabStripHandle, Me, 1)
End If
End sub

----------


## Krool

> Enough to replace one parameter
> Private Sub CreateTabStrip()
> ....
> If TabStripHandle <> 0 Then
>     If *Ambient.UserMode* = True Then Call ComCtlsSetSubclass(TabStripHandle, Me, 1)
> End If
> End sub


Hmmm.. is the Ambient.UserMode property returning "False" on the effected machine?
Or does it return "True", but just the call to it will do the issue to the TabStrip?
Is this also effecting the OCX version?

----------


## Romeo91

> Hmmm.. is the Ambient.UserMode property returning "False" on the effected machine?
> Or does it return "True", but just the call to it will do the issue to the TabStrip?


Ambient.UserMode return "True" - I tested it by adding a Msgbox 

By my mistake I made ​​in the variable assignment procedure sub main, and the project started with a form Form1.
As a result g_mbUserMode is always False, so the procedure call Call ComCtlsSetSubclass (TabStripHandle, Me, 1) does not occur. And then everything looks correct, but it works right? This is another question!




> Is this also effecting the OCX version?


In OCX-version all is work correctly

----------


## Krool

> Ambient.UserMode return "True" - I tested it by adding a Msgbox 
> 
> By my mistake I made ​​in the variable assignment procedure sub main, and the project started with a form Form1.
> As a result g_mbUserMode is always False, so the procedure call Call ComCtlsSetSubclass (TabStripHandle, Me, 1) does not occur. And then everything looks correct, but it works right? This is another question!
> 
> 
> In OCX-version all is work correctly


So *Ambient.UserMode* returns the correct value. *But* the call to it mess up the TabStrip?
Very strange problematic...

----------


## chosk

Recall that I have a Win8 x64 that exhibited the problem of the vertically stacked tabs. I was thinking this seems to be a problem of not able to create the tabs with the "proper" width and instead stretched full width and stacked. So I did a test. First I REM out the earlier Me.Refresh fix so that I can replicate the problem.

Strangely this time there was a problem but not the same problem. It resembles the problem one of the user reported back on Vista Home Premium.

Previously the tabs width were Justified. Now I tried Justified and Fixed. I hope the attached picture is self-explanatory and for further input hopefully can help in tracing the problem.

----------


## chosk

Hi Krool,

On the Toolbar. In your demo, the Divider is set to False, I set it to True to see how it would look like.

1) With Schmidt's method of inserting manifest into VB6.exe (the normal manifest file method does not work for me):
Initially, I see a thin sunken line between the top of the Toolbar and the Form caption bar. Then I run the project from the IDE. I get artifacts when I move the mouse around the Toolbar. Then when I close the run, back to the IDE, the Toolbar become black. I close and open the demo project, the Toolbar still black.

2) With the original VB6.exe, that is no theme:
No problem in the IDE, also after close the demo project and re-open no problem. But when I compiled (with your manifest in res), the compiled exe exhibited the same artifacts problem.

Perhaps the problem have to do when the Toolbar is themed and Divider is True?

----------


## Krool

> Perhaps the problem have to do when the Toolbar is themed and Divider is True?


That issue and one issue concerning the double-buffering are now fixed. Thanks for your report.

----------


## Almeida

*Krool,* does ListView support unicode?

----------


## Krool

> *Krool,* does ListView support unicode?


Yes.

----------


## Almeida

*Krool,* thank you. i just wanted to make sure before delving into it.

----------


## Krool

Update released.

I have found the problem with the "vertically stacked tabs" in the TabStrip control.
Reason was that the variable PropTabMinWidth is an 'Integer' and the lParam of the SendMessage expects a 'Long' variable.
So there was actually a value problem. It took the 2 bytes from the PropTabMinWidth variable and the other 2 bytes from "somewhere else" in the memory, resulting in a nonsense value. (but not always)
The fix was simple. I just put a CLng() around it.

----------


## Romeo91

Krool, Once we have so much time to discussing TabsStrip, make suggestions!
Can add to your set CommonControls control SStab (TabCtl32.ocx)?
I understand there are not very many differences from TabStrip, except that each tab is a separate container, and controls can be added to any of them even in the IDE.
If interested, I have two examples of more or less working but unstable

----------


## chosk

Thanks Krool for the update. Very much appreciated.

----------


## Krool

Update released. (Thanks to Jonney for finding)

----------


## Romeo91

Using listview on some computers I have an incomprehensible situation. Text element is reduced to a certain size, and placed at the end ... 

How can I fix this? 

I use a view=2 'viewlist
Elements add the following code



> With lvOptions.ListItems
>         If .Count = 0 Then
>             .Add 1, , strItemOptions1, , 1
>             .Add 2, , strItemOptions8, , 2
>             .Add 3, , strItemOptions2, , 3
>             .Add 4, , strItemOptions3, , 4
>             .Add 5, , strItemOptions4, , 5
>             .Add 6, , strItemOptions5, , 6
>             .Add 7, , strItemOptions9, , 7
> ...

----------


## Krool

> Using listview on some computers I have an incomprehensible situation. Text element is reduced to a certain size, and placed at the end ... 
> 
> How can I fix this? 
> 
> I use a view=2 'viewlist
> Elements add the following code


Use the 'ColumnWidth' property and set it to a higher value.

----------


## Romeo91

> Use the 'ColumnWidth' property and set it to a higher value.


I tried, not help. No response to parameter change. Win XP, but met this and Win7

----------


## Krool

> I tried, not help. No response to parameter change. Win XP, but met this and Win7


I have tried to replicate and I was only able to replicate it when setting the 'ColumnWidth' in Form_Load, but I could resolve it by placing a 'DoEvents' before setting the 'ColumnWidth'. I am not sure why this is necessary.

But please confirm that this solves your issue - for the moment.

----------


## Romeo91

> I have tried to replicate and I was only able to replicate it when setting the 'ColumnWidth' in Form_Load, but I could resolve it by placing a 'DoEvents' before setting the 'ColumnWidth'. I am not sure why this is necessary.
> 
> But please confirm that this solves your issue - for the moment.


On both my machines problem exist in the IDE, but no in compiled-exe. In IDE doevents not help.
Tomorrow check on other computers, as I remember that the problems encountered in the project compiled, but something I doubt

***********

If I use the ColumnWidth property to compile the project, on the contrary it leads to any machine to the problem of reducing the text to the same species, regardless of the ColumnWidth.
If the property is not used, it appears not all machines

----------


## Krool

> On both my machines problem exist in the IDE, but no in compiled-exe. In IDE doevents not help.
> Tomorrow check on other computers, as I remember that the problems encountered in the project compiled, but something I doubt
> 
> ***********
> 
> If I use the ColumnWidth property to compile the project, on the contrary it leads to any machine to the problem of reducing the text to the same species, regardless of the ColumnWidth.
> If the property is not used, it appears not all machines


Does it work when setting the ColumnWidth not in the Form_Load event? For instance in a CommandButton_Click event instead?

----------


## Romeo91

> Does it work when setting the ColumnWidth not in the Form_Load event? For instance in a CommandButton_Click event instead?


If property ColumnWidth is used in the event CommandButton_Click it works correctly

----------


## fafalone

Very nice project.

Bug: When you click on the Icons property of the ListView control, VB crashes. Same result in both sample project and new project. VB6/SP6 Win7 x64.

I was looking into ImageLists for the ListView. I noticed that I cannot use the system image list by setting the .Icons and .SmallIcons property to the system image list handle (no errors, but no icons). Not sure if that's a bug or just not possible with the design. I tried assigning it with LVM_SETIMAGELIST, however that tripped several breaks on Debug.Assert CBool(OldPointer <> NewPointer) in VTableSubclass.cls followed by complete lockup, had to ctrl+alt+del the ide. No indication of the problem was otherwise given. 

It's obviously critical to be able to use the system image list, hopefully it's something simple I'm overlooking.

----------


## Krool

> Bug: When you click on the Icons property of the ListView control, VB crashes. Same result in both sample project and new project. VB6/SP6 Win7 x64.


I am not able to replicate it.
Is your IDE crashing when clicking in the property browser or on the property page? Or both?




> I was looking into ImageLists for the ListView. I noticed that I cannot use the system image list by setting the .Icons and .SmallIcons property to the system image list handle (no errors, but no icons). Not sure if that's a bug or just not possible with the design. I tried assigning it with LVM_SETIMAGELIST, however that tripped several breaks on Debug.Assert CBool(OldPointer <> NewPointer) in VTableSubclass.cls followed by complete lockup, had to ctrl+alt+del the ide. No indication of the problem was otherwise given.
> 
> It's obviously critical to be able to use the system image list, hopefully it's something simple I'm overlooking.


The .Icons, .SmallIcons and .ColumnHeaderIcons does not handle a 'Long' value.

----------


## coolcurrent4u

good work, pls keep it up

----------


## Krool

> Using listview on some computers I have an incomprehensible situation. Text element is reduced to a certain size, and placed at the end ... 
> Attachment 111939
> How can I fix this? 
> 
> I use a view=2 'viewlist
> Elements add the following code


Update released.

Text element is now not getting reduced anymore when setting the 'SmallIcon' property. So the behavior is now the same as the original ListView control from MS.

----------


## quicken

*hello Krool 
i found a bug in date and time picker:*



*when you click on UpDown Button, it changes so fast, i think it should have a delay before rapid change..*

----------


## Krool

> *hello Krool 
> i found a bug in date and time picker:*
> 
> 
> 
> *when you click on UpDown Button, it changes so fast, i think it should have a delay before rapid change..*


what do you mean by rapid change?
By me, when I click, it increments or decrements by 1. But when you hold down the mouse button then it will speed up. I do not think that this is a bug.

----------


## Bandula Prasanna

Krool,

Thank for the CommonControls (Replacement of the MS common controls) project., a valuable project.

Do you have a user control developed for Explorer-style Folder/File Treeview?, If you can create such a tool which works without any dependency, it will be great to the VB6 community.

The only known solution to me in VB6 is  Folder Treeview control I found at the following location. 

http://ccrp.mvps.org/

But, it is released as an OCX.

Do you have any idea please?

Thanks once again.

----------


## Jonney

> Krool,
> 
> Thank for the CommonControls (Replacement of the MS common controls) project., a valuable project.
> 
> Do you have a user control developed for Explorer-style Folder/File Treeview?, If you can create such a tool which works without any dependency, it will be great to the VB6 community.
> 
> The only known solution to me in VB6 is  Folder Treeview control I found at the following location. 
> 
> http://ccrp.mvps.org/
> ...


I remembered PSC had the kind of Folderview codes using own-drawn treeview. You can search for it.

----------


## quicken

*sorry krool*

i figured that the problem is from my Windows, even Date and Time picker of windows not changing correctly, I don't know where the problem came from and how to fix it...
thank you krool and sorry for wrong bug report..

----------


## Krool

Update released.

This is quite important when using the ListView control.

----------


## Krool

Update released.

*For info:*
This update breaks the compatibility with the VBCCR10.OCX.
I will not create a new OCX now, as I want to wait to collect more such "break compatibility" updates.
But if there will be a critical bug (that does not break the compatibility) then I will adopt this also to the VBCCR10.OCX.  :Wink:

----------


## Krool

Update released.

VBCCR10.OCX cannot be updated with the new features as it breaks compatibility.
I still wait for more such updates before I will release VBCCR11.OCX.

----------


## netkiller

treeview bug? when set treeview's propety HideSelection=False, treeview not draw selected cell when lost focus,
i found must comment some code in following, it seem about drag and drop, but i think these code not work right

Private Function WindowProcUserControl(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  ...
  ...
                Case NM_CUSTOMDRAW
                    Dim NMTVCD As NMTVCUSTOMDRAW
                    CopyMemory NMTVCD, ByVal lParam, LenB(NMTVCD)
                    Select Case NMTVCD.NMCD.dwDrawStage
                        Case CDDS_PREPAINT
                            WindowProcUserControl = CDRF_NOTIFYITEMDRAW
                            Exit Function
                        Case CDDS_ITEMPREPAINT
                            If NMTVCD.NMCD.lItemlParam <> 0 Then
                                Set Node = PtrToObj(NMTVCD.NMCD.lItemlParam)
                                With Node
                                'If Not NMTVCD.NMCD.uItemState = (CDIS_FOCUS Or CDIS_SELECTED) Then
                                    'If SendMessage(TreeViewHandle, TVM_GETNEXTITEM, TVGN_DROPHILITE, ByVal TVI_ROOT) <> NMTVCD.NMCD.dwItemSpec Then
                                        'NMTVCD.ClrText = WinColor(.ForeColor)
                                        'NMTVCD.ClrTextBk = WinColor(.BackColor)
                                        'CopyMemory ByVal lParam, NMTVCD, LenB(NMTVCD)
                                    'End If
                                End If

----------


## Krool

> treeview bug? when set treeview's propety HideSelection=False, treeview not draw selected cell when lost focus


Update released. Thanks for your bug report.

----------


## netkiller

thanks for your nice work, first.

you add following code to skip problem:
*If NMTVCD.ClrTextBk <> WinColor(vbButtonFace) Then*
but i think your custom draw code with drag and drop seems no usage, comment it can increase custom draw speed and resolve this problem.

btw, hope ImageList  can support 32bit color icon with alpha channel(XP ICON)

thanks a lot :Smilie:

----------


## rgregory

Is it possible to use these controls in a VBA project? I have an existing VBA project that I've run into issues using the mscomctl.ocx library so I'm trying to find a replacement for it.

Thanks
Ron

----------


## Krool

> Is it possible to use these controls in a VBA project? I have an existing VBA project that I've run into issues using the mscomctl.ocx library so I'm trying to find a replacement for it.
> 
> Thanks
> Ron


Not possible to use in VBA. :-(

----------


## Schmidt

Well, the pre-compiled (and normally registered) OCX-version should do fine in VBA(UserForms).

Olaf

----------


## Krool

Update released.

----------


## Jim Naylor

Hi, Only found this a couple of days ago. Fantastic!

Still exploring but I note that there is no HelpContextID for the toolbar control although it's there for the other controls I've looked at. Pity as I use this on the project I was thinking of using replacing the controls on.

Also the toolbar has a BackColor property which doesn't seem to do anything. (But as there is no BackColor property for the MSToolbar I can't complain!)

Keep up the great work

----------


## Krool

> Also the toolbar has a BackColor property which doesn't seem to do anything. (But as there is no BackColor property for the MSToolbar I can't complain!)


The BackColor property is ignored when control paints via double-buffering. (DoubleBuffer property)
So in order to use a custom BackColor you need to set the DoubleBuffer property to False.




> Still exploring but I note that there is no HelpContextID for the toolbar control although it's there for the other controls I've looked at. Pity as I use this on the project I was thinking of using replacing the controls on.


Hmm. Thats true. The reason seems to be because the control cannot get the focus. As soon as I set the ToolBar to CanGetFocus = True the HelpContextID is available...

----------


## Jim Naylor

Thanks for that.

I've modified the CanGetFocus in the control and yes I can get the HelpContextID and with DoubleBuffer off the color is all OK. But that makes me ask, what does DoubleBuffer do? as nothing else seems to change.

----------


## Krool

> Thanks for that.
> 
> I've modified the CanGetFocus in the control and yes I can get the HelpContextID and with DoubleBuffer off the color is all OK. But that makes me ask, what does DoubleBuffer do? as nothing else seems to change.


Double buffering is reducing some flickering. Especially in the ListView control you can see the difference.

----------


## Jim Naylor

Thanks for the explaination. I doubt if flicker will be a problem on a toolbar, so I'll keep it off.

----------


## Ramses800

Krool,
Fantastic project, I have been following it for a while and tested several of the versions(the previous I downloaded was 2013-03-19) without any trouble.
I just tried the latest(2014-05-08) and got a new error from the Listview control at startup followed by IDE-crash.




> "To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher"




```
Public Property Get Groups() As LvwGroups
If PropGroups Is Nothing Then
    If ComCtlsSupportLevel() >= 1 Then
        Set PropGroups = New LvwGroups
        PropGroups.FInit Me
    Else
        Err.Raise Number:=91, Description:="To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher"
    End If
End If
Set Groups = PropGroups
End Property
```

I checked my system and my COMCTL32.DLL is File version 5.82.7601.18201 but Product version 6.1.7601.181201
The previous one(2014-03-19) I have works but not the newer one(2014-05-08)
Any suggestions?

----------


## Krool

> Krool,
> Fantastic project, I have been following it for a while and tested several of the versions(the previous I downloaded was 2013-03-19) without any trouble.
> I just tried the latest(2014-05-08) and got a new error from the Listview control at startup followed by IDE-crash.
> 
> 
> 
> 
> 
> ```
> ...


The demo is using the 'Groups' functionality, which requires a *manifest* linking to the comctl32.dll version 6.0 or higher. The compiled .exe is linked to version 6.0. But the IDE itself is most likely linked to version 5.x. Thus the Error happens in the IDE only.

However, whenever the functionality is called it will raise an error. (most likely in the IDE because this links to version 5.x)
In the demo I put a "On Error Resume Next" befor to the 'Groups' call to avoid this.

But this ("On Error Resume Next") will be only working when you configure the IDE like following:



> In order to trap error raises via "On Error Goto ..." or "On Error Resume Next" it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error Trapping.

----------


## Ramses800

Excellent, that did the trick!
Again, fantastic work!

----------


## Jim Naylor

Couple of minor issues with the toolbar

The MSToolbar is a container but the replacement isn't, fixed by changing the ControlContainer property of the control to True.

If you set the whole toolbar to Enabled = False, then later set Enabled = True, the disabled shaddows still partly show.

I fixed this by putting     UserControl.Refresh     after

If ToolBarHandle <> 0 Then EnableWindow ToolBarHandle, IIf(Value = True, 1, 0)

in the Enabled property of the control.

Everything else so far working great.

----------


## Krool

> Couple of minor issues with the toolbar
> 
> The MSToolbar is a container but the replacement isn't, fixed by changing the ControlContainer property of the control to True.
> 
> If you set the whole toolbar to Enabled = False, then later set Enabled = True, the disabled shaddows still partly show.
> 
> I fixed this by putting     UserControl.Refresh     after
> 
> If ToolBarHandle <> 0 Then EnableWindow ToolBarHandle, IIf(Value = True, 1, 0)
> ...


Thanks for your help. Appreciated.
Update released.  :Smilie:

----------


## chosk

Re the DateTime Picker.

1) I click on the Day part to highlight it. Then I scroll the mousewheel:

a) If I am at 30-Apr-2014 and I scroll up,
instead forward to 1-May-2014, it goes backward to 1-April-2014.

b) If I am at 1-Apr-2014 and scroll down,
instead backward to 31-Mar-2014, it jumps forward to 30-Apr-2014.


2) Similarly for the Month part, then use mousewheel to scroll:

a) At Dec-2013 and scroll up, instead of Jan-2014, it goes backward to Jan-2013.
b) At Jan-2014 and scroll down, instead of Dec-2013, it goes forward to Dec-2014


3) When click to open and show the calendar view:

a) If I am at 15-April-2014, click on the < to go to previous month,
instead of 15-Mar-2014, it goes to the 1-Mar-2014.

b) If I am at 15-April-2014, click on the > to go to next month,
instead of 15-May-2014, it goes to 1-May-2014.

----------


## Krool

> Re the DateTime Picker.
> 
> 1) I click on the Day part to highlight it. Then I scroll the mousewheel:
> 
> a) If I am at 30-Apr-2014 and I scroll up,
> instead forward to 1-May-2014, it goes backward to 1-April-2014.
> 
> b) If I am at 1-Apr-2014 and scroll down,
> instead backward to 31-Mar-2014, it jumps forward to 30-Apr-2014.
> ...


I assume this is the comctl32 v6.1 version?
At this version I did not do any "custom procedures" for mousewheel or so as there is a default procedure for that.
Thus all that behavior you encounter are default procedures.

----------


## Krool

Important update released when using the MonthView control.

----------


## c141heaven

This is fantastic!   I've been beating my head against the wall on an vb6 app trying to get it to load in the ide under windows 8.1 .... mscomctrl.ocx fails to load and though I''ve searched for a working solution I can't get any of them to work for more than a day or so.  This looks pretty promising.

I'm hopeful this OCX help me get back on track.   For any of you considering moving from xp to Windows 8.1 ... save yourself the frustration and stay on or upgrade to Win 7.  It was a huge mistake for me to even try.

----------


## Rinzwind

Great work! Bug report: seems to be something wrong with the statusbar control in the latest OCX version.
VBCCR10
Run-time error '91':
Object variable or With block variable not set

This message appears and won't close (or the IDE crashes).

----------


## georgekar

I loaded in Vb5, ersed some lines in cls files as usual (vb5 can't regognize that, was vb6 flags), no missing of the reference to tlb, so press F5 and that happen:



why???

----------


## Krool

> Great work! Bug report: seems to be something wrong with the statusbar control in the latest OCX version.
> VBCCR10
> Run-time error '91':
> Object variable or With block variable not set
> 
> This message appears and won't close (or the IDE crashes).


That actually happens to all OCX version, except revision number 0.
The reason was that the ASM Design Mode subclass only works on a "blank" compile.
If I compile with "binary compatibility" the ASM Design Mode subclass is like broken.
So I replaced the ASM Design Mode subclass with normal subclass as on a OCX this is no problem.
I only did a ASM Design Mode subclass as for the Std-EXE version this was necessary.

So as there is no ASM Design Mode subclass in the OCX version now the controls CoolBar and ToolBar should work now.

----------


## c141heaven

Question regarding the OCX.... I've tried to use the new Command Button .... it does not have a Style property that matches the old VB one .. (e.g., standard or graphical) that allows setting the background color of the command button.   My project sets the background color when the control gets focus ...but with this new one it does not seem to function.   I've fiddled with what seems like possible properties that might be related to this but nothing seems to get this to work for me.   Is there is a way?    Also, I can't seem to get the 'image and caption' option to work.   If I put an image on the button ... it only shows the image and not the caption.  Wont' caption unless the image is (none).


What would *REALLY*  be nice is two properties that permit setting of a 'got focus backcolor' and a 'lost focus backcolor' so it did it automatically so you don't need to use a lot of got_focus and lost_focus events to deal with it.

----------


## Krool

> Question regarding the OCX.... I've tried to use the new Command Button .... it does not have a Style property that matches the old VB one .. (e.g., standard or graphical) that allows setting the background color of the command button.   My project sets the background color when the control gets focus ...but with this new one it does not seem to function.   I've fiddled with what seems like possible properties that might be related to this but nothing seems to get this to work for me.   Is there is a way?    Also, I can't seem to get the 'image and caption' option to work.   If I put an image on the button ... it only shows the image and not the caption.  Wont' caption unless the image is (none).
> 
> 
> What would *REALLY*  be nice is two properties that permit setting of a 'got focus backcolor' and a 'lost focus backcolor' so it did it automatically so you don't need to use a lot of got_focus and lost_focus events to deal with it.


The CommandButtonW does not have a Style property yet. The 'Graphical' is in true a ownerdrawn button. To get a similar result you need to use the "PushLike" property but this does not include for instance the backcolor as you already encounter.
The 'image and caption' property is only working when you use a manifest file within your project to link to comctl32.dll 6.1. (Vista, 7+)

So at the moment the 'Graphical' (Ownerdrawn) style to emulate the intrinsic command button behavior and appearance is not yet done.

----------


## Jim Naylor

All working well for me, but I notice that you have replaced the standard vb msgbox function with your own, but I can't see any difference in the box produced on XP or Win 7. Any reason for the replacement? The same goes for GetAttr although I've not used that.

----------


## Krool

> All working well for me, but I notice that you have replaced the standard vb msgbox function with your own, but I can't see any difference in the box produced on XP or Win 7. Any reason for the replacement? The same goes for GetAttr although I've not used that.


I have replaced some functions in order to support unicode.

----------


## Romeo91

> I have replaced some functions in order to support unicode.


Krool, in last version control ToolTip property(Let/Get) DelayTime is wrong



```
Public Property Let DelayTime(ByVal TimeType As TipDelayTimeConstants, ByVal Value As Long)
Select Case Time
    Case TipDelayTimeReshow, TipDelayTimeShow, TipDelayTimeInitial
        Select Case Value
            Case 0 To 32767
                If ToolTipHandle <> 0 Then SendMessage ToolTipHandle, TTM_SETDELAYTIME, Time, ByVal MakeDWord(Value, 0)
            Case Else
                Err.Raise 380
        End Select
    Case Else
        Err.Raise 380
End Select
End Property
```

----------


## Krool

> Krool, in last version control ToolTip property(Let/Get) DelayTime is wrong
> 
> 
> 
> ```
> Public Property Let DelayTime(ByVal TimeType As TipDelayTimeConstants, ByVal Value As Long)
> Select Case Time
>     Case TipDelayTimeReshow, TipDelayTimeShow, TipDelayTimeInitial
>         Select Case Value
> ...


Oops. Fixed.  :Smilie: 
Thanks

----------


## Jonney

For Spinbox control,Due to increment can't be 0.1, is it possible to display Text "2.5" but the value is "25" with increment = 1?

----------


## Jonney

Bug report:
in Class CommonDialog ShowFont Function:

   Should put "Set PropFont = New StdFont" After "If RetVal <> 0 Then" to de-reference the old Font object.




> If RetVal <> 0 Then
>         Set PropFont = New StdFont


I found this bug in my post #765747.

After @Max187Boucher give solution, VB6's CommonDialog1 works perfectly.

But I used your CommonDialog class the problem still exist. After adding this line, problem gone.

----------


## Krool

> Bug report:
> in Class CommonDialog ShowFont Function:
> 
>    Should put "Set PropFont = New StdFont" After "If RetVal <> 0 Then" to de-reference the old Font object.
> 
> 
> 
> I found this bug in my post #765747.
> 
> ...


That is not necessary. In the Class_Initialize is already a 'Set PropFont = New StdFont'.
Just ensure that when you override the Font property of the CommonDialog this is always a new one and not referrenced to something else.

----------


## Jonney

> That is not necessary. In the Class_Initialize is already a 'Set PropFont = New StdFont'.
> Just ensure that when you override the Font property of the CommonDialog this is always a new one and not referrenced to something else.


I made a demo for you to troubleshooting.

Refer to attachment:
simplified demo_Krool.zip

----------


## Krool

> I made a demo for you to troubleshooting.
> 
> Refer to attachment:
> simplified demo_Krool.zip


I do not think it is a good idea to make a 'New' Font after the dialog was called. Thus it should be kept as the original.
Instead you should de-reference the passed Font from the Textboxes.

So Instead of:


```
Private Sub cmdNewFont_Click()
    Dim otempFont As StdFont, Flags As CdlCFConstants
    Dim FontDialog As KroolCommonDialog
    
    Set otempFont = txtFooter1.Font
```

Put like following:


```
Private Sub cmdNewFont_Click()
    Dim otempFont As StdFont, Flags As CdlCFConstants
    Dim FontDialog As KroolCommonDialog
    
    Set otempFont = New StdFont 'de-reference Font Object
    With otempFont
        .Bold = txtFooter1.FontBold
        .Italic = txtFooter1.FontItalic
        .Underline = txtFooter1.FontUnderline
        .Strikethrough = txtFooter1.FontStrikethru
        .Size = txtFooter1.FontSize
        .Name = txtFooter1.FontName
    End With
```

----------


## Jonney

> I do not think it is a good idea to make a 'New' Font after the dialog was called. Thus it should be kept as the original.
> Instead you should de-reference the passed Font from the Textboxes.
> 
> So Instead of:
> 
> 
> ```
> Private Sub cmdNewFont_Click()
>     Dim otempFont As StdFont, Flags As CdlCFConstants
> ...


OK. That is fine,I have to write more codes to assign Font. I don't know what the behind story of "Set otempFont = txtFooter1.Font" and "Set txtFooter1.Font = otempFont". This is the simply and logic but bring some strange problem.

----------


## quicken

hello Krool
can you please update OCX version. thank you very much

----------


## Krool

> hello Krool
> can you please update OCX version. thank you very much


Not now, but in near future I will release a version 1.1 of the OCX with the latest state.

Hotfixes are also done in the version 1.0 of the OCX as long as they did not break the compatibility.

----------


## quicken

> Not now, but in near future I will release a version 1.1 of the OCX with the latest state.
> 
> Hotfixes are also done in the version 1.0 of the OCX as long as they did not break the compatibility.


ok krool i am waiting for last release
thanks again

----------


## chosk

I show the vbLongDate and vbLongTime in the StatusBar. With every new version, I would go into StatusBar.ctl's Sub GetDisplayText to change Case SbrPanelStyleTime and Case SbrPanelStyleDate accordingly.

Without changing StatusBar.ctl, is there any way I can make the change in my project Form_Load? This will make it much easier.

----------


## I-Like-Toast

I am getting a run-time error after editing the Property Pages for the toolbar control (VB6 IDE crashed mid-edit, I now get the same error each time I try to run my program through the IDE or compile). 





Any suggestions?

PS - The demo program runs fine which references the same ocx.

Thank you

----------


## Krool

> treeview bug? when set treeview's propety HideSelection=False, treeview not draw selected cell when lost focus





> you add following code to skip problem:
> *If NMTVCD.ClrTextBk <> WinColor(vbButtonFace) Then*


Update released.

Due that this workaround does not work when the backcolor of the control is vbButtonFace I now tried to troubleshoot this once again.
And now this is finally solved "properly".




> I am getting a run-time error after editing the Property Pages for the toolbar control (VB6 IDE crashed mid-edit, I now get the same error each time I try to run my program through the IDE or compile).


This is solved on I-Like-Toast's side. The reason for this was a corrupt ImageList in a .frx file.

----------


## public

tests.zip

Hello

My test program crashes with your ocx control. :Cry: 
why?

----------


## Krool

> tests.zip
> 
> Hello
> 
> My test program crashes with your ocx control.
> why?


You forgot a point (".") before the 'Count'.

So, instead of this:


```
Private Sub Create_ListView_OCX()
    Dim nb As Long

    With ListView_OCX.ListItems

        If Count Then
            .Clear
        End If
```

do like following:


```
Private Sub Create_ListView_OCX()
    Dim nb As Long

    With ListView_OCX.ListItems

        If .Count Then
            .Clear
        End If
```

----------


## public

> You forgot a point (".") before the 'Count'.
> 
> So, instead of this:
> 
> 
> ```
> Private Sub Create_ListView_OCX()
>     Dim nb As Long
> 
> ...


thank you

But if I write



```
Private Sub Create_ListView_VB6()
    Dim nb As Long

    With ListView_VB6.ListItems
        .Clear
.....
```

and 



```
Private Sub Create_ListView_OCX()
    Dim nb As Long

    With ListView_OCX.ListItems
         .Clear
....
```

Only Create_ListView_OCX() Crash
Why?

And it's the same with The Treview TreeView...


The "Clear" command does not support empty lists! otherwise crashes

otherwise With the test of "Count"
If I click a second time on the "Rnd List OCX " button



the "Rnd ListVB6" button works perfectly!

----------


## SuperDre

LOL, that seems to be a bug yeah, clear should always be able to work with an empty list.. haha.. but I guess that'll be an easy fix..

----------


## Krool

Update released. Fixed the bug with the 'Clear' method.

Just for information:
Here it crashed:


```
With ListView_OCX.ListItems
.Clear
....
```

And here not:


```
ListView_OCX.ListItems.Clear
....
```

----------


## SuperDre

> Update released. Fixed the bug with the 'Clear' method.
> 
> Just for information:
> Here it crashed:
> 
> 
> ```
> With ListView_OCX.ListItems
> .Clear
> ...


Ohw.. those can be annoying bugs to track down... As you wouldn't expect a [b]with[b] statement to produce any different working as using it directly.. good job..

----------


## Krool

Updated released.

----------


## Ramses800

Anyone have any good links to information on how to create the VB6.EXE manifest linking to the comctl32.dll version 6.0 or higher?
I would like to test the newer controls in the IDE.

----------


## Krool

> Anyone have any good links to information on how to create the VB6.EXE manifest linking to the comctl32.dll version 6.0 or higher?
> I would like to test the newer controls in the IDE.


VB6 IDE Visual Style

----------


## Krool

Significant update released.

----------


## putuoka

Please help , i was done download ocx file and registered it wit regsvr32 and then i use resource hacker to add res file to vb6.exe it work fine showing your custom controls but when drag to the form it show without style. still in the old button item, etc  :Frown: 







> This is the 1.0 ActiveX Control version. (Revision 45)
> 
> Download VBCCR10.OCX
> 
> This binary is not compatible to any previous version as the library is renamed from "VBCCRLib" to "VBCCR10".
> I hope that this release is now stable and then in the future only a big change will result in a version increment.
> Any bugfixes in future will be compatible to this binary and only the revision number will be incremented.
> 
> Advantageous compared to the Std-EXE version is that all *property pages* support *Unicode*.
> ...

----------


## Krool

> Please help , i was done download ocx file and registered it wit regsvr32 and then i use resource hacker to add res file to vb6.exe it work fine showing your custom controls but when drag to the form it show without style. still in the old button item, etc


Are the VB intrinsic controls showing the visual styles?

----------


## public

Hello,

With the object "ComboBoxW" mode "DropDown List" (2) mode , change the value "Text" do not update the "ListIndex" list. The ComboBox VB6 yes.
Why?

----------


## public

Hello (again)

In the "TabStrip" object, how to know the background color of the client area.
Why the selected tab is called "SelectedTab" and not "SelectedItem" as in VB6?

best regards

----------


## Krool

> In the "TabStrip" object, how to know the background color of the client area.


The background color of the TabStrip control (respectively "SysTabControl32") is hardcoded in comctl32.dll.
When VisualStyles are False it is always vbButtonFace color.
If VisualStyle are True you need to look at the "GetThemeColor" function of uxtheme.dll.




> With the object "ComboBoxW" mode "DropDown List" (2) mode , change the value "Text" do not update the "ListIndex" list. The ComboBox VB6 yes.
> 
> Why the selected tab is called "SelectedTab" and not "SelectedItem" as in VB6?


Thanks for this information!
I will check your points soon.

----------


## public

Is it possible to have the property "BackgroundColorArea"?
This would "perhaps" easier to know the inside of your OCX

or better

Have an object "TabStripContainer"

Otherwise VERY good job


There should be some "On error goto" in places.
Example: Add an invalid image in the "*ListImage*" the control plant.

In "*PPImageListImages*"



```
Private Sub CommandInsert_Click()
Dim Path           As String, FileNames() As String
Dim OpenFileDialog As CommonDialog

    Set OpenFileDialog = New CommonDialog

    With OpenFileDialog
        .Flags = CdlOFNExplorer Or CdlOFNPathMustExist Or CdlOFNFileMustExist Or CdlOFNAllowMultiSelect
        .MaxFileSize = .MaxFileSize * 5000
        .Filter = "All Picture Files|*.ICO;*.CUR;*.BMP;*.GIF;*.JPG|Icons & Cursors (*.ICO;*.CUR)|*.ICO;*.CUR|Bitmaps (*.BMP;*.DIB)|*.BMP;*.DIB|GIF Images (*.GIF)|*.GIF|JPEG Images (*.JPG)|*.JPG|All Files (*.*)|*.*"
        .DialogTitle = "Select Picture"
    End With

    If OpenFileDialog.ShowOpen = True Then

        With OpenFileDialog

            If InStr(.FileName, vbNullChar) <> 0 Then
                Path = Left$(.FileName, .FileOffset - 1)

                If Not Right$(Path, 1) = "\" Then Path = Path & "\"
                FileNames() = Split(Mid$(.FileName, .FileOffset + 1), vbNullChar)
            Else
                Path = Left$(.FileName, .FileOffset)
                ReDim FileNames(0) As String
                FileNames(0) = .FileTitle
            End If

        End With

        On Error Resume Next

        If Not Path = vbNullString Then
            If PropertyPage.Changed = True Then Call PropertyPage_ApplyChanges

Dim i As Long, Picture As IPictureDisp

            For i = LBound(FileNames()) To UBound(FileNames())

                Set Picture = PictureFromPath(Path & FileNames(i))

                If Err.Number = 0 Then

                    With PropertyPage.SelectedControls(0)

Dim PictureWidth As Long, PictureHeight As Long

                        PictureWidth = PropertyPage.ScaleX(Picture.Width, vbHimetric, vbPixels)
                        PictureHeight = PropertyPage.ScaleY(Picture.Height, vbHimetric, vbPixels)

                        If PictureWidth = .ImageWidth And PictureHeight = .ImageHeight Then
                            CurrIndex = CurrIndex + 1
                            .ListImages.Add CurrIndex, , Picture
                            Call ApplyControlStates
                            Call FillShadowListImages
                            Call DrawImages
                            PropertyPage.Changed = True
                        Else
Dim Text As String

                            Text = "The size of the selected picture '" & FileNames(i) & "' is not compatible"

                            If PictureHeight <> .ImageHeight Then Text = Text & vbNewLine & "- Height is not " & .ImageHeight & " pixels"
                            If PictureWidth <> .ImageWidth Then Text = Text & vbNewLine & "- Width is not " & .ImageWidth & " pixels"
                            MsgBox Text, vbExclamation + vbOKOnly

                            Exit For

                        End If

                    End With

                Else
                    Err.Clear
                End If

            Next i

        End If
    End If

    On Error GoTo 0

End Sub
```

When you right-click to have the property of an object in the IDE, here is what happens.
Often, the property "*PropertyPage.SelectedControls (0).ControlsEnum*" does not exist


Well, that's all. (for the moment)

----------


## Krool

> With the object "ComboBoxW" mode "DropDown List" (2) mode , change the value "Text" do not update the "ListIndex" list. The ComboBox VB6 yes.
> 
> Why the selected tab is called "SelectedTab" and not "SelectedItem" as in VB6?


Done. And some other improvements.




> There should be some "On error goto" in places.
> Example: Add an invalid image in the "*ListImage*" the control plant.
> 
> In "*PPImageListImages*"


Done. I inserted a check whether the outcome Picture object is 'Nothing' or not. If it is Nothing it will result in a error MsgBox and the procedure is stopped. Thus IDE is not crashing anymore.




> Have an object "TabStripContainer"


Could you please describe the goal of such an object? Whats the purpose?




> When you right-click to have the property of an object in the IDE, here is what happens.
> Often, the property "*PropertyPage.SelectedControls (0).ControlsEnum*" does not exist


Hmm. That should exist. You can check in the control whether there is a "Property Get ControlsEnum". It's a hidden property.
When is this happening exactly? Only on the TreeView control? Only in the OCX?

----------


## putuoka

> Are the VB intrinsic controls showing the visual styles?


what did u mean? sorry my english not good.
like the pic as i post show, it's showing visual styles in VB intrinsic controls but when dragged on the form it hasn't a style same as if i run it

----------


## Krool

> what did u mean? sorry my english not good.
> like the pic as i post show, it's showing visual styles in VB intrinsic controls but when dragged on the form it hasn't a style same as if i run it


Intrinsic controls are those controls who are always available, even on a blank project. If they also do not show the visual styles then something is wrong with your VB6.exe resource.

----------


## public

Hello

Here is a screen copy this happens when the demand for property stops.




In the IDE, all routines using "ControlsEnum" have this problem.
The OCX works correctly.


I attached an example to find the background color of the "TabStrip" and why I wanted to know
A test with and without theme.

Test TabStrip.zip


VBA Version


VB6.EXE      6.0.81.76
VB6IDE.DLL  6.0.97.82
VB6.DLL       6.0.0.9782

----------


## public

Yeah

Changing "*ParentControls*" with "*Parent.Controls*" seems to work better.
I have no error on "ControlsEnum" at the request of the properties in the IDE!!  :Smilie: 




```
Public Property Get ControlsEnum() As Object
'    Set ControlsEnum = UserControl.ParentControls
    Set ControlsEnum  = UserControl.Parent.Controls
End Property
```

And it works for all controls, I tried.

I'm happy

----------


## Krool

This is the 1.1 ActiveX Control version. (End of support)

_Removed_

----------


## lrd_VB6

Normally Yes

VBA Version
Attachment 116209

VB6.EXE 6.0.81.76
VB6IDE.DLL 6.0.97.82
VB6.DLL 6.0.0.9782 

What would you like me to try the other?

Be careful, my system is in french!

----------


## Krool

> Normally Yes
> 
> VBA Version
> Attachment 116209
> 
> VB6.EXE 6.0.81.76
> VB6IDE.DLL 6.0.97.82
> VB6.DLL 6.0.0.9782 
> 
> ...


Change again "Parent*.*Controls" with "ParentControls" in the hidden ControlsEnum properties and then try following:

Instead of this


```
Dim ControlEnum As Object
For Each ControlEnum In .ControlsEnum
    If TypeName(ControlEnum) = "ImageList" Then
        ComboImageList.AddItem ProperControlName(ControlEnum)
    End If
Next ControlEnum
```

do this


```
If .ControlsEnum.Count > 0 Then
    For i = 0 To .ControlsEnum.Count - 1
        If TypeName(.ControlsEnum(i)) = "ImageList" Then
            ComboImageList.AddItem ProperControlName(.ControlsEnum(i))
        End If
    Next i
End If
```

for instance in the "PPTreeViewGeneral.pag"

----------


## lrd_VB6

Yes

When I saw my version of VBE.EXE and that of my folder ServicePacks VB6, I had a doubt.
VB6.EXE 6.0.*81.76* (current) and VB6.EXE 6.0.*97.82* (Service Pack)

After a New Update (again)
*VB6.EXE 6.0.97.82*

And it changes everything!

It seems that *ControlsEnum* working properly now!

Sorry for the time wasted on a failure who did not was not  :Blush:

----------


## Krool

> Yes
> 
> When I saw my version of VBE.EXE and that of my folder ServicePacks VB6, I had a doubt.
> VB6.EXE 6.0.*81.76* (current) and VB6.EXE 6.0.*97.82* (Service Pack)
> 
> After a New Update (again)
> *VB6.EXE 6.0.97.82*
> 
> And it changes everything!
> ...


Ok. Thats good. But would be interesting to know if the For...Next bypass would also solve it. Even on your VB6.EXE 6.0.*81.76* level.

----------


## lrd_VB6

confirmed

With VB6.EXE 6.0.*81.76* level.
Attachment 116225


With VB6.EXE 6.0.*97.82*
OK No problems.

I found the cause and Workarounds in the following links.

http://support.microsoft.com/kb/q223104

http://codes-sources.commentcamarche...ients-80010108

The right question is:
What is the difference between *UserControl.ParentControls* and *UserControl.Parent.Controls*?

----------


## Krool

> The right question is:
> What is the difference between *UserControl.ParentControls* and *UserControl.Parent.Controls*?


Referring to your linked KB-Article from MS: This problem is only occuring when there are 32 or more controls on the form. And the bug is fixed when at least SP3 is installed. Just as info.

The *UserControl.ParentControls* returns also the parent itself. So the count is always 1 higher than the *UserControl.Parent.Controls*.

Anyhow, everyone should use SP6.  :Stick Out Tongue:  As for sure there are also other problems which gets fixed by SP6.
But I don't want to look for every single problem when *not* SP6 is installed.
So I think I will stay with *UserControl.ParentControls*. And hey, this problem reminded you to update your VB6.  :Smilie:

----------


## lrd_VB6

Normally it should have been be the good version! :Ehh: 
Mystere

Just for information,

What version of the VB6.EXE you use?

What interest to change the type of *ControlsEnum* in *VBRUN.ParentControls* if it is a hidden property?

----------


## Krool

> Normally it should have been be the good version!
> Mystere
> 
> Just for information,
> 
> What interest to change the type of *ControlsEnum* in *VBRUN.ParentControls* if it is a hidden property?


The hidden property is used in the property page of the concerned control.
For general it is always better to cast the object directly to which it belongs instead of generic 'Objects'. (Performance)

----------


## lrd_VB6

Hello

In "TvwNodes.cls", Is it possible to change



```
Public Function Add(Optional ByVal Relative As Variant, _
                    Optional ByVal Relationship As TvwNodeRelationshipConstants, _
                    Optional ByVal Key As String, _
                    Optional ByVal Text As String, _
                    Optional ByVal Image As Long, _
                    Optional ByVal SelectedImage As Long) As TvwNode
```

In



```
Public Function Add(Optional ByVal Relative As Variant, _
                    Optional ByVal Relationship As TvwNodeRelationshipConstants = TvwNodeRelationshipNext, _
                    Optional ByVal Key As String, _
                    Optional ByVal Text As String, _
                    Optional ByVal Image As Long, _
                    Optional ByVal SelectedImage As Long) As TvwNode
```

This is the default reaction of *Nodes.Add*

http://msdn.microsoft.com/en-us/libr...=vs.60%29.aspx

----------


## lrd_VB6

Hello

I proceeded a "few" changes to routines *TreeView* and *Node(s)*.
I submit for your approval.

Now the *Image* and *SelectedImage* properties function as in the original.
You can use the keys as text or numeric.

Everything seems to work fine, but you never know ...  :Embarrassment: 

best regards

----------


## Krool

> I proceeded a "few" changes to routines *TreeView*


What did you exactly suggest to change in the TreeView itself?




> Now the *Image* and *SelectedImage* properties function as in the original.
> You can use the keys as text or numeric.


Ok. But what is the sense of have the Image and SelectedImage return a String if it was passed by a string, e.g. as "1" ? I dislike that overhead work.

----------


## lrd_VB6

Everything is in the Zip file!

Before



```
Public Function Add(Optional ByVal Relative As Variant, _
                    Optional ByVal Relationship As TvwNodeRelationshipConstants , _
                    Optional ByVal Key As String, _
                    Optional ByVal Text As String, _
                    Optional ByVal Image As Long, _
                    Optional ByVal SelectedImage As Long) As TvwNode
```

Now



```
Public Function Add(Optional ByVal Relative As Variant, _
                    Optional ByVal Relationship As TvwNodeRelationshipConstants = TvwNodeRelationshipNext, _
                    Optional ByVal Key As String, _
                    Optional ByVal Text As String, _
                    Optional ByVal Image As Variant, _
                    Optional ByVal SelectedImage As Variant) As TvwNode
```

In MainForm



```
    TreeView1.Nodes.Add , , , "1", "FOLDER_CLOSE", "FOLDER_OPEN"
    TreeView1.Nodes.Add(1, TvwNodeRelationshipChild, , "1-1", "MAIL", "OPEN").ForeColor = vbBlue
    TreeView1.Nodes.Add(1, TvwNodeRelationshipChild, , "1-2", 1).ForeColor = vbBlue
    TreeView1.Nodes.Add , TvwNodeRelationshipNext, , "2", 1
```



```
?TreeView1.Nodes(1).Image 
FOLDER_CLOSE
?TreeView1.Nodes(1).SelectedImage
FOLDER_OPEN
?TreeView1.Nodes(2).Image 
MAIL
?TreeView1.Nodes(3).Image 
 1
```

Values ​​"Image" or "SelectedImage" can be either text or numerical form.
This is normal operation.
I wrote a program that uses ONLY key in text form ..

----------


## Krool

> Values ​​"Image" or "SelectedImage" can be either text or numerical form.
> This is normal operation.
> I wrote a program that uses ONLY key in text form ..


Oh, Ok. Did not know that this can be a KEY of a ListImage.
Then this also effects to other controls?

----------


## lrd_VB6

Yes

All controls that use a "ListImage" work like that.

ToolBar, ListView etc..

Example code snippet I wrote



```
Private Function ModeleActif() As Boolean
    ModeleActif = (Toolbar1.Buttons(KEY_CONFIG).Image = "LOCK_GO" And Len(iniModele.IniFileName) > 0)
End Function

Private Sub ActiveModele(Name As String)
    iniModele.IniFileName = Name

    With Toolbar1.Buttons(KEY_CONFIG)

        If Len(Name) Then
            .Image = "LOCK_GO"
        Else
            .Image = "LOCK_OPEN"
        End If

    End With

    SetMainCaption
End Sub
```

For cons, I have a question:
I saw in the TwNode class (and elsewhere) 



```
Public Property Get NextSibling() As TvwNode
Set NextSibling = ShadowTreeView.FNodeNextSibling(PropHandle)
End Property

Public Property Set NextSibling(ByVal Value As TvwNode)   ' Why???
Err.Raise Number:=383, Description:="Property is read-only"
End Property
```

Why was the *Property Set* ?
If one does put THAT *Property Get*," then the property *IS* Read-only


Thank you to enlighten me.


best regards

----------


## Krool

Minor change done in the 'InitReleaseVisualStyles' function in VisualStyles.bas.
Instead of


```
CopyMemory IUnk, VarPtr(VTableHeaderPointer), 4
```

changed to


```
CopyMemory IUnk, ByVal VTableHeaderPointer, 4
```

As this seems to be more "stable". Under "strange" circumstances there is a possibility to get a error no. 16 "Expression too complex". This was solved by this change..

----------


## lrd_VB6

Good topic!

I do not know if you know this place but the following link should interest you.

This should simplify some routines.

http://www.xbeat.net/vbspeed/i_VBVM6Lib.html

As in the following code in the supplied Zip



```
lPrivate Function IHookXP_Message(ByVal hWnd As Long, _
                                 ByVal uiMsg As Long, _
                                 ByVal wParam As Long, _
                                 ByVal lParam As Long, _
                                 ByVal dwRefData As Long) As Long
Dim pt As POINTAPI, hMouseWnd As Long, Shift As Long, Delta As Integer

    Select Case uiMsg

 

        Case WM_SETCURSOR, &H2A2
            'Call TrackMouseEvent(mET)
            MouseMove_Msg "WM_SETCURSOR"

        Case WM_MOUSEHOVER
            'Debug.Print "WM_MOUSEHOVER:"; hWnd, uiMsg, wParam, VBVM6Lib.AsDWord(lParam).HiWord, VBVM6Lib.AsDWord(lParam).LoWord

        Case WM_MOUSEMOVE, WM_NCMOUSEMOVE
            Call TrackMouseEvent(mET)
            MouseMove_Msg "WM_MOUSEMOVE"
            Debug.Print "WM_MOUSEMOVE:"; hWnd, uiMsg, wParam, VBVM6Lib.AsDWord(lParam).HiWord, VBVM6Lib.AsDWord(lParam).LoWord
        
        Case WM_MOUSEWHEEL
            GetCursorPos pt
            hMouseWnd = WindowFromPoint(pt.x, pt.y)

            If wParam And MK_CONTROL Then Shift = Shift Or vbCtrlMask
            If wParam And MK_SHIFT Then Shift = Shift Or vbShiftMask
            Delta = VBVM6Lib.AsDWord(wParam).HiWord
            Debug.Print "WM_MOUSEWHEEL "; ObjName(hMouseWnd), Delta, Shift, Hex$(VBVM6Lib.AsDWord(wParam).LoWord)

       Case WM_MOUSEHWHEEL
            Debug.Print "WM_MOUSEHWHEEL "; ObjName(hWnd), uiMsg, wParam, lParam
 
        Case WM_NCDESTROY
            Call HookClear(Me.hWnd, Me)
        Case Else
            Debug.Print Hex$(uiMsg); ":"; hWnd, uiMsg, wParam, lParam
    End Select

    IHookXP_Message = HookDefault(hWnd, uiMsg, wParam, lParam)
End Function
```

----------


## Krool

> For cons, I have a question:
> I saw in the TwNode class (and elsewhere) 
> 
> 
> 
> ```
> Public Property Get NextSibling() As TvwNode
> Set NextSibling = ShadowTreeView.FNodeNextSibling(PropHandle)
> End Property
> ...


If you have only a 'Get' then VB6 *always* crash if you want to 'Write' on that Property. If there is a 'Set' and/or 'Let' with error raising then you have a chance to not crash the app when 'On Error Goto/Resume Next' is in place. It's like in the original controls. On many Read-Only properties you get a "manual" error raised.

----------


## putuoka

> Intrinsic controls are those controls who are always available, even on a blank project. If they also do not show the visual styles then something is wrong with your VB6.exe resource.


Here's my VB version.
i installing update sp 6



what i must to do?

----------


## Krool

> Here's my VB version.
> i installing update sp 6
> 
> 
> 
> what i must to do?


When you put a normal VB.CommandButton on the Form. Are the visual themes visible in your IDE?

----------


## Krool

Important/Critical update released, when using the CoolBar control.

There were some major mistakes done on the update from 13-Jul-2014. Sorry..
Now everything should work.

----------


## putuoka

> When you put a normal VB.CommandButton on the Form. Are the visual themes visible in your IDE?


i think yes, it's visible
here's more information from procmon(process monitor tools) when i drag your stylish button to the form
http://pastebin.com/raw.php?i=bdPVa0tN

----------


## Cube8

Judging by the about form, the obvious answer is _no_, because its buttons are not styled, either.

----------


## putuoka

> Judging by the about form, the obvious answer is _no_, because its buttons are not styled, either.


so what should i do to make this custom component work?

----------


## DrUnicode

It is a good idea to have 2 copies of Vb6.exe
One is the original.
Second is with embedded resource for Theme support so you can see Themed controls in the IDE without needing to compile every time.
Then it is just a matter copying the desired Vb6.exe to "C:\Program Files (x86)\Microsoft Visual Studio\VB98" folder.

There is obviously something wrong with your Manifest or it didn't get embedded. 
Your about screen should look like this?

----------


## Krool

> Hello
> 
> I proceeded a "few" changes to routines *TreeView* and *Node(s)*.
> I submit for your approval.
> 
> Now the *Image* and *SelectedImage* properties function as in the original.
> You can use the keys as text or numeric.
> 
> Everything seems to work fine, but you never know ... 
> ...


I think for the moment I will not change this as in the original.
As this would result in a big overhead. Also for "design time visible" controls, e.g. TabStrip.
And it would propably slow down some controls, e.g. ListView control...

----------


## Krool

Update. ActiveX Control Version 1.1 released.

----------


## quicken

good job krool 
thank you

----------


## putuoka

Thanks for the update krool also thanks for the help before guys
now i think i know my problem because of manifest & comctl32.dll
i got this error



Could anyone help me to fix this please?
i'm new with vb6 need tutorial to fix this error.
thank you.

----------


## lrd_VB6

- Create a copy of "VB6.EXE" and rename to "VB6_XP.EXE".
- copy attached file in the same folder. (manifest).
- Rename  *VB6_XP.EXE.manifest**.txt* in * VB6_XP.EXE.manifest*
- execute "VB6_XP.EXE"
You have VB6 with the theme and not error.  :Big Grin:

----------


## putuoka

> - Create a copy of "VB6.EXE" and rename to "VB6_XP.EXE".
> - copy attached file in the same folder. (manifest).
> - Rename  *VB6_XP.EXE.manifest**.txt* in * VB6_XP.EXE.manifest*
> - execute "VB6_XP.EXE"
> You have VB6 with the theme and not error.


It's working great. Thank you.
btw why we should change it to VB6_XP.EXE ? is it effect to deployment?

----------


## evanzulli

Hi!
Is there a way to modify the Tag property so as to use a Variant instead of a String?
Thanks

----------


## SMC1979

Quick question, I did a search on this thread first and didnt return any results.

On the textbox control, I can change the alignment at runtime on windows 7 but on xp it refuses to change, it even shows the alignment has changed yet does take effect (I use a msgbox to tell me the current alignment and it shows it changed). But on a newer OS it does are works fine. The normal textbox does it just fine on xp, so I am not sure if this is simply needing the v6 like some of the other features do.

So I have a simple drop down list that the user can set the alignment. In the IDE it doesnt work and it doesnt work when complied on xp. But it works fine on 7.

Am I missing something?

Any info would be great, and keep up the great work.

-Shane

----------


## Krool

> On the textbox control, I can change the alignment at runtime on windows 7 but on xp it refuses to change, it even shows the alignment has changed yet does take effect (I use a msgbox to tell me the current alignment and it shows it changed). But on a newer OS it does are works fine. The normal textbox does it just fine on xp, so I am not sure if this is simply needing the v6 like some of the other features do.


I have tested the 'Alignment' property in the TextBoxW control. Worked on XP and 7. (Whether comctl32.dll v5.8x or v6.x)
Anyone else other results?

----------


## SMC1979

Just to clarify, this is when the program is running and not in the IDE, in the IDE it works fine of course. Only changing it after it is running does it not work. But I have only tested on my XP in VMware that I program in, on 7 and 8 it works just fine. So the comctrl32 on the XP machine is 5.8 and of course the other OS's it is v6.

If it all helpful I could make a small short video showing it.

Shane

----------


## SMC1979

Another thing as well. The combo box. When I have a large list of items in a normal combo box I can start typing and it will pull up the best result. When I do that with the combo box with this one it is only taking the first letter and if I type a 2nd letter after it goes to a different item instead of using the first letter with it.

So say you have a combo box with these list items

Apple
Grape
Pie

And the combo current text is blank. You have focus on the combo box and start typing, as soon as you hit "a" apple shows up in the list, then just as quickly you hit "p" after the "a" and instead of staying on apple it goes right to "Pie"

So is there is a setting or option for the combo box that needs to be set so that it accepts more than just 1 letter when typing into it?

Shane

----------


## akogan

Halo Krool,

in the RichTextBox control (VBCCR11.OCX) there is no SelChange routine.

Thanks for your attention.

----------


## Krool

> in the RichTextBox control (VBCCR11.OCX) there is no SelChange routine.


There is a SelChange event on VBCCR11.OCX. (Even on VBCCR10.OCX is this event available)



```
Private Sub RichTextBox1_SelChange(ByVal SelType As Integer, ByVal SelStart As Long, ByVal SelEnd As Long)
```




> Another thing as well. The combo box. When I have a large list of items in a normal combo box I can start typing and it will pull up the best result. When I do that with the combo box with this one it is only taking the first letter and if I type a 2nd letter after it goes to a different item instead of using the first letter with it.
> 
> So say you have a combo box with these list items
> 
> Apple
> Grape
> Pie
> 
> And the combo current text is blank. You have focus on the combo box and start typing, as soon as you hit "a" apple shows up in the list, then just as quickly you hit "p" after the "a" and instead of staying on apple it goes right to "Pie"
> ...


This problem occurs because the ComboBox search is based on one character instead of the complete character set.

----------


## I-Like-Toast

Is it possible to set the RTB background to transparent?

The following seems to work for the original Rich Text Box, but for some reason not the new one:

    SetWindowLong richtextbox1.hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT


Thanks again for all your hard work

----------


## SMC1979

> This problem occurs because the ComboBox search is based on one character instead of the complete character set.


I was able to code a fix around for it. I had to change the combo from a list to a dropdown box, so the user could type in it. As they type the best result shows up (I have it set to show the drop down when they start typing) then, since I needed it as a list and not let them type in something, I have the combo do a find after the drop down closes and if there is a result it sets it, if there isnt it blanks out the text the typed in. So I get the effect that I need if the combo box was set back to a drop down list.

So I was able to do the effect I was looking for that way :-)

I dug in some more and think I know how the normal combo box does it. It holds a variable that if another key is pressed under a certain amount of time then it looks for that string, after a small amount of time pasts it resets back to the first letter that is typed next.

Just like how when you are typing text into the combo box it works fine as the best result comes up. When in drop down list mode you would have to have a variable and a timer to hold what the user is typing and then clear it after say, 1 sec. 

If you like I could do that into the control for you and send your way to see if it is something you could add.

Shane

----------


## Krool

> Is it possible to set the RTB background to transparent?
> 
> The following seems to work for the original Rich Text Box, but for some reason not the new one:
> 
>     SetWindowLong richtextbox1.hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT


It actually works. But, as there is a underlying UserControl under the RichTextBox it will always show the background of the UserControl. Thus it is not visible transparent. But again, the actual RichTextBox is indeed transparent with this.

I could make a 'Transparent' property for the RichTextBox which would do two things.
1. Set the WS_EX_TRANSPARENT extended style to the RichtTextBox control.
2. Make the background of the UserControl a replica of the underlying background to simulate transparency.

----------


## Krool

Update released.

----------


## stum

> Update released.


Hey Krool,

Is it free for commercial use as well ?

----------


## Krool

> Hey Krool,
> 
> Is it free for commercial use as well ?


Feel free to use it for commercial use. But only embedded in an application. Not the controls on its own.

----------


## ishalom

very cool controls 1 thing i noticed that is missing (which i use alot)
RightToLeft Property

----------


## ishalom

{{Ok I have noticed that the separator work as a placeholder, but the separator doesn’t exist}}
After Playing around i noticed that Separator and Placeholder are the same depending on the CustomWidth. Also the toolbar Style hast to be Flat In order to see the divider Line


A bug in the ocx version is on the buttons property page keeps messing things up.

----------


## Krool

> A bug in the ocx version is on the buttons property page keeps messing things up.


The bug was in the 1.1 OCX version. It is now fixed.
Thanks for this.

I also fixed another problem; that the HighLighted property of a Button in the ToolBar control did not consider the design time state at run time.

----------


## Krool

Update released.

----------


## ishalom

I have been using visual basic since version 3, I now use version 6 and I can say it does (almost) everything a good programming language needs.
It does although happen that I need to browse around the internet for custom control code, most of the time, I need to tinkle with the code to make it bug free, and to suite my needs
EXCEPT: for these controls, they are very comprehensive and delivers the FULL set of tools. No bugs. I am now including your OCX with all my applications. Just using the compiled version, no need to play around with the code.
Thank you!
What credits should I include in my compile applications, you deserve it?
PS. Do you have any plans to add any controls to the collection?

----------


## Krool

> What credits should I include in my compile applications, you deserve it?


Not any mandatory one. Maybe you can just add a link to this thread.




> Do you have any plans to add any controls to the collection?


What do you mean exactly?

----------


## ishalom

> Not any mandatory one. Maybe you can just add a link to this thread.


i think it's a decent thing to do..




> What do you mean exactly.


Any plans for a Splitter Control, Property List or to Create a combobox with the AutoComplete interface

----------


## Krool

> Create a combobox with the AutoComplete interface


You can already do this. By using my AutoComplete (Using the IAutoComplete interface) and pass the .hWndEdit of the ComboBoxW to it.

----------


## Krool

Update released.

Info: The bugfix for the internal CheckHeaderControl function in the ListView control is relevant when changing the 'View' property at run time. The CheckHeaderControl function assures that the header related properties are set accordingly when the 'View' property was set back and forth from/to 'Report'. Prior to bugfix this worked only once.

----------


## Thierry76

Download doesn't work for me... 
Trying to unzip without success, a message box say (in french) :
[Window Title] : Dossiers compressés
[Content] :Insérez le dernier disque de lensemble multi-volumes, et cliquer sur OK pour continuer. 

In my poor english it's the same problem with a rar file ... with multi files ... when you got only the first one...

----------


## Krool

You need to cut off the ".zip" extension and then open the .rar file. (e.g. with WinRAR)

----------


## Thierry76

Thanks a lot for your answer and ... for this great code !

----------


## ashian

Hi,
thank you for your work. I'm not familiar with VB, and I have a problem hope I can find a solution for it here.
We have an old VB6 application, which uses mscomct2.ocx to show date picker. we don't have it's source code. is it possible that without change it's code, replace mscomct2.ocx reference with your controls? 
Main problem is we want to change Calendar to support a local calendar which not include in MS windows. so hope with your date picker we can customize date and month view. Can we make an ocx with all mscomct2.ocx functionality with your control to replace this ocx file?

Best regards
Mehdi

----------


## ishalom

What is DoubleBuffer on the Toolbar Control

----------


## Krool

> What is DoubleBuffer on the Toolbar Control


It reduces the flickering.

----------


## ishalom

Is there a way to automaticly upgrade all Microsoft common control in a project to use the controls from here?

----------


## Krool

> Is there a way to automaticly upgrade all Microsoft common control in a project to use the controls from here?


Not really. But you can do it like this:

1. Include all the controls you want to your project.
2. Open the .frm file in the notepad editor (like by .txt files) and do a 'Replace All', for instance: VB.TextBox with [Your project name here].TextBoxW (e.g. "Project1.TextBoxW").

----------


## ishalom

> 2. Open the .frm file in the notepad editor (like by .txt files) and do a 'Replace All', for instance: VB.TextBox with [Your project name here].TextBoxW (e.g. "Project1.TextBoxW").


 Yes. I thought of that, but it wouldn't work on toolbar, statusbar, imagelist

Also. if you have set the font property, you have to change 
undefined Code:
BeginProperty Font
  as 
undefined Code:
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}

----------


## Krool

> Yes. I thought of that, but it wouldn't work on toolbar, statusbar, imagelist


Yes. The property bag is not compatible. For those you need to remove and create new from scratch.

----------


## Krool

Update released.

I included the IMEMode property in the TextBoxW control.
I did some tests (e.g. japanese Hiragana <> Katakana) and it worked.
But maybe someone who is more familiar with this at whole can do tests and report me when something is done wrong or so. Would be grateful.  :Smilie:

----------


## TomasEss

Hi, and thanks for excellent work.

I'm evaluating the statusbar control. I seem unable to change panel widths from code. It says "383 Property is write only" whenever I try. This happens regardless of the panel autosize setting. I assumed that at least the autosize=None should allow width changes from code like I'm used to.

I was also looking for the ability to have individual font settings (like bold) in the panels so that panel 1 is bold while the others are not. I have found the workaround using the picture property with a picture containing the bold text, but it would be nicer to have it done directly by the control. Would that be possible?

----------


## Krool

> I seem unable to change panel widths from code. It says "383 Property is write only" whenever I try. This happens regardless of the panel autosize setting. I assumed that at least the autosize=None should allow width changes from code like I'm used to.
> 
> I was also looking for the ability to have individual font settings (like bold) in the panels so that panel 1 is bold while the others are not. I have found the workaround using the picture property with a picture containing the bold text, but it would be nicer to have it done directly by the control. Would that be possible?


For adjusting the panel width you can use the MinWidth property. (Width property is meant to only receive the actual width)

The panels on my StatusBar control are owner drawn. So yes it would be possible do include a 'Bold' property. You want this? ;-)

----------


## TomasEss

Thanks. I was able to get it working using the MinWidth property. This is however not the same as with the MS StatusBar Control where Width is writable. No problem for me though, so no worries.
I also thought about using the backcolor set to black, but noticed that there's no forecolor so I got black on black.
So, to be usable for me, yes I would like to have a bold property aswell as a forecolor or ultimately the ability to set the back and font color separately per pane.

----------


## Thierry76

Dear Krool,
I was working last week on a VBA OCX version... an i was quite happy with it, it work with few changes of your code...
Is there anybody working/interesting to the same target ?
Thousand thanks
Thierry

PS1 I still got problem with the properties pages of all usercontrol (except the imagelist), do you have a clue ? 
PS2 At this time I working on a mecanism to selftregister it on HKCU on a very protected version of Windows (LUA, GPO etc) 
PS3 Could I share the resulte of my work here ?

----------


## Krool

> I was working last week on a VBA OCX version... an i was quite happy with it, it work with few changes of your code...
> Is there anybody working/interesting to the same target ?
> 
> PS3 Could I share the resulte of my work here ?


Yes and Yes.  :Wink:

----------


## Krool

Update released.

All controls in VBCCR10.OCX and VBCCR11.OCX are now marked as "*Safe for Initialization and Scripting*" by the IObjectSafety interface.
The Std-EXE project is untouched as it is not necessary to implement this.

----------


## lrd_VB6

hello

I'm a little annoyed. I can not seem to install "VBCCR11.OCX" version 9! 
Attached is a picture of the problem during installation.
Attachment 119627
There are special handling to do?
I think a "OLEGuids.tlb" in particular.

I replaced the old with the new, but it does not work ... :Frown: 

kind regards

----------


## Krool

> hello
> 
> I'm a little annoyed. I can not seem to install "VBCCR11.OCX" version 9! 
> Attached is a picture of the problem during installation.
> Attachment 119627
> There are special handling to do?
> I think a "OLEGuids.tlb" in particular.
> 
> I replaced the old with the new, but it does not work ...
> ...


The OLEGuids.tlb is not needed to run VBCCR11.OCX. It is just needed to compile it.
The only change between v8 and v9 is the new IObjectSafety interface. Can you please search in your registry if you can find the clsid of IObjectSafety?

Maybe just put the v8 again in place. Unregister it and replace with v9 and then register.

Does anybody else have the same problem?

----------


## lrd_VB6

> The OLEGuids.tlb is not needed to run VBCCR11.OCX. It is just needed to compile it.
> The only change between v8 and v9 is the new IObjectSafety interface. Can you please search in your registry if you can find the clsid of IObjectSafety?
> 
> Maybe just put the v8 again in place. Unregister it and replace with v9 and then register.
> 
> Does anybody else have the same problem?



I had already tried the method


```
REGSVR32 / u VBCCR11_v7.OCX
REGSVR32 VBCCR11_9.OCX
```

but it does not work

here is the part of the register of the object IObjectSafety


```
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{CB5BDC81-93C1-11CF-8F20-00805F2CD064}]
@="IObjectSafety"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{CB5BDC81-93C1-11CF-8F20-00805F2CD064}\NumMethods]
@="5"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{CB5BDC81-93C1-11CF-8F20-00805F2CD064}\ProxyStubClsid32]
@="{B8DA6310-E19B-11D0-933C-00A0C90DCAA9}"
```

I was too confident!
I forgot to make a copy of version 8.
It works very well, only V9 gives me problems!

----------


## Krool

I think I know the problem. When a interface is implemented into a UserControl then this makes no dependancy. But when a interface is implemented into a class module, like the CommonDialog.cls, then this interface is somehow dependant. Thus indeed the correct OLEGuids.tlb were necessary to run the latest VBCCR10.OCX and/or VBCCR11.OCX.
In order to solve this (to be independent to the OLEGuids.tlb) it is necessary to remove this new IObjectSafety from the CommonDialog.cls.
So we have then to live with the situation that only the actual controls are now marked as "safe".

I updated the OCX projects accordingly.

@lrd_VB6,
does the new OCX versions now work?

----------


## lrd_VB6

I just test it has now, everything seems to work normally. :Thumb: 
Sorry for the delay, but without electricity, it is not easy :big yellow:

----------


## lrd_VB6

hello,

Just a question:
Why keep the VBCCR10.OCX version?

I wrote (quickly) a converter to go from version 1.0 to 1.1.
I have used it to transform my sources without much effort.
This requires that be improved! :Roll Eyes (Sarcastic): 

Kind regards.

----------


## Krool

I have a added a .reg file on the post of each OCX version that will mark the CommonDialog class also "*Safe for Initialization and Scripting*".
It is necessary to do like this as contrary to the controls it is not possible to include the IObjectSafety interface in the CommonDialog class and to be also independent of the OLEGuids.tlb.

----------


## lrd_VB6

hello

I wish I could have access to the positioning of the box CommonDialog
I refer in particular to the message INIT_DIALOG (I think).
Is that possible?

Or a simpler something like a variable "StartupPosition"
CenterScreen or CenterWindow.
But the first idea allows more thing!

kind regards

----------


## Elroy

Say Krool,

FANTASTIC work.  I love the idea of having absolutely no OCX dependencies, without losing programming features.

I saw a comment above though about Unicode on the standard button.  Actually, this is no biggie at all.  I've attached a small project that does it.  The BAS module even has several other calls for doing Unicode things.

Also, it's not in there, but it's quite easy to write a CTL control based on little more than the button that saves Unicode from the IDE.  There are two tricks to getting this done: 1) You have to save the .Caption property into a byte array in the PropertyBag so that it's coerced into the .FRX file when you do a save.  The .FRM files are strictly ASCII so you can't save Unicode properties in them.  The second trick is that the actual Property Window won't handle Unicode either, so you have to design a custom property window for the button .Caption property using the RTF control with its Unicode turned on.

However, neither of those is terribly difficult.

Take Care,
Elroy
UnicodeButton.zip

Edit:  Ahhh, and I've actually done this but not cleaned it up for distribution.  In my opinion, if you're going to write a custom user control for a Unicode button, it should have the RTF box (for the Unicode property) actually on the control itself (in other words, no extra forms as support for the control).  Maybe you'll be motivated to do this with your API version of the RTF box.  Again, great work though.

----------


## ScriptBASIC

Hi Krool,

Outstanding job with the common controls replacement OCX. It works great (*.exe*) on XP, Win7 and Win10. I'm trying to use your OCX with ActiveX form contols I access with Script BASIC via it's COM OLE interface. Can the OCX be used in this way?

John Spikowski
Script BASIC open source project manager
www.scriptbasic.org

----------


## ScriptBASIC

> I have a added a .reg file on the post of each OCX version that will mark the CommonDialog class also "*Safe for Initialization and Scripting*".
> It is necessary to do like this as contrary to the controls it is not possible to include the IObjectSafety interface in the CommonDialog class and to be also independent of the OLEGuids.tlb.


I assume this topic is about using your control with ActiveX controls via and OLE scripted interface? I just posted a previous message on this topic. Clarification would be great!

----------


## ScriptBASIC

My first message was held for moderation as a new member but don't see it here.

Krool,

I have used your OCX with VB6 on XP, Win7 and Win10 with *.exe* based forms. I'm unable to get it to work with ActiveX forms (.dll) I'm scripting via Script BASIC. Does your OCX work in this environment?

----------


## Krool

> I have used your OCX with VB6 on XP, Win7 and Win10 with *.exe* based forms. I'm unable to get it to work with ActiveX forms (.dll) I'm scripting via Script BASIC. Does your OCX work in this environment?


I assume not. It does not even work in the VBA environment. Though one user claimed to get it to work by a few modifications, but he did not say which modifications were necessary.

----------


## ScriptBASIC

Thanks for the reply! 

Would you happen to know who that user was? It's critiacl I get AxtiveX forms themed and using current common controls.

----------


## ScriptBASIC

Krool,

Is source available for your enhanced common controls OCX project? The Script BASIC project would like to join in and expand on your work.

Here is a VB6 / COM ext. project for Script BASIC one of our developers contributed.

VB6 IDE/Debugger for embedded Script BASIC engine

John

----------


## Krool

> Would you happen to know who that user was? It's critiacl I get AxtiveX forms themed and using current common controls.


The name of the user is Thierry76. See below:




> I was working last week on a VBA OCX version... an i was quite happy with it, it work with few changes of your code...
> Is there anybody working/interesting to the same target ?
> 
> PS3 Could I share the resulte of my work here ?

----------


## ScriptBASIC

Thanks Krool!

I have sent Thierry76 a PM letting him know what I'm up to.

----------


## ScriptBASIC

Is source available for your enhanced common controls OCX project?

Resolving the issue of using your OCX replacement is going to be difficult if not impossible otherwise.

The reason I asked was this forum policy.

COM and ActiveX Policy Regarding Attachments

----------


## stum

Great work,

Only problem is the casual crashes on the IDE, (because of the hooks overuse i assume)
and the annoying windows crashing message when user closes the form, (when compiled).

which makes it rather impossible to relay on commercial use, but for private use its rather good.

By the way, if you're using VB6 on a 64bit system, be advised that WoW64 will make it difficult for you to place the .tlb file on C:\Windows\System and reference it to your project from there.
so just reference it to current file location (may it be even your desktop) regardless where it is, it will work just as good, even if not placed in C:\Windows\System.

----------


## Krool

> Great work,
> 
> Only problem is the casual crashes on the IDE, (because of the hooks overuse i assume)
> and the annoying windows crashing message when user closes the form, (when compiled).
> 
> which makes it rather impossible to relay on commercial use, but for private use its rather good.
> 
> By the way, if you're using VB6 on a 64bit system, be advised that WoW64 will make it difficult for you to place the .tlb file on C:\Windows\System and reference it to your project from there.
> so just reference it to current file location (may it be even your desktop) regardless where it is, it will work just as good, even if not placed in C:\Windows\System.


For commercial use I would rely on the OCX version, as it is IDE safe. And of course use the Side-by-Side technique to have not the step to register it first. By this the OCX just needs to be at the same place as a .exe, for instance.

BTW: Update released.

----------


## Elroy

Hey Krool, again, fantastic work, very impressive.  A comment.  For me, when using this, I'd never consider using the OCX version.  The most compelling reason (for me) to use your work would be to create EXE's that had no dependencies (other than the core dependencies built into all later versions of Windows).  What's cool about that is that it obviates any need to even think about the SxS stuff.  I've long dreamed of a way to have my OCX dependencies wrapped into the EXE upon compiling and have them treated as overlays (similar to a class for form).  And your work comes dangerously close to doing precisely that.

I guess, for me, if I'm going to use the OCX, I'll just stick with dependencies to all the other OCX files that your code does away with.

A question:  I taken a bit of a look at your work, and again, it's truly cool.  But I haven't studied it in detail.  Is it possible to, say, peel off one control and use just it?  (Say pulling out the CTL/CTX as well as its BAS module?)  I didn't really figure out if it was that well compartmentalized or not.

You take care,
Elroy

----------


## Krool

> A question:  I taken a bit of a look at your work, and again, it's truly cool.  But I haven't studied it in detail.  Is it possible to, say, peel off one control and use just it?  (Say pulling out the CTL/CTX as well as its BAS module?)  I didn't really figure out if it was that well compartmentalized or not.


You can of course just use those controls you actually need for your Std-EXE project. Only the common modules/classes need to be included. Regardless of how many controls you want, even when only using one.

----------


## ScriptBASIC

> I do intentionally not publish the *source code* for this to avoid redundancies.


 :EEK!: 

I'm curious how others are tweaking your control for their needs?

----------


## ScriptBASIC

Krool,

Could this be the reason your OCX enhancements aren't taking effect?



```
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

'this will show a non-modal form and return a reference to its
'form object which is a COM object that can be manipulated from the script
Public Function LaunchUI() As Long
    Set f = New Form1
    ShowWindow f.hwnd, 1 'this gets around can not display non modal form from dll thing..
    LaunchUI = ObjPtr(f)
End Function
```

----------


## ScriptBASIC

Damn. Ask about source or ActiveX DLL forms and you would think I just farted in the room.  :Roll Eyes (Sarcastic): 

Hope this thread gets rolling again!

----------


## Schmidt

> Damn. Ask about source or ActiveX DLL forms and you would think I just farted in the room. 
> 
> Hope this thread gets rolling again!


Your first question I don't really understand - because on page 1, post #1 of this thread 
there's all the Sources for the (admittedly non-ocx)-version...

That Krool prefers to do community-development on only the "Exe-Version" of his 
sources is understandable.
He considers that the "leading source" - and derives/updates the OCX-version 
(from time to time) from these newest sources.

Having both projects in the wild would be confusing and messsing up communication...


And that your second question is not answered, is because it's becoming a bit OffTopic IMO.

Your line:
ShowWindow f.hwnd, 1 'this gets around can not display non modal form from dll thing..

can very well cause misbehaviour with the COM-based OCX-Control-siting mechanism, 
when you avoid the intrinsic Form.Show method of the vbRuntime.

If I understand you correctly, you are searching for a nice COM-Dll-encapsulation of a 
broad set of Controls - if possible containing also a small (also COM-Dll-based) Form-Engine,
which is able to show all kind of TopLevel-Forms (no matter if modal or non-modal).

Well - such a thing exists in vbRichClient5 (other than VB6's intrinsic Form-Engine, fully Unicode-capable).

Here's a small example for how you would use it with VBScript (if that's any help) - 
and perhaps we should continue the discussion in the SubForum 'VBScript' or 'Other Basic-Dialects'
when you have further questions...

This part is only a preamble for VBScripts on 64Bit Win-Installations, to restart themselves 
in the 32-Bit ScriptingHost-Process (first snippet of e.g. a "TestRC5Binding.vbs" - file)



```
With CreateObject("WScript.Shell") 'this block auto-reshells a script to the 32Bit-WSH-version on Win64 (if needed)
	WS32on64 = .ExpandEnvironmentStrings("%SYSTEMROOT%\SysWOW64\wscript.exe")
	If StrComp(WScript.FullName, WS32on64, vbTextCompare) then 'So, when the Paths' differ, we...
	   If CreateObject("Scripting.FileSystemObject").FileExists(WS32on64) Then '...check if the target is there at all...
		 .Run """" & WS32on64 & """ """ & WScript.ScriptFullName & """", 1, False '...and re-launch the script to it!
		 WScript.Quit
	   End If
	End If
End With
```

Now the Form-Engine  and Widgets-Code, making use of VBScripts Event-Binding redirection-mechanism
(second part of "TestRC5Binding.vbs"):



```
'*** Cairo-Widgets-GUI per vbScript... Author: Olaf Schmidt (July 2013) ***
Set New_c = CreateObject("vbRichClient5.cConstructor") 'Main-RC5-Constructor

Set Cairo = New_c.Cairo 'ensure the global Cairo-Namespace-Entrypoint
	Set Form = Cairo.WidgetForms.Create(2, "MouseWheel to change Zoom", , 640, 480)
	WScript.ConnectObject Form, "Form_" '<-EventSink-Prefix and -Binding
	Form.Show
Cairo.WidgetForms.EnterMessageLoop 'here we enter the message-pump

Sub Form_Load()
    Form.Widgets.Add(CreateObject("vbWidgets.cwButton"),"btnHello").Caption = "Hello World"
	
	Form.Widgets.Add New cwMyWidget, "MyWidget1", 10, 10, 111, 88
	Form.Widgets.Add New cwMyWidget, "MyWidget2", 99, 77, 111, 88
End Sub

Sub Form_Resize()
    x = (Form.ScaleWidth  / Form.WidgetRoot.Zoom - 99) / 2
    y = (Form.ScaleHeight / Form.WidgetRoot.Zoom - 33) / 2
    Form.Widgets("btnHello").Widget.Move x, y, 99, 33
End Sub

Sub Form_MouseWheel(MouseKeys, Rotation, Xpos, Ypos)
	Zoom = Form.WidgetRoot.Zoom + 0.1 * Sgn(Rotation)
	If Zoom < 0.5 Then Zoom = 0.5 Else If Zoom > 2 Then Zoom = 2 
	Form.WidgetRoot.Zoom = Zoom
	Form_Resize
	Form.WidgetRoot.Refresh
End Sub

Sub Form_BubblingEvent(Sender, EventName, P1, P2, P3, P4, P5, P6, P7)
	If Sender.Widget.Key = "btnHello" And EventName = "Click" Then MsgBox "Hello World!"
		
	If TypeName(Sender) = "cwMyWidget" Then
	  Select Case EventName
	    Case "W_Paint": Sender.Paint P1, P4, P5 're-route to the Class
		Case "W_MouseEnter", "W_MouseLeave": Sender.Widget.Refresh
	  End Select
	End If
End Sub

Class cwMyWidget 'a small minimum-encapsulation for a cairo-Widget-Class
	Private W  'our class-internal Cairo.WidgetBase
	
	'below are the two Properties, any cwClass needs to implement 
	Property Get Widget():  Set Widget  = W:         End Property
	Property Get Widgets(): Set Widgets = W.Widgets: End Property
 
	Private Sub Class_Initialize()
	  Set W = Cairo.WidgetBase 'instantiate the internal W-WidgetBase 
	      W.BackColor = vbYellow: W.ForeColor = vbRed: W.Alpha = 0.6
		  W.FontName = "Arial": W.FontSize = 12 
	      W.Moveable = True
	End Sub

	Sub Paint(ByVal CC, ByVal dx, ByVal dy)
		CC.RoundedRect 0, 0, dx, dy, 7, True
		  CC.SetSourceColor (IIf(W.MouseOver, W.HoverColor, W.BackColor)), W.Alpha
		CC.Fill True '<- don't close the path yet
		  CC.SetSourceColor IIf(W.Focused, W.FocusColor, W.BorderColor), W.Alpha
		CC.Stroke

		'draw some centered Text, using the current W.Font...Props and W.ForeColor
		W.SelectFontSettingsInto(CC)
		S = "Hello World" & vbCrLf & "Cur.-Zoom: " & FormatPercent(W.Zoom)
		CC.DrawText 0, 0, dx, dy, CStr(S), False, 2, 4, True
	End Sub
End Class

Function IIf(Cond, ResultIfTrue, ResultIfFalse) 'add missing IIf to VBScript
	If Cond Then IIf = ResultIfTrue Else IIf = ResultIfFalse
End Function
```

So - in case your Scripting-Language supports COM in quite a similar way as VBScript, you 
can write full-blown Win-Applications with it - also note, that this approach contains a fully working
Control/Widget-Engine - so you could define your own Controls entirely in the Scripting-Language,
as shown with the small Class cwMyWidget above.

As said - better to continue in a new thread in case you see value in trying a few things with that approach
(which IMO is a better suited companion for Scripting - since as a Framework it contains "everything" - 
not just Controls).

Olaf

----------


## ScriptBASIC

*** moved ***

----------


## ScriptBASIC

Duplicate post ???

----------


## Schmidt

Would appreciate, when a moderator could move the last postings (from #496 onward) into a 
new thread in e.g.: http://www.vbforums.com/forumdisplay.php?16-Other-BASIC

... to continue the Discussion about "COM-Bindings to ScriptBasic" there...

Olaf

----------


## ishalom

a little bit a problem on the DateTimePicker control, when CustomFormat = "dd/MM/yyyy hh:mm:ss" the time cannot be edited on the control.
also on the Microsoft version you can edit each part of the date/time and move with the right/left key to the next part.

----------


## ScriptBASIC

Krool,




> For commercial use I would rely on the OCX version, as it is IDE safe.


Please excuse my ignorance as I just became aware of your library. I'm sensing the OCX version is not offered with source but there is another _fork_ that does include source? Please clear this up for me to stop the confusion.




> I taken a bit of a *look at your work*, and again, it's truly cool.


Why is this so confusing. Do only special members get to view source? Is your OCX a wrapper for the obvious that I seemed to have missed?

----------


## Arnoutdv

At the bottom of the first post there is a download link for the source code.

----------


## ScriptBASIC

> At the bottom of the first post there is a download link for the source code.


Thank You !!!

Sorry Krool for causing a stir about nothing. The thread and the project evolution took me a while to comprehend.

----------


## Krool

> a little bit a problem on the DateTimePicker control, when CustomFormat = "dd/MM/yyyy hh:mm:ss" the time cannot be edited on the control.
> also on the Microsoft version you can edit each part of the date/time and move with the right/left key to the next part.


Actually I cannot replicate your problem. However, I fixed another issue with the CustomFormat property. In fact that the CustomFormat property takes now only visible effect when the Format property is set to 'Custom'.

Can you describe your problem in more detail? (e.g. with a demo project or so)

----------


## wqweto

@Krool: I'm hoisting your UnsignedAdd implementation right away -- it's a one liner *and* it's faster than anything I've seen/produced :-))

The thing is we recently switched to set link=/largeaddressaware before compiling our apps and under stress my pointer arithmetic failed spectacularly with "overflow" errors near 2GB boundary.

Tell me you just used UnsignedAdd in you code out of habit and largeaddressaware flag was not something you were actively aware of? I can't think of any other case UnsignedAdd is needed for pointer arithmetic.

cheers,
</wqw>

----------


## Krool

> @Krool: I'm hoisting your UnsignedAdd implementation right away -- it's a one liner *and* it's faster than anything I've seen/produced :-))
> 
> The thing is we recently switched to set link=/largeaddressaware before compiling our apps and under stress my pointer arithmetic failed spectacularly with "overflow" errors near 2GB boundary.
> 
> Tell me you just used UnsignedAdd in you code out of habit and largeaddressaware flag was not something you were actively aware of? I can't think of any other case UnsignedAdd is needed for pointer arithmetic.
> 
> cheers,
> </wqw>


I am aware of this. Because of that critical point were the Long turns negative. (2GB positive, 2GB negative sign)

----------


## Jonney

As some senior programmers mentioned in other thread (http://www.vbforums.com/showthread.p...=1#post4782515),Owner-drawn textbox has some issues on Kazakh keyboard. In  Kazakh IME and type "asdf 890" in a TextBox, textbox show "фыва ???" instead of right "фыва үұқ". I think you have way to solve it.

----------


## ishalom

> Actually I cannot replicate your problem. However, I fixed another issue with the CustomFormat property. In fact that the CustomFormat property takes now only visible effect when the Format property is set to 'Custom'.
> 
> Can you describe your problem in more detail? (e.g. with a demo project or so)


well I just put a the datetime control on a form I can edit the time but when the focus goes to another control it reverts back to 00:00:00

----------


## Krool

> well I just put a the datetime control on a form I can edit the time but when the focus goes to another control it reverts back to 00:00:00


I don't have this problem. Do you have any code in the LostFocus event? Maybe something like this, or similar?


```
DTPicker1.Value = Int(DTPicker1.Value)
```

This will cause the time to be erased. Please check.




> As some senior programmers mentioned in other thread (http://www.vbforums.com/showthread.p...=1#post4782515),Owner-drawn textbox has some issues on Kazakh keyboard. In  Kazakh IME and type "asdf 890" in a TextBox, textbox show "фыва ???" instead of right "фыва үұқ". I think you have way to solve it.


I also get only "фыва ???". Also in the RichTextBox control. Don't know how to fix this. You can help?

----------


## Jonney

> As some senior programmers mentioned in other thread (http://www.vbforums.com/showthread.p...5),Owner-drawn textbox has some issues on Kazakh keyboard. In Kazakh IME and type "asdf 890" in a TextBox, textbox show "фыва ???" instead of right "фыва үұқ". I think you have way to solve it.





> I also get only "фыва ???". Also in the RichTextBox control. Don't know how to fix this. You can help?


Talent @tannerhelland has worked out solution in his PhotoDemon project. Please contact him on https://github.com/tannerhelland/PhotoDemon

----------


## Arnoutdv

He's a member on the forum:
http://www.vbforums.com/member.php?205967-Tanner_H

----------


## Tanner_H

Hi Krool.  I'll do my best to explain the "фыва ???" problem, and two possible solutions for it.  (I'm not sure I understand all the details of why the problem occurs, but maybe someone smarter than me can correct any mistakes.)

Key events don't arrive directly at a control.  They are first translated by the application's central message pump, using a series of functions: TranslateAccelerator, then TranslateMessage, and finally DispatchMessage.  Multiple functions are necessary because the message loop needs to check for accelerator key combinations.  If it finds one, it will send a WM_COMMAND or WM_SYSCOMMAND message to the parent window (instead of a WM_CHAR to the child window), so the parent can raise a menu or perform some other hotkey action.  

In VB, this is a problem for a Unicode window created by CreateWindowExW, because even though the child window is Unicode-aware, the main VB message pump isn't.  So Unicode character keypresses are converted to ANSI by the application's central TranslateMessageA/DispatchMessageA functions.

Pasting Unicode text into an edit box or RTB bypasses this problem, so there is no trouble pasting Kazakh text directly into an edit box.  IMEs can also bypass this problem, because they may perform the WM_KEYDOWN -> WM_CHAR conversion for you, bypassing VB's TranslateMessage entirely.  So Chinese input can work on the text box, for example, while a standard keypress from a Kazakh keyboard fails.

To my knowledge, this is why the problem occurs.  I can think of two possible solutions (but maybe there are more...?).

The solution I use is to subclass WM_KEYDOWN (which you do already, to raise KeyDown events).  Inside the WM_KEYDOWN message, you must perform your own translation from the virtual keycode into a Unicode character.  ToUnicode is the API that handles this.  Once ToUnicode has given you the correct Unicode character value, you can dispatch it manually to the edit box by sending your own WM_CHAR message, and supplying the Unicode value you obtained.

The second solution you could try is overriding the main VB message pump's -A functions with the -W equivalents.  In the thread Jonney linked, vbForums user wqweto describes his efforts to do this.  The advantage of this approach is not needing to manually generate your own Unicode characters for every Unicode-aware control that accepts key input.  However, I don't know if there are other side-effects with overriding VB's main functions this way.  (Windows should automatically convert Unicode messages sent to ANSI windows, but it's always hard to know side-effects with VB due to the way it custom handles some messages but not others.)

I hope this information helps.  You are welcome to look at or use my implementation if it's helpful.  It's BSD licensed and you can find it here.  The relevant window proc is the last function in the class.  I don't implement IOLEInPlaceActiveObject so there is some extra hooking code involved, but hopefully the ToUnicode stuff is not too hard to pick out.

----------


## DrUnicode

I would be hesitant to Hook the keyboard when there is another option.

A Vb6 solution for this problem was first published on 9/22/2000 in book "Internationalization with Visual Basic" by Michael Kaplan.
I had to modify the code slightly on 02-July-2005 to handle surrogate pairs (single keystroke generates 2 Unicode characters).
This technique can be applied to both TextBox and RichEdit controls.
Assuming the control is already subclassed, as would usually be the case for a control created with API CreatWindowExW:



```
Private Declare Function ToUnicodeEx Lib "user32" (ByVal uVirtKey As Long, ByVal uScanCode As Long, lpKeyState As Byte, ByVal pwszBuff As Long, ByVal cchBuff As Long, ByVal wFlags As Long, ByVal dwhkl As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, Src As Any, ByVal cb As Long) As Long

Private m_KeyCodeCached    As Long

'Cache the wParam in WM_KEYDOWN:
   m_KeyCodeCached = wParam And &HFFFF&

'Then, during WM_CHAR we get the Unicode character(s) by calling:

   Dim sChar            As String
   sChar = ToCharacterEx(wParam, m_KeyCodeCached, 0&)
   If Len(sChar) Then 'assign first Unicode character to wParam
      wParam = AscW(sChar)
   End If

'Again, in WM_CHAR, if there is a second character (Unicode surrogate pair) set m_KeyCodeCached as follows:

   If Len(sChar) > 1 Then 'In this case a second WM_CHAR will be generated
      m_KeyCodeCached = AscW(Mid$(sChar, 2, 1))
   End If

'Everything else is handled in WM_IME_CHAR or WM_IME_ENDCOMPOSITION.

'And finally the Function ToCharacterEx:

Private Function ToCharacterEx(ByVal KeyAscii As Long, _
   ByVal KeyCode As KeyCodeConstants, ByVal hKL As Long) As String
   
   Dim stBuff           As String
   Dim cch              As Long
   Dim cpg              As Long
   Dim lPtr             As Long
   Dim rgvkc(0 To 255)  As Byte

   stBuff = String$(32, vbNullChar)
   Call GetKeyboardState(rgvkc(0))

   lPtr = StrPtr(stBuff)
   cch = ToUnicodeEx(KeyCode, 0, rgvkc(0), lPtr, Len(stBuff), 0, hKL)
   ToCharacterEx = PtrToStrW(lPtr)
   If Not IsUnicode(ToCharacterEx) Then 'This may not be necessary
      ToCharacterEx = ChrW$(KeyAscii)
   End If

End Function

'And Function PtrToStrW:

'Dereference Unicode string pointer
Private Function PtrToStrW(ByVal lpsz As Long) As String
   Dim lLen    As Long
   If lpsz Then
      lLen = lstrlenW(ByVal lpsz)
      PtrToStrW = Space$(lLen)
      CopyMemory ByVal StrPtr(PtrToStrW), ByVal lpsz, lLen * 2
   End If
End Function

Private Function IsUnicode(s As String) As Boolean
   Dim i                As Long
   Dim bLen             As Long
   Dim Map()            As Byte

   If LenB(s) Then
      Map = s
      bLen = UBound(Map)
      For i = 1 To bLen Step 2 'Analise HighByte only.
         If (Map(i) > 0) Then
            IsUnicode = True
            Exit Function
         End If
      Next
   End If
End Function
```

----------


## Tanner_H

> I would be hesitant to Hook the keyboard when there is another option.


Thanks, DrUnicode.  I apologize for being unclear in my previous post - hooks shouldn't be required for Krool (or anyone else).  I only mentioned hooks in reference to _my_ sample code, if anyone decided to look at it.  I use hooks to solve a different problem, so some of my ToUnicode setup is handled outside the subclassing procedure, and I didn't want that to confuse anyone.

But your sample code is much more concise, so I definitely recommend referring to it instead of mine!




> A Vb6 solution for this problem was first published on 9/22/2000 in book "Internationalization with Visual Basic" by Michael Kaplan.
> I had to modify the code slightly on 02-July-2005 to handle surrogate pairs (single keystroke generates 2 Unicode characters).
> This technique can be applied to both TextBox and RichEdit controls.
> Assuming the control is already subclassed, as would usually be the case for a control created with API CreatWindowExW...


Do you know if your sample code has trouble handling dead characters?  I ask because Michael Kaplan did a great series on ToUnicode years after publishing his VB book, and he describes the extra steps required to work around ToUnicode's handling of dead keys.  (Relevant link: http://www.siao2.com/2005/01/19/355870.aspx)  There still seems to be a lot of confusion on this point (e.g. StackOverflow is full of questions on the topic), so I thought I'd mention it.

----------


## DrUnicode

> Do you know if your sample code has trouble handling dead characters?


No. All I can say is that I haven't had any support calls with IME complaints after fixing the surrogate issue in 2005.

----------


## Bonnie West

> ```
> 'And Function PtrToStrW:
> 
> 'Dereference Unicode string pointer
> Private Function PtrToStrW(ByVal lpsz As Long) As String
>    Dim lLen    As Long
>    If lpsz Then
>       lLen = lstrlenW(ByVal lpsz)
>       PtrToStrW = Space$(lLen)
> ...


Here's a shorter (and faster!) equivalent:



```
Private Declare Function SysReAllocString Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long) As Long

'Returns a copy of a null-terminated Unicode string (LPWSTR/LPCWSTR)

Private Function GetStrFromPtr(ByVal Ptr As Long) As String
    SysReAllocString VarPtr(GetStrFromPtr), Ptr
End Function
```

----------


## Tanner_H

So Krool, in a nutshell, here's how you can fix the problem with Kazakh (and other) keyboards:

1) Use DrUnicode's suggested code to capture the Unicode chars.  

2) DrUnicode's code needs one fix, if I may.  The return value of ToUnicode is important.  I recommend reading the full MSDN page for the function, but basically, the return code tells you the number of valid characters in the string that ToUnicode returns.  (It can also return 0 if no characters were generated, or -1 if a dead key was pressed.)  Anyway, if the return value is 1 or higher, you *must* use the return value to trim the string, because "the buffer may contain more characters than the return value specifies. When this happens, any extra characters are invalid and should be ignored."

3) After getting DrUnicode's fix working, you'll need to make sure dead keys still work.  Load up the US International keyboard and try a few keypresses:

` + a should give you à 
~ + n should give you ñ
' + e should give you é

...etc.  This should be checked because ToUnicode has some known issues with eating dead key presses when it's invoked.

4) If dead keys still work - great!  If not, let us know and hopefully we can sort it out.

----------


## DrUnicode

Typing "Tilde+a" and "Grave+a" I get this in Notepad and UniTextBox.

Notepad:
~a`a U.S. Normal
ãà     U.S. International
UniTextBox:
~a`a U.S. Normal
ãà      U.S. International

Looks good here.
Let`s wait for Krool to implement this and see if the results are the same.

----------


## georgekar

I found the solution again...
The system return always unicode last pressed as 94, or 0x5E, for dead keys... as Reserved (look here http://msdn.microsoft.com/en-us/libr...v=vs.85).aspx)

so in a keydown event we get that...
a 94 or -1 means...skip that....


```
  I = GetLastKeyPressed
 If I <> -1 And I <> 94 Then UKEY$ = ChrW(I) Else UKEY$ = ""
```

DrUnicode Thank you very much, for the excellent tasks you have for us...So now a simple upgrade " And I<>94 " to glist and the Textviewer can work with french keyboard (For greek keyboard that 94 keycode never produced...so there is a deeper layer for keyboard works I think...and I don't know...why???)

----------


## Krool

@ DrUnicode, your solution mightbe the best I guess. However, with your method I was able to fix the kazakh issue. But not the pair issue (dead key first), e.g. ^ + o = ô

You said you got it to work. Can you provide a full test sample. At best into my TextBox. Thanks

----------


## DrUnicode

U.S. Keyboard will not join ~ and a.
U.S. International will join them and print ã.
"Tilde" is to the left of Number 1 on U.S. International keyboard. Use shift to get it and then follow it with "a".
Try this in Notepad first.
Once you confirm this, try same in UniTextBox.

U.S. International layout (OnScreenKeyboard):

----------


## georgekar

Join as we speak, but this ã is another unicode char.

----------


## Krool

Does not work by me...  :Frown:

----------


## georgekar

In Xp those keys are blue...(here in red circles)

----------


## DrUnicode

> Does not work by me...


Does it work in Notepad but not in UniTextBox?

----------


## DrUnicode

This is with U.S. International:



This is with ABNT2 Brazilian Portuguese:

----------


## Krool

Ok, it seems to work now. Can anyone else check it out. By replacing the code in my TextBox as following:



```
Private TextBoxKeyCodeCache As Integer, TextBoxDeadKeyCodeCache As Integer
```



```
    Case WM_KEYDOWN, WM_KEYUP
        Dim KeyCode As Integer
        KeyCode = wParam And &HFF&
        If wMsg = WM_KEYDOWN Then
            RaiseEvent KeyDown(KeyCode, GetShiftState())
            If IsDeadKey(KeyCode) = True  And TextBoxDeadKeyCodeCache = 0 Then TextBoxDeadKeyCodeCache = KeyCode
            TextBoxKeyCodeCache = KeyCode
        ElseIf wMsg = WM_KEYUP Then
            RaiseEvent KeyUp(KeyCode, GetShiftState())
        End If
        wParam = KeyCode
    Case WM_CHAR
        Dim KeyChar As Integer, UniChar As String
        If TextBoxKeyCodeCache <> 0 Then
            If TextBoxDeadKeyCodeCache <> 0 Then
                KeyCodeToUniChar TextBoxDeadKeyCodeCache
                TextBoxDeadKeyCodeCache = 0
            End If
            UniChar = KeyCodeToUniChar(TextBoxKeyCodeCache)
            If Len(UniChar) > 1 Then
                TextBoxKeyCodeCache = CUIntToInt(AscW(Mid$(UniChar, 2, 1)))
            Else
                TextBoxKeyCodeCache = 0
            End If
        End If
        If Len(UniChar) > 0 Then
            KeyChar = CUIntToInt(AscW(UniChar))
        Else
            KeyChar = CUIntToInt(wParam And &HFFFF&)
        End If
        RaiseEvent KeyPress(KeyChar)
        If (wParam And &HFFFF&) <> 0 And KeyChar = 0 Then
            Exit Function
        Else
            wParam = CIntToUInt(KeyChar)
        End If
```



```
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyW" (ByVal uCode As Long, ByVal uMapType As Long) As Long
Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwThreadID As Long) As Long
Private Declare Function GetKeyboardState Lib "user32" (ByRef pbKeyState As Byte) As Long
Private Declare Function ToUnicodeEx Lib "user32" (ByVal uVirtKey As Long, ByVal uScanCode As Long, ByRef lpKeyState As Byte, ByVal lpwszBuffer As Long, ByVal cchBuffer As Long, ByVal wFlags As Long, ByVal hKL As Long) As Long

Public Function KeyCodeToUniChar(ByVal KeyCode As Integer) As String
Dim Buffer As String, BufferPtr As Long, B(0 To 255) As Byte, RetVal As Long
Buffer = String$(32, vbNullChar)
BufferPtr = StrPtr(Buffer)
GetKeyboardState B(0)
RetVal = ToUnicodeEx(KeyCode, 0, B(0), BufferPtr, Len(Buffer), 0, GetKeyboardLayout(0))
SysReAllocString VarPtr(KeyCodeToUniChar), BufferPtr
End Function

Public Function IsDeadKey(ByVal KeyCode As Integer) As Boolean
Const MAPVK_VK_TO_CHAR As Long = &H2
IsDeadKey = CBool(MapVirtualKey(KeyCode, MAPVK_VK_TO_CHAR) < 0)
End Function
```

----------


## DrUnicode

With your changes I'm getting "à" instead of "ã" with U.S. International keyboard.
What is strange is that I get this Grave accent both with and without shift.

BTW - I tried my original code also in your control and it worked OK, even with "ã".

----------


## DrUnicode

I don't know if this helps but if you hold the Shift Key, press Tilde and then "A" you get "Ã"
but if you release the shift after tilde you get "à" in lieu of "ã".

----------


## Krool

> With your changes I'm getting "à" instead of "ã" with U.S. International keyboard.
> What is strange is that I get this Grave accent both with and without shift.
> 
> BTW - I tried my original code also in your control and it worked OK, even with "ã".


Can you please show me your source code implemented into my TextBox? (couldn't get it work by me straight from your original code)

----------


## Krool

I found the reason. I skipped the following from your original code:


```
   If Not IsUnicode(ToCharacterEx) Then 'This may not be necessary
      ToCharacterEx = ChrW$(KeyAscii)
   End If
```

As I thought that this is not necessary. However, it actually is..

----------


## DrUnicode

Attached is IME code in your control. 
Attached Zip has only TextBoxW.ctl and Common.bas, the only 2 file that were modified.

----------


## georgekar

To many lines to make it to work. With much of research I found that the use of GetLastKeyPressed is what we need to do the job right.
These works for me...and I think that can be work for you too...If a key give two or more wchars then with GetLastKeyPressed  you don't need to interpret what it is interpreted for you...and in the right way...



```
dim UKEY$
Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoW" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As Long, ByVal cchData As Long) As Long
Private Declare Function GetKeyboardLayout& Lib "user32" (ByVal dwLayout&) ' not NT?
Private Const DWL_ANYTHREAD& = 0
Const LOCALE_ILANGUAGE = 1
Const WM_KEYFIRST = &H100  ' I have no idea why keyfirst must be &h100
 Const WM_KEYLAST = &H108
 Private Type POINTAPI
    X As Long
    Y As Long
End Type
 Private Type Msg
    hwnd As Long
    Message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End Type
Public Function GetLastKeyPressed() As Long
' no subclass
' we have one keyboard only so in the keydown...99.99% we get the keystroke
Dim Message As Msg
    If PeekMessageW(Message, 0, WM_KEYFIRST, WM_KEYLAST, 0) Then
        GetLastKeyPressed = Message.wParam
    Else
        GetLastKeyPressed = -1
    End If
    Exit Function
End Function

Function GetKeY(ascii As Integer) As String
    Dim Buffer As String, Ret As Long. r as long
    Buffer = String$(514, 0)
      r = GetKeyboardLayout(DWL_ANYTHREAD) And &HFFFF
      r = Val("&H" & Right(Hex(r), 4))
    Ret = GetLocaleInfo(r, LOCALE_ILANGUAGE, StrPtr(Buffer), Len(Buffer))
    If Ret > 0 Then
        GetKeY = ChrW$(AscW(StrConv(ChrW$(ascii Mod 256), 64, CLng(Val("&h" + Left$(Buffer, Ret - 1))))))
    Else
        GetKeY = ChrW$(AscW(StrConv(ChrW$(ascii Mod 256), 64, 1033)))
    End If
End Function



in keydown event
.........code for arrows and special keys
I = GetLastKeyPressed
 If I <> -1 And I <> 94 Then UKEY$ = ChrW(I) Else UKEY$ = ""


in keypress event
..................code for other keys...
 If EditFlag And KeyAscii > 32 And KeyAscii <> 127 Then
            If UKEY$ <> "" Then
            kk$ = UKEY$
            Else
  kk$ = GetKeY(KeyAscii)   ' this was the old way...I didn't deleted...If UKEY$ didn't work (if GetLastKeyPresserd give always -1, we can write...)
  End If
             RaiseEvent RemoveOne(kk$)   ' this is for undo
            If SelStart = 0 Then mSelstart = 1
           
            SelStartEventAlways = SelStart + 1
   
                List(SELECTEDITEM - 1) = Left$(List(SELECTEDITEM - 1), SelStart - 2) + kk$ + Mid$(List(SELECTEDITEM - 1), SelStart - 1)
            
         
            End If
         End If
```

With GetKey we can get the unicode from ascii...reading the keyboard localeid...but we miss the dead keys and double chars...
Now we have both...because we read the unicode value before. With the addition of Unicode No 94 as the dead key indicator..we are complete
In my control there is no RTB or other control..from third party. In fact there are no other control but the user control only, and three shapes for constructing the scroll bar.

----------


## Krool

I finally got it now to work, the solution was to save the keystate of the dead key.

@ DrUnicode, can you please test again on your side?



```
Private Declare Function GetKeyboardState Lib "user32" (ByRef pbKeyState As Byte) As Long

Private TextBoxKeyCodeCache As Integer, TextBoxDeadKeyCodeCache As Integer, TextBoxDeadKeyState(0 To 255) As Byte
```



```
    Case WM_KEYDOWN, WM_KEYUP
        Dim KeyCode As Integer
        KeyCode = wParam And &HFF&
        If wMsg = WM_KEYDOWN Then
            RaiseEvent KeyDown(KeyCode, GetShiftState())
            TextBoxKeyCodeCache = KeyCode
            If IsDeadKey(KeyCode) = True And TextBoxDeadKeyCodeCache = 0 Then
                TextBoxDeadKeyCodeCache = KeyCode
                GetKeyboardState TextBoxDeadKeyState(0)
            End If
        ElseIf wMsg = WM_KEYUP Then
            RaiseEvent KeyUp(KeyCode, GetShiftState())
        End If
        wParam = KeyCode
    Case WM_CHAR
        Dim KeyChar As Integer, UniChar As String
        If TextBoxKeyCodeCache <> 0 Then
            Dim ScanCode As Integer, B(0 To 255) As Byte
            ScanCode = LoByte(HiWord(lParam))
            If TextBoxDeadKeyCodeCache <> 0 Then
                KeyCodeToUniChar TextBoxDeadKeyCodeCache, ScanCode, TextBoxDeadKeyState()
                TextBoxDeadKeyCodeCache = 0
            End If
            GetKeyboardState B(0)
            UniChar = KeyCodeToUniChar(TextBoxKeyCodeCache, ScanCode, B())
            TextBoxKeyCodeCache = 0
        End If
        If Len(UniChar) > 0 Then
            KeyChar = CUIntToInt(AscW(UniChar))
        Else
            KeyChar = CUIntToInt(wParam And &HFFFF&)
        End If
        RaiseEvent KeyPress(KeyChar)
        If (wParam And &HFFFF&) <> 0 And KeyChar = 0 Then
            Exit Function
        Else
            wParam = CIntToUInt(KeyChar)
        End If
```



```
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyW" (ByVal uCode As Long, ByVal uMapType As Long) As Long
Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwThreadID As Long) As Long
Private Declare Function ToUnicodeEx Lib "user32" (ByVal uVirtKey As Long, ByVal uScanCode As Long, ByRef lpKeyState As Byte, ByVal lpwszBuffer As Long, ByVal cchBuffer As Long, ByVal wFlags As Long, ByVal hKL As Long) As Long

Public Function KeyCodeToUniChar(ByVal KeyCode As Integer, ByVal ScanCode As Integer, ByRef B() As Byte) As String
Dim Buffer As String, BufferPtr As Long, RetVal As Long
Buffer = String$(32, vbNullChar)
BufferPtr = StrPtr(Buffer)
RetVal = ToUnicodeEx(KeyCode, ScanCode, B(0), BufferPtr, Len(Buffer), 0, GetKeyboardLayout(0))
SysReAllocString VarPtr(KeyCodeToUniChar), BufferPtr
End Function

Public Function IsDeadKey(ByVal KeyCode As Integer) As Boolean
Const MAPVK_VK_TO_CHAR As Long = &H2
IsDeadKey = CBool(MapVirtualKey(KeyCode, MAPVK_VK_TO_CHAR) < 0)
End Function
```

----------


## georgekar

If someone press ' twice then the second time he has to get these ' two times.

----------


## DrUnicode

> @ DrUnicode, can you please test again on your side?


Yes. All working fine now. Tested Kazakh, U.S. Normal, U.S. International.

Did you remove this piece of code?


```
If Len(UniChar) > 1 Then
   TextBoxKeyCodeCache = CUIntToInt(AscW(Mid$(UniChar, 2, 1)))
```

I think you may need it for IME that generates 2 Unicode characters for single keystroke.
I can't remember which IME I tested this with because it was 9 years ago.

----------


## Krool

> Did you remove this piece of code?
> 
> 
> ```
> If Len(UniChar) > 1 Then
>    TextBoxKeyCodeCache = CUIntToInt(AscW(Mid$(UniChar, 2, 1)))
> ```
> 
> I think you may need it for IME that generates 2 Unicode characters for single keystroke.
> I can't remember which IME I tested this with because it was 9 years ago.


Yes I removed that. Because 2 Unicode characters by a single keystroke just happens when you press a dead key twice. (for e.g. pressing two times ^ will result in ^^ or 2x time WM_CHAR with key char ^)
This case is also described in the MSDN page for the ToUnicode API. ("_The most common cause for this is that a dead-key character (accent or diacritic) stored in the keyboard layout could not be combined with the specified virtual key to form a single character._")
But in our case this cannot happen. (VB's main loop itself will produce the WM_CHAR).
We just need to handle the case when a WM_CHAR is coming and previous key was a dead-key, in order to combine them.

Another point: AscW returns a key char and not a key code. Thus this would also be wrong, no?

----------


## DrUnicode

> Because 2 Unicode characters by a single keystroke just happens when you press a dead key twice.


It was 9 years ago when I ran into this issue reported by a customer.
Apparently a particular IME generated a surrogate pair, 2 Unicode characters for a single keystroke.
In this case you don't get a WM_KEYDOWN for the second charcter but you do get another WM_CHAR.
We need to find out which IME does this and which keystroke to test this.

----------


## georgekar

Maybe I write for nothing..but...I have solve this problem. I can't work with the library of Krool because I found difficulties to run it in Xp. 
We can get the pressing keys as unicode string before the keypress event..So we have to take these keys in a string and use it in the keypress event. So we need a string as  buffer, as a variable declared for  module/class/form/user control...The last pressing key return -1 if we have no char...so we skip the writing to the buffer. If we have a number 94 then that is ANY dead key (in any combination, so we don't have to read Shift state), and we just SKIP the buffer writing. In Keypress event we process the buffer if the key that supposed to give is a key in the range of keys and not delete or other<32 (in my control ascii code 32 is used for two things so I have to exclude it). 
So how we get  two or more keystrokes that produce ONE unicode code? Easy as you see, because we read the final Unicode code (so this is done from os for us)...and not the intermediate keystrokes. If you wish to write the OS again then make your own code..but in that situation..do not use the ready made control from MS...make your own, you will be happy too.  You can leave the original messages (by raising events prior the right process) to give external process for the final user...and check for changes to values and then "skip" the right process if you found any (because this process are not known to the final user).

----------


## Krool

> It was 9 years ago when I ran into this issue reported by a customer.
> Apparently a particular IME generated a surrogate pair, 2 Unicode characters for a single keystroke.
> In this case you don't get a WM_KEYDOWN for the second charcter but you do get another WM_CHAR.
> We need to find out which IME does this and which keystroke to test this.


Ok, then following way would solve it. (Though I cannot test)


```
    Case WM_CHAR
        Static SurrogateKeyChar As Integer
        Dim KeyChar As Integer, UniChar As String
        If TextBoxKeyCodeCache <> 0 Then
            If TextBoxDeadKeyCodeCache <> 0 Then
                KeyCodeToUnicode TextBoxDeadKeyCodeCache, TextBoxDeadScanCodeCache, TextBoxDeadKeyStateCache()
                TextBoxDeadKeyCodeCache = 0
            End If
            Dim KeyState(0 To 255) As Byte
            GetKeyboardState KeyState(0)
            UniChar = KeyCodeToUnicode(TextBoxKeyCodeCache, HiWord(lParam), KeyState())
            TextBoxKeyCodeCache = 0
        End If
        If Len(UniChar) > 0 Then
            KeyChar = CUIntToInt(AscW(UniChar))
            If Len(UniChar) > 1 Then SurrogateKeyChar = CUIntToInt(AscW(Mid$(UniChar, 2, 1)))
        Else
            If SurrogateKeyChar <> 0 Then
                KeyChar = SurrogateKeyChar
                SurrogateKeyChar = 0
            Else
                KeyChar = CUIntToInt(wParam And &HFFFF&)
            End If
        End If
        RaiseEvent KeyPress(KeyChar)
```

----------


## Krool

But still there is one important issue.
Open notepad and any of your Unicode TextBox. When you enter a dead key now in the notepad, for e.g. `. Then switch to the Unicode TextBox and enter the the 'a' character. Do you get 'à' or just 'a'? Same vice versa. The notepad does it correctly, seems like it somehow knows that a dead key was pressed before.

But I think in DrUnicode version this is not a problem due to the last thing "If Not IsUnicode(ToCharacterEx) Then" fixes this issue. But for me that is not a proper way.  :Stick Out Tongue:

----------


## Tanner_H

Nice work making progress on this!  While we're talking about dead keys, here's another language to test: Vietnamese.  The Vietnamese keyboard works a little differently because regular letters can function as dead keys, but only if they are followed by certain characters.

For example: in Notepad, typing 1 gives you:

ă

Typing 1 and then 9 erases that character, and replaces it with:

ặ

Similarly, typing 1 and then 8 gives you:

ắ

So that initial ă can be merged with a number of other diacritics, or it can be used as a standalone character.  This is different from other dead keys because the first character appears when pressed, and it's only treated as a dead key if a subsequent key modifies it in some way.  Hopefully your existing code works with these as well!

@Krool:




> "The notepad does it correctly, seems like it somehow knows that a dead key was pressed before."


ToUnicode, for better or worse, uses the global (kernel-mode) key buffer to assemble keystrokes.  So a dead key typed in one window will affect the ToUnicode buffer in another window.  It's part of what makes ToUnicode so difficult to use, because every time you call it, it rewrites the global key buffer, so trying to use it from a hook (for example) can prevent other windows from receiving the correct keystrokes.

----------


## Tanner_H

> It was 9 years ago when I ran into this issue reported by a customer.
> Apparently a particular IME generated a surrogate pair, 2 Unicode characters for a single keystroke.
> In this case you don't get a WM_KEYDOWN for the second charcter but you do get another WM_CHAR.
> We need to find out which IME does this and which keystroke to test this.


Could we test this with direct entry using the Alt key?  For example, Alt+173 569 should produce the surrogate pair character 𪘁.  

I haven't tested yet, but I'm not sure whether this still causes two WM_CHAR messages to be raised.  What's strange is that Notepad doesn't handle this kind of Alt+key input correctly.  (It produces a ☺character.)  However, WordPad correctly produces 𪘁.

----------


## wqweto

> But still there is one important issue.
> Open notepad and any of your Unicode TextBox. When you enter a dead key now in the notepad, for e.g. `. Then switch to the Unicode TextBox and enter the the 'a' character. Do you get 'à' or just 'a'? Same vice versa. The notepad does it correctly, seems like it somehow knows that a dead key was pressed before.


I'm positive Notepad knows nothing of this and doesn't need to mess with key down/up at all. It just uses the unicode version of the standard Edit windows control *and* has a unicode message pump as the main app loop (GetMessageW/DispatchMessageW). This way on WM_CHAR it does get a unicode character in wParam in the lower 16-bits (not only the lower 8-bits as in VB6).

VB6 run-time uses PeekMessageA/DispatchMessageA in the main msg pump, so even unicode hWnds (those created with CreateWindowExW or those with "unicode" wndproc set with SetWindowLongW) get a strippped down wParam on WM_CHAR -- the OS has done a Unicode to ACP (current system code page for non-unicode application) conversion on their behalf. And I doubt there is a reliable way to revert this conversion from ACP to Unicode once the damage is done.

You have to intercept WM_CHAR earlier, in case of VB6 dispatched messages in the control's wndproc it is already too late to take counter measures. I've tested CyberActiveX's Unicode rich-textbox (the free download) and it is not working with my keyboard (I'm a native Bulgarian using cyrillic alphabet with a twist -- almost like Kazakh one) -- unicode input get converted to ? both in the IDE and compiled. I can take screenshots, videos, whatever to prove it :-))

cheers,
</wqw>

----------


## georgekar

In post 533 I display that:
..........
If PeekMessageW(Message, 0, WM_KEYFIRST, WM_KEYLAST, 0) Then
        GetLastKeyPressed = Message.wParam
    Else
        GetLastKeyPressed = -1
    End If
    Exit Function
...........
And now in 544..we read it again...

----------


## DrUnicode

Using English iInternational I can type "`" in Notepad and  "a" in UniTextBox and I get the combined "à" in UniTextBox.
Same for keyboard ABNT2 Portuguese, type "~" in Notepad and "a" in UniTextBox and I get "â" in UniTextBox.
In both cases it works the other way around, accent in UniTextBox and "a" in Notepad gives "á" or "ã".

Tanner_H
Vietnamese:
In UniTextBox I get the correct character with 1, 1+9, 1+8
ă
ặ
ắ

In ComCtldemo I also get:
ă
ặ
ắ




> wqweto I've tested CyberActiveX's Unicode rich-textbox (the free download) and it is not working with my keyboard (I'm a native Bulgarian using cyrillic alphabet with a twist


There are 2 RichEdit controls that we distribute: 
One is UniRichEdit_BDC0849A.ocx, a wrapper for vbRichTextBox and we would not expect it to handle IME correctly.
The full Unicode version is UniRichEdit100_EDA1811C.ocx. This is the one that handles IME using same technique as UniTextBox.
You need to download UniSuitePlus to get this control.
UniTextBox is part of UniSuitePlus_BDC0849A.ocx which has 27 controls as a single ocx.

----------


## Tanner_H

> I'm positive Notepad knows nothing of this and doesn't need to mess with key down/up at all. It just uses the unicode version of the standard Edit windows control *and* has a unicode message pump as the main app loop (GetMessageW/DispatchMessageW). This way on WM_CHAR it does get a unicode character in wParam in the lower 16-bits (not only the lower 8-bits as in VB6).
> 
> VB6 run-time uses PeekMessageA/DispatchMessageA in the main msg pump, so even unicode hWnds (those created with CreateWindowExW or those with "unicode" wndproc set with SetWindowLongW) get a strippped down wParam on WM_CHAR -- the OS has done a Unicode to ACP (current system code page for non-unicode application) conversion on their behalf. And I doubt there is a reliable way to revert this conversion from ACP to Unicode once the damage is done.


I think we covered this ground a bit earlier in the thread...  :Wink: 

The ToUnicode API *can* be used to reverse-engineer the missing Unicode char.  It's not pretty, and you have to do some extra work to handle dead keys (because ToUnicode removes dead keys from the key buffer as it processes them).  But it does work.  No normal Unicode-aware program has reason to do this, because TranslateMessage (inside GetMessageW) typically does this for you.  But you can access ToUnicode directly and perform your own virtual key to character translations.

DrUnicode's solution (from Michael Kaplan, who literally wrote Microsoft's keyboard layout creator) handles this by waiting for WM_CHAR, then using ToUnicode to perform the same virtual key to Unicode translation that TranslateMessage normally would, using key state data cached during WM_KEYDOWN.

I found it easier to perform the translation inside WM_KEYDOWN, then dispatch the correct WM_CHAR message(s) manually.  Both of these methods produce the same Unicode output as a normal, W-aware message loop.

This said, there *are* some situations you can't solve this way.  As I just learned (in reference to my question about Alt+Unicode key values, above), Alt+# keypresses don't raise normal WM_KEYDOWN messages.  They raise WM_SYSKEYDOWN messages, and ToUnicode doesn't handle the WM_CHAR translation.  I don't know what does.  

So manual code is needed to cover this case, because WM_CHAR is indeed too late.

But for "normal" key events (including IME), these methods do work.  In fact, manual ToUnicode usage is the only way to convert keypresses to Unicode characters outside a normal message loop.  (For example, a windowless program.)  

@DrUnicode - awesome, that's great news.  I am also trying to track down an IME that produces surrogate pairs naturally (since we can't get them via Alt+numbers, as mentioned above).  I'll let you know if I find one.

----------


## Krool

Thanks to georgekar, I have finally a perfect solution.  :Smilie: 



```
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type TMSG
hWnd As Long
Message As Long
wParam As Long
lParam As Long
Time As Long
PT As POINTAPI
End Type
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageW" (ByRef lpMsg As TMSG, ByVal hWnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long

Public Function PeekCharCode(ByVal hWnd As Long) As Long
Dim Msg As TMSG
Const PM_NOREMOVE As Long = &H0, WM_CHAR As Long = &H102
If PeekMessage(Msg, hWnd, WM_CHAR, WM_CHAR, PM_NOREMOVE) <> 0 Then PeekCharCode = Msg.wParam
End Function
```

That 'PeekCharCode' function I do call in the WM_KEYDOWN message and cache it in a variable.
Then in the WM_CHAR message I cast this to back to wParam, but only in case the cache variable is <> 0.

I tested and it seems to work good. Even globally with the dead chars and so on.

Only issue might be the surrogate pairs, no? (But I don't know how to test this, since I do not know a sample) But in that case (surrogate pairs) the cached key char value would be 0 (due to no KeyDown before) but than the key char in WM_CHAR would be untouched. So at this point maybe not 100% but therefore the rest.  :Smilie: 

EDIT: Update released

----------


## wqweto

> Thanks to georgekar, I have finally a perfect solution. 
> 
> 
> 
> ```
> Private Type POINTAPI
> X As Long
> Y As Long
> End Type
> ...


@Krool: This is seems like a solution to the problem, good you somehow deciphered georgekar thoughts :-)) The only missing part is if someone uses SendMessage to send WM_CHAR to your wndproc (on-screen keyboard, whatever) then you don't get a chance to peek it on WM_KEYDOWN, more I doubt the WM_CHAR message even gets in the message queue.

Anyway, my proposal is to peek both ANSI *and* Unicode WM_CHARs (using both PeekMessageA and PeekMessageW one after another) and store these wParam's as an (ansi, unicode) pair for consecutive WM_CHAR handling. On WM_CHAR check if wParam is the ansi part of the pair and substitute with the unicode value, else leave wParam fall through.

@DrUnicode: I noticed you are including an upgraded release of a project of mine in your UniSuite -- the UniHookMenu. At least you've seen my profile picture on PSC from something like 12 years ago :-)) Btw, I like control's icon w/ the hook -- Dread Pirate Roberts, no? :-))

cheers,
</wqw>

----------


## Krool

> @Krool: This is seems like a solution to the problem, good you somehow deciphered georgekar thoughts :-)) The only missing part is if someone uses SendMessage to send WM_CHAR to your wndproc (on-screen keyboard, whatever) then you don't get a chance to peek it on WM_KEYDOWN, more I doubt the WM_CHAR message even gets in the message queue.
> 
> Anyway, my proposal is to peek both ANSI *and* Unicode WM_CHARs (using both PeekMessageA and PeekMessageW one after another) and store these wParam's as an (ansi, unicode) pair for consecutive WM_CHAR handling. On WM_CHAR check if wParam is the ansi part of the pair and substitute with the unicode value, else leave wParam fall through.


In that case (sending WM_CHAR manually) the wParam value of the sendmessage function will be used. Because the cache variable is zero and therefore the value of wParam gets not altered. So only when doing a user input (KeyDown) the wParam value in WM_CHAR gets altered, and in addition only when there is a WM_CHAR in the pipe-line already. That way, in my opinion, makes it very fail-safe.

----------


## Tanner_H

> @Krool: This is seems like a solution to the problem, good you somehow deciphered georgekar thoughts :-)) The only missing part is if someone uses SendMessage to send WM_CHAR to your wndproc (on-screen keyboard, whatever) then you don't get a chance to peek it on WM_KEYDOWN, more I doubt the WM_CHAR message even gets in the message queue.


Third-party applications that directly post Unicode character messages are hopefully using WM_UNICHAR.  This allows the target window to respond to the first probe (with wParam = UNICODE_NOCHAR, or 0xffff) with a 1, meaning it can accept WM_UNICHAR messages.

@Krool: it should be easy to add handling for WM_UNICHAR.  In fact, aside from the UNICODE_NOCHAR case, you could probably just forward WM_UNICHAR messages to your existing WM_CHAR code, and have it work without trouble.  (Though surrogate pairs might still require special handling...)

----------


## Krool

> Third-party applications that directly post Unicode character messages are hopefully using WM_UNICHAR.  This allows the target window to respond to the first probe (with wParam = UNICODE_NOCHAR, or 0xffff) with a 1, meaning it can accept WM_UNICHAR messages.
> 
> @Krool: it should be easy to add handling for WM_UNICHAR.  In fact, aside from the UNICODE_NOCHAR case, you could probably just forward WM_UNICHAR messages to your existing WM_CHAR code, and have it work without trouble.  (Though surrogate pairs might still require special handling...)


You mean like following?


```
Private Const WM_UNICHAR As Long = &H109, UNICODE_NOCHAR As Long = &HFFFF&

Case WM_UNICHAR
    If wParam = UNICODE_NOCHAR Then WindowProcControl = 1 Else SendMessage hWnd, WM_CHAR, wParam, ByVal lParam
    Exit Function
```

----------


## Tanner_H

That looks good to me!  

BTW, thanks for all your great work, Krool.  Really appreciate you sharing your controls.

----------


## lrd_VB6

hello

I slightly modified the control "Toolbar" because I thought it was not working properly.
Especially the height that I was not correct.

I was submiting your appobation but my tests are pretty conclusive.

I retouched all routines using "TB_GETSTYLE" and especially "UserControl_Resize"

What does the "TB_GETPADDING" because when I use the button size is wrong. (for me!).

I ask the question again:
Is it possible to have a control of the position "CommonDialog"?
This would be very useful to me! :wave: 

kind regards

Attachment 120825

----------


## Krool

> I slightly modified the control "Toolbar" because I thought it was not working properly.
> Especially the height that I was not correct.
> 
> I was submiting your appobation but my tests are pretty conclusive.
> 
> I retouched all routines using "TB_GETSTYLE" and especially "UserControl_Resize"
> 
> What does the "TB_GETPADDING" because when I use the button size is wrong. (for me!).
> 
> ...


I recommend the use of the CommonDialog class instead of a control in this case.
But, you can "wrap" the COmmonDialog class into a new UserControl, for you special needs.  :Smilie: 

For the ToolBar:
You are correct. TB_GETPADDING is wrong. ("The padding values are used to create a blank area between the edge of the button and the button's image and/or text")
And according to MSDN the divider line is always two-pixel. (CCS_NODIVIDER = "Prevents a two-pixel highlight from being drawn at the top of the control")
I will fix this soon. Thanks

----------


## Krool

> It was 9 years ago when I ran into this issue reported by a customer.
> Apparently a particular IME generated a surrogate pair, 2 Unicode characters for a single keystroke.
> In this case you don't get a WM_KEYDOWN for the second charcter but you do get another WM_CHAR.
> We need to find out which IME does this and which keystroke to test this.


It would be good to know which IME and what key exactly generates two WM_CHARs.
But the following would solve this case also?


```
Case WM_CHAR
    Dim KeyChar As Integer
    If TextBoxCharCodeCache <> 0 Then
        KeyChar = CUIntToInt(TextBoxCharCodeCache And &HFFFF&)
        TextBoxCharCodeCache = ComCtlsPeekCharCode(hWnd) ' Instead of 0&, look for another WM_CHAR in the pipeline.
    Else
        KeyChar = CUIntToInt(wParam And &HFFFF&)
    End If
```

And I tried some tests with PostMessage and SendMessage with manually WM_KEYDOWN and WM_CHAR and the current implementation seems to be very fail-safe. I could not detect an error with this solution. (peek charcode in WM_KEYDOWN)

----------


## wqweto

@Krool: Latest rich-textbox works with Bulgarian keyboard layout entering 'Shift+A' -- correctly produces ѝ (something like u with accent)

cheers,
</wqw>

----------


## DrUnicode

> It would be good to know which IME and what key exactly generates two WM_CHARs.
> But the following would solve this case also?


Went through my old Emails but could not find the one that addresses this issue.



```

Case WM_CHAR
    Dim KeyChar As Integer
    If TextBoxCharCodeCache <> 0 Then
        KeyChar = CUIntToInt(TextBoxCharCodeCache And &HFFFF&)
        TextBoxCharCodeCache = ComCtlsPeekCharCode(hWnd) ' Instead of 0&, look for another WM_CHAR in the pipeline.
    Else
        KeyChar = CUIntToInt(wParam And &HFFFF&)
    End If
```

This looks like it would solve the surrogate issue.

Tested your latest build with several IME and all worked OK.
Nice work.

----------


## lrd_VB6

hello

Too bad, I'm disappointed. :Cry: 
You have not used the code that I had proposed in the attached zip file.
I just tested the release and it does not work as well as mine.
Roll style "Align = Top" a "Align = Left" and it becomes almost imposible to adjust the width !!
I find your version a bit complicated but I have only tested on XP, so it may be there are things I do not know!

I find the code:



```
Private Function ChangeStyle(ByVal bSetMask, Mask As Long) As Boolean
Dim dwStyle As Long, NewStyle As Long

    If ToolBarHandle Then
        dwStyle = SendMessage(ToolBarHandle, TB_GETSTYLE, 0, ByVal 0&)

        If bSetMask Then
            NewStyle = dwStyle Or Mask
        Else
            NewStyle = dwStyle And Not Mask
        End If

        If dwStyle <> NewStyle Then
            SendMessage ToolBarHandle, TB_SETSTYLE, 0, ByVal NewStyle
            ChangeStyle = True
        End If
    End If

End Function

Public Property Let Divider(ByVal Value As Boolean)
    PropDivider = Value

    If ChangeStyle(Not PropDivider, CCS_NODIVIDER) Then
        SetWindowPos ToolBarHandle, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
        UserControl_Resize
    End If

    UserControl.PropertyChanged "Divider"
End Property
```

easier to read than:


```
Public Property Let Divider(ByVal Value As Boolean)
    PropDivider = Value

    If ToolBarHandle <> 0 Then
Dim dwStyle As Long

        dwStyle = SendMessage(ToolBarHandle, TB_GETSTYLE, 0, ByVal 0&)

        If PropDivider = True Then
            If (dwStyle And CCS_NODIVIDER) = CCS_NODIVIDER Then
                SendMessage ToolBarHandle, TB_SETSTYLE, 0, ByVal dwStyle And Not CCS_NODIVIDER
                SetWindowPos ToolBarHandle, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
            End If

        Else

            If Not (dwStyle And CCS_NODIVIDER) = CCS_NODIVIDER Then
                SendMessage ToolBarHandle, TB_SETSTYLE, 0, ByVal dwStyle Or CCS_NODIVIDER
                SetWindowPos ToolBarHandle, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
            End If
        End If

        Call UserControl_Resize
    End If

    UserControl.PropertyChanged "Divider"
End Property
```


Then my code version is "simpler" and does not have the default when you want to change the height or width if you change the property "*Align*"



```
Private Sub UserControl_Resize()
Static InProc As Boolean

    If ToolBarHandle = 0 Then Exit Sub
Dim dwStyle As Long
Dim mWidth  As Single, mHeight As Single
Dim mAlign  As VBRUN.AlignConstants
    If InProc Then Exit Sub
    InProc = True
    dwStyle = SendMessage(ToolBarHandle, TB_GETSTYLE, 0, ByVal 0&)

    With UserControl
        mAlign = .Extender.Align
'
'Align Change ?
'
        If ChangeStyle(mAlign = vbAlignRight Or mAlign = vbAlignLeft, CCS_VERT) Then ' force resize Height or Width

            Select Case mAlign 

                Case vbAlignTop, vbAlignBottom ', vbAlignNone
                    Me.Height = 10 

                Case vbAlignLeft, vbAlignRight
                    Me.Width = 10
            End Select

        End If

        MoveWindow ToolBarHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1 ' set size AND redraw for TB_AUTOSIZE calc
        SendMessage ToolBarHandle, TB_AUTOSIZE, 0, ByVal 0&

        GetIdealSize mWidth, mHeight
'
' In GetIdealSize() Now
'        If (dwStyle And CCS_NODIVIDER) = 0 Then
'            mHeight = mHeight + .ScaleY(2, vbPixels, vbContainerSize)
'        End If

        Select Case mAlign

            Case vbAlignTop, vbAlignBottom ', vbAlignNone
                mWidth = Me.Width

            Case vbAlignLeft, vbAlignRight
                mHeight = Me.Height

            Case Else
'optional, force a minimum width or height
                If Me.Height > mHeight Then mHeight = Me.Height
                If Me.Width > mWidth Then mWidth = Me.Width
        End Select

        .Size mWidth, mHeight
        MoveWindow ToolBarHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
    End With

    InProc = False
End Sub
```

But as I said, I did do the test ONLY on XP, so ....

Otherwise, nice work, I hope I can continue to make my contribution to the building.


kind regards

----------


## lrd_VB6

Oups

----------


## lrd_VB6

hello

Too bad, I'm disappointed. :Cry: 
You have not used the code that I had proposed in the attached zip file.
I just tested the release and it does not work as well as mine.
Roll style "Align = Top" a "Align = Left" and it becomes almost imposible to adjust the width !!
I find your version a bit complicated but I have only tested on XP, so it may be there are things I do not know!

I find the code:


```
Private Function ChangeStyle(ByVal bSetMask As Boolean, ByVal Mask As Long) As Boolean
Dim dwStyle As Long, NewStyle As Long

    If ToolBarHandle Then
        dwStyle = SendMessage(ToolBarHandle, TB_GETSTYLE, 0, ByVal 0&)

        If bSetMask Then
            NewStyle = dwStyle Or Mask
        Else
            NewStyle = dwStyle And Not Mask
        End If

        If dwStyle <> NewStyle Then
            SendMessage ToolBarHandle, TB_SETSTYLE, 0, ByVal NewStyle
            ChangeStyle = True
        End If
    End If

End Function

Public Property Let Divider(ByVal Value As Boolean)
    PropDivider = Value

    If ChangeStyle(Not PropDivider, CCS_NODIVIDER) Then
        SetWindowPos ToolBarHandle, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
        UserControl_Resize
    End If

    UserControl.PropertyChanged "Divider"
End Property
```

easier to read than:


```
Public Property Let Divider(ByVal Value As Boolean)
    PropDivider = Value

    If ToolBarHandle <> 0 Then
Dim dwStyle As Long

        dwStyle = SendMessage(ToolBarHandle, TB_GETSTYLE, 0, ByVal 0&)

        If PropDivider = True Then
            If (dwStyle And CCS_NODIVIDER) = CCS_NODIVIDER Then
                SendMessage ToolBarHandle, TB_SETSTYLE, 0, ByVal dwStyle And Not CCS_NODIVIDER
                SetWindowPos ToolBarHandle, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
            End If

        Else

            If Not (dwStyle And CCS_NODIVIDER) = CCS_NODIVIDER Then
                SendMessage ToolBarHandle, TB_SETSTYLE, 0, ByVal dwStyle Or CCS_NODIVIDER
                SetWindowPos ToolBarHandle, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
            End If
        End If

        Call UserControl_Resize
    End If

    UserControl.PropertyChanged "Divider"
End Property
```


Then my code version is "simpler" and does not have the default when you want to change the height or width if you change the property "*Align*"



```
Private Sub UserControl_Resize()
Static InProc As Boolean

    If ToolBarHandle = 0 Then Exit Sub
Dim dwStyle As Long
Dim mWidth  As Single, mHeight As Single
Dim mAlign  As VBRUN.AlignConstants
    If InProc Then Exit Sub
    InProc = True
    dwStyle = SendMessage(ToolBarHandle, TB_GETSTYLE, 0, ByVal 0&)

    With UserControl
        mAlign = .Extender.Align
'
'Align Change ?
'
        If ChangeStyle(mAlign = vbAlignRight Or mAlign = vbAlignLeft, CCS_VERT) Then ' force resize Height or Width

            Select Case mAlign 

                Case vbAlignTop, vbAlignBottom ', vbAlignNone
                    Me.Height = 10 

                Case vbAlignLeft, vbAlignRight
                    Me.Width = 10
            End Select

        End If
' necessary if the calculation does not work
' set size AND redraw for TB_AUTOSIZE calc
        MoveWindow ToolBarHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
' 
        SendMessage ToolBarHandle, TB_AUTOSIZE, 0, ByVal 0&

        GetIdealSize mWidth, mHeight
'
' In GetIdealSize() Now
'        If (dwStyle And CCS_NODIVIDER) = 0 Then
'            mHeight = mHeight + .ScaleY(2, vbPixels, vbContainerSize)
'        End If

        Select Case mAlign

            Case vbAlignTop, vbAlignBottom ', vbAlignNone
                mWidth = Me.Width

            Case vbAlignLeft, vbAlignRight
                mHeight = Me.Height

            Case Else
'optional, force a minimum width or height
                If Me.Height > mHeight Then mHeight = Me.Height
                If Me.Width > mWidth Then mWidth = Me.Width
        End Select

        .Size mWidth, mHeight
        MoveWindow ToolBarHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
    End With

    InProc = False
End Sub
```

But as I said, I did do the test ONLY on XP, so ....

Otherwise, nice work, I hope I can continue to make my contribution to the building.


kind regards

----------


## Krool

I'm happy with the UserControl_Resize handler how it is now. Only the Padding component was wrong, thanks for this. But the rest is OK for me.

You removed the row count check at the bottom. But if the ToolBar is wrappable then this is necessary when you resize once and the ToolBar adjust itself (row more or less) then the UserControl needs to resize also. For the Align things. This is also not for nothing there. This is when you change the Align at runtime, for instance. The width can be freely set when Align is None.

----------


## ishalom

Krool
When you release an update is it for the source code, the ocx or both?

----------


## lrd_VB6

> I
> You removed the row count check at the bottom. But if the ToolBar is wrappable then this is necessary when you resize once and the ToolBar adjust itself (row more or less) then the UserControl needs to resize also.


hello

Just for know, have you tried my code?

I removed this part, because it worked very well without.

When the property "*Wrappable*"is on, resizing works perfectly (on XP).
In either case, the reaction of undetermined. But your version does not seem to do better.

Now it may be there a case I did not think a check. nobody is perfect.
As long as it works well, it is not important.

kind regards

----------


## Krool

> hello
> 
> Just for know, have you tried my code?
> 
> I removed this part, because it worked very well without.
> 
> When the property "*Wrappable*"is on, resizing works perfectly (on XP).
> In either case, the reaction of undetermined. But your version does not seem to do better.
> 
> ...


When you resize with the mouse then the resize handler will be fired constantly. But when you resize only 'once' you will see the point I mean. However..

----------


## fafalone

Where is the IEnumVARIANT in your project coming from? I don't see it defined in the included OLEGuids and 'show definition' can't find it either. This needs to be explicitly referenced, because if you've defined it in another typelib with the standard declare from oaidl.idl (as it is in olelib.tlb), there's a type mismatch error and full VB crash as soon as you add a control to your form. Until it's specifically referenced I did a temporary fix by just removing it from olelib and recompiling the tlb, but in case I ever need it elsewhere I'd like to figure out a better solution.

Edit: I'm still getting type mismatches at random times in the IDE when I interact with the TextBoxW control, trying to figure out what's causing them, I suspect another conflicting interface. Fixing IEnumVARIANT did make a difference; the errors are no longer immediate. I can force the error by renaming or deleting a standard textbox then clicking on the textboxw. really weird.

Edit2: It's a handled error and changing break on all errors to break on unhandled errors stops the crashing, BUT; all the custom properties disappear. No '(Custom)', no Text, no OleANYTHING. This is just getting weirder by the minute. If I reload VB, they come back, until I do something to another textbox again.

Edit3: That seems to be a problem with having the real windows common controls in the same project. It causes the disappearing properties issue even in the sample project--- but even for the TextBox, which is not part of that in vb.
I may possibly have gotten a hint; I added the TabStrip to my form, restarted VB, and when I tried load the form it was on, I got a Type Mismatch error on this line in UserControl_ReadProperties:
.Contents = PropBag.ReadProperty("InitTabs", 0)

I'm unsure how to fix it though as there's only 1 PropertyBag type. I tried making it explicitly VBRUN.PropertyBag and adding CVar(), but no change.

Edit4: Removing the reference to MS common controls did not fix the problem. I can create a new project, add the new controls, have them work fine, add a reference to MS comctrl, the new controls start losing properties/erroring, I remove the reference to MS comctrols, but the new controls no longer work even if deleted and added again even with a VB restart. Absolutely maddening.

Edit5: Something else is causing an identical issue. I created a whole new project that never referenced MS comctl; error still happened. Really about to give up on this wonderful project and go back to manually doing it without user controls (which i had been doing since i hated ocx's and ctl's to begin with). The conflict is also coming from shell32 shell controls/automation reference, AND ms activex data objects 2.5. Everything good, add reference to one of those, no longer good.

Trying to narrow it down a bit; this line is in VTableHandle.bas causing a type mismatch error. Whether it's the only one I don't know, but it's a clue
Private Function IPPB_GetPredefinedStrings(ByVal This As Object, ByVal DispID As Long, ByRef pCaStringsOut As OLEGuids.OLECALPOLESTR, ByRef pCaCookiesOut As OLEGuids.OLECADWORD) As Long
and also Private Function IPPB_GetDisplayString(ByVal This As Object, ByVal DispID As Long, ByVal lpDisplayName As Long) As Long
and presumably the other IPPB_ function
[...]
*Set ShadowIPerPropertyBrowsingVB = This*

----------


## Krool

> Where is the IEnumVARIANT in your project coming from?


IEnumVARIANT is hidden. It is a member of the stdole library. (stdole2.tlb)
This library is referenced in VB6 by default.

----------


## Jonney

TextBoxW's LeftMarge/RightMarge doesn't work seemly.

----------


## Krool

> TextBoxW's LeftMarge/RightMarge doesn't work seemly.


What does not work? The property expects a value based on the scale mode of the container, e.g. in twips.

So - in twips - for a 5 pixel margin you would need a value of 75 (5*15) and not 5. (5 would be then actually a margin of 0 pixels)

----------


## reexre

maybe a stupid question:

If I rename the OCX as RES and embed it in a project as resource, does it work? and the EXE will run even in a system without VB6Runtimes ?

----------


## Krool

> maybe a stupid question:
> 
> If I rename the OCX as RES and embed it in a project as resource, does it work? and the EXE will run even in a system without VB6Runtimes ?


The OCX itself will need the VB6Runtimes. There is no way for this.
Included it in a resource?! Never heard of it.

----------


## reexre

> Included it in a resource?! Never heard of it.


I tried:

-I renamed VBCCR11.*OCX* to VBCCR11.*RES*
-Created a project and insert this .RES (Project - add File ... )
-Created the EXE
It Works!

----------


## Krool

> I tried:
> 
> -I renamed VBCCR11.*OCX* to VBCCR11.*RES*
> -Created a project and insert this .RES (Project - add File ... )
> -Created the EXE
> It Works!


And what is the sense of this? Will the exe run without the OCX registered on another system?

----------


## Jonney

> What does not work? The property expects a value based on the scale mode of the container, e.g. in twips.
> 
> So - in twips - for a 5 pixel margin you would need a value of 75 (5*15) and not 5. (5 would be then actually a margin of 0 pixels)


Feel silly. I Neglected scale mode.

I verify the KeyDown KeyCode differs to KeyUp Keycode. For example,In Baidu Chinese Input Mode, I typing "z" then "w" after press "1" to pick up Word combination:

KeyDown: 229
KeyUp: 90 ---> "z"
KeyDown: 229
KeyUp: 87 --->"w"
KeyDown: 229
KeyPress: 20013
KeyPress: 25991
KeyUp: 49 --"1"

It seems that KeyDown's KeyCode is not correct. KeyUp and KeyPress are OK.



Edited:
VB's Textbox KeyDown also is 229. So ignore my comment :Blush: .

KeyDown: 229 
KeyUp: 90 
KeyDown: 229 
KeyUp: 87 
KeyDown: 229 
KeyPress:-10544 
KeyPress:-12604 
KeyUp: 49

----------


## Schmidt

> I tried:
> 
> -I renamed VBCCR11.*OCX* to VBCCR11.*RES*
> -Created a project and insert this .RES (Project - add File ... )
> -Created the EXE
> It Works!


I'm quite sure it will not work, when you (priorily to running your Exe) -
first de-register the VBCCR11.ocx from your development-machine.

Olaf

----------


## reexre

I forgot to say that in Main Form I have put



```
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
                                     ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" ( _
                                     ByVal hLibModule As Long) As Long


Private Sub Form_Initialize()
    m_hMod = LoadLibrary("shell32.dll")
End Sub

Private Sub Form_Unload(Cancel As Integer)
    FreeLibrary m_hMod
    End
End Sub
```





> it will not work, when you (priorily to running your Exe) -
> first de-register the VBCCR11.ocx


I tried but unable to unregister [Search registry with REGEDIT. Did not found VBCCR11]

----------


## fafalone

> IEnumVARIANT is hidden. It is a member of the stdole library. (stdole2.tlb)
> This library is referenced in VB6 by default.


Ok but what about all the other conflicts? The properties are still disappearing an crashing if I turn off unhandled errors. Having a project with zero other references besides yours is not practical. Shell32 and MSADO 2.5 being present is still causing the issue; verified with a blank project with only these ctl's and those references.

----------


## Krool

> Ok but what about all the other conflicts? The properties are still disappearing an crashing if I turn off unhandled errors. Having a project with zero other references besides yours is not practical. Shell32 and MSADO 2.5 being present is still causing the issue; verified with a blank project with only these ctl's and those references.


So the crash appears when adding the references? Are there any forms "open" when you do that. Maybe try to close all forms, save, add references, save. ?

And what happens if turn back on unhandled errors?

----------


## Schmidt

> it will not work, when you (priorily to running your Exe) -
> first de-register the VBCCR11.ocx 
> 			
> 		
> 
> I tried but unable to unregister [Search registry with REGEDIT. Did not found VBCCR11]


In case you were really using the OCX-version, then you would need a registered version,
to be able to use the OCX in the IDE (and to be able to compile your project) on your Dev-machine.

Are you sure you have no entries in the registry (although the OCX shines up in your IDE-project)?

Olaf

----------


## fafalone

> So the crash appears when adding the references? Are there any forms "open" when you do that. Maybe try to close all forms, save, add references, save. ?
> 
> And what happens if turn back on unhandled errors?


The crash occurs after adding one of your controls, interacting with another control, then going back to your control. If 'break on all errors' is on, there's a type mismatch error and VB immediately crashes. If its 'break on unhandled errors', all the custom properties disappear until VB is restarted (or I can delete the control and re-add it). This occurs even with a blank project with nothing but 2 controls on the form and said references. I know my original post on this issue was long, but I went as far as I could and through painstaking debug statements identified the line where the error originates:
Set ShadowIPerPropertyBrowsingVB = This in IPPB_GetDisplayString, IPPB_GetPredefinedValue, and IPPB_GetPredefinedStrings
That causes a type mismatch error only when the problem happens so presumably it's the cause, because if I disable the hook that results in it being called the custom properties disappear also. Since both objects are explicitly typed, and there's no duplicate reference that is visible anyway, I don't know how to fix the issue.


Additional Information:
--------
I added an error trap specifically for that line and that line only;
On Error Goto error routine 2
Set IPerProp...
On Error Goto original error routine
with both error routines now having outputs .Error, .Error2. When the error/crash occurs, the errors occur in this sequence (for TextBoxW at least, I suspect it's one error for each custom property).


```
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetPredefinedStrings.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetPredefinedStrings.Error2->Type mismatch
```

Not sure if it's relevant, but additional replacement routines IOleControl_x , IEnumeration_x, and IOleIPAO all have extremely similar Set interface = This statements, and don't produce any errors at any time.


Edit:
So I tried the close, add, save, open routine you suggested and it appears to work ok under a blank project, but existing projects, I can't even save without huge numbers of errors being spawned from missing references, and it doesn't appear to work in any case since I can't dereference everything without taking a few days to comment out code and rebuild forms. Really hope to figure out a better solution since recreating even a minor project to work with this one would take many hours.

----------


## Krool

> Edit:
> So I tried the close, add, save, open routine you suggested and it appears to work ok under a blank project, but existing projects, I can't even save without huge numbers of errors being spawned from missing references, and it doesn't appear to work in any case since I can't dereference everything without taking a few days to comment out code and rebuild forms. Really hope to figure out a better solution since recreating even a minor project to work with this one would take many hours.


Open the .frm files in the text editor and change it directly there in one swoop. And for instance for the TabStrip control. Of course the 'InitTabs' property will cause an error when converting from the MS comctls. Thus delete the tabs section in the .frm files. You need to recreate the tabs then again in the IDE.
And in general. When adding a new reference to something it is recommended to have all forms close as the UserControls likes to 'die' when a reference is added.
And its true, the OCX will be always more stable in the IDE as the UserControls. Because when the OCX 'dies' then this is a separate binary and does not touch your current project.

----------


## SMC1979

Little of topic here, but while trying out the image combo I noticed that you cant change the colors on it properly. My program lets the users change colors, all the other controls work fine, but on the image combo when I change the background color it doesnt show till ran, which is fine, and the back ground will change color but the text is then inside a white box and ignores any colors I set, also the drop down menu doesnt take any colors changes as well.

I can post a screen shot of you like.

Shane

----------


## Krool

> I verify the KeyDown KeyCode differs to KeyUp Keycode. For example,In Baidu Chinese Input Mode, I typing "z" then "w" after press "1" to pick up Word combination:
> 
> KeyDown: 229
> KeyUp: 90 ---> "z"
> KeyDown: 229
> KeyUp: 87 --->"w"
> KeyDown: 229
> KeyPress: 20013
> KeyPress: 25991
> ...


I googled this and it seems that if an Input Method Editor is processing key input and the event is keydown, it returns always 229. Thus this is not a bug on my side.




> Little of topic here, but while trying out the image combo I noticed that you cant change the colors on it properly. My program lets the users change colors, all the other controls work fine, but on the image combo when I change the background color it doesnt show till ran, which is fine, and the back ground will change color but the text is then inside a white box and ignores any colors I set, also the drop down menu doesnt take any colors changes as well.


Yes. The BackColor is very restricted in the ImageCombo control. It works the best if the Style property is set to 'DropDownCombo' and not 'DropDownList'.
The drop down menu color change could be included but since it looks ugly (text background color is opaque and cannot be changed, thus its backcolor is then white) I did not include it.
Also the BackColor is in general ignored if you are Vista+ and use VisualStyles.
Yeah, the ImageCombo is a little bit messy at some points.

----------


## fafalone

> Open the .frm files in the text editor and change it directly there in one swoop. And for instance for the TabStrip control. Of course the 'InitTabs' property will cause an error when converting from the MS comctls. Thus delete the tabs section in the .frm files. You need to recreate the tabs then again in the IDE.
> And in general. When adding a new reference to something it is recommended to have all forms close as the UserControls likes to 'die' when a reference is added.
> And its true, the OCX will be always more stable in the IDE as the UserControls. Because when the OCX 'dies' then this is a separate binary and does not touch your current project.


A direct solution is needed. I've also found errors during runtime coming from that line in IOleControl_GetControlInfo too. Since this doesn't happen in any other user control there's gotta be another way of doing things without setting the interface that way. Can you at least elaborate a little bit about what this function is doing so I can implement it another way?

----------


## Krool

Update released.
Quite important when using the ImageList control. (Though it effects actually only WinXP)

----------


## ishalom

on the toolbar you can only set the image of the bound ImageList by index and not by key, any reason for that?

----------


## Jonney

Krool, Please consider this API SetWindowTheme to add full theme support for Listview / Treeview  on Vista/Win7/Win8:

In your demo Main():
Private Declare Function SetWindowTheme Lib "uxtheme.dll" (ByVal hWnd As Long, ByVal pszSubAppName As String, ByVal pszSubIdList As String) As Long

    Call ComCtlsInitIDEStopProtection
    Call InitVisualStyles
    Call SetWindowTheme(MainForm.TreeView1.hWnd, StrConv("explorer" & Chr(0), vbUnicode), vbNullString)
    Call SetWindowTheme(MainForm.ListView1.hWnd, StrConv("explorer" & Chr(0), vbUnicode), vbNullString)
    Call SetWindowTheme(MainForm.ListView2.hWnd, StrConv("explorer" & Chr(0), vbUnicode), vbNullString)
    Call SetWindowTheme(MainForm.ListView3.hWnd, StrConv("explorer" & Chr(0), vbUnicode), vbNullString)

You can use SetWindowThemeW as well.

Refer to screenshot.

----------


## Krool

> I show the vbLongDate and vbLongTime in the StatusBar. With every new version, I would go into StatusBar.ctl's Sub GetDisplayText to change Case SbrPanelStyleTime and Case SbrPanelStyleDate accordingly.
> 
> Without changing StatusBar.ctl, is there any way I can make the change in my project Form_Load? This will make it much easier.


For the panel's 'Style' property values 'Time', 'Date' and 'DateTime' the vbShortDate/vbShortTime will be used for the GetDisplayText function. Just like the MS StatusBar control does.

However, I could implement a panel's 'DTFormat' property? Which is set by default with 'Short', but could be then also set to 'Long'.
If set to 'Long' then the GetDisplayText function would use vbLongDate/vbLongTime instead of vbShortDate/vbShortTime.

Let me know your opinion.

----------


## chosk

Hi Krool,

This will be great. Thank!

----------


## Krool

Update released.

----------


## chosk

Hi Krool,

Thanks very much for the DTFormat. I want to let you know it is very much appreciated.

Thanks again.

----------


## Krool

Update released.

----------


## lrd_VB6

Hello

I tested the tooltips proposed by VBOCX11 and I do not understand why they have the default graphics that do not have my class ToolTips ...
I watched how the window is initialized "tooltips_class32" and I do not see why it does not work well.

I put in the example images with and without the fault.
Seems like the 3D effect is shifted by 1 pixel.

My ToolTip Attachment 122181
Your ToolTip Attachment 122183

Why did you create ToolTip as a "UserControl"?

Take a look at the "Populate" method is fast to add ToolTips has a form.
We can also attach a ToolTip has an object having no handle (hWnd). for example a "Shape"

I also create a class "cTabStripPictures" for managing bottom of TabStrips boxes with good background colors.
Works properly from "XP" up to "W8".

I hope this will give you ideas.

good continuation.

Best Regards
Attachment 122185
Attachment 122187

Postscript, Sorry for my english (it's rotten, I know) :Frown:

----------


## Krool

Update released.

----------


## adrez

Krool, 
- What type of license is this library released under?  
- Would you be willing to discuss source-code availability?
PM me if you prefer.

Thanks!

----------


## Jonney

A serious bug? The TextBoxW and RichTextBox can't move cursor by Left/Right Key after adding into a UserControl.
Version: 29Dec2014

----------


## Krool

> A serious bug? The TextBoxW and RichTextBox can't move cursor by Left/Right Key after adding into a UserControl.
> Version: 29Dec2014


This is not a bug. The VB.Form is forwarding the IOleInPlaceActiveObject::TranslateAccelerator method to the UserControl. If now a UserControl (e.g. TextBoxW) is embedded into another UserControl then VB will not forward the IOleInPlaceActiveObject::TranslateAccelerator method to the underlying UserControl.

So in each chain of this embedding the IOleInPlaceActiveObject interface must be implemented and forwarded.

In your case, probably only the case where my UserControl (e.g. TextBoxW) is embedded in "your" UserControl you need to add the following code to "your" UserControl:



```
Implements OLEGuids.IOleInPlaceActiveObjectVB

Private Sub IOleInPlaceActiveObjectVB_TranslateAccelerator(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal Shift As Long)
On Error Resume Next
Dim This As OLEGuids.IOleInPlaceActiveObjectVB
Set This = UserControl.ActiveControl.Object
This.TranslateAccelerator Handled, RetVal, wMsg, wParam, lParam, Shift
End Sub
```

This topic was already discussed in this thread.

----------


## Krool

> - What type of license is this library released under?  
> - Would you be willing to discuss source-code availability?


There is no license on the library.
We can discuss source-code for the library. But not the whole. This can be a reason for CLSIDs conflicts for future in the world wide web.  :Smilie:

----------


## Krool

> Why did you create ToolTip as a "UserControl"?


I am planning to end support of the ToolTip control and remove it from the project. As there are plenty of ToolTip classes already available.

----------


## Krool

> on the toolbar you can only set the image of the bound ImageList by index and not by key, any reason for that?


Yes, because of performance issues. Especially on the ListView. (obtaining real index by a key in a ImageList control)
For for non-mass items containing controls it can be an option, as the ToolBar or TabStrip is. Will see.  :Wink:  Maybe I will include it someday.

----------


## Krool

This is the 1.2 ActiveX Control version. (End of support)

_Removed_

----------


## Jonney

> This is not a bug. The VB.Form is forwarding the IOleInPlaceActiveObject::TranslateAccelerator method to the UserControl. If now a UserControl (e.g. TextBoxW) is embedded into another UserControl then VB will not forward the IOleInPlaceActiveObject::TranslateAccelerator method to the underlying UserControl.
> 
> So in each chain of this embedding the IOleInPlaceActiveObject interface must be implemented and forwarded.
> 
> In your case, probably only the case where my UserControl (e.g. TextBoxW) is embedded in "your" UserControl you need to add the following code to "your" UserControl:
> 
> 
> 
> ```
> ...


Can you please put this code snippet on your front page? Normal Textbox does't have this kind of issue.

----------


## Krool

> Can you please put this code snippet on your front page? Normal Textbox does't have this kind of issue.


Done. Also to note that this "bug" so called only exist in the Std-EXE Version.
The OCX version will just work fine with this, without any additional code.

----------


## Jonney

> Done. Also to note that this "bug" so called only exist in the Std-EXE Version.
> The OCX version will just work fine with this, without any additional code.


Thank you very much.
Please indicate "#597" and the link for easy jump.  :Smilie:

----------


## Jonney

Typing error in ListBoxW:


```
Public Property Let ItemHeight(Optional ByVal Index As Long, ByVal Value As Single)
   '...
   If PropDrawMode <> CboDrawModeOwnerDrawVariable Then  -> LstDrawModeOwnerDrawVariable
   '...
End Property
```

One headache is that ListBox does't have modem themed Selection.

----------


## Krool

> Typing error in ListBoxW:
> 
> 
> ```
> Public Property Let ItemHeight(Optional ByVal Index As Long, ByVal Value As Single)
>    '...
>    If PropDrawMode <> CboDrawModeOwnerDrawVariable Then  -> LstDrawModeOwnerDrawVariable
>    '...
> End Property
> ```


Thank you. Correction will be included in the next update.

----------


## carloc

Hi !

While migrating existing software (vb6) with the CommonCtrls replacement i discovered that when i'm running the application outside de debugger as exe it throws an error when all terminates has been fired.



While reading this forum i discovered that a lot of people reported errors when using a manifest file which resulted in errors on closing the application.
But I don't use any manifest or styling in my application !

Can the above exception still have anything to do with this ?

----------


## Krool

> I wish I could have access to the positioning of the box CommonDialog
> I refer in particular to the message INIT_DIALOG (I think).
> Is that possible?
> 
> Or a simpler something like a variable "StartupPosition"
> CenterScreen or CenterWindow.
> But the first idea allows more thing!


There will be a big enhancement in the CommonDialog class in the next update.

One of the things included will be a 'InitDialog' event where the hDlg is provided. There you can modify the dialog box before it gets displayed.
This is done by using the hook callbacks for the various dialogs. But there will be also a new property called 'HookEvents', which is by default set to False and must be set to True manually after initializing. That indicates that any events for the dialog that requires a hook callback can be raised. (which in fact means that the dialog will only be hooked when that property is True)
There will be also other events like a 'FontApply' event (in case the new added CdlCFApply flag is set) and such.

Just for info.  :Wink:

----------


## PaMarn

Looking to show a font dialog without using the common dialog control. Am I right in thinking the code is contained in ComCtlsDemo.rar.zip. How do I open this file. Winzip can't open it. Do I have to change the extension? Can't find how to do this in Windows 7. Help please.

----------


## PaMarn

Managed to change the extension and although Winzip couldn't open the .rar file I found another program that did. So I think I have answered my own questions

----------


## lrd_VB6

> There will be a big enhancement in the CommonDialog class in the next update.
> 
> One of the things included will be a 'InitDialog' event where the hDlg is provided. There you can modify the dialog box before it gets displayed.
> This is done by using the hook callbacks for the various dialogs. But there will be also a new property called 'HookEvents', which is by default set to False and must be set to True manually after initializing. That indicates that any events for the dialog that requires a hook callback can be raised. (which in fact means that the dialog will only be hooked when that property is True)
> There will be also other events like a 'FontApply' event (in case the new added CdlCFApply flag is set) and such.
> 
> Just for info.


great!

I look forward to it!
I still was using MsCommonDialog.ocx because of that.

For cons, I still have the graphical bug on tooltips (on XP) with "ToolTips.ctl."
I think this is related to the use of an Usercontrol since the fact of using a class, everything goes well.
If that is the case, is it really appropriate to use a UserControl?

Best Regards

----------


## Krool

Update released.

----------


## Jonney

> Thank you very much.
> Please indicate "#597" and the link for easy jump.


I found the trick still has problem in std-exe.
I put TextBoxW in my uc1, then I put uc1 to my uc2, both uc1 and uc2 have the trick, then I put uc2 on my demo form,At the first time uc2 can move cursor by Right/Left key, but the 2nd time failed to move any more. I put the trick into my Form as well, doesn't work.I replace TextBoxW with VB6 TextBox, everything is fine.

Edited: Not sure why. my uc2 (hide or show) put into FlexGrid as Editor. But if I put uc2 on the form,then uc2 or uc1 are all OK. I replace us2's TextBoxW with VB6 textbox, Arrow keys are normal.

"Set This = UserControl.ActiveControl.Object", *how about the activecontrol is not TextBoxW*???



```
Implements OLEGuids.IOleInPlaceActiveObjectVB

Private Sub IOleInPlaceActiveObjectVB_TranslateAccelerator(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal Shift As Long)
On Error Resume Next
Dim This As OLEGuids.IOleInPlaceActiveObjectVB
Set This = UserControl.ActiveControl.Object
This.TranslateAccelerator Handled, RetVal, wMsg, wParam, lParam, Shift
End Sub
```

Finally Edited:
I put code in uc1 which hosted TextBoxW, then the problem resolved.


```
Private Sub UserControl_Hide()
      SetFocusAPI UserControl.Parent.hWnd
End Sub
```

Normal VB6 TextBox desn't need this but perform normally. But at least I solved my problem.

----------


## Krool

> "Set This = UserControl.ActiveControl.Object", *how about the activecontrol is not TextBoxW*???


Then an error will be raised when the interface IOleInPlaceActiveObjectVB is not supported. (That is the case when ActiveControl.Object is not a TextBoxW, for instance)
But as there is an error handler nothing will crash. (Resume Next)

----------


## Jonney

> Then an error will be raised when the interface IOleInPlaceActiveObjectVB is not supported. (That is the case when ActiveControl.Object is not a TextBoxW, for instance)
> But as there is an error handler nothing will crash. (Resume Next)


When the parent hide,supposed the TextBoxW goes into hiding state as well or destroy at design time. Please check any improvement.

----------


## Krool

_mistake_

----------


## Jonney

> Krool, Please consider this API SetWindowTheme to add full theme support for Listview / Treeview  on Vista/Win7/Win8:
> 
> In your demo Main():
> Private Declare Function SetWindowTheme Lib "uxtheme.dll" (ByVal hWnd As Long, ByVal pszSubAppName As String, ByVal pszSubIdList As String) As Long
> 
>     Call ComCtlsInitIDEStopProtection
>     Call InitVisualStyles
>     Call SetWindowTheme(MainForm.TreeView1.hWnd, StrConv("explorer" & Chr(0), vbUnicode), vbNullString)
>     Call SetWindowTheme(MainForm.ListView1.hWnd, StrConv("explorer" & Chr(0), vbUnicode), vbNullString)
> ...


Can you please put some codes for Theme selection support? For Listview and Treeview:


```

Public Property Get ExplorerTheme() As Boolean
    ExplorerTheme = m_ExplorerTheme
End Property
Public Property Let ExplorerTheme(ByVal Value As Boolean)
    m_ExplorerTheme = Value
    If m_hListView Then
        If Value Then
            Call SetWindowTheme(m_hListView, StrPtr("explorer"), 0)
            Call SendMessage(m_hListView, LVM_SETCALLBACKMASK, LVIS_FOCUSED, ByVal 0)
        Else
            Call SetWindowTheme(m_hListView, 0, 0)
            Call SendMessage(m_hListView, LVM_SETCALLBACKMASK, 0, ByVal 0)
        End If
    End If
End Property
```

----------


## Jonney

Not sure a bug or default behavior:

ListBoxW1.DrawMode = lstDrawModeNormal:



```
Call SendMessage(ListBoxW1.hWnd, LB_SETITEMHEIGHT, 0,ByVal 40)
```

If ListBoxW.IntegralHeight is True, After SendMessage to set new ItemHeight, the ListBox got resize problem.

If ListBoxW.IntegralHeight is false,ListBox size is OK,But the scrollbar disappear,after a click of Bottom Item,VScrollbar show again.

----------


## Krool

> Not sure a bug or default behavior:
> 
> ListBoxW1.DrawMode = lstDrawModeNormal:
> 
> 
> 
> ```
> Call SendMessage(ListBoxW1.hWnd, LB_SETITEMHEIGHT, 0,ByVal 40)
> ```
> ...


There is a integrated 'ItemHeight' property in the ListBoxW. Tried that?

Also better make so


```
Call SendMessage(ListBoxW1.hWnd, LB_SETITEMHEIGHT, 0,ByVal 40&)
```

instead of


```
Call SendMessage(ListBoxW1.hWnd, LB_SETITEMHEIGHT, 0,ByVal 40)
```

----------


## Jonney

> There is a integrated 'ItemHeight' property in the ListBoxW. Tried that?
> 
> Also better make so
> 
> 
> ```
> Call SendMessage(ListBoxW1.hWnd, LB_SETITEMHEIGHT, 0,ByVal 40&)
> ```
> 
> ...


ItemHeight is sure OK, In case crazy guy send this message to ListBoxW though I send  this Message to VB6 ListBox which is OK.

Call SendMessage(ListBoxW1.hWnd, LB_SETITEMHEIGHT, 0,ByVal 40&) make no difference.

----------


## Tanner_H

@Jonney, Krool: not sure if this is helpful, but LB_SETITEMHEIGHT is only relevant for owner-drawn listboxes created with the LBS_OWNERDRAWVARIABLE style.  With that style, each listbox entry can have a different height.

LB_SETITEMHEIGHT has no effect on normal listboxes, or owner-drawn listboxes with the LBS_OWNERDRAWFIXED style (where each listbox item has an identical height).

LBS_NOINTEGRALHEIGHT allows you to set your own size for the listbox, and it allows listbox items to be partially shown.  LBS_INTEGRALHEIGHT makes the system set the size of the listbox to be a multiple of the fixed individual item size.  However, if you specify the LBS_OWNERDRAWVARIABLE flag, LBS_NOINTEGRALHEIGHT is assumed (per https://msdn.microsoft.com/en-us/library/bb775149.aspx).

Anyway, not sure if any of this is helpful, but if you haven't already, you should try combining the LBS_NOINTEGRALHEIGHT and WS_VSCROLL flags at list box creation time.  This should cause the scroll bar to appear correctly.  (The only exception is, if only a single listbox item lies partially off-screen, I think Windows doesn't show the scroll bar, because you can still click the last item okay.)  Also, you can use LB_GETITEMHEIGHT * LB_GETCOUNT to manually set a height where scrolling is never necessary, if your listbox doesn't contain too many items.

(Sorry if none of this is relevant!)

----------


## Krool

> Can you please put some codes for Theme selection support? For Listview and Treeview:
> 
> 
> ```
> 
> Public Property Get ExplorerTheme() As Boolean
>     ExplorerTheme = m_ExplorerTheme
> End Property
> Public Property Let ExplorerTheme(ByVal Value As Boolean)
> ...


There is already a integrated 'SetExplorerTheme' method for ListView and TreeView.
But why do you use LVM_SETCALLBACKMASK in your code?

----------


## Jonney

> @Jonney, Krool: not sure if this is helpful, but LB_SETITEMHEIGHT is only relevant for owner-drawn listboxes created with the LBS_OWNERDRAWVARIABLE style.  With that style, each listbox entry can have a different height.
> 
> LB_SETITEMHEIGHT has no effect on normal listboxes, or owner-drawn listboxes with the LBS_OWNERDRAWFIXED style (where each listbox item has an identical height).
> 
> LBS_NOINTEGRALHEIGHT allows you to set your own size for the listbox, and it allows listbox items to be partially shown.  LBS_INTEGRALHEIGHT makes the system set the size of the listbox to be a multiple of the fixed individual item size.  However, if you specify the LBS_OWNERDRAWVARIABLE flag, LBS_NOINTEGRALHEIGHT is assumed (per https://msdn.microsoft.com/en-us/library/bb775149.aspx).
> 
> Anyway, not sure if any of this is helpful, but if you haven't already, you should try combining the LBS_NOINTEGRALHEIGHT and WS_VSCROLL flags at list box creation time.  This should cause the scroll bar to appear correctly.  (The only exception is, if only a single listbox item lies partially off-screen, I think Windows doesn't show the scroll bar, because you can still click the last item okay.)  Also, you can use LB_GETITEMHEIGHT * LB_GETCOUNT to manually set a height where scrolling is never necessary, if your listbox doesn't contain too many items.
> 
> (Sorry if none of this is relevant!)


I just occasionally SendMessage LB_SETITEMHEIGHT to ListBoxW (Normal Mode), The ListBoxW just draw partially. I Send the same message to VB6 ListBox (normal mode as well),VB6 ListBox draw normally. So I think it *may* be a bug in ListBoxW. That I raise this question. Sorry for confusion.

----------


## Jonney

> There is already a integrated 'SetExplorerTheme' method for ListView and TreeView.
> But why do you use LVM_SETCALLBACKMASK in your code?


Sorry I miss this function!
BTW, ListBoxW's Selected doesn't work from what I tested, (Just test it not yet investigate.)

----------


## SMC1979

16 pages, I skimmed through them but not seeing the same problem I am having, unless I missed it.

I have the current code, and the bug is in it as well. The auto size for the labels do not work right. If I have it set to right or center for the text, auto size always expands left.

I was wondering if anyone has noticed this. I havent tested it using the v6 of the controls, only the v5.

----------


## SMC1979

Looking at the label code now and I see where the auto size code is, but I dont see any code to move it left when needed. I will see what I come up with :-)



```
Format = DT_NOCLIP
Select Case PropAlignment
    Case vbLeftJustify
        Format = Format Or DT_LEFT
    Case vbCenter
        Format = Format Or DT_CENTER
    Case vbRightJustify
        Format = Format Or DT_RIGHT
End Select
If Ambient.RightToLeft = True Then Format = Format Or DT_RTLREADING
If PropUseMnemonic = False Then Format = Format Or DT_NOPREFIX
If PropWordWrap = True Then Format = Format Or DT_WORDBREAK
If PropAutoSize = True And LabelAutoSizeFlag = True Then
    Dim Buffer As String
    Buffer = PropCaption
    If Buffer = vbNullString Then Buffer = " "
    DrawText .hDC, StrPtr(Buffer), -1, RC, Format Or DT_CALCRECT
    .Size .ScaleX((RC.Right - RC.Left) + (BorderWidth * 2), vbPixels, vbTwips), .ScaleY((RC.Bottom - RC.Top) + (BorderHeight * 2), vbPixels, vbTwips)
    LabelAutoSizeFlag = False
End If
SetRect RC, RC.Left + BorderWidth, RC.Top + BorderHeight, RC.Right - (BorderWidth * 2), RC.Bottom - (BorderHeight * 2)
If Not PropCaption = vbNullString Then DrawText .hDC, StrPtr(PropCaption), -1, RC, Format
```

----------


## SMC1979

OK I got auto size working like it should. I also found a few bugs that I fixed as well. When auto size is used the RC rest is redone by the drawtext api, and so it changes the size. So when using Right Justify the text wouldnt fit, it was to far to the left. So I redid it to take into account if auto size is being used and to use different math, otherwise keep using the norm.

So in the LabelW control, just replace the usercontrol paint event with this



```
Private Sub UserControl_Paint()
Dim RC As RECT, Format As Long
Dim OldRight As Long, OldCenter As Long, OldWidth As Long
Dim BorderWidth As Long, BorderHeight As Long
Dim Buffer As String
Buffer = PropCaption
    
With UserControl
SetRect RC, 0, 0, .ScaleWidth, .ScaleHeight
Select Case PropBorderStyle
    Case CCBorderStyleSingle
        BorderWidth = GetSystemMetrics(SM_CXBORDER)
        BorderHeight = GetSystemMetrics(SM_CYBORDER)
        UserControl.Line (0, 0)-(.ScaleWidth - BorderWidth, .ScaleHeight - BorderHeight), RGB(100, 100, 100), B
    Case CCBorderStyleThin
        BorderWidth = GetSystemMetrics(SM_CXBORDER)
        BorderHeight = GetSystemMetrics(SM_CYBORDER)
        DrawEdge .hDC, RC, BDR_SUNKENOUTER, BF_RECT
    Case CCBorderStyleSunken
        BorderWidth = GetSystemMetrics(SM_CXEDGE)
        BorderHeight = GetSystemMetrics(SM_CYEDGE)
        DrawEdge .hDC, RC, BDR_SUNKEN, BF_RECT
    Case CCBorderStyleRaised
        BorderWidth = GetSystemMetrics(SM_CXDLGFRAME)
        BorderHeight = GetSystemMetrics(SM_CYDLGFRAME)
        DrawEdge .hDC, RC, BDR_RAISED, BF_RECT
End Select
If .Enabled = False Then SetTextColor .hDC, WinColor(vbGrayText)
Format = DT_NOCLIP

Select Case PropAlignment
    Case vbLeftJustify
        Format = Format Or DT_LEFT
    Case vbCenter
        Format = Format Or DT_CENTER
    Case vbRightJustify
        Format = Format Or DT_RIGHT
End Select
If Ambient.RightToLeft = True Then Format = Format Or DT_RTLREADING
If PropUseMnemonic = False Then Format = Format Or DT_NOPREFIX
If PropWordWrap = True Then Format = Format Or DT_WORDBREAK
If PropAutoSize = True And LabelAutoSizeFlag = True Then

    OldRight = .Extender.Left + .Extender.Width
    OldCenter = .Extender.Left + (.Extender.Width / 2)
    OldWidth = .Extender.Width

    If Buffer = vbNullString Then Buffer = " "
    DrawText .hDC, StrPtr(Buffer), -1, RC, Format Or DT_CALCRECT
    .Size .ScaleX((RC.Right + (BorderWidth * 2)), vbPixels, vbTwips), .ScaleY((RC.Bottom + (BorderHeight * 2)), vbPixels, vbTwips)
    LabelAutoSizeFlag = False
    
    Select Case PropAlignment
    
            'we clear the string so it doesnt draw it, When the control is moved the refresh is triggered and so the draw will be called again. Otherwise this paint gets called 3 times instead of 2.
            'but we only clear the string if we are moving the control left at all.
            'we only move the control if needed. This helps keep it from blinking when being updated very quickly
            
        Case vbLeftJustify
            'we are left justifies, so we dont do anything as the calls already move things left
            
        Case vbCenter
            'ok we are center, lets make it so that the label stays centerd in its spot
            If .Extender.Left <> (OldCenter - (.Extender.Width / 2)) Then
                Buffer = vbNullString
                .Extender.Left = (OldCenter - (.Extender.Width / 2))
            End If
    
        Case vbRightJustify
            'ok we are right justified, lets move the lable so that the right side of it stays in place
            If .Extender.Left <> (OldRight - .Extender.Width) Then
                
                Buffer = vbNullString
                .Extender.Left = (OldRight - .Extender.Width)
            End If
    
    End Select

    'when using the auto size the rc changes and so we do a little different match to handle it. If we are not auto sizing then use the other math
    SetRect RC, RC.Left + BorderWidth, RC.Top + BorderHeight, RC.Right + BorderWidth, RC.Bottom + BorderHeight
Else
    SetRect RC, RC.Left + BorderWidth, RC.Top + BorderHeight, RC.Right - (BorderWidth * 2), RC.Bottom - (BorderHeight * 2)
End If

If Not Buffer = vbNullString Then DrawText .hDC, StrPtr(PropCaption), -1, RC, Format

End With
```

For me Autosize is now working (AT least in the test I have done) If I missed anything or you find a better way to do it please let me know. And thanks again for your great work. Love these controls. If it wasnt for you Unicode in VB6 would be a night mare.

----------


## wqweto

No github version, no pull requests. This project is pretty unwieldy now. 

Someone recommended Github for Windows in a separate thread...

cheers,
</wqw>

----------


## Krool

> OK I got auto size working like it should. I also found a few bugs that I fixed as well. When auto size is used the RC rest is redone by the drawtext api, and so it changes the size. So when using Right Justify the text wouldnt fit, it was to far to the left. So I redid it to take into account if auto size is being used and to use different math, otherwise keep using the norm.
> 
> So in the LabelW control, just replace the usercontrol paint event with this


Thanks. Will take this fix into account for the next update.

----------


## SMC1979

Thanks. I am still playing with it to get it working better. On a system with higher DPI the text doesnt fit, it isnt seeing that the text is larger and so the rec is still being sized as if the text is normal size.

So I am going to play around with the textwidth and textheight commands and see if I can use that to come up with more accurate math on what the size of the control should be on auto resize. So basically use the textwidth to get the size and then see what the width is of the rec and increase it if it is smaller than the textwidth reported.

----------


## Krool

@ SMC1979, this is my version of the LabelW_Paint procedure:


```
Dim RC As RECT, Format As Long
Dim BorderWidth As Long, BorderHeight As Long
With UserControl
SetRect RC, 0, 0, .ScaleWidth, .ScaleHeight
Select Case PropBorderStyle
    Case CCBorderStyleSingle
        BorderWidth = GetSystemMetrics(SM_CXBORDER)
        BorderHeight = GetSystemMetrics(SM_CYBORDER)
        UserControl.Line (0, 0)-(.ScaleWidth - BorderWidth, .ScaleHeight - BorderHeight), RGB(100, 100, 100), B
    Case CCBorderStyleThin
        BorderWidth = GetSystemMetrics(SM_CXBORDER)
        BorderHeight = GetSystemMetrics(SM_CYBORDER)
        DrawEdge .hDC, RC, BDR_SUNKENOUTER, BF_RECT
    Case CCBorderStyleSunken
        BorderWidth = GetSystemMetrics(SM_CXEDGE)
        BorderHeight = GetSystemMetrics(SM_CYEDGE)
        DrawEdge .hDC, RC, BDR_SUNKEN, BF_RECT
    Case CCBorderStyleRaised
        BorderWidth = GetSystemMetrics(SM_CXDLGFRAME)
        BorderHeight = GetSystemMetrics(SM_CYDLGFRAME)
        DrawEdge .hDC, RC, BDR_RAISED, BF_RECT
End Select
If .Enabled = False Then SetTextColor .hDC, WinColor(vbGrayText)
Format = DT_NOCLIP
Select Case PropAlignment
    Case vbLeftJustify
        Format = Format Or DT_LEFT
    Case vbCenter
        Format = Format Or DT_CENTER
    Case vbRightJustify
        Format = Format Or DT_RIGHT
End Select
If Ambient.RightToLeft = True Then Format = Format Or DT_RTLREADING
If PropUseMnemonic = False Then Format = Format Or DT_NOPREFIX
If PropWordWrap = True Then Format = Format Or DT_WORDBREAK
If PropAutoSize = True And LabelAutoSizeFlag = True Then
    Dim Buffer As String, CalcRect As RECT
    Buffer = PropCaption
    If Buffer = vbNullString Then Buffer = " "
    LSet CalcRect = RC
    DrawText .hDC, StrPtr(Buffer), -1, CalcRect, Format Or DT_CALCRECT
    Dim OldRight As Single, OldCenter As Single, OldWidth As Single
    OldRight = .Extender.Left + .Extender.Width
    OldCenter = .Extender.Left + (.Extender.Width / 2)
    OldWidth = .Extender.Width
    .Size .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbTwips), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbTwips)
    LabelAutoSizeFlag = False
    Select Case PropAlignment
        Case vbCenter
            If .Extender.Left <> (OldCenter - (.Extender.Width / 2)) Then
                .Extender.Left = (OldCenter - (.Extender.Width / 2))
                Exit Sub
            End If
        Case vbRightJustify
            If .Extender.Left <> (OldRight - .Extender.Width) Then
                .Extender.Left = (OldRight - .Extender.Width)
                Exit Sub
            End If
    End Select
End If
SetRect RC, RC.Left + BorderWidth, RC.Top + BorderHeight, RC.Right - (BorderWidth * 2), RC.Bottom - (BorderHeight * 2)
If Not PropCaption = vbNullString Then DrawText .hDC, StrPtr(PropCaption), -1, RC, Format
End With
```

Works fine so far. Same as the intrinsic Label control.
On your code was a "bug" when switching AutoSize property back and forth on certain situations. Maybe you can test my code and report if there is an issue or not.

----------


## Jonney

For Single line TextBoxW, my customized SolidBrush or ImageBrush works very well. But if the textbox's MultiLine is True, the text got "fuzzy" while I am typing or scrolling. Sir,What is solution? 

http://www.vbforums.com/showthread.p...07#post4829207

----------


## SMC1979

> Works fine so far. Same as the intrinsic Label control.
> On your code was a "bug" when switching AutoSize property back and forth on certain situations. Maybe you can test my code and report if there is an issue or not.


You know your code far better than I do, and I will be happy to test the code out today. Let me get some of this work caught up and I will test it out and report back :-)

Shane

----------


## SMC1979

Ok your code had one problem, when I loaded up a form and control the label showed fine, but when I would change the text from a command button LabelW1.Caption = "Test" (As an example) the label would go blank. I would have to call a refresh to get it to show.

I also needed to get it to work properly when a user had a higher DPI setting set on the system, so say their fonts where set to 100% and they raised it to 125%. The label control would auto size properly, ONLY after you changed the caption or refreshed the control, which would have it recalculate the sizes with the increased font size. The reason why it wouldnt work before a refresh or caption change is when the control is first loaded the auto resize section doesnt get called. (I removed the LabelAutoSizeFlag to fix that)

So I modified your new code, I took care of the control disappearing on text change and I was able to get it to properly show and size when the DPI is above 100% (On the first load and draw of the control) :-) So as of right now it is working perfectly. Let me know what you think.

First, add this to the top of the control code


```
Private bFirstPaint As Boolean
```

Then modified the label control UserControl_Initialize section to this


```
Private Sub UserControl_Initialize()
bFirstPaint = False
DispIDMousePointer = GetDispID(Me, "MousePointer")
Call SetVTableSubclass(Me, VTableInterfacePerPropertyBrowsing)
End Sub
```

Then finally replace the controls pain section with this


```
Private Sub UserControl_Paint()
Dim RC As RECT, Format As Long
Dim BorderWidth As Long, BorderHeight As Long
With UserControl
SetRect RC, 0, 0, .ScaleWidth, .ScaleHeight
Select Case PropBorderStyle
    Case CCBorderStyleSingle
        BorderWidth = GetSystemMetrics(SM_CXBORDER)
        BorderHeight = GetSystemMetrics(SM_CYBORDER)
        UserControl.Line (0, 0)-(.ScaleWidth - BorderWidth, .ScaleHeight - BorderHeight), RGB(100, 100, 100), B
    Case CCBorderStyleThin
        BorderWidth = GetSystemMetrics(SM_CXBORDER)
        BorderHeight = GetSystemMetrics(SM_CYBORDER)
        DrawEdge .hDC, RC, BDR_SUNKENOUTER, BF_RECT
    Case CCBorderStyleSunken
        BorderWidth = GetSystemMetrics(SM_CXEDGE)
        BorderHeight = GetSystemMetrics(SM_CYEDGE)
        DrawEdge .hDC, RC, BDR_SUNKEN, BF_RECT
    Case CCBorderStyleRaised
        BorderWidth = GetSystemMetrics(SM_CXDLGFRAME)
        BorderHeight = GetSystemMetrics(SM_CYDLGFRAME)
        DrawEdge .hDC, RC, BDR_RAISED, BF_RECT
End Select
If .Enabled = False Then SetTextColor .hDC, WinColor(vbGrayText)
Format = DT_NOCLIP
Select Case PropAlignment
    Case vbLeftJustify
        Format = Format Or DT_LEFT
    Case vbCenter
        Format = Format Or DT_CENTER
    Case vbRightJustify
        Format = Format Or DT_RIGHT
End Select
If Ambient.RightToLeft = True Then Format = Format Or DT_RTLREADING
If PropUseMnemonic = False Then Format = Format Or DT_NOPREFIX
If PropWordWrap = True Then Format = Format Or DT_WORDBREAK
If PropAutoSize = True Then
    Dim Buffer As String, CalcRect As RECT
    Dim lTextWidth As Long
    Buffer = PropCaption

    If Buffer = vbNullString Then Buffer = " "
    LSet CalcRect = RC
    DrawText .hDC, StrPtr(Buffer), -1, CalcRect, Format Or DT_CALCRECT
    
    Dim OldRight As Single, OldCenter As Single, OldWidth As Single
    OldRight = .Extender.Left + .Extender.Width
    OldCenter = .Extender.Left + (.Extender.Width / 2)
    OldWidth = .Extender.Width
    
    .Size .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbTwips), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbTwips)
    'no longer needed since we are exiting the sib. Plus if the users API is higher the control wont get updated to the increased text size when the control first loads.
    'LabelAutoSizeFlag = False
    Select Case PropAlignment
        Case vbCenter
            If .Extender.Left <> (OldCenter - (.Extender.Width / 2)) Then
                .Extender.Left = (OldCenter - (.Extender.Width / 2))
                'safe to call refresh here because it wont get called again unless the position has changed.
                'when calling refresh the pain is called again, have to be sure not to get stuck in a loop
                'we have to call a refresh after the control is moved so that it will draw properly.
                Me.Refresh
                If bFirstPaint = True Then Exit Sub
            End If
        Case vbRightJustify
            If .Extender.Left <> (OldRight - .Extender.Width) Then
                .Extender.Left = (OldRight - .Extender.Width)
                Me.Refresh
                DoEvents
                If bFirstPaint = True Then Exit Sub
            End If
    End Select

End If

bFirstPaint = True

SetRect RC, RC.Left + BorderWidth, RC.Top + BorderHeight, RC.Right - (BorderWidth * 2), RC.Bottom - (BorderHeight * 2)
If Not PropCaption = vbNullString Then DrawText .hDC, StrPtr(PropCaption), -1, RC, Format
End With
End Sub
```

Shane

----------


## LaVolpe

Krool, been browsing your control and came across a listview message you haven't implemented yet. Thought I'd give you a brief summary should you want to add it.


```
Const LVM_MAPINDEXTOID = (LVM_FIRST + 180)
Const LVM_MAPIDTOINDEX = (LVM_FIRST + 181)
```

Those allow you to create a permanent reference to any specific listview item. Requires manifested v6 common controls.

Ideally, you could remove any need to manually cross-reference listview items to classes or collections. Prevents needing to re-key collections due to deletions/additions of listview items.  Here's how it works

1) SendMessage LVM_MAPINDEXTOID and pass the 0-bound Listview item as wParam, lParam is always zero
What is returned is the listview provided permanent cross-reference unique ID (generally same index as wParam, but won't ever change)
If inadvertently called more than once on the same listview item, will return the same unique ID

2) SendMessage LVM_MAPIDTOINDEX and pass the unique ID as wParam, lParam is always zero. 
What is returned is the current listview item index that was mapped to that ID

How this can be useful? You can create a class of properties and user-defined extended properties. This class can be added to a collection and the collection keyed on the result of LVM_MAPINDEXTOID. Whenever those properties are requested for any specific listview item, you can call LVM_MAPIDTOINDEX to return the unique ID and then use that ID as the key to get the class of properties from your collection. When listview items are deleted, remove the collection item (if it exists) and never have to worry about re-keying since the unique ID is guaranteed to not change during the lifetime of that listview item, regardless of where it ends up in the listview.

The only restriction: not supported with LVS_OWNERDATA

Edited: The Treeview has similar mapping


```
TVM_MAPHTREEITEMTOACCID=TV_FIRST+43
TVM_MAPACCIDTOHTREEITEM=TV_FIRST+42
```

Seems that if these were used, one would never need individual listitem or treenode classes, other than a list of properties to set/return values at runtime via API calls. Any user-defined properties, like keys, tags, or whatever can be a class created on demand, indexed to the item via those messages and added to a collection. Would think that if say a listview only had 10% of the items having Keys and/or Tag values, only a small listing of classes would need to be created, not one for every item in the list/tree. Just my two-cents.

----------


## Krool

> ```
>         Case vbRightJustify
>             If .Extender.Left <> (OldRight - .Extender.Width) Then
>                 .Extender.Left = (OldRight - .Extender.Width)
>                 Me.Refresh
>                 DoEvents
>                 If bFirstPaint = True Then Exit Sub
>             End If
>     End Select
> ...


Why you put a DoEvents there? (only at vbRightJustify)
Also a problem by this solution is that if the AutoSize property is True then you cannot modify anymore the width and height manually. Like you could do on VB Label control. That is the purpose of "LabelAutoSizeFlag".
Possible workaround would be to keep the LabelAutoSizeFlag as placed as before and you call a "LabelW1.AutoSize = True" code manually in your Form_Load to force a re-calc of the autosizing, to respect a possible other DPI value.

@ LaVolpe,
Thanks for your input and suggestion. I know of those messages you mention. But what to do when comctl v5.8x is used and not v6.0?

----------


## LaVolpe

> @ LaVolpe,
> Thanks for your input and suggestion. I know of those messages you mention. But what to do when comctl v5.8x is used and not v6.0?


Force ppl to manifest their projects  :Wink: 

I know what you mean.

*Edited*: Actually, if the lParam of the LVITEM structure is not exposed to the user, then this can be used same as mapping for Listview items. Simply keep an incrementing value that is assigned to lParam member when user-defined properties are set. To locate the item by the value you placed in the lParam member, send LVM_FINDITEM with its .flags set to search the lParam. I wouldn't be surprised if this isn't very similar to how the LVM_MAPxxx messages work.  Not familiar enough with treeviews to suggest a similar method as its mapping messages.

----------


## LaVolpe

Just another note & done.

1st. Good suite of controls and lots to learn from.

2nd. I first came here because I wanted to learn more about creating/using the ListView/Treeview controls via APIs & CreateWindowEx, specifically to support unicode. It turns out, may not have been needed when using v5.8+. Simply setting text via SendMessage vs the VB control's ListItem & Node properties will allow unicode. Of course this means that you'd have to use SendMessage to get/set text properties, but in my case, that is far easier than recreating an entire control or two or three.

----------


## SMC1979

> Why you put a DoEvents there? (only at vbRightJustify)
> Also a problem by this solution is that if the AutoSize property is True then you cannot modify anymore the width and height manually. Like you could do on VB Label control. That is the purpose of "LabelAutoSizeFlag".
> Possible workaround would be to keep the LabelAutoSizeFlag as placed as before and you call a "LabelW1.AutoSize = True" code manually in your Form_Load to force a re-calc of the autosizing, to respect a possible other DPI value.


Opps lol, I only had those in there as I was testing some different code, forgot to remove the doevents :-)

And yes while you could resize a label in normal vb when the autosize was set to true, the instant you changed the caption or any settings and it would auto resize. But my goal is simply to get the control to auto resize on its first draw incase a users DPI is higher is all. You know better than me the best way to make that happen, so I will trust your judgment on it and try out any code you post :-)

Shane

----------


## Krool

Update released with the LabelW auto size fix.

----------


## SMC1979

Thanks!

----------


## Romeo91

Hi Krool.
Why such changes in a set?
I used thisa kontrol, big problems in it didn't notice.




> *List of revisions:*
> 11-Feb-2015
> ...
> - Removed the ToolTip control.

----------


## SMC1979

> Hi Krool.
> Why such changes in a set?
> I used thisa kontrol, big problems in it didn't notice.


I dont know why he removed it, but I know I had to stop using it because when debugging my program for any leaks, the GDI Objects in task manager would grow every time I used it and never go back down. Even when the form was closed and everything cleaned up. Once I removed the tooltip from the form the GDI Objects would rise and shrink like normal.

Not sure if that is the reason he removed it, but for me that is one of the reasons I stopped using it.

----------


## Krool

> Hi Krool.
> Why such changes in a set?
> I used thisa kontrol, big problems in it didn't notice.


There are plenty of ToolTip control classes around the web. Thus it is not really necessary to include it in my project. There were some problems with it also.
Anyhow, you have a backup of the control? If not I could send you a PM with it.

----------


## brandoncampbell

Krool, any plans to replace the winsock control?

----------


## Cube8

@brandoncampbell
Not really necessary.
See here, here and here.

----------


## ishalom

Just came across The commandButtonW SplitButton Property, it looks very interesting how do I add items and/or check what is selected?

----------


## Bonnie West

> ... how do I add items and/or check what is selected?


Create an invisible popup menu control (and its submenus) using the IDE's Menu Editor dialog, then pop it up when the CommandButtonW's DropDown event fires. Position the menu like this:



```
Private Sub CommandButtonW1_DropDown()
    With CommandButtonW1
        PopupMenu mnuPopup, vbPopupMenuRightButton, .Left, .Top + .Height
    End With
End Sub
```

----------


## ishalom

CommandButtonW has no MaskColor Property, is there a way around it?
can I use an imagelist instead, if so how do I assign the image index to the button?

----------


## Bonnie West

> CommandButtonW has no MaskColor Property, is there a way around it?


_I haven't tested this_, but I believe a MaskColor property is no longer necessary because the CommandButtonW's Picture property already supports transparency in icons/bitmaps.

----------


## ishalom

> _I haven't tested this_, but I believe a MaskColor property is no longer necessary because the CommandButtonW's Picture and PictureAndCaption properties already supports transparency in icons/bitmaps.


transparency  is only supported in icons not BMP files, and PNG files are not supported at all (although it would be great to see it added)

----------


## Bonnie West

> transparency  is only supported in icons not BMP files, ...


Transparency is indeed _supported_ for BMP files. However, it can't be just any regular BMP file, it has to be a pre-multiplied ARGB BMP file.

----------


## ishalom

> Transparency is indeed _supported_ for BMP files. However, it can't be just any regular BMP file, it has to be a pre-multiplied ARGB BMP file.


pre-multiplied ARGB BMP ? never heard of it (in vb6), could you elaborate please , or at least point me to the right direction.

tested it, and I am getting invalid picture.

----------


## Krool

> CommandButtonW has no MaskColor Property, is there a way around it?
> can I use an imagelist instead, if so how do I assign the image index to the button?


You can use a ImageList. The first image of the ImageList will be used automatically. If the ImageList has multiple images than the CommandButtonW uses for each state a certain index.

----------


## ishalom

how do I set RightToLeft Property to the controls?

----------


## Krool

> how do I set RightToLeft Property to the controls?


You can't. The controls are same as the ambient RighToLeft property.

----------


## Bonnie West

> pre-multiplied ARGB BMP ? never heard of it (in vb6), could you elaborate please , or at least point me to the right direction.


Sure. Check out the links in this Google search.

Attached below is a demo project and some pARGB BMP samples. Extract the archive contents to the ComCtlsDemo folder in Krool's ComCtlsDemo.rar.zip.


Oh, BTW, I created the pARGB BMPs with Pixelformer.

----------


## Alvaro66

I'm sorry for the slightly off topic, it's my first post here.
Could someone please tell me how can I add the this control replacement scheme to both a new vb6 project and also to an existent big vb6 project.
I do have an old vb6 big project, it's  Profound a GUI that interacts to a c++ checkers/draughts variant (spanish).
If it is an easy thing to do I really could get rid of that old MS controls dependency.
https://www.youtube.com/watch?v=bu2Nk1q5Y7Y
best regards,
Alvaro

----------


## Jonney

I used krool's OpenPrinterEx in CommonDialog class.But the printer dialog failed to assign my printer "\\192.4.4.143\Canon iR2002/2202 UFRII LT(1)".I watched the return printer name is  limited *30 Characters* of  "\\192.4.4.143\Canon iR2002/220"what is the reason?

Edited: Look like the string is being truncated. But I don't know the reason.

----------


## gigirex

Hi Krool and thank you for this fantastic piece of software!
I have only a problem in embedding your code in my old ocx-dependent:
Using the With instruction:


```
With MainForm.TabStrip.Tabs(TabsCounter)
.... code
End With
```

I have this error:

Thank you in advance for considering this problem.

Gigirex

----------


## Bonnie West

> I have this error:


Can you post the exact line and the entire procedure where that error occurs? Can you also please provide additional details about your issue?

----------


## gigirex

Thank you for replying.
The error is precisely on the With instruction.
As workaround I have directly assigned values without the width prefix and works without problems:


```
Let MainForm.TabStrip.Tabs(TabsCounter).Caption = strTab(TabsCounter)
```

..but it don't work if I use the With instruction:


```
With MainForm.TabStrip.Tabs(TabsCounter)
  Let .Caption = strTab(TabsCounter)
End With
```

..and the .key variable is read-only. Is not very important, but in the original ocx is r/w.

Thanks again.

Gigirex

----------


## lrd_VB6

hello

I just found by chance a bug in "CommonDialog.ShowOpen"
It is not possible to use "FileName" as the default file.

The simple solution is to add



```
Public Function ShowOpen() As Boolean
Dim Buffer As String, Filter As String

    Buffer = String(PropMaxFileSize, vbNullChar)

    Mid$(Buffer, 1) = PropFileName' Code add.

Dim OFN As OPENFILENAME

    With OFN
```

----------


## Krool

> The error is precisely on the With instruction.


I cannot confirm this error. By me its working. Anyone else problem on this?




> I just found by chance a bug in "CommonDialog.ShowOpen"
> It is not possible to use "FileName" as the default file.


Thank you. Will fix this issue. However, the save dialog did not had this bug.

----------


## Bonnie West

> I cannot confirm this error. By me its working. Anyone else problem on this?


I couldn't reproduce Gigirex's "UDT not defined" error as well. I don't see why the *With* block he posted would throw such an error. At any rate, it seems he has already figured out a workaround so I guess this issue is resolved.

----------


## Jonney

Refer to #659



```
NewPrinterName = Mid$(DNAMES.wExtra, _
                          DNAMES.wDeviceOffset - DNAMES.wDriverOffset + 1)
NewPrinterName = VBA.Left$(NewPrinterName, _
                          InStr(NewPrinterName, Chr$(0)) - 1)
```

----------


## lrd_VB6

hello
  Just for information:

Why do this:


```
        Buffer = String(PropMaxFileSize, vbNullChar)
        If Not PropFileName = vbNullString Then
            If Len(PropFileName) > (PropMaxFileSize + 1) Then
                Length = PropMaxFileSize * 2
            Else
                Length = LenB(PropFileName)
            End If

            CopyMemory ByVal StrPtr(Buffer), ByVal StrPtr(PropFileName), Length
        End If
```

while the following code does the same thing?


```
    Buffer = String(PropMaxFileSize, vbNullChar)
    Mid$(Buffer, 1) = PropFileName
```

VB guaranteed that the replacement string will never exceed the original chain.
(that is what is written in Help)

For proof:


```
a$="123456789"
?lenb(a$)
 18 
mid$(a$,1)="09876543210"
?a$
098765432
?lenb(a$)
 18
c$=vbnullstring
mid$(a$,1)=c$
?a$
098765432
?lenb(a$)
 18
```

Finally, in VBCCR11.ocx, "CommonDialog" does not have the event "InitDialog".
It is normal?


cordially

----------


## Krool

> in VBCCR11.ocx, "CommonDialog" does not have the event "InitDialog".
> It is normal?


Yes. The event "InitDialog" will be on VBCCR12.OCX. (not yet released)

----------


## ishalom

I have noticed that the ImageList is causing a lot of problems(Crashing, and by that sometimes corrupting the frm/frx file), has anyone had the same experience.

----------


## ishalom

> Yes. The event "InitDialog" will be on VBCCR12.OCX. (not yet released)


will projects using  VBCCR11.OCX automatically update to VBCCR12.OCX?

----------


## Krool

> I have noticed that the ImageList is causing a lot of problems(Crashing, and by that sometimes corrupting the frm/frx file), has anyone had the same experience.


Please describe the exact steps what causes the crashs. Thanks

----------


## Krool

> I used krool's OpenPrinterEx in CommonDialog class.But the printer dialog failed to assign my printer "\\192.4.4.143\Canon iR2002/2202 UFRII LT(1)".I watched the return printer name is  limited *30 Characters* of  "\\192.4.4.143\Canon iR2002/220"what is the reason?
> 
> Edited: Look like the string is being truncated. But I don't know the reason.


Update released.
This issue is now fixed. Thanks to Jonney for the solution.

----------


## Krool

Update released.

----------


## Krool

Update released.

Found out that in the VisualStyles.bas and in CommandButtonW.ctl (graphical style only) in case the button is disabled the 'DisabledPicture' was drawn in disabled state, instead it should be drawn normally or masked. Only when there is no 'DisabledPicture' the drawing should be in disabled state in case the button is disabled.

This issue is now fixed. Thus the behavior now matches to the intrinsic VB control.

----------


## fafalone

Ever figure out anything about why all the IPPB stuff is always throwing errors ?
VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
VTableHandle.IPPB_GetPredefinedStrings.Error2->Type mismatch

"Set ShadowIPerPropertyBrowsingVB = This" is the number one source of the errors. Click on control after clicking something else first, bunch of those errors scroll by, 9/10 properties disappear.  Have to close and reopen form to get them back.

----------


## Paul@QMC.net

Hi, can you provide the events for this great control.  I am using this for it's Treeview control as a work-around to the Win7/8 64 system issues with the old Treeview control, what a MS mess...
However, I cannot seem to get the Click event to work as with the VB 5/6 MS Treeview control.  And, when I End the EXE Program or when in VB design mode, I get a Windows (7/8) error that checks for a problem sol'n, but can't find.  Must then terminate the program.

Thank you so much, I see this as the ultimate sol'n to what MS does.

Again, thanks...  Paul

----------


## Krool

> I cannot seem to get the Click event to work as with the VB 5/6 MS Treeview control.


Does the Click event fire or not? Or does it not work the same only?
What about the other events. Please more details. Thanks




> And, when I End the EXE Program or when in VB design mode, I get a Windows (7/8) error that checks for a problem sol'n, but can't find.  Must then terminate the program.


Do you call the InitVisualStyles method at startup in the EXE?




> Ever figure out anything about why all the IPPB stuff is always throwing errors ?
> VTableHandle.IPPB_GetDisplayString.Error2->Type mismatch
> VTableHandle.IPPB_GetPredefinedStrings.Error2->Type mismatch
> 
> "Set ShadowIPerPropertyBrowsingVB = This" is the number one source of the errors. Click on control after clicking something else first, bunch of those errors scroll by, 9/10 properties disappear.  Have to close and reopen form to get them back.


Is this also happening in the Demo project?

----------


## Paul@QMC.net

What are the events for TreeView (such a Node Click)?  When Ending the program, all crashes, any fix.  Thanks, Paul

----------


## Paul@QMC.net

The issue is I can't find the code for the node click event. I only get 4 options, such as gotfocus, etc...

Have no idea on the IniVisualStyle code is or location to place in the EXE.

We have a major program for chemical engineers that does not work with the latest MS release of Comctl...  We and our Clients are panicking   
Do you know anyone that can work with us?  We are ChemE's and this is beyond us...

Thanks, Paul

----------


## Paul@QMC.net

This article seems to provide the reasons for the crash when closing the program...

http://www.vbaccelerator.com/home/VB...wn/article.asp

But I don't like the sol'n...  Paul

----------


## fafalone

The Type Mismatch errors don't seem to be happening in the demo project. I should also clarify it's only an issue in the IDE. It's never given that error or crashed while running, either from VB or compiled.

If I had to guess, the 'type mismatch' is related to the fact that OLEGuids.IPerPropertyBrowsingVB and OLEGuids.IPerPropertyBrowsing are both being used- and if it's me only... I'll look for something not explicitly typed to OLEGuids but I also have olelib.IPerPropertyBrowsing that has a different set of methods. However it's not in use anywhere and everything in your project is explicitly typed as OLEGuids.IPer.. so not sure how such a conflict would arise. Why these three all have a different set of methods is bothersome...



```
Private Sub ReplaceIPPB(ByVal This As OLEGuids.IPerPropertyBrowsing)
If VTableSubclassPPB Is Nothing Then Set VTableSubclassPPB = New VTableSubclass
If VTableSubclassPPB.RefCount = 0 Then
    VTableSubclassPPB.Subclass ObjPtr(This), VTableIndexPPBGetDisplayString, VTAbleIndexPPBGetPredefinedValue, _
    AddressOf IPPB_GetDisplayString, 0, _



Private Function IPPB_GetDisplayString(ByVal This As Object, ByVal DispID As Long, ByVal lpDisplayName As Long) As Long
Dim ShadowIPerPropertyBrowsingVB As OLEGuids.IPerPropertyBrowsingVB

[..]
Set ShadowIPerPropertyBrowsingVB = This 'type mistmatch
```

----------


## Krool

> This article seems to provide the reasons for the crash when closing the program...
> 
> http://www.vbaccelerator.com/home/VB...wn/article.asp
> 
> But I don't like the sol'n...  Paul


The solution is already implemented into the controls. ("LoadLibrary("shell32.dll")", etc.)
The InitVisualStyle method is located in VisualStyles.bas.

I had this problem also once and the reason was by one specific control. Maybe you can trial and error and look if it still crashes when you remove the controls except one and so on... So you run-trough all controls and trace the source of the problem.

----------


## Paul@QMC.net

Thanks, the only time it happens for my existing project (10+ years old) was 2 days ago when we included the VBCCR11.OCX.  And we only use the TreeView from this OCX, on 1 form, of over 5 dozen forms.  The crash occurs at an End statement.  The situation is that we must use the VBCCR11.OCX TreeView to provide access to the 100's of program we have in the QMC Program Suite.    See QMC.net.  Thanks so much, Paul

FYI:  The new MS supplied ComCtl32/TreeView does not work any more with the functionality we and many others need (and as seen on many forums) and is not compatible with any past releases (since 1997).  Right now it is only the TreeView they have changed making this a complete MS Mess.  With the way they do it provides no work around.  You cannot put the required ComCtl32 in the System32 or W[/B][/B]OW folders and over write the new MS ComCtl32 since it affects IE and other programs.  And when the old ComCtl32 is placed in rhe APP.PATH it will not register (programs still use the new new ComCtl32).   Please help...

----------


## Krool

It is not recommended at all to use the End statement. Does it crash when you make a 'clean' close of your App?

----------


## Paul@QMC.net

Don't know what a "clean-close" is...?  P

----------


## Krool

> Don't know what a "clean-close" is...?  P


Close the App by closing all Forms for instance instead of an End statement.

----------


## Paul@QMC.net

Did and it works great now...  What about the Node Click Event, does it exist for the TreeView with your Controls?  Thanks, so much.  (How can I repay you for this?  You are invaluable for sure!!!)

----------


## Krool

> What about the Node Click Event, does it exist for the TreeView with your Controls?


Yes, of course.

----------


## Paul@QMC.net

Can you give me a sample code for the sub?  I cannot find any click event under the object browser folder library for your control...  Thanks, Paul

----------


## Paul@QMC.net

Do you know a VB consultant that can help us move to your controls?  We have to get rid of MS dependencies or die...  Paul

----------


## Krool

> Can you give me a sample code for the sub?  I cannot find any click event under the object browser folder library for your control...


Can you see the NodeClick event in the Demo project?

----------


## Paul@QMC.net

What demo, all I have found are 2 versions of the OCX?  I am using VBCCR11.OCX which is a zip.  The only demo I have found is for a MDI ToolBar...  Can you please tell me wher the TreView DEMO is?  Thanks, Paul

----------


## Paul@QMC.net

But anyway, I get 4 events in my program with your Control:  DragDrop, DragOver, GotFocus, and LostFocus.  That's It, No Mas.  Nothing of what you show... ??? Re, Paul

----------


## Krool

On the first page the first post is a attachment "ComCtlsDemo.rar.zip". (On the bottom of the post)

----------


## Paul@QMC.net

Thanks, checking it out.  Paul

----------


## Niya

Hey Krool, does your TreeView have events for the adding and removal of nodes ?

----------


## Paul@QMC.net

Krool knows for sure, but using the followong seems to work:

Set nodX = tvQMCProgram.Nodes.Add(, , "Data Mining", "Data Mining Programs", 1, 2)

'Sub Folder Data Screener
Set nodX = tvQMCProgram.Nodes.Add("Data Mining", tvwChild, "DS", "Data Screening", 1, 2)

'QMCDLLs
MyName = "DataScreener DLL Test"
Set nodX = tvQMCProgram.Nodes.Add("DS", tvwChild, MyName, MyName, 3)

However, I cant seem to get the icons to load from a ImageList...

Paul

----------


## Paul@QMC.net

PS:  I also have the VB5 Comctl32.OCX loaded with Krool's in the same project...  P

----------


## Krool

> Hey Krool, does your TreeView have events for the adding and removal of nodes ?


I could create a event in response to TVN_DELETEITEM. However, there is no notification when a node is being added...

----------


## Paul@QMC.net

I am thinking the:

Function HitTest(X As Single, Y As Single) As TvwNode

And the Selected Item (Node) should work within the above FNC.  I will try over the weekend...  Paul

----------


## Niya

> I could create a event in response to TVN_DELETEITEM. However, there is no notification when a node is being added...


Oh, if you did, I just wanted to know what messages you intercepted. I have an inherited TreeView in .Net where I added events for the addition and deletion of nodes but its not perfect. There was no real direct message for these events so I had to get a bit clever but the solution has a couple nuances.

----------


## vb6rocks

The VBCCR11.ListView control, while doing a drag operation throws "Run-time error '0'" intermittently and causes the application to crash. 




Any insight on potential causes for this issue would help.

----------


## Krool

> The VBCCR11.ListView control, while doing a drag operation throws "Run-time error '0'" intermittently and causes the application to crash. 
> 
> 
> 
> 
> Any insight on potential causes for this issue would help.


Please provide your code. Does this also happen when using the StdEXE-ListView?

----------


## vb6rocks

> Please provide your code. Does this also happen when using the StdEXE-ListView?


No, the original control (MSComctlLib.ListView) that was replaced did not have this issue. 

I've attached the event handlers and properties. I did observe that when the run-time error happens, it does not hit the trace message at the beginning of OLEStartDrag event handler. It seems like something is happening even before that. When I debug, the application crashes after this error and I get a memory reference exception.

----------


## Krool

> No, the original control (MSComctlLib.ListView) that was replaced did not have this issue. 
> 
> I've attached the event handlers and properties. I did observe that when the run-time error happens, it does not hit the trace message at the beginning of OLEStartDrag event handler. It seems like something is happening even before that. When I debug, the application crashes after this error and I get a memory reference exception.


In my tests the OLEStartDrag event fires w/o any run-time error.. (W2K, WinXP and Win7 tested)

By StdEXE-ListView I did not mean the MSComctlLib.ListView, rather I mean my ListView control. (non-OCX, can be found in the Demo project) Can you test if there is the same issue?
Do you also use the latest VBCCR11.OCX version? (revision number)

----------


## vb6rocks

> In my tests the OLEStartDrag event fires w/o any run-time error.. (W2K, WinXP and Win7 tested)
> 
> By StdEXE-ListView I did not mean the MSComctlLib.ListView, rather I mean my ListView control. (non-OCX, can be found in the Demo project) Can you test if there is the same issue?
> Do you also use the latest VBCCR11.OCX version? (revision number)



I've not been able to reproduce the issue in the Demo project. However, as you can see, the implementations are different in both cases. It's not clear what is causing the issue. 

I was able to reproduce the run-time error on the latest version of VBCCR11.OCX (Revision 32).

----------


## vb6rocks

> I've not been able to reproduce the issue in the Demo project. However, as you can see, the implementations are different in both cases. It's not clear what is causing the issue. 
> 
> I was able to reproduce the run-time error on the latest version of VBCCR11.OCX (Revision 32).


Additionally, I was able to identify that the following line (in red) in VBCCR11 is what is causing the run-time error (Overflow):

Private Sub UserControl_OLEStartDrag(Data As DataObject, AllowedEffects As Long)
If ListViewDragIndex > 0 Then
    If ListViewHandle <> 0 Then
        Dim P(0 To 1) As POINTAPI, RC As RECT
        GetCursorPos P(0)
        ScreenToClient ListViewHandle, P(0)
        SendMessage ListViewHandle, LVM_GETITEMPOSITION, ListViewDragIndex - 1, ByVal VarPtr(P(1))
        SendMessage ListViewHandle, LVM_GETVIEWRECT, 0, ByVal VarPtr(RC)
        ListViewDragOffsetY = (P(1).Y - P(0).Y) + RC.Top
        ListViewDragOffsetX = (P(1).X - P(0).X) + RC.Left
    End If
    If PropOLEDragMode = vbOLEDragAutomatic Then
        Dim Text As String
        Text = Me.FListItemText(ListViewDragIndex, 0)
        Data.SetData StrToVar(Text & vbNullChar), CF_UNICODETEXT
        Data.SetData StrToVar(Text), vbCFText
        AllowedEffects = vbDropEffectMove Or vbDropEffectCopy
    End If
End If
RaiseEvent OLEStartDrag(Data, AllowedEffects)
If AllowedEffects = vbDropEffectNone Then ListViewDragIndex = 0
End Sub

----------


## vb6rocks

> Additionally, I was able to identify that the following line (in red) in VBCCR11 is what is causing the run-time error (Overflow):
> 
> Private Sub UserControl_OLEStartDrag(Data As DataObject, AllowedEffects As Long)
> If ListViewDragIndex > 0 Then
>     If ListViewHandle <> 0 Then
>         Dim P(0 To 1) As POINTAPI, RC As RECT
>         GetCursorPos P(0)
>         ScreenToClient ListViewHandle, P(0)
>         SendMessage ListViewHandle, LVM_GETITEMPOSITION, ListViewDragIndex - 1, ByVal VarPtr(P(1))
> ...


Another difference when compared to the demo is that in our case we are doing a drag and drop on controls that are in different forms. (The demo project has both the controls in the same form.) 

We are using your library extensively for Unicode support and it has been very beneficial so far. 

Update: We were able to identify the root cause of the run-time error. It was caused by one of the long variables (RC.Top/ RC.Left) getting set to it's max value (2147483647) and the addition operation caused an Overflow exception.

----------


## Krool

> Additionally, I was able to identify that the following line (in red) in VBCCR11 is what is causing the run-time error (Overflow):
> 
> Private Sub UserControl_OLEStartDrag(Data As DataObject, AllowedEffects As Long)
> If ListViewDragIndex > 0 Then
>     If ListViewHandle <> 0 Then
>         Dim P(0 To 1) As POINTAPI, RC As RECT
>         GetCursorPos P(0)
>         ScreenToClient ListViewHandle, P(0)
>         SendMessage ListViewHandle, LVM_GETITEMPOSITION, ListViewDragIndex - 1, ByVal VarPtr(P(1))
> ...


Is the same happening when you use the Std-Exe ListView?
If yes, what are the debug values? Maybe the var type 'Long' for ListViewDragOffsetX/Y is not sufficient..

EDIT: Ok you figured out that the RC.Top / RC.Left values (in fact LVM_GETVIEWRECT) are set to its max value and of course causing an Overflow exception. Try to declare ListViewDragOffsetX/Y as Double instead of Long. Does this solves the issue?

----------


## vb6rocks

> Is the same happening when you use the Std-Exe ListView?
> If yes, what are the debug values? Maybe the var type 'Long' for ListViewDragOffsetX/Y is not sufficient..
> 
> EDIT: Ok you figured out that the RC.Top / RC.Left values (in fact LVM_GETVIEWRECT) are set to its max value and of course causing an Overflow exception. Try to declare ListViewDragOffsetX/Y as Double instead of Long. Does this solves the issue?


Yes, technically, using Double would solve the problem. In our case, we just added a check to see if RC.Top is > max value, if yes, then set ListViewDragOffsetY to max value instead of doing an addition operation. This solved the problem for us. We'll wait for you to provide a fix for your library and in the interim, we'll use this solution, thanks.

----------


## Krool

> We'll wait for you to provide a fix for your library and in the interim, we'll use this solution, thanks.


Update released.

----------


## vb6rocks

> Update released.


Great, thanks for the quick turnaround!

----------


## ishalom

The textbox has a great Property 
Property Code:
AllowOnlyNumbers
 would it be possible to add AllowDecimal, and/or how many digits after the Decimal?

----------


## patojo

Thanks so much for this excellent control. Just wondering if you could add a vertical alignment property to the label and textbox control.

----------


## dz32

[...]

----------


## Krool

> is this in source control anywhere?


The source code for the ActiveX Controls are not public.

But the code for the Std-EXE Controls (located in the ComCtlsDemo project) are public. These are also with the latest features as the ActiveX Control project will be updated rarely. (Until now only two versions; 1.0 and 1.1)
Only bugfixes will be updated to the existing ActiveX Control versions, as this does not break binary compatibility.

----------


## dz32

[...]

----------


## MikiSoft

This is a bit off-topic question, but is there a replacement for Frame control because of this problem:

----------


## Krool

> This is a bit off-topic question, but is there a replacement for Frame control because of this problem:


This project have a replacement of the frame control, 'FrameW'.

----------


## MikiSoft

I'm so blind... Thanks for the controls, you did an excellent job!

----------


## DEXWERX

I am definitely a proponent of Github. I can't expound enough of how beneficial it is to legacy projects like this. Especially ones that are this valuable to the community. (this is an amazing code base Krool)

It's quite a shame that CCRP didn't open their sources. (for similar reason's why the OCX's here are technically not open source)

----------


## Romeo91

Hi, Krool!
Please see my project (https://github.com/ADIAProject/DIA), I can not understand in any of the components of the error. Or checkboxw from your kit or on the button that I use or scrollframe.
On checkbox has a black frame, but not on all elements, but only those which do not start at the time of focus.


For programs require the driverspacks, you can download torrent here
http://driveroff.net/sam/
or here http://driverpacks.net/driverpacks/latest

----------


## Krool

Update released.

Included the network address validation functionality into the TextBoxW control.

When the property 'NetAddressValidator' is set to true the TextBoxW control is internally a "msctls_netaddress" window and not a "Edit" window.

Example of how to validate:



```
Private Sub Command1_Click()
TextBoxW1.NetAddressType = TxtNetAddressTypeIPv6Address
Dim ErrVal As Long
On Error Resume Next
TextBoxW1.ValidateNetAddress
ErrVal = Err.Number
On Error GoTo 0
If ErrVal <> 0 Then
    TextBoxW1.ShowNetAddressErrorTip
    Exit Sub
Else
    MsgBox "Success!", vbOKOnly, "Validation Results"
End If
End Sub
```

The following point must be realized that "On Error Resume Next" on UserControls works:
_- In order to trap error raises via "On Error Goto ..." or "On Error Resume Next" it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error_ Trapping.

----------


## pepegriyo

Please,
Use a static code analyzer how:

http://www.axtools.com/products-codesmart-vb6.php

or

http://www.mztools.com/v3/download.aspx

Your code is terrible!

Too many code Dead, function, variable, constants...

----------


## Paul@QMC.net

But it works well and gets rid of MS BS and their constantly inconsistent controls; a never ending MS MESS is now over...

----------


## Krool

Update released.

----------


## Jonney

> Please,
> Use a static code analyzer how:
> 
> http://www.axtools.com/products-codesmart-vb6.php
> 
> or
> 
> http://www.mztools.com/v3/download.aspx
> 
> ...


Your comment is too rude and could hurt Krool who put tremendous effort for this great project. I believe there're more than thousands around the world using Krool's open source CommonControls.
You can use FORMAT tools to format the alignment. Don't force us to use the tools.

----------


## SuperDre

> Your comment is too rude and could hurt Krool who put tremendous effort for this great project. I believe there're more than thousands around the world using Krool's open source CommonControls.
> You can use FORMAT tools to format the alignment. Don't force us to use the tools.


Yes, it's not quite nice for Krool who put in a lot of work in the excellent controls, but the tools pepegriyo is refering to are about removing/pinpointing dead/unused variables/code, and it's good practice to use it as in the end it also makes life easier for yourself.. So it's not about format alignement, it's about removing dead code.. Format alignement is something that is always in the eye of the beholder, what you think is a good format might be crap for others (for instance,  I think aligning all variable declaraction makes the code more readable, but others think it's just a waste of time..

----------


## Niya

> Please,
> Use a static code analyzer how:
> 
> http://www.axtools.com/products-codesmart-vb6.php
> 
> or
> 
> http://www.mztools.com/v3/download.aspx
> 
> ...


Even the best apps have these problems. Have you ever read the comments about the Doom source code by programmers who ported it to modern operating systems ? By all accounts its one huge mess but it changed the world still. As long as a program works well for the people using it, and its not too much of a hassle for the people maintaining it, this shouldn't really matter. Your concern about dead code and such only really matters when multiple developers are involved in its maintenance and these developers aren't the original creators who would have been aware of the quirks in the source code. In other words, its more of a concern for large open source projects that may be updated and maintained by hundreds of developers.

----------


## DEXWERX

many lazy coders leave dead code in, as a sort of documentation, with references and placeholders for future work.
It's not the best practice, but honestly - not worth most people's time to fix.

If you don't like it - you can spend some time and clean it up yourself. That's the beauty of open source.


I don't know that I've ever heard an experienced programmer complain about dead code....

----------


## Krool

Update released.

Fixed a critical and stupid bug in the CDDS_ITEMPREPAINT handler in the ListView control.
Most likely impact for the bug was when using the 'Tile' view.

----------


## Paul@QMC.net

control replacement changes and below is list of screen explored and changed basically for Comctl32.ocx (TabStrip, Toolbar, Statusbar, Progressbar, Treeview, Listview, Imagelist, Slider). We are working on phase manner to have better control with replacing "ComCtl32.ocx" file as first phase, once done with it we will work on to replace the Comdlg32.ocx.


Faced issues with below screens having Toolbar control with button click event. Commented currently as VBCCR11 doesn't have click event, we will revisit this once we found a solutions for this.

	frmMainTaskBar.frm (Toolbar)
o	Private Sub ADVControl_ButtonClick(ByVal Button As VBCCR11.Button)  


We have replaced COMDLG32.ocx control with VBCCR11.CommonDialog in below screens list. Since there is no control available in VBCCR11 control list (screenshot A) had to explore on sample application to study the replacement working. Based on the analysis found that on declaring in the screen as Dim CommonDialog1 As New VBCCR11.CommonDialog it worked Ok. However VBCCR11.CommonDialog control doesnt support few events/methods/properties as stated hence have commented them.
	NumCopies = CommonDialog1.Copies
	CommonDialog1.FontBold = txtFontType(Index).FontBold
	CommonDialog1.FontItalic = txtFontType(Index).FontItalic
	CommonDialog1.FontName = txtFontType(Index).FontName
	CommonDialog1.FontSize = txtFontType(Index).FontSize

On Monday we will look into different screens for our commented properties/events/methods and possible fixing.

----------


## Paul@QMC.net

Krool, can you help on the following???

To update you,
Explored for more replacement control for Toolbar, ListView, CommonDialog as some events/methods/properties are not supported by VBCCR (VB Common Control Replacement). Below are the few links we explored. Lately we found one ctoolbar control (screenshot A) but it too had 2 events viz.DragDrop and DragOver similar to VBCCR control toolbar.

http://www.vbaccelerator.com/home/VB...ete_Source.asp
http://btmtz.mvps.org/listview/
http://www.freevbcode.com/ShowCode.asp?ID=5716
https://groups.google.com/forum/#!to...pi/4zsGrOEDdgg

Currently controls with below events/methods/properties are required in the QMCAPFTProgram. 
	VBCCR Toolbar has only DragDrop, DragOver but application needs Toolbar button click event.
	VBCCR ListView has only DragDrop, DragOver, GotFocus, LostFocus but application needs Listview item click event.
	VBCCR CommonDialog doesnt support below property.
o	NumCopies = CommonDialog1.Copies
o	CommonDialog1.FontBold = txtFontType(Index).FontBold
o	CommonDialog1.FontItalic = txtFontType(Index).FontItalic
o	CommonDialog1.FontName = txtFontType(Index).FontName
o	CommonDialog1.FontSize = txtFontType(Index).FontSize

In the absence of replacement controls fulfilling the above requirements please let us know how you want us to proceed.


Thanks, Paul

----------


## Krool

> Currently controls with below events/methods/properties are required in the “QMCAPFTProgram”. 
> •	VBCCR Toolbar has only DragDrop, DragOver but application needs Toolbar button click event.
> •	VBCCR ListView has only DragDrop, DragOver, GotFocus, LostFocus but application needs Listview item click event.
> •	VBCCR CommonDialog doesn’t support below property.
> o	NumCopies = CommonDialog1.Copies
> o	CommonDialog1.FontBold = txtFontType(Index).FontBold
> o	CommonDialog1.FontItalic = txtFontType(Index).FontItalic
> o	CommonDialog1.FontName = txtFontType(Index).FontName
> o	CommonDialog1.FontSize = txtFontType(Index).FontSize


Something in your environment is not OK as the ToolBar has a button click event, the ListView has a item click Event...
For the CommonDialog properties. Instead of ".FontBold" you should use ".Font.Bold". There is also no ".Copies" property in the CommonDialog class. The value can be retrieved and set via the "VB.Printer.Copies".

Are the events for ToolBar and ListView available in the Demo project?

----------


## Paul@QMC.net

Thanks, we are checking the Demo project...  Paul

----------


## vb6rocks!

I believe the ListBoxW using style "1 - vbListBoxCheckbox" has a bug. When I set the selected state of an item in code, it is not rendering as checked in the UI. Furthermore, the selected state property of a checked item is not correctly returned as "True."

Sample snippet:
ListBoxW1.Selected(0) = True

This does not result in the first item of a ListBoxW being selected. The same snippet works fine against a native VB6 ListBox.

I cross referenced the common controls test harness and there are no ListBoxW controls with checkboxes used.

----------


## Paul@QMC.net

Moving all projects to VB6, latest SP...

	We will move to VB6 platform using same VBCCR11.ocx as it seems to give most event in VB6 than VB5 platform.

	We will work to replace Microsoft comdlg32.ocx and comctl32.ocx with VBCCR11.ocx. For other controls we need to do some research. 

	If possible try to reach VB Programer and find his work on VB6.

	As suggested by you in the below example of Treeview control we will have to explore on the proper replacement for events/properties/methods and passing values.
>>>>
'Private Sub tvQMCProgram_NodeClick(ByVal Node As Node) - Old MS Mess w/Win XP to Win 10 and no-reason-whatsover MS BS Update just to cause complete chaos & stop all from working!
Private Sub tvQMCProgram_NodeClick(MyName) - New Krool w/no issues in VB6, for all Win Platforms

On Error Resume Next
Dim vTmp As Variant

'vTmp = Node.Key
'MyName = vTmp 'MS BS

vTmp = MyName  'Krool
StatusLabel.Enabled = True
        <<<<

To update you,
We downloaded and installed the given ComCtlsDemo.rar.zip in the virtual Pc with VB5 but on full compiling (Ctrl + F5) ComCtlsDemo gave screenshot A error. Explored on this error and as per screenshot B details this application points to be VB6 application. However continued with ComCtlsDemo application and commented the code highlighted in screenshot C for similar issue across various forms. 
This lead to screenshot D error Missing: OLE Guid and interface definitions. To fix this browsed to ComCtlsDemo\OLEGuids folder and picked OLEGuids.tlb which helped to fix the issue but started showing other issues like in screenshot E.

Further
	Setup a fresh virtual machine with VB6 and on it registered VBCCR11.OCX control. Created VB6- Test application, added Toolbar and Listview controls. In the screen code it displayed various events for both these controls (screenshot F).
	Next installed VB5 on this virtual machine having VB6. Created VB5- Test application added Toolbar and Listview controls. In the screen code it displayed only few events for both these controls as shown in QMCAPFTProgram (screenshot G).
	From this it seems VBCCR11.OCX Toolbar and Listview are not fully compatible with VB5.

Summary>  Use VB6

Or:

In VB5 use,

Private Sub Command1_Click()
On Error Resume Next
For I = 1 To tvQMCProgram.Nodes.Count + 1
IsChecked = tvQMCProgram.Nodes(I).Selected
MYOLDNAME = tvQMCProgram.Nodes(I).Text
If IsChecked = True Then
tvQMCProgram.Nodes(I).Selected = True
MyName = tvQMCProgram.Nodes(I).Text
Call tvQMCProgram_NodeClick(MyName)
tvQMCProgram.Nodes(I).Selected = False
tvQMCProgram.SingleSel = False
End If
Next I
j = tvQMCProgram.Nodes.Count
End Sub

By adding Button Control w/Krools TreeView

Thanks Krool, we are almost there,,,  Paul

----------


## Krool

Update released.




> I believe the ListBoxW using style "1 - vbListBoxCheckbox" has a bug. When I set the selected state of an item in code, it is not rendering as checked in the UI. Furthermore, the selected state property of a checked item is not correctly returned as "True."


There was an embarrassing bug in the Selected property that it just did not work in a single selection ListBoxW. This has been fixed now.
Also the "ItemClick" event will be fired when a change is resulted.

I know that in the intrinsic ListBox the checked item is rendered within the Selected property and the "ItemClick" event is fired once again when effectively a item is checked.
But in the ListBoxW control this has been changed as following: (Kind of break to MS ListBox)
- The "ItemCheck" event is fired when an item is effectively checked. This is more clear that this is seperated to the "ItemClick".
- When you want to change the checked state of an item by code then use the ItemChecked property and not the Selected property.

@ Paul@QMC.net
When using the Std-EXE method you need to have VB6.
For the OCX method, as you noticed, you will not be happy with VB5.

----------


## Paul@QMC.net

Thanks, all looks good for total withdrawal from MS.  Paul

----------


## PankajMewada

Hi Krool,

Can you please provide me link to the latest download for VBCCR11.OCX control for VB6.

Thanks

----------


## Arnoutdv

The download links are in the first post of this thread:
http://www.vbforums.com/showthread.p...=1#post4277565

----------


## vb6rocks!

> Update released.
> 
> 
> 
> There was an embarrassing bug in the Selected property that it just did not work in a single selection ListBoxW. This has been fixed now.
> Also the "ItemClick" event will be fired when a change is resulted.
> 
> I know that in the intrinsic ListBox the checked item is rendered within the Selected property and the "ItemClick" event is fired once again when effectively a item is checked.
> But in the ListBoxW control this has been changed as following: (Kind of break to MS ListBox)
> ...


Thanks Krool! I'll download the latest version and give it a shot.

----------


## ishalom

> in the List of revisions:
> 31-May-2015
> - Included the ForeColor/Style/DownPicture/DisabledPicture/UseMaskColor/MaskColor/DrawMode property and OwnerDraw event in the CommandButtonW control.


Sorry, but why cant I see those properties and event, I have revision 38

----------


## Krool

> Sorry, but why cant I see those properties and event, I have revision 38


That update was released after VBCCR11.OCX was published. Only bugfixes are implemented into the VBCCR11.OCX as those revisions do not break compatibility. Either you use the Std-EXE Version or wait until VBCCR12.OCX will be published.

----------


## PankajMewada

Hi Krool,

We are using VBCCR11.ocx.
Declaring object variable gives error. What is the alternative. Please suggest.

Dim mnodEditNode As Node
Dim itmX As ListItem    
Dim imgX As ListImage

----------


## ishalom

> how do I set RightToLeft Property to the controls?





> You can't. The controls are same as the ambient RighToLeft property.


It's not working, is it possible to add the RightToLeft  on each control like VBs controls do have.

----------


## Krool

> We are using VBCCR11.ocx.
> Declaring object variable gives error. What is the alternative. Please suggest.
> 
> Dim mnodEditNode As Node
> Dim itmX As ListItem    
> Dim imgX As ListImage


The object names are slightly different. The following should work:

Dim mnodEditNode As TvwNode
Dim itmX As LvwListItem    
Dim imgX As ImlListImage

----------


## PankajMewada

Hi Krool,


We replaced microsoft comctl32.ocx and comdlg32.ocx with VBCCR11.ocx in VB6 application. But noted the Toolbar was reset to default height and Toolbar buttons there in microsoft toolbar were missing now, the ImageList too was having images but after replacement it was empty.

FYI: We have only changed references of control.

Please let us know what steps we need to follow so the above control details remain as it is.


Regards

----------


## Krool

> We replaced microsoft comctl32.ocx and comdlg32.ocx with VBCCR11.ocx in VB6 application. But noted the Toolbar was reset to default height and Toolbar buttons there in microsoft toolbar were missing now, the ImageList too was having images but after replacement it was empty.
> 
> FYI: We have only changed references of control.
> 
> Please let us know what steps we need to follow so the above control details remain as it is.


You need to create them new from scratch, e.g. inserting again the images in the ImageList control.

If somebody knows how to avoid this "issue" please let me know.

----------


## SuperDre

> You need to create them new from scratch, e.g. inserting again the images in the ImageList control.
> 
> If somebody knows how to avoid this "issue" please let me know.


Change the link to the OCX control in the frm outside (the first line(s) in the frm when opened in a texteditor) the IDE before loading the project? I don't know if it will work in this case..

----------


## Krool

The ActiveX Control version 1.2 is now available.

----------


## PankajMewada

Hi Krool,

Please let us know the difference between ActiveX control VBCCR11.ocx and VBCCR12.ocx.

Thank You,

----------


## Krool

> Please let us know the difference between ActiveX control VBCCR11.ocx and VBCCR12.ocx.


Only bugfixes were implemented by the time into the VBCCR11.OCX and not any new functionality.
The Std-EXE project is always up-to-date but the OCX project not. Only every half year or so there is a new version with all the added functionalities.

----------


## Jonney

in ShowPrinterEx:

VB.Printer.PrintQuality = DMODE.DMPrintQuality doesn't work.  
I see  DMODE.DMPrintQuality =300 but .PrintQuality always maintains 600dpi.

is the unit dpi or VB Constants?




> vbPRPQDraft
> vbPRPQlow
> vbPRPQMedium
> vbPRPQHigh

----------


## Krool

> in ShowPrinterEx:
> 
> VB.Printer.PrintQuality = DMODE.DMPrintQuality doesn't work.  
> I see  DMODE.DMPrintQuality =300 but .PrintQuality always maintains 600dpi.
> 
> is the unit dpi or VB Constants?


This seems to be a common issue.
You can avoid this issue by not be dependent on the VB.Printer object.
For instance you can include the flag 'CdlPDReturnDC' in the '.Flags' property of the CommonDialog class and use the '.hDC' property at return from the dialog box.

----------


## Jonney

> This seems to be a common issue.
> You can avoid this issue by not be dependent on the VB.Printer object.
> For instance you can include the flag 'CdlPDReturnDC' in the '.Flags' property of the CommonDialog class and use the '.hDC' property at return from the dialog box.


Thank you sir, I got it.

----------


## Tech99

Thank you Krool. Excellent replacement controls. However - quickly looked contols properties and found out, that from DTPicker and Monthview controls - Week property is missing.

https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx



> •The Week property returns the number of the week containing the selected date.


Same applies to Monthview control also.
https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx

So at least these does not function as 'drop in' replacement/substitutes for the MS DTPicker or Monthview controls.

----------


## Krool

> Thank you Krool. Excellent replacement controls. However - quickly looked contols properties and found out, that from DTPicker and Monthview controls - Week property is missing.
> 
> https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx
> 
> 
> Same applies to Monthview control also.
> https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx
> 
> So at least these does not function as 'drop in' replacement/substitutes for the MS DTPicker or Monthview controls.


Thanks for this info. Just want to mention that the MS DTPicker (for VB6) do not have a 'Week' property. Only the MS MonthView control has.

----------


## Tech99

> Just want to mention that the MS DTPicker (for VB6) do not have a 'Week' property.


Yes, so it seems, despite of MS online documentation.
https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx

Fiddled with some calendar dates. There is a bug in week numbering display (week 53 vs. 1) also, altought this is corect in MS component.

fex. 29/12/2003 is week 1 not 53.
Attachment in left is MS common control-2 SP6 version MSCOMCT2.OCX and in right replacement control.

----------


## Krool

> Yes, so it seems, despite of MS online documentation.
> https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx
> 
> Fiddled with some calendar dates. There is a bug in week numbering display (week 53 vs. 1) also, altought this is corect in MS component.
> 
> fex. 29/12/2003 is week 1 not 53.
> Attachment in left is MS common control-2 SP6 version MSCOMCT2.OCX and in right replacement control.


Update released.

Included the Week property in the MonthView control.
Also the workaround for bug in the DatePart function is implemented as the MS MonthView does also.
Though I let it allow to set a Week 53 in the Property Let procedure as the MS MonthView allows also.
Another point is that the MS MonthView calculates the week based on the system setting and not based on the start of week setting set for the control. This is weird. So I decided to always base on the start of week setting set to the control.

Also did some internal improvements in the DTPicker and MonthView control concerning the Year/Month/Day and Hour/Minute/Seconds property.

Thanks for your help.

----------


## SuperDre

> Attachment 129239
> 
> Yes, so it seems, despite of MS online documentation.
> https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx
> 
> Fiddled with some calendar dates. There is a bug in week numbering display (week 53 vs. 1) also, altought this is corect in MS component.
> 
> fex. 29/12/2003 is week 1 not 53.
> Attachment in left is MS common control-2 SP6 version MSCOMCT2.OCX and in right replacement control.


Yep, you're right, 2004 has 53 weeks, maybe it's because some internal weekday setting (which day of the week is the first day, normally it should be set to monday)..

----------


## Tech99

Thank you.

Week property returns right week number. However there is still that 53 vs. 1 week bug in drawn controls week numbering.

In Finland, where i am located first day of the week is monday, MSCOMCT2 shows right week numbering, despite of regional settings - i mean be it Finnish, US/English or what ever.

----------


## Krool

> Thank you.
> 
> Week property returns right week number. However there is still that 53 vs. 1 week bug in drawn controls week numbering.
> 
> In Finland, where i am located first day of the week is monday, MSCOMCT2 shows right week numbering, despite of regional settings - i mean be it Finnish, US/English or what ever.


I have no influence on the drawn week number. Thats a issue then from the comctl32.dll itself.

Edit: SysMonthCal32 with MCS_WEEKNUMBERS style will display week 53 if used with themes (comctl32.dll 6.x) and week 1 if used without themes. (comctl32.dll 5.x)

----------


## Krool

Is it then correct that the 28th December 2015 (when start of week is Monday) is week 53? Because there are not four days in the first week on the new year. (only three days)

MS MonthView returns also 53 in that scenario.

----------


## SuperDre

> Is it then correct that the 28th December 2015 (when start of week is Monday) is week 53? Because there are not four days in the first week on the new year. (only three days)
> 
> MS MonthView returns also 53 in that scenario.


Yep 2015 has 53 weeks..

----------


## lrd_VB6

Hello

I have adapted the "VBCCR10_To_11" converter has the new version.
It is now called "VBCCR_11_To_12.OCX_converter"

Manual:
1 - Save the OCX in the manner of your choice.
2 - Register the OCX with "regsvr32" or create a program using VB6 VBCCR12.
3 - Make a backup of the program has convert from (as a precaution).
4 - Launch the converter and open the ".vbp" .
     A backup copy is created (.bak) for all converted files.

5 - Open the converted program.

An error is generated. This is normal, the version is set has "0.0" when converting.
VB6 will put the right value at the launch.


Good luck


Attachment 129353

----------


## Tech99

Hello Krool, is thre a way to adjust DTPicker checkbox size? Tested these more and found out that with display percentage scaling checkbox enlargens bit too much. Atachment is 125 percent scaled, when increasing display scaling checkbox does not fit in upper, left and lower bounds to inside drawn 'line' rectangle at the ownerdraw area. Same goes with datetext part, it is shifted/drawn bit too left.

----------


## Krool

> Hello Krool, is thre a way to adjust DTPicker checkbox size? Tested these more and found out that with display percentage scaling checkbox enlargens bit too much. Atachment is 125 percent scaled, when increasing display scaling checkbox does not fit in upper, left and lower bounds to inside drawn 'line' rectangle at the ownerdraw area. Same goes with datetext part, it is shifted/drawn bit too left.


I see no way to adjust the checkbox size...

----------


## Krool

Update released.

Included the StartOfWeek and Week property in the DTPicker control.

Fixed an embarrassing bug in the StartOfWeek property in the MonthView control...
The LParam in the MCM_SETFIRSTDAYOFWEEK message used a 'Integer' variable and can produce unpredictable results in 64-bit systems. (32-bit system seems to have no problems whatsoever)
This is now fixed with a CLng().

----------


## jpskiller

HI,

Sorry to ask but there is a massive amount of INFORMATION here but I think I have the jist please correct me if i'm wrong,

1) I have copied the VBCCR12.OCX to my windows\system32 dir and registered
2) in VB6 - Project References I have added windows\system32\VBCCR12.OCX - Now have all new controls in VB6 IDE
3) Also added reference to OLEGuids.tlb from the ComCtlsDemo\OLEGUIDs

4) created a program only using new controls

I now believed that for the program to work on any other machine, the VBCCR12.OCX just needs to be in same folder as my program .exe

Is this correct, thanks for help

----------


## Krool

> HI,
> 
> Sorry to ask but there is a massive amount of INFORMATION here but I think I have the jist please correct me if i'm wrong,
> 
> 1) I have copied the VBCCR12.OCX to my windows\system32 dir and registered
> 2) in VB6 - Project References I have added windows\system32\VBCCR12.OCX - Now have all new controls in VB6 IDE
> 3) Also added reference to OLEGuids.tlb from the ComCtlsDemo\OLEGUIDs
> 
> 4) created a program only using new controls
> ...


Hi,

you can skip point 3.) as the OLEGuids.tlb does not need to be referenced when using the OCX Version.

If you do use the Side-by-Side technique you just need to have the VBCCR12.OCX on the same folder.
Else it need to be registered, somewhere.

----------


## jpskiller

Cheers

Sounds daft but I thought, the final .exe file would some work without having to register the .ocx file on a different PC, reason why I need this is because I dont have admin rights on the user PC but still require to run my programs

how do I get round this?

----------


## Krool

> Cheers
> 
> Sounds daft but I thought, the final .exe file would some work without having to register the .ocx file on a different PC, reason why I need this is because I dont have admin rights on the user PC but still require to run my programs
> 
> how do I get round this?


Then you need to use the Std-EXE way and not the OCX. On that way the controls (UserControls) are compiled into the exe. Reference to OLEGuids.tlb is needed on design time = IDE. But on target PC OLEGuids.tlb is not needed. So you got full "indepedence".
Read first post for full explanation and also the sources in the attachment for the Std-EXE way.

----------


## jpskiller

> Then you need to use the Std-EXE way and not the OCX. On that way the controls (UserControls) are compiled into the exe. Reference to OLEGuids.tlb is needed on design time = IDE. But on target PC OLEGuids.tlb is not needed. So you got full "indepedence".
> Read first post for full explanation and also the sources in the attachment for the Std-EXE way.


When you say Std-EXE I cant find any instructions on how thats done, and what sources, I can only find the Demo, do you mean I need to add everthing to my project's like it is in that example?

----------


## jpskiller

Hi,

I am getting an error when use treeview control, this code works with normal treeview but produces an error with the replacement one, all I need to do is simply not run any code when users clicks on + or - sign to expand a branch, if theres another way I would be grateful

The error is concerning "MSComctlLib.Node"

Private Sub TreeView1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Me.TreeView1.SelectedItem = Me.TreeView1.HitTest(X, Y)
End Sub

Private Sub TreeView1_Collapse(ByVal Node As MSComctlLib.Node)
    bNodeImageClicked = True
End Sub

Private Sub TreeView1_Expand(ByVal Node As MSComctlLib.Node)
    bNodeImageClicked = True
End Sub


Private Sub TreeView1_Click()

 If bNodeImageClicked Then
        bNodeImageClicked = False
        Exit Sub
 End If

  If TreeView1.SelectedItem.Child Is Nothing Then
      textwh1.Text = TreeView1.SelectedItem.Text
   End If


End Sub

----------


## Krool

> The error is concerning "MSComctlLib.Node"


Sure, you need to replace it to 'TvwNode'. The replacement is not the 'MSComctlLib'.

----------


## jpskiller

> Sure, you need to replace it to 'TvwNode'. The replacement is not the 'MSComctlLib'.


Thanks thats resolved it cheers

----------


## dreammanor

The CommonControls are wonderful, thank Krool very much .

There are some questions when I use TreeView control：

(1) There is not 'ExpandedImage' property in TvwNode class

(2) The 'Image' and 'SelectedImage' properties of TvwNode can only accept 'long' parameter, not accept 'string' parameter, but MSComctlLib.Node can do so, such as  objNode.Image = "Closed"

(3) When I create TreeView Control dynamically, the control can not fire 'NodeClick' event, such as:

     Set TreeView1 = Me.Controls.Add("Project1.TreeView", "TreeView1")

----------


## fafalone

Image and SelectedImage refer to the index of the image in the assigned imagelist; you'll have to use that instead of the Key (or modify the code to look up by key instead, but really using the index is the best way to approach it).

ExpandedImage is a Vista+ thing, there's other features missing too-- the TVITEMEX type doesn't have the other 6.0 members either (uStateEx that allows nodes to be grayed out as disabled).

----------


## Krool

> (3) When I create TreeView Control dynamically, the control can not fire 'NodeClick' event, such as:
> 
>      Set TreeView1 = Me.Controls.Add("Project1.TreeView", "TreeView1")


Did you declare 'WithEvents' for object variable TreeView1?

----------


## Karl77

Problem setting icons to the toolbar

Up to now I use the CC5 toolbar, and I want to replace it because of the fixed background color.
In the current system, I populate a CC5 image list with PNG pictures at runtime.
Then I add buttons to the toolbar like this:



```
Dim Btn                 As CommonControls.TbrButton

With MF.xbar(0)
    .Buttons.Clear

    .ImageList = MF.imgl_24

    Set Btn = .Buttons.Add(, "ppa", , 0, 14)
    Set Btn = .Buttons.Add(, "ppb", , 0, 15)

End With
```

2 problems:

1)
The button icons do not show.
When I move the mouse over the place where a button should be, I can see there is an empty button.
On the CC5 toolbar they are there and working.

2)
With the Krool toolbar, using the Add method, I can specify the picture by index number only, not by the key string.
If I use the key string, then a type mismatch error comes up, and the IDE crashes.

---

This does not get any better if I use the CommonControls.TbrButtonStyleDefault insetad of just 0.
It also doesn't change if I use the Krool imagelist.

Do I miss something, or is it just not possible to use PNGs?
And what is about the image index 'problem'?


Thanks,
Karl

----------


## dreammanor

> Image and SelectedImage refer to the index of the image in the assigned imagelist; you'll have to use that instead of the Key (or modify the code to look up by key instead, but really using the index is the best way to approach it).
> 
> ExpandedImage is a Vista+ thing, there's other features missing too-- the TVITEMEX type doesn't have the other 6.0 members either (uStateEx that allows nodes to be grayed out as disabled).



Thanks a lot.

----------


## dreammanor

> Did you declare 'WithEvents' for object variable TreeView1?


Yes, I have declared 'WithEvents' for variable TreeView1:   

Private WithEvents TreeView1 As Project1.TreeView.

The 'Click' event can be fired, but 'NodeClick' event can not.  I tested it in Windows XP, Win7 and Win10.

----------


## Karl77

Ok, after fiddling with the right declarations I finally get the icon displayed.

But something is still wrong.
The toolbar shows 1 icon only, while 2 were set.
Also the transparency is wrong.
And there is no tooltip, while ShowTips = True.



The upper yellow toolbar is Krool's.
The lower is from comctl32.ocx.



```
Dim Btn As CommonControls.TbrButton

With MF.xbar(0)
    .Buttons.Clear
    .ImageList = MF.imgl_24

    Set Btn = .Buttons.Add(, "ppa", , 0, 14)
    Btn.ToolTipText = "14"
    Set Btn = .Buttons.Add(, "ppb", , 0, 15)
    Btn.ToolTipText = "15"

End With


Dim Btn5 As ComctlLib.Button

With MF.tbr_CC5
    .Buttons.Clear

    .ImageList = MF.imgl_24

    Set Btn5 = .Buttons.Add(, "ppa", , 0, 14)
    Btn5.ToolTipText = "14"
    Set Btn5 = .Buttons.Add(, "ppb", , 0, 15)
    Btn5.ToolTipText = "15"

End With
```


Hmm?

----------


## Krool

Important update released fixing the following issue:




> When I create TreeView Control dynamically, the control can not fire 'NodeClick' event, such as:
> 
>      Set TreeView1 = Me.Controls.Add("Project1.TreeView", "TreeView1")


The issue was that on dynamically added controls only the "InitProperties" event in the UserControl is fired. Problem was that on some controls the UserControl.hWnd was not subclassed and thus caused some lacks of functionality. Like in your case with 'NodeClick' event not firing. This has been fixed by subclassing the UserControl.hWnd also in the "InitProperties" and not only in the "ReadProperties" event on run-time.

----------


## jpskiller

I have a  questions about Treeview, 


1) Is it possible to change the lost focus highlight colour?

cheers, great controls keep up the good work.

All I need now is a self contained MSGraph replacment  :Smilie:

----------


## jpskiller

I am having real difficulty in get Treeview Keyup and Keydown to work how I want

All I want to do do is if press keyup or down then get the selected item text and if it is a child then call 1 proceudre and same if parent.

what seems to be happening is that if press up or down, it dosent register until the 2nd key press in same direction !

here's my code, any help would be appreciated

Private Sub TreeView1_NodeClick(ByVal Node As TvwNode, ByVal Button As Integer)

On Error GoTo MyErrorHandler

    If Node.Parent Is Nothing Then
        ' top level node
        Get_Totals (TreeView1.SelectedItem.Text)
        NPS.ListItems.Clear
        ManagerSelected = TreeView1.SelectedItem.Text
        AgentSelected = ""
    Else
      If Node.Child Is Nothing Then
        ' child level node
        Get_Agent_Surveys (TreeView1.SelectedItem.Text)
        NPS_Bonus = CalcBonus(Text3.Text, Text4.Text, Text5.Text, Text6.Text)
        AgentSelected = TreeView1.SelectedItem.Text
      End If
    End If
    Exit Sub

MyErrorHandler:

End Sub
=================================================
Private Sub TreeView1_KeyDown(KeyCode As Integer, Shift As Integer)

On Error GoTo errorhandler:

  Dim SaveIndex As Integer
  SaveIndex = Me.TreeView1.Nodes.Count

  If KeyCode = vbKeyDown Then
       Call TreeView1_NodeClick(TreeView1.SelectedItem, 1)
  End If 'End Sub

errorhandler:
End Sub

----------


## Krool

> I am having real difficulty in get Treeview Keyup and Keydown to work how I want


I have tested on a TreeView created at design-time and one created at run-time and both are firing the KeyDown event with vbKeyDown. So do you have problem in getting the KeyDown event firing or something else?




> I have a  questions about Treeview, 
> 
> 
> 1) Is it possible to change the lost focus highlight colour?


You mean when HideSelection is False? There is no such color property available. The only way for you to get what you want is to modify the NM_CUSTOMDRAW handler at CDDS_ITEMPREPAINT in WindowProcUserControl.




> Ok, after fiddling with the right declarations I finally get the icon displayed.
> 
> But something is still wrong.
> The toolbar shows 1 icon only, while 2 were set.
> Also the transparency is wrong.
> And there is no tooltip, while ShowTips = True.
> 
> 
> 
> ...


Is it correctly working when you do not work with PNGs?

----------


## jpskiller

hi,

no the keydown and keyup event do trigger but what I am trying to do is when press down or up keys then call the same code that is in the nodeclick event for the new selected item which runs code depending if parent or child selected.

I have found other code around the web for normal treeview but it uses things like node.next these dont seem to be supported in this version.

example click on a child node with mouse, perform code in nodeclick, if then press either up or down then its fine but if then change direction on keyboard it dosent seem to update the selected item so nodeclick does same thing until press key in same direction again!

I appreciate the help and will admit to being a novice.

----------


## Krool

Node.Next does not work as 'Next' is a locked keyword in VB6. You need to use Node.NextSibling instead in my TreeView.

----------


## dreammanor

> Important update released fixing the following issue:
> 
> 
> 
> The issue was that on dynamically added controls only the "InitProperties" event in the UserControl is fired. Problem was that on some controls the UserControl.hWnd was not subclassed and thus caused some lacks of functionality. Like in your case with 'NodeClick' event not firing. This has been fixed by subclassing the UserControl.hWnd also in the "InitProperties" and not only in the "ReadProperties" event on run-time.


The issue has been solved.   thank Krool very much !

----------


## Karl77

(Toolbar)




> Is it correctly working when you do not work with PNGs?


No.
I now have an imagelist (comctl32.ocx) prefilled with BMPs.

Result:


Also this time there are no tooltips on the upper toolbar.
Code is pretty much the same as with the PNG trial.
Using your imagelist instead makes no difference.

Thank you Krool.

----------


## Krool

> (Toolbar)
> 
> 
> 
> No.
> I now have an imagelist (comctl32.ocx) prefilled with BMPs.
> 
> Result:
> 
> ...


Can you create an sample project that demonstrate the error and post it here? Or send me via PM. Thanks

----------


## Karl77

> Can you create an sample project that demonstrate the error and post it here? Or send me via PM. Thanks


Sure.
I prefer PM, but now I found that it is not possible to attach something to a PM.
Or I'm too dense.

Please PM me your mail adress.
Thank you.

----------


## SuperDre

Maybe a dumb question, but if you are using BMP, have you set the transparent color of the imagelist to white?

----------


## Karl77

> Maybe a dumb question, but if you are using BMP, have you set the transparent color of the imagelist to white?


The usage of BMP was a test only.
They don't have any transparency and the white is in the picture itself.

And no, I didn't set the mask color to white.

----------


## Krool

@ Karl77,

my ToolBar works correctly in your test, but only when the MinButtonWidth and MaxButtonWidth are set to 0 (zero). *Or* by keeping MinButtonWidth and MaxButtonWidth like you have set but with no preset buttons created at design time.

----------


## Karl77

@Krool




> my ToolBar works correctly in your test, but only when the MinButtonWidth and MaxButtonWidth are set to 0 (zero).


That would be an easy solution...
This also works:


```
.Buttons.Clear
.MinButtonWidth = 0
.MaxButtonWidth = 0
```

Kind of works, the button width is wrong then:





> but with no preset buttons created at design time.


Not an option, as the toolbars are not to distinguish at design time then.
Usually I have one button set just to know which toolbar it is.

Thank you Krool.

----------


## Krool

Im not able to check right now...

Is the TextAlignment property set to 'Bottom' instead of 'Right'?

----------


## Karl77

> Im not able to check right now...
> 
> Is the TextAlignment property set to 'Bottom' instead of 'Right'?


No, right is set.

----------


## Krool

> No, right is set.


You have to set TextAlignment property to 'Bottom' instead of 'Right'.
Then you get the correct result.



And, about the point with the MinButtonWidth and MaxButtonWidth. This is not a bug, but a value of 30 means 2 pixel. If you look exactly the buttons are then 2 pixel wide, also tooltip is displayed. But it looks ugly as the picture goes far beyond and it looks like the button is not working, but it is. ;-)

----------


## Karl77

Thanks for the insights.



```
With MF.xbar(0)

    .Buttons.Clear
    .MinButtonWidth = 0
    .MaxButtonWidth = 0

    .TextAlignment = TbrTextAlignBottom

    .ImageList = MF.imgl_BMP

    Set Btn = .Buttons.Add(, "ppa", "First button", 0, 1)
    Btn.ToolTipText = "14"
    Set Btn = .Buttons.Add(, "ppb", , 0, 2)
    Btn.ToolTipText = "15"

    .TextAlignment = TbrTextAlignRight

End With
```

This way it works as well.
One can live with this 'solution'.







> a value of 30 means 2 pixel


In some cases, yes.
When it comes to different DPI settings, then not.

The toolbar behaves strange on different DPI settings.
A snippet of the effort to handle this can be seen in xbar_MouseDown.
But that is another story.

2 issues left:

1) Transparency handling
2) Adressing the imagelist's picture by key as string.

To 1)
Quite important.
If this is not possible I can stop other effort.

To the latter:
No problem, I could write a small function to manage this.
It would be more elegant to do it in the usercontrol's code.
Up to now I didn't find the right place where such a thing can be done.

Could you give me an advice where to place such code?

Good night Krool.

----------


## Karl77

Unfortunately I have found that placeholder is not available for a button.
Enough for today.

----------


## SuperDre

> The usage of BMP was a test only.
> They don't have any transparency and the white is in the picture itself.
> 
> And no, I didn't set the mask color to white.


yes I know the white is in the picture itself, that's why you need to set the mask color to the same white color so the white will be used as the color that should be transparent, otherwise it will use the default color of the imagelist for the transparent color and it seems it ain't white..

----------


## Krool

> Unfortunately I have found that placeholder is not available for a button.
> Enough for today.


Use the 'Separator' with a CustomWidth value set. then its same as placeholder.

----------


## Karl77

> yes I know the white is in the picture itself, that's why you need to set the mask color to the same white color so the white will be used as the color that should be transparent, otherwise it will use the default color of the imagelist for the transparent color and it seems it ain't white..


This is not what I would name transparency.
The maskcolor just replaces a certain color (white in our case) with nothing.
It gives the impression of transparency if you don't look close.

20 years AGO this was good enough.
Masking works ok for rectangular shapes, if you have round or angled shapes it just looks bad.
What we need today is real transparency, means respecting the alpha channel of the picture.
Comctl32.dll can handle the alpha channel.

Again, in this case the usage of BMP was meant as a test only.

----------


## Karl77

> Use the 'Separator' with a CustomWidth value set. then its same as placeholder.


Ah, good hint.
But with TbrButtonStyleSeparator we get also a visible separator.


Regardless if the Divider property is set or not.
Not very wanted.

For compatibility reasons, you could introduce TbrButtonStylePlaceholder?
At best without the vertical line...

----------


## Krool

> Ah, good hint.
> But with TbrButtonStyleSeparator we get also a visible separator.
> 
> 
> Regardless if the Divider property is set or not.
> Not very wanted.
> 
> For compatibility reasons, you could introduce TbrButtonStylePlaceholder?
> At best without the vertical line...


The Divider property is not for the buttons. Its for the control itself. (Displays a divider line at bottom)

----------


## Karl77

> The Divider property is not for the buttons. Its for the control itself. (Displays a divider line at bottom)


Oh well, yes.
I could have seen that myself.

Anyway, besides that, we get this vertical line.
I'll try a bit more to see if this also happens when a separator with zero size produces it as well.

For the placeholder usage the vertical line is not dramatic, I want to move a control to this place anyway.
This covers the vertical line then.

----------


## Krool

> 2 issues left:
> 
> 1) Transparency handling
> 2) Adressing the imagelist's picture by key as string.
> 
> To 1)
> Quite important.
> If this is not possible I can stop other effort.
> 
> ...


1)

I did some test on the ImageLists.

Here is the result when returning the 'Picture' property of a ListImage.



Here is the result when returning the 'ExtractIcon' property of a ListImage.
And this looks exactly what is the result on the ToolBar...



However, I did not figure out yet why the MS ToolBar is displaying the ListImage "transparent" and my Toolbar is displaying the background black from the MS ImageList and white from my ImageList..

2)

I thouht about this earlier. For TabStrip, ToolBar this could be done without any performance reduction. But for ListView this would result perfromance issues as the real image index is always provided in response to LVN_GETDISPINFO. And for the moment I am hesitating about this as this would cause a non-consistency.

----------


## Karl77

> 1)
> Here is the result when returning the 'ExtractIcon' property of a ListImage.
> And this looks exactly what is the result on the ToolBar...


No, it's not the same.
The transparency is replaced by white now, not black.

(The white icons in the former examples are BMPs, the color itself is white - not transparent.)

----------


## Jonney

I haven't yet follow the issue of toolbar. But I never had issue using maskcolor for my own-drawn toolbar (CreateWindowEx,"ToolbarWindow32") though it is not Krool's one.

----------


## jpskiller

on a side note guys, how do you use the replacment common dialog box for saving / loading files

----------


## Karl77

Regarding the transparency of buttons on toolbar, any news or insights?

----------


## Jonney

> Regarding the transparency of buttons on toolbar, any news or insights?


Probably this link helps you.  "ImageList and the Safety Palette" written by dilettante.

----------


## Karl77

> Probably this link helps you.  "ImageList and the Safety Palette" written by dilettante.


Thanks, but I don't have problems handling the various image formats...
They just don't show as intended on the Krool toolbar.
While they do on the comctl32.dll toolbar via comctl32.ocx.

Doesn't matter, for now I gave up with the Krool toolbar.

----------


## Romeo91

Hi, Krool!!
1. Event "TabClick" for control TabStrip don't work if it is an array of controls.


```
Private Sub TabStrip1_TabClick(Index As Integer, ByVal TabItem As TbsTab)
   MsgBox Index
End Sub
```

2. Is it possible to add transparency to the tab row?
If you place one item to another, you can see the background of control


P.S. In addition can you add a property multiline to TabStrip.Tabs.Caption ?

----------


## Krool

> 1. Event "TabClick" for control TabStrip don't work if it is an array of controls.
> 
> 
> ```
> Private Sub TabStrip1_TabClick(Index As Integer, ByVal TabItem As TbsTab)
>    MsgBox Index
> End Sub
> ```
> 
> ...


1. The Event is firing by me, even in an array of controls. Please let me have your project to resolve.

2. It's quite tricky to do it properly. And not straight forward. Because you need to intercept WM_PAINT, use WM_PRINTCLIENT to a memory DC, clip regions and fill background before. In XP it's different then on W7 (XP has rounded corners, W7 not). Thus I did not yet implement such a feature. Will change maybe in future.

Point P.S.: You can put 'vbLf' to a Tab caption by code. But in order to see the multiline text you may use 'TabWidthStyleFixed' and set TabFixedWidth/TabFixedHeight accordingly.

----------


## Romeo91

> 1. The Event is firing by me, even in an array of controls. Please let me have your project to resolve.


This is a test project - Test_Tabstrip.zip
I have identified, the event caught only since the second tab.




> Point P.S.: You can put 'vbLf' to a Tab caption by code. But in order to see the multiline text you may use 'TabWidthStyleFixed' and set TabFixedWidth/TabFixedHeight accordingly.


Thank you, it works. Now it seems to me is not enough text orientation. Orientation is only at the bottom.

Please see also:
1. The behavior of the checkbox and option controls outside of the visible portion of the container.
2. Resizing Tabstrip when the form is resized.

I can not understand what went wrong, or other 3rd-party control or in your code. In this project, this behavior is present.

----------


## Krool

> I have identified, the event caught only since the second tab.


This is normal. TabClick event is firing in response to TCN_SELCHANGE. So whenever the selected tab changes the event is firing.




> 1. The behavior of the checkbox and option controls outside of the visible portion of the container.


This is because you have set the Transparent property of my CheckBoxW and OptionButtonW to True and at the time the controls are not visible, thus causing a black background. What you need to do is calling '.Refresh' on those controls in case you scroll.




> 2. Resizing Tabstrip when the form is resized.


This is due to an error in your code. Look below image.

----------


## Romeo91

> This is normal. TabClick event is firing in response to TCN_SELCHANGE. So whenever the selected tab changes the event is firing.


I do not understand why this is normal?
It turns out I can never catch the events TabClick for the TabStrip2(0) on all tabs which is "located on the first tab TabStrip1" ?

This code for first tab of TabStrip2(0) on TabStrip1 not work always



> Case TCN_SELCHANGE
>                     Index = SendMessage(TabStripHandle, TCM_GETCURSEL, 0, ByVal 0&)
>                     If Index >= 0 Then RaiseEvent TabClick(*Me.Tabs(Index + 1)*)


instead of returning an object, just goes to the function ComCtl Subclass Proc - and don't  returns the object in



> Public Property Get Item(ByVal Index As Variant) As TbsTab
> *Set Item = PropTab(Index)*
> End Property





> What you need to do is calling '.Refresh' on those controls in case you scroll.


Thanks. I try it.




> This is due to an error in your code. Look below image.


Thanks

----------


## Krool

> I do not understand why this is normal?
> It turns out I can never catch the events TabClick for the TabStrip2(0) on all tabs which is "located on the first tab TabStrip1" ?
> 
> This code for first tab of TabStrip2(0) on TabStrip1 not work always
> 
> 
> instead of returning an object, just goes to the function ComCtl Subclass Proc - and don't  returns the object in


I do now understand what you mean. Yes, the reason is indeed due to control array.
The cause for this is a little bit complicated.
I will bring an update very soon to fix this issue on all controls.

----------


## Krool

Important update released.

Control arrays are now working properly on all controls.

----------


## chosk

Hi Krool,

I am using the CommonDialog.cls to .ShowPrinter. I am unable to find the .Orientation so that after choosing the orientation (portrait or landscape) in the dialog, I want to use it to set the Printer.Orientation = .Orientation.

Is there a way to do this?

----------


## Krool

> I am using the CommonDialog.cls to .ShowPrinter. I am unable to find the .Orientation so that after choosing the orientation (portrait or landscape) in the dialog, I want to use it to set the Printer.Orientation = .Orientation.
> 
> Is there a way to do this?


Printer.Orientation will be set already after dialog automatically.

----------


## chosk

Tks Krool.

Yes, Printer.Orientation is set automatically. I should have tested first.

Just one more question. How about .Copies? I just tested it to select 2 but printed only 1.

----------


## chosk

Hi Krool,

Using the CommonDialog.cls, I have a line:


```
.CancelError = True
```

and originally with the VB6 CommonDialog, I have this code in ErrorHandler:


```
If Err.number = mscomdlg.CdlCancel Then Exit Sub
```

Is it correct that with the CommonDialog.cls, I change this to:


```
If Err.number = CdlErrorConstants.CdlCancel Then Exit Sub
```

It seems to work but I want to be sure.

----------


## Krool

> Using the CommonDialog.cls, I have a line:
> 
> 
> ```
> .CancelError = True
> ```
> 
> and originally with the VB6 CommonDialog, I have this code in ErrorHandler:
> 
> ...


Yes, you can do.




> Just one more question. How about .Copies? I just tested it to select 2 but printed only 1.


You have to take care in your code to print more than once when .Copies is > 1.

----------


## chosk

> You have to take care in your code to print more than once when .Copies is > 1.


I already have prior codes to handle .Copies to print any number of copies selected in a For-Next loop when using the VB6 CommonDialog. But I am unable to find .Copies in CommonDialog.cls. I have also tested Printer.Copies and it is not automatically set.

I have gone through the dropdown list of CommonDialog.cls and can't find anything that can be used. I am missing something on how to capture the number of copies selected and use it.

----------


## Krool

> I already have prior codes to handle .Copies to print any number of copies selected in a For-Next loop when using the VB6 CommonDialog. But I am unable to find .Copies in CommonDialog.cls. I have also tested Printer.Copies and it is not automatically set.
> 
> I have gone through the dropdown list of CommonDialog.cls and can't find anything that can be used. I am missing something on how to capture the number of copies selected and use it.


You need to specify the flag 'CdlPDUseDevModeCopiesAndCollate'.
Then the VB.Printer.Copies will be set after the show printer dialog.

In the MS CommonDialog you also need to specify the flag 'cdlPDUseDevModeCopies' in order to get a meaningful value returned in the .Copies property.

I will include the constant 'CdlPDUseDevModeCopies' in my CommonDialog.cls to be compatible on that. (in fact 'CdlPDUseDevModeCopiesAndCollate' is same as 'CdlPDUseDevModeCopies', anyhow)

----------


## Jonney

I don't so understand what chosk means exactly, but I did add "Copies","Orientation" and "PaperKind" public property for easier call:



```
Private PropCopies As Long '***Add

Public Property Get Copies() As Long '***Add
Copies = PropCopies
End Property

Public Property Let Copies(ByVal value As Long) '***Add
If value < 0 Then err.Raise 380
PropCopies = value
End Property

Public Function ShowPrinterEx() As CdlPDResultConstants
Dim PDLGEX As PRINTDLGEX, PPAGERANGE As PRINTPAGERANGE, DMODE As DEVMODE, DNAMES As DEVNAMES
Dim lpDevMode As Long, lpDevNames As Long
Dim ObjPrinter As VB.Printer, NewPrinterName As String, Buffer As String
With PDLGEX
.lStructSize = LenB(PDLGEX)

If Not Screen.ActiveForm Is Nothing Then
   .hWndOwner = Screen.ActiveForm.hWnd
Else
   .hWndOwner = GetActiveWindow()
End If

.Flags = PropFlags
.nPageRanges = 1
.nMaxPageRanges = 1
PPAGERANGE.nFromPage = PropFromPage
PPAGERANGE.nToPage = PropToPage
.nMinPage = PropMin
.nMaxPage = PropMax
.lpPageRanges = VarPtr(PPAGERANGE)
Const START_PAGE_GENERAL As Long = &HFFFFFFFF
.nStartPage = START_PAGE_GENERAL
End With
If VB.Printers.Count > 0 And (PDLGEX.Flags And CdlPDReturnDefault) = 0 Then
    With VB.Printer
    DMODE.DMSize = LenB(DMODE)
    Buffer = Strings.Left$(.DeviceName, CCHDEVICENAME)
    CopyMemory DMODE.DMDeviceName(0), ByVal StrPtr(Buffer), LenB(Buffer)
    DMODE.DMFields = DM_ORIENTATION Or DM_PAPERSIZE Or DM_COPIES Or DM_DEFAULTSOURCE Or DM_PRINTQUALITY Or DM_COLOR Or DM_DUPLEX Or DM_COLLATE
    DMODE.DMOrientation = PropOrientation '.Orientation
    DMODE.DMPaperSize = PropPaperKind ' .PaperSize
    DMODE.DMCopies = PropCopies '.Copies
    DMODE.DMDefaultSource = .PaperBin
    DMODE.DMPrintQuality = .PrintQuality
    DMODE.DMColor = .ColorMode
    DMODE.DMDuplex = .Duplex
    DMODE.DMCollate = IIf((PDLGEX.Flags And CdlPDCollate) <> 0, 1, 0)
    DNAMES.wDriverOffset = 4
    DNAMES.wDeviceOffset = DNAMES.wDriverOffset + Len(.DriverName) + 1
    DNAMES.wOutputOffset = DNAMES.wDeviceOffset + Len(.DeviceName) + 1
    DNAMES.wDefault = 0
    Buffer = Strings.Left$(.DriverName & vbNullChar & .DeviceName & vbNullChar & .Port & vbNullChar, CCHDEVNAMESEXTRA)
    CopyMemory DNAMES.wExtra(0), ByVal StrPtr(Buffer), LenB(Buffer)
    PDLGEX.nCopies = .Copies
    PDLGEX.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DMODE))
    lpDevMode = GlobalLock(PDLGEX.hDevMode)
    CopyMemory ByVal lpDevMode, DMODE, LenB(DMODE)
    GlobalUnlock PDLGEX.hDevMode
    PDLGEX.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DNAMES))
    lpDevNames = GlobalLock(PDLGEX.hDevNames)
    CopyMemory ByVal lpDevNames, DNAMES, LenB(DNAMES)
    GlobalUnlock PDLGEX.hDevNames
    End With
End If
Dim ErrVal As Long
If PropHookEvents = False Then
    ErrVal = PrintDialogEx(PDLGEX)
Else
    Call ComCtlsCdlPDEXSetHook(Me)
    ErrVal = PrintDialogEx(PDLGEX)
    Call ComCtlsCdlPDEXRemoveHook
End If
If ErrVal = S_OK Then
    If PDLGEX.dwResultAction <> CdlPDResultCancel Then
        lpDevMode = GlobalLock(PDLGEX.hDevMode)
        CopyMemory DMODE, ByVal lpDevMode, LenB(DMODE)
        GlobalUnlock PDLGEX.hDevMode
        GlobalFree PDLGEX.hDevMode
        lpDevNames = GlobalLock(PDLGEX.hDevNames)
        CopyMemory DNAMES, ByVal lpDevNames, LenB(DNAMES)
        GlobalUnlock PDLGEX.hDevNames
        GlobalFree PDLGEX.hDevNames
       
        NewPrinterName = Mid$(DNAMES.wExtra, DNAMES.wDeviceOffset - DNAMES.wDriverOffset + 1)
        NewPrinterName = Strings.Left$(NewPrinterName, InStr(NewPrinterName, vbNullChar) - 1)
        Dim PrinterFound As Boolean
        If StrComp(VB.Printer.DeviceName, NewPrinterName, vbTextCompare) <> 0 Then
            For Each ObjPrinter In VB.Printers
                If StrComp(ObjPrinter.DeviceName, NewPrinterName, vbTextCompare) = 0 Then
                    Set VB.Printer = ObjPrinter
                    PrinterFound = True
                    Exit For
                End If
            Next ObjPrinter
        Else
            PrinterFound = True
        End If
        If PropPrinterDefault = True Then Call SetPrinterDefault(NewPrinterName)
        If PrinterFound = True Then
            On Error Resume Next
            With VB.Printer
            .Copies = DMODE.DMCopies
            .Duplex = DMODE.DMDuplex
            .Orientation = DMODE.DMOrientation
            .PaperSize = DMODE.DMPaperSize
            .PrintQuality = DMODE.DMPrintQuality
            .ColorMode = DMODE.DMColor
            .PaperBin = DMODE.DMDefaultSource
            PropPaperKind = DMODE.DMPaperSize
            PropOrientation = DMODE.DMOrientation
            PropCopies = DMODE.DMCopies
            End With
            On Error GoTo 0
        End If
        PropFlags = PDLGEX.Flags
        If (PropFlags And CdlPDUseDevModeCopiesAndCollate) <> 0 Then
            If DMODE.DMCollate = 1 And (PropFlags And CdlPDCollate) = 0 Then PropFlags = PropFlags Or CdlPDCollate
        End If
        PropFromPage = PPAGERANGE.nFromPage
        PropToPage = PPAGERANGE.nToPage
        PropMin = PDLGEX.nMinPage
        PropMax = PDLGEX.nMaxPage
        If (PropFlags And (CdlPDReturnDC Or CdlPDReturnIC)) <> 0 Then PropDC = PDLGEX.hdc
        ShowPrinterEx = PDLGEX.dwResultAction
    Else
        If PropCancelError = True Then err.Raise Number:=CdlCancel, description:="Cancel was selected."
    End If
Else
    If PDLGEX.hDevMode <> 0 Then GlobalFree PDLGEX.hDevMode
    If PDLGEX.hDevNames <> 0 Then GlobalFree PDLGEX.hDevNames
    Const E_OUTOFMEMORY As Long = &H8007000E, E_INVALIDARG As Long = &H80070057, E_POINTER As Long = &H80004003, E_HANDLE As Long = &H80070006, E_FAIL As Long = &H80004005
    Select Case ErrVal
        Case E_OUTOFMEMORY, E_INVALIDARG, E_POINTER, E_HANDLE, E_FAIL
            err.Raise Number:=CdlInitFailure, description:="The PrintDlgEx function failed during initialization."
        Case Else
            err.Raise Number:=ErrVal, description:="Unexpected error."
    End Select
End If

End Function
```

----------


## Krool

> I don't so understand what chosk means exactly, but I did add "Copies","Orientation" and "PaperKind" public property for easier call:


I agree with "Copies" and "Orientation". But there is no such "PaperKind" property in the MS CommonDialog control. (?)

----------


## Jonney

> I agree with "Copies" and "Orientation". But there is no such "PaperKind" property in the MS CommonDialog control. (?)


I added PaperKind Enum. It serves my purpose. .NET has such stuff.

----------


## jpskiller

running app in VB6 environment (design), I have the following code but when click cancel I get a pop up box that says

run-time error '32755"

cancel was selected

end/debug/help

if click on debug it opens commondialog file @
Case 0
            If PropCancelError = True Then err.Raise Number:=CdlCancel, Description:="Cancel was selected."



how do I stop this and just capture the cancel button
-------------------------------------------------------------------------------------
On Error GoTo ErrHandler

 Set CommonDialogShowOpen = New CommonDialog

     With CommonDialogShowOpen

        .CancelError = True
        .Flags = CdlOFNOverwritePrompt
        .Filter = "CSV"
        .DialogTitle = "Open  File"
        .InitDir = App.Path & "\Survey Files"
        .ShowOpen

        If Err.number = CdlErrorConstants.CdlCancel Then Exit Sub

        RepairFile.Text = .FileName

     End With

     .....

 Exit Sub

ErrHandler:

    Exit Sub


I get run-time error '32755"

cancel was selected

end/debug box

----------


## chosk

Move this line:
If Err.number = CdlErrorConstants.CdlCancel Then Exit Sub

to after ErrHandler.

ErrHandler:
If Err.number = CdlErrorConstants.CdlCancel Then Exit Sub

Because when cancel is selected, it is treated as an error (.CancelError) and you have first line "On Error GoTo ErrHandler" to take care of error in ErrHandler.

----------


## chosk

Hi Krool,

I do understand that Printer.Orientation is set automatically but I run into this problem.

The printer default is set to Portrait for normal use.

When printing in this particular project, I select Landscape in the dialog and select 2 copies.  I am using the flag CdlPDUseDevModeCopiesAndCollate from few days ago. The number of copies is no problem, but the 2nd copy seem to lose the Landscape orientation.

Either I am doing something wrong or perhaps I need to set Printer.Orientation inside the For-Next loop that print multiple copies? And if so, then need the .Orientation.



```
170    Dim CommonDialog1 As CommonDialog
180    Set CommonDialog1 = New CommonDialog

190    With CommonDialog1
200       .CancelError = True
210       .Flags = CdlPDReturnDC + CdlPDNoSelection + CdlPDNoPageNums + CdlPDUseDevModeCopiesAndCollate
220       .ShowPrinter
230       DoEvents
          'Printer.Orientation and Printer.Copies already set automatically
240       CopyPicChart Me.picChart
250       For i = 1 To Printer.Copies
260          Printer.PaintPicture Clipboard.GetData(), 0, 0, Printer.ScaleWidth, Printer.ScaleHeight
270          Printer.EndDoc
280       Next i
290   End With
```

----------


## chosk

Hi Jonney,

Was trying out your code with .ShowPrinterEx but running into some errors. I think a bit more code needed for:

PropOrientation
PropPaperKind

Private Prop...... As ...
Let
Get

I'm not sure how to do it. I know Orientation is 1 or 2 (Integer?)

----------


## chosk

I was about to go to bed, it is 2:00am here. Then the solution came so I got back up and fire up my computer. The solution is since Printer.Orientation is automatically set, I use an Integer variable to capture Printer.Orientaion.

Happy now. Good night!



```

...
125    Dim Orientation As Integer
...
...
...
170    Dim CommonDialog1 As CommonDialog
180    Set CommonDialog1 = New CommonDialog

190    With CommonDialog1
200       .CancelError = True
210       .Flags = CdlPDReturnDC + CdlPDNoSelection + CdlPDNoPageNums + CdlPDUseDevModeCopiesAndCollate
220       .ShowPrinter
230       DoEvents
          'Printer.Orientation and Printer.Copies already set automatically
235       Orientation = Printer.Orientation

240       CopyPicChart Me.picChart
250       For i = 1 To Printer.Copies
255          Printer.Orientation = Orientation
260          Printer.PaintPicture Clipboard.GetData(), 0, 0, Printer.ScaleWidth, Printer.ScaleHeight
270          Printer.EndDoc
280       Next i
290   End With
```

----------


## jpskiller

> Move this line:
> If Err.number = CdlErrorConstants.CdlCancel Then Exit Sub
> 
> to after ErrHandler.
> 
> ErrHandler:
> If Err.number = CdlErrorConstants.CdlCancel Then Exit Sub
> 
> Because when cancel is selected, it is treated as an error (.CancelError) and you have first line "On Error GoTo ErrHandler" to take care of error in ErrHandler.


Hi,

I tried that but still does same thing, when click cancel then a visual basic box appears with the information


Seems to only do this during design-run, when create compiled .exe file, then that works fine.

But during design it can be a pain, because it cause VB to crash every time and have to reopen project.

----------


## Krool

> I tried that but still does same thing, when click cancel then a visual basic box appears with the information
> 
> 
> Seems to only do this during design-run, when create compiled .exe file, then that works fine.
> 
> But during design it can be a pain, because it cause VB to crash every time and have to reopen project.


I think it has something todo with the error trapping settings. As you have this problem only in the IDE. Please advise what you have set.

Tools -> Options... -> General -> Error Trapping

----------


## jpskiller

Thank you mine was set to 'Break in class modules' now changed it and works fine

----------


## Krool

> I added PaperKind Enum.


I was thinking to include "Copies" and "Orientiation" property to my CommonDialog class.
But, when so thinking. I should also include, as you did, "PaperKind". And also others such as "ColorMode", "PaperBin" and so on.

And MS CommonDialog does not deal with the VB.Printer object. So when not using "PrinterDefault" or CdlPDReturnDC to use ".hDC" your like lost. At my CommonDialog the VB.Printer is set so you can deal with.

And also the problem of priority. When "Copies" property is not same as "VB.Printer.Copies" upon dialog call, choose what?

So at the end I decided to not include "Copies" and "Orientation" property.

Like chosk did, its easy to save the needed properties into variables after dialog return before actually printing. (multiple copies with orientation landscape for instance)

PS: Very stupid from VB to reset all when Printer.EndDoc is called.

----------


## jpskiller

these controls are great on a side note will you be making a gridcontrol replacement

----------


## Jonney

> PS: Very stupid from VB to reset all when Printer.EndDoc is called.


Nothing complain. User can create a class or something else to hold our setting after "Apply" or "OK" button Pressed.

----------


## Krool

Update released.

----------


## chosk

I just happen to notice this as I am getting the same result when I try to do this. The text of the whole Col3 should be in blue but the first row of Col3 would appear in black when first presented. Then click anywhere in the ListView and the first row Col3 will then become blue.

Edit to add: On closer observation, this might not be the case. Looks like actually the first row is "grey" making the text black. Sort of selected but not focus.

----------


## chosk

I noticed an issue with the ListView in the 23-Nov-2015 version.

The design:
a) I have a popup menu on the right mouse click.
b) The left mouse click only select the row, no popup.

Observation:
a) There is now a lag when I right mouse click. On the first right mouse click, the popup menu may or may not appear. Subsequent right mouse click the popup will appear.
b) After a right mouse click, the immediate next left mouse click will popup menu. It should not.

Resolve:
I use back the 16-Nov-2015 ListView version and all is well. By this I mean I copy only the ListView folder into my project.

----------


## chosk

I just found an issue with the CommonDialog class:




```
280    With CommonDialog1
...
...
400       .Filter = "Workspaces (*.tfw)|*.tfw"
410       .ShowSave
...
...      
470       WorkspacePath = .Filename
480       WorkspaceName = .FileTitle
...
...
```

When I input abc as the filename, both .Filename and .FileTitle do not show the ".tfw" but only abc and save the file as abc without file extension.

Next when I test to save another time as abc again. I get a prompt that abc already exist. This means it also just check for abc, instead of abc.tfw.

Previously with the VB6 ComonDialog, it handles the extension automatically.

----------


## chosk

I add a new line:

.DefaultExt = "tfw"

and it works now.


Edit to add:
The .DefaultExt will make the file to be saved with the file ext (abc.tfw). But when checking for file exist before saving, it is still checking without the file ext (abc).

----------


## Krool

> I noticed an issue with the ListView in the 23-Nov-2015 version.
> 
> The design:
> a) I have a popup menu on the right mouse click.
> b) The left mouse click only select the row, no popup.
> 
> Observation:
> a) There is now a lag when I right mouse click. On the first right mouse click, the popup menu may or may not appear. Subsequent right mouse click the popup will appear.
> b) After a right mouse click, the immediate next left mouse click will popup menu. It should not.
> ...


Update released.

Indeed, this bug happens on the ListView and TreeView control after the update on 21-Nov-2015.

But this has been fixed now. Thanks!

----------


## Cube8

> I add a new line:
> 
> .DefaultExt = "tfw"
> 
> and it works now.
> 
> 
> Edit to add:
> The .DefaultExt will make the file to be saved with the file ext (abc.tfw). But when checking for file exist before saving, it is still checking without the file ext (abc).


This is an issue with the common dialog itself.
I use _GetSaveFileName_ directly and I also sometimes get the file without the extension. I guess in this case we should check the _nFilterIndex_ property of the _OPENFILENAME_ structure and append the appropriate extension or just append the extension if there is only 1 option.

----------


## fafalone

A couple questions on the unusual version of oleguids.tlb that's included...

-IEnumeration is just a renamed IEnumVARIANT... but what is IEnumerationVB? A custom interface? I can't find a match for the CLSID.
-Same question with the others like that; IPerPropertyBrowsing even has nearly identical methods except one in the middle (MapPropertyToPage)-- wouldn't that throw off the vtable?
-If you're going to include placeholder interfaces that aren't valid, would you consider renaming them to __VB as well? IDataObject and IStorage are very frequently used and any project that also uses your controls has to always remember to explicitly type them since VB sometimes thinks a variable refers to the oleguids placeholder. 

I had originally just wanted to eliminate the reference in my project due to the conflicts; but need to understand the renamed and possibly custom interfaces first.

----------


## Krool

> A couple questions on the unusual version of oleguids.tlb that's included...
> 
> -IEnumeration is just a renamed IEnumVARIANT... but what is IEnumerationVB? A custom interface? I can't find a match for the CLSID.
> -Same question with the others like that; IPerPropertyBrowsing even has nearly identical methods except one in the middle (MapPropertyToPage)-- wouldn't that throw off the vtable?
> -If you're going to include placeholder interfaces that aren't valid, would you consider renaming them to __VB as well? IDataObject and IStorage are very frequently used and any project that also uses your controls has to always remember to explicitly type them since VB sometimes thinks a variable refers to the oleguids placeholder. 
> 
> I had originally just wanted to eliminate the reference in my project due to the conflicts; but need to understand the renamed and possibly custom interfaces first.


IEnumeration is equivalent to IEnumVARIANT, but "unrestricted". Thus it can be implemented into objects in VB.
IEnumerationVB is a custom interface, but actually not needed anymore cause its now working with raise events in the Enumeration.cls
But I kept the IEnumerationVB in the OLEGuids.tlb as it does not cause any harm. And it will also not be compiled into when it's not used in the VB project.

For the others: That's why I declared all my references to OLEGuids.tlb with 'OLEGuids.*', e.g. "As OLEGuids.IDataObject"
That is the preferred method to eliminate those conflicts.

----------


## fafalone

Apart from the *VB interfaces everything is also in olelib/oleexp.. Are the other ones used in a way the real ones can't be? Would just be nice to have one less reference and not have to worry about explicit typing (As OLEGuids.whatever).

----------


## Krool

> Apart from the *VB interfaces everything is also in olelib/oleexp.. Are the other ones used in a way the real ones can't be? Would just be nice to have one less reference and not have to worry about explicit typing (As OLEGuids.whatever).


You could use the OCX version. No OLEGuids.tlb needed for it.

----------


## fafalone

I'm trying to get rid of an IDE-only dependency, how do you think I feel about ocx dependencies lol. Your controls don't even replace the common controls ocx's for me, they replace me doing things with CreateWindowEx myself on controls I don't need to customize, because I don't even like those depends  :Smilie: 
I'm just asking for a little information to determine whether it is possible to use the Windows version of all the interfaces.. I'll do all the work myself I just thought you'd be able to answer whether it was possible or not before I spent hours on it to find out 'nope'.

----------


## Krool

> I'm trying to get rid of an IDE-only dependency, how do you think I feel about ocx dependencies lol. Your controls don't even replace the common controls ocx's for me, they replace me doing things with CreateWindowEx myself on controls I don't need to customize, because I don't even like those depends 
> I'm just asking for a little information to determine whether it is possible to use the Windows version of all the interfaces.. I'll do all the work myself I just thought you'd be able to answer whether it was possible or not before I spent hours on it to find out 'nope'.


I don't get what you want. Even the non *VB interfaces are needed in the OLEGuids.tlb in order to work.

What you can do is to build your own .tlb with only the *VB interfaces from OLEGuids.tlb and the other referring to your other ole typlib. Because these are std windows interfaces.

----------


## fafalone

All of the non-*VB interfaces are defined in my primary typelib. I don't want to have conflicts (yes I'm aware I can type to a specific typelib, but that and having the extra depend is what I'm trying to avoid). So I want to know if your controls depend on the customizations made by the *VB interfaces in such a way that modifying the code to simply use the normal interface instead is impossible/would require a ground-up rewrite.

----------


## Krool

> So I want to know if your controls depend on the customizations made by the *VB interfaces in such a way that modifying the code to simply use the normal interface instead is impossible/would require a ground-up rewrite.


No, without rewrite it is not possible to get the controls to work without the *VB interfaces.

You could try to create VB class objects for all *VB interfaces and replace them accordingly.

----------


## selma

Hello everybody,

we are just trying to take advantage of the whole in our Access 2010 database. We need a ListView, which allows Unicode. Sorry, we do not know how we will use the OCX from page 16 correctly.

*EDIT*: We found a way to insert the new ListView Control but Access 2007 & 2010 crashes while adding this control to our form. Any ideas?

We are unfortunately beginner in this regard.

Thank you

----------


## Krool

> we are just trying to take advantage of the whole in our Access 2010 database. We need a ListView, which allows Unicode. Sorry, we do not know how we will use the OCX from page 16 correctly.
> 
> *EDIT*: We found a way to insert the new ListView Control but Access 2007 & 2010 crashes while adding this control to our form. Any ideas?


The OCX is for VB6 only.

----------


## ErpEg2015

i know may be this is repeated or stupid question
i work as developer , company have internal application built in VB6 SP6 , after i found  this MS-Common-Control Replacement i want to change all VB Native Control to its equivalent in this VBCCR12 ... the forms in our project are more than 240 forms and controls i think in thousands so changing control by control is a heavy load and may be will take months , is there any tool or pre-written by any user that can do the right job as i described , i will truly appreciate if some one help me about this ,,, ha ha dont ask me to post my company applicaion source may be i will be fired and even sued if i do that

----------


## Krool

> i know may be this is repeated or stupid question
> i work as developer , company have internal application built in VB6 SP6 , after i found  this MS-Common-Control Replacement i want to change all VB Native Control to its equivalent in this VBCCR12 ... the forms in our project are more than 240 forms and controls i think in thousands so changing control by control is a heavy load and may be will take months , is there any tool or pre-written by any user that can do the right job as i described , i will truly appreciate if some one help me about this ,,, ha ha dont ask me to post my company applicaion source may be i will be fired and even sued if i do that


You could open the .frm files in notepad and do "Replace All". For example "VB.TextBox" to "VBCCR12.TextBoxW" and so on.

----------


## Jonney

I am testing the ListboxW on high DPI 200%. Look like ListBoxW has one issue. But I don't know how to describe.



```
Private Sub UserControl_Resize()
Static InProc As Boolean
If InProc = True Then Exit Sub
If ListBoxHandle = 0 Then Exit Sub
With UserControl
Dim WndRect As RECT
'Krool Original Code
'MoveWindow ListBoxHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
'Changed to：
MoveWindow ListBoxHandle, 0, 0, Extender.Width - 2, Extender.Height - 2, 1
If PropIntegralHeight = True Then
    GetWindowRect ListBoxHandle, WndRect
    InProc = True
    .Size .scaleX((WndRect.right - WndRect.left), vbPixels, vbTwips), .scaleY((WndRect.bottom - WndRect.top), vbPixels, vbTwips)
    InProc = False
End If
End With
End Sub
```

I modified to use Extender size, Works OK but I am not sure the side effect.

Edited: -2 is border thickness for my case (space for shadow).

----------


## Krool

> I am testing the ListboxW on high DPI 200%. Look like ListBoxW has one issue. But I don't know how to describe.
> 
> 
> 
> ```
> Private Sub UserControl_Resize()
> Static InProc As Boolean
> If InProc = True Then Exit Sub
> If ListBoxHandle = 0 Then Exit Sub
> ...


The MoveWindow API is just responsible to fill the ListBox window to the UserControl space. As the MoveWindow API expects pixels I use the UserControl.ScaleWidth/Height property. (ScaleMode of the UserControl is set to pixels).
This has nothing to do with the DPI.

----------


## LaVolpe

> This has nothing to do with the DPI.


The problem is that VB usercontrols do not scale well at 200% DPI. This is because the UC Width,Height property values are not the same as reported by the host; therefore the ScaleWidth,ScaleHeight are incorrect also. If you run your test project in 200% DPI, you should see the issue/problem. This DPI 'bug' occurs when 1440 / DPI <> a whole number, i.e., 1440 / 192 (200%) = 7.5

Edited: Of course DPI virtualization must be disabled or project manifested to be DPI-aware. Otherwise, at 200% DPI, VB will likely run in Virtualized 96 DPI and the problem doesn't exist, but the scaling of the project is rather unprofessional.

----------


## Jonney

With above modification, I tested 100%,125%,150% and 200%, check on or off "XP Style Scale", all work ok.




> but the scaling of the project is rather unprofessional.




```
If PropIntegralHeight = True Then
    GetWindowRect ListBoxHandle, WndRect
    InProc = True
    .Size .scaleX((WndRect.right - WndRect.left), vbPixels, vbTwips), .scaleY((WndRect.bottom - WndRect.top), vbPixels, vbTwips)
    InProc = False
End If
```

If I set PropIntegralHeight  =True, things get complicated. So I always use PropIntegralHeight = False to avoid going into such loop.

Conclusion: Always use MoveWindow/SetWindowPos API and Extender.Width/Height in UserControl_Resize to resolve DPI issue.

----------


## Krool

But Extender.Width could be in twips? (ScaleMode of container)
So maybe just use GetClientRect from UC's hWnd and size according to this. Does that work?

----------


## Jonney

> But Extender.Width could be in twips? (ScaleMode of container)
> So maybe just use GetClientRect from UC's hWnd and size according to this. Does that work?


Both Twips and Pixels mode work OK from what I tested.
Noted: I only took out ListBoxW UserControl then tested it, not the whole CCRP project.




> Tips from Lavolpe:
>     1. if the Extender object does not support the Left,Top properties, you simply cannot use it for positioning.
>     2. If the Extender does support Width,Height then you can use SetWindowPos instead of MoveWindow.
>     3. If the Extender object does not support any of those, you can use GetWindowRect to retrieve dimensions, scale them to DPI if needed, then use MoveWindow,SetWindowPos.

----------


## wqweto

Btw, using Move w/o passing width/height seems to fix the issue in high DPI. Something like this


```
If 1440 \ Screen.TwipsPerPixelX = 1440 / Screen.TwipsPerPixelX Then
    oCtl.Move oCtl.Left, oCtl.Top, newWidth, newHeight
Else
    oCtl.Move oCtl.Left + Screen.TwipsPerPixelX, oCtl.Top, newWidth, newHeight
    oCtl.Move oCtl.Left - Screen.TwipsPerPixelX
End If
```

(code from LaVolpe)

cheers,
</wqw>

----------


## Krool

> Btw, using Move w/o passing width/height seems to fix the issue in high DPI. Something like this
> 
> 
> ```
> If 1440 \ Screen.TwipsPerPixelX = 1440 / Screen.TwipsPerPixelX Then
>     oCtl.Move oCtl.Left, oCtl.Top, newWidth, newHeight
> Else
>     oCtl.Move oCtl.Left + Screen.TwipsPerPixelX, oCtl.Top, newWidth, newHeight
>     oCtl.Move oCtl.Left - Screen.TwipsPerPixelX
> ...


Ok, thats for sizing the UserControl itself. But the issue Jonney raised was with MoveWindow and fitting the ListBox window into the UserControl space. That could be simply solved by GetClientRect instead of ScaleWidth/Height, right?

----------


## Jonney

> Ok, thats for sizing the UserControl itself. But the issue Jonney raised was with MoveWindow and fitting the ListBox window into the UserControl space. That could be simply solved by GetClientRect instead of ScaleWidth/Height, right?


for my case, showing Listbox at certain Position, for example, Textbox + ListboxW = drop down ComboBox showing in Grid Cell with a double click.
After more tests, the simply way is to set the usercontrol (ListBoxW) scale mode from Twips to Pixels. 



> 1. ScaleMode: Twips:
>     MoveWindow ListBoxHandle, 0, 0, Extender.Width , Extender.Height, 1
> 2. ScaleMode: Pixels:
>     MoveWindow ListBoxHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
>     Or: MoveWindow ListBoxHandle, 0, 0, Extender.Width , Extender.Height, 1

----------


## Krool

The UserControl ScaleMode is already set to pixels. I dont get it why Extender.Width/Height should work.

----------


## LaVolpe

With high DPI, specifically non-whole number VB DPI (1440 / DPI), there are 2 separate issues. Internal resizing from the UC and external reszing from the UC's host. For simplicity, we will assume no non-client borders, i.e., no WS_BORDER, etc. And also, for simplicity, we'll say the host & UC are in the same scalemode. One last caveat, the stuff below pertains to VB being the host for the UC. The Extender object's Width,Height properties are not guaranteed to be supported in any non-VB host, i.e., Access, IE, Word, etc.

First. At 200% DPI, VB runs internally at 214% DPI. But if the UC and host sizes were in sync, this wouldn't be an issue. 214% DPI is equivalent to: (1440 / 7)  / 96. At 200% DPI the system's twips per pixel would be 7.5 but VB uses 7. 

Second. UC dimensions are saved as twips by VB within the project files.

*Internally*: ScaleWidth,ScaleHeight cannot be trusted. It can be less than what the host reports. If UC is designed with a width of 200 pixels, 3000 twips, in 96 DPI and shown in 200% DPI, then at 200% DPI, you would expect the host to report the UC as 400 pixels, twice as large at twice the original DPI. But not so. The host still reports the UC as 3000 twips as expected, but the size in pixels would be 3000 / 7 = 428.571. If your UC's scalemode were pixels, you'd expect its ScaleWidth to report 428.571. However, the UC's scalewidth in twips is 2800 and in pixels: 400, 28.571 pixels smaller than the host.The difference in VB and System twips per pixel can be used to show that difference: 3000 * 7 / 7.5 = 2800

For hWnd controls, SetWindowPos,MoveWindow can be used. However, GetClientRect or GetWindowRect is not useful, as is. Why? Well, you are getting pixel size from one API and supplying it to another API, no change in data. The UC, internally, should rescale itself during the resize event. The pixels returned from the API should be first scaled by the Extender property, using vbContainerSize, before sending to MoveWindow,SetWindowPos.

For Windowless controls, the reported size by the UC width,height or scalewidth,scaleheight are not really important. When the UC's Paint event is called, the size reported by the host is passed via the clipping rectangle in the passed hDC. But to know the real size, there are a few ways to get to it, with the Extender property being the easiest.

*Externally*: Simply changing the UC dimensions from the host, does not rescale the UC correctly in all cases. The code posted in #870 can be used without need for APIs, though slight modifications are needed if the UC can be Top/Bottom aligned.

Bottom line. ScaleWidth,ScaleHeight and Width,Height cannot be trusted. They will NOT report the same dimensions as the host in some DPIs

Above being said. Yes, an API window can be sized exactly to the UC scalewidth,scaleheight. However, that scalewidth,scaleheight may not be correctly scaled relative to the actual width/height. What happens is that your control on the form *appears* smaller, when drawn, than it should be when compared to other non-UCs. From a professional point of view: yuck. This can be easily proven and visualized with a simple test.

1. At 96 DPI, start new project. Add a picturebox & set properties: BackColor=Red, Borderless, not-3D
2. Add a new UC to the project and set it's backcolor to white
3. Place an instance of the UC inside the picturebox. Sizing UC doesn't matter right now
4. Add a button and behind the button, add this code:
UserControl1.Move 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight5. Save the project and change your system to 200% DPI
6. Disable DPI virtualization: VB6.exe properties compatibility tab. Check "Disable display scaling on high DPI settings"
7. Run the test project and click the button. You should see the UC did not 'fill up' the picturebox when drawn, though the picturebox & uc sizes are identical from the host's point of view

Tip: You'll know if VB is not running in virtual DPI, at all DPIs other than 96, if the Screen.TwipsPerPixelX returns something other than 15.

Edited: If your O/S doesn't have that compatibility tab option, you may need to disable DPI virtualization by creating an external manifest for vb6.exe saying that VB is DPI-aware.

----------


## Krool

> Btw, using Move w/o passing width/height seems to fix the issue in high DPI. Something like this
> 
> 
> ```
> If 1440 \ Screen.TwipsPerPixelX = 1440 / Screen.TwipsPerPixelX Then
>     oCtl.Move oCtl.Left, oCtl.Top, newWidth, newHeight
> Else
>     oCtl.Move oCtl.Left + Screen.TwipsPerPixelX, oCtl.Top, newWidth, newHeight
>     oCtl.Move oCtl.Left - Screen.TwipsPerPixelX
> ...


You mean the following addition in the UserControl_Resize handler fixes the DPI issue?



```
If 1440 \ Screen.TwipsPerPixelX = 1440 / Screen.TwipsPerPixelX Then
    Extender.Move Extender.Left, Extender.Top
Else
    Extender.Move Extender.Left + Screen.TwipsPerPixelX, Extender.Top
    Extender.Move Extender.Left - Screen.TwipsPerPixelX
End If
```

----------


## LaVolpe

> You mean the following addition in the UserControl_Resize handler fixes the DPI issue?
> 
> 
> 
> ```
> If 1440 \ Screen.TwipsPerPixelX = 1440 / Screen.TwipsPerPixelX Then
>     Extender.Move Extender.Left, Extender.Top
> Else
>     Extender.Move Extender.Left + Screen.TwipsPerPixelX, Extender.Top
> ...


Yes & no.

1. When the IF statement is true, you do not need to make any adjustments

2. Otherwise, the simple answer is yes with one major caveat. The Extender object MUST support .Move, .Left & .Top. VB, as the host, supports them. Other non-VB hosts, maybe not. I'd also suggest adding a flag in the event to address recursion during the double move

3. Though that would 'fix' the DPI issue, it doesn't address resizing your control from within, if needed. Most controls are not self-sizing.

4. If the control has the Alignable property set to true, then the double move should be tweaked if the control is set to be Top or Bottom aligned. The tweak is to adjust the Top property, not the Left property.

Edited: Regarding #4, this would need to be tested, but will adjusting both Top & Left handle the Alignable control regardless what side of the window it is aligned to? i.e.,


```
    Extender.Move Extender.Left + Screen.TwipsPerPixelX, Extender.Top + Screen.TwipsPerPixelY
    Extender.Move Extender.Left - Screen.TwipsPerPixelX, Extender.Top - Screen.TwipsPerPixelY
```

----------


## Krool

> Yes & no.
> 
> 1. When the IF statement is true, you do not need to make any adjustments
> 
> 2. Otherwise, the simple answer is yes with one major caveat. The Extender object MUST support .Move, .Left & .Top. VB, as the host, supports them. Other non-VB hosts, maybe not. I'd also suggest adding a flag in the event to prevent recursion during the double move
> 
> 3. Though that would 'fix' the DPI issue, it doesn't address resizing your control from within, if needed. Most controls are not self-sizing.
> 
> 4. If the control has the Alignable property set to true, then the double move should be tweaked if the control is set to be Top or Bottom aligned. The tweak is to adjust the Top property, not the Left property.


1. Thought that also.

2. should not be an issue as my controls are working in VB6 only anyway.

3. Some of mine are. E.g. ComboBox, Slider, CoolBar. But the internal resizing is based on the actual API window size. I use GetWindowRect and then UserControl.Size (Values passed there must be in Twips, regardless of scale modes). Anything to take care there or change?

4. That would be no problem to respect.

----------


## LaVolpe

#3. Yes.


```
Extender.Move Extender.Left, Extender.Top, _
    ScaleX(newWidth, [ScaleMode], vbContainerSize), _
    ScaleY(newHeight, [ScaleMode], vbContainerSize)
```

[ScaleMode] is the scale that the newWidth,newHeight values are in, be it, twips, pixels, etc.
Again, same caveat as previous reply. Extender.Move must be supported.

Here's one thing that could throw you and would require some testing. I've seen this in a UC I've created, but haven't gone back & finalized my solution. Adding a new control during design-time. The initial size of the Extender object was zero when queried after InitProperties, even though the default size was 128x128. During the resize event, no major issues. Whether 1st loaded or re-loaded from a previous saved project, the resize event is not guaranteed to occur after InitProps/ReadProps. I've seen resize events before and after those props events, but not consistently. Testing should be done,  to find the happy zone of when to resize the Extender object for self-sizing controls, if relying on the Extender.

For DPI awareness, do NOT use the UserControl.Size method.

----------


## LaVolpe

And just a follow-up regarding my last reply, hopefully clarifying for you & me...

Scenario: 1500x1500 twip (100x100 pixel) UC saved to form in 96 DPI and then later run in 192 DPI (200%). No resizing code in the UC, both the form & UC scalemode is twips

The following columns are: event name, UC.Width, UC.Height, Extender.Width, Extender.Height
The Extender values are also equal to the dimensions reported from the Form's perspective.

Existing control: ReadProperties executed. Here are sizes from some of the events, in order of event execution. 
resize1890  1834  1500  1500readprops1890  1834  1500  1500resize1498  1498  1500  1500paint1498  1498  1500  1500
UC added to form by double clicking on it from the toolbox to use default dimensions. InitProperties executed
initprops 1498  1498  0  0resize 1603  1603  1603  1603resize 1498  1498  1603  1603paint 1498  1498  1603  1603
Notes: 
1. The 2nd resize event, both scenarios, did not occur when running at 96 DPI
2. Though I didn't add it in the above, the Show event (prior to Paint) reported same as the Paint event
:: Paint events not received if UC AutoRedraw=True
:: Show event not received (runtime) if UC starts out with Visible=False. If UC not on visible part of the form, event fires if Visible=True
3. When the form closes, a final Resize event may occur

As you can see, you cannot trust the Usercontrol's dimensions reported by the UC. The Extender is far more reliable.

Edited: For me, the InitProps scenario is the most frustrating. The default size of the new UC should've been 1500x1500 twips reported by the Extender object.

----------


## jpskiller

Need little help

Got new laptop, its running Windows 10, up until now have been using Windows 7 with no issues.

I have installed VB6 and my existing app runs fine, but I need to add the Linklabel control, so I have added the files and when I try to add the control to my form I get the following error message : The LinkLabel control requires at least version 6.0 of comctl32.dll to use, you have to define a manifest fie for your application.

How do I fix this please.

----------


## Krool

This is the 1.3 ActiveX Control version. (End of support)

_Removed_

----------


## Krool

Update released. (Discard the update yesterday)

There was an issue with the CoolBar. It can be reproduced with the Demo project.

Compile .exe at 96 DPI setting. Change system to 120 DPI and you will notice the CoolBar is not sized correctly.
Everything will "increase" in size (because of higher DPI) but due to the Childs there can be a scenario which can cause a problem.
The CoolBar will try to queeze the child control into the given borders, but some controls (like the ImageCombo) which have an internal resizing can "reject" the squeeze. The CoolBar will back down and gives the ImageCombo the necessary space and thus the CoolBar resizes but will not notify the parent via RBN_HEIGHTCHANGE. And that's actually the issue. My UserControl is then unaware of this play and does not resize accordingly. (as no RBN_HEIGHTCHANGE notification in this scenario)
As long as IDE and .exe are both in same DPI setting this issue does not pop up. But in case the DPI setting is on one of the side different there is a difference in size and causing the issue.
This was solved by simply calling UserControl_Resize whenever a Child control is set to the CoolBar control.

----------


## jpskiller

I have a small issue, excuse me if it seems stupid 

I have this bit of code :

Private Sub TreeView1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
   Me.TreeView1.SelectedItem = Me.TreeView1.HitTest(X, Y)
End Sub

Private Sub TreeView1_NodeClick(ByVal Node As TvwNode, ByVal Button As Integer)

On Error GoTo MyErrorHandler

   AgentSelected = TreeView1.SelectedItem.Text

etc
end sub

the issue is that when I click in the Treeview1 it executes the NODE_CLICK before Treeview1_MouseDown

I need to execute the mouse down event first or somehow reproduce the same code in treeview1_mousedown at the moment I have to click twice on a item before it updates correctly.

help please

----------


## Krool

> I have a small issue, excuse me if it seems stupid 
> 
> I have this bit of code :
> 
> Private Sub TreeView1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
>    Me.TreeView1.SelectedItem = Me.TreeView1.HitTest(X, Y)
> End Sub
> 
> Private Sub TreeView1_NodeClick(ByVal Node As TvwNode, ByVal Button As Integer)
> ...


Oh.
This is a side effect caused by my update from 21-Nov-2015.
The update was reasonable.
Will look soon for a fix to bring the events in right order.
This bug now affects only ListView and TreeView.

The problem is due to internal DragDetect and thus WM_LBUTTONDOWN hangs.

----------


## Krool

Important update released.

Mouse events now again in correct order in the ImageCombo, TreeView and ListView control.
And there are raised 'After'. How it should be.

Problem was an internal modal message loop on these controls. (DragDetect)
This is also documented by MSDN.

Solution:
Custom message now implemented "UM_BUTTONDOWN".
This is posted (PostMessage API) to the control right before passing WM_LBUTTONDOWN/WM_RBUTTONDOWN to the control.

----------


## Krool

Update released.

Could be important when using the ListView control as the Shift parameter in the ItemActivate event was not properly set. (LVN_ITEMACTIVATE handler)

----------


## fafalone

Just wanted to point out a pretty significant omission given the level of feature-completeness of this project: overlays for treeview and listview. LVIS_OVERLAYMASK/TVIS_OVERLAYMASK, and the ability to add them in the ImageList control. Would be cool to have, but no biggie.

----------


## DEXWERX

This came up in another thread, but is there an example on how to use the Use Chevron Dropdown and ChevronPressed event of your Coolbar Control replacement?

----------


## Krool

> This came up in another thread, but is there an example on how to use the Use Chevron Dropdown and ChevronPressed event of your Coolbar Control replacement?


You have to enable "UseChevron" and define the "IdealWidth" value in a band.
The chevron button is shown if the band is smaller than "IdealWidth". When clicking on the button the event "ChevronPushed" is fired.

----------


## DEXWERX

> You have to enable "UseChevron" and define the "IdealWidth" value in a band.
> The chevron button is shown if the band is smaller than "IdealWidth". When clicking on the button the event "ChevronPushed" is fired.


IdealWidth was what I was missing. Perfect.

----------


## Karl77

Krool, do you plan to do something on the transparency effect of the toolbar buttons?
I mean the black background issue.

----------


## Krool

> Krool, do you plan to do something on the transparency effect of the toolbar buttons?
> I mean the black background issue.


I don't know how to achive for non-icon picture and w/o mask color...
You use png files in the ImageList?

----------


## DEXWERX

> I don't know how to achive for non-icon picture and w/o mask color...
> You use png files in the ImageList?


Yeah, that might require GDI+. possibly a can of worms for you to add it to your project, unless you want to do it Via the flatapi.

----------


## Karl77

> I don't know how to achive for non-icon picture and w/o mask color...
> You use png files in the ImageList?


Yes, PNG with alpha.
Tried ICO+alpha instead today.
Last idea for tomorrow is BMP32.
I'll report then.

It would be very good to get it working with your toolbar.
Because it is the only one I know of which doesn't draw a border around himself.
And has the ability to set a determined bg color.

BTW, the PNGs came into the imagelist via GDI+.

----------


## Karl77

> Yeah, that might require GDI+. possibly a can of worms for you to add it to your project, unless you want to do it Via the flatapi.


Flatapi?

----------


## Bobbles

> Flatapi?


I was wondering if someone would raise that

----------


## Tanner_H

GDI+ Flat API on MSDN

----------


## Karl77

> Last idea for tomorrow is BMP32.
> I'll report then.


No luck with BMP32.

The CC5 toolbar accepts the transparency.
The Krool toolbar should do it the same way, as it is the same control.

But another wrapper.
And my assumption is that all is ok with the Krool toolbar.
But the transparency information gets lost when the image data is handed over.

I *think* that this could be the only problem.
Just an idea.

https://www.freebasic-portal.de/tuto...icons-111.html

----------


## DEXWERX

Slightly unrelated, but something possibly omitted (but is in the link you posted) Are you going to add TBSTYLE_TRANSPARENT to the toolbar?

regards,

----------


## Krool

> No luck with BMP32.
> 
> The CC5 toolbar accepts the transparency.
> The Krool toolbar should do it the same way, as it is the same control.
> 
> But another wrapper.
> And my assumption is that all is ok with the Krool toolbar.
> But the transparency information gets lost when the image data is handed over.
> 
> ...


My assumption is that it lies on my ImageList control and the transparency gets lost by the PropertyBag. Did you try with an pure API ImageList and set manually to the ToolBar?

----------


## Karl77

> My assumption is that it lies on my ImageList control and the transparency gets lost by the PropertyBag. Did you try with an pure API ImageList and set manually to the ToolBar?


No, I didn't use your imagelist.
I used the one CC5 provides.
As this one works with the CC5 toolbar, I think we can exclude this as a cause.

What can I do to help to track down the issue?

----------


## Karl77

Krool,

VERY GOOD NEWS.

The transparency on the toolbar buttons works.
I must have done several things wrong before, but I don't really know what...

I re-downloaded your project.
Trew out some controls I don't intend to use, and the main form as well.

So I had the Pager form left.
Placed a new Krool-imagelist.
Recreated the icons as BMP32.
Filled the imagelist in the IDE.
BANG! Works.

See:


I apologize for the whole trouble I made.

Karl

----------


## DEXWERX

That looks great. (not being sarcastic because of the ugly green, but it's great that transparency works)
Now the question remains, can we get the Toolbar itself transparent (Design time Property of the toolbar / TBSTYLE_TRANSPARENT )

----------


## Krool

> Now the question remains, can we get the Toolbar itself transparent (Design time Property of the toolbar / TBSTYLE_TRANSPARENT )


I have noted this point in my ToDo list.

----------


## DEXWERX

> I have noted this point in my ToDo list.


You've single handedly surpassed the original CC Replacement project... It may be a can of worms, but donations for this project should also be on your todo.  :Smilie: 

Thanks for keeping VB alive. Regards.

----------


## Krool

I have now implemented TBSTYLE_TRANSPARENT. This was useful to have the BackColor property shown/visible at design-time.

I will also include soon a "Transparent" property. This makes a background as a replica of the underlying background. (simulated transparency)

----------


## Karl77

> donations for this project should also be on your todo.


I second that.

Small other remark: PNG works now as well.
I'll prepare an example next week.

Great work Krool!

----------


## Karl77

So here is the example for the toolbar using PNGs.
There is still a lot to do, but up to now it works quite well.
The graphics itself are for testing only, I know they have to be fine-tuned for the different sizes.

----------


## jpskiller

RichTextBox Help

I know that this auto detects URLS but so far I cant find a way to actual open the url with default app ie Browser / Email etc.

I have tried a couple of suggestions from around but there based on original and dont seem to work.

I presume since it auto detects i must be relatively simple to run it!


** I have also noticed if I use the RichTextbox on a MDI form and set as child, when close the form it crashes the app, when normal form it is OK

Help appreiated

----------


## Karl77

Busy Slider 

Krool, I have found a small issue in the slider.
It fires the scroll event 2 times when clicked.
The 'original' control doesn't show this beahvior.

To retrace:
Place a Slider1 on a form (range 1 to 4).
Place a label "lbl_1" (caption "0").
In Slider1_Scroll, lbl_1.Caption = CStr(CInt(lbl_1.Caption) + 1)

Scroll by mousewheel and see how the label increases by 1 on every scroll  action.
But click the slider and see how the label increases by 2.

Karl

----------


## Krool

> RichTextBox Help
> ** I have also noticed if I use the RichTextbox on a MDI form and set as child, when close the form it crashes the app, when normal form it is OK
> 
> Help appreiated


Does it also happen with the OCX version?

On UserControl Version did you include the VisualStyles.bas and init it on Sub_Main?

----------


## jpskiller

> Does it also happen with the OCX version?
> 
> On UserControl Version did you include the VisualStyles.bas and init it on Sub_Main?


I dont use the OCX version

Yes included VisualStyles and have done the Init from submain

----------


## jpskiller

I ment to say I have called this manually from my form_load on MDI form 'Call InitVisualStyles'

my MDI form is call frmMain and if use the Startup.bas code I get Ambiguous name detect : Main

*** just remeber I have a main in a different module so have added it there **

Still same issue

----------


## Krool

> I ment to say I have called this manually from my form_load on MDI form 'Call InitVisualStyles'
> 
> my MDI form is call frmMain and if use the Startup.bas code I get Ambiguous name detect : Main
> 
> *** just remeber I have a main in a different module so have added it there **
> 
> Still same issue


Can you try to use the OCX version? Just for debug.
And can you share a demo which shows the crash?

----------


## jpskiller

Heres a very basic program

MDi startup, opens form with richtextbox, when close form crash out

If change sub form to not MDI child then can close with no issues

Sorry not done OCX demo as I cant use it I have to have no dependencies and dont' know how to set it up with OCX

----------


## Krool

> Heres a very basic program
> 
> MDi startup, opens form with richtextbox, when close form crash out
> 
> If change sub form to not MDI child then can close with no issues
> 
> Sorry not done OCX demo as I cant use it I have to have no dependencies and dont' know how to set it up with OCX


I have no crash. What OS do you use?
In your demo now the VisualStyles.bas was not included.

----------


## Krool

> Busy Slider 
> 
> Krool, I have found a small issue in the slider.
> It fires the scroll event 2 times when clicked.
> The 'original' control doesn't show this beahvior.
> 
> To retrace:
> Place a Slider1 on a form (range 1 to 4).
> Place a label "lbl_1" (caption "0").
> ...


Done. Thanks

----------


## jpskiller

I use windows 10, and the VisualStyles.bas is showing up under Modules on the demo, I did add it!

----------


## Karl77

(Busy slider)




> Done. Thanks


Slight issue left:
If you click the control the only one scroll event is produced now - good.
But when you scroll by mousewheel, there is NO scroll event now...

(I only exchanged the Builds\Slider folder, as I found no other differences to the former release. Anything more to do?)

----------


## Krool

> Slight issue left:
> If you click the control the only one scroll event is produced now - good.
> But when you scroll by mousewheel, there is NO scroll event now...


Update released.
Now it should work as expected.

----------


## jpskiller

> RichTextBox Help
> 
> I know that this auto detects URLS but so far I cant find a way to actual open the url with default app ie Browser / Email etc.
> 
> I have tried a couple of suggestions from around but there based on original and dont seem to work.
> 
> I presume since it auto detects i must be relatively simple to run it!


I can live with mine crashing (cant explain why) I just use normal form nstead of Child MDI, but does anyone have any idea on how to do this part with this RichTextBox Control, cheers

----------


## jpskiller

I have re uploaded the test file I made and added all the files used for the demo in the root folder and reference them from there, still have same issue if use a MDI child form with a richtextbox, if close that form or the MDI form it just crashes out

OS:Windows 10

----------


## Karl77

> I have re uploaded the test file I made and added all the files used for the demo in the root folder and reference them from there, still have same issue if use a MDI child form with a richtextbox, if close that form or the MDI form it just crashes out
> 
> OS:Windows 10


It doesn't crash in here.
Not in the IDE, not as EXE.

----------


## Karl77

Pager question

Krool, 

the pager has an area for the buddy.
If the buddy is larger than the pager, the pager shows scroll buttons.

But if the pager is larger than the buddy, we can see the pager area.
This area has a fixed color.



I need another color for it.
Do you know of a way to 'inject' it somehow?

I looked through the pager docs, and it looks like there is no direct way.

Do have a hint or idea?

Karl

(BTW, Slider works ok now.)

----------


## jpskiller

> It doesn't crash in here.
> Not in the IDE, not as EXE.


I have no idea why but does on my laptop, I will try it on another system

----------


## Karl77

Statusbar Alignment

Set the Windows size dialog to this:


I know it is mean to set this value, but other work as well to show the effect (except 125, 150%).

On a new form, place the Krool StatusBar control.
Set alignment to bottom.
No code needed in the form.
Start the form.

See this:


Now I tested with the CC5 statusbar.
Same picture.
Perhaps the replacement statusbar should be better?



(Pager question)




> Do have a hint or idea?


If you have a good idea, then that would be nice.
For now the workaround is a picturebox to cover the area with the unwanted color.

----------


## Krool

> (Pager question)
> If you have a good idea, then that would be nice.
> For now the workaround is a picturebox to cover the area with the unwanted color.


I traced the problem. If an buddy control is in place the pager control takes the background color of the buddy.
For instance when using the ToolBar control. The child window which the pager control sets is the hWnd of the UserControl and not the ToolBar API window.
And my ToolBar control does not set the BackColor of the UserControl at run-time. Which could be changed of course to solve the issue for the ToolBar.

On which buddy control do you face the issue? ToolBar? Any other?

----------


## Karl77

> I traced the problem. If an buddy control is in place the pager control takes the background color of the buddy.
> For instance when using the ToolBar control. The child window which the pager control sets is the hWnd of the UserControl and not the ToolBar API window.
> And my ToolBar control does not set the BackColor of the UserControl at run-time. Which could be changed of course to solve the issue for the ToolBar.
> 
> On which buddy control do you face the issue? ToolBar? Any other?


Yes, I do use it for the awesome toolbars.
I didn't try it with other controls yet.

If you could make the pager working with the toolbars (regarding the color), that would be great.
Thank you.

----------


## Krool

> Yes, I do use it for the awesome toolbars.
> I didn't try it with other controls yet.
> 
> If you could make the pager working with the toolbars (regarding the color), that would be great.
> Thank you.


Done

----------


## Karl77

> Done


Great, works as expected.
Thank you for that.

----------


## jpskiller

Well guys, tested the MDI compiled app on different PC and as you said it works fine, but on this laptop in the IDE and compiled it still crashes out bizarre, but getting back to my original problem is there a way to respond to clinks on the links that are highlighted to open web page / email etc.

----------


## Krool

Double post...
I have moved the content of this post to the double post.

----------


## Krool

> Well guys, tested the MDI compiled app on different PC and as you said it works fine, but on this laptop in the IDE and compiled it still crashes out bizarre, but getting back to my original problem is there a way to respond to clinks on the links that are highlighted to open web page / email etc.


You need to handle the 'LinkEvent' event in the RichTextBox control.



```
Private Sub RichTextBox1_LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)

End Sub
```

Watch there for a WM_LBUTTONDOWN message for instance and then open your web page / email. (manually by your own code)

The params LinkStart and LinkEnd helps to trace the actual link that was clicked.




> Statusbar Alignment
> 
> Set the Windows size dialog to this:
> 
> 
> I know it is mean to set this value, but other work as well to show the effect (except 125, 150%).
> 
> On a new form, place the Krool StatusBar control.
> Set alignment to bottom.
> ...


Indeed by an DPI of 113% the ScaleWidth and ScaleHeight values are bugged in VB6.
This whole DPI story is still an open issue. (with exotic DPI values or very large, e.g. 200%)

----------


## jpskiller

cheers that's great

I have tried this as a presumed link end was the length of the string!

Private Const WM_LBUTTONDOWN As Long = &H201

Private Sub RichTextBox1_LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)
Dim txt As String

  txt = Mid$(RichTextBox1.Text, LinkStart, LinkEnd)

  Select Case wMsg
    Case WM_LBUTTONDOWN

   '   ShellExecute Me.hwnd, "Open", txt, vbNullString, "C:\", SW_SHOWNORMAL
  End Select
End Sub

It does capture where the link clicked start is but linkend can be any thing from 5 - 20 extra chars, so I guess thats not how you use it, help appreciated

you guys are great and I do love this project

----------


## Krool

> I have tried this as a presumed link end was the length of the string!
> 
> Private Const WM_LBUTTONDOWN As Long = &H201
> 
> Private Sub RichTextBox1_LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)
> Dim txt As String
> 
>   txt = Mid$(RichTextBox1.Text, LinkStart, LinkEnd)
> 
> ...


There is an error in your code, in the Mid$ function.

It should be like following:


```
txt = Mid$(RichTextBox1.Text, LinkStart + 1, LinkEnd - LinkStart)
```

----------


## jpskiller

> There is an error in your code, in the Mid$ function.
> 
> It should be like following:
> 
> 
> ```
> txt = Mid$(RichTextBox1.Text, LinkStart + 1, LinkEnd - LinkStart)
> ```



Thanks I have corrected my code to match and moved it into Case WM_LBUTTONDOWN, but still have an issue,could this be my laptop again

I have a link http://www.google.co.uk - this is highlighted in the rt box, but the above mid$ returns http://www.google.co
I have another link which is over 30 chars, that is returned with only the last 2 chars missing

And even stranger the shell command does not appear to run, and I am using the same shell command in other places and works fine even if the links incorrect!

Appreciate the help being provided

----------


## fafalone

The Mid() calculation is off... consider:
1234567890 ..say your link is 345. LinkStart=Instr(345)=3. LinkEnd=5. 
Mid(text, 3+1, 2) would only return 45

I'd also look at the routines providing the LinkStart/LinkEnd values too.

----------


## Krool

> The Mid() calculation is off... consider:
> 1234567890 ..say your link is 345. LinkStart=Instr(345)=3. LinkEnd=5. 
> Mid(text, 3+1, 2) would only return 45
> 
> I'd also look at the routines providing the LinkStart/LinkEnd values too.


LinkStart is beginning with zero. So you have to add + 1.

That the length can be incorrect lies maybe on the fact that LinkEnd is pointing to the actual URL and not the displayed text.

But using .Text and not .TextRTF is correct. But .Text is not showing the actual URL. Only the displayed Text. So LinkEnd can be tricky then.

LinkStart seems to be correct when adding + 1.

@ jpskiller
Please check the TextRTF and look if there is a hidden part of the URL which might fit into the length.

----------


## kulasart

Is it possible to attach somehow this controls to Excel file and use them in it as a replacement to standard MS Office Userform controls?

----------


## jpskiller

not quite sure what you mean by look at .textRTF that just seems to return all the formatting i.e 

"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang2057\deflangfe2057{\fonttbl{\f0\fswiss\fprq2\fchars  et0 Calibri;}}
{\colortbl ;\red0\green0\blue255;\red255\green153\blue0;\red255\green204\blue0;\red255\green0\blue0;}
{\*\listtable 
{\list\listhybri?"

----------


## Krool

@ jpskiller,
try the following code to extract the text:



```
txt = Mid$(RichTextBox1.Text, LinkStart + RichTextBox1.GetLineCount, LinkEnd - LinkStart)
```

or



```
txt = Mid$(Replace$(RichTextBox1.Text, vbLf, vbNullString), LinkStart + 1, LinkEnd - LinkStart)
```

Both worked in my testings.

@ kulasart,
It's not possible. This is VB6 only.

----------


## Krool

> ScaleWidth,ScaleHeight cannot be trusted. It can be less than what the host reports. If UC is designed with a width of 200 pixels, 3000 twips, in 96 DPI and shown in 200% DPI, then at 200% DPI, you would expect the host to report the UC as 400 pixels, twice as large at twice the original DPI. But not so. The host still reports the UC as 3000 twips as expected, but the size in pixels would be 3000 / 7 = 428.571. If your UC's scalemode were pixels, you'd expect its ScaleWidth to report 428.571. However, the UC's scalewidth in twips is 2800 and in pixels: 400, 28.571 pixels smaller than the host.The difference in VB and System twips per pixel can be used to show that difference: 3000 * 7 / 7.5 = 2800


I just want to reassure something concerning this. Because I am preparing the DPI aware fixes for this project.

Can it be that ScaleWidth,ScaleHeight can be correctly?

Because for example in my StatusBar control.
I need to make some of the tweaks there so the control is sized correctly. (use of Extender.Move instead of UserControl.Size and the use of Extender.Move in the UserControl_Resize event)
But in my CommandButtonW control it seems that there is no change actually necessary. There is only MoveWindow with ScaleWidth,ScaleHeight in the UserControl_Resize event and it looks that the ScaleWidth,ScaleHeight are correctly.

The other differences are only that the StatusBar does some internal resizing and is alignable.

Can it be?

Thank you

----------


## LaVolpe

Remember that this issue arises only when the DPI that VB is using is not the same as the operating system is reporting.  Using 200% DPI for example, the system will report 192 DPI (96 * 200%). At 192 DPI, twips per pixel will be 7.5 (1440/192). However, VB reports 7 twips per pixel which indicates a different internal DPI: 1440 / 7 = 205.7143 DPI or 214.29%. The following calculation will determine whether DPIs are different:


```
If 1440! \ Screen.TwipsPerPixelX < 1440! / Screen.TwipsPerPixelX Then ' non-system DPI in use
```

You can get ScaleWidth,ScaleHeight to sync up with the size the host is reporting by resizing from within the control via its Extender object. You may have to resize via the Extender each time the control is resized, i.e., when control is first loaded, whenever user resizes it from the host, and whenever you resize it from within the control, like AutoSizing.

----------


## jpskiller

thanks that's great much appreciated

txt = Mid$(Replace$(RichTextBox1.Text, vbLf, vbNullString), LinkStart + 1, LinkEnd - LinkStart) - this works fine, the other seemed to give other text from page

maybe for future development have option to return the link clicked on or even just auto open it depending if option ON/OFF, and include other types ie. auto detect email address

----------


## Krool

Important update released.

All controls are now "DPI Aware". (concerns exotic DPI or very large DPI, e.g. 113% and 200%)

I did extensive testings. However, please report if you do encounter an issue.

OCX versions will follow soon with this update.

----------


## Karl77

Krool, you are really a "Hyperactive Member".

I know I'm annoying... but:
I tested some different settings and found issues, marked with !.
All tests ran under Win10/64.

Here are the numbers:

100
101
105
110
113
115
! *120*
125
130
135
! *140*
! 141
! 145
! 146
! 147
! 149
150
! 151
! *160*
! 165
! *170*
200
250

Megafail, Windows itself fails, is not able to show an Explorer window
! 149
! 170 

Most of the settings will be uncommon, except 120, 140, 160 and alike.

Karl.

----------


## Karl77

CommandButtonW

Q1:



```
cmd_Test.Picture = imgl.ListImages(1).ExtractIcon
cmd_Test.Caption = "This is a test button"
```

Vista:


XP:


This works well under Vista+, but under XP the caption is not there.
The caption is only there if I assign an imagelist to the button - not very wanted.
Seems like a small glitch to me.

Q2:



```
cmd_Test.ToolTipText = "This is the button's tooltip" & vbLf & "cmd_Test"
```

For the toolbar buttons, the vbLF produces a nice multiline tooltip.
Not so for other controls like the CommandButtonW.
While I can easily live with it, perhaps it is not a big deal to get this working?

----------


## Krool

> CommandButtonW
> 
> Q1:
> 
> 
> 
> ```
> cmd_Test.Picture = imgl.ListImages(1).ExtractIcon
> cmd_Test.Caption = "This is a test button"
> ...


This is not a glitch with the CommandButtonW. The PictureAndCaption property is only supported on comctl32.dll version 6.1 or higher. (means Vista+)

For the ToolTip. That's normal. As for the ToolBar there is a API tooltip included by the control itself. (Button class collection)
And the CommandButtonW uses the intrinsic VB UserControl ToolTip function. And this is not multiline.
Solution: Let it empty and use a ToolTip class object for the CommandButtonW. (there are plenty of such class objects available on the net)

----------


## Karl77

> This is not a glitch with the CommandButtonW. The PictureAndCaption property is only supported on comctl32.dll version 6.1 or higher. (means Vista+)


Ok, I see.
But then, why does it work with an assigned imagelist?
I don't get it.

*EDIT:*
I can fill an imagelist on the fly and assign it to the button.
Then XP compatibility is done.

Q:
Can I create a Krool imaglist by code only?
Dim IL as new Projectname.imagelist doesn't work.





> For the ToolTip. That's normal. As for the ToolBar there is a API tooltip included by the control itself. (Button class collection)
> And the CommandButtonW uses the intrinsic VB UserControl ToolTip function. And this is not multiline.
> Solution: Let it empty and use a ToolTip class object for the CommandButtonW. (there are plenty of such class objects available on the net)


Also understood.
I thought it could be just an oversight.

Thank you for the explanation.

----------


## Krool

Important update released for vertical ToolBar control. (Align property set to vbAlignLeft or vbAlignRight)

The Vertical ToolBar behaves now like the original MS control when the Wrappable property is set to False.
Also changing from horizontal to vertical and vice versa after initialization works now properly.




> Can I create a Krool imaglist by code only?
> Dim IL as new Projectname.imagelist doesn't work.


No, you can't.
But what is the problem to place a ImageList control onto the Form? The CommandButtonW must be anyway placed on a Form.
So the ImageList can be just next to it.

----------


## Karl77

> But what is the problem to place a ImageList control onto the Form? The CommandButtonW must be anyway placed on a Form.
> So the ImageList can be just next to it.


No problem at all, I just want to place as less controls a possible on a form.
The extra imagelist is not the only one...

I think I have found an elegant solution for this "non-problem".

----------


## Krool

ActiveX Control versions (OCX) are now up to date with the bugfixes. (especially the "DPI Aware" modifications)

----------


## Regor Tejmar

Hi,
I am new to this thread and I was wondering if there is a 64 bit version of the OCX file that could be used with 64 bit office apps.

----------


## Krool

> Hi,
> I am new to this thread and I was wondering if there is a 64 bit version of the OCX file that could be used with 64 bit office apps.


Only VB6 IDE supported and 32-bit only.

----------


## Karl77

(DPI aware)




> I tested some different settings and found issues, marked with !.


Krool, could you find something regarding this?

----------


## Krool

> (DPI aware)
> 
> I tested some different settings and found issues, marked with !.
> 
> Krool, could you find something regarding this?


Oh, I did not notice your post. Will look soon.

----------


## Krool

> I tested some different settings and found issues, marked with !.
> All tests ran under Win10/64.
> 
> Here are the numbers:
> 
> 100
> 101
> 105
> 110
> ...


Indeed it is not yet working on the marked % numbers. But because the function to identify this fails on those cases.




> The following calculation will determine whether DPIs are different:
> 
> 
> ```
> If 1440! \ Screen.TwipsPerPixelX < 1440! / Screen.TwipsPerPixelX Then ' non-system DPI in use
> ```


If I remove the 'If' and use always the tweaks than the above marked % numbers will work proberly.

How can it be?

----------


## Magic Ink

I'm not a UserControl person but use the following which converts between the scales used in standard user controls and those used by vb, it's working pretty well.
Assumes Screen.TwipsPerPixelX and Screen.TwipsPerPixelY will be equal.
Maybe it'll give you some ideas...


```
Public Function DpiCorrectionFact() As Single
    
    'Useful to Size OCX Controls (eg. SSTab etc.) and to size other controls relative to them
    ' returns ratio between vb6 TwipsPerPixel/ Windows TwipsPerPixel; a number >0 <=1
    'Returns exactly 1 at the dpi 'sweet spots' of 96, 120, 144, 160, 180, 240 dpi etc
    ' when no corrections are required.
    DpiCorrectionFact = Screen.TwipsPerPixelX / (96 / GetWindowsDPI(0) * 15)
                
End Function
```

----------


## Karl77

I do it similar.



```
DPI = GetSettingLong(HKEY_CURRENT_USER, "Control Panel\Desktop\WindowMetrics", "AppliedDPI")
AppState.DPI_Registry = DPI

AppState.TwipsPerPixelExact = 1440 / DPI


Select Case DPI

    Case 0: DPIFaktor = 1 'not found
    Case 96: DPIFaktor = 1 '100%
    Case 120: DPIFaktor = 1.25 '125%
    Case 144: DPIFaktor = 1.5 '150%
    Case Else 'e.g. 103 at 107%
        DPIFaktor = ((100 / 96) * DPI) / 100

End Select


AppState.DPI_Percent = DPIFaktor
AppState.DPI_ScaleFactor = 1440 / Screen.TwipsPerPixelX / 96
AppState.DPI_StrangeFactor = AppState.TwipsPerPixelExact / Screen.TwipsPerPixelX
```

The key is the DPI_StrangeFactor, which is 1 at 96 dpi.

Karl

----------


## Krool

Update released.

The issue with the not always working calculation that determine if DPIs are different is now solved.

----------


## Karl77

> Update released.
> 
> The issue with the not always working calculation that determine if DPIs are different is now solved.


Yes, that works fine now.
Hero!

Karl

----------


## DEXWERX

Nit Picking the code base, but your IDispatch.GetIDsOfNames has the wrong definition?



```
	[
		uuid(00020400-0000-0000-C000-000000000046),
		odl
	]
	interface IDispatch : IUnknown
	{
		typedef IDispatch *LPDISPATCH;
		HRESULT GetTypeInfoCount([out] LONG *pctInfo);
    		HRESULT GetTypeInfo([in] LONG itinfo, [in] LONG lcid, [out] LONG *pptinfo);
    		HRESULT GetIDsOfNames([in] REFIID riid, [in] LPSTR *rgszNames, [in] LONG cNames, [in] LONG lcid, [in, out] LONG *rgDispID);
    		HRESULT Invoke([in] LONG DispIDMember, [in] REFIID riid, [in] LONG lcid, [in] SHORT wFlags, [in] DISPPARAMS *pdispparams, [in, out] VARIANT *pvarResult, [out] EXCEPINFO *pexcepinfo, [out] LONG *puArgErr);
	};
```

It should be LPWSTR, so you can pass in a BSTR. This way VB skips the Conversion, and you can skip the DoubleUnicode hack you did here.



```
Public Function GetDispID(ByVal This As Object, ByRef MethodName As String) As Long
Dim IDispatch As OLEGuids.IDispatch
Dim IID_NULL As OLEGuids.OLECLSID
Set IDispatch = This
IDispatch.GetIDsOfNames IID_NULL, StrConv(MethodName, vbUnicode), 1, 0, GetDispID
'IDispatch.GetIDsOfNames IID_NULL, MethodName, 1, 0, GetDispID
End Function
```

P.S. I definitely appreciate the quality of your code. Regards.

----------


## DEXWERX

per our conv. A workaround might be to rename the Typelib, and change it's guid, so new projects use the updated Typelib. Otherwise it may not be worth changing. Thanks for the support.

----------


## ishalom

what is the pager control?

----------


## Karl77

> what is the pager control?


A scrollable container.
Try the pager demo, see at the start of the thread.

----------


## pepegriyo

Hello, The RichTextBox Control have a error when is set visible=false.
RichTextBox.Visible=False
The error ocurred when close the execuble.

----------


## pepegriyo

Try this in Wine. Is more evident in it

----------


## Krool

> Hello, The RichTextBox Control have a error when is set visible=false.
> RichTextBox.Visible=False
> The error ocurred when close the execuble.


Did you call the InitVisualStyles method (from VisualStyles.bas) on startup in your executable?

If this doesn't help please provide a demo showing the error as else I cannot reproduce it.

----------


## jpskiller

I know this is dumb question but I have never used color picker dialog box and would like to know how to reference it so can call to be used to change form background etc.

----------


## jpskiller

> I know this is dumb question but I have never used color picker dialog box and would like to know how to reference it so can call to be used to change form background etc.


Said it was dumb, sorted it now

----------


## pepegriyo

> Did you call the InitVisualStyles method (from VisualStyles.bas) on startup in your executable?
> 
> If this doesn't help please provide a demo showing the error as else I cannot reproduce it.


Attach a Demo is not working RichTextbox

----------


## pepegriyo

> Attachment 137335
> 
> Attach a Demo is not working RichTextbox


I Attach Demo2, with completed code.

----------


## FunkyDexter

I've removed your attachments because they contained compiled executables.  We do ask that you don't include any compiled components in attachments.  It's source code only I'm afraid.

Please feel free to re-attach them but with the executables removed.

----------


## pepegriyo

> I re Attach Demo2, with completed code.


testRichtext2.zip

----------


## Krool

Update released.

Meaningful when using the DTPicker control.
The Change event was only raised when changing the value by the user.
This behavior is the same in the original MS DTPicker control.
But that behavior makes actually no sense and might be even a bug in the original MS DTPicker control.
On all the other controls the Click/Change (or whatever) events are also raised when changing by code.
So such a behavior is expected and that's why this fix was necessary in my opinion.

----------


## Krool

Update released.

Again concerning the DTPicker control.
Now it is possible to detect when the checkbox state has changed.
Regardless if it was changed by user or by code.

----------


## pepegriyo

> Update released.
> 
> Again concerning the DTPicker control.
> Now it is possible to detect when the checkbox state has changed.
> Regardless if it was changed by user or by code.


Could you check my attach?

----------


## chosk

Something has affected the DTPicker control.

My program uses 12 DTPickers.

4 need to check against one another, eg.
dtpLastDate.Value >= dtpStartDate.Value
dtpStartDate.Value <= dtpLastDate.Value
dtpStartDate.Value >= dtpCurrentDate.Value
dtpLastUpDate.Value <= dtpStartDate.Value


The other 8 are for changing the date to change the ListView info to display.
All 12 DTPicker uses only the Change event. The Click event are not used.

The program boots up in 2 seconds. Now with the new DTPPickers, the program boots up in 17 seconds.

My observation:
When I added these DTPickers into the project on 11-Feb-2014, naturally the Properties automatically show the Value as 11-Feb-2014 and I never need to change that, also I do not need to set any initial default value in the Form_Load. With the 5-May-2016 DTPicker, when the Value is "Change" in codes, something fire that cause errors to show up. This is not the main problem as can be fixed by setting default "Now" values in Form_Load.

The main problem is the extra 15 seconds for the software to boot.

Just notice another problem:
When I click 1 of the 8 DTPicker, the ListView display used to change in less than 2 seconds. Clicking on 1 of the 8 DTPickers synchronizes all 8. Now it take about 13 seconds to change the display.

----------


## Krool

@ chosk,

That is due to the fact that the change event is now fired when value was changed by code.
You can solve it by placing a "Freeze" variable on your form that is active when synchronizing all 8 DTPickers. At the end reset the variable and update listview. In each DTPicker change event should be a exit sub when the "Freeze" variable is active.

I know that I broke "compatibility". But it was stupid to have not Change event fired when value was changed by code.

----------


## chosk

> Update released.
> 
> Meaningful when using the DTPicker control.
> *The Change event was only raised when changing the value by the user.*
> This behavior is the same in the original MS DTPicker control.
> But that behavior makes actually no sense and might be even a bug in the original MS DTPicker control.
> On all the other controls the Click/Change (or whatever) events are also raised when changing by code.
> So such a behavior is expected and that's why this fix was necessary in my opinion.


I played around with an empty project with just the DTPicker and MsgBox in the Click and Change event handlers. I may have missed the gist of the change.

*The Change event was only raised when changing the value by the user.*

I now understand this to be when user *manually* click on the DTPicker and change the date.

----------


## Krool

> Hello, The RichTextBox Control have a error when is set visible=false.
> RichTextBox.Visible=False
> The error ocurred when close the execuble.


I know now the reason for this. I look for a solution..

In the meantime you can do the following as workaround to solve this:


```
Private Sub Form_Unload(Cancel As Integer)
RichTextBox1.IDEStop
End Sub
```

In the Form that contains the invisible RichTextBox call the hidden "IDEStop" method.
Now the application will close without any error.

----------


## Krool

Update released.

I have included the ExpandedImage property of a Node in the TreeView control to be more compatible to the original MS control.

----------


## Krool

Update released.

The first upload of the update today had a bug. I just re-uploaded the update of today.
I saw that 3 users downloaded the first upload..
Please re-download. Sorry..

----------


## Krool

Update released.

Might be important for those who use the TreeView control.
It is now possible to pass a Node object in the Relative parameter in Nodes.Add and Node.Move.
This is of course possible in the original MS control. This bug should have been detected already..
Anyway, now it's done.

----------


## Krool

Update released.

Again important for those who use the TreeView control.
It is now ensured that BeforeCollapse/BeforeExpand and Collapse/Expand events are always fired when Expanded property of a Node is being changed.
Prior to this update this was only once fired. (because of TVIS_EXPANDEDONCE)
Also it is now possible to have .Expanded = True even when there are no childs yet. It will be then "actually expanded" when a child is added.
So the behavior is now the same as in the original MS control.

----------


## Krool

Update released.




> The RichTextBox Control have a error when is set visible=false.
> RichTextBox.Visible=False
> The error ocurred when close the execuble.


This issue is now solved.
The temporary workaround in Form_Unload, that I have suggested for the meantime, is now not needed anymore.

----------


## pepegriyo

> Update released.
> 
> 
> 
> This issue is now solved.
> The temporary workaround in Form_Unload, that I have suggested for the meantime, is now not needed anymore.




OK Thank you!!  :Smilie:

----------


## AAraya

These controls have been a great aid to me in upgrading my app to Unicode support.  Thank you for all of your work!

I noticed a rare problem yesterday.  The tooltip on a ListBoxW control does not support Unicode.  The control does but the tooltip doesn't.  I'm using version 1.2

----------


## Krool

> The tooltip on a ListBoxW control does not support Unicode.  The control does but the tooltip doesn't.  I'm using version 1.2


You mean the intrinsic VB ToolTipText property of the control? Yes, sure. No unicode support for that.

----------


## DEXWERX

> I noticed a rare problem yesterday.  The tooltip on a ListBoxW control does not support Unicode.  The control does but the tooltip doesn't.  I'm using version 1.2





> You mean the intrinsic VB ToolTipText property of the control? Yes, sure. No unicode support for that.


The ToolTipText is hardcoded as part of the runtime, so it definitely doesn't support unicode. It is however easy to 
do them yourself manually... like in this example.

----------


## AAraya

> You mean the intrinsic VB ToolTipText property of the control? Yes, sure. No unicode support for that.


Thanks for the information.  If I'm to be honest, that's a bit disappointing I must say.  The other unicode replacement controls I've used in the past support unicode fully - even in the control's tooltip property.  I do appreciate your efforts very much however!

----------


## DEXWERX

> Thanks for the information.  If I'm to be honest, that's a bit disappointing I must say.  The other unicode replacement controls I've used in the past support unicode fully - even in the control's tooltip property.  I do appreciate your efforts very much however!


Both .NET, and other Non-Free unicode controls use a seperate control to manage ToolTips.
*The VB6 IDE just doesn't support unicode, because the property panel is ANSI only.*

Here's a very rough ToolTip class you can modify yourself... you may or may not have to set the font to get it to work properly with east asian languages.

Or you can grab one from elsewhere on this forum.
http://www.vbforums.com/showthread.p...iCode-ToolTips


```
Option Explicit

Private Const NULL_             As Long = 0&
Private Const HWND_TOPMOST      As Long = -1&
Private Const SWP_NOSIZE        As Long = &H1&
Private Const SWP_NOMOVE        As Long = &H2&
Private Const SWP_NOACTIVATE    As Long = &H10&
Private Const CW_USEDEFAULT     As Long = &H80000000
Private Const TTF_IDISHWND      As Long = &H1&
Private Const TTF_SUBCLASS      As Long = &H10&
Private Const TTF_TRACK         As Long = &H20&
Private Const TTS_NOPREFIX      As Long = &H2&
Private Const TTS_ALWAYSTIP     As Long = &H1&
Private Const WS_POPUP          As Long = &H80000000
Private Const WS_EX_TOPMOST     As Long = &H8&
Private Const WM_USER           As Long = &H400&
Private Const TTM_ADDTOOL       As Long = (WM_USER + 50&)
Private Const TTM_SETMAXTIPWIDTH As Long = (WM_USER + 24&)
Private Const TOOLTIPS_CLASS    As String = "tooltips_class32"

Private Type RECT
    Left   As Long
    Top    As Long
    Right  As Long
    Bottom As Long
End Type

Private Type TOOLINFO
    cbSize     As Long
    uFlags     As Long
    hWnd       As Long
    uId        As Long
    Rect_      As RECT
    hInst      As Long
    lpszText   As Long
    lParam     As Long
    lpReserved As Long
End Type

Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal uFlags As Long) As Long
Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExW" (ByVal dwExStyle As Long, ByVal lpClassName As Long, ByVal lpWindowName As Long, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByRef lpParam As Any) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As Long

Private m_hWnd As Long

Private Function CreateTooltipWindow(hWndParent As Long) As Boolean
    If m_hWnd Then
        CreateTooltipWindow = True
        Exit Function
    End If
    
    Dim Style As Long
    Style = WS_POPUP Or TTS_ALWAYSTIP Or TTS_NOPREFIX
    m_hWnd = CreateWindowEx(WS_EX_TOPMOST, StrPtr(TOOLTIPS_CLASS), NULL_, Style, _
                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, _
                            hWndParent, NULL_, App.hInstance, ByVal NULL_)
                            
    If m_hWnd Then
        SetWindowPos m_hWnd, HWND_TOPMOST, 0&, 0&, 0&, 0&, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOACTIVATE
        CreateTooltipWindow = True
    End If
End Function

Public Function SetToolTip(Control As Control, Caption As String) As Boolean

    If Not CreateTooltipWindow(Control.Parent.hWnd) Then Exit Function

    Dim ti As TOOLINFO
    ti.cbSize = LenB(ti)
    ti.hWnd = Control.Parent.hWnd
    ti.hInst = App.hInstance
    ti.uFlags = TTF_IDISHWND Or TTF_SUBCLASS  ' Or TTF_TRACK
    ti.uId = Control.hWnd
    ti.lpszText = StrPtr(Caption)
    SendMessage m_hWnd, TTM_ADDTOOL, 0&, ti
End Function

Private Sub Class_Terminate()
    If m_hWnd Then DestroyWindow m_hWnd
End Sub
```

----------


## Bonnie West

Here's another Unicode-aware ToolTip class module.

----------


## Krool

Update released.

The GetFirstVisible function in the TreeView, ListView and ImageCombo control has been removed.
It has been replaced by an improved TopItem property.

Reason is that 'TopItem' is more known/consistent in VB6. (e.g. 'TopIndex' in List and Combo control)

Also note the other improvements. (firing of events when changed by code)
It is not a error that the ItemCheck event in the ListView control is missing in the List, as that event in the ListView control was already fired when changed by code.

----------


## Krool

> Hi!
> Is there a way to modify the Tag property so as to use a Variant instead of a String?
> Thanks


Update released.
Your request was from 2014...
But hey, now its done. :-)

----------


## Krool

Update released.

The memory consumption in Report View in the ListView control has been decreased significantly.

Because the handling of the ListSubItems has been improved, which means:
Instead of a collection for each ListItem for the ListSubItems is now an internal array.
This saves one class object per ListItem. And class objects are like big animals. (116 bytes for class object, without content)
Also this internal array allows to have the Tag property of a ListSubItem to be Variant. Before this was very impractical to realize as the properties were saved directly on the Memory Heap.

----------


## xxdoc

why when i used in winxp have a error

how can  i do？thank

----------


## Krool

> why when i used in winxp have a error
> 
> how can  i do？thank


I assume you try to use the Groups feature. There are available on Windows XP, but only if the App is linked via manifest to comctl32.dll version 6.0.

If you want to keep the IDE on comctl32.dll version 5.8x and only the compiled app linked to 6.0 then use On Error Resume Next while on .Groups.

Hint: In order to trap error raises via "On Error Goto ..." or "On Error Resume Next" it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error Trapping.

----------


## Krool

> Because the handling of the ListSubItems has been improved, which means:
> Instead of a collection for each ListItem for the ListSubItems is now an internal array.
> This saves one class object per ListItem. And class objects are like big animals. (116 bytes for class object, without content)
> Also this internal array allows to have the Tag property of a ListSubItem to be Variant. Before this was very impractical to realize as the properties were saved directly on the Memory Heap.


Concerning the update for the ListSubItems.

Did a bugfix in the Key (String) handling for the ListSubItems method 'Add', 'Item' and 'Remove' in the ListView control.
This minor stupid bug had big impact that the Key accessing did not work at all.
Somehow I didn't notice that yesterday... Sorry.

But hopefully everything should be working now.  :Smilie:

----------


## xxdoc

> This project is intended to replace the MS common controls for VB6.
> 
> The "MSCOMCTL.OCX" (respectively "COMCTL32.OCX") can be replaced completly.
> The "MSCOMCT2.OCX" (respectively "COMCT232.OCX") can be replaced completly.
> The "RICHTX32.OCX" can be replaced completly.
> The "COMDLG32.OCX" can be replaced completly.
> The "COMCT332.OCX" can be replaced completly.
> The "MCIWNDX.OCX" (shipped with VB5) can be replaced completly.
> The "SYSINFO.OCX" can be replaced completly.
> ...


if i want used one control .i must del other controls,or when i load all controls that  is a very big exe.can any good ider?

----------


## xxdoc

> This project is intended to replace the MS common controls for VB6.
> 
> The "MSCOMCTL.OCX" (respectively "COMCTL32.OCX") can be replaced completly.
> The "MSCOMCT2.OCX" (respectively "COMCT232.OCX") can be replaced completly.
> The "RICHTX32.OCX" can be replaced completly.
> The "COMDLG32.OCX" can be replaced completly.
> The "COMCT332.OCX" can be replaced completly.
> The "MCIWNDX.OCX" (shipped with VB5) can be replaced completly.
> The "SYSINFO.OCX" can be replaced completly.
> ...


how can i used HotKey.control....may be have some  Instructions

----------


## Tech99

See the demo project, for the general usage... However it is quite easy to define hotkey and window handle to it.

' Set CTRL + ALT + F10 as the default hot key.
HotKey1.Value(vbCtrlMask + vbAltMask) = vbKeyF10
HotKey1.SetApplicationHotKey (Me.hWnd)

----------


## xxdoc

how can i  Raise Event is i used  CTRL + ALT + F10 for example。if everyone used CTRL + ALT + F10，i want hide EXE? THANKS

----------


## xxdoc

> See the demo project, for the general usage... However it is quite easy to define hotkey and window handle to it.
> 
> ' Set CTRL + ALT + F10 as the default hot key.
> HotKey1.Value(vbCtrlMask + vbAltMask) = vbKeyF10
> HotKey1.SetApplicationHotKey (Me.hWnd)


how can i Raise Event is i used CTRL + ALT + F10 for example。if everyone used CTRL + ALT + F10，i want hide EXE? THANKS

----------


## Tech99

> how can i Raise Event is i used CTRL + ALT + F10 for example。if everyone used CTRL + ALT + F10，i want hide EXE? THANKS


I believe that Hotkey control handles that - at least API function fails, if the key combination is already registered as a system wide hotkey.

So there could be no 'everyone used' this/that combination situation what so ever.

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

----------


## Chrissss

Hello,

and thanks a lot for this great piece of software. Works really fine so far.

I only encountered a problem with the tree view:
When using it in a custom control, the keys e.g. left, right, up, down and Enter (when editing the text of a node) are NOT working.

----------


## Chrissss

Hello,

and thanks a lot for this great piece of software. Works really fine so far.

I only encountered a problem with the tree view:
When using it in a custom control, the keys e.g. left, right, up, down and Enter (when editing the text of a node) are NOT working.

Now I have attached the example project were you can see this:
treeview.zip

Tested with VBCCR12.OCX 1.2.0.29


Another issuew with the treeview:
The key property of a node is write protected, although it is not in the original non unicode treeview.  Any chance to make the key property writeable as well?

Thanks a lot and keep up this great development!
Chris

----------


## Krool

> I only encountered a problem with the tree view:
> When using it in a custom control, the keys e.g. left, right, up, down and Enter (when editing the text of a node) are NOT working.


And normally it works? (When not editing text)
Does it work on the ListView? (for test)

Maybe try this:
If you want to embed the controls into another UserControl then you need to add the following code (Post #597) into your UserControl. As else the accelerator keys like the Left/Right key will not work. This issue is only relevant when using the Std-EXE Version.

----------


## Karl77

> if i want used one control .i must del other controls,or when i load all controls that  is a very big exe.can any good ider?


Sure the EXE becomes larger if you use all the provided controls.
On the other hand, you don't have to struggle with the MS originals.

If the size matters, you can, as you said, remove the unused controls, then the EXE becomes smaller.

Or just use the OCX version, then your EXE is as small as usual.

----------


## Chrissss

Thanks a lot. 




> This topic was already discussed in this thread.


ok, but clearly I i did not read the whole thread, and searching will search the whole forum and not only this thread.
So may be you may think about an own forum. This would help a lot.

Chris

----------


## DaveInCaz

> searching will search the whole forum and not only this thread.


There is a "search thread" function up at the top.

----------


## DEXWERX

No need to search when, just read the first post.




> *Notes:*
> - If you want to embed the controls into another UserControl then you need to add the following code (Post #597) into your UserControl. As else the accelerator keys like the Left/Right key will not work. This issue is only relevant when using the Std-EXE Version. (The OCX Version will just work fine without any additional code)

----------


## Krool

Update released.

Important when using the ListView control.
LabelEdit is now working again.  :Smilie:

----------


## mozaiktm

> Update released.
> 
> Important when using the ListView control.
> LabelEdit is now working again.


Hi Krool, thanks for the CommonControls, it's very helpful

but i have some problem,
is there a way to add an image to ImageList and display it to the ListView from code?
i mean, i want to add an image from file (such as icon from .DLL file), when i try to do this, the ListView just displaying black image.

Thanks. (and sorry for my bad english  :Big Grin: )

----------


## Karl77

Mozaiktnm,

I had similar problems with the toolbars.
Perhaps it is the same with the listview.

In case of PNGs with Alpha, you need to use the imagelist Krool provides.
And in this imagelist, you need to set the image format:


```
.ColorDepth = ImlColorDepth32Bit
```

Please try this.

----------


## Krool

Update released.




> ExpandedImage is a Vista+ thing, there's other features missing too--


I includeded on 11-May-2016 the ExpandedImage property, but this was implemented using TVN_GETDISPINFO and I_IMAGECALLBACK.
So even Win XP users can benefit from it..




> the TVITEMEX type doesn't have the other 6.0 members either (uStateEx that allows nodes to be grayed out as disabled).


This has been implemented by this update. (Enabled property)




> I had similar problems with the toolbars.
> Perhaps it is the same with the listview.
> 
> In case of PNGs with Alpha, you need to use the imagelist Krool provides.
> And in this imagelist, you need to set the image format:
> 
> 
> ```
> .ColorDepth = ImlColorDepth32Bit
> ```


Should I set the ColorDepth property to ImlColorDepth32Bit instead of ImlColorDepth24Bit by default ?

----------


## Karl77

> Should I set the ColorDepth property to ImlColorDepth32Bit instead of ImlColorDepth24Bit by default ?


Krool, I'm not so sure.

I assume most of today used images will be 32bit and nothing else.
In this respect it makes sense to have the default 32bit.

The original imagelist seems to have an automatic for this.
It can hold and manage 32bit images without explicitely setting it.

I think to copy this automatic is far too much effort.
Change the default to 32bit or just leave it as it is now.

To avoid an obstacle for new users of your project, it could be an idea to update the sample project using PNGs w. Alpha or BMP32.


My 2 cents.

Karl

----------


## Karl77

> So even Win XP users can benefit from it..


I would drop XP support completely.


Karl.

----------


## DEXWERX

> Should I set the ColorDepth property to ImlColorDepth32Bit instead of ImlColorDepth24Bit by default ?


I think the VB6 imagelist detects a bitdepth when an image is loaded.

----------


## Cube8

> I would drop XP support completely.
> 
> 
> Karl.


You shouldn't, since there are still many XP installations out there.

----------


## Arnoutdv

You should drop support, XP is not even supported by MS anymore

----------


## Krool

> You should drop support, XP is not even supported by MS anymore


I even support W2k...
I think there are many systems out there which are isolated and embedded and still use XP or even W2k. And they don't need to worry as it's not connected to internet or a network.

They are some hassles and workarounds sometimes of course..

----------


## LeandroA

hi in the Treeview is not present NodeLevel property, TreeView1.Nodes(x).Level

----------


## Krool

> hi in the Treeview is not present NodeLevel property, TreeView1.Nodes(x).Level


It was included on 4th of june.
However, not yet in the OCX. It will be included there when releasing VBCCR13..

----------


## Krool

Big update released.

Finally, it is possible to set now a index or key in a Image property in the class collections.
Affected are the CoolBar, ListView, ToolBar, ImageCombo, TabStrip and TreeView control.

----------


## Krool

Update released.

Also the new 1.3 ActiveX Control version (VBCCR13.OCX), together with a Registration-Free (Side-by-side) solution, is now available.

----------


## Karl77

> Finally, it is possible to set now a index or key in a Image property in the class collections.


Cool Krool.  :Smilie: 
This extensions makes so much sense, thank you for this.

Karl.

----------


## DEXWERX

Is there a way to get the checkbox or option boxes to have a transparent bg when used on a coolbar? similar to the way they look on a tabstrip.

*edit:* FYI definitely not important, since i dont even use the coolbar currently!

----------


## jpskiller

Windows 10
1.3 OCX activeX register error, I have not tried this before, but can you help please when I try to register I get Error : file loaded but unable-to-register-dll-error-code0x80004005, I have loaded cmd in admin mode but still same error, can some please help, basic guide thanks

----------


## Tech99

Possibly you are using wrong (64-bit version) of regsvr32 tool.

Correct path/folder to 32-bit executable is:
C:\Windows\SysWOW64\regsvr32.exe

https://support.microsoft.com/en-us/kb/249873

----------


## jpskiller

> Possibly you are using wrong (64-bit version) of regsvr32 tool.
> 
> Correct path/folder to 32-bit executable is:
> C:\Windows\SysWOW64\regsvr32.exe
> 
> https://support.microsoft.com/en-us/kb/249873


Yes I tried that one same error, do I have to put the OCX file in a specific folder.

----------


## Elroy

Say Krool,

The "ImageList" control isn't listed in your Select Case statement in the ComCtlsIDEStopProtectionHandler procedure.

Are we to assume that the ImageList control has no subclassing, or is this possibly an oversight?

In any case FANTASTIC work.

Thanks,
Elroy

----------


## Krool

> Yes I tried that one same error, do I have to put the OCX file in a specific folder.


You need to put the OCX to C:\Windows\SysWOW64.




> Are we to assume that the ImageList control has no subclassing, or is this possibly an oversight?


Yes, no subclassing. Thus no need to put into the ComCtlsIDEStopProtectionHandler procedure. Thanks anyhow.

----------


## jpskiller

[QUOTE=Krool;5069083]You need to put the OCX to C:\Windows\SysWOW64.

Thanks for info, I have tried that and still get same error "The module "vbccr13.ocx"  was loaded but the call to DllRegisterServer failed with error code 0x80004005", I will just stick to standard method.

----------


## Krool

> Thanks for info, I have tried that and still get same error "The module "vbccr13.ocx"  was loaded but the call to DllRegisterServer failed with error code 0x80004005", I will just stick to standard method.


Are you sure running the CMD with admin?

1. Click the Start button, then in the "Start Search" box, type CMD but DO NOT press Enter yet.
2. In the list above, under "Programs" right-click on CMD that appears above and choose "Run as Administrator" and click. You might need to press Shift while right clicking to have the "Run as Administrator" in the list.
3. In the open window, type the following command and press Enter:

regsvr32 c:\windows\sysWOW64\VBCCR13.OCX

----------


## jpskiller

> Are you sure running the CMD with admin?
> 
> 1. Click the Start button, then in the "Start Search" box, type CMD but DO NOT press Enter yet.
> 2. In the list above, under "Programs" right-click on CMD that appears above and choose "Run as Administrator" and click. You might need to press Shift while right clicking to have the "Run as Administrator" in the list.
> 3. In the open window, type the following command and press Enter:
> 
> regsvr32 c:\windows\sysWOW64\VBCCR13.OCX


thanks that seems to have worked, it was failing using the regsvr32 from the sysWOW64 folder

----------


## fafalone

OCX hell is why I offer a hearty "thank you" to Krool for providing the .ctl's that don't need one of those infernal ocx's.  :Thumb:

----------


## AAraya

> The textbox has a great Property 
> Property Code:
> AllowOnlyNumbers
>  would it be possible to add AllowDecimal, and/or how many digits after the Decimal?


This is a very useful property which I have just discovered also.  There are cases where I want to allow negative numbers but this control seems to allow only positive whole numbers.  It would be wonderful if "Numbers" was allowed to be defined somewhere (e.g. AllowDecimal, AllowNegative)

----------


## lrd_VB6

Hello

Very nice work, it is "almost" perfect. :Wink: 
I have a small problem with the control "*TreeView*"
If using the properties "*BackColor*" or "*ForeColor*", control is refreshed even if "*Redraw*" = False.

The easy solution is to change the method "*Refresh*"



```
Public Sub Refresh()

    If PropRedraw = False Then Exit Sub
    UserControl.Refresh
    RedrawWindow UserControl.hWnd, 0, 0, RDW_UPDATENOW Or RDW_INVALIDATE Or RDW_ERASE Or RDW_ALLCHILDREN
End Sub
```

I join my vb project converter to go from version 11-12 to version 13 of your OCX
Attachment 139475

----------


## Shaggy Hiker

I had to edit the attachment as it contained compiled binaries, which we don't allow because we can't vouch for their safety. Please remove any compiled files, such as .exe, .dll, or ocx files and re-attach.

----------


## Krool

> If using the properties "*BackColor*" or "*ForeColor*", control is refreshed even if "*Redraw*" = False.


Done. Thanks.

----------


## Krool

Improved version for the demo that shows of how to make the ToolBar control accessible per shortcut key on a MDIForm.

Just the following If statement has been included in the hook procedure: ('Me' is the MDI form)


```
If GetActiveWindow() = Me.hWnd Then
```

As WH_KEYBOARD_LL is a global hook the shortcut keys for the ToolBar were accessible from foreign processes, e.g. from the MS notepad.
And that is definitive not wanted..

The API GetActiveWindow() is perfect for this check, as:
- It will return 0 if the actual window is in a foreign process and not from within the calling thread.
- If an MDI form is active it returns always the main MDI form, even when a MDI Child form is actual active. (unlike Screen.ActiveForm, which would return the actual MDI Child form)

----------


## ishalom

in the ocx version 1.2 I could load a picture from an IPictureDisp into The ImageList and then create the toolbar from it in code.

Using OCX version 1.3 this does not work Am I missing anything?



Sample Code Code:
Dim tbb As VBCCR13.TbrButton, pic as IPictureDisp
 ''pic.Image = loadpicture from file or resource
 Imagelist1.ListImages.Add(1, "key",  pic.Image) 
 ToolBar.ImageList = ImageList1  
 Set tbb = ToolBar1.Buttons.Add(, "ButtonKey")
tbb.Description = b.Description
tbb.Enabled = b.Enabled
tbb.MixedState = b.MixedState
tbb.Image = 1

----------


## lrd_VB6

Hello,

I also found this "bug".
In "*ImageList*" , if "*ImageWidth*" <> 0 or "*ImageHeiht*" <> 0 AND the collection "*ImageList*" is empty, the addition does not work and without error.

I think the solution would be to slightly modify the ImagesList.FListImagesAdd () routine



```
Friend Sub FListImagesAdd(Optional ByVal Index As Long, _
                          Optional ByVal Picture As IPictureDisp)
Dim ImageListIndex As Long

    If Index = 0 Then
        ImageListIndex = Me.ListImages.Count + 1
    Else
        ImageListIndex = Index
    End If

    If Picture Is Nothing Then
        Err.Raise Number:=35607, Description:="Required argument is missing"
    ElseIf Picture.Handle = 0 Then
        Err.Raise Number:=35607, Description:="Required argument is missing"
    Else
        If ImageListHandle = 0 Or Me.ListImages.Count=0 Then
            If PropImageWidth = 0 Then PropImageWidth = UserControl.ScaleX(Picture.Width, vbHimetric, vbPixels)
            If PropImageHeight = 0 Then PropImageHeight = UserControl.ScaleY(Picture.Height, vbHimetric, vbPixels)
            If ImageListHandle = 0 Then Call CreateImageList
        End If
```

Or think of putting *ImageWidth* AND *ImageHeiht* to 0 BEFORE adding the first image.

----------


## ishalom

> Or think of putting *ImageWidth* AND *ImageHeiht* to 0 BEFORE adding the first image.


Ok, good suggestion, it worked.
I set ImageWidth and ImageHeight to 0, but once I added the images, I could no longer set the  ImageWidth and ImageHeight property, because of the following error
*Property is read-only if image list contains images*

so I commented out the two lines of code and it works...

----------


## lrd_VB6

> Ok, good suggestion, it worked.
> I set ImageWidth and ImageHeight to 0, but once I added the images, I could no longer set the  ImageWidth and ImageHeight property, because of the following error
> *Property is read-only if image list contains images*
> 
> so I commented out the two lines of code and it works...


 

```
Dim tbb As VBCCR13.TbrButton, pic as IPictureDisp
     
    ''pic.Image = loadpicture from file or resource
     
    With Imagelist1
           If .Count=0 then .ImageWidth=0: .ImageHeight=0
           .ListImages.Add(1, "key",  pic.Image) 
    End With
    ToolBar.ImageList = ImageList1  
     
    Set tbb = ToolBar1.Buttons.Add(, "ButtonKey")
    tbb.Description = b.Description
    tbb.Enabled = b.Enabled
    tbb.MixedState = b.MixedState
    tbb.Image = 1
```

----------


## Krool

I don't understand what you mean is a "bug" with the ImageList.

If the ImageWidth and/or ImageHeight is 0 it will be set automatically while loading the first image.


```
    If ImageListHandle = 0 And (PropImageWidth = 0 Or PropImageHeight = 0) Then
        If PropImageWidth = 0 Then PropImageWidth = UserControl.ScaleX(Picture.Width, vbHimetric, vbPixels)
        If PropImageHeight = 0 Then PropImageHeight = UserControl.ScaleY(Picture.Height, vbHimetric, vbPixels)
        Call CreateImageList
    End If
```

ImageListHandle = 0 means that a handle could not be created because either ImageWidth or ImageHeight is 0.
So there is no need to check if the Collection is empty because it is not possible to have the collection not empty and handle of <> 0.

What I tested now again is following:
I have the ImageHeight and ImageWidth set to both 16 pixels.
If I load now the first picture with 16x16 it works, no problem.
Even when I load a picture with 32x32 it works, it just gets "scaled".
So having ImageHeight and/or ImageWidth of 0 is just a convenience to retrieve the dimension from the first picture.
Later it is of course not possible to set ImageHeight and/or ImageWidth to 0 when pictures are already loaded.

So in my tests there is no such "bug".  :Confused:

----------


## ishalom

> What I tested now again is following:
> I have the ImageHeight and ImageWidth set to both 16 pixels.
> If I load now the first picture with 16x16 it works, no problem.
> Even when I load a picture with 32x32 it works, it just gets "scaled".
> So having ImageHeight and/or ImageWidth of 0 is just a convenience to retrieve the dimension from the first picture.
> Later it is of course not possible to set ImageHeight and/or ImageWidth to 0 when pictures are already loaded.
> 
> So in my tests there is no such "bug".


the problem is when populating the ImageList and Toolbar at runtime



```
Dim tbb As VBCCR13.TbrButton, pic as IPictureDisp

''pic.Image = load picture from file, resource or propertybag

Imagelist1.ListImages.Add(1, "key",  pic.Image) 

ToolBar.ImageList = ImageList1  
Set tbb = ToolBar1.Buttons.Add(, "ButtonKey")
tbb.Description = b.Description
tbb.Enabled = b.Enabled
tbb.MixedState = b.MixedState
tbb.Image = 1
```

if ImageHeight and/or ImageWidth is not 0 then the toolbar button won't show the picture
the problem only exist in version 13 of the ocx not in 12

----------


## Krool

Can you please provide a demo showing the issue?
Is this "bug" also in the Std-EXE version?
Thanks

----------


## lrd_VB6

Hello

I have a small test program that highlights the "bug" (problem)
The buttons "ImageSize" sets the size of the empty ImageList to 0 or 16
"Test 1" creates a imageList The TreeView without imposing size.
"Test 2" creates a imageList The TreeView by imposing a size size.

*THE TEST*

1. Start program
2. Click ImageSize = 0
3. Click "Test2" before "Test1" or "Test1" before "Test2"

or

1. Start program
2. Click ImageSize = 16
3. Click "Test2" before "Test1" or "Test1" before "Test2"

Following the order of tests, the message "ListImages is Nothing" appears.

This comes from the ImageList that was not created (ImageListHandle = 0) but without error when creating.

Another question.
The TreeView Version 13 "seems" slower than version 11. Is that normal?

----------


## Krool

> Following the order of tests, the message "ListImages is Nothing" appears.
> 
> This comes from the ImageList that was not created (ImageListHandle = 0) but without error when creating.


Update released. (VBCCR13.OCX and Std-EXE)
Thank you!
I changed the code now to the following:


```
    If ImageListHandle = 0 Or (PropImageWidth = 0 Or PropImageHeight = 0) Then
        If PropImageWidth = 0 Then PropImageWidth = UserControl.ScaleX(Picture.Width, vbHimetric, vbPixels)
        If PropImageHeight = 0 Then PropImageHeight = UserControl.ScaleY(Picture.Height, vbHimetric, vbPixels)
        If ImageListHandle = 0 Then Call CreateImageList
    End If
```




> Another question.
> The TreeView Version 13 "seems" slower than version 11. Is that normal?


This could be due to the extra overhead for the 'Variant' .Image property.
Is it also slower when not using the .Image property?

----------


## lrd_VB6

Hello,

happy to have made the project forward.

Another little detail to "tease"
In the following code:


```
If ImageListHandle = 0 Or (PropImageWidth = 0 Or PropImageHeight = 0) Then
        If PropImageWidth = 0 Then PropImageWidth = UserControl.ScaleX(Picture.Width, vbHimetric, vbPixels)
        If PropImageHeight = 0 Then PropImageHeight = UserControl.ScaleY(Picture.Height, vbHimetric, vbPixels)
        If ImageListHandle = 0 Then Call CreateImageList
End If
```

The first test is unnecessary.

By cons, it is important to leave last
If ImageListHandle = 0 Then Call CreateImageList

Last, I'd like able to benefit from your internal routines to implement the subclassing by the method of your choice (usercontrol, class or other)
To manage the mouse wheel by example.

Good luck and thank you for your work.

----------


## Krool

> Another little detail to "tease"
> In the following code:
> 
> 
> ```
> If ImageListHandle = 0 Or (PropImageWidth = 0 Or PropImageHeight = 0) Then
>         If PropImageWidth = 0 Then PropImageWidth = UserControl.ScaleX(Picture.Width, vbHimetric, vbPixels)
>         If PropImageHeight = 0 Then PropImageHeight = UserControl.ScaleY(Picture.Height, vbHimetric, vbPixels)
>         If ImageListHandle = 0 Then Call CreateImageList
> ...


Done. Thanks.

I also did another "tease". In the .ImageWidth and .ImageHeight property I replaced


```
If ImageListHandle <> 0 Then
    Call DestroyImageList
    Call CreateImageList
End If
```

with this


```
If ImageListHandle <> 0 Then Call DestroyImageList
If ImageListHandle = 0 Then Call CreateImageList
```

This ensures that the .hImageList will be valid when setting both .ImageWidth and .ImageHeight > 0.
For the moment this was only the case when setting at design-time. Now it is the same at run-time.
This can be important when setting the ImageList to a .ImageList property of a control prior loading the images!
Anyhow, now it should be perfect and cover all cases.




> Last, I'd like able to benefit from your internal routines to implement the subclassing by the method of your choice (usercontrol, class or other)
> To manage the mouse wheel by example.


Please explain in more detail.

----------


## ishalom

I am not sure this is the right place to ask, but is it possible to have a background picture on the textbox?

----------


## Krool

> I am not sure this is the right place to ask, but is it possible to have a background picture on the textbox?


Your question gets answered there: http://www.vbforums.com/showthread.p...e-to-a-textbox

----------


## Krool

General question put in the room:
Is there any need to make a lightweight ActiveX version?
Would be named VBCCR13*L*.OCX
If yes, which controls to exclude?

----------


## Elroy

My vote would be a huge NO!  A HUGE advantage of what you've done is to allow someone to make a registration-free VB6 program.

If you're just looking for more to do, add a Column Headers Property Page to the Listview control, or add the tabctl32.ocx (SSTab) to the list of what you've covered.   :Smilie: 

If you included the SSTab, I could go totally registration-free, with no SxS stuff on my primary project, which would be wonderful.

IDK, just my humble opinion, but I see the whole advantage of the wonderful work you've done is being able to wrap everything up into a single project.

Best Regards,
Elroy

----------


## Krool

@Elroy, I was talking about the .OCX and not the Std-EXE.

The package of Std-EXE would remain full as you can pick what you actually need.
For the OCX is different, you know?

Thats why I want to know if there is a need to make a lightweight ActiveX version.(VBCCR13*L*.OCX)

----------


## Elroy

Oh yes, in years past, I've done my own OCX compiles.  However, these days, I just tend to pull the source code of my custom controls into whatever project I'm working on.

It just seems that, if someone were going to go "back" to an OCX, they'd just use the one from Microsoft.  However, I do realize that you're offering some features that aren't in the original Microsoft controls.

If you're like me, you're just possibly looking for a way to do some further work on this project.  I also know that it's most fun for me if it's some idea I've thought up on my own.  But just to gently set it on the table, having this for the SSTab control would be wildly cool IMHO.  Regarding the Column Headers Property Page, I could do that pretty easily myself if I really wanted it.

I do hope you continue with the joy of coding in VB6, whatever that may involved.

Regards,
Elroy

----------


## jpskiller

I agree I don't see any real need to make a lightweight OCX as you can pick the controls from the std package if wish, (and I like the ability to use the OCX side by side with no registration) my wish list is as above is a SStab replacement and a really good grid control like LynxGrid (development stopped long ago).

I am only a novice programmer but use these controls all the time, due to my programs having to run on WYSE terminals which don't allow me to register anything.

The exe where getting very large 2mb+ but now I have got the side by side OCX working its great and keeps the exe size down.

----------


## Krool

> I agree I don't see any real need to make a lightweight OCX as you can pick the controls from the std package if wish, (and I like the ability to use the OCX side by side with no registration) my wish list is as above is a SStab replacement and a really good grid control like LynxGrid (development stopped long ago).
> 
> I am only a novice programmer but use these controls all the time, due to my programs having to run on WYSE terminals which don't allow me to register anything.
> 
> The exe where getting very large 2mb+ but now I have got the side by side OCX working its great and keeps the exe size down.


Its true. Actually it doesnt matter nowadays if a OCX is 4.6MB or only 2MB. And it would be difficult to find the best mix for such a lightweight OCX.

Concerning the grid replacement. I need also such an replacement, so I am developing a MSFlexGrid replacement. It will replace it completely, though the MSHFlexGrid will be replaced only partially as I don't think I will implement bands. Of course all known bugs and limitations (e.g. lack of mouse wheel support, cell limit, etc.) will be away.
But this will be in a separate project. It will not be included in this project as it is too big.

For SSTab. To be honest, I dont know much of it and what is the advantage over the TabStrip control?

----------


## chosk

The main different to a user is every tab of the SSTab is a container by itself. During design mode, you can put controls in the tabs. Unlike TabStrip where you need to have another container - usually picture box. During runtime, have to resize the picturebox when the TabStrip is resized. Don't have to do this with SSTab.

The downside is that SSTab is not themed, so it can look out of place when the other controls are themed.

Edited later to add:
In VB.NET, the tabs in TabStrip are containers.

----------


## Elroy

I know I'm going to say stuff that'll keep Krool from ever seriously looking at the SSTab, but hey ho.  Each tab actually isn't a container.  The whole control is a container, but the individual tabs just have some interesting logic that moves the controls around.  What it actually does is add and subtract 75000 twips from the control's left property to move it into and out of sight when the tabs are clicked.  

I've actually got some code that'll switch the tab a control is on, and it has nothing to do with changing the control's container.  I've actually previously posted these procedures in these forums.

The SSTab is also a bit buggy on one account (although, overall, I've found it to be quite bulletproof).  The sole bug I've found is that, under certain circumstances, it'll let a control on a non-visible tab take the focus.  So, when you're using the TAB-keyboard-key to change focus, the focus will appear to be in la-la-land.  I've written a class that I instantiate and attach to each SSTab control that I use that corrects this bug.

I must say though, all in all, I do like the SSTab control a great deal.

Regards,
Elroy

----------


## ishalom

I have played around with the Std-EXE, and I still use your OCX (thank you).
as a user of your OCX, I can say that a lightweight one would not be necessary. It is great the way it is, and you are better of spending your time with the stuff the others have mentioned.

The SStab would also be great, as Elroy says the ms one is a bit (a lot) buggy (I have stopped using it a long time ago). but the idea of not needing a picture box for each tab and the need of moving it around during design time, would be great.

since I see others are using this space for requests I would like to add two of mine:
1) the vb controls have a RightToLeft Property, with your OCX I have to use window API, and on a form with a controls it's a bit messy.
Also the Label Control does not have  an hWnd Property.
2) how about a PpropertyList, its not part of the MS Common Controls, but your are BETTER....

this is the code used for RightToLeft


```
Private Declare Function GetWindowLong Lib "User32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const WS_EX_RIGHT = &H1000&
Private Const WS_EX_RTLREADING = &H2000&
Private Const WS_EX_LAYOUTRTL = &H400000
Private Const WS_EX_LEFTSCROLLBAR = &H4000&
Private Const GWL_EXSTYLE = (-20)

Private Const GWL_STYLE = (-16)
Private Const WS_EX_NOINHERITLAYOUT = &H100000

Public Sub SetRTLControl(hwnd As Long)
Dim l As Long
l = GetWindowLong(hwnd, GWL_EXSTYLE)
l = l Or WS_EX_LAYOUTRTL
l = SetWindowLong(hwnd, GWL_EXSTYLE, l)

End Sub
```

----------


## Karl77

The original SSTab has also problems on multi-monitor systems.
I gave up on it years ago as well.

The major advantage of SSTab over the TabStrip is the easy handling at design time.
And at runtime, it makes things easier as well.

I like the idea of a STTab replacement.

---

Lightweight OCX: I can't imagine a single reason for it.

---

Karl

----------


## Elroy

Hey Karl,

I virtually never sit down at a computer these days that doesn't have at least two monitors on it.  One of my home development computers has three, but my primary one only has two.  Also, virtually all of my clients these days have primary workstations with two monitors.  In my primary application, I've even worked out procedures for shoving forms to the second monitor, specifically so they can view two things at once while working within the application, and the SSTab is frequently on one (if not both) of these forms.

I'm just wondering what multi-monitor problems you've seen with the SSTab control.

And yes, I suppose it is the "coolness" of IDE design-time development that attracts me to the control.  I just love being able to click the tabs and redesign one of the tab/pages while in the IDE.

Regards,
Elroy

p.s. Regarding multiple monitors, I'm starting to think we've all gone the wrong direction, except possibly for some specific applications.  My next system is going to have a 4k Ultra HD video card in it, with a single 4k Ultra HD monitor that's somewhere in the neighborhood of 40" diagonal.  That way, I can put forms and windows wherever I darn well please.

----------


## Karl77

Hello Elroy,

OT:

Regarding monitor usage, it seems we both have the same conditions.




> I'm just wondering what multi-monitor problems you've seen with the SSTab control.


Don't remember exactly, it is too long ago.
I think the problems occurred with negative screen coordinates, then the click onto a tab didn't work.

BTW, problems with negative screen coordinates can be found e.g. in the comctl32 treeview.
The NodeClick events doesn't work in this case.

Because Visual Styles were not possible with SSTAB, I gave up when XP came out.




> p.s. Regarding multiple monitors, I'm starting to think we've all gone the wrong direction, except possibly for some specific applications.  My next system is going to have a 4k Ultra HD video card in it, with a single 4k Ultra HD monitor that's somewhere in the neighborhood of 40" diagonal.  That way, I can put forms and windows wherever I darn well please.


Not sure.
I had the same idea, but...
With such sizes, the eye-screen distance is too different, upper left is further away than bottom left - problem for me.
Next is, the single pixel is very small, and doing pixel-fine work is even harder than with standard monitors.
And the quality of the cheaper ones is not so very super, I don't want to spend much more than 1000 for such a monitor.
Last is, a 40" display is virtually 4 standard displays - and a 20" monitor is quite small.

But I must confess, I didn't try a 40" 4K setup in reality.
Now I use 3x 26" 1920x1200.
I wait until a monitor dies.

Karl

----------


## Karl77

Hi Elroy,




> I'm just wondering what multi-monitor problems you've seen with the SSTab control.


From your own other post:



> and I've found that the SSTab control's size gets totally confused when DPI isn't set to precisely 96 DPI.


So it doesn't matter which problems I experienced in the past.
Non-DPI-aware is a killer anyway.

Krool's controls *ARE DPI aware*.
Better than the originals, really.
Perhaps someday he is bored and creates an SSTAB replacement.


Karl

----------


## Elroy

Hi Karl,

Well, to date, I've insisted that my clients always set their monitors to 96 DPI, so I have no problems.  If they want things bigger, they just use screen resolution (with the accompanying fuzziness).  As suggested in another thread, I know I've got to bite-the-bullet on this quite soon.  I've played with it some, and found that the SSTab control is particularly problematic.  I think the solution is just to "take charge" of its size (as well as the size of all the controls it contains, and the controls nested on containers on its tabs).  Arghh.  It's just not something I'm looking forward to.

Regards,
Elroy

----------


## Tech99

Tested briefly Listview control, but seems that it does allow editing only in first column? Likewise when FullRowSelect is set to False, it does not allow focus/selection in to other columns.

Listview has an another quirk... Try to drag some item in Listview3 upwards, works ok - but dragging item downwards, it pushes all items 'front' of it downwards, not just jump over as it should.

----------


## chosk

I am experimenting to create a Windows 10 style Hamburger Menu using OptionButtons as menu. How can I remove the round circle thing on the left so that only the caption show? I am using OptionButtons instead of Labels because I can vertical-center the caption.

Thanks.

Edit:
I think I use a Label and vertical center the caption manually. It also doesn't have the selected rectangle that makes it more suitable.

----------


## DEXWERX

is there an example of using a toolbar split dropdown button?

----------


## Krool

> is there an example of using a toolbar split dropdown button?


In the demo here.

----------


## dungdn93

Benefits of using the existing controls over what is? There is every driver has the same properties? They are new?
You can apply for a name change OLEGuids.tlb new to avoid a conflict with my current OLEGuids.tlb in the system32 folder?

----------


## Krool

> You can apply for a name change OLEGuids.tlb new to avoid a conflict with my current OLEGuids.tlb in the system32 folder?


You can rename my OLEGuids.tlb to OLEGuids2.tlb for instance. The uuid and library name differs, so no conflicts.

----------


## chosk

Hi Krool,

I am not sure whether I can or should ask you to include features in the LabelW control to align caption vertically. And also for a MouseOver event or something where when the mouse is over it, we can use the event to change the backcolor and change back when it leaves. This will make the label usable as a button to make the app adopt the Windows 10 look.

Right now, I have to insert a vbCrLf to push the caption down but then I will need to make the Label very tall. I also use MouseMove on the LabelW and also the form (and any other controls) to revert the LabelW backcolor back to non-hover color. This create a lot of flicker.

I attach a screen hot of my demo against the Windows 10 Money app for comparision.

----------


## chosk

I intend to use this also in Windows 7 by making the form without caption and border and creating my own caption bar. The Seogoe MDL2 Assets font can be downloaded and installed in Windows 7 from the link the lower choice option with the captcha:

https://www.azfonts.net/download/segoe-mdl2-assets.html

Eventually, I intend to use from a resource to avoid installing the font.

Here is the code to a very raw demo:



```
Option Explicit

Private Sub Form_Load()

    LabelW0.Font.Name = "Segoe MDL2 Assets"
    LabelW1.Font.Name = "Segoe MDL2 Assets"
    LabelW2.Font.Name = "Segoe MDL2 Assets"
    LabelW3.Font.Name = "Segoe MDL2 Assets"

    LabelW0.Font.Size = 14
    LabelW1.Font.Size = 14
    LabelW2.Font.Size = 14
    LabelW3.Font.Size = 14
    
    LabelW0.Caption = vbCrLf & Space(4) & ChrW$(&HE700)
    LabelW1.Caption = vbCrLf & Space(4) & ChrW$(&HE80F) & Space(5) & "Home"
    LabelW2.Caption = vbCrLf & Space(4) & ChrW$(&HE160) & Space(5) & "New"
    LabelW3.Caption = vbCrLf & Space(4) & ChrW$(&HE713) & Space(5) & "Settings"
    
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LabelW1.BackColor = &H80000015
    LabelW2.BackColor = &H80000015
    LabelW3.BackColor = &H80000015
End Sub

Private Sub Frame1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LabelW1.BackColor = &H80000015
    LabelW2.BackColor = &H80000015
    LabelW3.BackColor = &H80000015
End Sub

Private Sub LabelW1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LabelW1.BackColor = &H8000000D
    LabelW2.BackColor = &H80000015
    LabelW3.BackColor = &H80000015
End Sub

Private Sub LabelW2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LabelW2.BackColor = &H8000000D
    LabelW1.BackColor = &H80000015
    LabelW3.BackColor = &H80000015
End Sub

Private Sub LabelW3_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LabelW3.BackColor = &H8000000D
    LabelW1.BackColor = &H80000015
    LabelW2.BackColor = &H80000015
End Sub
```

----------


## Krool

Update released.




> I am not sure whether I can or should ask you to include features in the LabelW control to align caption vertically.


I have now included the VerticalAlignment property in the LabelW control. It supports also multi-line text.

----------


## chosk

> Update released.
> 
> I have now included the VerticalAlignment property in the LabelW control. It supports also multi-line text.


Hi Krool,

Thank you very much.

----------


## ishalom

Can't seem to find the link to download the OCX 1.3 and the Stdexe

----------


## Arnoutdv

OCX release 1.3

----------


## ishalom

> OCX release 1.3


*
Not available for the moment, due to forum policy. Please PM me to get it by another way.
Revision count will be updated here, for your reference.*

----------


## trose44

Great work, this is an awesome set of controls, however I have been unable to find a post about legally redistributing the OCX file. Can you point me in the right direction?

----------


## Krool

> I have been unable to find a post about legally redistributing the OCX file. Can you point me in the right direction?


There is no written notice for free license. However, of course, feel free to redistribute with your app, preferable with the reg-free solution.

----------


## Krool

> Also the Label Control does not have  an hWnd Property.


The LabelW is a lightweight control. (Windowless)
This way it supports true transparency, like the original.
Actually I do not miss the .hWnd on it, do you?

----------


## ishalom

> The LabelW is a lightweight control. (Windowless)
> This way it supports true transparency, like the original.
> Actually I do not miss the .hWnd on it, do you?


I also do not need the hWnd, what I do need is the ability to make it RightToLeft (a property which is not on your controls but is on the standard vb controls) without this property in design time, the only way to do it is with api which requires an hWnd.

----------


## ChenLin

Hello, everyone, who has more than 6 versions of comctl32.dll? My version is 5.0, Some of the features are not tested.

----------


## ishalom

> Update released.
> 
> 
> 
> I have now included the VerticalAlignment property in the LabelW control. It supports also multi-line text.


is this included in the OCX version 1.3.0.3?

----------


## Krool

> is this included in the OCX version 1.3.0.3?


No. Will be on next release, means 1.4.

----------


## Karl77

Krool, simple question:

Is it possible to have the toolbar vertical?
I have no clue if comctl32 has this functionality...

It is because I need one, and up to now it is made of a bunch of 'normal' toolbars, each with one button.

Only a question.

Karl

----------


## chosk

> Is it possible to have the toolbar vertical?


There are vbAlignLeft and vbAlignRight in the Align property. They will make the toolbar vertical on the left or right of the form respectively.

----------


## Karl77

> There are vbAlignLeft and vbAlignRight in the Align property. They will make the toolbar vertical on the left or right of the form respectively.


I know about align options, but speaking of orientation.

----------


## Krool

> I know about align options, but speaking of orientation.


The orientiation is vertical when you set the align option to vbAlignLeft or vbAlignRight.

----------


## Karl77

> The orientiation is vertical when you set the align option to vbAlignLeft or vbAlignRight.


Yes, this works when the toolbar is on the form.
BUT:

When it is in a picturebox, then it can't align...
...and the toolbar is always horizontal.

And as a next case, the toolbar is placed by .left and .top, so no alignment at all.

With the comctl32.ocx toolbar vertical orientation is not possible.
I thought maybe that's possible with the Krool toolbar.
Therefore the question.

Seems it is not possible.
Correct?

Karl

----------


## Krool

> Yes, this works when the toolbar is on the form.
> BUT:
> 
> When it is in a picturebox, then it can't align...
> ...and the toolbar is always horizontal.
> 
> And as a next case, the toolbar is placed by .left and .top, so no alignment at all.
> 
> With the comctl32.ocx toolbar vertical orientation is not possible.
> ...


For the moment not..
The behavior should remain the same, but I could include a Orientation property to make this possible.
It would be just overwritten when changing the align option, but that should be no problem.

----------


## Krool

> the vb controls have a RightToLeft Property, with your OCX I have to use window API, and on a form with a controls it's a bit messy.
> 
> this is the code used for RightToLeft
> 
> 
> ```
> Private Declare Function GetWindowLong Lib "User32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
> Private Declare Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
> Private Const WS_EX_RIGHT = &H1000&
> ...


RightToLeft is still a open topic. I really need to include it..

At the moment I have only the following when creating a control:


```
If Ambient.RightToLeft = True Then dwExStyle = dwExStyle Or WS_EX_RTLREADING
```

However, this makes only the text and not the layout RTL. (I am not adding the WS_EX_LAYOUTRTL style)
And I think the code above should be removed. It's a kind of automatism which should be avoided.

Instead, I would need to include a RightToLeft property to all controls which could then be set the following values: (enum instead of boolean)
- CCRightToLeftNone
- CCRightToLeftText (WS_EX_RTLREADING)
- CCRightToLeftLayout (WS_EX_RTLREADING)
- CCRightToLeftTextLayout (WS_EX_RTLREADING+WS_EX_LAYOUTRTL)

Default property would be CCRightToLeftNone.
And nothing else, correct?

PS: The VB's intrinsic RightToLeft properties are all read-only. (and only boolean)

----------


## Karl77

> I could include a Orientation property to make this possible.


Would be great!
Thanks for that in advance...

Karl

----------


## Krool

Again concerning the RightToLeft open topic.

What about doing like in .Net?
Two properties. 'RightToLeft' enum property and 'RightToLeftLayout' boolean property.

RightToLeft enums would be:
- Inherit (check for Ambient.RightToLeft; default value)
- No
- Yes

In addition the horizontal alignment properties would be reversed when RightToLeft.
So for instance setting right text align when RightToLeft is Yes the text will be displayed left.

And like MSDN states:
The RightToLeftLayout and RightToLeft properties cause the following Win32 API window styles to be set:
When RightToLeft is set to Yes and RightToLeftLayout is set to true, Windows Forms sets the WS_EX_LAYOUTRTL window style, and removes the WS_EX_RIGHT and WS_EX_RTLREADING styles.
When RightToLeft is set to Yes but RightToLeftLayout is set to No, Windows Forms sets the WS_EX_RIGHT and WS_EX_RTLREADING window styles.

Unlike RightToLeft, RightToLeftLayout does not inherit. If you want it to take effect for child controls, you must set it on each child control that you want mirrored.

----------


## AAraya

Found a problem with the ComboBoxW control.  Setting the Text property of the control does not fire the Change event like it does for VBs intrinsic Combo control



```
ComboBoxW1.Text = "foo"

Private Sub ComboBoxW1_Change() 
  'we never make it here
End Sub
```

----------


## Krool

> Found a problem with the ComboBoxW control.  Setting the Text property of the control does not fire the Change event like it does for VBs intrinsic Combo control
> 
> 
> 
> ```
> ComboBoxW1.Text = "foo"
> 
> Private Sub ComboBoxW1_Change() 
>   'we never make it here
> ...


Thanks a lot for notifying this bug.
Update released.

----------


## Krool

Update released.

Important bugfix in the TextBoxW control.

----------


## Bonnie West

> Update released.
> 
> Important bugfix in the TextBoxW control.


It might be better if the *Change* event was raised in a *WM_SETTEXT* handler in the *WindowProcControl* procedure rather than doing it only in the *Property Let Text* procedure. This way, that event will always be raised regardless of who sent the *WM_SETTEXT* message.

----------


## Krool

> It might be better if the *Change* event was raised in a *WM_SETTEXT* handler in the *WindowProcControl* procedure rather than doing it only in the *Property Let Text* procedure. This way, that event will always be raised regardless of who sent the *WM_SETTEXT* message.


Interesting issue.

Indeed the intrinsic VB TextBox control has some kind of special WM_SETTEXT handler. It raises the Change event in a multi-line TextBox. The VB TextBox does not send a EN_CHANGE notification, it must just raise the event inside the WM_SETTEXT handler.
However, for the other controls (e.g. ListBox control), there it does not do something similar. For instance for the LB_SETCURSEL message. It seems the VB ListBox does not have an handler which raises a Click event. You must go via the .ListIndex property there.
So VB is not consistent at that point.

----------


## pepegriyo2016

> This is the 1.2 ActiveX Control version. (Revision 35)
> 
> *Not available for the moment, due to forum policy. Please PM me to get it by another way.*
> Revision count will be updated here, for your reference.
> 
> Any bugfixes in future will be compatible to this binary and only the revision number will be incremented.
> 
> Advantageous compared to the Std-EXE version is that all *property pages* support *Unicode*.
> 
> ...


Krool,
Could you giveme the .ocx version? 1.2

Thanks

----------


## Karl77

Hi,

seems I'm too dense to populate the treeview correct.
This is with version 1.2.



```
With TreeView1

.Add(, , "root", "Root 1").Expanded = True
.Add "root", TvwNodeRelationshipChild, "ch1", "Child 1"
.Add "root", TvwNodeRelationshipChild, "ch2", "Child 2"

End With
```

Treeview doesn't expand after the code above ran.
It always shows "Root 1" collapsed.
Of course, after a click, it expands.
But it shall have the children expanded from the beginning without having to manually expand them.

I tried several combinations.
Regardless what I do, always the same.

In the sample project it work as wanted.
But I don't see the difference to what I do...

Someone has a hint?

Karl

----------


## Arnoutdv

I always do it in code after the child nodes have been added.


```
Dim rootNode as Node

With TreeView1

  Set rootNode = .Add(, , "root", "Root 1")
  .Add "root", TvwNodeRelationshipChild, "ch1", "Child 1"
  .Add "root", TvwNodeRelationshipChild, "ch2", "Child 2"
 
   rootNode.Expanded = True
End With
```

----------


## Karl77

> I always do it in code after the child nodes have been added.


Ok, thank you, that works.
Seems the treeview is not 100% compatible with the 'original'.

Doesn't matter.
It's ok as it is.


Karl

----------


## Krool

> Ok, thank you, that works.
> Seems the treeview is not 100% compatible with the 'original'.
> 
> Doesn't matter.
> It's ok as it is.
> 
> 
> Karl


Not true. Fixed both Std-Exe and OCX since 16-May-2016.

16-May-2016
- Improved the Expanded property of a Node in the TreeView control. It works now like in the original MS control.
  It is now ensured that BeforeCollapse/BeforeExpand and Collapse/Expand events are always fired when state is being changed.
  Also it is now possible to set the expanded state even when there are no child items associated.

*So:* Either use 1.3 or take the latest 1.2. (Watch for revision number)
Or use the Std-EXE version, of course.

----------


## Karl77

> 16-May-2016
> - Improved the Expanded property of a Node in the TreeView control.


Oh well yes Krool, I'm really behind.
Missed that totally.
Sorry for bringing up the same issue a second time, unnecessarily.

Karl

----------


## ChenLin

In IDE state to open the form MainForm will automatically exit.

----------


## chosk

I thought I have seen the question being asked previously but I may have mistaken because I am unable to find it.

How do I get the TabStrip's Placement property TbsPlacementBottom to work? Also Left and Right. Is there a pre-requisite? Whatever I choose, the tabs are always at the top.

----------


## Krool

> How do I get the TabStrip's Placement property TbsPlacementBottom to work? Also Left and Right. Is there a pre-requisite? Whatever I choose, the tabs are always at the top.


The placement property works not when using comctl32.dll version 6 or above.
What do you mean with Left and Right?

----------


## chosk

Ok thanks.

I understand now why I can't get it to work in Windows 7 and 10.
Left and Right, I was meaning TbsPlacementLeft and TbsPlacementRight.

----------


## Krool

> I understand now why I can't get it to work in Windows 7 and 10.
> Left and Right, I was meaning TbsPlacementLeft and TbsPlacementRight.


Just for info. You can set the Placement property when the DrawMode property is set to 'OwnerDraw'.

EDIT: Was in wrong memory. It does only work when using comctl32.dll v5.8x. DrawMode property changes nothing in this case.

----------


## VbNetMatrix

Plz enlight me on something...
Can you post a project... and/or  explain how to use theses new component ?
You talked about using VBCCR13.OCX wich I did not find in any of your download link, 
I did downloaded ComCtlsDemo, I can compile it without problem, I even registered OLEGuids.tlb
Where I'm stuck is, where is the OCX, and how do I use the RES file?

also, I noticed while downloading both RES file, they download as ANSI file but loading it in NotePad++, they are not ANSI file because they include some NUL caracter at begin and end.  Is there any purpose to theses NUL caracter or can I remove them ?
I was under impression SideBySide were supposed to be XML file (therefore not containing any unusual caracter)

thanks a lot.

----------


## chosk

There are 2 versions of the controls.

1) ComCtlsDemo
The replacement common controls are all in UserControls, therefore no need OCX. You will see them under User Controls in the IDE. Where required, they come with their own Classes and Pages. They are all in the respective Build sub-folders.

2) OCX
You will find download instruction in the link on the first page. You may have already gone there since you know about the RES files. Read the instruction in red on how to download the OCX. The RES are VB6 resource files that includes side-by-side usage of the OCX without the need to register the OCX on target computers. On your development computer you will have to register the OCX. All information are in the respective download posts.

----------


## Tech99

Listview - drag down works errorneosly.

----------


## DEXWERX

interesting, does that happen with the VB6 ListView?

----------


## Tech99

No, not to my knowledge. Items scroll over when dragged, as they should.

----------


## Krool

> No, not to my knowledge. Items scroll over when dragged, as they should.


Do you have SnapToGrid disabled? Also happen on Icon view instead of Tile View?

----------


## Tech99

> Do you have SnapToGrid disabled? Also happen on Icon view instead of Tile View?


Negative. Settings are/were as in attachment.

----------


## Krool

> Negative. Settings are/were as in attachment.


Try with setting SnapToGrid to False.

----------


## Tech99

> Try with setting SnapToGrid to False.


Yes - without SnapToGrid it doesn't push items in forward, but no worky either, as items are not ordered. 

Dragged item stays where it is dropped, without added empty space to position item between items, likewise no removed empty space where the item was positioned before drag operation.

----------


## Krool

> Yes - without SnapToGrid it doesn't push items in forward, but no worky either, as items are not ordered. 
> 
> Dragged item stays where it is dropped, without added empty space to position item between items, likewise no removed empty space where the item was positioned before drag operation.


I think for your purpose you need some kind of manual mode d&d. Like it is used in the Demo on the TreeView.
Start dragging and drop per InsertMark.

----------


## Tech99

> I think for your purpose you need some kind of manual mode d&d. Like it is used in the Demo on the TreeView.
> Start dragging and drop per InsertMark.


Have to code it that way then. 

btw... OleDragDropScroll = False - setting, does not have an effect as items are still scrolling down, when items are dragged down.

----------


## Krool

> Have to code it that way then. 
> 
> btw... OleDragDropScroll = False - setting, does not have an effect as items are still scrolling down, when items are dragged down.


That property means scrolling the scrollbar when drag near the border, not item scrolling down.

----------


## chosk

Hi Krool,

I have been stumped for the past several hours and still not finding where the problem lies.

I am using the Std-EXE. I just place a LabelW in the startup form and in Form_Load I have only SetupVisualStyles Me, and this is the only code in the project nothing else.

I run the project and it is my bad habit (have to change this) to always click the stop button on the IDE. Usually this may not be a problem but in this case, it is always. This is not a problem with ComCtlsDemo.Then I get the error:

Debug.Assert CBool(OldPointer <> NewPointer) in Sub CreateSubclass in VTableSubclass.

If I were to put only a FrameW and nothing else, I get the same error.

I think it is something simple but I am not getting it. Any help will be appreciated.

Edit: Usually after asking for help on a stupid problem, the answer finally come itself. I should make Startup Object as Sub Main, instead of MainForm. Problem solved.

----------


## padbravo

"Not available for the moment, due to forum policy. Please PM me to get it by another way.
Revision count will be updated here, for your reference."

So... If I got it in proper manner, to get the latest version of the controls, is to ask for them?
to who? and by what way?

Or I am missing something?

----------


## DEXWERX

> "Not available for the moment, due to forum policy. *Please PM me to get it by another way.*
> Revision count will be updated here, for your reference."
> 
> So... If I got it in proper manner, to get the latest version of the controls, is to ask for them?
> to who? and by what way?
> 
> Or I am missing something?


You are missing the part, where it says to PM him. 
Click on his name user name "Krool"
Click "Private Message"
Type in a message to ask him to email or send you a download link.

----------


## KurtB

Hi Krool! I just stumbled upon this thread - Wow! Is this set of controls all your creation? I've been wanting to hack up VB's controls forever, and it looks like you've done it, the right way! The biggest one for me is Unicode support: VB ends up eating 2 bytes for every string character you store, but you get no benefit from it. And then you have to suffer conversion back and forth from Unicode to ANSI and back...What were they thinking?
Can I download and test your current version? Some more questions:
1. Do you accept bug fixes?
2. Do you consider/accept compatible enhancements to original functionality? (Enhancements that were not intended functionality, broken or otherwise?)
3. How close are you on completing your goals for this project? In other words, are you just doing bugfixes at this stage, or do you have a lot more to add?

You should sell this code - I'd be happy to pay for corrected functionality, after suffering MS' original offerings for many years. I know everyone has gone .NET, but I just can't get my head around that idea. VB's simplicity and feel just cannot be beaten. You've effectively built VB7  :Smilie: 

Thanks in advance.

----------


## Krool

> Can I download and test your current version?


Sure.  :Smilie: 




> 1. Do you accept bug fixes?


Feel free to report anything you like. Here public or private by PM.




> 2. Do you consider/accept compatible enhancements to original functionality? (Enhancements that were not intended functionality, broken or otherwise?)


Yes




> 3. How close are you on completing your goals for this project? In other words, are you just doing bugfixes at this stage, or do you have a lot more to add?


I am developing an MSFlexGrid replacement. (with more features and with bugfixes)
But that will be in a separate project. Not linked to this set of controls.
Concerning this project, I think the set of controls seems to be complete. However, bugfix support will be continued and also some more features, if necessary.
For example right-to-left support for all controls is still missing and is in work right now.

----------


## padbravo

Tks for the observation, DexWerx, also to Krool...

----------


## KurtB

> Sure. 
> 
> 
> Feel free to report anything you like. Here public or private by PM.
> 
> 
> Yes
> 
> 
> ...


Sounds good. How exactly do I download your files? When I click on the link, the forum replies with this:
*Not available for the moment, due to forum policy. Please PM me to get it by another way.*
Revision count will be updated here, for your reference.
I tried to PM you, but I couldn't figure out how to do that either. I have a feeling that I'm being an idiot...  :Frown:  Honestly, I did not read the 29 pages in this thread. Any help would be appreciated. I will be sure to thoroughly test your work, in return for your help  :Smilie:  Question about the FlexGrid: Will it provide cell editing capabilities? That's the most sorely missed control from the original set. I imagine I'm not the only guy to try to dynamically fit text boxes over grid cells - ugh!

Thanks again for what you do - it's like a dream come true.

----------


## DEXWERX

Proper Scrollbars and a Virtual Databound mode are probably more missed, than editing a flexgrid.

Also the link to download all the code - is at the bottom of the first post.

----------


## padbravo

Look... I was in the same situation as you...
"PM" means "send a private message", so, in order to get the download link, you need to send a private message to Krool, asking him to pass you a download link, not by "email" but in a message delivered to your inbox inside this site.

In order to do it:

You are missing the part, where it says to PM him.
Click on his name user name "Krool"
Click "Private Message"
Type in a message to ask him to email or send you a download link.

----------


## Karl77

> Proper Scrollbars and a Virtual Databound mode are probably more missed.


Yes.
And sorting capabilities.




> editing a flexgrid.


Yes, placing a textbox over a cell is the easiest job.
Also I'm against such comfort, as in my usage other things than just editing a cell can happen.
E.g. selecting a color or showing a popup menu...

When it comes to a flexgrid, we should wait until Krool opens a separate thread for it.
Before this thread becomes unreadable...

Karl

----------


## Krool

> Proper Scrollbars and a Virtual Databound mode are probably more missed, than editing a flexgrid.


Proper scrollbars. Haha, very true. It is a shame that MSHFlexGrid have problems when scrolling beyond 65,535 rows.
But enough now. As Karl77 mentioned the discussion gets off-topic.

----------


## Chris1969

Hi

I am trying to download these controls but not able to find the PM option to contract Krool.  Is this component information available anywhere else on the .net?

----------


## milan.opa

> Hi
> 
> I am trying to download these controls but not able to find the PM option to contract Krool.  Is this component information available anywhere else on the .net?


Me too !  I've just registered to this forum to be able to send the PM, but that option is not listed when clicking on "Krool". I have only "View profile" and "View forum posts" available.
Can it be that the account is too "fresh" ? 

Edited: After few hours (or posting this message), the option suddenly appeared. So I guess, you just have to be patient   :Smilie:

----------


## DEXWERX

Are you able to download the controls from the first post? All the controls are downloadable at the bottom the first post.
The "Demo" includes all the code.
You only need to PM Krool if you want the distributable OCX.

----------


## milan.opa

> Are you able to download the controls from the first post? All the controls are downloadable at the bottom the first post.
> The "Demo" includes all the code.
> You only need to PM Krool if you want the distributable OCX.


Yes, I wasn't aware that it is the source code of the project. Thank you.

----------


## Krool

Major update released.

The right-to-left properties are now implemented, beside some minor and one critical bugfix.

All controls (except ImageList, IPAddress, MCIWnd, HotKey and SysInfo control) includes now a RightToLeft and RightToLeftMode property.
Some controls includes in addition a RightToLeftLayout property.

The effect is different on each control.
But in general the RightToLeft property enables bi-directional reading and the RightToLeftLayout property turns on mirror placement.
If RightToLeftLayout is enabled, it is only active when also the RightToLeft property is enabled. (Like in .net)

The RightToLeftMode property controls of how the RightToLeft property should be checked.
It can be set to following:
- NoControl
- VBAME
- SystemLocale
- UserLocale
- OSLanguage

VBAME means the check will be done by VB itself. (effectively by VBAME.DLL)

----------


## dudley

> Me too !  I've just registered to this forum to be able to send the PM, but that option is not listed when clicking on "Krool". I have only "View profile" and "View forum posts" available.
> Can it be that the account is too "fresh" ? 
> 
> Edited: After few hours (or posting this message), the option suddenly appeared. So I guess, you just have to be patient


Glad I'm not the only one! I've been trying for the last week to figure out why I had no option to sen a PM either.
For any other newbies to the forum, I'm assuming you must post first before you get the PM option. (Hence this post  :Smilie: ).

This set of controls are awesome and have renewed my zeal to keep using VB6 for development.

----------


## Karl77

> Major update released.
> The right-to-left properties are now implemented, beside some minor and one critical bugfix.


I'm not very interested in RTL, but would like to know what the bugfixes are...

Karl

----------


## VbNetMatrix

> Glad I'm not the only one! I've been trying for the last week to figure out why I had no option to sen a PM either.
> For any other newbies to the forum, I'm assuming you must post first before you get the PM option. (Hence this post ).
> 
> This set of controls are awesome and have renewed my zeal to keep using VB6 for development.



With new control, like Lavolpe (Alpha Image) wich allow us to use PNG in vb6 and This new set of control, I too intend to keep develloping in Vb6.  I think I will post my "Microsoft Access" Library soon.  It is a Wrapper around ADO wich simplify Database related activity.  Maybe if Krool want to join me, I'll build a web site just for this purpose  :Smilie: 

interested Krool ?

----------


## DEXWERX

> With new control, like Lavolpe (Alpha Image) wich allow us to use PNG in vb6 and This new set of control, I too intend to keep develloping in Vb6.  I think I will post my "Microsoft Access" Library soon.  It is a Wrapper around ADO wich simplify Database related activity.  Maybe if Krool want to join me, I'll build a web site just for this purpose 
> 
> interested Krool ?


ADO is so simple, I just haven't seen a need for another abstraction. 
The only VB6 ORM I know of is here --> http://www.hisystems.com.au/databaseobjects/


@Karl77 from the first post.



> 28-Sep-2016
> - Fixed a critical bug in the 'Bands' property page in the CoolBar control that was caused by update on 07-Jul-2016.
> - Included the RightToLeft and RightToLeftMode property on supported controls.
> - Included the RightToLeftLayout property on some controls. (where mirror placement is applicable)
> - Included the RightToLeftMirror property in the ImageList control.
>   If enabled, an list image is drawn mirrored on a right-to-left device context (WS_EX_LAYOUTRTL) to preserve directional-sensitivity.
> - Some internal improvements to ensure right-to-left support. (e.g. use of MapWindowPoints instead of the ScreenToClient)
> - Bugfix in the TextBoxW control that the horizontal scrollbar could disappear on certain conditions.
> - Removed the Orientation property in the SpinBox control.
> ...

----------


## VbNetMatrix

> ADO is so simple, I just haven't seen a need for another abstraction. 
> The only VB6 ORM I know of is here --> http://www.hisystems.com.au/databaseobjects/
> 
> @Karl77 from the first post.


Simple.... yes I guess it is.  But are you using ADO with embeded control ? or manual ?
Because with manual utilisation, there is so much you need to take care of.
My control for example will tell you if you forgot to close a table of a database on leaving and you can therefore fix your code before it go into production.

Also, my control doesn't allow you to "try" to send the wrong data type into a field, it check it before trying to write into the Db.  it also Autoload all table and field into memory before you even open a table, allowing you to know exactly the database composition.  I also can open any Access Database without the password.  (sorry if MS screwed the security on that one)  I did that component because it is almost impossible to make a mistake that will crash your program with it.  it got error handle all over.  It support up to Access 2010 format (2013 is 2010 format)

----------


## Krool

Update released.

Now ListSubItems can display a ToolTipText. Also the ShowLabelTips property works as expected.
Problem with the ShowLabelTips property was that LVS_EX_LABELTIP should be the style bit which indicates if partially hidden labels lacks tool tip text, the ListView will unfold the label.
However, even if the LVS_EX_LABELTIP style bit is removed, the ListView insists on displaying the label tip. Therefore it must be an MS bug.

To solve this it was necessary to check for LVS_EX_LABELTIP on TTN_GETDISPINFO and TTN_SHOW in the ListView and on LVN_GETINFOTIP in the UserControl.
Also then it was possible to enable ToolTipText support for ListSubItems.

----------


## ChenLin

Why compressed files can not be extracted it?

----------


## Karl77

> Why compressed files can not be extracted it?


Download and use the current 7ZIP, then it works.
I also had problems because I used an older 7ZIP from 2015.

Karl

----------


## Krool

> Why compressed files can not be extracted it?


Also ensure to remove the .zip extension from the .z01.zip file. (.z01.zip -> .z01)

----------


## ChenLin

> Download and use the current 7ZIP, then it works.
> I also had problems because I used an older 7ZIP from 2015.
> 
> Karl


Thank you, 7ZIP can be directly extracted, this is indeed very good, winzip can not be directly extracted.

----------


## ChenLin

> Also ensure to remove the .zip extension from the .z01.zip file. (.z01.zip -> .z01)


Thank you Krool, according to the operation you said the success of the Karl installation of 7ZIP is very good, very convenient.

----------


## vitweb

Good afternoon,

I need the CommonControls control but I don't know how to contact Krool in private. I try to click on his user name (as suggested in a previous post) but I can see only "view profile" and "view forum posts".

Anyone can help, please?

Thank you,
Vittorio

----------


## Arnoutdv

All download links are in the 1st post, unless you need something specific.

----------


## vitweb

Hi Arnoutdv,

Thank you for answering. I have tried to go to the first post. When I click to version 1.3 of the ocx I am redirected to another post where there is this message:

"Not available for the moment, due to forum policy. Please PM me to get it by another way.
Revision count will be updated here, for your reference"

Thank you.

----------


## DEXWERX

> Hi Arnoutdv,
> 
> Thank you for answering. I have tried to go to the first post. When I click to version 1.3 of the ocx I am redirected to another post where there is this message:
> 
> "Not available for the moment, due to forum policy. Please PM me to get it by another way.
> Revision count will be updated here, for your reference"
> 
> Thank you.


At the very bottom of the first post is a Download for the Demo files. It contains the source to all the controls.

----------


## VB6-Guy

Great Demo...  Thanks! :Smilie:

----------


## Carlos Rocha

Hi Krool,

Something went wrong while sending you a private message asking for the OCX version. To avoid bloating your In-Box in case it was sent I'm asking it here, if possible.

Thank you

----------


## GaryW

Need to get a copy of a VB6.exe.manifest to use updated comctl32.dll

----------


## Krool

> Need to get a copy of a VB6.exe.manifest to use updated comctl32.dll


http://www.vbforums.com/showthread.p...ues&highlight=

----------


## Karl77

There is a problem with the CommonDialog.

For ShowSave, it doesn't return the entered filename + *extension*.
The original delivers the extension.



```
Dim CD      As CommonDialog
Dim TheFile As String
'--------------------------------------------------

Set CD = New CommonDialog

With CD
    .Flags = CdlOFNOverwritePrompt Or CdlOFNHideReadOnly Or CdlOFNExplorer
    .Filter = "?INI files" & "(*.ini)|*.ini|" & "?All files" & " (*.*)|*.*|"
    .DialogTitle = "?Export configuration"
    .InitDir = GS.Inifolder
    .ShowSave
    TheFile = .FileName
End With

Set CD = Nothing

MsgBox TheFile

End Sub
```

Example:
In the dialog, I enter 'BLA'.
The original returns 'C:\SomePath\BLA.INI'.
The kroolish returns 'C:\SomePath\BLA'.

Do I miss something?

Karl

----------


## Krool

> Do I miss something?


The DefaultExt property.

----------


## VbNetMatrix

> Need to get a copy of a VB6.exe.manifest to use updated comctl32.dll


Can you enlight me on this ??  wich updated comctl32.dll ??
I'm using v6.1.7601.18837, wich techniquely is the last that I know of.  and I don't use manifest.

----------


## VbNetMatrix

> http://www.vbforums.com/showthread.p...ues&highlight=


Hi Krool, I looked at your post on this... I don't understand why you're using this.  I'm on Win7x64 I don't have any problem with UAC (of course you need to set up your Shortcut link the proper way)  What would be my gain to use Manifest ?  I also tried to follow the method you described to see if any difference and Ressource Hacker refused to insert the res file.  Did I miss something ?

----------


## Karl77

> The DefaultExt property.


Thanks.
I never had to use it, the original seems to make it automatic.

Also the other replacement I formerly used.
From what I see here, the 'lpstrDefExt' only must not be empty to achieve this.

It wouldn't hurt if your controls would do the same.
But not very important for sure.

I can send you the code of the other replacement if wanted.

Karl

----------


## Krool

> It wouldn't hurt if your controls would do the same.
> But not very important for sure.
> 
> I can send you the code of the other replacement if wanted.


I agree that behavior should be the same.
Please share the other replacement.

----------


## Krool

Update released.




> From what I see here, the 'lpstrDefExt' only must not be empty to achieve this.


That was exactly the point. Thanks

I just needed to add the following code to get the expected behavior: (DefaultExt is an extra buffer)


```
If PropDefaultExt = vbNullString Then DefaultExt = vbNullChar Else DefaultExt = PropDefaultExt
.lpstrDefExt = StrPtr(DefaultExt)
```

Because when 'lpstrDefExt' is NULL (according to MSDN), no extension is appended at all.
Therefore in our case 'lpstrDefExt' should be never NULL, because we want an extension appended.
The DefaultExt property therefore only has effect when the Filter was *.*
The only scenario where no extension will be appended is when the selected filter was *.* and the DefaultExt is not set. (=vbNullChar)

----------


## swambast

This is spectacular work...wow, thank you.  However, I'm having an issue with the RichTextBox playing nicely with the Find dialog control.  

When I search for a word using the Find dialog box, it is not getting highlighted within the RichTextBox.  However, I know it is finding it, because once I close the Find/Replace dialog box, the RichTextBox suddenly gets the focus and the proper "found" word becomes highlighted.  What am I overlooking?

Also, is there a function that allows "Replace" as well or is it only restricted to the "FIND" property?

----------


## Krool

> This is spectacular work...wow, thank you.  However, I'm having an issue with the RichTextBox playing nicely with the Find dialog control.  
> 
> When I search for a word using the Find dialog box, it is not getting highlighted within the RichTextBox.  However, I know it is finding it, because once I close the Find/Replace dialog box, the RichTextBox suddenly gets the focus and the proper "found" word becomes highlighted.  What am I overlooking?
> 
> Also, is there a function that allows "Replace" as well or is it only restricted to the "FIND" property?


Look at the Demo. There you find a working find dialog. For the replace is actually the same. Use the Find method and then set the SelText property to your replace text.

----------


## swambast

Krool, yes I tried to reproduce that and that is the exact code bank I was using from the demo, but still same issue.  Part of resolution that helped was setting custom form to modeless but now there's still other errors on form load, and sometimes the RTB just grays out or won't load (not to mention all the other build dependencies as well).  So honestly Krool, despite my excitement and absolute interest in this, this is beyond me and I've simply spent far too much time trying to get everything to work...feel like I'm putting together a jigsaw puzzle here constantly with missing pieces.   :Confused:  

I'm going back to the standard controls now despite a few more .ocx and loss of visual themes - they just tend to work more straight forward and I have supporting code that covers the unicode issues anyway.  I wanted to say thanks for your efforts on providing us with another option though!   :Cool:

----------


## Krool

> Krool, yes I tried to reproduce that and that is the exact code bank I was using from the demo, but still same issue.  Part of resolution that helped was setting custom form to modeless but now there's still other errors on form load, and sometimes the RTB just grays out or won't load (not to mention all the other build dependencies as well).  So honestly Krool, despite my excitement and absolute interest in this, this is beyond me and I've simply spent far too much time trying to get everything to work...feel like I'm putting together a jigsaw puzzle here constantly with missing pieces.   
> 
> I'm going back to the standard controls now despite a few more .ocx and loss of visual themes - they just tend to work more straight forward and I have supporting code that covers the unicode issues anyway.  I wanted to say thanks for your efforts on providing us with another option though!


I bet your issues can be solved.
However, you might try the OCX version. (please pm me)

----------


## martin.matten

Hello Krool, I have downloaded and used "VBCCR13.OCX" as a replacement for "MSCOMCTL.OCX" on July 13th 2016. I had done this because of problems with that reference in my Access applications since August 2012. This problem occurred after a Windows Update from time to time. Generally, a workaround could be found in registering an older version, but lately this failed to work on certain PC's at a client site. The "VBCCR13.OCX" replacement worked fine for some time, but the client has now some new PC's that have problems with that replacement. The "MSCOMCTL.OCX" reference works fine for those PC's now. So this is confusing me of course. 
I can't dowload new versions of "VBCCR13.OCX", I would need to send you a pm. I just registered as a new member but I can't send a private message so far. 
Of course, would I solve my specific problem with a new version, or is this some recurring nasty registry problem that I'm suffering from?
Thanks in advance for your opinion.

----------


## lhartono

Hello Krool, 

how can I remove focus rect?

Thanks.

----------


## Krool

> how can I remove focus rect?


Find and remove all kinds of WM_CHANGEUISTATE messages.


```
SendMessage hWnd, WM_CHANGEUISTATE, MakeDWord(UIS_CLEAR, UISF_HIDEFOCUS Or UISF_HIDEACCEL), ByVal 0&
```





> would I solve my specific problem with a new version, or is this some recurring nasty registry problem that I'm suffering from?


A new version would certainly change nothing in that regard. I think it is some registry problem on your PC.

----------


## martin.matten

OK Krool, thanks for your opinion.
In the meantime I have made 2 runtime versions for my application. So far, if the version MSCOMCTL doesn't work, the VBCCR13 does,  or vice versa. Let's hope that this workaround will stand until we have a clear view on the registry problem behind...

----------


## chosk

> OK Krool, thanks for your opinion.
> In the meantime I have made 2 runtime versions for my application. So far, if the version MSCOMCTL doesn't work, the VBCCR13 does,  or vice versa. Let's hope that this workaround will stand until we have a clear view on the registry problem behind...


If you use VBCCR13 with the side-by-side resource provided, you will never encounter any problem caused by registry in the user computer. Your application will always run no matter what problem there may be with the registry.

The only consideration is minimum WinXP SP2, which is no longer a problem today.

----------


## martin.matten

> If you use VBCCR13 with the side-by-side resource provided, you will never encounter any problem caused by registry in the user computer. Your application will always run no matter what problem there may be with the registry.
> 
> The only consideration is minimum WinXP SP2, which is no longer a problem today.


Thank you chosk. However, I have to admit that I have never used a side-by-side resource myself as an Access programmer. The projects are adp or mdb files. The exe file is "msaccess.exe" which opens the project file. From the project file I can add references, but those need to be registered by "regsvr32.exe" first. Could I use a side-by-side resource also? Thanks for your help anyway!

----------


## chosk

Sorry, I missed the part about Access. Probably won't work then.

----------


## Arnoutdv

@martin.martin:
Then you should create an installation package to distribute and install the VBCCR13 on client computers.

----------


## martin.matten

> @martin.martin:
> Then you should create an installation package to distribute and install the VBCCR13 on client computers.


Thanks Arnout, however I must admit that I have never created an installation package so far either. I prefer to be honest even if this make me look behind reality ;-) I will go into further investigation whenever I run out of workarounds again.

----------


## Krool

Update released.

Fixed a bug in the Selected property of a Node in the TreeView control.
The issue was that a focused (but not selected) Node could not get the selected state by code.
That bug can be easily replicated by following code:


```
TreeView1.Nodes(1).Selected = Not TreeView1.Nodes(1).Selected
```

The code should toggle the selected state, but it was not working.
However, now it works. (like in the original MS control)

----------


## Semke

what is the latest version (build) of the OCX

----------


## putu.oka

Hi, i have project that already contain *.res file and it can't have more than one *.res file how i can implement this custom control without adding new res file from your project demo/example? because i realize that this control can't working fine without resources.res

----------


## DaveInCaz

Hello Krool, as many others have also said already, thanks for your outstanding work on this control library.

I may have found a slight difference in how VBCCR (still using 12) implements the CommonDialog.FilterIndex property as compared to Microsoft's. Our original code would specify a new value for .FilterIndex, then show the file open dialog, and then again read from .FilterIndex to see what file type the user selected.

Using VBCCR12, the .FilterIndex property does not get updated after the file selection. (It always returns back the same default which was set originally). However, reading MSDN ([1] and [2]) I'm not actually sure what it is supposed to do. It sounds like perhaps it is meant to be used ONLY for setting the default (not for reading the user's selection). But nonetheless the Microsoft version seemed to allow that and even if that was a bug on their part, it is now a difference in behavior.

I'm curious what your opinion of this issue is. Is there an approach for getting the selected filter (other than parsing the selected filename)?

Thanks again!

----------


## Semke

> This is the 1.3 ActiveX Control version. (Revision 10)
> 
> *Not available for the moment, due to forum policy. Please PM me to get it by another way.*


 I cannot pm you, could you send me the latest ocx please

----------


## Krool

> I may have found a slight difference in how VBCCR (still using 12) implements the CommonDialog.FilterIndex property as compared to Microsoft's. Our original code would specify a new value for .FilterIndex, then show the file open dialog, and then again read from .FilterIndex to see what file type the user selected.
> 
> Using VBCCR12, the .FilterIndex property does not get updated after the file selection. (It always returns back the same default which was set originally). However, reading MSDN ([1] and [2]) I'm not actually sure what it is supposed to do. It sounds like perhaps it is meant to be used ONLY for setting the default (not for reading the user's selection). But nonetheless the Microsoft version seemed to allow that and even if that was a bug on their part, it is now a difference in behavior.
> 
> I'm curious what your opinion of this issue is. Is there an approach for getting the selected filter (other than parsing the selected filename)?


Update released.
Thanks

----------


## dtencer

Thanks

----------


## Krool

Update released.

Fixed a bug in the NoImage property of a Button in the ToolBar control.
It was not possible to set the NoImage property of a Button to True when no ImageList was set.

Beside that, I have noticed another "point":
When an ImageList is set for a ToolBar control and this is changed to Nothing then the spaces for the Images are removed.
However, a ToolBar that has already no ImageList will display these spaces for the Images even when setting again the ImageList property to Nothing.
Only setting a valid ImageList and then setting to Nothing will remove these "spaces". But the spaces will come again if the ToolBar gets re-created.


So, there are then three options, which I hope to get some opinions:
1. keep as described above. (same as MS ToolBar)
2. Never show spaces for the images when there is no ImageList set.
3. Always keep the spaces for the Images in all scenarios.

----------


## chosk

I am not sure where this fall into which of the three options.

When an imagelist is set for the toolbar and there are buttons with images and there are also buttons without images, then for those buttons that do not have images there be no space for the image.

Edit to add:
This to apply only when TextAlignment is set to 1-Right. When TextAlignment is 0-Bottom, then images are expected for all buttons.

----------


## Krool

When ImageList is set all buttons expect images, to exclude a button there is the NoImage property.
But whats for the case when no ImageList is set?
You say for TextAlignment 0-Bottom keep the spaces and for 1-Right remove the spaces, right?

----------


## chosk

> When ImageList is set all buttons expect images, to exclude a button there is the NoImage property.
> But whats for the case when no ImageList is set?
> You say for TextAlignment 0-Bottom keep the spaces and for 1-Right remove the spaces, right?


Yes.

----------


## dtencer

Krool,
I have run into an issue that results in VB crashing upon stopping my test app in debug or closing my test app.

I have narrowed it down to this:
If you place as ListView control and a Button control on a form the add this code to the button:

Private Sub CommandButtonW1_Click()
   Dim loItem As LvwListItem

   For Each loItem In ListView1.ListItems
      loItem.Ghosted = False
   Next

End Sub

When you close the form or click Stop in debug mode VB6 will crash.
I can workaround this code by doing this:

Private Sub CommandButtonW1_Click()
   Dim loItem As LvwListItem
   Dim i as integer


   For i = 1 to ListView1.ListItems.Count
      Set loItem = ListView1.ListItems(i)
      loItem.Ghosted = False
   Next

End Sub

As I am evaluating using your control, it seems the intent is to have your control replace the CommonControls.
I am just wondering if there was a known list of differences so that I can be sure to make adjustments in my code and avoid any issues?

Any help here would be appreciated.
Thank you

----------


## Krool

> Krool,
> I have run into an issue that results in VB crashing upon stopping my test app in debug or closing my test app.
> 
> I have narrowed it down to this:
> If you place as ListView control and a Button control on a form the add this code to the button:
> 
> Private Sub CommandButtonW1_Click()
>    Dim loItem As LvwListItem
> 
> ...


Never noticed such thing. Can you make a demo? (Ensured the issue comes up)
Also do you use the Std-EXE or OCX version?
Beside that, pushing IDE stop button is not recommended, however closing form has to work..

----------


## dtencer

> Never noticed such thing. Can you make a demo? (Ensured the issue comes up)
> Also do you use the Std-EXE or OCX version?
> Beside that, pushing IDE stop button is not recommended, however closing form has to work..


I am using the .ocx.
Here is the behavior I am seeing: http://screencast.com/t/jx58rQBWI0C

I've attached a sample program:

Project1.zip

----------


## Krool

> I am using the .ocx.
> Here is the behavior I am seeing: http://screencast.com/t/jx58rQBWI0C
> 
> I've attached a sample program:
> 
> Project1.zip


I have tested on WinXP and Win7 and it worked fine.. hmm.
Does this happen when sample program is compiled? Does it also happen when using the Std-EXE version?
Did you test on other controls? (e.g. TreeView)

Anyone else having this issue?

----------


## Semke

hi, Thanks Krool (again, I can't stop thanking you)

How often do you update the OCX? I see in the latest revision (10) some thing are not included (like RTL support)

----------


## dtencer

> I have tested on WinXP and Win7 and it worked fine.. hmm.
> Does this happen when sample program is compiled? Does it also happen when using the Std-EXE version?
> Did you test on other controls? (e.g. TreeView)
> 
> Anyone else having this issue?


It does not happen when compiled.  But I have seen an issue like this before and if it does this in debug it will have a negative effect latter on the application.  One example is if I compile to a .dll then call from another .exe it will throw an exception.
I have not tried the Sdt-EXE version.
It works fine with the TreeView control, it seems to be isolated to the ListView.

Thanks

----------


## Krool

> It does not happen when compiled.  But I have seen an issue like this before and if it does this in debug it will have a negative effect latter on the application.  One example is if I compile to a .dll then call from another .exe it will throw an exception.
> I have not tried the Sdt-EXE version.
> It works fine with the TreeView control, it seems to be isolated to the ListView.
> 
> Thanks


Ok, difference between TreeView and ListView is following.
TreeView uses native Collection enumeration. ListView uses custom enumeration. (Enumeration.cls)
Because ListView need to be enumerated in visible order and not order of the collection.
I think that some reference is not terminated, thats why the crash.
I await your try with the Std-EXE version. There we can get closer to the cause and find out a solution.
However, as already said, I can not replicate the issue and thus I am dependent on you. :-)

----------


## dtencer

> Ok, difference between TreeView and ListView is following.
> TreeView uses native Collection enumeration. ListView uses custom enumeration. (Enumeration.cls)
> Because ListView need to be enumerated in visible order and not order of the collection.
> I think that some reference is not terminated, thats why the crash.
> I await your try with the Std-EXE version. There we can get closer to the cause and find out a solution.
> However, as already said, I can not replicate the issue and thus I am dependent on you. :-)


Please direct me to instruction on how to test/use the Std-EXE version.  I have only just discovered your .ocx.
Thank you

----------


## Krool

> Please direct me to instruction on how to test/use the Std-EXE version.  I have only just discovered your .ocx.
> Thank you


In the first post in this thread is the Std-EXE version. On that Demo you can actually test. You may need only to copy the OLEGuids.tlb in your SysWoW64 (64bit OS) or System32 (32bit OS) path first.

----------


## Krool

> How often do you update the OCX? I see in the latest revision (10) some thing are not included (like RTL support)


I update the OCX only for internal improvements or bugfixes. Additional features are not implemented to ensure compatibility.
The new features are collected and will be implemented all together in the next OCX release. (would be then VBCCR14.OCX)




> I am not sure where this fall into which of the three options.
> 
> When an imagelist is set for the toolbar and there are buttons with images and there are also buttons without images, then for those buttons that do not have images there be no space for the image.
> 
> Edit to add:
> This to apply only when TextAlignment is set to 1-Right. When TextAlignment is 0-Bottom, then images are expected for all buttons.


I have thought about this and came to the conclusion that by default the MS behavior should be respected.
Therefore when no ImageList is set the default image dimension will be set. Due to a bug in my ToolBar (and also in MS ToolBar) the image dimensions were set to 0x0 when removing an ImageList after a valid ImageList was set. I have fixed this bug now by setting the default dimensions "back" via TB_SETBITMAPSIZE.

But, as a second step, there could be also new properties to have actually control of what behavior you want to have.
So the new properties could be called "DefaultImageWidth" and "DefaultImageHeight" and would contain the image dimensions if no ImageList is set. (so called Default)
Of course, these properties would be set on init to the MS image dimensions to have the MS behavior.
But by changing these properties, e.g. to 0x0, you can actually then change the behavior.
What do you think?

----------


## chosk

> ...
> 
> I have thought about this and came to the conclusion that by default the MS behavior should be respected.
> Therefore when no ImageList is set the default image dimension will be set. Due to a bug in my ToolBar (and also in MS ToolBar) the image dimensions were set to 0x0 when removing an ImageList after a valid ImageList was set. I have fixed this bug now by setting the default dimensions "back" via TB_SETBITMAPSIZE.
> 
> But, as a second step, there could be also new properties to have actually control of what behavior you want to have.
> So the new properties could be called "DefaultImageWidth" and "DefaultImageHeight" and would contain the image dimensions if no ImageList is set. (so called Default)
> Of course, these properties would be set on init to the MS image dimensions to have the MS behavior.
> But by changing these properties, e.g. to 0x0, you can actually then change the behavior.
> What do you think?


Good.

----------


## Krool

Update released.

Bugfix in the ToolBar control, quite important in my opinion.
The bug appeared when all buttons have no caption and at least one button has the AutoSize property set to true.
That resulted in a messed up ButtonWidth/ButtonHeight property.

----------


## Krool

Again update released. This time an internal improvement.

WM_SETREDRAW was replaced with the LockWindowUpdate API in all internal ReCreate methods.

Problem was when the size of a control changed while the redraw state was locked, a "ghost" painting occured.
This will not happen with the LockWindowUpdate API, as it will invalidate the old bounding rectangle, forcing an eventual redraw.
Also LockWindowUpdate will not clear the WS_VISIBLE style bit, thus it is not necessary to check the visibility anymore.
The only downside is that LockWindowUpdate can only lock one window at a time.
So if another window is already locked then the ReCreate method will not clear the locking to break nothing. If that's the case there is no other option to have no locked redraw state, which results then in a flicker.

So the pros outweigh that single disadvantage of an eventual flicker when another window is already locked.

So instead of


```
Private Sub ReCreate[...]
Dim Visible As Boolean
Visible = Extender.Visible
With Me
If Visible = True Then SendMessage UserControl.hWnd, WM_SETREDRAW, 0, ByVal 0&
[...]
If Visible = True Then SendMessage UserControl.hWnd, WM_SETREDRAW, 1, ByVal 0&
.Refresh
End With
End Sub
```

now:


```
Private Sub ReCreate[...]
Dim Locked As Boolean
With Me
Locked = CBool(LockWindowUpdate(UserControl.hWnd) <> 0)
[...]
If Locked = True Then LockWindowUpdate 0
.Refresh
End With
End Sub
```

----------


## Krool

Update relased.

Finally the Transparent property is included in the ToolBar control.
DEXWERX has requested this twice.  :Smilie: 




> Slightly unrelated, but something possibly omitted (but is in the link you posted) Are you going to add TBSTYLE_TRANSPARENT to the toolbar?





> Now the question remains, can we get the Toolbar itself transparent (Design time Property of the toolbar / TBSTYLE_TRANSPARENT )


But, TBSTYLE_TRANSPARENT was not used for the Transparent property. It was implemented only to have the BackColor property shown/visible at design-time.
Instead, like in the other controls where a Transparent property is available, it makes a replica of the underlying background. (simulated transparency)
However, the property is ignored when the control paints via double-buffering. (same as BackColor; only working when DoublerBuffer = False)

----------


## Sam_

I love these controls, but I'm struggling with the DT Picker. Everything is as expected, apart from GetDayBold. Here's the code I am currently using but the behivior seems to happen in all cases even if i replace my code with the demo code



```
Private Sub dtp_CalendarGetDayBold(ByVal StartDate As Date, ByVal Count As Long, State() As Boolean)
    Dim rs As New ADODB.Recordset
    If Not QCOnly Then
        Set rs = LoadDatabase.Execute("SELECT DateDue, Count(*) AS [OrderCount] FROM Orders WHERE DateDue Between #" & Date2US(StartDate) & "# And #" & Date2US(StartDate + Count - 1) & "# AND HospitalCode = '" & HospitalCode & "' AND Hidden = False GROUP BY DateDue ORDER BY DateDue")
    Else
        Set rs = LoadDatabase.Execute("SELECT DateDue, Count(*) AS [OrderCount] FROM Orders WHERE DateDue Between #" & Date2US(StartDate) & "# And #" & Date2US(StartDate + Count - 1) & "# AND Investigation = 'Point Source' GROUP BY DateDue ORDER BY DateDue")
    End If
    Do While Not rs.EOF
        State(DateDiff("d", StartDate, rs.Fields("DateDue")) + 1) = True
        rs.MoveNext
    Loop
    rs.Close
    Set rs = Nothing
End Sub
```

(Date2US formats as mm/dd/yyyy string)

It is a hard feature to test, as the bold dates are only visible in a compiled program, but essentially I must change months then return for the correct dates to be highlighted. Any ideas?

*Edit:*
If i remove 

```
dtp.Value = Date
```

 from my form load event the dates are highlighted as I would expect (with a default value of '1/1/16' in the property page - also struggling to make this value stay when compiling not sure why). If I use 1/11/16 (so this month) I get the same behavior though, incorrect dates highlighted, switch months and switch back and all is well. I have tried 



```
Private Sub dtp_DropDown()
    Dim tDate As Date
    tDate = dtp.Value
    dtp.Value = "1/1/2001"
    dtp.Value = tDate
End Sub
```

along with various combinations of switching on and off .CalenderDayState and .Refresh in the Form_Load event.

If appropriate I can create my one thread, but this problem seems so specific to these controls I thought here would be fine...

----------


## Krool

Update released.

@ Sam_,
the CalenderDayState should work now as expected.
Thanks for reporting.

----------


## VbNetMatrix

Hi Krool ... about that bug...

just wondering... do you take into account that when using module (.bas) in an OCX, all "public" variable are SHARED for all instance ?

only variable in the .CTL are not shared (public and private)

I had a similar issue in past with that.  I can post you an exemple project that show the bug.

----------


## Sam_

> Update released.
> 
> Thanks for reporting.


Fantastic, thanks.

----------


## Krool

> just wondering... do you take into account that when using module (.bas) in an OCX, all "public" variable are SHARED for all instance ?
> 
> only variable in the .CTL are not shared (public and private)
> 
> I had a similar issue in past with that.  I can post you an exemple project that show the bug.


Which bug? Please show example.

----------


## ChenLin

Hi Krool,Why open the mainform vb6 collapse in the IDE?

----------


## VbNetMatrix

> Which bug? Please show example.


good question... my previous post didn't post  :Frown: 

I'll make an example, it's easier to explain.

----------


## Karl77

Hello Krool,

there is a small glitch in the ProgressBar control.
If you change the height *by code*, a 1px frame is seen around it.

To retrace:
Use the ComCtlsDemo.
In MainForm, set *VisualStyles = false* for ProgressBar1.

At the end of Form_Load, add:



```
With ProgressBar1
.Left = 100
.Top = 600
.Width = 5530
.Height = 270
End With
```

Now comment out the .Height = 270.
See the difference?

Karl

P.S.: tested at 125% screen

*EDIT2:*
While we are at that, a caption property for the progressbar would be nice.
Like in the old old CCRP.

----------


## Krool

> there is a small glitch in the ProgressBar control.
> If you change the height *by code*, a 1px frame is seen around it.
> 
> To retrace:
> Use the ComCtlsDemo.
> In MainForm, set *VisualStyles = false* for ProgressBar1.
> 
> At the end of Form_Load, add:
> 
> ...


Update released.

The problem was that normally a ProgressBar will be created with the WS_EX_STATICEDGE style bit.
However, when visual styles are enabled the style bit WS_EX_STATICEDGE is not set on window creation.
That's why this border issue only appears when using a manifest for comctl32.dll version 6.0 or higher and the VisualStyles property is set to False.

The solution was to set or remove the style bit WS_EX_STATICEDGE in the VisualStyles property.

Thanks for reporting.

For the caption property:
Yes, certainly good idea. But there are many ways of how to implement.
I imagine an "inverted" color text for classic theme and for visual theme a theme text within a white box rectangle. (for readability)

----------


## Karl77

Hello Krool,




> The problem was that normally a ProgressBar will be created with the WS_EX_STATICEDGE style bit.


great, it is fixed now.

In fact I meant it the other way around :-).
The border is not wanted, it makes problems when the control is nested in another control (statusbar in this case).

I'll try to change it myself, now as I know where to look.
Otherwise we would need a Border property... 





> For the caption property:
> Yes, certainly good idea. But there are many ways of how to implement.
> I imagine an "inverted" color text for classic theme and for visual theme a theme text within a white box rectangle. (for readability)


Let the user decide:
TextAutocolor
TextForeColor
TextBackColor
TextBackgroundColor
something like that.

Thank you.

----------


## Krool

> The border is not wanted, it makes problems when the control is nested in another control (statusbar in this case).
> 
> I'll try to change it myself, now as I know where to look.
> Otherwise we would need a Border property...


It's difficult to have no border as it's back always when the control size has been changed.

----------


## VbNetMatrix

> Update released.
> ...
> That's why this border issue only appears when using a manifest for comctl32.dll version 6.0 or higher and the


Speaking of it, can you post a full example on how to use a manifest for comctl32.dll ?
I never succeeded to make it right on Win7

thanks

----------


## Krool

> Speaking of it, can you post a full example on how to use a manifest for comctl32.dll ?
> I never succeeded to make it right on Win7
> 
> thanks


Just look the Demo..

----------


## Karl77

> It's difficult to have no border as it's back always when the control size has been changed.


Yes, I experienced this too.
Solution seems to be simple:



```
Public Property Let VisualStyles(ByVal Value As Boolean)
PropVisualStyles = Value
If ProgressBarHandle <> 0 And EnabledVisualStyles() = True Then
    Dim dwExStyle As Long, dwExStyleOld As Long
    dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE)
    dwExStyleOld = dwExStyle
    If PropVisualStyles = True Then
        ActivateVisualStyles ProgressBarHandle
        If (dwExStyle And WS_EX_STATICEDGE) = WS_EX_STATICEDGE Then dwExStyle = dwExStyle And Not WS_EX_STATICEDGE
    Else
        RemoveVisualStyles ProgressBarHandle
        If Not (dwExStyle And WS_EX_STATICEDGE) = WS_EX_STATICEDGE Then
            dwExStyle = dwExStyle And Not WS_EX_STATICEDGE
        End If
    End If
    'If dwExStyle <> dwExStyleOld Then
    SetWindowLong ProgressBarHandle, GWL_EXSTYLE, dwExStyle
    Call ComCtlsFrameChanged(ProgressBarHandle)
    'End If
    Me.Refresh
End If
UserControl.PropertyChanged "VisualStyles"
End Property
```

EDIT:
This is also the place where a Border property could snap to.

----------


## Krool

> Yes, I experienced this too.
> Solution seems to be simple:
> 
> 
> 
> ```
> Public Property Let VisualStyles(ByVal Value As Boolean)
> PropVisualStyles = Value
> If ProgressBarHandle <> 0 And EnabledVisualStyles() = True Then
> ...


What does that solve when resizing?
You changed the part on RemoveVisualStyles, but there is an error on your change.



```
        RemoveVisualStyles ProgressBarHandle
        If Not (dwExStyle And WS_EX_STATICEDGE) = WS_EX_STATICEDGE Then
            dwExStyle = dwExStyle And Not WS_EX_STATICEDGE
        End If
```

Should be:


```
        RemoveVisualStyles ProgressBarHandle
        If (dwExStyle And WS_EX_STATICEDGE) = WS_EX_STATICEDGE Then
            dwExStyle = dwExStyle And Not WS_EX_STATICEDGE
        End If
```

As you want no border in both cases.

----------


## swambast

Had a clarifying question - does the new CommandButtonW make any improvements to visual styles/themes?  For example, when doing a side by side comparison of the new CommonControls replacement command button vs. the default VB6 style, they look identical.  I know there are a lot more features with the new CommandButtonW such as side-by-side captioning, image alignment, split buttons, etc. but is there any change in the actual visual style (e.g., a more modern WinXP or other style upgrade)?

----------


## Karl77

> What does that solve when resizing?


Apparently it works, no border comes back on resize.
Try it...




> As you want no border in both cases.


Not exactly, I don't want the border in classic style only.

Karl

----------


## Karl77

> any improvements to visual styles/themes?


The style is given by the OS setting, and the controls use exactly this style.
Nothing less and nothing more.

Karl

----------


## Krool

Update released.

Critical bugfix in the ListBoxW control. The Click event was not fired in two cases:
- User has de-selected an item in a multiple-selection list box
- User has clicked again on a selected item in a single-selection list box

I'm surprised that this bug did not pop up earlier..

----------


## Romeo91

Hi, Krool!
Quiet updated common.bas file(Not seen in the history of changes) - it has new features replaces the standard-VB
There is an error:
FileLen function has always "0" return value.

----------


## Krool

> Quiet updated common.bas file(Not seen in the history of changes) - it has new features replaces the standard-VB
> There is an error:
> FileLen function has always "0" return value.


Yes, thanks for this side note. The common.bas includes also functions not necessary for this project. Therefore I do not add in history of changes when updating.
The function FileLen was actually not complete..
I completed the function now and actually improved it. The return value is now as a 'Decimal' Variant. So it can hold unsigned big integer value. (kind of ULONGLONG)

----------


## VbNetMatrix

Hi, 

did I missed something ?

in post #1

The latest update of   ComCtlsDemo.zip (december 7th 2016)

doesn't compile because of missing reference "OLE Guid and interface definition"
"Implements OLEGuids.IOleInPlaceActiveObjectVB" in "IpAdress.ctl"

Do I need any tlb that I doesn't have ?

thanks for your help

----------


## chosk

From post #1:



> At design time (IDE) there is only one dependency. (OLEGuids.tlb)


It is included in the download.

----------


## VbNetMatrix

> From post #1:
> 
> It is included in the download.


you're right... when I first installed it, I read everything about the component, now I was at work and tried to download and nothing worked...  forgot about it.  litle brain, litle brain...

----------


## Krool

Update released.

Modified the OLEGuids.tlb. (with new uuid)
And sorry for this inconvenience. I know it is a pain in the *** to replace everything, but I couldn't keep it like it is.  :Big Grin: 

The IEnumerationVB interface is now removed as not necessary anymore as the Enumeration.cls is event driven since a while. (due to de-coupling issues)
The IEnumeration interface was actually always IEnumVARIANT. But it was named as IEnumeration to not intefere with the stdole.IEnumVARIANT.
But as the IUnknown interface was already named IUnknownUnrestricted to not interfere with the stdole.IUnknown I could also name it likewise to IEnumVARIANTUnrestricted, so I did now. So it is now a clear definition..

And, of course, the correction in IDispatch.GetIDsOfNames was made. (thanks to DEXWERX)



> your IDispatch.GetIDsOfNames has the wrong definition?
> It should be LPWSTR, so you can pass in a BSTR. This way VB skips the Conversion, and you can skip the DoubleUnicode hack you did here.

----------


## ScriptBASIC

Thanks for the update to 1.3. It works fine on XP, Win7 and Win10.

HERE is a Script BASIC IDE/Debugger (VB6 app) example.

I hope to be test your library with an OLE interface from Script BASIC to VB6 form controls.

*Update*

Your COM replacement control works fine when generated as an ActiveX *.exe* control.

----------


## Krool

Update released.

I need to explain a little bit about the recent changes in the ListView control...

The included NewWidth parameter in the ColumnAfterResize event is useful when TrackSizeColumnHeaders property is False, because when ColumnAfterResize is called the new width is not yet applied. So doing ColumnHeader.Width will return the old width.
Also the NewWidth parameter is 'ByRef', which means it can be modified in that event. By that it is possible to define a min/max width for column resizing.
Or to cancel the new width at all, example:


```
Private Sub ListView1_ColumnBeforeResize(ByVal ColumnHeader As LvwColumnHeader, Cancel As Boolean)
ColumnHeader.Tag = ColumnHeader.Width
End Sub

Private Sub ListView1_ColumnAfterResize(ByVal ColumnHeader As LvwColumnHeader, NewWidth As Single)
If [CancelCondition] = True Then NewWidth = ColumnHeader.Tag
End Sub
```

In the 15-Dec-2016 update I included the HDN_DIVIDERDBLCLICK handler in the ColumnBeforeResize event as it effects the width of a column header.
However, there is no HDN_ENDTRACK fired by HDN_DIVIDERDBLCLICK.
That's why on this update (16-Dec-2016) I isolated HDN_DIVIDERDBLCLICK and included the new event ColumnDividerDblClick, which also has a Cancel parameter.

When the ResizableColumnHeader property is set to False there is no resizing possible at all and also no ColumnBeforeResize nor ColumnDividerDblClick are generated.




> Your COM replacement control works fine when generated as an ActiveX *.exe* control.


I don't get it. You mean generating an ActiveX .exe control? (do you mean .OCX or really .exe ?)
The downside for ActiveX .exe is that they don't work with regfree manifest..

----------


## ScriptBASIC

> I don't get it. You mean generating an ActiveX .exe control? (do you mean .OCX or really .exe ?)
> The downside for ActiveX .exe is that they don't work with regfree manifest..


The reason I'm using a *.exe* ActiveX control rather that a *.dll* version is the .exe version doesn't need to be registered before use. Good to know about the *regfree* issue. I was just playing around with the idea of using VB forms as controls and interacting with them from Script BASIC but *IUP* as a cross platform native GUI is the better solution. Using VB to create the *IDE* is a good example how I plan to us your library in the future.

----------


## Romeo91

> Yes, thanks for this side note. The common.bas includes also functions not necessary for this project. Therefore I do not add in history of changes when updating.
> The function FileLen was actually not complete..
> I completed the function now and actually improved it. The return value is now as a 'Decimal' Variant. So it can hold unsigned big integer value. (kind of ULONGLONG)


Hi!
Krool, function FileLen still contains an error.
If someone does not see, it can affect its program code



```
' (VB-Overwrite)
Public Function FileLen(ByVal PathName As String) As Long
Const INVALID_HANDLE_VALUE As Long = (-1)
Const GENERIC_READ As Long = &H80000000, FILE_SHARE_READ As Long = &H1, OPEN_EXISTING As Long = 3, FILE_FLAG_SEQUENTIAL_SCAN As Long = &H8000000
Dim hFile As Long, Length As Double
If Left$(PathName, 2) = "\\" Then PathName = "UNC\" & Mid$(PathName, 3)
hFile = CreateFile(StrPtr("\\?\" & PathName), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)
If hFile <> INVALID_HANDLE_VALUE Then
    Length = GetFileSize(hFile, 0)
    CloseHandle hFile
Else
    Err.Raise Number:=53, Description:="File not found: '" & PathName & "'"
End If
End Function
```

Always - FileLen=0

----------


## Krool

> Hi!
> Krool, function FileLen still contains an error.
> If someone does not see, it can affect its program code
> 
> 
> 
> ```
> ' (VB-Overwrite)
> Public Function FileLen(ByVal PathName As String) As Long
> ...


You posted the old code. The new returns Decimal Variant. Please re-download and check again.

----------


## Romeo91

> You posted the old code. The new returns Decimal Variant. Please re-download and check again.


File common.bas in fresh archive (from 17 December 2016) from 5 December.
This code from this file

----------


## chosk

The Function is expecting a return of FileLen as Long 

I think change the line


```
Length = GetFileSize(hFile, 0)
```

to


```
FileLen = GetFileSize(hFile, 0)
```

----------


## Krool

The function should be like this:



```
' (VB-Overwrite)
Public Function FileLen(ByVal PathName As String) As Variant
Const INVALID_HANDLE_VALUE As Long = (-1), INVALID_FILE_SIZE As Long = (-1)
Const GENERIC_READ As Long = &H80000000, FILE_SHARE_READ As Long = &H1, OPEN_EXISTING As Long = 3, FILE_FLAG_SEQUENTIAL_SCAN As Long = &H8000000
Dim hFile As Long
If Left$(PathName, 2) = "\\" Then PathName = "UNC\" & Mid$(PathName, 3)
hFile = CreateFile(StrPtr("\\?\" & PathName), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)
If hFile <> INVALID_HANDLE_VALUE Then
    Dim LoDWord As Long, HiDWord As Long, Value As Variant
    LoDWord = GetFileSize(hFile, HiDWord)
    CloseHandle hFile
    If LoDWord <> INVALID_FILE_SIZE Then
        If (LoDWord And &H80000000) Then
            Value = CDec(LoDWord And &H7FFFFFFF) + CDec(2147483648#)
        Else
            Value = CDec(LoDWord)
        End If
        If (HiDWord And &H80000000) Then
            HiDWord = HiDWord And &H7FFFFFFF
            Value = Value + (CDec(HiDWord) + CDec(2147483648#)) * CDec(4294967296#)
        Else
            Value = Value + CDec(HiDWord) * CDec(4294967296#)
        End If
        FileLen = Value
    Else
        FileLen = Null
    End If
Else
    Err.Raise Number:=53, Description:="File not found: '" & PathName & "'"
End If
End Function
```

----------


## fafalone

Was just noticing the columns in the ListView control weren't behaving like my normal setups... would definitely request support for column autosizing.. both the basic LVS_EX_AUTOSIZECOLUMNS style and the LVCOLUMN members you can use with it (cxMin, cxDefault, and cxIdeal)

----------


## Krool

> Was just noticing the columns in the ListView control weren't behaving like my normal setups... would definitely request support for column autosizing.. both the basic LVS_EX_AUTOSIZECOLUMNS style and the LVCOLUMN members you can use with it (cxMin, cxDefault, and cxIdeal)


There is already a AutoSize method in the ColumnHeader, just in case you oversaw it.
Anyhow, will check your other suggestions soon.
Thanks

----------


## fafalone

LVSCW_AUTOSIZE and LVSCW_AUTOSIZE_USEHEADER are entirely different than LVS_EX_AUTOSIZECOLUMNS, the latter prevents resizing to 0 (exact size is auto adjusted to the presence of image, checkbox, split button or filter too), automatically scales all columns as the ListView is resized both smaller then larger again, and is required to set the minimum width with .cxMin. The Autosize method that's there now just does a single scale operation on a single column when called. They're both useful for sure, just different.


In this pic, columns 1, 2, and 4 have been resized as small as they're now allowed with the auto-set width. Column 1 has a checkbox and a splitbutton, column 2 just a split button, and column 4 only text. No additional resizing code needed.


Here the ListView has been resized, and columns 3 and 5 have both been automatically scaled down, no other code involved.

The .cxMin allows setting a min width larger than LVS_EX_AUTOSIZECOLUMNS allows alone.

----------


## AcidJeff

Hi, Krool. How can I get the VBCCR13.OCX? I am newly registered here in the forum and can't send PMs.

----------


## Krool

Update released.

As the ResizableColumnHeaders property does not need anymore comctls32.dll version 6.1 or higher to work it is only consistent that also the Resizable property of a ColumnHeader will work when the comctls32.dll version is below 6.1.

The bugfix in the ResizableColumnHeaders was in the 'Get' function.
It returned always True in case the property is not supported. (not supporting = resizable)
But now as the support barrier is gone it must return of course the actual property value.




> Hi, Krool. How can I get the VBCCR13.OCX? I am newly registered here in the forum and can't send PMs.


I sent you a pm.

----------


## AcidJeff

> Update released.
> 
> As the ResizableColumnHeaders property does not need anymore comctls32.dll version 6.1 or higher to work it is only consistent that also the Resizable property of a ColumnHeader will work when the comctls32.dll version is below 6.1.
> 
> The bugfix in the ResizableColumnHeaders was in the 'Get' function.
> It returned always True in case the property is not supported. (not supporting = resizable)
> But now as the support barrier is gone it must return of course the actual property value.
> 
> 
> I sent you a pm.


Thank you very much.

----------


## Romeo91

Hi Krool.
Change .Value option on OptionButtonW (also CheckboxW) does not generate a click event.
It is right?

----------


## Krool

Update released.




> Change .Value option on OptionButtonW (also CheckboxW) does not generate a click event.
> It is right?


Yes, your are right.. Thanks for reporting.
This is now fixed, also in the OCX version. Certainly this was the last 'event loophole', hopefully.  :Wink:

----------


## Krool

Update released.

In this update the mouse events were improved. It concerns the button and shift states for the various mouse events, such as MouseMove.

Before this update the states were retrieved using GetAsyncKeyState.
Now the states are retrieved using the wParam value of the message. (except the ALT shift state, this is retrieved using GetKeyState, not GetAsyncKeyState)
This change might be also a minor performance boost as less API calls are now involved.

However, the main improvement is that the correct button value is now passed in case the left and right mouse button are "swapped" in the windows settings.

----------


## torrid33

How do we download the files?  I saw something about PM'ing you but I can click your profile and it does not give a way to PM you.

Also will these fix the problem of trying to use common dialog control in windows 7 in the VB6 IDE... gives a message that I don't have proper licensing to use the control (which makes no sense).
i.e. switch to your replacements and avoid all of the common dialog issues

----------


## Krool

> How do we download the files?  I saw something about PM'ing you but I can click your profile and it does not give a way to PM you.
> 
> Also will these fix the problem of trying to use common dialog control in windows 7 in the VB6 IDE... gives a message that I don't have proper licensing to use the control (which makes no sense).
> i.e. switch to your replacements and avoid all of the common dialog issues


You can download the Std-EXE version at the first post of this thread. Note that the .z01.zip must be renamed to .z01 before unpacking.
The licensing issue is of course avoided when using a replacement.

----------


## Krool

Important update released.

As of this update all key and mouse events are now improved. I recommend to replace all components..

In fact now in all message handlers is now the GetKeyState API used.
(-> GetShiftStateFromParam/GetMouseStateFromParam and GetShiftStateFromMsg/GetMouseStateFromMsg functions)

GetAsyncKeyState is therefore not used anymore.
(-> GetShiftState/GetMouseState function)

The improvement is now that always the "buffered" shift and button state is passed into the events and not the "current" state anymore.
This can be important when the application is unresponsive for some time.
Another important improvement is the "correct" mouse button state when the left and right mouse buttons are swapped in the system settings.
GetKeyState returns always the state of the logical mouse button, whereas GetAsyncKeyState returns the state of the physical mouse button.
Therefore the SM_SWAPBUTTON mapping is only done in the GetShiftState/GetMouseState (GetAsyncKeyState) function and not in the others, for info.

Sorry for the inconvenience caused and the "wrong" handling in the past.

----------


## Elroy

Krool, I've said it before but it's worth repeating.  This is _truly_ a phenomenal effort, and I'm continually impressed with your willingness to listen to suggestions for improvements.

Someday, I should attempt to follow your lead and include the MSFLXGRD.OCX and TABCTL32.OCX in this endeavor.  The FiexGrid might be a bit of work, as it has some rather complex features.  However, the TabControl is nothing but a fancy container that just shifts the controls off to the left when you click the different tabs.  Knowing what I know about it, I could probably mock one up pretty quickly using the TabStrip and PictureBox, which you've already done.

----------


## yokesee

Hi Elroy , you have received my private message
Problems sending it will not let me send them, it does not appear to me as sent.
Sorry for disturbing this post
a greeting

----------


## Krool

> Someday, I should attempt to follow your lead and include the MSFLXGRD.OCX and TABCTL32.OCX in this endeavor.  The FiexGrid might be a bit of work, as it has some rather complex features.  However, the TabControl is nothing but a fancy container that just shifts the controls off to the left when you click the different tabs.  Knowing what I know about it, I could probably mock one up pretty quickly using the TabStrip and PictureBox, which you've already done.


A FlexGrid replacement is already in process as said earlier. But will take some time as the first shot should be a complete replacement and quite stable.
However, that control will fit into this architecture (so the folder can included along the other controls) but will be separated from this here. As the FlexGrid is no "common control" and quite complex.

----------


## vb56390

hi, Krool

 I want a copy of the newest version of the VBCCR13.OCX , it is best to bring the source code , thx
 you can send me by address : 198838369(please replace with @)163.com

 Best Regards

----------


## Romeo91

Hi, Krool!
My project Crashes when the program exits from the event Form_KeyDown (Unload Me)
Crashes in IDE and exe-compiled.
If the exit from the program by pressing the cross, all ok.

My project is large, and are also used by other components using subsclassing, but error generate this function


```
Public Property Let SubclassEntry(ByVal Entry As Long, ByVal Value As Boolean)
Entry = Entry - 1
Dim EntryPointer As Long
Debug.Assert Entry >= 0 And Entry <= PropVTableCount And VTableHeaderPointer <> 0
If Me.SubclassEntry(Entry + 1) Xor Value Then
    EntryPointer = UnsignedAdd(VTableHeaderPointer, Entry * 4)
    If Value = True Then
        Call CreateSubclass(EntryPointer, vTable(Entry), VTableOld(Entry))
    Else
        Call CreateSubclass(EntryPointer, VTableOld(Entry), 0)
        VTableOld(Entry) = 0
    End If
End If
End Property
```

Check please, when will be the time
P.S. https://github.com/ADIAProject/DIA

----------


## Krool

> Hi, Krool!
> My project Crashes when the program exits from the event Form_KeyDown (Unload Me)
> Crashes in IDE and exe-compiled.
> If the exit from the program by pressing the cross, all ok.
> 
> My project is large, and are also used by other components using subsclassing, but error generate this function
> 
> 
> ```
> ...


I cannot replicate this crash in the Demo. Would be too easy of course if it also crashes there on Form_KeyDown. ;-)
I did not check your project, maybe you can try to narrow down the cause more on your own. For instance removing some of your other subclasses and so on.
Also it would be a try worth to use the OCX and see what happens there.

----------


## Romeo91

Hi Krool.
Small bug in OptionButtonW
If set .value=true for OptionButtonW, when close form and reopen i see that in Gui .value=false (no dot), in options .value=true

----------


## Krool

> Small bug in OptionButtonW
> If set .value=true for OptionButtonW, when close form and reopen i see that in Gui .value=false (no dot), in options .value=true


Fixed. Thank you.
Also small bug in CheckBoxW. The Click event was not fired when changing the Value property by code and when the DrawMode is OwnerDraw.
The OCX version was also updated for this bug.

----------


## vb56390

hello Krool, how can I get an "OCX" version of CommonControls (Replacement of the MS common controls) ?

----------


## Mahdi Jazini

@Krool

I want to use this ocx but before using i have 2 questions:

1) is this ocx completely free? should we buy it? (because i saw a screen shot with a title bar that there was a demo text in it)

2) did you write it yourself? or copied from another company website to this thread?

Thank you

----------


## Krool

> 1) is this ocx completely free? should we buy it? (because i saw a screen shot with a title bar that there was a demo text in it)


Its free, nothing to buy. Where did you see the screen shot with demo text? You mean the demo project at first page? This is in fact the Std-EXE version and the leading version and the OCX derived from this from time to time. (Half or full year)




> 2) did you write it yourself? or copied from another company website to this thread?


It's written by myself. Though I got inspired by vbaccelerator, which is also open source free.

----------


## Mahdi Jazini

> Where did you see the screen shot with demo text? You mean the demo project at first page? This is in fact the Std-EXE version and the leading version and the OCX derived from this from time to time. (Half or full year)


Yes, at the first page




> It's written by myself. Though I got inspired by vbaccelerator, which is also open source free.


Thank you for writing this project. it can help me so much because it supports unicode

Again thank you for sharing it free. God bless you  :wave:

----------


## Mahdi Jazini

Krool your ocx was so useful but there is a problem in ListBoxW

It doesn't support text align

Persian and Arabic languages need this property

Could you add these properties:

TextAlign
TextDirection

If a text starts with a number:

for example: 2 کرول

at this time (TextAlign=Right) can't help but (TextAlign=Right) + (TextDirection=RTL) can help very much

TNX  :Smilie:   :wave:

----------


## Krool

> Krool your ocx was so useful but there is a problem in ListBoxW
> 
> It doesn't support text align
> 
> Persian and Arabic languages need this property
> 
> Could you add these properties:
> 
> TextAlign
> ...


There is a RightToLeft property available in ListBoxW.  :Wink:

----------


## Krool

Update released.

Quite important bugfix for ListBoxW control. When the control has no items (empty) the .NewIndex property returned 0 instead of -1.
The ComboBoxW control was not affected, it already returned correctly -1 in this case.

Also enhanced the ListBoxW control when using it as an OLE drop target.
Included the InsertMark/InsertMarkColor property and HitTestInsertMark function.
The InsertMark property and the HitTestInsertMark function have both an optional 'After' parameter.
The demo project has been extended so that the ListBoxW control accepts OLE drop, showing the InsertMark functionality.

----------


## ChenLin

If there is a print preview of the good, such as support for DataGrid, mshflexgrid.

----------


## Mahdi Jazini

> There is a RightToLeft property available in ListBoxW.


But there is no this property in your ListboxW

This property is only in the classic listbox:



```
list1.RightToLeft=True
```

Where can i find the above property in your ocx?

TNX  :Smilie:

----------


## chosk

> But there is no this property in your ListboxW
> 
> This property is only in the classic listbox:
> 
> 
> 
> ```
> list1.RightToLeft=True
> ```
> ...


It is not implemented in the OCX ListboxW yet. It is implemented in the Std-EXE ListboxW.

----------


## Mahdi Jazini

> It is not implemented in the OCX ListboxW yet. It is implemented in the Std-EXE ListboxW.


How to use Std-EXE ListboxW ?

What's Std-EXE ?

Can you help me?  :Frown: 

Tnx

----------


## Krool

> How to use Std-EXE ListboxW ?
> 
> What's Std-EXE ?
> 
> Can you help me? 
> 
> Tnx


Yes, as chosk pointed out, the RightToLeft property is not available in the OCX yet. (only Std-EXE)
When you run the Demo project in the first page, that is a Std-EXE project. And there is also the Std-EXE ListBoxW used.
Just include the necessary components into your project. You actually don't need the whole OCX if you are just looking to implement a Unicode ListBox..




> If there is a print preview of the good, such as support for DataGrid, mshflexgrid.


what is a print preview of the good? There is only a PageSetup and a Print dialog in CommonDialog.cls, no print preview..

----------


## Mahdi Jazini

> Yes, as chosk pointed out, the RightToLeft property is not available in the OCX yet. (only Std-EXE)
> When you run the Demo project in the first page, that is a Std-EXE project. And there is also the Std-EXE ListBoxW used.
> Just include the necessary components into your project. You actually don't need the whole OCX if you are just looking to implement a Unicode ListBox..


Ahhhh

Tnx, i have got it

Std-EXE = The standard exe (Open Source) version

I have found the RightToLeft property in it

Thank you  :wave:

----------


## Mahdi Jazini

@Krool: your useful ActiveX resolved another problem:

http://www.vbforums.com/showthread.p...in-RichTextBox

Thank you again  :Smilie:   :wave:

----------


## DaveDavis

> @Krool: your useful ActiveX resolved another problem:
> 
> http://www.vbforums.com/showthread.p...in-RichTextBox
> 
> Thank you again


@Mahdi Jazini : Love God is good. But please keep it in our hear instead of waste VBForums resource, the sentence occupied space and my mobile data flow, we normally use the signature for links of useful stuff.

----------


## Mahdi Jazini

The following example not working:



```

RichTextBox1.RightToLeft = True
RichTextBox1.Text = "Krool"
```

The following example worked fine:



```

RichTextBox1.RightToLeft = True
RichTextBox1.Text = "Krool"
RichTextBox1.Text = RichTextBox1.Text & ""
```

!!!!  :Confused:

----------


## Krool

Update released.

The standard windows list box control has a 16-bit barrier when dragging the scroll box. (SB_THUMBPOSITION and SB_THUMBTRACK)
That limitation could be circumvented in the ListBoxW control by intercepting WM_HSCROLL/WM_VSCROLL and using the 32-bit GetScrollInfo function.

Also included the ScrollTrack property which controls if SB_THUMBTRACK will set the new position. (If set to False only SB_THUMBPOSITION has an effect)
Setting ScrollTrack to False could be an performance boost when using some code in the Scroll event.

@ Mahdi Jazini,
changing the RightToLeft in the RichTextBox control at run-time can be strange as the TextRTF itself does hold some rtl information.
The safest way to change it at run-time is to do following:


```
RichTextBox1.TextMode = RtfTextModePlainText
RichTextBox1.RightToLeft = True
RichTextBox1.TextMode = RtfTextModeRichText
```

----------


## chosk

Hi Krool,

Any chance of an earlier release of the OCX with the LabelW VerticalAlignment property?

----------


## Krool

Update released.

the 32-bit thumb scrolling support works now properly in each "scenario" in the ListBoxW control.
Means vertical scolling is always 32-bit.
Horizontal scrolling is only 32-bit when also the MultiColumn property is set to True.
Else it remains 16-bit, which is the case for 'HorizontalExtent' scrolling. And that should certainly be sufficient.  :Wink: 
Sorry for the confusion..




> Any chance of an earlier release of the OCX with the LabelW VerticalAlignment property?


I also think it gets time to bring out the next OCX release.
But as the forum rules are restricted about closed binaries I am thinking of publishing the source code along the binary.
This way I could upload everything in "UtilityBank - Components" and make a link from here to there.

What you guys think?

----------


## DEXWERX

> I also think it gets time to bring out the next OCX release.
> But as the forum rules are restricted about closed binaries I am thinking of publishing the source code along the binary.
> This way I could upload everything in "UtilityBank - Components" and make a link from here to there.
> 
> What you guys think?


 :Thumb:  x2 from me.
thanks either way!

----------


## VB6-Guy

Hi Krool,
I wold love a new OCX version with the updates.  I wold also like to know if the Palettes for selecting colors in the new .OCX would now work.
Thanks for the great work!

----------


## chosk

> ...
> I also think it gets time to bring out the next OCX release.
> But as the forum rules are restricted about closed binaries I am thinking of publishing the source code along the binary.
> This way I could upload everything in "UtilityBank - Components" and make a link from here to there.
> 
> What you guys think?


I am also okay either way. I see a lot of new forum users having problem with sending PM. If you release OCX source code, you may want to provide a "warning" on avoiding compatibility issue if any after the release of source code. But I guess using the reg-free manifest method should avoid this.

----------


## Jonney

> Update released.
> 
> the 32-bit thumb scrolling support works now properly in each "scenario" in the ListBoxW control.
> Means vertical scolling is always 32-bit.
> Horizontal scrolling is only 32-bit when also the MultiColumn property is set to True.
> Else it remains 16-bit, which is the case for 'HorizontalExtent' scrolling. And that should certainly be sufficient. 
> Sorry for the confusion..
> 
> 
> ...


Krool, OCX version should not free. You can get a little money from commercial users for inspiration.
Free always means poor service and slow bugs removal. For reliability and unity, I prefer OCX is sealed with close source.

----------


## Mahdi Jazini

> Update released.
> 
> the 32-bit thumb scrolling support works now properly in each "scenario" in the ListBoxW control.
> Means vertical scolling is always 32-bit.
> Horizontal scrolling is only 32-bit when also the MultiColumn property is set to True.
> Else it remains 16-bit, which is the case for 'HorizontalExtent' scrolling. And that should certainly be sufficient. 
> Sorry for the confusion..
> 
> 
> ...


The open source (standard exe) version was enough for me  :Smilie: 

In my opinion, this ActiveX is very valuable. Krool has lost more time on this project... Time is very important... I'm not a rich person otherwise I'll pay a very high price for it... Instead, i can pray for krool every month, and i think it's so valuable than money... every month 1 unique prayer just for krool  :Smilie:   :wave:  God bless him

----------


## chosk

Krool,

Maybe you consider to delay the decision to release the OCX source code and give yourself more time to decide. I also do support a paid OCX should you decide to go that direction.

----------


## Krool

> Maybe you consider to delay the decision to release the OCX source code and give yourself more time to decide. I also do support a paid OCX should you decide to go that direction.


Thanks for your opinion. I'm not money driven on this project. And actually those people with some knowledge could just build the OCX out of the Std-EXE version.




> Free always means poor service and slow bugs removal. For reliability and unity, I prefer OCX is sealed with close source.


First point I don't agree, but certainly with your second point I do agree.

So I still don't know.  :Smilie:

----------


## Elroy

> Free always means poor service and slow bugs removal.


I also rather strongly disagree, but just didn't want to be the first to say it.  I think it's important to differentiate between _free_ and _open-source_.  Those two terms mean something entirely different.  For instance, we can find _all kinds_ of free software.  However, it's often not open-source.  

And, on the other hand, just because a program is open-source doesn't mean it has to be free.  My work is a prime example of that.  I distribute (and wrote) a large application used by many orthopedic hospitals.  It assists with assessing the gait (walking ability) of a person.  It's all open-source, but I also charge nice consulting fees to come in and modify various reports and/or make additional enhancements to it (such as the recent addition of a "balance" protocol, with work ongoing to make it work with a variety of hardware platforms).

Also, the idea that free (or open-source) means poor service is antithetical to many facts.  I'd give myself as an example, but let's use Krool instead.  He's incredibly active and responsive in this thread (as are many others who've posted in the codebank).  Also, we can look at two rather classic examples: The Unix OS (and all its derivatives) and the C language.  Both are open-source and _extremely_ actively maintained and enhanced by a vibrant open-source community.

Sure, there are plenty of examples of abandoned-and-buggy open-source, but there are also plenty of examples of abandoned-and-buggy proprietary (for profit) software.  If software is abandoned, I'd much rather have it be open-source than closed-source.  The actual VB6 IDE comes to mind as a classic (and extremely irritating) example of an abandoned closed-source program.  

Best Regards,
Elroy

----------


## Mahdi Jazini

Difference between the *classic Combobox* with the *Combobox designed by @Krool*:

*In Classic Combobox:*



```

            Dim Tcombo As Integer
            For Tcombo = 1 To 10
                Combo1.AddItem (CStr(Tcombo))
            Next Tcombo

            Combo1.text={Recordset Data}
```

After that, All items of the classic combobox (added before) will be deleted  :EEK!: 

*In the Combobox designed by @Krool*



```

            Dim Tcombo As Integer
            For Tcombo = 1 To 10
                ComboBoxW1.AddItem (CStr(Tcombo))
            Next Tcombo

            ComboBoxW1.text={Recordset Data}
```

After that, the text value will be selected in the combox without removing the last data  :Smilie:   :wave: 

*Edited:*

Difference between the *classic Richtextbox* with the *Richtextbox designed by @Krool*: His Richtextbox supports Zoom *.ZoomFactor*

----------


## Krool

> Difference between the *classic Combobox* with the *Combobox designed by @Krool*:
> 
> *In Classic Combobox:*
> 
> 
> 
> ```
> 
>             Dim Tcombo As Integer
> ...


For me on both cases will be nothing deleted..

----------


## vb56390

I think open source is great, but you spend a lot of time for the project, should be rewarded, I want to take this project to translate into Chinese so that China programmers can use, if approved, I can also do pay.

----------


## Mahdi Jazini

> For me on both cases will be nothing deleted..


My VB version is: Ver. 6.0 (Version 8176)

Anyway i have deleted the classic combo box and replaced with yours  :Smilie:

----------


## Krool

Update released.

As in the ListBoxW control the 32-bit thumb scrolling support has been implemented into the ComboBoxW control.

Beside that another point is resolved.
On 29-Feb-2016 update I noticed that CB_GETCOMBOBOXINFO "seems" to be not supported on Windows 2000.
So I made then on that time an workaround to retrieve at least the edit handle.
However, .hWndList was still 0 when using Windows 2000.

Now I found out that there is a GetComboBoxInfo API in user32.dll, and that works as of Windows 2000.
In MSDN is described that the GetComboBoxInfo API is equivalent to CB_GETCOMBOBOXINFO.
Although CB_GETCOMBOBOXINFO returns 1 (success) in Windows 2000 there is no handle returned. But GetComboBoxInfo API works, odd?

So I decided to just replace CB_GETCOMBOBOXINFO with the GetComboBoxInfo API, then it will work in any case.  :Roll Eyes (Sarcastic):

----------


## Krool

Update released.

By now I think one of the last differences between intrinsic VB controls and my controls are resolved.

Before this update the Locked property in my ComboBoxW control only prevented text change (by user) in the edit control.
However, selecting items in the list box portion was possible. In the VB ComboBox this is not possible.
So now the Locked property is
1. supported in all three ComboBox styles
2. works like in the original, means no user select possible.

To achieve this the ComboBoxW control needs now to subclass also the internal ListBox (.hWndList) control. (So now everything is being subclassed  :Smilie: )
However, this subclass was also necessary to have 32-bit thumb scrolling support. So the additional subclass has it "right to exist" in my opinion.  :Wink: 

Info: ComCtlsIDEStopProtectionHandler() was amended accordingly. (subclass of .hWndList)

Edit: Same improvements implemented into the ImageCombo control.

----------


## ScriptBASIC

Krool,

Would it possible to script a VB6 form and controls using your VBCCR13.OCX on the fly? I'm able to interact with a VB6 form generated as an ActiveX/OCX form control now.

----------


## Semke

> Thanks for your opinion. I'm not money driven on this project. And actually those people with some knowledge could just build the OCX out of the Std-EXE version.
> .


that is so true, I used to do that but then I thought of the conflict that could happen if my ocx would find itself on a pc with an ocx of somebody else enjoying this forum. I therefore use the ocx version. I rarely use the Std-EXE version, only when I need no more then 1 or 2 controls.


thanks krool, I am looking forward for the next ocx version
you are the greatest.

----------


## Semke

Hi Again

while its not part of the common controls, but the control is quite common, I am of course referring to the office ribbon, did you ever consider working on that?

----------


## Krool

Big announcement.  :Smilie: 

The new 1.4 ActiveX Control version is now released. You can find the link to it in the first page of this thread.
Or here: http://www.vbforums.com/showthread.p...55#post5129155

The source code is also included. But please refrain from building another binary out of it as this will cause redundancies.
If modification is necessary please rename the library before.




> I am looking forward for the next ocx version


Done.  :Wink: 




> Would it possible to script a VB6 form and controls using your VBCCR13.OCX on the fly? I'm able to interact with a VB6 form generated as an ActiveX/OCX form control now.


I don't know what you mean. But creating controls on the fly should be possible with Controls.Add. (?)

----------


## Semke

Thank you, So much

----------


## ScriptBASIC

> But creating controls on the fly should be possible with Controls.Add


I may have to instantiate a blank form as an ActiveX DLL before adding controls via scripting. I'll let you know how it works out. Thanks for 1.4 and all your hard work to keep VB6 relevant.

----------


## Krool

Update released.

Again bugfixes, this time the ListBoxW control.

First bug was a non-critical behavior bug in a multi-column checkbox style list box. Default behavior is that checking a checkbox is possible even when the item is not selected before, but then it must be a "direct click" within the checkbox. And that was not working.

Second bug (supposedly a nasty "MS bug") is that everything goes crazy (top index gets negative) when both RightToLeft and MultiColumn are set to True.
But that could be solved by a little workaround on control creation.

The OCX is also updated accordingly with these two fixes.

----------


## Krool

Update released.

No bugfix this time, but new feature.

The Style property in the ListBoxW control can now be '2 - Option', beside '1 - Checkbox' and '0 - Standard'.
With this the list box can have options that are mutually exclusive.

Benefit to a OptionButton-Array is obvious as it inherits some useful features like scrolling, sorting, data binding and multi-column.

With the new 'OptionIndex' run-time property the app can control the current checked item.
Setting OptionIndex to -1 will clear everything.
However, the ItemChecked property can also be used. Also the ItemBeforeCheck and ItemCheck events are called by this.



Second point is for the ListView.
There is a behavior difference between MS ListView version 5.0 and 6.0.
By that new property 'AutoSelectFirstItem' the behavior can be chosen actually. By default it is True to match the behavior of MS 6.0 ListView.

EDIT:
Fixed a bug that the item's checkboxes/options were not drawn grayed in a disabled non-standard Style ListBoxW control.
On update from 18-Oct-2016 was only the text fixed to drawn grayed in that case, but not the button itself.

The OCX has been updated accordingly that the checkboxes will now drawn grayed in a disabled Checkbox Style ListBoxW control. (options not available in OCX)

----------


## Semke

> The OCX has been updated accordingly that the checkboxes will now drawn grayed in a disabled Checkbox Style ListBoxW control. (options not available in OCX)


What do you mean, "options not available in OCX" not available in *this* update or will *never* be available?

----------


## Krool

> What do you mean, "options not available in OCX" not available in *this* update or will *never* be available?


That means it will not be available in the 1.4 OCX.
Will be available in 1.5 OCX. (future version)

----------


## VbNetMatrix

> That means it will not be available in the 1.4 OCX.
> Will be available in 1.5 OCX. (future version)


Hi Kroll, 

I got a problem with last update.  I have registered OleGuids in sysWow64 as usual...
but when I ran demo in IDE, I got:

"To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher."

then IDE crash. (Vb6 IDE close down unexpectly)

I look all over forum, could you please give me a step by step on how to install the whole thing ?
1. install Oleguids  in Syswow64 ?  regtlib Oleguids.tlb ??
2. over last version, do we need to uninstall the Oleguids, if so, wich method do you use, RegTlib doesn't have -u
3. do we need manifest, if so, how to implement, where to place the file

thanks for everythings.

----------


## Krool

> Hi Kroll, 
> 
> I got a problem with last update.  I have registered OleGuids in sysWow64 as usual...
> but when I ran demo in IDE, I got:
> 
> "To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher."
> 
> then IDE crash. (Vb6 IDE close down unexpectly)
> 
> ...


The .Groups functionality in ListView is causing the error. (When no manifest for VB6.exe)

There is a On Error Resume Next in the Demo to avoid the crash.
However it only works when setup following:

- In order to trap error raises via "On Error Goto ..." or "On Error Resume Next" it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error Trapping.

----------


## Darkbob

> Hi Kroll, 
> 
> I got a problem with last update.  I have registered OleGuids in sysWow64 as usual...
> but when I ran demo in IDE, I got:
> 
> "To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher."
> 
> then IDE crash. (Vb6 IDE close down unexpectly).


I get the same thing.  This is such an amazing project but it's a shame the demo doesn't run at all. 

I read in another link you need to hack the VB6.EXE file to include resources.  Frankly I have no idea what a manifest is and I'm a bit reluctant to hack the VB6.EXE - but if I have to, I'll do it.  I downloaded a resource hacker and gave it a go but no luck.

I know it must be simple to get it up and running but honestly coming in late in the game like this and see the demo crash and burn it's tempting to just say "meh it doesn't work" and move on.  

Still, I'm determined to ditch some of these old MS dependencies and move on to something more modern - without having to ditch VB6 entirely.  It would be great if there was some kind of comprehensive install guide.

----------


## Cube8

> I get the same thing.  This is such an amazing project but it's a shame the demo doesn't run at all. 
> 
> I read in another link you need to hack the VB6.EXE file to include resources.  Frankly I have no idea what a manifest is and I'm a bit reluctant to hack the VB6.EXE - but if I have to, I'll do it.  I downloaded a resource hacker and gave it a go but no luck.
> 
> I know it must be simple to get it up and running but honestly coming in late in the game like this and see the demo crash and burn it's tempting to just say "meh it doesn't work" and move on.  
> 
> Still, I'm determined to ditch some of these old MS dependencies and move on to something more modern - without having to ditch VB6 entirely.  It would be great if there was some kind of comprehensive install guide.


http://www.vbforums.com/showthread.p...nifest-Creator

----------


## Darkbob

Thanks for the general info link.  I'm afraid it doesn't really help in this case.

Digging into this project a bit I've found the problem is in the Public Function ComCtlsSupportLevel() 

On my computer it's return a null.  

Digging deeper it looks like I'm running some DLL that's at v5.82.  ComCTLsSupportLevel is written in such a way as to return 1 if you have v6.0 and 2 if you have higher than 6.0 but it doesn't handle a situation where you have anything lower than 6.

I modified the routine to return a value of 2 and the demo now runs.  But clearly something's wrong either with this routine or with my VB install.

Edit.  Further digging and I see my version of ComCtl32.OCX - digitally signed by Microsoft November 2, 2016 is version 5.82.  I'm guessing I have an old version of ComCtl32.OCX somehow? 



Whats weird is that ComCTL32.dll is 6.1.

----------


## VbNetMatrix

> http://www.vbforums.com/showthread.p...nifest-Creator


that's very nice but it doesn't tell us what to include in the manifest so Vb6.exe DON'T CRASH.

----------


## VbNetMatrix

> Whats weird is that ComCTL32.dll is 6.1.


Where did you get that information? how can you make such deduction?  I'm tyring to understand, you lost me here.,
What is your OS ?
I'm on Win7x64, in my Syswow64, my version of comctl32.dll is 5.82.7601.18837

plz post more.

----------


## VbNetMatrix

I know your product is great...  and I'm pretty sure you did it this way for a reason.
however, the question remain:

1. install Oleguids in Syswow64 ? regtlib Oleguids.tlb ??
2. over last version, do we need to uninstall the Oleguids, if so, wich method do you use, RegTlib doesn't have -u
3. do we need manifest, if so, how to implement, where to place the file

as for the on error hack, I got other class that I use that need to use the error debug as it is by default.
so I'm stuck...

and finally... it doesn't explain why the Vb6 IDE completely crash and close upon this error.  are you subclassing ? (if so I missed it)

----------


## chosk

Using a manifest to use ver 6 of comctl32.dll has been well publicized in many sources on the Internet.

This began during the time long ago when WinXP was the then latest Windows and that is like 15 or 16 years ago. That was the time when VB6 users wanted to use the XP Theme for the software they wrote so that they will look modern. This same manifest method also works to make VB6 software work with the new themes in WinVista, Win7, Win8 and Win10.

This is the same manifest method that is asked here.

For reading of what this manifest thing is all about**:

Making VB Apply XP Visual Styles at Design and Debug Time

This links in that page are not working, they both point to:

Adding XP Visual Styles to Your Visual Basic Application

Read the para titled *Manifests*. You can ignored the para titled "Ensuring Your Application Links to ComCtl32.dll" because Krool has already handled that in the source.

Hope this helps.

----------


## Krool

> I know your product is great...  and I'm pretty sure you did it this way for a reason.
> however, the question remain:
> 
> 1. install Oleguids in Syswow64 ? regtlib Oleguids.tlb ??
> 2. over last version, do we need to uninstall the Oleguids, if so, wich method do you use, RegTlib doesn't have -u
> 3. do we need manifest, if so, how to implement, where to place the file
> 
> as for the on error hack, I got other class that I use that need to use the error debug as it is by default.
> so I'm stuck...
> ...


If you change the error trapping setting the On Error ... will work in both UserControl and Class Module. So dont worry.

The OLEGuids you can actually just overwrite by copy&paste.

----------


## VbNetMatrix

> Using a manifest to use ver 6 of comctl32.dll has been well publicized in many sources on the Internet.  (...) like 15 or 16 years ago.


Must have missed that... but then again, 15 years ago, I was already making my own skin for all my commercial program.

I just don't like too much how people act on forum when you ask a question and they are like "you should know it"
and then provide link that talk about the subject, but not answering the question directly. and you have to dig and dig and look at like 10 web site with different discussion on the subject to finally find what you're looking for.

this being said, this information is very apreciated and I'm glad you enlight me on this.

----------


## chosk

The links I posted have all the explanation and implementation. They answer your questions directly. They do it better than I can if I were just give the answer without explanation. After all, the posts were the authoritative source back at that time and it is better you read direct from Steve McMahon, rather than from me. HE is the man.

I was merely trying to explain the background of how the use of manifest to use v6 of comctl32.dll came about.

----------


## VbNetMatrix

> The links I posted


thanks... and don't take my answer bad.  It was really apreciated.

----------


## chosk

Hi Krool,

I have a project has many forms and I started it when it was still VBCCR13.ocx. Now I want to move the project to VBCCR14.ocx and looking for a more efficient way instead of manually redoing all the controls on all the forms, realigning, resizing, etc. which can be very tedious.

I experimented first starting a simple test project to use VBCCR13.ocx. Then I made the following changes to the test project files to VBCCR14.ocx:

1) In Project1.vbp:
Change
Object={07C05129-C2E5-483C-8237-8636C3F11E4E}#1.1#0; VBCCR13.ocx
to
Object={A99BDCD4-AB6D-490E-A03D-BF90764CBC6B}#1.0#0; VBCCR14.ocx

2)In Form1.frm
Change
Object = "{07C05129-C2E5-483C-8237-8636C3F11E4E}#1.1#0"; "VBCCR13.ocx"
to
Object = "{A99BDCD4-AB6D-490E-A03D-BF90764CBC6B}#1.0#0"; "VBCCR14.ocx"

Within the Begin VB.Form Form1... End Loop,
change all
Begin VBCCR13.<control> <control name>
to
Begin VBCCR14.<control> <control name>

The "converted" test project seems to work. Is this a safe way? Are there unforeseen consequences?

Thanks

Edit to add:
I should have done a search on the Internet before I posted. I just found  OCX Updater .

I tested and it works. I think it change automatically what I would have change manually.

Thanks anyway.

----------


## lrd_VB6

Hello

I changed my converter to the new version (v14)

1 Open your project with "Charger VBP"
2. The conversion is done ....
3. The project is converted for the new version (v14) :Thumb: 

Converted files are saved (.bak)

----------


## chosk

Hi Ird_VB6,

I did not realize a solution already existed in this thread. Now bookmarked.

Thanks.

----------


## Krool

Update released.

The RightToLeft property did not work in the TabStrip control. (but only when RightToLeftLayout is set to False)
Reason was that the control apparently ignores the WS_EX_RTLREADING flag. Instead the TCIF_RTLREADING mask bit must be included on each tab item.
Somehow this fact I had overlooked when the RightToLeft properties got included..

The OCX has been updated accordingly.

----------


## Darkbob

Quite impressive!  The demo still crashes VB6 so that doesn't instill confidence.  And I've had zero luck with any of the visual styles and manifest and all that.  But using the OCX is fairly simple.  Nice easy drop-in replacement for the standard controls.  Thanks!

----------


## Krool

Update released.

Bugfix in the ImageCombo control.
Changing the Text property of a ComboItem did not work as expected.
The Text when adding a ComboItem is not effected. (of course, else the bug would have been noticed already)

I hope that this was one of the last stupid bugs..

The OCX has been updated accordingly.

----------


## DEXWERX

> Quite impressive!  The demo still crashes VB6 so that doesn't instill confidence.  And I've had zero luck with any of the visual styles and manifest and all that.  But using the OCX is fairly simple.  Nice easy drop-in replacement for the standard controls.  Thanks!


That's the reason people prefer the OCX. You don't have to be a VB expert to use it and deploy normally.

----------


## Cube8

I have a special problem with RichTextBox.
Until now, I subclassed a textbox, in order to catch WM_CONTEXTMENU and show a custom popup menu. I have a class that does all the dirty work of subclassing and unsubclassing. Basically, it captures this message and it shows the menu.
I tried it with RichTextBox control but it doesn't work as expected. Although it works when pressing the appropriate key on the keyboard (next to the right ctrl), the class doesn't receive the WM_CONTEXTMENU message then right clicking the control.
I looked at the control's subclassing code but I didn't see anywhere any message-consuming statement. Or maybe I missed something.

I considered using the control's ContextMenu event but it would be too much of a hassle to recreate the custom-menu-process just for this control.
BTW, my subclassing method works as is with your textboxes, so it must be something with RichTextBox that prevents the message from arriving.

Thanks in advance.

----------


## Krool

> I have a special problem with RichTextBox.
> Until now, I subclassed a textbox, in order to catch WM_CONTEXTMENU and show a custom popup menu. I have a class that does all the dirty work of subclassing and unsubclassing. Basically, it captures this message and it shows the menu.
> I tried it with RichTextBox control but it doesn't work as expected. Although it works when pressing the appropriate key on the keyboard (next to the right ctrl), the class doesn't receive the WM_CONTEXTMENU message then right clicking the control.
> I looked at the control's subclassing code but I didn't see anywhere any message-consuming statement. Or maybe I missed something.
> 
> I considered using the control's ContextMenu event but it would be too much of a hassle to recreate the custom-menu-process just for this control.
> BTW, my subclassing method works as is with your textboxes, so it must be something with RichTextBox that prevents the message from arriving.
> 
> Thanks in advance.


There is no WM_CONTEXTMENU message for the RichTextBox control.
However, there is a '*OLEGetContextMenu*' and '*OLEContextMenuClick*' event available in my RichTextBox control.
The usage is demonstrated in the ComCtlsDemo project. (RichTextBoxForm.frm)

----------


## Cube8

There is, since you handle it:


```
Private Function WindowProcControl(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case wMsg
...
    Case WM_VSCROLL, WM_HSCROLL
        ' The notification codes EN_HSCROLL and EN_VSCROLL are not sent when clicking the scroll bar thumb itself.
        If LoWord(wParam) = SB_THUMBTRACK Then RaiseEvent Scroll
    Case WM_CONTEXTMENU
        If wParam = RichTextBoxHandle Then
            Dim P As POINTAPI, Handled As Boolean
            P.X = Get_X_lParam(lParam)
            P.Y = Get_Y_lParam(lParam)
            If P.X > 0 And P.Y > 0 Then
                ScreenToClient RichTextBoxHandle, P
                RaiseEvent ContextMenu(Handled, UserControl.ScaleX(P.X, vbPixels, vbContainerPosition), UserControl.ScaleY(P.Y, vbPixels, vbContainerPosition))
            ElseIf P.X = -1 And P.Y = -1 Then
                ' If the user types SHIFT + F10 then the X and Y coordinates are -1.
                RaiseEvent ContextMenu(Handled, -1, -1)
            End If
            If Handled = True Then Exit Function
        End If
    
...
End Select
...
End Sub
```

Also, as I mentioned before, the context-menu-key on the keyboard works fine.

----------


## Krool

Update released.

Two bugfixes in the SelPrint and PrintDoc methods in the RichtTextBox control.
1. RightMargin/BottomMargin were added to the printable area instead deducted.
2. The printable area was not converted from device units to twips. (the paper area was not wrong)

The 1. bug was truly my fault (stupid bug again), but the impact was not that critical.
But the 2. bug was critical and I give MSDN the fault for this.  :Mad:  (and partially me for not noticing the error)

MSDN: https://msdn.microsoft.com/de-de/lib...=vs.85%29.aspx
In their code the paper area is converted from device units to twips. But in the printable area they did not convert.


```
// Set page rect to physical page size in twips.
fr.rcPage.top    = 0;  
fr.rcPage.left   = 0;  
fr.rcPage.right  = MulDiv(cxPhys, 1440, GetDeviceCaps(hDC, LOGPIXELSX));  
fr.rcPage.bottom = MulDiv(cyPhys, 1440, GetDeviceCaps(hDC, LOGPIXELSY)); 

// Set the rendering rectangle to the pintable area of the page.
fr.rc.left   = cxPhysOffset;
fr.rc.right  = cxPhysOffset + cxPhys;
fr.rc.top    = cyPhysOffset;
fr.rc.bottom = cyPhysOffset + cyPhys;
```

When I tested the functionality at beginning I did only a simple tests with some words and this worked of course.  :Roll Eyes (Sarcastic): 
But now I tried to print a real document and wondered that it got wrapped in the middle of the printer page...

So, that's the story, with a happy end now.  :Smilie: 

The OCX has been updated accordingly.

@ Cube8,
I reviewed the point again with the context-menu.
If EM_SETOLECALLBACK is used in the RichTextBox control then WM_CONTEXTMENU will not be sent.
Instead the other OLE events will be send as described previously.
I just let the WM_CONTEXTMENU handler in for the case the EM_SETOLECALLBACK will not be used.
So if you want to have WM_CONTEXTMENU to be sent then set a comment in Sub CreateRichTextBox: (see red line)


```
    Dim This As OLEGuids.IRichEditOleCallback
    ' Set This = RichTextBoxOleCallback
    If Not This Is Nothing Then
        RichTextBoxIsOleCallback = CBool(SendMessage(RichTextBoxHandle, EM_SETOLECALLBACK, 0, ByVal ObjPtr(This)) <> 0)
    Else
        RichTextBoxIsOleCallback = False
    End If
```

However, a lot of other functionality will be lost. So I recommend to use the other OLE events to get a context-menu.

----------


## Cube8

Yes, commenting that statement does the job. Thank you.

I have added a new property _OleCallbackEnabled_ [True (default)/False]. Then, instead of just commenting out this statement, I put an _If_ statement before that one. After changing the property, it calls _ReCreateRichTextBox_ and everything works as expected.
You could merge this small change to the code for cases like mine.

Thank you for this wonderful project.  :Thumb:  :Smilie:

----------


## Krool

Again modified the SelPrint and PrintDoc routines in the RichtTextBox control.
It now checks if the passed hDC is a printer or not and acts then differently.
A printer DC will be processed like before and split into pages, if necessary.
But if it is a non-printer DC (e.g. PictureBox.hDC) then it will print only what will fit on the screen. (same behavior like in the MS RichTextBox)

The OCX has been updated accordingly.

----------


## Semke

I just noticed a  few controls called HotKey, CommandLink, Pager What is it? what are these?
also how do you use the Coolbar?

----------


## DEXWERX

> I just noticed a  few controls called HotKey, CommandLink, Pager What is it? what are these?
> also how do you use the Coolbar?


https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Coolbar = Rebar.
CommandLink = SysLink

----------


## LOfADay

Hi Krool, amazing stuff! What are your terms of use? LGPL? I'd like to use your controls, especially with your specific permission, in my project www.vb64.com (I'm sure you noticed on the other forum ?) -- a replacement IDE for VB6. With your permission, I'd be very happy to put you at the top of the credits.

Work on it is progressing well and am hoping to release a VBScript editing version as a freebie to whet appetites. Obviously VBScript has no controls and I'd like to look at releasing with it a standard control set, as compiled OCX's, based on yours. 

You are obviously a devoted VB6er as I am -- VB6 represented a paradigm shift, and I am determined to bring that paradigm back. I got some stick for making it commercial, but I think that's the only pragmatic way to make it happen, and it protects users as well (see Commercial ). Anyway, the early VBScript version will be free.

----------


## labmany

Firstly, keep up the great work. 

Secondly, when I place one or more control from the following list:

CommandButtonW 
TextBoxW
SpinBox
OptionButtonW
FrameW
CheckBoxW

on a form, create the EXE along with a .manifest file, compile and run the 'Project1.exe' and close it on my Development machine all is OK.

I copied the 'Project1.exe' and 'Project1.exe.manifest' to a new fresh Windows 7 Ultimate SP1 32bit (virtual Machine) and ran it I got the following message:

"Project1 has stopped working... 
check online... 
close the program..." 


If I add another/extra control other than any of the above list the error does not show anymore!


The attached example is running OK on my development machine but it gives:
Runtime error '0' on the Virtual/Fresh Windows on start up (Project1.exe)

Also with the attached example, I selected and deleted all controls Except CommandButtonW control, compiled and ran on the Fresh Windows and it gave:

Runtime error '50003'
Unexpected error

Again, keep up the great work.

----------


## Krool

> Secondly, when I place one or more control from the following list:
> 
> CommandButtonW 
> TextBoxW
> SpinBox
> OptionButtonW
> FrameW
> CheckBoxW
> 
> ...


Thanks for your report and thus help improving the project.

I did a first test and could resolve the problem when removing all properties (not whole control) from the form1.frm (via Notepad) when there is a reference to "form1.frx".
After that the Project1.exe works fine.
So, the problem is then that something goes corrupt on form1.frx at a certain point. However, I was not yet able to isolate the cause and when it happens.

----------


## Krool

@ labmany,

I have found now the properties which are "corrupt".
When you remove the following lines (marked as red) in the .frm file it will work again:



```
   Begin VBCCR14.ImageList ImageList1 
      Left            =   30
      Top             =   915
      _ExtentX        =   1005
      _ExtentY        =   1005
      ImageWidth      =   24
      ImageHeight     =   24
      InitListImages  =   "Form1.frx":02BC
   End
[...]
   Begin VBCCR14.CommandButtonW CommandButtonW1 
      Height          =   1770
      Left            =   4350
      TabIndex        =   2
      Top             =   2550
      Width           =   4005
      _ExtentX        =   7064
      _ExtentY        =   3122
      [...]
      Appearance      =   0
      BackColor       =   -2147483643
      ForeColor       =   -2147483640
      Caption         =   "Form1.frx":34BA
      Picture         =   "Form1.frx":34E4
      SplitButton     =   -1  'True
      DownPicture     =   "Form1.frx":51BE
   End
```

Maybe the pictures you have loaded and that are then stored in the property bag are not compatible?

----------


## Simos

Please advise...
How can I add an ico in imagelist at run time without using LoadPicture. (Select from 32bit or 24bit layers in ico file)

----------


## dreammanor

Krool, Please see my thread (#16):
http://www.vbforums.com/showthread.p...-another-color  #16

When I copy the contents of my sample.doc into your RichTextBox, each picture becomes two.

----------


## Krool

> Krool, Please see my thread (#16):
> http://www.vbforums.com/showthread.p...-another-color  #16
> 
> When I copy the contents of my sample.doc into your RichTextBox, each picture becomes two.


Can you prepare a demo showing the problem?
Because with normal .rtf files I see no problems.

----------


## nisharamj

Hi, I am trying to use VBCCR14.OCX for my VB6 project to support Unicode. I have registered the .ocx file in windows 10 and attached to the project. All the UI's were created,  works fine. But when I move the project into different PC and try to run it, it gives me an error "Error in loading DLL" though I register the .ocx file. Can anyone please help me to solve this problem please?

----------


## Semke

> Hi, I am trying to use VBCCR14.OCX for my VB6 project to support Unicode. I have registered the .ocx file in windows 10 and attached to the project. All the UI's were created,  works fine. But when I move the project into different PC and try to run it, it gives me an error "Error in loading DLL" though I register the .ocx file. Can anyone please help me to solve this problem please?



just a thought, if you are using 64bit windows you need to copy the OCX into "C:\Windows\SysWOW64" not in the system32 folder.

----------


## dreammanor

> Can you prepare a demo showing the problem?
> Because with normal .rtf files I see no problems.


I have put the sample.rtf in MyRichText7.zip which is in my new thread:
http://www.vbforums.com/showthread.p...43#post5147343

----------


## Krool

There is a problem in the CommonDialog.cls concerning the printer dialogs.

In MSComDlg the 'PrinterDefault' property is set to True by default. In my CommonDialog.cls it is not, it is set to False by default.

Instead the CommonDialog.cls will set the application instance printer to the selected one via "Set VB.Printer = ObjPrinter".
This works fine in the StdEXE version. However, in the OCX version it is not working as "Set VB.Printer = ObjPrinter" seems to has no effect..

Of course a solution would be to set 'PrinterDefault' to True then the VB.Printer will be changed accordingly to the new system default printer.
This would then also work via the OCX. (Like in MSComDlg)

So my question is:
Shall I change the default value of 'PrinterDefault' to True? Or only set to True in the OCX and not in the StdEXE version?
Include a 'DeviceName' property in CommonDialog.cls so the app can enum the VB.Printer on his own?
Any other solution?

Thanks in advance for any help.

----------


## chosk

> ...
> In MSComDlg the 'PrinterDefault' property is set to True by default. In my CommonDialog.cls it is not, it is set to False by default.
> ...
> So my question is:
> Shall I change the default value of 'PrinterDefault' to True? Or only set to True in the OCX and not in the StdEXE version?
> Include a 'DeviceName' property in CommonDialog.cls so the app can enum the VB.Printer on his own?
> Any other solution?
> 
> Thanks in advance for any help.


I think set default value of 'PrinterDefault' to True, for both Std-Exe and OCX. I am not sure what need to be done in the codes but the end result should be the default printer is initially shown.

----------


## Krool

Update released.

'PrinterDefault' is now initially set to True in the CommonDialog class. (like in the MS CommonDialog)

The statement "Set VB.Printer = ObjPrinter" *does* have an effect in the OCX. But that change is not accessible from the app. Only in the OCX.
So all the changes (like PaperSize etc.) are saved and re-used in the printer dialog. (of course the CommonDialog must be on Form-Level)
But normally the app does not need to know the chosen PaperSize, it is sufficient if the printer dialog knows it as the app will anyhow print on the .hDC.
The only property the app might be interested is the number of Copies. That is not reflected into the .hDC and not accessible in the OCX. (only Std-EXE Version)
That's why I have now included the Copies property. (like in the MS CommonDialog)
The printer dialog will now read/write to that Copies property instead of the VB.Printer object, so it is accessible when using the OCX version.

----------


## Krool

Update released.

So after a series of updates in the CommonDialog class I am now finally happy with the situation.

The VB.Printer object is eliminated in the CommonDialog which will be essential for the next OCX release.
Also the behavior is now the same as in the MS CommonDialog class. (by default)

But the MS CommonDialog class had some limitations.
In the MS CommonDialog class you can only write code to print directly to the VB.Printer object in the app when 'PrinterDefault' is True.
Otherwise ('PrinterDefault' is False) you need to rely on the control's hDC property, but no chance of knowing which printer was selected.
Therefore I have included the PrinterDriver/PrinterName/PrinterPort property which will be set after a printer was selected.

Also included 'PrinterDefaultInit' property which determines if the default or user-selected printer will be initialized. (pre-selected)
The default value of 'PrinterDefaultInit' is True to have the same behavior with the MS CommonDialog. (pre-select always default printer)
So when 'PrinterDefaultInit' is False and the user selected a non-default printer that printer will be pre-selected the next time.

Another limitation was that the MS CommonDialog managed internally the Orientation/PaperSize/Copies/PaperBin, but only exposed the Orientation/Copies property.
My class also exposes the PaperSize/PaperBin property which is very helpful when using the page setup dialog. (or exchange information)

The only remaining "issue" is how to handle the PrintQuality/ColorMode/Duplex.
In the MS CommonDialog they are not managed and thus always the driver's default value is used.
Which is not a bad idea as when a printer color mode is monochrome by default and you want to print (one-time) a color document then the next time it will be monochrome again.
So I am thinking/struggling of how to implement this. Maybe others can give some ideas.  :Smilie:

----------


## Krool

D'oh, critical bugfix for yesterday update.

The PrinterDriver/PrinterPort was wrongly extracted from the DEVNAMES structure... (wrong use of the .wOffset members)
This caused the PrinterDriver/PrinterPort to be cut/truncated. For instance the PrinterDriver 'winspool' got cut/truncated to 'spool'.
In my testings yesterday this was not shown up as the print dialog however managed to find it.
But now in a pdf printer I found out that it failed.. (PrinterPort got truncated to null) But with the fix today it is now working.  :Roll Eyes (Sarcastic): 

Another improvement done as following:
PrinterDriver/PrinterName/PrinterPort are on default empty. This indicates that the default printer will be initialized.
However, when a default printer was selected then that default printer got set in the PrinterDriver/PrinterName/PrinterPort.
When then the user in the meantime changes the system default printer then next time the print dialog shows up the non-default will be selected and not the default.
The improved solution is now that after user selection the DEVNAMES structure is checked on the wDefault member if it includes the DN_DEFAULTPRN flag.
If so the PrinterDriver/PrinterName/PrinterPort will be set to empty, if not then they will be set.
That means that the app should check on return if the PrinterName is empty (= default) or not (= specific) and act accordingly.

So it could look like this:


```
Dim ObjPrinter As VB.Printer
With New CommonDialog
.PrinterDefault = False
.Flags = CdlPDUseDevModeCopiesAndCollate
If .ShowPrinter = True Then
    If .PrinterName = vbNullString Then
        Set ObjPrinter = VB.Printer ' Default
    Else
        For Each ObjPrinter In VB.Printers
            If ObjPrinter.DeviceName = .PrinterName Then Exit For
        Next ObjPrinter
    End If
    MsgBox ObjPrinter.DeviceName
End If
End With
```

----------


## nisharamj

Thanks for the reply. I have put the OCX file in "C:\Windows\SysWOW64" and registered it. But still I am getting this DLL error. Project is working in the developing machine without any problem but if the project moves to another machine(same environment), this problem happens.

----------


## chosk

> Thanks for the reply. I have put the OCX file in "C:\Windows\SysWOW64" and registered it. But still I am getting this DLL error. Project is working in the developing machine without any problem but if the project moves to another machine(same environment), this problem happens.


If you are very sure you have registered the OCX properly in the another machine, then open any VB6 project, or create a new one in the another machine. Then add the OCX into the project by going to "Project/Components..." pull down menu. In the Components dialog that open, select the Controls tab and look for VB Common Controls Replacement 1.4 Library. When you find it, select it and click the Apply button. If it goes smoothly, you have registered it correctly. If you cannot find it, then something went wrong with your registration. You will have to fix the registration to fix the DLL not found error.

When you create a VB6 project with one or more OCX added and want to open this project in other machines, the OCX must be in the same logical path in all your other machines before they can work. Otherwise you have to re-do the Project/Components... again to get the OCX that are in different logical paths, therefore cannot be found by the project.

----------


## Krool

Update released.

Included the MouseEnter/MouseLeave event and MouseTrack property in the LabelW control.
Other controls will follow soon with the same enhancements.

The MouseTrack property determines whether mouse events occurs when the mouse pointer enters or leaves the control. (Default is False)

My main focus was to solve first the LabelW control before any other as there is a special difficulty on it as it is a "windowless" control. (TrackMouseEvent function will not work)
In addition there is the problem that the bounding rectangle of the LabelW is not always a simple rectangle, it can be a complex region if it is covered by a shape or image control.

So seems like very difficult to accomplish.. However, the solution is quite easy. (inspired by TimeSoft-Software)

I store the mouse position of the last MouseMove event. In a Timer event there is then the following check:
1. Determine if GetCapture is equal to .ContainerHwnd. (Kind of dragging state, no MouseLeave during that case)
2. Check with WindowFromPoint if mouse cursor is still on .ContainerHwnd. (MouseLeave occurs when different)
3. Check if current mouse position is different than the last known position. If it is, this means that no MouseMove event occured although the cursor has been moved. And that can only be when the mouse pointer is no longer over the control. (MouseLeave occurs)

----------


## chosk

> Update released.
> 
> Included the MouseEnter/MouseLeave event and MouseTrack property in the LabelW control.


This is great. Thank you!

This make using LabelW for Win10 style hamburger menu and pretentious tab buttons (to simulate tabcontrol buttons) for a Win10 look alike UI easier. I don't know whether it is possible to have Tabstop property for LabelW possible. If yes, this will complete the works.

Here is an example on how LabelW can be used using screen shot from the Win10 Money app:

----------


## JohnTurnbull

Just wondering. Does the latest version handle WM_ Settabstops for TextboxW ?

----------


## Krool

> Just wondering. Does the latest version handle WM_ Settabstops for TextboxW ?


You mean EM_SETTABSTOPS ?
No, there is no function or method included in the TextBoxW that sends EM_SETTABSTOPS.

----------


## JohnTurnbull

I added this sub to your ComCtlsDemo project....



```
Sub SetTabStops(TB As Object)
Dim TabStops() As Long
Dim xx&, yy&
Dim Ret As Long
Dim Stops&
'-----------------------
On Error GoTo Bad
ReDim TabStops(6) As Long
Stops = 7
yy = 12
For xx = 0 To UBound(TabStops)
    TabStops(xx) = yy
    yy = yy + 12
Next
Ret = SendMessage(TB.hWnd, 203, Stops, TabStops(0)) '203 = &HCB
Exit Sub
'------------------------------------
Bad:
Resume Here
Here:
End Sub
```

I changed your textboxw1 to multi-line and passed it to that sub. In your demo, it worked perfectly setting 3 space tabs. However, when I added it to my project, VB crashes "Visual basic has stopped working"

Any ideas why it should work in one project and not in another?

----------


## Semke

> I added this sub to your ComCtlsDemo project....
> 
> 
> 
> ```
> Sub SetTabStops(TB As Object)
> Dim TabStops() As Long
> Dim xx&, yy&
> Dim Ret As Long
> ...


i am not sure if I am correct but I think the LB_SETTABSTOPS (= &H192) will work for listbox not for textbox.

----------


## JohnTurnbull

Not using LB_SETTABSTOPS (= &H192)
Using EM_SETTABSTOPS (= 203)

----------


## Semke

> Not using LB_SETTABSTOPS (= &H192)
> Using EM_SETTABSTOPS (= 203)


try using tb.hWndUserControl

----------


## Karl77

A question to the toolbar:

I have a toolbar with several buttons.
All the buttons have the Style = TbrButtonStyleDefault.
In some place of the code I toggle the values of the buttons, like


```
.tlb_All.Buttons("xxx").Value = TbrButtonValuePressed.
```

This works ok, the button shows a pressed state.

I can also get the value of the button, tested with a command button:


```
Debug.Print "PressedState:", tlb_All.Buttons("xxx").Value
```

Works as well.

Now when I click a button, before any action, I want to get the state as well.
But inside the tlb_All_ButtonClick event, always 0 is seen.
Regardless of the current value.

What can this be, or how can I get the value inside the ButtonClick event?

Thank you,
Karl

----------


## Krool

> A question to the toolbar:
> 
> I have a toolbar with several buttons.
> All the buttons have the Style = TbrButtonStyleDefault.
> In some place of the code I toggle the values of the buttons, like
> 
> 
> ```
> .tlb_All.Buttons("xxx").Value = TbrButtonValuePressed.
> ...


That it is normal. The behavior is the same as in the original MS ToolBar.
The ButtonClick is fired when the mouse is released, so the button state is unpressed as this moment.
Only when the Style is for instance set to TbrButtonStyleCheck then it remains pressed within the ButtonClick and Value will be TbrButtonValuePressed.

----------


## Karl77

Hello Krool,




> That it is normal. The behavior is the same as in the original MS ToolBar.


Ah ok, I didn't test, I didn't expect that this is standard.




> when the Style is for instance set to TbrButtonStyleCheck


Yes, that works now.
In the click event the opposite state is seen, the click switches the value before we can get the value.
Interesting, but works reliable.

Solved.

Thanks,
Karl

----------


## chosk

Regarding my question whether LabelW can have TabStop. LinkLabel has recently been added the MouseTrack/MouseEnter/MouseLeave property in the 9-April update. It already has the TabStop property. If it can also have Center Alignment in both Vertical and Horizontal, then it can be used for Win10 look-alike GUI.

----------


## Krool

> Regarding my question whether LabelW can have TabStop. LinkLabel has recently been added the MouseTrack/MouseEnter/MouseLeave property in the 9-April update. It already has the TabStop property. If it can also have Center Alignment in both Vertical and Horizontal, then it can be used for Win10 look-alike GUI.


TabStop can only be implemented in the LabelW when 'CanGetFocus' is set to True, which I am not going to do as it breaks the sense of the Label control.
The LinkLabel is a different story, but there is no way I can see to have a Center Alignment.
So I guess you need to "manually" center it with line breaks and spaces.

----------


## chosk

> ...
> The LinkLabel is a different story, but there is no way I can see to have a Center Alignment.
> So I guess you need to "manually" center it with line breaks and spaces.


Thanks for the reply.

I wasn't hopeful with the LabelW queston. I was checking the LinkLabel in VS 2017 Form and there is center alignment so I tried my luck. Guess the only way for me now to adopt Win10 GUI is to bite the bullet and go UWP and accept the fact that I can only target Win10 and later.

Thanks anyway.

----------


## Krool

Update released.

Included the ShowTips property in the CoolBar control and the corresponding ToolTipText property of a Band.
RBS_TOOLTIPS style is not working (according to MSDN "not yet supported"), so it was necessary to create a own internal tool tip control.

The "hot region" for showing the ToolTipText is the caption/icon area in a Band.

----------


## softv

This post - http://www.vbforums.com/showthread.p...=1#post5160309 - of mine, in the related ActiveX thread, is with regard to some problems encountered by me while using the RichTextBox control of the 'MS Common Controls Replacement' project. I realised today that there is not much activity in the related ActiveX thread. Hence, I am now re-posting my aforesaid reply-post in this thread, hereunder. Hope thats okay, Krool and others. Kindly please help.


First and foremost, thanks a ton to Krool for this wonderful effort. This is absolutely marvelous and it is pretty exciting to go through the various aspects of this project (Replacement of the MS common controls). Though I am interested in all the controls, as of now, my primary interest is on the RichTexBox. So, I started experimenting with it and I encountered some problems.


I am listing the problems below along with a code snippet to illustrate the problems. Please note that I am new to this forum and this is the first time I am writing here. So, in case I have not followed any protocols related to posting, kindly bear with me and please do guide me for later posts. Also, in case I have understood things completely wrongly about one or more aspects of either the RichTextBox control of this project or of this project itself and that is the reason for me facing the following problems, then kindly correct my understanding and kindly guide me as to what to do to set right the following problems.


Problems:
1. When I set some string (e.g. "a") for a RichTexBox control (say, named 'rtb1') and then compare the text with the same string (i.e. if rtb1.text = "a"), the comparison does not return true. Also, adding some string to the end of 'rtb1' results in characters not present in the string getting added (and displayed). I found that space in the original string was always getting replaced by a character whose Unicode value was U2000 (Decimal - 8192). Same with other characters, as far as I observed. A specific character (say 'a') was always getting replaced by one other specific character.


2. 'Len' and 'Instr' consider "VbCrLf"s fully whereas 'SelStart' and 'Find' ignore the Lf in "VbCrLf"s. Because of this, inconsistencies arise.


The code below illustrates what happens because of the above two problems. It needs a Form with a CommandButton (Command1) and a RichTextBox (named 'rtb1')


```
Private Sub Command1_Click()
  
  Dim s As String
  
  s = " a " & vbCrLf & vbCrLf & " ab"
  
  rtb1.Text = s
  If rtb1.Text = s Then
    MsgBox "yes"
  End If
  
  MsgBox "Length = " & Len(rtb1.Text) '10 is displayed
  rtb1.SelStart = Len(rtb1.Text)
  MsgBox "Selstart = " & rtb1.SelStart '8 is displayed
    
  MsgBox "Instr b = " & InStr(rtb1.Text, "b") '10 is displayed
  MsgBox "Find b = " & rtb1.Find("b") '7 is displayed
  
  rtb1.Text = rtb1.Text & s 'characters not present in string 's' get added (and displayed)
                            
End Sub
```


Note-1:
After working on "problem 1" for around 6 hours - to find its cause and a possible solution, I finally set right the problem at my end by introducing a line of code in the following function of 'RichTextBox.ctl'.


```
Private Function StreamStringOut(ByRef Value As String, ByVal Flags As Long) As Long
```


I added the following line


```
Value = Left$(Value, Len(Value))
```

after the line


```
Value = RtfStreamStringOut()
```

in the aforesaid 'StreamStringOut' function.


I am not at all suggesting that the inclusion of the above line of code is the right thing to do. I am just mentioning what I did so that it can serve as a tip to Krool or any other member to find out the right thing to be done, eventually.


Note-2:
As of now, I do need VbCrLf in my programs. So, I would be happy if the eventual solution does consider VbCrLf fully so that it is consistent with the behavior of the normal RichTextBox (RICHTX32.OCX component, I mean).


Note-3:
I have tested with the latest version of the ocx control (1.4.11). My system is Windows 7, 64-bit.


A few queries now:
1. The links in the RichTextBox are not clickable. I have to set some property on or off to make them clickable? If so, what is that property? If not, is anything planned for making the links clickable in future?
2. The normal RichTextBox wraps text around even if horizontal scroll bar is set. The RichTextBox of this project wraps text around only when the horizontal scroll bar is not set. Can the RichTextBox of this project also made to wrap text around even if horizontal scroll bar is set?


Thanks.

----------


## Krool

Update released. (Thanks to softv)




> Problems:
> 1. When I set some string (e.g. "a") for a RichTexBox control (say, named 'rtb1') and then compare the text with the same string (i.e. if rtb1.text = "a"), the comparison does not return true.


There was indeed an error in the RtfStreamCallbackStringOut and RtfStreamStringIn function in the RichTextBoxBase.bas module.

Fix in RtfStreamCallbackStringOut


```
ReDim Preserve StreamStringOut(0 To (StreamStringOutUBound + BytesRequested - 1)) As Byte
```

Fix in RtfStreamStringIn


```
ReDim StreamStringIn(0 To (StreamStringInLength - 1)) As Byte
```

The Byte array is zero-based so the string was then in fact 11 bytes long for a 5 char (10 bytes) string.
However, Len() still reports 10, but comparison did not return true as 11 bytes vs 10 bytes. That's why your workaround with Value = Left$(Value, Len(Value)) "solved" the issues as it cut of the 1 byte at the end. But now the error is solved at the root cause.

The other issues concerning the 'SelStart' and 'Find' I don't have a solution. I have no influence of what EM_EXGETSEL/EM_EXSETSEL or EM_FINDTEXTEX does.

----------


## Elroy

Krool, I've said it before but I'll say it again.  You're INCREDIBLE to maintain this code to the level you do.  I maintain substantial pieces of code myself, but I typically get paid for it.  It's all GPLv3 open source, but I still get paid for improvements.  On the beneficent side, I do try to throw generic chunks of it out onto these forums as often as I can when it seems appropriate.

But what you've done here is truly *remarkable*.

Best Regards,
Elroy

----------


## LaVolpe

Just some thoughts regarding the InStr() and Find() not returning same value. Using the exact code 3 posts up and in IDE using the standard RTF ocx (not this project's RTF control), those functions do NOT return the same value. However, Len() and SelStart() do. 

I don't know what version VB's standard RTF is, but have read that RTF standards v1 used CrLf (internally) for /par markers and v2 uses Lf (internally). This appears to be the reason for the differences in this project's RTF? And if tested, if you added this text: "0123456789" & vbCrLf, 10 times, Len() should be 10 characters longer than SelStart after SelStart=Len()

Note that when rtf is converted to standard text, /par is converted to CrLf. Am unsophisticated test is setting the control's text to: "a" & vbLF. Len() returns 3 not 2. Hence Len() which works on non-rtf returning more characters than SelStart which works on rtf.

----------


## softv

Thanks for your very prompt multiple action (fixing the error at its root and also releasing a new update immediately), Krool. Great! 

This project is a phenomenal work, not only because of the complexity involved but for the immense benefit it is providing as well. 1000s of developers must be getting benefited through this work and as a consequence, millions of end-users must be getting benefited too. In that way, what a monumental contribution to the world society! 

Well, reg. 'SelStart' and 'Find', I will try to do something similar to what I did for "problem 1". If I succeed, I will share the lines of code here so that, if at all possible, you can give an eventual solution for the issues concerning 'SelStart' and 'Find' also.

I will also try to study more about EM_EXGETSEL/EM_EXSETSEL and EM_FINDTEXTEX.

Thanks.

----------


## softv

> Just some thoughts regarding the InStr() and  Find() not returning same value. Using the exact code 3 posts up and in  IDE using the standard RTF ocx (not this project's RTF control), those  functions do NOT return the same value.


Actually, I had  tested that same code at my end too, with the standard rtf ocx. I tested  it again at my end after reading your above observation. Find()  returned/returns the expected value (9), which is one lesser than the  value (10) returned by InStr(). So, with standard rtf ocx, Find() does  work correctly at my end, right? Kindly advise. My richtx32.ocx version  is 6.1.97.82.

Thanks.

----------


## dan_p

Hi Kroll,

Congratulations for your effort, first of all!!!
There's no alternative for mscomctl.ocx 64bit and I'm struggling to find a solution for that since Microsoft doesn't seem to care. Could your replacement project be compiled for 64bit?

Thanks and kind regards,
Dan

----------


## DEXWERX

> Hi Kroll,
> 
> Congratulations for your effort, first of all!!!
> There's no alternative for mscomctl.ocx 64bit and I'm struggling to find a solution for that since Microsoft doesn't seem to care. Could your replacement project be compiled for 64bit?
> 
> Thanks and kind regards,
> Dan


If you can find a 64bit VB6 compiler, Krool will make it happen!

----------


## Krool

Update released.

All internal tooltips are now as top-most. (effects all controls that have a internal tooltip control)
When the tooltip was created by the common control itself it will be changed via SetWindowPos HWND_TOPMOST, otherwise (own tooltip) WS_EX_TOPMOST will be simply added on CreateWindowEx.

I think it is not "unusual" to set the tooltip window as top-most, there are many tutorials/examples that suggest in doing so to ensure that the tooltip will always be shown.
Reason that it could not be displayed would be for example when the form window is set to top-most, then the tooltip is displayed behind it. Now it will display correctly in that scenario.

----------


## Karl77

Label problem:

Place 2 labels on a form, both the same font and fontsize.
1 standard label
1 Krool label


Then execute this:



```
With Label1
.AutoSize = True
.Caption = "abcdefg"
Debug.Print "Label1: ", .Width
End With

With LabelW1
.AutoSize = True
.Caption = "abcdefg"
Debug.Print "Labelw1: ", .Width
End With
```

The labels both appear correct, their width is ok.
But the widths are different numbers:


The width is 71 pixels.
Screen.TwipsPerPixelX is 12.
71 x 12 = 852

Something is wrong so far...

Next effect:
When I execute the code the second time, the width is 852 for both labels.

Thank you,
Karl

----------


## Krool

> The labels both appear correct, their width is ok.
> But the widths are different numbers:
> 
> When I execute the code the second time, the width is 852 for both labels.


When you set a new caption, then in LabelW a UserControl.Refresh is done. The effective autosizing is done in the UserControl_Paint event as there is a hDC available which is necessary for a DrawText DT_CALCRECT.
However, it seems there is a "lag" from UserControl.Refresh to effective UserControl_Paint, kind of a PostMessage "effect". It is not immediately.
I have no idea for the moment of how to solve it. Of course a "Call UserControl_Paint" instead of "UserControl.Refresh" seems to solve the issue, but actually that is not "allowed", or?

----------


## LaVolpe

> Of course a "Call UserControl_Paint" instead of "UserControl.Refresh" seems to solve the issue, but actually that is not "allowed", or?


With a windowless control, you need the host to initiate the paint event since it is what sends the UC a clipped hDC to draw on. The delay you are seeing is likely between your Refresh call, VB getting that call, and then deciding when to initialize a paint. 

One workaround in this case is to resize the control after setting the caption, when AutoSize is active. If you opt for this, it should be employed in the AutoSize property also when setting it to True.


```
Public Property Let Caption(ByVal Value As String)
...
If Me.AutoSize Then
    UserControl.Extender.Width = UserControl.Extender.Width + Screen.TwipsPerPixelX \ 2 + 1
Else
    Me.Refresh
End If
...
```

This should force VB to call a repaint immediately, before your property returns, and the resizing above doesn't matter because your AutoSize will resize the control anyway. Just a thought. Personally, I don't necessarily like using TwipsPerPixelX as the offset because that can be quite large if the container's scalemode is say vbInches. A better approach would be to determine the container's scalemode. TwipsPerPixelX is likely the largest unit which should guarantee a resize. If scalemode was twips and we increased size by just +1, no resize event occurs.

Another workaround is to invalidate the rect of your usercontrol within the host and force a redraw via API. But that may be more difficult for windowless controls than the suggestion above.

Edited: The downside is that when a border is visible, you may see a flash between the resizing. Maybe the Extender left,top should be used in an Invalidate call after all. But you'll have to find the container's hWnd because your control's container could feasibly be another windowless usercontrol (no hWnd to be used with RedrawWindow)

----------


## wqweto

> But you'll have to find the container's hWnd because your control's container could feasibly be another windowless usercontrol (no hWnd to be used with RedrawWindow)


FYI, windowless controls cannot be controls containers per se and this makes ContainerHwnd property always available I guess.

Btw, this project needs a github repo since long time ago (and probably has been suggested numerous times already).

cheers,
</wqw>

----------


## LaVolpe

> FYI, windowless controls cannot be controls containers per se


Actually, that's the only type of control a windowless control can contain. I'm just not sure (have never tried it) if a VB windowless UC can have the ControlContainer property set to True and be assigned as a container for another windowless control that way. However, while the UC is being designed, this is doable with/without the ControlContainer property. I sure hope my memory is good here; not near a VB box prove myself wrong  :Wink: 

Edited: Just a follow up now that I have access to VB again. I created a windowless, transparent, UC and simply placed Krools LabelW inside it & set its backstyle to transparent. When that UC was placed on a form, both the UC & LabelW remained transparent. But your 2nd point appears to 100% valid: The LabelW control reported the UC's container hWnd as its own ContainerHwnd. But, subclassing was a bit messed up in that scenario.

----------


## wqweto

My bad. I thought the point was about control containers (like PictureBox) not UserControls with constituent controls.

cheers,
</wqw>

----------


## Krool

Update released for the LabelW control. (thanks to Karl77 to bring this issue up)

It got now two internal improvements.

Explanation/Solution:

The first improvement concerns the AutoSize property when the Alignment is <> Left and/or the VerticalAlignment is <> Top.
Now the glitch as can be seen in the screen below will not happen anymore.

This was solved by making an "InvalidateRect .ContainerHwnd, RC, 1" after the resizing and reposition of the control, where RC is the old bounding rectangle.

The second improvement concerns also the AutoSize property. Problem was that after property returns the new state is not reflected immediately, because we needed to wait for a UserControl_Paint to occur in order to do the resizing and reposition. (auto sizing)

That issue was solved by modifying the Refresh method as following:


```
Public Sub Refresh()
If LabelAutoSizeFlag = False Then
    UserControl.Refresh
Else
    Dim RC As RECT
    With UserControl
    RC.Left = .ScaleX(.Extender.Left, vbContainerPosition, vbPixels)
    RC.Top = .ScaleY(.Extender.Top, vbContainerPosition, vbPixels)
    RC.Right = RC.Left + .ScaleWidth
    RC.Bottom = RC.Top + .ScaleHeight
    InvalidateRect .ContainerHwnd, RC, 1
    UpdateWindow .ContainerHwnd
    ' In UserControl_Paint the bounding rectangle will be invalidated again.
    ' That's why two times UpdateWindow is necessary.
    UpdateWindow .ContainerHwnd
    End With
End If
End Sub
```

So only when LabelAutoSizeFlag is True the redrawing is done immediately. (and thus the auto sizing)
And that is necessary to have the new bounding dimensions set before the property returns in order to work with.
However, when LabelAutoSizeFlag is False the normal .Refresh method is used as no immediate redraw is necessary and also not wanted.
Because else when you set 10x Caption in a row it would be redrawn 10x, but with UserControl.Refresh it will be consolidated to 1x redraw, which is common behavior all over to improve performance.
So in fact when you have AutoSize set to True and change the Caption 10x it will be redrawn 10x. But in that special case it is actually wanted because maybe you want to check on each Caption change the resulting Width etc.

----------


## VBClassic04

Krool thanks for so much hard work.
One little change/addition I made to the
PPImageListImages.CommandInsert routine
to save some user drudgery:



```
Dim Path As String, FileNames() As String
Dim OpenFileDialog As CommonDialog
Set OpenFileDialog = New CommonDialog
With OpenFileDialog
.Flags = CdlOFNExplorer Or CdlOFNPathMustExist Or CdlOFNFileMustExist Or CdlOFNAllowMultiSelect
.MaxFileSize = .MaxFileSize * 5000
.Filter = "All Picture Files|*.ICO;*.CUR;*.BMP;*.GIF;*.JPG|Icons & Cursors (*.ICO;*.CUR)|*.ICO;*.CUR|Bitmaps (*.BMP;*.DIB)|*.BMP;*.DIB|GIF Images (*.GIF)|*.GIF|JPEG Images (*.JPG)|*.JPG|All Files (*.*)|*.*"
.DialogTitle = "Select Picture"
.InitDir = GetSetting("VBCCR14", "ImageList", "File", App.Path)
End With
If OpenFileDialog.ShowOpen = True Then
    With OpenFileDialog
    If InStr(.FileName, vbNullChar) <> 0 Then
        Path = Left$(.FileName, .FileOffset - 1)
        If Not Right$(Path, 1) = "\" Then Path = Path & "\"
        FileNames() = Split(Mid$(.FileName, .FileOffset + 1), vbNullChar)
    Else
        Path = Left$(.FileName, .FileOffset)
        ReDim FileNames(0) As String
        FileNames(0) = .FileTitle
    End If
    End With
    
    If Not Path = vbNullString Then
        SaveSetting "VBCCR14", "ImageList", "File", Path
```

----------


## Semke

is there a way to manipulate the width of the combo/list box scrollbar?
not sure this is the right place for this question, but it would sure be a very useful addition to the controls.
thanks

----------


## Karl77

Textbox, small problem

This is an optical problem, no complaints about the functionality.
When the CCBorderStyleSingle is set, the control loses the upper horizontal line of the border.
It is ok when the textbox doesn't have the focus.

To retrace:
Start a fresh VB.
Add the Krool controls.
Set the font of the Form1 to Segoe UI, 11.
Place a textbox on the form.
Copy and paste this textbox, create a control array.
Set the borderstyle CCBorderStyleSingle to the copied textbox.
Run.
Click into the textbox that has CCBorderStyleSingle.
Now you should see this:

----------


## Krool

> Textbox, small problem
> 
> This is an optical problem, no complaints about the functionality.
> When the CCBorderStyleSingle is set, the control loses the upper horizontal line of the border.
> It is ok when the textbox doesn't have the focus.
> 
> To retrace:
> Start a fresh VB.
> Add the Krool controls.
> ...


I cannot replicate the problem, at least on win 7.
Somebody else has this issue?

----------


## chosk

When the TextBoxW height is not "tall" enough. Depending on the height, either the top border or both top and bottom border do not show. The solution is to set the height tall enough.

Tested on Win7.

----------


## Krool

> When the TextBoxW height is not "tall" enough. Depending on the height, either the top border or both top and bottom border do not show. The solution is to set the height tall enough.
> 
> Tested on Win7.


But normally that should not appear as the edit has its margin from border to content. The content should be clipped then.

----------


## chosk

Only when CCBorderStyleSingle is applied and the TextBoxW is not "tall" enough. I just did some quick sample. Actually don't have to create a control array. Also no need to be Segoe UI.

----------


## chosk

Earlier I ran the project from the IDE. I just compiled and run the exe. Now no need to have the focus. Note in the screenshot, the focus is on the left.

----------


## chenfrank_1

Hello Krool ,

        Thanks for offer the CommonControls. That I can use controls in Unicode.

        Something need to help. 

        I use the "Listview" control, attachment show we can change the subItem data when we click the data.

        And double Click the data to show some dialog to choose.

        How to do that ? Need your help.

Thanks

----------


## Krool

> Hello Krool ,
> 
>         Thanks for offer the CommonControls. That I can use controls in Unicode.
> 
>         Something need to help. 
> 
>         I use the "Listview" control, attachment show we can change the subItem data when we click the data.
> 
>         And double Click the data to show some dialog to choose.
> ...


Your image shows kind of a flex grid control and not a ListView control.
The ListView control is intended to represent data and not to edit data, thus without additional custom code there is no sub item edit available out of the box.

----------


## DaveInCaz

> Update released.
> Thanks


Referring to post #1187...

Just wanted to reply to this update regarding the .FilterIndex property - I can confirm now that in my original scenario which had the problem, the issue is now fixed. I substituted the most recent VBCCR14 in place of what we had been using (VBCCR12) and the problem was resolved. Thanks!

----------


## chenfrank_1

Delete this quiz... :wave:

----------


## Jonney

> Attachment is the file for your reference. I am poor for that. But is it similar to "Listview" ?



We never dare to  open your attachment. You may open a new thread for your question instead of disturbing this thread.

----------


## Krool

Update released.

Improved the "DPI Awareness" in the controls.
The pixel dimensions of the StdPicture objects were retrieved via UserControl.ScaleX/Y and vbHimetric/vbPixel.
According to LaVolpe's latest addition in his "Being DPI Aware" Tutorial he reported that VB's ScaleX/Y is broken on exocit or very large DPI settings.
And indeed, in my testings a 16x16 icon got reported 17x17 at 175% DPI.
With the new included internal functions CHimetricToPixel_X/Y in Common.bas the correct value 16x16 will be retrieved. (16x16 is just an example)

----------


## Eduardo-

> Update released.
> 
> Improved the "DPI Awareness" in the controls.
> The pixel dimensions of the StdPicture objects were retrieved via UserControl.ScaleX/Y and vbHimetric/vbPixel.
> According to LaVolpe's latest addition in his "Being DPI Aware" Tutorial he reported that VB's ScaleX/Y is broken on exocit or very large DPI settings.
> And indeed, in my testings a 16x16 icon got reported 17x17 at 175% DPI.
> With the new included internal functions CHimetricToPixel_X/Y in Common.bas the correct value 16x16 will be retrieved. (16x16 is just an example)


AFAIK the problem is that VB handles the TwipsPerPixelX/Y for the screen (unlike the printer object) with integers, so if the actual value of TwipsPerPixelX/Y is not an integer, there will be problems.

At 96 DPI: for Windows it is 100%, there are 15 TwipsPerPixelX/Y, an integer.
At 120 DPI: for Windows it is 125%, there are 12 TwipsPerPixelX/Y, an integer.
At 144 DPI: for Windows it is 150%, there are 10 TwipsPerPixelX/Y, an integer.

The following preset option that Windows has is 192 DPI, 200%, and the TwipsPerPixelX real value for that is 7.5, a non integer, and there are problems in VB at that DPI setting because VB threat the TwipsPerPixelX/Y as being 7 (or 8, i don't remember now how it rounds).

At 175%, it is 168 DPI, and the value for TwipsPerPixelX/Y is 8.5714285714285714285714285714286, a non integer, probably rounded to 9 in VB. And there will be problems at that DPI in VB.

The problems are not limited to the ScaleX/Y functions and the Screen.TwipsPerPixelsX/Y properties, the position and size of the controls that VB handles automatically are also affected.

For high DPI that can work on VB, we need to chose an integer for TwipsPerPixelX/Y, for example:

8 TwipsPerPixelX/Y: 180 DPI -> 187.5%
6 TwipsPerPixelX/Y: 240 DPI -> 250%

TwipsPerPixelX/Y= 1440/DPI
DPI= 1440/TwipsPerPixelX/Y

----------


## Krool

> The problems are not limited to the ScaleX/Y functions and the Screen.TwipsPerPixelsX/Y properties, the position and size of the controls that VB handles automatically are also affected.


I know. The size will be "corrected" already within UserControl_Resize. In a way that afterwards .ScaleWidth etc. will report correct.
That point with himetric conversion was only an additional issue.

----------


## Eduardo-

> I know. The size will be "corrected" already within UserControl_Resize. In a way that afterwards .ScaleWidth etc. will report correct.
> That point with himetric conversion was only an additional issue.


Yes, you can make the controls to work properly on non integer TwipsPerPixelsX/Y values and that's very nice, and for some projects it will be a solution, but in most cases VB still won't work properly, because it will position and size the forms wrongly, and if the program uses Screen.TwipsPerPixelsX/Y to position controls (or for other purposes) it will report a wrong value. Also ScaleX/Y of the forms will fail.

Unfortunately, we'll need a fix on VB itself to solve that.

----------


## Krool

I just want to put out a question in the room.
Shall my new VBFlexGrid (almost completed) be included in this project or separated as initially intended to be?
Reason for my struggle is that it would fit perfectly in the architecture of this project, but did it separate because of the size and complexity.
However, who cares if the VBCCR15.OCX will be 4.4 MB or 5.6 MB?
Thanks

----------


## dreammanor

Congratulations, Krool. I am extremely interested in your new VBFlexGrid. 

I have used the Farpoint Spread control for many years. IMO, the new VBFlexGrid should be separated into a independent control, because the Grid control is too complicated, the size of a fully functional Grid control will eventually reach 2-5M, or even greater. 

In addition, separating VBFlexGrid as a stand-alone control makes it easier for users to use it. 

Look forward to seeing your new control as soon as possible.


Added: 
The size of the VBFlexGrid is not a problem. However, the VBFlexGrid is a new control, when it is a separated OCX, it will be more convenient to debug, correct errors and add new features. At the same time, it won't affect the original VBCCR controls. 

Of course, if the VBFlexGrid is integrated into a single file, there are other benefits.

----------


## chosk

Hi Krool,

Will there be an option for new VBFlexGrid be Std-Exe? Or will it just be OCX only?

----------


## Krool

> Hi Krool,
> 
> Will there be an option for new VBFlexGrid be Std-Exe? Or will it just be OCX only?


It will be first Std-EXE and after a certain trial period also OCX.

----------


## chosk

Hi Krool,

Thank you.

----------


## Eduardo-

> I just want to put out a question in the room.
> Shall my new VBFlexGrid (almost completed) be included in this project or separated as initially intended to be?
> Reason for my struggle is that it would fit perfectly in the architecture of this project, but did it separate because of the size and complexity.
> However, who cares if the VBCCR15.OCX will be 4.4 MB or 5.6 MB?
> Thanks


My first thought is that it's better to have everything in a single file.

Let's try to find the pros and cons:

Pros:
1) Everything in a single file/reference, is simpler.
2) Easier to find for people that don't know that it is available out there.
3) The file size is not a problem nowadays (at least in most of cases, perhaps 99%).

Cons:
1) To have everything together increase the number of types available. I mean, for example, one reason I don't like to use ADO is because I'm used to declare String variables as *Dim a as str*[and press *Space* or *Enter*] and it becomes *Dim a as String*, but having a reference to ADO it becomes *Dim a as Stream*, and I need to navigate down for several types to find *String*. 
The point is that having unused Types is not good for intellisense.

Others?

----------


## Karl77

I would prefer a single file solution as well.
When fixes like the last DPI issue are solved, then the grid inherits the changes automatically.
Separate solutions are more work to maintain.
---
The OCX is not small anyway.
I personally don't care about the file size, but it is important nowadays as well.
We can always use and strip the EXE version to optimize the overall file size.
---
A new Grid control is definitely a *very good* thing.
I use the MSFLEXGRID for too many years now.
It lacks some very basic functionality, but it is 'easy' to implement it (edit, sorting etc.).
But the appearance is fixed: Scrollbars, fixed columns...
Eager to play with the new control!

Karl

----------


## dreammanor

Edit: The size of the VBCCR is not a problem. However, the VBFlexGrid is a new control, when it is a separated OCX, it will be more convenient to debug, correct errors and add new features. At the same time, it won't affect the original VBCCR controls. Of course, if the VBFlexGrid is integrated into a single file, there are other benefits.

Whether it is a separated OCX or integrated into a single file, it isn't a big problem. The most exciting thing is that Krool's new VBFlexGrid is almost completed.   :Smilie:

----------


## Arnoutdv

I'm quite curious to see what the VBFlexGrid has to offer.
For years I'm using the vsFlexGrid from ComponentOne and I really really like it.

----------


## Semke

You are great, all this AND a Grid, A1.

I vote for a single file, for the reasons you have suggested 

thank you so much

----------


## DaveInCaz

Hi Krool, from my point of view having a single OCX to manage in development and deployment is preferable. And I agree, an extra 1 MB plus or minus is not important. 

Since it seems that managing the code is also easier from your side of things, and you do all this work graciously than that is also something to be optimized for!

Dave

----------


## DEXWERX

I would expect the VBGrid to ultimately be a seperate OCX.

1 Question - how API compatible with the flexgrid will it be?

Also - just like to point out you've single handedly:
- Replaced all VB's Common Controls with updated Unicode Compatible replacements
- Made Multithreading easy in VB
- Will have replaced the flexgrid (arguably the most used control beyond the common controls)

All open source... Quite epic as far as classic VB goes.

Cheers!

----------


## Krool

> I would expect the VBGrid to ultimately be a seperate OCX.
> 
> 1 Question - how API compatible with the flexgrid will it be?


I tend to the separate solution again. (again  :Smilie:  )
Since updates are isolated. Own thread for community etc.

What you mean API compatible?
Like an old fashioned dll control?
The control itself is an own registered window. But the interface is all tru the UserControl container properties and method. There will be no separate message based 'interaction'.

----------


## DEXWERX

> I tend to the separate solution again. (again  )
> Since updates are isolated. Own thread for community etc.
> 
> What you mean API compatible?
> Like an old fashioned dll control?
> The control itself is an own registered window. But the interface is all tru the UserControl container properties and method. There will be no separate message based 'interaction'.


I just meant, are your VBGrid's properties and methods going to be the same as an MSHFlexGrid?

Regards,

----------


## Krool

> I just meant, are your VBGrid's properties and methods going to be the same as an MSHFlexGrid?
> 
> Regards,


Yes, of course. It will be an replacement where not much code needs to be changed. Of course limitation and bugfixes will be removed and new features added.

----------


## Karl77

Krool,

before your gift comes out, could you please look again at #1382?
Thank you.

Karl

----------


## Schmidt

I think I've found an incompatibility to the old intrinsic Controls (whilst updating an older Project at work, which had
quite some amount of Forms - by just replacing "Begin VB.TextBox " with "Begin VBCCR14.TextBoxW " same for CommandButtons -
... all done in a Replace-loop over all *.frm Files, just to lift-up the old TextBoxes and CommandButtons to Unicode-awareness)

That worked well enough - the Project loaded just fine after that.

The only problem (currently) seems to be, that Validate-Events are not raised, when a Mouse-triggered Focus-Change happens
*from any Control* - *to another CCR14*-Control... (on the "*any Control*" that is)...
Mouse-triggered FocusChanges *to* older Intrinsic-Controls work fine though and *do* trigger the Validate-Event in a CCR14-Control,
which is about to loose the Focus.


TabKey-based Focus-Changes work fine (as in: "they always trigger the Validate-Events on CCR14-Controls")
Also Form.ValidateControls seems to work the same way as with the Intrinsics (triggering a response in the currently focused CCR14-Control).
It's (as said) only the problem with MouseBased-FocusChanges.

Here's an example (please place the appropriate CCR14-Controls like listed in the snippet below on an otherwise empty Form)


```
Option Explicit

Private Sub TextBoxW1_Validate(Cancel As Boolean)
  Debug.Print "TextBoxW1_Validate"
End Sub

Private Sub TextBoxW2_Validate(Cancel As Boolean)
  Cancel = True
  Debug.Print "TextBoxW2_Validate (Cancel set to True)"
End Sub

Private Sub ComboBoxW1_Validate(Cancel As Boolean)
  Debug.Print "ComboBoxW1_Validate"
End Sub
 
Private Sub CommandButtonW1_Click()
  Unload Me 'we should not reach this, when the Focus was sitting within TextBoxW2
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
   On Error GoTo 1
     Me.ValidateControls 'this seems to work correcly (same as with intrinsics)
1  If Err.Number = 380 Then Cancel = 1
End Sub
```

Olaf

----------


## Krool

> I think I've found an incompatibility to the old intrinsic Controls (whilst updating an older Project at work, which had
> quite some amount of Forms - by just replacing "Begin VB.TextBox " with "Begin VBCCR14.TextBoxW " same for CommandButtons -
> ... all done in a Replace-loop over all *.frm Files, just to lift-up the old TextBoxes and CommandButtons to Unicode-awareness)
> 
> That worked well enough - the Project loaded just fine after that.
> 
> The only problem (currently) seems to be, that Validate-Events are not raised, when a Mouse-triggered Focus-Change happens
> *from any Control* - *to another CCR14*-Control... (on the "*any Control*" that is)...
> Mouse-triggered FocusChanges *to* older Intrinsic-Controls work fine though and *do* trigger the Validate-Event in a CCR14-Control,
> ...


Thank you.

I could replicate this problem, but only in the OCX version.
The Std-EXE version works fine.

The problem lies in the WM_MOUSEACTIVATE handlers in the controls.
It seems the OCX has a problem with:


```
Screen.ActiveForm.ValidateControls
```

I suppose replacing it with


```
UserControl.Parent.ValidateControls
```

could probably fix this issue. (But that fix would not work when mouseactivating from a form control to a nested control in another UserControl)

I will investigate soon further.

----------


## DEXWERX

Not sure if these links help.

http://www.xtremevbtalk.com/interfac...ercontrol.html

https://web.archive.org/web/20080628...ol-object.html

----------


## Eduardo-

> It seems the OCX has a problem with:
> 
> 
> ```
> Screen.ActiveForm.ValidateControls
> ```


Yes, because Screen.ActiveForm returns a reference to the active form (when there is any) of the current project, the OCX, not of the client project.

----------


## Schmidt

> I could replicate this problem, but only in the OCX version...


Yep, that's what we're using here...

Before you might undertake a recompilation, there's another thing with 
TextBoxes that we made use of in our old Forms - it's the DataChanged-Property,
which (in case of the TextBoxW-replacements) never seems to be set (when content
is changed that is different from the "initial Form-Designer-Value").

We also have detected a Bug in the TreeView, which on Node-Deletes (which contain Children)
does not seem to delete the Children, not updating the "Count" properly - and then later 
(whilst collapsing/re-expanding Nodes) will run into an error.

In case you cannot reproduce that Tree-behaviour easily, I'd be happy to provide an example...
(a collegue of mine discovered that, and we don't have a "reduced test-case" prepared yet).

Regards,

Olaf

----------


## DEXWERX

a github would be convenient for bug tracking, version control and for others to supply patches. *nudge*

----------


## Schmidt

> a github would be convenient for bug tracking, version control and for others to supply patches. *nudge*


Yep.

@Krool
Just coming in from my colleague again... (sorry for just throwing that stuff out "as it happens", but maybe it's easy to fix along with the other things)

- the "DataChanged-Prop-not-set"-thingy seems not only restricted to TextBoxW, but also to CheckBoxW and OptionButtonW
- the FrameW does not contain a "HelpContextID"-Property (as the VB-original)

The latter one would probably break compatibility with the OCX-TypeLib (or the Manifest) - 
but it'd be nice to have in the long run.

As said, this all came up in our "simple replace-test" we undertook (just replacing the ProgIDs in the VB *.frm Files) 
on a larger (older) VB6-App - it's surprising how well that worked out, aside from these small "glitches" I've reported
(which came up when running some of the "upgraded" Forms in question).

Regards,

Olaf

----------


## Krool

> Yes, because Screen.ActiveForm returns a reference to the active form (when there is any) of the current project, the OCX, not of the client project.


Yes. Thus I need to abandon the Screen.ActiveForm.
I have found a way to solve a nested UserControl in another UserControl, however this solution goes only one deep. So nesting 2x times would not work. But for now this would be a good hotfix and solves nearly all scenarios. Again, only if somebody is nesting like crazy it won't work. :-)



```
If TypeOf UserControl.Parent is VB.Form Then
    UserControl.Parent.ValidateControls
Else
    UserControl.ParentControls(0).Parent.ValidateControls
End If
```

So I think I will implement that solution soon for the moment until something better comes up.

----------


## DEXWERX

courtesy of Vlad (wqweto)

takes advantage of the fact that UserControls all derive from the UserControl interface, even though they don't respond to a 
QI for _UserControl. It seems that VB nicely skips the QI when it thinks it's assigning between the same interfaces.
I would have come up with this eventually.  :Smilie: 

Of course the assumption is that if the parent is not a Form, its a UserControl...
This may not work if it's not hosted on a Form!



```
Private Property Get ParentForm() As Form
    Dim oTopParent      As Object
    Dim oUserControl    As UserControl
    
    Set oTopParent = Extender.Parent
    Set oUserControl = AsUserControl(oTopParent)
    Do While Not oUserControl Is Nothing
        If oUserControl.Parent Is Nothing Then
            Exit Do
        End If
        Set oTopParent = oUserControl.Parent
        Set oUserControl = AsUserControl(oTopParent)
    Loop
    Set ParentForm = oTopParent
End Property

Private Function AsUserControl(oObj As Object) As UserControl
    Dim pControl        As UserControl
  
    If TypeOf oObj Is Form Then
        '--- do nothing
    Else
        Call CopyMemory(pControl, ObjPtr(oObj), 4)
        Set AsUserControl = pControl
        Call CopyMemory(pControl, 0&, 4)
    End If
End Function
```



This doesn't seem to fix if a ComboboxW gets the focus?
although my patch was a bit hurried.

----------


## Krool

Update released. Thanks DexWerx for the code to get the parent form of the UserControl, regardless of how deep it is nested.

I have found the bug with the CausesValidation not working on mouse activation quite urgent. (though it concerns effectively only the OCX, however)
The OCX version is therefore also updated.

In the Common.bas module the following new function is included:


```
Public Function GetUserControlParentForm(ByVal Parent As Object) As VB.Form
If Parent Is Nothing Then Exit Function
If TypeOf Parent Is VB.Form Then
    Set GetUserControlParentForm = Parent
Else
    On Error Resume Next
    Dim UserControl As VB.UserControl, TempObj As VB.UserControl
    CopyMemory TempObj, ObjPtr(Parent), 4
    Set UserControl = TempObj
    CopyMemory TempObj, 0&, 4
    Do While Not UserControl Is Nothing
        If TypeOf UserControl.Parent Is VB.Form Then
            Set GetUserControlParentForm = UserControl.Parent
            Exit Do
        Else
            CopyMemory TempObj, ObjPtr(UserControl.Parent), 4
            Set UserControl = TempObj
            CopyMemory TempObj, 0&, 4
        End If
    Loop
    On Error GoTo 0
End If
End Function
```

Of course the GetUserControlParentForm function will return _Nothing_ in case the UserControl is sited on:
- Internet Explorer
- Excel, Word etc. (VBA)
- VB.PropertyPage

But when GetUserControlParentForm is used with an error handler then they should be no harm actually.
In this case then .ValidateControls will not be invoked.

However, it would be good to make this work also with VB.PropertyPage as .ValidateControls is supported on it.
But I was not able to get it done...

If somebody finds a way please let me know.  :Smilie: 
I will then extend the function and might rename it from 'GetUserControlParentForm' As VB.Form to 'GetUserControlTopParent' As Object.

In the meantime it then stays like this.




> This doesn't seem to fix if a ComboboxW gets the focus?


It does fix the ComboBoxW as well.

PS:
I do not forget the other open issues, which are:  :big yellow: 
- TextBoxW CCBorderStyleSingle border draw problem on certain conditions.
- "DataChanged-Prop-not-set" on TextBoxW, CheckBoxW and OptionButtonW
- FrameW does not contain a "HelpContextID"-Property
- Bug in the TreeView, which on Node-Deletes (which contain Children) does not seem to delete the Children, not updating the "Count" properly

----------


## Krool

EDIT:

I found a solution to get the VB.PropertyPage. But that cannot be wrapped in a single function as a 'GetUserControlTopParent' As Object does not work. It must be set explicitly to VB.PropertyPage.

So the function 'GetUserControlParentForm' will stay as currently is, instead the code in the UserControl itself will be enhanced.

So the solution would be as following: (will be implemented soon)


```
On Error Resume Next
With UserControl
If .Extender.CausesValidation = True Then
    InProc = True
    GetUserControlParentForm(.Parent).ValidateControls
    If Err.Number = 91 Then
        Err.Clear
        Dim PropertyPage As VB.PropertyPage, TempObj As VB.PropertyPage
        CopyMemory TempObj, ObjPtr(.Parent), 4
        Set PropertyPage = TempObj
        CopyMemory TempObj, 0&, 4
        PropertyPage.ValidateControls
    End If
    InProc = False
    If Err.Number = 380 Then
        WindowProcControl = MA_NOACTIVATEANDEAT
    ' ...
```

EDIT2:
if a UserControl is nested in another UserControl and sited on a VB.PropertyPage. In that case it don't work.
Thus beside 'GetUserControlParentForm' an additional function 'GetUserControlParentPropertyPage' is needed that walks up the UserControl chain first.
Luckily there is no chain on VB.PropertyPage.  :Smilie: 
Final solution will come soon.

----------


## Krool

Update released.

I have renamed 'GetUserControlParentForm' to 'GetUserControlTopParent'.

This is now the final solution to retrieve the top parent VB.Form of a UserControl:



```
Public Function GetUserControlTopParent(ByVal ParentControls As VBRUN.ParentControls) As VB.Form
If ParentControls.Count = 0 Then Exit Function
If TypeOf ParentControls(0) Is VB.Form Then
    Set GetUserControlTopParent = ParentControls(0)
Else
    Dim OldParentControlsType As VBRUN.ParentControlsType
    OldParentControlsType = ParentControls.ParentControlsType
    ParentControls.ParentControlsType = vbExtender
    If TypeOf ParentControls(0) Is VB.VBControlExtender Then
        ParentControls.ParentControlsType = vbNoExtender
        Dim UserControl As VB.UserControl, TempUserControl As VB.UserControl
        CopyMemory TempUserControl, ObjPtr(ParentControls(0)), 4
        Set UserControl = TempUserControl
        CopyMemory TempUserControl, 0&, 4
        Dim TempParentControlsType As VBRUN.ParentControlsType
        Do
            With UserControl
            If .ParentControls.Count = 0 Then Exit Do
            If TypeOf .ParentControls(0) Is VB.Form Then
                Set GetUserControlTopParent = .ParentControls(0)
                Exit Do
            Else
                TempParentControlsType = .ParentControls.ParentControlsType
                .ParentControls.ParentControlsType = vbExtender
                If TypeOf .ParentControls(0) Is VB.VBControlExtender Then
                    .ParentControls.ParentControlsType = vbNoExtender
                    CopyMemory TempUserControl, ObjPtr(.ParentControls(0)), 4
                    Set UserControl = TempUserControl
                    CopyMemory TempUserControl, 0&, 4
                    .ParentControls.ParentControlsType = TempParentControlsType
                Else
                    .ParentControls.ParentControlsType = TempParentControlsType
                    Exit Do
                End If
            End If
            End With
        Loop
    End If
    ParentControls.ParentControlsType = OldParentControlsType
End If
End Function
```

It is now safe in every scenario.

Because, before if the parent was not a VB.Form it was "assumed" to be a UserControl.
And this resulted in a crash when the Control is sited on a non-VB6 environment, e.g. VBA, IE etc. (tested)

Now trough the ParentControls it is possible to test if the Parent supports VB.VBControlExtender.
Because every UserControl implements this, thus instead of "assuming", we now know for sure it is a UserControl. (Thus CopyMemory is safe)
This check is repeated in the iteration for safety, because if the top parent is a VB.PropertyPage, it would cast the PropertyPage as UserControl...
So if it goes up the UserControl chain and detects the top parent is not a VB.Form and there is no further UserControl it will exit and return Nothing. (e.g. in case the top parent would be a VB.PropertyPage)

However, unfortunately there is no way to check if the top parent is a VB.PropertyPage or not. (if not a VB.Form of course)
So, they will be no support for VB.PropertyPage. (of course only for .ValidateControls)

An workaround would be to replace TextBoxW again to TextBox in every PropertyPage in the OCX version. (like it is in the Std-EXE version)
Of course if somebody would use the OCX in their PropertyPage the problem for mouse activation and validation would be there again...

----------


## wqweto

@Krool: There is no need to manually call `ValidateControl` when UC's in-place activation is implemented correctly IMHO. The internet floating IPAO implementation (based on `OLE Guid and interface definition` typelib) has this bug you are experiencing that I've been researching in the past. On my controls (hosting API created hwnds) I'm currently using something like this for API ctl WM_SETFOCUS handler (see pvSetFocus)


```
Private Type RECT
    Left                As Long
    Top                 As Long
    Right               As Long
    Bottom              As Long
End Type

Private Type IPAOHookStruct 'IOleInPlaceActiveObjectHook
    lpVTable            As Long                     'VTable pointer
    IPAOReal            As IOleInPlaceActiveObject  'Un-AddRefed pointer for forwarding calls
    TBEx                As ITranslateAccelerator    'Un-AddRefed native class pointer for making Friend calls
    ThisPointer         As Long
End Type

Private m_IPAOHookStruct        As IPAOHookStruct
Private m_bMouseActivate        As Boolean

Private Sub pvSetFocus()
    Dim pOleObject          As IOleObject
    Dim pOleInPlaceSite     As IOleInPlaceSite
    Dim pOleInPlaceFrame    As IOleInPlaceFrame
    Dim pOleInPlaceUIWindow As IOleInPlaceUIWindow
    Dim PosRect             As RECT
    Dim ClipRect            As RECT
    Dim FrameInfo           As OLEINPLACEFRAMEINFO
       
    On Error Resume Next
    Set pOleObject = Me
    Set pOleInPlaceSite = pOleObject.GetClientSite
    If Not pOleInPlaceSite Is Nothing Then
        pOleInPlaceSite.GetWindowContext pOleInPlaceFrame, pOleInPlaceUIWindow, VarPtr(PosRect), VarPtr(ClipRect), VarPtr(FrameInfo)
        'Get in-place frame and make sure it is set to our in-between
        'implementation of IOleInPlaceActiveObject in order to catch
        'TranslateAccelerator calls
        If m_IPAOHookStruct.ThisPointer <> 0 Then
            If Not pOleInPlaceFrame Is Nothing Then
                pOleInPlaceFrame.SetActiveObject m_IPAOHookStruct.ThisPointer, vbNullString
            End If
            If m_bMouseActivate Then
                pOleObject.DoVerb OLEIVERB_UIACTIVATE, 0, pOleInPlaceSite, 0, UserControl.hWnd, VarPtr(PosRect)
            End If
        End If
    End If
End Sub
```

The difference w/ your current impl (besides `ThisPointer` holding naked pointer As Long and correspondingly tweaked typelib) as far as I can see is that on `m_bMouseActivate` flag I'm calling `DoVerb OLEIVERB_UIACTIVATE` at which point control validation takes place (must be). I'm certainly not calling `ValidateControls` on top container manually and just confirmed that `Validate` is raised on source control both on keyb and mouse activation of such IPAO impl in UC.

cheers,
</wqw>

----------


## DEXWERX

@wqweto awesome. Thanks for clearing that up. 
It's great to have people with so much experience with user controls helping out.

----------


## Krool

Thanks wqweto.

Unfortunately does 'DoVerb OLEIVERB_UIACTIVATE' not solve the problem. It is actually only a SetFocus command to the UserControl.
That 'DoVerb OLEIVERB_UIACTIVATE' does actually the same as in my WM_SETFOCUS handler:


```
    Case WM_SETFOCUS
        If wParam <> UserControl.hWnd Then SetFocusAPI UserControl.hWnd: Exit Function
```

If I do remove the WM_MOUSEACTIVATE handler, then the validation is working the "native good way".
However, in order to have full functionaly I need to handle WM_MOUSEACTIVATE. (reason why see example below)

Just do the following test in the CheckBoxW control:
Remove the WM_MOUSEACTIVATE handler. Now when you click on it the check is not set, only when you click again.
Only when I remove the 'DoVerb OLEIVERB_UIACTIVATE' (or SetFocusAPI UserControl.hWnd) in the WM_SETFOCUS handler the check is set on the first click.
But then you have the issue of wrong TabIndex, ActiveControl not new one etc.

So my conclusion is now that I keep the infrastructure as it is.
Maybe at some point I manage to get the VB.PropertyPage to work. (manual .ValidateControls in WM_MOUSEACTIVATE)

----------


## Krool

Update released. (quite important when using the TreeView control)

Now the child node objects of a TreeView are removed when removing a parent node object.
Thus the 'Nodes.Count' property returns the correct number after a parent node removal.

Furthermore there was a minor error in the ListView control related to the filter edit. (UseColumnFilterBar = True)
When the user clicks in a filter the whole text will be selected.
If the user now clicks again at a specific character the caret will be positioned to that character. (this was not working before)

And some other minor internal improvements.




> We also have detected a Bug in the TreeView, which on Node-Deletes (which contain Children)
> does not seem to delete the Children, not updating the "Count" properly - and then later 
> (whilst collapsing/re-expanding Nodes) will run into an error.


The "Count" problem is now solved. It should also fix the "then later" problem. However, please check.




> FrameW does not contain a "HelpContextID"-Property (as the VB-original)


The problem is that the HelpContextID property is only available when the UserControl has the 'CanGetFocus' property to True.
In case of the FrameW control this is not wanted. The Frame shouldn't be allowed to get focus.
That's why I do not have a solution for this problem..




> Textbox, small problem
> 
> This is an optical problem, no complaints about the functionality.
> When the CCBorderStyleSingle is set, the control loses the upper horizontal line of the border.
> It is ok when the textbox doesn't have the focus.
> 
> To retrace:
> Start a fresh VB.
> Add the Krool controls.
> ...


I now could replicate the problem. (according to chosk's example)
However, the normal VB.TextBox control does also have the same "glitch" in that scenario.
So I am afraid that this is a MS bug. (?)




> there's another thing with TextBoxes that we made use of in our old Forms - it's the DataChanged-Property,
> which (in case of the TextBoxW-replacements) never seems to be set (when content
> is changed that is different from the "initial Form-Designer-Value").


I did a quick test with the VB.Data control and an access DB.
When the record is loaded into the TextBoxW control the DataChanged property returns False. If I now change the text it returns True.
So in my understanding it does work. (?)
Edit: You can also try to use the TextBoxW.Modified property. (of course you need to set it to False manually after you load the data - as initial value)

----------


## Schmidt

> The "Count" problem is now solved. It should also fix the "then later" problem. However, please check.


I've checked, but it doesn't seem to work "fully" yet (tested with a larger Tree in one of our Forms - 
will try to post a reduced example for that...).
Currently it looks, as if only the "first-level-children" will be removed - but not in a fully recursive manner -
as said, will try to post more details on that later...




> The problem is that the HelpContextID property is only available when the UserControl has the 'CanGetFocus' property to True.
> In case of the FrameW control this is not wanted. The Frame shouldn't be allowed to get focus.
> That's why I do not have a solution for this problem..


In that case, a "manually applied" (explicitely coded) HelpContextID-Property might help (altough probably 
breaking the BinComp or the SxS-manifest then - but for the next version it might worth a try)...
Then managing the F1-KeyPress yourself inside FrameW (when it got "EnterFocus"-state) - and then 
delegating to the usual "Show-Help"-API-Call manually as well.




> I did a quick test with the VB.Data control and an access DB.
> When the record is loaded into the TextBoxW control the DataChanged property returns False. If I now change the text it returns True.
> So in my understanding it does work. (?)
> Edit: You can also try to use the TextBoxW.Modified property. (of course you need to set it to False manually after you load the data - as initial value)


The DataChanged-Prop seems related to DataBinding, but this is only *one* case where it applies -
because it works (and is used by us) also without any DataBindings in some Forms...

The behaviour is (quite similar to your .Modified-Prop), that the "initial FormDesigner-Value" of a Control 
will not cause the DataChange-Prop to go to True (when the Form is loading) - so far so good...

However, *any* change of a Controls-Content that follows (be it "programmatically" or "by User-Input"), 
will set (in the VB.TextBox) the DataChanged-Prop to True - though one can "reset" it to False again after e.g.
a "programmatical change" which was a "desired one" (e.g. when filled from a DB on Form-Load).

The following Example shows the differences we stumbled over (all without any DataBinding)
The Form needs:
- a Timer1
- a Text1 and a Label1 from VBs intrinsics
- a TextBoxW1 and a LabelW1 from the CCR14-OCX


```
Private Sub Form_Load()
  Timer1.Interval = 100
  Text1.Text = "Initial-Value":     Debug.Print "Text1: "; Text1.DataChanged
  TextBoxW1.Text = "Initial-Value": Debug.Print "TextBoxW1: "; TextBoxW1.DataChanged
  
  'after setting the .Text-Prop programmatically, we reset the Flag (to be able to see new changes)
  Text1.DataChanged = False
  TextBoxW1.DataChanged = False
End Sub

Private Sub Timer1_Timer()
  Label1.Caption = Text1.DataChanged
  LabelW1.Caption = TextBoxW1.DataChanged
End Sub
```

From your description it sounds as if your TextBoxW.Modified Property shows the desired behaviour 
(working the same way as the .DataChanged-Prop in the old TextBox) - but since we currently "just replace the ProgID"
in a loop over all our *.frm Files, it would be nice when the two (.Modified and .DataChanged) would be "synchronized".

Thanks for working on fixing these things with such a short response-time BTW... 

Olaf

----------


## Schmidt

Ok, here the promised example for the Tree-Node-Remove-Problem (I'm already using the recent CCR14 version) - 
accompanied by another issue with AutoSized-LabelWs which "freshly came in" from my colleagues:

The Form needs 3 freshly dropped Controls, all in their "virginal, unchanged state":
VB.Label1,  VBCCR14.LabelW1,  and a VBCCR14.TreeView1 


```
Private Sub Form_Load()
  With TreeView1
  
    .Nodes.Add , , "Node_0", "Node_0"
    
       .Nodes.Add "Node_0", TvwNodeRelationshipChild, "Node_0_0", "Node_0_0"
          .Nodes.Add "Node_0_0", TvwNodeRelationshipChild, "Node_0_0_0", "Node_0_0_0"
          .Nodes.Add "Node_0_0", TvwNodeRelationshipChild, "Node_0_0_1", "Node_0_0_1"
      
       .Nodes.Add "Node_0", TvwNodeRelationshipChild, "Node_0_1", "Node_0_1"
          .Nodes.Add "Node_0_1", TvwNodeRelationshipChild, "Node_0_1_0", "Node_0_1_0"
          .Nodes.Add "Node_0_1", TvwNodeRelationshipChild, "Node_0_1_1", "Node_0_1_1"
    
 
    Debug.Print "NodeCount should be 7:"; .Nodes.Count
    .Nodes.Remove "Node_0" '<- now we remove the Root-node
    Debug.Print "NodeCount should be 0:"; .Nodes.Count
    
  End With
  
  With Label1
    Debug.Print .Name; ".Width, initial AutoSize False: "; .Width
    .Font.Name = "Arial"
    .Font.Size = 10
    .Caption = "Some Text"
    .AutoSize = True
    Debug.Print .Name; ".Width, after AutoSize True: "; .Width
    .Caption = "Some more Text"
    Debug.Print .Name; ".Width, after Caption-Change: "; .Width
  End With

  With LabelW1
    .WordWrap = False '<- just to match with the VB.Label Default
    Debug.Print .Name; ".Width, initial AutoSize False: "; .Width
    .Font.Name = "Arial"
    .Font.Size = 10
    .Caption = "Some Text"
    .AutoSize = True
    Debug.Print .Name; ".Width, after AutoSize True: "; .Width
    .Caption = "Some more Text"
    Debug.Print .Name; ".Width, after Caption-Change: "; .Width
  End With
End Sub
```

HTH

Olaf

----------


## Krool

Update released.




> I've checked, but it doesn't seem to work "fully" yet (tested with a larger Tree in one of our Forms - 
> will try to post a reduced example for that...).
> Currently it looks, as if only the "first-level-children" will be removed - but not in a fully recursive manner


Oh yes, of course a recursion needs to be done to get all children on each level.
This should be now fixed, please check again.




> another issue with AutoSized-LabelWs which "freshly came in" from my colleagues:


This kind of issue we had "already" and was solved.
However, when doing this in Form_Load it seems to not work. (else when Form is displayed this does already work)

Your other points are noted and will be checked soon.

Thanks Olaf for your reports anyhow, such a project 1:1 replacement conversion is always a good "trial of fire" test.  :Smilie:

----------


## Krool

I have detected a major important bug that needs to be fixed!

Right ahead: I do have a solution in mind for this, later more.

1. Start a fresh Std-EXE project

2. Load VBCCR14.OCX components (or Std-EXE CommonControls, doesn't matter)

3. Put first a TextBoxW1 and then a CommandButtonW1 on Form1.

4. Add new Form (as Form2)

5. Put a TextBoxW1 and a TextBoxW2 on Form2.

6. put following code in Form1:


```
Private Sub CommandButtonW1_Click()
Form2.Show vbModal
End Sub

Private Sub Form_Load()
CommandButtonW1.Default = True
End Sub
```

7. Run project -> when on TextBoxW1 press Return key -> Form2 will be shown modally -> now press right arrow key

The IOleInPlaceActiveObject seems to stuck on Form1 when Form2 is shown modally, thus the accelerator keys are not trapped in Form2 on the TextBoxW controls, resulting that instead of moving the caret on right arrow key the other TextBoxW2 is focused instead.

The solution in mind is when ActivateIPAO is called on a new Form then re-subclass the VTable for IOleInPlaceActiveObject with a new ObjectPointer from Form2, this way it is not "stuck" on Form1.

However, that solution is still in process and I need some time to find an optimal way. However, I do already want to make this bug public.

What I do also find interesting is when "clicking" (by mouse) CommandButtonW1 the issue is not happening.
Only when invoking by return key (via Default) the problem seems to appear. (I have a clue, but not sure..)

Did somebody else already encountered this bug? Or is this new?
Can everybody reproduce it?

EDIT: On modeless Form2 this bug is of course not happening

----------


## Krool

Update released.




> However, unfortunately there is no way to check if the top parent is a VB.PropertyPage or not. (if not a VB.Form of course)
> So, they will be no support for VB.PropertyPage. (of course only for .ValidateControls)


Now VB.PropertyPage is supported for .ValidateControls (CausesValidation; mouse activation) when a Control is sited on such a VB.PropertyPage.
There was indeed no VB native way to check if the top parent is a VB.PropertyPage or not. (TypeOf)
However, with a manual IUnknown.QueryInterface for IPropertyPage it is possible to check for it.

The 'GetUserControlTopParent' in Common.bas is removed and replaced by a generic 'GetTopUserControl' function.
That generic GetTopUserControl function will return the current UserControl if there is no "upper" UserControl, else it will walk the chain up to the final UserControl.
It is intended that such a generic function is placed in Common.bas as it can be used for many other purposes.

Included 'VTableInterfaceSupported' function in VTableHandle.bas. This is a generic function that will do a IUnknown.QueryInterface on a given IID (as String) and returns a Boolean if it is supported or not.

Included 'ComCtlsTopParentValidateControls' function in ComCtlsBase.bas. This is a specific wrapper function that will do following:


```
Public Sub ComCtlsTopParentValidateControls(ByVal UserControl As Object)
With GetTopUserControl(UserControl)
If TypeOf .Parent Is VB.Form Then
    Dim Form As VB.Form
    Set Form = .Parent
    Form.ValidateControls
Else
    Const IID_IPropertyPage As String = "{B196B28D-BAB4-101A-B69C-00AA00341D07}"
    If VTableInterfaceSupported(.Parent, IID_IPropertyPage) = True Then
        Dim PropertyPage As VB.PropertyPage, TempPropertyPage As VB.PropertyPage
        CopyMemory TempPropertyPage, ObjPtr(.Parent), 4
        Set PropertyPage = TempPropertyPage
        CopyMemory TempPropertyPage, 0&, 4
        PropertyPage.ValidateControls
    End If
End If
End With
End Sub
```

So in each control it is just enough to make a 'Call ComCtlsTopParentValidateControls(Me)' and test for error code 380.

----------


## Sam_

This set of controls would be 100% complete for me if it could have:

> TreeView with columns (would need extending with columns and subitems for each node) - currently I use this but there are a few issues and keeping just one set of controls up to date and in the same place makes like easier
> COM control (never expect this to happen, but I don't get on with MSCOMM and I hate dragging the ocx around)

and then I would never need anything else  :Big Grin: 

Keep up the amazing work!

----------


## dreammanor

> This set of controls would be 100% complete for me if it could have:
> 
> > TreeView with columns (would need extending with columns and subitems for each node) - currently I use this but there are a few issues and keeping just one set of controls up to date and in the same place makes like easier
> > COM control (never expect this to happen, but I don't get on with MSCOMM and I hate dragging the ocx around)
> 
> and then I would never need anything else 
> 
> Keep up the amazing work!


I don't know what "COM control" means. Krool has released the pre-compiled VBCCR14.OCX:
http://www.vbforums.com/showthread.p...55#post5129155

----------


## Arnoutdv

Sam_ is referring to an alternative of the MSCOMM component which is used for accessing (serial) COM ports.

----------


## Krool

Update released.

Issue described on post #1431 is now solved.

The OCX is also updated, except the change concerning the default value of the WordWrap property for the LabelW control.
This will be respected only in a future OCX release.

----------


## ChenLin

Can listview set the height of each item?

----------


## softv

Hi Krool, 

Please refer to my message #1363 and your reply message #1364 (related to the RichTextBox control).

With respect to the solution you provided to fix one error at it's root cause, what happens now is that whenever my RichTextBox control (say, rtb1) becomes empty (i.e. having no text), the following error occurs:
"Subscript out of range"

The above-mentioned error occurs at the following line:


```
ReDim StreamStringIn(0 To StreamStringInLength - 1) As Byte
```

This is because 'StreamStringInLength' is 0.

So, at my end, I am keeping your old lines of code itself (i.e. without adding '-1') and hence I am still resorting to use my following line of code:


```
Value = Left$(Value, Len(Value))
```

I, in fact, have one more line of code before the above line to tackle the issues related to VbCrLf. It is as follows:


```
Value = Replace(RtfStreamStringOut(), vbCrLf, vbCr)
```

So far, everything has been working smoothly at my end with my above two lines of code. But, I would love to hear from you as to whether there is any other solution to fix the error at it's root cause.

Best of all wishes to you, ever, for your wonderful work!

----------


## Krool

> Please refer to my message #1363 and your reply message #1364 (related to the RichTextBox control).
> 
> With respect to the solution you provided to fix one error at it's root cause, what happens now is that whenever my RichTextBox control (say, rtb1) becomes empty (i.e. having no text), the following error occurs:
> "Subscript out of range"


Oops. Thank you.

Update released.

Fix was following change in RichTextBoxBase.bas:


```
Public Sub RtfStreamStringIn(ByVal Value As String)
StreamStringInLength = LenB(Value)
Erase StreamStringIn()
If StreamStringInLength > 0 Then
    ReDim StreamStringIn(0 To (StreamStringInLength - 1)) As Byte
    CopyMemory StreamStringIn(0), ByVal StrPtr(Value), StreamStringInLength
End If
StreamStringInPos = 0
End Sub
```

----------


## Krool

> by another issue with AutoSized-LabelWs which "freshly came in" from my colleagues:
> 
> 
> 
> ```
> Private Sub Form_Load()
>   
>   With Label1
>     Debug.Print .Name; ".Width, initial AutoSize False: "; .Width
> ...


I pointed out this issue now.
The problem is certainly that the auto sizing feature is dependent on the UserControl_Paint event, which is not being fired during Form_Load.
Only solution which come into my mind is to remove the auto size calculation in UserControl_Paint and do it in a separate routine with a memory DC.
I think that little overhead is reasonable and certainly the intrinsic Label control must be doing something similar..
So I think that problem is worth solving in the near future.

----------


## DaveInCaz

I noticed a small glitch in the display of the StatusBar (using VBCCR14.ocx). When a panel is visible showing the time there is a noticeable flicker whenever the time is updated. This could be, obviously, at a rate of 1 Hz (once per second) which is frequent enough to be an inconvenient problem.

I eventually realized that this occurs whether you use the built-in time feature of the control, or do something like use a timer control to manually update the time string. Probably it flickers with any update but only the frequent clock-based ones are noticed.

I have no idea if this is something which could conceivably be fixed, and it may not be worth the time even if it is, but I thought I should at least point it out. I'm running Windows 7 64 bit in case that makes any difference.

Thanks Krool

----------


## chosk

If it is time display on a Statusbar panel, I don't see any flicker. I attached a short video. For this I am using the VBCCR14.ocx. Win7 x64.

----------


## DaveInCaz

> If it is time display on a Statusbar panel, I don't see any flicker. I attached a short video. For this I am using the VBCCR14.ocx. Win7 x64.


After seeing your video (nicely done BTW) I did some more tests to see if I could find another cause of the flicker. I could not. I disabled the entire timer event because it did some other manipulations of form controls and thought it was possible this could be causing the flicker. But no, even with the timer totally nonfunctional the flicker occurs. And if I switch the panel type from time to text, the flicker stops.

What difference between our programs (or systems) are we overlooking which might cause this?

----------


## Krool

Update released.

The AutoSize property in the LabelW control got improved. The auto sizing is now done independently in a separate routine with a memory DC, thus not located anymore in the UserControl_Paint procedure.
That change makes it now possible set the .AutoSize = True during Form_Load and check immediately after the .Width property.
Therefore the behavior in below test from Schmidt is now the same as in the original VB.Label control.




> by another issue with AutoSized-LabelWs which "freshly came in" from my colleagues:
> 
> 
> 
> ```
> Private Sub Form_Load()
>   
>   With Label1
>     Debug.Print .Name; ".Width, initial AutoSize False: "; .Width
> ...


The OCX version has also been updated concerning this.

----------


## chosk

Hi Krool,

Regarding the RichTextBox (OCX version. Haven't try the Std-Exe).

I don't know whether this is a bug or is a setting I missed. I have Multiline is True and ScrollBar is 3 - vbBoth. When the content is full, the vertical scroll bar will auto appear. Then when I resize the Form taller (therefore RichTextBox taller) to show all the content, the scrollbar disappear as normal behaviour. However, when I resize the Form back to shorter, the vertical scrollbar doesn't auto re-appear. Only after I let go the mouse and then resize again, then the vertical scrollbar re-appear.

No problem with the horizontal scrollbar.

----------


## chosk

The same issue with the Std-Exe. Resize the Form taller will trigger the vertical scrollbar to appear.

I attach a video.

----------


## Krool

> In that case, a "manually applied" (explicitely coded) HelpContextID-Property might help (altough probably 
> breaking the BinComp or the SxS-manifest then - but for the next version it might worth a try)...
> Then managing the F1-KeyPress yourself inside FrameW (when it got "EnterFocus"-state) - and then 
> delegating to the usual "Show-Help"-API-Call manually as well.


I want to address that issue further.

Issue is that the FrameW control does not provide a HelpContextID property. (like the VB.Frame)
The problem is that the HelpContextID property is only available when the UserControl has the 'CanGetFocus' property to True.
In case of the FrameW control this is not wanted. The Frame shouldn't be allowed to get focus.

So your idea sounds good but in practice how to accomplish?
The manual calling HtmlHelp part with HH_HELP_CONTEXT does work. However, problem remains of how to catch such an F1 keypress?
VB's logic is like this:
_The current context number is the value of HelpContextID for the object that has the focus. If HelpContextID is set to 0, then Visual Basic looks in the HelpContextID of the object's container, and then that object's container, and so on. If a nonzero current context number can't be found, the F1 key is ignored._
So how to play within that chain in a manual HelpContextID property?




> I don't know whether this is a bug or is a setting I missed. I have Multiline is True and ScrollBar is 3 - vbBoth. When the content is full, the vertical scroll bar will auto appear. Then when I resize the Form taller (therefore RichTextBox taller) to show all the content, the scrollbar disappear as normal behaviour. However, when I resize the Form back to shorter, the vertical scrollbar doesn't auto re-appear. Only after I let go the mouse and then resize again, then the vertical scrollbar re-appear.


Interesting, thanks for reporting.
Indeed this seems like a minor issue. However, if you set the 'DisableNoScroll' to True this issue will not appear, like in the TextBoxW.
Only when 'DisableNoScroll' is False there is a issue on resize and auto re-appear as you described.
I have found an solution, but I am not quite sure why this is necessary.

Like it is current within UserControl_Resize:


```
If RichTextBoxHandle <> 0 Then MoveWindow RichTextBoxHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
```

Possible fix:


```
If RichTextBoxHandle <> 0 Then
    MoveWindow RichTextBoxHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
    InvalidateRect RichTextBoxHandle, ByVal 0&, 0
    UpdateWindow RichTextBoxHandle
End If
```

Possible fix alternative:


```
If RichTextBoxHandle <> 0 Then
    MoveWindow RichTextBoxHandle, 0, 0, .ScaleWidth, .ScaleHeight, 0
    InvalidateRect RichTextBoxHandle, ByVal 0&, 0
    UpdateWindow RichTextBoxHandle
    SetWindowPos RichTextBoxHandle, 0, 0, 0, 0, 0, SWP_DRAWFRAME Or SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER
End If
```

I don't know why this is necessary as when bRepaint is 1 on MoveWindow this is all supposed to be done...
MSDN:
_If the bRepaint parameter is TRUE, the system sends the WM_PAINT message to the window procedure immediately after moving the window (that is, the MoveWindow function calls the UpdateWindow function)_

----------


## Schmidt

> I want to address that issue further.
> 
> Issue is that the FrameW control does not provide a HelpContextID property. (like the VB.Frame)
> The problem is that the HelpContextID property is only available when the UserControl has the 'CanGetFocus' property to True.
> In case of the FrameW control this is not wanted. The Frame shouldn't be allowed to get focus.
> 
> So your idea sounds good but in practice how to accomplish?
> The manual calling HtmlHelp part with HH_HELP_CONTEXT does work. However, problem remains of how to catch such an F1 keypress?
> VB's logic is like this:
> ...


If that gets too complicated, there's a quite simple way out (since it's a *very* simple Control really).

Here's a working, pure VB6-approach for such a Frame:
- which consists of an "outer" Public ucFrame.ctl
- and an inner, Private ucNoFocus.ctl (which does the Drawing on itself).

Into the inner ucNoFocus (which gets adjusted with CanGetFocus = False):


```
Option Explicit

Private mCaption As String

Private Sub UserControl_Initialize()
  AutoRedraw = True
  ScaleMode = vbPixels
End Sub

Public Property Get BackColor() As Long
  BackColor = UserControl.BackColor
End Property
Public Property Let BackColor(ByVal RHS As Long)
  UserControl.BackColor = RHS
End Property

Public Property Get Caption() As String
  Caption = mCaption
End Property
Public Property Let Caption(ByVal RHS As String)
  mCaption = RHS: UserControl_Resize
End Property

Private Sub UserControl_Resize()
  Dim yOffs, xOffs, TW
  Const BorderColor = &H888888
  Cls
  xOffs = 8
  yOffs = TextHeight(mCaption) / 2
  If Len(mCaption) Then
    TW = TextWidth(mCaption)
    CurrentX = xOffs + 3: CurrentY = 0: Print mCaption
    
    Line (0, yOffs)-(xOffs, yOffs), BorderColor
    Line (0, yOffs)-(0, ScaleHeight), BorderColor
    Line (0, ScaleHeight - 1)-(ScaleWidth, ScaleHeight - 1), BorderColor
    Line (ScaleWidth - 1, yOffs)-(ScaleWidth - 1, ScaleHeight), BorderColor
    Line (ScaleWidth - 1, yOffs)-(xOffs + 6 + TW, yOffs), BorderColor
  Else
    Line (0, 0)-(ScaleWidth - 1, ScaleHeight - 1), BorderColor, B
  End If
End Sub
```

And this into the outer ucFrame-Control with the above ucNoFocus1 on it (adjust it with "ControlContainer=True"):


```
Option Explicit

Public Property Get BackColor() As Long
  BackColor = ucNoFocus1.BackColor
End Property
Public Property Let BackColor(ByVal RHS As Long)
  ucNoFocus1.BackColor = RHS
End Property

Public Property Get Caption() As String
  Caption = ucNoFocus1.Caption
End Property
Public Property Let Caption(ByVal RHS As String)
  ucNoFocus1.Caption = RHS
End Property
 
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
  Extender.TabStop = False
End Sub

Private Sub UserControl_Resize()
  ucNoFocus1.Move 0, 0, ScaleWidth, ScaleHeight
End Sub
```

And that's it - no APIs, no SubClassing, no VTable-manipulations... just straight-forward VB6...

Ok, TextOutW would have to be used for rendering the Caption in a real implementation,
but the Main-Problem, how to get the VB6-HelpContextID-behaviour back on a "NonFocusable/NonTabStopable" Container seems solved.

Olaf

----------


## Trdrego

> If that gets too complicated, there's a quite simple way out (since it's a *very* simple Control really).
> 
> Here's a working, pure VB6-approach for such a Frame:
> - which consists of an "outer" Public ucFrame.ctl
> - and an inner, Private ucNoFocus.ctl (which does the Drawing on itself).
> 
> Into the inner ucNoFocus (which gets adjusted with CanGetFocus = False):
> 
> 
> ...


Great, I was looking for exactly something like this. Thanks :Smilie:

----------


## Krool

> And that's it - no APIs, no SubClassing, no VTable-manipulations... just straight-forward VB6...


You know that this project has nothing todo with a simple, no subclassing, no VTable-manipulations etc... solution.
It is intended that the FrameW control hosts a BS_GROUPBOX window to draw the system frame border and all other overheads, like VisualStyles, RightToLeft etc. as well as replace all existing VB.Frame equivalent properties of course.
So I do have an interest of including the missing HelpContextID property, but it is not about simple.  :Smilie: 
Also on ToolBar control there is also a HelpContextID missing.
I need a way of including such functionality without the trick with an outer and inner UserControl. With that trick there is also the cosmetic downside that other methods and properties gets exposed which are not wanted, e.g. .SetFocus.

----------


## chosk

> Interesting, thanks for reporting.
> Indeed this seems like a minor issue. However, if you set the 'DisableNoScroll' to True this issue will not appear, like in the TextBoxW.
> Only when 'DisableNoScroll' is False there is a issue on resize and auto re-appear as you described.
> ...
> ...
> I don't know why this is necessary as when bRepaint is 1 on MoveWindow this is all supposed to be done...
> MSDN:
> _If the bRepaint parameter is TRUE, the system sends the WM_PAINT message to the window procedure immediately after moving the window (that is, the MoveWindow function calls the UpdateWindow function)_


I set the 'DisableNoScroll' to True and I believe issue remains.

Regarding the Repaint, I am no expert in this. I wonder whether there is similarity with the VB6 Picturebox where the paint event won't fire when the picturebox is resized smaller but will fire when resized bigger. Because there may be resemblance experience.

----------


## chosk

I search and found this article:
https://www.vb-helper.com/tip_refres...nvalidate.html

So I added RichTextBox1.Refresh after RichTextBox1 is resized and it seems to solve the issue.

----------


## Minieggs

Just stumbled across this thread

Is it possible to have a checkbox with a bold label WITHOUT removing its theme ?

By that I mean I want the checkbox to remain visually the same, have bold text and when it has the focus the focus rectangle goes around the box and the label (and not just the box which i would if you used a separate label object)

Thanks

----------


## Zphere

@Krool,

I started using your controls collection for displaying very long and unicode path/file names.
It's the first time I'm using a ListView control so please excuse if the following question sounds somehow trivial for you.

It seems that the ListView control isn't able to display a string (path) that exceeds the 260 chars boundary.
I created a ListView control with default options.

Simple code snippset:


```
Dim sPath as string
sPath="\\?\D:\欢迎\test1\test2\test3\test4\test5\test6\test7\test8\test9\test10\test11\test12\test13\test14\test15\test16\test17\test18\
test19\test20\test21\test22\test23\test24\test25\test26\test27\test28\test29\test30\test31\test32\test33\test34\test35\test36\test37\
test38\test39\test40\test41\123456789_123456789\1ＤＥＫＯのじゃんくぼっくす。.mht"

With lvwData
    .ColumnHeaders.Clear
    .ListItems.Clear
    .ColumnHeaders.Add , , "File Paths", , LvwColumnHeaderAlignmentLeft
    .ListItems.Add , , sPath
    If Len(sPath) > 259 then .ForeColor = vbRed
    .ColumnHeaders(1).AutoSize (1)
End With
```

Result in the ListView:
"\\?\D:\欢迎\test1\test2\test3\test4\test5\test6\test7\test8\test9\test10\test11\test12\test13\test14\  test15\test16\test17\test18\
test19\test20\test21\test22\test23\test24\test25\test26\test27\test28\test29\test30\test31\test32\te  st33\test34\test35\test36\test37"
...whereas the label tooltip shows the full path  :EEK!: 

Although this behaviour offers a very simple possibility to display the potions of
a file path that can be accessed from the OS I wonder if this is "by design" or if it is a bug?
I fiddled around with possible options of the ListView property page - but no success.

Thanks in advance for any response.

----------


## Krool

> I started using your controls collection for displaying very long and unicode path/file names.
> It's the first time I'm using a ListView control so please excuse if the following question sounds somehow trivial for you.
> 
> It seems that the ListView control isn't able to display a string (path) that exceeds the 260 chars boundary.
> I created a ListView control with default options.
> 
> Simple code snippset:
> 
> 
> ...


It's not a bug.

MSDN:
_Note that although the list-view control allows any length string to be stored as item text, only the first 260 TCHARs are displayed._

----------


## Zphere

Thanks much for clarification.
That's exactly what I wanted to know.

----------


## MountainMan

I mainly am a VBA programmer so I don't use .ctl files very often but I have a question for you. The .ocx approach is good because compile times are much better and because we can use unicode at design time. However, the .ctl approach allows us to have just one file and not have to deal with a separate .ocx file for our users. So, is there any way to get the best of both worlds? Can we develop code with the .ocx and then switch to the .ctl files for the production code? I haven't read every post in the thread but I have read most and I haven't seen anyone bring this up. It this possible?

----------


## Arnoutdv

No you can not work with the compiled OCX in the IDE and somehow have the source code of the controls compiled in your final executable, unless you create 2 separate project files.
In project A you use the OCX and all your own source files.
In project B you use the CTLs and the same source files.
But why not use the OCX and use a manifest which will be embedded in your application? No need to install the OCX on a client computer.

----------


## chosk

> However, the .ctl approach allows us to have just one file and not have to deal with a separate .ocx file for our users. So, is there any way to get the best of both worlds? Can we develop code with the .ocx and then switch to the .ctl files for the production code? I haven't read every post in the thread but I have read most and I haven't seen anyone bring this up. It this possible?


This is exactly what I am doing.

You have to first do a bit of test work to see what is needed to change from the OCX to .ctl Std-Exe. To get myself familiar with what to change/switch, I created 2 simple and similar test projects with some codes for the control event handler to see the diffrences in the files. One project with the OCX and the other with the Std-Exe. Then open the .vbp and all the .frm with Notepad to see what are the differences and these differences are what need to be changed/switched. 

When time come for switching, make a copy of the project as backup. Add in all the Std-Exe controls, modules, class modules and pages that you will need so that your projects will have everything needed. Then open .vbp and all the .frm with Notepad and do a Replace to replace the OCX with the Std-Exe ctls. Make very sure you have a backup before doing this so that if anything, you know where you need to redo amd more.

Hope this help.

----------


## Schmidt

> You know that this project has nothing todo with a simple, no subclassing, no VTable-manipulations etc... solution.


I certainly didn't intend to "push a button" on your end - just to provide a simple example which solved the problem (how to make a NonFocusable Control with a HelpContextID) - 
my comment was meant for those, who wanted to use the example "on its own" (as a starting-point for a simple Frame-Control).




> It is intended that the FrameW control hosts a BS_GROUPBOX window to draw the system frame border and all other overheads, like VisualStyles, RightToLeft etc. as well as replace all existing VB.Frame equivalent properties of course.
> So I do have an interest of including the missing HelpContextID property, but it is not about simple.


Kind of disagreeing here... being the nerds we are, it is *always* about, how to accomplish things in a simpler way IMO.
In this regard though (now that we are at it) - some of your controls surely *could* be written with significantly less lines of code
(FrameW being one of those, which are "graphically" not really challenging, ButtonW, CheckBoxW, OptionBoxW ... etc are others).

If you think logically about it for a moment..., what is it that a FrameControl really *does*? - right, nothing (besides being a container).
And what does it consist of graphically? - right, 5 thin lines have to be drawn + a single TextString-Caption has to be rendered.

Can somebody here explain to me, why on earth such a simple Control would need interaction with an MS-Dll which provides a Control-Window,
then allows communication only per SendMessage - (and is hiding the most interesting bits - easy to use Rendering-Interfaces - from developers) - 
instead of simply drawing things on your own - or using (if Win-conform-Theming is wanted), uxTheme.dll directly for that?




> Also on ToolBar control there is also a HelpContextID missing.


Then the code below for a transparent, unicode-aware (uxTheme.dll using) VB.Frame-compatible-Control might inspire you, to
maybe rewrite/shorten your codebase for at least some of your Controls which are similar (Button-like Controls and ToolBar included).
The savings compared to your current FrameW-Control are about 500 lines - so I guess with a consequently applied 
uxTheme.dll based approach you could save about 5000 lines of code over your whole project - and make most of your Controls
look much more "VBish" (and understandable) on the inside.




> I need a way of including such functionality without the trick with an outer and inner UserControl. 
> With that trick there is also the cosmetic downside that other methods and properties gets exposed which are not wanted, e.g. .SetFocus.


Well, the inner UC was used to avoid having to use SubClassing in my previous example - the new Demo 
below will use a single-Control + SubClassing (to suppress the MouseActivation of the FrameControl) instead.

That leaves the remaining "SetFocus" (along with the also available Focus-Events) - but having "something extra to just ignore"
would not bother me at all - compared to "something badly missing" - and perhaps some users will find creative uses for a
Focus- and Tabbing-enabled Frame or ToolBar (e.g. in case of a ToolBar I'd find the ability to "Tab through its Buttons" a convenient feature.

Ok, here a ScreenShot:


And here the Demo-Code for "ucFrameT":  http://vbRichClient.com/Downloads/ucFrameT.zip

Olaf

----------


## Krool

> If you think logically about it for a moment..., what is it that a FrameControl really *does*? - right, nothing (besides being a container).
> And what does it consist of graphically? - right, 5 thin lines have to be drawn + a single TextString-Caption has to be rendered.
> 
> Can somebody here explain to me, why on earth such a simple Control would need interaction with an MS-Dll which provides a Control-Window,
> then allows communication only per SendMessage - (and is hiding the most interesting bits - easy to use Rendering-Interfaces - from developers) - 
> instead of simply drawing things on your own - or using (if Win-conform-Theming is wanted), uxTheme.dll directly for that?


Yes I will consider it for future to-do to make the drawing directly, without resorting to MS-Dll Control-Window.
There will be actually no difference on the appearance like now (also in regard to transparency etc.) but indeed it will simplify that control at some point.




> Then the code below for a transparent, unicode-aware (uxTheme.dll using) VB.Frame-compatible-Control might inspire you, to
> maybe rewrite/shorten your codebase for at least some of your Controls which are similar (Button-like Controls and ToolBar included).
> The savings compared to your current FrameW-Control are about 500 lines - so I guess with a consequently applied 
> uxTheme.dll based approach you could save about 5000 lines of code over your whole project - and make most of your Controls
> look much more "VBish" (and understandable) on the inside.


Thanks. On FrameW control I certainly agree to abandon the MS-Dll Control-Window. (like stated above)
However, for ToolBar control I do disagree and will stay with the MS-Dll Control-Window.

About the lines of code:
Please note that on each control there is a coding "overhead" of at least 110 lines because I do expose some "Extender" properties explicity.
Example:


```
FrameW1.ZOrder vbBringToFront
```

Will do always work. However the following will only work when doing that "overhead":


```
Dim This As FrameW
Set This = FrameW1
This.ZOrder vbBringToFront
```

That's why you can count 3,410 lines of codes only to this "overhead" cause, by exposing some Extender properties.




> Well, the inner UC was used to avoid having to use SubClassing in my previous example - the new Demo 
> below will use a single-Control + SubClassing (to suppress the MouseActivation of the FrameControl) instead.


Yes I would also going the SubClassing way. At least for the Std-EXE version it would be irritating to have another UC just for private use in the FrameW control.

----------


## Krool

Minor change in the OLEGuids.tlb file.
Just included ISpecifyPropertyPages, which allows to show the property pages at run-time for a control.
As there was no "break change" to existing interfaces, it was compiled with the same uuid. Means just overwrite to the existing file is OK.
However, that change is not crucial to this project.
It was included just for enrichement and due to preparations for the VBFlexGrid (MSFlexGrid replacement) Demo project.

----------


## MountainMan

I have developed a VBA solution to the opportunity of being able to develop VB6 programs using Krool's controls in an OCX form but then having the capability of doing a re-compile with a  copy of your program using the raw code embedded into your file. This means a) there can be EXE that have no additional files (especially if you embed your manifest into the EXE file), b) you only have code for the controls you have actually used on your forms included in your code instead of code for all controls by using the OCX version and c) your file size is 3-3.5 MB smaller because you don't include the OCX file with code for all controls.

I did this using VBA but I have code that works in VB6 and all 32 and 64-bit versions of Microsoft Office. If someone wants to take my simple user interface (on the "Main" sheet) and make the equivalent VB6 form out of it please do and post it.

There is only 1 file, Controls.xlsb and it should work in all versions of Excel. Just make sure you turn on the option to run Macros.

There is an Instructions sheet and then you will likely go to the Main sheet (red tab) where you will use the (hopefully) simple interface to achieve what you need.

I am using several of my personal libraries that I have been using for a very long time. I have written (MS Word) documentation on most of the modules which I can send you if you are interested.

----------


## MountainMan

Krool,

In ComCtrlsDemo there are two lines in the Main procedure in Startup.bas for which I have a  question.



```
Call ComCtlsInitIDEStopProtection
Call InitVisualStyles
```

Are these two lines required when using the OCX version of your controls or does your code do these steps automatically?

----------


## Krool

> Krool,
> 
> In ComCtrlsDemo there are two lines in the Main procedure in Startup.bas for which I have a  question.
> 
> 
> 
> ```
> Call ComCtlsInitIDEStopProtection
> Call InitVisualStyles
> ...


Call ComCtlsInitIDEStopProtection is not needed for OCX.
The other is needed depended if your app is manifested or not to use theming.

----------


## MountainMan

Thanks, that's what I thought. I have a VB6 version of the utility I posted a couple of days ago that allows a developer to switch from the OCX version to the Std-EXE version. I will post it in the next day or so. I hope you don't mind the add-on. I know this is your thread and if you would prefer I won't post it but it seems like the best place to keep it since it is specifically designed to work with what you've done.

----------


## MountainMan

Krool,

One more question. The utility I am writing re-compiles the project after switching all of the references in the project from the OCX to the Std-Exe controls. The compilation occurs using the commandline compiler and does not use the IDE. Do I need to include the line "Call ComCtlsInitIDEStopProtection" since we aren't using the IDE? I am writing some code to find the .BAS file in the project that contains Sub Main but it gets to be a bit of a hassle knowing where exactly to drop in this line in that subroutine. It would be nice to not have to include it if we don't need it.

----------


## Krool

> Krool,
> 
> One more question. The utility I am writing re-compiles the project after switching all of the references in the project from the OCX to the Std-Exe controls. The compilation occurs using the commandline compiler and does not use the IDE. Do I need to include the line "Call ComCtlsInitIDEStopProtection" since we aren't using the IDE? I am writing some code to find the .BAS file in the project that contains Sub Main but it gets to be a bit of a hassle knowing where exactly to drop in this line in that subroutine. It would be nice to not have to include it if we don't need it.


The Sub ComCtlsInitIDEStopProtection does only have an effect when running in IDE. In that Sub is a InIDE() test and does nothing when False.
So when you debug with OCX and compile with Std-EXE you certainly do not need to call that sub.
Means: ignore it completly.

And: Yes, please share that utility you are working right now.

----------


## JohnTurnbull

Hi Krool,

I have your TextboxW as Text1. When I call...

   xx = SendMessage(Text1.hWnd, EM_LINESCROLL, 0, 1)

The textbox scrolls to the end, not just one line!

I stepped through your code and there was no handling for EM_LINESCROLL.

It is some time since I updated so this may have been added. If it has, please let me know. If not, is there any chance of a patch to add to handle it?

----------


## chosk

xx = SendMessage(Text1.hWnd, EM_LINESCROLL, 0, 1) works for me scrolling one line at a time with the latest version. I can also scroll any number of lines I want.

EM_LINESCROLL can be found in the TextBoxW.ScrollToLine method and is used there to handle scroll to a particular linenumber, not for your intended purpose.

----------


## JohnTurnbull

Thank you for your quick reply.
I will download the latest version.
.SrollToLine doesn't seve my purpose

----------


## Krool

> EM_LINESCROLL can be found in the TextBoxW.ScrollToLine method and is used there to handle scroll to a particular linenumber


Improved the ScrollToLine method. The selection and caret position is not changed anymore by this method.

----------


## JohnTurnbull

Well I downloaded the latest version and still...

xx = SendMessage(Text1.hWnd, EM_LINESCROLL, 0, 1)

scrolls to the end, not just one line!

There's no panic as I got round the problem by using Sendkey and the down arrow to scroll the number of lines I wanted. However, it would be nice to know if TextBoxW responds incorrectly to an EM_LINESCROLL message or whether I am doing something wrong!

----------


## chosk

It is working with me. I did a screen capture.

----------


## Krool

> Well I downloaded the latest version and still...
> 
> xx = SendMessage(Text1.hWnd, EM_LINESCROLL, 0, 1)
> 
> scrolls to the end, not just one line!
> 
> There's no panic as I got round the problem by using Sendkey and the down arrow to scroll the number of lines I wanted. However, it would be nice to know if TextBoxW responds incorrectly to an EM_LINESCROLL message or whether I am doing something wrong!


Maybe you Need to do it as:

xx = SendMessage(Text1.hWnd, EM_LINESCROLL, 0, ByVal 1&)

Depends on how you declared the SendMessage API.

----------


## JohnTurnbull

Ah!

The older I get, the dumber I get!

Thank you both.

----------


## MountainMan

Update - In post #1480, Sam_ asked if the package could be adjusted so that a project using none of Krools's controls but using the CommonDialog could be set to not use the OCX but the individual files. This update enables that plus cleans up some other stuff. That was addressed in version was 0.9.1 and the new one attached to this post is *version 0.9.2*. It addresses the situation where the reference to the CommonDialog function was done inside of a form. I had previously checked .cls and .bas files in the project but not .frm files. This is now fixed.

Introduction

In post #1463 I uploaded a version of a utility that takes a project using Krool's .OCX controls and adjusts everything so that the OCX is no longer required and the code for each control used in your project (and only those used in your project) was compiled within the program. The earlier post was done in VBA with Excel and kind of tossed together. This post discusses an update to that effort and it is available for VB6 and Excel. The VB6 version is "OCX2StdExe.vbp" and the Excel version is "OCX2StdExe.xlsb".

Basically you develop a project in VB6 using the OCX version of Krool's controls and then when you get to (or near) the final version you run this utility to make a new project that is just like the old one except that it no longer needs the OCX file because all of the controls code is in the file (like it does for his ComCtlsDemo that is on the first page of this thread. Your original project is unchanged.

The current version is 0.9.2. One zip file includes a detailed ReadMe.doc file with usage instructions and screenshots. The other contains the Excel version. I hope you find the utility easy to use and productive.

----------


## Krool

Update released.

Major internal improvement in the FrameW control. Thanks to Schmidt for bringing this up.

I have done the graphical drawing directly, without resorting to BS_GROUPBOX window.
It supports and behave like the intrinsic Frame control. It will draw themed when VisualStyles are in use, or classic when not.
Also 'Flat' appearance is supported. (Classic only)
The Border property got renamed to 'BorderStyle'. Thus making a replacement easier.

The code got now clearly more compact and more efficient.
Other side benefits are that the ForeColor property is now even working when VisualStyles are in use.
Nevertheless in Windows XP the ForeColor is still ignored when VisualStyles are in use, since the API to draw themed colored text is Vista+ only.
Also the Transparent property will work in design-time.

----------


## xxdoc123

> I have developed a VBA solution to the opportunity of being able to develop VB6 programs using Krool's controls in an OCX form but then having the capability of doing a re-compile with a  copy of your program using the raw code embedded into your file. This means a) there can be EXE that have no additional files (especially if you embed your manifest into the EXE file), b) you only have code for the controls you have actually used on your forms included in your code instead of code for all controls by using the OCX version and c) your file size is 3-3.5 MB smaller because you don't include the OCX file with code for all controls.
> 
> I did this using VBA but I have code that works in VB6 and all 32 and 64-bit versions of Microsoft Office. If someone wants to take my simple user interface (on the "Main" sheet) and make the equivalent VB6 form out of it please do and post it.
> 
> There is only 1 file, Controls.xlsb and it should work in all versions of Excel. Just make sure you turn on the option to run Macros.
> 
> There is an Instructions sheet and then you will likely go to the Main sheet (red tab) where you will use the (hopefully) simple interface to achieve what you need.
> 
> I am using several of my personal libraries that I have been using for a very long time. I have written (MS Word) documentation on most of the modules which I can send you if you are interested.


may be fixed

With Main.Range("VBP_Path")

----------


## Sam_

> In post #1463 I uploaded a version of a utility
> [...]
> The current version is 0.9.0. The zip file includes a detailed ReadMe.doc file with usage instructions and screenshots.


In one program I have the only part of Krools pack that is used is the Common Dialogue Control - this tells me that there are no controls in use (which is kind of true as nothing is on any forms) so does not insert any code. Is this intentional or can it be added?

----------


## MountainMan

xxDoc123,

I don't understand your comment




> may be fixed
> 
> With Main.Range("VBP_Path")


I have an updated version of the Excel one with the current package but the old one from post #1463 works just fine. Did you encounter an error using the older Excel version?

----------


## MountainMan

> In one program I have the only part of Krools pack that is used is the Common Dialogue Control - this tells me that there are no controls in use (which is kind of true as nothing is on any forms) so does not insert any code. Is this intentional or can it be added?


See post #1477 for an updated version of this program which addresses your issue. Let me know if it works for you.

----------


## Sam_

> See post #1477 for an updated version of this program which addresses your issue. Let me know if it works for you.


Not working for me with the code inside a form, does work when the code is in a module - also subscript out of range error with tiny (really tiny) programs, tried to make a test case with just the CDC for a form and in a module. One more thing to maybe add could be a check for the OLE Guid reference, as the code will run without it (will not compile), and if you were to use this utility for compilation then it could be missed (rare I know).

----------


## MountainMan

> Not working for me with the code inside a form, does work when the code is in a module - also subscript out of range error with tiny (really tiny) programs, tried to make a test case with just the CDC for a form and in a module. One more thing to maybe add could be a check for the OLE Guid reference, as the code will run without it (will not compile), and if you were to use this utility for compilation then it could be missed (rare I know).


I do look inside the form (the .frm file) for references to Krool's OCX file and then I remove those references because they aren't needed when you use the individual controls (all of the files making up each controls are referenced in the .vbp project file). Could you send me a copy of the program that wouldn't work and I'll find out why. (My email address is at the end of the .doc file.)

Also, could you send me a copy of the tiny program that gave you the subscript out of range error? Thanks.

I am not sure I understand your last point. Are you concerned that someone would try to use my code on a project that had no reference to the OCX file (i.e., it didn't have the GUID at all)? I do look in the .vbp file for a line containing "vbccr14.ocx" and since I didn't think you could have comments in a .vbp file I thought that if I found the reference to the OCX file that in fact the project used it.

----------


## MountainMan

Krool,

I have a question for you regarding the use of the OCX version compared to the STD-EXE version.

In your ComCtlsDemo project, in the Load sub of the form Main, there is the following code:



```
If ComCtlsSupportLevel() = 0 Then
    ListView1.ColumnHeaders(1).Icon = 1
    Dim EnumColumn As LvwColumnHeader
    For Each EnumColumn In ListView1.ColumnHeaders
        EnumColumn.IconOnRight = True
    Next EnumColumn
Else
    ListView1.SelectedColumn = ListView1.ColumnHeaders(1)
    ListView1.ColumnHeaders(1).SortArrow = LvwColumnHeaderSortArrowDown
End If
```

and I found the function ComCtlsSupportLevel in ComCtlsBase, a normal module. This function is not available in the OCX version and I looked through all of the normal and hidden classes and variables in ComCtlsDemo and it's not there and there isn't any equivalent. I am guessing that since it is in a .bas file and not in a control or a class module that even though it is a public procedure it won't be visible in the OCX.

So the first question is how do we do the equivalent of your code above when we are using the OCX version of the controls? I suppose we could include the API declaration and the ComCtlsSupprotLevel function in our code but since you are already making the call, it would seem to be easier to just make the result of that call available to users of the OCX as a property or variable.

Also, the function is called many times throughout your code. Since it is just checking the version number of the ComCtl32.dll file, wouldn't it be better to just call it once int he initialization code and then keep the results of that one call in a global variable?

----------


## MountainMan

In post #1483 Sam_ said he had a problem using my utility in situations where there none of Krool's controls were used but his CommonDialog function was used. I had checked for it in class and standard modules but not inside of forms. This is now fixed and Sam_'s code compiles properly with the OCX reference removed but the references to a handful of Krool's modules required to support that function call included.

I have now posted the update in post #1477 as version 0.9.2.

----------


## Krool

> I found the function ComCtlsSupportLevel in ComCtlsBase, a normal module. This function is not available in the OCX version and I looked through all of the normal and hidden classes and variables in ComCtlsDemo and it's not there and there isn't any equivalent. I am guessing that since it is in a .bas file and not in a control or a class module that even though it is a public procedure it won't be visible in the OCX.
> 
> So the first question is how do we do the equivalent of your code above when we are using the OCX version of the controls? I suppose we could include the API declaration and the ComCtlsSupprotLevel function in our code but since you are already making the call, it would seem to be easier to just make the result of that call available to users of the OCX as a property or variable.
> 
> Also, the function is called many times throughout your code. Since it is just checking the version number of the ComCtl32.dll file, wouldn't it be better to just call it once int he initialization code and then keep the results of that one call in a global variable?


If you look in the function ComCtlsSupprotLevel the API is already only called once and the result is stored in a Static variable.
For OCX. Yes it could be added in a global class module.

----------


## Tech99

ListBoxW vs. VB Intrinsic Listbox Selected property and visibility - problem

Any idea why selected property and selection visibility, does not work via code, as in intrinsic VB Listbox?

Test project attached...

----------


## Krool

> ListBoxW vs. VB Intrinsic Listbox Selected property and visibility - problem
> 
> Any idea why selected property and selection visibility, does not work via code, as in intrinsic VB Listbox?
> 
> Test project attached...


In ListBoxW use the .ItemChecked property instead. I know that this is a little break for migration but then the .Selected property remains free for its actual selection state.

----------


## Tech99

Ok, big thanks, for fast response.

So it means, that SendMessage LB_ADDSTRING works as usual
'lstFolderList.AddItem CStr(Columns(1)) '
SendMessage lstFolderList.hWnd, LB_ADDSTRING, ByVal 0&, ByVal (CStr(Columns(1))) 'Add item to listbox

but, selection do not.
'SendMessage lstFolderList.hWnd, LB_SETSEL, ByVal CLng(Columns(0)), ByVal CLng(i) 'Selected/not selected via API.

----------


## Tech99

and this does not work either.


```
Private Sub lstFolderList_Click()
If lstFolderList.ListIndex > -1 Then
    If lstFolderList.ItemChecked(lstFolderList.ListIndex) Then 'Clicked item is not selected, before Click event fires -> Does not work
    'If lstFolderList.Selected(lstFolderList.ListIndex) Then 'Clicked item selected, before Click event fires -> Wworks
                'Do something
    Else 'not selected
    End If
End Sub
```



```
For i = 0 To UBound(Rows) - 1
    Columns = Split(Rows(i), "*")
    SendMessage lstFolderList.hWnd, LB_ADDSTRING, ByVal 0&, ByVal (CStr(Columns(1))) 'Can't use this method
     'lstFolderList.AddItem CStr(Columns(1)) '
     'lstFolderList.ItemChecked(i) = CBool(Columns(0)) 'as this does not work
     lstFolderList.ItemChecked(lstFolderList.NewIndex) = CBool(Columns(0)) 'for some reason neither do newindex method.
Next i
```

Newindex method works only with AddItem method, not with SendMessage API LB_ADDSTRING.


```
lstFolderList.AddItem CStr(Columns(1))
lstFolderList.ItemChecked(lstFolderList.NewIndex) = CBool(Columns(0))
```

----------


## Krool

> and this does not work either.
> 
> 
> ```
> Private Sub lstFolderList_Click()
> If lstFolderList.ListIndex > -1 Then
>     If lstFolderList.ItemChecked(lstFolderList.ListIndex) Then 'Clicked item is not selected, before Click event fires -> Does not work
>     'If lstFolderList.Selected(lstFolderList.ListIndex) Then 'Clicked item selected, before Click event fires -> Wworks
>                 'Do something
> ...


Yes, don't use API to add items.
At least not when using Style other than Normal or using .NewIndex.

----------


## Tech99

Ok, must use AddItem and NewIndex methods then.

----------


## Romeo91

Hi Krool!

Is it possible to do scroll-control based on the framew-control?
Ie also a container, but with the appearance of scrolbars when the elements are out of the container.

----------


## Schmidt

In TextBoxW there's still two Problems, which prevent us from rolling out our
"Unicode-awareness-updates" in a large old VB6-Project.

*Problem 1: DataChanged-Property*

One can fix that easily (making it behaving identically to the intrinsic VB.TextBox),
by setting a Boolean m_DataChanged to True, in a Code-line *before* the Changed-Event is raised.

This Property (in the original VB.TextBox) can be reset at any time per: TextBox.DataChanged = False

*
Problem 2: Cursor-Movement per Arrow-Keys*

The ScreenShot-LabelTexts below explain the Problem.


Here's a Download-Link for a small Project which demonstrates the Problem
(the Problem shows itself only in the Executable, not in the IDE):
http://vbRichClient.com/Downloads/CC...ve_Problem.zip

Olaf

----------


## Krool

> *Problem 1: DataChanged-Property*
> 
> One can fix that easily (making it behaving identically to the intrinsic VB.TextBox),
> by setting a Boolean m_DataChanged to True, in a Code-line *before* the Changed-Event is raised.
> 
> This Property (in the original VB.TextBox) can be reset at any time per: TextBox.DataChanged = False


Will follow soon.




> *Problem 2: Cursor-Movement per Arrow-Keys*
> 
> The ScreenShot-LabelTexts below explain the Problem.
> 
> 
> Here's a Download-Link for a small Project which demonstrates the Problem
> (the Problem shows itself only in the Executable, not in the IDE):
> http://vbRichClient.com/Downloads/CC...ve_Problem.zip


In IDE you are using the .OCX version which has no problem with embedding into another UserControl.
However at run-time you are switching to the Std-EXE version and for this to properly work embedded into another UserControl there needs to be some code added.
The details are described at Post #597.

----------


## Schmidt

DataChanged-Property...



> Will follow soon.


Great.  :Smilie: 




> In IDE you are using the .OCX version which has no problem with embedding into another UserControl.
> However at run-time you are switching to the Std-EXE version ...


No, no no...

If there's a professionally maintained binary available (even coming with a nice manifest for regfree-deployment, as in your case) -
 then I'd never embed any larger source-codes into the production-code of my own Std-exe projects.

The Zipped-StdExe-Project I've posted above does make use (references) the OCX-version of your Controls (the latest one).
And this Project only needs to be run compiled (then still internally using your external OCX-binary), for the problem to occur.

Olaf

----------


## Krool

> No, no no...
> 
> If there's a professionally maintained binary available (even coming with a nice manifest for regfree-deployment, as in your case) -
>  then I'd never embed any larger source-codes into the production-code of my own Std-exe projects.
> 
> The Zipped-StdExe-Project I've posted above does make use (references) the OCX-version of your Controls (the latest one).
> And this Project only needs to be run compiled (then still internally using your external OCX-binary), for the problem to occur.


Oops. Then I must had only tested this with the OCX at design-time only. Because as you encountered this is only when run compiled...
Then the OCX has the same issue as the Std-EXE version at run-time.
However, the solution as like in the Std-EXE version does also work with the OCX. I know that this is not nice but I do not find a way as this seems to be a VB behavior (bug?) as the VB.Form does correctly dispatch IOleInPlaceActiveObjectVB to the ActiveControl but the VB.UserControl not. That's why this must be done "manually" as described in the code at Post #597.
If somebody finds a way to solve I am happy to hear, otherwise it needs to stay like this.

----------


## Krool

Edit: I have an idea to maybe fix the whole VB.UserControl embedding issue without adding some extra code to the host UserControl. Will check this out soon.

----------


## chosk

Hi Krool,

I think something might not right with DPI-Aware in the TabStrip - it is not scaling with the other controls.

In this example, I place the ComboBoxW and the CommandButton in line directly below the 2nd and 4th tabs respectively. I am using "2 - Fixed" for the TabWidthStyle, because I prefer the tabs to be taller. The "0 - Justified" has shorter Tab height by default.

Screen shots taken after I logged out and then back in for the change to take effect.

----------


## Krool

> I think something might not right with DPI-Aware in the TabStrip - it is not scaling with the other controls.
> 
> In this example, I place the ComboBoxW and the CommandButton in line directly below the 2nd and 4th tabs respectively. I am using "2 - Fixed" for the TabWidthStyle, because I prefer the tabs to be taller. The "0 - Justified" has shorter Tab height by default.


I have figured out the problem here. Thanks for reporting.
Problem is that the TabFixedWidth/TabFixedHeight/TabMinWidth are stored as pixels in the property bag.
I think a solution could be to convert always from vbContainerSize to vbTwips instead of vbPixels for writing the properties.
But if I change this it would completly break the property bag compatibility. Everybody would need to re-define the properties...

There could be the same problem for other controls, e.g. ToolBar and the ButtonWidth/ButtonHeight/MinButtonWidth/MaxButtonWidth properties.




> Edit: I have an idea to maybe fix the whole VB.UserControl embedding issue without adding some extra code to the host UserControl. Will check this out soon.


I have found an solution(!). But it requires an internal change on each control. So it will take a while until update will be released.

----------


## DEXWERX

> I have figured out the problem here. Thanks for reporting.
> Problem is that the TabFixedWidth/TabFixedHeight/TabMinWidth are stored as pixels in the property bag.
> I think a solution could be to convert always from vbContainerSize to vbTwips instead of vbPixels for writing the properties.
> But if I change this it would completly break the property bag compatibility. Everybody would need to re-define the properties...
> 
> There could be the same problem for other controls, e.g. ToolBar and the ButtonWidth/ButtonHeight/MinButtonWidth/MaxButtonWidth properties.


would it be possible to store a "design mode dpi" property (default 96), to translate the stored pixels when loading/saving the properties?
It's a kludgy idea for a workaround.

----------


## chosk

> I have figured out the problem here. Thanks for reporting.
> Problem is that the TabFixedWidth/TabFixedHeight/TabMinWidth are stored as pixels in the property bag.
> I think a solution could be to convert always from vbContainerSize to vbTwips instead of vbPixels for writing the properties.
> But if I change this it would completly break the property bag compatibility. Everybody would need to re-define the properties...
> 
> There could be the same problem for other controls, e.g. ToolBar and the ButtonWidth/ButtonHeight/MinButtonWidth/MaxButtonWidth properties.


I just tested with "0 - Justified" and with DPI Manifest there is also the same issue. TabFixedWidth/TabFixedHeight/TabMinWidth are all 0.

I also just tested the MS TabStrip and it scale nicely with DPI Manifest applied.

Unless there is a work around, otherwise the UI with the TabStrip will not look right. I think this may need to be addressed even with completely breaking the property bag compatibility.

----------


## Krool

Update released. (Major; it is necessary to replace all components and controls)

This update will fix reliably the issue that a kludgy workaround was necessary in order to get the controls properly work when there are embedded into another UserControl.
Now it doesn't matter where the control is sited on, no workaround necessary anymore.

So you can just put the Std-EXE or OCX control into another UserControl and it will just work.
The issue as described by Olaf below will not occur anymore.

The OCX version and the VBFlexGrid control got also updated.




> *
> Problem 2: Cursor-Movement per Arrow-Keys*
> 
> The ScreenShot-LabelTexts below explain the Problem.
> 
> 
> Here's a Download-Link for a small Project which demonstrates the Problem
> (the Problem shows itself only in the Executable, not in the IDE):
> http://vbRichClient.com/Downloads/CC...ve_Problem.zip

----------


## chosk

Hi Krool,

From the 3-Jul update and the one yesterday, I have this issue with most of the existing FrameW that was created from earlier versions. A black horizontal line appear on top of the FrameW. This happen to most of the FrameW that are pre-existing (about 90% or more though I did not actually count). If I replace the FrameW.ctl file back to the earlier version and re-load the project the black line will not appear.

A new FrameW created on the form with the "new" version will not have the black line.

The problem is that I have 20 or more FrameW and there are controls within them. If I were to re-create all the FrameW, I will mess up all the tabstop order in all the forms and have to re-do.

Is it possible to find out what may be causing this?

----------


## Krool

There is a "huge" Problem with yesterdays update.

All controls that have child controls, such as IPAddress control etc. will not work properly with the arrow keys.
Thus there is a Little bit rework to be done.......

----------


## Krool

Critical fix for yesterday's update..

*Please again replace everything. Sorry for the inconvenience caused.*

The fault was that the *new* method must be "handled" for all window controls. In yesterday update I did this only for the main window control, if the main window control does have any child control the whole thing was broken.
Now in today fix I also "handled" the known child window controls for all main window controls.
Example: IPAddress window has 4 edit child window controls or ListView has a label edit or filter edit child window control etc..

In addition the *new* method is now "double secured". If there would be any child window control forgotten to be handled it will be rescued by the *old* method.
Of course if there would be such case this "rescue" would only help when the control is not embedded into another UserControl.

Conclusion:
For normal use now _very_ reliable. As combination of new and old method.
For embedding in another UserControl certainly reliable. Only in theory if there would be some new unknown child control which is not handled yet it would not work at that point.

@ Chosk,
I cannot reproduce your issue. I used the old FrameW and saved into property bag. Then just replaced and there was no issue..
Can you make a demo? It should show up when you make all the settings you used with the old FrameW and then replace.

----------


## Romeo91

> Hi Krool,
> 
> From the 3-Jul update and the one yesterday, I have this issue with most of the existing FrameW that was created from earlier versions. A black horizontal line appear on top of the FrameW. This happen to most of the FrameW that are pre-existing (about 90% or more though I did not actually count). If I replace the FrameW.ctl file back to the earlier version and re-load the project the black line will not appear.
> 
> A new FrameW created on the form with the "new" version will not have the black line.
> 
> The problem is that I have 20 or more FrameW and there are controls within them. If I were to re-create all the FrameW, I will mess up all the tabstop order in all the forms and have to re-do.
> 
> Is it possible to find out what may be causing this?


I have the same problem. I solved it by changing the borderstyle parameter

----------


## DrUnicode

> A black horizontal line appear on top of the FrameW.


Pretty sure this Black Line appears when you place a Windowless control on the Frame.
That explains why you don't see it when you just place an empty FrameW on the form or by using only non-Windowless controls.

The solution is adding "UserControl.Picture = UserControl.Image" at the end of Sub DrawFrame.

Thanks to LaVolpe for solution at:
http://www.vbforums.com/showthread.p...=1#post3913211

----------


## chosk

> Pretty sure this Black Line appears when you place a Windowless control on the Frame.
> That explains why you don't see it when you just place an empty FrameW on the form or by using only non-Windowless controls.
> 
> The solution is adding "UserControl.Picture = UserControl.Image" at the end of Sub DrawFrame.
> 
> Thanks to LaVolpe for solution at:
> http://www.vbforums.com/showthread.p...=1#post3913211


Hi DrUnicode,

Yes! That solved the black line problem.

I put "UserControl.Picture = UserControl.Image" after End With and before End Sub. Hope this is the right place.

Thanks.

----------


## Krool

Update released.




> Yes! That solved the black line problem.
> 
> I put "UserControl.Picture = UserControl.Image" after End With and before End Sub. Hope this is the right place.


That kinda solved it. However, there was still an issue when resizing the FrameW control.
I solved that by doing an "UserControl.Picture = Nothing" before the drawing.



```
Private Sub DrawFrame()
With UserControl
.Cls
Set .Picture = Nothing
[...drawing routine...]
Set .Picture = .Image
End With
End Sub
```

----------


## Jonney

it is frustrated that the increment  can't be single or double for VB6 UpDown control. Can it be modified?

----------


## DEXWERX

> it is frustrated that the increment  can't be single or double for VB6 UpDown control. Can it be modified?


You might have to make a custom up-down control, the windows up down control typically uses a 16 bit integer, although it can be extended to a 32bits.

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

----------


## Krool

Yes the UpDown control is limited to 32bit Long Integer.
However, to some degree, you can scale an Double to a Long. For example a Double 0,0000 to 1,0000 can be represented by 0 to 10000. Or do you mean something other?

----------


## Jonney

> Yes the UpDown control is limited to 32bit Long Integer.
> However, to some degree, you can scale an Double to a Long. For example a Double 0,0000 to 1,0000 can be represented by 0 to 10000. Or do you mean something other?


what I expects the UpDown control as .NET's numericUpDown, which can set decimal place and the increment can be single such as 0.25.

----------


## Krool

Update released.

The DataChanged property works now like in the original MS controls.
Means it's .DataChanged return value is meaningful even when the control is not data-binded.
Also it can be reset anytime with .DataChanged = False.




> *Problem 1: DataChanged-Property*
> 
> One can fix that easily (making it behaving identically to the intrinsic VB.TextBox),
> by setting a Boolean m_DataChanged to True, in a Code-line *before* the Changed-Event is raised.
> 
> This Property (in the original VB.TextBox) can be reset at any time per: TextBox.DataChanged = False

----------


## chosk

I have been trying to figure out this problem after I released an update to my app a few days ago. I am not sure whether this is related to the Std-EXE controls but because the error is caused by MSVBVM60.DLL on quite a few Win7 computers, I thought maybe I try to ask.

Before this, my previous release was Jan 2016 and I was using the then version of the controls. This is the only difference in components between then and now with some rework/update of of my own program codes. Is there anything in the controls that may sparodically caused MSVBVM60.DLL to trigger an Exception c0000005 which is a memory exception, probably DEP related.

 I am just trying to isolate out and if my question is rude and irrelevant, pls excuse and pardon me.

Thanks for any input.

----------


## Krool

Chosk, I can't help you without any additional background info. And as you say, you are not able to isolate the reason..
But such error is unknown to me in relation to my controls.
You need to provide more info when this happens.

----------


## DaveInCaz

> I have been trying to figure out this problem after I released an update to my app a few days ago. I am not sure whether this is related to the Std-EXE controls ...


chosk, if you can reliably reproduce the problem on some PC, then I would try to substitute in the older version of VBCCR which you used and see if the problem is then resolved. (Ideally without changing anything else). That may rule VBCCR in or out as the cause..?

----------


## chosk

Thanks Krool and DaveInCaz.

I did not have the problem on my Win7 which I use to develop with the Jun 2017 controls. I tested the setup.exe and after that running the app on 2 other Win10 before release and also no problem. So I cannot even produce the problem on my computers.

There are quite a few who came back with this same problem so I narrow down to perhaps DEP related. My exe is 4196KB so is not big. I will dig more and see what I can get.

Thanks for the help.

----------


## Cube8

DEP issues are caused by some subclassing methods.
Do you do any subclassing? If yes, how?

However, I doubt if this is relevant to this thread.

----------


## Romeo91

> Hi Krool!
> 
> Is it possible to do scroll-control based on the framew-control?
> Ie also a container, but with the appearance of scrolbars when the elements are out of the container.


Hi Krool. Sorry for repeating the topic. Perhaps you did not notice him, did you really make such a control?

----------


## Mith

VBCCR14.OCX v1.4.24

maybe i found a small bug at the ListBoxW:

the last item at the listbox always get unchecked automatically if i move a item up or down.

the code i use with a workaround (bold lines) for this problem:



```
Public Function ListBoxW_Move_Item_UP(ListBox As VBCCR14.ListBoxW) As Boolean
      
      Dim currIndex As Integer
      Dim currItemText  As String
      Dim currItemChecked As Boolean
      Dim currItemData As Long
      Dim lastItemChecked As Boolean
      Dim prevItemChecked As Boolean
      
20    With ListBox
      
30    If .ListIndex >= 1 Then
40       currIndex = .ListIndex
50       currItemText = .List(currIndex)
60       currItemData = .ItemData(currIndex)
70       currItemChecked = .ItemChecked(currIndex)
80       prevItemChecked = .ItemChecked(currIndex - 1)
90       lastItemChecked = .ItemChecked(.ListCount - 1)

100      .RemoveItem currIndex
110      .AddItem currItemText, currIndex - 1
120      .ListIndex = .NewIndex
130      .ItemData(.NewIndex) = currItemData
140      .ItemChecked(.NewIndex) = currItemChecked
150      If currIndex = .ListCount - 1 Then
160         .ItemChecked(.NewIndex + 1) = prevItemChecked
170      Else
180         .ItemChecked(.ListCount - 1) = lastItemChecked
190      End If
200      ListBoxW_Move_Item_UP = True
210   End If
          
220   End With
          
End Function
```



```
Public Function ListBoxW_Move_Item_DOWN(ListBox As VBCCR14.ListBoxW) As Boolean
      
      Dim currIndex As Integer
      Dim currItemText  As String
      Dim currItemChecked As Boolean
      Dim currItemData As Long
      Dim lastItemChecked As Boolean
      Dim nextItemChecked As Boolean
      
20    With ListBox

30    If .ListIndex <> -1 And .ListIndex < .ListCount - 1 Then
40       currIndex = .ListIndex
50       currItemText = .List(currIndex)
60       currItemData = .ItemData(currIndex)
70       currItemChecked = .ItemChecked(currIndex)
80       nextItemChecked = .ItemChecked(currIndex + 1)
90       lastItemChecked = .ItemChecked(.ListCount - 1)

100      .RemoveItem currIndex
110      .AddItem currItemText, currIndex + 1
120      .ListIndex = .NewIndex
130      .ItemData(.NewIndex) = currItemData
140      .ItemChecked(.NewIndex) = currItemChecked
150      If .NewIndex < .ListCount - 1 Then
160         .ItemChecked(.ListCount - 1) = lastItemChecked
170      Else
180         .ItemChecked(.NewIndex - 1) = nextItemChecked
190      End If
200      ListBoxW_Move_Item_DOWN = True
210   End If

220   End With

End Function
```

----------


## Krool

> VBCCR14.OCX v1.4.24
> 
> maybe i found a small bug at the ListBoxW:
> 
> the last item at the listbox always get unchecked automatically if i move a item up or down.


Update released. Thanks for reporting this bug. There was indeed an bug in the .AddItem method. (CopyMemory shifting)

The OCX has also been updated with this bugfix to v1.4.31.

----------


## Krool

Update relased. Quite important when full "DPI Awareness" is needed.

Problem was that some properties are saved as pixels in the property bags. For example the TabFixedWidth property in the TabStrip control.

This issue was solved now by saving the pixels as DIPs (Device-independent pixels) in the Property bag.
The TabStrip, ToolBar, Pager and CoolBar control were affected.




> Unless there is a work around, otherwise the UI with the TabStrip will not look right. I think this may need to be addressed even with completely breaking the property bag compatibility.


This solution is a "soft" compatibility break.
When the developer has run the VB6 IDE at 100% (96) DPI there is no compatibility break.
If it was devevloped by another DPI setting the affected controls shall be recreated.

The OCX has also been updated. (and also the VBFlexGrid btw.)

----------


## Krool

Alert: concerning yesterday "DPI Aware" enhancement.

There is still a "trap" as I did not handled the UserControl_InitProperties. (only did ReadProperties and WriteProperties)

Fix for this will come asap.

----------


## Krool

Update released. Bugfixes for yesterday update for "DPI Aware" enhancement. Please replace again, sorry for the inconvenience caused.
Affects TabStrip, ToolBar and CoolBar control. (Pager control no change necessary)
Nevertheless there was no harm when having a DPI of 100% (96) in the VB6 IDE.

Now it should be possible to work in whatever DPI setting in the VB6 IDE and of course the compiled resulting target display.

----------


## Krool

Again update for "DPI Aware". After all that was kind of a hard nut to crack with the whole DPI Aware story..

In various controls I have done minor tweaks to improve appearance on higher DPI, for example:
- In ListBoxW with Style Checkbox or Option the state image (checkbox or optionbox) is now drawn in correct proportion. (15 * PixelsPerDIP_X())
- When in ListView.ColumnHeaders.Add no Width was specified the default width is now in correct proportion. (96 * PixelsPerDIP_X())
- and so on...

The improvements done in the functions PixelsPerDIP_X/PixelsPerDIP_Y is just simply that the first return value is preserved for all future calls.
This has two benefits:
1 - higher performance
2 - Consistent conversion between ReadProperties and WriteProperties

----------


## Hosam AL Dein

hi krool 

it is a great job you are doing here solving most of vb6 standard controls problems we are facing for years including visual style and performance

I downloaded the project and here are the points

1- the buttons having the style graphical hides the caption until style  property is  refreshed or recalled during runtime
2- the filter button of listview is not visually styled even after compilation

this is what i remember for now concerning bugs

and for improvements , i have been trying to set the menus background color for toolbar buttons and i could not . i also did not get the exact line of code which creates the menus. i already have an example for coloring menus background but failed to combine it with your control  , so why dont you add it . i think it is a serious matter for visual styling to abandon all grayed colors in favor of whiteness  . 

also for toolbar button menus it can not create submenus which is necessary

that`s for now

and lots of thanks for you for these great tools

----------


## Hosam AL Dein

hi krool ,

there is a bug when buttonsw are set to graphical style and having a backcolor , the caption is hidden and comes back when the property os set at runtime

listview column filter button is not visually styled even after compilation

the project you attatched loads normally but when i try to view the main form or run the project , the ide crashes . i made anew project and added the ocx and files for visual styling manually to solve this problem

for toolbar , i suggest adding the background color for menues to be white or to be a property to get rid of the grayed color

also the toolbar menues for buttons has no submenus 

 i want to thank you so much for this great job and i hope everyone can test it sothat we can be be able to trust it 100%

and sorry for bad english

----------


## Hosam AL Dein

sorry for double posting , 
i am working on listview and i will be testing it for the next few days because i am replacing the old one in some project and i found some bugs and i think all are connected to reading and setting properties for column headers

1- if a column header has an icon and you set the sort arrow then the icon disappears and vice versa maybe you intended this and not a bug
2- when i set -for example- the alignment property for some coulumn , nothing happens and it remains as it is . wen i changed the column index to another column , now both have the alignment i had previously chosen for the first column edited . i mean that the property does not respond until it is set to another item , and also keeps it for both

3- please , if there is a solution for the point that : i have to compile the whole project to see the visual effects and this is time consuming . is there a way to synchronize it with IDE ?

----------


## Hosam AL Dein

for listview column headers , is there a possibility for :

1- making them accept png transparent icons , like lavolpe`s image control ?
2 - making the column header text or caption accept vbclrf or vbnewline ? why ? it will be good to make benefit of this for adding the sum for a specific column , because if we add this value or string to the caption it will affect the column width or it will not be visible for the user and he has to widen the column to view this sum value which is supposed to be always visibe to the user
3- a suggestion for columns sorting , why dont you make a sort dropdown somewhere which displays a menu with all columns names and choosing this sort to be ascending or descending in a checked submenu ? this will solve the problem of sorting icon which removes the main icon for the header . this dropdown can also be visible or invisible depending on a property .

me especially appreciate this tremendous work and i wish i could help in developing it , but it crosses my knowledge border in most of its areas . so , thanks again

----------


## Hosam AL Dein

how to collapse a group after it is expanded ?
why the group subset items count is set only to the first group ?

suggestions :

1- making the listview much more ready for all functional operations like adding (select all - select none - select inverse ) for the group level and for all listview items level . and this will act for item checking or item selection (for multi selection property set to true)

2- after this , we may add this command list (delete selected/checked- highlight selected/checked) and we will make this command list more dynamic to enable the programmer to add more buttons to it like (print selected/checked) and so on ... 

i am working on listview user control and i was developing all these functions to it , it was with win common controls 6 library which can not be themed and i need checkboxes within it which is not found with version 5 so i decided to use your listview and combine them together by replacing my 6th version with yours . so i will try to re-make my listview control and upload it here after i finish merging between them both

----------


## Krool

Update released.

Bugfix for ListBoxW concerning "DPI Aware". (again)





> the buttons having the style graphical hides the caption until style  property is  refreshed or recalled during runtime


I cannot replicate that bug. I think somewhere in your code you might have a SetWindowLong GWL_STYLE for the button and that may kill of the BS_OWNERDRAW bit.
That's why you need to recall the Style property. Can you check if your doing something like this? (SetWindowLong GWL_STYLE)




> the filter button of listview is not visually styled even after compilation


That is by design from the comctl32.dll. No influence for this.




> also for toolbar button menus it can not create submenus which is necessary


The .ButtonMenus property is meant for simple and rapidstart use. If you want to have custom background menu and submenus do as following:
Don't set any ButtonMenu in .ButtonMenus, instead handle the event 'ButtonDropDown' and create your own menu there.




> if a column header has an icon and you set the sort arrow then the icon disappears and vice versa maybe you intended this and not a bug


That is not a bug. If you set a sort arrow the icon will not be visible but remain. When you now remove the sort arrow the icon will re-appear.




> when i set -for example- the alignment property for some coulumn , nothing happens and it remains as it is . wen i changed the column index to another column , now both have the alignment i had previously chosen for the first column edited . i mean that the property does not respond until it is set to another item , and also keeps it for both


I cannot replicate that bug. Please provide full example.




> i have to compile the whole project to see the visual effects and this is time consuming . is there a way to synchronize it with IDE ?


You can manifest the VB6.exe and thus enable theming in the IDE. See here: http://www.vbforums.com/showthread.p...ues&highlight=




> how to collapse a group after it is expanded ?


Use the Group.Collapsed property. (also verify that Group.Collapsible property is set accordingly)




> why the group subset items count is set only to the first group ?


This is just in the demo. You can make any group to subset items. Use the Group.Subseted = True in order to do so.

----------


## Hosam AL Dein

thanks for your reply krool , 

i have been playing with the listview control and did some practices on it to get to know its properties and methods and things are better now .

but still some issues 

 for button , here is the scenario .  i did it on an empty project only containing the command on a form

1- add a button
2- change style property to to graphical
3- change its backcolor to some color like "blue"
4- change its forecolor to "red"
5- change the appearance property to "flat" , now , what happens is the whole button is white . the backcolor property is "white" instead of blue , and this is ok , we can rechange it , but the forecolor is still red and it does not appear on the button even when we change it to any other color i mean by refreshing the property .
6- i mean setting the property to flat is the point . the button has to be refreshed after setting it its appearanace to flat  . mainly by refreshing the style property 

this is for the button

for listview column properties , i will  uploade this bug after i determine it exactly and with pictures

----------


## LaVolpe

> You can manifest the VB6.exe and thus enable theming in the IDE. See here: http://www.vbforums.com/showthread.p...ues&highlight=


Another option of making the IDE themed without modifying the exe, can be found here. It does have the advantage of being able to change the manifest without re-modifying the exe. Just another option. 

In your original link you included this statement: "Reason for this is that adding a manifest file into the VB6.exe directory won't work anymore in Windows 7." I've always been able to get the external manifest to work, but may require a registry edit & reboot at most. The registry edit can be undone after the manifest takes effect. Am currently using external manifest in Win10.

----------


## Krool

> In your original link you included this statement: "Reason for this is that adding a manifest file into the VB6.exe directory won't work anymore in Windows 7." I've always been able to get the external manifest to work, but may require a registry edit & reboot at most. The registry edit can be undone after the manifest takes effect. Am currently using external manifest in Win10.


I have removed that statement and you are correct. Thanks
At that time I did not knew that external manifests are disabled by default because of security concerns by MS and that this can be enabled again with a registry tweak.

----------


## Hosam AL Dein

for listview columns , i cant re-simulate the error i mentioned above .maybe i was doing sth wrong .

but there is a bug i think



```
lvmain.ColumnHeaders.Add(, , "Col1").Alignment = LvwColumnHeaderAlignmentCenter
lvmain.ColumnHeaders.Add(, , "Col2").AutoSize LvwColumnHeaderAutoSizeToHeader
lvmain.ColumnHeaders.Add(, , "Col3").ForeColor = vbRed
lvmain.ColumnHeaders.Add(, , "Col4").CheckBox = True
lvmain.ColumnHeaders.Add(, , "Col5").Checked = True
lvmain.ColumnHeaders.Add(, , "Col6").Icon = 1
lvmain.ColumnHeaders.Add(, , "Col7").SplitButton = True
```

the column 2 size displays like this 





there is another problem in IDE , when selecting a backcolor property for any control , the system colors show normally while the palette shows like this . and this happened after i followed the instruction you have provided for theming IDE

----------


## Hosam AL Dein

[QUOTE=LaVolpe;5196541]Another option of making the IDE themed without modifying the exe, can be found here. It does have the advantage of being able to change the manifest without re-modifying the exe. Just another option. 

thanks so much lavolpe for your precious notices .

and I want to thank you for all what you are doing here in the forum , I have been developing with vb6 for 9 years and i have never joined a forum until i saw some fresh posts for you and krool  and i am now happy to be a part of this . i found that you mainly concentrate on visual styling for interface and images and this graphical area is not so good in vb6 . you have solved many problems for me especially by your alpha image control . and krool also with this replacement tool which is great at visual and functional levels .  just wanted to let you know that you were the main reason for me registering for this forum and to tell you that you are doing great things

----------


## LaVolpe

> there is another problem in IDE , when selecting a backcolor property for any control , the system colors show normally while the palette shows like this . and this happened after i followed the instruction you have provided for theming IDE


This is a bug in the IDE when the IDE is manifested to use themes. It is very, very annoying. I've been using a manifest with IDE for several years and am not so annoyed as I used to be. Just got used to it.

The system colors tab does work, so use that to select system colors.
For the non-system colors, the palette, a workaround would be to use the Palette from the IDE menu: View | Color Palette. The palette offered to you from that menu item can set either the forecolor or backcolor properties or both.

Also know that you can copy & paste the color values from other properties on that property sheet if another property already has the color you want.

----------


## Krool

> 1- add a button
> 2- change style property to to graphical
> 3- change its backcolor to some color like "blue"
> 4- change its forecolor to "red"
> 5- change the appearance property to "flat" , now , what happens is the whole button is white . the backcolor property is "white" instead of blue , and this is ok , we can rechange it , but the forecolor is still red and it does not appear on the button even when we change it to any other color i mean by refreshing the property .
> 6- i mean setting the property to flat is the point . the button has to be refreshed after setting it its appearanace to flat  . mainly by refreshing the style property 
> 
> this is for the button


What you mean by "the forecolor is still red and it does not appear on the button". You mean the caption is not visible?
I can't reproduce such behavior. The control will be refreshed when setting the Appearance property.




> the column 2 size displays like this


Can you wrap this in a demo?

----------


## Hosam AL Dein

https://www.youtube.com/watch?v=edxxiw8Q-98

here is a video demonstration for both command and listview errors

----------


## Krool

> here is a video demonstration for both command and listview errors


The command bug was a real one. However, it only affected the OCX version, which you are using. That's why I could not replicate it in the first place.
But now it's fixed. Thanks for reporting.
The bug was related to subclassing while in design mode. That's why that bug occured only in design mode and not at run-time.
This fix might also solved other similar problems in other controls, which are not yet detected. But now they can't be detected anymore.  :Smilie: 

The listview error is not a bug. It is normal behavior.

To solve this you need to process like this:


```
ListView1.ColumnHeaders.Add , , "Col1"
ListView1.ColumnHeaders.Add , , "Col2"
ListView1.ColumnHeaders.Add , , "Col3"
ListView1.ColumnHeaders.Add , , "Col4"

ListView1.ColumnHeaders(2).AutoSize LvwColumnHeaderAutoSizeToHeader
```

Instead of doing like this:


```
ListView1.ColumnHeaders.Add , , "Col1"
ListView1.ColumnHeaders.Add(, , "Col2").AutoSize LvwColumnHeaderAutoSizeToHeader
ListView1.ColumnHeaders.Add , , "Col3"
ListView1.ColumnHeaders.Add , , "Col4"
```

Reason: When doing autosize to columnheader "Col2" at time of autosizing it is the "last" columnheader. And then it's sized to right side of client edge.
To avoid this just add all columnheaders and do autosizing afterwards.

----------


## Hosam AL Dein

Nice work krool .

for listview i had already processed my code like what you have just provided to solve this error . and i also recommend that all autosizing is set even after listview items population because of "lvwColumnHeaderAutoSizeToitems" has to know the max length of all items .


think about these improvements . i think they are easy to be included compared to this massive work and will increase usability level for listview

1- listview column header backcolor
2- listview item alternate row color (items backcolor)
3- this one is necessary and will solve many problems :: making the header multiline or adding a sub-header or may be a footer to display sum or overage values for numerical columns if the user needs this function for both group level and all items level .
4- select all/none/inverse
5- command list which is dynamic for commands to be added maybe with default buttons like(delete-highlight .....) for checked or selected records
6- alias for bool values like say ( "in stock" if true ) ( "out of stock" if false )
7 - the most important one i think is related to working with touch screens . can we make listview scrolling is called by mousedown of listview . because it is annoying when in touch screens catching the scrollbar and scrolling is not a comfort

i am working on these improvements already , but i think it will be well more engineered if you make them in your original control

----------


## Krool

> 2- listview item alternate row color (items backcolor)


Use the 'ItemBkColor' event for this.
Then use Mod 2 on item index to change color to all alternate rows.

----------


## Semke

what do I have to add to my program when using the ocx version in order to get the xp themed controls.
I always use a manifest, but for a quick small app, I don't want that


I know it has been posted here, I just cant find it

----------


## Krool

> what do I have to add to my program when using the ocx version in order to get the xp themed controls.
> I always use a manifest, but for a quick small app, I don't want that
> 
> 
> I know it has been posted here, I just cant find it


If you don't want to depend on the OCX you can include just the Std-EXE project version components to your quick small app.
The manifest is still needed to enable the theming.

----------


## Krool

Update released.

I am puzzled why this bug remained for so long..
The X/Y param in the MouseDown/MouseMove/MouseUp event on controls with child windows, e.g. edit control, were wrong.
This is due to fact that each window starts from 0,0 coord.

Best example to illustrate is the IPAddress control, the X param started again from 0 on each of the 4 edit controls when moving the mouse from left to right:


This bug was easy to fix to just make a conversion via MapWindowPoints to the main control window.

Affected were the IPAddress, ComboBoxW, ImageCombo, SpinBox and DTPicker control. Basically those controls who have "shared" mouse events for both main and child controls.

The OCX was also updated.

----------


## Mith

hi Krool,

two more bugs found:

1. listview: the alignment of the checkboxes with view mode "list" are always top-left and dont align with the item text. see 1. control at the screenshot.

2. listbox: the item with the longest text at a listbox is always cutted at the end when using multicolumn and checkboxes. see 2. control at the screenshot.

----------


## chosk

Hi Krool,

There seems a problem with the Toolbar height on initial run. It is too short (as in icons are truncted or if there are text then text height is truncated. This is seen when I have a control below the toolbar and I resize it to fill.

On Form_Load, I understand the Form_Resize will be fired. But it seems that at this point of the run, the toolbar height is incorrect. After the form is shown, toolbar height then is correct and another manual Form_Resize will correct things.

I am using 28x28 icons for the toolbar.

----------


## Krool

> two more bugs found:
> 
> 1. listview: the alignment of the checkboxes with view mode "list" are always top-left and dont align with the item text. see 1. control at the screenshot.
> 
> 2. listbox: the item with the longest text at a listbox is always cutted at the end when using multicolumn and checkboxes. see 2. control at the screenshot.


1. I cannot replicate that issue. Please provide a demo project.

2. Use the .SetColumnWidth method. This method is likewise to the .net equivalent method. Therefore you can read the msdn article about how to best to use it.
https://msdn.microsoft.com/en-us/library/1w4k926x.aspx





> There seems a problem with the Toolbar height on initial run. It is too short (as in icons are truncted or if there are text then text height is truncated. This is seen when I have a control below the toolbar and I resize it to fill.
> 
> On Form_Load, I understand the Form_Resize will be fired. But it seems that at this point of the run, the toolbar height is incorrect. After the form is shown, toolbar height then is correct and another manual Form_Resize will correct things.
> 
> I am using 28x28 icons for the toolbar.


By default the windows toolbar has icon of 16x15 pixels but computes the button size as if the images were 16x16 pixels.
However, when you have an ImageList with a different icon size it will be recognized after Form_Load.
Since the ImageLists are assigned after it, it is not possible to assign during UserControl_ReadProperties.

A workaround solution would be to do following during Form_Load, then you have the correct height immediately:



```
Private Sub Form_Load()
Set ToolBar1.ImageList = ToolBar1.ImageList
Debug.Print "Form_Load: " & ToolBar1.Height
```

Beside this workaround there is no other immediate solution now possible.

----------


## chosk

> A workaround solution would be to do following during Form_Load, then you have the correct height immediately:
> 
> 
> 
> ```
> Private Sub Form_Load()
> Set ToolBar1.ImageList = ToolBar1.ImageList
> Debug.Print "Form_Load: " & ToolBar1.Height
> ```
> ...


This workaround did the trick. Thank you.

Actually, I did try the MS toolbar control earlier and it did size correctly to 28x28 icons on launch (with and without text).

----------


## Mith

> 1. I cannot replicate that issue. Please provide a demo project.


Its easy to replicate without a demo project. 
Just set the listview font type to "MS Sans Serif" and the font size to 12.

The checkbox will always stay top-left and not align-center with the item text:

----------


## Mith

> 2. Use the .SetColumnWidth method. This method is likewise to the .net equivalent method. Therefore you can read the msdn article about how to best to use it.https://msdn.microsoft.com/en-us/library/1w4k926x.aspx


I could fixed the problem with the listbox method .SetColumnWidth in combination with the api "GetTextExtentPoint32W" to determine the width of the largest item text.

Looks much better now:

----------


## Krool

> I could fixed the problem with the listbox method .SetColumnWidth in combination with the api "GetTextExtentPoint32W" to determine the width of the largest item text.
> 
> Looks much better now:


You may also add a buffer amount for the checkbox image.
However the 4/3 extrapolation in the msdn fits that gap in this case, but just for info.

----------


## VbNetMatrix

found a visual bug with calendar, and dropdown calendar (DTPicker1)

on a french computer (Canada French) the word Today is "Aujourd'hui" wich is large.  The date at end is truncated, check the number 13 in the picture.


also, DTPicker1 doesn't have a min size and can be resized in a way where it's not possible to select it anymore in IDE with the mouse

----------


## DEXWERX

> found a visual bug with calendar, and dropdown calendar (DTPicker1)
> 
> on a french computer (Canada French) the word Today is "Aujourd'hui" wich is large.  The date at end is truncated, check the number 13 in the picture.
> 
> 
> also, DTPicker1 doesn't have a min size and can be resized in a way where it's not possible to select it anymore in IDE with the mouse


Do you think this is a bug in Krool's common controls (which lets us use MS Common Controls in VB6), or a bug in the MS control itself?

----------


## VbNetMatrix

> Do you think this is a bug in Krool's common controls (which lets us use MS Common Controls in VB6), or a bug in the MS control itself?


not sure I understand your question.  Krool tools is a REDESIGNED of original control, it has nothing to do with the old control it's a redraw of them
the original control didn't had this problem.....

therefore, a bug in the "new" (Krool) control.

Edit: Ms Control is already available in Vb6 without help of Kroll  so not sure what u meant...

----------


## LaVolpe

> not sure I understand your question.  Krool tools is a REDESIGNED of original control, it has nothing to do with the old control it's a redraw of them
> the original control didn't had this problem.....
> 
> therefore, a bug in the "new" (Krool) control.


Not sure your statement is correct. If you look at the datepicker.ctl, you will not see anywhere within it where Krool paints/draws the control. At least I didn't see any such statements. Krool creates an instance of the SysDateTimePick32 class (CreateDTPicker() routine) and exposes it via his usercontrol.  So, from a cursory look at his code, doesn't look like he's redesigned anything significant, but mostly added support for unicode. However, what you are showing in your screen capture may indicate the font property should be changed (by you & preferably true-type) or some method called (by Krool) that would force the datepicker to adjust size based on font. Just a guess though.

----------


## DEXWERX

> not sure I understand your question.  Krool tools is a REDESIGNED of original control, it has nothing to do with the old control it's a redraw of them
> the original control didn't had this problem.....
> 
> therefore, a bug in the "new" (Krool) control.
> 
> Edit: Ms Control is already available in Vb6 without help of Kroll  so not sure what u meant...


ah no problem. I think you now know that Krool's controls simply wrap the existing controls found in comctl32.dll. 

so we have 4 different controls we can use in VB6.
* comctl32.dll <-- use the API manually
* ComCtrls v5 OCX <-- wraps the controls in comctl32.dll in user controls
* ComCtrls v6 OCX <-- based on the source of comctl32.dll (windows XP version), but is independent.
* Krools Controls <--- wraps the controls in comctl32.dll in user controls

If you want to learn about the Windows Common Controls, MSDN has a huge reference to the APIs.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Regardless, does the same bug show up in .NET's DTPicker control?

----------


## VbNetMatrix

> ah no problem. I think you now know that Krool's controls simply wrap the existing controls found in comctl32.dll. 
> 
> so we have 4 different controls we can use in VB6.
> * comctl32.dll <-- use the API manually
> * ComCtrls v5 OCX <-- wraps the controls in comctl32.dll in user controls
> * ComCtrls v6 OCX <-- based on the source of comctl32.dll (windows XP version), but is independent.
> * Krools Controls <--- wraps the controls in comctl32.dll in user controls
> 
> If you want to learn about the Windows Common Controls, MSDN has a huge reference to the APIs.
> ...


Thanks for the link.  I didn't had all theses information...  I knew about v5 and v6...  v6 (xp) being the fixed version and v5 being the theme able version. and I knew Krool is somewhat similar to v5 but was missing the whole picture  :Wink: 

as for your question, I'm not sure about .net version, not using it  but the v6 version is drawed properly.

----------


## VbNetMatrix

> Not sure your statement is correct. If you look at the datepicker.ctl, you will not see anywhere within it where Krool paints/draws the control. At least I didn't see any such statements. Krool creates an instance of the SysDateTimePick32 class (CreateDTPicker() routine) and exposes it via his usercontrol.  So, from a cursory look at his code, doesn't look like he's redesigned anything significant, but mostly added support for unicode. However, what you are showing in your screen capture may indicate the font property should be changed (by you & preferably true-type) or some method called (by Krool) that would force the datepicker to adjust size based on font. Just a guess though.


very pertinent comment. 100% agree.  as for my font, I used the default Vb6 one, "MS Sans Serif".  I tried with the 'new' (.NET) default SegoUI and it work properly

----------


## chosk

I set Location to Canada, Region and Language to French(Canada) but don't get "Aujourd'hui" which is the cause of the problem because it screwed the alignment. To get the 'original' sizing/scaling, perhaps making "Aujourd'hui" back to Today. I know I know Today is not French.

I tried Location as France and Region and Language as French(France), I get the "Aujourd'hui" but is is aligned properly.

----------


## chosk

MS San Serif different font size. Trying to help but cannot replicate.

----------


## LaVolpe

> very pertinent comment. 100% agree. as for my font, I used the default Vb6 one, "MS Sans Serif". I tried with the 'new' (.NET) default SegoUI and it work properly


I don't know if DPI was in play or not. If it was, say screen at 120-150% DPI, non-truetype fonts don't scale as well and the poor results would not be unexpected.

----------


## Tanner_H

@VbNetMatrix: what version of Windows are you on?  Maybe this is a longshot, but the DateTimePicker got a large overhaul between XP and Vista (and minor updates since), and maybe a precise Windows version is required to reproduce your bug.  I have seen weird spacing issues before, but I thought these were mostly rectified as of Windows 8...

----------


## Krool

> found a visual bug with calendar, and dropdown calendar (DTPicker1)
> 
> on a french computer (Canada French) the word Today is "Aujourd'hui" wich is large.  The date at end is truncated, check the number 13 in the picture.
> Attachment 150611
> 
> also, DTPicker1 doesn't have a min size and can be resized in a way where it's not possible to select it anymore in IDE with the mouse


For me it looks like you have a manifest to v6 of comctl32.dll but you use classic style windows theme? Can you confirm?
If yes, then I have no influence about the size of the drop-down calendar. If it would be v5.8x we could have tweaked it. So this could be really an MS bug.

----------


## Krool

Update released. Quite important internal improvements on some controls.

Some controls adjust their size according to some settings and windows preferences, e.g. the MonthView control.
Therefore after creating the API control it is necessary to resize the UserControl boundaries to fit in.

The dimensions (Width, Height) of an control are saved trough the UserControl.Extender object into the property bag.
Problem is that these dimensions will be applied to the UserControl after UserControl_ReadProperties is finished.
So any attempt to resize a control at ReadProperties will be overwritten afterwards...
UserControl_InitProperties is not affected since there are no saved dimensions yet in the property bag.

Solution was resolved by just applying the dimensions within UserControl_Resize to the Extender object, even if DPICorrectionFactor() equals 1.
There was also some bugfixing done, e.g. ComboBoxW. If applicable, only the Extender.Height is applied and not the Width also via Extender.Move. This allows preservation of previous Width setting stored in the property bag. That change is crucial when migration for instance from ComboBox to this ComboBoxW.

----------


## MountainMan

Krool, the updated files did not get attached to post #1...

----------


## VbNetMatrix

> MS San Serif different font size. Trying to help but cannot replicate.


Hi, 

one thing different I noticed, in your example, the today's date is in a circle while mine is in a rectangle.
This seem to be causing the difference in alignment.  What cause my side to have the rectangle instead of the circle ?

----------


## VbNetMatrix

> I don't know if DPI was in play or not. If it was, say screen at 120-150% DPI, non-truetype fonts don't scale as well and the poor results would not be unexpected.


very good comment, somethime we miss this simple solution...  not in my case though, I hate DPI change in Windows, about 4 program out of 5 doesn't run well with DPI change.

Mine is set at normal 100%  (running Win7 PRO x64)
(btw, I believe MS Sans Serif is a TTF isn't ?)

----------


## VbNetMatrix

> For me it looks like you have a manifest to v6 of comctl32.dll but you use classic style windows theme? Can you confirm?
> If yes, then I have no influence about the size of the drop-down calendar. If it would be v5.8x we could have tweaked it. So this could be really an MS bug.


damn...  you pin it...  my IDE doesn't use manifest.  I compiled and got a different result.  compiled I got the circle instead of rectangle for "today"
I still got a problem though, the circle is lilttle bit too low and got cut.
can u give me a link where I can get the manifest for vb6.exe ?
or link where you explain how to "completely" use and install your component ?  maybe I missed a few step...
I installed OLEGuids.tlb, but didn'T find information about installing a manifest.

----------


## Mith

hi krool,

i can reproduce the run-time error message 50003 using windows 8.1 and OCX v1.4.37:



the vb-project contains only the imagelist control with 2 icons and no source code is used.

Sample project: error50003.zip

----------


## VB6 Programming

> Mine is set at normal 100%  (running Win7 PRO x64)
> (btw, I believe MS Sans Serif is a TTF isn't ?)


'MS Sans Serif' is NOT a TrueType font.

A similar named font 'Microsoft Sans Serif' is TrueType.

'Segoe UI' is probably a better (TrueType) font to use nowadays.

----------


## Krool

Again small update related to yesterday bugfix, especially on the ComboBoxW control.
For instance on ComboBoxW control the height could be screwed up when the hidden VBControlExtender properties _ExtentX/_ExtentY were 0 or not set.
Typical scenario is on migration from VB.Combo to ComboBoxW that _ExtentX/_ExtentY are not set.

But I carefully tested now again every component and I hope all different scenarios are now resolved.




> i can reproduce the run-time error message 50003 using windows 8.1 and OCX v1.4.37:
> 
> 
> 
> the vb-project contains only the imagelist control with 2 icons and no source code is used.
> 
> Sample project: error50003.zip


I can run that sample project without any error...

----------


## Hosam AL Dein

hi krool ,

I have 2 issues here with listview


1 - when setting the property "usecolumnchevron" to true and autosizing the last column to header , these bugs occur

   a -   the header caption disappears
   b -   the width of the column gets too wide and the arrows "chevron" appear

while resetting the property "usecolumnchevron" to false , fixes the problem . this happens only in the last column when use chevron is  true

2- autosizing a column to the header caption works fine if the column caption is wider than the items , but if the items text is wider than the column header caption , autosizing for the header is still related to the items text which is wider than the caption although autosizing is set to the header not the items . this happens for any column with chevron is true or false


this is my code . try different captions in various widthes greater or less than items widthes  . also comment and uncomment the chevron line to check for the first issue but with the last column . column 3



```
Dim i As Long
lvmain.View = lvwReport
lvmain.ListItems.clear



'lvmain.UseColumnChevron = True



lvmain.ColumnHeaders.Add , , "column_a"
lvmain.ColumnHeaders.Add , , "column_b"
lvmain.ColumnHeaders.Add , , "column_c"

For i = 1 To 6
lvmain.ListItems.Add , , "row_a"
lvmain.ListItems(i).ListSubItems.Add , , "row_bbbbbbbbbbbbbbbbbbb"
lvmain.ListItems(i).ListSubItems.Add , , "row_c"
Next i

lvmain.ColumnHeaders(2).AutoSize LvwColumnHeaderAutoSizeToHeader

lvmain.Refresh
lvmain.Redraw = True
```

----------


## VbNetMatrix

> 'MS Sans Serif' is NOT a TrueType font.
> 
> A similar named font 'Microsoft Sans Serif' is TrueType.
> 
> 'Segoe UI' is probably a better (TrueType) font to use nowadays.



thanks for the information...  I never realized there were a "MS" Sans Serif and a "Microsoft" Sans Serif.  I thought they were the same and I knew the microsoft one was TTF.

I just changed my "default" Font in Vb6.exe to SegoUI (yup, I had to hack the .exe)

----------


## Krool

> thanks for the information...  I never realized there were a "MS" Sans Serif and a "Microsoft" Sans Serif.  I thought they were the same and I knew the microsoft one was TTF.
> 
> I just changed my "default" Font in Vb6.exe to SegoUI (yup, I had to hack the .exe)


Maybe you can create a tutorial thread of how to achieve this? It could be a common demand to change the default font in the IDE to a truetype font.

----------


## Cube8

> Originally Posted by VbNetMatrix
> 
> 
> thanks for the information...  I never realized there were a "MS" Sans Serif and a "Microsoft" Sans Serif.  I thought they were the same and I knew the microsoft one was TTF.
> 
> I just changed my "default" Font in Vb6.exe to SegoUI (yup, I had to hack the .exe)
> 
> 
> Maybe you can create a tutorial thread of how to achieve this? It could be a common demand to change the default font in the IDE to a truetype font.


Yes, it would be very handy, since MS Sans Serif is outdated...

----------


## DEXWERX

> Yes, it would be very handy, since MS Sans Serif is outdated...


some binary IDE hacks would be nice, things like changing the code editing colors, and default fonts. great ideas.

----------


## VB6 Programming

> thanks for the information...  I never realized there were a "MS" Sans Serif and a "Microsoft" Sans Serif.  I thought they were the same and I knew the microsoft one was TTF.
> 
> I just changed my "default" Font in Vb6.exe to SegoUI (yup, I had to hack the .exe)


Also consider the font size

MS Sans Serif 8 point was the default for older Windows and for VB6.
In newer Windows Segoe UI 9 point is normal.

When updating VB6 apps from MS Sans Serif (and you should do this to support DPI-aware controls) you need to choose a TrueType or OpenType font.
Segoe UI is an obvious one (because it is used by Windows), but it can appear smaller than MS Sans Serif - if you only change the fontname, and not the fontsize - so it may look better to increase the font size too (from e.g. 8pt to 9pt).

Another alternative is to use Microsoft Sans Serif. This is the TrueType/OpenType version of MS Sans Serif and is very similar in size. This means you don't need to change the fontsize.

If you are updating an existing app, using Microsoft Sans Serif is a little easier, but (imo) Segoe UI looks better.

Remember, changing the font on an existing application may give problems if it doesn't quite fit. For example a button may be only just wide-enough to fit the caption (text) using the existing font, changing the font may no longer fit.

----------


## VbNetMatrix

> Maybe you can create a tutorial thread of how to achieve this? It could be a common demand to change the default font in the IDE to a truetype font.


a tutorial on how to "hack" the Vb6.exe ?  I think I'll get flamed by the Forum Administator.

not sure it will be accepted ...  but maybe as a "Learning Technique" ?  a "how to"

I could provide source code of how to make the vb6 "Patcher"  we'll see if it is accepted  :Smilie: 

I'll get right on it.  Thanks for the suggestion.

----------


## VbNetMatrix

I used a lot of method to Hack my Vb6.exe...  for example, you can edit the "ressource" of vb6.exe and change all Windows Size
look at my Vb6/Reference Windows for example...  very handy I was tired of scrolling on my 27inch monitor...  :Smilie:   No more scrolling bar  :Smilie:

----------


## VbNetMatrix

> Also consider the font size
> 
> MS Sans Serif 8 point was the default for older Windows and for VB6.
> In newer Windows Segoe UI 9 point is normal.
> 
> When updating VB6 apps from MS Sans Serif (and you should do this to support DPI-aware controls) you need to choose a TrueType or OpenType font.
> Segoe UI is an obvious one (because it is used by Windows), but it can appear smaller than MS Sans Serif - if you only change the fontname, and not the fontsize - so it may look better to increase the font size too (from e.g. 8pt to 9pt).
> 
> Another alternative is to use Microsoft Sans Serif. This is the TrueType/OpenType version of MS Sans Serif and is very similar in size. This means you don't need to change the fontsize.
> ...


2 things...

1. unfortunately, Vb6.exe (for some reason) doesn't seem to include "fontSize" for the "default" font object (at least I didn't find it in the binary).  
You can only change the "default" Font
2. Changing the "default" font only affect "new" object you drop on a form.  it will not mess with your existing project.

but you're right,  "Microsoft Sans Serif"  might be a better alternative for the size reason...

I didn't know this thing would attract so many attention...  glad to hear some people still love Vb6  :Smilie:   so I'll go work right on it, I should finish the patcher code in an hour, I'll post it in a thread and let you know

----------


## Hosam AL Dein

hi krool ,

I have 2 issues here with listview


1 - when setting the property "usecolumnchevron" to true and autosizing the last column to header , these bugs occur

a - the header caption disappears
b - the width of the column gets too wide and the arrows "chevron" appear

while resetting the property "usecolumnchevron" to false , fixes the problem . this happens only in the last column when use chevron is true

2- autosizing a column to the header caption works fine if the column caption is wider than the items , but if the items text is wider than the column header caption , autosizing for the header is still related to the items text which is wider than the caption although autosizing is set to the header not the items . this happens for any column with chevron is true or false


this is my code . try different captions in various widthes greater or less than items widthes . also comment and uncomment the chevron line to check for the first issue but with the last column . column 3



```
Dim i As Long
lvmain.View = lvwReport
lvmain.ListItems.clear



'lvmain.UseColumnChevron = True



lvmain.ColumnHeaders.Add , , "column_a"
lvmain.ColumnHeaders.Add , , "column_b"
lvmain.ColumnHeaders.Add , , "column_c"

For i = 1 To 6
lvmain.ListItems.Add , , "row_a"
lvmain.ListItems(i).ListSubItems.Add , , "row_bbbbbbbbbbbbbbbbbbb"
lvmain.ListItems(i).ListSubItems.Add , , "row_c"
Next i

lvmain.ColumnHeaders(2).AutoSize LvwColumnHeaderAutoSizeToHeader

lvmain.Refresh
lvmain.Redraw = True
```

----------


## VbNetMatrix

> Maybe you can create a tutorial thread of how to achieve this? It could be a common demand to change the default font in the IDE to a truetype font.


Because you're the Thread Administrator, I answer here  :Wink: 
I did tutorial in a Vb6 project   :Wink:  and I started a blog about all thing I want to share about Vb6...
The blog is "under construction" but project is available...

http://vbx64.wordpress.com/vb6-default-font-fixer/

To ALL: if you want to talk about this, let's do it on the Blog to avoid floading Krool Thread  :Smilie:

----------


## Hosam AL Dein

hey all , I posted a question here twice and seemed to be ignored . is there something wrong ? are they visible mainly ?

----------


## VbNetMatrix

> hey all , I posted a question here twice and seemed to be ignored . is there something wrong ? are they visible mainly ?


No question have been ignored to my knowledge, can you give us the Post #  so we can validate ?

----------


## Hosam AL Dein

1585 and 1576

----------


## Mith

> I can run that sample project without any error...


Did you run the compiled exe or the project via the IDE?
What windows version did you use for your test?

----------


## VbNetMatrix

> 1585 and 1576


can you give us a snapshot picture of what you mean ?

----------


## Hosam AL Dein

video demonstration for what I mean for both 2 issues

https://www.youtube.com/watch?v=R9ocSUOAxOM

----------


## Hosam AL Dein

another bug in listview not related to the previous issues

when you set a splitbutton to a column and you manually re-position it , it loses the property and it is set to the other column which replaces it
and here is a video demonstration

https://www.youtube.com/watch?v=l-lo...ature=youtu.be

----------


## Hosam AL Dein

check this one too
it is in linklabel , when set to transparent this bug happens

https://www.youtube.com/watch?v=HtVQ...ature=youtu.be

----------


## Hosam AL Dein

the previous bug does not happen if it is placed on a user control as the net video shows
https://www.youtube.com/watch?v=cRkM...ature=youtu.be

----------


## Hosam AL Dein

also in linklabel , the font is not affected in design time . run the project once , now it will be drawn in both run time and design time
https://www.youtube.com/watch?v=6vX7...ature=youtu.be

----------


## Hosam AL Dein

still in linklabel , as said above , the transparency works fine only in usercontrols. but , it is not real transparency to my knowledge . It gets its backcolor from its parent as you will see in the next video when we put a label behind it . Is this intended to be like this or it is a bug ?

https://www.youtube.com/watch?v=_sLK...ature=youtu.be

and how to change the forecolor because it has never changed with any trial to change other properties might be preventing it to be changed .

----------


## Krool

Hosam AL Dein, you don't have any patience?
I do not forget your issues.. there will be noted.
Sometimes I posted an update for an issue raised 1 month before or so..

----------


## Hosam AL Dein

sorry krool , I am new to any forum and I doubted that my posts were not properly published because I used to see the message that tells the post will be published after admin revision and I no longer see it so I thought there was something wrong .

and about the posts I publish in a sequence , I always find it hard to make my point clear due to my " bad english " so I assign a time to record them in a video and publish them all in one time .

I really appreciate what you are doing and keep it up . sorry again

----------


## Krool

> 2 things...
> 
> 1. unfortunately, Vb6.exe (for some reason) doesn't seem to include "fontSize" for the "default" font object (at least I didn't find it in the binary).  
> You can only change the "default" Font
> 2. Changing the "default" font only affect "new" object you drop on a form.  it will not mess with your existing project.
> 
> but you're right,  "Microsoft Sans Serif"  might be a better alternative for the size reason...


Due to the fact that the default FaceName in vb6.exe is limited to 13 chars there seems to be no way to define "Microsoft Sans Serif", right?
So we could define "Segoi UI" but would need to life with FontSize of 8 instead of 9?




> Did you run the compiled exe or the project via the IDE?
> What windows version did you use for your test?


Win XP SP3 (VM) and Win 7 SP1. (both 32bit)

----------


## VB6 Programming

> Due to the fact that the default FaceName in vb6.exe is limited to 13 chars there seems to be no way to define "Microsoft Sans Serif", right?
> So we could define "Segoi UI" but would need to life with FontSize of 8 instead of 9?


To be consistent with newer versions of Windows, Segoe UI 9pt would be better.




> I did tutorial in a Vb6 project  and I started a blog about all thing I want to share about Vb6...
> The blog is "under construction" but project is available...


Does your VB6 'hack' change the font used in a VB6 app's menu ?

----------


## VB6 Programming

Krool,

In the Toolbar control you can change the font and this works fine. But the font used in the dropdown 'ButtonMenus' doesn't change. Is there any way to set this font ?

----------


## LaVolpe

> To be consistent with newer versions of Windows, Segoe UI 9pt would be better


Probably not a bad choice. That font appears to be available since Vista. If an app, using that font were shipped to XP (for sake of argument), the font would be changed to something else unless font is also shipped. 

I created a test app in Vista with a font I know wasn't installed on Win10. When opened in Win10, that font was changed to Arial. I don't know how VB (or system) selected Arial other than some system font-fallback algo. The plus side to this is that Arial is at least an Open/True type font which would scale better with DPI awareness.

If hacking the vb6.exe, suggest considering how far back one wants to support backward compatibility with fonts. Other options for fonts that do not use hacking vb6.exe are:

1) Whenever a form is added to your project, first thing to do is change the font on the form. Then, with most controls, the added control can inherit the form's font.

2) Create a form with the desired font and save it to VB's \Template\Forms folder and name it something like "Default.frm". Now you can replace the base form VB gave you with that one (via the selection window) and can select that new default whenever you want to add additional forms to the project. Similar solution for MDI forms: \Template\MDIForms folder.

In any case, font-fallback will be in play if the font you chose is not installed on the systems the app is run on. It's a shame VB didn't buffer the embedded font name within vb6.exe with full 32 characters. 

My only concern for hacking VB6.exe would be that it would fail to open if an uninstalled font was hacked into the exe. Maybe it would just default to Arial or something else? Maybe it will crash? Probably should verify that by hacking a completely bogus font name: BogusFont (suffixing null chars or spaces to fill it out to 13 chars)

Edited & FYI: using NotePad to enter a bogus font in an existing .frm file did NOT prevent the form from loading. The font, however, was changed to Arial (Win10). Maybe Arial would be a more consistent choice instead of Segoe UI?

*One more edit*... Hacked vb6.exe myself and provided a bogus font and VB defaulted to Arial. I then re-hacked it and provided a valid font and all went well. There are two locations in the exe where "MS Sans Serif" is listed, I replaced both instances, filling out the 13 characters with null chars as needed. I chose Arial over Segoe UI, but Segoe UI worked also. I personally prefer Arial as the default. Always hack a copy of the exe. And be pretty sure of the font you want. If you revisit this in a year, you may forget that the space allocated for the font is 13 characters. The font displayed in the exe won't show as 13 characters any longer if you selected a font with a shorter name.

----------


## VB6 Programming

> Probably not a bad choice. That font appears to be available since Vista. If an app, using that font were shipped to XP (for sake of argument), the font would be changed to something else unless font is also shipped.


Segoe UI has been the default Windows font since Vista, and has shipped with Office since Office2007 (so is often found on XP PCs too).  The Microsoft logo uses the Segoe font.




> I personally prefer Arial as the default.


I like Arial too. It was just that Microsoft chose Segoe for Windows that made me choose it.




> Create a form with the desired font and save it to VB's \Template\Forms folder and name it something like "Default.frm". Now you can replace the base form VB gave you with that one (via the selection window) and can select that new default whenever you want to add additional forms to the project. Similar solution for MDI forms: \Template\MDIForms folder.


That's how I do it. And I also save a Project (and Form) into the \Template\Projects folder, so I don't need to replace the base form each time.
But the Menu font remains as MS Sans Serif 8pt.

----------


## Krool

> I have 2 issues here with listview
> 
> 1 - when setting the property "usecolumnchevron" to true and autosizing the last column to header , these bugs occur
> 
> a - the header caption disappears
> b - the width of the column gets too wide and the arrows "chevron" appear


a: If the column headers are wider than the client area and can't be displayed all together the chevron button is shown.
   It is normal behavior that that caption where the chevron button currently is will not be shown.
b: I already explained, but again: When doing autosize to the last columnheader it is sized to right side of client edge.




> when you set a splitbutton to a column and you manually re-position it , it loses the property and it is set to the other column which replaces it


Seems to be an MS bug as other column properties (e.g. CheckBox) is shifting properly. The splitbutton though will stick to current column order and thus shifts to another column.
It seems worth to make some internal extra effort to address that bug. Bug is noted.




> also in linklabel , the font is not affected in design time . run the project once , now it will be drawn in both run time and design time


Fixed. Thanks. It was not an bug per definition, but linklabel did not refresh after WM_SETFONT so a RedrawWindow was necessary afterwards.




> it is in linklabel , when set to transparent this bug happens


Fixed. Thanks. It was not an bug per definition, but linklabel needed the dummy WM_PAINT after creation before the intial caching transparent brush.
Info: On all controls the caching of the transparent brush can be renewed with '.Refresh'. So keep in mind whenever background changes and you want to update the transparency make an .Refresh.




> In the Toolbar control you can change the font and this works fine. But the font used in the dropdown 'ButtonMenus' doesn't change. Is there any way to set this font ?


The dropdown 'ButtonMenus' uses the system font.
Again, the .ButtonMenus property is meant for simple and rapidstart use. If you want to have custom font do as following:
Don't set any ButtonMenu in .ButtonMenus, instead handle the event 'ButtonDropDown' and create your own menu there. (e.g. custom drawn PopupMenu)

-

Edit: OCX was also updated conerning LinkLabel.

----------


## VbNetMatrix

> Due to the fact that the default FaceName in vb6.exe is limited to 13 chars there seems to be no way to define "Microsoft Sans Serif", right?
> So we could define "Segoi UI" but would need to life with FontSize of 8 instead of 9?



Well... yes that's an issue for Microsoft Sans Serif...  the other solution would be to rename a font to a smaller name, this can be achieve with a tools... problem is you'll need to distribute that font with your EXE because I doubt the destination computer would "recognized" it as the original font...

However, on my machine, the program give me 126 other fonts to choose from, including SegoUI and Arial...  wich are both "acceptable"

as for the size, I didn't find a place in the vb6.exe where they store it.  I assume, 8 is the minimal font size of ms sans serif and that might be why that size was selected.  something like  MinSizeOfFont("Ms Sans Serif")  worth exploring since I noticed the font "Ms Sans Serif" was also stored at another adress in the exe, I'll make some test to validate that theory.

Did you tried the Vb6.exe font changer from my blog yet ?

----------


## VbNetMatrix

> To be consistent with newer versions of Windows, Segoe UI 9pt would be better.


Agree but it doesn'T seem to be possible for the moment.  I'm exploring something to allow it... I'll keep you informed.




> Does your VB6 'hack' change the font used in a VB6 app's menu ?


No but I have achieved this by modifying ressource inside the program.  

This would be the topic of another program since it's really 2 differents things...    When I'll get time I'll make the documentation on how to achieve that and post it on my blog.

----------


## VbNetMatrix

Thanks Lavolpe, you have pertinent observation.




> Probably not a bad choice. That font appears to be available since Vista. If an app, using that font were shipped to XP (for sake of argument), the font would be changed to something else unless font is also shipped.


SegoUI is the Microsoft Choice as "default" font for many thing including Visual Studio 2010 and up.




> I created a test app in Vista with a font I know wasn't installed on Win10. When opened in Win10, that font was changed to Arial. I don't know how VB (or system) selected Arial other than some system font-fallback algo. The plus side to this is that Arial is at least an Open/True type font which would scale better with DPI awareness.


You are right.  It's a System behavior (herited from Win95).  Microsoft made it a System behavior with the arrival of Web (WWW).  Some web page made for MacOS user wasn't showed properly because of font difference.  First, the family font is analyze, then the font attribute like "Serif", "StrikeThrough", etc...  then the closest font available is selected.  Arial will be selected more then 85% of the time but sometime Helvetica got elected.




> It's a shame VB didn't buffer the embedded font name within vb6.exe with full 32 characters.


Yeah, they simply did: OurVarDefaultFontName = "Ms Sans Serif" and the terminated Null




> My only concern for hacking VB6.exe would be that it would fail to open if an uninstalled font was hacked into the exe. Maybe it would just default to Arial or something else? Maybe it will crash?


Won't crash... I tested it first.  I would not have offered this solution without knowing it was safe.  However since this is only for the IDE and  since nobody will "share" their vb6.exe because it contain your serial number encrypted (install Vb6 fresh on a machine, save the vb6.exe, uninstall and install back, you'll get a different vb6.exe binary each time)





> Always hack a copy of the exe.


pretty sure you meant BACK (up) instead of HACK




> If you revisit this in a year, you may forget that the space allocated for the font is 13 characters. The font displayed in the exe won't show as 13 characters any longer if you selected a font with a shorter name.


That's why it is safer with the program I made.  I save the font as  Left(strFontName & String(13,0)), 13)

 :Smilie:

----------


## VbNetMatrix

about**: \Template\Forms folder 




> That's how I do it. And I also save a Project (and Form) into the \Template\Projects folder, so I don't need to replace the base form each time.
> But the Menu font remains as MS Sans Serif 8pt.


But you need to select "new project" and your template right?

My Vb6 is set to open a new project everytime instead of the select menu
Did you find a way to open your selected template by default ?

I'm looking for a way achieve this.  Sadly the design of the IDE in itself was poorly think.  There is limited option of personalisation

----------


## LaVolpe

> That's why it is safer with the program I made.  I save the font as  Left(strFontName & String(13,0)), 13)


I just overwrote the 13 bytes. Nothing fancy. Think you should warn user if a font name is > 13 characters. You don't want to truncate the font name. If you do, the hacked font won't be what they expected. Just a suggestion.

Regarding my concerns about crashing, etc. If you noticed my edited comments in my reply, already confirmed that it won't crash and it will select another font if a the hacked font isn't installed. I added those comments after I hacked my copy of vb6.exe to test it.

P.S. I tried searching the exe to see if I can find where the font size of 8 is set. Didn't spend a ton of time on it, but if there's a LOGFONT structure in there somewhere, I didn't see it. It is possible that there is no value set. LOGFONT.lfHeight can be set to 0, meaning: default height.

----------


## VbNetMatrix

> P.S. I tried searching the exe to see if I can find where the font size of 8 is set. Didn't spend a ton of time on it, but if there's a LOGFONT structure in there somewhere, I didn't see it. It is possible that there is no value set. LOGFONT.lfHeight can be set to 0, meaning: default height.


Sorry I had missed your edited comment... I started to answer and I had to leave, when I came back, I just finished my answer and posted it.
as for the font size...  you're probably right...

what we need is a NEW IDE !!!  :Smilie: 

We need to learn how to "load an OCX at run time" to emulate the IDE behavior...  and to run in memory for debugging like the IDE...  The rest is simply an editor  :Wink: 
loool.

p.s. did you found a new dizzy yet ?

----------


## LaVolpe

> p.s. did you found a new dizzy yet ?


Yep, custom made for my engine specs. Will take about another 2 weeks to finish and get here. Can't wait, cold weather is not that far out and the Mustang is just sitting in the garage, collecting dust, while waiting for it. *50 year old cars* are money pits, but its worth it to some of us.

Krool, sorry. Won't hijack your thread talking about muscle cars.

----------


## LaVolpe

@Krool, VbNetMatrix and others that may be hacking vb6.exe to replace the default font... 

Don't do it yet without more testing. See this post where I responded to a similar scenario that failed and it can be replicated. This font hack is not perfect as it is.

----------


## chosk

The ideal solution is an IDE add-in that "intercept" add new form and at that point change the font name and size according to one's preference. Can even do more than this - add new control (or anything) and change bla bla bla.

Here is link to MS documenatation that may help but I am not up to the standard. Maybe maybe one day I may try.
https://msdn.microsoft.com/en-us/lib...60(VS.60).aspx

----------


## chosk

Hi Krool,

There may be a problem with FrameW font. I created all the FrameW and all controls in all the forms with Arial. Now, I manually go into them and change the font to Tahoma. With the FrameW, visually and in the properties it reflected the change. Save to make the changes permanent. Close and open the forms, the FrameW font physically revert back to Arial but the properties still show Tahoma.

Update:
I just replaced the FrameW.ctl and .ctx with that from 20170627 and without doing anything else, all FrameW now correctly show the Tahoma font.

----------


## Krool

I would like to deploy the ActiveX Control version 1.5 "soon", though there are still some points open todo before that..
However, please let me know if you have some other points to consider which I might not know yet.
Thanks

----------


## MountainMan

You set up the FlexGrid replacement control as a different project even though it shares a lot with this project. The thread traffic is relatively slow so I wonder if it is time to merge this project with that. It would make use a bit easier only having to mess with one set of files, whether as controls or an OCX.

----------


## VbNetMatrix

> The ideal solution is an IDE add-in that "intercept" add new form and at that point change the font name and size according to one's preference. Can even do more than this - add new control (or anything) and change bla bla bla.
> 
> Here is link to MS documenatation that may help but I am not up to the standard. Maybe maybe one day I may try.
> https://msdn.microsoft.com/en-us/lib...60(VS.60).aspx


I had a project in past... I didn't finished it... it would do exactly like that...  for me it was to calculate time I pass on programming on each project...  maybe it's time to revive that project and add more functionality  :Smilie:

----------


## chosk

> Hi Krool,
> 
> There may be a problem with FrameW font. I created all the FrameW and all controls in all the forms with Arial. Now, I manually go into them and change the font to Tahoma. With the FrameW, visually and in the properties it reflected the change. Save to make the changes permanent. Close and open the forms, the FrameW font physically revert back to Arial but the properties still show Tahoma.
> 
> Update:
> I just replaced the FrameW.ctl and .ctx with that from 20170627 and without doing anything else, all FrameW now correctly show the Tahoma font.


To correct my mistake. The FrameW was created with Arial font with earlier version of Std-exe controls and displayed correctly as Arial. But now when used with current version, it is actually showing MS San Serif and I did not realize it still thinking it is Arial because it is not Tahoma. The current version seems to ignore what font is set (although reflecting the chosen font in properties) but actually display MS San Serif.

----------


## Krool

> To correct my mistake. The FrameW was created with Arial font with earlier version of Std-exe controls and displayed correctly as Arial. But now when used with current version, it is actually showing MS San Serif and I did not realize it still thinking it is Arial because it is not Tahoma. The current version seems to ignore what font is set (although reflecting the chosen font in properties) but actually display MS San Serif.


This is a side effect error when modified the FrameW on 03-Jul-2017 from MS control window to direct rendering. Fix will follow very soon.

PS: OCX is not affected as it still uses the "old" FrameW.

----------


## chosk

Hi Krool,

Thanks for the fix.

----------


## fafalone

The new Frame control doesn't support using an icon instead of text (I haven't updated in a while so I don't know what specific version this change was made in, I was using the one dated 11/18/2016)... it doesn't seem to be a real control, just drawn using theme API. For now I can drop the old version in as it's compatible with the newer subclassing/tlb, but would definitely like to see it continue to be supported in new versions.


It was done by setting the imagelist via BCM_SETIMAGELIST (and its margins via BCM_GETIMAGELIST after its first set) with the .hWndGroupBox handle, which was the hWnd from the CreateWindowEx call, which the new control doesn't have, and sending it to the only hWnd I see, UserControl.hWnd, obviously doesn't work.

----------


## Krool

> The new Frame control doesn't support using an icon instead of text (I haven't updated in a while so I don't know what specific version this change was made in, I was using the one dated 11/18/2016)... it doesn't seem to be a real control, just drawn using theme API. For now I can drop the old version in as it's compatible with the newer subclassing/tlb, but would definitely like to see it continue to be supported in new versions.
> 
> 
> It was done by setting the imagelist via BCM_SETIMAGELIST (and its margins via BCM_GETIMAGELIST after its first set) with the .hWndGroupBox handle, which was the hWnd from the CreateWindowEx call, which the new control doesn't have, and sending it to the only hWnd I see, UserControl.hWnd, obviously doesn't work.


True. Only way is to simulate such thing..
I could implement a 'Picture' property and render likewise. (Instead of ImageList; less overhead)
Question: Display image along caption or both? A 'PictureAndCaption' bool property could control such question. (Just like in CommandButtonW, CheckBoxW, OptionButtonW etc.)

EDIT: Question in the room: Is there a need for a property page for the LabelW control? This would allow to make multiple lines of text in the caption property in design time.

----------


## fafalone

Image along caption would be wonderful actually, as that doesn't seem possible with the current frame control; you wouldn't need two properties, it would be picture-only when caption="", and text only when there's no picture; just adjust the start point of the text. 

But if I may ask... what advantage is offered by creating a control exclusively with theme API instead of CreateWindowEx? Because this probably won't be the only rare customization that doesn't work, especially if other controls do this too.

----------


## AAraya

It would be awesome if Toolbar ButtonMenus offered the ability to have images, change backcolor, set font so that Explorer style interfaces could be created, like this:



I know that this can be done by creating my own menu (or form) and showing it in the ButtonMenu click event but it would be wonderful if these enhancements were added to the ButtonMenus.

----------


## Krool

> It would be awesome if Toolbar ButtonMenus offered the ability to have images, change backcolor, set font so that Explorer style interfaces could be created, like this:
> 
> 
> 
> I know that this can be done by creating my own menu (or form) and showing it in the ButtonMenu click event but it would be wonderful if these enhancements were added to the ButtonMenus.


Use the 'ButtonDropDown' instead for showing your own menu. If there is so much demand for a better rapidstart menu I will consider making the ButtonMenus OwnerDrawn.




> Image along caption would be wonderful actually, as that doesn't seem possible with the current frame control; you wouldn't need two properties, it would be picture-only when caption="", and text only when there's no picture; just adjust the start point of the text. 
> 
> But if I may ask... what advantage is offered by creating a control exclusively with theme API instead of CreateWindowEx? Because this probably won't be the only rare customization that doesn't work, especially if other controls do this too.


FrameW is the only control which is done without CreateWindowEx. Reasons are more compact and understandable code. Also it allows to have a themed text color (ForeColor) via DrawThemeTextEx.

----------


## Krool

> Image along caption would be wonderful actually, as that doesn't seem possible with the current frame control; you wouldn't need two properties, it would be picture-only when caption="", and text only when there's no picture; just adjust the start point of the text.


Update released.
Included Picture property in FrameW control.

Not only the start point, but also the height needed to be adjusted in case the picture height is larger than the font height.

----------


## DrUnicode

In FrameW the image is not rendering correctly for 32bpp images.
I use DrawIconEx here and have external Manifest for Vb6.exe so I can see correct 32bpp in IDE.

Vb6.exe External Manifest works for me in Windows 10 if you add this Registry item:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide
Value: PreferExternalManifest
Data: 1 = prefer, 0 = don't prefer

Also noticed similar issue with ImageList not rendering Alpha channel for 32bpp in the PropertyPage.
Even though the images don't display correctly, the ImageList does in fact have the correct 32bpp images and work correctly when attached to your controls.
Using ImageList_Draw with ILD_TRANSPARENT fixes this.

----------


## Krool

> In FrameW the image is not rendering correctly for 32bpp images.


Thanks, and not only the FrameW. Also the StatusBar for the Panel.Picture was affected.
And of course the Images Property Page in the ImageList control. (cosmetic issue at design-time)

OCX got also updated for StatusBar and ImageList.

----------


## Krool

Further tweak for the Picture property in the FrameW control. The new included PictureAlignment property controls now if the picture is displayed left or right of the caption.
This might be useful especially when using right-to-left reading.

----------


## VB6 Programming

> If there is so much demand for a better rapidstart menu I will consider making the ButtonMenus OwnerDrawn.


That would be really useful.

----------


## Karl77

Hello Krool,



```
Private Sub ToolBar1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Debug.Print "Button", Button
End Sub
```

Button is always 1.

In MouseMove it is always 0.

What can be wrong?

----------


## Krool

> ```
> Private Sub ToolBar1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
> Debug.Print "Button", Button
> End Sub
> ```
> 
> Button is always 1.
> 
> In MouseMove it is always 0.
> ...


I cannot replicate that issue. MouseMove is of course 0 when no mouse button is hold down.
MouseDown is working correctly.. it gives me 1, 2 and 4 etc..

----------


## Karl77

> MouseDown is working correctly.. it gives me 1, 2 and 4 etc..


Not for me.
Regardless of the orientation of the toolbar.
(Had it vertical in the beginning).

Here's a form to play with.

----------


## Krool

> Not for me.
> Regardless of the orientation of the toolbar.
> (Had it vertical in the beginning).
> 
> Here's a form to play with.


I tested your Form with VBCCR14.OCX and get again 1, 2 and 4..

----------


## Karl77

> I tested your Form with VBCCR14.OCX and get again 1, 2 and 4..


Hmm, now I'm out of ideas.

---

*I must confess I'm too stupid for programming.
I mixed the MOUSE button with the TOOLBAR button.

Shame on me.
Forget the below...
*

---

I tried:
Quit all VB IDE's.
Reload project.
Compile to exe, with MsgBox on MouseDown.
Reboot of the PC.
Same procedure.

And I never get other Button values than 1.

Info:
VB6 has SP6B.
VB6.EXE has edited resources in order to show styles and DPI effects. *
Windows is 10/64, up to date.
Current DPI setting is 100%.
VBCCR14 is 1.4.044.
Side-by-side manifest is used in the project.

*I tried all the above with the original VB6.EXE as well.

What can I do/try/test/prepare/whatever?

----------


## chosk

I was slow.

----------


## fafalone

> Update released.
> Included Picture property in FrameW control.
> 
> Not only the start point, but also the height needed to be adjusted in case the picture height is larger than the font height.


Wonderful. Works great-- thank you.

----------


## Semke

> You set up the FlexGrid replacement control as a different project even though it shares a lot with this project. The thread traffic is relatively slow so I wonder if it is time to merge this project with that. It would make use a bit easier only having to mess with one set of files, whether as controls or an OCX.


I agree with the above, this is a busy thread with active members, so the grid would have a proper discussion here

----------


## Mith

Version: 1.4.46
Control: ListView

The search function "FindItem" doesnt work here.
I tried different combination of the parameters but i never get back any ListItem.

Can anybody check this please?

BTW: Why does the function "FindItem" doesnt support the value-parameter (lvwText,lvwSubitem,lvwTag) ?
See FindItem Method (ListView Control)

----------


## Mith

i cant edit my own post to add a attachment... :Mad: 

attached you will find a example project to test the FindItem method of the ListView.

----------


## Karl77

Remarks on the CommandButtonW



The CommandButtonW shall show a picture, so an imagelist is defined. Works fine.

A:
The caption starts right after the image border.
ImageListMargin seems to work on the left edge only.
Ok, I could make a special image for the button.
It would be good if it would work on the right edge too.

B:
LabelW and other controls have the wonderful EllipsisFormat.
Could we have it for a CommandButtonW as well?

Thank you.

----------


## Karl77

> I agree with the above, this is a busy thread with active members, so the grid would have a proper discussion here


Me too.
Otherwise it may be not clear that a new flexgrid is in the works.
It would be too bad to miss it.

----------


## Krool

> i cant edit my own post to add a attachment...
> 
> attached you will find a example project to test the FindItem method of the ListView.


You want to search for subitems which is not supported by API LVM_FINDITEM.
Anyway I do find the MS ListView FindItem method with lvwSubItem more or less stupid as you don't can search for a specific subitem or has an indication on which subitem the search was successful.
That's why I have excluded the 'Where' parameter in my FindItem method.

I could include a new function 'FindSubItem' (wrapper function) where it would be possible to specify a search on a specific subitem or when that param is missing do a search on all subitems. But that function would be performed 'manual' and not done by an API call.




> Remarks on the CommandButtonW
> 
> 
> 
> The CommandButtonW shall show a picture, so an imagelist is defined. Works fine.
> 
> A:
> The caption starts right after the image border.
> ImageListMargin seems to work on the left edge only.
> ...


A: In order to work the ImageListMargin on the right edge you need to change ImageListAlignment to 'Right'.

B: Not possible to include EllipsisFormat property to common CommandButtonW. However, it could work for a 'Graphical' Style CommandButtonW? Would that be sufficient?

-

Is there a need for a property page for the LabelW control? This would allow to make multiple lines of text in the caption property in design time.

Also is there a need for a ColumnHeaders property page in the ListView control? This would allow to setup the ColumnHeaders at design-time.

----------


## chosk

> Also is there a need for a ColumnHeaders property page in the ListView control? This would allow to setup the ColumnHeaders at design-time.


This will be good.

----------


## Mith

> I could include a new function 'FindSubItem' (wrapper function) where it would be possible to specify a search on a specific subitem or when that param is missing do a search on all subitems. But that function would be performed 'manual' and not done by an API call.


Sounds good  :Thumb:

----------


## Krool

Major update released.

This time the Font properties are affected.

Whenever a new control is placed on a Form the new control will inherit the Font of the Form. (Ambient.Font)
When closing the Form the control's Font properties should normally not be saved into the property bag when it is equal with the Ambient.Font. (MS controls behavior)
This has the advantage that later on you can modify the ".frm" and change the Font of the Form and all controls will be loaded then with the new Ambient.Font.
Note that this trick does not work when changing the Form's Font property in the IDE as then the controls have already loaded the Font.

However, in _my_ controls the control's Font properties are always saved to the property bag.
That's why the trick with modifiyng the ".frm" file does not work, unless you change all occurrences of the Font and change them, which is not comfortable.

It seemed that 


```
.WriteProperty "Font", PropFont, Ambient.Font
```

does not do what I thought it would do. I thought there would be nothing saved when the Font equals the _DefaultValue_ of Ambient.Font.
But of course it does not work as the Font's are always "different" due to different object instances. ("If PropFont Is Ambient.Font" will not work)

Solution was to make the "equal test" task in a separate new function 'OLEFontIsEqual' and saving the property like this:


```
.WriteProperty "Font", IIf(OLEFontIsEqual(PropFont, Ambient.Font) = False, PropFont, Nothing), Nothing
```

Of course the opposite side has also been tweaked to


```
Set PropFont = .ReadProperty("Font", Nothing)
```

So now when the Font equals the Ambient.Font there will nothing be saved into the property bag. And on loading the Font will be Nothing in the first place.
But of course when the Font will be assigned and it is Nothing the Ambient.Font will be taken.


```
Public Property Set Font(ByVal NewFont As StdFont)
If NewFont Is Nothing Then Set NewFont = Ambient.Font
```

In order to realize this update into existing projects an "Update UserControls" task is necessary. Also ensure that "Lock Controls" is not active while doing so.

----------


## VbNetMatrix

> .WriteProperty "Font", PropFont, Ambient.Font


Hi Krool, I think, this is wrong for many reason...
The Default property should be the "default" value of the OCX or, in this case, the VbDefault Value,
i.e.: MS Sans Serif

From my own experience, I found out the best way to use them in the Write/Read property is as followed:


```
1. define a global var like 
Private gfntDefault As StdFont


2. in UserControl_Terminate()

Private Sub UserControl_Terminate()
  Set gfntDefault = nothing
End Sub


3. in UserControl_Initialize()

Private Sub UserControl_Initialize()
  SET gfntDefault = new StdFont
  gfntDefault.Name = "MS Sans Serif"
  gfntDefault.Size = 9
  gfntDefault.Bold = False
  gfntDefault.Italic = False
  gfntDefault.Strikethrough = False
  gfntDefault.Underline = False
End Sub

4. Finally...
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
   PropBag.WriteProperty "Font", PropFont, gfntDefault
End Sub
```

----------


## VbNetMatrix

Hi Krool,

I found out a weird bug with ComboBoxW

When Using the MoveWindow() Api, even if you don't move, don't resize the control, the DropDown Windows appear somewhere else.
Further more, you cannot Click the Control anymore.

Here a picture, Since you can't click the Control aftter MoveWindow(), I used CB_SHOWDROPDOWN to show where the DropDown appear.



What I was trying to achieve was to set the Height Property so the DropDown list would have a different size.
However, I learned later, this trick only work when the App is NOT using comctl32.dll version 6

Furthermore:

*Using original Vb6 Control*
#1 When using comctl32.dll version 5 (Default Vb6, IDE not patched, no manifest)
ComboBox DropDown box is limited to 8 items  You can use the MoveWindow() trick to change that behavior.

#2 When using comctl32.dll version 6 (IDE patched, or manifest)
if you put a lot (let's say 50) item in the ComboBox, the DropDown box will fill out the available screen region.
This seem to be a bug.  The compiled program is OK



in Themed app, the proper way is CB_SETMINVISIBLE but I was attempting to make a code that would work either it is themed or not...

Is there a way from IDE/EXE to detect if this is the case ?

----------


## VbNetMatrix

> Major update released.


Hi Krool and thanks for the Update.

Also, I was wondering...

is it normal the version number doesn'T appear in ComCtlsDemo.vbp ?

----------


## Krool

> Hi Krool, I think, this is wrong for many reason...
> The Default property should be the "default" value of the OCX or, in this case, the VbDefault Value,
> i.e.: MS Sans Serif
> 
> From my own experience, I found out the best way to use them in the Write/Read property is as followed:
> 
> 
> ```
> 1. define a global var like 
> ...


No, it should be the Form's default value (or container) and not the standard init value. That is the behavior at least for the VB intrinsic and MS controls.

----------


## Krool

> Hi Krool,
> 
> I found out a weird bug with ComboBoxW
> 
> When Using the MoveWindow() Api, even if you don't move, don't resize the control, the DropDown Windows appear somewhere else.
> Further more, you cannot Click the Control anymore.
> 
> Here a picture, Since you can't click the Control aftter MoveWindow(), I used CB_SHOWDROPDOWN to show where the DropDown appear.
> 
> ...


There is already a 'MaxDropDownItems' property available which takes care of that mess in the ComboBoxW and ImageCombo control.

And concerning MoveWindow() its normal. The VB.ComboBox has the coords of the Form, whereas my ComboBoxW control is a child of a UserControl and therefore has the coords of the UserControl and not the Form. Like SetParent API, use .hWndUserControl for such things.

----------


## LaVolpe

> No, it should be the Form's default value (or container) and not the standard init value. That is the behavior at least for the VB intrinsic and MS controls.


100% agree if your tools are meant as a replacement, but next quote below breaks this behavior...




> So now when the Font equals the Ambient.Font there will nothing be saved into the property bag. And on loading the Font will be Nothing in the first place


However, this appears to be contrary to some (if not all) intrinsic controls behavior. VB seems to always write the intrinsic control font name if not MS Sans Serif, at least it does with Command buttons. It appears intrinsic controls fonts are compared with a hard coded font.

----------


## Krool

> 100% agree if your tools are meant as a replacement, but next quote below breaks this behavior...
> 
> 
> However, this appears to be contrary to some (if not all) intrinsic controls behavior. VB seems to always write the intrinsic control font name if not MS Sans Serif, at least it does with Command buttons. It appears intrinsic controls fonts are compared with a hard coded font.


If you change the Form's Font to 'Tahoma' and the VB intrinsic CommandButton is 'MS Sans Serif' it will be saved. If the CommandButton will also be changed to 'Tahoma' it will not be saved anymore.

----------


## LaVolpe

I had to go back and re-read your summary of changes regarding the font. I must have read it incorrectly at first and better understand your logic, which I agree with. My bad.

----------


## Karl77

> A: In order to work the ImageListMargin on the right edge you need to change ImageListAlignment to 'Right'.


Then the whole image is on the right side.
I was after having a distance to the text on the right side of the image, a padding around all borders of the image.
In the meantime I had a too simple idea to have it: A leading space in the caption. Done.




> B: Not possible to include EllipsisFormat property to common CommandButtonW. However, it could work for a 'Graphical' Style CommandButtonW? Would that be sufficient?


No, I consider the graphical style useless at all.
A toolbar with one button only is better, it has the Ellipsis thing.
But it has not the appearance of a button, except VisualStyles=False, and this doesn't look good.
In the end I think I have to fake the Ellipsis format myself (it's not so hard).




> Is there a need for a property page for the LabelW control? This would allow to make multiple lines of text in the caption property in design time.


No.

----------


## Mith

Hi Krool,

is there any chance that u add a background color property for a complete row (item+subitems) at the listview (report mode)?  :Smilie: 

here you can find a code example:

background-color-for-a-listview-item

...or ist this already possible? i didnt see any property for this...

----------


## Hosam AL Dein

> Hi Krool,
> 
> is there any chance that u add a background color property for a complete row (item+subitems) at the listview (report mode)? 
> 
> here you can find a code example:
> 
> background-color-for-a-listview-item
> 
> ...or ist this already possible? i didnt see any property for this...


yes it already exists . you can do so by ItemBkColor event of the listview



```
Private Sub lvmain_ItemBkColor(ByVal Item As VBCCR14.LvwListItem, RGBColor As Long)
If Item.Index = 3 Then RGBColor = 16711935
End Sub
```

----------


## Zphere

At first, I don't know if my question is related to Krools controls in particular 
because of my missing knowledge here.
So, please excuse if you think that I'm hijacking this thread.

ListViewW question:
Is there any way for fast clearing the Listview?

Background:
A ListView with four columns (Headers:StrLen, Type, Size,DirectoryContent).
Purpose is to load an array with directory/volume contents into it (using FindFirstFileW/FindNextFileW/FindClose).
When trying to load an array that contains all files and folders of volume "C:\" (about 350000 entries for me) 
the approximated time is about 35 secs on my personal pc (this is acceptable I think).
But time to clear this list (lvwdata.ListItems.Clear) feels like eternities (about 2-3 minutes). This is really annoying.
In comparison, using a ListBoxW to load this data, LstData.Clear blanks the list nearly immediately.
I wanna stay at the ListViewW control because of some of its features.

So, is there any way to clear a huge list faster? Or did I miss a specific method?
Thanks much in advance for any reply.

----------


## Krool

@ Mith, I have now included the 'FindSubItem' function in the ListView control.

Short explanation of the usage:

When doing a search on all sub items:


```
Dim ListItem As LvwListItem, SubItemIndex As Long
Set ListItem = ListView1.FindSubItem("test123", , SubItemIndex)
If Not ListItem Is Nothing Then
    MsgBox "Found: " & ListItem.ListSubItems(SubItemIndex).Text
End If
```

When only searching on a specific sub item:


```
Dim ListItem As LvwListItem
Set ListItem = ListView1.FindSubItem("test123", , 1)
If Not ListItem Is Nothing Then
    MsgBox "Found: " & ListItem.ListSubItems(1).Text
End If
```

So in fact if the param "SubItemIndex" was passed with 0 a search on all sub items will be performed and the return sub item index will be passed back.
If it was passed > 0 then only on that specific sub item index will be searched.

The rest works likewise to the FindItem function. (Partial, Wrap)




> Is there any way for fast clearing the Listview?
> 
> Background:
> A ListView with four columns (Headers:StrLen, Type, Size,DirectoryContent).
> Purpose is to load an array with directory/volume contents into it (using FindFirstFileW/FindNextFileW/FindClose).
> When trying to load an array that contains all files and folders of volume "C:\" (about 350000 entries for me) 
> the approximated time is about 35 secs on my personal pc (this is acceptable I think).
> But time to clear this list (lvwdata.ListItems.Clear) feels like eternities (about 2-3 minutes). This is really annoying.
> In comparison, using a ListBoxW to load this data, LstData.Clear blanks the list nearly immediately.
> ...


I have no quick answer to that. Normally in my tests the clearing takes a few seconds in the demo project when containing 100,000 rows.
So the best is maybe you provide a demo showing the 2-3 minutes. Maybe something different can also be improved.

----------


## VbNetMatrix

> No, it should be the Form's default value (or container) and not the standard init value. That is the behavior at least for the VB intrinsic and MS controls.



You're right of course... (there is a missing step in my example where I initialized the Usercontrol property with thoses provided as default)

what I so badly attempted to point out is the fact that using a value other then the "default" value as the third param in property save/read is always leading to strange result in the long run, especially if that parameter value is not fixed from 1 run to another like when you're using Ambient.

but again... I should not intrude on that.  You made excellent work.


Some people like Lavolpe (see post #1613) have a knack to politely show what could be seen as other mistake without provocation.  Unfortunately I apparently lack this aptitude and I apologize.

and I thanks Lavolpe for pointing out my error so delicately.

----------


## VbNetMatrix

Hi Krool...  

a little back on the Calendar bug I described early...

First, I went back to developping (IDE) without manifest and only compile with manifest.
IDE with manifest (Theme) has too much bug (like the color palette unavailable)

anyway, I'm not sure if it'S the fact of not using the manifest for vb6.exe but now I got the proper circle instead of the rectangle for the date
and the "aujourd'hui" word is placed properly too.

However, I noticed something knew...
here the picture.

can you reproduce ?

----------


## Karl77

> I have no quick answer to that. Normally in my tests the clearing takes a few seconds in the demo project when containing 100,000 rows.
> So the best is maybe you provide a demo showing the 2-3 minutes. Maybe something different can also be improved.


I don't know, but could it be something like this?
http://www.vbforums.com/showthread.p...ry-slow-in-VB6
I fell into this trap several times.

----------


## Mith

> @ Mith, I have now included the 'FindSubItem' function in the ListView control.
> 
> Short explanation of the usage:
> 
> When doing a search on all sub items:
> 
> 
> ```
> Dim ListItem As LvwListItem, SubItemIndex As Long
> ...


lets say i have report with 4 columns and 100.000 rows and the word "findme" stays at the first row at the last column.
does this mean i have to run a search with FindItem through all 100.000 rows and then run a search with FindSubItem and the SubItemIndex 0 to get the back the first row?

what i want to say is that it would be more efficent to have one Search-Function that check the item&subitems of each row at one time and not check all existing items first and later check the subitems again...

----------


## Zphere

Thanks Krool for having a look.
I admire your patience and willingness to answer all requests in this thread.

Attached is a project sample to address the issue mentioned in my previous post.
I tried to remove everything not needed from my orig. project.
As usual, remove the docx extension of the attached file.

Some environmental information that might be of help?:
OS: Win10Pro v.1703 x64; OLEGuids.odl/tlb in "SysWOW64" folder.
Mainboard: AsusP8Z68-V-LE
Proc: Pentium i7 
RAM: 32GB
HD:NVMe Samsung SSD 950 Pro (OverProvisioning enabled)

If compiled, getting the filelist and loading it into the ListView takes about 35 secs. Deletion takes about 90-120 secs.
In IDE loading takes about 70-80 secs and deletion about 120 to150 secs.

----------


## Mith

> yes it already exists . you can do so by ItemBkColor event of the listview
> 
> 
> 
> ```
> Private Sub lvmain_ItemBkColor(ByVal Item As VBCCR14.LvwListItem, RGBColor As Long)
> If Item.Index = 3 Then RGBColor = 16711935
> End Sub
> ```


Thank you for the useful hint! Works like a charm  :Big Grin:

----------


## OldClock

Hi Krool

The second screenshot of the first post shows a nice-looking listview with sortable columns, so I would like to try this replacement out. However two bits of information are missing:
1. What licence does ComCtls use?
2. Where does one download it? There are a few links, one is a "demo" of something, the other is an "ActiveX version" and you used the capitalized phrase "Registration-Free". These things could be interpreted to mean very different things.

Could you please add an unambiguous link to the latest vanilla version, and state the licence this project is released under?

----------


## Krool

> lets say i have report with 4 columns and 100.000 rows and the word "findme" stays at the first row at the last column.
> does this mean i have to run a search with FindItem through all 100.000 rows and then run a search with FindSubItem and the SubItemIndex 0 to get the back the first row?
> 
> what i want to say is that it would be more efficent to have one Search-Function that check the item&subitems of each row at one time and not check all existing items first and later check the subitems again...


Use only FindSubItem. No need to use FindItem first. It works like you imagine.

----------


## Krool

Critical update released.

UserControl_ReadProperties crashes in the LabelW control. Very sorry for this stupid bug.
In the Demo is no LabelW on the form, that's why it just got to my attention now later..

Also all controls have now MouseEnter/MouseLeave events. The IPAddress was the last control that now got the additional mouse events..

----------


## Hosam AL Dein

the forecolor for link label does never change

----------


## Krool

> the forecolor for link label does never change


In the link label are two texts. Normal text and link text.
In order to change link text color there is a event for that.

----------


## Krool

> If compiled, getting the filelist and loading it into the ListView takes about 35 secs. Deletion takes about 90-120 secs.
> In IDE loading takes about 70-80 secs and deletion about 120 to150 secs.


I have now looked into your case and must say I don't know how to improve that case.
Some explanation about the current logic:
Per "Row" in the ListView is 1 LvwListItem class stored. This is necessary to store the whole data and also to allow "If ThisItem Is ThatItem Then".
The LvwListSubItems and LvwListSubItem classes are only created when needed, so there is a no issue with "VB class-unloading". All data for the sub items is stored in a UDT array, which is certainly the fastest approach on unloading. (Erase)
So my guess is that it is VB6 fault that it takes so long to destroy 1 LvwListItem class object per "Row".

I guess there is some sort of "exponential" reason behind this. At some point when you increase with factor of 10, the unloading takes more than factor of 10.




> The second screenshot of the first post shows a nice-looking listview with sortable columns, so I would like to try this replacement out. However two bits of information are missing:
> 1. What licence does ComCtls use?
> 2. Where does one download it? There are a few links, one is a "demo" of something, the other is an "ActiveX version" and you used the capitalized phrase "Registration-Free". These things could be interpreted to mean very different things.
> 
> Could you please add an unambiguous link to the latest vanilla version, and state the licence this project is released under?


1. no license, free.
2. "Registration-Free" means an SxS manifest approach to allow using the ActiveX Control without "regsvr32" first. What you mean with unambiguous link?

----------


## OldClock

Thank you Krool




> 1. no license, free.


It would prevent such confusion for others if you added "Licence: public domain" to the first post.




> What you mean with unambiguous link?


The post currently links to a "This Demo", links to a "Version 1.4", and has an attached "ComCtlsDemo.zip.docx" with no version in its filename. I'm confused.

To make this clear, I would suggest writing something like this:
The latest version is 06-Sep-2017
Download SxS: [download]
Download ActiveX: [download]
Or if the download includes both:
The latest version is 06-Sep-2017
Download: [download]
(includes both ActiveX and SxS)
Download sample projects:
1. How to make the ToolBar control accessible per shortcut key on a MDIForm: [Download]
2. How to foo bar something else: [Download]
Making the download links clearly tell me the version and what they are would clear this up.

Speaking of versions, one of the links in your post mentions "1.4", while the changelog makes no mention of any such version (or any numeric version at all) and instead uses dates. So which is the latest, is it 1.4 or is it 06-Sep-2017? This would need to be cleared up as well.

----------


## Krool

@ OldClock,

(Copy&Paste from ActiveX Thread)
_The development state of the ActiveX Control version does not necessarily match to the Std-EXE version.
That comes because the Std-EXE version is the "leading source" and the ActiveX Control version is derived from the Std-EXE version after a certain time.
Reason why is that it is not practicable to release a new ActiveX Control after each new feature.
However, certain bugfixes can and will be implemented into the current ActiveX Control version. (Revision)_

1.4 is the version of the ActiveX project. The Std-EXE project gets frequently updated and does not have an internal versioning.
If you like you can put a "timestamp" on the downloaded Std-EXE project..

----------


## Karl77

> I guess there is some sort of "exponential" reason behind this. At some point when you increase with factor of 10, the unloading takes more than factor of 10.


Exactly because of this effect I had to give up on using classes when it comes to large counts.
UDTs are the only way for better performance.

This is a really weak spot in VB6.
IMO classes are only useful when the count is low.
Olaf pointed out a method to get class destroying faster.
But that is a LOT of effort.

'Changing' such scenarios to UDT has it's obstacles and is effort as well.
The reward is a performance boost of factor >1000.

Karl

----------


## DEXWERX

> Olaf pointed out a method to get class destroying faster.
> But that is a LOT of effort.


do you have this thread link? trying to find it.

----------


## Zphere

Again, thank you Krool.
I expected (and feared) this kind of answer.

@Karl77,
I'm also very interested in providing the thread link.

----------


## Krool

The thread can be found here.
I have now (quick and dirty) test implemented the approach and the unloading took now 2 secs. (instead of 27 secs, in IDE)
The loading is nearly unchanged at 80 secs.. (in IDE)

EDIT: But I encounter an "memory leak". When using the fast approach by Olaf I have not the same memory usage after .Clear then before loading..

----------


## DEXWERX

It looks like the only caveat is a lack of event support. and since Class_Initialize/Terminate are events, those need to be sidestepped too, which doesnt seem to be a problem for LvwListItem/LvwListSubItem.

----------


## Krool

> It looks like the only caveat is a lack of event support. and since Class_Initialize/Terminate are events, those need to be sidestepped too, which doesnt seem to be a problem for LvwListItem/LvwListSubItem.


Memory leak solved.  :Smilie:

----------


## Karl77

> do you have this thread link? trying to find it.


http://www.vbforums.com/showthread.p...ry-slow-in-VB6
(was a few post here ago)

----------


## Krool

As said the unloading will be fast soon.
However, loading is no real change.
Seems to be no diff between..
..Current:


```
Dim NewListItem As New LvwListItem
```

..and new approach:


```
Dim NewListItem As LvwListItem
Set NewListItem = New_LvwListItem ' Olaf's function
```

But of course that change in loading will drastically improve unloading.

----------


## chosk

The MS ListView also suffer from this performance hit when too many rows/items are displayed. Perhaps MS did not intend ListView for such usage. I believe their Windows Explorer also do not read all files in the beginning but only read the folders/items as and when required (when node is selected). This gives the UI a good user experience.

vbVision has a sample project called Virtual ListView Demo that seems to load 1,000,000 rows in a flash but it is not really that. Instead it merely "displays on-demand" the info that is viewable. The info can be in an array or in recordset.

http://www.mvps.org/vbvision/Sample_..._ListView_Demo

----------


## VbNetMatrix

> Memory leak solved.


Hi Krool, 

can you give us the step you used to diagnosed and find the memory leak ?
it could be usefull for debuging.

I'm fighting with a nasty one using MsFlexGrid...  trying to find out if that's coming from my component or not.
thanks

----------


## Zphere

In the meanwhile I did some tests with the previously attached project.
Intent was to check if slowness might be related to the ListSubItems only or by defining several columns (data fields) or both.
Volume C: about 280000 files in 45000 directories = 325000 rows 

1st test:
Still defined four columns for the listview.
But writing all data fields of my UD-Array into one column only (.ListItems.Add,,srcArr(Z).FName & "|" & srcArr(Z).FLen  & "|" & srcArr(Z).FSize & "|" & srcArr(Z).FType).
Result: Loading takes about 25-35 secs only in IDE. Clearing is not significantly reduced (still 100-120 secs).

2nd test:
Listview contains only one column.
Writing all data fields of my UD-Array into this column (.ListItems.Add,,srcArr(Z).FName & "|" & srcArr(Z).FLen  & "|" & srcArr(Z).FSize & "|" & srcArr(Z).FType).
Result: Loading takes about 15-25 secs only in IDE. Clearing time is the same as in the 1st test.

3rd test:
Listview contains only one column.
Writing  filepaths only of my UD-Array into this column (.ListItems.Add,,srcArr(Z).FName).
Result: mainly the same as in the 2nd test.

So, would it be "bold" to say that chsok is right - but in general only?
It seems that loading and unloading time is also influenced by the number of data fields used (columns/.ListSubItems).?
But maybe my testing approach is also faulty and doesn't say anything.
Again, this is an undiscovered area for me. I just do a little more than guessing.

Will now try to implement Schmidts approach into my example project.
While having a first look into his code I see that it is far beyond my skills.
But leastwise, I think that I understand how to use it.
Will report if this is of any interest.

Krool,
wouldn't it speed up things if you try to implement your working solution (including your memory leak solution)  into one of the next updates?
I'm convinced that this will greatly enhance your project (...just a suggestion).

----------


## Krool

_removed as performance boost for ListView control was "false measured". Sorry.._

----------


## chosk

I found this in snippets I collected over the years. This one is from Randy Birch This will clear the listview in a jiffy. I see if I can find loading. If I recall vaguely, it is also using API but I am not sure. I know I did API add with ComboBox and it speed up a lot.

In a Module:


```
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As Long
```

In Private Sub cmdClear_Click():


```
    TimeStart

    Const LVM_FIRST As Long = &H1000
    Const LVM_DELETEALLITEMS  As Long = (LVM_FIRST + 9)

    Dim r As Long

    r = SendMessage(lvwData.hWnd, LVM_DELETEALLITEMS, 0&, ByVal 0&)

    Me.StatusBar.Panels(3).Text = TimeEnd
```

----------


## Krool

> I found this in snippets I collected over the years. This one is from Randy Birch This will clear the listview in a jiffy. I see if I can find loading. If I recall vaguely, it is also using API but I am not sure. I know I did API add with ComboBox and it speed up a lot.
> 
> In a Module:
> 
> 
> ```
> Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As Long
> ```
> 
> ...


Chosk..

I am doing this already since beginning.



```
Public Sub Clear()
ShadowListView.FListItemsClear
Set PropListItem = New Collection
End Sub
```



```
Friend Sub FListItemsClear()
If ListViewHandle <> 0 Then SendMessage ListViewHandle, LVM_DELETEALLITEMS, 0, ByVal 0&
Call CheckItemFocus(0)
End Sub
```

However, LVM_DELETEALLITEMS will not cleanup the Collection to free up the memory.

----------


## chosk

Hi Krool,

Normally, I do not look into your codes. I am not aware you are using this already. It so happen that I found the code and substitute it into Sub cmdClear_Click() and the result was 1.97 sec vs 260 sec for nearly 600,000 rows. I just tested again and you are right that memory was not free up.

I do not know what cause the difference in clearing speed when used in the Sub.

----------


## Krool

I think I will not implement Schmidts approach for fast class allocation and destruction because there is an risk for an memory leak.
If it would be an isolated area with no outside influence I would go that way. But here we have influence of "outside", means the end-user developing with the ListView control.
When the end-user developer now caches the ListItems and call .Clear then Schmidts approach will fail as the RefCounter was influenced by the end-user developer.
So there is always a risk here..

The only way I see to get an real performance boost in general is to get rid of the 1 Class usage per Row in the ListView control. (go the UDT way)
However, the down-side of this is that the end-user developer cannot compare two items if there are the same, e.g.


```
Private Sub ListView1_ItemClick(ByVal Item As LvwListItem, ByVal Button As Integer)
If Item Is ListView1.ListItems(1) Then MsgBox "test123"
End Sub
```

would not work anymore.

So question to everyone, which way to go? Or keep like it is?

----------


## Karl77

> ```
> Private Sub ListView1_ItemClick(ByVal Item As LvwListItem, ByVal Button As Integer)
> If Item Is ListView1.ListItems(1) Then MsgBox "test123"
> End Sub
> ```
> 
> would not work anymore.
> 
> So question to everyone, which way to go? Or keep like it is?


Go the UDT road.

----------


## Krool

> Go the UDT road.


To be honest I have no mood to go that road either..  :Smilie: 
It is so convenient the current way as the 1 class per row is stored as ObjPtr in the lParam member of LVITEM.
Changing this has for sure other perfomance drawbacks.

So I am likely to suggest for such large lists: go virtual.

----------


## Karl77

> To be honest I have no mood to go that road either.. 
> It is so convenient the current way as the 1 class per row is stored as ObjPtr in the lParam member of LVITEM.
> Changing this has for sure other perfomance drawbacks.
> 
> So I am likely to suggest for such large lists: go virtual.


Yes, you are right.
Especially for this seldom case.

----------


## Zphere

I'm still on testing, but I would like to post a preliminary opinion here:
In case the claimed performance boost affects loading only I would also say No, don't change anything.

In general - does one optimisation justifies a dependent drawback of a program?
I think Yes- but only if strength of optimisation is better than the drawback on the other side.
Is this the case here?

For me and and in practical terms, loading time for big data is not so important as long as it is complies
to general/common rules (vb standards).
Anybody of us knows that loading big data takes its time before you can do some further actions in a programm.

In contrast, the unloading slowness has a much bigger weight for me.
It does NOT comply to general vb standards here and is much more annoying than any kind of loading speed.
Not just that you can't do anything while your program is running, it also still consumes cpu performance
and resides in memory the time it takes to unload the listview after you tried to close the program
(tested by procexp - or use taskmgr if you want).

So, unless anybody finds a reliable AND valid solution for an unloading slowness I tend to say that
Krool shouldn't change anything here (test results will follow).

----------


## Hosam AL Dein

hi krool , 
in listview , setting the forecolor property at runtime affects only the first column. A bug or I am missing something ?

*Edit 1*

another notice . 

if I set the forecolor for the first item in column 1 to green and then changed the listview forecolor to red , besides the point that it only affects the first column , it also does not affect the item which is colored green which I colored by code .

----------


## chosk

ListView1.ListItems(r).ListSubItems(c).ForeColor = whatevercoloryouwant

r for row
c for column

----------


## Hosam AL Dein

> ListView1.ListItems(r).ListSubItems(c).ForeColor = whatevercoloryouwant
> 
> r for row
> c for column



no problem with this , I mean setting the forecolor for the listview in general . Or it is designed for setting forecolor item by item

----------


## chosk

> no problem with this , I mean setting the forecolor for the listview in general . Or it is designed for setting forecolor item by item


I was replying to your post before you made the edit. Note the time of my post and your edit.

----------


## Krool

> *Edit 1*
> 
> another notice . 
> 
> if I set the forecolor for the first item in column 1 to green and then changed the listview forecolor to red , besides the point that it only affects the first column , it also does not affect the item which is colored green which I colored by code .


OMG. You are right. How can this be...

Update released. Was a very tiny bugfix as can be seen below: (red marked)


```
Friend Sub FListSubItemsAdd(ByRef SubItemIndex As Long, ByVal Index As Long, Optional ByVal Key As String, Optional ByVal Text As String, Optional ByVal ReportIconIndex As Long)
PropShadowListSubItemsCount = PropShadowListSubItemsCount + 1
If Index = 0 Then
    SubItemIndex = PropShadowListSubItemsCount
Else
    SubItemIndex = Index
End If
ReDim Preserve PropShadowListSubItems(1 To PropShadowListSubItemsCount) As ShadowListSubItemStruct
If SubItemIndex < PropShadowListSubItemsCount Then
    Dim i As Long
    For i = PropShadowListSubItemsCount To SubItemIndex + 1 Step -1
        LSet PropShadowListSubItems(i) = PropShadowListSubItems(i - 1)
    Next i
    LSet PropShadowListSubItems(i) = PropShadowDefaultListSubItem
Else
    LSet PropShadowListSubItems(SubItemIndex) = PropShadowDefaultListSubItem
End If
With PropShadowListSubItems(SubItemIndex)
.Key = Key
.Text = Text
.ReportIconIndex = ReportIconIndex
End With
End Sub
```

OCX was also updated of course.

----------


## Hosam AL Dein

it is worth effort this awesome listview

----------


## Hosam AL Dein

still the point of the edit in my post krool . if you set a different color by code to an item , and then changed the forecolor again , the forecolor now applies to all the items except the one you changed by code . the bug fix solved the point that it only colors the first column .

like 


```
listview1.listitems(1).forecolor=vbgreen

listview1.forecolor=vbred
```

now all the items will have the red color except item 1 which you have previously set its color to green

*Edit 1 :*

this includes listitems and listsubitems

----------


## Krool

> still the point of the edit in my post krool . if you set a different color by code to an item , and then changed the forecolor again , the forecolor now applies to all the items except the one you changed by code . the bug fix solved the point that it only colors the first column .
> 
> like 
> 
> 
> ```
> listview1.listitems(1).forecolor=vbgreen
> 
> listview1.forecolor=vbred
> ...


That behavior is expected to be. To reset an fore color of an list item or list sub item set to -1.

----------


## Hosam AL Dein

shouldn`t forecolor paint all items ?
I am performing a conditional formatting on the items . Each matched item will have a specific different color . To reset it to the default color , I will have to loop and paint item by item with the default forecolor . 

and what does this mean 


> To reset an fore color of an list item or list sub item set to -1.


 set which value to -1 ?

----------


## Krool

When you have set ListView1.ListItems(r).ForeColor and/or ListView1.ListItems(r).ListSubItems(c).ForeColor it will be painted with that color, regardless what is defined by ListView1.ForeColor.
To "reset" the color at ListView1.ListItems(r).ForeColor and/or ListView1.ListItems(r).ListSubItems(c).ForeColor set them to -1. Then they will again "inherit" the ListView1.ForeColor.

----------


## Hosam AL Dein

I think the normal behavior should be : forecolor will paint all items .. this is the main case or original need for this property

but you use this logic : forecolor will paint all the items except those whose fore color has been previously set despite the fact that the majority will set a different forecolor for a specific item for less reasons and in very specific situations . I mean this is the exception not the main case . 

example : in my case here , this will force me to loop and check for item fore color if it is not equal the main forecolor then I will set it to -1 despite I have already looped for a specific *condition* on all items . now ,to set their color back I will have to loop again . but why do that while I have a forecolor property which should apply the whole thing . I mean conditions are exceptions but *forecolor means paint all the items* and this seems more logic to me . what do you think ?

----------


## Krool

> I think the normal behavior should be : forecolor will paint all items .. this is the main case or original need for this property
> 
> but you use this logic : forecolor will paint all the items except those whose fore color has been previously set despite the fact that the majority will set a different forecolor for a specific item for less reasons and in very specific situations . I mean this is the exception not the main case . 
> 
> example : in my case here , this will force me to loop and check for item fore color if it is not equal the main forecolor then I will set it to -1 despite I have already looped for a specific *condition* on all items . now ,to set their color back I will have to loop again . but why do that while I have a forecolor property which should apply the whole thing . I mean conditions are exceptions but *forecolor means paint all the items* and this seems more logic to me . what do you think ?


That is the same behavior as in the original MS ListView.
The specific overrides the general.
It would be terrible if changing the ListView1.ForeColor would reset all ListItems and ListSubItems ForeColor settings.

----------


## Hosam AL Dein

say 1000 rows :: filter some(50) to color red . so I will filter after setting the general . I will loop to preform this . I dont need to loop again to set the 1000 color to original .

the logic if I want to perform this

1- set the forecolor (if we want to color all items)
2- filter loop for exceptions (which surely will be less than all the items count)

so yes , specific overrides the general , thats why there is a method for changing the item forecolor .but also this method should be called after we generally set the main forecolor . *so forecolor will paint all and if we want to color some other items, we have made you a method to color the specific item and it surely will override the general but also should be called after the genaral beacuse if you use it you are willing to filter only some items which are less than the all surely .*

your consider it terrible and you are right if I set the item fore color before setting the general forecolor . the opposite should be done and *will be more logic and also will not face the problem you mentioned above*

----------


## Hosam AL Dein

Is this convincing ? or I am totally wrong or what ?

----------


## chosk

> That is the same behavior as in the original MS ListView.
> The specific overrides the general.
> It would be terrible if changing the ListView1.ForeColor would reset all ListItems and ListSubItems ForeColor settings.


Hi Krool,

I hope you keep to the original MS behaviour. Because I have preference setting for users to change forecolor and row backcolor, while keeping  those cells already colored unchanged. Example, for alternate row backcolors of white and green the forecolor usually black. For alternate row backcolors of gray and black the forecolor usually white. Those cells already colored *before* the change maintain their cell colors. If you change away from original MS behaviour, not only will I be screwed but others also using your controls who are coding according to MS behaviour.

----------


## Cube8

A _ResetAllColors_ method could be added, which would do what Hosam AL Dein requests.

----------


## chosk

This will reset the ListView ForeColor. 



```
'Private Sub ResetListViewForeColor(lvw As VBCCR14.ListView, FColor As Long)
Private Sub ResetListViewForeColor(lvw As ListView, FColor As Long)
    Dim i As Long
    Dim j As Long
    
    lvw.ForeColor = FColor
    
    lvw.Visible = False
    For i = 1 To lvw.ListItems.Count
        lvw.ListItems(i).ForeColor = lvw.ForeColor
        For j = 1 To lvw.ColumnHeaders.Count - 1
            lvw.ListItems(i).ListSubItems(j).ForeColor = lvw.ForeColor
        Next
    Next
    lvw.Visible = True
End Sub
```

Usage:


```
ResetListViewForeColor ListView1, vbBlack
```

----------


## chosk

This should be neater. Do away with the lvw.ForeColor = FColor



```
'Private Sub ResetListViewForeColor(lvw As VBCCR14.ListView, FColor As Long)
Private Sub ResetListViewForeColor(lvw As ListView, FColor As Long)
    Dim i As Long
    Dim j As Long
    
    lvw.Visible = False
    For i = 1 To lvw.ListItems.Count
        lvw.ListItems(i).ForeColor = FColor
        For j = 1 To lvw.ColumnHeaders.Count - 1
            lvw.ListItems(i).ListSubItems(j).ForeColor = FColor
        Next
    Next
    lvw.Visible = True
End Sub
```

----------


## Krool

> This should be neater. Do away with the lvw.ForeColor = FColor
> 
> 
> 
> ```
> 'Private Sub ResetListViewForeColor(lvw As VBCCR14.ListView, FColor As Long)
> Private Sub ResetListViewForeColor(lvw As ListView, FColor As Long)
>     Dim i As Long
>     Dim j As Long
> ...


I would suggest as following. (Red marked)



```
'Private Sub ResetListViewForeColor(lvw As VBCCR14.ListView)
Private Sub ResetListViewForeColor(lvw As ListView)
    Dim i As Long
    Dim j As Long
    
    lvw.Redraw = False
    For i = 1 To lvw.ListItems.Count
        With lvw.ListItems(i)
        .ForeColor = -1
        For j = 1 To lvw.ColumnHeaders.Count - 1
            .ListSubItems(j).ForeColor = -1
        Next
        End With
    Next
    lvw.Redraw = True
End Sub
```

EDIT: I will not change the behavior. It will remain like in the original MS ListView.

----------


## Hosam AL Dein

Guys , I do not have a problem with code here , I was talking about something which I thought ( and still - according to my little knowledge - ) to be more logical . ِِِِِAnyway , seems that I could not propose it or it is having some side effects which I do not recognize .

----------


## Cube8

> Guys , I do not have a problem with code here , I was talking about something which I thought ( and still - according to my little knowledge - ) to be more logical . ِِِِِAnyway , seems that I could not propose it or it is having some side effects which I do not recognize .


It would be "too much" to make these changes in functionality to such a "simple" method/property. That's why we proposed a new method for what you ask.

----------


## Hosam AL Dein

*I will retry to make my point more clear by some questions  :*

* 1 - What is the purpose of this explanation  ?*
the purpose of this explanation is to make a comparison between two behaviors being discussed about the way we should follow when calling this line of code *listview1.forecolor=....*  .


* 2 - what are the two ways being compared ?*

*way1*Setting the listview forecolor should be applied to all items and sub items of a listview regardless of the specifically colored items . So , when we call _listview1.forecolor=vbrgreen_ , we expect all items to be colored by green including specifically colored items
*way2*Setting the listview forecolor should be applied to all items and sub items of a listview except the specifically colored items . So , when we call _listview1.forecolor=vbrgreen_  , we expect all items to colored by green excluding specifically colored items . And to reset any item to its original forecolor (green) , we should use _listview1.listitem(i).forecolor = -1_ to set item i color to be the main forecolor for the listview (green) .


* 3 - why do I think that way2 is not the appropriate one (according to my opinion ) ?*  
If I have a listview with forecolor green and has - say -  1000 items and I want to color some few items to be red (based on some condition) . I will run a loop through 1000 records and do comparison and set the item color to red if it met the condition and nothing wrong with that in both ways . 

The problem will rise up at this next point . When I intend to Re-run conditional formatting function , I should add a line of code before setting any specific items colors . This line should reset all items forecolors to its default using *listview1.forecolor=listview1.forecolor* and I expect all items to be colored to default as *way1* suggests .
 On the other hand , using *way2* , will force me to write another loop through 1000 items and perform this instruction *listview1.listitem(i).forecolor = -1* to reset the 1000 items forecolor the listview main forecolor or add it to an existing loop which is not guaranteed in all of the cases and situations as loop may exist or not . Even if it existed , then we have added to it more 1000 * n instructions execution time through usercontrol classes , collections and properties and this will surely  deteriorate its performance in large scale listviews.


*way1*


```
Dim i as integer
listview1.forecolor=listview1.forecolor
for i=1 to 1000
if number(i) > 7 then listview1.listitems(i).forecolor=vbrednext i
```

*way2*


```
Dim i as integer
for i=1 to 1000
listview1.listitems(i).forecolor= -1if number(i) > 7 then listview1.listitems(i).forecolor=vbrednext i
```

Also consider , in the previous code , I have made use of the already running loop to escape creating another loop to set colors to default . But in some cases not related to this example , this loop might not be available.


* 4 - can items populating loop implicate or act as an already running loop to host item by item coloring ?*  

yes , but in some cases , - like mine - which is also very common , this can not be done as the user calls a window where he can select the column and the condition for conditional formatting . So , this can not be done during items population phase . And also I dont want to repopulate the list view before running the conditional format function causing another loop to run before conditional formatting function loop to guarantee that all items colors are set to default .*Note 1 : Items population after listview clearing method sets forecolors to the deafult*
* 5 - why did Microsoft provide a forecolor property for a lsitview ?* 
to apply the color to all listview items .
* 6 - why did Microsoft provide an item.forecolor property for a lsitview ?* 
also to apply the color to all listview items ???!!!!! No . the one up there handles this mission . So , the answer is : they thought some users will need to color some specific items by some different color while keeping the general forecolor to handle all the items . So it is made for EXCEPTIONS . Seems logic to me .
* 7 - what about the MS original list view which uses the same behavior ?* 
At this moment , I feel like it is some type of bug or un-handled analysis which they did not take care of . Otherwise , there is a piece of information I dont know which made it necessary while setting the forecolor property to leave all specifically colored items as they are . I thought about one issue but I also dont find it a complete answer . I thought of they said : "Set the forecolor as you want by the *general forecolor* . Now for exceptions use *item.forecolor* and don`t worry when you reset the *general forecolor* again we will not touch your exceptions to not oblige you to re-run the code for coloring exceptions again (saving performnce) and if you want to reset your exceptions to default use the value -1 to the item.forecolor using likely a loop (no performance saving here) " . But this has many more questions to be asked about the way they implemented it . Could it has been done more easier and logical and also performance-considerations aware ? . why dont I pass -1 to the general forecolor ? why to keep my exceptions while mainly in the level of items re-populating it erases all settings (this happens more often than just passing a forecolor to the listview) so I will anyway populate the items (now all colors removed see note 1 above) and I will color my exceptions again each time I refresh my data .

To simplify : Which one of these scenarios occur more often than the other ?

1- setting the general forecolor at runtime for a listview . (there where Microsoft wants to keep specific forecolors)
2- refreshing list items and repopulating the list view . (which will remove all specific forecolors)

surely the second case with a ratio about 300 :1

What is the worth of protecting exceptions while they will be demolished 300 times before it is even needed to be protected . Not only this is not useful , but also this protection operation will cost more performance load to recover from.

I mean , the general forecolor setting occurrance which will happen 1 time to 300 times repopulating which will demolish your protection to the (1 occurrance ) which also cost you over performance load . Why did not they even design this protection in a better way to recover from ? if I even consider this protection was necessary . They saved your effort in one time and you will exert it 300 times each time you repopulate the items .

So , It is an open discussion for everybody who can provide us with a case where he could not do without this feature or cases supporting my point . Maybe we can change the mind about going original MS road . If it was badly designed , can we improve this issue ? 

This is not a personal demand , even about this performance issue , it will not exhaust my apps which dont usually load more then 30 to 60 thousands records where such loops will not heavily affect performance . I opened the discussion just to improve it IF AND ONLY IF we agree to the point I have declared above . And of course you are free to decide krool .

Maybe I am missing something which makes my post totally wrong , but I will be glad to learn if so . I created my opinion based on that I did not find any reason for keeping these exceptions not affected by the general forecolor and the negative effect on performance while trying to recover from this protection .

@chosk @Cube8  . Firstly thanks for trying to help by code but it was not the problem for me . I was talking about performance . Thanks again




> Hi Krool,
> 
> I hope you keep to the original MS behaviour. Because I have preference setting for users to change forecolor and row backcolor, while keeping those cells already colored unchanged. Example, for alternate row backcolors of white and green the forecolor usually black. For alternate row backcolors of gray and black the forecolor usually white. Those cells already colored before the change maintain their cell colors. If you change away from original MS behaviour, not only will I be screwed but others also using your controls who are coding according to MS behaviour.


This is not an issue to be affected by any of the two methods chosk . It is a visual matter which can be solved by assigning the appropriate colors to each theme .

----------


## chosk

> This is not an issue to be affected by any of the methods chosk . It is a visual matter which can be solved by assigning the appropriate colors to each theme .


You are not getting it. It is not about color themes. It is about there is no existing color themes and the user have the freedom to choose any combination of colors.

The problem I see here is that you are putting your arguments against the way MS designed their controls and insisting MS is wrong and therefore any developers of controls that follow MS controls behaviors are also wrong.

Please take a step back and look at your own post carefully. I am sorry if I am rude which I think I am.

----------


## chosk

I normally don't like to show off. But I make an exception yet still taming my own mind.

I have done this for more than 10 years now from as long as VB6 was borned, first using MS controls and then using Krool's. Every row can be any color (in this case the chosen ones are black, blue and red) and they can change from one day to the next. Some cells on the right have another color different from the row. There are several ListViews and I don't have performance problem.

----------


## chosk

> This is not a personal demand


Then why are you so insistence on changing the .Forecolor behaviour? Perhaps you should politely with respect to Krool put forth a feature request instead of insisting that .Forecolor behaviour is wrong and therefore must be changed to your liking.

I would like to be able to copy codes from the Internet to test and explore whenever I encountered a coding problem and they just work with Krool's controls . No one will be able to do this if Krool's controls are not to MS behavior.

----------


## chosk

> *way1*
> 
> 
> ```
> Dim i as integer
> listview1.forecolor=listview1.forecolor
> for i=1 to 1000
> if number(i) > 7 then listview1.listitems(i).forecolor=vbrednext i
> ```
> ...



How about this? Then _listview1.listitems(i).ForeColor = -1_ will not be executed when not necessary.

*way 2*


```
Dim i As Integer
For i = 1 To 1000
    If Number(i) > 7 Then
        listview1.listitems(i).ForeColor = vbRed
    Else
        listview1.listitems(i).ForeColor = -1
    End If
Next i
```

Sorry if I am rude again although I know you like to say you don't have problem with coding.

----------


## Karl77

> No one will be able to do this if Krool's controls are not to MS behavior.


Full agree.
100% compatibility is the very main thing.
This makes it 'simple' to refresh an old app with the Krool's new controls.
If this wouldn't be the case, and we would have to think about every nitty-gritty detail, it would be more cumbersome.
Even with this 100% compatibility, there is enough to consider and re-code.

Which doesn't mean there shall be no new features.
There are a LOT of new and better features in the Krool controls.
If they were not there, the replacement wouldn't make any sense.

So all is right.

---

I myself fell into the 'break compatibility' trap, as I thought in #1691.
That was not a good idea.

----------


## chosk

Sorry, Krool.

I shall stop now.

Sorry.

----------


## Arnoutdv

The source code is also available, so if you want to create a personal version I think you are free to do so!

----------


## Hosam AL Dein

.
.

I was just typing a reply till I saw your posts . I have nothing to say here . Although I am holding much . 

About krool , 
he can read and determine if I said he was wrong or not . I am not (technically) in a position to judge krool or Microsoft . I was opening a discussion accepting the fact that I might be totally wrong due to a missing info .


About 


> feature request


I do not find it shameless to me to ask for any type of help . So , if I needed it , I would have asked for it because I am here to learn and I have already asked in the way which I find too clean and you suspect "my intentions" , go ahead . Also , I appreciate what krool is doing and for free helping all folks here including you . No need to be the bad guy here . Also , everyone can see that I did not do anything wrong to you or to anybody .


About being 


> polite


I think it is me who can teach you such thing .





> How about this? Then listview1.listitems(i).ForeColor = -1 will not be executed when not necessary.


.
this line was intentionally written like this because it was in a separate clear_format function where this method for comparison could not be done due to the changing operands , operators , parameters , colors and columns being tested . So , I had to clear all and set all to -1 before assigning new colors and I had copied it in here . So , you Just wanted to show off and fix what you considered an error . Even if it is , I do not mind . I am totally self-confident and do not need to search and seek for a kiddy comment to prove something .





> Sorry if I am rude again although I know you like to say you don't have problem with coding


Seems we both have problems but yours is the one I find shameless to have .


Such type of speech is time-wasting . I will not reply to any of your posts or whatever you say here for many reasons .

----------


## Hosam AL Dein

> The source code is also available, so if you want to create a personal version I think you are free to do so!


yes Arnoutdv , but I am not even willing to do so . As I said it is not a problem for me (the performance issue) . I have no problem with looping affecting performance in my apps level as I said . So , I thought this might be useful to anyone . It might be right or wrong .

----------


## DEXWERX

> yes Arnoutdv , but I am not even willing to do so . As I said it is not a problem for me (the performance issue) . I have no problem with looping affecting performance in my apps level as I said . So , I thought this might be useful to anyone . It might be right or wrong .


You've made a great and logical argument, and no one is saying you are wrong on those merits.
However considering it is subjective behavior (arguable either way), Microsoft chose differently.
Considering this project is a replacement of Microsoft's controls - compatibility completely over rides any subjective differences in logic.

And now comes the beauty of open source - If you want a behavior that's different from how Microsoft has done it for the last 20+ years, anyone can fork / change it.

----------


## Krool

I don't want to deepen the discussion about the forecolor in the ListView too much further, but:
Like others said it is essential that an replacement set does replace as flawless as possible.
So in fact it doesn't matter who is right or wrong with the ListView ForeColor'ing, the replacement must fulfill the MS behavior.

As an example even that can be tricky. For example the ListView 5.0 does have in one point an other behavior than the ListView 6.0
The ListView 5.0 will not autoselect the first listitem added to the list, whereas the ListView 6.0 does.
So which behavior should I take? Both seems to be "correct"?
I then decided to bring up a property called "AutoSelectFirstItem". It's default value is True.
When True it behaves like MS ListView 6.0, when False it does behave like MS ListView 5.0.
So everyone can decide which behavior to follow. I have chosen the MS ListView 6.0 behavior as default because my assumption was that the most will likely replace the MS ListView 6.0 and not an 5.0 one.

----------


## MountainMan

I think that we should be able to make everybody happy with this. I am not convinced that Hosam necessarily wants his desired feature to be the default and break compatibility with the MS version. I am guessing that if there were a new method added that is separate from and in addition to the MS methods that could be called then Hosam would be happy because he could do what he wants to do and everyone else should be happy because they can keep the MS compatibility and also have the option to use the new "Hosam method." Krool, this doesn't sound too hard to add another method (my guess is that would be better than creating a new fork), is this something you would like to add?

MountainMan

----------


## DEXWERX

> I think that we should be able to make everybody happy with this. I am not convinced that Hosam necessarily wants his desired feature to be the default and break compatibility with the MS version. I am guessing that if there were a new method added that is separate from and in addition to the MS methods that could be called then Hosam would be happy because he could do what he wants to do and everyone else should be happy because they can keep the MS compatibility and also have the option to use the new "Hosam method." Krool, this doesn't sound too hard to add another method (my guess is that would be better than creating a new fork), is this something you would like to add?
> 
> MountainMan


After thinking this through, I can see why Microsoft decided to go the way they did. To me it seems non-intuitive that by setting a default ForeColor - you are also resetting all previously set individual colors. It's kind of like completely erasing the bitmap on a form, by setting the BackColor. (which is the default behavior)

So what you/ Hosam are proposing is something like a ForeColorReset(), which removes all individual colors.

----------


## Krool

> After thinking this through, I can see why Microsoft decided to go the way they did. To me it seems non-intuitive that by setting a default ForeColor - you are also resetting all previously set individual colors. It's kind of like completely erasing the bitmap on a form, by setting the BackColor. (which is the default behavior)
> 
> So what you/ Hosam are proposing is something like a ForeColorReset(), which removes all individual colors.


As far as I also understood is that he needs a method to erase all customizing colors of the listitems (and subitems).

I have in mind a "ResetForeColors" method in .ListItems.
Means (syntax): 

```
ListView1.ListItems.ResetForeColors
```

That method would actually just set the ForeColor of all ListItems and ListSubItems back to -1. (equal ListView.ForeColor)

The same could be done for the TreeView:


```
TreeView1.Nodes.ResetForeColors
```

----------


## VbNetMatrix

> I have in mind a "ResetForeColors" method in .ListItems.
> Means (syntax): 
> 
> ```
> ListView1.ListItems.ResetForeColors
> ```


Best of both world.... not breaking compatibility and offering a good feature... just like you did with all your component.

----------


## Hosam AL Dein

> You've made a great and logical argument, and no one is saying you are wrong on those merits.
> However considering it is subjective behavior (arguable either way), Microsoft chose differently.
> Considering this project is a replacement of Microsoft's controls - compatibility completely over rides any subjective differences in logic.
> And now comes the beauty of open source - If you want a behavior that's different from how Microsoft has done it for the last 20+ years, anyone can fork / change it.


This was the main reason for opening this discussion DEXWERX  . We put all merits and demerits on a scale and then come up with a solution which takes main and essential functions into consideration . Is this right ? what is the reason for this behavior ? can we change it ? if no , so what can we do to solve it ? how will this solution affect the control ? and so on . This was the way of discussion I was expecting and asking for and it seems we have reached to this point and I am happy with that .



> Like others said it is essential that an replacement set does replace as flawless as possible.


Totally agree with this point , krool .



> I think that we should be able to make everybody happy with this. I am not convinced that Hosam necessarily wants his desired feature to be the default and break compatibility with the MS version.


You got the main point and said all what I want to express ,MountainMan



> After thinking this through, I can see why Microsoft decided to go the way they did. To me it seems non-intuitive that by setting a default ForeColor - you are also resetting all previously set individual colors. It's kind of like completely erasing the bitmap on a form, by setting the BackColor. (which is the default behavior).


Yes DEXWERX , regardless of the solution and its effects , I have been asking myself why they had choosen this behavior and this maybe some logic they adopted .



> As far as I also understood is that he needs a method to erase all customizing colors of the listitems (and subitems).
> 
> I have in mind a "ResetForeColors" method in .ListItems.
> Means (syntax): 
> 
> ```
> ListView1.ListItems.ResetForeColors
> ```
> 
> ...


Thanks krool for providing a suitable solution but does this mean you are going to add it or you suggest this solution to be added by anyone who wants this feature ?

Anyway , thanks all for getting us to a useful end point and lets continue to work to a next step forward

----------


## Krool

> but does this mean you are going to add it or you suggest this solution to be added by anyone who wants this feature ?


The method ResetForeColors is now included into the ListView control. (also TreeView control)
I have put it now directly to the ListView and not to .ListItems.
Means (syntax)


```
ListView1.ResetForeColors
```

The method should be quite fast, even on large lists.

----------


## Hosam AL Dein

Attachments were not updated krool .

----------


## Krool

> Attachments were not updated krool .


Std-EXE version was updated. OCX not as new feature. It will be included into version 1.5.

----------


## MountainMan

When will you release v1.5 ? What did you decide to about incorporating FlexGrid into this project or leaving it separate?

----------


## Karl77

I use a Krool toolbar which is changed by code quite often while it is visible.
The toolbar flickers in it's whole size when I set another image for a single button.
It also flickers when I set the same image that was already set.

Toolbar1.Buttons(i).Image = "otherimage"

The image comes from a Krool imagelist.
I already tried to set the toolbar to DoubleBuffer = true.
Still flickers.

The MS original via comctl32.ocx does not flicker, not a little bit.

Is there a special trick to get rid of the flicker with the Krool toolbar?
Perhaps I miss something...

Thanks,
Karl

----------


## Dragokas

Hi, Krool !

Can you please append VisualStyles.bas module with *_W2K functions of subclassing like you done in 'ComCtlBase' ?

Also, I noticed that program crashes if OS has no installed printers and you click => RichTextBox Demo => Page Setup => Cancel.

P.S. Again, thanks a lot for your project !!!
Alex.

----------


## Krool

> When will you release v1.5 ? What did you decide to about incorporating FlexGrid into this project or leaving it separate?


v1.5 will be released still this year imo. The FlexGrid will remain separated.




> Can you please append VisualStyles.bas module with *_W2K functions of subclassing like you done in 'ComCtlBase' ?


There is no need to include *_W2K functons in VisualStyles.bas module as those will be used only when "GetComCtlVersion >= 6".
And this is not the case in W2K. That's why there will be no subclassing applied.




> Also, I noticed that program crashes if OS has no installed printers and you click => RichTextBox Demo => Page Setup => Cancel.


The dialog returns CdlPrinterNotFound error. This can be easily fixed in the RichTextBox Demo by adding an Error Handler. Will do that. Thx




> The toolbar flickers in it's whole size when I set another image for a single button.
> It also flickers when I set the same image that was already set.


I see. I have a solution in mind and will be fixed very soon.

----------


## Dragokas

> There is no need to include *_W2K functons in VisualStyles.bas module as those will be used only when "GetComCtlVersion >= 6".
> And this is not the case in W2K. That's why there will be no subclassing applied.


Your program crashes on Win2k currently (checked on Win 2k Server SP4 Rollup 2). I added aliases #410/412/413, and it works fine now. I didn't dig deeply to know how and where your subclassing is initiated.
But I know that aliases solved problem for me.

----------


## Krool

> Your program crashes on Win2k currently (checked on Win 2k Server SP4 Rollup 2). I added aliases #410/412/413, and it works fine now. I didn't dig deeply to know how and where your subclassing is initiated.
> But I know that aliases solved problem for me.


In my VM for W2K it does not crash.
Can you remove the aliases again and and comment following out: (green marked)


```
Public Sub SetupVisualStyles(ByVal Form As VB.Form)
If GetComCtlVersion() >= 6 Then SendMessage Form.hWnd, WM_CHANGEUISTATE, MakeDWord(UIS_CLEAR, UISF_HIDEFOCUS Or UISF_HIDEACCEL), ByVal 0&
If EnabledVisualStyles() = False Then Exit Sub
Dim CurrControl As Control
For Each CurrControl In Form.Controls
    Select Case TypeName(CurrControl)
        Case "Frame"
            SetWindowSubclass CurrControl.hWnd, AddressOf RedirectFrame, ObjPtr(CurrControl), 0
        Case "CommandButton", "CommandButtonW", "CheckBox", "CheckBoxW", "OptionButton", "OptionButtonW"
            If CurrControl.Style = vbButtonGraphical Then
                If CurrControl.Enabled = True Then SetProp CurrControl.hWnd, StrPtr("Enabled"), 1
                SetWindowSubclass CurrControl.hWnd, AddressOf RedirectButton, ObjPtr(CurrControl), ObjPtr(CurrControl)
            End If
    End Select
Next CurrControl
End Sub
```

Does it still crash? And what does GetComCtlVersion() returns in your W2K?

----------


## Dragokas

Sorry, Krool, I don't feel well and my answers took a long time.

I think problem is more complicated. Here what I have:

I have 2 states now of VMWare:

1) Fresh install Rollup 2:
Compiled exe crashes.

2) Fresh install Rollup 2 + VB6 IDE installed:
Compiled exe is NOT crashes.
In IDE - crashes.

There was also error on line:


```
Err.Raise Number:=91, Description:="To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher."
```

but I commented it. And I sure you specificially created it.

Anyway, do you think problem with compiled EXE arises due to some missing dll in OS?
I'll try to get crash dump.

---
BTW, about subclassing, please forget what I wrote, I confused the source of the problem.

----------


## Krool

> Sorry, Krool, I don't feel well and my answers took a long time.
> 
> I think problem is more complicated. Here what I have:
> 
> I have 2 states now of VMWare:
> 
> 1) Fresh install Rollup 2:
> Compiled exe crashes.
> 
> ...


Your issue is solved when you do: (see Notes in first Post)
_In order to trap error raises via "On Error Goto ..." or "On Error Resume Next" it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error Trapping._

----------


## Dragokas

I decided to compare snapshots with ProcMon.

I found that after adding such reg fix:


```
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731}]
@="VBPropertyBag"

[HKEY_CLASSES_ROOT\CLSID\{D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731}\InProcServer32]
@="C:\\WINNT\\system32\\MSVBVM60.DLL"
"ThreadingModel"="Apartment"
```

ComCtlsDemo.exe is no longer crashes on fresh Win 2k without VB6 IDE installed.

Is it can be fixed somehow?

----------


## Krool

Update released.

Improvement in the CommonDialog.cls. However, the improvement is only meaningful for the ActiveX Control version.
The owner window of an dialog box was determined as following:


```
If Not Screen.ActiveForm Is Nothing Then
    .hWndOwner = Screen.ActiveForm.hWnd
Else
    .hWndOwner = GetActiveWindow()
End If
```

But 'Screen' will certainly not be meaningful from within the ActiveX Control. It will only be properly in the Std-EXE Version.
Now in order to work in both worlds the 'Screen' object needs to be eliminated. (like it was done with the 'Printer' object before)

Now the owner window for the dialog box is retrieved via API with an helper function in CommonDialog.cls:


```
.hWndOwner = GetOwnerWindow()

Private Function GetOwnerWindow() As Long
Dim hWnd As Long, hWndMDIClient As Long
hWnd = GetActiveWindow()
If hWnd <> 0 Then hWndMDIClient = FindWindowEx(hWnd, 0, StrPtr("MDIClient"), 0)
If hWndMDIClient <> 0 Then
    Const WM_MDIGETACTIVE As Long = &H229
    GetOwnerWindow = SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, ByVal 0&)
Else
    GetOwnerWindow = hWnd
End If
End Function
```




> The toolbar flickers in it's whole size when I set another image for a single button.
> It also flickers when I set the same image that was already set.


This was fixed by changing 'ClipControls' to True in the UserControl of the ToolBar.




> Is it can be fixed somehow?


No, I have no influence about missing registration key of "VBPropertyBag" on W2K.

----------


## Karl77

Label CCVerticalAlignmentCenter vs. TextBoxW

I discovered this option recently and thought 'nice, now it's easy to align a label to a textbox'.
But now I see it's not perfect.
The label's text is not vertically centered correct.
It is 1 pixel too low.



(the red cross is 1 pixel)

----------


## Dragokas

> No, I have no influence about missing registration key of "VBPropertyBag" on W2K.


It is not missed. It is by default.

----------


## Krool

Update released.

Major memory usage reduction in the ListView control. The text for the list and list sub items are now retrieved via callback. (LPSTR_TEXTCALLBACK)
Before this update the text for a list item (or list sub item) was stored in a class and also in the API ListView.
Now the text strings are only stored once in the class.

The TreeView, for instance, works different. The text for the nodes are not stored in the class and only in the API TreeView.
So there is actually no need for a callback, so it remains now like it is.

Reason why in the ListView the texts are stored in a class is easy to explain by few examples: (why the texts must be persisted in the class)
- The ListItems and ListSubItems can be created before creating the ColumnHeaders.
- The ListSubItems can be created in any View. So it is possible to change the View later on.

And, by the way, the MS ListView works internally also via LPSTR_TEXTCALLBACK.

----------


## Krool

> Label CCVerticalAlignmentCenter vs. TextBoxW
> 
> I discovered this option recently and thought 'nice, now it's easy to align a label to a textbox'.
> But now I see it's not perfect.
> The label's text is not vertically centered correct.
> It is 1 pixel too low.
> 
> 
> 
> (the red cross is 1 pixel)


The TextBoxW vertical alignment is Top, that's why at some point there will be an offset.
But when I set the TextBoxW and LabelW Height to 255 the offset is 0.
When setting the Height to 315 the offset is 1 and will increase the more the Height is.
Again such thing is expected as the vertical alignment of the TextBoxW is Top.

----------


## chosk

Also the border on the TextBoxW pushes the text down and right slightly (probably 1 pixel). So if possible, make the LabelW's height smaller (instead of same as TextBoxW's) to account for the TextBoxW border for better alignment.

----------


## Karl77

> Also the border on the TextBoxW pushes the text down and right slightly (probably 1 pixel). So if possible, make the LabelW's height smaller (instead of same as TextBoxW's) to account for the TextBoxW border for better alignment.


I don't like the idea so very much.
The good thing with the label's vertical centering is to not have to think about this...

EDIT:
Last paragraph removed, that was nonsense.

----------


## Karl77

Textbox problem

In my program I have a routine that selects all text in a textbox when it gets the focus (optional).
This doesn't work with TextBoxW so very well.



```
Private Sub TextBoxW1_GotFocus()

With TextBoxW1
.SelStart = 0
.SelLength = 999
End With

End Sub
```

The effect is, that the text gets selected from the start to the clicked point.

The intrinsic textbox doesn't show this behavior.
The text gets completely selected as intended.

----------


## Krool

> Textbox problem
> 
> In my program I have a routine that selects all text in a textbox when it gets the focus (optional).
> This doesn't work with TextBoxW so very well.
> 
> 
> 
> ```
> Private Sub TextBoxW1_GotFocus()
> ...


I did a test with an intrinsic VB TextBox and the TextBoxW:


```
Private Sub Text1_GotFocus()
With Text1
.SelStart = 0
.SelLength = 999
End With
End Sub

Private Sub TextBoxW2_GotFocus()
With TextBoxW2
.SelStart = 0
.SelLength = 999
End With
End Sub
```

Both do select the whole text at GotFocus but the mouse click changes the length of selection to actual clicked point.
So in my point behavior is exactly the same.

EDIT:
Proper implementation of AutoSelect by OnFocus would be as following:


```
Private Sub TextBoxW2_GotFocus()
If GetMouseStateFromMsg() = 0 Then
    With TextBoxW2
    .SelStart = 0
    .SelLength = Len(.Text)
    .Tag = "Focused"
    End With
End If
End Sub

Private Sub TextBoxW2_LostFocus()
TextBoxW2.Tag = vbNullString
End Sub

Private Sub TextBoxW2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
With TextBoxW2
If .SelLength = 0 And .Tag = vbNullString Then
    .Tag = "Focused"
    .SelStart = 0
    .SelLength = Len(.Text)
End If
End With
End Sub
```

EDIT2:
I could include an "AutoSelectOnFocus" property which would take care of this internally.

----------


## DEXWERX

i've got SP6, and can confirm the standard common controls textbox has this behavior.




> EDIT2:
> I could include an "AutoSelectOnFocus" property which would take care of this internally.


That would be a nice addition from the MS Access Textbox.

----------


## Karl77

The intrinsic works different from my view and experience.
It is forgiving regarding the mouseclick.




> I could include an "AutoSelectOnFocus" property which would take care of this internally.


Highly appreciated.
I need the tag property for other things.
Thank you very much.

EDIT:
I'm not sure if "AutoSelectOnFocus" is enough.
This would cover only the case when all shall be selected.

There are other behaviors which require different handling.
All with GotFocus by mouse click into the textbox.
A: Move the cursor to the end
B: Select all and move cursor to the end
C: Select all and move cursor to the start
D: Do nothing, just leave the cursor where it was set by click
As said, no problem with the intrinsic textbox.

If all this should happen in the textbox control, I would need "OnFocusSelectMode".

Wouldn't it be easier to swallow the mouseclick 1x?

EDIT2:
It seems to be a completely different problem.
See from #1758 on.

----------


## Krool

> The intrinsic works different from my view and experience.
> It is forgiving regarding the mouseclick.


Can you please provide a Demo showing the different behaviors?

----------


## Eduardo-

> Can you please provide a Demo showing the different behaviors?


In the standard textbox, if the click is short (normal click), the selection that was made in the GotFocus event is preserved, but if the mouse button is hold pressed down a bit more time (longer click), in that case the end of selection changes to the clicking point.

(it is my conclussion after a test)

----------


## Karl77

> Can you please provide a Demo showing the different behaviors?


Good you asked.
In a first attempt, I couldn't find any difference either.
And then I found out why.

See the attached project.
It is made with intrinsic controls only.
Try the different options and see them working as expected.

And then place a TextBoxW1 somewhere.
Don't add any code to it.
See how the formerly working selection in the intrinsic textbox doesn't work anymore.

Interesting effect.
Textbox problem.zip.docx

----------


## Krool

> Good you asked.
> In a first attempt, I couldn't find any difference either.
> And then I found out why.
> 
> See the attached project.
> It is made with intrinsic controls only.
> Try the different options and see them working as expected.
> 
> And then place a TextBoxW1 somewhere.
> ...


Yes, interesting. But it is *not* my TextBoxW which is causing this.
You can put any blank UserControl with 'CanGetFocus' to True on the Form.
The issue also only happens when you click on the VB.TextBox from an VB.UserControl. When you click from the VB.CommandButton to the VB.TextBox you have your expected behavior.

EDIT: Again it is better behavior to select all in GotFocus by tab key and in MouseUp when clicking. In MouseUp also only all text will be selected if SelLength is 0. Thus the user is still free to select partially text without overriding. (See my example above)

----------


## Eduardo-

> Yes, interesting. But it is *not* my TextBoxW which is causing this.
> You can put any blank UserControl with 'CanGetFocus' to True on the Form.
> The issue also only happens when you click on the VB.TextBox from an VB.UserControl. When you click from the VB.CommandButton to the VB.TextBox you have your expected behavior.


That's not what happens to me.

----------


## Karl77

> That's not what happens to me.


Eduardo, Krool is right.
In here, it also happens with your example.
Not always.

Krool's suggestion to do the selection on MouseUp helps, kind of.

As we must be able to set the focus by Tab key, we need the GotFocus event.
Works good.
But when we set the focus by mouse, the GotFocus kicks in, and does something which is not ok.
No problem, MouseUp cures it.

But it doesn't look clean, we can see the selection change from GotFocus to MouseUp.

I remember there is a possibility to check HOW a control got the focus.
http://www.devx.com/vb2themax/Tip/18274

EDIT:
Solved.
We just need to invoke the selection routine in both GotFocus and MouseUp.
See attached project.
Textbox problem SOLVED.zip.docx

Sorry Krool for the suspicion on your control.

----------


## Krool

> As we must be able to set the focus by Tab key, we need the GotFocus event.
> Works good.
> But when we set the focus by mouse, the GotFocus kicks in, and does something which is not ok.
> No problem, MouseUp cures it.
> 
> But it doesn't look clean, we can see the selection change from GotFocus to MouseUp


That is handled in my example...



```
Private Sub TextBoxW2_GotFocus()
If GetMouseStateFromMsg() = 0 Then
    With TextBoxW2
    .SelStart = 0
    .SelLength = Len(.Text)
    .Tag = "Focused"
    End With
End If
End Sub
```

----------


## Karl77

> That is handled in my example...
> 
> 
> 
> ```
> Private Sub TextBoxW2_GotFocus()
> If GetMouseStateFromMsg() = 0 Then
>     With TextBoxW2
>     .SelStart = 0
> ...


Oh well, I didn't see, my eyes only saw the Tag property.
Sorry again.

----------


## Eduardo-

> Eduardo, Krool is right.
> In here, it also happens with your example.


Ah, now I think that you mean that it happens to the standard VB TextBox when the focus comes from a Krool's TexBoxW.
I didn't test that.

I tested just with a CommandButton and an UserControl, and it *doesn't happen*.




> Not always.


Only when the click is long. May be VB checks that if the click doesn't pass the double click time, then it preserves the selection, always (at least here in my machine).

----------


## Karl77

Pager small error

I wondered why it is not possible to set the border of a Pager, or the button size.
To retrace, place a command button on the Pager form in the demo, and try



```
With Pager1
.BorderWidth = 5
.ButtonSize = 200
End With
```

Or use the properties panel.

Nothing happens, because



```
Public Property Let BorderWidth(ByVal Value As Single)
If Value < 0 Then
    If Ambient.UserMode = False Then
        MsgBox "Invalid property value", vbCritical + vbOKOnly
        Exit Property
    Else
        Err.Raise 380
    End If
End If
Dim IntValue As Integer, ErrValue As Long
On Error Resume Next
IntValue = CInt(UserControl.ScaleX(Value, vbContainerSize, vbPixels))
ErrValue = Err.Number
On Error GoTo 0
If IntValue >= 0 And ErrValue = 0 Then
    PropBorderWidth = IntValue
    If PagerHandle <> 0 Then
        SendMessage PagerHandle, PGM_SETBORDER, 0, ByVal PropBorderWidth
        Me.Refresh
    End If
Else
    If Ambient.UserMode = False Then
        MsgBox "Invalid property value", vbCritical + vbOKOnly
        Exit Property
    Else
        Err.Raise 380
    End If
End If
UserControl.PropertyChanged "BorderWidth"
End Property
```

Something is wrong with IntValue.
If I, just for a test, use Value, then something happens.

---

Perhaps there are some more 'instances' of this.





Karl

----------


## Krool

> Pager small error
> 
> I wondered why it is not possible to set the border of a Pager, or the button size.
> To retrace, place a command button on the Pager form in the demo, and try
> 
> 
> 
> ```
> With Pager1
> ...


That's normal. Since the ScaleMode of the Form is Twips a value of 5 results in 0 pixels.

----------


## Karl77

```
That's normal. Since the ScaleMode of the Form is Twips a value of 5 results in 0 pixels.
```

Again I was stupid.
Twips not Pixels.

----------


## Krool

Update released.

The reason why the StatusBar flickers so much because it flashes between erasing (WM_ERASEBKGND) and drawing (WM_PAINT).
As there was no in-built DoubleBuffer support for the StatusBar it needed to be done manually.
This was achieved by blocking WM_ERASEBKGND and do the erasing and drawing into a memory DC in WM_PAINT.

----------


## Krool

Also updated the ToolBar concerning the DoubleBuffer property.
The built-in TBSTYLE_EX_DOUBLEBUFFER style is not used anymore. It is now done "manually", likewise as in the StatusBar control now.
This has the advantage that the BackColor and Transparent property are now also working whe DoubleBuffer is set to True.
Also it can be used on comctl32 version 5.8x. (TBSTYLE_EX_DOUBLEBUFFER needed version 6.0 or higher)

----------


## Karl77

Spinbox question

Tried in the 2017-09-22 demo

I want do disallow the user input by keyboard, only the up/down buttons and the mousewheel shall work.
Is the Locked property the right one?
Seems to have no effect...
And what about HideSelection?
I see no difference when True/False.

I assume I'm too blind again, but can't avoid to ask.
What do I have to do to disable the textbox part for direct input?

Thanks,
Karl

----------


## Krool

> I want do disallow the user input by keyboard, only the up/down buttons and the mousewheel shall work.
> Is the Locked property the right one?
> Seems to have no effect...
> And what about HideSelection?
> I see no difference when True/False.


The Locked property is the right one. On my side it is working. (also the HideSelection property works as expected)

----------


## Karl77

> The Locked property is the right one. On my side it is working. (also the HideSelection property works as expected)


Yes, Locked locks the input.
But the cursor blinks, also the whole text is selected.
It looks like an input is possible.
It gets selected when using the up/down buttons.

Try with the attached example.

I get this:


Spin.zip

----------


## Krool

For those with HideSelection = False did you select the 0 before, because when nothing is selected there is no difference between HideSelection False or True.
The Locked property works as in the normal TextBox. It is your responsibility to give it a "Locked look" by for example setting BackColor to vbButtonFace.

----------


## Karl77

> For those with HideSelection = False did you select the 0 before, because when nothing is selected there is no difference between HideSelection False or True..


Ok, I didn't understand the meaning of HideSelection, now I do.




> The Locked property works as in the normal TextBox. It is your responsibility to give it a "Locked look" by for example setting BackColor to vbButtonFace.


Also understood.

In a normal TextBox I can HideCaret on GotFocus.


```
Call HideCaret(SpinBox3.hWndEdit)
```

Fine.
Now it doesn't look like as we can type in something.

When the SpinBox has the focus the border indicates that it has it.
When I now use the arrow up/down keys or the mousewheel, we can see the changing numbers.
But when I use the up/down buttons with the mouse, the text gets highlighted.
Not wanted.

I tried this, but it has no effect:


```
Private Sub SpinBox3_TextChange()

Debug.Print "SpinBox3_TextChange"

SpinBox3.SelStart = 0
SpinBox3.SelLength = 0

Debug.Print "len(SpinBox3.SelText)", Len(SpinBox3.SelText)

End Sub
```


Any idea what I can do to remove the highlight when using the buttons?

----------


## Krool

> When the SpinBox has the focus the border indicates that it has it.
> When I now use the arrow up/down keys or the mousewheel, we can see the changing numbers.
> But when I use the up/down buttons with the mouse, the text gets highlighted.
> Not wanted.


According to MSDN about UpDown controls with edit buddy control:
_"WM_LBUTTONUP: Completes the position change and releases the mouse capture if the up-down control has captured the mouse. If the buddy window is an edit control, it selects all the text in the edit control."_

So you could process the MouseUp event and undo the text highlighting.

But why you want an locked SpinBox control at all?
If you do not "trust" user input you can validate the user input right away after every input:


```
Private Sub SpinBox1_TextChange()
Static InProc As Boolean
If InProc = True Then Exit Sub
InProc = True
SpinBox1.ValidateText
InProc = False
' other stuff to do
End Sub
```

Or later on:


```
Private Sub SpinBox1_LostFocus()
SpinBox1.ValidateText
End Sub
```

----------


## Karl77

> But why you want an locked SpinBox control at all?


Because it will replace a now existing selfmade spinbox UC (>10 years old).
And I don't want to change feel.

I will end up in re-creating my old Spinbox UC.
It has a feature that is not there in VBCCR:
Fire the change event after a determined time only.
This means that when I scroll from 1 to 100, I don't get 100 change events.
But after let's say after 0.2 sec. from the last real change.

This 'Change delay' is quite useful when there is more time consuming code to execute.

----------


## Cube8

> Because it will replace a now existing selfmade spinbox UC (>10 years old).
> And I don't want to change feel.
> 
> I will end up in re-creating my old Spinbox UC.
> It has a feature that is not there in VBCCR:
> Fire the change event after a determined time only.
> This means that when I scroll from 1 to 100, I don't get 100 change events.
> But after let's say after 0.2 sec. from the last real change.
> 
> This 'Change delay' is quite useful when there is more time consuming code to execute.


You can implement this behavior by putting the time-consuming code in a timer. The timer should be initially disabled, interval=200.
Then, all you have to do is:


vb Code:
Private Sub SpinBox1_TextChange()Timer1.Enabled = False  'Reset timerTimer1.Enabled = TrueEnd Sub Private Sub Timer1_Timer()Timer1.Enabled = False 'Your code ...End Sub

----------


## Karl77

> You can implement this behavior by putting the time-consuming code in a timer. The timer should be initially disabled, interval=200.
> Then, all you have to do is:
> 
> 
> vb Code:
> Private Sub SpinBox1_TextChange()Timer1.Enabled = False  'Reset timerTimer1.Enabled = TrueEnd Sub Private Sub Timer1_Timer()Timer1.Enabled = False 'Your code ...End Sub


That's what I have in my old ugly UC.
I would like to have the timer in the UC, because if you have some SpinBoxes on a form, then you need as much timers or a more sophisticated approach.
Not so comfy and save.

EDIT:
Regarding the manual input into the SpinBox, I changed my mind.
While investigating the old UC, I saw there is the min/max range check already in the change event.
So no risk to trust the user, the value is always correct.

EDIT2:
This automatic 'stay in range' is not given in the VBCCR SpinBox.
Set Max to 10, and type in 123.
It can be that that is a correct behavior.
But correct doesn't always make sense.

EDIT3:
The VBCCR SpinBox is far better than mine, no question.
Mousewheel, arrow keys etc.
That's why I want to use it instead of my 'solution'.

----------


## Karl77

In the end, too easy...

I can pack the VBCCR Spinbox into an own UC and add the wanted functionality.

Still don't like that the text gets selected when using the up/down control.
Ok, I could set the SpinBox text again in it's Change event, but with a delay it doesn't look very well.
So I leave it as it is.

This is my solution now:
DelayedSpin.zip

EDIT:
Found a glitch in the VBCCR SpinBox.
If I paste a value using the context menu, the Change event doesn't fire.
To retrace:
Select the text in the SpinBox by mouse.
Right-click, and Paste.
As the Change event doesn't come, no chance to check for the Min/Max range.

----------


## Hosam AL Dein

I was using a previous version of the ocx . It was the one released about 10 days ago and everything was fine . I have a user control which has a listview .

I have just updated to the current version and here is what happens :

If the listview is populated and I end the project by "End" word or even by pressing the "break"command in IDE , VB crashes . This does not happen when the listview is not populated . 
*Note 1* I use no subclassing at all .

*Edit 1* : I have no code in form_unload or in usercontrol_terminate

*Edit 2 :* the previous version number is 
14-Sep-2017
- Revision update. (Version 1.4.51)

----------


## Krool

> EDIT:
> Found a glitch in the VBCCR SpinBox.
> If I paste a value using the context menu, the Change event doesn't fire.
> To retrace:
> Select the text in the SpinBox by mouse.
> Right-click, and Paste.
> As the Change event doesn't come, no chance to check for the Min/Max range.


It's not a bug. The Change event does only fire when the .Value property changes.

When I open your project and Paste via ContextMenu a value of 342 the Change event will be fired as the value has changed to 100.
In case you paste again 342 you get then "342342". However the value has not changed from 100. (equal to Max)
If you want to catch up everything you need to handle the TextChange event and do .ValidateText.




> I was using a previous version of the ocx . It was the one released about 10 days ago and everything was fine . I have a user control which has a listview .
> 
> I have just updated to the current version and here is what happens :
> 
> If the listview is populated and I end the project by "End" word or even by pressing the "break"command in IDE , VB crashes . This does not happen when the listview is not populated.


I cannot replicate with the current OCX. at least in a blank project. Can you provide a demo showing the problem?

----------


## DaveInCaz

> The reason why the StatusBar flickers so much because it flashes between erasing (WM_ERASEBKGND) and drawing (WM_PAINT).
> As there was no in-built DoubleBuffer support for the StatusBar it needed to be done manually.
> This was achieved by blocking WM_ERASEBKGND and do the erasing and drawing into a memory DC in WM_PAINT.


Thanks Krool, this was probably the cause of the issue I mentioned in a prior post . I'll try to setup my example again and confirm if the problem is gone.

----------


## Hosam AL Dein

I made a separate project then added the usercontrol with the latest ocx version and the problem does not occur . How can I replicate the bug which causes vb to crash ?

----------


## DEXWERX

> I made a separate project then added the usercontrol with the latest ocx version and the problem does not occur . How can I replicate the bug which causes vb to crash ?


If that didn't work the typical strategy is to start with a copy of your project, and continue stripping it down until you find your bug.

----------


## Hosam AL Dein

> If that didn't work the typical strategy is to start with a copy of your project, and continue stripping it down until you find your bug.


thanks dexwerx , I will give this a try

----------


## Hosam AL Dein

the frameW control forecolor is not working . Is this because I am using an earlier version or I am missing something ? . I am using version 14-Sep-2017 - Revision update. (Version 1.4.51)

----------


## Krool

> the frameW control forecolor is not working . Is this because I am using an earlier version or I am missing something ? . I am using version 14-Sep-2017 - Revision update. (Version 1.4.51)


The new FrameW is only in the Std-EXE version. It will be included in the next OCX version 1.5.

----------


## VbNetMatrix

> I made a separate project then added the usercontrol with the latest ocx version and the problem does not occur . How can I replicate the bug which causes vb to crash ?


btw, ending a project with "END" keyword should only be used for debugging purpose.
it's like telling Vb to "crash" the project, like the Stop button in the IDE.
all handle will stay open wich might under some circonstance crash the project like you experience.

Krool: does some of the component of the use Subclassing ?  could crash under some circonstance.

----------


## Karl77

RichTextBox

.SelFontName returns the string + a bunch of 00.
When using Richtx32.ocx it's correct.

Try the attached.RTF-VBCCR-2017-09-28.zip

----------


## Krool

> RichTextBox
> 
> .SelFontName returns the string + a bunch of 00.
> When using Richtx32.ocx it's correct.


Done. Thanks
OCX + Std-EXE got updated.




> Krool: does some of the component of the use Subclassing ?  could crash under some circonstance.


What do you mean? If you mean the ComCtls then yes, they make heavy use of subclassing. Also VTable wise subclassing.
The Std-EXE version will never be "End" secure as even when the subclassing could be done via ASM the VTable subclassing will still crash.
So I stick to non-ASM subclassing (as it makes no sense) and just catch the "Stop" button via ComCtlsInitIDEStopProtection.
However, the OCX should be certainly crash-free, even by "End".

----------


## Karl77

Toolbar question

I use the EXE version, but it is exactly the same with the OCX.

I found that my way of populating a toolbar takes quite long.
39 buttons/placeholders take 250msec.
Also while a toolbar gets filled, the whole screen flickers.
This happens when the containing form gets loaded, at this time it is not visible.
Don't know if the toolbar itself flickers.
I'm unhappy with the _screen_ flicker and the long processing time.

I already tried to set Visible and Enabled, but it has no effect on the loading times and still flickers.
Is there a built-in method to get that much faster, and also to avoid the screen flicker?



```
tc = GetTickCount

With MF.tbr_Main

    .AllowCustomize = False
    .BackColor = ToolbarBackColor
    .Buttons.Clear
    Set .ImageList = IL 'the ImageList is a VBBCR ImageList
    .Divider = False
    .ShowTips = True
    .DoubleBuffer = False
    .Transparent = Not True
    .MinButtonWidth = 0
    .MaxButtonWidth = 0
    .TextAlignment = TbrTextAlignBottom

    Set B = .Buttons.Add(, "new", , TbrButtonStyleDefault, "new")
    B.ToolTipText = "New"

    Set B = .Buttons.Add(, , , TbrButtonStyleSeparator)

    'etc.

    .GetIdealSize WS, HS
    .Width = WS
    .Height = HS

    Set B = Nothing

End With

ms = CStr(GetTickCount - tc) & " msec."
m = m & "Time to populate: " & vbCrLf & ms & vbCrLf

'this comes after all toolbars are ready
Debug.Print m
```

Karl

----------


## Krool

Make .DoubleBuffer = True instead of False to avoid flicker.

----------


## Karl77

> Make .DoubleBuffer = True instead of False to avoid flicker.


I tried before.
No effect on the *screen* flicker.
It is a desktop flicker, not the toolbar itself.

I can clearly see in my app the flicker comes from populating the toolbars.
I have 11 toolbars, and the flicker occurs 11x.
Nothing else is done when it happens.

Unfortunately, and 'of course', in a small demo app there is no desktop flicker.

But the long time to populate.
The CC5 toolbar is ready in no time.
Hmm.

Still need an idea.

----------


## gwboolean

What is the possibility of getting a multicolumn Combobox in the queue?  Or is there one already there?

----------


## Karl77

> Still need an idea.


Found out how to avoid the screen flicker.
When I comment out this:



```
.TextAlignment = TbrTextAlignBottom
```

then no flicker occurs.

EDIT:
Also the performance is FAR better, 78 instead of 250msec.
Of course without the TextAlignment property, the toolbars are not as intended.

EDIT2:
The flicker is also there when I set TextAlignment *after* populating the buttons.

----------


## Krool

Update released.

The performance of the ToolBar has been increased.
This was achieved by internally doing at some points (if applicable) a invalidation instead of a refresh.




> Found out how to avoid the screen flicker.
> When I comment out this:
> 
> 
> 
> ```
> .TextAlignment = TbrTextAlignBottom
> ```
> 
> then no flicker occurs.


Changing .TextAlignment will cause re-creating of the control. During the re-creation LockWindowUpdate is used:



```
Private Sub ReCreateToolBar()
Dim Locked As Boolean
With Me
Locked = CBool(LockWindowUpdate(UserControl.hWnd) <> 0)
[...]
If Locked = True Then LockWindowUpdate 0
.Refresh
End With
```

Maybe LockWindowUpdate does cause a screen flicker in your particular app, just a guess.

Solution could be to set the .TextAlignment already at design-time to the wanted value.




> What is the possibility of getting a multicolumn Combobox in the queue?  Or is there one already there?


You mean something like this ?

----------


## Elroy

Hi Krool,

That's a nifty little C# project you've linked to in the prior post.  Too bad it's not VB6. 

It looks like they've taken a standard ComboBox and attached a ListView to it for the dropdown.  With that understanding, this seems like it'd be a fairly straightforward project for a custom User Control (possibly using your controls to start with).  It's also somewhat nifty that the dropdown can go outside of the main form (which is also true of a standard ComboBox).  It may take a bit of doing to work that out, but not that big a deal.  As stated in a recent thread, I'd just use a second form to do that.

Take Care,
Elroy

----------


## Karl77

> During the re-creation LockWindowUpdate is used:


From what I understand, MS says WM_SETREDRAW should be used instead.
https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
Why did you decide for LockWindowUpdate?
Just curious.

----------


## Krool

> From what I understand, MS says WM_SETREDRAW should be used instead.
> https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
> Why did you decide for LockWindowUpdate?
> Just curious.


Refer to http://www.vbforums.com/showthread.p...=1#post5108773 for reason and explanation.

----------


## lrd_VB6

Hello,

Sorry for my English, (google translated!)

Me too, I noticed this effect with "LockWindowUpdate (0)" :Frown: . The whole screen is refreshed, causing the flicker.
I prefer the "ValidateRect / InvalidateRect" method and generate a PAINT when necessary. Or make a DoEvents (by managing the reantrance)..
With this method, I do not have the blinking of the screen.

----------


## Karl77

> Update released.
> The performance of the ToolBar has been increased.
> This was achieved by internally doing at some points (if applicable) a invalidation instead of a refresh.


Very good, works well, thanks.




> Changing .TextAlignment will cause re-creating of the control. During the re-creation LockWindowUpdate is used:





> Maybe LockWindowUpdate does cause a screen flicker in your particular app, just a guess.


It does.
I don't use LockWindowUpdate in the app, which could be the cause.
Also I don't know of other controls that do, at least I can't find because they are compiled (CC5).




> Refer to http://www.vbforums.com/showthread.p...=1#post5108773 for reason and explanation.


Understood.
This improvement will work for sure if VBCCR is alone in the world.




> Solution could be to set the .TextAlignment already at design-time to the wanted value.


This solution works very ok.
Changing .TextAlignment is very unlikely.
Flickering is solved so far.

----------


## Krool

> Understood.
> This improvement will work for sure if VBCCR is alone in the world.


Also see http://fgaillard.com/2011/02/the-unf...-wm_setredraw/

I won't switch back to WM_SETREDRAW.  :Smilie:

----------


## Karl77

> Also see http://fgaillard.com/2011/02/the-unf...-wm_setredraw/


Very informative.
The desktop flicker occurs when the handle is 0, right?

My initial problem is solved anyway.
But it is interesting why the flicker comes up in your Recreate.




> I won't switch back to WM_SETREDRAW.


Why should you?

----------


## Karl77

> The performance of the ToolBar has been increased.
> This was achieved by internally doing at some points (if applicable) a invalidation instead of a refresh.


I forgot to report the advantage.
Before: 250 msec. and more
Now: 16 msec., and less

----------


## Mith

VBCCR14.OCX v1.4.0.50
Control: ListView in Report mode

hi krool,

i drag and dropped a folder with unicode characters in the name from the windows explorer on the list view in report mode but the event "OLEDragDrop" just returns the folder path in ANSI and the unicode characters are replaced with char "?".

Is this something you can fix?

----------


## Mith

VBCCR14.OCX v1.4.0.50
Control: ListView in Report mode

Hi Krool,

i use the following code with a list view in report mode but the content of the list view doesnt get mirrored as expected:

lvwFF.RightToLeft = True
lvwFF.RightToLeftLayout = True

i tried that code with win7x64 and the display language arabic.

Any ideas why this is not working?

----------


## Krool

> VBCCR14.OCX v1.4.0.50
> Control: ListView in Report mode
> 
> Hi Krool,
> 
> i use the following code with a list view in report mode but the content of the list view doesnt get mirrored as expected:
> 
> lvwFF.RightToLeft = True
> lvwFF.RightToLeftLayout = True
> ...


How is .RightToLeftMode set?

----------


## Mith

> How is .RightToLeftMode set?


.RightToLeftMode = CCRightToLeftModeVBAME

i didnt set/changed this option. its the standard value.

ok, i could solve the problem after changing the value to:

.RightToLeftMode =CCRightToLeftModeNoControl



thx for the hint!

----------


## Krool

Update released.

This time the CoolBar control got my attention to make the control better.

First bugfix is that changing the VerticalGripper property on a vertical orientation CoolBar control was cumbersome.
The solution was to reset all header size dimensions to -1, thus the control has to recalculate them.

Second bugfix was that the HideCaption property of a Band was never written to the property bag.. easy fix to include in WriteProperties.

The actual improvement (make the control better) is as following:

The ForeColor of a Band (whether derived via 'UseCoolBarColors' or directly) was not supported when visual styles are applied.
However, that improvement works only on Vista+ (minimum comctl32.dll 6.1) since DrawThemeTextEx is not supported in Windows XP.



But there is another glitch that is fixed also for Windows XP. (MS never fixed this since Windows XP)
However, that glitch does not appear when visual styles are *not* applied.

The glitch can be replicated in following scenario:
Orientation = 1 - Vertical
VerticalGripper = True
3 Bands with initial settings except MinHeight of 1st Band set to 800 and input Caption text of "asd asd yxcyxc".
Then at run-time drag the band from left to right.

Before:


After:


As can be seen the text "asd asd yxcyxc" is measured by MS always on top-left and not the actual band coordinates.

These enhancements  can be switched off by the conditional compilation constant 'ImplementThemedReBarFix'.

----------


## Mith

> VBCCR14.OCX v1.4.0.50
> Control: ListView in Report mode
> 
> hi krool,
> 
> i drag and dropped a folder with unicode characters in the name from the windows explorer on the list view in report mode but the event "OLEDragDrop" just returns the folder path in ANSI and the unicode characters are replaced with char "?".
> 
> Is this something you can fix?


i used this code:



```
Private Sub lvwTest_OLEDragDrop(data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, y As Single)

Dim I As Long

If data.GetFormat(vbCFFiles) Then

   For I = 1 To data.Files.Count
            
      ' data.Files.Item(I) is ANSI and contains no unicode characters
      
   Next I

End If

End Sub
```

----------


## Krool

> i used this code:
> 
> 
> 
> ```
> Private Sub lvwTest_OLEDragDrop(data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, y As Single)
> 
> Dim I As Long
> 
> ...


http://cyberactivex.com/UnicodeTutor...gDrop_or_Paste

----------


## Mith

> http://cyberactivex.com/UnicodeTutor...gDrop_or_Paste


How about we implement this inside VBCCR14.OCX to support unicode at the OLEDragDrop-event for all controls?

----------


## Karl77

SUBCLASSING ADVICE 

Up to now I use SSUBTMR6.DLL for subclassing.
From now on, I want to use the same technique that Krool uses in his controls.

I'm stuck.
Implements ISubclass creates the ISubclass_Message function, and I could do what I want from there.
But I don't know how to bring messages into the game.
In SSUBTMR6.DLL I simply had to attach/detach messages, which I could process in ISubclass_WindowProc.

How does it work with Krool's subclassing?
A very basic example would help me out.

Thank you.

Edit:
I try this in the main form of the example (post #1).

----------


## DEXWERX

> SUBCLASSING ADVICE 
> 
> Up to now I use SSUBTMR6.DLL for subclassing.
> From now on, I want to use the same technique that Krool uses in his controls.
> 
> I'm stuck.
> Implements ISubclass creates the ISubclass_Message function, and I could do what I want from there.
> But I don't know how to bring messages into the game.
> In SSUBTMR6.DLL I simply had to attach/detach messages, which I could process in ISubclass_WindowProc.
> ...


Krool's method (common controls subclassing) does not filter messages. unless intercepted, you get them all.

also you gotta make sure you forward to ComCtlsDefaultProc (DefSubclassProc) in your ISubclass_Message


```
Option Explicit

Implements ISubclass

Private Sub Form_Load()
    ComCtlsSetSubclass hWnd, Me, 0
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ComCtlsRemoveSubclass hWnd
End Sub

Private Function ISubclass_Message(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal dwRefData As Long) As Long
    Select Case wMsg
        Case WM_DESTROY
    End Select
    ISubclass_Message = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
End Function
```

----------


## Karl77

> Krool's method (common controls subclassing) does not filter messages. unless intercepted, you get them all.
> 
> also you gotta make sure you forward to ComCtlsDefaultProc (DefSubclassProc) in your ISubclass_Message
> 
> 
> ```
> Option Explicit
> 
> Implements ISubclass
> ...


Thank you DEXWERX.
That was very helpful.

----------


## Karl77

PAGER PROBLEMS

See attached project.
Pager.zip

There are 3 Pagers.

Pager1 (red) is vertical.
Buddycontrol is Picture1, set at design time.

Pager2 (blue) is horizontal.
Buddycontrol is Picture2, set at design time.

Pager3 (lila) is horizontal.
Buddycontrol is Toolbar1, set at design time.

a)
When I start, only Pager3 catches the Buddy correct.
To assign the Buddies in Form:Load doesn't help.
When the Form is loaded, the CommandButton works to do it.

b)
Now let's resize the form manually.
Watch the Pager Buttons.
The Pager shows it's Button wrong.
It doesn't refer to the contained window size.
Also when we resize back and forth, this Button shows up at different window sizes.


---

With a toolbar as the contained window, it works ok.

Do I do something wrong, or is a PictureBox not suitable for a Pager?

Thanks
Karl

----------


## Mith

VBCCR14.OCX v1.4.0.56
Control: ListView in Report mode

Does anyone know how to center the icons at the column header and the subitems?

----------


## chosk

```
    ListView1.ColumnHeaders.Add , , "Name", 2000, LvwColumnHeaderAlignmentLeft
    ListView1.ColumnHeaders.Add , , "Symbol", 1200, LvwColumnHeaderAlignmentCenter
    ListView1.ColumnHeaders.Add , , "Anything", 1200, LvwColumnHeaderAlignmentRight
```

or 



```
    ListView1.ColumnHeaders(2).Alignment = LvwColumnHeaderAlignmentCenter
```

----------


## ErpEg2015

is there a tool ,can be used to upgrade or migrate VB common Controls sp6 to CCRP v 1.4 ???
had any one ade or used a tool like this , speciall for ToolBar and ImageList ... ?? 
if yes please guide me or provie me a link to such tool

----------


## Krool

> PAGER PROBLEMS
> 
> There are 3 Pagers.
> 
> Pager1 (red) is vertical.
> Buddycontrol is Picture1, set at design time.
> 
> Pager2 (blue) is horizontal.
> Buddycontrol is Picture2, set at design time.
> ...


There is indeed a specialty with the PictureBox control.
It seems that the PictureBox will be re-sized by the Pager control. Also the issue with not able to set at design-time or at Form_Load is strange.
For example setting a FrameW control (pure VB.UserControl only) works without issues.

However, with following workaround you get the PictureBox behavior also correct:



```
Private Sub Form_Load()
' Preserve dimensions as the PictureBox will be re-sized by Pager control due to unknown reasons..
H1 = Picture1.Height + (Pager1.BorderWidth * 2)
W1 = Picture2.Width + (Pager2.BorderWidth * 2)

End Sub
```

Don't let the Pager control calculate the sizes automatically, adjust to preserved dimensions accordingly.


```
Private Sub Pager1_CalcSize(Width As Single, Height As Single)
Height = H1
End Sub

Private Sub Pager2_CalcSize(Width As Single, Height As Single)
Width = W1
End Sub
```

----------


## Karl77

> There is indeed a specialty with the PictureBox control.
> It seems that the PictureBox will be re-sized by the Pager control. Also the issue with not able to set at design-time or at Form_Load is strange.
> For example setting a FrameW control (pure VB.UserControl only) works without issues.


I wondered why my PictureBox size changes magically as well.
Of course I investigated my code first...

Ok, this workaround will work.
In my case the PictureBox size is quite dynamic, and I need to set and get the size often.
This workaround is too cumbersome for me.

I will use FrameW with BorderStyle = 0.
(Just found out that 0 doesn't draw frame and caption).

Solved so far, thank you.

----------


## Mith

> ```
>     ListView1.ColumnHeaders.Add , , "Name", 2000, LvwColumnHeaderAlignmentLeft
>     ListView1.ColumnHeaders.Add , , "Symbol", 1200, LvwColumnHeaderAlignmentCenter
>     ListView1.ColumnHeaders.Add , , "Anything", 1200, LvwColumnHeaderAlignmentRight
> ```
> 
> or 
> 
> 
> ...


I tried this code but is doesnt center the icons at the columnheader and the subitem.

Columnheader:

Adding one space char at the text property of the columnheader fixed the problem and the columnheader icon gets centered with the text (" ").

Subitem:

I also added a space char to the text property of the subitem but the icon of the subitems is still left-aligned...



Maybe krool can check if this is a bug inside his code or a MS-related problem...

----------


## Mith

hi krool,

i loaded two different files with unicode text into the RichTextBox and the font always was changed automatically at a specific line.

Here at the 3. line:


Download: folders2.txt

and here at the 7. line:


Download: log 2.txt



```
rtfTest.LoadFile sFile$, RtfLoadSaveFormatUnicodeText
```

After loading the unicode files i had set the font again but it doesnt changed the font display at the RichTextBox...any hints whats going here?

----------


## DEXWERX

the control automatically jumps to font substitution as soon as you get to a character not available in the original font.
try using a font that has those characters already.

----------


## Jonney

ListBoxW etc. is lack of DataMember, DataSource, DataFeild,DataFormat properties... Can you implement those like VBFlexGrid?

----------


## Mith

> the control automatically jumps to font substitution as soon as you get to a character not available in the original font.
> try using a font that has those characters already.


Thank you very much for that hint!

Setting the font of the RichTextBox to "Arial Unicode MS" fixed the problem!

----------


## Krool

Update released.

Certain tweaks done in order to run better in the VB*A* environment.
In theory those tweaks only would effect the OCX version. However, to be in sync the Std-EXE version got tweaked as well.
There is no actual difference for VB6 IDE. It works like before.

But for new VBCCR14.OCX (rev 61 onwards) and for future VBCCR15.OCX the support for the VBA IDE is better.
Certainly newer Office version (e.g. 2010) is not so "sensitive" as older Office version (e.g. XP, 2002) for crashes.
However, all tests are done in Office 2002 to be reliable.

Also the "Cannot call friend function on object which is not an instance of defining class" error for the class collection objects is fixed. (VBA only)

In order to replace to new version of the OCX it is strongly recommended to *delete* certain cache files for MS Office:



```
C:\Users\<username>\AppData\Local\Temp\VBE\VBCCR14.exd
```



```
C:\Users\<username>\Application Data\Microsoft\Forms\VBCCR14.exd
```

Those cache files do only exist when previously loaded VBCCR14 into the toolbox on a UserForm.

Then replace the new VBCCR14.OCX in the system directory.

----------


## Krool

Update released.

Again some further tweaks to run better in the VBA environment.
There might be some pitfalls left. (e.g. StatusBar is known to still makes some troubles)

However, as described in previous post the cache files should be deleted (again) when attempting to replace the OCX.

----------


## Tech99

Tested newest version, ListView downward dragging bug still exists.

http://www.vbforums.com/showthread.p...=1#post5087103

Also with MultiSelect=True, dragging moves only item under mouse cursor.

and...


```
LvwListItem.ListSubItems.Add objSub.Index, objSub.Key, objSub.Text, objSub.ReportIcon, objSub.ToolTipText
```

Wrong number of parameters -> missing tooltip parameter.

https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx

----------


## Krool

> Tested newest version, ListView downward dragging bug still exists.
> 
> http://www.vbforums.com/showthread.p...=1#post5087103
> 
> Also with MultiSelect=True, dragging moves only item under mouse cursor.
> 
> and...
> 
> 
> ...


Update released.

Thanks for the hint of missing 'ToolTipText' parameter in .ListSubItems.Add in the ListView control.
Also good that this has been fixed now before the release of VBCCR15. (VBCCR14 can not be fixed in this regard due to binary compatibility)

Concerning the downward dragging. This might not be a bug, rather a feature when 'SnapToGrid' property is True.  :Smilie:

----------


## Hosam AL Dein

Hi all ,
I need to use the latest features for the ocx , but as Krool stated , he will release version 5 later this year or the next one . I tried to build a new activex control project and attach the controls and all common elements to it but it is difficult for me to set instances for class modules . I tried to open the STDexe project and change its type to activex control project after removing all forms and setting all user controls to public but did not work too . I think this is something related to conditional compiling . I need an activex control project holding the controls to be able to compile them to the ocx version or use the project itself in a group project without compliling . How can I do this ? and what I am missing here ? krool .

----------


## VbNetMatrix

I see no problem in what you're trying to achieve but make sure you changed the CLSID of the project AND the output filename of the OCX to avoid compatibility issue.  if someone make a commercial product out of krool ocx and on the same computer the client is using your product, one of the program (eitheir the commercial product or yours) won't load...

EDIT: in the first few post, KROOL made the exact same warning about this.

----------


## Hosam AL Dein

> I see no problem in what you're trying to achieve but make sure you changed the CLSID of the project AND the output filename of the OCX to avoid compatibility issue.  if someone make a commercial product out of krool ocx and on the same computer the client is using your product, one of the program (eitheir the commercial product or yours) won't load...
> 
> EDIT: in the first few post, KROOL made the exact same warning about this.


Thanks ,vbnet . Regardless of the point of compatibility , the program raises errors after changing its type to Activex control .

here is what I have done :

1- I opened the STDexe project
2- removed all forms
3- changed its type to activex control project
4- A message appears " the project (start mode) property has changed " 
5- set all user controls to public
6- set the "IsubClass" class module instances to global multiuse . 
7- removed the line which loads the main form from Sub_main()
8- tried to compile to ocx , then error is raised as the next picture implies


what is missed here?

----------


## Krool

Hosam, I will soon release VBCCR15.OCX for sure.
So I suggest you wait a little bit further.

The point is I want to ensure VBA works pretty good from the beginning of VBCCR15.
I am almost done. 2 updates already released for VBA improvement. But a 3 (final one) is needed.

So again, please little patience.  :Smilie:

----------


## Hosam AL Dein

> Hosam, I will soon release VBCCR15.OCX for sure.
> So I suggest you wait a little bit further.
> 
> The point is I want to ensure VBA works pretty good from the beginning of VBCCR15.
> I am almost done. 2 updates already released for VBA improvement. But a 3 (final one) is needed.
> 
> So again, please little patience.


No offense krool , take your time . I am not hustling you at all . I know it is a headache developing such GIANT project . But if you dont mind , I am still in need to solve this problem because I want to accomplish a base for my new project and I want to work on the level of user controls not the ocx or make it as a separate ocx maybe after some final customization . Also I want to solve it to add this problem to my too little knowledge . Thanks for your patience Krool.

----------


## VbNetMatrix

> Thanks ,vbnet . Regardless of the point of compatibility , the program raises errors after changing its type to Activex control .
> 
> here is what I have done :
> 
> 1- I opened the STDexe project
> 2- removed all forms
> 3- changed its type to activex control project
> 4- A message appears " the project (start mode) property has changed " 
> 5- set all user controls to public
> ...


the image you provide is blurry and I cannot read it to see the error msg.
it seem to do with the public enum wich cannot be passed at outside perogative (normal)

however, did you tried to compare your change with the existing (previous version) ocx project ?

----------


## Hosam AL Dein

> the image you provide is blurry and I cannot read it to see the error msg.
> it seem to do with the public enum wich cannot be passed at outside perogative (normal)
> 
> however, did you tried to compare your change with the existing (previous version) ocx project ?


I did not change anything in code . I think this is due to conditional compiling for enums variables  which varies from one project type to another .

If you or anyone here can make this and provide me with the proper steps I will be so grateful . I want to know how this is done to at least increase my knowledge .

----------


## Semke

> I did not change anything in code . I think this is due to conditional compiling for enums variables  which varies from one project type to another .
> 
> If you or anyone here can make this and provide me with the proper steps I will be so grateful . I want to know how this is done to at least increase my knowledge .


I did a little tinkering for that it looks like you need to remove some of the code in the *ComCtlsBase* module, and put it in the *ISubclass*  class module.
_krool has put this code I different locations in the ocx source code then in the exe, I am not sure why. Please enlighten us krool_
below is the code you should move, try it and report your results, so others can be helped



```
#If False Then
Private OLEDropModeNone, OLEDropModeManual
Private CCAppearanceFlat, CCAppearance3D
Private CCBorderStyleNone, CCBorderStyleSingle, CCBorderStyleThin, CCBorderStyleSunken, CCBorderStyleRaised
Private CCBackStyleTransparent, CCBackStyleOpaque
Private CCLeftRightAlignmentLeft, CCLeftRightAlignmentRight
Private CCVerticalAlignmentTop, CCVerticalAlignmentCenter, CCVerticalAlignmentBottom
Private CCIMEModeNoControl, CCIMEModeOn, CCIMEModeOff, CCIMEModeDisable, CCIMEModeHiragana, CCIMEModeKatakana, CCIMEModeKatakanaHalf, CCIMEModeAlphaFull, CCIMEModeAlpha, CCIMEModeHangulFull, CCIMEModeHangul
Private CCRightToLeftModeNoControl, CCRightToLeftModeVBAME, CCRightToLeftModeSystemLocale, CCRightToLeftModeUserLocale, CCRightToLeftModeOSLanguage
#End If
Public Enum OLEDropModeConstants
OLEDropModeNone = vbOLEDropNone
OLEDropModeManual = vbOLEDropManual
End Enum
Public Enum CCAppearanceConstants
CCAppearanceFlat = 0
CCAppearance3D = 1
End Enum
Public Enum CCBorderStyleConstants
CCBorderStyleNone = 0
CCBorderStyleSingle = 1
CCBorderStyleThin = 2
CCBorderStyleSunken = 3
CCBorderStyleRaised = 4
End Enum
Public Enum CCBackStyleConstants
CCBackStyleTransparent = 0
CCBackStyleOpaque = 1
End Enum
Public Enum CCLeftRightAlignmentConstants
CCLeftRightAlignmentLeft = 0
CCLeftRightAlignmentRight = 1
End Enum
Public Enum CCVerticalAlignmentConstants
CCVerticalAlignmentTop = 0
CCVerticalAlignmentCenter = 1
CCVerticalAlignmentBottom = 2
End Enum
Public Enum CCIMEModeConstants
CCIMEModeNoControl = 0
CCIMEModeOn = 1
CCIMEModeOff = 2
CCIMEModeDisable = 3
CCIMEModeHiragana = 4
CCIMEModeKatakana = 5
CCIMEModeKatakanaHalf = 6
CCIMEModeAlphaFull = 7
CCIMEModeAlpha = 8
CCIMEModeHangulFull = 9
CCIMEModeHangul = 10
End Enum
Public Enum CCRightToLeftModeConstants
CCRightToLeftModeNoControl = 0
CCRightToLeftModeVBAME = 1
CCRightToLeftModeSystemLocale = 2
CCRightToLeftModeUserLocale = 3
CCRightToLeftModeOSLanguage = 4
End Enum
```

----------


## Krool

In addition to what Semke stated please remove the WM_STYLECHANGED handler on those controls that have a WindowProcUserControlDesignMode function in it. (Recommended)

Also I put an IObjectSafety implementation on the controls. (Optional)

And also the controls in the Property Pages are replaced to support Unicode at design time. (Optional)

So in my case it is a little bit of work to migrate to OCX version. But of course you can skip the 2 last steps.
The 1. step however you should consider. (WM_STYLECHANGED)

And as side note I do also a little bit of cleanup in the OCX version. (e.g. VisualStyles.bas is reduced to what is necessary etc.)

----------


## Hosam AL Dein

Thanks semke , I followed what you provided and it worked . An essential step to add to the previous ones is that I changed the instances for all class modules to "GlobalMultiuse" . I will summarize the steps here 

*Steps for converting STDexe to Activex control project :
*

1- Open the STDexe project
2- Remove all forms
3- Change the project type to Activex control project
4- A message appears " the project (start mode) property has changed " 
5- Set all user controls to public
6- Set all class modules instances to GlobalMultiuse . 
7- Remove the line which loads the main form from Sub_main()
8-Remove this code from *ComCtlsBase* module, and put it in the *ISubclass* class module



```
#If False Then
Private OLEDropModeNone, OLEDropModeManual
Private CCAppearanceFlat, CCAppearance3D
Private CCBorderStyleNone, CCBorderStyleSingle, CCBorderStyleThin, CCBorderStyleSunken, CCBorderStyleRaised
Private CCBackStyleTransparent, CCBackStyleOpaque
Private CCLeftRightAlignmentLeft, CCLeftRightAlignmentRight
Private CCVerticalAlignmentTop, CCVerticalAlignmentCenter, CCVerticalAlignmentBottom
Private CCIMEModeNoControl, CCIMEModeOn, CCIMEModeOff, CCIMEModeDisable, CCIMEModeHiragana, CCIMEModeKatakana, CCIMEModeKatakanaHalf, CCIMEModeAlphaFull, CCIMEModeAlpha, CCIMEModeHangulFull, CCIMEModeHangul
Private CCRightToLeftModeNoControl, CCRightToLeftModeVBAME, CCRightToLeftModeSystemLocale, CCRightToLeftModeUserLocale, CCRightToLeftModeOSLanguage
#End If
Public Enum OLEDropModeConstants
OLEDropModeNone = vbOLEDropNone
OLEDropModeManual = vbOLEDropManual
End Enum
Public Enum CCAppearanceConstants
CCAppearanceFlat = 0
CCAppearance3D = 1
End Enum
Public Enum CCBorderStyleConstants
CCBorderStyleNone = 0
CCBorderStyleSingle = 1
CCBorderStyleThin = 2
CCBorderStyleSunken = 3
CCBorderStyleRaised = 4
End Enum
Public Enum CCBackStyleConstants
CCBackStyleTransparent = 0
CCBackStyleOpaque = 1
End Enum
Public Enum CCLeftRightAlignmentConstants
CCLeftRightAlignmentLeft = 0
CCLeftRightAlignmentRight = 1
End Enum
Public Enum CCVerticalAlignmentConstants
CCVerticalAlignmentTop = 0
CCVerticalAlignmentCenter = 1
CCVerticalAlignmentBottom = 2
End Enum
Public Enum CCIMEModeConstants
CCIMEModeNoControl = 0
CCIMEModeOn = 1
CCIMEModeOff = 2
CCIMEModeDisable = 3
CCIMEModeHiragana = 4
CCIMEModeKatakana = 5
CCIMEModeKatakanaHalf = 6
CCIMEModeAlphaFull = 7
CCIMEModeAlpha = 8
CCIMEModeHangulFull = 9
CCIMEModeHangul = 10
End Enum
Public Enum CCRightToLeftModeConstants
CCRightToLeftModeNoControl = 0
CCRightToLeftModeVBAME = 1
CCRightToLeftModeSystemLocale = 2
CCRightToLeftModeUserLocale = 3
CCRightToLeftModeOSLanguage = 4
End Enum
```

These steps are open for any modification and addition by anyone who finds them incomplete or missing some points to be added or mentioned

The previous steps are tested and the project works fine and I have not yet applied Krool`s steps . However , I am going to go on this advice and remove the exception until it is suitable time for krool to explain the reason for this step and the case which will raise a problem if these exceptions were not removed . Thanks all for help

----------


## Krool

> 6- Set all class modules instances to GlobalMultiuse.


Wrong. Put all classes to "PublicNotCreatable".
Except CommonDialog.cls. This shall be "MultiUse". (Not "GlobalMultiUse")
Also some classes should kept "Private" such as Enumeration.cls, VTableSubclass.cls etc.
So an advise to put everything on GlobalMultiUse is not so good.

For the other stuff in WindowProcUserControlDesignMode it is a safety to remove subclassing in IDE at DesignTime. In the OCX this is not needed. If it keeps there it can even produce glitches. You had once an issue with the CommandButtonW that it went blank on certain steps. This was one case of that.

Anyhow, you can proceed how you want..

----------


## Hosam AL Dein

> Wrong. Put all classes to "PublicNotCreatable".
> Except CommonDialog.cls. This shall be "MultiUse". (Not "GlobalMultiUse")
> Also some classes should kept "Private" such as Enumeration.cls, VTableSubclass.cls etc.
> So an advise to put everything on GlobalMultiUse is not so good.
> 
> For the other stuff in WindowProcUserControlDesignMode it is a safety to remove subclassing in IDE at DesignTime. In the OCX this is not needed. If it keeps there it can even produce glitches. You had once an issue with the CommandButtonW that it went blank on certain steps. This was one case of that.
> 
> Anyhow, you can proceed how you want..


thanks a lot krool for correction . Of course I will proceed in the way you provided . I will re-write these steps again until we come to the ideal way

----------


## Krool

OCX Version 1.5 now released.

----------


## vbLewis

> OCX Version 1.5 now released.


Thanks for the new release. Im using these controls in a new project. really appreciate your time and effort in these controls! 
Was wondering if there would be any chance of being able to add a color option for tool bar button caption text.
thanks again.

----------


## Krool

> Thanks for the new release. Im using these controls in a new project. really appreciate your time and effort in these controls! 
> Was wondering if there would be any chance of being able to add a color option for tool bar button caption text.
> thanks again.


You must have overlooked it. There is a ForeColor property available.


```
ToolBar1.Buttons(1).ForeColor
```

This can also be defined at design-time trough the property page.

----------


## vbLewis

ahh ok. yes i missed it, i was looking under the color tab and in the main toolbar properties. The fact that it is per button makes it even cooler! Thankyou!

Edit: I couldnt get any of the custom foreground colors to 'stick' from the property pages, only set from code, so far for toolbar button and status bar panels. is this by design?

----------


## Krool

Source code for both Std-EXE and ActiveX version has been put on GitHub. Link can be found on initial post.




> I couldnt get any of the custom foreground colors to 'stick' from the property pages, only set from code, so far for toolbar button and status bar panels. is this by design?


For me it works, so I cannot replicate your problem. What do you mean exactly? Please describe step-by-step.

----------


## vbLewis

Add toolbar control to form -> click on 'custom' to open custom property page dialog -> add toolbar button -> click on colored command button to change button foreground color -> select new color for button caption -> click OK -> color dialog closes and color on command button in property sheet stays the same as it was. same for font, cannot change size. 

are you calling 'propertychanged()'  when property is changed in in property sheet? it may be a storage bag permission problem on my end too.

when i use the normal toolbar properties tab in the IDE to change font, font size is changed and works ok. but of course it doesnt edit colors for a single button, only the entire toolbar. I can set color for individual buttons from code and works good that way.

----------


## Krool

> Add toolbar control to form -> click on 'custom' to open custom property page dialog -> add toolbar button -> click on colored command button to change button foreground color -> select new color for button caption -> click OK -> color dialog closes and color on command button in property sheet stays the same as it was. same for font, cannot change size. 
> 
> are you calling 'propertychanged()'  when property is changed in in property sheet? it may be a storage bag permission problem on my end too.
> 
> when i use the normal toolbar properties tab in the IDE to change font, font size is changed and works ok. but of course it doesnt edit colors for a single button, only the entire toolbar. I can set color for individual buttons from code and works good that way.


Update released. Please test again. Thanks

----------


## Karl77

New Pager Problem

Try with the attached.
Pager3.zip

The problem is, when I modify a Pager's buddy, then the buddy gets clipped.
It is not with a PictureBox (discussed before), but with a standard UC.

EDIT:
A PictureBox as the buddy works ok with the workaround described in #1820.
Now I use this approach instead of using a UC as the buddy.

----------


## MountainMan

Krool,

I was just working with you VBFlexGrid Demo system and now that you have an OCX version I thought I would make the same sample program using the OCX file. I decided to make the two forms with your VBCCRxx OCX files and I just noticed that you didn't include a PictureBox in your VBCCRxx controls. Was that intentional and if so, why? I assume I can use the ImageList control to achieve the same results and I am guessing that's why you didn't do one for VBCCRxx but I thought I would ask.

----------


## Krool

MountainMan,
PictureBox replacement is not needed and there are also better alternatives, e.g. AlphaImageControl.
ImageList was necessary to work together with the controls.

----------


## kagachiu

Want to report a problem
RichTextBox can't do anything to clear up, if SelProtected is being used or the document is already contain SelProtected Text
BTW, thank you for this wonderful control!

----------


## Karl77

TABSTRIP QUESTION

The TabClick events is fired immediately when the mouse button is down on the tab.
In other controls, like CommandButtonW, the click events is not fired until the mouse button is released over the control.

Any chance to improve this behavior for the TabStrip?

Karl

----------


## Karl77

SUBCLASSING QUESTION (again)

In post #1814 Dex told me how to use the subclassing provided by VBCCR.
This works quite well.

But when we use the OCX and not the EXE version, this can't be done.
ComCtlsSetSubclass/ComCtlsRemoveSubclass is not avaiable.

Krool, is it possible to use your subclassing along with the OCX version?
And if, how?

----------


## Krool

Update released.

The IDE (does not effect compiled exe) will not crash anymore when using VBCCRxx.OCX and VBFLXGRDxx.OCX in paralell. (Std-EXE version not concerned)

----------


## Hosam AL Dein

here is a video demonstration of my problem

part1
https://www.youtube.com/watch?v=yGxSBtCk7co

part2
https://www.youtube.com/watch?v=1IZPDRRCAsI

and sorry for awful accent

----------


## Karl77

Hosam, do you use the most recent version or the former version?
If you use the most recent version, can you try the same with yesterday`s version?
Or the other way around?

Do you get the same result when you use the OCX?

----------


## Hosam AL Dein

thanks karl , here is the test for the ocx 
https://youtu.be/sPcpaampZa4

----------


## Hosam AL Dein

here is a test with the most recent ocx and it is the same result
https://youtu.be/uooZxHBKV24

----------


## Karl77

Hosam
I think it will be good if you *upload the projects* in question here.
So that we and especially Krool can retrace the error.
Videos are not so very helpful in this case.

----------


## Hosam AL Dein

I think it  is not a problem of code karl . As in the videos , the same code runs successfully in a time and causes vb to crash in another time . Also , the STDexe project never run successfully with me . Once I open it , or just try to view the FrmMain , Vb crashes . This of course is not the case for any of the members here as almost no one reported this problem . So , I think it is not a matter of code . It might be something related to registry entries or binary conflict or something in VB6 IDE itself . This was the reason I uploaded these videos : to see what is wrong in my case . But I will upload the project also . It might be something common . Thanks karl .

*Edit 1 :* 
the project source code . Just put the database in the D:\ partition and add a reference to ado 2.5 library and of course VBCCR 1.5 OCX

test.zip.docx

----------


## Karl77

Hosam

Do you run the VB6 IDE with admin rights?
From the videos, I don't see the UAC dialog coming up.

I tried to test here with VBCCR15, but it seems I don't have the correct database tools installed.
Unfortunately, I can't run the project using the data connection.

When I comment out all the database related stuff, then the project runs well in the IDE.
And does never crash.

A remark:
It is good to use Option Explicit in your code, it can help a lot.

----------


## Hosam AL Dein

yes karl vb6 runs with admin rights .



and I used option explicit and same results came up

For the database , I use MS access 2010 . It is necessary to setup it and run the database code to exactly simulate the case I have

----------


## MMcC

Hi, would this work for 64-bit Word / Excel?
Do you have anything to replace OWC11, again for 64-bit Word?
Thanks

----------


## VbNetMatrix

> Hi, would this work for 64-bit Word / Excel?
> Do you have anything to replace OWC11, again for 64-bit Word?
> Thanks



I believe it would not.  Office x64 is not compatible with 32bit COM
beside for your information, Microsoft does recommand to NOT install x64 version of Office UNLESS:

"you are opening image or database of more then 2gb"
ref.:
https://support.office.com/en-us/art...e-6c6f49b8d261

People tend to think x64 version are better and faster.  This is absolutely not true with the exception of file OVER 2gb
wich very FEW people in the whole world use (news editors is a good example of such users)

I have a very large Database in access with history of more then 100 000 records and the database has a file of 3mb
The biggest I ever saw in Office was a 240mb file from a powerpoint for the end of school (prom) newspaper.  there were over 
thousand images in it.  we're far from the 2gb limit

----------


## Krool

> I believe it would not.  Office x64 is not compatible with 32bit COM
> beside for your information, Microsoft does recommand to NOT install x64 version of Office UNLESS:
> 
> "you are opening image or database of more then 2gb"
> ref.:
> https://support.office.com/en-us/art...e-6c6f49b8d261


The project is limited to 32 bit.

Even in Access 2013 format x64 the database limit is 2GB. So even no advantage on that..

And the 4GB memory limitation for 32 bit is not an argument. Every 32 bit process can have 4gb allocation. (Not in total allocation; per process allocation)
So who want to use more than 4gb of ram in an office instance?

My advise: go back to 32 bit office.

----------


## MMcC

> The project is limited to 32 bit.
> 
> Even in Access 2013 format x64 the database limit is 2GB. So even no advantage on that..
> 
> And the 4GB memory limitation for 32 bit is not an argument. Every 32 bit process can have 4gb allocation. (Not in total allocation; per process allocation)
> So who want to use more than 4gb of ram in an office instance?
> 
> My advise: go back to 32 bit office.


The application we're running in 32-bit is hitting the memory limit and so we're getting Out Of Memory errors. It's a very complex planning application with a big updateable data cube being presented in an embedded worksheet in Word. We've slimmed it down as much as we can but it's right up against the limit. Hence we are looking at the possibility of 64-bit which doesn't have the 4Gb memory limitation. 

Is there any way we can get multiple processes running from within the one VBA app?

----------


## Krool

> The application we're running in 32-bit is hitting the memory limit and so we're getting Out Of Memory errors. It's a very complex planning application with a big updateable data cube being presented in an embedded worksheet in Word. We've slimmed it down as much as we can but it's right up against the limit. Hence we are looking at the possibility of 64-bit which doesn't have the 4Gb memory limitation. 
> 
> Is there any way we can get multiple processes running from within the one VBA app?


I have made the experience that x64 office also do raise "out of memory". Reason could be some virtual memore pages and not related to physical memory at all.

----------


## MMcC

> I have made the experience that x64 office also do raise "out of memory". Reason could be some virtual memore pages and not related to physical memory at all.


So what approach would you recommend to avoid / reduce / manage the out of memory errors?

----------


## MountainMan

MMcC, it is fairly easy to get multiple apps running from one VBA application. VBA is inherently single-threaded but using shell you can start as many new process as you have memory for. In addition, you can communicate between the separate processes. For example, I have a file manager program that is written in Excel that has the option of doing the specified file operation(s) such as copy, move, rename or delete files and/or folders within the currently running instance of Excel or it can spawn a new instance of Excel and do them separate from the current instance. In fact, you can spawn as many of these as you want. I have also seen this technique used to do many web searches at one time. Yes there is some overhead by starting new instances of Excel, Access, Word, etc. but it is really not that much (maybe 20mb) in today's multiple gigabyte systems. It is a handy way of effectively multi-tasking from within VBA (same code works in VB6 too). I could upload some code to show you how to do this if you are interested.

----------


## Victor Bravo VI

> The application we're running in 32-bit is hitting the memory limit and so we're getting Out Of Memory errors.


Out Of Memory Does Not Refer to Physical Memory might offer some insight on why you're getting that error.

----------


## VbNetMatrix

> The application we're running in 32-bit is hitting the memory limit and so we're getting Out Of Memory errors. It's a very complex planning application with a big updateable data cube being presented in an embedded worksheet in Word. We've slimmed it down as much as we can but it's right up against the limit. Hence we are looking at the possibility of 64-bit which doesn't have the 4Gb memory limitation. 
> 
> Is there any way we can get multiple processes running from within the one VBA app?



if your program is using more then 4gb ram memory (in ANY scenario), it is most likely a memory leak issue.
in c# for example, lot of people are using COM component without using the garbage collector wich is MANDATORY when using COM component in Managed code.  More to that, while using COM, the simple rule that apply is "never use 2 dot" (meaning don't use this.property.property) because it will cause a memory leak while the .NET do this in memory:
TempObject= this.property
userobject = TempObject.property (equivalent to this.property.property )

the TempObject will reside in memory even if you use the GC collector and then you got memory leak.

you're talking about using worksheet in Word, (this is using COM component)  plz check your code for double dot and GC collector properly used.

Krool:  didn'T intended to hijack your thread with this answer, if you think it was innapropriate, just tell me I'll refrain myself in the futur.

----------


## Hosam AL Dein

Any suggestions for my question guys ?

----------


## Tech99

> Any suggestions for my question guys ?


Briefly watched your video. I think that it is not the grid component, but the ADO which causes the IDE crash. Solution is to properly close ADO connection and set the ADO object to nothing (by VB code) before closing application.

fex...


```
'in form QueryUnload routine
    DB.Close 'close db connection
    Set DB = Nothing
'or 
Set rs = Nothing
Set cmd.ActiveConnection = Nothing
Set cmd = Nothing
```

More information
https://docs.microsoft.com/en-us/sql...ose-method-ado
https://docs.microsoft.com/en-us/sql...ods-example-vb
http://www.vbforums.com/showthread.p...ado-connection

----------


## VbNetMatrix

double post for some server reason...

----------


## VbNetMatrix

> here is a video demonstration of my problem
> 
> part1
> https://www.youtube.com/watch?v=yGxSBtCk7co
> 
> part2
> https://www.youtube.com/watch?v=1IZPDRRCAsI
> 
> and sorry for awful accent


There is a few thing I have noticed but it is really simple Vb6 programming rules that are not applied.

one of the is your declaration with the NEW keyword.

in Vb6 you must NEVER declare a variable with a NEW keyword, this has been documentated at least a hundred time
it mess up the memory in many ways.

always prefers the method:

Dim YourObject as ...

Set YourObject = new ...

then, never forget to DESTROY the object when you are done with it.

Set YourObject = Nothing
(you're not doing it so you got a memory leak there that in time will crash the IDE while debugging)

same thing with the WITH keyword, it's better to avoid it when not necessary, I missed why you really need the first WITH.

aside from that, you didn't showed what reference object you are using for the RecordSet, there is many version of the MDAC and only the 2.8 and 6.1 (6.0) are stable for Win7+  if you're using anything different, it might as well be your problem
Microsoft recommend to use only the 6.0 for Win7+

if you could post a non working project, it would be easier for diagnose.  as for me, I didn't use that component for year because I created my own component based on 6.0

I doubt it has anything to do with Krool control.  did you tested your code with regular control ?

I also noticed the bug you got when you open Vb6, the only time I saw this bug was with a Custom made USB portable version for Vb6 and it contain a Trojan (virus)
I would fix your installation before attempting to search for gremlins.

----------


## Krool

> TABSTRIP QUESTION
> 
> The TabClick events is fired immediately when the mouse button is down on the tab.
> In other controls, like CommandButtonW, the click events is not fired until the mouse button is released over the control.
> 
> Any chance to improve this behavior for the TabStrip?


It seems that behavior is wanted by the TabStrip control. It's done by comctl32.dll. (TCN_SELCHANGE)
The only workaround would be to handle MouseUp event and perform a HitTest.

Edit: you certainly also need to handle TabBeforeClick and pass True to the 'Cancel' parameter. Thus it will not change selection prior your MouseUp workaround.

----------


## Hosam AL Dein

Thanks for precious information VBnetmatrix . I will give these points a try and post my the result here

----------


## Karl77

> It seems that behavior is wanted by the TabStrip control. It's done by comctl32.dll. (TCN_SELCHANGE)


Aha, I thought it was not intended.




> The only workaround would be to handle MouseUp event and perform a HitTest.


Ok, that's not much effort.




> Edit: you certainly also need to handle TabBeforeClick and pass True to the 'Cancel' parameter. Thus it will not change selection prior your MouseUp workaround.


And this makes trouble.
If I set Cancel to true, then I can't select a tab at all.
I could manage the Cancel value, but I think this is not a good approach.

See attached example.Tbs.zip

----------


## Krool

> And this makes trouble.
> If I set Cancel to true, then I can't select a tab at all.
> I could manage the Cancel value, but I think this is not a good approach.


When you select the Tab during MouseUp you Need to flag an private variable (form variable) so during that selection you do not set Cancel to True in the TabBeforeClick Event.
I think the event will also be fired when you Change the tab by code. So in that exception you need to by-pass it once.

----------


## Karl77

> When you select the Tab during MouseUp you Need to flag an private variable (form variable) so during that selection you do not set Cancel to True in the TabBeforeClick Event.
> I think the event will also be fired when you Change the tab by code. So in that exception you need to by-pass it once.


That what I meant by "I could manage the Cancel value, but I think this is not a good approach.".
It works in this special case of course.

When I make it like this, I must set the variable on every single .Selected call.
And reset it afterwards.
Ok, this can be made.

But for scrolling through the tabs by wheel, this approach fails.
Cancel is true, so scrolling doesn't work.
As there is no Scroll events, I can't do anything.

And it is not a solution to set the variable on MouseDown.
If no MouseUp happens, then I'm lost.
MouseEnter/Leave both don't fire, so no chance to reset (while this wouldn't be reliable in this case anyway).

Again see attached sample.
Tbs2.zip

Any better idea? Or I hint on what I'm overlooking?

EDIT:
I tried several apps to see how they react on MouseDown on a tab.
They all switch the tab immediately on MouseDown, and not on MouseUp.
So what we find in VBCCR is a correct behavior.

But I don't like it so much.
The Tab control seems to be the only control that doesn't behave like all other controls.

If the workarounds are too much effort, then I fear I have to live with the standard.

----------


## Krool

> MouseEnter/Leave both don't fire, so no chance to reset (while this wouldn't be reliable in this case anyway).


They fire only when the MouseTrack property is set to True.

----------


## Karl77

> They fire only when the MouseTrack property is set to True.


Thanks for the hint!

Anyway, I now decided to accept the immediate action on MouseDown.
It doesn't make sense to make non-standard solutions.

----------


## OldClock

Hello

There are no installation instructions and no clear download link.



> At design time (IDE) there is only one dependency. (OLEGuids.tlb)


That means I'm looking for a file called "OLEGuids.tlb", nothing more.

The first post states:



> List of revisions
> 21-Dec-2017
> - Improved the WM_MOUSEWHEEL handler for fine-grained wheel changes in the TabStrip, MonthView and DTPicker control.


I see no "Download" link. The only way to get the file seems to be through GitHub, but VBCCR/Standard EXE Version/OLEGuids/OLEGuids.tlb was last updated on 18 November 2017.

How is one supposed to get the latest version of this CommonControls library?

----------


## DEXWERX

the project download is at the bottom of the first post. If you have issues setting up the project, you can just download the already compiled ocx from this thread. also at the bottom of the OCX threads post.

see here --> http://www.vbforums.com/showthread.p...on-controls%29

download the VBCCR15.OCX.rar.docx file, and rename it to VBCCR15.OCX.rar
extract the rar, to a folder using winzip/winrar or 7zip.
copy the VBCCR15.OCX to a permanent location like syswow64. and register it there.
(open a *admin* commandline, and run regsvr32.exe VBCCR15.OCX /register from syswow64)

----------


## OldClock

1. Why not write clear installation instructions in the first post?
2. Why not offer a clear download link for the "only one dependency", "OLEGuids.tlb"?

----------


## OldClock

Thank you for the reply DEXWERX. I checked the attachments to the first post of the EXE version. The only attachment visible to me is "ComCtlsDemo.zip.docx". It contains "OLEGuids.tlb" from 2017-06-09. How does one get the "leading source" EXE version from 21-Dec-2017?

----------


## OldClock

In the meanwhile I'm trying to use the Slider widget in an existing project. I've copied OLEGuids.tlb from 21-Dec-2017 into the system folder, and added a reference to it. Nothing new appeared in the toolbox, so I clicked Project > Add User Control > Existing, selected ComCtlsDemo/Builds/Slider/Slider.ctl. It appears in the toolbox. However, when I try to place it in a form, I get an error: "User-defined type not defined" from


```
Private PropRightToLeftMode As CCRightToLeftModeConstants
```

So I grepped and found that that probably comes from Builds/ComCtlsBase.bas, so I added that module, tried again, and, user-defined type not defined:


```
Public Sub ComCtlsSetSubclass(ByVal hWnd As Long, ByVal This As ISubclass, ByVal dwRefData As Long, Optional ByVal Name As String)
```

Found it in Builds\ISubclass.cls, so I added that, tried again, fail again with "DPICorrectionFactor"...

Surely this brute-force head-banging is not the correct procedure for adding a widget to an existing project... But I see no installation instructions. What am I missing?

----------


## Krool

OldClock,

It seems you don't understand the concept of the Std-EXE version.

That's why I advise you to just use the OCX version.
When you read the first post carefully you will find a link to the OCX.

----------


## OldClock

By explaining the issues a new user to your custom controls such as myself encounters I was hoping the situation could be improved for everyone - by browsing through these 48 pages I see I'm not alone.
I raised some issues already in September last year - none of them were addressed. There still are no clear installation instructions for incorporating these custom controls in an existing project and in a new project, no clear licencing, no clear download link. When one is involved with something for a long time, one becomes blinded to how it appears from the outside; I think that may the the case here. For example someone trying to find what licence this whole thing is under will not find that information in the standard place - a "LICENCE" text file is not bundled with the project and is not to be found on the GitHub page, it does not exist. Only through luck would one find "no license, free" on page 42 of this forum. It reminds me of H2G2,



> "But the plans were on display . . ."
> - "On display? I eventually had to go down to the cellar to find them."
> "That's the display department."
> - "With a torch."
> "Ah, well the lights had probably gone."
> - "So had the stairs."
> "But look, you found the notice, didn't you?"
> - "Yes," said Arthur, "yes I did. It was on display in the bottom of a locked filing cabinet stuck in a disused lavatory with a sign on the door saying Beware of the Leopard."





> OldClock,
> It seems you don't understand the concept of the Std-EXE version.


Maybe I don't.



> At design time (IDE) there is only one dependency. (OLEGuids.tlb)
> This is a modified version of the original .tlb from the vbaccelerator website.
> But for the compiled .exe there are no dependencies, because the .tlb gets then compiled into the executable.
> Everything should be self explained, because all functions and properties have a description.


Having everything compiled into the EXE is what I want. If I missed the concept, would you explain it better?

I verbosely explained the issues in this and previous posts in hopes that these issues can be addressed properly, for everyone's benefit.

----------


## jpbro

Hey OldClock - why so rude and demanding? Please don't forget that Krool is donating his time to this project, offering it all 100% free of charge. Yes it would be splendid if he spent even more time putting it all together in a perfect professional package with polished documentation, but that's a lot to just demand or expect from a volunteer.

You've identified a pain point, so maybe this would be a good thing to contribute back once you've worked out the details? You know, for everyone's benefit  :Wink:

----------


## OldClock

jpbro:
1. I disagree about rude. It takes time to point out issues clearly, and instead of acknowledging the problem, I received "It seems you don't understand the concept of the Std-EXE version" in reply. As I admitted, perhaps I don't, but that means the concept can be explained more clearly.
2. Demanding - I'm pointing this out for my own selfish needs as well as for every other layman's benefit. I'm not asking for much either. A project that's been going of for many years is shooting itself in the foot if it doesn't explain the basics to attract more users, testers and potential developers - in that order.
3. I've been heavily involved in open-source for the last 10 years and am quite familiar with how it works. I can't give back before I understand anything about this.

----------


## DEXWERX

I understand your frustration. It's difficult to jump into a complex project as a beginner.

Some helpful info:
A typelib is a binary file that defines types, object interfaces, and more specific API definitions needed for COM interop / marshalling (and VB)
There is no code in it per-se, just a set of definitions needed to interact with certain APIs. So you won't find any controls in a type library.

They can be embedded in an ActiveX DLL or OCX, or as standalone .TLB files, and they are installed similarly using REGTLIB.EXE

So plop the typelib in a good spot - and browse to it under references to add it to your project.

Like jp said - Write down the steps you take to get the standard exe going and paste the instructions here, so you can help other beginners figure it out too.

Word of caution though - the standard exe project can be difficult to work with for developers that don't already have the pre-req knowledge of
1) building user controls in VB
2) COM/typelibs/ActiveX Dlls
3) Win32 API, Subclassing, Windows Common Controls

Feel free to ask specific questions - there are plenty of people here other than KROOL that are willing to help out. That's the beauty of open source.


*edit:* another tip - There are many dependencies for the controls - and they are all packaged nicely in the OCX version. 
If you are trying to use just a couple controls of the EXE project - start by getting the EXE project going, and then removing all the pieces you don't need.
Spend some time figuring out the dependencies before you go and try adding stuff piecemeal to another project.

----------


## jpbro

> jpbro:
> 1. I disagree about rude.


We'll have to agree to disagree about this one.

I haven't really used Krool's controls much so I may be wrong about the following, but I just tried getting a "minimal" project together to use a subset of the controls without requiring the OCX as follows:

 Download the latest source code from GitHub as a ZIP file. Extract the _Standard EXE Version_ folder. Start a new VB EXE project. Rename _Form1_ to _MainForm_ Click the *Project* menu, then click *References*. The _References_ window appears. Click the *Browse* button. Navigate to the _Standard EXE Version_ fodler that was extracted in Step #2, then navigate to the _OLEGuids_ subfolder and select the _OLEGuids.tlb_ file and click *Open*. Back on the _References_ window, click *OK*. Add all of the files from the _Standard EXE Version\Common_ folder to the project. Add all of the files from the _Standard EXE Version\Builds_ folder to the project (not all of the files from the subfolders, just the BAS/CLS files in the Builds folder). Add the individual UserControls from the various _Builds_ subfolders that I want to be part of my EXE (for example, to add the ComboBoxW control, add the ComboBoxW.ctl file from the _Standard Exe Version\Builds\ComboBoxW_ folder to the project).

From there I added a control to MainForm and it seemed to get sited, compile, and run fine. Again, I haven't done this before so I may have made mistakes (or added more files than necessary), but the above should be a good place to start.

----------


## DEXWERX

I love that these projects are on github now. It's cool to see someone submit a fix (for the flexgrid) and see what was fixed.

----------


## chosk

Hi Krool,

If LabelW is inside FrameW, the LabelW_Click() event does not fire.

I experimented with the "old" FrameW (before 3-Jul-2017 version), it works.

----------


## chosk

Hi Krool,

Ref attached screenshot.

I am converting a more than 10 year old app to use your controls. The screenshot show a MDI child window which is normally used to show a chart on a picturebox. During the occasional optimization process, the chart will be cleared using .cls. On every iteration/permutation, .cls again and the running updated optimization information are re-printed using .CurrentX, .CurrentY and .Print. This repeats until the last iteration/permutation.

This process can be aborted anytime with the Abort button. Using the VB6 commandbutton, it stay on the window. When I use CommandButtonW, it won't show. However, when I resize the window, it will show and then sometime flicker on and off and disappear.

It is not really a problem because for this one button I can use the VB6's. But if there is some thing  I can do, I rather use your CommandButtonW.

----------


## Krool

> Hi Krool,
> 
> If LabelW is inside FrameW, the LabelW_Click() event does not fire.
> 
> I experimented with the "old" FrameW (before 3-Jul-2017 version), it works.


For some odd reason the HelpContext features/properties are only available when the UC's CanGetFocus is True.
So in order to not gain focus in the FrameW the WM_MOUSEACTIVATE is handled.
And that also avoid clicking on a windowless Label control...
Solution would be to put a Picturebox above the FrameW and the Label on the Picturebox.
Other solution would be to discard WM_MOUSEACTIVATE and put CanGetFocus to False, but that's not recommended due to loss of help features.
Sorry..

----------


## chosk

Hi Krool,

Thanks.

No problem. I can use the old FrameW.

Edit:
I decided to use a CommandButtonW instead of the LabelW

----------


## Krool

> No problem. I can use the old FrameW.


Hmm. I have found an solution, but I think it is not the "cleanest" way, or is it? Maybe somebody can advise. (?)

So instead of


```
Private Function WindowProcUserControl(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If wMsg = WM_MOUSEACTIVATE Then
    Dim Pos As Long
    Pos = GetMessagePos()
    If WindowFromPoint(Get_X_lParam(Pos), Get_Y_lParam(Pos)) = hWnd Then
        WindowProcUserControl = MA_NOACTIVATEANDEAT
        Exit Function
    End If
```

I would use then


```
Private Function WindowProcUserControl(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If wMsg = WM_SETFOCUS Then
    SetFocusAPI wParam
    Exit Function
```

to avoid getting the Focus by mouse click. So any Label control would receive it's mouse clicks.
The tabbing is already avoided by applying TabStop = False on FrameW startup.

----------


## Semke

oldclock. 

krool has invested a lot of time in designing these controls, and many others have added a lot of comments to help this project, we are all so thankful, and we feel that criticism can only jeopardise this beautiful project.


having said that, with krools permission, I would be glad to write a post with all the proper links to download and install the ocx (exe version and ocx version)

do you agree for me to do it, krool?

thanks krool , I use you stuff all the time..

----------


## Krool

> do you agree for me to do it, krool?


Yes, please. Thanks a lot.

----------


## Greyling

Yes, what Semke said!!!!!   ("Krool has invested a lot of time in designing these controls, and many others have added a lot of comments to help this project, we are all so thankful, and we feel that criticism can only jeopardise this beautiful project.") .............. Thank you Krool

----------


## OldClock

Quite the opposite. Constructive criticism leads to improvements.

----------


## Semke

The .docx extension was necessary so it could be uploaded. (there is a file limit of 500 KB without .docx extension) 
OCX Source (includes a Compiled OCX)
EXE-Version Only Source

If you would like to open the source code in Visual Basic, you will need to register OLEGuids.tlb which is in the OLEGuids Folder in the zip file, this is an updated type library with classes required for this project

----------


## DEXWERX

> Quite the opposite. Constructive criticism leads to improvements.


Constructive criticism would come across much better with a little humility. 
Especially when you don't know what a typelib, or a manifest, or a resource file is.

----------


## jpbro

Agreed @Dexwerx...sometimes it's not the message, it's the delivery.

----------


## Krool

I think I will revert in the FrameW control back to CanGetFocus = False and thus loosing the HelpContextID feature but gaining the mouse clicks. (both label, or windowless controls on container, and frame itself)
I would consider that more important than an obselete HelpContextID for this case.
If somebody uses HelpContextID for an old app, than the Frame control might stay with the VB.Frame then.. any comments concerning this before I suceed? Schmidt?

----------


## Krool

Update released.




> If LabelW is inside FrameW, the LabelW_Click() event does not fire.


This point got me so annoyed. The own MouseDown or Click event of the FrameW is not firing and of course not any placed windowless controls on it, as for instance a LabelW control.

So I switched back and turned off again CanGetFocus to False and made some other minor modifications related to that.
Now you can click on it and get all your events and of course it won't receive focus.
But, as already warned, this has been done in the expense of the HelpContextID support. However, I will stick with this solution as of now.. When somebody complaints about HelpContextID then I want an advise of how to resolve both.  :Smilie:  Or just simply switch to VB.Frame when really HelpContextID is needed.

The OCX has also been updated now in 1.5. However, in order to not wait until 1.6 I needed to "ghost" the HelpContextID property. (remove was not allowed in order to maintain binary compatibility)


```
Public Property Get HelpContextID() As Long
' HelpContextID = Extender.HelpContextID
End Property

Public Property Let HelpContextID(ByVal Value As Long)
' Extender.HelpContextID = Value
End Property
```

----------


## Karl77

OPTIONBUTTONW PROBLEM

OptionButtonW fires 1 event too much on a mouseclick.
See attached:
Option.zip

OptionButtonW1(0).Value = True after Form_Load.

When I click OptionButtonW1(1), I get 2 click events.
1x from OptionButtonW1(0): Value = False
1x from OptionButtonW1(1): Value = True

The intrinsic control doesn't show this behavior.

---

EDIT:
I know it's easy to workaround this.
As I would have to do this in many distributed places, I mentioned it here.

----------


## Krool

Update released.




> OPTIONBUTTONW PROBLEM
> 
> OptionButtonW fires 1 event too much on a mouseclick.


Good catch, solved. Thanks

----------


## Hosam AL Dein

In the STD-exe project , when I click on the image combo to expand it and then close the form , IDE crashes !! . It also has no images displayed despite being set to Imagelist 1

----------


## Hosam AL Dein

the previous problem did not occur after removing some ado connection code . this same code with no change at all did not raise any problems . I was about to re-post about this problem and it is hard for me to explain . how come that : some code works fine - close the program - start again - unload the form - now IDE crashes . I am fed up with this error . If possible , I need someone`s help on teamviewer . 3 months of suffering with this issue and with every update I come here to test again and same results . I am sure I am not doing something wrong .

----------


## Hosam AL Dein

This problem is about 4 months old for now and I can not find a solution or even determine what the problem exactly is .
I have posted about it in this thread and followed all suggestions for solution but it never got solved .

*The problem was that* : In a form , If I open a connection using ado and the form contained a populated listview , VB IDE crashes when the form is unloaded or the program is terminated in any way : like End statement or Break in the IDE or even by pressing the close button on a form .

If I remove the ADO connection code , the problem disappears then . And also If don`t populate the listview and keep the connection code only , then the problem also does not occur .* So , they are somehow related .*

After many tests and workarounds the result is the same . I thought it might be something related to binary conflict while I was upgrading from one version to another or something related to registry or manifests . I was using windows 10 64 bits and some copy of VB6 .Now I have just installed a new copy of Win7 32 bit and also downloaded a new VB6 copy from the web with no known or common problems to get to the very basic clean start point to avoid any mistakes which could have been there in my old system (win 10 - VB6 - registry - manifests or type libraries) . In the old system , the STD-Exe project never ran in my machine . I was using the OCX version only and it was fine till version 1.4 . The problem was about 1.5 version .

Now , with the new windows , I can run the STD-Exe project and I don`t exactly know what has solved this problem(new windows , or some version update of the STD-Exe or some binary conflict removed) but anyway , this is a good point and I thought that this would be the end of my suffer . I made the same old experiment within the STD-Exe project itself . In the main form , I left everything as it is . I have just added a separate command button which just connects to an access 2010 database and just opens the connection and a table in the database.I did not even touch the listview or populate it with the recordset data . I have only opened a connection . 

when I posted about this problem here in this post , some people who I`m thankful to , have suggested to organize my code which opens the connection like freeing up memory after the code executes . I followed the advice previously and also in the new system and the problem still occurs .I have even tried all MS Activex Data Objects library with versions like 2.5 -2.8 -6 and 6.1 . The point was that it might be raising some error in the form unload , terminate or the query_unload events and causes the IDE to crash maybe . I have put error handlers in the 3 events and no error was raised at all in any of the test cases .

I said it might be the way I connect to the database is what caused the problem . So , I have used a very clean code from Microsoft examples to open the connection with error handlers and cleaning up lines of code and the problem has never been solved  .
*
Note : I have recently solved this problem but I can not determine the cause accurately  . So , there is a problem not related to something wrong I was doing as I said before . I will preview the solution in a separate post for investigation by the folks here about what are the causes of this problem and how this solution resolved it .*

----------


## Hosam AL Dein

Sorry for late posting . I have been away the last 3 days . 
About the previous problem , I have logged into the event viewer in windows and I have become able to be more close to it by viewing the error reports of the App Crash error . I found some of the modules which have been previously loaded before the IDE crashes . Some of them were some office libraries . This shed a light in my mind about the database itself (I use Access 2010) . So , I have changed the database to Access 2003 and changed the connection string and everything is fine now . I even changed it to MySql and also the problem did not happen . I have made a link between the last VBA enhancements made by krool and thought that : this might explain the point that the project worked smoothly before some VBA enhancements starting from some version in 1.4 and to the last in 1.5 .

I can not determine the cause of this problem but I found the solution to avoid it . Now , I abandoned using access 2010 and started using Mysql . I was anyway planning to upgrade the database I am using in my next projects . But , the problem is still here for the VBCCR control itself . I will post the error description in event viewer so we can investigate it and determine the problem and its cause .  

text from error report



> Version=1
> EventType=APPCRASH
> EventTime=131619560662224530
> ReportType=2
> Consent=1
> UploadTime=131619560663704615
> ReportIdentifier=4460b171-073e-11e8-ad02-344b50b7ef23
> IntegratorReportIdentifier=4460b170-073e-11e8-ad02-344b50b7ef23
> Response.type=4
> ...


here is another error report generated besides the previous one




> Faulting application name: vb6.exe, version: 6.0.81.76, time stamp: 0x3592011f
> Faulting module name: ntdll.dll, version: 6.1.7601.17514, time stamp: 0x4ce7b96e
> Exception code: 0xc0000374
> Fault offset: 0x000c37b7
> Faulting process id: 0x1488
> Faulting application start time: 0x01d39b4ad9c24dee
> Faulting application path: C:\Program Files\Microsoft Visual Studio\VB98\vb6.exe
> Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
> Report Id: 4460b170-073e-11e8-ad02-344b50b7ef23



depending on some key errors from the previous two logs I have come to thes points :

1- The program faults in module ntdll.dll .
2- The error category is StackHash_bd6d. (comes from the first log)
3- The exception code is 0xc0000374 .(comes from the second log )
4- The program crashes few steps after loading office14 modules .

The point #4 is what made me try another database option and this way I could *"avoid"* the problem but as I said I can not determine it accurately .


I googled the error StackHash_bd6d and the Exception Code 0xc0000374  and they are talking about page heap corruption in memory . Maybe the VBA enhancements are the cause or maybe something related to my system . Actually , I don`t exactly know but I posted it perhaps someone could help .

----------


## frog357

Krool,
Thank you for your great work towards improving the community.  I have discovered a minor issue with the Listview control.  To demonstrate, modify your Standard EXE example so that the top right Listview has Multiselect = True. Next scroll to the far bottom right and click with the left button in an empty area as if you were about to create a box to draw a selection around everything in this window.  What happens for me is the mouse jumps to the top left of the screen.  The jump seems to happen in mouse down.  I can move the mouse back down and eventually finish my selection.  I discovered this behavior with the listview set to report but it was much more difficult to reproduce.

----------


## VbNetMatrix

> About the previous problem


I've looked into your post...

can you give us your code for the ADO you're using for connection ?
Win Win7+ you must use at least ADO 6.0
with Office 2010, you CANNOT use JET OLE, you MUST use ACE

the only way I could see an IDE crash would be subclassing issue, do you subclass your form ?

we can't fix something we don't see the code for.

----------


## VbNetMatrix

> The .docx extension was necessary so it could be uploaded. (there is a file limit of 500 KB without .docx extension) 
> OCX Source (includes a Compiled OCX)
> EXE-Version Only Source
> 
> If you would like to open the source code in Visual Basic, you will need to register OLEGuids.tlb which is in the OLEGuids Folder in the zip file, this is an updated type library with classes required for this project



What some people don't seem to understand is that FORUM are limited from what we can do.

Krool did a tremendous job and proposition like the documentation really show teamwork collaboration and THAT is what Krool need.  Thanks.

I also offered something in past and I hope to deliver soon, it could solve some of the collaboration problem. (if Krool still agree)

I want to show my deep appreciation for Krool work.

----------


## Krool

> Krool,
> Thank you for your great work towards improving the community.  I have discovered a minor issue with the Listview control.  To demonstrate, modify your Standard EXE example so that the top right Listview has Multiselect = True. Next scroll to the far bottom right and click with the left button in an empty area as if you were about to create a box to draw a selection around everything in this window.  What happens for me is the mouse jumps to the top left of the screen.  The jump seems to happen in mouse down.  I can move the mouse back down and eventually finish my selection.  I discovered this behavior with the listview set to report but it was much more difficult to reproduce.


If your described issue is the same as described in the following link "ListView quirks in Win 10" 
http://www.vbforums.com/showthread.p...irks-in-Win-10
then I will reject any fix as this is a Todo for MS from last update in Win 10.
If not (please confirm again) we can look at.

----------


## Karl77

I have read about Eduardo's SSTab replacement, which is a good thing.

As I gave up on the original SSTab many years ago, I don't need the replacement.
The TabStrip is good enough for me.

Eduardo's work has the BackColor property.
This would be very useful for the TabStrip as well.
Here:


Could this be done for your TabStrip as well?

----------


## frog357

> If your described issue is the same as described in the following link "ListView quirks in Win 10" 
> http://www.vbforums.com/showthread.p...irks-in-Win-10
> then I will reject any fix as this is a Todo for MS from last update in Win 10.
> If not (please confirm again) we can look at.


You have every right to decide what you will focus your time on.  It seems odd when a fix is available to improve something you released, yet instead you would rather cast blame.  Someone is always to blame, the goal here was to create a solution.  Why reject any fix, they are not responsible for the controls you created?  If you were confident they would fix it why did you bother to create these *fixed* components in the first place?

----------


## chosk

MS screw up comctl32.dll? And that affect all controls so created, even MS own? How/who to fix comctl32.dll?

----------


## Krool

> MS screw up comctl32.dll? And that affect all controls so created, even MS own? How/who to fix comctl32.dll?


Exactly. Every SysListView32 is affected. So it makes no sense to just make a workaround fix for my wrapper..




> I have read about Eduardo's SSTab replacement, which is a good thing.
> 
> As I gave up on the original SSTab many years ago, I don't need the replacement.
> The TabStrip is good enough for me.
> 
> Eduardo's work has the BackColor property.
> This would be very useful for the TabStrip as well.
> Here:
> 
> ...


There is no native way as COLOR_BTNFACE is hard-coded in comctl32.dll for the SysTabControl32.
There is a hacky way too workaround that:
http://www.glennslayden.com/code/win...ckground-brush
However, the adjustmants are mainly guessings and very vague. It might work for now but in a newer OS it might be not perfect anymore. So in fact there is no straight forward method to calc. the stuffs needed.
So IMO it's too hacky to implement as a property to trust on.

----------


## Karl77

> There is no native way as COLOR_BTNFACE is hard-coded in comctl32.dll for the SysTabControl32.
> There is a hacky way too workaround that:
> http://www.glennslayden.com/code/win...ckground-brush
> However, the adjustmants are mainly guessings and very vague. It might work for now but in a newer OS it might be not perfect anymore. So in fact there is no straight forward method to calc. the stuffs needed.
> So IMO it's too hacky to implement as a property to trust on.


Ok, I see.
I hoped it would be an easy straightforward thing; it's not.

But the very last method form Paul Sanders on the page seems to be good enough, or?
The background color would be nice.

----------


## Krool

> Ok, I see.
> I hoped it would be an easy straightforward thing; it's not.
> 
> But the very last method form Paul Sanders on the page seems to be good enough, or?
> The background color would be nice.


There are much +- 1, 2 and rounded corners or not. The calculation is done very specific to get perfect result.
However, for me that's not "straight forward" as in a new themed style the offsets can go wrong. And even DPI scaling is also a factor which is not considered.
So I'm afraid of implementing such a property.

----------


## Karl77

> And even DPI scaling is also a factor which is not considered.


Which is very important..


> So I'm afraid of implementing such a property.


Full agree, better don't.

----------


## Dragokas

Hi, Krool !

When typing ALT + 3333 in textbox, '?' is appearing instead of '♣'. Is that a bug?

Thanks.

----------


## Krool

> Hi, Krool !
> 
> When typing ALT + 3333 in textbox, '?' is appearing instead of '♣'. Is that a bug?
> 
> Thanks.


It's a bug.
I need to fiddle with WM_SYSKEYDOWN and WM_SYSCHAR in order to find a solution. (Caching CharCode to avoid VB's ANSI message bump)
Currently this case is not handled..
Thanks for pointing this out. It's not that critical but a weak spot that needs to be handled in order to be "full unicode compatible".
I will come back for this soon.

----------


## Krool

Update released.

Unicode support when generating ASCII key combos, e.g. ALT + 3333.

Both the Std-EXE version and the VBCCR15.OCX got updated.

In fact it was not necessary (and not applicable) to fiddle with WM_SYSKEYDOWN/WM_SYSCHAR as just WM_KEYUP needed to be cached as well.
When generating ASCII key combos the WM_CHAR is generated actually in WM_KEYUP instead of normally on WM_KEYDOWN. That's it  :Smilie: 

Again thanks to Dragokas for pointing this issue out.

----------


## VbNetMatrix

> Update released.
> 
> Unicode support when generating ASCII key combos, e.g. ALT + 3333.
> 
> Both the Std-EXE version and the VBCCR15.OCX got updated.
> 
> In fact it was not necessary (and not applicable) to fiddle with WM_SYSKEYDOWN/WM_SYSCHAR as just WM_KEYUP needed to be cached as well.
> When generating ASCII key combos the WM_CHAR is generated actually in WM_KEYUP instead of normally on WM_KEYDOWN. That's it 
> 
> Again thanks to Dragokas for pointing this issue out.


really fast turn around!  thanks.

----------


## Krool

Update released.

Major internal improvement in the VTableHandle.bas module. (thanks to TimoSoft)

The VTableHandle.bas subclassed IOleInPlaceActiveObject, IOleControl, IPerPropertyBrowsing and IEnumVARIANT.
The logic were all "straight forward" except for IOleInPlaceActiveObject as it required some quirky workarounds.

It turned out that subclassing IOleInPlaceActiveObject is not necessary as in IOleInPlaceUIWindow::SetActiveObject you can place any IOleInPlaceActiveObject interface.
So, the new solution is creating an own "lightweight" IOleInPlaceActiveObject VTable which is used on the SetActiveObject. Thus no subclassing required.

The other interfaces IOleControl, IPerPropertyBrowsing and IEnumVARIANT will still need subclassing. But that's no problem as they caused no quirks anyway.

----------


## VbNetMatrix

> I have read about Eduardo's SSTab replacement, which is a good thing.
> 
> As I gave up on the original SSTab many years ago, I don't need the replacement.
> The TabStrip is good enough for me.
> 
> Eduardo's work has the BackColor property.
> This would be very useful for the TabStrip as well.
> Here:
> 
> ...


just for curiosity, any reason you gave up on the sstab ?  I use it a lot and I was wondering if there were bug I should be aware of ...

----------


## Karl77

> just for curiosity, any reason you gave up on the sstab ?  I use it a lot and I was wondering if there were bug I should be aware of ...


No special bug I remember.
I think the main reasons were not displaying perfect with visual styles.
And not being able to disable controls that are not visible.
And the additional dependency.
It can be that my bad experience is from VB3 times, except the visual styles thing.

When SSTab works good for you, fine.
As said, I see no need for me.

----------


## VbNetMatrix

> No special bug I remember.


Some people seem to think the -75000 pixel unit .Left is a bug for hidden tab as in fact is a feature.  we can live well with it when testing for it.





> I think the main reasons were not displaying perfect with visual styles.


didn't experienced that




> And not being able to disable controls that are not visible.


You need to put a picture box in Each tab, use it as a container and disable that container on requirement. work well




> And the additional dependency.


Refular Stab also got aditional dependency isn't ??




> It can be that my bad experience is from VB3 times, except the visual styles thing.


Since activating Visual managment from Vb6 cause more bug then the definitive improve gain experience, I have created my own visual component to have a good look and feel inside my program, so I didn't experienced that.




> When SSTab works good for you, fine.


what I love most is the fact you can place your stuff in the IDE on each different TAB and manage each Tab independently and manage from there, it's easier to build your program interface.

----------


## Karl77

VbNetMatrix

Don't let us hijack Krool's thread...




> You need to put a picture box in Each tab, use it as a container and disable that container on requirement. work well


Same procedure as with TabCtl.
While I would expect from a SSTab that it manages this on it's own.




> Refular Stab also got aditional dependency isn't ??


Yes, to Comctl32.ocx
Which is very well substituted by the VBCCR controls.
In fact there is only one single dependency for all the controls needed for a 'normal' UI.
Or no dependency if you work with the EXE version.




> Since activating Visual managment from Vb6 cause more bug then the definitive improve gain experience,


Hmm? Not nearly true.




> what I love most is the fact you can place your stuff in the IDE on each different TAB and manage each Tab independently and manage from there, it's easier to build your program interface.


For me, this is a very minor benefit, if at all.

----------


## VbNetMatrix

> VbNetMatrix  Don't let us hijack Krool's thread...


Agree...  let's focus on Krool project...




> In fact there is only one single dependency for all the controls needed for a 'normal' UI.
> Or no dependency if you work with the EXE version.


not sure I follow...  Krool is not totally replacment since it depend on original control.  It's improvment of original control, meaning it require the SAME dependency  or do I miss something ?

what about the documentation about the installation and use of the EXE version ?  is it completed yet ?

----------


## Karl77

> not sure I follow...  Krool is not totally replacment since it depend on original control.


Not true.
The VBCCR control base is comctl32.dll (part of the OS).




> It's improvment of original control, meaning it require the SAME dependency  or do I miss something ?


Yes, you do...
The best thing is, you start reading this thread from the very first post on.
Then you should know 'everything'.




> what about the documentation about the installation and use of the EXE version ?  is it completed yet ?


No need for an installation, just copy the folders and files.
You can see all the needed coding in the demo.
Again, you should read this in the first few posts.

http://www.vbforums.com/showthread.p...=1#post4277565

----------


## Krool

Update released.

Included the VirtualMode/VirtualItemCount property and GetVirtualItem/FindVirtualItem event in the ListView control.

When there are over 100,000 items it is worth to consider virtual mode as the VB6 class destruction (ListItems collection) will get slow at some point.
This issue is not existent on virtual mode as all the data can be cached in a recordset or private array.

The new VirtualControlsForm in the demo project demonstrates an example usage of the virtual list view.

All normal list view events are supported, e.g. ItemClick. However, passed ListItem objects in these events are limited in their functionality when VirtualMode is on.

Several functions/properties/methods are disabled (error raise) when VirtualMode is on. (e.g. Tile view, Groups, Sorting, ListItems collection etc.)

Also included VirtualDisabledInfos property that allows to disable not needed virtual properties and to increase performance. (less GetVirtualItem event calls)

At run-time that property can be changed.


```
ListView1.VirtualDisabledInfos = 0 ' None disabled info
ListView1.VirtualDisabledInfos = LvwVirtualPropertyForeColor + LvwVirtualPropertyBold ' Disable CustomDraw callbacks
```

----------


## MBOS

Hi Krool,

First I'd like to say a big thank you for putting lots of effort in this project!

I'm facing a problem when trying to implement the TextBoxW control in a project of mine.
The problem is very easily reproducible.

*1. Create an ActiveX Control project 'MyButton'.*
Drag a CommandButton on the control.
Assign the following code:


*2. Make a new VB project, Project1.vbp, which has Form1.*
Drag a TextBoxW control and the newly created MyButton control on it.


*3. Now unload Form1 when MyButton is clicked:*


 :Thumb:  When the button is clicked via left mouse button, the form unloads correctly.
 When the button is clicked via the keyboard enter, the project crashes.

*Additional information:*
If the TextBoxW control is replaced by LabelW, FrameW or ImageList. The project doesn't crash.
If the TextBoxW control is replaced by any other control, the same error occurs.

----------


## Krool

Update released.

Potential crash in the GetVirtualItem event fixed in the ListView control.

----------


## chosk

Hi Krool,

I am starting another project same as one I did in end-2016 but this time, I hit a problem with the TabStrip. I am using Std-EXE. Then I tested the older control builds and the last control build that do not have the problem is 5-May-2017. Tabstrip after this date up to the latest has the problem.

The project is a MDI project that is:
1) Using TabStrip as MDI Tabs
2) Child form's tag is set to "Chart"
3) Child form's .WindowsState is always = vbMaximized
4) Child form's .Visible = True or False, depending on tab selected

The problem is that child forms momentarily show as vbNormal (in a flicker) whenever the TabStrip is clicked. When tab is already selected and shown and tab clicked again, the child form show as vbNormal. There is no code to show it vbNormal.

TabStrip_TabClick codes:


```
Private Sub TabStrip_TabClick(ByVal TabItem As TbsTab)
    Dim i As Integer
        
    'Do two loops to prevent potential problems
    
    'First, hide all child forms
    For i = Forms.Count - 1 To 0 Step -1
        If Forms(i).Tag = "Chart" Then
            Forms(i).Visible = False
        End If
    Next
    
    'Then, show only selected child form
    For i = Forms.Count - 1 To 0 Step -1
        If Forms(i).Tag = "Chart" Then
            If Forms(i).Symbol = TabItem Then
                Forms(i).Visible = True
            End If
        End If
    Next
End Sub
```

I attached two video to show, using 5-May-2017 and 2-Mar-2018. The versions is shown in the MDI Parent caption.

----------


## Krool

Important update released.

@ MBOS,

I could not replicate your scenario. However, I was able to get such a crash in another context/scenario (for me like a random scenario).
My scenario though was only replicable in the IDE and not on the executable.
I was able to find the cause for it and the explanation.

Due to the VTableHandle.bas update on 25-Feb-2018 the IOleInPlaceActiveObject switched from Subclassed to own lightweight VTable object.
The issue is that the lightweight VTable object relies on AddressOf functions and that these addresses _could_ go "invalid" (addresses in .bas module changed) on unload.

The straight forward solution was now to restore the original IOleInPlaceActiveObject object in the DeActivateIPAO method. So it is safe in either case to unload.

----------


## VbNetMatrix

> The best thing is, you start reading this thread from the very first post on.
> Then you should know 'everything'.


I did that...  still don't understand... something is incredibly easy for me like programming.... and other are incredibly complex, like managing a smart phone.  And I read this forum since the first post and unless it changed since I read it, I still don't understand.

----------


## chosk

Hi Krool,

I am happy to continue using the 5-May-2017 version of TabStrip for my current project because this serve my purpose. I just need to include the improvement/fixes to DPI-Aware that were in the 25 and 26 Jul 2017 releases. I believe these two releases fixed the DPI-Aware problem reported in post #1500:

http://www.vbforums.com/showthread.p...=1#post5189339




> 26-Jul-2017
> - Bugfixes related to 25-Jul-2017 update in the TabStrip, ToolBar and CoolBar control.
> 
> 25-Jul-2017
> - Pixels in property bags are now treated as DIPs. (Device-independent pixels)
>   There is no compatibility break in the property bags when there were saved at 100% (96) DPI.
>   Included new functions PixelsPerDIP_X/PixelsPerDIP_Y in Common.bas.
>   This "DPI Aware" enhancement affects the TabStrip, ToolBar, Pager and CoolBar control.


If you could let me know where do I make the changes, I will be more than happy to do it myself.

----------


## Karl77

VbNetMatrix

2 possibilities:
1) Take the complete EXE demo. Delete all that you don't need. Add your code into this project.
2) Use the OCX version. Usage is as with other OCX's.

----------


## chosk

Can I offer my help with some screenshots? The steps is really easy and simple to add only the control/s needed.

I normally use my own module, eg, MainModule.bas, and the Main function within and do not drag-and-drop the Startup.bas. These screenshots here is only for example.

----------


## MBOS

> Important update released.
> 
> @ MBOS,
> 
> I could not replicate your scenario. However, I was able to get such a crash in another context/scenario (for me like a random scenario).
> My scenario though was only replicable in the IDE and not on the executable.
> I was able to find the cause for it and the explanation.
> 
> Due to the VTableHandle.bas update on 25-Feb-2018 the IOleInPlaceActiveObject switched from Subclassed to own lightweight VTable object.
> ...


My issue also seems to be solved!  :Smilie:

----------


## Krool

Chosk,

Yes no problem I can tell you the lines to change for DPI Aware.
However, I would like to first try to find the cause of the flicker problem in the latest TabStrip control..

@ MBOS, great. I have the feeling now I never need to touch VTableHandle.bas again. It's done now.  :Big Grin:

----------


## chosk

> Chosk,
> 
> Yes no problem I can tell you the lines to change for DPI Aware.
> However, I would like to first try to find the cause of the flicker problem in the latest TabStrip control..


Hi Krool,

Now, I do not know whether the cause is in the TabStrip. I just tested using a ListBoxW, instead of TabStrip, and same flicker and child form windowstate become Normal also happen in the latest release but not with the 5-May-2017 release.

----------


## Krool

> Now, I do not know whether the cause is in the TabStrip. I just tested using a ListBoxW, instead of TabStrip, and same flicker and child form windowstate become Normal also happen in the latest release but not with the 5-May-2017 release.


WM_MOUSEACTIVATE was changed after 5-May-2017 release on all controls. Looks now like its coming from that change..

----------


## Semke

the OLEGuids.tlb supplied. is this a replacement for the one provided by windows, or do I still need to keep the original

----------


## Krool

> the OLEGuids.tlb supplied. is this a replacement for the one provided by windows, or do I still need to keep the original


It's a custom tlb. It's only needed in the IDE on the dev PC. At the run-time (end user) it's not needed.

----------


## Karl77

PAGER FEATURE WISH/QUESTION

I use the pager control a lot.
The AutoScroll feature is quite handy.
For this, the mouse must hover over the pager button.
Very ok so far.

It would be even more comfy if I could use the mouse wheel in addition to the buttons.
While being somewhere in the pager area.
And not over a control which makes use of the wheel message.

Is this possible at all?

----------


## Elroy

WOW Krool.  You've made Wikipedia.   :Smilie:

----------


## Semke

> It's a custom tlb. It's only needed in the IDE on the dev PC. At the run-time (end user) it's not needed.


thank you, I know that its a custom tlb. does it also include all the other types which are in the original OLEGuids.tlb

----------


## Karl77

> PAGER FEATURE WISH/QUESTION
> It would be even more comfy if I could use the mouse wheel in addition to the buttons.
> While being somewhere in the pager area.
> And not over a control which makes use of the wheel message.


Ok, I added WM_MOUSEWHEEL in WindowProcControl.
The message comes in, and controls in the pager do work as usual regarding the mouse wheel.
Looks promising.

I don't know how to make the pager scroll.
Do I really need to get+set the position, or is there a function/message for it?

*EDIT:*
Too easy.
I can just make use of the Value property.
Problem solved.

*EDIT 2:*
Once again a good example for the benefit to have access to the sources.

----------


## Karl77

GetTitleBarHeight

In Common.bas, there is the handy GetTitleBarHeight function.
I think there is something wrong.
It adds the frame 2x, while it should 1x only.



```
Select Case Form.BorderStyle
Case vbSizable, vbSizableToolWindow
CY = CY + (GetSystemMetrics(SM_CYSIZEFRAME) * 2)
Case vbFixedSingle, vbFixedDialog, vbFixedToolWindow
CY = CY + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2)
End Select
```

At least to my measurements.

----------


## Krool

> GetTitleBarHeight
> 
> In Common.bas, there is the handy GetTitleBarHeight function.
> I think there is something wrong.
> It adds the frame 2x, while it should 1x only.
> 
> 
> 
> ```
> ...


For my usage the 2x is correct. The naming is maybe a little bit misleading..
In fact Form.Height contains the ScaleHeight and the "outer" height. I use the GetTitleBarHeight to exclude the "outer" height.
So I can apply something like following:


```
Me.Height = GetTitleBarHeight(Me) + (ListView.Top + ListView.Height) + StatusBar.Height + 120
```

The 120 twips is just a buffer then between a ListView and a StatusBar.

Edit: A better name for it could be 'GetNonScaleHeight'. ^^

Edit 2: The ListView in my code example is of course in a variable height setup at Form_Load, otherwise such calculation would be meaningless.

----------


## Karl77

(GetTitleBarHeight)




> For my usage the 2x is correct.


I didn't inspect your usage of the function - of course it is correct for you.
GetTitleBarHeight came into my view when I searched for a constant in my code.
And hey, I found a ready function, the name expresses exactly what I wanted.
My fault that I didn't look more in detail.

----------


## Karl77

MSGBOX QUESTION

Perhaps a stupid question:
In common.bas, there is the Public Function MsgBox.
What is it's advantage over the intrinsic function?

----------


## Arnoutdv

Maybe also a Unicode variant?

----------


## SuperDre

Or mabye non-blocking? the intrinsic function blocks everything.

----------


## Karl77

> Or mabye non-blocking? the intrinsic function blocks everything.


Aha, I'll test.




> Maybe also a Unicode variant?


Ah, of course!

Thank you both for answering my too basic question.

----------


## Karl77

TOOLBAR PROBLEM

Place a toolbar, ShowTips=True, on a form.
Use a timer to Debug.Print the toolbar's ShowTips property value.
Place a command button to set ShowTips=False.
Fill it with buttons and set their tooltips by code.
Start.

See it working: ShowTips=True
Hit the command button to set ShowTips=False.
See in the Debug window that this worked.

Move over the buttons, and still see the tooltips.

---

I need to kill the tooltip in special cases.
I tried to ShowTips=False to kill it, and ShowTips=True afterwards.
Doesn't work.

Ideas?

----------


## Arnoutdv

Normally I don't try to kill a Tooltip but I just clear it's contents.
An empty tooltip is not shown
This works for most controls/components I use (and tested).

----------


## Karl77

> Normally I don't try to kill a Tooltip but I just clear it's contents.
> An empty tooltip is not shown
> This works for most controls/components I use (and tested).


Ok, good idea, I'll test that.
Thank you

EDIT:
While it is a good idea, it is not sufficient.
It takes the normal time for the tooltip to disappear.
I need it immediately.

----------


## Krool

> I need to kill the tooltip in special cases.
> I tried to ShowTips=False to kill it, and ShowTips=True afterwards.
> Doesn't work.


In the ComCtlsDemo I have put in Command2_Click the following code, and it worked:


```
ToolBar1.ShowTips = Not ToolBar1.ShowTips
```

When True the first two buttons do show info tip, when false they don't. So for me it works..
Can you double check this example?

----------


## Karl77

> In the ComCtlsDemo I have put in Command2_Click the following code, and it worked:
> 
> 
> ```
> ToolBar1.ShowTips = Not ToolBar1.ShowTips
> ```
> 
> When True the first two buttons do show info tip, when false they don't. So for me it works..
> Can you double check this example?


Double checked, and no, no effect.

I have made a short example:
Toolbar Tooltip.zip

In the IDE, it doesn't work.
Compiled to EXE, it works.

Difference:
In the IDE the Visual Styles are active.
Not in the EXE.

----------


## chosk

> I have made a short example:
> Toolbar Tooltip.zip
> 
> In the IDE, it doesn't work.
> Compiled to EXE, it works.
> 
> Difference:
> In the IDE the Visual Styles are active.
> Not in the EXE.


I tested in IDE twice:
It works (VB6.exe with and without Theme manifest)

Also tested project1.exe twice:
It works (with and without Theme manifest)

----------


## Karl77

This is what I see:


Chosk, which OS are you on? Not Win10?

EDIT:
I made a manifested EXE as well now.
On Win7, it works as expected.
On Win10, it doesn't.
Both tested in VMs.

----------


## chosk

> Chosk, which OS are you on? Not Win10?


I was on Win7.

I just tested in Win10. Yes, .ShowTips = False does not work with Theme.

I also just tested MS toolbar v5 and v6 to check the problem. Their .ShowTips is read-only.

----------


## Karl77

PERFORMANCE PROBLEM

VBCCR15

I have one form for all settings.
The settings are a lot, so many controls are needed.
Labels, OptionButtons, CheckBoxes etc..

This settings form takes a long time to load, barely acceptable long.
I investigated why, and I found that the VBCCR controls are the cause.
The slow loading is seen even when no code, but only the controls, are on the form.
The same form with intrinsic controls has no noticeable load time.

To prove it, I made a little test app that shows the effect.
I found out the OptionButtonW is the slowest control.
Here: Performance.zip
Of course a control count of 1000 (each) in not realistic.

But it shows the tendency.
In my tests, I didn't see a real difference if VisualStyles are enabled or not, and I see the same on Win7/10.

Is there a chance to get this a bit better?

Thank you

----------


## Arnoutdv

Do you see this performance drop only when running your application in the IDE or also when compiled?

How is the performance if you use the precompiled OCX version?

----------


## Karl77

> Do you see this performance drop only when running your application in the IDE or also when compiled?


Both the same.




> How is the performance if you use the precompiled OCX version?


I do so already (VBCCR15.OCX), see example.

----------


## Arnoutdv

My bad, because this thread is about the CTL versions I assumed you were using these.

----------


## Karl77

> My bad, because this thread is about the CTL versions I assumed you were using these.


Is it?

----------


## Krool

Is the ToolBar ShowTips issue resolved? I don't know what to fix. Could this be a Win 10 bug?




> To prove it, I made a little test app that shows the effect.
> I found out the OptionButtonW is the slowest control.
> Here: Performance.zip
> Of course a control count of 1000 (each) in not realistic.


Hmm, interesting. I could replicate your demo and confirm.


Beside OptionButtonW1 the CheckBoxW1 is also slow. CommandButtonW1 is also slow but the intrinsic one is not really better.
Right now I'm clueless. By each Load command the UserControl_Intialize and UserControl_ReadProperties is called, which is OK and necessary.
I cannot tell now if it's VB.UserControl fault or some overhead in my sources..

----------


## Karl77

> Is the ToolBar ShowTips issue resolved? I don't know what to fix. Could this be a Win 10 bug?


No, not really resolved.
For now, I decided to use a short tooltip for the 'special' buttons.





> Hmm, interesting. I could replicate your demo and confirm.


And it becomes even more interesting:
In the calling form, make a menu using the menu designer.
From a submenu, call form 2.
Test the form2 behavior by clicking the menu with the MOUSE.
Note the values by screenshot or alike.
Quit and restart.
Hit F10 to activate the menu, and hit Enter on the menu by KEYBOARD.
This is _a lot_ faster than the mouse method.
I can't see such a difference when using intrinsic controls. 
Perhaps this fires your fantasies?




> Right now I'm clueless. By each Load command the UserControl_Intialize and UserControl_ReadProperties is called, which is OK and necessary.
> I cannot tell now if it's VB.UserControl fault or some overhead in my sources..


I don't expect the same speed as with the intrinsic controls.
Option and Check are very slow.
CommandButton is good enough, as there won't be 100 of them in one Form.
The LabelW is "acceptable".
I doubt the slowness is because of the UserControl model only.
But I didn't investigate deeper.

----------


## Krool

Update relased in ComCtlsBase.bas.

In the internal ComCtlsShowAllUIStates the message WM_CHANGEUISTATE (travels down tree up and down; overhead) has been replaced by the direct WM_UPDATEUISTATE. No side effects detected by this change, so it's ok.

As you see the performance for CheckBoxW is increased drastically, though still OptionButtonW is weak.


However, when skipping some control load loop, the performance of OptionButtonW is also increased.


So the problem has been partially resolved; performance still gets weak the more controls there are.

----------


## Karl77

> performance for [...] is increased drastically


Yes, confirmed.
Drastically is the right term.
*Wow!*

My settings dialog loads in an acceptable time now.
Also there is no real difference if started by mouse click or Enter.

I'm very curious how this mouse/Enter difference came.
I can't imagine...

----------


## Mith

one of my users gets an error window titled VBCCR15 which states the run-time error -2147024770 when starting my app.
he uses win8.1x64 but i cant reproduce this error when using win8.1x64.
i already googled for -2147024770 but no results.

any hints how to fix that?

----------


## DEXWERX

sounds like a deployment issue. How was VBCCR installed?

----------


## Mith

> sounds like a deployment issue. How was VBCCR installed?


side-by-side (embedded manifest inside the exe via res-file)

----------


## Mustaphi

Hi Krool 
I'm trying to save the content of the TextBoxWs in inifiles but when I load them I'm getting question marks.
The  content of the TextBoxWsis is in Arabic Language.
This is how I'm doing:
 For Saving


```
If TypeOf ctl Is TextBoxW Then
   
   RetVal = WriteToAppINI(Me.Name & "Control", ctl.Name & " FontSize", CStr(ctl.Font.Size), App.Path & "\MyAppSettings.dat")
    RetVal = WriteToAppINI(Me.Name & "Control", ctl.Name & " text", CStr(ctl.text), App.Path & "\MyAppSettings.dat")
    RetVal = WriteToAppINI(Me.Name & "Control", ctl.Name & " FontName", CStr(ctl.Font.Name), App.Path & "\MyAppSettings.dat")
    RetVal = WriteToAppINI(Me.Name & "Control", ctl.Name & " Font_CharSet", CStr(ctl.Font.Charset), App.Path & "\MyAppSettings.dat")
   RetVal = WriteToAppINI(Me.Name & "Control", ctl.Name & " FontBold", CStr(ctl.Font.Bold), App.Path & "\MyAppSettings.dat")
  RetVal = WriteToAppINI(Me.Name & "Control", ctl.Name & " FontItalic", CStr(ctl.Font.Italic), App.Path & "\MyAppSettings.dat")
 
End If
```

For Loading



```
If TypeOf ctl Is TextBoxW Then
ctl.Font.Size = ReadFromAppINI(Me.Name & "Control", ctl.Name & " font.size", ctl.Font.Size, App.Path & "\MyAppSettings.dat")
ctl.text = ReadFromAppINI(Me.Name & "Control", ctl.Name & " text", ctl.text, App.Path & "\MyAppSettings.dat")
ctl.Font.Name = ReadFromAppINI(Me.Name & "Control", ctl.Name & " Font.name", CStr(ctl.Font.Name), App.Path & "\MyAppSettings.dat")
ctl.Font.Charset = ReadFromAppINI(Me.Name & "Control", ctl.Name & " Font_CharSet", ctl.Font.Charset, App.Path & "\MyAppSettings.dat")
ctl.Font.Bold = ReadFromAppINI(Me.Name & "Control", ctl.Name & " Font.Bold", ctl.Font.Bold, App.Path & "\MyAppSettings.dat")
ctl.Font.Italic = ReadFromAppINI(Me.Name & "Control", ctl.Name & " Font.Italic", ctl.Font.Italic, App.Path & "\MyAppSettings.dat")
End If
```



```
Public Function ReadFromAppINI(SectionHeader As String, VarName As String, ByVal Default As String, strFile As String) As String
Dim RetStr As String
RetStr = String(255, Chr(0))
ReadFromAppINI = Left(RetStr, GetPrivateProfileString(SectionHeader, ByVal VarName$, Default, RetStr, Len(RetStr), strFile))
End Function
```



```
Public Function WriteToAppINI(strSection As String, strKeyName As String, strValue As String, strFile As String) As Long
Dim intStatus As Long
On Error GoTo PROC_ERR
intStatus = WritePrivateProfileString(strSection, strKeyName, strValue, strFile)
WriteToAppINI = (intStatus <> 0)
PROC_EXIT:
Exit Function 
PROC_ERR:
MsgBox "Error: " & Err.Number & "   " & Err.Description, , "WriteToAppINI"
Resume PROC_EXIT
End Function
```

Any idea please?

----------


## Krool

Mustaphi, you need to use the unicode API for writing and reading INI.

----------


## Mustaphi

> Mustaphi, you need to use the unicode API for writing and reading INI.


Thank you Krool for the quick reply

Is the Appi included in the Demo?

----------


## Krool

> Thank you for your great work towards improving the community.  I have discovered a minor issue with the Listview control.  To demonstrate, modify your Standard EXE example so that the top right Listview has Multiselect = True. Next scroll to the far bottom right and click with the left button in an empty area as if you were about to create a box to draw a selection around everything in this window.  What happens for me is the mouse jumps to the top left of the screen.  The jump seems to happen in mouse down.  I can move the mouse back down and eventually finish my selection.  I discovered this behavior with the listview set to report but it was much more difficult to reproduce.


Reportedly this issue has been resolved by MS on the 1 May spring update.

----------


## DEXWERX

> Thank you Krool for the quick reply
> 
> Is the Appi included in the Demo?


You need to use the W APIs and the INI file needs to have a Unicode BOM at the beginning as well.

If you don't know how to add a BOM notepad can do it automatically, open up the INI in notepad, click Save As, and change the encoding from ANSI to Unicode.

----------


## Krool

Update released.

It concerns the drop-down in the DTPicker control, though only on comctl version 5.8x and 6.0. Vista+ not affected (>= 6.1)
The bug was that the drop-down does not show at all when having some of the Calendar* properties not at default setting. (e.g. CalendarShowWeekNumbers = True)

The actual bug was a stupidity. The red marked element was missing and has now been added.


```
SendMessage CalendarHandle, MCM_GETMINREQRECT, 0, ByVal VarPtr(WndRect)
```

It resulted in the WndRect struct not properly set and thus sizing the drop-down to zeros.

What was strange though that this bug only affected the OCX version. The Std-EXE version did work.. curious.
And btw that was also the reason it did not come to my attention before.  :Smilie: 
However, it was fixed now in both versions of course.

----------


## Mith

VBCCR15 v1.5.20 (side by side)

some users got the following error message box when starting my app under windows 10:



```
VBCCR15
Run-time-error ´429´
ActiveX component can´t create object
```

This error message displays 2 more times after clicking the OK button.
after that the app shows "Run-time-error ´440 Automation error" and the app GUI never displays.

Any ideas how to fix or debug this problem? 

Does anyone know what kind of objects will be created by VBCCR15 ?

Maybe it is some kind of a dependency problem?

BTW: i cant reproduce this problem by myself using win10...

----------


## Krool

Update released.

AutoSelect property included in the ComboBoxW control.

It mimics certainly the auto-selecting feature of the combo box in the font common dialog box. (as example)

----------


## Krool

Update released.

New common control 'FontCombo' included. Demo usage has been implemented into the RichTextBoxForm.

----------


## christ62

Hi, Good work !
I always use a VM with winXP to VB6 . This code need a COMCTL32.dll V6. But my VM have the 5.82 version. If I copy the v6.10 (from my win10) XP, XP refuses because it is used. Any idea ? Thx

----------


## Karl77

> Demo usage has been implemented into the RichTextBoxForm.


Worth to mention is that this new control provides mechanisms to manage the recently used fonts.

----------


## Semke

> Update released.
> 
> New common control 'FontCombo' included. Demo usage has been implemented into the RichTextBoxForm.


Very Nice, Thanks
when will this be included in the OCX version

----------


## Krool

> when will this be included in the OCX version


The time span get's longer for any next OCX major release as they are not so more new features.
However, I will look forward to bundle in Q3 or latest in Q4 2018.




> Worth to mention is that this new control provides mechanisms to manage the recently used fonts.


A few more words about the new FontCombo control:
The FontCombo is actually a clon of the ComboBoxW control, but trimmed down to it's essential features and needs.
It's also trimmed to a 'read-only' control. Means no .AddItem or changing .List() property.

Also at initial the control is setup with style 2 - FtcStyleDropDownList instead of 0 - FtcStyleDropDownCombo.
And the AutoSelect property is by default set to True. (meaningful for style other than 2 -FtcStyleDropDownList)

The core property are the FontPitch and FontType property which determines what kind of fonts are loaded at init.

Just use the .Text property to read and set the selected font name.

Another core feature is the recent list. By default though the RecentMax property is set to 0 - off.
When set higher than 0 the feature is turned on.
Then whenever the user picks a font from the list it is added into the recent list up to RecentMax.
To know the offset to the core list and to know how many items are in the recent list you can read the RecentCount property.
The RecentBackColor/RecentForeColor is intended to visually seperate the recent list from the core list.

ClearRecent method sets the RecentCount to zero and clears the recent list.
SaveRecent/RestoreRecent receives and sets a variant (string) array. By that you can save a recent list to a file or registry.
It's also possible to restore a recent list by hard code:


```
FontCombo1.RestoreRecent Array("Arial", "MS Sans Serif")
```

----------


## Krool

> Hi, Good work !
> I always use a VM with winXP to VB6 . This code need a COMCTL32.dll V6. But my VM have the 5.82 version. If I copy the v6.10 (from my win10) XP, XP refuses because it is used. Any idea ? Thx


OMG. You can't change the system file.
You can access 5.82 or 6.00 in XP depending if you have an manifest for the app. If you have no clue search around concerning theming and VB6.
You can't use the >=6.10 Vista+ features of comctl32.dll in a XP VM.
Why you don't install the VB6 IDE directly on your Win 10?

----------


## christ62

> Why you don't install the VB6 IDE directly on your Win 10?


Just because, I had done it but in the IDE of Visual Studio 6, I had "jerks" when, by example, I move Controls on form etc...  :Frown:

----------


## Karl77

FONTCOMBO

Small problem

This occurs only if the control is set to RecentMax > 0.

Let's say, the last selected font name was "Zürich".
Then it appears at the top of the list.

If we now press 'End' on the keyboard, the list doesn't scroll down to "Zürich".
It stops at the top, the place where "Zürich" ist found in the recents list.

I would expect that 'End' would go down to the list.

---

Otherwise, a very handy control.
Also it is quite fast, even with a lot of installed fonts in Windows.

Really good to have - thank you.

----------


## Krool

> FONTCOMBO
> 
> Small problem
> 
> This occurs only if the control is set to RecentMax > 0.
> 
> Let's say, the last selected font name was "Zürich".
> Then it appears at the top of the list.
> 
> ...


It's not a problem with the control. It's a event problem in connection with the RichTextBox.
The same problem occurs in the Demo.

The reason is that FontCombo1_Click sets the SelFontName of the RichTextBox which on the other hand fires it's own SelChange event and then again sets the Text of the FontCombo.
In order to avoid this circular thing I added in the Demo (RichTextBoxForm.frm) a Freeze boolean flag: (red marked)


```
Private Sub FontCombo1_Click()
If FontComboFreezeClick = True Then Exit Sub
RichTextBoxFreezeSelChange = True
If FontCombo1.ListIndex > -1 Then RichTextBox1.SelFontName = FontCombo1.Text
RichTextBoxFreezeSelChange = False
End Sub

Private Sub FontCombo1_CloseUp()
RichTextBox1.SetFocus
End Sub

Private Sub RichTextBox1_SelChange(ByVal SelType As Integer, ByVal SelStart As Long, ByVal SelEnd As Long)
If RichTextBoxFreezeSelChange = True Then Exit Sub
If (SelType And RtfSelTypeText) <> 0 Or SelType = RtfSelTypeEmpty Then
    FontComboFreezeClick = True
    If IsNull(RichTextBox1.SelFontName) Then
        FontCombo1.ListIndex = -1
    Else
        FontCombo1.Text = RichTextBox1.SelFontName
    End If
    FontComboFreezeClick = False
End If
End Sub
```

----------


## Karl77

> It's not a problem with the control. It's a event problem in connection with the RichTextBox.


I see.
Now with your 2 variables it works as expected.

Thank you.

----------


## Krool

Feature update for the FontCombo control.

The FontCombo control now has a BuddyControl property which can be set to _another_ FontCombo only.

Example:
a Form has FontCombo1 and FontCombo2.
FontCombo1.BuddyControl is set to FontCombo2.
Thus FontCombo1 will display the font names and FontCombo2 will display the font sizes of the selected font of FontCombo1.
If FontCombo1 changes FontCombo2 will be updated. It's all managed within the control so there is no code effort in the app.

FontCombo2 is then internally marked as "buddied" and thus the RecentMax feature is off and also in case the Style is not List only number input is allowed.

The RichTextBoxForm has been extended to demonstrate this new feature.

----------


## Mustaphi

Krool 

thanks for sharing

----------


## Hosam AL Dein

hi all , does anyone know what is the property ListItemIndices for listview group is used for ?
I was looking for something to act as a summary panel for the listview control and I started playing with methods and properties and I passed by the previous property and I did not know what it is for

----------


## Semke

yesterday I compiled a program using the ocx, (I didn't use a manifest), the buttons (on the toolbar, the only control on the form) were not flat.

am I missing anything?

----------


## Hosam AL Dein

> yesterday I compiled a program using the ocx, (I didn't use a manifest), the buttons (on the toolbar, the only control on the form) were not flat.
> 
> am I missing anything?


External manifests or embedded resource file is essential for visual styles to be applied . OCX only will not give you the visual effect of Windows.

----------


## Semke

> External manifests or embedded resource file is essential for visual styles to be applied . OCX only will not give you the visual effect of Windows.


that's what I thought, I just wanted to confirm. 

thank you

----------


## ScriptBASIC

Hi Krool,

I mention some time ago I would like to use your VBCCR with a OCX as a forms object that is interfaced via a COM/OLE automation and callbacks to the host for event processing. 

I'm happy to say it's working out great using Script BASIC as the host. Here is a thread I have going on the All BASIC Forum

I remember there being two *side-by-side* files besides the VBCCR15.OCX. Are these still needed and if so how are they added to the project? Everything seems fine without them so far.

John




> OCX only will not give you the visual effect of Windows.


Seems to work for me.

----------


## Krool

> hi all , does anyone know what is the property ListItemIndices for listview group is used for ?
> I was looking for something to act as a summary panel for the listview control and I started playing with methods and properties and I passed by the previous property and I did not know what it is for


The description for ListItemIndices property of a Group object says:
_"Returns a reference to a collection containing the indexes to the list items referring to this group. Requires comctl32.dll version 6.0 or higher."_

----------


## Hosam AL Dein

> The description for ListItemIndices property of a Group object says:
> _"Returns a reference to a collection containing the indexes to the list items referring to this group. Requires comctl32.dll version 6.0 or higher."_


thanks a lot

----------


## Hosam AL Dein

> Seems to work for me.


I am not sure of the platform you are on . But , for visual studio 6 , it is necessary to manifest the IDE itself to see visual effects during design time . Also for the EXE it is necessary to include an external manifest or an embedded resource file with manifest contents .
I think this is the general case except if you are having these settings already done or maybe you are judging the case only within design time (assuming you have a manifested IDE) . Is it the case also for EXEs ?

----------


## Hosam AL Dein

Is there a way to detect the column index in listview when clicking and item or subitem ? I came up to hit test . Is there any other way implemented in the current listview and I am missing it ? If not  , Can it be added ? if I may suggest .

----------


## Krool

> Is there a way to detect the column index in listview when clicking and item or subitem ? I came up to hit test . Is there any other way implemented in the current listview and I am missing it ? If not  , Can it be added ? if I may suggest .


A ColumnHeader has a SubItemIndex function. So even when the ColumnHeader orders are changed it will advise you the correct index for accessing the sub items.


```
ListView1.ColumnHeaders(Index).SubItemIndex
```

So you can use this to check/compare with subitem index to the corresponding column index.

----------


## Hosam AL Dein

> A ColumnHeader has a SubItemIndex function. So even when the ColumnHeader orders are changed it will advise you the correct index for accessing the sub items.
> 
> 
> ```
> ListView1.ColumnHeaders(Index).SubItemIndex
> ```
> 
> So you can use this to check/compare with subitem index to the corresponding column index.


It seems I could not form my question clearly .

how can I implement this in the event (item_click) . It has no arguments to deal with column headers . I am mainly asking for how to get the index of the column through the click position on a listview item . The code you provided krool requires the index of the column as input while I want it to be retrieved .

To make it more clear , my main goal is :
when the user right-clicks the listview or accurately an item , I need to extract what column this click was over , to get to the text under the mouse whether it was the first item or another subitem . 
I am limited to click event , mouse-up and mouse-down events to detect the mouse button since I want "right click" .

Thanks in advance krool .

----------


## gilman

> Is there a way to detect the column index in listview when clicking and item or subitem ? I came up to hit test . Is there any other way implemented in the current listview and I am missing it ? If not  , Can it be added ? if I may suggest .


Add this code to the MainForm:

```
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce
'               or publish this code on any web site,
'               online service, or distribute as source
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
```

I've adapted the original code from http://vbnet.mvps.org/index.html?cod.../lvhittest.htm

----------


## gilman

> Is there a way to detect the column index in listview when clicking and item or subitem ? I came up to hit test . Is there any other way implemented in the current listview and I am missing it ? If not  , Can it be added ? if I may suggest .


Add this code to the MainForm:

```
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce
'               or publish this code on any web site,
'               online service, or distribute as source
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
```

I've adapted the original code from http://vbnet.mvps.org/index.html?cod.../lvhittest.htm

Edit:
I deleted the original code due to the copyright notice, but you can adapt the code from the link

----------


## Krool

In the ListView is an in-built FindSubItem function. There you can pass byRef a SubItem index variable.

----------


## Karl77

Thank you for the 21-Sep-2018 enhancement.
The toolbar performance boost is very important for my app.

----------


## ScriptBASIC

> I think this is the general case except if you are having these settings already done or maybe you are judging the case only within design time (assuming you have a manifested IDE) . Is it the case also for EXEs ?


Script BASIC is an interpreter. The Windows (non-console) version has a resource manifest. If I run the same program using the console version of Script BASIC it looks like Win2K.

----------


## OldClock

I would like to start using VBCCR in a large existing project. Let's start with the VBCCR ListView for example. The project currently uses both "Microsoft Windows Common Controls 6.0 (SP6)" and "Microsoft Windows Common Controls-2 6.0 (SP6)".

Steps:
1. Download the ComCtlsDemo.zip attachment from the first post.
2. Copy ComCtlsDemo\OLEGuids\OLEGuids.tlb to C:\Windows\system32
3. In the VB6 IDE, open the project, go to Project -> References... -> Browse, select C:\Windows\system32\OLEGuids.tlb , tick "OLE Guid and interface definitions".

What now?

----------


## Krool

Update released.

Included 'VirtualListItems' that returns a collection of virtual list items.
This is actually a limited/stripped down and mostly read-only version of the normal 'ListItems'. ('ListItems' feature is disabled when VirtualMode is turned on.)
So when migrating a project from non-virtual to virtual this addition will for sure make things easier as you don't need to reference everywhere to the virtual data source. So you can then go here the re-direction of retrieving for example a text in 'VirtualListItems' which then fires the normal GetVirtualItem event.

But most important you can control there some item states. For example the Selected state of an arbitrary index.
Due to 'ListItems' not available for virtual mode list views you had to use some API. Now that's not necessary anymore.

The Item property only accepts an Index As Long. No AddItem because everything remains controlled by the VirtualItemCount property. The Count property here is just for completeness and returns the same as VirtualItemCount.

Again: Nothing was changed in the general virtual mode processing. This is just an addition for comfort and ease of migration. And to avoid some extra API work when going the virtual way. Also events like ItemClick will work in virtual mode. For there 'LvwListItem' will work as before even in virtual mode within these events.




> I would like to start using VBCCR in a large existing project.


For large existing projects I would recommend to use the ActiveX version of VBCCR in a reg-free way.
Doing this way you don't have to load so much components into your large project. Also it is IDE-safe to use ActiveX version.
After that you open each .frm file and replace all occurrences of 'ComctlLib' to 'VBCCR15' for example.
You may also need to replace other stuff, like enum constants or class objects. For example 'ComctlLib.ListItem' will be 'VBCCR15.*Lvw*ListItem'.

----------


## Krool

VBCCR16.OCX released.

----------


## Hosam AL Dein

Hi krool , 
This issue is under version 1.6 only .
for ComboBoxW , If the style is dropdown list and the control got focus , it does not show the focus rectangle over the combobox . This was not the behavior for the previous versions . Is it right or I am missing something ?

----------


## Krool

> Hi krool , 
> This issue is under version 1.6 only .
> for ComboBoxW , If the style is dropdown list and the control got focus , it does not show the focus rectangle over the combobox . This was not the behavior for the previous versions . Is it right or I am missing something ?


You have a visual styles manifest, right?
Did you call SetupVisualStyles on the Form during Form_Load ? (And InitVisualStyles during Sub Main)

----------


## Hosam AL Dein

> You have a visual styles manifest, right?


yes , I am using a manifest and it is applying the visual styles properly on all other controls .




> Did you call SetupVisualStyles on the Form during Form_Load ? (And InitVisualStyles during Sub Main)


I am using the OCX version

----------


## Krool

> yes , I am using a manifest and it is applying the visual styles properly on all other controls .
> 
> 
> 
> I am using the OCX version


Doesnt' matter. InitVisualStyles and SetupVisualStyles also need to be applied when using OCX.
For me it's not possible to integrate into OCX.
Its responsibility of the application who use the OCX.

----------


## Hosam AL Dein

> Doesnt' matter. InitVisualStyles and SetupVisualStyles also need to be applied when using OCX.
> For me it's not possible to integrate into OCX.
> Its responsibility of the application who use the OCX.


this is the first time to know this point . I was using all the previous versions without these functions and it worked a bit fine except some casual crashes in IDE . This maybe the reason for these crashes , I will give it a try and report here .

Before this reply , I was suspicious about the way I upgraded the ocx from 15 to 16 and I was intending to ask about it also .
I have opened all the forms and modules and replaced VBCCR15 with VBCCR16 . Is this the proper way for upgrading from one version to another ?

----------


## Hosam AL Dein

I am developing a usercontrol which has a textboxw . Should I call setupvisualstyles in the Initialize event as well as the form holding the usercontrol ? If yes , how ? while setupvisualstyles requires a form as a parameter . If no , How are visualstyles properly applied in a usercontrol ?

I am asking this question because I have casual IDE crashes when dealing with the user control which contains a VBCCR textbox . I am suspecting the _hwnd_ and _hwndusercontrol_ and also visual styles functions calling you provided in the previous post .

For focus rectangle , the problem is solved by adding _visualstyles_ and _common_ modules and calling the functions in main and in each form load event . Thanks a lot

----------


## Karl77

COMPILER QUESTION

I have my 'own' VBCCR OCX, made from the original Exe sources + some extensions.
Same structure as with the original OCX version.
The OCX is quite large - no problem so far.

Now I'm tuning my app for performance.
Out of curiosity, I compiled the OCX as P-code.
It is a lot smaller.

And the P-code version has no performance advantage.
I didn't really expect it, but wanted to try.
Also it is _not slower_.

Can it harm somehow to have the OCX as P-code?

Thank you.

----------


## Karl77

> Should I call setupvisualstyles in the Initialize event as well as the form holding the usercontrol ? If yes , how ? while setupvisualstyles requires a form as a parameter . If no , How are visualstyles properly applied in a usercontrol ?


No.
If you use the OCX version no need to call SetupVisualStyles at all.
All you need is a manifest for the app.

Rem.:
You won't see any VisualStyles in the IDE.
Unless you have a patched VB6.EXE.

----------


## Krool

> No.
> If you use the OCX version no need to call SetupVisualStyles at all.
> All you need is a manifest for the app.
> 
> Rem.:
> You won't see any VisualStyles in the IDE.
> Unless you have a patched VB6.EXE.


Even in OCX you shall call SetupVisualStyles during Form_Load event. It fixes several stuff for visualstyles in general, e.g. focus rects etc.

----------


## Hosam AL Dein

> No.
> If you use the OCX version no need to call SetupVisualStyles at all.
> All you need is a manifest for the app.
> 
> Rem.:
> You won't see any VisualStyles in the IDE.
> Unless you have a patched VB6.EXE.


I already have the IDE manifested and all works fine . I am asking based on krool note about calling visualsyles functions in the forms and main method . I am asking about usercontrols themselves

----------


## Hosam AL Dein

> Even in OCX you shall call SetupVisualStyles during Form_Load event. It fixes several stuff for visualstyles in general, e.g. focus rects etc.


I followed the info you provided krool , and the problem is solved . But I encounter casual crashes in IDE in the forms that contain a usercontrol which has a VBCCR textbox . I am wondering if this point could be a reason of theses crashes ? 
and what about the proper way for upgrading ?

----------


## Krool

> I followed the info you provided krool , and the problem is solved . But I encounter casual crashes in IDE in the forms that contain a usercontrol which has a VBCCR textbox . I am wondering if this point could be a reason of theses crashes ? 
> and what about the proper way for upgrading ?


Do you have a Sub Main which calls InitVisualStyles prior to first form load?
Yes, your upgrading is ok. Just replace in notepad from VBCCR15 to VBCCR16.

----------


## Karl77

> Even in OCX you shall call SetupVisualStyles during Form_Load event. It fixes several stuff for visualstyles in general, e.g. focus rects etc.


Thanks for the correction.
I couldn't see any difference in behavior with or without the call.

EDIT:
Now I see the difference.

----------


## MountainMan

Krool,

I am looking at VBCCR16 in the Object Browser and I do not see SetupVisualStyles or InitVisualStyles as procedures I can call. Also, neither of these show up anywhere in the source code provided with the OCX. I don't mind calling them but I can't find them. Where are they?

----------


## MountainMan

Dbl post

----------


## Krool

......
Look in ComCtlsDemo in first post for VisualStyles.bas

----------


## MountainMan

Krool,

You are saying we need to use InitVisualStyles in Procedure Main before showing a form. Okay. How about SetupVisualStyles? It is in VisualStyles.bas in the demo program (no OCX)  and it looks like you put it as the first line of code in each of the forms. However, it is not present in the OCX version so do we assume that it got called internally in your OCX for each form or that is isn't needed or something else. if we should call it in the Form_Load procedure, do we nneed to put SetupVisualStyles into a different module or use VisualStyles.bas?

----------


## MountainMan

Krool,

You are saying we need to use InitVisualStyles in Procedure Main before showing a form. Okay. How about SetupVisualStyles? It is in VisualStyles.bas in the demo program (no OCX)  and it looks like you put it as the first line of code in each of the forms. However, it is not present in the OCX version so do we assume that it got called internally in your OCX for each form or that is isn't needed or something else. if we should call it in the Form_Load procedure, do we nneed to put SetupVisualStyles into a different module or use VisualStyles.bas?

----------


## Krool

The OCX is a isolated component, it can't access any form of the application that uses it.

VisualStyles is a Std-EXE process topic and has nothing todo with the OCX.
You can use the OCX in VBA with no theming at all.
Or use in Vb6 with no theming at all.

If you decide to theme your Vb6 exe you have to deal with issues like everybody else exe.

For example, you use a vb6 exe with theming manifest and only use vb6 native controls (No OCX) then you will notice that focus rects are not shown.
It's complete independent... i hope you got it now.

----------


## MountainMan

That makes sense but it also brings up three questions that i have been wondering about for a while.

1 - In the Std-Exe demo there is no manifest included like there is for the OCX version. Does the Std-Exe version do theming and if so, how does it do it without a manifest?

2 - How difficult would it be to make a same program using the OCX version that is basically the same as the Std-Exe demo? That would be a really good sample so that we could figure out what we have to do with the OCX version to get the same results as the Std-Exe version (such as needing to use SetUpVisualStyles at the top of each form) and vice versa.

3 - Aren't the MS Office products (Excel, Word, etc.) themed? If our VBA code is basically children of the top level Office programs why aren't they themed as well?

Thanks.

----------


## Krool

> 1 - In the Std-Exe demo there is no manifest included like there is for the OCX version. Does the Std-Exe version do theming and if so, how does it do it without a manifest?


The Std-EXE demo has a manifest. Look in the Resources subfolder for Resources.res.




> 2 - How difficult would it be to make a same program using the OCX version that is basically the same as the Std-Exe demo? That would be a really good sample so that we could figure out what we have to do with the OCX version to get the same results as the Std-Exe version (such as needing to use SetUpVisualStyles at the top of each form) and vice versa.


There are basically the same. For both usages you need to include manifest and fix visual styles issues.




> 3 - Aren't the MS Office products (Excel, Word, etc.) themed? If our VBA code is basically children of the top level Office programs why aren't they themed as well?


The office products (EXCEL.EXE etc.) have no manifest therefore when you put a VBCCR control on a UserForm it won't be themed.
The intrinsic controls which the office product are used are basically super-classed owner drawn styled controls. Therefore it looks like there are somewhat themed, but not same theming as VBCCR.

----------


## Hosam AL Dein

> Do you have a Sub Main which calls InitVisualStyles prior to first form load?


yes , I placed it there

----------


## Hosam AL Dein

one more problem , I think there is something I am missing . As I mentioned above , I am using the ocx . 
another issue showed up . For all the controls ,they dont initiate click event at the first hit and require two hits . The first one sets the focus the second one is for click .
I have placed _InitVisualStyles_  in my main sub and called _setupvisualstyles_ in the form load .

----------


## Hosam AL Dein

sorry for double posting 

one more problem , I think there is something I am missing . As I mentioned above , I am using the ocx . 
another issue showed up . For all the controls ,they dont initiate click event at the first hit and require two hits . The first one sets the focus the second one is for click .
I have placed _InitVisualStyles_  in my main sub and called _setupvisualstyles_ in the form load .

----------


## Hosam AL Dein

the previous problem does not occur in the exe , it happens only in IDE

----------


## Krool

Hosam AL Dein,

I can't help you by magic.
Please isolate your issue in a demo project with no other dependencies than VBCCR then I can try to help.
Thanks

----------


## MountainMan

Krool,

Back to the visual styles of the OCX version. When I look in the code for forms in ComCtlsDemo I find the first line is always a call to SetupVisualStyles which is in VisualStyles.bas in the Common folder. However, when I look at the code included with the OCX version I find a file named VisualStyles.bas but it is a very abbreviated version of the VisualStyles.bas and it doesn't have a Sub named SetupVisualStyles.  If I understand your previous posts right, we still need to include the code from this sub in each of our forms in order to get themes to work properly with our forms. Is this correct?

Also, I see that the 2 files in the Common folder for the OCX (Common.bas and VisualStyles.bas) are both needed to compile VBCCR16 into VBCCR16.OCX. Other than what is mentioned above regarding possible use of the sub SetupvisualStyles (which isn't in either of these modules anyway), are there any routines in either of the two subs that you recommend/require we use to be able to use your controls and get the theming effects?

----------


## Karl77

> For all the controls ,they dont initiate click event at the first hit and require two hits . The first one sets the focus the second one is for click .


I had this as well.

It came up from time to time, and the only cure was a reboot.
But even then it came back sooner or later.
The effect is seen less often since all Comctl constants were replaced by their VBCCR equivalents.
Sounds unlikely, but that's what I experienced.

The effect still comes up, but it takes some hours or days.
I think the cause could be a GDI or other memory leak?

@Krool
No chance to bake a demo app showing this.
I tried, but 'of course' the problem doesn't show in a simple small project.
That's why I never mentioned it.
Fortunately, the problem is in the IDE only.
EXE is ok.

----------


## Krool

> Krool,
> 
> Back to the visual styles of the OCX version. When I look in the code for forms in ComCtlsDemo I find the first line is always a call to SetupVisualStyles which is in VisualStyles.bas in the Common folder. However, when I look at the code included with the OCX version I find a file named VisualStyles.bas but it is a very abbreviated version of the VisualStyles.bas and it doesn't have a Sub named SetupVisualStyles.  If I understand your previous posts right, we still need to include the code from this sub in each of our forms in order to get themes to work properly with our forms. Is this correct?
> 
> Also, I see that the 2 files in the Common folder for the OCX (Common.bas and VisualStyles.bas) are both needed to compile VBCCR16 into VBCCR16.OCX. Other than what is mentioned above regarding possible use of the sub SetupvisualStyles (which isn't in either of these modules anyway), are there any routines in either of the two subs that you recommend/require we use to be able to use your controls and get the theming effects?


Correct. The OCX has just an trimmed down version of VisualStyles.bas. It has only functions to determine whether theming is on or not to control if some features are available or not.
In your Std-Exe you shall use the full VisualStyles.bas and apply the InitVisualStyles and SetupVisualStyles accordingly.

----------


## Semke

> Correct. The OCX has just an trimmed down version of VisualStyles.bas. It has only functions to determine whether theming is on or not to control if some features are available or not.
> In your Std-Exe you shall use the full VisualStyles.bas and apply the InitVisualStyles and SetupVisualStyles accordingly.


I have been using the ocx for some time now. I never had any problems, I never used  the InitVisualStyles and SetupVisualStyles.
From what I am reading here, it looks like I have to include the full VisualStyles.bas in every project. is this correct? if so for what purpose.
please correct me If I misunderstood.

----------


## DEXWERX

> I have been using the ocx for some time now. I never had any problems, I never used  the InitVisualStyles and SetupVisualStyles.
> From what I am reading here, it looks like I have to include the full VisualStyles.bas in every project. is this correct? if so for what purpose.
> please correct me If I misunderstood.


It's not required. It's only if you want to fix some visual inconsistencies, like the aforementioned focus rects.
(Some built in windows dialogs don't even show proper focus)

----------


## VBClassic04

Sorry if this has already been discussed but
in the RichTextBox Control the KeyUp and KeyDown events never return
vbAltMask.  Shift and Control work fine.

----------


## Krool

> Sorry if this has already been discussed but
> in the RichTextBox Control the KeyUp and KeyDown events never return
> vbAltMask.  Shift and Control work fine.


Oh. Yes, it's a missing feature.
The following red marked code needs to be included in the key handlers in TextBoxW and RichtTextBox. (WindowProcControl)


```
    Case WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP
        Dim KeyCode As Integer
        KeyCode = wParam And &HFF&
        If wMsg = WM_KEYDOWN Or wMsg = WM_SYSKEYDOWN Then
            RaiseEvent KeyDown(KeyCode, GetShiftStateFromMsg())
        ElseIf wMsg = WM_KEYUP Or wMsg = WM_SYSKEYUP Then
            RaiseEvent KeyUp(KeyCode, GetShiftStateFromMsg())
        End If
        Select Case wMsg
            Case WM_KEYDOWN, WM_KEYUP
                [...]
                TextBoxCharCodeCache = ComCtlsPeekCharCode(hWnd)
        End Select
        wParam = KeyCode
```

Also other controls might be affected such as VBFlexGrid. But not all VB intrinsic controls show vbAltMask. E.g. VB.ListBox won't show vbAltMask.
I need to investigate further before releasing fixes.
Also IOleInPlaceActiveObjectVB::TranslateAccelerator might needs to be included with those WM_SYS*

----------


## VBClassic04

Many thanks Krool. The changes worked perfectly.
I'm working on a text editor and I added these
routines to the control.



```
Private Const EM_LINEFROMCHAR As Long = &HC9 '**added
Private Const EM_GETRECT As Long = &HB2      '**
'....
Public Sub GoToLine(ByVal Line As Long, Optional ByVal Column As Long = 0)
 Dim LIndex As Long
 Dim LLength As Long
 If (Line >= 0) And (Line <= GetLineCount - 1) Then
  LIndex = SendMessage(RichTextBoxHandle, EM_LINEINDEX, Line, ByVal 0&)
  LLength = Len(GetLine(Line))
  If Column > LLength Then Column = LLength
  SetRange LIndex, Column
  Call SendMessage(RichTextBoxHandle, EM_SCROLLCARET, 0&, 0&) 'brings the line into view
  Call SendMessage(RichTextBoxHandle, EM_SETSEL, -1&, 0&) 'unselect
 End If
End Sub

Private Sub SetRange(ByVal SelSt As Long, ByVal SelLen As Long)
 Dim tChrRng As RECHARRANGE
 tChrRng.Min = SelSt
 tChrRng.Max = SelSt + SelLen
 Call SendMessage(RichTextBoxHandle, EM_EXSETSEL, 0&, tChrRng)
End Sub

Public Function CurrLineLength() As Long
 CurrLineLength = SendMessage(RichTextBoxHandle, EM_LINELENGTH, SelStart, ByVal 0&)
End Function

Public Sub SelectAll()
 Call SendMessage(RichTextBoxHandle, EM_SETSEL, 0&, ByVal -1&)
End Sub

Public Function CurrentLineNumber() As Long
 CurrentLineNumber = SendMessage(RichTextBoxHandle, EM_LINEFROMCHAR, SelStart, ByVal 0&)
End Function

Public Function CurrentColumnNumber() As Long
 Dim LIndex As Long
 Dim Line As Long
 Line = CurrentLineNumber
 LIndex = SendMessage(RichTextBoxHandle, EM_LINEINDEX, Line, ByVal 0&)
 CurrentColumnNumber = SelStart - LIndex
End Function

Public Function FirstVisibleLine() As Long
 FirstVisibleLine = SendMessage(RichTextBoxHandle, EM_GETFIRSTVISIBLELINE, 0&, ByVal 0&)
End Function
Public Function LastVisibleLine() As Long
 Dim LIndex As Long
 Dim PT As POINTAPI
 Dim RC As RECT
 Call SendMessage(RichTextBoxHandle, EM_GETRECT, 0&, RC)
 PT.X = 0
 PT.Y = RC.Bottom
 LIndex = SendMessage(RichTextBoxHandle, EM_CHARFROMPOS, 0&, PT)
 LastVisibleLine = SendMessage(RichTextBoxHandle, EM_EXLINEFROMCHAR, 0&, ByVal LIndex)
End Function

Public Function VisibleLineCount() As Long
 VisibleLineCount = LastVisibleLine - FirstVisibleLine + 1
End Function
```

----------


## Krool

> The changes worked perfectly.


Update released.
WM_SYSKEYDOWN/WM_SYSKEYUP is now considered on all KeyDown/KeyUp events of every control affected.
IOleInPlaceActiveObjectVB::TranslateAccelerator was not concerned and it made no sense at all to consider WM_SYSKEYDOWN/WM_SYSKEYUP also there.

Thanks again for bringing this up.

EDIT:
Your 'GoToLine' is very similar or equal to the 'ScrollToLine' in-built function in the RichTextBox.

----------


## VBClassic04

Mr Krool, another question about the RichTextBox control.
I would expect that using the SelText method would make
CanUndo be true.  However, it does not.  The Change Event
is triggered as expected.

Perhaps something to do with the SetEventMask call in the
CreateRichTextBox routine?




```
Private Sub cmdRepl_Click()      'button Replace
 RTF.SelText = txtRepl.Text
 Debug.Print RTF.CanUndo      'always false
 cmdFind_Click                      'find next match
End Sub
```

----------


## Semke

> Update released.
> WM_SYSKEYDOWN/WM_SYSKEYUP is now considered on all KeyDown/KeyUp events of every control affected.
> IOleInPlaceActiveObjectVB::TranslateAccelerator was not concerned and it made no sense at all to consider WM_SYSKEYDOWN/WM_SYSKEYUP also there.
> 
> Thanks again for bringing this up.
> 
> EDIT:
> Your 'GoToLine' is very similar or equal to the 'ScrollToLine' in-built function in the RichTextBox.


is the ocx also updated?

----------


## Krool

> is the ocx also updated?


Yes, of course.

----------


## lrd_VB6

Hello,

Here is the update of my converter for the latest version of VBCCRxx (16).
Translates your code using VBCCR from 11 to 15 for version 16.
All converted files are saved (.bak) as a precaution.

When you have a project of 10000 lines (and more), it makes the task easier.  :Wink: 

VBCCRvxx_converter.zip

Good work

----------


## Karl77

DARK MODE QUESTION

Now we have a bunch of very fine and usable controls.
Invaluable for today's VB6 apps.
All the controls do look and work good on white or light gray background.

Nowadays more and more applications with a dark mode come up. 
I'm not a big fan, it feels a bit like in MS-DOS times.
My personal taste is not important in this respect.
Some users do want a dark UI.

Generally not a big deal to switch certain colors.
Unfortunately, most VBCCR (~=comctl32) controls don't offer such color properties.
Some do, e.g. the toolbar.

Would it be possible to tweak the other VBCCR controls somehow to use the wanted colors?

Thank you.

----------


## Eduardo-

> Mr Krool, another question about the RichTextBox control.
> I would expect that using the SelText method would make
> CanUndo be true.  However, it does not.  The Change Event
> is triggered as expected.
> 
> Perhaps something to do with the SetEventMask call in the
> CreateRichTextBox routine?
> 
> 
> ...


Hello Krool. I recently had a similar issue and found a solution for changing text by code and still letting the user to undo the change.

First the text in the control that has to be replaced must be selected (using .SelStart and .SelLenght or by other means)


```
Const EM_REPLACESEL As Long = &HC2

SendMessage txtCtl.hWnd, EM_REPLACESEL, ByVal 1&, ByVal strNewText
```

HTH

----------


## Hosam AL Dein

> DARK MODE QUESTION
> 
> Now we have a bunch of very fine and usable controls.
> Invaluable for today's VB6 apps.
> All the controls do look and work good on white or light gray background.
> 
> Nowadays more and more applications with a dark mode come up. 
> I'm not a big fan, it feels a bit like in MS-DOS times.
> My personal taste is not important in this respect.
> ...


Totally agree with this point . I am  so concerned of the GUI look and feel . Thankfully ,the folks on the forum here brought up many controls supporting this approach . But , as you mentioned karl , VB6 still lacking some points to fully support the approach you are aiming . But I will add 2 points , The colors issue only will not get us there , The more important requirements for controls are :

1- Being flat
2- Accepting Png ( or mainly support transparency with no restrictions ) in Icons and normal images .

These points are fulfilled in some user controls here in the forum but it definitely will be great to add it to Krool VBCCR .
I can participate in this project with some user controls I have made but not in VBCCR itself . It has techniques I never practiced before .

----------


## Hosam AL Dein

*Sorry for double posting 
*





> DARK MODE QUESTION
> 
> Now we have a bunch of very fine and usable controls.
> Invaluable for today's VB6 apps.
> All the controls do look and work good on white or light gray background.
> 
> Nowadays more and more applications with a dark mode come up. 
> I'm not a big fan, it feels a bit like in MS-DOS times.
> My personal taste is not important in this respect.
> ...


Totally agree with this point . I am  so concerned of the GUI look and feel . Thankfully ,the folks on the forum here brought up many controls supporting this approach . But , as you mentioned karl , VB6 still lacking some points to fully support the approach you are aiming . But I will add 2 points , The colors issue only will not get us there , The more important requirements for controls are :

1- Being flat
2- Accepting Png ( or mainly support transparency with no restrictions ) in Icons and normal images .

These points are fulfilled in some user controls here in the forum but it definitely will be great to add it to Krool VBCCR .
I can participate in this project with some user controls I have made but not in VBCCR itself . It has techniques I never practiced before .

----------


## DEXWERX

Not speaking for KROOL, but I think DARK MODE is a bit outside the scope of VBCCR. VBCCR at it's heart is an implementation of the already existing themed *Windows Common Controls* (Comctl32.dll). 

If the Common Controls don't support Dark Mode, how would you propose VBCCR would?

All the controls would have to be created from scratch, custom drawn, without using Comctl32. 
What you're proposing would have to be a completely separate project, possibly much larger in scope than VBCCR, specifically targeting a UWP design language.

Who wants to get started on the VBUWPUI project?  :Smilie:  

https://developer.microsoft.com/en-u...ws/apps/design

https://docs.microsoft.com/en-us/win...to-uwp-enhance

I would think the renderer would be based on Direct2D, similar to the XAML compositer.
https://stackoverflow.com/questions/...l-in-win32-app

----------


## Hosam AL Dein

> Not speaking for KROOL, but I think DARK MODE is a bit outside the scope of VBCCR. VBCCR at it's heart is an implementation of the already existing themed *Windows Common Controls* (Comctl32.dll). 
> 
> If the Common Controls don't support Dark Mode, how would you propose VBCCR would?
> 
> All the controls would have to be created from scratch, custom drawn, without using Comctl32. 
> What you're proposing would have to be a completely separate project, possibly much larger in scope than VBCCR, specifically targeting a UWP design language.
> 
> Who wants to get started on the VBUWPUI project?  
> 
> ...


Can these controls be adopted in VB6  ? If yes , I will be learning the language tomorrow  :Eek Boom: 

I am close to the concept found there  :big yellow:

----------


## DEXWERX

more leads on the Acrylic effect and using *SetWindowCompositionAttribute()*
https://www.reddit.com/r/Windows10/c...d_it_can_have/
https://stackoverflow.com/questions/...-on-windows-10

Hosting XAML controls in a win32 app --> https://docs.microsoft.com/en-us/win...-host-controls
https://docs.microsoft.com/en-us/win...ml-hosting-api
https://github.com/clarkezone/cppwin...mlIslandsWin32

----------


## Hosam AL Dein

I am surprised https://github.com/Microsoft/Desktop...es/VB6withXaml . It can be done !

----------


## VBClassic04

A suggested correction to the Find method of the RichTextBox Control.
This allows searching in the Up direction.



```
Public Function Find(ByVal Text As String, Optional ByVal Min As Long, Optional ByVal Max As Long = -1, Optional ByVal Options As RtfFindOptionConstants) As Long
 If RichTextBoxHandle <> 0 Then
  Dim REFTEX As REFINDTEXTEX, dwOptions As Long
  With REFTEX
   With .CharRange
    If Min >= 0 Then
     .Min = Min
    Else
     Err.Raise 380
    End If
    If Max >= -1 Then
     .Max = Max
    Else
     Err.Raise 380
    End If
   End With
   .lpstrText = StrPtr(Text)
   Const FR_DOWN As Long = &H1
   If Min < Max Then                             '********** added
    dwOptions = FR_DOWN
   End If                                              '**********added
   If (Options And RtfFindOptionWholeWord) <> 0 Then dwOptions = dwOptions Or FR_WHOLEWORD
   If (Options And RtfFindOptionMatchCase) <> 0 Then dwOptions = dwOptions Or FR_MATCHCASE
   Find = SendMessage(RichTextBoxHandle, EM_FINDTEXTEX, dwOptions, ByVal VarPtr(REFTEX))
   If (Options And RtfFindOptionNoHighlight) = 0 And Find <> -1 Then SendMessage RichTextBoxHandle, EM_EXSETSEL, 0, ByVal VarPtr(.CharRangeText)
  End With
 End If
End Function
```

----------


## VBClassic04

BTW, Edwardo's post about SelText in the RichTextBox Control fixed the undo problem

----------


## Krool

> I think DARK MODE is a bit outside the scope of VBCCR.


I agree. VBCCR should not be the solution for everything. It is intended to get rid of the old OCX dependencies and to support Unicode. (and more handy, bugfixes, features etc..)
If new "modern" UI is needed then another alternative approach is better. (without comct32.dll)




> A suggested correction to the Find method of the RichTextBox Control.
> This allows searching in the Up direction.
> 
> 
> 
> ```
> Public Function Find(ByVal Text As String, Optional ByVal Min As Long, Optional ByVal Max As Long = -1, Optional ByVal Options As RtfFindOptionConstants) As Long
>  If RichTextBoxHandle <> 0 Then
>   Dim REFTEX As REFINDTEXTEX, dwOptions As Long
> ...


You can search up also without any modification.
Example in RichTextBoxForm:


```
If (CommonDialogFind.Flags And CdlFRDown) = CdlFRDown Then
    RetVal = RichTextBox1.Find(CommonDialogFind.FindWhat, RichTextBox1.SelStart + RichTextBox1.SelLength, , Options)
Else
    RetVal = RichTextBox1.Find(CommonDialogFind.FindWhat, , RichTextBox1.SelStart, Options)
End If
```

However, I might consider including an 'RtfFindOptionUp' or 'RtfFindOptionReverse'. When flag is set, no FR_DOWN (default) will be set.

But, I can't include your addition as it changes behavior which some apps does not expect. (compatibility)




> BTW, Edwardo's post about SelText in the RichTextBox Control fixed the undo problem


The solution is just to pass 1 in wparam on EM_REPLACESEL.
MSDN:
_wParam
 Specifies whether the replacement operation can be undone. If this is TRUE, the operation can be undone. If this is FALSE , the operation cannot be undone._

It seems the "MS RichTextBox" (RICHTX32.OCX) also seems to trigger CanUndo on .SelText.
So, in the next update I will change wparam from 0 to 1 on EM_REPLACESEL. (for both, RichTextBox and TextBoxW)

EDIT: EM_REPLACESEL fix released.

----------


## Eduardo-

> It seems the "MS RichTextBox" (RICHTX32.OCX) also seems to trigger CanUndo on .SelText.
> So, in the next update I will change wparam from 0 to 1 on EM_REPLACESEL. (for both, RichTextBox and TextBoxW)


I tested it and the standard textbox doesn't allow to undo the action after a selection is replaced by code, unlike the RichTextBox.

----------


## Krool

> I tested it and the standard textbox doesn't allow to undo the action after a selection is replaced by code, unlike the RichTextBox.


Maybe because the MS RichTextBox has Undo and Redo methods, do they decided that SelText triggers Undo.
Whereas standard TextBox has no duch methods there was no "need" that SelText triggers something.
Anyhow, my TextBoxW has just like RichTextBox Undo method, so it makes sense or does not harm when SelText triggers Undo. Or?

----------


## Eduardo-

> Maybe because the MS RichTextBox has Undo and Redo methods, do they decided that SelText triggers Undo.
> Whereas standard TextBox has no duch methods there was no "need" that SelText triggers something.
> Anyhow, my TextBoxW has just like RichTextBox Undo method, so it makes sense or does not harm when SelText triggers Undo. Or?


Yes Krool, that makes sense.

----------


## Karl77

> Not speaking for KROOL, but I think DARK MODE is a bit outside the scope of VBCCR. VBCCR at it's heart is an implementation of the already existing themed *Windows Common Controls* (Comctl32.dll). 
> If the Common Controls don't support Dark Mode, how would you propose VBCCR would?


Dex, that was a _question_, not a proposal.
My question came up because Krool achieved some interesting things like transparent toolbars.




> All the controls would have to be created from scratch, custom drawn, without using Comctl32.


Too much effort for a small advantage.

Perhaps one day in a newer comctl32 we'll find a 'color set' property...

----------


## DEXWERX

> Perhaps one day in a newer comctl32 we'll find a 'color set' property...


One can hope, considering most back office / data type GUI's are still based on common controls.
It's hard to say given all the effort that's been invested in UWP.

----------


## Karl77

TEXTBOXW IN UC QUESTION

The effect is seen in the IDE only.

When I place an intrinsic textbox in a usercontrol, the textbox is inactive when the usercontrol is placed on a form.
When I do the same with a TextBoxW it is active.
Means I can move the cursor, type text etc.
This is not only a cosmetic issue, it is cumbersome to select such a UC in the IDE.

To retrace:
Make a new project, and load the VBCCR component.
Make a new UC, and place a TextBoxW on it.
No additional code.
Place this UC on a form.
See the TextBoxW in action.
Make a new UC, and place an intrinsic textbox on it.
Place this 2nd UC on a form.
See that that textbox is inactive.

How can we get the same behavior as with the intrinsic textbox?

Thank you

----------


## Krool

> TEXTBOXW IN UC QUESTION
> 
> The effect is seen in the IDE only.
> 
> When I place an intrinsic textbox in a usercontrol, the textbox is inactive when the usercontrol is placed on a form.
> When I do the same with a TextBoxW it is active.
> Means I can move the cursor, type text etc.
> This is not only a cosmetic issue, it is cumbersome to select such a UC in the IDE.
> 
> ...


I can't replicate this.  :Confused:  I tested with OCX and Std-EXE version.. (at least on XP and 7)

----------


## Karl77

> I can't replicate this.  I tested with OCX and Std-EXE version.. (at least on XP and 7)


Now I wanted to throw together a small sample, and I can't replicate as well.
Nothing happened in the meantime, only a PC standby.

The small problem bothered me for so long, and now it is solved automatically.
I don't understand.

I'll watch more closely to know when the problem occurs and come back (or not).

Thanks for your effort

*EDIT:*

The effect is back again.
Unfortunately, I have no clue what happened.
A restart of the IDE cures the symptom.
After a while it comes back.

Krool, do you have an idea what I should check?
(There is no code in the UC that I test with.)


*EDIT2:*
Short after the UC issue an additional issue came up.
Hosam already reported it in #2047.
It's about command buttons don't react on the first click.
Perhaps this triggers your fantasy?

----------


## Krool

Internal improvement in the CommonDialog class for ShowPrinterEx function.

Prior to this update a WH_CALLWNDPROCRET hook for ShowPrinterEx (when 'HookEvents' = True) was used. (in order to raise InitDialog)
Now a more effective (no hook) lightweight IPrintDialogCallback is used to raise the InitDialog.
If needed in future, more features related to IPrintDialogCallback (and possibly IPrintDialogServices) may be added to interact more with the dialog while it's open.

----------


## Karl77

TOOLTIP APPEARANCE QUESTION

The tooltips on TabStripW, ToolbarW and some more are fine, and they support even multiline.
Also the appearance is fine.

Other controls like CommandButtonW, FrameW etc. show different looking tooltips.
Here is an example:


Is there any chance to get the same tooltips as with TabStripW etc. in any control?

Thanks.

----------


## softv

Hi Krool,

Writing here after quite some time. 

As ever, remaining immensely thankful to your controls. They are proving to be of immeasurable benefit to the society. My thanks in TONS once again.

Well, I use the non-ocx version (always) and I wish to place the following two observations. Please note that I observed the following while testing with the latest non-ocx version too. I did not test with any of the ocx versions though, so far. 

*Observation 1.* 
To set a word as hyperlink in a RichTextBox control (for e.g. to set the word "works" in a RichTextBox named 'rtb1' as a hyperlink), I keep the word "works" selected and call the following code:



```
Dim myFormat As CHARFORMAT2
With myFormat
        .cbSize = LenB(myFormat)
        .dwEffects = CFE_LINK
        .dwMask = CFM_LINK
End With
SendMessage rtb1.hWnd, EM_SETCHARFORMAT, SCF_SELECTION, myFormat
```

The above code works in Windows7. The word "works" does turn into a hyperlink (i.e. it does get underlined, does get displayed in blue color and when the mouse hovers over the word "works", the cursor does change to hand pointer). 

But, the code  does not work in Windows10. In Windows 10, the word "works" remains as it is, without turning into a hyperlink. 

_So, what has to be done for Windows10? Kindly please help, when possible._
(I tried certain things but they did not help. So, I checked whether the above code works when the normal 'MS RichTextBox' Control is used in Windows 10. It does  work. The word "works" does turn into a hyperlink in a RichTextBox created using the 'MS RichTextBox' Control) 

*Observation 2.* 
In a RichTextBox, when the MaxLength propery is left at its default value of '0', I am able to internally set texts of length more than the 64kb. But, when I copy/paste text from outside sources OR try to type in the text area, no characters appear if the text length of our RichTextBox has crossed 64kb already. For this, what I have been doing is to explicitly set the MaxLength of our RichTextBoxes to '2147483647'. This works well. No problems while copying texts from external sources OR when trying to type. Even if the text length has already crossed 64KB, everything works correctly. But, I personally feel it is safer for the developer only if even with the default value of '0', normal behavior is exhibited. So, _if possible to set right this issue, kindly please set it right._ 

_Hope my above observations were/are right. If not, kindly please bear with me and please let me know what mistake I have done and guide me on what to do to set right the above issues._

My best wishes to you at all times, for your supremely phenomenal work!

----------


## Krool

> *Observation 1.* 
> To set a word as hyperlink in a RichTextBox control (for e.g. to set the word "works" in a RichTextBox named 'rtb1' as a hyperlink), I keep the word "works" selected and call the following code:
> 
> 
> 
> ```
> Dim myFormat As CHARFORMAT2
> With myFormat
>         .cbSize = LenB(myFormat)
> ...


Thank you softv for your points.
Concerning this point I can say that you should try to set the 'AutoURLDetect' property to False. It's by default to True in the RichTextBox.
Because MSDN says:
_Do not set SetAutoURLDetect to TRUE if your edit control uses the CFE_LINK effect for text other than URLs. SetAutoURLDetect enables this effect for URLs and disables it for all other text_

Also good to point out this because my RichTextBox is lacking a 'SelLink' property. Will be put in Todo. Currently I would like to maintain sync between ocx and non-ocx that's why I will for the moment not release such a new feature.




> *Observation 2.* 
> In a RichTextBox, when the MaxLength propery is left at its default value of '0', I am able to internally set texts of length more than the 64kb. But, when I copy/paste text from outside sources OR try to type in the text area, no characters appear if the text length of our RichTextBox has crossed 64kb already. For this, what I have been doing is to explicitly set the MaxLength of our RichTextBoxes to '2147483647'. This works well. No problems while copying texts from external sources OR when trying to type. Even if the text length has already crossed 64KB, everything works correctly. But, I personally feel it is safer for the developer only if even with the default value of '0', normal behavior is exhibited. So, _if possible to set right this issue, kindly please set it right._ 
> 
> _Hope my above observations were/are right. If not, kindly please bear with me and please let me know what mistake I have done and guide me on what to do to set right the above issues._


That's right. According to MSDN:
_Specifies the maximum amount of text that can be entered. If this parameter is zero, the default maximum is used, which is 64K characters. A COM object counts as a single character._




> The tooltips on TabStripW, ToolbarW and some more are fine, and they support even multiline.
> Also the appearance is fine.
> 
> Other controls like CommandButtonW, FrameW etc. show different looking tooltips.
> Here is an example:
> 
> 
> Is there any chance to get the same tooltips as with TabStripW etc. in any control?


I understand fully. However, it's not possible to overwrite the in-built 'ToolTipText' of the VBControlExtender.
For instance with the TabStrip control. I can't overwrite the 'TabStrip1.ToolTipText' property. Of course I can provide a better tooltip for the tabs, e.g. 'TabStrip1.Tabs(1).ToolTipText'

----------


## Karl77

> However, it's not possible to overwrite the in-built 'ToolTipText' of the VBControlExtender.
> For instance with the TabStrip control. I can't overwrite the 'TabStrip1.ToolTipText' property. Of course I can provide a better tooltip for the tabs, e.g. 'TabStrip1.Tabs(1).ToolTipText'


What about a ToolTipTextW property then?
Just an idea.

----------


## softv

> Thank you softv for your points.
> Concerning this point I can say that you should try to set the  'AutoURLDetect' property to False. It's by default to True in the  RichTextBox.
> Because MSDN says:
> _Do not set SetAutoURLDetect to TRUE if your edit control uses the  CFE_LINK effect for text other than URLs. SetAutoURLDetect enables this  effect for URLs and disables it for all other text_


Thanks for your prompt reply, as ever, Krool.

The workaround suggested by you does help for Windows10. It works and Thank You so much.  :Smilie: 

Well,  you must be knowing the following already with regard to Windows7  systems but yet stating it hereunder since, based on the same, I have a  question.

*In Windows 7*, even with AutoURLDetect  property set to True, I am able to easily set hyperlinks for our  RichTextBox's text containing 100s of absolute URLs (e.g.  http://google.com) and named URLs (e.g. "Click here to visit Google").  The AutoURLDetect property (which is set to True) takes care of setting  the hyperlinks for the absolute urls, *automatically*.  So, I need to take care of setting the hyperlinks for the named URLs  alone, programmatically (using the already mentioned code, which uses  CFE_LINK and CFM_LINK).

Based on the above, I have a question for _Windows 10 systems_. 

*In Windows 10*  (may be in Windows 8 too; I do not have a Windows 8 system), it is  clear now that setting 'AutoURLDetect property to False' for our  RichTextBox (say rtb1) alone can help me set hyperlinks for named URLs  in rtb1's text, when using the 'CFE_LINK  and CFM_LINK' method. That being the case, the only way I have now (_in Windows 10 systems_) to set hyperlinks for all the URLs when rtb1's text contains both named and absolute URLs (in 100s) is:
Set the AutoURLDetect property of rtb1 to False.Set the hyperlinks for the named URLs in rtb1's text, as usual. i.e.  set them programmatically (using the already mentioned code, which uses  CFE_LINK and CFM_LINK)Programmatically detect all the absolute URLs in rtb1's text.Set hyperlinks for the detected absolute URLs using the same 'CFE_LINK  and CFM_LINK' method, the one used for setting hyperlinks for named  URLs.

Is my above approach right? If not, _when possible_, either you or any other member may kindly let me know the better/easier approach. Thanks.

My hearty thanks and best wishes, at all times, for all your noble deeds, Krool.

----------


## Karl77

LABELW REFRESH PROBLEM

A LabelW gets a new caption in a loop.

To let it display, I let it .Refresh.
This has no effect.
The new caption is not displayed.

I tried with an intrinsic label, and that works ok.

And surprise, if an intrinsic label gets the .Refresh, then the LabelW updates as well.
A miracle...

Try in the attached sample.
To see LabelW becoming lazy, it is sufficient to set the standard label .Visible = false.

Thank you


Label Refresh.zip

----------


## wqweto

A Repaint routine can be implemented as a stronger alternative to Refresh like this

thinBasic Code:
Private Sub pvPumpMessages(ByVal hWnd As Long, ByVal lFromMsg As Long, ByVal lToMsg As Long)
    Dim uMsg            As APIMSG
    
    Do While PeekMessage(uMsg, hWnd, lFromMsg, lToMsg, PM_REMOVE) <> 0
        Call DispatchMessage(uMsg)
    Loop
End Sub
 Public Sub Repaint()
    pvPumpMessages ContainerHwnd, WM_PAINT, WM_PAINT
End Sub
. . . or Karl77 can call pvPumpMessages in client code after batch updating the other 100s of labels on the form in question :-))

cheers,
</wqw>

----------


## Krool

> LABELW REFRESH PROBLEM


Should be solved now. Thanks also to wqweto.
It's now properly implemented into the LabelW control.




> What about a ToolTipTextW property then?


Not so bad idea. Will be put in the Todo's.




> Is my above approach right?


Yes, but for Windows 7 I did the following observation:

True. In Windows 7 you can have AutoURLDetect to True and set manual links.
However, when I type something on a word block that have a partial link it will be gone if any char is typed.
Example: "asdasdasdasdasdasdasdx"
When the blue was marked as link and I put an x at end of the word block the blue link is erased.
But that's only the case when AutoURLDetect is True. If it's False then there is no harm.
In Windows 10 then you have no way to make manual links when AutoURLDetect is True. Which is in accordance to the MSDN description.
So my opinion is that this was a "behavior bug" in Windows 7 and was corrected then. Manual links shouldn't be possible when AutoURLDetect is True.

----------


## Karl77

(LABELW REFRESH PROBLEM)




> Should be solved now. Thanks also to wqweto.
> It's now properly implemented into the LabelW control.


Confirmed.
Works ok now.
Thanks to both of you.

----------


## Krool

Update released.

Major performenance boost when interacting with the .ComboItems collection in the ImageCombo control.
The following figures (*in seconds*) illustrate the effect. (run in IDE)
old:


```
10000x Add (index missing) = 0,754062
10000x Add (index:1) = 450,999812
10000x Item (index:i) = 0,142875
10000x Item (index:1) = 0,046875
10000x Remove (index:1) = 427,6133
```

new:


```
10000x Add (index missing) = 0,749937
10000x Add (index:1) = 5,776812
10000x Item (index:i) = 0,046875
10000x Item (index:1) = 0,031250
10000x Remove (index:1) = 5,814750
```

It's embarrassing to show this. The old figures got proportionately slower the more items.

----------


## Krool

Housekeeping update.

Enumeration.cls got removed and replaced by a lightweight COM replacement (based on DEXWERX's [VB6] IEnumVARIANT / For Each support without a typelib) directly in VTableHandle.bas.
The Enumeration is now faster and less complicated.

----------


## Karl77

> The Enumeration is now faster and less complicated.


Sounds good.

I wanted to start to take over the new code into 'my' OCX.
But first I have a question.

In the new VTableHandle.bas, there is this line:


```
If VTableIPAOData.RefCount > 0 Or 1 > 2 Then
```

I don't understand the  > 0 Or 1 > 2.
Isn't 1 > 2 always false?

Karl

----------


## Krool

> In the new VTableHandle.bas, there is this line:
> 
> 
> ```
> If VTableIPAOData.RefCount > 0 Or 1 > 2 Then
> ```
> 
> I don't understand the  > 0 Or 1 > 2.
> Isn't 1 > 2 always false?


The Or 1 > 2 is a leftover and can be removed, which I will do at next oppurtinity.
Luckily this has no impact/effect if it's there or not, but of course not needed.

Reason for this was that I wanted to test something and exclude this block.
Therefore I did:


```
If VTableIPAOData.RefCount > 0 And 1 > 2 Then
```

So the line is never True. (For testing)
Then I wanted to allow (temporary) the block and changed to:


```
If VTableIPAOData.RefCount > 0 Or 1 > 2 Then
```

It was intended that at the end this temp 1 > 2 is removed.

However, again. Luckily this forgotten removal has no impact and will be cleaned at next occasion.

----------


## Krool

Important update released for VTableHandle.bas.

Possible delay in *_Terminate events in Forms, UserControls etc. (could cause possible gdi overloads)
I am so sorry for this incompetence.  :Mad: 


```
Public Sub DeActivateIPAO()
On Error GoTo CATCH_EXCEPTION
If VTableIPAOData.OriginalIOleIPAO Is Nothing Then Exit Sub
Dim PropOleObject As OLEGuids.IOleObject
Dim PropOleInPlaceSite As OLEGuids.IOleInPlaceSite
Dim PropOleInPlaceFrame As OLEGuids.IOleInPlaceFrame
Dim PropOleInPlaceUIWindow As OLEGuids.IOleInPlaceUIWindow
Dim PropOleInPlaceActiveObject As OLEGuids.IOleInPlaceActiveObject
Dim PosRect As OLEGuids.OLERECT
Dim ClipRect As OLEGuids.OLERECT
Dim FrameInfo As OLEGuids.OLEINPLACEFRAMEINFO
Set PropOleObject = VTableIPAOData.OriginalIOleIPAO
Set PropOleInPlaceActiveObject = VTableIPAOData.OriginalIOleIPAO
Set PropOleInPlaceSite = PropOleObject.GetClientSite
PropOleInPlaceSite.GetWindowContext PropOleInPlaceFrame, PropOleInPlaceUIWindow, VarPtr(PosRect), VarPtr(ClipRect), VarPtr(FrameInfo)
PropOleInPlaceFrame.SetActiveObject PropOleInPlaceActiveObject, vbNullString
If Not PropOleInPlaceUIWindow Is Nothing Then PropOleInPlaceUIWindow.SetActiveObject PropOleInPlaceActiveObject, vbNullString
Set VTableIPAOData.OriginalIOleIPAO = Nothing
Set VTableIPAOData.IOleIPAO = Nothing
CATCH_EXCEPTION:
End Sub
```

The bugfix is marked as red in above internal function 'DeactivateIPAO'.
After restoring the IPAO to VB's original IPAO it is necessary to de-reference our objects in VTableIPAOData.
As this was not done previously there was a reference link that hindered the UserControls to fire _Terminate event and also Form_Terminate.

So please replace. It will for sure solve other issues you may have encounter.

----------


## wqweto

> Reason for this was that I wanted to test something and exclude this block.
> Therefore I did:
> 
> 
> ```
> If VTableIPAOData.RefCount > 0 And 1 > 2 Then
> ```
> 
> So the line is never True. (For testing)


FWIW, I'm using And False to disable predicates like this

thinBasic Code:
If VTableIPAOData.RefCount > 0 And False Then
and later enable with Then ' before fake conjunction like this

thinBasic Code:
If VTableIPAOData.RefCount > 0 Then ' And False Then
cheers,
</wqw>

----------


## Karl77

> Important update released for VTableHandle.bas.


This is not incompetence, it is the exact opposite.
Same is true for 'embarrasing' in post #2092.
You can and do solve things.

Regarding the change in VTableHandle, it has indeed a big impact on stability.
With this change it is the 1st time MZTool's Programm analysis runs through my large project.
Before it always hung at some point and crashed VB in the end.
Very good!

Up to now I didn't see the unresponsive command buttons as well (see e.g. #2081).


*EDIT:*
The strange active UC problem, reported in #2079, is *not* healed by the change.

----------


## DEXWERX

This is just a great project / contribution to the community. 
It has far surpassed the original CCRP. (not to mention the original was closed source, and died without fixing some major bugs)

----------


## Elroy

I'd just like to throw my vote of confidence in too.

Krool, this is an absolutely phenomenal project, and your diligence to maintaining it says volumes about your integrity.

All The Best,
Elroy

----------


## wqweto

> The strange active UC problem, reported in #2079, is *not* healed by the change.


This is ActivateIPAO problem. vbAccelerator's impl had this problem and so every control "borrowing" it has the same issue.

DoVerb OLEIVERB_UIACTIVATE impl in #1424 fixes this.

cheers,
</wqw>

----------


## Krool

> This is ActivateIPAO problem. vbAccelerator's impl had this problem and so every control "borrowing" it has the same issue.
> 
> DoVerb OLEIVERB_UIACTIVATE impl in #1424 fixes this.
> 
> cheers,
> </wqw>


Thanks. However I responded in #1426 why it makes no difference.

The problem Karl77 faces is apparently something different.

So a TextBoxW in another UC, then the Ambient.UserMode is True and therefore the TextBoxW is subclassed and handles WM_MOUSEACTIVATE and activates it on click. Normally 'ComCtlsRootIsEditor' should avoid such case but I think there is a glitch sometimes. I can't replicate the issue and also Karl77 only has it sometimes.

The solution would be to not use


```
Ambient.UserMode
```

But rather use:


```
GetTopUserControl(Me).Ambient.UserMode
```

----------


## Karl77

LISTBOX QUESTION

In the ListViewW, we have the very handy SortType option.
The ListBoxW doesn't have it, it can only sort alphabetically.

I can fill the data into an invisible ListViewW, let it sort and transfer it to the ListboxW.
It would be nice if it would work without this step.

Just a wish.

----------


## Krool

> LISTBOX QUESTION
> 
> In the ListViewW, we have the very handy SortType option.
> The ListBoxW doesn't have it, it can only sort alphabetically.
> 
> I can fill the data into an invisible ListViewW, let it sort and transfer it to the ListboxW.
> It would be nice if it would work without this step.


This would be possible only per WM_COMPAREITEM.
However, that is only "available" without LBS_HASSTRINGS. So practically "Half-VirtualMode".
Because for "Full-VirtualMode" the LBS_NODATA prevents LBS_SORT at all, which makes sense since the sorting should be done on client side.

I will put this in Todo to add feature "Full-VirtualMode" because that can be a necessity.
But "Half-VirtualMode" makes no sense at all to just have a better sorting..

For ComboBox "Full-VirtualMode" would also be possible. But there I would need superclassing to catch WM_CREATE for class 'Combo*L*Box' to apply LBS_NODATA on ComboLBox creation.




> The strange active UC problem, reported in #2079, is *not* healed by the change.


That problem is not connected to VTableHandle.bas.
It's rather a "subclass activated in design mode" issue.

As said recently the below would ensure "never a subclass in design mode":


```
GetTopUserControl(Me).Ambient.UserMode
```

However, I'm afraid that this would be not a good idea.
Because maybe the UC that hosts those control are dependent that the control is 100% "on". (subclass=yes)

But let's try a hotfix on your side to just see if another workaround solves the issue and to isolate it actually.

So in your OCX version just change (temporary until verified it solved) in TextBoxW the following:


```
Case WM_MOUSEACTIVATE
    Static InProc As Boolean
    If ComCtlsRootIsEditor(hWnd) = False And GetFocus() <> TextBoxHandle Then
```

into


```
Case WM_MOUSEACTIVATE
    Static InProc As Boolean
    If GetTopUserControl(Me).Ambient.UserMode = True And GetFocus() <> TextBoxHandle Then
```

and report if you still encounter the issue.

----------


## Karl77

> But let's try a hotfix on your side to just see if another workaround solves the issue and to isolate it actually.
> 
> So in your OCX version just change (temporary until verified it solved) in TextBoxW the following:
> 
> 
> ```
> Case WM_MOUSEACTIVATE
>     Static InProc As Boolean
>     If ComCtlsRootIsEditor(hWnd) = False And GetFocus() <> TextBoxHandle Then
> ...


Still there, but different.

I have one UC that contains a next UC, and in this UC there are a)some UCs using TextBoxW b)some UCs using SpinBox.


In the IDE, the Form is selected.
Now I click the UC with TextBoxW (white).
All is good.

I click the UC with SpinBox (green).
Not ok, the cursor is active in the SpinBox, I can change the value by typing or mousewheel.
After that, I click a UC with TextBoxW (white).
Cursor is active in the TextBoxW, I can change the text by typing.
Then I click another UC with TextBoxW (white).
Cursor is active in the TextBoxW.

I select the form now.
Then I click a UC with TextBoxW (white).

Now it's ok until I click the UC with SpinBox (green).

---

The change in WM_MOUSEACTIVATE seems to work partially.

Unfortunately, I can't show this in a sample app, even not with the same UCs.

----------


## Krool

Karl77,
If you also change WM_MOUSEACTIVATE in the SpinBox then it also works there.
Will check what is the optimal solution.

----------


## Karl77

> If you also change WM_MOUSEACTIVATE in the SpinBox then it also works there.


I thought so, but first wanted to point out that when the SpinBox got active, the TextBoxW can get active even when WM_MOUSEACTIVATE was changed in it.

It is not a big issue at all, only a bit inconvenience in the IDE.

----------


## Krool

Karl77,
Ok another trial error attempt. Please restore changes done before on WM_MOUSEACTIVATE and just comment out 1 line in below function: (green marked)


```
Public Function ComCtlsRootIsEditor(ByVal hWnd As Long) As Boolean
Static Done As Boolean, Value As Boolean
If Done = False Then
    Const GA_ROOT As Long = 2
    hWnd = GetAncestor(hWnd, GA_ROOT)
    If hWnd <> 0 Then
        Dim Buffer As String, RetVal As Long
        Buffer = String(256, vbNullChar)
        RetVal = GetClassName(hWnd, StrPtr(Buffer), Len(Buffer))
        If RetVal <> 0 Then Value = CBool(Left$(Buffer, RetVal) = "wndclass_desked_gsk")
    End If
    ' Done = True
End If
ComCtlsRootIsEditor = Value
End Function
```

----------


## wqweto

> Thanks. However I responded in #1426 why it makes no difference.
> 
> The problem Karl77 faces is apparently something different.


I've seen exactly this problem with vbAccelerator's IPAO -- a custom UC1 is marked as control container, a UC with flawed IPAO is sited at design-time (in this case TextBoxW), once an instance of UC1 is placed on Form1 the TextBoxW can be activated in the designer in the IDE.

Take a look at how ATL implements set focus in CComControlBase::OnSetFocus -- pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos) is the meat. Also notice how m_bInPlaceActive flag is handled throughout the whole atlctl.h -- a very instructive read for control creators IMO.

cheers,
</wqw>

----------


## Karl77

> Karl77,
> Ok another trial error attempt. Please restore changes done before on WM_MOUSEACTIVATE and just comment out 1 line in below function: (green marked)
> 
> 
> ```
> Public Function ComCtlsRootIsEditor(ByVal hWnd As Long) As Boolean
> Static Done As Boolean, Value As Boolean
> If Done = False Then
>     Const GA_ROOT As Long = 2
> ...


I'm 99.9% sure it works.
Let's wait one day for the last 0.1%, as the effect sometimes wasn't there for unknown reasons.

----------


## Krool

> I've seen exactly this problem with vbAccelerator's IPAO -- a custom UC1 is marked as control container, a UC with flawed IPAO is sited at design-time (in this case TextBoxW), once an instance of UC1 is placed on Form1 the TextBoxW can be activated in the designer in the IDE.
> 
> Take a look at how ATL implements set focus in CComControlBase::OnSetFocus -- pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos) is the meat. Also notice how m_bInPlaceActive flag is handled throughout the whole atlctl.h -- a very instructive read for control creators IMO.


I have tested now again (and tested before) and I noticed that DoVerb OLEIVERB_UIACTIVATE behaves the same as applying SetFocus API.
Even when the Validation cancellation should occur the DoVerb OLEIVERB_UIACTIVATE just set's the focus. So currently I see no difference in this way and my current implementation.

The real point is (and maybe we talked past each other about it) is WM_MOUSEACTIVATE. It is crucial that the validation needs to take place in WM_MOUSEACTIVATE and then set the focus accordingly.

What is interesting in the GitHub source you provided that in OnMouseActivate also Ambient.UserMode is checked. (same as my previous idea with GetTopUserControl(Me).Ambient.UserMode instead of the quirky ComCtlsRootIsEditor() workaround which obviously does not always work)


```
	LRESULT OnMouseActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		BOOL bUserMode = TRUE;
		HRESULT hRet = GetAmbientUserMode(bUserMode);
		// UI activate if in user mode only
		// allow activation if we can't determine mode
		if (FAILED(hRet) || bUserMode)
		{
			CComPtr<IOleObject> pOleObject;
			ControlQueryInterface(__uuidof(IOleObject), (void**)&pOleObject);
			if (pOleObject != NULL)
				pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos);
		}
		bHandled = FALSE;
		return 1;
}
```

Again, I see no difference in applying DoVerb OLEIVERB_UIACTIVATE or direct SetFocus.

----------


## MountainMan

Krool,

I am working on a utility for your VBCCR and VBFLXGRD projects that enables either or both to be updated. In addition, if you have a project that uses the .OCX versions of each, this utility will swap out the .OCX references and replaces them with the appropriate files from the respective StdEXE versions and then it does a command-line compile to make a program that has no dependencies. I find this useful because although the StdEXE versions provide the lack of dependencies they take a whole lot longer to compile so with this utility you only do the long compile at the end instead of each time to check syntax or compile during development.

I am having a problem doing both VBCCRxx and VBFLXGRDxx at the same time. As you know, a given program can only have one module of a certain name and these two have some common modules. Both of you sets of controls come from the same underlying common code so the StdEXE versions hav several modules that have the same name. If the modules are the same (such as Common\Common.bas and Common\VisualStyles.bas in the StdEXE versions) then I can just use one of them for both. The problem comes with modules that are the same name but different. The one that is causing me problems right now is Builds\VTableHandle.bas. In the latest ComCtlsDemo this file is 27.4 kb and is dated 30 Sep 2018 but in VBFlexGridDemo this file is 27.6 kb and is dated 4 Mar 2018. The two files are fairly different internally too. VBFlexGridDemos version of VTableHandle.bas uses an old Enumeration.cls that is not present in ComCtlsDemo.bas.

There are some common public routines and variables so I cant just rename one of the files and include both. In fact, as it is now, even forgetting about the utility I am working on now, you cant build a program that uses the controls in both of the StdEXE versions since each requires its own VTableHanlde.bas and they are different.

So my question is do you intend for Builds\VTableHandle.bas to be the same any time in the near future? If so, when? Thanks.

MountainMan

----------


## Krool

> Krool,
> 
> I am working on a utility for your VBCCR and VBFLXGRD projects that enables either or both to be updated. In addition, if you have a project that uses the .OCX versions of each, this utility will swap out the .OCX references and replaces them with the appropriate files from the respective StdEXE versions and then it does a command-line compile to make a program that has no dependencies. I find this useful because although the StdEXE versions provide the lack of dependencies they take a whole lot longer to compile so with this utility you only do the “long” compile at the end instead of each time to check syntax or compile during development.
> 
> I am having a problem doing both VBCCRxx and VBFLXGRDxx at the same time. As you know, a given program can only have one module of a certain name and these two have some common modules. Both of you sets of controls come from the same underlying common code so the StdEXE versions hav several modules that have the same name. If the modules are the same (such as “Common\Common.bas” and “Common\VisualStyles.bas” in the StdEXE versions) then I can just use one of them for both. The problem comes with modules that are the same name but different. The one that is causing me problems right now is “Builds\VTableHandle.bas”. In the latest ComCtlsDemo this file is 27.4 kb and is dated 30 Sep 2018 but in VBFlexGridDemo this file is 27.6 kb and is dated 4 Mar 2018. The two files are fairly different internally too. VBFlexGridDemo’s version of VTableHandle.bas uses an old Enumeration.cls that is not present in ComCtlsDemo.bas.
> 
> There are some common public routines and variables so I can’t just rename one of the files and include both. In fact, as it is now, even forgetting about the utility I am working on now, you can’t build a program that uses the controls in both of the StdEXE versions since each requires its own VTableHanlde.bas and they are different.
> 
> So my question is do you intend for “Builds\VTableHandle.bas” to be the same any time in the near future? If so, when? Thanks.
> ...


Wow. Thanks for your efforts.

I always keep shared stuff in sync. I don't see different VTableHandle.bas version in ComCtlsDemo and VBFlexGridDemo. (?)

----------


## Karl77

> if you have a project that uses the .OCX versions of each, this utility will swap out the .OCX references and replaces them with the appropriate files from the respective StdEXE versions and then it does a command-line compile to make a program that has no dependencies. I find this useful because although the StdEXE versions provide the lack of dependencies they take a whole lot longer to compile so with this utility you only do the long compile at the end instead of each time to check syntax or compile during development.


I like that idea!
Also from what I have read here, it could have some performance advantages.
Krool said this, but don't ask for the exact post #.
But there is also the risk that there are behavior differences.
I don't know.




> I am having a problem doing both VBCCRxx and VBFLXGRDxx at the same time.


What about merging the 2 projects?
Would reduce maintenance effort.

I have both projects (and some additional things) in one OCX.
Works very good.

----------


## jpbro

Hi Krool, thanks for your excellent work on this project!

I've been using your RichTextBox control and it works great, but I've found a potential spot for a performance improvement. Right now getting RTF via the TextRtf property can be quite slow on large documents (for example, documents with large images embedded). On my computer it is taking almost 3 seconds to return about 4MB of RTF.

I traced this to the RtfStreamCallbackStringOut method, where the BytesRequested parameter tends to use fairly small chunks of around 4KB. Combined with around 1000 Redim Preserves, this seems to be the culprit. Maybe there's a way to increase the "chunk" size the RichEdit control uses, but I'm not aware of this. 

Instead I've tried implementing a 1MB buffer that increases in BufferSize*2 chunks with a final Redim Preserve to the correct size (reducing the number of Redims to 4 vs. 1000 in the example case). The performance boost is significant, taking about 0.1 seconds vs 2.5-3 seconds).

Here's my code if you are interested. Feel free to use it, or modify it in any way that you see fit. It hasn't been tested heavily yet, so there may be issues so please review it carefully if you intend to use it (especially check for off-by-one errors on the buffer resizing/ubound at chunk boundaries).

*In the general section of RichTextBoxBase.bas:*


```
Private StreamStringOutBufferSize As Long
```


*2 Modified functions in RichTextBoxBase.bas:*


```
Public Function RtfStreamStringOut() As String
If StreamStringOutUBound > 0 Then
   ReDim Preserve StreamStringOut(0 To StreamStringOutUBound - 1) As Byte
   RtfStreamStringOut = StreamStringOut()
   Erase StreamStringOut()
   StreamStringOutUBound = 0
   StreamStringOutBufferSize = 0
End If
End Function

Public Function RtfStreamCallbackStringOut(ByVal dwCookie As Long, ByVal ByteBufferPtr As Long, ByVal BytesRequested As Long, ByRef BytesProcessed As Long) As Long
Dim l_BufferBump As Long

If BytesRequested > 0 Then
   If StreamStringOutBufferSize < StreamStringOutUBound + BytesRequested - 1 Then '
      If StreamStringOutBufferSize = 0 Then
         ' Initialize buffer to ~1MB
         l_BufferBump = 104576
      Else
         ' Increase buffer by current buffer size
         l_BufferBump = StreamStringOutBufferSize
         If l_BufferBump > 16777216 Then l_BufferBump = 16777216 ' Cap buffer bump at ~16MB
      End If
      
      If l_BufferBump < BytesRequested Then l_BufferBump = BytesRequested  ' Make sure buffer size is large enough for BytesRequested
      StreamStringOutBufferSize = StreamStringOutBufferSize + l_BufferBump

      ReDim Preserve StreamStringOut(0 To StreamStringOutBufferSize) As Byte
   End If
   CopyMemory StreamStringOut(StreamStringOutUBound), ByVal ByteBufferPtr, BytesRequested
   StreamStringOutUBound = StreamStringOutUBound + BytesRequested
   BytesProcessed = BytesRequested
Else
    BytesProcessed = 0
End If
RtfStreamCallbackStringOut = 0
End Function
```

----------


## Karl77

(ComCtlsRootIsEditor change)




> I'm 99.9% sure it works.
> Let's wait one day for the last 0.1%, as the effect sometimes wasn't there for unknown reasons.


Ok, now I'm 100% sure it works..

But why does ComCtlsRootIsEditor fail sometimes? There must be a reason.
So I'm not so sure that this ComCtlsRootIsEditor change is a good solution.

----------


## Krool

> Still there, but different.
> 
> I have one UC that contains a next UC, and in this UC there are a)some UCs using TextBoxW b)some UCs using SpinBox.
> 
> 
> In the IDE, the Form is selected.
> Now I click the UC with TextBoxW (white).
> All is good.
> 
> ...





> But why does ComCtlsRootIsEditor fail sometimes? There must be a reason.
> So I'm not so sure that this ComCtlsRootIsEditor change is a good solution.


Update released. This issue is now solved the proper way. (both Std-EXE and in OCX version)

Each control persists now on UserControl_InitProperties/UserControl_ReadProperties the Ambient.UserMode and GetTopUserControl(Me).Ambient.UserMode values into local variables.
Example: (TextBoxW)


```
Private Sub UserControl_InitProperties()
If DispIDMousePointer = 0 Then DispIDMousePointer = GetDispID(Me, "MousePointer")
TextBoxDesignMode = Not Ambient.UserMode
TextBoxTopDesignMode = Not GetTopUserControl(Me).Ambient.UserMode

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
If DispIDMousePointer = 0 Then DispIDMousePointer = GetDispID(Me, "MousePointer")
TextBoxDesignMode = Not Ambient.UserMode
TextBoxTopDesignMode = Not GetTopUserControl(Me).Ambient.UserMode
```

Those two events are the earliest time Ambient.UserMode is meaningful.
All occurences of Ambient.UserMode are replaced accordingly. (Ambient.UserMode = True -> ...DesignMode = False; Ambient.UserMode = False -> ...DesignMode = True)

The other change is on each WM_MOUSEACTIVATE handler where ComCtlsRootIsEditor() got obsolete and was removed from ComCtlsBase.bas.
It just got replaced by the ...TopDesignMode variable.

Example: (TextBoxW)


```
Case WM_MOUSEACTIVATE
    Static InProc As Boolean
    If TextBoxTopDesignMode = False And GetFocus() <> TextBoxHandle Then
```

----------


## Karl77

(UC active issue)




> Update released. This issue is now solved the proper way. (both Std-EXE and in OCX version)


Works flawless, thanks.

VBFlexGrid is also updated.
Wouldn't it be good to merge VBCCR and VBFlexGrid anyway?
Both projects are mature enough to marry.
Or?

----------


## Semke

> (UC active issue)
> 
> 
> Works flawless, thanks.
> 
> VBFlexGrid is also updated.
> Wouldn't it be good to merge VBCCR and VBFlexGrid anyway?
> Both projects are mature enough to marry.
> Or?


I second that.

----------


## MountainMan

Krool,

I am close to finishing the utility that takes OCX versinos of both VBFLXGRDxx and VBCCRxx and cuts out the OCX parts and brings in the various control files from your ComCtlsDemo and VBFlexGridDemo packages. My goal is to have the fast and relatively simple aspects of the OCX version in use during development but do a final compilation with the controls being compiled as part of the final executable

I am 99% done but I have a question. In the StdEXE versions you have various controls with property page files (.pag extension). If I put the controls into the executables and then do a commandline compile do I need the property page files? I can easily drop them out but I don't want to mess anything up. I am not a wizard in self-made controls but it seems that the property pages are of use in the IDE during development but are not required to make the EXE. Is my assumption correct or do I need to include these files for the commandline compile?

----------


## Krool

MountainMan,

True. The property pages are only needed for IDE or OCX.
For the compiled Std-EXE it is not needed.

Even the API 'OleCreatePropertyFrame' to show the property pages at run-time do work only in IDE or when compiled only when linked to a OCX.

----------


## LOfADay

An extraordinary volume of work. Keep it up! Sad I was unable to make use of it in a VB6 reboot. I had the finance, the planning, the background, the external support, and I made the big mistake of coming here and asking for input, help and encouragement. Sadly MS has broken your colleagues here and rampant negativity, even mockery, was all I got. I now know how Elon Musk felt when he offered the Thai cave boys a submarine only to be rounded on. Maybe someone will come and make use of your fantastic work as you deserve recognition.

----------


## MountainMan

Hi LOfADay. Just about everyone on this forum is contributing to not only keeping VB6 alive but improving on it. Krool's work is evidence of that but he is by no means the only one. I am not sure what your beef is about but if you want to be part of our small community please join us in a positive way. We'd love to have you and your ideas. I looked at your previous posts on this forum and couldn't see anything particularly bad but obviously something ticked you off. Every online community has some irritating people but this forum seems to have a lot less of that than almost any online community I have seen or been part of. If you want to be positive please jump in. if you don't please take the negativity somewhere else.

----------


## Semke

First of all thanks for all your wooooork.

in .Net it is possible to add to the toolbar (in addition to the Button) other controls like Textbox, Combo Etc.... I have even managed to put DateTime and many other Controls.


Would this be possible to add this on your toolbar, this would save lots of coding of positioning controls on form load.


thanks

----------


## Krool

> First of all thanks for all your wooooork.
> 
> in .Net it is possible to add to the toolbar (in addition to the Button) other controls like Textbox, Combo Etc.... I have even managed to put DateTime and many other Controls.
> 
> 
> Would this be possible to add this on your toolbar, this would save lots of coding of positioning controls on form load.
> 
> 
> thanks


You can use the CoolBar in combination with the ToolBar. The CoolBar can manage child controls.

----------


## MountainMan

Krool,

One more question. In the standard module ComCtlsBase you have a conditional compilation constant ImplementIDEStopProtection and it appears to toggle whether or not you include code for the StdEXE controls to be safely used in the IDE. If I have a project with the OCX version of your controls and I modify it to now use the StdEXE ones and then I compile that with the commandline compilation capability of VB6.exe, I believe I can set this conditional compilation constant = FALSE because the resultant executable is not going to be in the IDE. Is this correct?

----------


## wqweto

> A Repaint routine can be implemented as a stronger alternative to Refresh like this
> 
> thinBasic Code:
> Private Sub pvPumpMessages(ByVal hWnd As Long, ByVal lFromMsg As Long, ByVal lToMsg As Long)
    Dim uMsg            As APIMSG
    
    Do While PeekMessage(uMsg, hWnd, lFromMsg, lToMsg, PM_REMOVE) <> 0
        Call DispatchMessage(uMsg)
    Loop
End Sub
 Public Sub Repaint()
    pvPumpMessages ContainerHwnd, WM_PAINT, WM_PAINT
End Sub
> . . . or Karl77 can call pvPumpMessages in client code after batch updating the other 100s of labels on the form in question :-))
> 
> cheers,
> </wqw>


Just FYI, I have to admit that recently I found out that there is a win32 API function specifically for sending WM_PAINT messages (only if required/if anything is invalidated) to a hwnd and it's as simple as UpdateWindow.

Using pvPumpMessages in Repaint above is an example of over-complication par excellance instead of a simple Call UpdateWindow(ContainerHwnd) API call.

Sorry once again about that. . .

cheers,
</wqw>

----------


## Semke

Hi!

Is there any way to print on toobar button placeholder, I use that to put controls and I would like to print a description of the control above it.

----------


## Karl77

COMMON DIALOG QUESTION

Using the VBCCR CommonDialog class, how can I add a button to the file dialog?
Like this:


And let some code work from this button?
The goal is to set a predifined folder to browse.

Thank you

----------


## Krool

> Krool,
> 
> One more question. In the standard module ComCtlsBase you have a conditional compilation constant ImplementIDEStopProtection and it appears to toggle whether or not you include code for the StdEXE controls to be safely used in the IDE. If I have a project with the OCX version of your controls and I modify it to now use the StdEXE ones and then I compile that with the commandline compilation capability of VB6.exe, I believe I can set this conditional compilation constant = FALSE because the resultant executable is not going to be in the IDE. Is this correct?


Correct

----------


## Karl77

> COMMON DIALOG QUESTION
> Using the VBCCR CommonDialog class, how can I add a button to the file dialog?


I now see this is easily possible with this:
http://www.vbforums.com/showthread.p...t-Another-One)
It seems I can easily use this one instead of the VBCCR solution.
Means: Solved.

----------


## AAraya

On the LinkLabel control, is it possible to expose the Link forecolor property to the developer?  It's currently outside of the developer's ability to control (there's no property for this on the control).  I imagine that it's reading some system value for this.  In my app I use a slightly different shade of blue for links and I'd like to set the LinkLabel.LinkForeColor to this same app-wide link color.

Thanks for the consideration.

----------


## AAraya

Also, I'd like to use the LinkLabel control as a replacement for the current Label control when the caption requires an embedded hyperlink.  Therefore, it should have much of the same functionality as the Label control where possible to allow for easiest drop in replacement.  For example, the Alignment options for LinkLabel should be vbLeftJustify, vbCenterJustify, and vbRightJustify just the Label control.  But currently only Left and Right are offered.  Is there a reason for this?

Other "missing" LinkLabel properties which would be useful are:
Appearance
AutoSize
EllipsisFormat
VerticalAlignment
WordWrap


Of all of these discussed, the two which are preventing me from using this control in my project are the LinkForeColor and Alignment = vbCenter

----------


## Krool

> On the LinkLabel control, is it possible to expose the Link forecolor property to the developer?  It's currently outside of the developer's ability to control (there's no property for this on the control).  I imagine that it's reading some system value for this.  In my app I use a slightly different shade of blue for links and I'd like to set the LinkLabel.LinkForeColor to this same app-wide link color.


There is a Event for it:


```
LinkForeColor(ByVal Link As LlbLink, ByRef RGBColor As Long)
```

The param RGBColor is preset with system value but there you can override the value.
You may use the 'Visited' and/or 'Hot' property of the LlbLink object to finetune further the RGBColor.

----------


## AAraya

> There is a Event for it:
> 
> 
> ```
> LinkForeColor(ByVal Link As LlbLink, ByRef RGBColor As Long)
> ```
> 
> The param RGBColor is preset with system value but there you can override the value.
> You may use the 'Visited' and/or 'Hot' property of the LlbLink object to finetune further the RGBColor.


Not an obvious place to set a ForeColor property but it works well.  Thanks!

----------


## Krool

> For example, the Alignment options for LinkLabel should be vbLeftJustify, vbCenterJustify, and vbRightJustify just the Label control.  But currently only Left and Right are offered.  Is there a reason for this?


Yes there is a reason. Left is by default and Right is achieved by LWS_RIGHT style. There is no native way by comctl32.dll (e.g. LWS_CENTER) to make center alignment.

----------


## AAraya

There appears to be a bug with Tooltips for the LabelW control.  The label caption displays Unicode text but the tooltip does not.  See screenshot.  Is this a known issue?  Let me know if you need more details.

----------


## Cube8

> There appears to be a bug with Tooltips for the LabelW control.  The label caption displays Unicode text but the tooltip does not.  See screenshot.  Is this a known issue?  Let me know if you need more details.


If you use the _ToolTipText_ property, it is normal because it does not support unicode.

----------


## AAraya

> If you use the _ToolTipText_ property, it is normal because it does not support unicode.


Is this a limitation of the VBCCR.LabelW control or of the underlying Windows APIs which it's built on?  

Is there a way around this?  One of the reasons I replaced all of the controls in my project to the VBCCR ones was for Unicode support.

----------


## AAraya

Old age has set in... sigh...

I posted this same issue but with a Listbox about a year and half ago.  Completely forgot about that.  The response was that the TooltipText property does not support Unicode.  Man, that's a small nuisance. Any thoughts about adding a TootipTextW property to these controls which can handle Unicode?

In the meanwhile I'll look into implementing my own using this code:
http://www.vbforums.com/showthread.p...iCode-ToolTips

----------


## DEXWERX

Maybe we should consider overriding VBs tooltips engine like Merri had figured out.

Not sure how you would get around the IDE properties window. Maybe a TooltipW on a property page?

----------


## DrUnicode

> Not sure how you would get around the IDE properties window. Maybe a TooltipW on a property page?


Several options here:

1. Add 7 Properties to each control for full control of ToolTips.
   ToolTipTextW, ToolTipTitleW, ToolTipIcon, ToolTipStyle, ToolTipBackColor, ToolTipForeColor, ToolTipMaxWidth
   You will need a PropertyPage for ToolTipTextW and ToolTipTitleW so you can add Unicode at design time.
The PropertyPage will need a Unicode aware TextBox to do this.
   This seems a bit excessive if you have dozens of controls. 

2. Raise an Event via MouseEnter at runtime to request ToolTipTextW and ToolTipTitleW.

3. Set the Unicode via Public Sub InitTooltip at runtime.  



```
Public Sub InitTooltip(Text As String, Optional Title As String, Optional Icon As ToolTipIcon, Optional Style As ToolTipStyle = ttsBalloon, Optional BackColor As OLE_COLOR = vbInfoBackground, Optional ForeColor As OLE_COLOR = vbInfoText, Optional MaxWidth As Long = 260)
  mToolTipText = Text
  mToolTipTitle = Title
  mToolTipIcon = Icon
  mToolTipStyle = Style
  mToolTipBackColor = BackColor
  mToolTipForeColor = ForeColor
  mToolTipMaxWidth = MaxWidth
End Sub
```

Unicode Tooltips are handled via a class which is instantiated when necessary for each control.
Specifically, start the ToolTip during MouseEnter Event and stop (destroy class) via MouseLeave Event.

----------


## Krool

> TOOLTIP APPEARANCE QUESTION
> 
> The tooltips on TabStripW, ToolbarW and some more are fine, and they support even multiline.
> Also the appearance is fine.
> 
> Other controls like CommandButtonW, FrameW etc. show different looking tooltips.
> Here is an example:
> Attachment 162595
> 
> ...


This topic was already raised several times.
The ToolTipText property of a UserControl is in-built and can't be overrided. Thus a ToolTipTextW property would be needed.
Again, this is only an issue directly on the control.
For example, TabStrip1.Tabs(1).ToolTipText (and other similaries) can handle unicode and multiline text.

----------


## Eduardo-

Here there is a way to hook the tooltips, but I don't know if that can be of help.

----------


## Krool

Minor update for the VisualStyles.bas module.
It could happen when having a vbGraphical style CommandButtonW and calling Unload Form on the Click event to cause a crash. (run-time error 438)
Reason was that the internal 'RedirectButton' function in VisualStyles.bas calls the .Refresh method of the button object on WM_LBUTTONUP.
WM_LBUTTONUP causes a WM_COMMAND and the corresponding Click event and if that Click event unloads the form (and ultimately destroys the button object) the following .Refresh method in 'RedirectButton' failed with a crash.
This issue (and possibly other potential messages) got now resolved in VisualStyles.bas.

----------


## Hosam AL Dein

hi krool , 
I am using textboxw in a usercontrol . It is a custom textbox .

problem info :
1- this problem happens occasionally in the same circumstances every time . I mean sometimes it happens and sometimes it does not .
2- it happens only in a manifested IDE .
3- It happens When I try to click the usercotrol .

In the video link is a description of the scenario .

https://www.youtube.com/watch?v=Jwhs...ature=youtu.be

----------


## jpbro

Hi Krool - 

2 questions about the TabStrip control:

1) The TabStrip TabBeforeClick event passes a TabItem parameter. I would expect this to be the TabItem of the tab you have clicked (so you can decide whether or not to Cancel the operation based on conditions related to the new tab), but it appears the be a reference to the currently selected tab. Is this by design or is it a bug?

2) Perhaps I'm missing something, but I don't see a way to Disable individual tabs. Is this currently possible, and if not would you consider this for a future feature enhancement?

Thanks, and Happy New Year!

----------


## Hosam AL Dein

> hi krool , 
> I am using textboxw in a usercontrol . It is a custom textbox .
> 
> problem info :
> 1- this problem happens occasionally in the same circumstances every time . I mean sometimes it happens and sometimes it does not .
> 2- it happens only in a manifested IDE .
> 3- It happens When I try to click the usercotrol .
> 
> In the video link is a description of the scenario .
> ...


the link above no longer works . here is the new link 
https://www.youtube.com/watch?v=laFr...ature=youtu.be

----------


## Krool

> 2 questions about the TabStrip control:
> 
> 1) The TabStrip TabBeforeClick event passes a TabItem parameter. I would expect this to be the TabItem of the tab you have clicked (so you can decide whether or not to Cancel the operation based on conditions related to the new tab), but it appears the be a reference to the currently selected tab. Is this by design or is it a bug?
> 
> 2) Perhaps I'm missing something, but I don't see a way to Disable individual tabs. Is this currently possible, and if not would you consider this for a future feature enhancement?


First of all, compared to other comctl32 controls the SysTabControl32 is poor developed with not much possibilities.

TCN_SELCHANGING (TabBeforeClick) provides no way to determine which tab is about to be selected. It is a common issue you will find when googling about it.

So there are only two ways to use it:

1. (error in current tab, prevent change)
The TabItem in TabBeforeClick is the item which currently is selected (and not the new one; as not possible)
So you can make a check for the current tab if the content of the shown page panel (or whatever else you display with this tab) is valid. If error/invalid in your app then set Cancel parameter to True and prevent the change. (no flicker)

2. (disabled tab feature = cumbersome workaround with flicker)


```
Private LastTabItem As TbsTab

Private Sub TabStrip1_TabBeforeClick(ByVal TabItem As TbsTab, Cancel As Boolean)
Set LastTabItem = TabItem
Cancel = False ' Not applicable to use in this scenario as no way to know new selected tab. (blame MS)
End Sub

Private Sub TabStrip1_TabClick(ByVal TabItem As TbsTab)
If TabItem.Index = 2 Then ' Index 2 is our sample disabled Tab
    TabStrip1.SelectedItem = LastTabItem ' If LastTabItem is Nothing then no tab will have focus.
End If
End Sub
```

----------


## Hosam AL Dein

#2148

http://www.vbforums.com/showthread.p...=1#post5345409

Is there something I could be missing here ?

----------


## jpbro

> First of all, compared to other comctl32 controls the SysTabControl32 is poor developed with not much possibilities.
> 
> TCN_SELCHANGING (TabBeforeClick) provides no way to determine which tab is about to be selected. It is a common issue you will find when googling about it.
> 
> So there are only two ways to use it:


Understood, and thank you very much for the workaround code examples.

PS: I'm providing a link to an earlier post of mine because I didn't hear anything back from you about it. If you don't think the proposed changes are worthwhile/correct that's OK of course, I just wanted to make sure you didn't miss the post: http://www.vbforums.com/showthread.p...=1#post5330725

----------


## Krool

> #2148
> 
> http://www.vbforums.com/showthread.p...=1#post5345409
> 
> Is there something I could be missing here ?


In the form with code it crashes and same controls (copy & paste) to the test form without code it does not crash.
I suggest the problem is in your form code. Please check as this was not visible shown in your video. (Only UserControl was all code excluded by commenting)




> PS: I'm providing a link to an earlier post of mine because I didn't hear anything back from you about it. If you don't think the proposed changes are worthwhile/correct that's OK of course, I just wanted to make sure you didn't miss the post: http://www.vbforums.com/showthread.p...=1#post5330725


Oops. I forgot it. Will take a look soon when time is available.

----------


## DaveInCaz

Hi Krool, I'm using VBCCR16 (1.6.0.12) and have the following problem: *during compilation* of my EXE the following error message pops up:




> VBCCR16
>   Run-time error '0'


I've pasted a screenshot of this below. 

There have been NO problems when running from the IDE, and in fact VBCCR has been in use for quite some time without ever seeing this before during compilation.

Any ideas? It is preventing builds...

Thanks!
Dave

----------


## Krool

> Hi Krool, I'm using VBCCR16 (1.6.0.12) and have the following problem: *during compilation* of my EXE the following error message pops up:
> 
> 
> 
> I've pasted a screenshot of this below. 
> 
> There have been NO problems when running from the IDE, and in fact VBCCR has been in use for quite some time without ever seeing this before during compilation.
> 
> Any ideas? It is preventing builds...
> ...


With this information I can't dream the solution.
Please try to bundle this in a demo to isolate the problem.
Do you use any kind of add-ins that might interfere during compilation?

----------


## DaveInCaz

> With this information I can't dream the solution.
> Please try to bundle this in a demo to isolate the problem.
> Do you use any kind of add-ins that might interfere during compilation?


I totally understand that... I was mainly hoping you might already have familiarity with this. I will try to narrow down what is going on. The build environment hasn't changed in years so I doubt it is an add-in or other tool. 

For a long time we used VBCCR14, and more recently updated to VBCCR16. This may have been the first build since that was done.

In the ordinary course of a VB6 build is there any code inside an OCX which would be run during compilation? If so maybe that could provide a hint where to look further. I can see in VBCCR16 source code there is a custom MsgBox function, and from the look of that dialog it seems like it might be displayed using that code (maybe).

Thanks

----------


## Karl77

@Dave

Did you try to compile using the command line?
Like so:



```
"C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.EXE" /make YourProject.VBP
```

Just as a test.

----------


## DaveInCaz

> @Dave
> 
> Did you try to compile using the command line?
> Like so:
> 
> 
> 
> ```
> "C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.EXE" /make YourProject.VBP
> ...


I use Kinook Visual Build Pro to run the VB6 build, and I believe that is what it does, yes. The same error messagebox popped up when that was running as when I build from the IDE (the screenshot I showed).

Thanks

----------


## DaveInCaz

> @Dave
> 
> Did you try to compile using the command line?
> Like so:
> 
> 
> 
> ```
> "C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.EXE" /make YourProject.VBP
> ...


I use Kinook Visual Build Pro to run the VB6 build, and I believe that is what it does, yes. The same error messagebox popped up when that was running as when I build from the IDE (the screenshot I showed).

Thanks

----------


## wqweto

During compile-time custom UserControls are instantiated and read/write properties are fired which might lead to subclassing being setup etc. complications.

I'm using following code to filter compile-time from run-time&design-time and skip subclassing in my custom UCs


thinBasic Code:
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    With PropBag
        AutoSize = .ReadProperty("AutoSize", True)
        ...
    End With
    If Ambient.UserMode And Not IsCompileTime(Extender) Then
        SubClass m_uSubclass, hWnd, ObjPtr(Me), AddressOf RedirectWndProc
    End If
End Sub
 Private Function IsCompileTime(Extender As Object) As Boolean
    Dim oTopParent      As Object
    Dim oUserControl    As UserControl
    
    On Error GoTo QH
    Set oTopParent = Extender.Parent
    Set oUserControl = AsUserControl(oTopParent)
    Do While Not oUserControl Is Nothing
        If oUserControl.Parent Is Nothing Then
            Exit Do
        End If
        Set oTopParent = oUserControl.Parent
        Set oUserControl = AsUserControl(oTopParent)
    Loop
    Select Case TypeName(oTopParent)
    Case "Form", "UserControl"
        IsCompileTime = True
    End Select
QH:
End Function
 Private Function AsUserControl(oObj As Object) As UserControl
    Dim pControl        As UserControl
  
    If TypeOf oObj Is Form Then
        '--- do nothing
    Else
        Call CopyMemory(pControl, ObjPtr(oObj), 4)
        Set AsUserControl = pControl
        Call CopyMemory(pControl, 0&, 4)
    End If
End Function
It's a bit hacky and probably can be further simplified.

cheers,
</wqw>

----------


## DaveInCaz

> With this information I can't dream the solution.
> Please try to bundle this in a demo to isolate the problem.
> Do you use any kind of add-ins that might interfere during compilation?


Additional detail - this error occurs on our build environment (a Win7-32 virtual machine), but not on another developer's PC. 

So there is something environmental which is somehow influencing when the error occurs. I believe i have ruled out disk space (made sure there was at least 20 GB free during the compile).

Could it be some missing dependency? AFAIK both environments have all the same files related to VBCCR.

----------


## wqweto

> Could it be some missing dependency? AFAIK both environments have all the same files related to VBCCR.


Could VB6 be missing Service Pack 6?

cheers,
</wqw>

----------


## DaveInCaz

> Could VB6 be missing Service Pack 6?
> 
> cheers,
> </wqw>


Hi wqw,

I thought it was updated to SP6 but I double checked just to make sure - it is. It says SP6 in Help > About.

But thanks for the suggestion.

----------


## Krool

> Additional detail - this error occurs on our build environment (a Win7-32 virtual machine), but not on another developer's PC. 
> 
> So there is something environmental which is somehow influencing when the error occurs. I believe i have ruled out disk space (made sure there was at least 20 GB free during the compile).
> 
> Could it be some missing dependency? AFAIK both environments have all the same files related to VBCCR.


Please try to further isolate the problem. Commenting out code and removing controls one after another until the error do not appear anymore and find the boogeyman.

----------


## DaveInCaz

> Please try to further isolate the problem. Commenting out code and removing controls one after another until the error do not appear anymore and find the boogeyman.


Well I've made a little progress...

Trying to narrow this down: In the IDE, I decided to load / save all the forms in the project which use any VBCCR16 controls. Sure enough, I found one form which refuses to load, showing the SAME error message I saw from the compiler: "VBCCR16 ... Run-time error '0'". So this is not exclusively a compile-time issue.

It also produces an error log file for the form, containing:



```
Line 15: Cannot load control ToolBar1; license not found.
Line 51: Cannot load control StatusBar1; license not found.
Line 62: Cannot load control TreeView1; license not found.
Line 75: Cannot load control ListView1; license not found.
```

What does "license not found" mean?  Each of those are VBCCR16 controls, for example:



```
   Begin VBCCR16.ToolBar ToolBar1 
      Align           =   1  'Align Top
      Height          =   810
      Left            =   0
      Top             =   0
      Width           =   7590
      _ExtentX        =   13388
      _ExtentY        =   1429
      ImageList       =   "imlIcons"
      Style           =   1
      ShowTips        =   -1  'True
      AllowCustomize  =   0   'False
      ButtonWidth     =   23
      InitButtons     =   "Main.frx":038A
   End
```

(I know this message could apply to controls which genuinely do require a license, but VBCCR16 does not, and as previously noted this does not happen on my other dev PC.)

BTW I have unregistered / re-registered VBCCR16, to no effect.

Thanks!

----------


## Krool

Update released. (see below)




> I've been using your RichTextBox control and it works great, but I've found a potential spot for a performance improvement. Right now getting RTF via the TextRtf property can be quite slow on large documents (for example, documents with large images embedded). On my computer it is taking almost 3 seconds to return about 4MB of RTF.
> 
> I traced this to the RtfStreamCallbackStringOut method, where the BytesRequested parameter tends to use fairly small chunks of around 4KB. Combined with around 1000 Redim Preserves, this seems to be the culprit. Maybe there's a way to increase the "chunk" size the RichEdit control uses, but I'm not aware of this. 
> 
> Instead I've tried implementing a 1MB buffer that increases in BufferSize*2 chunks with a final Redim Preserve to the correct size (reducing the number of Redims to 4 vs. 1000 in the example case). The performance boost is significant, taking about 0.1 seconds vs 2.5-3 seconds).
> 
> Here's my code if you are interested. Feel free to use it, or modify it in any way that you see fit. It hasn't been tested heavily yet, so there may be issues so please review it carefully if you intend to use it (especially check for off-by-one errors on the buffer resizing/ubound at chunk boundaries).


Thanks for your enhancement. I implemented your solution.  :Smilie: 

I like the idea and it is clever, not hacky and very straight forward actually. It seems the 4 KB chunk size of the rich edit control can't be changed. (I didn't find a way to do so)
So, the only way to improve the performance is (as you have shown) is to reduce the number of ReDim Preserve by bumping the array with higher chunks and at end to make a final correction.
However, in my opinion the 1MB up to 16MB buffer bumps were too much.
I decided to just make 16KB up to 64KB buffer bumps.
This already made a very huge performance boost instead of always buffer bumping max. 4 KB.

So my version is:


```
Public Function RtfStreamStringOut() As String
If StreamStringOutUBound > 0 Then ReDim Preserve StreamStringOut(0 To (StreamStringOutUBound - 1)) As Byte
RtfStreamStringOut = StreamStringOut()
Erase StreamStringOut()
StreamStringOutUBound = 0
StreamStringOutBufferSize = 0
End Function

Public Function RtfStreamCallbackStringOut(ByVal dwCookie As Long, ByVal ByteBufferPtr As Long, ByVal BytesRequested As Long, ByRef BytesProcessed As Long) As Long
If BytesRequested > 0 Then
    If StreamStringOutBufferSize < (StreamStringOutUBound + BytesRequested - 1) Then
        Dim BufferBump As Long
        If StreamStringOutBufferSize = 0 Then
            BufferBump = 16384 ' Initialize at 16 KB
        Else
            BufferBump = StreamStringOutBufferSize
            If BufferBump > 65536 Then BufferBump = 65536 ' Cap at 64 KB
        End If
        If BufferBump < BytesRequested Then BufferBump = BytesRequested
        StreamStringOutBufferSize = StreamStringOutBufferSize + BufferBump
        ReDim Preserve StreamStringOut(0 To (StreamStringOutBufferSize - 1)) As Byte
    End If
    CopyMemory StreamStringOut(StreamStringOutUBound), ByVal ByteBufferPtr, BytesRequested
    StreamStringOutUBound = StreamStringOutUBound + BytesRequested
    BytesProcessed = BytesRequested
Else
    BytesProcessed = 0
End If
RtfStreamCallbackStringOut = 0
End Function
```

Just as info: There was a typo error in your code.


```
' Initialize buffer to ~1MB
 l_BufferBump = 104576
```

1 MB would be 1048576

----------


## jpbro

> Update released. (see below)
> 
> Thanks for your enhancement. I implemented your solution.


That's great, happy to help and glad I contribute (however small) back to your great project!




> I like the idea and it is clever, not hacky and very straight forward actually.


Thanks  :Smilie:  




> It seems the 4 KB chunk size of the rich edit control can't be changed. (I didn't find a way to do so)
> So, the only way to improve the performance is (as you have shown) is to reduce the number of ReDim Preserve by bumping the array with higher chunks and at end to make a final correction.
> However, in my opinion the 1MB up to 16MB buffer bumps were too much.
> I decided to just make 16KB up to 64KB buffer bumps.
> This already made a very huge performance boost instead of always buffer bumping max. 4 KB.


I agree that 1MB-16MB bumps are pretty aggressive in the general case, but in my use case I found a lot of RTFs with large-ish images in them, so it made sense to do larger buffer jumps. As a general solution though, I think you are right that smaller bumps might more sense. My use cases might be unusual, but I think you might want to reconsider the 64K max bump though as RTF files with images can get big quickly, and 64KB chunks can still mean 100s of ReDims. Capping at 512Kb might be appropriate? If the cap isn't being hit it won't matter anyway, but if it is needed then it will help performance.  Just a thought though, I certainly defer to your expertise in the matter if you think 64K is appropriate.




> Just as info: There was a typo error in your code.
> 
> 
> ```
> ' Initialize buffer to ~1MB
>  l_BufferBump = 104576
> ```
> 
> 1 MB would be 1048576


Good catch, thanks a lot!

----------


## Cube8

> ...
> I agree that 1MB-16MB bumps are pretty aggressive in the general case, but in my use case I found a lot of RTFs with large-ish images in them, so it made sense to do larger buffer jumps. As a general solution though, I think you are right that smaller bumps might more sense. My use cases might be unusual, but I think you might want to reconsider the 64K max bump though as RTF files with images can get big quickly, and 64KB chunks can still mean 100s of ReDims. Capping at 512Kb might be appropriate? If the cap isn't being hit it won't matter anyway, but if it is needed then it will help performance.  Just a thought though, I certainly defer to your expertise in the matter if you think 64K is appropriate.
> ...


There could be a new property (long), called (for example) _LoadBufferSize_, that would take the chunk size in bytes.

----------


## Krool

> My use cases might be unusual, but I think you might want to reconsider the 64K max bump though as RTF files with images can get big quickly, and 64KB chunks can still mean 100s of ReDims. Capping at 512Kb might be appropriate? If the cap isn't being hit it won't matter anyway, but if it is needed then it will help performance.  Just a thought though, I certainly defer to your expertise in the matter if you think 64K is appropriate.


Ok, I changed the max. chunk size to 512 kb. It will start at 16 kb, then next on 32 kb, then 64 kb, then 128 kb, then 256 kb, then 512 kb and any further be capped at 512 kb.
I think this is now a good balance for all uses.




> There could be a new property (long), called (for example) _LoadBufferSize_, that would take the chunk size in bytes.


Too much I think. I think the hard-coded range now is a good balance for all uses and not necessary to make a new property (long).

----------


## Derp!

Hey Krool,  Thanks for this awesome set of controls!  I came across them while searching for an RTF box that has a backcolor setting for text.  The only other thing that’s always peeved be about the standard VB RTFbox was that there was no way to temporarily stop the Selchange event from firing.  I added that in my copy of your tools so that the control checks a Boolean variable (set through a property) before firing off the event.  Otherwise I had a procedure that colors the background text firing off the Selchange event dozens of times every time I formatted the box.  I added the DisableEvents property to some other controls such as the sliders for the same reason.  It made a world of difference!

----------


## Derp!

Hey Krool,  Thanks for this awesome set of controls!  I came across them while searching for an RTF box that has a backcolor setting for text.  The only other thing thats always peeved be about the standard VB RTFbox was that there was no way to temporarily stop the Selchange event from firing.  I added that in my copy of your tools so that the control checks a Boolean variable (set through a property) before firing off the event.  Otherwise I had a procedure that colors the background text firing off the Selchange event dozens of times every time I formatted the box.  I added the DisableEvents property to some other controls such as the sliders for the same reason.  It made a world of difference!

----------


## Mith

> Ok, I changed the max. chunk size to 512 kb. It will start at 16 kb, then next on 32 kb, then 64 kb, then 128 kb, then 256 kb, then 512 kb and any further be capped at 512 kb.
> I think this is now a good balance for all uses.





> 06-Jan-2019
> - Major perfomance boost when reading .Text or .TextRTF in the RichTextBox control.
>   This was achieved by reducing the number of 'ReDim Preserve' in the internal RtfStreamCallbackStringOut function.


there is also a performance problem using the function .LoadFile:

1. loading a text file with 8,41 MB using .LoadFile with the parameter _RtfLoadSaveFormatText_  takes only 1 second
2. loading a text file with 8,41 MB using .LoadFile with the parameter _RtfLoadSaveFormatUnicodeText_  takes ~100 seconds!

i found the function "_LoadFile(ByVal FileName As String, Optional ByVal Format As RtfLoadSaveFormatConstants = RtfLoadSaveFormatRTF, Optional ByVal SelectionOnly As Boolean)_" at the source code and included a do-loop to read chunks from the file but i dont know how to use the func "_StreamStringIn_" multiple times. everytime i call StreamStringIn the previous added text will be deleted. any hints how to do that?

----------


## pepegriyo2016

I have used your library for a long time. I always use the .ocx and some time ago I started adding to my project only the components that I use in my project to not depend more on the .ocx library.
I have also started using the tool
http://www.aivosto.com/vbwatch.html
which notifies of errors in the program and allows you to see in what function and procedures it fails.
I have to tell you that it fails in many functions. The site of aivosto.com delivers a 7 day demo of VB Watch to test it. I could try it and see for yourself where it fails or I could send you a version of CommonControls with this included if you like.

----------


## pepegriyo2016

Sorry Krool,
Your tools is working perfect. I compile the project and don't have error.

The was my project with yours controls. I will be check my code. Sorry for the report.

----------


## Stu2

I have a problem with the MonthView control.
It shows in the standard demo program.

If UseShortestDayNames = False(the property set at design time) the days on the calendar show as "Mo", "Tu", "We", ...

(In the DTPicker, with CalendarUseShortestDayNames = False the days show as "Mon", "Tue", "Wed", ...  which is what I would expect.)

It seems a workaround to fix the issue is to _programmatically_ set MonthView1.UseShortestDayNames = False
If I programmatically set MonthView1.UseShortestDayNames = False the days show as "Mon", "Tue", "Wed", ...


Is this the expected behavior?

_
Further Information_

At design time, if I set UseShortestDayNames = True,  then set it back to False the days show as "Mon", "Tue", "Wed", ...
But this isn't remembered, if I Run the application it reverts back to  "Mo", "Tu", "We", ...

----------


## DaveInCaz

> Please try to further isolate the problem. Commenting out code and removing controls one after another until the error do not appear anymore and find the boogeyman.


I have managed to narrow this down to the following scenarios.

*On PC #1:*
Load a specific ICO file into ImageList on a form. _No problem._
Open / close that form in designer - _No problem._
Compile & run program - _No problem._

*On PC #2, Scenario 1:*
Load _the same ICO file_ into ImageList on a form. Shows error message "VBCCR16 ... Invalid picture". Ok...


*On PC #2, Scenario 2:* 
Share the form _including this icon from PC#1_... 
Attempt to load ANY FORM which uses ANY VBCCR16 control in the IDE - get the error that I showed previously ("VBCCR16 ... Run time error 0").
Attempt to compile the program - same error.

*Notes:*
PC#1 is Windows 10 x64
PC#2 is Windows 7 x32

Here is a copy of the "evil" icon file: Space2_16x16.zip


*Comments & ideas:*
I can see in the VBCCR16 code that the ImageList tries to use OleLoadPicturePath() to load the actual ICO file. And if this fails for any reason the "Invalid picture" message is generated.


So this seems like progress, but also raises a lot of questions:

Why the difference between the two computers? Is something wrong with the ICO file? Even if so, why does it work on one computer only?

When the bad icon data is loaded on PC#2, why do ALL forms using VBCCR16 get affected?

I see that OleLoadPicturePath() comes from OLEAUT32.dll. On PC#1, it is version 10.0.16299.431.  On PC#2 is is version 6.1.7601.17676.

Dave

----------


## Steve Grant

Your 16 x 16 icon is 32bit. On windows 10 it appears you can get away with it. On Windows 7 you must adhere to the limits imposed by VB6.

I have attached the same image converted to 8 bit (256 colors), see if that helps.

----------


## Krool

> I have a problem with the MonthView control.
> It shows in the standard demo program.
> 
> If UseShortestDayNames = False(the property set at design time) the days on the calendar show as "Mo", "Tu", "We", ...


Fixed. Thanks for bringing this up!

----------


## SuperDre

> Your 16 x 16 icon is 32bit. On windows 10 it appears you can get away with it. On Windows 7 you must adhere to the limits imposed by VB6.
> 
> I have attached the same image converted to 8 bit (256 colors), see if that helps.


I think if you also have 32bit in the same ICO there is no problem, at least not with a regular icons for forms. But then again I use the original Icon in the Icon property and have the same Icon also in a resource which I later load through the WinAPI (which ofcourse only works outside the IDE, at least on Windows 7 as I'm still developing in Windows 7 x64 with VB6)

----------


## SuperDre

> Your 16 x 16 icon is 32bit. On windows 10 it appears you can get away with it. On Windows 7 you must adhere to the limits imposed by VB6.
> 
> I have attached the same image converted to 8 bit (256 colors), see if that helps.


I think if you also have 32bit in the same ICO there is no problem, at least not with a regular icons for forms. But then again I use the original Icon in the Icon property and have the same Icon also in a resource which I later load through the WinAPI (which ofcourse only works outside the IDE, at least on Windows 7 as I'm still developing in Windows 7 x64 with VB6)

----------


## Steve Grant

The original was a single 16 x 16 x 32 icon. Nothing else in it. Were you able to try it?

----------


## DaveInCaz

> Your 16 x 16 icon is 32bit. On windows 10 it appears you can get away with it. On Windows 7 you must adhere to the limits imposed by VB6.
> 
> I have attached the same image converted to 8 bit (256 colors), see if that helps.


Hello Steve - yes, this worked - thank you for the clear explanation & help.

I'm still surprised that this depends on the Windows version... if they have "improved" the mechanism in Windows 10 to now accept 32-bit icons, and it never used to, it seems like a backwards-compatibility fail to me.

Dave

PS: I used to live in SE9, not terribly far from your area! Now back in NY  :Smilie:

----------


## Krool

> there is also a performance problem using the function .LoadFile:
> 
> 1. loading a text file with 8,41 MB using .LoadFile with the parameter _RtfLoadSaveFormatText_  takes only 1 second
> 2. loading a text file with 8,41 MB using .LoadFile with the parameter _RtfLoadSaveFormatUnicodeText_  takes ~100 seconds!
> 
> i found the function "_LoadFile(ByVal FileName As String, Optional ByVal Format As RtfLoadSaveFormatConstants = RtfLoadSaveFormatRTF, Optional ByVal SelectionOnly As Boolean)_" at the source code and included a do-loop to read chunks from the file but i dont know how to use the func "_StreamStringIn_" multiple times. everytime i call StreamStringIn the previous added text will be deleted. any hints how to do that?


I can't replicate the issue.

I tested this with a text file which was ANSI and was 5,68 MB file big. I just re-saved them as Unicode and it went to 11,3 MB.

Both file loadings take same time. ~0,87 sec

So I can't see why it would take 100 sec!

Please provide a demo. Thanks

*EDIT:*
Update released. I found the issue. The issue was that you loaded an actual ANSI file (no Unicode BOM) with the RtfLoadSaveFormatUnicodeText flag.
However, now when RtfLoadSaveFormatUnicodeText is used it will remove the SF_UNICODE flag in case there is no Unicode BOM = Solved.
This means RtfLoadSaveFormatUnicodeText will be same as RtfLoadSaveFormatText in case you load a non-Unicode file (e.g. ANSI)
I think this solution is properly and therefore RtfLoadSaveFormatUnicodeText is save to use in any case now.

----------


## pepegriyo2016

> Your 16 x 16 icon is 32bit. On windows 10 it appears you can get away with it. On Windows 7 you must adhere to the limits imposed by VB6.
> 
> I have attached the same image converted to 8 bit (256 colors), see if that helps.


you can also use 24bits and size 16x16

----------


## pepegriyo2016

Delete post

----------


## Karl77

@DaveInCaz

A few days ago I had icon problems as well.
The compiled EXE silently crashed on some PCs.

Error hunting was a long story, but to make it short:
A form had an icon assigned in the IDE.
This form made the whole app crash with no chance for error handling.
Once I removed the icon, made a new EXE, the app runs without this crash.

When I set the form icon via API, no error occurs.
I do this anyway in other forms, so no effort to fix it.

I think the error only comes up if the form icon is set in the IDE when the IDE runs on Win10.

I don't think this has to do with VBCCR at all.

----------


## DaveInCaz

> @DaveInCaz
> 
> A few days ago I had icon problems as well.
> The compiled EXE silently crashed on some PCs.
> 
> Error hunting was a long story, but to make it short:
> A form had an icon assigned in the IDE.
> This form made the whole app crash with no chance for error handling.
> Once I removed the icon, made a new EXE, the app runs without this crash.
> ...


Hi Karl, Thanks for sharing your experience - that is exactly what I have narrowed my problem down to also. I think something has changed in Windows. It is not a bug in VBCCR, its just that VBCCR uses whatever underlying API has changed.


Krool - as far as it goes however, VBCCR has an opportunity here ... It looks like the ImageList uses OleLoadPicturePath to load the action icon file. Something underneath OleLoadPicturePath() must be what has changed to allow previously INVALID icons to be loaded without error.

So, to avoid that problem, the ImageList could confirm that the bit depth of the icon is actually acceptable to VB6, and reject it otherwise. To me this change in OleLoadPicturePath seems like a bug, in that it introduces this awful incompatibility between your resulting compiled program and some Windows PCs. So some extra checking here might be a valuable addition.

Dave

----------


## DEXWERX

From what I understand this has been an existing bug with even the original ImageList. (One of several backwards incompatible bugs)
A run-time check/warning depending on OS however would be nice.

----------


## Karl77

@DaveInCaz




> So some extra checking here might be a valuable addition.


No, at least not in my case.
The form icons were assigned years ago, so I very well know that the icons are valid and ok.
Also they were not handled via ImageList or VBCCR ImageList, they were assigned in the IDE.

For the VBCCR Imagelists I have another wish:
AddPNG from external resource dll
But that's another story.

----------


## DaveInCaz

> From what I understand this has been an existing bug with even the original ImageList. (One of several backwards incompatible bugs)
> A run-time check/warning depending on OS however would be nice.


Krool, one other thing to consider is the way this problem becomes visible when it occurs. In my original post I showed the error messages I was getting which said something about "licensing" issues, which didn't make any sense. I'm not sure if VBCCR has any control over that error message - maybe not - but it it is possible to report better errors that would help diagnosis a lot. It seems like the failures due to the incompatible icon were in the event handlers which get called when the IDE loads a form, and during compilation (ReadProperties, I'd guess).

This is just a "wish list" item!

Dave

----------


## Krool

Update released. (phase 1 of 2 concerning StdPicture rendering improvement)

Improved BitmapHandleFromPicture function. (internal function used by various controls, e.g. ListView)
It now also draws the BackColor parameter for non-icons.
This has the advantage that transparent GIF bitmaps and metafiles look better for example in the ListView.
ListView can only handle bitmaps. That was the sense of BitmapHandleFromPicture to return a bitmap from whatever picture format.

Also a change CommandButtonW/CheckBoxW/OptionButtonW concerning drawing of disabled pictures in vbButtonGraphical style. (in case no explicit DisabledPicture property is set)
To draw disabled state from a normal picture the three controls use DrawState API.
Now they use the improved BitmapHandleFromPicture function to better draw non-icons:


```
If ButtonPicture.Type = vbPicTypeIcon Then
    DrawState DIS.hDC, 0, 0, ButtonPicture.Handle, 0, X, Y, CX, CY, DST_ICON Or DSS_DISABLED
Else
    Dim hImage As Long
    hImage = BitmapHandleFromPicture(ButtonPicture, vbWhite)
    ' The DrawState API with DSS_DISABLED will draw white as transparent.
    ' This will ensure GIF bitmaps or metafiles are better drawn.
    DrawState DIS.hDC, 0, 0, hImage, 0, X, Y, CX, CY, DST_BITMAP Or DSS_DISABLED
    DeleteObject hImage
End If
```

previously the code block looked as following:


```
If ButtonPicture.Type = vbPicTypeIcon Then
    DrawState DIS.hDC, 0, 0, ButtonPicture.Handle, 0, X, Y, CX, CY, DST_ICON Or DSS_DISABLED
ElseIf ButtonPicture.Type = vbPicTypeBitmap Then
    DrawState DIS.hDC, 0, 0, ButtonPicture.Handle, 0, X, Y, CX, CY, DST_BITMAP Or DSS_DISABLED
End If
```

Metafiles were not processed and transparent GIF bitmaps looked ugly.
Also with the new method the Metafiles with transparency also looks better. (even better than in intrinsic VB controls)

----------


## Mith

> Update released. (phase 1 of 2 concerning StdPicture rendering improvement)
> This has the advantage that transparent GIF bitmaps and metafiles look better for example in the ListView.
> ListView can only handle bitmaps.


i have a listview with some subitems and the subitems contain only a icon to check/uncheck a option.
is it somehow possible to center the icons of subitems at the listview when using the report mode?

----------


## Krool

> i have a listview with some subitems and the subitems contain only a icon to check/uncheck a option.
> is it somehow possible to center the icons of subitems at the listview when using the report mode?


It's not possible. At least of that I know.
Only workaround is to set LVS_OWNERDRAWFIXED and do the drawing yourself.

----------


## ScriptBASIC

Hi Krool,

I recently upgraded to Windows 10 with a new laptop and happy to report that the VB6 IDE is running great under Windows 10. I had to select *Windows Vista SP2* emulation for *VB6.EXE* to get the resizing to work normally but everything else seems fine. 

What is the best way to upgrade your CCR with a project using an older version?

----------


## Krool

> What is the best way to upgrade your CCR with a project using an older version?


You mean for example switching from 1.4 to 1.6?
MountainMan created an convenient
Update Utility

----------


## Krool

Update released.

Cleanup and performance improvement of VisualStyles.bas.
It also now use WM_QUERYUISTATE to consider if focus rect or accel should be drawn.

VisualStyles.bas only considers now VB intrinsic CommandButton/CheckBox/OptionButton controls.

CommandButtonW/CheckBoxW/OptionButtonW controls now draw themed on vbButtonGraphical by their own.
This way the ForeColor property can be used on vbButtonGraphical even when themed.



Edit:
OCX version also updated. As only internal changes were done there was no compatibility break.
Std-EXE and OCX version are still full in sync as of today.

----------


## Krool

Again update related to VisualStyles.bas.

It seems there was a strange bug for the VB.OptionButton control. (not for VB.CommandButton or VB.CheckBox)
The OptionButtonW control was also not affected. (both, before recent update to draw within VisualStyles.bas and after recent update to draw itself)

The bug was that the theming could just dissapear without any cause by the application itself for the VB.OptionButton control.

Previously there was a check in WM_PAINT to draw only themed when the window has visual styles applied:


```
Case WM_PAINT
    If IsWindowVisible(hWnd) <> 0 And GetVisualStyles(hWnd) <> 0 Then
```

Now (also performance improvement) the check is only done once at initialization and only update on WM_THEMECHANGE, the code of WM_PAINT is therefore now:


```
Case WM_PAINT
    If IsWindowVisible(hWnd) <> 0 And GetProp(hWnd, StrPtr("VisualStyles")) <> 0 Then
```

This solved the issue for VB.OptionButton (I have no real explanation why whatsoever..) and of course is also more efficient. (performance)

----------


## Mith

VBCCR16 v1.6.23

I use the Slider-Control with ShowTip=True and while i drag the thumb around a tooltiptext is displayed with the current value BUT the event ModifyTipText is never triggered.
I want to format the value shown at the tooltiptext. Does the event ModifyTipText not exist for this reason?

----------


## Mith

using an non-empty ImageList with ColorDepth=32 under WinXP will crash VBCCR16.OCX v1.6.23 at the start of the app:



I didnt do any coding inside the test app. I just placed a ImageList on the form, set it to ColorDepth=32 and added one 32bit icon.

Maybe you can catch the error and return a blank icon so the app will still run?

----------


## Krool

Update released.




> I use the Slider-Control with ShowTip=True and while i drag the thumb around a tooltiptext is displayed with the current value BUT the event ModifyTipText is never triggered.
> I want to format the value shown at the tooltiptext. Does the event ModifyTipText not exist for this reason?


Resolved. Thanks!




> using an non-empty ImageList with ColorDepth=32 under WinXP will crash VBCCR16.OCX v1.6.23 at the start of the app:
> 
> 
> 
> I didnt do any coding inside the test app. I just placed a ImageList on the form, set it to ColorDepth=32 and added one 32bit icon.
> 
> Maybe you can catch the error and return a blank icon so the app will still run?


It's a pity that 32bit icons can't be loaded in Windows XP to a StdPicture.  :Sick: 
Or to be optimistic. It's a pleasure to be able to load 32bit icons in Windows 7 and later into a StdPicture object.  :Smilie: 

However, this is a true obstacle when developing in Windows 7 and later on use in Windows XP.  :Sick: 

I could imagine to determine when - browsing a picture to load to - to persist a flag in the property bag that this doesn't work on Windows XP or older.
That would be quite less overhead costs.

But of course that would not be backward compatible. But I think it is anyway not possible to be backward compatible as loading this 32 bit icon from the property bag will already crash Windows XP.

So a flag in the property bag is anyhow needed. But of course the drawback will always then be that it would only work on new image list set's.

Open question: Handling this issue? Or just keep it as it is as this obstacle was put up by MS.  :Big Grin:

----------


## DaveInCaz

> Update released.
> 
> Open question: Handling this issue? Or just keep it as it is as this obstacle was put up by MS.



This seems like a similar / same root issue as I had mentioned a few weeks ago (. 

The problem in my case was that the 32-bit icon was allowed under Win10, and then caused mysterious failures on other systems (Win7). It was very hard to debug.

If there is a reasonable way to catch this problem up front and avoid the issue, I would recommend that.

----------


## Mith

> Update released.


the event ModifyTipText works now as expected with the new update!





> So a flag in the property bag is anyhow needed. But of course the drawback will always then be that it would only work on new image list set's.
> Open question: Handling this issue? Or just keep it as it is as this obstacle was put up by MS.


i vote for the new flag at the property bag! 
this will avoid the app crash under winxp!

----------


## Mith

I use the ListView in Report Mode with multiple columns and i want that the user can edit the cell of every column (subitems).

LabelEdit = True let me only edit the cell of the first column. 

Is it maybe possible to add a LabelEdit for all columns?

I also tried to write my own LabelEdit-handler for subitems 
but the Event ItemDblClick(ByVal Item As VBCCR16.LvwListItem, ByVal Button As Integer) 
only returns a DblClick of the first column item.

Is it possible to enhance the Event ItemDblClick to return subitems too?

----------


## ScriptBASIC

Krool,

I thought I would give my VB6 OCX form control a try in Wine. I was surprise it work since I haven't had much luck with VB6 and Wine in the past. This form is using your CCR OCX which works fine under standard Windows but for some reason the checkbox background is black. The other controls seem to render and theme okay.

----------


## Krool

Update released.

Replaced WM_CHANGEUISTATE with WM_UPDATEUISTATE in VisualStyles.bas.
This change was already done in ComCtlsBase.bas since a while. (use of WM_UPDATEUISTATE instead of WM_CHANGEUISTATE)

The difference between the two is (in short) the message travel direction. WM_CHANGEUISTATE travels the tree up, verifies if change is needed, and then issue WM_UPDATEUISTATE down the tree for all childs.
For our needs we want for SetupVisualStyles to have all child controls the needed ui state. So WM_UPDATEUISTATE is more direct and more performant.
Beside that, when using MDI child forms WM_CHANGEUISTATE will only work *once*. Because it travels up to the top-level window (MDI container form).
So next time a new MDI child form is open WM_CHANGEUISTATE will not issue WM_UPDATEUISTATE as the top-level window is already marked with the needed changes.
This is another argument why WM_UPDATEUISTATE is definitely better for VisualStyles.bas




> I thought I would give my VB6 OCX form control a try in Wine. I was surprise it work since I haven't had much luck with VB6 and Wine in the past. This form is using your CCR OCX which works fine under standard Windows but for some reason the checkbox background is black. The other controls seem to render and theme okay.


Your screenshot looks like the typical VB.Frame theme bug
In the VisualStyles.bas this is fixed by redirecting WM_PRINTCLIENT message (for the black background drawing flaws) and WM_MOUSELEAVE (for some flicker) to DefWindowProc:


```
Private Function RedirectFrame(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Select Case wMsg
    Case WM_PRINTCLIENT, WM_MOUSELEAVE
        RedirectFrame = DefWindowProc(hWnd, wMsg, wParam, lParam)
        Exit Function
End Select
RedirectFrame = DefSubclassProc(hWnd, wMsg, wParam, lParam)
If wMsg = WM_NCDESTROY Then Call RemoveRedirectFrame(hWnd, uIdSubclass)
End Function
```

Can you check if your Form uses VB.Frames ?

----------


## ScriptBASIC

I'm using your frame control for the form. (CCR14)

Here is a thread on my VB6 OCX Form with Script BASIC project. 

https://www.allbasic.info/forum/inde...sg5269#msg5269

----------


## ScriptBASIC

It seems that the problem extends to radio buttons as well.  :Mad:

----------


## Krool

Please update to CCR16. (The FrameW control was remade after CCR14)

----------


## ScriptBASIC

Thanks *Krool*!

Upgrading to *VBCCR16.OCX* fixed the problem.

----------


## Krool

> Upgrading to *VBCCR16.OCX* fixed the problem.


That's not sure. It looks like you tested it un-themed. The typical issue is that such black backgrounds only occur when theming is enabled.

----------


## ScriptBASIC

You're right. My Windows 10 install of VB6 IDE isn't theming the executable's like they were under Windows 7. Do I need the SidebySide files? All I did was add VBCCR16.OCX to the project. I forgot how to enable theming since it's been so long since I set that up on Windows 7.

It's interesting theming works fine within the IDE but it's W2K look as an executable.

It took me while to get the instructions in your readme about OLEGuids to register. The file needed to go into SyWow64 rather then System32. Funny VB6 resource browser wouldn't even show the file even with *.*.

Appreciate any help or suggestions to refresh my memory.

----------


## Krool

> You're right. My Windows 10 install of VB6 IDE isn't theming the executable's like they were under Windows 7. Do I need the SidebySide files? All I did was add VBCCR16.OCX to the project. I forgot how to enable theming since it's been so long since I set that up on Windows 7.
> 
> It's interesting theming works fine within the IDE but it's W2K look as an executable.
> 
> It took me while to get the instructions in your readme about OLEGuids to register. The file needed to go into SyWow64 rather then System32. Funny VB6 resource browser wouldn't even show the file even with *.*.
> 
> Appreciate any help or suggestions to refresh my memory.


For the OCX you don't need to register OLEGuids.

----------


## SuperDre

> The file needed to go into SyWow64 rather then System32. Funny VB6 resource browser wouldn't even show the file even with *.*.


that's how Windows 10 (and 7) x64 works, it's actually only using SysWo64.
Also wasn't theming part of Aero which is removed from windows 10 (if I'm not mistaken). I never bothered with themes, was just too much hassle and to me it really didn't add anything to the application, I saw the problem with the black background with checkboxes and optionboxes in a competing application and it seems like it's got something to do with windowless controls (if I'm not mistaken).

----------


## Tech99

Highlighting bug in monthview control 'Today' section?

- when mouse is over 'Today' last character is not highlighted 20.2.2019 -> 9
- when clicked today and mouse is out of 'Today' area last character 'stays' highlighted.

Tested in Windows 7x64, 10x64 finnish localized (fi locale = 1035) system, both has latest updates.

----------


## ScriptBASIC

> Also wasn't theming part of Aero which is removed from windows 10 (if I'm not mistaken).


The Online Dictionary OCX form was created under Windows 7 using VBCCR14.OCX. Theming works under Windows 10 for this control. 

I'm clueless at the moment why theming works within the IDE (run) but is themeless when generated as a .EXE under my Windows 10 install of VB6 IDE.

----------


## pepegriyo2016

Krool, Could you implement Big TexBox in texbox?
Use this code
http://www.vbforums.com/showthread.p...=1#post4608889

----------


## ScriptBASIC

Krool,

I was able to get theming to work adding the sidebysideandstyles.res file to the project. Under Windows 10 it looks great.

I'm not so lucky under Wine. Adding the .res file now causes a page fault on exit of the program.   :EEK!:

----------


## DEXWERX

ah the old crash at shutdown of a manifested comctl app. you need to load shell32.dll prior to comctl32.dll. 

are you using non-VBCCR controls on the form?

----------


## Krool

> Krool,
> 
> I was able to get theming to work adding the sidebysideandstyles.res file to the project. Under Windows 10 it looks great.
> 
> I'm not so lucky under Wine. Adding the .res file now causes a page fault on exit of the program.


Do you use VisualStyles.bas ? If you call InitVisualStyles at sub Main the crash is avoided.

----------


## ScriptBASIC

There is no *InitVisualStyles* function in *VisualStyles.bas*.

----------


## Krool

> There is no *InitVisualStyles* function in *VisualStyles.bas*.


In the OCX project this is true. When you use the OCX in a EXE project then you shall use VisualStyles.bas from the first page in this thread from ComCtlsDemo.
Also on each Form_Load call SetupVisualStyles.

----------


## ScriptBASIC

Krool,

I'm noticing other issues non-display related with trying to run VB6 apps / OCXs on Wine. I'm going to put this on the back burner till I have more time to trouble shoot the issues.

On a positive note my new laptop running Windows 10 with VB6 IDE / VS2008 installed is working great so far and that is where I would rather spend any free time I have to spare.

Thankls for your efforts with trying to get this going.

----------


## dreammanor

Krool's CommonControls is a great product set, and if it was released 10 years earlier, its value would be 10 times greater than it is now.

Since the release of Win8, the controls that come with Windows can meet the requirements of most VB6 UI designs. The need to use heavyweight custom CommonControls is not so urgent.

I once had the idea of rewriting Krool's CommonControls in a DUI way so that these controls could be made more lightweight, more flexible (using XML as the controls' configuration files), and easier to port to Linux (Wine).

Since there are fewer and fewer people using win desktop-apps, I gave up on this idea.

*Edit:*
Changing CommonControls to Dui-controls would be a huge benefit, and maybe Krool should take a look at this link: 
Duilib: https://github.com/duilib/duilib
(use Google translator to translate Chinese into English)

The Windows APIs and Windows messages used in the DUI controls are identical to Krool's CommonControls, which means that a lot of code in Krool's CommonControls can still be reused in the DUI controls.

----------


## ScriptBASIC

> Since there are fewer and fewer people using win desktop-apps, I gave up on this idea.


*VB6* is a great way for me to create intelligent form OCX controls that the events call back to Script BASIC for processing.  If I need cross platform then I use *IUP* for my GUI environment.

----------


## Krool

> Highlighting bug in monthview control 'Today' section?
> 
> - when mouse is over 'Today' last character is not highlighted 20.2.2019 -> 9
> - when clicked today and mouse is out of 'Today' area last character 'stays' highlighted.
> 
> Tested in Windows 7x64, 10x64 finnish localized (fi locale = 1035) system, both has latest updates.


That's an issue from comctl32.dll. Nothing I can do about.

----------


## Krool

> Krool's CommonControls is a great product set, and if it was released 10 years earlier, its value would be 10 times greater than it is now.


It's never too late. If they decide to kill VB6 it will make at the end anyway no difference. And the idea is to just replace the stuff developed 10 or more years ago. (For example make an old app unicode aware)
But that concern about desktop app would slide to much into off-topic.




> Changing CommonControls to Dui-controls would be a huge benefit, and maybe Krool should take a look at this link: 
> Duilib: https://github.com/duilib/duilib
> (use Google translator to translate Chinese into English)
> 
> The Windows APIs and Windows messages used in the DUI controls are identical to Krool's CommonControls, which means that a lot of code in Krool's CommonControls can still be reused in the DUI controls.


No, thanks

----------


## Krool

Bugfix in the StatusBar control concerning PanelClick.

Prior to bugfix the order in a double click sequence was:


```
panel click
mouse up
click
panel dbl click
dbl click
panel click
mouse up
```

The red marked part is not needed and also not happening in the original MS control.

The notification NM_CLICK is used for the PanelClick event. NM_DBLCLK for the PanelDblClick event.
However, NM_CLICK is also fired when NM_DBLCLK is generated.
To solve this issue it is necessary to detect a double click on NM_CLICK.
This is now done with help of GetDoubleClickTime(), GetSystemMetrics(SM_CXDOUBLECLK) and GetSystemMetrics(SM_CYDOUBLECLK) API.

EDIT: easier solution found. No need of GetDoubleClickTime(), GetSystemMetrics(SM_CXDOUBLECLK) and GetSystemMetrics(SM_CYDOUBLECLK) APIs anymore in StatusBar.

----------


## Hosam AL Dein

I am facing total instability in VBCCR16 through the last 7 months . I tried to post the problems here and could not go with any solution unfortunately . The fact that the problems I am facing can not be isolated in one single project and also can not be reproduced by a scenario . They simply happen occasionally with the same circumstances and sometimes they don`t . 

This made me in some projects give up using VBCCR or using it in a small scale . I decided to check what could be wrong with my usage style for VBCCR , So , I have downloaded and read @MountainMan documentation for VBCCR . I followed all the instructions and started a new clean project and started to code again . Everything was ok and suddenly with no changes made to the last working copy of the project , the problems started to rise again and I changed nothing since it was last working . 

The problem is vb6 crashes when I touch some VBCCR controls . I am using VBCCR in user controls mainly and not in forms directly .
I think this point needs investigation because not the majority here are using it in UserControls and this may explain why it is me the only one (or one of the minority) who is facing such problems .

Being not able to determine the problem because vb6 just crashes and shows me no clue why this happened , I was thinking it would be too easy for people to report problems and bugs if there was error handlers and reports within VBCCR . The only method I could preview my problems with VBCCR was by capturing my screen in a video and post it to youtube and pass the link here .

I need someone to chat with me instantly at any time he decides and discuss about these problems and post them here in a clear way .

problems :
1 - In the STDExe version . when I open it and run the project , VB6 crashes .
2 - I used the OCX version and : In usercontrols , VB6 crashes when I touch a user control that has a VBCCR text or listview within it .
3- Once I put a usercontrol on a form and this usercontrol has a listview in it , I can`t move the usercontrol by holding the listview in design time while I can do so by holding any other controls in the user control .

With these problems , I can get to that there is a problem with my usage for VBCCR in user controls . I have read that I should call SetupVisualStyles sub in the form_load event to make sure that all controls in a form can provide visual styles and this can not be done in user controls . If someone can help me implement the function SetupVisualStyles in a user control , this could be a good start and I will check what happens . I am thinking this may be the problem because these problems don`t happen in an unmanifisted IDE . Also I suspect the HwndUserControl Prpoperty although I am not using Hwnd or HwndUsercontrol in my code wheather in usercontrol or in forms . 

I need help seriously .

----------


## Krool

> 1 - In the STDExe version . when I open it and run the project , VB6 crashes


Do you mean ComCtlsDemo project?

----------


## Hosam AL Dein

> Do you mean ComCtlsDemo project?


yes krool .

Since I posted the above post , I have been trying t find the problem and I think I found something interesting . Give me half an hour and I will post a video .

----------


## Krool

@ Hosam AL Dein,

I might have just detected an instability which _can_ causes crash in case a VBCCR control is hosted in another UserControl, but only in specific certain scenarios. (It's about references not being decremented)
I already have found the solution and await "approval" by the owner of the bug report.
Full story can be read there: https://github.com/Kr00l/VBCCR/issues/4

So I am quite sure this will fix maybe some issues which you struggle to replicate.
(I thought VTableHandle is now quite bullet proof. So I am quite confident that's THE last hole.  :Smilie:  )

But that being said, the ComCtlsDemo is certainly not effected by that bug. So I also suspect some corruption on your PC. Because the ComCtlsDemo ran on many other computers without a problem that I have tested.

----------


## Hosam AL Dein

https://www.youtube.com/watch?v=9ft8C7utHsk

sorry for lateness , I was facing some difficulties in video capturing and uploading .
the quality is a bit low . I will post it again in a higher quality and another video for comctlsdemo project

----------


## Hosam AL Dein

> @ Hosam AL Dein,
> 
> I might have just detected an instability which _can_ causes crash in case a VBCCR control is hosted in another UserControl, but only in specific certain scenarios. (It's about references not being decremented)
> I already have found the solution and await "approval" by the owner of the bug report.
> Full story can be read there: https://github.com/Kr00l/VBCCR/issues/4
> 
> So I am quite sure this will fix maybe some issues which you struggle to replicate.
> (I thought VTableHandle is now quite bullet proof. So I am quite confident that's THE last hole.  )
> 
> But that being said, the ComCtlsDemo is certainly not effected by that bug. So I also suspect some corruption on your PC. Because the ComCtlsDemo ran on many other computers without a problem that I have tested.


I have read a little in this article , but I think it is a a part of the problem . This problem is referenced in my video in the first 6 minutes .

but from here https://www.youtube.com/watch?v=9ft8...youtu.be&t=378 , this is (as I think after the quick reading) another problem .

----------


## Hosam AL Dein

Deleted.

----------


## Hosam AL Dein

This is another video and shows ComCtlsDemo project crash behavior which is the same with my project . It also has the remaining explanation of the problem .

https://www.youtube.com/watch?v=z7G4...ature=youtu.be

----------


## Hosam AL Dein

Have a look here krool , please . 

I was trying to check if the previous issue only happens with usercontrols . So , I opened ComCtlsDemo after I removed most of the controls in MainForm with notepad . And the previous problem still exist even with the VBCCR controls placed directly on the form no only if they were hosted in a usercontrol .

I switched to my project to perform the same test but not with a usercontrol , but with VBCCR components placed directly on the form .But , another strange problem occured , VBCCR is not registered . I tried to re-register it and since then , the controls seemed strange . they were only gray and are not accessible as normal VBCCR components . 

https://www.youtube.com/watch?v=uAl4...ature=youtu.be
https://www.youtube.com/watch?v=2QRL...ature=youtu.be

----------


## Krool

Hosam AL Dein, seens your system is screwed up. Did you try on another machine?

----------


## Hosam AL Dein

No krool , not yet . But regardless of the registration issue which appeared last , what about the issue related to the number of controls on a form ? Is it the same behavior on someone`s machine ? and if not , what could be the reason for it , especially that this crash occurred with me over the last 7 months with different new win10 setups . All were 64 bits by the way .

What could be wrong with my machine but only affects projects including VBCCR ? 
should I post my event log of the error ? may it be helpful ?
could it be the copy of VB6 setup package I use ? because in the VB98 path I find ocx`s and dll`s which were not registered by me since the last VB6 setup I have made , like VBCCR14 and 15 and I did not open any projects containing these versions of VBCCR ocx .

Can you pass me a link of clean VB6 setup package ?

What makes me too worried about these problems is that I am committed to deliver a working copy of a large POS within the end of march and I was developing these user controls to save coding time for me and this can not go any good for now . So , excuse me if I am annoying you with these questions . Thanks for your help and appreciate your patience and time .

----------


## Krool

Update released related to VTableHandle.bas.

It must be the last fix for this now..

----------


## Hosam AL Dein

I solved the problem related to the number of controls on a form . 

1 - I installed Win7 64bit and the problem remained as it was .
2 - VB6 IDE crashed and debugged it and found some message talking about " Access Violation "
3 - I suspected the VB6 exe . It was manifested internally and I was used to replace the default VB6.exe with a pre-manifested one that I have made .
4 - I cleared all manifest resources from VB6.exe and replaced them with manifest only that handles visual styles .
5 - It worked and the problem was solved in both ComCtlsDemo project and also in my project where I use the ocx version and I re-switched to win10 64 bit and it also worked on win 10

But , About the issue related to VBCCR CommandButtons and TextBoxes hosted in a user control and being able to click the separately in design mode in IDE , it is the same and still exists although I replaced the OCX with the latest version in the same path and unregistered the old one and re-registered the newer one too .

What could be wrong here ? 

https://www.youtube.com/watch?v=UF0E...ature=youtu.be

----------


## Hosam AL Dein

The previous problem does not happen in a new user control .
https://www.youtube.com/watch?v=QxFy...ature=youtu.be

----------


## Karl77

> But , About the issue related to VBCCR CommandButtons and TextBoxes hosted in a user control and being able to click the separately in design mode in IDE , it is the same


I had the same problem a while ago, but it was solved some weeks ago for me.

Could you post your project that shows the error?
I would like to see if it happens here as well.

----------


## DaveDavis

> I had the same problem a while ago, but it was solved some weeks ago for me.
> 
> Could you post your project that shows the error?
> I would like to see if it happens here as well.


a while ago is older or earlier than some weeks ago?

----------


## Karl77

> a while ago is older or earlier than some weeks ago?


See post #2117.
http://www.vbforums.com/showthread.p...=1#post5332087

----------


## Hosam AL Dein

> I had the same problem a while ago, but it was solved some weeks ago for me.
> 
> Could you post your project that shows the error?
> I would like to see if it happens here as well.



Thanks for your reply karl ,
I will be wrapping a demo today attached with video as I am testing some scenarios now .

----------


## Hosam AL Dein

I could reproduce the scenario which causes this *problem* and it is such a strange and tricky .

https://www.youtube.com/watch?v=IaxZ...ature=youtu.be

I was limited to 15 minutes of recording so , there is an uncompleted test result at the end of the video but it should be enough to make the point clear for now .

*Summary for video :*

The scenario :

1- Add a new user control
2- Place normal textbox or any VB6 intrinsic controls in the user control .
3- Place any VBCCR control in the user control 
4- In the _UserControl_Initialize_  event , add these lines of code . 

Lets say you used a VB intrinsic Textbox and a VBCCR CommandButtonW . Add these lines 



```
text1.text="Hello"
commandbuttonw1.caption ="Hello"
```

5- The problem happens 
6 - Uncomment the code , The problem now disappears .
7 - Put the following code in the same event 


```
Dim s as string
s= "Hello , I prove that not all code causes the problem , It is only for the code that draws an item in the user control"
```

8 - With this previous case , the problem does not happen .

More details and tests are found in the video for tests on the _ComCtlsDemo_ project

Thanks everybody for your help and sorry for bad English .

----------


## Karl77

> I could reproduce the scenario which causes this


Easy to reproduce, and happens in here the same way.

While the effect is bothering, it is more a cosmetic issue.
I lived with it for a long time, and it didn't stopped me to get things done.

But good to point out the issue!
And I would appreciate a solution as well.

----------


## Krool

> I could reproduce the scenario which causes this *problem* and it is such a strange and tricky .
> 
> https://www.youtube.com/watch?v=IaxZ...ature=youtu.be
> 
> I was limited to 15 minutes of recording so , there is an uncompleted test result at the end of the video but it should be enough to make the point clear for now .
> 
> *Summary for video :*
> 
> The scenario :
> ...


It's a very bad idea to make some code involving the child usercontrol in the host usercontrol inside the UserControl_Initialize() event. The UC Ambient.UserMode property is not meaningful at that place. Please set your code that involves the child usercontrols in the UserControl_ReadProperties()/UserControl_InitProperties().

----------


## Karl77

> It's a very bad idea to make some code involving the child usercontrol in the host usercontrol inside the UserControl_Initialize() event. The UC Ambient.UserMode property is not meaningful at that place. Please set your code that involves the child usercontrols in the UserControl_ReadProperties()/UserControl_InitProperties().


Aha.
Now I know why did it right in my apps.
Not because of knowledge, I just don't use UserControl_Initialize anywhere in my UCs.
Except in one of them, and I will correct that immediately.

----------


## Tech99

Krool, thank you for these superb usercontrols. In terms of DTPicker there is AllowUserInput, but this property does not 'lock' control fex. like in vb intrinsic combobox locked property does - maintaining control look like 'enabled'. Hence asking is your DTPicker control possible to set 'locked' state, without disabling it? If not, then could you consider adding locked property?

----------


## AAraya

I need to change the BackColor of a tab control but it has no BackColor property.  Is this an accidental omission or is there a technical reason for this?

----------


## Hosam AL Dein

> It's a very bad idea to make some code involving the child usercontrol in the host usercontrol inside the UserControl_Initialize() event. The UC Ambient.UserMode property is not meaningful at that place. Please set your code that involves the child usercontrols in the UserControl_ReadProperties()/UserControl_InitProperties().


Thanks for your reply krool ,
This is the first time to know that . I will go on your advice to avoid this issue .

----------


## Krool

Update released.

Minor bugfix in each WM_MOUSEACTIVATE handler.

This is a very tiny behavior "bug" which I didn't notice and obviously nobody else.  :Smilie: 
The standard handler of WM_MOUSEACTIVATE looked like below (taken from TextBoxW)
and used MA_NOACTIVATEANDEAT when hittest the border or the Validate event doesn't allow to.
However, it is more correct to use MA_ACTIVATEANDEAT.


```
Case WM_MOUSEACTIVATE
    Static InProc As Boolean
    If TextBoxTopDesignMode = False And GetFocus() <> TextBoxHandle Then
        If InProc = True Or LoWord(lParam) = HTBORDER Then WindowProcControl = MA_NOACTIVATEANDEAT: Exit Function
        Select Case HiWord(lParam)
            Case WM_LBUTTONDOWN
                On Error Resume Next
                With UserControl
                If .Extender.CausesValidation = True Then
                    InProc = True
                    Call ComCtlsTopParentValidateControls(Me)
                    InProc = False
                    If Err.Number = 380 Then
                        WindowProcControl = MA_NOACTIVATEANDEAT
                    Else
                        SetFocusAPI .hWnd
                        WindowProcControl = MA_NOACTIVATE
                    End If
                Else
                    SetFocusAPI .hWnd
                    WindowProcControl = MA_NOACTIVATE
                End If
                End With
                On Error GoTo 0
                Exit Function
        End Select
    End If
```

Because let's assume you have a TextBoxW which can't get focus because the currently focused control doesn't allow. (Validate Cancel = True)
Then assume the form get's inactive (for instance when clicking on desktop) then now when you click on the TextBoxW which is not allowed to get focus you will see that the Form will not get active. But in VB.TextBox the form will get active where the focus is still on the upper TextBox which have Validate Cancel = True.


So this update brings the behavior to same. I know it's a very tiny detail.

_as Info: the MA_NOACTIVATE in above WM_MOUSEACTIVATE handler is still correct as SetFocusAPI implies activation of the top-level form. (SetFocusAPI internally also activates the form)_

----------


## pepegriyo2016

Hello Krool,
I found a bug.
I have a form with 200 texbox from vb6.
When i convert my project from VBCCR6 to Source code CommonControls, in the moment when I compiling the project I obtein a error , runtime '0' , the haven't a licence from your control.

----------


## pepegriyo2016

Hello Krool,
I use MzTools 3.0 ( https://programacion.net/noticia/mzt...ual_basic_1751 ) and the properties "Fontname" in TextboxW is missing.
The TexBox default have a properties "FontName".

Could you fix this?

----------


## Krool

> Hello Krool,
> I found a bug.
> I have a form with 200 texbox from vb6.
> When i convert my project from VBCCR6 to Source code CommonControls, in the moment when I compiling the project I obtein a error , runtime '0' , the haven't a licence from your control.


You need to convert from VBCCR16.TextBoxW to [your project name].TextBoxW

----------


## Krool

Update released.

Bugfix in the internal ComCtlsTopParentValidateControls function.
If a control validation takes place in an MDIForm it was functional working, but it had a strange "re-position" effect on mdi-child forms.
Below illustration says more than words..

Before



*After fix*



It could be fixed by just adding red marked code block:


```
Public Sub ComCtlsTopParentValidateControls(ByVal UserControl As Object)
With GetTopUserControl(UserControl)
If TypeOf .Parent Is VB.MDIForm Then
    Dim MDIForm As VB.MDIForm
    Set MDIForm = .Parent
    MDIForm.ValidateControls
ElseIf TypeOf .Parent Is VB.Form Then
    Dim Form As VB.Form
    Set Form = .Parent
    Form.ValidateControls
Else
    Const IID_IPropertyPage As String = "{B196B28D-BAB4-101A-B69C-00AA00341D07}"
    If VTableInterfaceSupported(.Parent, IID_IPropertyPage) = True Then
        Dim PropertyPage As VB.PropertyPage, TempPropertyPage As VB.PropertyPage
        CopyMemory TempPropertyPage, ObjPtr(.Parent), 4
        Set PropertyPage = TempPropertyPage
        CopyMemory TempPropertyPage, 0&, 4
        PropertyPage.ValidateControls
    End If
End If
End With
End Sub
```

VB.Form is inherited in each VB.MDIForm. However, it seems to work "better" if .ValidateControls is called on the VB.MDIForm directly.
So it's not a real functional bugfix but rather a cosmetic fix.

VBFlexGrid is likewise updated.

----------


## pepegriyo2016

Hello Krool,
I have an error in TextBoxW


In line Of TextBoxW:


```
Public Property Set Container(ByVal Value As Object)
Set Extender.Container = Value
End Property
```


My code is:



```
Private Sub ZoomControls(miTxt As TextBoxW, miLb As LabelW, miFrame_1 As FrameW)

Set miTxt.Container = miFrame_1

End Sub
```


With the OCX Controls, i haven't the error.

----------


## pepegriyo2016

Krool,
This is the example the error.

Add This form to ComCtlsDemo Project

ComCtlsDemo.zip

----------


## Krool

> Hello Krool,
> I have an error in TextBoxW
> 
> 
> In line Of TextBoxW:
> 
> 
> ```
> Public Property Set Container(ByVal Value As Object)
> ...


In the OCX the FrameW interface is an amalgamation of VBControlExtender and the real FrameW interface.

Whereas in the Std-EXE version the FrameW interface is encapsulated. However, when using FrameW1 on the control itself it contains VBControlExtender, but not when passed to a sub with As FrameW.


Solution could be to not pass FrameW into the sub but VBControlExtender.
Changed:


```
Private Sub ZoomControls(miTxt As TextBoxW, _
                         miLb As LabelW, _
                         miFrame_1 As VB.VBControlExtender)
```

Unchanged:


```
Private Sub cmdZoomURL_Click()
Call ZoomControls(txtUrl, lbURL, Frame(1))
End Sub
```

----------


## pepegriyo2016

Thank you very much!!
It's working

----------


## Darkbob

Problem:

1)  Download Demo from first post in this thread
2)  Copy contents of OLEGuids to Windows\System32
3)  Open VB6 
4)  Open ComCtlsDemo.vbp  (loads without issue)
5)  Run

VB6 closes

Same thing happens when I try and open MainForm.frm in the IDE

Any ideas?

----------


## Krool

> Problem:
> 
> 1)  Download Demo from first post in this thread
> 2)  Copy contents of OLEGuids to Windows\System32
> 3)  Open VB6 
> 4)  Open ComCtlsDemo.vbp  (loads without issue)
> 5)  Run
> 
> VB6 closes
> ...


No idea.

----------


## jpbro

> Problem:
> 2)  Copy contents of OLEGuids to Windows\System32


Did you register the TLB?

----------


## Darkbob

> Did you register the TLB?


I had to google registering a TLB... never heard of TLB's and I have no clue on how to register them.  I can't see it mentioned anywhere in the readme.  But I googled, found out how to register a TLB and got it registered.  

Unfortunately now the project won't run.

Really a shame that the demo for this project won't run and there's really no mention of at least two critical steps to get the demo running.  It must turn a lot of people off using it.  But I'm determined to stick with it for a bit longer before I give up.

When I try and run the project I see this:



In Debug I see this line highlighted:



If the demo needs a manifest, shouldn't it be included?  Where can I get one and/or make one for this project?

----------


## jpbro

> I can't see it mentioned anywhere in the readme.  But I googled, found out how to register a TLB and got it registered.


It is mentioned in the GitHUb readme: "In order to use that type library, it is necessary to load the OLEGuids.tlb in the IDE. (Project -> References... -> Browse -> select file OLEGuids.tlb -> check item "OLE Guid and interface definitions")", but Googling works too so glad you got that part figured out and working.




> If the demo needs a manifest, shouldn't it be included?  Where can I get one and/or make one for this project?


I suspect it doesn't include the manifest because it is actually outside the scope of the project, and is something most devs have done as a matter of course years ago. The VB6 IDE needs to be manifested to use the newer V6 common controls. Search for "manifest vb6 ide" for a bunch of results on how to do this. Here are a few articles I found with those search terms that might be helpful:

http://vbnet.mvps.org/code/forms/vbidevista.htm
http://www.vbaccelerator.com/home/VB...VB/article.asp

----------


## Darkbob

Well if the purpose of a demo is to show you how easy it will be to use... mission accomplished.  The instructions are hidden on GitHub?  You have to Google menifest creation in order to try out the demo?

Somebody put a ton of work into this.  Much better than many commercial products and very necessary with Microsoft constantly playing games. Really a shame the demo is so poor that it won't run out of the box.  Especially since all you would need to do is edit the readme and give people a hint on how to run it.

----------


## jpbro

> Well if the purpose of a demo is to show you how easy it will be to use...


I didn't see that purpose stated the documentation  :Wink:  

I think the purpose of the demo was to showcase the available controls, and the purpose of the project in general is to provide Unicode replacements for the ANSI common controls used by default by VB6. Nobody said that would be easy! You need to weigh your need for Unicode controls vs. the work required to get them up and running in your environment. I assure you that Krool has done the vast majority of the _really_ hard work compared to writing your own Unicode control replacement library. Registering a TLB and adding a manifest to your VB6 IDE is a small step above the absolute minimum that can be expected from a developer to get an OCX working from source.

----------


## MountainMan

darkbob,

You do not need a manifest in order to run the demo. The only thing you need is to reference the OLEGuids.tlb file in your project. BTW, the .tlb means it is a type library. It enables VB6 to be able to specify data types, call stack order etc. differently than what is built-in to VB6. It is a powerful feature that is used all the time in VB6; normally it is behind the scenes.

Krool included the latest OLDGuids.tlb in the OLEGuids folder of the package yo downloaded. You can reference it there. Alternatively, I keep the ltest version in C:\Windows\SysWow64 (C:\Windows\System32if you are running 32-bit Windows). It hasn't changed in 2 years so it isn't much of a hassle to put it in the common folder.

You don't need to register it. Let's say you copied it to C:\Windows\SysWow64. In a blank VB6 project go to Project | References then click on Browse. Go find it and include it in your project. Now it will be available for all future projects you do. Just do Project | References and look for "OLE Guid and interface definitions" and check the choice.

Know also that the type library is only used when you are in the IDE &/or compiling. It is not required to be included with the final distribution program. So it is just a file you will want to keep n your development machine. It allows you to do a lot of interesting things as Krool's demo will show you.

That's all you need to run his demo or to use his controls.

You will probably notice that all of his controls are included in the demo are source files. Typically controls are distributed pre-compiled in a .OCX file and you never see the source files. The advantages of what Krool has done here is that once you get it compiled you no longer need the control files; they're compiled into your code.

There is another version of his controls where he has pre-compiled everything into one large .OCX file (read the first post of his to find the link to the thread containing that OCX file). If you go this route your compiles are faster because you dn't have to compile the source code for the controls each time but when you have your final EXE file you have to distribute that OCX with it. [That's where the side-by-side stuff can start coming into play but that's a topic for another day.]

Let us know how all of this works for you. Krool has put in some incredible work here and I hope you can benefit from it as we have.

----------


## Krool

> I had to google registering a TLB... never heard of TLB's and I have no clue on how to register them.  I can't see it mentioned anywhere in the readme.  But I googled, found out how to register a TLB and got it registered.  
> 
> Unfortunately now the project won't run.
> 
> Really a shame that the demo for this project won't run and there's really no mention of at least two critical steps to get the demo running.  It must turn a lot of people off using it.  But I'm determined to stick with it for a bit longer before I give up.
> 
> When I try and run the project I see this:
> 
> 
> ...


Please make the following setting in your VB6 IDE to not crash the IDE when it is *not* manifested.

*In order to trap error raises via "On Error Goto ..." or "On Error Resume Next" it is necessary to have "Break on Unhandled Errors" selected instead of "Break in Class Module" on Tools -> Options... -> General -> Error Trapping.*

----------


## Pablo72

Hello Krool,
great job. I have a question. Can these controls work in 64bit VBA?
Thanks a lot for reply.
Pablo72

----------


## Krool

> Hello Krool,
> great job. I have a question. Can these controls work in 64bit VBA?
> Thanks a lot for reply.
> Pablo72


No. You can't even use MS comctl on 64bit VBA. That's why even MS advises that for companies it may be better to use 32bit office.

----------


## Pablo72

> No. You can't even use MS comctl on 64bit VBA. That's why even MS advises that for companies it may be better to use 32bit office.


Yes, I know... but I was hoping that comctl32.dll (as the basis of these controls) can be used on 64bit application..maybe   :Smilie:  
The problem is that next release of sotware (with integrated VBA) we administrate will be  64-bit only  :Frown:  .. So I'm looking for some solution.. 
Anyway, thanks for quick reply.

----------


## Hosam AL Dein

Hi krool ,

In commandbuttonW , the _dropdown_ event is not fired with the property _SplitButton_ set to *true* and property _SplitButtonNoSplit_  set to *true* .

Is this an intrinsic MS behavior ,intended or a bug ?

----------


## Krool

> Hi krool ,
> 
> In commandbuttonW , the _dropdown_ event is not fired with the property _SplitButton_ set to *true* and property _SplitButtonNoSplit_  set to *true* .
> 
> Is this an intrinsic MS behavior ,intended or a bug ?


Seems MS intended. In this case the button is treated like 'WholeDropDown'.

----------


## ChenLin

Hello Krool, it is suggest  that ImageList can save the image list and open the image list, and it is perfect if PNG is supported when adding images.

----------


## Pablo72

> No. You can't even use MS comctl on 64bit VBA. That's why even MS advises that for companies it may be better to use 32bit office.


I know it!  :Smilie:  See post bellow. And we can't use 32bit VBA cause our app with VBA integration is 64bit.

----------


## Pablo72

How delete own post...

----------


## Krool

> Hello Krool, it is suggest  that ImageList can save the image list and open the image list, and it is perfect if PNG is supported when adding images.


You mean a save and load method for the designer only?
What's the reason? For backup?
For inter-project transfer you could copy&paste?

----------


## ChenLin

Yes, Krool, so if you don't need to re-add it when other projects are used, just open the saved image list file.

----------


## Karl77

> you don't need to re-add it when other projects are used


Can't we just copy/paste the whole control that holds the images?

EDIT:
I load the images from a res file at runtime anyway.
It is more convenient than to handle the images in the imagelist directly.
Also for what DaveInCaz says.

----------


## DaveInCaz

One reason I can think of is for long-term archival in source control. I've been in the situation where you no longer know what source images were used, and no one wrote that down either. But you could export & checkin the text file listing.

(Not saying it is worth the effort just for this... )

----------


## ChenLin

> Can't we just copy/paste the whole control that holds the images?
> 
> EDIT:
> I load the images from a res file at runtime anyway.
> It is more convenient than to handle the images in the imagelist directly.
> Also for what DaveInCaz says.


This is a good idea, and I will consider reading from the RES later so that I can leave the toolbar.

----------


## Semke

> Can't we just copy/paste the whole control that holds the images?
> 
> EDIT:
> I load the images from a res file at runtime anyway.
> It is more convenient than to handle the images in the imagelist directly.
> Also for what DaveInCaz says.


do you use the res file to load the image list, could you please show the code how you do it

----------


## Karl77

Semke:



> do you use the res file to load the image list


Oh well, now I must show my ugly code...
It is far easier to load the images from internal resources.

I think it is better to search here in the forum for an explainable solution.
My approach is not good as a retraceable example.




```
Dim i As VBCCR.ImageList
Dim s As String
Dim R As New c_ResFromDLL

s = "_24"

R.LibraryFilePath = App.Path & "\RES20.dll"

StartGDIPlus

Set i = MF.imgl_Menu

i.ListImages.Clear
i.ColorDepth = ImlColorDepth32Bit
i.ImageWidth = 0
i.ImageHeight = 0

ResDLLToImgl i, R, "tips" & s 'and this a few 100 times with the single images

Set i = Nothing

StopGDIPlus

R.CloseLibrary
Set R = Nothing




Public Sub ResDLLToImgl(ByRef imgl As VBCCR.ImageList, _
                        ByRef TheClass As c_ResFromDLL, _
                        ByVal key As String)
imgl.ListImages.Add , key, TheClass.DLL_LoadPNG(key)
End Sub
```

----------


## Semke

is there a way to increase checkbox size of a listbox and checkbox.
also is it possible to have a carriage return in a list, so each selected item is two lines.

it looks like the only way to do it is by using owner draw, which is implemented in these controls (_thank you krool_), however I do need some directing, of how to do it.

I guess that the ItemDraw event comes into play, but that's all I have figured out for now

having a font size of 18 and a tiny checkbox is really unattractive.

----------


## ahenry

Selecting the Toolbar DisabledImageList and HotImageList property page entries cause an immediate crash to desktop.  Regular ImageList and PressedImageList work fine.  I checked an older CCR version from January and that was OK.  Active-X and STD on Windows 10.

I was running in the IDE without manifesting for VB6.exe.

Also, it only happens when clicking in the VB MDI property page properties.  I can set the same properties using the pop-up property window without killing VB.

----------


## Krool

> Selecting the Toolbar DisabledImageList and HotImageList property page entries cause an immediate crash to desktop.  Regular ImageList and PressedImageList work fine.  I checked an older CCR version from January and that was OK.  Active-X and STD on Windows 10.
> 
> I was running in the IDE without manifesting for VB6.exe.
> 
> Also, it only happens when clicking in the VB MDI property page properties.  I can set the same properties using the pop-up property window without killing VB.


Sorry. I can't replicate the problem. Can you provide a demo with the steps to encounter the crash? Thanks

----------


## ahenry

I've had trouble replicating it myself.  I can get it to consistently fail, and then I'll open another project and it starts working again.  Maybe I'm mixing incompatible versions somehow, but when things are breaking, it's easy to reproduce:
Open VB - Create a new Project - Add VBCCR16 as a component - Add Toolbar on the main form
Then when I click on the HotImageList property, VB will exit after about a half-second.

The Application logs shows:
Faulting application name: VB6.EXE, version: 6.0.97.82, time stamp: 0x403acf6c
Faulting module name: ntdll.dll, version: 10.0.17134.799, time stamp: 0x636bcb43
Exception code: 0xc0000374
Fault offset: 0x000d8519
Faulting process id: 0x148c
Faulting application start time: 0x01d53597850cbd50
Faulting application path: C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.EXE
Faulting module path: C:\WINDOWS\SYSTEM32\ntdll.dll
Report Id: ffce8926-a4e0-4cbc-a64c-c55bd9fed625

But if I remember to stay away from those properties in the generic VB properties window, everything is OK, so it's no big deal.

Now the whole reason I was trying out the Toolbar replacement was to use 32-bit alpha-channel images, which don't really work anyhow.  But being able to use ImageList controls with 32-bit images stored makes things easier regardless.

----------


## Krool

Critical update released for ListView control.
The application could crash. Mostly relevant when using the 'UseColumnFilterBar' feature.

The root problem was that the internal SysHeader32 control missed the activation/deactivation of the VBCCR's IOleInPlaceActiveObject object.
This got now fixed.

The reason why it certainly only applies for the 'UseColumnFilterBar' feature is really sneaky. Details below:

The ListView was only *unstable* when the internal SysHeader32 control received focus and the previous window didn't receive WM_KILLFOCUS.
A normal SetFocus API should be safe as it ensures WM_KILLFOCUS...
So where's the problem? -> comctl32 is the problem. (partially)

Because the comctl32 SysListView32 control for the internal filter edit window (in the filter bar) only sends WM_KILLFOCUS to the edit window when the user clicks something else or by a focus change by code.
However, when the user types ESC or RETURN in the filter edit window comctl32 will only send EN_KILLFOCUS. No WM_KILLFOCUS whatsoever.
And after EN_KILLFOCUS the SysHeader32 control will receive focus.. that's the starting point of the upcoming potential crash.

So now the VBCCR's IOleInPlaceActiveObject object still is activated. And as the SysHeader32 window does not care about VBCCR's IOleInPlaceActiveObject, it is still activated. (but after this fix it will take care)

Now depending on the next action the application will crash or not:
- Clicking another VBCCR control. Safe again, no crash.
- Something else like clicking a VB control... maybe or maybe not, let's see:
Still no crash so far. But now any action that will modify the original VB's IOleInPlaceActiveObject can cause a crash. And what can do this?
Well for example, let's assume the user then clicked a VB.CommandButton to open a Modal VB.Form. Still no crash.
In that modal VB.Form the user then clicks another VB.CommandButton that will make a Unload on the modal form. Here the crash happens.
Because the VBCCR's IOleInPlaceActiveObject reference to the original VB object is outdated. By outdated I mean VB can refresh it's own IOleInPlaceActiveObject reference, e.g. when a modal form opens.

Then the user Unloads the form which will then raise a IOleInPlaceActiveObject::EnableModeless call and as the reference to the original VB object is outdated the crash is executing...  :Smilie: 

I know it's very specific issue but I just want to point out which strange circumstances can cause a crash.

----------


## Tech99

Feature request.

ComboBoxW and ListBoxW item background or foreground color settable (ownerdrawn items)?
Before used emorcillo's ODComboBox and ODListBox for this purpose, but like to switch Krool's controls.

----------


## Krool

> Feature request.
> 
> ComboBoxW and ListBoxW item background or foreground color settable (ownerdrawn items)?
> Before used emorcillo's ODComboBox and ODListBox for this purpose, but like to switch Krool's controls.


Both, ComboBoxW and ListBoxW, have a DrawMode property which you can set to OwnerDraw.
A little bit of browsing thru the props would help..

----------


## Tech99

> Both, ComboBoxW and ListBoxW, have a DrawMode property which you can set to OwnerDraw.
> A little bit of browsing thru the props would help..


Sure, i looked properties and made test app



```
Private Sub Form_Load()
Dim i As Long
SetupVisualStyles Me
MainForm.Show vbModeless

For i = 1 To 10
If i = 3 Then ComboBoxW1.ListBackColor = vbRed Else ComboBoxW1.ListBackColor = vbWhite
ComboBoxW1.AddItem "1." & Format(i, "00000")
Next i

ComboBoxW1.ListIndex = 0
End Sub
```

Tried to set DrawMode to cboOwnerDrawFixed and then cboOwnerDrawVariable, also tried to set ExtendedUI = True. 
Dropdown part does not list any items ie. draws only dropdown border, item list is does not show.

----------


## Krool

> Sure, i looked properties and made test app
> 
> 
> 
> ```
> Private Sub Form_Load()
> Dim i As Long
> SetupVisualStyles Me
> MainForm.Show vbModeless
> ...


You need to draw your stuff of course.
Look ItemMeasure and ItemDraw events.
ItemMeasure is only needed when OwnerDraw is Variable.

----------


## AAraya

Is there a way to disable an item in a ComboBoxW dropdown list?

----------


## AAraya

Has anyone used the OwnerDraw abilities of these controls?  I see that the ability exists but have no idea how to get started.  Is there a basic tutorial or sample project on how to use these properties of the controls?

----------


## Krool

> Is there a way to disable an item in a ComboBoxW dropdown list?


There is a .Locked property. But it will disable all items. There is no easy way to disable particular items.
If really needed. You would need to go the hard way and subclass the ComboLBox window and suppress certain input message manually at certain mouse locations.




> Has anyone used the OwnerDraw abilities of these controls?  I see that the ability exists but have no idea how to get started.  Is there a basic tutorial or sample project on how to use these properties of the controls?


If you use the easier Fixed OwnerDraw then you only need to handle the ItemDraw event. That event is a direct forward call of an WM_DRAWITEM message.
So if you google for other OwnerDraw example handling WM_DRAWITEM then you might have your starting point already. You certainly only need to adapt some few things to consider the event parameter namings etc.

----------


## Mith

VBCCR16 v.1.6.38 09-Jul-2019
VB6 Sp6

There is a problem with the calculation of the column width at the ListBoxW control using MultiColumn=True.

ListBoxW vs. MS ListBox:



The text of some items is larger than the column width.

See demo project: test - ListBoxW MultiColumn ItemWidth.zip

----------


## Krool

> VBCCR16 v.1.6.38 09-Jul-2019
> VB6 Sp6
> 
> There is a problem with the calculation of the column width at the ListBoxW control using MultiColumn=True.
> 
> The text of some items is larger than the column width.


_It's not a bug, it's a feature_. The MS ListBox column width is fixed.
However, the ListBoxW column width is flexible.
Solution to your problem is to measure the longest string and call the .SetColumnWidth method. (or manually LB_SETCOLUMNWIDTH with SendMessage API)



```
lbDays.SetColumnWidth Me.TextWidth("letzten Donnerstag") + 375 ' check state image and extra buffer
```

If your content would be even larger than you would struggle with the MS ListBox. Because as the column width is fixed you can't even change with LB_SETCOLUMNWIDTH.

So I found it for the ListBoxW the best solution to depend on LB_SETCOLUMNWIDTH and not fixing something in the drawing.

----------


## AAraya

> If you use the easier Fixed OwnerDraw then you only need to handle the ItemDraw event. That event is a direct forward call of an WM_DRAWITEM message.
> So if you google for other OwnerDraw example handling WM_DRAWITEM then you might have your starting point already. You certainly only need to adapt some few things to consider the event parameter namings etc.


Thanks, this was helpful.  I was able to use this information and some code from Elroy to change the forecolor of an item in the list. Cool!

----------


## Mith

> [I]Solution to your problem is to measure the longest string and call the .SetColumnWidth method. (or manually LB_SETCOLUMNWIDTH with SendMessage API)


Thanks for the information and the quick solution!
Now i use the API GetTextExtentPoint32W to determine the text width and everything looks fine.




> ```
> lbDays.SetColumnWidth Me.TextWidth("letzten Donnerstag") + 375 ' check state image and extra buffer
> ```


I only struggle a little bit with the fixed value 375 because many ppl using DPI scaling higher than 100% and i guess this value have to increase too, or?

----------


## Krool

> I only struggle a little bit with the fixed value 375 because many ppl using DPI scaling higher than 100% and i guess this value have to increase too, or?


A fixed twips value is better than a fixed pixel value.
A fixed twips value will be converted into more pixel in case of higher DPI.
I use in VBCCR a lot of fixed pixel values but call them DIP. (Device independent pixels)
That DIP will then be multiplied with PixelsPerDIP_X()
However, storing twips is in this case easier.

----------


## Mith

> A fixed twips value is better than a fixed pixel value.
> A fixed twips value will be converted into more pixel in case of higher DPI.
> I use in VBCCR a lot of fixed pixel values but call them DIP. (Device independent pixels)
> That DIP will then be multiplied with PixelsPerDIP_X()
> However, storing twips is in this case easier.


I've done some test with 100%, 125% & 150% DPI scaling and everything looks fine!

Win7 100%:


Win10 125%


Win10 150%

----------


## Karl77

Mith, I would check 225% too.
I had some issues with that setting.
Just a thought.

----------


## Hosam AL Dein

H krool ,
In listview , while in virtual mode enabled , the forecolor property is neglected and reverts the forecolor to black .

----------


## Krool

> H krool ,
> In listview , while in virtual mode enabled , the forecolor property is neglected and reverts the forecolor to black .


Please provide a Demo. Did you disable the ForeColor with the VirtualDisabledInfos?

----------


## Hosam AL Dein

> Please provide a Demo. Did you disable the ForeColor with the VirtualDisabledInfos?


No , no disabled info at all , I even tested it in comctlsdemo project .

you can reproduce the issue by setting the listview forecolor to any color say "red"  and run the demo form for virtualised controls and the color is black .

----------


## AAraya

> If you use the easier Fixed OwnerDraw then you only need to handle the ItemDraw event. That event is a direct forward call of an WM_DRAWITEM message.
> So if you google for other OwnerDraw example handling WM_DRAWITEM then you might have your starting point already. You certainly only need to adapt some few things to consider the event parameter namings etc.


I was able to use this information to prevent the selection of certain combo items.  Thanks!  Now I'd like to make a small visual tweak.  I'd like the separator bar item to be half the height of a normal combo item.  

I changed from Fixed  to Variable Owner Drawn and am handling the ItemMeasure event.  I leave all of the item's ItemHeight values as default except for the separator bar.  I leave ItemDraw event code exactly as it was when in Fixed mode. This works properly for sizing the individual items but there's a problem - the combo dropdown list is not the correct size - rather than being large enough to show all of the  items in the list it's only as large as one of the items.  Is this a bug or am I supposed to be handling this somewhere?  

The ItemMeasure event seems to be only for the combo items.  Do I need to add some code to ItemDraw in Variable mode which I don't need in Fixed mode?

Appreciate any guidance you can provide.

----------


## wqweto

JFYI, variable sized owner-drawn combo boxes are completely useless as there is this bug since Windows 9x that the drop-down list animates the scrolling in *opposite* direction which is really confusing for end-user and everyone.

Just use fixed height owner-drawn lists and prevent mouse down reaching original wndproc on disabled items. For keyboard selected ones I usually spoof the ListIndex property (or Value) to return -1 (or Empty) or something along these lines.

cheers,
</wqw>

----------


## AAraya

> JFYI, variable sized owner-drawn combo boxes are completely useless as there is this bug since Windows 9x that the drop-down list animates the scrolling in *opposite* direction which is really confusing for end-user and everyone.
> 
> Just use fixed height owner-drawn lists and prevent mouse down reaching original wndproc on disabled items. For keyboard selected ones I usually spoof the ListIndex property (or Value) to return -1 (or Empty) or something along these lines.
> 
> cheers,
> </wqw>


Good to know.  Thank you.

----------


## wqweto

> Good to know.  Thank you.


Btw, just tested it. This bug seems to be fixed in Windows 10 so one can safely use CBS_OWNERDRAWVARIABLE nowadays it appears.

My bad!
</wqw>

----------


## Krool

> No , no disabled info at all , I even tested it in comctlsdemo project .
> 
> you can reproduce the issue by setting the listview forecolor to any color say "red"  and run the demo form for virtualised controls and the color is black .


I can't reproduce your problem. I think you do something wrong.
In the GetVirtualItem event please make following:


```
If VirtualProperty = LvwVirtualPropertyForeColor Then Value = vbRed
```

In my testings this works. Please check again.




> Now I'd like to make a small visual tweak.  I'd like the separator bar item to be half the height of a normal combo item.  
> 
> I changed from Fixed  to Variable Owner Drawn and am handling the ItemMeasure event.  I leave all of the item's ItemHeight values as default except for the separator bar.  I leave ItemDraw event code exactly as it was when in Fixed mode. This works properly for sizing the individual items but there's a problem - the combo dropdown list is not the correct size - rather than being large enough to show all of the  items in the list it's only as large as one of the items.  Is this a bug or am I supposed to be handling this somewhere?  
> 
> The ItemMeasure event seems to be only for the combo items.  Do I need to add some code to ItemDraw in Variable mode which I don't need in Fixed mode?
> 
> Appreciate any guidance you can provide.


It should work. I did a quick test and there was definitely more than 1 item in the list.
What's the setting of the MaxDropDownItems property?
Can you provide a demo project showing your issue? It would be good to know if there is maybe indeed a bug.

----------


## Krool

Update released for the ListView control.

In the MS common controls it is possible to change the .Key of an item in the control's collection. I didn't know it was even possible  :Roll Eyes (Sarcastic): 

I will internally achieve this by adding a new item on the collection with the new key (or blank) and removing the old item. (of course the order is important in case of an error break)
Of course the ObjPtr() of the real item will stay the same..

Each control will need it's own procedure for this. Therefore I started with the ListView control (.ListItems) and others will follow then step by step.

VBCCR16 got also updated and will benefit from this.
In theory this must break compatibility as an property was read-only and now is read/write. However, VB6 treats only interface changes as compatibility break. And in this case it's only an addition.  :Smilie:  (Let Procedure of the Key property)
However, I must admit that it can cause confusion if an old VBCCR16 version has different behavior than the new one.
But I don't want to split now the StdExe version from the OCX version... also it would be too long for the OCX to benefit from this.

----------


## Mith

VBCCR16 v.1.6.38
VB6sp6 Win7

i found a mouse-event bug at the ListView control: 

the MouseUp-event will be triggered 2 times from one mouse click.

How to reproduce:

- ListView with subitems using report view
- FullRowSelect=false
- MultiSelect=false
- first you must do one mouse-click on a item (mouse events are ok)

Now everytime you click on a subitem the following happens:

- the MouseUP-event starts
- the MouseDown-event starts
- the MouseUP-event starts

The issue can be reproduced with the attached vb-project: test - ListView MouseUp event bug.zip

I hope you can fix this nasty event-bug easily...

----------


## Krool

> i found a mouse-event bug at the ListView control: 
> 
> the MouseUp-event will be triggered 2 times from one mouse click.
> 
> How to reproduce:
> 
> - ListView with subitems using report view
> - FullRowSelect=false
> - MultiSelect=false
> ...


Easy fix done. An additional variable reset was necessary..
The TreeView could encounter the same bug (in theory) so I applied the same there.

----------


## Mith

I need to display a ToolTipText when the user moves the MouseCursor over a column header at the ListView (Report mode) but i cant get the column header at the MouseMove event. 

Any ideas how to do that?

BTW: i already display individual ToolTipText's for Items and SubItems using the MouseEvent

----------


## Krool

> I need to display a ToolTipText when the user moves the MouseCursor over a column header at the ListView (Report mode) but i cant get the column header at the MouseMove event. 
> 
> Any ideas how to do that?
> 
> BTW: i already display individual ToolTipText's for Items and SubItems using the MouseEvent


For the Items and SubItems you can use the ToolTipText property? Why the workaround with MouseEvent?
Example:


```
With ListView1.ListItems(1)
.ToolTipText = "item tip"
.ListSubItems(1).ToolTipText = "sub item tip"
End With
```

Concerning the header. Just like the MS ListView the header will not be forwarded to MouseMove event.
I may consider ColumnMouse* events in future or just add an easy to use ToolTipText property for the ColumnHeaders.
However, in the meantime you can only subclass the .hWndHeader and catch WM_MOUSEMOVE yourself.

----------


## Mith

> Mith, I would check 225% too.
> I had some issues with that setting.


i run some tests with win10 using the follwing DPI scaling values and everything looks fine: 125%, 150%, 175%, 200%, 225%, 250% and 300%.

----------


## Mith

> For the Items and SubItems you can use the ToolTipText property? Why the workaround with MouseEvent


The reason is that the old vb tooltip style looks so ugly. 

At my tests (win7) the VisualStyles property doenst change the old tooltip style to the new modern style.

Now i use a tooltip class and replace the tooltiptext property of all controls on the form for a more fresh look.

----------


## Mith

Here is a solution if someone get the error message "missing msstdfmt.dll..." under win10:

open the frm-file and check the code for the following lines:



```
BeginProperty DataFormat 
...
EndProperty
```

Delete the complete DataFormat property and the app runs without error message again.

Reason:

Setting the DataFormat property of a VBCCR16 control at design time will add a dependency for the file "msstdfmt.dll".

----------


## Krool

> The reason is that the old vb tooltip style looks so ugly. 
> 
> At my tests (win7) the VisualStyles property doenst change the old tooltip style to the new modern style.
> 
> Now i use a tooltip class and replace the tooltiptext property of all controls on the form for a more fresh look.


The tooltip class will be considered in the VisualStyles property in VBCCR16..

----------


## Mith

> The tooltip class will be considered in the VisualStyles property in VBCCR16..


That would avoid to loop through all controls on a form everytime you open the form and save a lot of time opening a form with hundreds of controls on it  :Alien Frog:

----------


## samer22

Hi Krool 
I downloaded the MDI_ToolBar Demo but I can't figure outhow to make the ToolBar control accessible per shortcut key on a MDIForm
For example what code I need to show Form2 and where shall I place this code as it is not possible to place it in KeyDown event of the MDIForm

----------


## Krool

> I downloaded the MDI_ToolBar Demo but I can't figure outhow to make the ToolBar control accessible per shortcut key on a MDIForm
> For example what code I need to show Form2 and where shall I place this code as it is not possible to place it in KeyDown event of the MDIForm


If you download the demo then run and test it out.
If it does what you expect then study the demo project how it's done. (E.g. what's for code in the Form, how are the properties set etc.)
It should be all self-explaining. I would just repeat here what's shown in the demo project..




> That would avoid to loop through all controls on a form everytime you open the form and save a lot of time opening a form with hundreds of controls on it


Not "would". It is.

----------


## samer22

> If you download the demo then run and test it out.
> If it does what you expect then study the demo project how it's done. (E.g. what's for code in the Form, how are the properties set etc.)
> It should be all self-explaining. I would just repeat here what's shown in the demo project..


Sorry sir I'm a beginner
I downloaded the demo and tested it 
I was expecting I could do something like that


```
If KeyCode = vbKeyF1 Then FormChild.Show
```

The same thing I do in a form Form_KeyDown event.
But since a MdiForm doesn't have a KeyDown event, I couldn't figure out how to make use of  shortcut keys.

----------


## Krool

> Sorry sir I'm a beginner
> I downloaded the demo and tested it 
> I was expecting I could do something like that
> 
> 
> ```
> If KeyCode = vbKeyF1 Then FormChild.Show
> ```
> 
> ...


Yes, an MDIFrom doesn't have a KeyDown event.
The MDI_ToolBar demo is therefore using a WH_KEYBOARD_LL hook to detect WM_SYSKEYDOWN and with flag LLKHF_ALTDOWN and pass to ToolBar1.ContainerKeyDown. ToolBar1.ContainerKeyDown is a convinient method that will trigger a button click, when there is a button caption with an Ampersand (e.g. "&New Doc", which displays "New Doc") an key code matching it. (of course the button also must be enabled, not disabled)
However, what you want is then independent from ToolBar1.ContainerKeyDown.
To reach your behavior I just changed the hook, see below:


```
Private Type KBDLLHOOKSTRUCT
VKCode As Long
ScanCode As Long
Flags As Long
Time As Long
dwExtraInfo As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Const WM_KEYDOWN As Long = &H100
Implements IHook

Private Sub IHook_Before(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal HookType As HookTypeConstants, ByVal HookCode As HookCodeConstants, ByVal wParam As Long, ByVal lParam As Long)
If HookType = WH_KEYBOARD_LL Then
    If HookCode = HC_ACTION Then
        If wParam = WM_KEYDOWN Then
            If GetActiveWindow() = Me.hWnd Then
                Dim KBDLLHS As KBDLLHOOKSTRUCT
                CopyMemory KBDLLHS, ByVal lParam, LenB(KBDLLHS)
                Dim KeyCode As Integer
                KeyCode = KBDLLHS.VKCode And &HFF&
                If KeyCode = vbKeyF1 Then
                    With New FormChild
                    .Show vbModeless
                    End With
                    Handled = True
                    RetVal = 1
                End If
            End If
        End If
    End If
End If
End Sub

Private Sub IHook_After(ByRef RetVal As Long, ByVal HookType As HookTypeConstants, ByVal HookCode As HookCodeConstants, ByVal wParam As Long, ByVal lParam As Long)
End Sub

Private Sub MDIForm_Load()
Call SetHook(Me, WH_KEYBOARD_LL)
End Sub

Private Sub MDIForm_Unload(Cancel As Integer)
Call RemoveHook(Me, WH_KEYBOARD_LL)
End Sub
```

To make this user-friendly you could include in the button caption in the ToolBar an "(F1)". Even when in real it's totally disconnected.

----------


## samer22

Thank you sir
now it works as  I was expecting

----------


## Mith

> Quote Originally Posted by Mith View Post
> That would avoid to loop through all controls on a form everytime you open the form and save a lot of time opening a form with hundreds of controls on it
> 
> Not "would". It is.


It is? Do you mean the VisualStyles property has already included a newer modern version of the tooltip class?  :Confused:

----------


## Krool

> It is? Do you mean the VisualStyles property has already included a newer modern version of the tooltip class?


Yes. (?)

----------


## Mith

> Yes. (?)


No...

CommandButtonW with the standard ToolTipText property:



CommandButtonW using my extra ToolTip-Class:



As you can see the standard ToolTipText property still shows tooltips with the old ugly style...

Tested with v1.6.41

----------


## Krool

> No...
> 
> CommandButtonW with the standard ToolTipText property:
> 
> 
> 
> CommandButtonW using my extra ToolTip-Class:
> 
> 
> ...


You talked about the ListView ListItems and ListSubItems !!!!!

----------


## Mith

> You talked about the ListView ListItems and ListSubItems !!!!!


no, i wrote this at one of my posts:




> Now i use a tooltip class and replace the tooltiptext property of *all controls* on the form for a more fresh look.


I guess there is no "modern look" tooltiptext with all the vbccr16 controls possible without using an extra tooltip class...

----------


## Krool

> no, i wrote this at one of my posts:
> 
> 
> 
> I guess there is no "modern look" tooltiptext with all the vbccr16 controls possible without using an extra tooltip class...


For the Control.ToolTipText your right. This was already discussed before and an idea was to include an .ToolTipTextW property that supports Unicode and theming. It's not possible to overwrite .ToolTipText because it's handled by VBControlExtender.

----------


## Mith

> This was already discussed before and an idea was to include an .ToolTipTextW property that supports Unicode and theming. It's not possible to overwrite .ToolTipText because it's handled by VBControlExtender.


if the current .ToolTipText property can save unicode text it would be better to add a new option to select the using of the .ToolTipText property:

1. standard VB ToolTipText
2. new ToolTipText class with modern look

but i guess if the .ToolTipText is handled by VBControlExtender you cant save unicode text, or?

----------


## Mith

I use a form with a white background and the TabStrip uses a grey background color:



Does anyone know how to change the background color of the TabStrip control or to change the control background to transparent?

I cant find any property to do this...

----------


## Karl77

> I cant find any property to do this...


There is no such property.
I asked for this some time ago as well.

The COMCTL32 doesn't offer a possibility.
And all other means require a major effort to be reliable.

----------


## wqweto

Changing backcolor on tab-strip's tabs can be implemented on *parent* WM_PRINTCLIENT msg like this



```
    Case WM_PRINTCLIENT
        '--- for tab-strip integration
        If (lParam And PRF_CLIENT) <> 0 Then
            Call GetClientRect(m_hWnd, rc)
            Call FillRect(wParam, rc, m_hBackBrush)
            Exit Function
        End If
```

This is just an idea for Krool so he can can look to it if possible to impl here.

cheers,
</wqw>

----------


## Krool

> Changing backcolor on tab-strip's tabs can be implemented on *parent* WM_PRINTCLIENT msg like this
> 
> 
> 
> ```
>     Case WM_PRINTCLIENT
>         '--- for tab-strip integration
>         If (lParam And PRF_CLIENT) <> 0 Then
>             Call GetClientRect(m_hWnd, rc)
> ...


Wow, I didn't know that. This works and is straight-forward. Is this an implementation on later OS ?
Though, it only works with VisualStyles set to True and with style 'Tabs' (all other styles are anyway not themed)

I thought it needs to be "hacked" via WM_PAINT with calculation of all the item rects and glitching around…

That the parent needs to handle WM_PRINTCLIENT reminds me of the ListView control. There was something similar added since Vista.

Thank you. Will consider this one.

----------


## Karl77

> Changing backcolor on tab-strip's tabs can be implemented on *parent* WM_PRINTCLIENT msg like this


Very interesting.
Do you have a small working example?

EDIT:
Just saw Krool's answer.
So an example for me is not needed.

----------


## Krool

So, the WM_PRINTCLIENT trick works for themed TabStrip back to Windows XP. So that is great. Thanks again wqweto. How did you come to this?

For the other styles, unthemed *or* when owner drawn the workaround to catch WM_PAINT and draw in memory dc would work sufficient as the item rect's are meaningful to get by API's, no rounded corners and assumptions(!) like in the themed tab.




> Do you have a small working example?


When somebody can't wait for the official BackColor property, then you may apply the following in the function "WindowProcUserControl":


```
Case WM_PRINTCLIENT
    ' hard-coded as no BackColor property there yet. :) Just a demo.
    If TabStripHandle <> 0 Then
        If WindowFromDC(wParam) = TabStripHandle Then
            Dim RC As RECT, Brush As Long
            GetClientRect TabStripHandle, RC
            Brush = CreateSolidBrush(vbRed)
            FillRect wParam, RC, Brush
            DeleteObject Brush
            Exit Function
        End If
    End If
```

Two minor modification compared to wqweto.
1. no PRF_CLIENT flag check needed because WM_PRINTCLIENT is per definition always PRF_CLIENT.
2. added a check that the associated wParam (DC) is really linked to the TabStrip and not any other window..

----------


## Karl77

> When somebody can't wait for the official BackColor property


I could not.
Works flawless.

Thanks to Mith's question, wqweto's hint, and Krool's implementation.

----------


## Mith

I loaded a file with a BOM header FFFE using the flag RtfLoadSaveFormatUnicodeText into a RichTextBox.
The BOM header was removed and not shown up at the text window.
Everything was fine until here.

Later i saved the file with the flag RtfLoadSaveFormatUnicodeText but the BOM header FFFE not have been added to file again!
I thought using the flag RtfLoadSaveFormatUnicodeText when saving a file would always add the BOM header to the file...

Is this a bug or how can i save the file including the BOM header again?

----------


## Krool

> I loaded a file with a BOM header FFFE using the flag RtfLoadSaveFormatUnicodeText into a RichTextBox.
> The BOM header was removed and not shown up at the text window.
> Everything was fine until here.
> 
> Later i saved the file with the flag RtfLoadSaveFormatUnicodeText but the BOM header FFFE not have been added to file again!
> I thought using the flag RtfLoadSaveFormatUnicodeText when saving a file would always add the BOM header to the file...
> 
> Is this a bug or how can i save the file including the BOM header again?


Thanks. Fixed.

That was a "bug". Not really a bug because the rich edit control just handle streams. It does not care about BOM header.
So it was an oversight by me to not write the BOM header when saving a Unicode file.

----------


## Krool

I also slightly modified LoadFile for RichTextBox.
It will load unicode file even when there is no BOM.
Prior to this change (when there is no BOM) it fall backs to ANSI text. But that does not make sense at all when specifying RtfLoadSaveFormatUnicodeText. It should read Unicode for BOM and no BOM cases without unlogic fall back to ANSI when there is no BOM.

----------


## Mith

Im missing the reverse flag at the the Find function of the RichTextBox to search a document backwards.

See https://docs.microsoft.com/en-us/dotnet
/api/system.windows.forms.richtextboxfinds?view=netframework-4.8

Or does the RichTextBox of the CommonControls not support this flag?

.redraw property 

Currently i use my own reverse search function but the backward search can be very slow when using large files and the search text isnt found.

I guess a .redraw property for the RichTextBox would be very nice to speed up the search.

Maybe this code helps you to implement a .redraw property: 
https://stackoverflow.com/questions/...ng-its-display

----------


## samer22

> Yes, an MDIFrom doesn't have a KeyDown event.
> The MDI_ToolBar demo is therefore using a WH_KEYBOARD_LL hook to detect WM_SYSKEYDOWN and with flag LLKHF_ALTDOWN and pass to ToolBar1.ContainerKeyDown. ToolBar1.ContainerKeyDown is a convinient method that will trigger a button click, when there is a button caption with an Ampersand (e.g. "&New Doc", which displays "New Doc") an key code matching it. (of course the button also must be enabled, not disabled)
> However, what you want is then independent from ToolBar1.ContainerKeyDown.
> To reach your behavior I just changed the hook, see below:
> 
> 
> ```
> Private Type KBDLLHOOKSTRUCT
> VKCode As Long
> ...


Hello sir
I noticed that when I call the function SetHook I will be unable to use keyboard keys.
Hence, Impossible to write in textboxes
thanks

----------


## samer22

> Yes, an MDIFrom doesn't have a KeyDown event.
> The MDI_ToolBar demo is therefore using a WH_KEYBOARD_LL hook to detect WM_SYSKEYDOWN and with flag LLKHF_ALTDOWN and pass to ToolBar1.ContainerKeyDown. ToolBar1.ContainerKeyDown is a convinient method that will trigger a button click, when there is a button caption with an Ampersand (e.g. "&New Doc", which displays "New Doc") an key code matching it. (of course the button also must be enabled, not disabled)
> However, what you want is then independent from ToolBar1.ContainerKeyDown.
> To reach your behavior I just changed the hook, see below:
> 
> 
> ```
> Private Type KBDLLHOOKSTRUCT
> VKCode As Long
> ...


Hello sir
I noticed that when I call the function SetHook I will be unable to use keyboard keys.
Hence, Impossible to write in textboxes
thanks

----------


## Krool

> Im missing the reverse flag at the the Find function of the RichTextBox to search a document backwards.


There is no reverse flag, right.
However, you can search backwards by flipping the parameters. It's demonstrated in the Demo:


```
If (CommonDialogFind.Flags And CdlFRDown) = CdlFRDown Then
    RetVal = RichTextBox1.Find(CommonDialogFind.FindWhat, RichTextBox1.SelStart + RichTextBox1.SelLength, , Options)
Else
    RetVal = RichTextBox1.Find(CommonDialogFind.FindWhat, , RichTextBox1.SelStart, Options)
End If
```

So if Down is selected in the Find common dialog the search in RichTextBox is forward.
If Up is selected then the search appears backward.
But if two hit results are found it's the first from start and not the first from SelStart.
So it's not real backward but for most cases appear ok.
Whatsoever I will look to include Reverse flag soon.

----------


## Mith

> So it's not real backward but for most cases appear ok.


Currently i use the following function for a real backward search:



```
Public Function RTB_FindReverse(ByRef cRTB As VBCCR16.RichTextBox, ByVal sFindText As String, Optional ByVal lStartPos As Long = -1, Optional ByVal lSearchFlags As Long) As Long
         
      Dim I As Long
      Dim lPos As Long
      Dim TextLen As Long
      
20    TextLen = Len(sFindText)
      
30    Call LockWindowUpdate(cRTB.hwnd)
      
40    If lStartPos = -1 Then
50       lStartPos = Len(cRTB.Text) 'end of file
60    End If
      
70    For I = lStartPos To 0 Step -1
            
80       lPos = cRTB.Find(sFindText, I, I + TextLen, lSearchFlags)
90       If lPos <> -1 Then Exit For
         
100   Next I
      
110   Call LockWindowUpdate(0)
      
120   RTB_FindReverse = lPos
      
End Function
```

I hope the new reverse flag will help to speed up backward searching through large files...

----------


## Krool

> Im missing the reverse flag at the the Find function of the RichTextBox to search a document backwards.
> 
> See https://docs.microsoft.com/en-us/dotnet
> /api/system.windows.forms.richtextboxfinds?view=netframework-4.8
> 
> Or does the RichTextBox of the CommonControls not support this flag?


Thanks Mith. You become a good tester.  :Smilie: 

The flag 'RtfFindOptionReverse' is now included for the Find method.
It has the same value 16 (&H10) as in the .net RichTextBoxFinds Enum.

Your RTB_FindReverse helper function is slow because you call the .Find method in a loop.
Also in each loop the control blinks as the text is selected unless the NoHighlight enum option was specified.
So please try 'RtfFindOptionReverse'. It should work fast without any need to turn off redrawing.




> I noticed that when I call the function SetHook I will be unable to use keyboard keys.
> Hence, Impossible to write in textboxes
> thanks


I tested the code snipped I provided to you again in my MDI_ToolBar demo and it was no problem to write in the textbox of the child form.
Please provide a demo project showing your issue.

----------


## samer22

sorry again sir
I was using select case mistakengly



```
Select Case KeyCode
              Case vbKeyF1
                  
                  FormChild.Show

                 End Select

                    Handled = True
                    RetVal = 1
```

----------


## Mith

> Thanks Mith. You become a good tester.


I guess more reports will come n the future because i use your controls to convert a very large vb6 project to unicode  :Smilie: 

I wish we had a unicode TreeGrid control...does anyone known a TreeGrid control with unicode support?




> The flag 'RtfFindOptionReverse' is now included for the Find method.


The new flag works very well and fast! Thanks for the implementation!

----------


## Arnoutdv

> I wish we had a unicode TreeGrid control...does anyone known a TreeGrid control with unicode support?


I use the vsFlexGrid from ComponentOne
Seems it's called Grapecity nowadays...
https://www.grapecity.com/activex

----------


## Karl77

> a TreeGrid control with unicode support


http://www.vbforums.com/showthread.p...xGrid-control)

EDIT:
Oops, TreeGrid <> Flexgrid
Don't know what you mean by TreeGrid.

----------


## Arnoutdv

> I wish we had a unicode *Tree*Grid control...does anyone known a *Tree*Grid control with unicode support?


Does the vbFlexGrid also supports a Treeview in a given column?

----------


## Krool

> Does the vbFlexGrid also supports a Treeview in a given column?


How should that look like?

----------


## Arnoutdv

"Official" screenshot here:
https://www.componentsource.com/prod...nshots/2196344

The attached image is from one of my applications

----------


## Krool

BackColor property in the TabStrip now included.

Also the OCX got updated. I don't like it as it is a functional jump, even it's still binary compatibility.
However, I also found the alternative to wait for 1.7 too stupid. As this feature was so often asked and wqweto now provided a solution...  :Smilie: 

So still until today OCX is still in sync with Std-EXE version.

The BackColor property in TabStrip will be enriched in future so it also works when VisualStyles is False or DrawMode is OwnerDrawn. This was just the first step.

Also bugfix for "TabStrip1.DrawBackground(hWnd, hDC)" method in this update. The bug was was that an offset could happen due to difference between window rect and client rect.
The new routine is also simplified. It's now directly mapped between client hWnd and TabStrip.
Also instead of SendMessage WM_PAINT it now uses WM_PRINT with PRF_CLIENT + PRF_ERASEBKGND. (for correct result even when theming is off)


```
Public Sub DrawBackground(ByVal hWnd As Long, ByVal hDC As Long)
If TabStripHandle <> 0 And hWnd <> 0 And hDC <> 0 Then
    Dim RC As RECT, P As POINTAPI
    GetClientRect hWnd, RC
    MapWindowPoints hWnd, TabStripHandle, RC, 2
    P.X = RC.Left
    P.Y = RC.Top
    SetViewportOrgEx hDC, -P.X, -P.Y, P
    SendMessage TabStripHandle, WM_PRINT, hDC, ByVal PRF_CLIENT Or PRF_ERASEBKGND
    SetViewportOrgEx hDC, P.X, P.Y, P
End If
End Sub
```

----------


## Mith

> BackColor property in the TabStrip now included.


Confirmed, it works very nice! Good job!

Now i can set the TabStrip background color to the form background color:



At the beginning i was confused because at the IDE your dont see the defined background color.

----------


## Mith

There exists a ListItem property named "UseItemStyleForSubItems" that enables you to change the backcolor of ListItems and SubItems.

Is it possible to add this property to the ListView control?

See https://www.google.com/search?q=list...yleForSubItems

----------


## Mith

i created a listview with report mode and defined that the first and fifth column is right-aligned.
i also used FullRowSelect=False and AutoSelectFirstItem=False

after i created the report i get this:



the first item is auto selected but i used AutoSelectFirstItem=False and the alignment is switched from right to left because the item was autoselect...


normally it should look like this:



after i click on another item it looks like this:



1. i can avoid this alignment-swapping when i set FullRowSelect=True.

2. if AutoSelectFirstItem is set to False the control should not autoselect the first item ,or?

3. is it somehow possible to lock the listview without using enable=false to prevent user mouse clicks or keyboard inputs? i guess a .locked property would help here...

Example project: test - ListView Alignment bug.zip

----------


## Krool

Update released

The BackColor property works now when the VisualStyles property is False and regardless of the style, placement or draw mode.. So BackColor is always rendered now.



Due to the 2-step drawing of the TabStrip (WM_ERASEBKGND+WM_PAINT) I decided to include a DoubleBuffer property merging the two steps into one in a memory DC on WM_PAINT.
This reduces flicker also for the themed TabStrip.(!)




> At the beginning i was confused because at the IDE your dont see the defined background color.


That's because I want to avoid subclassing the control + usercontrol at design time. The property is clearly stating:
"_Returns/sets the background color used to display text and graphics in an object. This property is ignored at design time._"




> There exists a ListItem property named "UseItemStyleForSubItems" that enables you to change the backcolor of ListItems and SubItems.
> 
> Is it possible to add this property to the ListView control?
> 
> See https://www.google.com/search?q=list...yleForSubItems


You'r right. There is no BackColor property for ListItems and SubItems..
However, you can change the BackColor via the ItemBkColor event. (applicable for all it's SubItems of an ListItem)



```
ListView1_ItemBkColor(ByVal Item As LvwListItem, RGBColor As Long)
```




> the first item is auto selected but i used AutoSelectFirstItem=False


I re-checked and confirm that this behavior is intended.
If AutoSelectFirstItem is True the item has LVIS_SELECTED + LVIS_FOCUSED
If False the item has only LVIS_FOCUSED

But in both cases .SelectedItem returns an item because it checks for LVNI_FOCUSED.
This behavior is intended to be like this and won't be changed.




> can avoid this alignment-swapping


As you noted you can workaround this by having fullrowselect = true
MSDN says:
_LVS_REPORT
This style specifies report view. When using the LVS_REPORT style with a list-view control, the first column is always left-aligned. You cannot use LVCFMT_RIGHT to change this alignment. See LVCOLUMN for further information on column alignment._ 

I know this limitation. In my implementation I workaround this by adjust the LVCOLUMN.fmt value after the insert of the item.
So at least it works for fullrowselect = true. However, when that's False then you have glitches.

----------


## AAraya

> VBCCR15 v1.5.20 (side by side)
> 
> some users got the following error message box when starting my app under windows 10:
> 
> 
> 
> ```
> VBCCR15
> Run-time-error ´429´
> ...


Did you ever discover the cause of this?  I'm having what I believe is a similar issue.  Upon launching my application, two users both report a msgbox window with title "VBCCR16" and a message of "Run-time error 0".  When they click OK they get a Run-time-error 429.  And my app never appears.  This is my first app I've deployed with VBCCR16 so any support tips for dealing with these issues would be appreciated!

----------


## Krool

> Did you ever discover the cause of this?  I'm having what I believe is a similar issue.  Upon launching my application, two users both report a msgbox window with title "VBCCR16" and a message of "Run-time error 0".  When they click OK they get a Run-time-error 429.  And my app never appears.  This is my first app I've deployed with VBCCR16 so any support tips for dealing with these issues would be appreciated!


Do you use ImageList with 32 bit pictures?
It has been discussed several times with run-time error 0. It's MS fault and I can't really help.

----------


## AAraya

> Do you use ImageList with 32 bit pictures?
> It has been discussed several times with run-time error 0. It's MS fault and I can't really help.


I may.  I will check.  What is the solution for this problem?  What color-depth is acceptable for this control?

Also, I'm curious why only a couple of my users see this.  What other factors are involved here?

----------


## Arnoutdv

Try to investigate the differences between the users.
Windows versions etc etc

----------


## Karl77

I remember a similar problem.
No special reason found, but the solution:

Some of my form had an icon associated in the IDE.
On my test-PCs all worked fine, on some but not all users PCs not.
Error 429, error 0, and only when using VBCCR.

The solution was to remove the icons of the forms.
And set them by code during runtime.
No single error since then.

This is a shot in the dark, but perhaps you can try.

EDIT:
I think the error came up on Win7 systems only.

----------


## DaveInCaz

<deleted duplicate post>

----------


## DaveInCaz

IIRC the problem is that Win10 accepts images to be loaded into the imagelist at design time which are NOT acceptable to Windows 7. So everything works fine on a Win10 dev machine but can fail when the app is run on Win7.

Details:
https://stackoverflow.com/a/54136587/3195477


and actually this other post was trying to get to the bottom of the issue in Windows:
https://stackoverflow.com/questions/...ion-of-windows

but never had a satisfactory conclusion.

----------


## Mith

VBCCR16 v.1.6.45

one user recieved this error message using my app under win10:



*Run-time-error -2147221164 (80040154) Class not registered*

I use VBCCR16.OCX side-by-side w/o registering the ocx.

any ideas how to fix that?

I cant reproduce this error message myself using a fresh installed win10.

Thanks for any help!

----------


## Krool

> VBCCR16 v.1.6.45
> 
> one user recieved this error message using my app under win10:
> 
> 
> 
> *Run-time-error -2147221164 (80040154) Class not registered*
> 
> I use VBCCR16.OCX side-by-side w/o registering the ocx.
> ...


Is the side-by-side msnifest in a resource file integrated into the .exe or external file?
Some windows installation don't accept external file manifests due to settings.

----------


## Mith

> Is the side-by-side msnifest in a resource file integrated into the .exe or external file?
> Some windows installation don't accept external file manifests due to settings.


Yes, the manifest file is integraded into a ressource file compiled into the exe.

but guess what, i told the user to manually register the VBCCR16.OCX and now the app runs w/o the error!

i thought we dont need to register SxS files at the system to use them, or im wrong?

----------


## DaveInCaz

<deleted duplicate post>

----------


## DaveInCaz

> i thought we dont need to register SxS files at the system to use them, or im wrong?



Registering it manually was a *workaround* for the problem in the manifest. If you can correct the manifest then it isn't necessary.

I've sometimes found Process Monitor and Process Explorer (google) useful to debug VB6 manifest issues. You can see what tries to get loads & fails, what really is loaded, etc.

----------


## Mith

> Registering it manually was a *workaround* for the problem in the manifest. If you can correct the manifest then it isn't necessary.
> 
> I've sometimes found Process Monitor and Process Explorer (google) useful to debug VB6 manifest issues. You can see what tries to get loads & fails, what really is loaded, etc.


i tested the app with windows 10 / WinXP and no error occured. the manifest file should be correct, or?

i also compared my manifest file with the file "VBCCR16SideBySide.res" and everything is the same.
my manifest file includes more than 20 ocx/dll files and none of them makes a problem.
i guess there must be another problem with the computer of the user because all other users can use the app w/o any problem!
The question is: what is wrong with this computer? 
SxS works at this computer, because all other OCX files dont need to be manually registered.

----------


## Karl77

Can someone tell me the advantages to not register the OCX?

----------


## Krool

> Can someone tell me the advantages to not register the OCX?


Yes, "dll-hell"

----------


## Mith

> Can someone tell me the advantages to not register the OCX?


- your app can use another dll version than the one on the system installed
- all the DLLs you use can stay in one (sub)folder
- portable app

----------


## pramod9763

Thanks a lot for your valuable work sir! 
I Packaged the 'ComCtlsDemo' project using 'Package & Deployment Wizard' and installed the application on my Windows 10 - 32 bit PC. When I run the application, all the controls look beautiful with latest theme. But, when I click on 'RichTextBox' or 'Command2' button, the application crashes without any warning. However, everything works just fine under VB IDE, though the controls look in classic style. 

Please suggest a solution! 

Also, if possible, please add Scrollbar controls.

----------


## DaveInCaz

> Can someone tell me the advantages to not register the OCX?


In general (not specific to this OCX) I've found that our manifested VB6 apps are far more robust. Our manifest is quite comprehensive of dependencies and this has reduced a lot of brittleness and customer support issues because there are just far fewer places for things to go wrong.

Aside from the fact that the manifested app is more isolated from other random changes on the customer's PC, it also means we are always running against & testing against exactly the configuration that we ship. 

Dave

----------


## PauloFranc

Hi, I have a problem with the Toolbar. The TAGs of the ButtonMenus of the Buttons disappear when saving/running the project. I've used the KEY instead of TAG as a workaround but don't know if it's a bug.

----------


## Krool

> Hi, I have a problem with the Toolbar. The TAGs of the ButtonMenus of the Buttons disappear when saving/running the project. I've used the KEY instead of TAG as a workaround but don't know if it's a bug.


That was a bug, which was easy to fix now.
Thanks for reporting.

----------


## pramod9763

I am using VBCCR16. OCX. 
I observed that when rtf text is loaded in RichTextBox and if ScrollBars property is 3 - vbBoth, the rtf text gets aligned horizontally outside horizontal boundaries of RichTextBox and only Horizontal ScrollBar appears. So you've to traverse horizontally to read the text. 

I think the case should be opposite. 
The rtf text should align vertically and so a Vertical ScrollBar should appear first. Therefore, you should be able to traverse vertically to read rtf text.

----------


## Mith

> VBCCR16 v.1.6.45
> 
> one user recieved this error message using my app under win10:
> 
> 
> 
> *Run-time-error -2147221164 (80040154) Class not registered*
> 
> I use VBCCR16.OCX side-by-side w/o registering the ocx.
> ...


Another user has send me the same bugreport. 

He installed windows 10 v1903 and after he installed my app.
When starting the app he got the error "VBVCCR16 Run-time error "-2147221164 (80040154)": Class not registered".
I told him to manually register the file and now the app runs well.

Why he have to manually registering a side-by-side OCX file? I dont get it...

----------


## Karl77

> Why he have to manually registering a side-by-side OCX file? I dont get it...


When I began using VBCCR, I also used the side-by-side approach.
In here it turned out that it was not reliable.
Of course I thought (and think) this was caused by *my own errors*.

In order to avoid DLL hell, I made my 'own' VBCCR with a different name.
It can't conflict with the original.
While I was at that, I married VBCCR and VBFlexGrid, and added most of my own UCs.

And because it is so simple, I register this 'All-in-one' OCX on setup.
No single error up to now.

----------


## Krool

I can't replicate any SxS error. It would be interesting to know if something is missing in the manifest or if this is just windows setting confusion stuff on certain users.

----------


## DaveInCaz

> I can't replicate any SxS error. It would be interesting to know if something is missing in the manifest or if this is just windows setting confusion stuff on certain users.


FWIW I've been running VBCCR1x in a SxS manifest for years and have never had a problem either.

----------


## jpbro

> I can't replicate any SxS error. It would be interesting to know if something is missing in the manifest or if this is just windows setting confusion stuff on certain users.


Maybe related to the manifest padding issue described here?

----------


## PauloFranc

Hi Krool,

Just to say thanks for making this and making it available to all of us that are still using VB6  :Smilie: 

And thanks for how fast you solved this...

----------


## Mith

> In order to avoid DLL hell, I made my 'own' VBCCR with a different name.
> It can't conflict with the original.


The user did a fresh windows 10 installation and there was no other VBCCR16.OCX on that system installed...

i guess there must be some windows 10 bug with the SxS functionality.
It looks like that the Windows system cant automatically register the file VBCCR16.OCX when starting the app.
But as i wrote before, i cant reproduce this problem at Windows 10 and 1000 other users dont have this problem too.
Only 1-2 users expierend this problem and the workaround is to register the OCX for all users at the windows system.
I used SxS to avoid registering the OCX files of my app for all windows users but now SxS not works correctly and only for the file VBCCR16.OCX. 
All the other OCX/DLLs of my app have no problem with SxS...strange

----------


## Mith

> Maybe related to the manifest padding issue described here?


Thanks for the hint but the manifest works w/o any problems for me and the most users.
i couldnt find any error at the manifest file.

Juding by the error message of the 2 users it looks like there be some other reason the windows system cant automatically registering VBCCR16.OCX when the app starts...

----------


## Krool

> Thanks for the hint but the manifest works w/o any problems for me and the most users.
> i couldnt find any error at the manifest file.
> 
> Juding by the error message of the 2 users it looks like there be some other reason the windows system cant automatically registering VBCCR16.OCX when the app starts...


My bet is that they make a custom resource file with all kinds of manifests (xml nodes) included and that maybe in that heavy weight .res file there is a issue with the manifest.

Would be interesting to know those users who have problem with SxS with VBCCR16.OCX still have it when using the "original" manifest which can be downloaded here.

----------


## Mith

> My bet is that they make a custom resource file with all kinds of manifests (xml nodes) included and that maybe in that heavy weight .res file there is a issue with the manifest.


I already tested the app on all windows platforms from WinXP to Win10 and there are no SxS problems.
And thousand other users using the app on different windows platforms and noone had a problem so far with SxS and VBCCR16.
IMHO the problem not comes from a wrong manifest file. If so all users including me should expierend the same problem, or?




> Would be interesting to know those users who have problem with SxS with VBCCR16.OCX still have it when using the "original" manifest which can be downloaded here.


Sorry, thats currently not possible. The users with the SxS problem already have registered the OCX file at their windows system...

My bet is there is some kind of a windows bug that prevents the VBCCR16.OCX to register themself under specific circumstances when the app starts. Maybe it have something to do with the user rights?

----------


## Karl77

> Sorry, thats currently not possible. The users with the SxS problem already have registered the OCX file at their windows system...


If your user is patient and willing to help you (and all of us), he could unregister it and see what happens.

----------


## wqweto

> Sorry, thats currently not possible. The users with the SxS problem already have registered the OCX file at their windows system...

Manifests overwrite registry COM entries.

It's possible to get into a limbo though, a franken-registration where half the keys are from the manifest and some missing entries are gleaned from the registry.

That would be very hard to debug, probably w/ RegMon from sysinternals on the broken machine.

cheers,
</wqw>

----------


## Semke

thanks krool for all your work...

one suggestion, could you add an about box for each control, many a time I got confused what control I am using, MS Controls or VBCCRP.

thanks

----------


## Karl77

FONTCOMBO QUESTION

I'm in the middle of investigating the FontCombo control (struggling with the "@" fonts).



```
Private Function EnumFontFunction
```

is called twice.
I wonder if this is right or not?

----------


## Krool

> FONTCOMBO QUESTION
> 
> I'm in the middle of investigating the FontCombo control (struggling with the "@" fonts).
> 
> 
> 
> ```
> Private Function EnumFontFunction
> ```
> ...


Yes, that's correct. The enum is per charset and the additional enum is wanted for the SYMBOL_CHARSET.

----------


## Karl77

FONTCOMBO QUESTION2

In the EnumFontFunction I need to exclude determined fonts from populating the list.
I added a ExcludeList property to the control.
Works fine if I set the ExcludeList at design time.

But I need the functionality at runtime.
That doesn't work because the list gets populated before I can set my ExcludeList.
I tried with .Refresh after setting the ExcludeList, but that doesn't work either.

What should I do?

----------


## Krool

> FONTCOMBO QUESTION2
> 
> In the EnumFontFunction I need to exclude determined fonts from populating the list.
> I added a ExcludeList property to the control.
> Works fine if I set the ExcludeList at design time.
> 
> But I need the functionality at runtime.
> That doesn't work because the list gets populated before I can set my ExcludeList.
> I tried with .Refresh after setting the ExcludeList, but that doesn't work either.
> ...


What does your custom ExcludeList property exactly?
So I can check why it's only working at design time.
Workaround could be that at run-time you loop thru all items and use CB_DELETESTRING.

----------


## Karl77

> So I can check why it's only working at design time.


That's now logical to me, because the list gets populated before the UC can read the property.
And after I set the ExcludeList property there is not function to recreate the list.
So no need to check on this.




> Workaround could be that at run-time you loop thru all items and use CB_DELETESTRING.


That seems to be the only correct way to me, and not a workaround.
Because the EnumFontFunction runs twice as you explained, it makes no sense to do the exclusion in that place.

Could you make a very short example on how to CB_DELETESTRING from the Combobox?
I fear to destroy the order when certain items get deleted.

Thank you for that.

----------


## Krool

> That's now logical to me, because the list gets populated before the UC can read the property.
> And after I set the ExcludeList property there is not function to recreate the list.
> So no need to check on this.
> 
> 
> That seems to be the only correct way to me, and not a workaround.
> Because the EnumFontFunction runs twice as you explained, it makes no sense to do the exclusion in that place.
> 
> Could you make a very short example on how to CB_DELETESTRING from the Combobox?
> ...


I can't code right now. It's just illustration and not tested. But it should give you the idea.



```
With FontCombo1
Do
  bDelete = False
  For i = 0 To .ListCount - 1
    If .List(i) = strExcludeList Then
      SendMessage .hWnd, CB_DELETESTRING, i, ByVal 0&
      bDelete = True
      Exit For
    End If
  Next i
Loop Until bDelete = False
End With
```

----------


## AAraya

> Did you ever discover the cause of this?  I'm having what I believe is a similar issue.  Upon launching my application, two users both report a msgbox window with title "VBCCR16" and a message of "Run-time error 0".  When they click OK they get a Run-time-error 429.  And my app never appears.  This is my first app I've deployed with VBCCR16 so any support tips for dealing with these issues would be appreciated!


As an update for any others who may encounter this problem.  I replace hundreds of 32-bit icons with 24-bit icons in my app but it did not resolve the problem.

Three of my users were having this issue.  One had Vista and two had Win 7 which had not had all updates installed.  When the Windows 7 computer was updated, the VBCCR16 "run-time error 0" issue no longer happens.  

Hope this saves someone a bunch of time chasing down other possibilities.

----------


## DaveInCaz

> When the Windows 7 computer was updated, the VBCCR16 "run-time error 0" issue no longer happens.



What specifically was updated? What changed? Thanks

----------


## AAraya

> What specifically was updated? What changed? Thanks


The Windows 7 OS was updated. No idea exactly which patch(es) resolved this issue.  These are end-users, not computer engineers.  They didn't go one-by-one, install update, test, install update, test.  They just let Windows install all needed OS updates that hadn't been applied yet.

----------


## LaVolpe

This is for Krool. Others may want to experiment.

Background: When a DPI-aware project is loaded into non-integral DPI (my own term), 175%, 200%, etc, where VB's twipsPerPixel (TPP) is not the same as the system's (1440 / realDPI) <> VB's TPP, then OCXs have problems. An ocx for simplicity: any control that is not a VB intrinsic control.

Problem: The ocx does not draw into the full width/height of the ocx, it draws smaller than expected. This is directly related to the TPP discrepancy.

Fix when resizing ocxs in this scenario: while sizing, also move the control +1 units Left & Top, then re-move the control -1 units left and top. Though this does address the problem, it still fails when an OCX has an Align property that is set to other than vbAlignNone (zero). You can try with common controls progressbar and set its Align property to non-zero. Again project must be DPI-aware and loaded into 175% DPI or similar non-integral DPI

Ultimate fix is to send the control the dimensions of itself as pixels via an Interface method. That addresses the problem whether the ocx is aligned or not. This requires a bit of low-level API calls, if no TLB for that interface. We would call that interface method each time the form is resized because resizing the form changes the ocx dimensions when Align is non-zero.

Here is some sample code that can be used from the parent/form of an ocx. It should be called from within the Form_Resize event for ocxs that have an Align property set to non-zero.


```
Private Declare Function DispCallFunc Lib "oleaut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As Long, ByVal paValues As Long, ByRef retVAR As Variant) As Long
Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As Long, ByVal lpiid As Long) As Long

Public Sub SyncOcxClientToParent(theControl As Control)

    ' This can be called in any DPI, but for for non-intrinsic controls, should always
    ' be called in non-integral DPI. In that case, external OCXs (not VB
    ' intrinsic controls) may not render to the full bounds of the control. This method
    ' attempts to fix that. It should only be called for non-intrinsic controls and
    ' after the control is sized. 

    Dim oIUnk As IUnknown, oObj As Object, frm As Form
    Dim vParamPtr(0 To 1) As Long, vParamType(0 To 1) As Integer
    Dim vRtn As Variant, vParams(0 To 1) As Variant
    Dim aData(0 To 3) As Long
    Dim hWnd As Long, sm As ScaleModeConstants
    Const IID_IOleInPlaceObject = "{00000113-0000-0000-c000-000000000046}"
    Const IOIP_SetRects As Long = 28&

    On Error Resume Next
    Set oObj = theControl.object
    If Err Then
        Err.Clear
    Else
        Set frm = theControl.Parent
        If Err Then                     ' applies to forms only
            Err.Clear: Set oObj = Nothing
        Else
            sm = theControl.Container.ScaleMode
            If Err Then
                Err.Clear: sm = vbTwips
            End If
        End If
    End If
    On Error GoTo 0
    
    If oObj Is Nothing Then Exit Sub
    
    IIDFromString StrPtr(IID_IOleInPlaceObject), VarPtr(aData(0))
    ' set up call to DispCallFunc for querying for IID_IOleInPlaceObject
    vParams(0) = VarPtr(aData(0)): vParams(1) = VarPtr(oIUnk)
    vParamType(0) = vbLong: vParamType(1) = vbLong
    vParamPtr(0) = VarPtr(vParams(0)): vParamPtr(1) = VarPtr(vParams(1))
    ' does object implement IID_IOleInPlaceObject?
    DispCallFunc ObjPtr(oObj), 0&, 4&, vbLong, 2, VarPtr(vParamType(0)), VarPtr(vParamPtr(0)), vRtn
    If oIUnk Is Nothing Then
        With theControl
            .Move .Left + frm.ScaleX(1, vbPixels, sm), .Top + frm.ScaleX(1, vbPixels, sm)
            .Move .Left - frm.ScaleX(1, vbPixels, sm), .Top - frm.ScaleX(1, vbPixels, sm)
        End With
    Else
        aData(0) = frm.ScaleX(theControl.Left, sm, vbPixels)
        aData(1) = frm.ScaleX(theControl.Top, sm, vbPixels)
        aData(2) = aData(0) + frm.ScaleX(theControl.Width, sm, vbPixels)
        aData(3) = aData(1) + frm.ScaleX(theControl.Height, sm, vbPixels)
        vParams(1) = VarPtr(aData(0))
        DispCallFunc ObjPtr(oIUnk), IOIP_SetRects, 4&, vbLong, 2, VarPtr(vParamType(0)), VarPtr(vParamPtr(0)), vRtn
    End If
    Set oObj = Nothing: Set oIUnk = Nothing: Set frm = Nothing

End Sub
```

Now, the above should work in most cases, but can still fail when multiple aligned controls are stacked on each other. Multiple sizing events may occur that undoes the call to SyncOcxClientToParent. In that case, you need a delay. For example, use a disabled timer with a short interval and when Form_Resize kicks off, enable the timer. When the timer kicks off, disable it, and call SyncOcxClientToParent for the affected controls.

For Krool: The above code is for an external call. I'd imagine you can fix your own CCR controls using the same logic. However, here's some things to consider:

1. That sample code needs the UC's position/dimensions from the container's point of view and translated to pixels relative to the form's client area. Consider using the UC's Extender. You can't use GetWindowRect on the UC.hWnd because it will return the wrong dimensions. Actually, you could but would need to scale it by the difference in VB TPP vs real TPP. But not all UCs have hWnds (windowless).

2. The interface method expects two rectangles. Both are identical, so use the same pointer: VarPtr(udtRect)

3. If you are using TLBs, may want to include IOleInPlaceObject. Doing so should negate the DispCallFunc, IIDFromString calls along with the variables used for those calls.

4. From trial and error. Calling the interface method should be done whenever the control resizes, after it resizes, i.e., trap WM_SIZE if possible. If no subclassing is in play, see if Usercontrol_Resize will be good enough & if not, maybe a timer delay method like described earlier.

Questions? PM me.

----------


## Karl77

> I can't code right now. It's just illustration and not tested. But it should give you the idea.
> 
> 
> 
> ```
> With FontCombo1
> Do
>   bDelete = False
>   For i = 0 To .ListCount - 1
> ...


Perfect, thank you.
I implemented it in the UC directly.

----------


## Krool

Response to LaVolpe's post:

As preparation I included now IOleInPlaceObject in the OLEGuids.tlb.
In a second update then all the UC's will be updated. It needs time and to test everything out.

---

PS: The ComCtlsDemo in the thread's first post is now only as .zip and not anymore with .docx extension. This was now possible as the VBForums file size limit has been increas for ZIP to 1,024,000.

----------


## Krool

Criticial bug for the OLEGuids.tlb.
The recent modification - few hours ago - included interface IOleInPlaceObject.
However, it was defined as:


```
interface IOleInPlaceObject : IUnknown
```

But should have been


```
interface IOleInPlaceObject : IOleWindow
```

This is now fixed. If anyone replaced OLEGuids.tlb just recently please do again.
If not replaced again now it's not an issue "right now" but may become in future an issue.

Sorry for the inconvinience caused.

----------


## Krool

> This is for Krool. Others may want to experiment.
> 
> Background: When a DPI-aware project is loaded into non-integral DPI (my own term), 175%, 200%, etc, where VB's twipsPerPixel (TPP) is not the same as the system's (1440 / realDPI) <> VB's TPP, then OCXs have problems. An ocx for simplicity: any control that is not a VB intrinsic control.
> 
> Problem: The ocx does not draw into the full width/height of the ocx, it draws smaller than expected. This is directly related to the TPP discrepancy.
> 
> Fix when resizing ocxs in this scenario: while sizing, also move the control +1 units Left & Top, then re-move the control -1 units left and top. Though this does address the problem, it still fails when an OCX has an Align property that is set to other than vbAlignNone (zero). You can try with common controls progressbar and set its Align property to non-zero. Again project must be DPI-aware and loaded into 175% DPI or similar non-integral DPI
> 
> Ultimate fix is to send the control the dimensions of itself as pixels via an Interface method. That addresses the problem whether the ocx is aligned or not. This requires a bit of low-level API calls, if no TLB for that interface. We would call that interface method each time the form is resized because resizing the form changes the ocx dimensions when Align is non-zero.
> ...


This seems not to be an issue because when the control moves +1 units Left & Top, then re-move -1 units left and top adresses the issue properly when done within UserControl_Resize.
However, I will consider using IOleInPlaceObject::SetObjectRects as this will move the control once instead of twice. (Small benefit)
Also it looks better, rather a direct fix instead a strange looking workaround.
LaVolpe confirmed it.

----------


## Krool

> 1. That sample code needs the UC's position/dimensions from the container's point of view and translated to pixels relative to the form's client area. Consider using the UC's Extender. You can't use GetWindowRect on the UC.hWnd because it will return the wrong dimensions. Actually, you could but would need to scale it by the difference in VB TPP vs real TPP. But not all UCs have hWnds (windowless).


To assume VB.Form as control's container is not secure. It could be nested within another UserControl.
I liked the idea to use GetWindowRect and correct accordingly VB TPP vs real TPP. However, as you mention, it's not possible for windowless controls. (e.g. LabelW)

So, I come up with this function below. It seems to work. Can you review/comment and/or confirm?
_removed_

In this context I noticed that in the DPICorrectionFactor common function was a flaw. It should be:


```
Public Function DPICorrectionFactor() As Single
Static Done As Boolean, Value As Single
If Done = False Then
    Value = ((96 / DPI_X()) * 15) / Screen.TwipsPerPixelX
    Done = True
End If
' Returns exactly 1 when no corrections are required.
DPICorrectionFactor = Value
End Function
```

instead of


```
Public Function DPICorrectionFactor() As Single
Static Done As Boolean, Value As Single
If Done = False Then
    Value = Screen.TwipsPerPixelX / ((96 / DPI_X()) * 15)
    Done = True
End If
' Returns exactly 1 when no corrections are required.
DPICorrectionFactor = Value
End Function
```

So currently the Factor must be divided. Which is odd, because a Factor means by definition always multiplication from a result.

I wait a little bit before doing something ..

----------


## LaVolpe

@Krool, we we're talking about the Align property. A control cannot have it set to other than vbAlignNone if the form is not its container. That is correct, isn't it?

In that code, the form was located to use ScaleX,ScaleY. The scalemode of the control's parent was retrieved from theControl.Container.

And non-integral TPP/DPI only needs to compare the system DPI to the form's TPP, if project is system aware or better. VB can only be loaded into system DPI or virtual 100% DPI.

----------


## Krool

> @Krool, we we're talking about the Align property. A control cannot have it set to other than vbAlignNone if the form is not its container. That is correct, isn't it?
> 
> In that code, the form was located to use ScaleX,ScaleY. The scalemode of the control's parent was retrieved from theControl.Container.
> 
> And non-integral TPP/DPI only needs to compare the system DPI to the form's TPP, if project is system aware or better. VB can only be loaded into system DPI or virtual 100% DPI.


The fix to sync the object rect is always necessary regardless of Align property. Right?
If the new fix should only be used for <> vbAlignNone than I can keep the current implementation and change nothing? Sounds easier for me..
My attempt was now to get rid of the double resizing and only fix resize once for all cases.

----------


## LaVolpe

> The fix to sync the object rect is always necessary regardless of Align property. Right?


Yes, if (1440 / Screen.TwipsPerPixelX) <> (1440 \ Screen.TwipsPerPixelX)

However, and this may not apply to you, but maybe it does. With Win10, one could load forms into different DPI awareness contexts. This means on one form with your controls can be running in per-monitor awareness, while in another form they run in system awareness and in yet in another they run as unaware. In all three cases VB's TwipsPerPixel values do not change. Those values are set when VB initially loads and do not change for the life of the project. When forms are run in a different awareness than what the project loaded into, it has an affect on UCs/OCXs similar to running @ 175% DPI in some cases. I've just discovered that yesterday and am still trying to understand when/why it happens so it can be addressed. I'll follow up once I know more details.

----------


## Krool

> Yes, if (1440 / Screen.TwipsPerPixelX) <> (1440 \ Screen.TwipsPerPixelX)
> 
> However, and this may not apply to you, but maybe it does. With Win10, one could load forms into different DPI awareness contexts. This means on one form with your controls can be running in per-monitor awareness, while in another form they run in system awareness and in yet in another they run as unaware. In all three cases VB's TwipsPerPixel values do not change. Those values are set when VB initially loads and do not change for the life of the project. When forms are run in a different awareness than what the project loaded into, it has an affect on UCs/OCXs similar to running @ 175% DPI in some cases. I've just discovered that yesterday and am still trying to understand when/why it happens so it can be addressed. I'll follow up once I know more details.


I understand.
In logic I first need to fix the object rect to an system DPI aware state and the VB TPP vs real TPP bug within UserControl_Resize.
I would skip per monitor awareness in that case.

Then later in another step there could be a DPIMonitorVsSystemScaleFactor(...) which when <> 1 on WM_DPICHANGE_BEFOREPARENT then scale another time object rect accordingly with the current diff factor to system aware state.

Agree?

EDIT: maybe this was too easy thought. What happens when the control resizes again due to .Align? I don't know how the behavior is exactly. Maybe such a DPIMonitorVsSystemScaleFactor needs to be done already also within UserControl_Resize...

It's a messy topic. Something in me tells just stick to system dpi awareness and just don't do a per monitor manifest.  :Big Grin: 
Even MS states in their memo about it that it still is in early stages where sometimes mixed-mode dpi awareness is necessary.
So best IMO is to get system dpi aware done properly and don't loose the nerves for per monitor awareness.
I don't find it bad when the OS bitmap stretches system dpi vs monitor dpi the applications. This at least ensures ecerything is in correct physical sizes.

----------


## LaVolpe

You can always ensure the user has access to graphical items so that they can change the scale if they want to, i.e., ensure fonts and images (that don't change automatically by the API window) are available to the user either via SendMessage and/or public UC properties. That might be a good workaround and allows users to make your control fully DPI aware.

The biggest issue I have right now with per-monitor awareness is that not all API windows may support it. And when they do, is there any guarantee that what isn't scaled now won't be scaled in future versions (backward compatibility). It would also have been nice if Microsoft required WM_DPICHANGED_BEFOREPARENT to return non-zero if it DPI changes are going to be handled by the window.

----------


## Krool

So I think I got my SyncObjectRectsToContainer now pretty straight forward without any cumbersum calculations.

It now receives the border rect of the parent window where the object's window should be located. IOleInPlaceSite::GetWindowContext
Together with IOleInPlaceObject::SetObjectRects it functions now as a perfect straight forward fix for the VB TPP vs real TPP bug.
Or in other words: Apply the dimensions what the host reports to the client.

Doesn't it look clean the new function? Works for all scenarios.


```
Public Sub SyncObjectRectsToContainer(ByVal This As Object)
On Error GoTo CATCH_EXCEPTION
Dim PropOleObject As OLEGuids.IOleObject
Dim PropOleInPlaceObject As OLEGuids.IOleInPlaceObject
Dim PropOleInPlaceSite As OLEGuids.IOleInPlaceSite
Dim PosRect As OLEGuids.OLERECT
Dim ClipRect As OLEGuids.OLERECT
Dim FrameInfo As OLEGuids.OLEINPLACEFRAMEINFO
Set PropOleObject = This
Set PropOleInPlaceObject = This
Set PropOleInPlaceSite = PropOleObject.GetClientSite
PropOleInPlaceSite.GetWindowContext Nothing, Nothing, VarPtr(PosRect), VarPtr(ClipRect), VarPtr(FrameInfo)
PropOleInPlaceObject.SetObjectRects VarPtr(PosRect), VarPtr(ClipRect)
CATCH_EXCEPTION:
End Sub
```

LaVolpe: I wait your feedback until I release an update.  :Smilie: 
The question remains. Should this new function be always called to ensrue integrity between host and client dimensions? Or only when DPICorrectionFactor() is <> 1 ? (DPICorrectionFactor is only system DPI; not per monitor)

----------


## LaVolpe

Don't wait too long for feedback. You are using some interfaces and methods I have never played with. I'm interested in it as it does look like it should be a better option than using ScaleX,ScaleY and trying to get container scalemode, etc, that I was initially using.

BTW, I did figure out in what scenarios mixing DPI awareness within a project would cause the OCX to not size correctly. It isn't just DPIs like 175%. The logic looks like this: If 1440 / GetDpiForSystem <> Screen.TwipsPerPixel. At 175%, 200% DPI, that calculation returns not equal. And when mixed awareness is in play, the calculation appears to work perfectly. When that calculation returns not equal, then sync is needed else is not. This is just FYI for you. I don't know if you plan on calling your new SyncObjectRectsToContainer during every resize or not. Prior to Win8.1, the old calculation will work just fine.

Tip: GetDpiForSystem is for Win10,v1607 or better. Need to use GetProcessAwareness for Win8.1 to Win10 before v1607.

Just saw your edited question. That's kinda tough. Right now, I know of two specific/different scenarios that cause DPICorrectionFactor<>1. Will there be more in future Win10 updates. If your new function does not trigger extra resize events, maybe always call it, else only call it when DPICorrectionFactor<>1.

----------


## Krool

> I don't know if you plan on calling your new SyncObjectRectsToContainer during every resize or not.


That's the questions.. Should I just call SyncObjectRectsToContainer on every UserControl_Resize. My feeling says just call it when it's necessary.
But what should be the condition when to call it? So that system DPI user or per Monitor DPI user will be happy and face no issues with the VBCCR.

----------


## LaVolpe

Krool, I tried your new routine and converted it to TLB-less calls and tested that too. All looks good.

In my tests, I chose only to sync when DPICorrectionFactor<>1 and it worked well. 

FYI: I re-ran your CCR project in that other DPI awareness scenario discussed earlier: Started VB in per-monitor & then loaded your test form as DPI unaware. The current method of moving the control twice worked there too. So I think that answers your question -- maybe just sync when DPICorrectionFactor<>1

----------


## Krool

Update released.

New function SyncObjectRectsToContainer now in place for all controls to support non-integral DPI.
For the end-user is no visible impact. Before it "works" and now it works. However, the number of resizes is reduced a lot for non-integral DPI.

----------


## Krool

Update released.

Affected are all controls which has a Transparent property and set to True and also the app runs on non-integral DPI. (dpi-aware)
The background most likely is black. A .Refresh fixes this issue but it's unfair when on integral DPI it's not necessary. So the developer is most likely not aware to call .Refresh after load.
Thus now whenever UserControl_Resize is called the transparent background will be updated.

----------


## DaveDavis

EN_SETEVENTMASK value (although CCR's RichTextBox doesn't use it) is 1073 (&H431) or 1093 (&H445)? I am confused.

Edited: EN_SETEVENTMASK should be 1093. I am confused on some pages by google search.

internal const int EM_SCROLLCARET          = (NativeMethods.WM_USER + 49);
internal const int EM_SETEVENTMASK         = (NativeMethods.WM_USER + 69);

----------


## Krool

> EN_SETEVENTMASK value (although CCR's RichTextBox doesn't use it) is 1073 (&H431) or 1093 (&H445)? I am confused.
> 
> Edited: EN_SETEVENTMASK should be 1093. I am confused on some pages by google search.
> 
> internal const int EM_SCROLLCARET          = (NativeMethods.WM_USER + 49);
> internal const int EM_SETEVENTMASK         = (NativeMethods.WM_USER + 69);


?
EM_SETEVENTMASK is used already.

----------


## DaveDavis

> ?
> EM_SETEVENTMASK is used already.


Sorry, I missed. CCR used during creation.

I taught EM_SETEVENTMASK can do fast updating. But I have no evidence.



```
private int updating = 0;
private int oldEventMask = 0;
public void BeginUpdate() //Faster Updating
        {
            ++updating;
            if (updating <= 1)
            {                
                const int EM_SETEVENTMASK = 0x445;
                const int WM_SETREDRAW = 0xB;    
                //Prevent the control from raising any events. This message returns the previous event mask.                         
                oldEventMask = SendMessage(new HandleRef(this, base.Handle), EM_SETEVENTMASK, 0, 0); 
                // Prevent the control from redrawing itself.
                SendMessage(new HandleRef(this, base.Handle), WM_SETREDRAW, 0, 0); 
            }
        }

        public void EndUpdate() 
        {

            --updating;
            if (updating <= 0)
            {                
                const int EM_SETEVENTMASK = 0x445; 
                const int WM_SETREDRAW = 0xB;                
                // Allow the control to redraw itself.
                SendMessage(new HandleRef(this, base.Handle), WM_SETREDRAW, 1, 0); 
                // Allow the control to raise event messages.
                SendMessage(new HandleRef(this, base.Handle), EM_SETEVENTMASK, 0, oldEventMask); 
            }
        }
```

----------


## fafalone

So the TabStrip randomly stopped working today. Didn't make any changes to any control-related files. The tabs stopped displaying, and when I try to open the (Custom) property page, I get run-time error 0x80010108 'The object invoked has disconnected from its clients.' at which point VB freezes and has to be killed from a process manager. No idea where this could be coming from.  :Confused: 
I'm using it as a UserControl; added all needed files. It's been stable for years. A frame control also stopped drawing but deleting it and creating a new one fixed that issue; deleting and creating a new TabStrip however did not.

----------


## Krool

> So the TabStrip randomly stopped working today. Didn't make any changes to any control-related files. The tabs stopped displaying, and when I try to open the (Custom) property page, I get run-time error 0x80010108 'The object invoked has disconnected from its clients.' at which point VB freezes and has to be killed from a process manager. No idea where this could be coming from. 
> I'm using it as a UserControl; added all needed files. It's been stable for years. A frame control also stopped drawing but deleting it and creating a new one fixed that issue; deleting and creating a new TabStrip however did not.


At which spot the error raises?
Can you encapsulate it in a demo?

----------


## fafalone

It happens when I click the button to bring up the property page of the (Custom) property at the top... couldn't initially tell the exact line because it was frozen, but...

I tried to place one on another form in the same project, and it worked normally.

Then I tried a 3rd form, and it didn't lock up when the run-time error popped up, and the problem is arising in PPTabStripGeneral:


```
Private Sub PropertyPage_SelectionChanged()
Dim i As Long
FreezeChanged = True
With PropertyPage.SelectedControls(0)
CheckEnabled.Value = IIf(.Enabled = True, vbChecked, vbUnchecked)
CheckVisualStyles.Value = IIf(.VisualStyles = True, vbChecked, vbUnchecked)
For i = 0 To ComboMousePointer.ListCount - 1
    If ComboMousePointer.ItemData(i) = .MousePointer Then
        ComboMousePointer.ListIndex = i
        Exit For
    End If
Next i
If ImageListEnumerated = False Then
    Dim ControlEnum As Object
    For Each ControlEnum In .ControlsEnum
```

The error is raised on that last line. VB crashes entirely a few seconds later.

Edit: I think it's some kind of system condition... like I mentioned the code hadn't changed, and the same problem seems to be happening in backup copies where definitely nothing has changed.
Edit2: Tried to upgrade to the newest version and now nothing works at all. Can't open any old form that had one of the controls on it, placing new controls stops working random (crash), tried to open the ComCtlsDemo.vbp and whenever I go to open one of those forms, app crash (no runtime error, just full-on crash). Unregistered the old version of OLEGuids and registered the new one, so that's not the issue.

----------


## Hosam AL Dein

Hi Krool ,

In listview control , when I try to read the _hint_ property of a listview group , the IDE crashes . I have downloaded and re-registered the OCX and replaced the OleGUID files to the latest ones but same problem still happens . I tested this in a fresh-downloaded _comctlsdemo_ project and the result was the same .

I tried to read it by index and key but these were not successful



```
Msgbox listview1.groups(1).hint   ' failed
Msgbox listview1.groups("SomeKey").hint   ' failed
```

All other properties I have tested for the _groups_ collection are working properly .

----------


## Krool

> In listview control , when I try to read the _hint_ property of a listview group , the IDE crashes . I have downloaded and re-registered the OCX and replaced the OleGUID files to the latest ones but same problem still happens . I tested this in a fresh-downloaded _comctlsdemo_ project and the result was the same .
> 
> I tried to read it by index and key but these were not successful
> 
> 
> 
> ```
> Msgbox listview1.groups(1).hint   ' failed
> Msgbox listview1.groups("SomeKey").hint   ' failed
> ...


Thanks!
It's fixed now.

----------


## fafalone

I've tried different versions and they're all just crashing... all my projects that use these controls are completely unusable now  :Frown: 

Best I can offer at this point is the call stack leading up to 
Exception thrown at 0x770630BD (ntdll.dll) in VB6.EXE: 0xC0000005: Access violation reading location 0x6CE044C7.


```
>	ntdll.dll!_RtlSizeHeap@12()	Unknown
 	AcXtrnal.dll!NS_FaultTolerantHeap::APIHook_RtlFreeHeap(void *,unsigned long,void *)	Unknown
 	kernel32.dll!_HeapFree@12()	Unknown
 	VB6.EXE!0049fc2b()	Unknown
 	[Frames below may be incorrect and/or missing, no symbols loaded for VB6.EXE]	
 	VBA6.DLL!0fc01e3a()	Unknown
 	VBA6.DLL!0fc01dfd()	Unknown
 	VBA6.DLL!0fa91baa()	Unknown
 	VBA6.DLL!0fb48b8f()	Unknown
 	VBA6.DLL!0fa91e09()	Unknown
 	VBA6.DLL!0fc01e3a()	Unknown
 	comctl32.dll!_CallNextSubclassProc@20()	Unknown
 	comctl32.dll!_MasterSubclassProc@16()	Unknown
 	user32.dll!_InternalCallWinProc@20()	Unknown
 	user32.dll!_UserCallWinProcCheckWow@32()	Unknown
 	user32.dll!_SendMessageWorker@24()	Unknown
 	user32.dll!_SendMessageW@16()	Unknown
 	comctl32.dll!_CCSendNotify@12()	Unknown
 	comctl32.dll!CReBar::_ResizeChildren(void)	Unknown
 	comctl32.dll!CReBar::_ResizeNow(void)	Unknown
 	comctl32.dll!CReBar::_Resize(int)	Unknown
 	comctl32.dll!CReBar::_SetBarInfo(struct tagREBARINFO *)	Unknown
 	comctl32.dll!CReBar::_WndProc(struct HWND__ *,unsigned int,unsigned int,long)	Unknown
 	comctl32.dll!CReBar::s_WndProc(struct HWND__ *,unsigned int,unsigned int,long)	Unknown
 	user32.dll!_InternalCallWinProc@20()	Unknown
 	user32.dll!_UserCallWinProcCheckWow@32()	Unknown
 	user32.dll!_SendMessageWorker@24()	Unknown
 	user32.dll!_SendMessageW@16()	Unknown
 	VBA6.DLL!0fc01d67()	Unknown
 	VBA6.DLL!0fc01e3a()	Unknown
 	VBA6.DLL!0fc01826()	Unknown
 	VBA6.DLL!0fc01826()	Unknown
 	VB6.EXE!0047b936()	Unknown
 	VB6.EXE!0047b90f()	Unknown
 	VB6.EXE!0047b700()	Unknown
 	VB6.EXE!00478921()	Unknown
 	VB6.EXE!00403882()	Unknown
 	VB6.EXE!00405bc3()	Unknown
 	user32.dll!_NtUserGetCPD@12()	Unknown
 	user32.dll!_InternalCallWinProc@20()	Unknown
 	user32.dll!_UserCallWinProcCheckWow@32()	Unknown
 	user32.dll!_DispatchMessageWorker@8()	Unknown
 	user32.dll!_DispatchMessageA@4()	Unknown
 	VB6.EXE!0047acce()	Unknown
 	VB6.EXE!0047ac2e()	Unknown
 	MSO97RT.DLL!3078d393()	Unknown
 	MSO97RT.DLL!3078d224()	Unknown
 	VB6.EXE!0047ad57()	Unknown
 	VB6.EXE!004653c3()	Unknown
 	VB6.EXE!00463f5a()	Unknown
 	kernel32.dll!@BaseThreadInitThunk@12()	Unknown
 	ntdll.dll!___RtlUserThreadStart@8()	Unknown
 	ntdll.dll!__RtlUserThreadStart@8()	Unknown
```

770630BD  mov         cx,word ptr [ecx+10h]  
Happens whenever I try to view the main form (but not the other forms) in the ComCtlsDemo.vbp project, or any of my projects with most of the controls.

Copied everything to a fresh VM with Win8, the ComCtlsDemo project worked, I opened my other project, it crashed on form load, then ComCtlsDemo also started crashing on form load, this time with error pointing to AcLayers.dll instead of ntdll. Somehow something has happened whereby just viewing a form in my old project completely breaks this project for the entire system and all future projects going forward even if reinstalled, despite not changing a single byte in any project file.

Edit: It might possibly just be something about that form... I recovered it by deleting all controls from this project manually in Notepad, but my project has other forms with the controls and no crashing occurs, but if I even try to create a new one on my main form, boom... needless to say, this is baffling.
As an experiment, I copied all controls to a new form; created a new TabStrip and crashed outright. Created new form, created TabStrip, works normally, paste controls from other form, 'Object has disconnected from clients' runtime error on property page, then crash. (Only controls being copied are pure native VB controls at this point, not even regular common controls)

----------


## Hosam AL Dein

Thanks for your response Krool ,

In ListView , When I added 30 columns and some list items ( Enough to fill the height space of ListView ) , horizontal scrolling process is too slow and produces much flicker within the control . I have made some tests to get the factors affecting this issue and I trapped some and excluded some more .

I came to a conclusion that this is affected by the number of ListView columns and the VISIBLE ListView items and consequently ListView height ( which can hide or show some populated list items ) . 

I was suspicious about if it was the control width or the columns widths are those who causing this lag too as they increase the columns visual space for the control , but found that they are not involved .

 I encapsulated a demo by which you can control :

Number of columnsListview height ( Number of visible list items)Number of total list itemsListView WidthListView Columns Widths

Actually , the first two factors are those who affect this issue .

Scenario :

Add 30 columns with say 14 rows . Scroll Horizontally and notice the lag .Add 30 columns with say 200 rows . Scroll Horizontally and notice the lag  >> Same lag as above with no increaseStart decreasing the ListView height by 10 % to reduce the number of visible list items and notice the lag  >> Scrolling is smootherRepeat the last step until there is one or two visible list items >> Almost no lag at all .With any of the steps above , ListView width and columns widths don`t affect scrolling smoothly nor laggy .

I switched to windows explorer and watched the listview behavior with about 40 columns horizontal scrolling and this was not an issue and scrolled smoothly .

Demo :
ListView Hscroll Demo.zip

----------


## Hosam AL Dein

> I've tried different versions and they're all just crashing... all my projects that use these controls are completely unusable now


Hi fafalone ,
I faced issues like these for a long time and I fixed them through time by suspicion , experiment and luck nothing else . Because when it comes to sudden IDE crashes I have no clue of what is going on .

I will not provide fixes but rather areas to watch and consider and I am sure you are totally aware of them but you may find them somehow useful .

Considering the Aclayers.dll module crash , I faced this exact error and with the same scenario you provided , as I remember , this module does some graphical manipulations and this explains why _comctlsdemo_ project crashes when you try to view the main form in IDE rather than running the project and showing it in runtime . In both cases it will not show and the IDE will crash .

What fixed this issue for me ?

*1 -* It was some conflict and bad data in the manifest of VB6 exe and the manifest resource file included in my project .

I have also faced these IDE crash occurrences in earlier time before the manifest issue and these were some mistakes I have been doing :

*2 -* At every OCX version update , I was not correctly replacing the old one . I did not un-register the previous version or the update file with the same version . So , It was registry issue .When I ran older projects with older versions registered and disk file locations for the OCX conflicted with those found in registry , the project re-registers the old OCX file maybe from the same location as the newer one or even from its original place if it was still kept in place . I mean it was registry issue related to updating the OCX with either new version or same version with a little tweak .

*3 -* The last thought is that you maybe using something "Globally" in another project which conflicted with VBCCR . Instancing and scopes of Activex COM classes are the items that I would start searching if I was suspecting the last point because I am not close enough to them .

----------


## Krool

> In ListView , When I added 30 columns and some list items ( Enough to fill the height space of ListView ) , horizontal scrolling process is too slow and produces much flicker within the control . I have made some tests to get the factors affecting this issue and I trapped some and excluded some more .
> 
> I came to a conclusion that this is affected by the number of ListView columns and the VISIBLE ListView items and consequently ListView height ( which can hide or show some populated list items ) . 
> 
> I was suspicious about if it was the control width or the columns widths are those who causing this lag too as they increase the columns visual space for the control , but found that they are not involved .
> 
>  I encapsulated a demo by which you can control :
> 
> Number of columnsListview height ( Number of visible list items)Number of total list itemsListView WidthListView Columns Widths
> ...


Thanks for your report.

However, I think I can't do something about it.

1. Windows Explorer don't use ListView. There use a direct internal control not exposed to comctl32.dll since Win 7.
2. I have no control over comctl32.dll. I removed NM_CUSTOMDRAW as potential bottle neck and no improvement noticed. So that's not the cause.
3. Microsoft Windows Common Controls 5.0 (COMCTL32.OCX) shows the same lag for their ListView. This OCX is also directly linked to comctl32.dll

----------


## Hosam AL Dein

I have an idea which I don`t know if it is applicable or not . It is built on some information I have extracted from some testing . If the info is wrong then you may forget about the rest of the post .

Info : 

After a scroll operation , the entire control is redrawn . So , while holding down the horizontal scrollbar and start scrolling , the control is redrawn at every change of the scrollbar ( which is DeltaX ) whose minimum value is the small change of the scrollbar .DeltaX value is not always number of many small changes it can be greater than small change as the public method *Scroll* does . And that`s a good point to build a solution on .

What I have thought about depending on the previous info :

I tried to implement a solution that hides the columns that are not in the visible area of the ListView . >> This failed because of first , there is no property to hide a column . second , I thought that the left property of the column changes while a scroll operation has finished ,which was not true . so , I could not control *Visibility*  depending on the *Column Left*

In the previous demo I provided , I updated it by adding the following 



```
Private Sub ListView1_AfterScroll(ByVal DeltaX As Single, ByVal DeltaY As Single)
ListView1.Redraw = False
End Sub
```



```
Private Sub ListView1_BeforeScroll(ByVal DeltaX As Single, ByVal DeltaY As Single)
ListView1.Redraw = False
End Sub
```

to stop redrawing the control and it scrolled very smoothly but surely the control appearance was exploited because it had to be redrawn after the scroll operation has ended . This was the point which made me sure the process uses entire control redrawing . 

I edited the code to the following : 



```
Private Sub ListView1_AfterScroll(ByVal DeltaX As Single, ByVal DeltaY As Single)
Timer1.Enabled = True
End Sub
```



```
Private Sub ListView1_BeforeScroll(ByVal DeltaX As Single, ByVal DeltaY As Single)
ListView1.Redraw = False
End Sub
```



```
Private Sub Timer1_Timer()
ListView1.Redraw = True
Timer1.Enabled = False
End Sub
```

So ,the control will not be redrawn at every change of the scrollbar but rather in one second after the scroll has ended which is the code of Timer1 (Sets the redraw to true and then disables it self) . Of course , this is not an optimal solution but I was just testing the behavior . The result was better and lagging is now *discrete* and happens every one second .

I tried to refine the solution by combining mouse_down event of listview to fire the redrawing at one second after the scroll has ended and while the mouse is not down . and this event was not firing with lisview scrollbars (intrinsic behavior as I think) . Also It will not be applicable if the scroll is done automatically by mouse scroll , here the mouse down refinement will not be present .

So , now , my solution has two suggestions based on two points : 

1- Redrawing only the columns which appear in the visible width space of the listview ? like the way of Virtual List Items does . And this is changed in every horizontal scroll change .

2- Keep entire control redrawing but firing it after a scrollbar journey ends not during the journey . I mean some event like Scroll_In_Progress . In this event we will not be redrawing the control but will only redraw after the scroll really ends . And the words *Really ends* here is not meant to be fired at end of a change event of a scroll bar but I think it can be implemented by measuring the silence time of a scroll bar after the first scroll . I mean , now I grabbed the the scrollbar , moving it right and left , this should not fire redrawing until it is not moved and remained still for a specific period of time say 100 ms . the we can say the Journey of scroll really ended and then we can fire the redrawing . This approach is a bit like the public method Scroll of the listview . The control is redrawn after a full DeltaX journey and that`s what I think it should be done .This method summarizes what I mean to say in this suggestion .

3 - Combine both solutions . By replacing the last four words of suggestion 1 and applying the suggestion 2 .

I have attached the previous demo with a timer firing the redrawing after one second of horizontal scrolling process completion and you can notice it is smooth for a second >> lags when redrawing >> smooth for a second >>  lags when redrawing >> and so on .


Attachment 171851

----------


## Karl77

> I've tried different versions and they're all just crashing... all my projects that use these controls are completely unusable now


When I began using VBCCR I experienced 'unexplainable' crashes as well.
But I didn't give up...

In some scenarios the IDE failed to write the .frx files correctly.
It took me some time to find out, because the .frm/.bas etc. were identical to the working version.

Check the .frx files.
Just an idea.

----------


## Mith

VBCCR16 v.1.6.50 
VB6SP6

i get the error message *457 - This key is already associated with an element of this collection* when i try to change the KEY property of an listview item.

thats what i do to get the error message:

- add a new item with the KEY "test"
- set the KEY property to "TEST"

is this a bug or is the KEY property read only?

update:

i checked your function FChangeKey



```
Friend Sub FChangeKey(ByVal Ptr As Long, ByRef OldKey As String, ByVal NewKey As String)
Dim Item As Variant, i As Long
For Each Item In PropListItem
    i = i + 1
    If ObjPtr(Item) = Ptr Then
        If NewKey = vbNullString Then
            PropListItem.Add Item
            OldKey = vbNullString
        Else
            PropListItem.Add Item, NewKey
            OldKey = NewKey
        End If
        PropListItem.Remove i
        Exit For
    End If
Next Item
End Sub
```

i guess the item with the "old" key has to be removed first before you add a new item with the same key but a different upper/lower-case...or?

----------


## Krool

> VBCCR16 v.1.6.50 
> VB6SP6
> 
> i get the error message *457 - This key is already associated with an element of this collection* when i try to change the KEY property of an listview item.
> 
> thats what i do to get the error message:
> 
> - add a new item with the KEY "test"
> - set the KEY property to "TEST"
> ...


The collection has always been text compare and not binary compare.
So don't change from lower to upper case a key.
Keep for example always in lower case and change key when it's really changed text compare wise only.

----------


## OldClock

Hey

Thanks to MountainMan's documentation, I'm finally starting to use VBCCR, great stuff!

I haven't found documentation nor examples of how the ListView column filter is to be used - how do I get the listview to show only matches once something is typed into the filter? I'm not supposed to manually clear and re-populate the listview, am I?

If I need to be able to edit cells in other columns than the first, should I use vbflxgrd or something else from vbccr?

----------


## Krool

> Hey
> 
> Thanks to MountainMan's documentation, I'm finally starting to use VBCCR, great stuff!
> 
> I haven't found documentation nor examples of how the ListView column filter is to be used - how do I get the listview to show only matches once something is typed into the filter? I'm not supposed to manually clear and re-populate the listview, am I?
> 
> If I need to be able to edit cells in other columns than the first, should I use vbflxgrd or something else from vbccr?


Filtering ListView needs you to re-populate.
The best performance is to use VirtualMode in ListView, thus making filtering fast.

For cell editing vbflexgrid is the feature richest variant in my controls. So yes, use then vbflexgrid instead of ListView for complex data represantion (view) and cell edits.
vbflexgrid cell edit allows textbox edit, combobox style edit or custom dialog box edit and many events for data validation etc.

----------


## Hosam AL Dein

In CmoboBoxW , How Can I draw items manually ? and What is the difference between Fixed and Variable drawing Enums in _DrawMode_ property .

I am asking this question because I - in most cases - use the combo style "List" , which draws a gray background for the combo box , once I changed the DrawMode property , the backcolor I set is what is shown .
My last concern is , If I draw items manually , would this affect some features or other properties ?

Thanks in advance .

Edit 1 : 
Another question . what is the property ExtendedUI is intended to do . The only effect I noticed is that : If it is set to true , scrolling the combobox opens the list otherwise , scrolling does not open the list and changes the list index and text of the combobox while the list is not opened or dropped down .

Edit 2 :
I have tested the _ItemDraw_  Event and noticed that it is not fired when the _DrawMode_  property is set to Normal . Thus I thought it would be something to start with . But , I did not get the point of some parameters like _ItemAction_ and _ItemState_ . Or This is not right start point ?

----------


## Krool

> In CmoboBoxW , How Can I draw items manually ? and What is the difference between Fixed and Variable drawing Enums in _DrawMode_ property .
> 
> I am asking this question because I - in most cases - use the combo style "List" , which draws a gray background for the combo box , once I changed the DrawMode property , the backcolor I set is what is shown .
> My last concern is , If I draw items manually , would this affect some features or other properties ?
> 
> Thanks in advance .
> 
> Edit 1 : 
> Another question . what is the property ExtendedUI is intended to do . The only effect I noticed is that : If it is set to true , scrolling the combobox opens the list otherwise , scrolling does not open the list and changes the list index and text of the combobox while the list is not opened or dropped down .
> ...


The Style 'List' has special appearance. However, on OwnerDrawn only the normal appearance is drawn by default by the OS. When DrawMode is <> Normal the ItemDraw event is fired, else it's not fired.
The difference between Fixed and Variable DrawMode is that on Variable an additional event ItemMeasure is fired to let you size the height of each particular item individually instead of all items having same height.

Concerning ExtendedUI. Normally (ExtendedUI = False) the Dropdown list is rolled out by pressing F4 or Alt+Down (or Alt+Up)
If ExtendedUI is set (True) the F4 is dismissed and just Down arrow key will roll out the Dropdown list.

----------


## pepegriyo2016

Hello,
Could you replace FileExists() by this?

Is Full Unicode and Universal.




```
Private Declare Function PathFileExists Lib "shlwapi" Alias "PathFileExistsW" (ByVal pszPath As Long) As Long
 
Public Function FileExists(ByVal PathName As String) As Boolean
    FileExists = CBool(PathFileExists(StrPtr(PathName)))
End Function
```

----------


## Victor Bravo VI

Here's a better one.

----------


## HosseinMoradi

Hi Krool, thanks for this great project.
I'm using ItemBkColor event of listview to change back color of items in report mode
but back color of the selected column is not changing
is there a way to fix this ?

----------


## pepegriyo2016

> Here's a better one.


This is not good, it generates an error, even if it is controlled with On Error Summary, which is not good in programming.


```
 On Error Resume Next
    FileExists = (GetAttr(sFileName) And vbDirectory) <> vbDirectory
    On Error GoTo 0
```

Krool, please could you change the function by the API of Windows?

----------


## Victor Bravo VI

> This is not good, it generates an error, even if it is controlled with On Error Summary, which is not good in programming.


While it is indeed good practice to avoid excessive use of *On Error Resume Next*, there's really nothing wrong with it when employed in situations like in that ANSI-only *FileExists* function. There's really no way of preventing the *GetAttr* function from raising an error when supplied with an invalid path, is there?

That said, it seems you've overlooked the other Unicode-aware *FileExists* routine there, which is what I actually wanted to refer you to, but obviously did a poor job of pointing it out.




> Krool, please could you change the function by the API of Windows?


*PathFileExists* isn't really the best choice because it doesn't distinguish files from folders:




> Determines whether a path to a file system object such as a file or folder is valid.





> The shell provides the *PathFileExists* function which is simpler than the approaches mentioned thus far but is limited in that it does not distinguish between files and directories.


Also, as it turns out, *PathFileExists* relies on *GetFileAttributes* anyway, so why not call *GetFileAttributes* directly ourselves? (and in the process, avoid loading shlwapi.dll if that's the only thing we need it for)




> Incidentally, the *PathFileExists* function I mentioned above uses *GetFileAttributes* internally if it determines that youre running on a supported version of Windows.


See these articles if you are still unconvinced *GetFileAttributes* is the way to go:

Superstition: Why is GetFileAttributes the way old-timers test file existence?Visual C++ in Short: Determining whether a path refers to a file system objectCheck if a file exists

----------


## MountainMan

Below is code I use to determine if a file exists or not or whether it is a folder. It is unicode and can take path names up to 32,767 characters.



```
Option Explicit

' The function "Exists" allows you to determine if a specified path is a folder, a file or
' non-existent. It is unicode and works for 32-bit VB6 and 32 or 64-bit VBA.
' A test sub called Main at the end of this module shows exaamples of each.

#If Win64 Then
Private Declare PtrSafe Function GetFileAttributesW Lib "kernel32.dll" (ByVal lpFileNamePtr As LongPtr) As Long
#Else
Private Declare Function GetFileAttributesW Lib "kernel32.dll" (ByVal lpFileNamePtr As Long) As Long
#End If

Dim UCPath As String

#If Win64 Then
Public Function UniCodePtr(ByRef Filename As String) As LongPtr
#Else
Public Function UniCodePtr(ByRef Filename As String) As Long
#End If
' Returns a pointer to module variable UCPath (32 or 64-bit) that is set to allow
'  filenames in unicode that can be up to 32,757 characters.
' UCPath is a module-level string because if it is local to this function then
'  the variable is destroyed and the pointer points to a variable location that
'  no longer exists.
' Values from this function are used in Windows API calls that end in "W" (wide, unicode)
'  instead of "A" (ANSI) such as CreateFileW, RemoveDirectoryW, CopyFileW, DeleteFileW, etc.
'  that Windows allows to have up to 32,767 characters in the name instead of
'  MAX_PATH (about 260).
If LenB(Filename) > 0 Then
   If AscW(Filename) = 92 Then ' starts with a \
      If AscW(Mid$(Filename, 2, 1)) = 92 Then ' starts with \\
         UCPath = "\\?\UNC\" & Right$(Filename, Len(Filename) - 2)
      Else
         UCPath = "\\?\" & Left$(CurDir$, 2) & Filename
         End If
   Else
      UCPath = "\\?\" & Filename
      End If
   UniCodePtr = StrPtr(UCPath)
   End If
End Function

Function Exists(Filename As String) As Long
' Filename is treated as unicode, can be up to 32,757 characters long
'Return values
' -1 Filename specifies a folder
'  0 Filename does not exist (can use Err.LastDllError to get Windows error code if you want to know more)
'  1 Filename sepecifies a file
Dim i As Long
i = GetFileAttributesW(UniCodePtr(Filename))
If i <> &HFFFFFFFF Then
   Exists = IIf((i And vbDirectory) <> 0, -1, 1)
   End If
End Function
```


Below is a simple test sub you can use either in VB6 or Excel to show samples of each.



```
Sub Main()
#If VBA6 Then
 MsgBox Exists(ThisWorkbook.Path) & vbCrLf & vbCrLf & "Should be -1 (Found a directory)"
 MsgBox Exists(ThisWorkbook.Path & "\" & ThisWorkbook.Name) & vbCrLf & vbCrLf & "Should be 1 (found a file)"
 MsgBox Exists(ThisWorkbook.Path & "1") & vbCrLf & vbCrLf & "Should be 0 (Specified path or file does not exist.)"
#Else
 ' save this project somewhere on your hard drive
 MsgBox Exists(App.Path) & vbCrLf & vbCrLf & "Should be -1 (Found a directory)"
 MsgBox Exists(App.Path & "\" & App.EXEName & ".vbp") & vbCrLf & vbCrLf & "Should be 1 (found a file)"
 MsgBox Exists(App.Path & "1") & vbCrLf & vbCrLf & "Should be 0 (Specified path or file does not exist.)"
#End If
End Sub
```

I have attached a simple VB6 project and an Excel file that have the above code in it.

MountainMan

----------


## Krool

Please don't bring this thread off-topic with this FileExists() function.
I don't change because it uses already an unicode replacement version of GetAttr() which can also take names up to 32,767 characters.
So in my view it's already best set..

----------


## shagratt

Hi Krool! Thanks for this amazing work. Do you have any plans for a flat version of the controls?

----------


## Krool

> Do you have any plans for a flat version of the controls?


No. Comctl32.dll doesn't support it.

----------


## ayu2127

@Krool,
in the Form I am using splitter on the Top I am using TreeView and now i am replacing it with your TreeView (to get unicode Support) but when I am Dragging and Dropping on the top of Splitter, VB6 is getting crashed.
can you please check it, whether it has any issue with the existing controls or other third party controls.

----------


## Krool

> @Krool,
> in the Form I am using splitter on the Top I am using TreeView and now i am replacing it with your TreeView (to get unicode Support) but when I am Dragging and Dropping on the top of Splitter, VB6 is getting crashed.
> can you please check it, whether it has any issue with the existing controls or other third party controls.


Please provide a demo

----------


## fafalone

> When I began using VBCCR I experienced 'unexplainable' crashes as well.
> But I didn't give up...
> 
> In some scenarios the IDE failed to write the .frx files correctly.
> It took me some time to find out, because the .frm/.bas etc. were identical to the working version.
> 
> Check the .frx files.
> Just an idea.


Meant to reply earlier that I do believe Karl77 is right on the cause of my issues. Since copying/pasting non-CCR controls onto new forms was then triggering CCR bugs, and other forms with CCR controls lacked bugs, I went back and tried some of my backup frx files instead of trying to recreate the forms manually, and the bugs seem to be related to some frx issue. Something appears to trigger some frx issue and then the CCR bugs pop. Things have stabilized.

----------


## OldClock

What does "the .frm/.bas etc. were identical to the working version" mean?

----------


## Karl77

> What does "the .frm/.bas etc. were identical to the working version" mean?


When I WinMerged a _working_ backup-version with _failing_ version, there was _no difference_ in frm/bas files.

----------


## Hosam AL Dein

I have two issues concerning ListView , 

*1-* The first item is always selected even if the property _AutoSelectFirstItem_ is set to _False_ . This was unexpected to me as I thought it will do this if only _AutoSelectFirstItem_ is set to _True_ . 
*2-* The _Item_Select_ Event is not fired in the previous case ( _AutoSelectFirstItem_ is set to _False_ ) although there is an item selected as I mentioned above . This also sounds strange to me . The event fires only if  AutoSelectFirstItem is set to True and this is logical and no problem with it .

I wonder ,  First , Why does ListView select the first item while the _AutoSelectFirstItem_ is set to _False_ ?  . Second , while the first item is selected with the previous circumstances , Why does the event _Item_Select_ is not fired ?

----------


## OldClock

How do I initialize visual styles on program startup when using the ActiveX version of VBCCR? The only documentation is MountainMan's, and in the "VBCCR OCX Version Guide" section it says to call InitVisualStyles, but that procedure is only present in the StdEXE version of VisualStyles.bas. In the same section it also says, "The easiest thing to do is to include the standard module VisualStyles.bas from the StdEXE version and then in your program". Why would I include the StdEXE version of VisualStyles.bas when using the OCX? Is this an error in the documentation?

----------


## Krool

> How do I initialize visual styles on program startup when using the ActiveX version of VBCCR? The only documentation is MountainMan's, and in the "VBCCR OCX Version Guide" section it says to call InitVisualStyles, but that procedure is only present in the StdEXE version of VisualStyles.bas. In the same section it also says, "The easiest thing to do is to include the standard module VisualStyles.bas from the StdEXE version and then in your program". Why would I include the StdEXE version of VisualStyles.bas when using the OCX? Is this an error in the documentation?


The documentation is not wrong.

The visual styles have nothing todo with the OCX.

Always the EXE is responsible to apply visualstyles.

It would be possible to make an isolate aware manifest for the OCX, but that would be not good as maybe some apps (EXE) want to run w/o visual styles by design.




> I have two issues concerning ListView , 
> 
> *1-* The first item is always selected even if the property _AutoSelectFirstItem_ is set to _False_ . This was unexpected to me as I thought it will do this if only _AutoSelectFirstItem_ is set to _True_ . 
> *2-* The _Item_Select_ Event is not fired in the previous case ( _AutoSelectFirstItem_ is set to _False_ ) although there is an item selected as I mentioned above . This also sounds strange to me . The event fires only if  AutoSelectFirstItem is set to True and this is logical and no problem with it .
> 
> I wonder ,  First , Why does ListView select the first item while the _AutoSelectFirstItem_ is set to _False_ ?  . Second , while the first item is selected with the previous circumstances , Why does the event _Item_Select_ is not fired ?


The first item is always _focused_. The AutoSelectFirstItem just controls if it is also being _selected_. I hope this answers all.

The inner purpose of AutoSelectFirstItem is to behave like either as v5 or v6 MS ListView.

----------


## Hosam AL Dein

Thanks a lot for clarification krool  . You are right about 

```
The AutoSelectFirstItem just controls if it is also being selected
```

 but I will add the word *Fully* before the word *selected* . And I mean by *fully*  : the item is  _Selected_ and the _Item_Select_ event is raised as 


> The first item is always focused


 and selected too regardless of  _AutoSelectFirstItem _  property but the event is not fired in absence of AutoSelect or when set to false .

Directly after the ListView population , this code returns 1



```
Msgbox ListView1.selectedItem.Index
```

But , with _AutoSelectFirstItem_ set to _True_, the _Item_Select_ event is fired , otherwise , it is not - although being focused and selected - . Anyway , this is intrinsic behavior and it is better to be not touched as I guess you prefer . That`s why I think MS added the property _AutoSelectFirstItem_  : to select the first item then raises the event _Item_Select_ as it is not raised at the point after the list item is populated although the item is already selected .

----------


## Krool

> Thanks a lot for clarification krool  . You are right about 
> 
> ```
> The AutoSelectFirstItem just controls if it is also being selected
> ```
> 
>  but I will add the word *Fully* before the word *selected* . And I mean by *fully*  : the item is  _Selected_ and the _Item_Select_ event is raised as  and selected too regardless of  _AutoSelectFirstItem _  property but the event is not fired in absence of AutoSelect or when set to false .
> 
> Directly after the ListView population , this code returns 1
> ...


ListView1.selectedItem.Index returns the _focused_ item, not the _selected_ item.
I know it's all a little bit confusing with the wordings and detailed.. but it's "correct" as it is now.

----------


## VBClassic04

Question about disabled CCR Button (Style 1-Graphic) Bitmap Picture
It seems to work well for Icons but not for bitmaps.
The first two pics in the attached shows a regular VB Button Enabled/Disabled
The third shows the CCR Button disabled.
I've tried the DrawState function with my own buttons and get the
same result as the CCR Button.  Any hints?

----------


## Krool

> Question about disabled CCR Button (Style 1-Graphic) Bitmap Picture
> It seems to work well for Icons but not for bitmaps.
> The first two pics in the attached shows a regular VB Button Enabled/Disabled
> The third shows the CCR Button disabled.
> I've tried the DrawState function with my own buttons and get the
> same result as the CCR Button.  Any hints?


Please provide demo and picture files.

----------


## VBClassic04

See attached zip

----------


## Krool

I need some advise.. (the trick ?  :Smilie:  )

Concerning my VTable.bas handling.
I am quite happy with it but looking always for optimization.

Only two "base VTables" remain subclassed.
IOleControl and IPerPropertyBrowsing.

I am eveluating if the subclass of those base VTable can be avoided and to replace only the VTable of the individidual instance.

It "works". But then I am 100% responsible for it. (Downside)
Therefore I need a way to redirect to the original VTable in some cases.

When I try to call the original VTable "within" my VTable I get a StackHash crash.

How to solve?

_Info:
IOleInPlaceActiveObject works already complete isolated. But it does not crash as I don't change the ObjPtr's VTable but rather supply a brand new object on .SetActiveObject.
So I can provide my own lightweight COM object and redirect to original VTable, if necessary._

----------


## Krool

> I need some advise.. (the trick ?  )
> 
> Concerning my VTable.bas handling.
> I am quite happy with it but looking always for optimization.
> 
> Only two "base VTables" remain subclassed.
> IOleControl and IPerPropertyBrowsing.
> 
> I am eveluating if the subclass of those base VTable can be avoided and to replace only the VTable of the individidual instance.
> ...


Ok, I have to quote myself right now.. as I found the solution.

However, I need to check it carefully before any new release.
But it would be worth the change, because no subclass is a stability plus and no theoritcal conflicts with other (foreign) vtable subclasses.

----------


## Krool

Update released. (also for OCX)

As previously mentioned, the VTableHandle.bas, got once again improved.
The IOleControl interface is NOT subclassed anymore.

The only remaining left, which is being subclassed, is IPerPropertyBrowsing.

So, the goal to _abolish_ 'VTableSubclass.cls' and throw it away is getting closer.

----------


## VBClassic04

Any uipdate on the disabled button issue?

----------


## Krool

> Any uipdate on the disabled button issue?


I use DrawState API with DSS_DISABLED flag.
For DST_ICON type it seems to work properly whereas for DST_BITMAP it looks odd.
Looks like a often asked issue in the net.
(E.g. https://www.autoitscript.com/forum/t...-dss_disabled/)

VB seems to handle this somehow different.
Workaround would be to use 'DisabledPicture' with exactly that picture how you expect.

----------


## VBClassic04

Regarding disabled bitmap button,  what about GreyScale?
Don't know much about it, but this renders
a fairly close approximation of a disabled picture.
Using the same Options.bmp as in my download above


```
Option Explicit

Private Function GreyScale(ByVal lColor As Long) As Long
 Dim lGrayValue As Long
 lGrayValue = (77& * (lColor And &HFF&) + 150& * (lColor And &HFF00&) \ &H100& + 28& * ((lColor And &HFF0000) \ &H10000)) \ 255&
 GreyScale = RGB(lGrayValue, lGrayValue, lGrayValue)
 If GreyScale <= &H151515 Then  '?????
  GreyScale = &H808080             'dark gray
 End If
End Function

Private Sub Form_Load()
 Dim X As Single, Y As Single
 Dim c As Long
 For Y = 0 To Picture1.ScaleHeight    'Picture1 autoredraw = true, scalemode = pixels
  For X = 0 To Picture1.ScaleWidth
   c = Picture1.Point(X, Y)
   Picture1.PSet (X, Y), GreyScale(c)
  Next
 Next
End Sub
```

----------


## Krool

Updated released. (also for OCX)

No VTable subclassing anymore at all. VTableSubclass.cls got removed.

I claim now that VTableHandle.bas has reached it's final state now.  :Smilie: 

Unfortunately in OLEGuids.tlb was a bug for IPerPropertyBrowsing and it was necessary to re-compile it again. (with same uuid)

----------


## OldClock

What does this mean for us users? What is lost, what is gained?

----------


## Krool

> What does this mean for us users? What is lost, what is gained?


Good question. For "most of the users" there is no visible change.

However, from the principles point of view it has following gains: (no losses)

*1)* 1 less .cls file
*2)* VTable Subclass needs to manage *all* calls (global), whereas now only the affected objects needs to be managed. (= performance gain)
*3)* Because as VTable subclass is so global it can lead to conflicts when multiple things want to subclass the same VTable.

A practical example of such a conflict situation was VBCCRxx.OCX and VBFLXGRDxx.OCX.
They both need to manage the same VTables.
(Std-EXE version was not affected, because only one VTable subclass was compiled into the EXE, but OCX are pre-compiled and they both had their own VTable subclass)

In the past I used the hidden ThunderMain window to avoid conflicts between VBCCRxx.OCX and VBFLXGRDxx.OCX.

However, now that's not needed anymore as only each private VTable for the individual objects are managed and therefore the global base VTable remains untouched.
So, when a projects uses now VBCCRxx.OCX and VBFLXGRDxx.OCX, then it has the freedom or ability to subclass all VTables.
Which leads to the last gain point..

*4)* Clean solution




> I'm using ItemBkColor event of listview to change back color of items in report mode
> but back color of the selected column is not changing
> is there a way to fix this ?


There is a undocumented feature to change the backcolor of the selected column. So then it would all look the same in a row.
See thread from fafalone: http://www.vbforums.com/showthread.p...ghlight-column
I bundled it quickly into following helper function:


```
Private Type CLSID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long, ByRef lpRect As Any, ByVal bErase As Long) As Long
Private Declare Function UpdateWindow Lib "user32" (ByVal hWnd As Long) As Long

Public Sub LvwSetSelectedColumnBkColor(ByVal hLV As Long, ByVal RGBColor As Long)
Const LVM_FIRST As Long = &H1000
Const LVM_QUERYINTERFACE As Long = (LVM_FIRST + 189)
Dim IID_IVisualProperties As CLSID, pIVisualProperties As IUnknown
' {E693CF68-D967-4112-8763-99172AEE5E5A}
With IID_IVisualProperties
.Data1 = &HE693CF68: .Data2 = &HD967: .Data3 = &H4112
.Data4(0) = &H87: .Data4(1) = &H63: .Data4(2) = &H99: .Data4(3) = &H17
.Data4(4) = &H2A: .Data4(5) = &HEE: .Data4(6) = &H5E: .Data4(7) = &H5A
End With
SendMessage hLV, LVM_QUERYINTERFACE, VarPtr(IID_IVisualProperties), ByVal VarPtr(pIVisualProperties)
If Not pIVisualProperties Is Nothing Then
    Const VPCF_SORTCOLUMN As Long = 3
    VTableCall vbLong, ObjPtr(pIVisualProperties), 5, VPCF_SORTCOLUMN, RGBColor
    InvalidateRect hLV, ByVal 0&, 1
    UpdateWindow hLV
End If
End Sub
```

The function VTableCall (red marked) you can find in the VTableHandle.bas module if you want to copy it into your project. (in case you use OCX)

I might include in future in the ListView a property so no helper function would be necessary.

----------


## Semke

in the CommonDialog.ShowColor is it possible to predefine the custom colour(s) and is it possible to retrieve the custom colours that were defined (even it was not selected at the close of the dialog)?


thanks

----------


## Krool

> in the CommonDialog.ShowColor is it possible to predefine the custom colour(s) and is it possible to retrieve the custom colours that were defined (even it was not selected at the close of the dialog)?


Good point. Update released.

A new property named 'CustomColors' is included in the CommonDialog class.

To retrieve the custom colors use this:


```
Dim Arr16() As Long ' 0 to 15 (zero-based always)
Arr16() = CommonDialog1.CustomColors
```

Changing the custom colors is very flexible, you can take whatever single-dimensioned array with numeric values.
Also if it's zero-based or whatever else doesn't matter. It will take the first *16* values.
Example:


```
Dim MyArr(-1 To 100) As Long
MyArr(-1) = vbHighlight ' First color
MyArr(0) = vbRed ' Second color
' And so on
CommonDialog1.CustomColors = MyArr()
```

Another example with same effect:


```
CommonDialog1.CustomColors = Array(vbHighlight, vbRed)
```

----------


## Semke

> Good point. Update released.
> 
> A new property named 'CustomColors' is included in the CommonDialog class.


Thanks, works very well

----------


## OldClock

Hey

I used VBCCR16.OCX 1.06.0052, and now am updating to 1.06.0057. I have a few questions. I prefer using git instead of downloading files from forums, as git allows complete clarity regarding what and when.

1. I use side-by-side and want to enable visual styles in my shipped application (don't care about IDE). I read the whole guide from MountainMan, but it's convoluted and a bit outdated now. I used to use VBCCR16SideBySideAndVisualStyles.res, but now I can't find it anywhere (not in the first post, not in your git repo). MountainMan's docs says: 


> There are also 2 VB6 resource files in the first post on VBForums: “VBCCR16SideBySide.res” and “VBCCR16SideBySideAndVisualStyles.res”


 The first post in this thread no longer has that. The ComCtlsDemo.zip file contains only Resources.res. Why are the files gone, and will my old VBCCR16SideBySideAndVisualStyles.res still work with VBCCR 1.6.57?

2. I copied the new VBCCR16.OCX file from git master (commit e5546a6) into my project (also updated the other files - Common.bas, VisualStyles.bas, etc.). When I opened the project and saved it, the modified VBP file changed like so (git diff):


```
-Object={0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.6#0; VBCCR16.OCX
+Object={0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.7#0; VBCCR16.OCX
```

The old file was 1.6.52, the new one is 1.6.57 - still 1.6.x, so why does the VBP contain 1.7? Confusing.

3. MountainMan's documentation says I should call InitVisualStyles before any form loads. However, that procedure is only available in Standard EXE Version/Common/VisualStyles.bas:143. If I want to use visual styles with the OCX version, do I *not* need to call InitVisualStyles? If I still do need to call it, why does ActiveX Control Version/Common/VisualStyles.bas not include it?

4. If the manifest file embedded in the resource file is what actually enables visual styles, what does InitVisualStyles do? I read somewhere that visual styles have some issues (I couldn't find a list of these issues, just mentioned a missing button border) - is InitVisualStyles's job only to fix those issues? If so, it would be good to rename that function to InitVisualStyleFixes to make things more clear.

----------


## Krool

> I used VBCCR16.OCX 1.06.0052, and now am updating to 1.06.0057. I have a few questions. I prefer using git instead of downloading files from forums, as git allows complete clarity regarding what and when.


OK, see below.




> 1. I use side-by-side and want to enable visual styles in my shipped application (don't care about IDE). I read the whole guide from MountainMan, but it's convoluted and a bit outdated now. I used to use VBCCR16SideBySideAndVisualStyles.res, but now I can't find it anywhere (not in the first post, not in your git repo). MountainMan's docs says:  The first post in this thread no longer has that. The ComCtlsDemo.zip file contains only Resources.res. Why are the files gone, and will my old VBCCR16SideBySideAndVisualStyles.res still work with VBCCR 1.6.57?


You looked in the wrong thread (post). (Std-EXE)
Please go into the ActiveX Thread (1st Post) and there you find the needed .res file.




> 2. I copied the new VBCCR16.OCX file from git master (commit e5546a6) into my project (also updated the other files - Common.bas, VisualStyles.bas, etc.). When I opened the project and saved it, the modified VBP file changed like so (git diff):
> 
> 
> ```
> -Object={0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.6#0; VBCCR16.OCX
> +Object={0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.7#0; VBCCR16.OCX
> ```
> 
> The old file was 1.6.52, the new one is 1.6.57 - still 1.6.x, so why does the VBP contain 1.7? Confusing.


The version of the VBCCR16.OCX is still 1.6. Just the TypeLib version increased from 1.6 to 1.7 due to the recent included property 'CustomColors' in CommonDialog.cls.
The TypeLib version of VBCCR16.OCX started from 1.0.
So it's just a coincidence that the TypeLib version was 1.6 and the VBCCRxx.OCX is version 1.6.

A TypeLib version has a Major and Minor number. If only the Minor changes, a Project using that TypeLib does NOT need to re-compile. So, there is no harm.




> 3. MountainMan's documentation says I should call InitVisualStyles before any form loads. However, that procedure is only available in Standard EXE Version/Common/VisualStyles.bas:143. If I want to use visual styles with the OCX version, do I *not* need to call InitVisualStyles? If I still do need to call it, why does ActiveX Control Version/Common/VisualStyles.bas not include it?


That's the common miss-understanding between Std-EXE and OCX version.
The OCX is independent from any manifest.

Ever, ever the Std-EXE project is responsible to include manifest files.

So, if you have a Std-EXE project that uses VBCCR16.OCX, then you can include manifest files.

The VisualStyles.bas differs from the OCX and Std-EXE version, because the OCX version has a shrinked subset of VisualStyles.bas. The reason is that the OCX can't fix any VisualStyles issues. It just needs to know with which version of comctl32.dll to deal with, because of the functional differences.

6.x enables more functions than 5.8x. So it's not only theming.
To complicate matters 6.1 (Vista+) has more functions than 6.0 (WinXP).
So the OCX needs to know 3 Levels currently. Level 0 by default.
If Major number is exactly 6 and Minor 0 then Level 1.
If Major number is exactly 6 and Minor greater 0 OR Major greater 6 then Level 2.




> 4. If the manifest file embedded in the resource file is what actually enables visual styles, what does InitVisualStyles do? I read somewhere that visual styles have some issues (I couldn't find a list of these issues, just mentioned a missing button border) - is InitVisualStyles's job only to fix those issues? If so, it would be good to rename that function to InitVisualStyleFixes to make things more clear.


Ok, let's agree on that point. InitVisualStylesFixes would be more clear.

----------


## OldClock

Thank you Krool.

----------


## Hosam AL Dein

In CommandButtonW , 
1- What is the method SetShield is intended to do ?
2- There are some properties about ImageList and this implies that I can set the picture by an imagelist and I could not find any method or event that can do this . I noticed this while I was trying to align the picture right ,left , top , or bottom and this only appears in properties related to imagelist .

----------


## Krool

> In CommandButtonW , 
> 1- What is the method SetShield is intended to do ?
> 2- There are some properties about ImageList and this implies that I can set the picture by an imagelist and I could not find any method or event that can do this . I noticed this while I was trying to align the picture right ,left , top , or bottom and this only appears in properties related to imagelist .


1- Read the description of the method.
2- You need to apply a ImageList object to the 'CommandButtonW1.ImageList' property at run-time or already at design-time. Only then the additional ImageList* properties are meaningful.

----------


## Hosam AL Dein

Excuse me , but I couldn`t find a description for the method in comments in activex version or even in mountainman`s documentation . Where can I find it ?

And for commandbuttonw , my bad . I have forgotten to set it at first .

*Edit :*
I found it in object browser . Thanks krool .

----------


## Krool

> If so, it would be good to rename that function to InitVisualStyleFixes to make things more clear.


I will make things more clear and followed your suggestion. Therefore VisualStyles.bas got updated.

* InitVisualStyles -> InitVisualStylesFixes
* SetupVisualStyles -> SetupVisualStylesFixes

Info:
I really thought about the renaming. Rather to rename as 'VisualStylesFixes' or as you suggested 'VisualStyleFixes'.
However, looking at this as a single noun phrase rather than "two words in plural" brought me to the conclusion to 'VisualStylesFixes', because a 'fix' is a relationship between multiple components.
Thus, the singular form is "visual styles fix". (There is never just 1 single visual style affected, thus this always refer to plural visual styles)
And as there are different kind of fixes the plural is "visual styles fixes".

----------


## OldClock

Krool, Great!

Now a different topic - migration.

In my effort to migrate my large project to use VBCCR, I got the idea of simply replacing every occurrence of standard MS widgets with VBCCR ones using sed (tested in Linux using sed-4.5).

The script is:


```
sed -i -E \
    -e "s/(Begin[[:blank:]]+)MSComCtl2.DTPicker([[:blank:]]+)/\1VBCCR16.DTPicker\2/" \
    -e "s/(Begin[[:blank:]]+)MSComCtl2.MonthView([[:blank:]]+)/\1VBCCR16.MonthView\2/" \
    -e "/[[:blank:]]+StartOfWeek[[:blank:]]+=[[:blank:]]+[[:digit:]]+/d" \
    -e "s/(Begin[[:blank:]]+)MSComCtl2.UpDown([[:blank:]]+)/\1VBCCR16.UpDown\2/" \
    -e "s/(Begin[[:blank:]]+)MSComctlLib.ListView([[:blank:]]+)/\1VBCCR16.ListView\2/" \
    -e "s/(Begin[[:blank:]]+)MSComctlLib.ProgressBar([[:blank:]]+)/\1VBCCR16.ProgressBar\2/" \
    -e "s/(Begin[[:blank:]]+)MSComctlLib.Slider([[:blank:]]+)/\1VBCCR16.Slider\2/" \
    -e "s/(Begin[[:blank:]]+)MSComctlLib.TreeView([[:blank:]]+)/\1VBCCR16.TreeView\2/" \
    -e "s/(Begin[[:blank:]]+)RichTextLib.RichTextBox([[:blank:]]+)/\1VBCCR16.RichTextBox\2/" \
    -e "s/(Begin[[:blank:]]+)VB.CheckBox([[:blank:]]+)/\1VBCCR16.CheckBoxW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.ComboBox([[:blank:]]+)/\1VBCCR16.ComboBoxW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.CommandButton([[:blank:]]+)/\1VBCCR16.CommandButtonW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.Frame([[:blank:]]+)/\1VBCCR16.FrameW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.Label([[:blank:]]+)/\1VBCCR16.LabelW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.ListBox([[:blank:]]+)/\1VBCCR16.ListBoxW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.OptionButton([[:blank:]]+)/\1VBCCR16.OptionButtonW\2/" \
    -e "s/(Begin[[:blank:]]+)VB.TextBox([[:blank:]]+)/\1VBCCR16.TextBoxW\2/" \
    foo.frm
```

Test-project:
test_repo.zip

This seems to work well in the test-project. To prove it:
1. Open the mscc.vbp in the attached project, then open Form1 in the VB6 IDE.

2. Run the script on mscc.frm. All it does is to replace the MS widgets with the VBCCR ones, e.g.:


```
-   Begin VB.OptionButton Option1
+   Begin VBCCR16.OptionButtonW Option1
```

3. Open mscc.vbp in the VB6 IDE, open Form1. Still works well, and all the widgets are now VBCCR, great.


However, when I do the same to my real project, then when I open the project in the VB6 IDE and try to open the form I get this error:



> Run-time error '713':
> Class not registered.




When I try opening the form again, I now get this error:



> Run-time error '429':
> ActiveX component can't create object




Any idea what this means, or where to look, or how to get VB6 to tell me which class is not registered?

----------


## Krool

> Any idea what this means, or where to look, or how to get VB6 to tell me which class is not registered?


There are quite some other "naming swaps" needed.
Example: 'MSComctlLib.Node' -> 'VBCCR16.TvwNode'
and so on..

----------


## OldClock

Those would cause problems at compile time, but not while just attempting to open a form, no?

----------


## Krool

> Those would cause problems at compile time, but not while just attempting to open a form, no?


Which compile time errors? Then you know the spot which is causing the error and you can fix it.

----------


## OldClock

> Which compile time errors? Then you know the spot which is causing the error and you can fix it.


Having MSComctlLib.Node in the code would cause errors at compile-time, but that is not the problem. The problem I'm experiencing is an error when trying to open a form in the IDE, and as far as I know the form has no MSComctlLib.Node (I searched through the form code).

----------


## Krool

> Having MSComctlLib.Node in the code would cause errors at compile-time, but that is not the problem. The problem I'm experiencing is an error when trying to open a form in the IDE, and as far as I know the form has no MSComctlLib.Node (I searched through the form code).


The .frx file is the problem in this case.
You can only delete it and supply then the lost information again in the properties.

----------


## OldClock

Ah that's a pity - would have been so easy otherwise.

----------


## OldClock

I managed to pull it off, and documented the process in the "How I migrated my project to VBCCR" thread:
http://www.vbforums.com/showthread.p...45#post5444945

----------


## Krool

> I managed to pull it off, and documented the process in the "How I migrated my project to VBCCR" thread:
> http://www.vbforums.com/showthread.p...45#post5444945


Good one.  :Thumb: 

Update released. The migration problem for 'PasswordChar' got fixed. So you can update your script accordingly that the removal is not necessary anymore.

----------


## OldClock

Thanks, script updated - PasswordChar line removed.

----------


## sbri

Krool, thank you for these controls, they saved my app.
I have a problem with the status bar control, the "Spring" autosize parameter seems to not work like the standard control.
When all the panels of the bar have the "Spring" parameter and you resize the container window, in the standard controls they resize proportionally, but in your control all but the last panel remain of the design-time size, while the last one fills all the new space.
What can I do to reproduce the standard control behavior?
Attached a sample project.
StatusBar.zip

----------


## OldClock

kr00l is centering text in textboxes broken in 1.6.58? I can't get it centered...

textbox_not_centering.zip

----------


## Krool

> I have a problem with the status bar control, the "Spring" autosize parameter seems to not work like the standard control.
> When all the panels of the bar have the "Spring" parameter and you resize the container window, in the standard controls they resize proportionally, but in your control all but the last panel remain of the design-time size, while the last one fills all the new space.
> What can I do to reproduce the standard control behavior?


Fixed. Thanks!! (Update released)




> kr00l is centering text in textboxes broken in 1.6.58? I can't get it centered...


I can't reproduce. For me it's centering and no problem in your demo...  :Confused:

----------


## sbri

> Fixed. Thanks!! (Update released)


Thank you for the fix!

----------


## sbri

(duplicate please delete)

----------


## OldClock

Hi kr00l

In relation to http://www.vbforums.com/showthread.p...=1#post5446145

My MainForm.frm is very large. Editing it in the VB6 IDE was slow when using Microsoft Windows Common Controls(-2) 6.0, but now with VBCCR16 (currently on 1.06.0058 OCX) it has become unusably slow (>20 seconds to open the MainForm for editing in the IDE). I suspect my program is larger than most, so it's no surprise that these issues appear.

Sometimes a crash occurs while opening the main form in the IDE or in the compiled program. The first time I run the compiled EXE after booting Windows (XP SP3 in VBox), the login screen shows correctly, and when I log it and the program tries to show the MainForm it crashes with a VBCCR window appearing with the error message 


> Run-time error '0'


The login screen should look like this:


When it crashes, it becomes like this, with those diagonal lines and horrible kerning:


The error signature:



> AppName: cannonfodder.exe	 AppVer: 3.0.0.5	 ModName: msvbvm60.dll
> ModVer: 6.0.98.2	 Offset: 00063f5a


If I re-run the EXE and re-login, the MainForm shows correctly.

These crashes do not result from the program's code, as it has been stable for a long time, and only appeared after switching to VBCCR. I suppose they come from a combination of factors: the main form containing a huge number of controls (2500 in total), perhaps more than VB6 was designed for; imperfections in VBCCR; and bugs in Windows.

Sometimes the same sort of crash happens from within the IDE, with the diagonal lines and bad kerning, but there the error signature says:



> AppName: vb6.exe	 AppVer: 6.0.97.82	 ModName: unknown
> ModVer: 0.0.0.0	 Offset: 1110a460


Is this a known issue, and is there anything I can do to mitigate it?

Unfortunately I am not allowed to upload the code.

I also ran into this error:



> Run-time error '7':
> Out of memory




It turns out this has nothing to do with memory, and appears only if the OCX file is not placed alongside my program's executable (I use side-by-side loading via the manifest file embedded in the resource file). It would be better if the error message actually said that the OCX file is missing.

Kind regards

----------


## Krool

OldClock,

The run time error '0' we had already a few times in this thread.
Its an incompatibility of 32 bit icons loaded at design time on in Vista+ (ok so far) but then later crashes when you attempt to use them in Win XP. (MS issue)

----------


## npac4o

Hi Krool,

Thank you for your effort to keep this project alive and up-to-date, it's a huge commitment, also huge time-consumer. Appreciate it.

Today I decided to replace some of components in my application with a ListView control. Since dark theme is widely used nowadays, my app also support it. However, when I added Groups to my listview, the result wasn't very beautiful as you can see below:



 Initially, I tried to set fore color of the Group text as follows:



```
Friend Property Let FGroupForeColor(ByVal Value As OLE_COLOR)
Dim groupMetrics As LVGROUPMETRICS

groupMetrics.cbSize = Len(groupMetrics)
groupMetrics.Mask = LVGMF_TEXTCOLOR
groupMetrics.crHeader = Value

If ListViewHandle <> 0 Then
    SendMessage ListViewHandle, LVM_SETGROUPMETRICS, 0, ByVal VarPtr(groupMetrics)
    Me.Refresh
End If
End Property
```

Unfortunately, LVGMF_TEXTCOLOR is not implemented (really) and the result was...none.

Most of the Google results state that changing color of group text is not possible (like this). However, I found that article in MSDN forum:

https://social.msdn.microsoft.com/Fo...orum=vbgeneral

and after some time, I had this:



After adding centered blank header title:


The code is quite ugly but it works somehow, just to prove that it is completely possible to draw a custom Group header:



```
       Case NM_CUSTOMDRAW
                        Dim FontHandle As Long, Bold As Boolean, ForeColor As OLE_COLOR
                        Dim NMLVCD     As NMLVCUSTOMDRAW

                        CopyMemory NMLVCD, ByVal lParam, LenB(NMLVCD)

                        Select Case NMLVCD.NMCD.dwDrawStage
                            Case CDDS_PREPAINT
                                WindowProcUserControl = CDRF_NOTIFYITEMDRAW

                                If NMLVCD.dwItemType = LVCDI_GROUP Then
                                    Dim rectHeader As RECT: rectHeader.Top = LVGGR_HEADER
                                    Dim nItem      As Long: nItem = NMLVCD.NMCD.dwItemSpec
                                    Dim nRet       As Long: nRet = SendMessage(ListViewHandle, LVM_GETGROUPRECT, nItem, rectHeader)
                                    
                                    Dim hPen       As Long: hPen = CreatePen(0, 1, vbRed)
                                    Dim OldhPen    As Long: OldhPen = SelectObject(NMLVCD.NMCD.hDC, hPen)
                                    Dim hBrush     As Long: hBrush = CreateSolidBrush(&H80FF&)
                                    Dim OldhBrush  As Long: OldhBrush = SelectObject(NMLVCD.NMCD.hDC, hBrush)
                                                                        
                                    Rectangle NMLVCD.NMCD.hDC, rectHeader.Left, rectHeader.Top, rectHeader.Right, rectHeader.Bottom
                                    Call SetTextColor(NMLVCD.NMCD.hDC, vbGreen)
                                    Call DrawText(NMLVCD.NMCD.hDC, "TEST1-2-3", Len("TEST1-2-3"), rectHeader, DT_SINGLELINE Or DT_CENTER Or DT_VCENTER)
                                    
                                    DeleteObject hPen: DeleteObject hBrush
                                End If

                                Exit Function
```


I believe that many people will appreciate a custom Group Header. My knowledge is not enough to make it bullet-proof, I just copy-paste. For example, now adding a footer doesn't work - IDE crash. 

Dark theme really doesn't look good with blue group header  :Smilie: 

Thank you.

Edit: the code above doesn't break *Group.Footer*, in my case the *Footer* works only when *SubsetLink* is set, otherwise, the IDE crashes. It's the same with *Standard EXE Version* sample.



```
        With .Groups.Add(, , "Header Title")
            '.SubsetLink = "Subset Link?"
            .Footer = "Footer Title"
            .FooterAlignment = LvwGroupFooterAlignmentCenter
        End With
```

----------


## npac4o

```
If NMLVCD.dwItemType = LVCDI_GROUP Then
    Dim rectHeader As RECT: rectHeader.Top = LVGGR_HEADER
    Dim nItem      As Long: nItem = NMLVCD.NMCD.dwItemSpec
    Dim nRet       As Long: nRet = SendMessage(ListViewHandle, LVM_GETGROUPRECT, nItem, rectHeader)
    
    Dim hPen       As Long: hPen = CreatePen(5, 1, vb3DFace)
    Dim OldhPen    As Long: OldhPen = SelectObject(NMLVCD.NMCD.hDC, hPen)
    Dim hBrush     As Long: hBrush = CreateSolidBrush(&H80FF&)
    Dim OldhBrush  As Long: OldhBrush = SelectObject(NMLVCD.NMCD.hDC, hBrush)
                                        
    Dim lvg As LVGROUP: With lvg
        .cbSize = Len(lvg)
        .Mask = LVGF_STATE Or LVGF_GROUPID Or LVGF_HEADER
    End With

    nRet = SendMessage(ListViewHandle, LVM_GETGROUPINFO, nItem, lvg)
    Dim sText As String: sText = GetStringFromPointer(lvg.pszHeader)
                                        
    Call Rectangle(NMLVCD.NMCD.hDC, rectHeader.Left, rectHeader.Top, rectHeader.Right, rectHeader.Bottom)
    Call SetTextColor(NMLVCD.NMCD.hDC, vbGreen)
    Call DrawText(NMLVCD.NMCD.hDC, sText, Len(sText), rectHeader, DT_SINGLELINE Or DT_CENTER Or DT_VCENTER Or DT_NOCLIP)
    
    DeleteObject hPen: DeleteObject hBrush
    WindowProcUserControl = CDRF_SKIPDEFAULT
Else
    WindowProcUserControl = CDRF_NOTIFYITEMDRAW
End If
```



It's a fun to experiment  :Smilie:

----------


## dseaman

Now that LabelW is Windowless, does it no longer support OLEDragDrop?

----------


## dseaman

> Now that LabelW is Windowless, does it no longer support OLEDragDrop?


My bad. It was not Automatic. I can set Caption via Private Sub LabelW1_OLEDragDrop Event.

----------


## dseaman

Duplicate post.

----------


## Krool

> My bad. It was not Automatic. I can set Caption via Private Sub LabelW1_OLEDragDrop Event.


Glad you figured it out. But, LabelW was from the beginning windowless. Just for the records..

----------


## Semke

Hi!
I am looking at the Checkbox ownerdraw event, could you please give a description of the paramaters

OwnerDraw(ByVal Action As Long, ByVal State As Long, ByVal hDC As Long, ByVal Left As Long, ByVal Top As Long, ByVal Right As Long, ByVal Bottom As Long)

thanks

----------


## Krool

> the code above doesn't break *Group.Footer*, in my case the *Footer* works only when *SubsetLink* is set, otherwise, the IDE crashes. It's the same with *Standard EXE Version* sample.
> 
> 
> 
> ```
>         With .Groups.Add(, , "Header Title")
>             '.SubsetLink = "Subset Link?"
>             .Footer = "Footer Title"
>             .FooterAlignment = LvwGroupFooterAlignmentCenter
> ...


Interesting. However, it applies only when the ListView1.GroupSubsetCount is > 0. (feature is enabled)

I don't know how to solve it, seems like a comctl32.dll bug.

But, you can workaround it by going way 1 or way 2:

Way1:


```
With .Groups.Add(, , "Header Title")
.SubsetLink = "" ' StrPtr <> 0
.Footer = "Footer Title"
.FooterAlignment = LvwGroupFooterAlignmentCenter
End With
```

Way2: (can be done of course already at design time. A new ListView has GroupSubsetCount = 0 by default)


```
ListView1.GroupSubsetCount = 0
```




> Hi!
> I am looking at the Checkbox ownerdraw event, could you please give a description of the paramaters
> 
> OwnerDraw(ByVal Action As Long, ByVal State As Long, ByVal hDC As Long, ByVal Left As Long, ByVal Top As Long, ByVal Right As Long, ByVal Bottom As Long)


Certain members of the DRAWITEMSTRUCT are passed to the OwnerDraw event.



```
typedef struct tagDRAWITEMSTRUCT {
  UINT      CtlType;
  UINT      CtlID;
  UINT      itemID;
  UINT      itemAction;
  UINT      itemState;
  HWND      hwndItem;
  HDC       hDC;
  RECT      rcItem;
  ULONG_PTR itemData;
} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT;
```

itemAction -> Action
itemState -> State
hDC -> hDC
rcItem -> Left, Top, Right, Bottom

You may find plenty of examples on the net about subclassing a checkbox and handling WM_DRAWITEM.
So just look at those snippets and implement them accordingly into the OwnerDraw event.

----------


## OldClock

Hey

I'm making a UserControl button using VBCCR 1.06.0059 widgets.

The button has three states:
Disabled
When disabled, the icon and text should be gray.
Normal
Icon and text white.
Hover
Icon and text gold.


The button is made using the Image, LabelW and FrameW widgets. Some VBCCR widgets, such as LabelW and FrameW, support the MouseEnter and MouseLeave events, however the UserControl itself does not. I created procedures for LabelW and FrameW to support the MouseEnter and MouseLeave events, however they never fire. What am I doing wrong?

I need the UserControl to change the image to "hover" when the user moves the mouse over it, and to revert the image to "normal" when the mouse leaves. Since the picture doesn't change on MouseEnter/MouseLeave, I made it change on Click to just show that the Click event works while the others don't.

The project is attached. Note how the FrameW1_MouseMove and LabelW1_MouseMove events fire (if you uncomment them), while UserControl_MouseMove and none of the MouseEnter/MouseLeave events ever fire.

menubutton.zip

----------


## Krool

> I'm making a UserControl button using VBCCR 1.06.0059 widgets.
> 
> The button has three states:
> Disabled
> When disabled, the icon and text should be gray.
> Normal
> Icon and text white.
> Hover
> Icon and text gold.
> ...


Set .MouseTrack = True for FrameW and LabelW and try again.

----------


## OldClock

That works, thank you!

----------


## Eduardo-

Hello Krool, I'm using some of your controls in a project so thank you very much.
I want to ask you what's the purpose of having two properties in the ScrollBar control: RightToLeft and RightToLeftLayout that need to be both set to True to set the direction RTL?

Also I want to report that with the last version of the controls, opening the main form, selecting the ProgressBar, and pressing F4 to show the property screen, I get this error message: 


The message says: Expected Function or variable.

I think it might be because you updated OLEGuids.tlb and I'm using an old version.

Anyway the controls that I am actually using in my project are from the older version (I downloaded it about two months ago), so I don't know if it would be a good idea to register the newer OLEGuids.tlb in my case.

I attached the image full scaled.

----------


## Krool

> I'm using some of your controls in a project so thank you very much.
> I want to ask you what's the purpose of having two properties in the ScrollBar control: RightToLeft and RightToLeftLayout that need to be both set to True to set the direction RTL?


It's a complex story. Every control has it's unique treatment.
In general, when a RightToLeft = True then apply WS_EX_RTLREADING and if RightToLeft and RightToLeftLayout = True then apply only WS_EX_LAYOUTRTL.

Here is my internal documentation about the RightToLeft handling for each control:


```
> CoolBar
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; CDDS_PREPAINT in NM_CUSTOMDRAW SetTextAlign
  Extra  : RightToLeftLayout property
> LinkLabel
  dwMask : CDDS_PREPAINT in NM_CUSTOMDRAW SetTextAlign
  Extra  : InitReverse .Alignment; ToolTip
> DTPicker
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; EditHandle: WS_EX_RTLREADING
  Extra  : RightToLeftLayout property; Reverse .CalendarRightAligned; 
> MonthView
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL
  Extra  : RightToLeftLayout property
> Pager  
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL
  Extra  : RightToLeftLayout property
> ListView
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; WS_EX_RTLREADING
  Extra  : RightToLeftLayout property; ToolTip; HDF_RTLREADING
> ComboBoxW/FontCombo
  dwMask : WS_EX_RTLREADING Or WS_EX_RIGHT Or WS_EX_LEFTSCROLLBAR
  Extra  : Clear ES_RIGHT in .hWndEdit
> ImageCombo
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; WS_EX_RTLREADING Or WS_EX_RIGHT Or WS_EX_LEFTSCROLLBAR
  Extra  : RightToLeftLayout property; Clear ES_RIGHT in .hWndEdit
> ToolBar
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; TB_SETDRAWTEXTFLAGS DT_RTLREADING
  Extra  : RightToLeftLayout property; TPM_RIGHTALIGN+TPM_LAYOUTRTL in ShowButtonMenuItems; ToolTip; Call ReCreateToolBar
> Slider
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL
  Extra  : RightToLeftLayout property; ToolTip; Call ReCreateSlider
> UpDown
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL
  Extra  : RightToLeftLayout property
> ProgressBar
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL
  Extra  : RightToLeftLayout property
> CommandLink
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; WS_EX_RTLREADING
  Extra  : RightToLeftLayout property
> Animation
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL
  Extra  : RightToLeftLayout property; Call ReCreateAnimation
> TreeView
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; TVS_RTLREADING
  Extra  : RightToLeftLayout property
> StatusBar
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; 0
  Extra  : RightToLeftLayout property; ToolTip; DrawPanel SetTextAlign
> TabStrip
  dwMask : RightToLeftLayout = True WS_EX_LAYOUTRTL; WS_EX_RTLREADING
  Extra  : RightToLeftLayout property; MapWindowPoints; ToolTip; Call ReCreateTabStrip
> SpinBox
  dwMask : Edit: WS_EX_RTLREADING; UpDown: 0
  Extra  : InitReverse/Reverse .Alignment; InitReverse/Reverse .TextAlignment; Remove .Orientation
> CheckBoxW
  dwMask : WS_EX_RTLREADING
  Extra  : InitReverse .Alignment; InitReverse/Reverse .TextAlignment; InitReverse/Reverse .ImageListAlignment
> CommandButtonW
  dwMask : WS_EX_RTLREADING
  Extra  : Reverse .Alignment; InitReverse/Reverse .ImageListAlignment; InitReverse/Reverse .SplitButtonAlignment
> LabelW
  dwMask : DT_RTLREADING
  Extra  : InitReverse .Alignment
> ListBoxW
  dwMask : WS_EX_RTLREADING Or WS_EX_RIGHT Or WS_EX_LEFTSCROLLBAR
  Extra  : vbListBoxCheckbox SetTextAlign
> FrameW
  dwMask : WS_EX_RTLREADING
  Extra  : InitReverse/Reverse .Alignment
> TextBoxW
  dwMask : WS_EX_RTLREADING Or WS_EX_LEFTSCROLLBAR
  Extra  : InitReverse .Alignment
> RichTextBox
  dwMask : WS_EX_RTLREADING Or WS_EX_RIGHT Or WS_EX_LEFTSCROLLBAR
  Extra  : Call ReCreateRichTextBox()
> OptionButtonW
  dwMask : WS_EX_RTLREADING
  Extra  : InitReverse .Alignment; InitReverse/Reverse .TextAlignment; InitReverse/Reverse .ImageListAlignment
```




> I think it might be because you updated OLEGuids.tlb and I'm using an old version.


Yes, just copy/paste the new OLEGuids.tlb and replace the old one.

----------


## Eduardo-

> It's a complex story. Every control has it's unique treatment.
> In general, when a RightToLeft = True then apply WS_EX_RTLREADING and if RightToLeft and RightToLeftLayout = True then apply only WS_EX_LAYOUTRTL.


I think I understand that you added the RightToLeft property to all controls that need to have a RightToLeftLayout property even if they are not displaying any text, just to standardize the controls properties and how they work.

The rule is: first set RightToLeft to True, then you are allowed to also set RightToLeftLayout to True.

Is that right?




> Yes, just copy/paste the new OLEGuids.tlb and replace the old one.


But can I have any problem if I stay using the old version of the controls with the new version of OLEGuids.tlb?

----------


## Krool

> I think I understand that you added the RightToLeft property to all controls that need to have a RightToLeftLayout property even if they are not displaying any text, just to standardize the controls properties and how they work.
> 
> The rule is: first set RightToLeft to True, then you are allowed to also set RightToLeftLayout to True.
> 
> Is that right?


Yes




> But can I have any problem if I stay using the old version of the controls with the new version of OLEGuids.tlb?


Yes you can have problems. What's the reason to only update one thing but not the other?

----------


## Eduardo-

> Yes


OK.




> Yes you can have problems. What's the reason to only update one thing but not the other?


I didn't update anything.

I just wanted to see something and for it I downloaded and opened your latest version of Common Controls project, and then I saw the error and wanted to report it.

But no, I'm not planning to change the controls in my project often unless I have a reason. I'm just using some LabelWs, ComboBoxWs and a ProgressBar in a quite straightforward manner, mainly for supporting Unicode and RightToLeft (I'm not using the OCX version but the source code, and just what I need).

What problem can I have if I ever register the new TLB? (I guess a lot of people can be in the same situation because I don't think that everybody is updating their projects to the latest version of the controls continuously, but they could eventually register the new TLB -on purpose or perhaps unintentionally)

----------


## Krool

> (I guess a lot of people can be in the same situation because I don't think that everybody is updating their projects to the latest version of the controls continuously, but they could eventually register the new TLB -on purpose or perhaps unintentionally)


It should have been perfect from the beginning. Somehow this was not possible and I am _sorry_ for the continuously updates..

----------


## Eduardo-

> It should have been perfect from the beginning. Somehow this was not possible and I am _sorry_ for the continuously updates..


Sorry, but I think you got me wrong, I was answering to the question:




> What's the reason to only update one thing but not the other?


not complaining.

I was trying to help when I reported what I thought it could be an error.

----------


## ahenry

Is Windows XP supposed to be supported?  I fired up a small XP VM and get some runtime errors with the Toolbar or maybe the related ImageList.  I'm not planning to deploy to XP, so I won't bother looking into it any further if that OS isn't supported by VBCCR16.OCX.

----------


## OldClock

Windows XP is supported.

----------


## Eduardo-

> It should have been perfect from the beginning. Somehow this was not possible and I am _sorry_ for the continuously updates..


Sorry Krool if you got offended. It wasn't my intention.
Sometimes we as programmers expect that everybody will update to the latest version, but for the users sometimes it is not so easy due to different reasons.

I want to comment that I tested updating to your latest version but I experienced an issue, so I went back to the previous one.

The issue can be seen also in your demo project.
To do so please open MainForm and go to the code in Form_Load.
Then put a stop watch in the first line (Call SetupVisualStylesFixes(Me)) by pressing F9.
Press F5 to run.
When it stops on that line, press F8 to continue step by step.

If the problem is reproduced successfully there, you'll see that the code flow goes to the line:


```
Private Function IOleControl_AddRef(ByRef This As Long) As Long
```

 in VTableHandle module and does not move further by pressing F8 more times. It only resumes by pressing F5, but then lossing the possibility to run step by step.

I also found by chance an error in your demo project: to see it click on the button "RichTextBox Demo". The test program is trying to assign a read-only property.

HTH

----------


## Krool

> I want to comment that I tested updating to your latest version but I experienced an issue, so I went back to the previous one.
> 
> The issue can be seen also in your demo project.
> To do so please open MainForm and go to the code in Form_Load.
> Then put a stop watch in the first line (Call SetupVisualStylesFixes(Me)) by pressing F9.
> Press F5 to run.
> When it stops on that line, press F8 to continue step by step.
> 
> If the problem is reproduced successfully there, you'll see that the code flow goes to the line:
> ...


_removed_




> I also found by chance an error in your demo project: to see it click on the button "RichTextBox Demo". The test program is trying to assign a read-only property.


I can't reproduce that. Please provide more details.

----------


## Eduardo-

> Going back to VTable subclass is NO option.


Is there anything dangerous/wrong with the VTable subclass approach?
(I ask because now I'm sticking to the older version that use that technique)




> 2. Go to the VTableHandlingSupported routine in VTableHandle.bas and add a InIDE() IF like below...
> 
> Of course this disables the IOleControl features during debugging.


Thank you for the tip, in case I decide to use the latest version.

What are the IOleControl features, something related to navigating with arrow keys?




> I can't reproduce that. Please provide more details.


When clicking the "Rich TextBox demo" button, it loads RichTextBoxForm and at the end of the Form_Load it is the line:



```
If Not IsNull(RichTextBox1.SelFontName) Then FontCombo1.Text = RichTextBox1.SelFontName
```

since RichTextBox1.SelFontName is not null, it tries to set "MS Sans Serif" to FontCombo1.Text, but FontCombo control's property Text is read-only. Hence it raises the error at the line:



```
Err.Raise Number:=383, Description:="Property is read-only"
```

----------


## npac4o

Hi All,

I am trying to extract icons from DLL file and add them to ImageList and then show them in ListView. The code is as follows:



```
ListView1.ListItems.Clear
ImageList1.ListImages.Clear
ImageList1.ImageHeight = 32
ImageList1.ImageWidth = 32
ImageList1.ColorDepth = ImlColorDepth24Bit


For i = 0 To UBound(arrSomething)
            Picture1.Cls
            Picture1.Picture = GetIconFromFile(arrSomething(i).IconPath, True) ' Yep, the extracted icon is correct

            ImageList1.ListImages.Add i+1 , , GetIconFromFile(arrSomething(i).IconPath, True) '<- this function return large icon as StdPicture
          ' ImageList1.ListImages.Add i+1 , , Picture1.Picture ' Just for testing - works but randomly

          ' Picture1.Picture = ImageList1.ListImages(i + 1).ExtractIcon ' This works always

            With ListView1.ListItems.Add(, , arrSomething(i).Name, i+1) 
                    ....
            End With
Next i
```

It works...randomly - sometimes I have all the icons, sometimes not; after a listview refresh, sometimes they disappear; after a few refreshes, they come back again eventually. Picture1 always receives the icon, no matter if it's from the function or from the ImageList.

Am I doing something wrong or it's a bug in the ListView?!

Thank you.

----------


## Krool

Update released.

Improvement (cosmetic, not a bug) in VTableHandle.bas so that IOleControl do not disturb anymore in IDE on debugging.
Setting breakpoints (F9, F8 etc.). This cosmetic issue only affected the Std-EXE version and NOT the OCX.




> I want to comment that I tested updating to your latest version but I experienced an issue, so I went back to the previous one.
> 
> The issue can be seen also in your demo project.
> To do so please open MainForm and go to the code in Form_Load.
> Then put a stop watch in the first line (Call SetupVisualStylesFixes(Me)) by pressing F9.
> Press F5 to run.
> When it stops on that line, press F8 to continue step by step.
> 
> If the problem is reproduced successfully there, you'll see that the code flow goes to the line:
> ...


You know what? This issue is resolved.  :Smilie:  It was easier than I thought and pretty straight forward solution.
So, there is nothing issue for you to update everything to the latest version.




> Is there anything dangerous/wrong with the VTable subclass approach?
> (I ask because now I'm sticking to the older version that use that technique)


I described this in post #2472




> Thank you for the tip, in case I decide to use the latest version.
> 
> What are the IOleControl features, something related to navigating with arrow keys?


Just ignore the tip, as it's resolved. I deleted the tip to avoid confusion.




> When clicking the "Rich TextBox demo" button, it loads RichTextBoxForm and at the end of the Form_Load it is the line:
> 
> 
> 
> ```
> If Not IsNull(RichTextBox1.SelFontName) Then FontCombo1.Text = RichTextBox1.SelFontName
> ```
> 
> since RichTextBox1.SelFontName is not null, it tries to set "MS Sans Serif" to FontCombo1.Text, but FontCombo control's property Text is read-only. Hence it raises the error at the line:
> ...


In fact the FontCombo.Text is not always read-only. It's only when there is no match in the list.
This behavior is the same as in the VB.ComboBox.

Here is a portion of the Text property in FontCombo:


```
Case FtcStyleDropDownList
    If FontComboHandle <> 0 And FontComboDesignMode = False Then
        Dim Index As Long
        Index = SendMessage(FontComboHandle, CB_FINDSTRINGEXACT, -1, ByVal StrPtr(Value))
        If Not Index = CB_ERR Then
            Me.ListIndex = Index
        Else
            Err.Raise Number:=383, Description:="Property is read-only"
        End If
    Else
        Exit Property
    End If
```

As you see, it's only read-only when CB_FINDSTRINGEXACT returns CB_ERR. So in other words, "MS Sans Serif" is missing in your FontCombo1 list.
I don't have the issue because in my FontCombo1 "MS Sans Serif" is contained.
Can you please check which fonts are in your list and if "MS Sans Serif" is missing?

----------


## Eduardo-

> You know what? This issue is resolved.  It was easier than I thought and pretty straight forward solution.
> So, there is nothing issue for you to update everything to the latest version.


Great!, thank you very much Krool  :Thumb: 




> In fact the FontCombo.Text is not always read-only. It's only when there is no match in the list...
> 
> Can you please check which fonts are in your list and if "MS Sans Serif" is missing?


MS Sans Serif is not on the list of the FontCombo control, but it is on the font list of other programs such as Notepad.

I'll try to investigate the code to find the cause why it is skipped, but I'll do it later.
I'll update this post then. (*)
(I think that font is a type of font that is not vector based, that might be the cause -just a guess-)

** Update:* I found that the cause was that I have Windows configured as the language for non Unicode programs to Hebrew (because I'm working with some right-to-left issues in my program).
As soon as I changed the Language back to Spanish, the MS Sans Serif font got listed on the control.

Studing the code, I found that while Windows is configured to display Hebrew, the EnumFontFamiliesEx API does not list the MS Sans Serif font. But other programs list it and it is available on the system.

----------


## ahenry

> Is Windows XP supposed to be supported?  I fired up a small XP VM and get some runtime errors with the Toolbar or maybe the related ImageList.  I'm not planning to deploy to XP, so I won't bother looking into it any further if that OS isn't supported by VBCCR16.OCX.


It turned out my issue was with 32-bit pictures.  VBCCR16 was failing with runtime error 50003 when I tried to open the form, but when I tried to load 32-bit images in a clean project, I got an "invalid picture format" error.  Not a big deal; I don't need XP to work anyhow.

----------


## wmdong

krool,nice job,I am trying to get Msgbox text,But get null,thank you!
Private Sub CommandButtonW1_Click()
kkk
End Sub
Private Function kkk() As Long
    Dim Result As Long
    Dim strErrMsg As String
    Dim intOldMousePointer As Long

    On Error GoTo errHandler

        intOldMousePointer = Screen.MousePointer
        Screen.MousePointer = vbHourglass
        Result = -1
        If Result = -1 Then
            Err.Description = "this is test"
            GoTo errHandler:
        End If
errHandler:
   Screen.MousePointer = intOldMousePointer
   strErrMsg = Err.Description

    On Error Resume Next

    MsgBox strErrMsg
End Function

----------


## Arnoutdv

You raise an error by calling err.raise and specifying the error number.
Nothing to do with Krools Common Controls

----------


## wmdong

> You raise an error by calling err.raise and specifying the error number.
> Nothing to do with Krools Common Controls


thanks Arnoutdv 
add code: debug.print strErrMsg,the strErrMsg is null(use vbcc CommandButtonW)
add code: debug.print strErrMsg,the strErrMsg is "this is test"(use vb CommandButton)

I get the reason,"Screen.MousePointer = intOldMousePointer",it created some mouse messages，and WindowProcControl received the mouse messages。I have solved the problem(use SetCapture、ReleaseCapture)。

----------


## darjeeling

Hi Krool

Please how to change the Statusbar Backcolor property ?

----------


## Eduardo-

> how to change the Statusbar Backcolor property ?


First set VisualStyles to False and then set the BackColor.

----------


## darjeeling

Hi Eduardo
Yes this works but the SizeGrip Backcolor remain unchanged !

----------


## Eduardo-

> Hi Eduardo
> Yes this works but the SizeGrip Backcolor remain unchanged !


If you need only the SizeGrip and not the whole StatusBar, you can use this control.

----------


## sbri

Krool,
a little difference between ComboBoxW and the standard control: you can not perform ".Additem vbNullString", it raises a strange error.
It's not a problem, to solve it is enough to use an empty string (""), I just want to let you know.

----------


## Krool

> Yes this works but the SizeGrip Backcolor remain unchanged !


Like Eduardo suggested. You can use a special "SizeGrip UserControl".

I also posted a SizeGrip control here in the forum long time ago which draws on comctl32.dll (either themed or not, depending on manifest) and contrary to Eduardo's solution does not depend on static images.

My control was updated now to include a BackColor property. (SizeGrip; see link above)




> a little difference between ComboBoxW and the standard control: you can not perform ".Additem vbNullString", it raises a strange error.
> It's not a problem, to solve it is enough to use an empty string (""), I just want to let you know.


Good point. I was not aware that CB_ADDSTRING or CB_INSERTSTRING returns CB_ERR when the string pointer is 0..

However, I added following check now inside the AddItem method to avoid such a situation in the ComboBoxW. (update released)


```
Public Sub AddItem(ByVal Item As String, Optional ByVal Index As Variant)
[...]
If StrPtr(Item) = 0 Then Item = ""
```

----------


## Hosam AL Dein

Hi Krool , 

*1-* In previous posts here , there was a discussion about who is responsible for calling the SetupVisualStyles method and you said that it is the EXE`s responsibility not the ocx . But there is a question here , What about the controls created at runtime ? . I the have to recall the sub again after loading them . This seems normal in simple cases (low repetitive calls , not many controls , the loaded controls are in a form .. etc) . But there are some other cases where calling this method is tricky and overhead like if there are too many controls(loaded in runtime) or when calling this sub for many times depending on the control load logic and behavior in the code and also when these newly created controls are in a nested user control or non-nested one . All the previous cases have a workaround and can be done . But just a thought if it can be handled or being re-thought about this case .

*2-* In Dtpicker , while formatted for time and the digits are displayed in Arabic with SegeoUI font , the hours panel is not fully displayed . When the hours are represented in two digits like 12 or 13 etc , the digit 1 is not at all visible . If for example the hour is 23 , the digit 2 is partially visible and so on .This happens only in digits in Arabic format . So , The area for the hours panel is not drawing correctly in this case .

*3-* About TextBoxW Balloon Tips , It only shows the balloon for the last textbox . Can this be solved ? . I know this is because it should hide when the text box loses the focus and this is the case when showing these tips . 
If it can be handled without changing focus or capture state it will be nice because it also has some disadvantages . The first one is mentioned above : is that the they can not be shown simultinously .And also , they force the text box to fire both LostFocus and GotFocus events too many times which adds overhead especially when these events contain some code (Like in my case)  . 

I used debug.print in both LostFocus and GotFocus events for the TextBox when showing the balloon tip and the result was as following :

exit
enter
enter
exit
enter
exit

Besides overhead , There is something which is more dangerous that is firing SetFocus event two times one after another which can not happen in normal behavior. Most of code that is placed in gotfocus event is sometimes related to lostfocus event as it is always expected that when  gotfocus event is fired , it will never be fired again until it loses the focus .This double call caused a lot of problems in my case and I have just figured out the reason . So , If it is possible for balloon tips to implemented without dealing with setting and releasing the capture , it will add many advantages (Showing many ones at the same time - reducing overhead - solving the double calls for set capture - saving performance by eliminating multiple calls for LostFocus and GotFocus events too many times ) .

Thanks a lot for you effort .

----------


## OldClock

Is anyone else experiencing the problem that text inside TextBoxW with alignment set to vbCenter does not get centered?



```
TextBoxW1.Text = "this should be centered"
TextBoxW1.Alignment = vbCenter
```

----------


## ahenry

Works for me in Windows 10.  Checked running in the IDE and design mode with the OCX version.

----------


## OldClock

Windows XP, Home Edition, SP3, version 2002.

Using VBCCR16.OCX 1.06.0061 3af959d

----------


## Krool

Update released.

I noticed in a new form-less application that CommonDialog.ShowPrinterEx was not working and raised the error "The PrintDlgEx function failed during initialization." with the error value E_HANDLE.

The CommonDialog.ShowPrinter was not affected.

It turns out that the PrintDlg API can deal without owner window whereas on PrintDlgEx the owner window member value cannot be NULL. It returns E_HANDLE when it's NULL.

The internal function to get the owner window in CommonDialog is as following:


```
Private Function GetOwnerWindow() As Long
Dim hWnd As Long, hWndMDIClient As Long
hWnd = GetActiveWindow()
If hWnd <> 0 Then hWndMDIClient = FindWindowEx(hWnd, 0, StrPtr("MDIClient"), 0)
If hWndMDIClient <> 0 Then
    Const WM_MDIGETACTIVE As Long = &H229
    GetOwnerWindow = SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, ByVal 0&)
Else
    GetOwnerWindow = hWnd
End If
End Function
```

So in a form-less application GetOwnerWindow() is NULL.
As the other common dialog boxes accepts a NULL value and only PrintDlgEx being an exception I keep GetOwnerWindow() unchanged and do a workaround in the ShowPrinterEx function only, as following: (code in blue is new, added)


```
.hWndOwner = GetOwnerWindow()
If .hWndOwner = 0 Then
    ' According to MSDN:
    ' This member must be a valid window handle; it cannot be NULL.
    ' The PrintDlgEx function will return E_HANDLE when this member was NULL.
    .hWndOwner = GetDesktopWindow()
End If
```

Also, which I was not aware of, is that .ShowPrinter (PrintDlg) looks different in a form-less app than in a normal form app. (difference being owner window NULL or not)

PrintDlg (Valid owner window)


PrintDlg (Owner window NULL)

----------


## quickbbbb

hi   Krool

Whether next version can support the following 

http://www.vbforums.com/showthread.p...oplist-problem

----------


## yereverluvinuncleber

Krool,

I too have a request. Hopefully it isn't too much work. VB6 provides a horizontal and vertical scrollbar for dropping onto your form, however, they don't seem to respond to mouse scroll wheel movement natively. 

My form has your treeview and slider controls, both of which respond to mouse scrollwheel movement (a quick aside - when the treeview's contents extend in x/y beyond the control's boundaries, your treeview only responds to vertical scrolls even when the horizontal scrollwheel has the focus, same as .NET). Regardless of any perceived inconsistency there, that is all well and good for me. I am very impressed by the treeview control.

My form also uses the VB6 native file listbox which strangely already responds to mouse scrollwheel events. Even better.



The trouble is that I also have a pseudo-thumbnail view and use both a horizontal and vertical scroll bar, one to navigate through my icons in that thumbnail view and the other horizontal one, to scroll an icon map. Neither of these two standard VB6 scrollbars respond to mouse scroll wheel movement and as a result these controls are inconsistent with the rest of the form.



My VB.NET version, of course handles all mouse scroll wheel movements as the user would expect but I prefer the VB6 version and I want it to operate as well as the VB.NET does.

So, my request is: Can you please create the vertical/horizontal scrollbar controls and add them to your collection?  I think it would be a useful addition, certainly for me.

We could call them SKroolbars...

----------


## dseaman

> your treeview only responds to vertical scrolls even when the horizontal scrollwheel has the focus, same as .NET).


How about updating Horizontal Scrollbar via MouseWheel when Kybd Shift is pressed.
That is how it works on Web Scrollbars.

See ucScrollbar control where Kybd Shift has been implemented for Horizontal Scrollbar.
http://www.vbforums.com/showthread.p...=1#post5437197

----------


## yereverluvinuncleber

> How about updating Horizontal Scrollbar via MouseWheel when Kybd Shift is pressed.
> That is how it works on Web Scrollbars.
> 
> See ucScrollbar control where Kybd Shift has been implemented for Horizontal Scrollbar.
> http://www.vbforums.com/showthread.p...=1#post5437197


I could do that but I prefer scrollbars to operate as they should and just as they do in other apps and also how they operate in the .NET version of the same application.  

Also, bearing in mind what I said in my request, that the other scrollbars are all functioning just as they ought. It is just these two native scrollbars that do not. It would be logically more sensible to fix the two bars that aren't functioning as expected, rather than have to work on all those that are working correctly in order to make them operate differently and counter-intuitively to most user expectations.

----------


## Eduardo-

Hello Krool, I want to ask you what is the purpose of your MsgBox overwrite function:



```
' (VB-Overwrite)
Public Function MsgBox(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title As String) As VbMsgBoxResult
```

Thank you.

----------


## Krool

> Hello Krool, I want to ask you what is the purpose of your MsgBox overwrite function:
> 
> 
> 
> ```
> ' (VB-Overwrite)
> Public Function MsgBox(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title As String) As VbMsgBoxResult
> ```
> 
> Thank you.


The purpose is one word: "Unicode"

----------


## MountainMan

It is Unicode.

----------


## Eduardo-

> The purpose is one word: "Unicode"


Ah, OK, thank you.

----------


## dseaman

If you sort your controls alphanumeric in the Vbp file they will appear sorted in the ToolBox.
Actually, I usually sort the entire block containing Modules/Classes/Controls/PropertyPages to make the Vbp more readable.

----------


## OldClock

Is it possible to make a list (listview?) where a row spans multiple lines, possibly using different formatting for some elements?

An example:


Note that the second row is selected, and the name is in bold.

----------


## Semke

> Is it possible to make a list (listview?) where a row spans multiple lines, possibly using different formatting for some elements?
> 
> An example:
> 
> 
> Note that the second row is selected, and the name is in bold.


this is where ownerdraw come into play
on the listbox (and some other controls) there is a DrawMode property and corresponding events.
although I can not see these on the listview control, maybe krool will decide to add it at some point.
you could still use the windows api to do it

----------


## Semke

> Hello Krool, I want to ask you what is the purpose of your MsgBox overwrite function:
> 
> 
> 
> ```
> ' (VB-Overwrite)
> Public Function MsgBox(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title As String) As VbMsgBoxResult
> ```
> 
> Thank you.


is this available in the ocx version?

----------


## Krool

> is this available in the ocx version?


Is that a real question?

This thread should not answer each beginner's question...

----------


## Eduardo-

Replacing the intrinsic VB functions form the OCX would be possible using ASM code.

----------


## Semke

> Is that a real question?
> 
> This thread should not answer each beginner's question...


looks like you misunderstood the question.

I know I can create the function (Unicode), but the one you created is not exposed in the ocx version.

I have been working with visual basic since its first version and I am far from being a beginner.

----------


## Darkbob

Last time I tried it the sample wouldn't load.  I don't think they are really trying to make something people can use.  Just tech types having fun I think.

----------


## yereverluvinuncleber

> Last time I tried it the sample wouldn't load.  I don't think they are really trying to make something people can use.  Just tech types having fun I think.


I don't think you are correct there old chum. You may need some guidance on getting it to work for you but your current attitude is akin to going to the doctor once and saying, "I tried some medicine once and it didn't work. I don't think they are really trying to make people better. Just medico types trying to look important I think."

----------


## Darkbob

> I don't think you are correct there old chum. You may need some guidance on getting it to work for you but your current attitude is akin to going to the doctor once and saying, "I tried some medicine once and it didn't work. I don't think they are really trying to make people better. Just medico types trying to look important I think."


The demo still doesn't run.  Not saying it's impossible to get it to run.  But normally you run a demo - it doesn't work - you give up and move on.  I asked about it, googled, tried a few things - more than most people would ever bother doing - and it still doesn't run.  So for sure it's a terrible demo that makes the entire project look bad.  And it's still in the first link here.  If people are serious about a project they make sure the demo works.  If they are just tech types having fun then they don't care.  I get the feeling that's the case here.

I'll show you what people see when they run this project...



I think I found the problem here:



So you do some digging, find the missing file (it's actually hidden inside the demo if you know where to look)... you fix that problem and you are still no further ahead because of THIS issue... 



Long before this point most people would just give up.  As I said.. not really a criticism... just an observation.  But this isn't a project where the author is trying to make something useful for most VB programmers.  He's having fun doing something he enjoys.  Great for him.  Unfortunately a potentially great and useful project is ruined by a non functional demo.

Out of curiosity.. what the heck is "a manifest specifying comctl32.dll version 6.0 or higher" and where would a person get one?  

I found the VBCCR OCX in another thread and registered it and loaded it up to test.  Some of the controls do work but about half of them say something like:

"The linkLabel control requires at least version 6.0 of comctl32.dll".  

I have the version from SP6 so shouldn't it be the right version?  And isn't the entire point of this project to get away from comctl32?  



And then the project wants me to make a manifest for VB6... * sigh *  Time to give up again.  But as I said last time, it's an interesting project.  Hopefully some day somebody can get the demo to work right.

----------


## Krool

> The demo still doesn't run.  Not saying it's impossible to get it to run.  But normally you run a demo - it doesn't work - you give up and move on.  I asked about it, googled, tried a few things - more than most people would ever bother doing - and it still doesn't run.  So for sure it's a terrible demo that makes the entire project look bad.  And it's still in the first link here.  If people are serious about a project they make sure the demo works.  If they are just tech types having fun then they don't care.  I get the feeling that's the case here.
> 
> I'll show you what people see when they run this project...
> 
> 
> 
> I think I found the problem here:
> 
> 
> ...


It's modern nowadays to give up immediately on first problems instead to read the notes or make some research?

If youwould read the notes in the first thread you would know to make following setting;

Goto menu Tools -> Options... -> General -> Error Trapping.
"Break on Unhandled Errors" should be selected instead of "Break in Class Module".

This is some odd default setting of VB6 whichI can't do something about. However, it's s one-time change in settings and then OK for the end of life of that installation.

Now the demo runs.

About the rest make some google research about manifesting and theming.
It's optional, when you don't want full features you not need to manifest. It's not my restriction. It's windows.

comctl32.dll is a windows system file, and not an MS OCX. The .dll is part of the core and always pre-installed.

Please don't post such statements with "half knowledge".
If it's too overwhelming for you just move on.




> I know I can create the function (Unicode), but the one you created is not exposed in the ocx version.


It's the responsibility of the >>EXE<< to make such things. It would be ridicolous if an OCX overwrites VB functions without any control and with ASM hacks..

----------


## Darkbob

> If youwould read the notes in the first thread you would know to make following setting;
> 
> Goto menu Tools -> Options... -> General -> Error Trapping.
> "Break on Unhandled Errors" should be selected instead of "Break in Class Module".


Well... that did change things.  Now the whole IDE just closes and exits without any error message.  But the demo still doesn't run.  

Just to make sure it wasn't just this new laptop I'm having troubles with I downloaded the demo and ran it on another computer.  Identical result.  Press Run and * poof * the IDE closes and exits.  No error message.  Just gone.

Best of luck on what looks like a very powerful project with a lot of potential.  I'll be sure to keep an eye on this thread and see what happens in future.

----------


## Eduardo-

> It's the responsibility of the >>EXE<< to make such things. It would be ridicolous if an OCX overwrites VB functions without any control and with ASM hacks..


What do you mean "without any control"?

It works very well indeed.

BTW: I updated the sample

----------


## Krool

> What do you mean "without any control"?
> 
> It works very well indeed.
> 
> BTW: I updated the sample


It's NOT the job of the OCX to do that.

*Reapeating*: It's the EXE responsibility to change fancy things.




> Well... that did change things.  Now the whole IDE just closes and exits without any error message.  But the demo still doesn't run.  
> 
> Just to make sure it wasn't just this new laptop I'm having troubles with I downloaded the demo and ran it on another computer.  Identical result.  Press Run and * poof * the IDE closes and exits.  No error message.  Just gone.
> 
> Best of luck on what looks like a very powerful project with a lot of potential.  I'll be sure to keep an eye on this thread and see what happens in future.


Ok. Bye.

----------


## Eduardo-

> It's NOT the job of the OCX to do that.


It is your component, you do whatever you want.

But you cannot state it as a general rule, because it can be done and it works without problem.




> *Reapeating*: It's the EXE responsibility to change fancy things.


Again, it is your opinion, your project, your decision.
I thought it could be a good idea to offer that possibility, since your project mainly seems to be intended to upgrade VB6 bringing Unicode support to it (and other things), and leaving those intrinsic VB Functions in their ANSI version somewhat undermines the goal.
I think for that reason you added them to the exe version.

But if you are afraid that it could cause any problem, I understand.
Or whatever reason that you have to think so.
I just suggested it as a possibility, nothing more.
I realize that you don't like contributions (or opinions). 
OK, no problem.

----------


## Hosam AL Dein

> Last time I tried it the sample wouldn't load.  I don't think they are really trying to make something people can use.  Just tech types having fun I think.


Try this . Add this manifest to your VB6.exe . I used _ResourceHacker_ to update it .



```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
      <application> 
        <!--This Id value indicates the application supports Windows Vista functionality -->
          <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
        <!--This Id value indicates the application supports Windows 7 functionality-->
          <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
        <!--This Id value indicates the application supports Windows 8 functionality-->
          <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
        <!--This Id value indicates the application supports Windows 8.1 functionality-->
          <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      </application> 
  </compatibility>
  <assemblyIdentity type="win32" 
                    name="myOrganization.myDivision.mySampleApp" 
                    version="6.0.0.0" 
                    processorArchitecture="x86" 
                    publicKeyToken="0000000000000000"
  />
  <dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
  </dependency>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
        <dpiAware  xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>  
</assembly>
```

I am using the OCX version , and I always combine the following files to the project > Most of them are oriented to visual styles issue .
1- VisualStyles.bas
2- Common.bas
3- Resource file and following is its content :



```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
      <application> 
        <!--This Id value indicates the application supports Windows 8 functionality-->
          <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
      </application> 
  </compatibility>
  <assemblyIdentity type="win32" 
                    name="myOrganization.myDivision.mySampleApp" 
                    version="6.0.0.0" 
                    processorArchitecture="x86" 
                    publicKeyToken="0000000000000000"
  />
  <dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
  </dependency>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
        <dpiAware  xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>  
</assembly>
```

4- In each form_load event , add this line


```
SetupVisualStyles Me
```

----------


## Darkbob

> Try this . Add this manifest to your VB6.exe . I used _ResourceHacker_ to update it .
> 
> ... 
> 
> I am using the OCX version , and I always combine the following files to the project > Most of them are oriented to visual styles issue .
> 1- VisualStyles.bas
> 2- Common.bas
> 3- Resource file and following is its content :


First, thanks very much for your suggestions.  Very helpful.  I realize it's not your job to spoon feed me so I'll try to figure out how to add a manifest to VB6.  Last time I tried... it didn't end well.  But I'm up for another try.  But any idea where a person would find VisualStyles.bas and Common.bas?

----------


## Hosam AL Dein

Don`t mention it .



> But any idea where a person would find VisualStyles.bas and Common.bas?


 . Download the demo found in the first page of this thread . You will find them in the _Common_ folder . 

Now you have the most recent version of VBCCR controls . The function _SetupVisualStyles_ I mentioned above is updated to _SetupVisualStylesFixes_ . (I have not yet upgraded to the latest version therefore I wrote the name I am still using) . See this post http://www.vbforums.com/showthread.p...=1#post5444619 .

About Manifesting VB6 Exe , Download _ResourceHacker_ . File > Open .. Browse for VB6.Exe > Open the _Manifest_  node > delete all text > Paste the text provided above > Press the green arrow button _Compile Script_ Then save it > Replace the old VB6.exe with this one . That`s it .

Keep your old VB6.Exe in the same directory with another name in case of any failure . If you encountered permission error saving the new exe in this location , then save it in any other location then copy>paste it manually . Start IDE , you will notice that it is themed (If everything is ok) . One clear sign for that is you will not find any colors in the palette tab while setting the back color  - (or any property dealing with colors) - property of any control from properties window .

----------


## Eduardo-

There is a bug in the LabelW control in the DoAutoSize procedure.

The line:


```
.Extender.Move .Extender.Left, .Extender.Top, .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
```

Should be changed to:


```
If PropWordWrap = True Then
    .Extender.Move .Extender.Left, .Extender.Top, .Extender.Width, .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
Else
    .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
End If
```

----------


## Darkbob

> About Manifesting VB6 Exe , Download _ResourceHacker_ . File > Open .. Browse for VB6.Exe > Open the _Manifest_  node >


Humm... No manifest node...  Any ideas?

----------


## Hosam AL Dein

Sorry , I produced the steps above by opening a manifested exe while in your case it is not . So , yes , you will not find this node as your exe is still not manifested yet .

Anyway , 
_Action_ > _Add from blank script_ > ((then a clean window opens - paste the manifest text in there )) > Compile green button > Save

----------


## wqweto

You don’t have to embed the manifest (I would advise against modifying vb6.exe in any way). Just place the .manifest file next to the .exe file and restart the OS. The last step is required for the manifest cache to be cleared and is usually not heeded and then someone declares in the forums external manifest is not working.

You can clear the manifest cache for vb6.exe by changing its last modified date with touch.exe utility or similar too.

----------


## Eduardo-

> You dont have to embed the manifest (I would advise against modifying vb6.exe in any way).


Why?

----------


## Darkbob

> _Action_ > _Add from blank script_ > ((then a clean window opens - paste the manifest text in there )) > Compile green button > Save


Ah!  Well.. that seems to work.  But just a question... what does this all do?

In my case I did notice the IDE showed a few minor changes to bold text but not much else.  

The only thing I noticed on my own existing VB project was that the background color for the drop-down combo box changed from green to light grey.  Not sure why that would happen.

Is there some benefit I'm not seeing?  Or does the benefit only happen when you start using the replacement controls?

----------


## Darkbob

OMG it works.  The demo actually works!!!  Hosan Al Dein showed the way with his brilliant post about adding a manifest into the VB6.EXE file... and presto.  The demo finally works!  Might be an idea to edit post #1 and add this info.  Now I can finally see what you guys are talking about.

----------


## wqweto

> Why?


Because it's not needed. Why would I want to modify the compiler just to run the IDE manifested if I don't have to?

Of course vb6.exe is not digitally signed nor is it a protected OS file so there are no "defenses" against corrupting it yourself at will.

Why does Resource Hacker always create a backup file next to the modified executable? Obviously fiddling w/ PE files this is not as reliable as adding/removing "resources" to a .zip file -- never seen 7-zip creating backup files when modifying an archive.

cheers,
</wqw>

----------


## dseaman

Several years ago I used an embedded Vb6.exe Manifest until I managed to corrupt Vb6 after a fresh install of Windows.
Since then I always use an external Manifest "Vb6.exe.manifest".
I did have to make a registry change so that it is recognized.

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide
Value(REG_DWORD): PreferExternalManifest
Data: 1 = prefer, 0 = don't prefer

----------


## Elroy

--

*A .Refresh on the status bar wipes out the text.  That doesn't seem correct.*

I'm just using it as a single StatusBar, and using the SimpleText property.

I'm also using the source code version, and just including it in my project.

Here's the code I originally had:



```

Public Sub UndoChanges()
    ' Careful, FilePath and FileName shouldn't be undone.
    '


    If miUndoCount = 0& Then
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus "There are no remaining undo points."
        Exit Sub
    End If
    '




End Sub




Public Sub SetStatus(sText As String):
    StatusBar.SimpleText = " " & sText
    StatusBar.Refresh
End Sub


```


I just wanted it to blink a bit.

If I comment out the *StatusBar.Refresh* line, the text doesn't get cleared, but I don't get my blink.

-----

Actually, I was hoping for a .ForeColor (or maybe .FontColor), so I could blink it red, but that wasn't an easy option.

But I suspect, even with that, I'd still have a problem making it blink, which I want.

--------

EDIT1:  Ok, I was being a bit dense.  I needed something like the following to get my blink.  



```

    If miUndoCount = 0& Then
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus vbNullString
        Sleep 200
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus vbNullString
        Sleep 200
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus vbNullString
        Sleep 200
        SetStatus "There are no remaining undo points."
        Sleep 200
        SetStatus vbNullString
        Sleep 200
        SetStatus "There are no remaining undo points."
        Exit Sub
    End If


```

And that actually worked, blink and all.

I think my question still stands though.  A .Refresh is suppose to clear the text?

----------


## wqweto

> I did have to make a registry change so that it is recognized.


My point exactly: *this* is the kind of cargo-culting in this thread that my duty called. . .



No need to change this reg key. Just create the the vb6.exe.manifest and then restart the OS :-))

cheers,
</wqw>

----------


## Krool

> Actually, I was hoping for a .ForeColor (or maybe .FontColor), so I could blink it red, but that wasn't an easy option.
> 
> I think my question still stands though.  A .Refresh is suppose to clear the text?


When using .Style = Normal you can use the .Panels(Index).ForeColor property.

A .Refresh should erase the text? I can't replicate such thing.




> There is a bug in the LabelW control in the DoAutoSize procedure.


Thanks, your right. Update released.




> OMG it works.  The demo actually works!!!  Hosan Al Dein showed the way with his brilliant post about adding a manifest into the VB6.EXE file... and presto.  The demo finally works!  Might be an idea to edit post #1 and add this info.  Now I can finally see what you guys are talking about.


The demo should also works without manifest. At least it does for me.

----------


## Eduardo-

> Because it's not needed. Why would I want to modify the compiler just to run the IDE manifested if I don't have to?
> 
> Of course vb6.exe is not digitally signed nor is it a protected OS file so there are no "defenses" against corrupting it yourself at will.
> 
> Why does Resource Hacker always create a backup file next to the modified executable? Obviously fiddling w/ PE files this is not as reliable as adding/removing "resources" to a .zip file -- never seen 7-zip creating backup files when modifying an archive.
> 
> cheers,
> </wqw>


OK, I just asked to know if there was an issue I wasn't aware about.

----------


## Hosam AL Dein

> OMG it works.  The demo actually works!!!  Hosan Al Dein showed the way with his brilliant post about adding a manifest into the VB6.EXE file... and presto.  The demo finally works!  Might be an idea to edit post #1 and add this info.  Now I can finally see what you guys are talking about.


Really glad to help , Darkbob .




> Is there some benefit I'm not seeing? Or does the benefit only happen when you start using the replacement controls?


The benefit is you can see visual styles applied to the controls in design time . So , As Krool mentioned , you can still ignore this option and you will see visual styles applied after you compile your project (not in design time) if you did one of the following : 1 - you have a manifest embedded in your resource file 2 - you provide external manifest to your exe .

This is a general rule that has nothing to do with VBCCR controls . But why is it around here in VBCCR ? because VBCCR support visual styles . So , we add this manifest to see this effect . Adding manifest to vb6.exe or your exe  is optional unless you use some VBCCR features which require a manifest that supports Common Controls 6 or higher .

So to conclude , Manifests do many things . One of them is to provide visual styles ability . 
You can use them externally by adding the manifest text in an external file with the same name as your exe and with .Manifest extension and some tweaks in your OS . Or you can use them embedded in your exe like what you have done in your vb6.exe . 

Why did we add a resource file to the project ? Because we need this manifest to be compiled with the exe . 

I hope I could make it clear for you as English is not my first language . Have a nice day .

*Edit 1:*
Some posts are ignored in my reply .
*Edit 2:*
This post does not answer the question that you may ask : Why did this manifest solved the problem if its only purpose in this project is to see visual styles effects in design time ? 
I can guess an answer but still not pretty sure about it .

----------


## Krool

> There is a bug in the LabelW control in the DoAutoSize procedure.
> 
> The line:
> 
> 
> ```
> .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
> ```
> 
> ...


Hi Eduardo,

I updated yesterday your suggested bugfix. However, I think the behavior is now not really correct.

E.g. make a LabelW1.Caption = "test" with a Width of 255 and WordWrap = True and AutoSize = True.
Now change the Caption to "test_added". The VB.Label autosize the width while now the LabelW doesn't.

My proposed solution would be:


```
If PropWordWrap = True Then
    .Extender.Height = .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
    If .ScaleWidth < ((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2)) Then .Extender.Width = .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize)
Else
    .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
End If
```

Can you confirm before I update another bugfix?

----------


## Eduardo-

> Hi Eduardo,
> 
> I updated yesterday your suggested bugfix. However, I think the behavior is now not really correct.
> 
> E.g. make a LabelW1.Caption = "test" with a Width of 255 and WordWrap = True and AutoSize = True.
> Now change the Caption to "test_added". The VB.Label autosize the width while now the LabelW doesn't.
> 
> My proposed solution would be:
> 
> ...


Yes, you are right. When its width is smaller than any of the individual words, it extends the width to that.
I performed some testing with your new code and it seems to make it work as the original.

----------


## Krool

Update released.

Thanks Eduardo.

I fiddled also now again a while with the LabelW AutoSize in comparison to VB.Label with the WordWrap and my previously suggested version works in all scenarios. (slightly modified to cause only 1 resize)


```
If PropWordWrap = True Then
    If .ScaleWidth < ((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2)) Then
        .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
    Else
        .Extender.Height = .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
    End If
Else
    .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((CalcRect.Right - CalcRect.Left) + (BorderWidth * 2), vbPixels, vbContainerSize), .ScaleY((CalcRect.Bottom - CalcRect.Top) + (BorderHeight * 2), vbPixels, vbContainerSize)
End If
```

----------


## Eduardo-

:Thumb:

----------


## travma

Latest ComCtlsDemo.zip of 20/20/2020 can't start (F5 or Ctrl-F5) and throws the error "To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher." Note that I have the themes service on XP machine disable because I don't use any theme. How to add the manifest in the project to be able to step through?
Although It makes the exe form the make File->Make ComCtlsDemo.exe and all the controls appear to work the RichTextBox Demo button just ends (or crash) the executable without any clue. The OLEGuids are in system32.

----------


## Krool

> Latest ComCtlsDemo.zip of 20/20/2020 can't start (F5 or Ctrl-F5) and throws the error "To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher." Note that I have the themes service on XP machine disable because I don't use any theme. How to add the manifest in the project to be able to step through?
> Although It makes the exe form the make File->Make ComCtlsDemo.exe and all the controls appear to work the RichTextBox Demo button just ends (or crash) the executable without any clue. The OLEGuids are in system32.


If youwould read the notes in the first thread you would know to make following setting;

Goto menu Tools -> Options... -> General -> Error Trapping.
"Break on Unhandled Errors" should be selected instead of "Break in Class Module".

This is some odd default setting of VB6 which I can't do something about. However, it's a one-time change in settings and then OK for the end of life of that installation.

----------


## Darkbob

> I hope I could make it clear for you as English is not my first language


Your post was far clearer than any of the other posts from the experts.  I think you speak well in my native tongue - nOOb!  :Smilie: 

Thanks very much again for your help!

----------


## Darkbob

> Latest ComCtlsDemo.zip of 20/20/2020 can't start (F5 or Ctrl-F5) and throws the error "To use this functionality, you must provide a manifest specifying comctl32.dll version 6.0 or higher." Note that I have the themes service on XP machine disable because I don't use any theme. How to add the manifest in the project to be able to step through?
> Although It makes the exe form the make File->Make ComCtlsDemo.exe and all the controls appear to work the RichTextBox Demo button just ends (or crash) the executable without any clue. The OLEGuids are in system32.


You ran into the same problem I found.  The demo simply doesn't work.  But don't give up - it's a great project and you CAN make it run.  There are a bunch of steps you need to take to get it working but the most important is to put a manifest right inside the VB6.EXE.  You would think they would maybe mention that somewhere in bold letters in the first post wouldn't you?  The details are buried deep in this thread if you dig hard enough.  Take a look at posts on Page 64 by Hosam AL Dein.

----------


## travma

> You ran into the same problem I found.  The demo simply doesn't work.  But don't give up - it's a great project and you CAN make it run.  There are a bunch of steps you need to take to get it working but the most important is to put a manifest right inside the VB6.EXE.  You would think they would maybe mention that somewhere in bold letters in the first post wouldn't you?  The details are buried deep in this thread if you dig hard enough.  Take a look at posts on Page 64 by Hosam AL Dein.


On searching to resolve the "manifest thing" I add a manifest to the vb.exe with some _manifester tool_ I had found there but then again the "manifest error" doesn't go away and because I didn't think that it was relevant to VB options I was never go to change that option mention in the 1st post. Now, thanks to  *Krool* it was resolved, and I guess that I need to carefully look here again to find out why the error 383 on Form_load event raised on FontCombo1.Text = RichTextBox1.SelFontName which VB complain is "Property is read only" when I hit the RichTextBox Demo button. Anyway I never use the RichTextBox. I was searching on listview thinking that control has multiline/wrap ability (vbCrLf kind of stuff) when I realize the listbox and later listview doesn't have that feature and the rows are always one-liners only.
Any help to that matter is welcome as the code structure will stay as intended eg. loop to fill listview with multi-line text in its rows. The single textbox (which seems the only option for me now) doesn't need to attach to a loop to fill with stuff, as the user can click inside another listbox\listview control to see his selection "magnified" in this textbox. But this click-to-see user experience is not what I think.

----------


## Krool

> If you sort your controls alphanumeric in the Vbp file they will appear sorted in the ToolBox.
> Actually, I usually sort the entire block containing Modules/Classes/Controls/PropertyPages to make the Vbp more readable.


Makes sense. Thanks.
I sorted now the vbp file for the ComCtlsDemo. The next VBCCR17 will be then sorted likewise.

----------


## Krool

With today's update the sync between Std-EXE and OCX version is broken.

It's intended to be. It's necessary to fix some problems and also an opportunity to include new features or to solve deficits.

So when somebody has a wish, now it's the time.

The idea is to bring everything in order so in a few weeks/months VBCCR17 can be released.
Also then when a (maybe final?) VBCCR17 is then released I could spent some time to make a documentation..

----------


## Elroy

Vertical Slider that will truly reverse.

---------

Also, I've been neglecting to bring this up because it'd probably take quite a bit to isolate the problem, but I'm having some kind of a timing issue.  Also, it's probably not a problem in the OCX version, but I don't know, as I've got your Slider, TreeView, and StatusBar source code just included in my project.

But basically, under some strange circumstances, it's cycling through the certain controls on a form, causing them to fire GotFocus and LostFocus events, which was giving me a big problem.  It's happening after certain forms get loaded, and even after the completion of my *Sub Main* procedure ... but before the user actually does anything.  In other words, it's as if something about the VBCCR is "settling down" and firing those GotFocus and LostFocus events.

The control that was giving me the most problem was NOT the first of the TabIndex order.  I checked that thoroughly.  I also checked to make sure that nothing I did was setting the focus of that control, and nothing is.  And it's definitely before the user does anything.  I'll admit that I didn't check to see if it was both a compiled and IDE problem.  I was getting the problem in the IDE (while running) ... no problems in design mode.  Also, just as a further FYI, as I jiggle the design of the form, the problem control moves around to different controls.

Here's how I fixed it.  First, I created a global variable:



```

Public gbStarting               As Boolean              ' Just used during program startup to give a few milliseconds to let things settle down.


```

And then, I put my own timer on the primary form.  I pre-set it to *Enabled=True* and *Interval=500*.

And then, I put this in the timer's event, which just executes once:



```

Private Sub TimerStartup_Timer()
    ' This just fixes some weird startup thing where a random control gets the focus, which may mess things up.
    ' I believe it has something to do with Krool's controls.
    '
    TimerStartup.Enabled = False
    gbStarting = False
End Sub


```

And then, in a few critical places, I checked the gbStarting global, and just did an *Exit Sub* if it was true.

Without releasing the thread, I couldn't find a way to solve the problem.  Also, just as a further FYI, I tried tracing back from the GotFocus event, and it immediately went into some of your code in the *ComCtlsBase.bas* module.  Let me turn off the timer and see if I can get the error again.  ...  Well drat, I can't reproduce it at the moment.  That was quite a few versions back (of MY program) that I was getting it and implemented that above fix.

Other than deleting the *property pages* in the Slider, TreeView, and StatusBar controls, I'm using your code *perfectly unchanged*.  I've got the following modules of yours in my project:

ISubclass.clsCommon.basComCtlsBase.basVisualStyles.basVTableHandle.basSlider.ctl/ctxStatusBar.ctl/ctxTreeView.ctl/ctxTvwNode.clsTvwNodes.clsSbrPanel.clsSbrPanels.clsSbrPanelProperties.cls
-----

I'm good, but, since you asked for stuff, I thought I'd outline it for you.

Elroy

----------


## MountainMan

Krool,

Is it time to fold VBFlexGrid into the forthcoming VBCCR17?

----------


## yereverluvinuncleber

Krool, as per my previous request, which I think you haven't yet seen...

http://www.vbforums.com/showthread.p...=1#post5453057

Add Horiz. & Vert. Skroolbars to the CommonControls Collection

----------


## Karl77

> So when somebody has a wish, now it's the time.


Not easy to enhance a perfect thing!

Unsorted and perhaps unrealistic:

-a- unified tooltip appearance
-b- full control over the colors in order to get a dark mode
-c- a menu control that can show icons
-d- all existing controls with a horizontal scrollbar shall react to the wheel when mouse is over it

To a:
AFAIK in the works from time time.

To b:
I know comctl32 doesn't offer a dark mode.
Maybe it is somehow possible anyway?

To c:
I know there are some solutions around.
And I use one of them, but it's cumbersome to work with it.
Not nearly the quality as VBCCR.

To d:
Paint.net has this feature, and I think it is a clever idea.


My $0.02

----------


## Krool

> Krool, as per my previous request, which I think you haven't yet seen...
> 
> http://www.vbforums.com/showthread.p...=1#post5453057
> 
> Add Horiz. & Vert. Skroolbars to the CommonControls Collection


I read it but ignored it. There are 2 types of scrollbars.
1. Encapsulated with in an independent hWnd
2. Embedded in a control, same hWnd as control. (NC area)

So making a type 1 scrollbar like VB.scrollbar won't make a difference without hooks/subclasses.
And my aim is to avoid hooks whereever possible and not to subclass "beyond the UC border".
So the answer tends to say: no.




> Is it time to fold VBFlexGrid into the forthcoming VBCCR17?


Think not. The VBFlexGrid might be developed further after VBCCR17. When it's separated then the development can be independent.

----------


## OldClock

How do you repaint a CommandButtonW's picture with a vertical offset?

Before using VBCCR, I made custom graphical buttons by creating a PictureBox (which I call PictureBtn), setting PictureBox.Picture to a GIF, and setting the size of the PictureBox to half the height of the GIF. The GIF contains two versions of an image stacked vertically: the top one is the image in a normal state, and the bottom one is a darker version of itself. The idea is that when you hover the mouse over the button, the picture changes to the darker version, to convey the hover effect.


To do that, on PictureBox_MouseMove I would PaintPicture with the vertical offset Y1 set to -128, but there is no MouseLeave event for the PictureBox so I would work around that by using Frame_MouseMove and PaintPicture with the PictureBox's vertical offset Y1 set to 0:



```
Private Sub PictureBtn_MouseMove(Index As Integer, Button As Integer, Shift As Integer, x As Single, y As Single)
    PictureBtn(Index).PaintPicture PictureBtn(Index).Picture, 0, -128
End Sub

Private Sub Frame_MouseMove(Index As Integer, Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim pb As PictureBox

    For Each pb In PictureBtn
        pb.PaintPicture pb.Picture, 0, 0
    Next
End Sub
```

But using Frame_MouseMove is unreliable, since the mouse might not move onto the frame but onto some other control.

VBCCR's CommandButtonW has the MouseEnter and MouseLeave events, great. I created a CommandButtonW with Style=vbButtonGraphical and the Picture set to the same GIF as above. However, the picture is centered vertically, so this is what I see:


I tried changing CommandButtonW.VerticalAlignment but it seems to have no effect on the picture or on the caption.

Using Windows XP SP3.

How do I repaint the picture with Y=0, and with Y=-128?

I see there is CommandButtonW.Picture.Render but no luck figuring out how to use that yet.

----------


## OldClock

Well, I managed to redraw the picture using this:



```
Private Sub RoundButtons_MouseEnter(Index As Integer)
    With RoundButtons(Index).Picture
        .Render GetDC(RoundButtons(Index).hwnd), 0, 0, 128, 256, _
             0, .Height / 2, .Width, -.Height, 0
    End With
End Sub

Private Sub RoundButtons_MouseLeave(Index As Integer)
    With RoundButtons(Index).Picture
        .Render GetDC(RoundButtons(Index).hwnd), 0, 0, 128, 256, _
             0&, .Height, .Width, -.Height, ByVal 0&
    End With
End Sub
```

However, the picture is still vertically centered (i.e. looks wrong) when the form is loaded, and only gets "fixed" once I mouse-over. I tried calling the RoundButtons_MouseLeave routine to re-render the picture from Form_Activate (it's an MDI child form) but when the form appears the button is still wrong. I tried calling it from Form_Paint, but for some reason the form paint event never fires. And even if I mouse-over the button (which makes it look correct, the picture gets set to y=0), then it gets re-centered (i.e. broken) if I switch to a different window and then switch back to my program.

----------


## Krool

> How do you repaint a CommandButtonW's picture with a vertical offset?


Why making it so complicated? And why this problem should be solved in CommandButtonW? Next time somebody comes with an horizontal offset, or diagonal...

Instead use a paint program and split your picture in two pieces and put the normal picture in PictureBox1 and the hover picture in PictureBox2 and just make:



```
Private Sub CommandButtonW1_MouseEnter()
Set CommandButtonW1.Picture = Picture1.Picture
End Sub

Private Sub CommandButtonW1_MouseLeave()
Set CommandButtonW1.Picture = Picture2.Picture
End Sub
```

----------


## Krool

TreeView control is now 'Alignable'.
This enables it now to be placed on MDIForms, for example as a 'menu tree' style control.

----------


## baka

I download and started ComCtlsDemo and I get:

so I can't do much. it freezes the IDE and I need to hard-close the IDE.
https://i.postimg.cc/28VKdRKd/Image1.png

----------


## Krool

> I download and started ComCtlsDemo and I get:
> 
> so I can't do much. it freezes the IDE and I need to hard-close the IDE.
> https://i.postimg.cc/28VKdRKd/Image1.png


Overwrite with new OLEGuids.tlb.

----------


## baka

downloaded from https://github.com/Kr00l/VBCCR/tree/...rsion/OLEGuids
and I get the same error.

----------


## Krool

> downloaded from https://github.com/Kr00l/VBCCR/tree/...rsion/OLEGuids
> and I get the same error.


Did you replace the file in SysWOW64 folder? (or System32)

----------


## Simos

Thanks for your effort

I'm using your CommonDialog and maybe there is an issue easy to solve but...

Option Explicit

Public myPrinter As Printer     ' initialized in app.main

Public Sub SetMyPrinter()

    With New CommonDialog
        .CancelError = False
        .PrinterDefault = False
        .PrinterDefaultInit = False
        .PrinterName = myPrinter.DeviceName
        .PrinterPort = myPrinter.Port
        .PrinterDriver = myPrinter.DriverName

        If .ShowPrinter Then
            If Len(.PrinterName) = 0 Then
*                ' if the default printer was selected Krool's CommonDialog returns true but printer parms are not set
                ' Using the Printer object solves this issue
*                Set myPrinter = Printer

            Else

                Dim objPrinter As Printer

                For Each objPrinter In Printers

                    If objPrinter.DeviceName = .PrinterName Then
                        Set myPrinter = objPrinter

                        Exit For

                    End If

                Next

            End If
        End If

    End With

End Sub

If the default printer was selected CommonDialog returns true but printer parms are not set

Is this the way it works?

Or maybe the following:
        If ((DNAMES.wDefault And DN_DEFAULTPRN) = 0) Then 
should be:
        If ((DNAMES.wDefault And DN_DEFAULTPRN) = 0) Or (PropPrinterDefaultInit = False) Then

or better:

    Dim bReq As Byte
    If (PDLG.Flags And CdlPDReturnDefault) = 0 Then
        bReq = PropPrinterDefaultInit = False And Not (PropPrinterDriver = vbNullString Or PropPrinterName = vbNullString _
                Or PropPrinterPort = vbNullString)

        If ((DNAMES.wDefault And DN_DEFAULTPRN) = 0) Or bReq Then


QUESTION:
Is it possible to use CommonDialog as above and skip User input like when PropFlags = CdlPDReturnDefault

----------


## Krool

Update released. (VBCCR16.OCX also updated on this)




> If the default printer was selected CommonDialog returns true but printer parms are not set


I always use CdlPDReturnDC so this didn't bother me yet.
Also the MS Common Dialog doesn't provide such functionality, so there is no "comparable behavior" to consider.

The idea was: if the params return null then the default printer was selected. (kind of alias)

However, for some use cases it might not appropriate. Thanks for your feedback.
Therefore I changed it now and the printer params are now *always* returned.

The flag DN_DEFAULTPRN is now only taken to decide whether or not to change the default printer when PropPrinterDefault = True.




> Is it possible to use CommonDialog as above and skip User input like when PropFlags = CdlPDReturnDefault


No.

----------


## Simos

Thanks a lot

----------


## Simos

please check also:
with new CommonDialog:  .ShowPrinter: end with
In the Dialog click Preferences and then click OK. 
You must use Task Manager to end the IDE or restart the pc if this action was from an exe

----------


## Krool

> please check also:
> with new CommonDialog:  .ShowPrinter: end with
> In the Dialog click Preferences and then click OK. 
> You must use Task Manager to end the IDE or restart the pc if this action was from an exe


I don't understand anything..

----------


## Simos

just call .ShowPrinter . When the PrintDialog appears then click the button Preferences. When the new Dialog appears click  the button OK.

----------


## Simos

> just call .ShowPrinter . When the PrintDialog appears then click the button Preferences. When the new Dialog appears click  the button OK.

----------


## Simos

> 


I found that this problem exists only if the first selected printer is "Microsoft Print to PDF"
If you click on any other printer then PrintDialog->Preferences->OK works fine
Next click the  printer "Microsoft Print to PDF" then Preferences->OK don't crash !!!

----------


## Simos

Sorry to bother you.
In order to reproduce the CommonDialog crash you must:
1. set "Miscrosoft Print to PDF" printer as default OR set PrinterName="Microsoft Print to PDF", PrinterPort="Ne01:", PrinterDriver="winspool"
2. call ShowPrinter and when PrintDialog appears with the above printer selected, don't click on any other printer … just click Preferences and then OK
I hope that this time I was able to give you the correct info to reproduce the crash.

----------


## Simos

Please let me know if you reproduced the problem

----------


## Simos

About the CommonDialog problem:

MSDN: The DEVMODE structure actually used by a printer driver contains the device-independent part
followed by a driver-specific part that varies in size and content with each driver and driver version.
Because of this driver dependence, it is very important for applications to query the driver for the correct
size of the DEVMODE structure before allocating a buffer for it.

I have changed the ShowPrinter function to copy DEVMODE structure in the correct buffer as above and the crash problem is fixed now.

If you wish I can upload it.

Thank you

----------


## Krool

> About the CommonDialog problem:
> 
> MSDN: The DEVMODE structure actually used by a printer driver contains the device-independent part
> followed by a driver-specific part that varies in size and content with each driver and driver version.
> Because of this driver dependence, it is very important for applications to query the driver for the correct
> size of the DEVMODE structure before allocating a buffer for it.
> 
> I have changed the ShowPrinter function to copy DEVMODE structure in the correct buffer as above and the crash problem is fixed now.
> 
> ...


Please. Thanks

----------


## Simos

CommonDialog.zip

----------


## Simos

I created the Private Function PrinterDevMode(ByVal hWndOwner As Long, ByRef dmOutBuf() As Byte,  ByRef bufsize As Long) As Boolean
and updated ShowPrinter,  ShowPrinterEx and ShowPageSetup.
CommonDialog.zip

----------


## Simos

New issue:  propPrinterPort = Left$(Buffer, InStr(Buffer, vbNullChar) - 1)
It seems that the last vbNullChar is optional. 
Error if you select "OneNote" printer.
Fixed as:   propPrinterPort = Left$(Buffer, InStr(Buffer & vbNullChar, vbNullChar) - 1)

----------


## Krool

@Simos, great bug reports. Such things are needed. Will ensure that all gets fixed soon. Thanks

----------


## Simos

> @Simos, great bug reports. Such things are needed. Will ensure that all gets fixed soon. Thanks


Krool. I know that CommonDialog is not on this thread contents and you can't deal with it now.
Maybe I should work on this and when finished I will let you know. I will mark all changes.
Is this ok?

----------


## Krool

> Maybe I should work on this and when finished I will let you know. I will mark all changes.
> Is this ok?


Not needed. I already released an update now to address
1. the issue with the vbNullChar
2. the DEVMODE structure

In fact I did go another way than you did for point 2.

You query the whole DEVMODE struct.
However, I do the "light version" and only retrieve the buffer length to define DMDriverExtra.
And then of course in the allocation to add the DMDriverExtra.


```
DMODE.DMSize = LenB(DMODE)
If PropPrinterDefaultInit = False And Not (PropPrinterDriver = vbNullString Or PropPrinterName = vbNullString Or PropPrinterPort = vbNullString) Then
    DMODE.DMDriverExtra = GetDMDriverExtra(DMODE.DMSize, PropPrinterName)
    Buffer = Left$(PropPrinterName, CCHDEVICENAME)
    CopyMemory DMODE.DMDeviceName(0), ByVal StrPtr(Buffer), LenB(Buffer)
Else
    DMODE.DMDriverExtra = GetDMDriverExtra(DMODE.DMSize)
End If
[...]
PDLG.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DMODE) + DMODE.DMDriverExtra)
```

The helper function GetDMDriverExtra: (using OpenPrinterW/DocumentPropertiesW)



```
Private Declare Function DocumentProperties Lib "winspool.drv" Alias "DocumentPropertiesW" (ByVal hWnd As Long, ByVal hPrinter As Long, ByVal lpszDeviceName As Long, ByVal lpDevModeOutput As Long, ByVal lpDevModeInput As Long, ByVal fMode As Long) As Long
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterW" (ByVal lpszPrinterName As Long, ByRef hPrinter As Long, ByVal lpDefault As Long) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
Private Declare Function GetDefaultPrinter Lib "winspool.drv" Alias "GetDefaultPrinterW" (ByVal lpszPrinterName As Long, ByRef cch As Long) As Long

Private Function GetDMDriverExtra(ByVal DMSize As Long, Optional ByVal PrinterName As String) As Long
' According to MSDN:
' The DEVMODE structure actually used by a printer driver contains the device-independent part
' followed by a driver-specific part that varies in size and content with each driver and driver version.
' Because of this driver dependence, it is very important for applications to query the driver for the correct
' size of the DEVMODE structure before allocating a buffer for it.
If PrinterName = vbNullString Then
    Dim Length As Long
    GetDefaultPrinter 0, Length
    If Length > 0 Then
        Dim Buffer As String
        Buffer = String(Length, vbNullChar)
        GetDefaultPrinter StrPtr(Buffer), Length
        PrinterName = Left$(Buffer, Length - 1)
    End If
End If
Dim hPrinter As Long
If OpenPrinter(StrPtr(PrinterName), hPrinter, 0) Then
    Dim RetVal As Long
    RetVal = DocumentProperties(0, hPrinter, StrPtr(PrinterName), 0, 0, 0)
    If RetVal > -1 Then
        If RetVal > DMSize Then GetDMDriverExtra = RetVal - DMSize
    End If
    ClosePrinter hPrinter
    hPrinter = 0
End If
End Function
```

----------


## Simos

Perfect. Thanks

----------


## Simos

About vbNullChar:   You must also add size to CCHDEVNAMESEXTRA. OneDriver printer has wExtra > 120

----------


## Krool

> About vbNullChar:   You must also add size to CCHDEVNAMESEXTRA. OneDriver printer has wExtra > 120


It's defined currently as 100. What value do you suggest?
There is no clear definition. I guess it can be any?
So let's go for 200 then?

Edit:
Also must the dmSpecVersion be always set fixed to = DM_SPECVERSION ?

----------


## Simos

> It's defined currently as 100. What value do you suggest?
> There is no clear definition. I guess it can be any?
> So let's go for 200 then?
> 
> Edit:
> Also must the dmSpecVersion be always set fixed to = DM_SPECVERSION ?


1.200 should be sufficient enough to cover long Network Printer names and PortNames like OneNote. Just in case don't remove the last "& vbNullChar"

2.I don't know. This is why I fetched the driver's buffer. The info about DeviceName, SpecVersion, … exist in that buffer and you don't have to set these values to DMODE


QUESTION: 
Will you add the CommonDialogW to your excellent collection?
If you don't and with your permission I will create an ActiveX CommonDialogW
*Maybe you don't know that your CommomDialogW solves the problem of "Generic / Text" printer and "Device font 10cpi"
*

----------


## Krool

> 1.200 should be sufficient enough to cover long Network Printer names and PortNames like OneNote. Just in case don't remove the last "& vbNullChar"
> 
> 2.I don't know. This is why I fetched the driver's buffer. The info about DeviceName, SpecVersion, … exist in that buffer and you don't have to set these values to DMODE
> 
> 
> QUESTION: 
> Will you add the CommonDialogW to your excellent collection?
> If you don't and with your permission I will create an ActiveX CommonDialogW
> *Maybe you don't know that your CommomDialogW solves the problem of "Generic / Text" printer and "Device font 10cpi"
> *


CommonDialog is included in the OCX. Don't get your question.

----------


## Simos

:Smilie: Sorry...Yes it exists in toolbar. Was it there a year ago?

----------


## Simos

No... Actually it's not in the toolbox "ComCtlsDemo" project

----------


## Simos

Sorry... Forget the above. I was just looking the controls collection. (Replace vb's CommonDialog). No need to make a UserControl for this.
Just curious... Do you know the "Generic / Text" and "Device font 10cpi" problem ?

----------


## Krool

> Do you know the "Generic / Text" and "Device font 10cpi" problem ?


No I don't.

----------


## Simos

> No I don't.


Easy to reproduce.
Use vbCommonDialog or any other wrapper PrintDlgA (vbAccelerator, …). Select this printer and print something(even to file)
That's it. The printer object's font changes to "Device Font 10cpi" and there is no way to set another font to the printer.
You must exit the app and start over. The strange thing is that if the first printout off the app was with another normal printer this problem no longer exists. I don't know if this exists only in Unicode environments.(here is Greece dif.codepage). Since then I always check the first printout and stop it if the printer is the above.

----------


## Krool

> 2.I don't know. This is why I fetched the driver's buffer. The info about DeviceName, SpecVersion,  exist in that buffer and you don't have to set these values to DMODE


The "correct" way is even longer.
https://support.microsoft.com/en-us/...rties-function
1. Determine size (fMode = 0)
2. Read (fMode = DM_OUT_BUFFER)
3. Modify DevMode
4. Merge (fMode = DM_IN_BUFFER OR'ing DM_OUT_BUFFER)

You skipped point 4 and I skipped all except 3, with yesterday update skipped 2 and 4.
I will do it properly and will update soon w/o any skips.

----------


## Simos

I think step 4 is not needed. You have already merged the DevMode part. PrintDlgW will do the rest

----------


## Simos

I think step 4 was actually when I copied DMODE back to the dmoutbuf() and then CopyMemory ByVal lpDevMode, dmOutbuf(0), buflen

----------


## Krool

> I think step 4 was actually when I copied DMODE back to the dmoutbuf() and then CopyMemory ByVal lpDevMode, dmOutbuf(0), buflen


That's the hard merge. However DM_IN_BUFFER OR'ing DM_OUT_BUFFER merges involving the driver so that eventual amendments in the private section can be done, according to MSDN.

----------


## Simos

I still think that since we return in dmOutbuf() the size of our DMODE struct the driver will adjust the private part. But you may not agree.

----------


## Simos

when DMODE gets the dmOutbuf()  data the DMODE.DMSize is either 0 or 1. This is something to think about. Perhaps Old/New DMODE struct

----------


## Simos

Please run this:
Sub Main()
    Debug.Print Printer.FontName            ' should be any font
    Dim obj As Printer
    For Each obj In Printers
        If obj.DeviceName = "Generic / Text Only" Then
            Set Printer = obj
            Debug.Print Printer.FontName    ' also the above font
            Printer.FontName = "Tahoma"     ' or any other font
            Debug.Print Printer.FontName    ' Ooops...Device Font 10cpi... you must exit IDE
            Exit For
        End If
    Next
End Sub

----------


## Simos

Since you are working on CommonDialogW maybe you should make some other changes to make it more user friendly.
1. Trim out not supported flags. e.e. CdlPDNoNetworkButton and cdlPDPrintSetup not supported in ShowPrinterEx and the error returned is generic
2. Maybe propFlags should be set to zero on exit of all Show functions. (After ShowPrinter I called ShowColor without setting any flags and I got an error)

----------


## Krool

Update released.

Internal improvement for ShowPrinter/ShowPrinterEx/ShowPageSetup dialog in the CommonDialog class.
The DevMode plays now by the rules. (https://support.microsoft.com/en-us/...rties-function)
Which means the long run:
1. Determine DevMode size (fMode = 0)
2. Prepare DevMode (fMode = DM_OUT_BUFFER)
3. Adjust DevMode for Orientation, PaperSize, ColorMode, and so on... (CommonDialog properties)
4. Finalize/Merge DevMode (fMode = DM_IN_BUFFER OR'ing DM_OUT_BUFFER)




> 1. Trim out not supported flags. e.e. CdlPDNoNetworkButton and cdlPDPrintSetup not supported in ShowPrinterEx and the error returned is generic
> 2. Maybe propFlags should be set to zero on exit of all Show functions. (After ShowPrinter I called ShowColor without setting any flags and I got an error)


1. CdlPDNoNetworkButton and cdlPDPrintSetup are supported in ShowPrinter. How should I trim them out for ShowPrinterEx ? An error is already returned by PrintDlgEx in such case with the error code E_FAIL.
2. No, sometimes propFlags are different after dialog return, which can be evaluated. So it makes no sense to cut this feature off. It's an easy thing to set .Flags = 0 yourself in your app. The MS CommonDialog control behaves the same. So no change here.  :Smilie: 




> 1.200 should be sufficient enough to cover long Network Printer names and PortNames like OneNote. Just in case don't remove the last "& vbNullChar"


Done. CCHDEVNAMESEXTRA has been increased now from 100 to 200.

----------


## Simos

:Smilie: Perfect. 
Just curious: why bother to set DMODE if dwBytes=0? If OpenPrinter Or DocumentProperties failed PrintDialog should fail also or not ?
Sorry. Forget it. PrintDialog drops with the Default Printer if the PrinterName provided does not exist

----------


## Krool

> Just curious: why bother to set DMODE if dwBytes=0? If OpenPrinter Or DocumentProperties failed PrintDialog should fail also or not ?
> Sorry. Forget it. PrintDialog drops with the Default Printer if the PrinterName provided does not exist


Exactly. I just did a minor modification in code so it's more clear to read and to not bother manually with initializing DevMode in case user-defined printer is invalid.
If all fails then (red marked) dwBytes is 0 and so will hDevMode (and hDevNames) be NULL, which signals the PrintDlg(Ex) to initialize on their own.



```
If PropPrinterDefaultInit = False And Not (PropPrinterDriver = vbNullString Or PropPrinterName = vbNullString Or PropPrinterPort = vbNullString) Then
    DeviceName = PropPrinterName
    dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
    If dwBytes = 0 Then
        ' Fallback to default printer as user-defined printer name is invalid.
        DeviceName = GetPrinterDefault()
        dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
    End If
Else
    DeviceName = GetPrinterDefault()
    dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
End If
If dwBytes > 0 Then
    [...]
End If
```

----------


## Simos

Yes. This is the perfect logic.
Did you test the Generic / Text Only ?

----------


## Krool

Update released.
Sorry for the ongoing updates with CommonDialog.cls
Hopefully this is now final.  :Smilie: 




> Yes. This is the perfect logic.


Almost. Now only the PropPrinterName is used to select a non-default printer on initialization.
Also the DEVNAMES structure is now always filled according to the DeviceName. (which can be GetPrinterDefault() or PropPrinterName)
DEVNAMES is important if the printer name is > 32 chars. (if less 32 then DMDeviceName will be read)
Also PropPrinterDriver and PropPrinterPort are not needed actually, so there are ignored on input.
On output (dialog function returns) of course the DEVNAMES will be read and all PropPrinterName/PropPrinterDriver/PropPrinterPort will be set.
I played around very extensively now and this logic must be the "correct" one.

In code this means following: (changes marked as red)


```
Dim hPrinter As Long, DeviceName As String, DMODE_B() As Byte, dwBytes As Long
If PropPrinterDefaultInit = False And Not PropPrinterName = vbNullString Then
    DeviceName = PropPrinterName
    dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
    If dwBytes = 0 Then
        ' Fallback to default printer as user-defined printer name is invalid.
        DeviceName = GetPrinterDefault()
        dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
    End If
Else
    DeviceName = GetPrinterDefault()
    dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
End If
If dwBytes > 0 Then
    [...]
```



```
    [...]
    If Not DeviceName = vbNullString Then
        ' wDeviceOffset will only be used on input when DMDeviceName got truncated due to the 32 characters limit.
        ' wDriverOffset and wOutputOffset are ignored on input.
        DNAMES.wDriverOffset = 4
        DNAMES.wDeviceOffset = DNAMES.wDriverOffset + 1
        DNAMES.wOutputOffset = DNAMES.wDeviceOffset + Len(DeviceName) + 1
        DNAMES.wDefault = 0
        Buffer = Left$(vbNullChar & DeviceName & vbNullChar & vbNullChar, CCHDEVNAMESEXTRA)
        CopyMemory DNAMES.wExtra(0), ByVal StrPtr(Buffer), LenB(Buffer)
        PDLG.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DNAMES))
        lpDevNames = GlobalLock(PDLG.hDevNames)
        CopyMemory ByVal lpDevNames, DNAMES, LenB(DNAMES)
        GlobalUnlock PDLG.hDevNames
    End If
End If
```




> Did you test the Generic / Text Only ?


No. Why?

EDIT:
Another gotcha fixed. (potential memory issue)
On return, when reading hDevNames, the size is flexible. So instead using LenB(DNAMES) now use GlobalSize().
I defined CCHDEVNAMESEXTRA as 200 to ensure big enough buffer. However, it may be smaller when not necessary.
And therefore using LenB(DNAMES) could CopyMemory too much, out of scope of the allocated memory block.
So GlobalSize() should be the safe way.


```
If PDLG.hDevNames <> 0 Then
    ' DEVNAMES is a variable length memory block.
    Dim dwMemSize As Long
    dwMemSize = GlobalSize(PDLG.hDevNames)
    If dwMemSize > LenB(DNAMES) Then dwMemSize = LenB(DNAMES)
    Erase DNAMES.wExtra()
    lpDevNames = GlobalLock(PDLG.hDevNames)
    CopyMemory DNAMES, ByVal lpDevNames, dwMemSize
    GlobalUnlock PDLG.hDevNames
    GlobalFree PDLG.hDevNames
    [...]
```

----------


## Simos

Just curious to see if it exist on your pc. 
If it does then call ShowPrinter before the loop. The problem should be fixed.

----------


## Eduardo-

> With today's update the sync between Std-EXE and OCX version is broken.
> 
> It's intended to be. It's necessary to fix some problems and also an opportunity to include new features or to solve deficits.
> 
> So when somebody has a wish, now it's the time.


I don't know whether it is still "the time", what I would like is the Err object information to be preserved.

I'm already doing this on my own, but that means that I won't be able to update to new versions of the CC (at least not without manually addding that code).

As a second wish I would like the code of the common controls not to use standard naming for public members that can interfere with already existent public members on the host project, that on other hand, might not be totally compatible one with the other.

Examples:
ISubclass interface.
InIDE function

Remember, you invited to send "wishes".

----------


## Krool

> I don't know whether it is still "the time", what I would like is the Err object information to be preserved.
> 
> I'm already doing this on my own, but that means that I won't be able to update to new versions of the CC (at least not without manually addding that code).
> 
> As a second wish I would like the code of the common controls not to use standard naming for public members that can interfere with already existent public members on the host project, that on other hand, might not be totally compatible one with the other.
> 
> Examples:
> ISubclass interface.
> InIDE function
> ...


What do you mean with Err object?

----------


## Eduardo-

> What do you mean with Err object?


Forget about that. That seems to be a problem only when an OCX is not compiled (it seems to share the same Err object for both projects, exe and ocx in that case).
I mean, any 'On Error' statement in the OCX project will erase the error information of the Err object of the host program, but that only happens when the OCX is not compiled. 
So it seems not necessary to preserve that information.

----------


## Elroy

Ok, I've now found a bug that I need a fix (or work-around) for.

The _TreeView_ ... when you examine the TreeView1._SelectedItem_ in either the TreeView1__Click_ or TreeView1__DoubleClick_ event, it's the previously selected item, and not the currently selected item.

It does get changed, but *AFTER* the TreeView1_Click or TreeView1_DoubleClick events are completed.

Krool, I can put together a demo if you like, but I think that's pretty clear.

I just need to find a way of figuring out which node was clicked in both of these events.  I suppose I could set a timer in the events, and do my work in the timer ... but that's ugly.

Am I missing something?

Thanks,
Elroy

EDIT2: Correction ... Apparently, it's only the Click event, and not the DblClick event.

EDIT:  I went ahead and made a demo and a video.  Here's the demo code in a Form1:



```

Option Explicit

Private Sub Form_Load()
    TreeView1.Nodes.Add , TvwNodeRelationshipNext, , "aaaaaa"
    TreeView1.Nodes.Add , TvwNodeRelationshipNext, , "bbbbbb"
    TreeView1.Nodes.Add , TvwNodeRelationshipNext, , "cccccc"
    TreeView1.Nodes.Add , TvwNodeRelationshipNext, , "dddddd"
End Sub

Private Sub TreeView1_Click()
    Debug.Print TreeView1.SelectedItem.Text
    MsgBox TreeView1.SelectedItem.Text
End Sub


```

And a video:



And the little demo is attached:

----------


## yereverluvinuncleber

> Ok, I've now found a bug that I need a fix (or work-around) for.
> 
> The _TreeView_ ... when you examine the TreeView1._SelectedItem_ in either the TreeView1__Click_ or TreeView1__DoubleClick_ event, it's the previously selected item, and not the currently selected item.
> 
> It does get changed, but *AFTER* the TreeView1_Click or TreeView1_DoubleClick events are completed.
> 
> Krool, I can put together a demo if you like, but I think that's pretty clear.
> 
> I just need to find a way of figuring out which node was clicked in both of these events.  I suppose I could set a timer in the events, and do my work in the timer ... but that's ugly.
> ...


I found this out earlier Elroy and I raised it with Krool.




> The old MSCOMCTL treeview, when you click on a node in the tree, the click captured using
> 
> folderTreeView_Click()
> 
> - then the returned node is the one you just clicked on as you would expect.
> 
> eg. folderTreeView.SelectedItem.Key is the current node in the tree
> 
> It would seem that using Krool's TreeView that is not the case.
> ...


Hope that is useful to you. It seems that the treeview click operation in Krool's version  is different from the original, I had suggested to Krool that some documentation might be sensible explaining the differences between the two. I offered my quote above as part of that documentation. In response Krool has created the Wiki and I will add my penn'orth to the wiki but life has prevented me from doing so for the moment (sick parents) - so just a quick word here.

----------


## Elroy

Ahhh, ok.  This will work for me.

----------


## yereverluvinuncleber

> Ahhh, ok.  This will work for me.


You have helped me several times, so it is nice to be able to return the favour. 

I will do that bit of documentation - perhaps you could add your penn'orth? If you find any more differences do present them to me and I'll add them to the Wiki.

----------


## LinkFX

Good evening. Krool I believe I found a strange bug in your controls, my guess is it's the ImageList control but it may also be the ListView. I've attached a sample project that shows the bug in action.

Essentially, I have a project that adds a configurable amount items to a ListView and loads a small 32x32 image file with LoadPicture to serve as the icon which gets added to the associated imagelist. In the IDE this works correctly 100% of the time, but in the compiled .exe the icons sometimes simply do not get loaded at random. Sometimes you'll open the .exe and all 3 included icons will load no problem, other times they will just be blank for all the items.

And if they do fail to load, it will keep failing to load them forever, until the program is reopened. Sometimes it will fail immediately upon launching too, and the only way around it is to launch the .EXE again. Again, in the IDE this never happens, they load correctly 100% of the time.

Moreover, if you try adding many items to the listview, you will crash (typically around 5k to 10k is when it will crash). This crashes both in the IDE and in the compiled EXE. Without the icons the listview works fine, I can add tens of thousands of items with no issues, but as soon as there are icons it crashes around that mark. *This particularly is the issue I really need fixed most.*

Attached is the source of the project that displays this bug. It's a very simple one that should be easy to understand. If you could please review it and fix this issue, I'd be incredibly grateful, as it's actually preventing me from developing another application that's suffering from the same problem.

Thank you very much for your time and thank you for breathing life into this otherwise forgotten language with your excellent work!  :Smilie: 

P.S. I should add, this happens both using the OCX and the user controls directly in the project.


VBCCR Problem.zip

----------


## yereverluvinuncleber

Crashing with thousands of icons certainly sounds like a memory issue. Without knowing Krool's code I imagine that it may be trying to cache the icons and hence the problem. I recently rolled my own image list to get round a similar problem. On the icon display my own control had an option to display and cache just the icons that were being shown on the panel. It sounds like Krool needs to do the same. This will make the icon display markedly slower each time the icon view is moved onto another page' but it might resolve the crash.

----------


## happyubuntu

Hello, 

First of all i want to thank you for your continuous effort.

are there any plans to develop a new COMCTL32.OCX compatible with Windows touch screen? I know that MSCOMCTL.OCX solves the issue, but we are hoping not to have to replace the executable in our code, but only register the OCX in the system.

Thank you.

----------


## happyubuntu

Hello, 

First of all i want to thank you for your continuous effort.

are there any plans to develop a new COMCTL32.OCX compatible with Windows touch screen? I know that MSCOMCTL.OCX solves the issue, but we are hoping not to have to replace the executable in our code, but only register the OCX in the system.

Thank you.

----------


## LinkFX

> Crashing with thousands of icons certainly sounds like a memory issue. Without knowing Krool's code I imagine that it may be trying to cache the icons and hence the problem. I recently rolled my own image list to get round a similar problem. On the icon display my own control had an option to display and cache just the icons that were being shown on the panel. It sounds like Krool needs to do the same. This will make the icon display markedly slower each time the icon view is moved onto another page' but it might resolve the crash.


I've briefly looked at alternate image list controls but sadly couldn't find any that both supported 32 bit with alpha and were compatible with Krool's Listview control. I don't suppose yours could do it? If so I'd love to give it a shot.  :Smilie:

----------


## yereverluvinuncleber

> I've briefly looked at alternate image list controls but sadly couldn't find any that both supported 32 bit with alpha and were compatible with Krool's Listview control. I don't suppose yours could do it? If so I'd love to give it a shot.


I'm sorry, I have just had a look at the code and it isn't in a fit state to even extract at the moment. I'm unsure if I could even do it. I used LaVolpe's alpha image code and hacked together something that is inseparable from the rest of my application rather than doing it properly as a real control. It would be unusable to you. However, I will try and extricate the code and build a proper control from it and I'll let you have it when done. I had previously intended to do that. Don't hang around though as I am rather busy with real life so I only get to code for an hour per day if I am lucky. Apologies for raising your hopes. Rather wait for Krool to respond, he is good.

----------


## LinkFX

> I'm sorry, I have just had a look at the code and it isn't in a fit state to even extract at the moment. I'm unsure if I could even do it. I used LaVolpe's alpha image code and hacked together something that is inseparable from the rest of my application rather than doing it properly as a real control. It would be unusable to you. However, I will try and extricate the code and build a proper control from it and I'll let you have it when done. I had previously intended to do that. Don't hang around though as I am rather busy with real life so I only get to code for an hour per day if I am lucky. Apologies for raising your hopes. Rather wait for Krool to respond, he is good.


No worries man, thanks for considering it though and best of luck with your control! ^-^

----------


## Arnoutdv

> Hello, 
> 
> First of all i want to thank you for your continuous effort.
> 
> are there any plans to develop a new COMCTL32.OCX compatible with Windows touch screen? I know that MSCOMCTL.OCX solves the issue, but we are hoping not to have to replace the executable in our code, but only register the OCX in the system.
> 
> Thank you.


Even if a new control is compatible with an already used control you need the recompile the application.
It has to do with references, they have of course different IDs.

----------


## Krool

> Essentially, I have a project that adds a configurable amount items to a ListView and loads a small 32x32 image file with LoadPicture to serve as the icon which gets added to the associated imagelist. In the IDE this works correctly 100% of the time, but in the compiled .exe the icons sometimes simply do not get loaded at random. Sometimes you'll open the .exe and all 3 included icons will load no problem, other times they will just be blank for all the items.
> 
> And if they do fail to load, it will keep failing to load them forever, until the program is reopened. Sometimes it will fail immediately upon launching too, and the only way around it is to launch the .EXE again. Again, in the IDE this never happens, they load correctly 100% of the time.
> 
> Moreover, if you try adding many items to the listview, you will crash (typically around 5k to 10k is when it will crash). This crashes both in the IDE and in the compiled EXE. Without the icons the listview works fine, I can add tens of thousands of items with no issues, but as soon as there are icons it crashes around that mark. *This particularly is the issue I really need fixed most.*
> 
> Attached is the source of the project that displays this bug. It's a very simple one that should be easy to understand. If you could please review it and fix this issue, I'd be incredibly grateful, as it's actually preventing me from developing another application that's suffering from the same problem.


I think the bottleneck are the GDI object count. (which I can't fix)



> GDI objects represent graphical device interface resources like fonts, bitmaps, brushes, pens, and device contexts (drawing surfaces). As it does for USER objects, the window manager limits processes to at most 10,000 GDI objects


Why you want to load 5k to 10k unique picture handles ?
Cannot you use, let's say 10 unique pictures, and re-use them for all the list items? Then it is no problem to have 20k list items having pictures which rely on 10 picture handles.
Please provide more info on your use-case. Because this is not a good design you have chosen..

----------


## LinkFX

Bingo! Thank you very much for the tip! I was not aware of this limit! Following the instructions on this page, I was able to raise that GDI limit further which completely solved that issue!

The sample project I posted only loads a single individual icon which of course doesn't make sense to make new picture handles from, but the actual application I'm having this issue in does in fact load thousands of individual icons was my point. Now that's fixed and I can load them all without problems though.  :Smilie: 

However, the issue of the icons randomly not loading still persists. Could you perhaps take a look at the sample project and see if you can figure out what's wrong and if it's somehow related to your controls? The fact that it works correctly in the IDE but randomly fails in the compiled .EXE mystifies me. 

Thanks a ton for your assistance so far Krool!  :Smilie:

----------


## Shaggy Hiker

> Good evening. Krool I believe I found a strange bug in your controls, my guess is it's the ImageList control but it may also be the ListView. I've attached a sample project that shows the bug in action.
> 
> Essentially, I have a project that adds a configurable amount items to a ListView and loads a small 32x32 image file with LoadPicture to serve as the icon which gets added to the associated imagelist. In the IDE this works correctly 100% of the time, but in the compiled .exe the icons sometimes simply do not get loaded at random. Sometimes you'll open the .exe and all 3 included icons will load no problem, other times they will just be blank for all the items.
> 
> And if they do fail to load, it will keep failing to load them forever, until the program is reopened. Sometimes it will fail immediately upon launching too, and the only way around it is to launch the .EXE again. Again, in the IDE this never happens, they load correctly 100% of the time.
> 
> Moreover, if you try adding many items to the listview, you will crash (typically around 5k to 10k is when it will crash). This crashes both in the IDE and in the compiled EXE. Without the icons the listview works fine, I can add tens of thousands of items with no issues, but as soon as there are icons it crashes around that mark. *This particularly is the issue I really need fixed most.*
> 
> Attached is the source of the project that displays this bug. It's a very simple one that should be easy to understand. If you could please review it and fix this issue, I'd be incredibly grateful, as it's actually preventing me from developing another application that's suffering from the same problem.
> ...


The attachment you had in this post included compiled code. This site does not allow that due to the potential for the inclusion of harmful items. Please remove the compiled parts and re-attach.

----------


## Krool

> Bingo! Thank you very much for the tip! I was not aware of this limit! Following the instructions on this page, I was able to raise that GDI limit further which completely solved that issue!
> 
> The sample project I posted only loads a single individual icon which of course doesn't make sense to make new picture handles from, but the actual application I'm having this issue in does in fact load thousands of individual icons was my point. Now that's fixed and I can load them all without problems though. 
> 
> However, the issue of the icons randomly not loading still persists. Could you perhaps take a look at the sample project and see if you can figure out what's wrong and if it's somehow related to your controls? The fact that it works correctly in the IDE but randomly fails in the compiled .EXE mystifies me.


Whenever you clear the imagelist (.ListImages.Clear) the hImageList changes.
The internal reason for the hImageList change is that ImageWidth/ImageHeight are "free" again. And that ultimately needs always a re-creation of the hImageList.

Therefore at end of your routine a simple re-assignment fixes the issue.


```
Set lvwTest.Icons = lvwTest.Icons
lvwTest.Redraw = True
```

*EDIT*:

The behavior of the original MS ImageList is more strict. It just throws out an error if you attempt to make .ListImages.Clear when it is already bound to a control:


However, I don't want to be so strict. With the possibility of mis-use, like you did. However, it's fix-able with a simple re-assignment.

----------


## LinkFX

> Whenever you clear the imagelist (.ListImages.Clear) the hImageList changes.
> The internal reason for the hImageList change is that ImageWidth/ImageHeight are "free" again. And that ultimately needs always a re-creation of the hImageList.
> 
> Therefore at end of your routine a simple re-assignment fixes the issue.
> 
> 
> ```
> Set lvwTest.Icons = lvwTest.Icons
> lvwTest.Redraw = True
> ...


Thank you very much for looking into my case! That makes a ton of sense.  :Smilie:

----------


## Mith

VBCCR v1.6.72 (Side-by-side)
VB6sp6 (win7x64 developing machine)

i get the VBCCR16 messagebox "Run-time error '0'" when testing my compiled app on some non-developing-pc's (WinXP(sp3), WinXPx64, Vista or Win8.1x64) and the app crashes. 
Some forms of the app are working fine using the VBCCR-controls, some show up the error message box.

The same compiled app runs without any error on my developer-pc (Win7x64) and on a test-machine with Win10x64  :Confused: 

Does anyone have some expierence with this error message when loading & displaying a form?

Any ideas how to debug this problem?

SOLUTION:

the problem was the 32bit icons of some buttons and a image-list with 32bit icons!
After changing the icons to 24bit everythings runs fine again!

----------


## Mith

Does anyone have a clue why you can use 32-bit icons with Win7 and Win10 but the app crashes using WinXP, Vista and Win8!
First i thought WinXP and Vista are too old but Win7 is older than Win8, i dont get it... :Confused: 

for example: 

Windows XP supports 32-bit icons, which are 24-bit images with an 8-bit alpha channel. 
is it vb6 that not support 32bit icons on some OS version?
or maybe you use a icon/image api that is not supported by some older OS?

----------


## Mith

VBCCR v1.6.72 (Side-by-side)
VB6sp6 (win7x64 developing machine)

The caption text of some LabelW-Controls is truncated when using the app under WinXP (SP3).
Many other Label-Controls at my app are not truncated.


The form with the Label at the IDE at Win7:



This is how the form looks using the app under WinXP:

----------


## Krool

> VBCCR v1.6.72 (Side-by-side)
> VB6sp6 (win7x64 developing machine)
> 
> The caption text of some LabelW-Controls is truncated when using the app under WinXP (SP3).
> Many other Label-Controls at my app are not truncated.


Nobody can test, when you just attach an exe file (which is NOT allowed) and no source code (Project1.vbp)
Please re-do.




> Does anyone have a clue why you can use 32-bit icons with Win7 and Win10 but the app crashes using WinXP, Vista and Win8!
> First i thought WinXP and Vista are too old but Win7 is older than Win8, i dont get it...
> 
> for example: 
> 
> Windows XP supports 32-bit icons, which are 24-bit images with an 8-bit alpha channel. 
> is it vb6 that not support 32bit icons on some OS version?
> or maybe you use a icon/image api that is not supported by some older OS?


The problem is here OleAut32.lib and it's various OleLoadPicture API's. So it's MS fault, as so often. And it also doesn't matter if creating the IPicture by an byte stream or by an Path.

What surprises me now is that Win8 also encounter the issue? (I can't test Win8)
Can you try to to make the following quick and dirty test and try to load a 32-bit icon via VB's LoadPicture ?


```
Set Pic = LoadPicture("YourPath\test.ico")
```

Your "run-time error 0" comes by following:
You load and persist successfully the 32-bit icon in a "good" OS.
The error comes then on an "bad" OS when you let VB creating the IPicture from the property bag. (design time usage in ImageList)
When you would do it only at run-time you would receive the "invalid picture" error.

I still don't know how to circumvent the issue, because since years the same question over and over re-appears.

----------


## Mith

VB example project for testing the LabelW caption text bug:
Label-Test-WinXP-sourcecode.zip

I've done a 32bit icon test with the following code under Win8.1 x64:



```
Dim pic As Variant
Set pic = LoadPicture(App.Path & "\32bit.ico")
```

Error message:

----------


## Krool

> VB example project for testing the LabelW caption text bug:
> Label-Test-WinXP-sourcecode.zip
> 
> I've done a 32bit icon test with the following code under Win8.1 x64:
> 
> 
> 
> ```
> Dim pic As Variant
> ...


For me the LabelW I see no bug. It's behaving the same as VB.Label.
Somehow your Win7 gives for the same font (Arial, Bold, 11pt) a width of 1500 twips and on your WinXP 1560. (Caption "Dateivergleich")
For me it returns both 1560 on Win7 and WinXP.

Anyhow, the safest approach is to make an "LabelW1.AutoSize = True" at run-time. (even if already True, re-applying with True will trigger a re-calculation)

Concerning your icon test. How to avoid this dilemma? Maybe a warning sign when defining 32-bit color depth for an image list at design time. Because that would explain some users up front of an potential "run time error 0". (?)

----------


## Shaggy Hiker

Thank you for attaching the source. I removed the attachment with the exe. The forum doesn't allow including compiled code because of things that have happened in the past. Source is always better anyways.

----------


## Mith

> For me the LabelW I see no bug. It's behaving the same as VB.Label.
> Somehow your Win7 gives for the same font (Arial, Bold, 11pt) a width of 1500 twips and on your WinXP 1560. (Caption "Dateivergleich")
> For me it returns both 1560 on Win7 and WinXP.


Are you sure you tested the compiled exe (SxS) or just the test project inside the IDE?

I did another test with the compiled exe using a fresh installed WinXP 64bit and the caption text is here truncated too:






> Concerning your icon test. How to avoid this dilemma? Maybe a warning sign when defining 32-bit color depth for an image list at design time. Because that would explain some users up front of an potential "run time error 0". (?)


I had a lot of command buttons with 32-bit icons at the picture property.
It was a pain in the ass to find all these controls with 32-bit icons...
i guess a warning would be very nice to avoid such problems in the future.
If someone develops a app that must also run with WinXP, Vista or Win8 he cannot use 32bit icons anywhere at the VBCCR controls.
Im not sure how & where to implement such a warning if the dev adds somewhere a 32bit icon....

----------


## Mith

Some news about the caption text bug:

1. the labels use the font "Segoe UI" and this font is not installed under WinXP!
2. i added some MS-Labels with the same text, font, font size and background color to the test project

1&3. row is VBCCR and 2&4. row is MS:



As you can see the autosize works correct with the MS-Labels.
Only the autosize of the background color is not correct.

Maybe the font fallback causes the problem with the incorrect autosizing?

New test project: Label-Test-WinXP-sourcecode.zip

----------


## Krool

> Are you sure you tested the compiled exe (SxS) or just the test project inside the IDE?
> 
> I did another test with the compiled exe using a fresh installed WinXP 64bit and the caption text is here truncated too:


I don't test ever a compiled exe. Did you read my suggestion to put a LabelW.AutoSize = True at run-time, e.g. at Form_Load.

The VB.Label behaves the same, means no automatic autosizing.
The VB.Label and LabelW will for example also do autosizing when you change the .Caption property.

----------


## Mith

> I don't test ever a compiled exe.


Why not? A compiled exe reacts different than a vb project inside the IDE!




> Did you read my suggestion to put a LabelW.AutoSize = True at run-time, e.g. at Form_Load.


Yes, but is impractical for large projects...




> The VB.Label behaves the same, means no automatic autosizing.


At my test with compiled exe the VB-Label does a correct autosizing of the the caption and the LabelW-control not!
The VB-Label shows the complete text and the LabelW-Control truncates the text at the end...
Look at the last screenshot again...

----------


## Mith

i tried your suggestion with LabelW.AutoSize = True

Before:



After:



It gets better but the letter 'e' of the word 'Profile' is still cutted at the end...

----------


## Krool

Update released.
Important for all controls.




> It gets better but the letter 'e' of the word 'Profile' is still cutted at the end...


I could now replicate the issue. Yes, the font you selected 'Segoe UI Semibold' does not exist in Windows XP.
It fallbacks to Arial, as Bold. But not with a Weight of 700, instead it is 600.
When you open the IDE first time and the fallback occurs, it happens. When you then save the project and re-open it does not happen again as the Weight was corrected by the property bag from 600 back to 700.

The problem is that the LabelW uses for display the UserControl.Font. However, for auto-sizing it creates a temporary hDC and selects a temporary hFont into it.
The fix for the LabelW was now to use 'GDIFontFromOLEFont' instead of 'CreateGDIFontFromOLEFont'. (GDIFontFromOLEFont is a small wrapper function which returns the hFont from a StdFont object via it's hidden IFont)
This approach is also better for the LabelW to have less overhead. (get the temporary hFont from the already existing IFont, instead of creating a new one and delete right after auto-size)

However, for the other controls (where a permanent hFont is needed) it could be an cosmetic issue. (though hard to see, because in your example a Weight of 600 vs 700 is not noticed easily)
The fix for the others was to change the CreateGDIFontFromOLEFont function.
(red marked text was old code and blue marked text is new code)


```
Public Function CreateGDIFontFromOLEFont(ByVal Font As IFont) As Long
[...]
If Font.Bold = True Then .LFWeight = FW_BOLD Else .LFWeight = FW_NORMAL
.LFWeight = Font.Weight
[...]
CreateGDIFontFromOLEFont = CreateFontIndirect(LF)
End Function
```

So, thanks for your report. It took a while to re-construct and find the cause.

----------


## Mith

i tested the new version .74 and i can cofirm that *manual* resizing (turning autosize off and on) fixes now the problem with the truncated text.

But why does the autosize feature of the MS label control works correct without manual resizing?
it looks like there is still something to improve/fix...

----------


## Krool

> i tested the new version .74 and i can cofirm that *manual* resizing (turning autosize off and on) fixes now the problem with the truncated text.
> 
> But why does the autosize feature of the MS label control works correct without manual resizing?
> it looks like there is still something to improve/fix...


I don't think the VB.Label will trigger an auto-size in case of an Font fallback. Indicator for me is the background not sized accordingly on the VB.Label. it just draw beyond the border due to DT_NOCLIP. (LabelW uses also DT_NOCLIP, so normally same result should be seen)

Can you make a test with VB.Label as following:
1.In Win7 in IDE set AutoSize = True and then enlarge afterwards the width.
2. Compile
3. Test on WinXp. Is the Width shortened due to the font fallback and autosize?

Thanks

----------


## pepegriyo2016

Delete post

----------


## pepegriyo2016

Delete post

----------


## SuperDre

> Does anyone have a clue why you can use 32-bit icons with Win7 and Win10 but the app crashes using WinXP, Vista and Win8!
> First i thought WinXP and Vista are too old but Win7 is older than Win8, i dont get it...
> 
> for example: 
> 
> Windows XP supports 32-bit icons, which are 24-bit images with an 8-bit alpha channel. 
> is it vb6 that not support 32bit icons on some OS version?
> or maybe you use a icon/image api that is not supported by some older OS?


Yeah, I had that problem too.. Now I just use 256 color Icons (use a good color downgrader) for the forms itself from within VB and for all the icons I want in full color I have an resource attached to the project and load that icon through the API and connect it to the form, that doesn't seem to give me a problem on any system. 
So it's partly a problem with VB6 itself.
But now I've updated my development enviroment to Windows 10, we have said we don't support Windows 7 or below anymore, if something happens we will try for a moment if we can easily fix it, but we won't spend time anymore on actually testing it on the older platforms anymore. Windows 7 and older are really safe anymore. So if it works it's ok, if it doesn't the client is just out of luck and should upgrade to windows 10 (they have had more than enough time by now).

----------


## SuperDre

> Does anyone have a clue why you can use 32-bit icons with Win7 and Win10 but the app crashes using WinXP, Vista and Win8!
> First i thought WinXP and Vista are too old but Win7 is older than Win8, i dont get it...
> 
> for example: 
> 
> Windows XP supports 32-bit icons, which are 24-bit images with an 8-bit alpha channel. 
> is it vb6 that not support 32bit icons on some OS version?
> or maybe you use a icon/image api that is not supported by some older OS?


Yeah, I had that problem too.. Now I just use 256 color Icons (use a good color downgrader) for the forms itself from within VB and for all the icons I want in full color I have an resource attached to the project and load that icon through the API and connect it to the form, that doesn't seem to give me a problem on any system. 
So it's partly a problem with VB6 itself.
But now I've updated my development enviroment to Windows 10, we have said we don't support Windows 7 or below anymore, if something happens we will try for a moment if we can easily fix it, but we won't spend time anymore on actually testing it on the older platforms anymore. Windows 7 and older are really safe anymore. So if it works it's ok, if it doesn't the client is just out of luck and should upgrade to windows 10 (they have had more than enough time by now).

----------


## Krool

Update released.

A nice-to-have "niche" feature included in the ListView control.

The new ShowColumnTips property controls now if a tooltip control (with 1 callback based item) is created for the header control.

The ColumnHeader has 3 ToolTipText related properties now.
- ToolTipText
- ToolTipTextFilterBtn
- ToolTipTextDropDown

The rule is simple:
if on filter button zone use ToolTipTextFilterBtn, if on drop-down (split)button zone use ToolTipTextDropDown, else ToolTipText.
The filter value/edit and divider drag zone is excluded for any ToolTipText.

----------


## pepegriyo2016

Hello @Krool,
I suggest you use the following VBAddin
https://github.com/rubberduck-vba/Rubberduck

Regards,
P

----------


## sbri

Krool,
I think I have found a difference between the standard Label control and the LabelW.
The LabelW is not printed when you call the PrintForm method of a form, while the standard label is printed.
Attached a sample project.
Thank you.

FormPrint.zip

----------


## Krool

One of the last milestone to have this project as a clean and straightforward solution is to remove the WM_MOUSEACTIVATE handlers.

Typical example:


```
Case WM_MOUSEACTIVATE
    Static InProc As Boolean
    If TextBoxTopDesignMode = False And GetFocus() <> TextBoxHandle Then
        If InProc = True Or LoWord(lParam) = HTBORDER Then WindowProcControl = MA_ACTIVATEANDEAT: Exit Function
        Select Case HiWord(lParam)
            Case WM_LBUTTONDOWN
                On Error Resume Next
                With UserControl
                If .Extender.CausesValidation = True Then
                    InProc = True
                    Call ComCtlsTopParentValidateControls(Me)
                    InProc = False
                    If Err.Number = 380 Then
                        WindowProcControl = MA_ACTIVATEANDEAT
                    Else
                        SetFocusAPI .hWnd
                        WindowProcControl = MA_NOACTIVATE
                    End If
                Else
                    SetFocusAPI .hWnd
                    WindowProcControl = MA_NOACTIVATE
                End If
                End With
                On Error GoTo 0
                Exit Function
        End Select
    End If
```

I always disliked this solution because of the overhead to determine the top design mode and emulate the validation via ComCtlsTopParentValidateControls.

However, I found now a solution to avoid the cumbersome WM_MOUSEACTIVATE (in fact it was just too simple..)

The new solution is to process WM_LBUTTONDOWN prior to the default window proc to set focus to the UserControl.
(if that happens VB took already care of the validation process by itself)
Then when the default window proc processes WM_LBUTTONDOWN, it sets the focus to the real control.

That's it. I updated now CheckBoxW/CommandButtonW/OptionButtonW/CommandLink.
VBFlexGrid also got updated.

However, the other (more complex) controls will follow in phases and in successive updates to have more time to ensure correct behaviors.

----------


## xxdoc123

i have a error

when i used  VBCCR16.OCX 1.6.0.74  and VBCCR16SideBySideAndVisualStyles.res.

DTPicker1 have a bug

right open the Property page -mousepointer -Choose an option at random -click font ,err 

---------------------------
VBCCR16
---------------------------
Runtime error '0'
---------------------------

In some computers when i close the project be err

Question signature:
   Problem Event Name: APPCRASH
   App name: xxxxx.exe
   Application version: 1.0.0.0
   Application time stamp: 5e91c40f
   Fault module name: comctl32.DLL_unloaded
   Faulty module version: 0.0.0.0
   Fault module time stamp: 553a8345
   Exception code: c0000005
   Abnormal offset: 73beb8e1
   OS version: 6.1.7601.2.1.0.256.1
   Locale ID: 2052
   Additional information 1: 8450
   Additional information 2: 8450d023fd181a791e73b6aee2fda96d
   Additional information 3: 9911
   Other Information 4: 9911318d37447f2f9004eb2bbc943537

can not used xp style

<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>

----------


## Mith

> I don't think the VB.Label will trigger an auto-size in case of an Font fallback. Indicator for me is the background not sized accordingly on the VB.Label. it just draw beyond the border due to DT_NOCLIP. (LabelW uses also DT_NOCLIP, so normally same result should be seen)
> 
> Can you make a test with VB.Label as following:
> 1.In Win7 in IDE set AutoSize = True and then enlarge afterwards the width.
> 2. Compile
> 3. Test on WinXp. Is the Width shortened due to the font fallback and autosize?
> 
> Thanks


No, the manual resized width doesnt autosize when running the exe:

I used a single 2D border style to get a better view of the real label size.
single 2D border style = LabelW
NO single 2D border style = MS Label

With autosize=True and without the manual resizing of the label width it looks like this:

There is still a problem with the calculation of the correct text width...

i run the new tests with v1.6.77

----------


## Mith

VBCCR 1.6.77
VB6SP6

When using the TreeView under WinXP a large unnecessary horizontal scrollbar shows up:

Windows 7:


WinXP SP3:


Sample Project:
TreeView.zip

----------


## Krool

> I think I have found a difference between the standard Label control and the LabelW.
> The LabelW is not printed when you call the PrintForm method of a form, while the standard label is printed.


I don't know what is important for the PrintForm so that it decides to print something. So I can't help you on that.
However, many sources in the internet advises to use NOT the PrintForm method as it's very buggy.




> DTPicker1 have a bug
> 
> right open the Property page -mousepointer -Choose an option at random -click font ,err


I tested and couldn't replicate..




> There is still a problem with the calculation of the correct text width...


No, it's not. It's a problem with the font fallback. (due to that semi-bold is not supported in WinXP, even the VB.Label is not sized correctly)

You can simply fix it when doing a .AutoSize = True during Form_Load.




> When using the TreeView under WinXP a large unnecessary horizontal scrollbar shows up:


You have the .Scroll property to True. (True = TVS_NOSCROLL not applied)
So Win7 is handling it better than WinXP. If it annoys you on WinXP simply set the .Scroll property to False.[/QUOTE]

----------


## Mith

> You have the .Scroll property to True. (True = TVS_NOSCROLL not applied)
> So Win7 is handling it better than WinXP. If it annoys you on WinXP simply set the .Scroll property to False.


The .Scroll property must be set to TRUE. Otherwise no scrollbar is displayed if needed.

I tested the treeview with *Vista (32bit)* too, same result, a horizontal scrollbar is displayed:


Same when testing the treeview with *Win8.1 x64*:


The question is why is the horizontal scrollbar displayed if not needed?

----------


## Mith

i also tested the treeview problem with Win10 and guess what, same problem:


I added a new treeview to the form and voila, no scrollbar problem:


BUT after i set *.Checkboxes = true* then scrollbar appears again:


there must be something wrong with the calculation for the scrollbars when activating the checkboxes...

----------


## Mith

> No, it's not. It's a problem with the font fallback. (due to that semi-bold is not supported in winxp, even the vb.label is not sized correctly)


Thats not correct. the caption text of the vb.label is sized correctly:

Only the border and the background area is not sized correctly.
So no problem in normal circumstances when you use a transparent vb.label.

I just wish the LabelW has the same behaviour as the MS.label: no caption text clipping.
the VB.label uses the width of the caption text for the control width.
for me it looks like you use the clipped rect size of the background when you define the control width.
maybe you can change this at the source code?

----------


## Krool

> I added a new treeview to the form and voila, no scrollbar problem:
> 
> BUT after i set *.Checkboxes = true* then scrollbar appears again:
> 
> there must be something wrong with the calculation for the scrollbars when activating the checkboxes...


Update released.

Indeed the .Checkboxes was the cause.

According to MSDN:



> The TVS_CHECKBOXES style must be set with SetWindowLong after the tree view control is created.


So in the internal CreateTreeView method the TVS_CHECKBOXES is not supplied now in the CreateWindowEx, but rather set afterwards via SetWindowLong.
This change fixes your scrollbar issue.

----------


## Mith

> Update released. Indeed the .Checkboxes was the cause.
> This change fixes your scrollbar issue.


Confirmed! The new version 1.6.79 fixes the scrollbar issue!
Thank you very much for the fast update!

----------


## Krool

> I just wish the LabelW has the same behaviour as the MS.label: no caption text clipping.


Again you are absolutely right. Update released.

If the .AutoSize property is True the VB.Label has a NULL clipping region. Otherwise normal clipping region.



The new code (blue) in the paint routine:


```
Dim hRgn As Long
If PropAutoSize = True Then
    ' Temporarily remove the clipping region in this case.
    hRgn = CreateRectRgn(0, 0, 0, 0)
    If hRgn <> 0 Then
        If GetClipRgn(.hDC, hRgn) = 1 Then
            SelectClipRgn .hDC, 0
        Else
            DeleteObject hRgn
            hRgn = 0
        End If
    End If
End If
DrawText .hDC, StrPtr(Buffer), -1, RC, Format Or DT_MODIFYSTRING
If hRgn <> 0 Then
    SelectClipRgn .hDC, hRgn
    DeleteObject hRgn
    hRgn = 0
End If
```

----------


## Mith

> Again you are absolutely right. Update released.
> If the .AutoSize property is True the VB.Label has a NULL clipping region. Otherwise normal clipping region.


I confirm that the label text clipping problem is fixed!

Let's move on to the next problem:

I use a ImageCombo with the Style = ImcStyleDropDownList.
After i select a new icon item from the DropDownList the Change-event is not triggered.
Is this a bug or how to know the user changed the selected item for this control?

----------


## Mith

> Update released.
> 
> A nice-to-have "niche" feature included in the ListView control.
> 
> The new ShowColumnTips property controls now if a tooltip control (with 1 callback based item) is created for the header control.
> 
> The ColumnHeader has 3 ToolTipText related properties now.
> - ToolTipText
> - ToolTipTextFilterBtn
> - ToolTipTextDropDown


I cant find the new property ShowColumnTips and the new ColumnHeader  properties:

----------


## Krool

> I confirm that the label text clipping problem is fixed!
> 
> Let's move on to the next problem:
> 
> I use a ImageCombo with the Style = ImcStyleDropDownList.
> After i select a new icon item from the DropDownList the Change-event is not triggered.
> Is this a bug or how to know the user changed the selected item for this control?


The change event is only triggered in a ImageCombo or ComboBoxW when it gets CBN_EDITCHANGE.

For a style DropDownList use the Click event. (CBN_SELCHANGE)

The behavior for a VB.ComboBox is the same.




> I cant find the new property ShowColumnTips and the new ColumnHeader  properties:


It's only availabe for the StdEXE version and foreseen for the upcoming VBCCR17. But a few things must still be done before releasing a VBCCR17..

----------


## Mith

> The change event is only triggered in a ImageCombo or ComboBoxW when it gets CBN_EDITCHANGE.
> 
> For a style DropDownList use the Click event. (CBN_SELCHANGE)
> 
> The behavior for a VB.ComboBox is the same.


Ok, now i use the TAG property to store the last selected item index and compare this value when the Click-Event fires with the new selected item index.
So i will know the user changed the settings or not.

----------


## vb56390

Hi, Krool, thanks for the VBCCR controls.

Report a few bug to you

1. The Mouse_Enter and Mouse_Leave event seems not work very well in CommandButtonW and FrameW control(perhaps some other controls else)
2. When I set a toolbar control to a coolbar as a child, then the toolbar couldn't transparent, the backcolor of toolbar also couldn't work
3. If I using the manifest to set system therme, some of controls just like toolbar and coolbar couldn't set backcolor

----------


## Krool

> Hi, Krool, thanks for the VBCCR controls.
> 
> Report a few bug to you
> 
> 1. The Mouse_Enter and Mouse_Leave event seems not work very well in CommandButtonW and FrameW control(perhaps some other controls else)
> 2. When I set a toolbar control to a coolbar as a child, then the toolbar couldn't transparent, the backcolor of toolbar also couldn't work
> 3. If I using the manifest to set system therme, some of controls just like toolbar and coolbar couldn't set backcolor


1. Can't confirm. For me it works. Please be more precise what is not working on your side.

2. Yes, any control with a (fake)Transparency won't work in the CoolBar.

3. On CoolBar, read the Description of the BackColor property. As you also see, the ToolBar just works fine with BackColor property.

----------


## Krool

Update released.

The IPAddress control does not rely anymore on the buggy and very limited SysIPAddress32 class.

Instead everything is done from scratch within the UserControl and with 4 internal edit controls.

The behavior and usage is 100% mimic to the SysIPAddress32, but looks and feels more "VB-ish" now.

Some details..
- New BackColor and BorderStyle property.
- UserControl_Resize does not need a re-creation. (limitation in SysIPAddress32 as MoveWindow API does not work)
- ForeColor property also effects now the three dots.
- New Locked property.
- New RightToLeft property. (just for completeness)
- 'FieldChange' event renamed to 'SelChange'.
  And 'SelChange' has no parameter anymore. Instead use new .SelectedItem property.
- 'Address' property renamed to 'Text'.
- 'Value' property not read-only anymore. (Let also supported)
- SetFocusToField method removed.
  Instead use IPAddress1.SetFocus and then IPAddress1.SelectedItem = x
- IsEmptyField function and FieldValue property removed without any replacement.
  Can all be replicated via the .Text property. (for simplicity)
- Design time property page included.
- New 'AutoSelect' property for keyboard focus control:
  "0 - None" will retain focus to .SelectedItem.
  "1 - First" always focus first item. (default)
  "2 - Second" always focus second item.
  "3 - Third" always focus third item.
  "4 - Fourth" always focus fourth item.
  "5 - Blank" will focus first blank item. If all are non-blank then focus first item.
  Of course any mouse button focus overrides it and the item under mouse will be selected.

Info: VBCCR16.OCX does not benefit from this (compatibility).

----------


## LaVolpe

@Krool. Suggestion if not already being done.

Any changes you make to enhance/redesign a Windows class, recommend ensuring the updated control will honor windows messages designed for that windows class.

----------


## Krool

> @Krool. Suggestion if not already being done.
> 
> Any changes you make to enhance/redesign a Windows class, recommend ensuring the updated control will honor windows messages designed for that windows class.


Yes, of course. Should have come to this by my own.. Thanks. Updated again.

So, the UserControl (IPAddress1.hWnd) responds now 1:1 like the SysIPAddress32 to the following messages:


```
IPM_CLEARADDRESS As Long = (WM_USER + 100)
IPM_SETADDRESS As Long = (WM_USER + 101)
IPM_GETADDRESS As Long = (WM_USER + 102)
IPM_SETRANGE As Long = (WM_USER + 103)
IPM_SETFOCUS As Long = (WM_USER + 104)
IPM_ISBLANK As Long = (WM_USER + 105)
```

----------


## Mith

i found a another bug using the CommandW control:

At the Click-Event of a CommandW control i starting a function of another control (3rd Party Folder-/FileView-Control) to create a new folder at a Folder-Tree.
The other control gets the focus, the Click-Event of a CommandW control ends, a new tree node is created and the edit mode is started to enter the name of the new node.



The Bug: Every time i press Enter/Return to accept the new node name the Click-Event of the CommandW is triggered again and a new node is created again!

I verified this with the MS Command Button control: no Click-Event looping!

Any ideas why the CommandW control still catches the Enter-key without having the focus?

----------


## vb56390

oh,sorry
Here are my computer's environment information
Windows 7 x64 ultimate sp1
I7 core 7700HQ CPU
VB6 simplified-Chinese sp6(build 9782) using system theme by a manifest file
The toolbar can set BackColor in design mode, but when I debug to run the program , it didn't work, a compiled exe also.

----------


## Krool

> Any ideas why the CommandW control still catches the Enter-key without having the focus?


Do you have the CommandW.Default = True ? My assumption is that the 3rd Party Folder-/FileView-Control does not EAT the Enter-Key when in edit mode.
Please provide demo project for further investigation.




> The toolbar can set BackColor in design mode, but when I debug to run the program , it didn't work, a compiled exe also.


Please provide a simple demo project showing the problem.

----------


## Elroy

Say Krool,

Could I ask for a small change to the *ComCtlsBase* module?  In the *ComCtlsSetSubclass* procedure, you've got the module name mentioned so that the AddressOf operator will work correctly.  It's done in two places in that module:



```
Public Function ComCtlsSubclassProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Select Case wMsg
    Case WM_DESTROY
        ComCtlsSubclassProc = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
        Exit Function
    Case WM_NCDESTROY, WM_UAHDESTROYWINDOW
        ComCtlsSubclassProc = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
        If ComCtlsW2KCompatibility() = False Then
            RemoveWindowSubclass hWnd, AddressOf ComCtlsBase.ComCtlsSubclassProc, uIdSubclass
        Else
            RemoveWindowSubclass_W2K hWnd, AddressOf ComCtlsBase.ComCtlsSubclassProc, uIdSubclass
        End If
        Exit Function
End Select
On Error Resume Next
Dim This As ISubclass
Set This = PtrToObj(uIdSubclass)
If Err.Number = 0 Then
    ComCtlsSubclassProc = This.Message(hWnd, wMsg, wParam, lParam, dwRefData)
Else
    ComCtlsSubclassProc = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
End If
End Function
```

I realize that it would take a couple of "helper" functions, but the reference to the module name could be eliminated as follows:



```
Public Function ComCtlsSubclassProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Select Case wMsg
    Case WM_DESTROY
        ComCtlsSubclassProc = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
        Exit Function
    Case WM_NCDESTROY, WM_UAHDESTROYWINDOW
        ComCtlsSubclassProc = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
        If ComCtlsW2KCompatibility() = False Then
            RemoveWindowSubclass hWnd, AddressOfComCtlsSubclassProc, uIdSubclass
        Else
            RemoveWindowSubclass_W2K hWnd, AddressOfComCtlsSubclassProc, uIdSubclass
        End If
        Exit Function
End Select
On Error Resume Next
Dim This As ISubclass
Set This = PtrToObj(uIdSubclass)
If Err.Number = 0 Then
    ComCtlsSubclassProc = This.Message(hWnd, wMsg, wParam, lParam, dwRefData)
Else
    ComCtlsSubclassProc = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
End If
End Function

Private Function AddressOfComCtlsSubclassProc()
    AddressOfComCtlsSubclassProc = ProcedureAddress(AddressOf ComCtlsSubclassProc)
End Function

Private Function ProcedureAddress(AddressOf_TheProc As Long) As Long
    ProcedureAddress = AddressOf_TheProc
End Function
```

The reason I ask is that I find myself often using "pieces" of your project.  And, for organizational purposes, I like to rename your modules.  For example:



Sure, I can easily fix it when I rename your modules, but I don't like tampering with your source code.  Also, when I grab one of your updates, I also have to remember and make this little patch-up.  If you were to make this suggested change, it would obviate any need for me to patch-up your source code.

Obviously, not a major request.  Just, if you happen to be thinking about it when you're in there, this change would be appreciated.

Again, FABULOUS work.

Take Care,
Elroy

----------


## Krool

Just updated the ListView so no WM_MOUSEACTIVATE handler anymore needed. (was used in the past for Validation workaround..)

It's not a small improvement. For demonstration just compare the two below clips.
1. scrolling the scrollbar with the mouse does not cause a focus change anymore.
2. Initial click which cause change a focus does not start LabelEdit.
Reason was that the previous WM_MOUSEACTIVATE handler did the focus change already.
So SysListView32 thought "oh, a click on the current selected item and control already has focus -> start label edit".
Now the focus change is upon WM_LBUTTONDOWN and the SysListView32 thinks now "oh, a click on the current selected item, but control has not focus yet -> change focus first (if the user clicks again then start label edit)".

before (old)


after (new)

----------


## Krool

> I realize that it would take a couple of "helper" functions, but the reference to the module name could be eliminated


Good idea. In next occasion I will change that.

----------


## LaVolpe

> Good idea. In next occasion I will change that.


Just my 2 cents - why have a subclass procedure call two other functions before returning from its call, for this reason? I'd almost suggest creating a module-level variable and set its value and use it inside the procedure instead of calling two more unneeded functions (if even making the change at all)

----------


## Mith

> Do you have the CommandW.Default = True ?


no




> My assumption is that the 3rd Party Folder-/FileView-Control does not EAT the Enter-Key when in edit mode.


Why is everyting fine when i use the standard VB command button control?
This tells me there must be something wrong with the subclassing of the key events or how is it possible that the Click-Event triggers again after i pressed the Enter-key inside another control?




> Please provide demo project for further investigation.


Can i include the OCX of the 3rd party control?

----------


## Krool

> Can i include the OCX of the 3rd party control?


Is it free? Where could i download it?

----------


## pepegriyo2016

Hello,
Bug:
On the button, when you add a picture, the "style" property does not change to "vbButtonGraphical"

----------


## Elroy

> Just my 2 cents - why have a subclass procedure call two other functions before returning from its call, for this reason? I'd almost suggest creating a module-level variable and set its value and use it inside the procedure instead of calling two more unneeded functions (if even making the change at all)


I thought about speed as well, but Krool is only making those calls when the window is being destroyed.  So, it's not calling those functions every time through the subclassing procedure.  Either way is fine with me.  I just thought it would be a little nicety for me and maybe others who organize their module names like I do.

----------


## pepegriyo2016

The Name of Variable is different in Original Texbox of Microsoft

El nombre de la variable de TextBox original de Microsoft es *KeyAscii*



```
Private Sub Text1_KeyPress(KeyAscii As Integer)

End Sub
```



In this project the name of variable is *KeyChar* in event KeyPress



```
Private Sub TextBoxW1_KeyPress(KeyChar As Integer)

End Sub
```

----------


## Krool

> Hello,
> Bug:
> On the button, when you add a picture, the "style" property does not change to "vbButtonGraphical"


It's not a bug. You can have a picture assigned with either style, normal or graphical.

----------


## Mith

> Is it free? Where could i download it?


No, its not for free but you can download a free test version at this website: FolderView ActiveX Control

VB example project: test - Command button.zip

----------


## Krool

> The Name of Variable is different in Original Texbox of Microsoft
> 
> El nombre de la variable de TextBox original de Microsoft es *KeyAscii*
> 
> 
> 
> ```
> Private Sub Text1_KeyPress(KeyAscii As Integer)
> 
> ...


That's absolutely not harmful.
VB6 events do not care about param names as long as the types are correct. So any migration won't fail.
If you add new events then the name is 'KeyChar' but if you want you can rename to 'KeyAscii' in the form. It will succeed.

----------


## Krool

> I thought about speed as well, but Krool is only making those calls when the window is being destroyed.  So, it's not calling those functions every time through the subclassing procedure.  Either way is fine with me.  I just thought it would be a little nicety for me and maybe others who organize their module names like I do.


Yes, should not be a big deal. Anyhow, I updated now ComCtlsBase.bas (and VBFlexGridBase.bas) to not to reference itself.
It's done now as LaVolpe suggested with an internal module variable.

----------


## Krool

> No, its not for free but you can download a free test version at this website: FolderView ActiveX Control
> 
> VB example project: test - Command button.zip


Ok, I installed it on a dummy VM and could replicate it.

The reason is that VB6 still thinks the UserControl is active and sends UserControl_AccessKeyPress on CommandButtonW.

So be patient, solution will come.

----------


## Krool

Update released.

Forgot to include WM_KILLFOCUS DeActivateIPAO on CheckBoxW/CommandButtonW/CommandLink/LinkLabel/OptionButtonW.

@ Mith, your issue is now fixed.. Thanks for pointing out.

----------


## pepegriyo2016

Hello Krool,
Object IPAddress in .ocx.

Exist the .Address Property 

In Exe Module, exist .Text or .Value

Could You check this?

----------


## Krool

> Hello Krool,
> Object IPAddress in .ocx.
> 
> Exist the .Address Property 
> 
> In Exe Module, exist .Text or .Value
> 
> Could You check this?


Yes, it was changed on 17-Apr-2020. Once VBCCR17 will be released the OCX and Exe are in Sync then again..

----------


## pepegriyo2016

Hello Krool,
I'am using the last version:

----------


## pepegriyo2016

Delete Post

----------


## pepegriyo2016

Krool,

If your insert a Frame and inside insert a TextBoxW, when you change Frame.Enabled=False, the TexBox have the cursor inside.
I have fixed this



```
SendKeys vbTab
```

TextBoxW is Multiline and Scrooll=Both

----------


## Mith

> Update released.
> 
> Forgot to include WM_KILLFOCUS DeActivateIPAO on CheckBoxW/CommandButtonW/CommandLink/LinkLabel/OptionButtonW.
> 
> @ Mith, your issue is now fixed.. Thanks for pointing out.


I can confirm this. The problem is solved.
The focus stays now inside the other control.

Well done!!

----------


## Elroy

> Yes, should not be a big deal. Anyhow, I updated now ComCtlsBase.bas (and VBFlexGridBase.bas) to not to reference itself.
> It's done now as LaVolpe suggested with an internal module variable.


Thank you.   :Smilie:

----------


## vb6forever

Krool:

I'm still using VB5 but would like to use _W versions (your controls).
Per your #3 Post:



> Only the common controls 5.0 from MS are linked to the comctl32.dll, but the COM hull is very old and so they have a leak of the latest functions and properties. Also controls like the DTPicker, MonthView or UpDown are not included.


Any issues with using your controls with VB5, and if so (issues), is there a workaround?

Thanks
David

----------


## Mith

Feature request for the Progress Bar:

Is it maybe possible to add a .text/.caption or a .DisplayPercentage property to display the current percentage inside the progress bar?

I currently use my own progress bar usercontrol with this feature but i want/try to transfer all controls used in my project to VBCCR if possible...

----------


## Mith

Im using the following code to auto size each column in my ListView:



```
.AutoSize (LvwColumnHeaderAutoSizeToItems Or LvwColumnHeaderAutoSizeToHeader)
```

Result:



How can i avoid the stretching of the last column to the end of the control ?


I want that the autosize of the last column is the same like all other columns:



Is there maybe another flag availble to change this behavior?

----------


## LaVolpe

> Any issues with using your controls with VB5, and if so (issues), is there a workaround?


There are significant differences between usercontrols in VB5 & VB6, and of course some v6 functions that didn't exist in v5. However, that doesn't mean that Krool's controls are using something incompatible with VB5. You should simply try it and report back on success or failure. You might want to  do a quick scan for "vba6.dll" and replace with "vba5.dll" first.

----------


## vb6forever

LaVolpe:
LaVolpe:  Thanks for responding.




> You should simply try it and report back on success or failure.


My Bad.   Had hoped someone had already put forth the effort.
Probably wasting my time, but trying to move all code as much as possible to API usage in case M$ pulls the plug on Classic
hoping I might have a better shot at portability to something else.

----------


## Semke

toolbar question:
does the toolbar have a DC? reason I am asking, because I would like to print text on the toolbar mainly on placeholders (without the need to add a picturebox on it)

----------


## Semke

StatusBar


```
StatusBar.Panels("aPanel").Width = lWidth
```

returns error 383:Property is read-only 
in the MS Controls this was Read/Write

----------


## Krool

> Any changes you make to enhance/redesign a Windows class, recommend ensuring the updated control will honor windows messages designed for that windows class.


For the FrameW I added the handlers WM_SETTEXT/WM_GETTEXT/WM_GETTEXTLENGTH now.

Because..
just remembered that from 03-Jul-2017 onwards the FrameW renders now directly on the UserControl, without resorting to BS_GROUPBOX window.

_Like it was done recently with the IPAddress control. (not resorting to SysIPAddress32)_

----------


## smileyoufucn

VB6:
Private Sub ctTextBox_GotFocus()
 
End Sub

Private Sub ctTextBox_LostFocus()

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Suggest adding events：

Private Sub ctTextBoxW_GotFocus()
 ''''
End Sub

Private Sub ctTextBoxW_LostFocus()


''''
End Sub

----------


## Caine

> Im using the following code to auto size each column in my ListView:
> 
> 
> 
> ```
> .AutoSize (LvwColumnHeaderAutoSizeToItems Or LvwColumnHeaderAutoSizeToHeader)
> ```
> 
> Result:
> ...


Just don't use LvwColumnHeaderAutoSizeToHeader with the last column. According to MSDN "If you use this value with the last column, its width is set to fill the remaining width of the list-view control".

----------


## Mith

> Just don't use LvwColumnHeaderAutoSizeToHeader with the last column. According to MSDN "If you use this value with the last column, its width is set to fill the remaining width of the list-view control".


Using only _LvwColumnHeaderAutoSizeToItems_ doesnt help, because the last column will look like this if the item text is smaller than the header caption:



It looks like there is no solution to set the width of the last column like this:

IF header caption > items width THEN use header width
IF items width > header caption THEN use items width

----------


## Krool

Bugfix in the GetClipboardText function (CF_UNICODETEXT clipboard) in the Common.bas.

As maybe some make use of my Common.bas I think I need to report this quite crucial bugfix.

The bug was in fact that, for the string length determination, the function GlobalSize of the memory block was used.
In most cases, this was really the length of the string.
However, for example MS Excel applies for very large copy blocks a bigger memory block than actually needed, which resulted in garbade trailing chars.
Large copy blocks from MS Notepad always apply the memory block just perfect. However, MS Excel seems to be a bit sloppy. (probably due to a internal "ReDim style" chunk increase efficiency)

So, instead of GlobalSize the lstrlen function is used (after GlobalLock) for the string length determination. This of course cut-offs any in-between null chars.
However, the VB.Clipboard.GetText(vbCFText) function behaves the same as it also cut-offs any in-between null chars.

----------


## pepegriyo2016

Hello Krool,
I'am using the last version of OCX (1.6.0.93) and Source Code (26-Apr-2020)







With images it is easier to understand

----------


## Krool

Update released.

Bugfix for the ListView control.

*1.*
When inserting the very first item in a ListView control, the focus is automatically set to it. (Index = 1)
However, the ItemFocus event was not fired.

The bug lied in LvwListItems.cls in the .Add function.
FListItemsAdd was called which led the control to set focus to the first item. However, problem was that the LvwListItems collection did not yet include that item. That was the reason ItemFocus event did not fire.
Now the order is changed, first include new item to the collection and then let SysListView32 add new item.

New


```
If Key = vbNullString Then
    PropListItem.Add NewListItem
Else
    PropListItem.Add NewListItem, Key
End If
ShadowListView.FListItemsAdd Ptr, Index, Text
```

Old


```
ShadowListView.FListItemsAdd Ptr, Index, Text
If Key = vbNullString Then
    PropListItem.Add NewListItem
Else
    PropListItem.Add NewListItem, Key
End If
```

But watch out because the ItemFocus event is now firing when inserting the very first ListItem. Any possible ListSubItem does not yet exist. So, it's anyway a safe advise to check the existense of any subitems first when handling ItemFocus event. (if subitems are needed at all for handling ItemFocus event, depends on your app.)
But that's the same behavior as the ItemSelect event. (which fired before already at very first ListItem, depending on the AutoSelectFirstItem property)

*2.*
When clearing the list view the ItemFocus event fired with an Item parameter as Nothing. This was clearly a mis-feature.
The ItemSelect event also did not fire at that point. When an event is firing the parameter must be valid and cannot be Nothing.




> I'am using the last version of OCX (1.6.0.93) and Source Code (26-Apr-2020)
> 
> With images it is easier to understand


For the IPAddress there is currently a mismatch between the OCX and Std-EXE version.
Reason is that it was completely re-done from scratch to make it "VB-ish". (update 17-Apr-2020)
So for the OCX to be using the new component it is necessary to wait until VBCCR17.

----------


## pepegriyo2016

Hello Krool,

The ForeColor in object "CheckboxW" is not working. I set the color "&H00FF0000&" in design mode and the color is not show . Runtime does not work either.

----------


## Krool

> Hello Krool,
> 
> The ForeColor in object "CheckboxW" is not working. I set the color "&H00FF0000&" in design mode and the color is not show . Runtime does not work either.


Do you have theming enabled?

----------


## pepegriyo2016

Hello Krool,




> Do you have theming enabled?


yes

----------


## Krool

> Hello Krool,
> 
> 
> yes


The ForeColor works only when un-themed or style = graphical.

----------


## Krool

Update released.

Internal improvement for the OptionButtonW control. (actually a bugfix)

The problem was that I thought that the OLE_OPTEXCLUSIVE must be triggered via UserControl.PropertyChanged "Value" only for the TRUE value.
However, that works as long as the order is "sequential" in the .frm file. Now the OLE_OPTEXCLUSIVE will be triggered in either case.

Best to explain in pictures. In Frame1 the order in the .frm file is first W3 then W4.
But in Frame2 the order in the .frm file is also W5 and then W6. However, W6 was put then afterwards before W5 and the TabIndex was changed.
Both W3 and W6 are pre-defined with value TRUE at design time. (important for the test)

Now compare the behavior when simply "tabbing" through.

Before:


After:

----------


## IliaPreston

Hi Krool.

Thanks again for the great unicode-aware combo box.

If you remember, in post #57 under http://www.vbforums.com/showthread.p...ombo-box/page2, I requested some changes:
1. bas module renames (both the module name itself in the IDE and the file name) to have a "ComCtls" or "CC" prefix.
2. class module renames (both the class module name itself in the IDE and the file name) to have a "ComCtls" or "CC" prefix.
3. folder name changes: All four folders (Builds, Common, OLEGuids and Resources) to have a "ComCtls" or "CC" prefix in their names.
4. Creation of one separate folder called Demo, so that every file and folder that is only part of the demo be moved in there.
For example all the frm and frx files as well as the ComCtlsDemo.vbp and ComCtlsDemo.vbw and some other files and also the entire folder "Resources" need to be moved under the Demo folder.
Or for another example, why is the Startup.bas module currently under the "Common" folder? It only belongs in the demo, so it shouldn't be there.
Not sure if you ever had a chance to review my suggestions or not, because you haven't responded to them yet.
And I don't know if I should continue to wait for a response or not.

But, I believe there are good reasons to have those changes:
1. The programmer may have bas and class modules by the same name in his own vbp project and there will be a conflict or at least a confusion.
2. Currently with every new release of the ComCtls, the programmer has to do all of these renamings and relocations himself. But, if all these changes were made in the ComCtls package itself, with each new release of a new version of ComCtrls, the programmer could simply download the new package, unzip it and overwrite the old files and folders with the files and folders from the newly released package. Currently, it is not just download, unzip and overwrite. Currently it is a bit of a painful job to do all of necessary steps to replace the old version with the new one.
3. The programmer may unnecessarily add the demo forms and the Startup.bas to his own project.
4. There is real value for any package to be very well organized.
5. Other reasons.
The ComCtls that you have developed are really world-class stuff, and this causes people to expect that they be very well organized.
That is why I am requesting these changes.
Just my humble opinion.

If you don't agree with me or don't want to make these changes for any reason, that would be understandable.
But, at lease a response (even a "No" response would be greatly appreciated.
You never responded to my request, so I am still in the dark as to what will happen.

Once again, thanks a lot for these great controls.
Ilia

----------


## Krool

> If you remember, in post #57 under http://www.vbforums.com/showthread.p...ombo-box/page2, I requested some changes:
> 1. bas module renames (both the module name itself in the IDE and the file name) to have a "ComCtls" or "CC" prefix.
> 2. class module renames (both the class module name itself in the IDE and the file name) to have a "ComCtls" or "CC" prefix.
> 3. folder name changes: All four folders (Builds, Common, OLEGuids and Resources) to have a "ComCtls" or "CC" prefix in their names.
> 4. Creation of one separate folder called Demo, so that every file and folder that is only part of the demo be moved in there.
> For example all the frm and frx files as well as the ComCtlsDemo.vbp and ComCtlsDemo.vbw and some other files and also the entire folder "Resources" need to be moved under the Demo folder.
> Or for another example, why is the Startup.bas module currently under the "Common" folder? It only belongs in the demo, so it shouldn't be there.
> Not sure if you ever had a chance to review my suggestions or not, because you haven't responded to them yet.
> And I don't know if I should continue to wait for a response or not.
> ...


Sorry for not responding. Here my response:

I am likely not to change it because this would cause conflicts for my internal naming conventions. Because I use these common stuff also for other projects and as it is now is more convenient "for me" to copy & paste.

I would like to point something out. I encourage to use the OCX version as it is a "plug and play" replace. There you don't have to bother about any naming conflicts.

It is very ABNORMAL to even provide a Std-EXE source at all... most VB6 componenents are ONLY available as OCX.
I already thought about the idea to dis-miss the Std-EXE version at all and to only provide a OCX version to ease everything and to reduce questions.

Wouldn't it be just more easy to everyone to just provide a OCX. Then I could say "just register it and there you go".
However, I still think that for some use-cases it still makes sense to use a Std-EXE version to be "as portable as possible"..

So, using the OCX has also other advantages if an update comes out - just copy paste the new OCX file - you don't have to re-compile your app. (only if a big change comes like soon 1.6 -> 1.7)
But that's a one-time thing and 1.7 will be most probably the last version as then everything will be clean in an "infrastructure" point of view of the sources.

Thanks for your idea. I hope you understand my point.

----------


## wqweto

> The problem was that I thought that the OLE_OPTEXCLUSIVE must be triggered via UserControl.PropertyChanged "Value" only for the TRUE value.
> However, that works as long as the order is "sequential" in the .frm file. Now the OLE_OPTEXCLUSIVE will be triggered in either case.


This seems like the only case when passing *actual* (non-empty) property name to PropertyChanged notification makes huge difference to the container.

cheers,
</wqw>

----------


## Krool

> Feature request for the Progress Bar:
> 
> Is it maybe possible to add a .text/.caption or a .DisplayPercentage property to display the current percentage inside the progress bar?
> 
> I currently use my own progress bar usercontrol with this feature but i want/try to transfer all controls used in my project to VBCCR if possible...


Good idea. I think a .Font, .Text and .TextColor (.ForeColor already in use by ProgressBar) is enough?

If Text is not a NullString then overlay draw is enabled. (Overlay draw being also the technical term, because a double-buffer style drawing is not possible, at least not for the themed ProgressBar as otherwise the "draw movement" is "too fast")

The text shall be drawn always Center/VCenter so there is no need for extra alignment properties.
The text property should be able to process placeholders (e.g. {0} = Value, {1} = Min, {2} = Max and {3} = Percent value between 0 and 100)

Am I missing something?

----------


## IliaPreston

> ......
> (only if a big change comes like soon 1.6 -> 1.7)
>       ......


Thanks a lot for your response.

And do you have any idea as to when probably that version 1.7 will come out?

I just downloaded the latest version, and in the Readme.txt file there is no mention of what version it is.
Nor is any mention in the List of Revisions.txt
They mention the release date, but not the release version number.
It would be nice to specify the version number in one of these two text files as well, because it is easier to refer to them (even before deploying the whole package in VB6 IDE.)

Thanks.

----------


## Krool

Update released.

as suggested already yesterday the ProgressBar includes now new Font/Text/TextColor property.
Important to note are the text placeholders {0} = Value, {1} = Min, {2} = Max and {3} = Percent value between 0 and 100.
Using these are recommended to avoid unecessary redrawings. (applying new .Text will invalidate the region, whereas placeholder will automatically be used on ordinary draw when new value change occurs)
So a commonly needed .Text property may be: "{3} %"

I must quoute now Karl77 as he asked already for such a feature back in Dec, 2016  :Roll Eyes (Sarcastic): 



> While we are at that, a caption property for the progressbar would be nice.
> Like in the old old CCRP.


EDIT: using WM_PRINTCLIENT on the ProgressBar will include also the new Text property.





> I just downloaded the latest version, and in the Readme.txt file there is no mention of what version it is.
> Nor is any mention in the List of Revisions.txt
> They mention the release date, but not the release version number.


You are looking in the wrong thread. This here is the Std-EXE version. Here is the OCX version.
There in the List of Revisions.txt you find the version number history with the release dates.

----------


## Semke

on the imagelist, when I set a maskcolor, the images get a funny colour in the property window. on the toolbar it is ok, but in some places they are bad (I think its when I use the picture property of the image)

----------


## Mith

Im converting old TreeView source code to the new VBCCR TreeView but i struggle with the missing NEXT property of the tree node:



Normally the NEXT property is used to loop through the node childs:



```
Set xNode = Node.Child

For I = 1 To Node.Children

   xNode.Checked = True
   Set xNode = xNode.Next

Next I
```

Any ideas?

SOLTUION:

ok, i got it, the equivalent for the NEXT property is NextSibling...is there any reason to use another name for this property?

----------


## Krool

> Im converting old TreeView source code to the new VBCCR TreeView but i struggle with the missing NEXT property of the tree node:
> 
> Attachment 176799
> 
> Normally the NEXT property is used to loop through the node childs:
> 
> 
> 
> ```
> ...


'Next' is a reserved keyword. So I can't use it.
So I used 'NextSibling'..

----------


## KurtB

Hi Krool!

My name is Kurt, and I just wanted to say a few things. I am programmer, and I'm _still_ coding in VB6. I do not say this with shame as many others might. I know the limitations of the language and all of the "power I am missing" from not using a "modern" "non-toy" language, etc. etc. I am sure that everyone reading this forum calls "bulls___" on anyone making such claims  :Smilie: 

Yes, we suffer in ways, but we do so because we know just how close MS was to perfecting VB, all the way up to the point where they abandoned the language, and abandoned us, the coders. Krool: your work here is the continuance of the job that MS dropped: You are creating the true VB7 here, and I do not exaggerate! Thank you so much for your dedication!

I have 3 questions for you:

1. I have a very real and immediate need for a solution like yours for the intrinsic controls, the Treeview, and the Listview in Unicode-ready format. My 1st question is: Do you maintain a bug list that would help me decide on the readiness of these controls? I can't just drop them in to a 150,000+ line project, without doing tons of unit testing, unless a bug list helped me decide. I tend to maintain bug lists - I'm just wondering if you do the same, and, if so, could you please direct me to it?

2. Can I provide you any coding assistance, either directly in the main project, or in a unit mass-testing capacity?

3. Any other ways I could support? With your level of dedication, and the potential help that work could provide me, it seems like a monetary donation would be in order.  Seriously. You're doing work that I have wanted to do, but haven't have the time for. And, I know how long you've been working on it. Finally, I've seen some of your code, and I can say with certainty that the length of time is not due to any lack of skill  :Smilie: 

Please send me a PM, if you have a minute or two, so we can discuss it. This is not a completely selfless thing either...as mentioned, I have a vested interest in helping you succeed!

Please stay safe, and have a nice day!
Kurt

----------


## Semke

in the toolbar control.
when adding buttons using property pages, if an image is added to a button, where the selected key does not exist in the associated imagelist, you get a runtime error..

PS. I hope that I am helping you by submitting these bugs, I have submitted a few, which I hope were helpful, my intention is not to criticize, I greatly appreciate your work.

----------


## Krool

> 1. I have a very real and immediate need for a solution like yours for the intrinsic controls, the Treeview, and the Listview in Unicode-ready format. My 1st question is: Do you maintain a bug list that would help me decide on the readiness of these controls? I can't just drop them in to a 150,000+ line project, without doing tons of unit testing, unless a bug list helped me decide. I tend to maintain bug lists - I'm just wondering if you do the same, and, if so, could you please direct me to it?


What you mean with bug list? I try always to fix the bugs asap so there is no long "bug list" waiting to be done. So I can't tell you right now which bugs are still existent.
The best is of course you try to replace your large project with the new controls and see what happens. Doing large project conversions helps best to improve it as every corner is used.




> 2. Can I provide you any coding assistance, either directly in the main project, or in a unit mass-testing capacity?


If you find something that can be improved or simplified you can advise. No problem.
Of course the biggest help so far was the crowd testing.

----------


## LaVolpe

> What you mean with bug list?


He means 70 pages, 2700+ posts  :Smilie: 

But seriously, many of us will keep a list of why new versions/revisions were released. That list will say which 'bugs' were found/fixed and which enhancements were added, and which methods became obsolete/removed. Whether he is asking for a list of known bugs not yet fixed, not sure.

----------


## Semke

> toolbar question:
> does the toolbar have a DC? reason I am asking, because I would like to print text on the toolbar mainly on placeholders (without the need to add a picturebox on it)


I found a work around;
by creating a label control and/or other controls and in the form load event you set the toolbar as the control container of the Label.
you will also need to position the control and make it visible. you can use the button.top, button.left properties for that





```
Set txtBrandName.Container = tbrToolbar
Set lblBrandName.Container = tbrToolbar
```

----------


## Krool

> I found a work around;
> by creating a label control and/or other controls and in the form load event you set the toolbar as the control container of the Label.
> you will also need to position the control and make it visible. you can use the button.top, button.left properties for that
> 
> 
> 
> ```
> Set txtBrandName.Container = tbrToolbar
> Set lblBrandName.Container = tbrToolbar
> ```


Sorry for the delay and not responding.

Exactly, like the MS ToolBar the VBCCR ToolBar is a "ControlContainer". (But which can't get focus; CanGetFocus = False)
So, the best is, as you just did, to change the container of external controls to the toolbar.

----------


## KurtB

> He means 70 pages, 2700+ posts 
> 
> But seriously, many of us will keep a list of why new versions/revisions were released. That list will say which 'bugs' were found/fixed and which enhancements were added, and which methods became obsolete/removed. Whether he is asking for a list of known bugs not yet fixed, not sure.


Yeah, I guess that is what I meant  :Smilie: 

Basically, what I was asking for was your level of confidence that I could replace the shipped controls with your controls, in a big project, and have a reasonable expectation that my project would remain stable. If you told me that you were pretty confident, that would be enough for me to give it a try. I might even make a project-wide mass-replacement tool that would open .frm and .ctl files, and swap out the controls. (Maybe your users could get some use out of such a tool?). But, if you said that you knew of some pending bugs that might cause me some issues, now or down the road, I suppose I'd have to go through a big testing phase first. Sure, I should probably do that anyway, but, as most programmers are, I'm strapped for time.

Based on your response, I might just give it a try  :Smilie:  By the way, I can still contribute resources, if you're interested, now, or in the future. Send a PM.

Thanks again for your time, your response, and in general, what you do!

----------


## KurtB

This forum software is weird...first an error, then a double post...

----------


## wqweto

> This forum software is weird...first an error, then a double post...


Has been like that for some years. On error don't hit back and re-post as your reply is probably posted already. Just open a new tab and reload the topic to see if your request was successful on first attempt.




> I might even make a project-wide mass-replacement tool that would open .frm and .ctl files, and swap out the controls. (Maybe your users could get some use out of such a tool?).


I think there is already an existing tool for this posted in the code-bank sub-forum somewhere.

cheers,
</wqw>

----------


## Krool

> Yeah, I guess that is what I meant 
> 
> Basically, what I was asking for was your level of confidence that I could replace the shipped controls with your controls, in a big project, and have a reasonable expectation that my project would remain stable. If you told me that you were pretty confident, that would be enough for me to give it a try. I might even make a project-wide mass-replacement tool that would open .frm and .ctl files, and swap out the controls. (Maybe your users could get some use out of such a tool?). But, if you said that you knew of some pending bugs that might cause me some issues, now or down the road, I suppose I'd have to go through a big testing phase first. Sure, I should probably do that anyway, but, as most programmers are, I'm strapped for time.
> 
> Based on your response, I might just give it a try  By the way, I can still contribute resources, if you're interested, now, or in the future. Send a PM.
> 
> Thanks again for your time, your response, and in general, what you do!


The VTable handling is definitely clean now (was a long road to get rid of VTable subclass and lightweight COM)
Also the latest cleansing of no need for WM_MOUSEACTIVATE handlers anymore gives me the conclusion that the state as of now is pretty confident.
So go for it, now or when new VBCCR17 will be released.

----------


## KurtB

> Has been like that for some years. On error don't hit back and re-post as your reply is probably posted already. Just open a new tab and reload the topic to see if your request was successful on first attempt.
> 
> 
> 
> I think there is already an existing tool for this posted in the code-bank sub-forum somewhere.
> 
> cheers,
> </wqw>


Will do - I'll ignore the error!
Well, I'm happy there's already a conversion tool, but sad, because that was my big way to contribute  :Smilie:  I'll probably build it anyway, cause it sounds like a fun exercise. I'll probably end up posting it, just for an alternative.




> The VTable handling is definitely clean now (was a long road to get rid of VTable subclass and lightweight COM)
> Also the latest cleansing of no need for WM_MOUSEACTIVATE handlers anymore gives me the conclusion that the state as of now is pretty confident.
> So go for it, now or when new VBCCR17 will be released.


That's good enough for me - I'll give it a shot! I'll keep monitoring the forum and try out VBCCR17. It's actually kinda exciting - it's like getting a new VB7  :Smilie:

----------


## Krool

> Will do - I'll ignore the error!
> Well, I'm happy there's already a conversion tool, but sad, because that was my big way to contribute  I'll probably build it anyway, cause it sounds like a fun exercise. I'll probably end up posting it, just for an alternative.
> 
> 
> That's good enough for me - I'll give it a shot! I'll keep monitoring the forum and try out VBCCR17. It's actually kinda exciting - it's like getting a new VB7


You could contribute MUCH if you make a migration guide (documentation). :-)

----------


## KurtB

I think that would involve said conversion program. It would also involve:
1. Me working with the new controls and identifying differences, new properties, changes to properties, etc.
2. Making any changes necessary to my code that references the controls.

As of yet, I have no experience with the controls, so what I can do is, first, convert the controls in a significant program, and, second, get some experience working with them, and, third, document anything I have to do to get them working. That should provide a good-as-any starting place for a migration guide, right? Any idea when version 17 will be released? (I want to start with the latest release.)

----------


## LaVolpe

@Krool. You may want to give Kurt a heads up of any standard methods that had to be renamed so he is aware of them when his first run fails due to "Method not Found" type errors. For example, NextSibling, FirstSibling, etc

----------


## KurtB

> Has been like that for some years. On error don't hit back and re-post as your reply is probably posted already. Just open a new tab and reload the topic to see if your request was successful on first attempt.
> 
> 
> 
> I think there is already an existing tool for this posted in the code-bank sub-forum somewhere.
> 
> cheers,
> </wqw>





> @Krool. You may want to give Kurt a heads up of any standard methods that had to be renamed so he is aware of them when his first run fails due to "Method not Found" type errors. For example, NextSibling, FirstSibling, etc


I think that maybe what Krool would like to see in this future Migration guide. I'm thinking that some of that will become obvious when I try to compile a freshly converted project. I might even be able to make the convertor update property names and property-related function names.

So, unless there is already a list of changed property names that you can easily send me, maybe give me a chance to discover these, and create some documentation myself. Like I mentioned before, I am extremely busy, but not so busy that I can't do a little bit of documentation on a nice set of controls that makes my life a lot easier  :Smilie:  Thanks.

----------


## Krool

> I think that maybe what Krool would like to see in this future Migration guide. I'm thinking that some of that will become obvious when I try to compile a freshly converted project. I might even be able to make the convertor update property names and property-related function names.
> 
> So, unless there is already a list of changed property names that you can easily send me, maybe give me a chance to discover these, and create some documentation myself. Like I mentioned before, I am extremely busy, but not so busy that I can't do a little bit of documentation on a nice set of controls that makes my life a lot easier  Thanks.


VBCCR16 has all latest fixes. And for a replacement it has all it needs. VBCCR17 will still take a while as I wish to include some missing features (e.g. VirtualMode List/ComboBox like already done in ListView).

Concerning names. Like LaVolpe explained for TreeView, since the original method named "Next" and since it is a restricted keyword I was forced to name it "NextSibling".

I don't have notes listing all the differences..

----------


## Krool

> StatusBar
> 
> 
> ```
> StatusBar.Panels("aPanel").Width = lWidth
> ```
> 
> returns error 383:Property is read-only 
> in the MS Controls this was Read/Write


Sorry for late response.

How stupid the behavior.. Yes the .Width property is read-only.
Luckily I put it as following


```
Public Property Let Width(ByVal Value As Single)
Err.Raise Number:=383, Description:="Property is read-only"
End Property
```

So I can change it even in the VBCCR16 without breaking compatibility.

But I need to figure out what the MS StatusBar do with the .Width property.

When AutoSize = sbrContents the .Width just changes the .MinWidth property. (redirection)
When AutoSize = sbrSpring the .Width changes nothing. (no-op w/o error)
When AutoSize = sbrNoAutoSize the .Width will be applied 1:1

Am I missing something, Semke?

----------


## LaVolpe

> But I need to figure out what the MS StatusBar do with the .Width property.


I believe it works this way (pseudo code):


```
' thumb is triangle in bottom right corner if applies
    Offset = 0: Size = 0
    For n = 1 to nrPanels
        Select Case panel(n).AutoSize
        Case sbrNoAutoSize: Size = panel(n).Width
        Case sbrContents: 
            If TextWidth(panel(n).text) > panel(n).MinWidth Then
                Size = TextWidth(panel(n).text)
            Else
                Size = panel(n).MinWidth
            End If
        Case sbrSpring:
            Size = TextWidth(panel(n).text)
        End Select
        draw panel text @ Offset not exceeding Offset + Size
        Offset = Offset + Size + SizeOf(separator)
        If Offset > sbar.ScaleWidth + SizeOf(thumb) Then Exit For 
    Next
```

----------


## KurtB

> VBCCR16 has all latest fixes. And for a replacement it has all it needs. VBCCR17 will still take a while as I wish to include some missing features (e.g. VirtualMode List/ComboBox like already done in ListView).
> 
> Concerning names. Like LaVolpe explained for TreeView, since the original method named "Next" and since it is a restricted keyword I was forced to name it "NextSibling".
> 
> I don't have notes listing all the differences..


I've already opened up v16, and I'm checking it out.

I'm sure I'm going to have 100 questions for you, but I'm going to make a log of the questions, and send them all in one step, to avoid overwhelming you. I imagine that most of them can be answered by combing through 70 pages of forum, and eventually I will download these, locally compile them into a single page, and read them. However, I do want to ask and mention a few right off the bat, if that's ok. I'll number them to make conversation a bit easier. Please forgive my ignorance, as I have very little experience in VBCCR as of yet.

1. I've just run the Standard EXE ComCtrls Demo. First off, I must say that this demo needs a lot of work. Sorry for the criticism, right at the start. But this demo has a few flaws:
  a. It barely scratches the surface, as far as showing the power of the new controls.
  b. All the text is in ANSI English, missing a great opportunity for showing Unicode capabilities, which is a BIG selling point!
  c. It's very difficult to see what each component is supposed to do. Sometimes 2 components interact, sometimes not. Some components don't seem to do anything.
  d. It takes an experienced VB programmer to realize just how cool it is to be able to load 100,000 items into a ListView in less than one second!
  e. There's more, but I don't want to be more negative in my first comment (sorry)

  Honestly, I don't expect a demo to be perfect. I already know the controls are good and powerful. But the demo is where first impressions happen. Maybe I can eventually create a demo that showcases the power of the controls.

2. What's the difference between the Standard demo and the ActiveX demo? Is the ActiveX version the same as the Standard version, but without the demo forms? Am I missing something?

3. I noticed a strange form lack-of-refresh issue while paused (debug mode), and I got a crash when stopping the project with the stop button. Is this due to the subclassing stuff? Is it generally a bad idea to stop the program in this manner? And, more importantly, does this only occur when running in the IDE?
    (The "lack-of-refresh" is better described as follows: When paused, the VB form would not repaint when passing other windows on top of it. And, in the immediate window, I typed a command that produced a VB error msgbox. But, the msgbox was hidden under this non-painting VB form, and it was nearly impossible to answer the msgbox, giving me the impression that VB had locked up. Eventually, I was able to get focus under that form, and press ENTER, answering the msgbox, and giving me back control of the project. By the way, I'm running VB6 SP6 on a Win7 box).

4. When I start developing "for real" with CCR, I'm going to want to compile the controls into a single OCX, I think, to avoid loading all the UserControls, modules, and Property Pages into the design environment.
  a. Have you done this before?
  b. Does it work ok?
  c. Will it compile the OleGUIDs.tlb into the OCX, so I don't have to load OleGUIDs.tlb into my project?
  d. If I do this, and it works, I should probably name the OCX a static name, like VBCCR.OCX, instead of VBCCR16.OCX, right?
  e. To extend the previous question, will I have any binary compatibility problems when version 17 is released? Will I be able to compile version 17 into a VBCCR.OCX file, and use it with projects built with version 16, or will I have to rebuild all of my forms?

5. I noticed that some of your controls have a "W" suffix like "ListBoxW" and some do not, like TreeView. I can create a form with the original TreeView and a CCR Treeview on the same form, and they both work. Furthermore, for an original Treeview, the following command evaluates to True, but for a CCR TreeView, it evaluates to False:
IsATreeView = TypeOf Form1.Controls(1) is TreeView 

  In fact, I cannot determine what name to use to get that statement to return True. I tried a few names. I tried ComCtlsDemo.TreeView, and I tried VBCCR16.TreeView. I actually do have a function that uses TypeOf to check all the controls on a passed form. It's used for language translation. When I open a form, I call a function that loads a language-specific translation for all controls on the form, and applies the translation to the form's controls, in the manner required for each control (sometimes it's .Caption, sometimes it's .ColumnHeaders(n).Text, etc.)

  a. The properties window and the toolbox button tooltip both name this control "TreeView". What programmatic control type name is required?
  b. Why didn't you name the TreeView "TreeViewW"? Don't get me wrong - I'm not trying to tell you your business. I just mean that it adds a level of confusion in various places that doesn't need to be there, in my humble opinion. I think VB knows it has 2 control types with the same name, so it's forcing me to be more specific and qualify the control name. The toolbox icon looks different, so that helps a bit. And renaming a control type, at this stage, would probably break a lot of projects. I'm just trying to be complete, and document an accurate picture of exactly what I experience from the beginning, through a complete implementation. I hope this explains my intentions of this whole reply.

All in all, everything seems pretty darn nice, so far. I think I'm going to have to build a suite of Unicode string functions that will help me make the most out of the controls. I can't believe that MS forced everyone to store strings 2-bytes per character, but provided no way to get any use out of it  :Smilie:  I saw some code on the web that allows Unicode Form captions. Do your controls, by chance, provide this capability?

Thanks again for your time. From now on, I'll queue up my questions. I had to ask these to help me determine and plan a starting point.

----------


## LaVolpe

@Kurt. This is an easy one, so I will pick it off and let Krool concentrate on the tool-related issues



> IsATreeView = TypeOf Form1.Controls(1) is TreeView


If you have controls having the same name from different libraries, you will need to include the library name else VB picks one based on some  hierarchy. The same would apply if you added both v6 & v5 of Windows common controls to the same project.

IsATreeView = TypeOf Form1.Controls(1) is ComctlLib.TreeView (MSComctlLib.TreeView)
IsATreeView = TypeOf Form1.Controls(1) is ComCtlsDemo.TreeView  ' << works for me
If in doubt, hit F8 and see what library names are loaded into project

Of course, in the compiled ocx, its library name will not be ComCtlsDemo

----------


## Krool

> StatusBar
> 
> 
> ```
> StatusBar.Panels("aPanel").Width = lWidth
> ```
> 
> returns error 383:Property is read-only 
> in the MS Controls this was Read/Write





> I believe it works this way (pseudo code):


Update released.

Semke, the Width property of a Panel is now not read-only anymore. Luckily VBCCR16 could be updated w/o break of compatibility. (technical sense)
Please confirm that it's fine. Thanks

LaVolpe, the algo was already sufficient. Only a small addition was needed to have the Width property behaves as MS.
Just a new internal per panel variable 'FixedWidth' which is initialized as -1 (alias for invalid).
It will be taken into consideration when it is > -1 and AutoSize is None.
For AutoSize Content MS really only changes the MinWidth (redirection), so I did the same.
For AutoSize Spring MS really does nothing when applying a Width property. It also does not cache something which will be taken when switching to another AutoSize property.




> 1. I've just run the Standard EXE ComCtrls Demo. First off, I must say that this demo needs a lot of work. Sorry for the criticism, right at the start. But this demo has a few flaws:
>   a. It barely scratches the surface, as far as showing the power of the new controls.
>   b. All the text is in ANSI English, missing a great opportunity for showing Unicode capabilities, which is a BIG selling point!
>   c. It's very difficult to see what each component is supposed to do. Sometimes 2 components interact, sometimes not. Some components don't seem to do anything.
>   d. It takes an experienced VB programmer to realize just how cool it is to be able to load 100,000 items into a ListView in less than one second!
>   e. There's more, but I don't want to be more negative in my first comment (sorry)
> 
>   Honestly, I don't expect a demo to be perfect. I already know the controls are good and powerful. But the demo is where first impressions happen. Maybe I can eventually create a demo that showcases the power of the controls.


If you want you can make a new demo project.  :Smilie: 
For me it's just a testing demo and not a "show room".




> 2. What's the difference between the Standard demo and the ActiveX demo? Is the ActiveX version the same as the Standard version, but without the demo forms? Am I missing something?


There is no ActiveX demo. The ActiveX project is a real project for compilation. The Standard demo is just for confusion and the "possibility" to compiled into the Std-EXE version without a need for a OCX. The standard demo is the leading source which will be derived into the OCX at some point.
However, using OCX version is better. If there is an update, just replace the OCX and there you go.
Also it's stable for IDE usage and with the SxS reg-free approach just convinient.





> 4. When I start developing "for real" with CCR, I'm going to want to compile the controls into a single OCX, I think, to avoid loading all the UserControls, modules, and Property Pages into the design environment.
>   a. Have you done this before?
>   b. Does it work ok?
>   c. Will it compile the OleGUIDs.tlb into the OCX, so I don't have to load OleGUIDs.tlb into my project?
>   d. If I do this, and it works, I should probably name the OCX a static name, like VBCCR.OCX, instead of VBCCR16.OCX, right?
>   e. To extend the previous question, will I have any binary compatibility problems when version 17 is released? Will I be able to compile version 17 into a VBCCR.OCX file, and use it with projects built with version 16, or will I have to rebuild all of my forms?


There is already a pre-compiled OCX available. I recommend using the pre-compiled binary instead cooking your own OCX.
OLEGuids.tlb will be compiled INTO it. It's only needed for YOU the developer and just within the IDE.




> 5. I noticed that some of your controls have a "W" suffix like "ListBoxW" and some do not, like TreeView. I can create a form with the original TreeView and a CCR Treeview on the same form, and they both work. Furthermore, for an original Treeview, the following command evaluates to True, but for a CCR TreeView, it evaluates to False:
> IsATreeView = TypeOf Form1.Controls(1) is TreeView 
> 
>   In fact, I cannot determine what name to use to get that statement to return True. I tried a few names. I tried ComCtlsDemo.TreeView, and I tried VBCCR16.TreeView. I actually do have a function that uses TypeOf to check all the controls on a passed form. It's used for language translation. When I open a form, I call a function that loads a language-specific translation for all controls on the form, and applies the translation to the form's controls, in the manner required for each control (sometimes it's .Caption, sometimes it's .ColumnHeaders(n).Text, etc.)
> 
>   a. The properties window and the toolbox button tooltip both name this control "TreeView". What programmatic control type name is required?
>   b. Why didn't you name the TreeView "TreeViewW"? Don't get me wrong - I'm not trying to tell you your business. I just mean that it adds a level of confusion in various places that doesn't need to be there, in my humble opinion. I think VB knows it has 2 control types with the same name, so it's forcing me to be more specific and qualify the control name. The toolbox icon looks different, so that helps a bit. And renaming a control type, at this stage, would probably break a lot of projects. I'm just trying to be complete, and document an accurate picture of exactly what I experience from the beginning, through a complete implementation. I hope this explains my intentions of this whole reply.


LaVolpe already answered. (thank you)

About this "W" suffix. I made it according to following logic:

If there is a VB intrinsic comparable control -> "W" suffix
Else not, because I assume that the MS Common Controls are replaced and ComctlLib and such are not referenced anymore. Thus there is no conflict with same namings.
The "W" is really just put to make it easier to distinguish between VB and VBCCR. (not for the MS Common Controls)

----------


## Krool

Stupid bugfix that was created in today's update for StatusBar. Sorry.. should be fine now.

----------


## KurtB

Thanks LaVolpe and Krool. It all makes sense.

@Krool: I meant no insult about your demo. As a testbed, it's fine, and the "audience" is made up of programmers. But even programmers want to see what your controls can do! And, honestly, I think you deserve a showcase for your controls. I'll see what I can do. It's going to take me some time, however.

I think, to avoid asking foolish questions, I'll need to combine and read this thread in its entirety, and spend some time with the controls. It looks like you put a lot of care into emulating the original controls as much as possible, which I value very highly - it means that replacing the originals with your controls should be nearly seamless for everyone (and probably a nightmare for you, huh?   :Smilie: 

It's going to take me some time, but I'll get back to you. Take care.

----------


## KurtB

Uh - one more comment:

This code is freakin' insane! (I mean that in the best way possible.) How did you learn how to do all of this? Was there some disassembling involved? Why are you building VB6 controls, instead of just building your own language???

Very impressive, man, I gotta say. What's your secret?  :Smilie:  Me like.

----------


## MountainMan

You will find that there are quite a few guys on this site that do stuff with VB6 that you would have thought was not possible...

BTW, I had that double post problem and someone told me to do "Go Advanced" on replies and you only get 1 post. I do that now and it seems to work.

----------


## KurtB

Oh, I already knew they were good. In all honesty, risking sounding conceited, I'm good enough to know 'good' when I see it.
Most guys will chuck a jar of lukewarm cat piss in your general direction. Many of the guys on this site can lob a grenade 100 feet towards you, and you better run. This code is like a laser-guided precision strike, and there's no need to run...Boom! It's all over.

Don't get me wrong - I'm no mastermind. But, when you've been coding for 40+, you just know. I know enough to recognize that the API calls being made here are pretty darn close to what the original C code was doing. It's all the meat, with very little fat. Sure, you could beat on it for a while, and maybe wring 5 to 10% more this-or-that out of it.

From what I've seen, it's quite a clean codebase - nicely named vars, enums instead of magic numbers, VB quirks maintained. Obviously a labor of love. I don't know how much collaboration was involved, but, again, I'm impressed, which is rare.

In my career, I've developed a pet-peeve when end-users don't realize just how much work went into the final product. You put in a ton of work behind-the-scenes, and the end-users see it and think "Of course it works that way, how else would it work?" They don't realize that your program is only easy for them to use because you put in countless hours making it that way. They don't realize that you added a clever optimization that reduced runtime from hours to seconds. And, they don't care, as long as it always runs that fast!

I think these controls are like that in a way: A ton of work has given us exactly what we expected to get in 1995. If we hadn't dealt with the quirky MS controls for 25 years, the CCR controls do what you expect. Which is awesome. We are the only people that can really appreciate them for what they are - that's just the way it is.

I knew VB could be made to do it, after beating it into submission. I've been wanting to do something like this for a long time. But, I'm glad I don't have to, because it would have been the most difficult project I've ever done, I'm sure. I wish you guys knew my capabilities, only so that you would believe me when I say that this is a top-notch accomplishment! I am rarely such a cheerleader...it's kinda making me sick to read it back  :Smilie:  I'm sure it sounds over-the-top to everyone reading it. I can say no more.

----------


## Mith

Hey Kurt8,

i have some information for you about "mass-testing" the VBCCR control.

The popular freeware AllDup uses the VBCCR OCX control. The freeware is available in 20 different languages.
They have a lot of users with different computer setups, Windows versions and so on.

A good proof that the VBCCR OCX control is running stable, or?

----------


## Mith

The label control features the useful AutoSize property.

Is it possible to add the AutoSize property to the CheckBox and OptionButton control?

This would be very useful when dealing with multi-language apps!

Currently i extend the width of every CheckBox/OptionButton to the max. visible size to fit text from different languages.

----------


## KurtB

@Mith: Yes, that's good proof! Naturally, a programmer always has to do some testing. But I like to ask the developer himself, because good developers are always honest about the state of their wares!

When sizing controls, I use this:
controlName.Width = controlName.TextWidth(Caption)

Of course, a built-in property is nicer.

----------


## Mith

> controlName.Width = controlName.TextWidth(Caption)


VBCCR doesnt support the control property .TextWidth ...

having a AutoSize property would be very handy...

sometimes when needed i use the API GetTextExtentPoint32W to determine the width of unicode text.

----------


## Krool

> VBCCR doesnt support the control property .TextWidth ...
> 
> having a AutoSize property would be very handy...
> 
> sometimes when needed i use the API GetTextExtentPoint32W to determine the width of unicode text.


Does the VB control support TextWidth?
I guess he was referring to the Form's TextWidth function.

The problem is that BCM_GETIDEALSIZE works only for push button. So for a check and radio button it would need to be calculated manually.. will look after it.

----------


## KurtB

Controls that can be PRINTed on support the TextWidth and TextHeight property, so, for example, Forms, Picture Boxes, and User Controls. If you set a form's ScaleMode property to vbPixels, and both the label and the form use the same font, you can auto-size a label on the form as follows:

BorderWidth = 4: Label1.Width = Form1.TextWidth(Label1.Caption) + BorderWidth

It would probably be better to request the BorderWidth via a Windows API, instead of hard-coding '4', but unless I'm building a library (like VBCCR), I usually can't be bothered.

I actually prefer to set the width myself, to handle special cases, like if the label's caption would make the label wider than the form it's on!

----------


## Mith

> The problem is that BCM_GETIDEALSIZE works only for push button. So for a check and radio button it would need to be calculated manually.. will look after it.


Before i switched to the VBCCR controls i used my own unicode usercontrols with the support of AutoSize for the Checkbox & OptionButton control.
I used the windows API GetTextExtentPoint32W to determine the width of the unicode text. t's quite easy to implement such a feature. The only tricky thing was to take care of the Alignment property, for example, if you have a RightAlignment you need to move the control to the left and not only extend the usercontrol width! Just my 2 cents...

----------


## Krool

> Before i switched to the VBCCR controls i used my own unicode usercontrols with the support of AutoSize for the Checkbox & OptionButton control.
> I used the windows API GetTextExtentPoint32W to determine the width of the unicode text. t's quite easy to implement such a feature. The only tricky thing was to take care of the Alignment property, for example, if you have a RightAlignment you need to move the control to the left and not only extend the usercontrol width! Just my 2 cents...


In the VBFlexGrid I already included a TextWidth function.
It also takes into account multi-line text, like VB Form's TextWidth.

So I will include soon some TextWidth function to certain VBCCR controls. (Where it makes sense)

Thanks for your comments always.

----------


## Semke

> In the VBFlexGrid I already included a TextWidth function.
> It also takes into account multi-line text, like VB Form's TextWidth.
> 
> So I will include soon some TextWidth function to certain VBCCR controls. (Where it makes sense)
> 
> Thanks for your comments always.


speaking of VBFlexGrid 

I remember some time ago, there was a discussion of whether to include/combine it with VBCC.
so, I wonder if it will be so, in my opinion, it would be very good idea.

----------


## Arnoutdv

In my opinion it's not a good idea.
Why put an independent control in the same OCX?
Makes it more difficult to maintain and for the developer nor the end user it makes no difference.

----------


## OldClock

> You could contribute MUCH if you make a migration guide (documentation). :-)


I wrote that here:
http://www.vbforums.com/showthread.p...=1#post5444945




> Do you maintain a bug list


https://github.com/Kr00l/VBCCR/issues
https://github.com/Kr00l/VBCCR/blob/...0revisions.txt

----------


## OldClock

Kr00l I'm having an issue with the CommonDialog. I placed one on MDIForm1, then I need to use it from some module:


```
    Dim cDlg As VBCCR16.CommonDialog
    Set cDlg = MDIForm1.ComDlg
```

This results in:



> Run-time error: '13':
> Type mismatch


Same if I do:


```
    Dim cDlg As CommonDialog
    Set cDlg = MDIForm1.ComDlg
```

I now looked inside MDIForm1.frm and see this:


```
   Begin MSComDlg.CommonDialog ComDlg
```

How do I place a VBCCR16 CommonDialog instead of a MSComDlg? I only have one CommonDialog button in the Toolbox...

----------


## OldClock

Well I solved/worked around this by:
1. Deleting all CommonDialog controls from my forms.
2. This allowed me to remove the "Microsoft Common Dialog Control 6.0" component.
3. With no actual CommonDialog control on any form, I then changed the code to:


```
    Dim cDlg As VBCCR16.CommonDialog
    Set cDlg = New VBCCR16.CommonDialog
```

And it works fine.

----------


## Semke

> Kr00l I'm having an issue with the CommonDialog. I placed one on MDIForm1, then I need to use it from some module:
> 
> 
> ```
>     Dim cDlg As VBCCR16.CommonDialog
>     Set cDlg = MDIForm1.ComDlg
> ```
> 
> This results in:
> ...


in mdiForm 


```
Public cDlogM As VBCCR16.CommonDialog
```

in user Form/Module


```
Dim cDlogF As VBCCR16.CommonDialog

Set  MDIForm1.cDlogM  = New VBCCR16.CommonDialog
set cDlogF = MDIForm1.cDlogM
```

----------


## LaVolpe

Bug Report: ListView, whether listitems exist or not
- when listview is shown and has 2+ column headers, remove all but one
- re-add 1 or 2 column headers
- Subscript out of Range error 

I think the control is trying to redraw somewhere between the column header being added, but the header not being appended to the collection yet.

Updated: I don't know if this was the right thing to do or not, but solved the problem...
Class: lvwColumnHeaders
Method: Add
Action: moved the "ShadowListView.FColumnHeadersAdd" call to end of method

-----------------------------------------------------------------------------------------------

Have an option for you. Not just reporting bugs!

Been playing with your ListView and found something lacking  :Wink: . I noticed you added several types of sorting options, but didn't include the one I was looking for... Explorer-like sorting when text & numeric listitems are intermixed. Suggestion follows.


```
Private Declare Function StrCmpLogicalW Lib "shlwapi" (ByVal psz1 As Long, ByVal psz2 As Long) As Long

Private Function ListItemsSortingFunctionLogical(ByVal lParam1 As Long, ByVal lParam2 As Long) As Long
    Dim Text1 As String, Text2 As String
    Text1 = Me.FListItemText(lParam1 + 1, PropSortKey)
    Text2 = Me.FListItemText(lParam2 + 1, PropSortKey)
    ListItemsSortingFunctionLogical = StrCmpLogicalW(StrPtr(Text1), StrPtr(Text2))
    If PropSortOrder = LvwSortOrderDescending Then ListItemsSortingFunctionLogical = -ListItemsSortingFunctionLogical
End Function
```

edited: sample of differences, logical compare on the left side
2string
20string

3string
2string

20string
3string

st2ring
st20ring

st3ring
st2ring

st20ring
st3ring

string2
string2

string3
string20

string20
string3

----------


## LaVolpe

*Edited*. Following is not a bug per-se. Behavior in the VB usercontrols does the same. A misunderstanding on my part, thinking that deleting a column removed the column contents. It does not, it just removes the column and hides the far right visible subitem.

Krool, found another bug.

This one will take a bit more work. When a listview column is removed, you shift all subitems left one. That only works if the last subitem was the one removed. In your sample project, try removing column 2 (subitem 1). The column headers shift correctly, but the subitems do not.

Updated. May have fixed it, but unsure. I think you need to take a closer look at what happens to subitems when columns are added/removed during runtime on populated listviews.

UC: ListView

Method: FColumnHeadersAdd
Action: call RebuildListItems, passing current column header count. If you are inserting columns in listsubitems for new columns vs. always appending, then I'd imagine you want to pass the new index instead

Method: FColumnHeadersRemove
Action: call RebuildListItems, passing the subitem index to be removed as a negative value. This is called before SetColumnsSubItemIndex, not after

Method: RebuildListItems
Action: added Index parameter and tweaked a little code:


```
        If .FListSubItemsCount > 0 Then
            If Index = Count Then   ' adding new column
                ' however you want to handle this, I didn't look at it
            ElseIf -Index < Count Then
                .ListSubItems.Remove -Index
            End If
        End If
```

----------


## Krool

> Bug Report: ListView, whether listitems exist or not
> - when listview is shown and has 2+ column headers, remove all but one
> - re-add 1 or 2 column headers
> - Subscript out of Range error 
> 
> I think the control is trying to redraw somewhere between the column header being added, but the header not being appended to the collection yet.
> 
> Updated: I don't know if this was the right thing to do or not, but solved the problem...
> Class: lvwColumnHeaders
> ...


The fix as you suggested is OK. However, I would like to replicate the problem to look for another potential issue.
But I couldn't replicate. Can you bundle a small demo?





> I noticed you added several types of sorting options, but didn't include the one I was looking for... Explorer-like sorting when text & numeric listitems are intermixed.


Thanks. Will include sort option StrCmpLogicalW soon.




> When a listview column is removed, you shift all subitems left one. That only works if the last subitem was the one removed. In your sample project, try removing column 2 (subitem 1). The column headers shift correctly, but the subitems do not.


The MS ListView behaves exactly the same. So I do not consider this being a "bug". Thanks however for your testing.

----------


## LaVolpe

> The fix as you suggested is OK. However, I would like to replicate the problem to look for another potential issue.
> But I couldn't replicate. Can you bundle a small demo?


I used your demo in post #1. I added 2 new test buttons with code below. Note. Setting .Redraw=False also prevents the error.


```
' button to remove listitems & column headers
Dim n&
ListView1.ListItems.Clear
For n = ListView1.ColumnHeaders.Count To 2 Step -1
    ListView1.ColumnHeaders.Remove n
Next

' button to re-add columns & errors
ListView1.ColumnHeaders.Add , , "NewCol"
ListView1.ColumnHeaders.Add , , "NewCol2"
```




> The MS ListView behaves exactly the same. So I do not consider this being a "bug". Thanks however for your testing.


Wow, never really noticed. I was assuming it would react similar to deleting a column from an Excel sheet. But v6 of the Listview doesn't shift column contents when headers are removed. I should've been using the .ListSubItems.Remove method of each listview item to produce the results I expected. With old age no longer creeping up, it has settled in, wonder if this is something I re-learned?

----------


## Shaggy Hiker

For what it's worth, if a post is in the wrong thread, you can just report it, as the mods can move the post to the right thread, as long as we know which thread is the right thread.

----------


## Krool

> I used your demo in post #1. I added 2 new test buttons with code below. Note. Setting .Redraw=False also prevents the error.
> 
> 
> ```
> ' button to remove listitems & column headers
> Dim n&
> ListView1.ListItems.Clear
> For n = ListView1.ColumnHeaders.Count To 2 Step -1
>     ListView1.ColumnHeaders.Remove n
> ...


I still tested on Windows 7 where it does not happen.
I tested now on Windows 10 and it crashes upon CDDS_ITEMPREPAINT on the Header Control, which makes sense.

I will make an update as you suggested in the ColumnHeaders::Add method to shift the FColumnHeadersAdd after it has been added to the Collection.

EDIT: Bugfix applied.

----------


## OldClock

Hey

1. How can I check whether a vertical scrollbar has appeared in a listview? I want to resize column widths if a vertical scrollbar appear.

2. Is it possible to allow a vertical scrollbar to appear when needed, but not a horizontal scrollbar?
P.S. I am aware of ShowScrollBar, but when I use it to hide the horizontal scrollbar then visual artifacts appear in the bottom row where the scrollbar would have been, and the horizontal scrollbar appears anyway when I scroll vertically.

While trying to find a solution, I encountered some odd behavior, can't say whether they're bugs or not:

3. 


> Sub ComputeControlSize(VisibleCount As Long, Width As Single, Height As Single, [ProposedWidth As Single], [ProposedHeight As Single])
>     Member of VBCCR16.ListView
>     A method that returns the width and height for a given number of visible list items.




```
    Dim ww As Single
    Dim hh As Single
    Call lv.ComputeControlSize(20, 5295, 2475, ww, hh)
    Debug.Print "ww: " & ww & ", hh: " & hh
```

This always prints 0. The LV's width is 5295 twips, height is 2475, using View=LvwViewReport. Since the LV at that font size can only show 11 rows, and I set the VisibleCount parameter to 20 (I also tried with just 1), I would expect the computed vertical size to be larger than 2475.

4. 


> Function GetVisibleCount() As Long
>     Member of VBCCR16.ListView
>     Returns the number of fully visible list items. If the list view is in 'icon', 'small icon' or 'tile' view then the return value is the total number of list items.


I added 4 ListItems to that LV, but Debug.Print lv.GetVisibleCount prints 11. There are 11 fully-visible rows, but only 4 ListItems. The description is misleading.

----------


## Krool

> 3. 
> 
> 
> ```
>     Dim ww As Single
>     Dim hh As Single
>     Call lv.ComputeControlSize(20, 5295, 2475, ww, hh)
>     Debug.Print "ww: " & ww & ", hh: " & hh
> ```
> ...


You flipped the params. You should call as following:



```
Dim ww As Single
Dim hh As Single
Call lv.ComputeControlSize(20, ww, hh, 5295, 2475)
```

Or omitting proposed width/height:


```
Dim ww As Single
Dim hh As Single
Call lv.ComputeControlSize(20, ww, hh)
```

----------


## OldClock

That works, thanks Krool.

----------


## Krool

> 1. How can I check whether a vertical scrollbar has appeared in a listview? I want to resize column widths if a vertical scrollbar appear.


Use GetWindowLong and test for WS_VSCROLL.




> 2. Is it possible to allow a vertical scrollbar to appear when needed, but not a horizontal scrollbar?
> P.S. I am aware of ShowScrollBar, but when I use it to hide the horizontal scrollbar then visual artifacts appear in the bottom row where the scrollbar would have been, and the horizontal scrollbar appears anyway when I scroll vertically.


In the article below is described how to avoid vertical scrollbar. (intercept WM_NCCALCSIZE)
So for a horizontal it is likewise the same.

https://stackoverflow.com/questions/...n-details-mode

----------


## OldClock

> 1. How can I check whether a vertical scrollbar has appeared in a listview?


For reference, I used:



```
Public Enum ScrollBarStyles
    Horizontal_SBS = &H100000
    Vertical_SBS = &H200000
End Enum

Public Function isScrollbarVisible(ByVal hWnd As Long, ByVal sbs As ScrollBarStyles) As Boolean
    Dim wndStyle As Long
    wndStyle = GetWindowLong(hWnd, GWL_STYLE)
    isScrollbarVisible = (wndStyle And sbs) <> 0
End Function

' Usage:
If isScrollbarVisible(lv.hWnd, ScrollBarStyles.Horizontal_SBS) Then
    (...)
```

----------


## pepegriyo2016

Hello Krool,

You could avoid using the "*On Error Resume Next*" and solve the error that appears on the line


```
If CLng (Button.Parent.ActiveControl.Default)> 0 Then Else Default = False
```



```
Private Sub DrawButton(ByVal hWnd As Long, ByVal hDC As Long, ByVal Button As Object)
...

Select Case ButtonPart
    Case BP_PUSHBUTTON
        Default = Button.Default
        If GetFocus() <> hWnd Then
            On Error Resume Next
            If CLng(Button.Parent.ActiveControl.Default) > 0 Then Else Default = False
            On Error GoTo 0
        End If
...
End Sub
```

----------


## Krool

> Hello Krool,
> 
> You could avoid using the "*On Error Resume Next*" and solve the error that appears on the line
> 
> 
> ```
> If CLng (Button.Parent.ActiveControl.Default)> 0 Then Else Default = False
> ```
> 
> ...


I don't know what you mean..
However, you are referring to the VisualStyles.bas to fix the graphical style for the VB.CommandButton.

The CLng(Button.Parent.ActiveControl.Default) should never be > 0.
It only forks to the true branch when an error happens. (in this case Default should remain True even if GetFocus() <> hWnd)
So it is intended to have an OERN.

----------


## pepegriyo2016

> I don't know what you mean..
> However, you are referring to the VisualStyles.bas to fix the graphical style for the VB.CommandButton.
> 
> The CLng(Button.Parent.ActiveControl.Default) should never be > 0.
> It only forks to the true branch when an error happens. (in this case Default should remain True even if GetFocus() <> hWnd)
> So it is intended to have an OERN.



I have this error and it always stops there.

----------


## pepegriyo2016

> I have this error and it always stops there.


Krool,
I found how to fix it. With Val ()

'On Error Resume Next
If CLng(*Val*(Button.Parent.ActiveControl.Default)) > 0 Then Else Default = False
'On Error GoTo 0

----------


## Krool

> Krool,
> I found how to fix it. With Val ()
> 
> 'On Error Resume Next
> If CLng(*Val*(Button.Parent.ActiveControl.Default)) > 0 Then Else Default = False
> 'On Error GoTo 0


This "fixes" nothing, at least for me.

I suggest the problem is that you have "Break on All Errors" selected in the IDE options.

----------


## pepegriyo2016

Krool,
The Val() only fix the error 13 runtime, but I have another error is no fixed with Val()

----------


## Krool

Update released.

Included the VirtualCombo control.

It is actually a super-classed combo box control with a no-data list box portion. (LBS_NODATA)
I called the class "VComboBoxWndClass".

It would be a mess to include a "VirtualMode" property to the existing ComboBoxW. Therefore like the ImageCombo, FontCombo (and even VB.DriveListBox) are separate encapsulated combo box controls. (trimmed down to what actually is needed)

Populating a VirtualCombo control is very quickly as just the .ListCount property must be set. (it can also be set at design-time)

The VirtualCombo control retrieves the strings (when they need to be drawn) via the GetVirtualItem event.
IncrementalSearch/FindVirtualItem event can also be handled to enable full functionality and behavior.

----------


## Krool

Behavior bugfix for the VirtualCombo control when Style is <> DropDownList.

The ComboBox attempts to apply the top index for the drop-down list according to the text of the edit portion.
For this case the LB_FINDSTRING is now handled and the related FindVirtualItem event must be handled for correct top index behavior by the ComboBox.

Also added the DrawMode property, which can only be set to Normal (ownerdraw handled by VirtualCombo itself) or to OwnerDrawFixed where a ItemDraw event will be fired. (OwnerDrawVariable not possible due to LBS_NODATA restriction)

----------


## Krool

Since the VirtualCombo control is in a early stage I decided to change the event param in the 'IncrementalSearch' event.

The old params were..


```
Event IncrementalSearch(ByVal KeyChar As Integer, ByVal StartIndex As Long, ByRef FoundIndex As Long)
```

and the new one is simply..


```
Event IncrementalSearch(ByVal SearchString As String, ByVal StartIndex As Long, ByRef FoundIndex As Long)
```

The difference in addition is also that the SearchString can "build-up" if typing multiple keys within a short interval. (short interval = system's double click time, multiplied with 2)

So, using Len(SearchString) tells you the current "level" of incremental search.

If classic search (like in a typical ListBox) is wanted with only 1 character search then simply just use Right$(SearchString, 1) within the IncrementalSearch event.

----------


## ScriptBASIC

Hi Krool,

I'm having a problem getting VBCCR16.OCX working in my project. I get the following error dialog. VBCCR14.OCX seems to work. (Windows 10 Pro)

I regsvr32.exe the VBCCR16.OCX as administrator in a console.

VBCCR15 does the same as VBCCR16. 

Is this a Windows 10 issue running the IDE?

----------


## Semke

> Update released.
> 
> Included the VirtualCombo control.
> 
> It is actually a super-classed combo box control with a no-data list box portion. (LBS_NODATA)
> I called the class "VComboBoxWndClass".
> 
> It would be a mess to include a "VirtualMode" property to the existing ComboBoxW. Therefore like the ImageCombo, FontCombo (and even VB.DriveListBox) are separate encapsulated combo box controls. (trimmed down to what actually is needed)
> 
> ...



Hi!
I am a bit confused with this one.
how is it used, and what is the advantage of it?

----------


## Krool

> Hi Krool,
> 
> I'm having a problem getting VBCCR16.OCX working in my project. I get the following error dialog. VBCCR14.OCX seems to work. (Windows 10 Pro)
> 
> I regsvr32.exe the VBCCR16.OCX as administrator in a console.
> 
> VBCCR15 does the same as VBCCR16. 
> 
> Is this a Windows 10 issue running the IDE?


This is the clsid for the ListView. Can you search in regedit and tell what is there?

----------


## Krool

> Hi!
> I am a bit confused with this one.
> how is it used, and what is the advantage of it?


There is the common habit of transferring the data again and again.

For example, you have a Recordset which queried a huge list.

Normally, you would populate a ComboBox from that recordset into the ComboBox via .AddItem.
So, in fact the data is in memory twice. (in the recordset and in the ComboBox)

Using Virtual controls is not very known here. The advantage is that you only need to retrieve the data once, in our example in a recordset.
The virtual control is only told how many records we have. So it is "populated" in light speed.

Whenever the virtual control needs to draw the items in the current viewport it will raise a event. In that event you search the recordset for that specified index.

So, the drawing tends to be slightly slower but that is marginal compared to the advantage of the light speed population.

----------


## ScriptBASIC

All the VBCCR controls pop this dialog with a different GUID.

----------


## Krool

> All the VBCCR controls pop this dialog with a different GUID.


When you search these guids in regedit, what do you find?

----------


## ScriptBASIC

Krool,

I have VBCCR16 and the sidebysideand styles file as part of my project. I did a search of the registry using the *listview* GUID. FWIW VBCCR15 does the same as VBCCR16 with the dialog error.

*Update*

I unregistered all VBCCR## versions other than VBCCR16.OCX and it still is popping the error dialog. For some reason the VB6 component list is still showing VBCCR14 even though I unregistered all instances on the laptop.

I then registered VBCCR14.OCX and was able to add VBCCR controls to the form again.

----------


## Mith

VBCCR 1.6.109

I have a ListView with 2 columns (Report Mode).

The 2. column contains text with more than 300 characters but only 260 characters will be displayed.

Using _.AutoSize (LvwColumnHeaderAutoSizeToItems Or LvwColumnHeaderAutoSizeToHeader)_ resizes the column to a max of 260 chars only.

Manually setting of the column width makes the column widther but still only 260 characters are displayed at the column and the rest of the text is truncated...

Can you remove the 260 char display restriction per column or is this a hardcoded limitation of the ListView?

----------


## Semke

> Update released.
> 
> Included the VirtualCombo control.


Hi!,

Is there any reason the VirtualCombo control is not included in the Compiled OCX Version (1.6.113).

----------


## Krool

> VBCCR 1.6.109
> 
> I have a ListView with 2 columns (Report Mode).
> 
> The 2. column contains text with more than 300 characters but only 260 characters will be displayed.
> 
> Using _.AutoSize (LvwColumnHeaderAutoSizeToItems Or LvwColumnHeaderAutoSizeToHeader)_ resizes the column to a max of 260 chars only.
> 
> Manually setting of the column width makes the column widther but still only 260 characters are displayed at the column and the rest of the text is truncated...
> ...


It's a hard limit by comctl32.dll. Only 260 will be displayed, but as the list view items are single-lined it is actually sufficient in most cases. (read-ability)




> Hi!,
> 
> Is there any reason the VirtualCombo control is not included in the Compiled OCX Version (1.6.113).


It will be included in OCX version 1.7
Reason to not include in 1.6 is to maintain binary compatibility and keep the same clsid.

----------


## AAraya

I want a Label to auto-size its width to fit the length of the label text but I want its height to remain unchanged.  The AutoSize property of the label control changes both height and width.  Right now I'm hard-coding the height I want everywhere I set the label's caption but is there a more elegant way to do this?  I'm open to subclassing this with some guidance.

TIA

----------


## AAraya

> I want a Label to auto-size its width to fit the length of the label text but I want its height to remain unchanged.  The AutoSize property of the label control changes both height and width.  Right now I'm hard-coding the height I want everywhere I set the label's caption but is there a more elegant way to do this?  I'm open to subclassing this with some guidance.
> 
> TIA


According to documentation I've seen, the VB6 Label can do this using these settings:


```
AutoSize = True
WordWrap = False
```

LabelW does not behave the same way however.




> Use the AutoSize and WordWrap properties to determine how the Label displays lengthy text in its Caption. If you set the AutoSize property of the Label to True (default is False), the Label automatically shrinks or stretches to the exact size needed to display the text. The WordWrap property determines whether or not an autosized Label changes size in a horizontal direction (WordWrap = False, its default value) or in a vertical direction (WordWrap = True). Remember, WordWrap has an effect only if you first set AutoSize to True.

----------


## wqweto

> According to documentation I've seen, the VB6 Label can do this using these settings:

IMO auto-sizing VB.Label *always* recalculates Height. This might remain unchanged if the new recalculated value is the same as the old value (i.e. rarely or when repeating previous auto-sizing).

WordWrap controls if Width is fixed (not Height). When WordWrap is True then Width is not re-calculated. When WordWrap is False *both* Width and Height are re-calculated.

cheers,
</wqw>
p.s. Consider when is this auto-sizing happening -- on Caption property assignment, on Font assignment, on WordWrap assigment and on AutoSize pulsing (set False and immediately to True) -- which is *very* confusing and just not very clever programming interface design for such functionality. (Bet this kludge happened progressively while adding features with each new VB version.)

----------


## Mith

The position of the text of a checkbox or option button a little bit wrong when using a font size larger than 9px:

Larger:


I guess the text position should be 1 pixel up if the font size is larger than 9px
or you have to auto center the text by checking the text height and the checkbox/option height to make this water proof for all font sizes.

----------


## tnrprog

deleted

----------


## tnrprog

Listview smallicons glitch when screen DPI>96

----------


## Mith

Whats the problem with the icons? i dont get it...
You should post a second picture and show how they look without the "glitch".

----------


## tnrprog

DPI=96 (screen size 100%). Icons are OK:


DPI=120 (screen size 125%). Icons are OK if themed, but bugged if classic:


DPI=192 (screen size 200% - I use it for 4K display). Icons have bug. And here it is obvious that the Imagelist returns part of the next ListImage. Although it should not. The MS version does not.

----------


## Krool

> DPI=96 (screen size 100%). Icons are OK:
> 
> 
> DPI=120 (screen size 125%). Icons are OK if themed, but bugged if classic:
> 
> 
> DPI=192 (screen size 200% - I use it for 4K display). Icons have bug. And here it is obvious that the Imagelist returns part of the next ListImage. Although it should not. The MS version does not.


I bet that on MS ListView V5 you have the same..

The MS ListView V6 is a zombie state version of an ancient comctl32.dll.

If you would like this to be fixed then good luck opening a MS ticket.

----------


## tnrprog

> I bet that on MS ListView V5 you have the same..
> 
> The MS ListView V6 is a zombie state version of an ancient comctl32.dll.
> 
> If you would like this to be fixed then good luck opening a MS ticket.


I don't think that Microsoft will devote time to the classic theme in 2020
I'm sure it will be easier for me to generate a scaled ImageList for each DPI on runtime. Thanks

----------


## MSI-Packager

I have a listview question. Standard behavior is when focus is lost a selected item is no longer highlighted with the select (blue) color, but gets soft grey and less visible for the user as selected.
If you select hide selection then it will be white making it look like nothing is selected at all. For my project I switched from listbox to listview where list box keeps the highlighted color but listbox is very limited in its usage.
Is it possible to keep the (blue) color after a different control gets focus or is this just a vb/windows thingy and am I out of luck?

Thx for the awesome controls btw!

----------


## Krool

> I have a listview question. Standard behavior is when focus is lost a selected item is no longer highlighted with the select (blue) color, but gets soft grey and less visible for the user as selected.
> If you select hide selection then it will be white making it look like nothing is selected at all. For my project I switched from listbox to listview where list box keeps the highlighted color but listbox is very limited in its usage.
> Is it possible to keep the (blue) color after a different control gets focus or is this just a vb/windows thingy and am I out of luck?
> 
> Thx for the awesome controls btw!


There is no "straight forward" solution as the select (blue) color overrides any (possible) custom draw.

BUT, there is a nice trick using the DropHighlight functionality. (important is that HideSelection is True)
There is no visual difference in the appearance of a DropHighlight row or Selected row.

If single-selection is enough then using the in-built functionality is sufficient.



```
Private Sub Form_Load()
ListView1.MultiSelect = False
ListView1.HideSelection = True
End Sub

Private Sub ListView1_GotFocus()
Set ListView1.DropHighlight = Nothing
End Sub

Private Sub ListView1_LostFocus()
Set ListView1.DropHighlight = ListView1.SelectedItem
End Sub
```

However, if you need MultiSelect = True then a little bit API is doing the job.



```
Private Type LVITEM
Mask As Long
iItem As Long
iSubItem As Long
State As Long
StateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
End Type
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long

Private Sub ListViewMultiDropHighlightFromSelRange(ByVal Obj As ListView, Optional ByVal Reset As Boolean)
Const LVM_FIRST As Long = &H1000
Const LVM_GETNEXTITEM As Long = (LVM_FIRST + 12)
Const LVM_SETITEMSTATE As Long = (LVM_FIRST + 43)
Const LVNI_ALL As Long = &H0, LVNI_SELECTED As Long = &H2
Const LVIS_DROPHILITED As Long = &H8
Dim iItem As Long, LVI As LVITEM
LVI.StateMask = LVIS_DROPHILITED
If Reset = False Then
    LVI.State = LVIS_DROPHILITED
    iItem = SendMessage(Obj.hWnd, LVM_GETNEXTITEM, -1, ByVal LVNI_ALL Or LVNI_SELECTED)
    Do While iItem > -1
        SendMessage Obj.hWnd, LVM_SETITEMSTATE, iItem, ByVal VarPtr(LVI)
        iItem = SendMessage(Obj.hWnd, LVM_GETNEXTITEM, iItem, ByVal LVNI_ALL Or LVNI_SELECTED)
    Loop
Else
    LVI.State = 0
    SendMessage Obj.hWnd, LVM_SETITEMSTATE, -1, ByVal VarPtr(LVI)
End If
End Sub

Private Sub Form_Load()
ListView1.MultiSelect = True
ListView1.HideSelection = True
End Sub

Private Sub ListView1_GotFocus()
ListViewMultiDropHighlightFromSelRange ListView1, True
End Sub

Private Sub ListView1_LostFocus()
ListViewMultiDropHighlightFromSelRange ListView1
End Sub
```

----------


## MSI-Packager

Thanks! This is exactly I was looking for and it works beautifully.

----------


## ScriptBASIC

Hi Krool,

Any news why VBCCR greater than 14 won't work on Windows 10 in the VB6 IDE?

----------


## Krool

> Hi Krool,
> 
> Any news why VBCCR greater than 14 won't work on Windows 10 in the VB6 IDE?


I don't know. I can't reproduce your problem. Can anyone else?

----------


## AAraya

> Hi Krool,
> 
> Any news why VBCCR greater than 14 won't work on Windows 10 in the VB6 IDE?


I'm on Win10 64-bit and have no problems using VBCCR16 in my VB6 IDE.  What do you mean that it won't work? What happens?

----------


## Semke

> Hi Krool,
> 
> Any news why VBCCR greater than 14 won't work on Windows 10 in the VB6 IDE?


if you have 64bit Windows you need to copy the OCX in the SysWOW64 folder not in the system32 folder.

----------


## ScriptBASIC

I tried moving the VBCC16.OCX to the SysWOW64 directory (and registered it) but I'm still getting the control not registered error. The toolbar shows all the VBCCR controls but if I try to place one on the form the error dialog appears.


VBCCR14 works.

----------


## Krool

> I tried moving the VBCC16.OCX to the SysWOW64 directory (and registered it) but I'm still getting the control not registered error. The toolbar shows all the VBCCR controls but if I try to place one on the form the error dialog appears.
> 
> 
> VBCCR14 works.


I have no clue. I'm afraid that I can't help you.

----------


## tnrprog

Is it possible for ListView in report style to set different backcolor of even and odd items like it works with FlexGrid's "BackColor" and "BackColorAlt" ?

----------


## Krool

> Is it possible for ListView in report style to set different backcolor of even and odd items like it works with FlexGrid's "BackColor" and "BackColorAlt" ?


Yes, you can handle the ItemBkColor event and change when Mod 2.

----------


## vbLewis

Hi Krool,Many thanks for your continued hard work! Is there any chance we could get a scrollbar control? (something like the flatscrollbar in mscomct2). i really detest the built in scroll bars of vb6.

----------


## Krool

Included new control 'VListBox'. (virtual list box)

It is intended to not call it 'VirtualList' (likewise to the 'VirtualCombo') as 'VirtualList' is a common word to refer to a virtual list view.

In this work for the new control I found some things to fix/improve for the 'ListBoxW' control:
- TabbedTextOut API now used in a Checkbox/Option Style ListBoxW control when UseTabStops property is True
- Bugfix in the 32-bit scrolling in a multi-column ListBoxW and when WS_EX_LEFTSCROLLBAR is set
- Text property in ListBoxW now data-bindable to a VB.Data control

----------


## vbLewis

Im using the Slider control from the vbccr activex control as a volume control. When I have it in vertical layout mode the small value starts at the top and values get larger as you scroll down. Is there a way to reverse this? I would like the small value at the bottom and large at the top. so as you move the slider up, the volume increases. The "Reverse" property seemed to have no effect.

----------


## Krool

> Im using the Slider control from the vbccr activex control as a volume control. When I have it in vertical layout mode the small value starts at the top and values get larger as you scroll down. Is there a way to reverse this? I would like the small value at the bottom and large at the top. so as you move the slider up, the volume increases. The "Reverse" property seemed to have no effect.


The "Reversed" property says:
_Returns/sets a value that determines whether or not to reverse the default, making down equal left and up equal right on horizontal orientation and left equal down and right equal up on vertical orientation._

So it just reverses the left and right arrow keys, which is useful. (TBS_DOWNISLEFT)

In addition TBS_REVERSED is set, which has no effect on the control; it is simply a flag that can be checked..

So, what do you need in addition ?

You can reverse the "result" easily:


```
ReverseResult = (Slider1.Max - Slider1.Value) + Slider1.Min
```

To fix the tip info text:


```
Private Sub Slider1_ModifyTipText(Text As String)
Text = (Slider1.Max - Slider1.Value) + Slider1.Min
End Sub
```

----------


## vbLewis

Thanks for the reply! Thats what i was doing, recalculating but the tooltip still showed it going down instead of up so i will try the modifytiptext event. I was just hoping there was an easy way to reverse the up down direction.

----------


## LaVolpe

Krool, consider adding support for listview's LVN_ODCACHEHINT notification. It helps with virtual listivews. Supporting it is just a few lines of code. Users, on the other hand need to learn to use it.

Supporting it... you'll need a new udt: NMLVCACHEHINT and a new event: VirtualSetCacheHint


```
Case LVN_ODCACHEHINT
    Dim NMLVC As NMLVCACHEHINT
    CopyMemory NMLVC, ByVal lParam, LenB(NMLVC)
    RaiseEvent VirtualSetCacheHint(NMLVC.iFrom + 1, NMLVC.iTo + 1)
```

For users. Most often with virtual listviews, you won't have data cached. It will be in a stream, in a database, in a file, somewhere else, but not in active memory, i.e., some array. In other words, you need to retrieve it when it's needed. The cache hint is how the listview attempts to tell you, "hey I'm gonna need these items in the short term - might want to pre-cache them". Only at that point, do you load your data and cache it in memory. The message is likely to tell you to cache no more than 50-ish items (whatever can fit on screen). Then when Krool raises his GetVirtualItem event, you get the data from your cache. Listviews don't always ask for items you cached, so you need to verify the item is in your cache and fallback to retrieving it otherwise.

Edited: Here's how I implemented the cache. My actual code is a bit more complex. I also don't want to cache subitems whose columns are not on screen (horz scrollbar in effect). In addition, the listview, for whatever reasons, always queries the 1st 8 listitems, so not a bad idea to keep them permanently cached.


```
 ReDim strCache(0 To ListView1.ColumnHeaders.Count - 1, FromItem To ToItem) ' String array
' "FromItem" passed in VirtualSetCacheHint event 
' "ToItem" passed in VirtualSetCacheHint event 
... populate the array with the items from your database or whatever
```

And this is how one could use that cache


```
Private Sub ListView1_GetVirtualItem(ByVal Index As Long, ByVal SubItemIndex As Long, ByVal VirtualProperty As LvwVirtualPropertyConstants, ByRef Value As Variant)

    If Index < LBound(strCache, 2) Or Index > UBound(strCache, 2) Then
        ' not in cache, retrieve it manually
    Else
        Value = strCache(SubItemIndex, Index)
    End If
End Sub
```

----------


## Krool

> consider adding support for listview's LVN_ODCACHEHINT notification. It helps with virtual listivews.


Thanks as always for your constructive input.

When I use a virtual list view (e.g. SQLite DataSet) then all is already pre-cached and thus no need for it.
However, maybe for other cases it might be useful. Therefore I included the 'VirtualSetCacheHint event' 1:1 as you suggested.

Concerning virtual list view in general I found other things:

1.
a virtual list view sends LVN_ITEMCHANGED only for some cases. If a range is selected it uses LVN_ODSTATECHANGED and not LVN_ITEMCHANGED for each item.
I catch now LVN_ODSTATECHANGED and translate a 'ItemSelect event' for each item in that range.

Also a virtual list view informs only about each selected item, not about each deselected item.

It uses an alias for deselection. A .iItem = -1 in LVN_ITEMCHANGED. So in order to give full feature I need to pass then a 'ItemSelect event' with ListItem 'As Nothing' and the param 'Selected' as False.

2.
There is a problem when using a virtual ListView control in a control array in the GetVirtualItem event.
Because the param 'Index As Long' clashes with the 'Index As Integer'.
I renamed the 'Index As Long' to 'ItemIndex As Long'.

----------


## LaVolpe

> Thanks as always for your constructive input.
> 
> However, maybe for other cases it might be useful. Therefore I included the 'VirtualSetCacheHint event' 1:1 as you suggested.


But if your recordset is 100K records, dozen+ fields, would you really want to cache all that ahead of time? If not, the "cache hint" option performs better than JIT accessing database fields in response to the GetVirtualItem callback. In other cases, the source could be a stream or large random-access file for example.

There are other issues too, but more on the user side -- learning curves (for me too). For example, if you position a column via code, depending on how you are designing your cache, you may need to rebuild the cache as the column offsets in the cache may now be wrong. The virtual listview doesn't seem to send a new cache hint message when changing a column's order via code.

P.S. Another enhancement I needed to add... ColumnHeaders(x).EnsureVisible or something similar. When navigating the listview by keyboard (subitem to subitem, custom handled), there is no easy way to set the active column, triggering a horizontal scroll as needed. The solution was to call HDM_SETFOCUSEDITEM. LVM_SETSELECTEDCOLUMN selects, but doesn't activate. In the image below, if I keep hitting the right arrow, the highlighted item changes. At column 7+, I'll want the listview to scroll so that the highlighted item will be completely in view.

----------


## Krool

> Another enhancement I needed to add... ColumnHeaders(x).EnsureVisible or something similar.


There is a undocumented message which does the job.
However, it seems that it works only as of Vista+ (comctl32.dll 6.1 or greater)



```
Const LVM_FIRST As Long = &H1000
Const LVM_ENSURESUBITEMVISIBLE As Long = (LVM_FIRST + 184) ' Undocumented
Dim ItemIndex As Long, SubItemIndex As Long
ItemIndex = 0 ' zero-based
SubItemIndex = 2 ' zero-based
' Returns 1 on success
Debug.Print SendMessage(ListView1.hWnd, LVM_ENSURESUBITEMVISIBLE, ItemIndex, ByVal SubItemIndex)
```

----------


## Krool

LaVolpe, I did a test with just setting the focus (SetFocusAPI) to the header control and pressing keyoard arrow keys. (but no HDM_SETFOCUSEDITEM needed)
What is your current code?

Illustration:

----------


## LaVolpe

> What is your current code?


The right arrow keydown is trapped. On enter, I calculate the next subitem (column header index) based on column order and force a repaint of the listitem if no scroll is needed else I call HDM_SETFOCUSEDITEM which triggers the repaint. When it repaints, the old selected subitem's backcolor is redone and new one is yellow.
^^ edited: subitem vs. item ^^

----------


## Krool

Update released.

I didn't test the VirtualCombo when not manifested, means comctl version 5.8x.
Because I just noticed that it fails.

However, adding the red marked line of code in the WM_CREATE handler of the 'ComboLBox' window fixed it for comctl version 5.8x.
Why this was not needed for comctl version 6.x is unknown for me..


```
If wMsg = WM_CREATE Then
    Dim CS As CREATESTRUCT
    CopyMemory CS, ByVal lParam, LenB(CS)
    CS.dwStyle = CS.dwStyle Or LBS_NODATA
    CopyMemory ByVal lParam, CS, LenB(CS)
    SetWindowLong hWnd, GWL_STYLE, CS.dwStyle
    VcbComboLBoxHandle = hWnd
End If
```

----------


## LaVolpe

Krool, more for your consideration...

Customizing listivew items/subitems beyond just a font, forecolor or backcolor. It is entirely possible to draw a subitem completely on your own without having to owner-draw the entire listview. However, your raised event doesn't provide what is needed, though it could.

If the raised event would pass the hDC and RECT for the current item/subitem, then a user has more control. But that needs some thinking about how to raise the events (prepaint, paint, postpaint?) and how to respond to them. For example, CDRF_NEWFONT Or CDRF_NOTIFYSUBITEMDRAW may not be enough to return on CDDS_ITEMPREPAINT. May need CDRF_NOTIFYPOSTPAINT for example and respond to


```
Case CDDS_ITEMPOSTPAINT, (CDDS_ITEMPOSTPAINT Or CDDS_SUBITEM)
```

I was just thinking that if the control offers customizing per item, it probably should offer the entire package. Anyway, just a suggestion.

In my case, I wanted a subitem to appear raised. In order to do that, I needed to respond to the post-paint message so I could draw a raised border:


If you are considering it, here is what I'm using now. Comments added for you.


```
Public Event CustomDrawNotify(CustomDraw As Boolean)
' sent on Case NM_CUSTOMDRAW. If param returned false, exit subclass, no custom drawing
' event sent before copying the draw structure from received lParam

Public Event DrawItemPrePaint(ByVal ItemIndex As Long, ByVal SubItemIndex As Long, WantPaintEvents As Boolean)
' sent on Case CDDS_PREPAINT, If last param returned false, exit subclass, no drawing of this item
' otherwise, set subclass proc to CDRF_NOTIFYITEMDRAW
' note: v6 of listview class can set .dwItemSpec = -1
'      the NMLVCD.ItemType should be checked for v6. If value is 2 then CDDS_PREPAINT notification applies to all items

Public Event DrawItemPaint(ByVal ItemIndex As Long, ByVal SubItemIndex As Long, _
                      ForeColor As OLE_COLOR, BackColor As OLE_COLOR, ItemStateFlags As Long, _
                      ByVal hDC As Long, ByVal pRECT As Long, WantPostPaintEvent As Boolean)
' sent on Case CDDS_ITEMPREPAINT, (CDDS_ITEMPREPAINT Or CDDS_SUBITEM)
' note: pRECT can be RECT structure if in TLB
' Setting ItemStateFlags to exclude bit 2 prevents default selection coloring on subitems when FullRow select applies
' subclass proc returns CDRF_NOTIFYSUBITEMDRAW Or CDRF_NEWFONT by default
' and if WantPostPaintEvent is returned true, then proc return value includes CDRF_NOTIFYPOSTPAINT

Public Event DrawItemPostPaint(ByVal ItemIndex As Long, ByVal SubItemIndex As Long, _
                      ByVal hDC As Long, ByVal pRECT As Long)
' final custom drawing event sent on Case CDDS_ITEMPOSTPAINT, (CDDS_ITEMPOSTPAINT Or CDDS_SUBITEM)
' note: pRECT can be RECT structure if in TLB

Note the ForeColor & BackColor params are sent byref and applied to clrText, clrTextBk. 
user should supply CLR_DEFAULT (0xFF000000) or CLR_NONE (0xFFFFFFFF) if applicable
```

----------


## Krool

> Customizing listivew items/subitems beyond just a font, forecolor or backcolor. It is entirely possible to draw a subitem completely on your own without having to owner-draw the entire listview. However, your raised event doesn't provide what is needed, though it could.


Yes, it's very complex to offer NM_CUSTOMDRAW via delegated events (e.g. CustomDraw event) and not understand by many.
That's why I thought to dismiss that kind of events and if an app needs really very customized appearance they are likely to subclass the control anyway, then they can also catch NM_CUSTOMDRAW and override it.

In my opinion it kind of bloat the control further off if offering all kinds of custom draw events. So I am likely to keep it this way.


Another question, more like a general question to everyone, for the TreeView control:

It's concerning the 'FocusRect' of the Caret item in the TreeView control.

The comctl32.dll 5.8x and 6.0 (XP) do it nice I think:


However, on 6.1 (Vista) or greater the appearance is changed/tricked:


There would be a way to *fix* this in the NM_CUSTOMDRAW. (code example below)
Proceed to fix this? Or don't care at all? Providing another property which could say -> enum ShowFocusRect, 0=NoControl, 1=Off, 2=On
So (default 0) would have no change at all, Having 1 would erase CDIS_FOCUS always for the caret item and 2 would have below code.


```
' CDIS_FOCUS controls if the tree view draws a focus rect.
 If (NMTVCD.NMCD.uItemState And CDIS_FOCUS) = 0 Then
     ' If CDIS_FOCUS is not set but it is the caret item then force a focus rect.
     If SendMessage(TreeViewHandle, TVM_GETNEXTITEM, TVGN_CARET, ByVal 0&) = NMTVCD.NMCD.dwItemSpec Then
         NMTVCD.NMCD.uItemState = NMTVCD.NMCD.uItemState Or CDIS_FOCUS
         CopyMemory ByVal lParam, NMTVCD, LenB(NMTVCD)
     End If
 Else
     ' If CDIS_FOCUS is set but it is not the caret item then avoid a focus rect.
     If SendMessage(TreeViewHandle, TVM_GETNEXTITEM, TVGN_CARET, ByVal 0&) <> NMTVCD.NMCD.dwItemSpec Then
         NMTVCD.NMCD.uItemState = NMTVCD.NMCD.uItemState And Not CDIS_FOCUS
         CopyMemory ByVal lParam, NMTVCD, LenB(NMTVCD)
     End If
 End If
```

The benefit of having the focus rect properly is that if you click a node and pressing the mouse button (not released yet) and you move the caret item via keyboards then it visually known where the caret item is. (illustration below, with fix code applied)

----------


## LaVolpe

> Yes, it's very complex to offer NM_CUSTOMDRAW via delegated events (e.g. CustomDraw event) and not understand by many.
> That's why I thought to dismiss that kind of events and if an app needs really very customized appearance they are likely to subclass the control anyway, then they can also catch NM_CUSTOMDRAW and override it.


I understand. The advantage of including an event for each drawing stage is that a user wouldn't need to subclass a control that is already subclassed and is already checking for those messages. But, I do understand.

----------


## Semke

Hi!
I have 2 Features which would be nice to add to the ComboBox;
1) autocomplete from items in the list, with an option to raise an event if the text that was input is not an item in the list (this would be raised during the validate event, or even a new event could be created for this purpose.
2) cancel the dropdown before it has been dropped.

----------


## Krool

Included the MultiSelect function to the TreeView control.
It is somewhat a common need for certain usages. For example in a drag and drop usage. With a multi select TreeView it is easier to drag more items at once.

I think some explanation is necessary:

When MultiSelect is 0 - None all is like before. Otherwise the MultiSelect feature is turned on.
If set to 1 - All then the selection is "free" without any restriction. However, when doing a shift selection then also the collapsed (hidden) nodes will be selected.
This can be changed when setting MultiSelect to 2 - VisibleOnly, then it is ensured that during a shift selection only the visible nodes are selected. (thus any collapsed child nodes are not selected)
The last option 3 - RestrictSiblings will ensure that only within a subset of siblings a selection can be made.

The new 'TvwSelectedNodes' class is convinient to access all the currently selected nodes.
The index 1 is certainly always the focused caret item since it is sorted by the order of selection(grow/history).


```
Dim Node As TvwNode
For Each Node In TreeView1.SelectedNodes
    Debug.Print Node.Text
Next Node
```

To sort out the focused caret item just compare with the .SelectedItem property. It is still valid like in a single-select TreeView.


```
Dim Node As TvwNode
For Each Node In TreeView1.SelectedNodes
    If Not Node Is TreeView1.SelectedItem Then Debug.Print Node.Text
Next Node
```

A given node can be included/removed in the selection by code in using the .Selected property of a Node.


```
Node.Selected = [True / False]
```

The .SelectedIndex function of a Node returns index of the selected nodes collection associated with this node.
If that function will make any sense in a scenario/use-case I don't know. I just included it for completeness.


```
Dim Node As TvwNode
For Each Node In TreeView1.SelectedNodes
    Debug.Print TreeView1.SelectedNodes(Node.SelectedIndex).Text
Next Node
```

Also for completeness the .AnchorItem property which returns the current reference from which a multiple selection starts.


```
If Not TreeView1.AnchorItem Is Nothing Then Debug.Print TreeView1.AnchorItem.Text
```

The behavior and usage should be stable as I fiddled and tested it for a while to ensure a good starting point.
However, please report any bugs if encountered.

EDIT: AnchorItem not read-only anymore. It supports now Get/Let/Set. So it can be modified by code, if needed.

----------


## KurtB

Krool,

I'd be lying if I said that I've done justice to testing your control set. As it is, I am struggling to release an update of my own. To top that, my development box just fried my boot drive  :Frown: 

I absolutely will be testing many of the control thoroughly; in fact, I hope to include them in the next update to the project I mentioned above. I'm sorry I haven't been able to do more with them yet - believe me when I say that I think they are a Godsend, and MS should send you a few years of back pay (or pay each of us something for our struggles thus far  :Smilie: 

Please don't take my lack of progress reporting as a sign of lack of appreciation, or interest. Life is tough like that, sometimes.

If you want to be done working on them, I suppose the community may have to do some maintenance, if needed. Regardless, you *will* get that progress report from me, eventually.

Anyway, thanks for the professional control set, and professional code!

----------


## Krool

Update released.

Reworked the .WorkAreas property in the ListView control.
It is more convinient to use at it uses the new 'LvwWorkAreas' collection class.

With it the items can be added/removed or cleared more easily.


```
ListView1.WorkAreas.Add 0, 0, ListView1.Width / 2, ListView1.Height
Dim WorkArea As LvwWorkArea
For Each WorkArea In ListView1.WorkAreas
    Debug.Print WorkArea.Index & "/" & WorkArea.Left & "/" & WorkArea.Width
Next WorkArea
ListView1.WorkAreas.Remove 1
ListView1.WorkAreas.Clear
```

'LvwWorkAreas' uses no "private" data and fully relies on LVM_GETWORKAREAS/LVM_SETWORKAREAS.
So even if an app uses pure API for work area creation it can make use of the collections.

Another enhancement is that a particular list item can be tested to which work area it belongs to.
The rules are according to MSDN (https://docs.microsoft.com/en-us/win...-working-areas), so if multiple work areas overlap it returns the first one.



```
Dim WorkArea As LvwWorkArea
Set WorkArea = ListView1.ListItems(1).WorkArea
If Not WorkArea Is Nothing Then
    MsgBox "Within working area '" & WorkArea.Index & "'."
Else
    MsgBox "Not within a working area"
End If
```

Also the other way around, starting from a 'LvwWorkArea' all list items belonging to it can be retrieved.
It also follows the same rules when multiple working areas overlap.



```
Dim Item As Variant
For Each Item In ListView1.WorkAreas(1).ListItemIndices
    Debug.Print Item
Next Item
```

----------


## Krool

Update released.

Included new "NodeRangeSelect" event for the TreeView control.

Let's imagine you want that a disabled node does not get selected.
So, you handle the "NodeBeforeSelect" event and return Cancel.



```
Private Sub TreeView1_NodeBeforeSelect(ByVal Node As TvwNode, Cancel As Boolean)
' Avoid caret (focus) node to be changed for a disabled node.
If Node.Enabled = False Then Cancel = True
End Sub
```

However, for a shift-range selection (MultiSelect = True) the NodeBeforeSelect event is only fired for the new focused item.
Now, for each node in a shift-range selection the "NodeRangeSelect" is fired. (Anchor and focused item being excluded)



```
Private Sub TreeView1_NodeRangeSelect(ByVal Node As TvwNode, Cancel As Boolean)
' Avoid that a disabled node will be selected in a shift-range selection.
If Node.Enabled = False Then Cancel = True
End Sub
```

With this enhancement a disabled node can be effectively avoided to be selected in a multi-select TreeView.

----------


## KurtB

I hope these are unique questions. I have just gotten started with this wealth of powerful controls, and I have 2 questions so far:
1. I found the OverTypeMode property of the TextBoxW control, and tried to set it in VB's property window in design mode, in VB's Immediate window in Break mode, and at runtime by pressing the Insert key when a TextBoxW control had focus, but I couldn't seem to trigger OverType mode, no matter what. What am I doing wrong?

2. I didn't expect to see this, but I was hoping: Many standard controls, like the TextBox, ComboBox, and ListBox let you set the text ForeColor, and BackColor, but not the "HighlightColor", which is traditionally dark blue. I believe this color comes from the user's chosen global Windows settings. Is this something that I could add to my own copy of VBCCR without too much trouble? And, if so, would you, Krool, or anyone else be interested to have this as a standard new setting in the VBCCR controls? I would be happy to add it myself, and provide it, if I thought that 1) I had the ability, and 2) that it was wanted, and 3) that it wouldn't break anything for anyone.

I am trying to provide a user "theme edit" capability to a particular screen, but this could be an issue if the user chooses dark blue for their text ForeColor, for instance. (I know, "don't do that"  :Smilie: 

Thanks in advance for your time and consideration.

----------


## Krool

> 1. I found the OverTypeMode property of the TextBoxW control, and tried to set it in VB's property window in design mode, in VB's Immediate window in Break mode, and at runtime by pressing the Insert key when a TextBoxW control had focus, but I couldn't seem to trigger OverType mode, no matter what. What am I doing wrong?
> 
> 2. I didn't expect to see this, but I was hoping: Many standard controls, like the TextBox, ComboBox, and ListBox let you set the text ForeColor, and BackColor, but not the "HighlightColor", which is traditionally dark blue. I believe this color comes from the user's chosen global Windows settings. Is this something that I could add to my own copy of VBCCR without too much trouble? And, if so, would you, Krool, or anyone else be interested to have this as a standard new setting in the VBCCR controls? I would be happy to add it myself, and provide it, if I thought that 1) I had the ability, and 2) that it was wanted, and 3) that it wouldn't break anything for anyone.


1. Ensure that AllowOverType property is True.

2. Not possible for standard. However, you can set DrawMode property to OwnerDraw. Then you can color all how you like at the cost of additional code in your sources. (Handling ItemDraw event etc.)

----------


## MountainMan

Krool,

I can't get the ComCtlsDemo sample to compile or even load properly to work within the IDE. The culprit is line 123 in Animation.ctl:



```
Private Sub IOleInPlaceActiveObjectVB_TranslateAccelerator(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal Shift As Long)
```

----------


## Krool

> Krool,
> 
> I can't get the ComCtlsDemo sample to compile or even load properly to work within the IDE. The culprit is line 123 in Animation.ctl:
> 
> 
> 
> ```
> Private Sub IOleInPlaceActiveObjectVB_TranslateAccelerator(ByRef Handled As Boolean, ByRef RetVal As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal Shift As Long)
> ```


You have an outdated OLEGuids.tlb.
Just replace on syswow64 (or system32 on 32bit OS) with the new one in the download.

----------


## KurtB

> 1. Ensure that AllowOverType property is True.
> 
> 2. Not possible for standard. However, you can set DrawMode property to OwnerDraw. Then you can color all how you like at the cost of additional code in your sources. (Handling ItemDraw event etc.)


AllowOverType, huh? Duh! I didn't see that.
OwnerDraw is always a good thing. It's overkill for my desired usage, though.

Thanks for the quick response.

----------


## OldClock

Hey

VBCCR16 1.6.126

See the attached project.

1. Is it possible to prevent Windows from overriding a ComboBox's BackColor when using CboStyleDropDownList? I set a combobox to &H00C0FFFF& (gold color) and Windows XP correctly shows all three ComboBox styles in gold, but Windows 10 only shows CboStyleDropDownCombo and CboStyleSimpleCombo in gold while showing CboStyleDropDownList in gray (probably from the Windows color scheme).

2. Is it possible to programmatically disable the ComboBox drop-down animation? I wrote a routine to allow the user to search through a combo for a keyword and show only matching results. It works nicely in Windows XP where the drop-down shows instantly, but in Windows 10 the drop-down is animated and that makes searching slow.

3. When the mouse cursor hovers over the program window, Windows hides the mouse cursor when I call ComboBox.DroppedDown = True. That's very user-unfriendly. How do I prevent Windows from hiding the cursor?

4. Does the VBCCR ComboBox allow a better way of searching for partial matches at any point in the string than the way I did it?

Kind regards

----------


## OldClock

vbccr_testing_v1.0.0.zip above contains the compiled program. Attached here is the source code.
VBCCR16.OCX missing due to its 5MB size - the forum allows attachments of max 1MB.

----------


## Thierry76

Does anyone use the compiled version in VBA Excel professional environment with success ? (maybe few new happy users  :wave: )

----------


## Krool

> 1. Is it possible to prevent Windows from overriding a ComboBox's BackColor when using CboStyleDropDownList? I set a combobox to &H00C0FFFF& (gold color) and Windows XP correctly shows all three ComboBox styles in gold, but Windows 10 only shows CboStyleDropDownCombo and CboStyleSimpleCombo in gold while showing CboStyleDropDownList in gray (probably from the Windows color scheme).


No, that's the visual style. If you want to to have a BackColor shown in CboStyleDropDownList then you need to set .VisualStyles = False.




> 2. Is it possible to programmatically disable the ComboBox drop-down animation? I wrote a routine to allow the user to search through a combo for a keyword and show only matching results. It works nicely in Windows XP where the drop-down shows instantly, but in Windows 10 the drop-down is animated and that makes searching slow.


I am not aware of a solution to a specific ComboBox.
If you want to avoid animation for the whole system consider using SPI_SETCOMBOBOXANIMATION.




> 3. When the mouse cursor hovers over the program window, Windows hides the mouse cursor when I call ComboBox.DroppedDown = True. That's very user-unfriendly. How do I prevent Windows from hiding the cursor?


After some research this is a "common" issue and described as a "very obscure set of circumstances".
The edit control in the ComboBox hides the cursor when entering a character. (just like a normal TextBox also does)
However, moving the mouse in an edit control resolves this issue.
But the drop-down list will set the "mouse capture" when it shows the drop-down portion.
Thus when the hCursor is NULL in that moment the mouse cursor will kept hidden.

I will encounter the issue more and will soon make an update to refresh the hCursor upon CBN_DROPDOWN in case it is NULL. (there is a solution for this)




> 4. Does the VBCCR ComboBox allow a better way of searching for partial matches at any point in the string than the way I did it?


A Virtual ComboBox is a perfomant use-case for such a "searching" functionality.
However, it might be better (considering the slow drop-down animation) to use the IAutoComplete interface.
It can be attached to any edit control. (= ComboBox1.hWndEdit)




> Does anyone use the compiled version in VBA Excel professional environment with success ? (maybe few new happy users )


Do you mean 64bit or 32bit VBA ? Please note that VBCCR works only on 32bit VBA.

----------


## Semke

> Hi!
> I have 2 Features which would be nice to add to the ComboBox;
> 1) autocomplete from items in the list, with an option to raise an event if the text that was input is not an item in the list (this would be raised during the validate event, or even a new event could be created for this purpose.
> 2) cancel the dropdown before it has been dropped.


Hi! Krool
Did you see these suggestion? What do you think about it?

----------


## OldClock

> If you want to avoid animation for the whole system consider using SPI_SETCOMBOBOXANIMATION.


Great, thanks.

I tried that, but get a buggy result. When I disable combobox animation in Windows, SPI_*GET*COMBOBOXANIMATION returns False. Good. But when I use SPI_*SET*COMBOBOXANIMATION to set it to False, SPI_*GET*COMBOBOXANIMATION then returns True. What's going on?



```
    Call SystemParametersInfo(enSystemParametersInfo.SPI_GETCOMBOBOXANIMATION, 0, r_comboAniOrg, 0)
    MsgBox "r_comboAniOrg before: " & r_comboAniOrg

    If SystemParametersInfo(enSystemParametersInfo.SPI_SETCOMBOBOXANIMATION, 0, False, 0) Then
        MsgBox "Setting to False succeeded"
    Else
        MsgBox "Setting to False failed"
    End If

    Call SystemParametersInfo(enSystemParametersInfo.SPI_GETCOMBOBOXANIMATION, 0, r_comboAniOrg, 0)
    MsgBox "r_comboAniOrg after: " & r_comboAniOrg
```

See attached source code.

----------


## Krool

Update released for ComboBoxW, FontCombo, VirtualCombo and ImageCombo control.
Those all controls receive CBN_DROPDOWN.

There is this misbehavior in user32.dll that when sending a CB_SHOWDROPDOWN upon CBN_EDITCHANGE that the hCursor is NULL and due to the ComboLBox mouse capture will be kept NULL until the drop-down list closes up again. (CBN_CLOSEUP)

Therefore new RefreshMousePointer is included in Common.bas. (due to it's generic purpose)



```
Case CBN_DROPDOWN
    If PropStyle <> CboStyleDropDownList And ComboBoxEditHandle <> 0 Then
        If GetCursor() = 0 Then
            ' The mouse cursor can be hidden when showing the drop-down list upon a change event.
            ' Reason is that the edit control hides the cursor and a following mouse move will show it again.
            ' However, the drop-down list will set a mouse capture and thus the cursor keeps hidden.
            ' Solution is to refresh the cursor by sending a WM_SETCURSOR.
            Call RefreshMousePointer(lParam)
        End If
    End If
```



```
Public Sub RefreshMousePointer(Optional ByVal hWndFallback As Long)
Const WM_SETCURSOR As Long = &H20, WM_NCHITTEST As Long = &H84, WM_MOUSEMOVE As Long = &H200
Dim P As POINTAPI, hWndCursor As Long
GetCursorPos P
hWndCursor = GetCapture()
If hWndCursor = 0 Then hWndCursor = WindowFromPoint(P.X, P.Y)
If hWndCursor <> 0 Then
    If GetWindowThreadProcessId(hWndCursor, 0) <> App.ThreadID Then hWndCursor = hWndFallback
Else
    hWndCursor = hWndFallback
End If
If hWndCursor <> 0 Then SendMessage hWndCursor, WM_SETCURSOR, hWndCursor, ByVal MakeDWord(SendMessage(hWndCursor, WM_NCHITTEST, 0, ByVal Make_XY_lParam(P.X, P.Y)), WM_MOUSEMOVE)
End Sub
```




> Hi!
> I have 2 Features which would be nice to add to the ComboBox;
> 1) autocomplete from items in the list, with an option to raise an event if the text that was input is not an item in the list (this would be raised during the validate event, or even a new event could be created for this purpose.
> 2) cancel the dropdown before it has been dropped.


1) What do you mean exactly? Please describe as detailed as possible. You can check in Validate() event if an item exists? Why re-invent the wheel?
2) Not possible. You cannot cancel CBN_DROPDOWN. However, I will try to find another mechanism to achieve something similar.




> I tried that, but get a buggy result. When I disable combobox animation in Windows, SPI_*GET*COMBOBOXANIMATION returns False. Good. But when I use SPI_*SET*COMBOBOXANIMATION to set it to False, SPI_*GET*COMBOBOXANIMATION then returns True. What's going on?


1. Change r_comboAniOrg As Boolean to As Long
2. use ByVal 0& instead of False -> SPI_SETCOMBOBOXANIMATION, 0, ByVal 0&

----------


## Semke

> 1) What do you mean exactly? Please describe as detailed as possible. You can check in Validate() event if an item exists? Why re-invent the wheel?


like you have on internet explorer/ edge / chrome, when you start typing an address it autofills the rest of the text.

about the validate event, you are probably right.

----------


## OldClock

Fantastic, thank you!

----------


## OldClock

Hey

I have an issue and a question regarding the VBCCR16.TreeView:

1. Problem: The first root node collapses when the TreeView gets focus. To reproduce, populate the treeview using a hierarchical structure (parent and child nodes), and expand all nodes. Programmatically set focus on some other widget. Run the program. Hit the Tab key to switch focus from that other widget to the TreeView, and the first root node and all of its children collapse. Expected behavior: nothing collapses by itself unless the user hits the "[-]" icon to collapse it. Reproduced in latest commit ba8dd7c (1.6.130).

2. How can I show checkboxes only on the lowest-level nodes? i.e. not on any node which has children.

Sample project attached.

----------


## Krool

> Hey
> 
> I have an issue and a question regarding the VBCCR16.TreeView:
> 
> 1. Problem: The first root node collapses when the TreeView gets focus. To reproduce, populate the treeview using a hierarchical structure (parent and child nodes), and expand all nodes. Programmatically set focus on some other widget. Run the program. Hit the Tab key to switch focus from that other widget to the TreeView, and the first root node and all of its children collapse. Expected behavior: nothing collapses by itself unless the user hits the "[-]" icon to collapse it. Reproduced in latest commit ba8dd7c (1.6.130).
> 
> 2. How can I show checkboxes only on the lowest-level nodes? i.e. not on any node which has children.
> 
> Sample project attached.


1. Set .SingleSel property to False. When having it to True it auto-collapses...

2. Set the .NoImages property of a TvwNode to True.
Red marked text is the addition in your code.


```
For Each n In tv.Nodes
    n.Expanded = True
    If n.Children > 0 Then n.NoImages = True
Next
```

Or (alternatively)


```
For Each n In tv.Nodes
    n.Expanded = True
    If Not n.Child Is Nothing Then n.NoImages = True
Next
```

----------


## OldClock

Thank you!

----------


## Krool

Update released.

Enhancement for the FrameW control.

The UserControl.ForwardFocus is now set to True. (UserControl.CanGetFocus keeps = False)


With this change and using the internal UserControl.AccessKey property the caption now effectively handles mnemonics.
Also the UserControl exposes now the TabIndex property to the Extender. (like the VB.Frame also exposes the TabIndex property)

So in below example, pressing ALT+M will move the focus to the TextBoxW1 control.
In order to work properly the TabIndex property must be set meaningful. (means "TextBoxW1.TabIndex = FrameW1.TabIndex + 1" in this example)



The VB.Label (and LabelW) control offers a UseMnemonic property, which controls whether an & in the caption defines an access key or not.
The VB.Frame lacks this functionality. The FrameW includes now a UseMnemonic property.

Info: VBCCR16 will not see this change, only the upcoming VBCCR17..

----------


## Krool

VBCCR17.OCX now released.

----------


## c141heaven

> VBCCR17.OCX now released.



I'm confused about where to actually get this file.  I've scanned the thread and all I see is the original release.

----------


## Krool

> I'm confused about where to actually get this file.  I've scanned the thread and all I see is the original release.


There is a dedicated thread for the OCX version. (https://www.vbforums.com/showthread....55#post5129155)

----------


## c141heaven

Thanks.

----------


## Crapahute

Hello,
With the latest version, do we have now to remove this line from our projects :
Call ComCtlsInitIDEStopProtection

Thank you

----------


## Krool

> Hello,
> With the latest version, do we have now to remove this line from our projects :
> Call ComCtlsInitIDEStopProtection
> 
> Thank you


Yes, it's removed. It anyhow didn't protect the IDE in case of an Error stop/break. It just resolved the End button.
So, in order to strip down the project it got removed. If you wish full IDE safety then resort to the OCX version.

Even without the IDEStopProtection handler it is half way IDE safe. Try the ComCtlsDemo project and run the MainForm. Press the end button. No crash, even without a IDEStopProtection handler.

However, in more complex scenarios the IDE crashes of course. (e.g. in ComCtlsDemo if you run the MainForm and open the RichTextBox modal demo form in addition, then pressing end button crashes the IDE)

But the Std-EXE version is for advanced users only who know exactly what they are doing.
It would blow up the project to have full IDE safety. (and it's so easy to get IDE safety by just resorting to the OCX version)

----------


## Mith

Is there any guide that shows how to convert projects from 1.6 to 1.7?

Quick-Guide by myself:

vbp files:

replace the line:


```
Object={0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.7#0; VBCCR16.OCX
```

with:


```
Object={7020C36F-09FC-41FE-B822-CDE6FBB321EB}#1.0#0; VBCCR17.OCX
```


frm files:

replace the line:


```
Object = "{0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.7#0"; "VBCCR16.OCX"
```

with:


```
Object = "{7020C36F-09FC-41FE-B822-CDE6FBB321EB}#1.0#0"; "VBCCR17.OCX"
```


frm/bas files:

replace everywhere the text:


```
VBCCR16.
```

with:


```
VBCCR17.
```

----------


## Mith

> VBCCR17.OCX now released.


I just remember you added a lot of features the last months but only available using the Std-Exe version.

What features are new compared with OCX v1.6?

----------


## Krool

> I just remember you added a lot of features the last months but only available using the Std-Exe version.
> 
> What features are new compared with OCX v1.6?


When you look in the "List of revisions" then all new features as of 25-Feb-2020 are not contained in the v1.6.
However, bugfixes which do not break binary compatibility were revised also in v1.6.

As of now (v1.7) the features are in sync between Std-EXE and OCX version. And I certainly do not foreseen to change that anymore, unless there is a good reason for..
Bugreports however will be fixed then in both Std-EXE and OCX version.

----------


## DaveDavis

Have anyone tested the demo with DpiAwareness = PerMonitorV2? It seems not so perfect. Please krool do some inspections.

----------


## Krool

> Have anyone tested the demo with DpiAwareness = PerMonitorV2? It seems not so perfect. Please krool do some inspections.


VBCCR is system dpi-aware. (pre-condition for everything that shall come on-top)

PerMonitorV2 is extremely difficult to manage properly. (even MS stated that much needs to be handled)
Example: Usage of GetSystemMetricsForDpi instead of GetSystemMetrics upon a WM_DPICHANGED event.

You stated that VBCCR is odd on PerMonitorV2. That's true, because the comctl32.dll handles _already_ "some" part upon a WM_DPICHANGED message and other GUI parts are untouched.
If comctl32.dll would not handle WM_DPICHANGED at all the result would synchronous. (means no scale change for all GUI parts)

MSDN states:



> There are two versions of Per-Monitor awareness that an application can register itself as: version 1 and version 2 (PMv2). Registering a process as running in PMv2 awareness mode results in:
> 
> - The application being notified when the DPI changes (both the top-level and child HWNDs)
> - The application seeing the raw pixels of each display
> - The application never being bitmap scaled by Windows
> - Automatic non-client area (window caption, scroll bars, etc.) DPI scaling by Windows
> - Win32 dialogs (from CreateDialog) automatically DPI scaled by Windows
> - Theme-drawn bitmap assets in *common controls* (checkboxes, button backgrounds, etc.) being automatically rendered at the appropriate DPI scale factor


I have no idea of somebody managed already to make a whole VB6 app PerMonitorV2 DPI aware.
PerMonitorV1 is even more difficult as only the top-level window receives a WM_DPICHANGED.

There is no real walk-trough.. maybe at some point LaVolpe manages to release a helper class to ease PerMonitorV2 to scale all Fonts etc.
When I would handle WM_DPICHANGED isolated in my VBCCR project there is the danger of potentially "double-handle" a scaling.

Therefore it would be better to have a common helper class (e.g. from LaVolpe at some point) and then to see how things are going.

And maybe then to see if there are some exceptions to handle isolated in VBCCR where the helper class cannot help. (e.g. above example with internal usage of GetSystemMetricsForDpi in VBCCR etc.)

_Edit_: I forgot that LaVolpe's helper class is already out. Though I did not try it nor do I need PerMonitorV2 really.

----------


## Eduardo-

I don't think it is an issue that the Common Controls should or may handle because it is something about the forms size/position and control size/positions, something that need to be handled on the host side.

Also to note, that if the App need to be RightToLeft ready, that adds more complexity.

Also, in forms where the controls are placed fixed, statically, it could be handled transparently with a class, but for controls that are sized or moved in code based on certain conditions, that need to be handled in place applying the correction factor.

All this would, at the same time, fix the non-integer twips-per-pixel issue.

----------


## DaveDavis

> VBCCR is system dpi-aware. (pre-condition for everything that shall come on-top)
> 
> PerMonitorV2 is extremely difficult to manage properly. (even MS stated that much needs to be handled)
> Example: Usage of GetSystemMetricsForDpi instead of GetSystemMetrics upon a WM_DPICHANGED event.


Please make an effort to improve MonthView, it is one of obvious non-compatibility (unusable) with PerMonitorV2, Wondering why DTPicker's Monthview dropdown is OK.

Edited: FYI, On.NET, MonthCalendar has SingleMonthSize property that we can use to set the size. From .NET 4.7.2, MonthCalendar is DpiAware, it do auto scale following with DpiAwareness setting in app.config/manifest.

----------


## Krool

> Please make an effort to improve MonthView, it is one of obvious non-compatibility (unusable) with PerMonitorV2, Wondering why DTPicker's Monthview dropdown is OK.


OK, please test following change for MonthView, if you confirm I will release a bugfix:

Before


```
Private Sub UserControl_Resize()
Static InProc As Boolean
If InProc = True Then Exit Sub
InProc = True
With UserControl
If DPICorrectionFactor() <> 1 Then Call SyncObjectRectsToContainer(Me)
If MonthViewHandle = 0 Then InProc = False: Exit Sub
If MonthViewReqWidth <> 0 And MonthViewReqHeight <> 0 Then
    [...]
    .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((MonthViewReqWidth + ExtraWidth), vbPixels, vbContainerSize), .ScaleY((MonthViewReqHeight + ExtraHeight), vbPixels, vbContainerSize)
End If
If DPICorrectionFactor() <> 1 Then Call SyncObjectRectsToContainer(Me)
MoveWindow MonthViewHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
End With
InProc = False
End Sub
```

After (new code marked as red)


```
Private Sub UserControl_Resize()
Static InProc As Boolean
If InProc = True Then Exit Sub
InProc = True
With UserControl
If DPICorrectionFactor() <> 1 Then Call SyncObjectRectsToContainer(Me)
If MonthViewHandle = 0 Then InProc = False: Exit Sub
If MonthViewReqWidth <> 0 And MonthViewReqHeight <> 0 Then
    [...]
    ' .Extender.Move .Extender.Left, .Extender.Top, .ScaleX((MonthViewReqWidth + ExtraWidth), vbPixels, vbContainerSize), .ScaleY((MonthViewReqHeight + ExtraHeight), vbPixels, vbContainerSize)
    .Extender.Width = .ScaleX((MonthViewReqWidth + ExtraWidth), vbPixels, vbContainerSize)
    .Extender.Height = .ScaleY((MonthViewReqHeight + ExtraHeight), vbPixels, vbContainerSize)
End If
If DPICorrectionFactor() <> 1 Then Call SyncObjectRectsToContainer(Me)
MoveWindow MonthViewHandle, 0, 0, .ScaleWidth, .ScaleHeight, 1
End With
InProc = False
End Sub
```

----------


## DaveDavis

```
    .Extender.Width = .ScaleX((MonthViewReqWidth + ExtraWidth), vbPixels, vbContainerSize)
    .Extender.Height = .ScaleY((MonthViewReqHeight + ExtraHeight), vbPixels, vbContainerSize)
```

I didn't see the difference.
I have to set MonthColumns and MonthRows =2 then the calendar can show whole size (wider a bit).

Edited:
It seems we need GetDpiForWindow then do scaling, something like this:


```
.ScaleX((MonthViewReqWidth + ExtraWidth) * CurrentDpiScale , vbPixels, vbContainerSize)
```

I tried to write hard code for testing (my 2nd Monitor is 175% scale), then I see almost the same with MonthCalendar in .NET 4.7.2:


```
.Extender.Move .Extender.Left, .Extender.Top, .ScaleX((MonthViewReqWidth + ExtraWidth) * 1.75, vbPixels, vbContainerSize), 

.ScaleY((MonthViewReqHeight + ExtraHeight + 14) * 1.75, vbPixels, vbContainerSize)
```

If my 2nd Monitor is 150% scale, also I see almost the same with MonthCalendar in .NET 4.7.2:


```
.Extender.Move .Extender.Left, .Extender.Top, .ScaleX((MonthViewReqWidth + ExtraWidth) * 1.5, vbPixels, vbContainerSize), 

.ScaleY((MonthViewReqHeight + ExtraHeight + 14) * 1.5, vbPixels, vbContainerSize)
```

----------


## Krool

> ```
>     .Extender.Width = .ScaleX((MonthViewReqWidth + ExtraWidth), vbPixels, vbContainerSize)
>     .Extender.Height = .ScaleY((MonthViewReqHeight + ExtraHeight), vbPixels, vbContainerSize)
> ```
> 
> I didn't see the difference.


Well, you showed a picture with a MonthView "out-of-place".
I attempted to fix the position. Don't know. Thought of


```
.Extender.Move .Extender.Left, .Extender.Top
```

screwing things up. So if it's unchanged using .Width/.Height instead of .Move then I don't know what's going on.
All other controls are correctly located though.

I don't speak about size/scale because this I won't handle. (IMO the app is responsible)
Exeption might be the MonthView as it self resizes. So an App can't fix it. But I want to first ensure the location is fixed.

----------


## DaveDavis

> Well, you showed a picture with a MonthView "out-of-place".


The location has no problem. The picture confused you, my apology. I purposely move out the monthview from original position to the right side on the mainForm to say it is not showing entirely (auto size problem).

----------


## smileyoufucn

StatusBar ：
Unsuccessful setting of status bar background color

----------


## Nouyana

Krool, can you help me with translation of descriptions? Please, look at the screenshot. How could it be so? I have changed (translated) the "Attribute Left.VB_Description" value in the CheckBoxW.ctl file. Then I opened the ComCtlsDemo.vbp project and got two different descriptions of one property.

----------


## Krool

> StatusBar ：
> Unsuccessful setting of status bar background color


When you read the property description it gives you the answer:



> Returns/sets the background color used to display text and graphics in an object. This property is ignored if the version of comctl32.dll is 6.0 or higher and the visual styles property is set to true







> Krool, can you help me with translation of descriptions? Please, look at the screenshot. How could it be so? I have changed (translated) the "Attribute Left.VB_Description" value in the CheckBoxW.ctl file. Then I opened the ComCtlsDemo.vbp project and got two different descriptions of one property.


The .Left property description gets overwritten by the VBControlExtender.
It is actually not needed to declare it in the .ctl file. I just did it so "shadow" objects (e.g. "As CheckBoxW") can make use of such VBControlExtender properties.

----------


## Nouyana

> The .Left property description gets overwritten by the VBControlExtender.
> It is actually not needed to declare it in the .ctl file. I just did it so "shadow" objects (e.g. "As CheckBoxW") can make use of such VBControlExtender properties.


Thank you. I am working on translation of your control's descriptions into Russian. I am using the official Russian help file for VB5. Look at theese files, may be you will find them useful:

GetVbDescr.bas
This is a ready to use program (Sub Main) without GUI. It creates an mdb database with descriptions of the control's subs, events, properties, etc. All you need to use it is to set up the sSrcPath constant (path to "Builds" folder) and run it. The program will create a vbccr.mdb database with all the descriptions.

SetVbDescr.bas
This program will replace the VB_Description with value from vbccr.mdb (t_DESCR.SUB_TRANSL field). All you need to use it is to set up the sSrcPath constant.

vbccr.pdf
This is a standard Microsoft Access report. Somebody can use it as a help file.

I will improve this program in the future. I want to add a GUI. So we will be able to automatically translate descriptions within the new versions of controls.

----------


## SuperDre

> Thank you. I am working on translation of your control's descriptions into Russian. I am using the official Russian help file for VB5. Look at theese files, may be you will find them useful:
> 
> GetVbDescr.bas
> This is a ready to use program (Sub Main) without GUI. It creates an mdb database with descriptions of the control's subs, events, properties, etc. All you need to use it is to set up the sSrcPath constant (path to "Builds" folder) and run it. The program will create a vbccr.mdb database with all the descriptions.
> 
> SetVbDescr.bas
> This program will replace the VB_Description with value from vbccr.mdb (t_DESCR.SUB_TRANSL field). All you need to use it is to set up the sSrcPath constant.
> 
> vbccr.pdf
> ...


Not to downplay your intention and work, but what's the use of this? I think most people who are still using VB6 will know english as I think most of the IDE isn't available in any other language anyway, and replacing code in orginal files is certainly not a good way to go about it.

----------


## Nouyana

> Not to downplay your intention and work, but what's the use of this? I think most people who are still using VB6 will know english as I think most of the IDE isn't available in any other language anyway, and replacing code in orginal files is certainly not a good way to go about it.


First of all, it is a way to create a documentation. The vbccr.pdf is a draft. I think it should be a chm file.

For the second, I have been using VB6 for 15 years. And yes, I think the IDE should be original (in English). But Russian descriptions and help files make my work faster and more convenient.

----------


## SuperDre

> First of all, it is a way to create a documentation. The vbccr.pdf is a draft. I think it should be a chm file.
> 
> For the second, I have been using VB6 for 15 years. And yes, I think the IDE should be original (in English). But Russian descriptions and help files make my work faster and more convenient.


Ok, but for the few times you actually look at the descriptions, isn't the time better spent on just developing new features for your applications?
It's a lot of work to translate all the descriptions, and in reality, not many people will use it as the object browser shows everything you need, personally as everything is in english in the IDE I have a harder time reading something if some stuff are in dutch(my native language) and most in english, so I work faster if it's just in english.. But then again, I don't have any problems with reading english..

----------


## DaveDavis

What is the top & bottom white space in Krool's MonthView? How to measure the height? I didn't see in MS MonthView.

----------


## Krool

> What is the top & bottom white space in Krool's MonthView? How to measure the height? I didn't see in MS MonthView.


I cannot replicate. I tried comctl32.dll both v5 and v6 (manifested) and no white spaces either way for the VBCCR MonthView. (VisualStyles = False for v6 comctl32.dll)

Can you provide a demo ?

----------


## DaveDavis

> I cannot replicate. I tried comctl32.dll both v5 and v6 (manifested) and no white spaces either way for the VBCCR MonthView. (VisualStyles = False for v6 comctl32.dll)
> 
> Can you provide a demo ?


I put an offset 14 and forget to remove. I am so embarrassed... Forgive me.

----------


## DaveDavis

I have done some experimental trail on PerMonitorV2 for MonthView. I subclass the  WM_DPICHANGED_BEFOREPARENT inside MonthView to get current Dpi to re-scale MonthView, so that when we dragging the demo Form to another monitor, the MonthView can be sizing accordingly. I used PerMonitorV2 marked in Resource file.
1) New Resource file
2) Delcare: 


```
Private Declare Function GetDpiForWindow Lib "user32" (ByVal hWnd As Long) As Long
Private DpiScale As Single
Private currentDpi As Single, oldDpi As Single
```

3) UserControl_Resize


```
If DpiScale = 0 Then DpiScale = 1
.Extender.Move .Extender.Left, .Extender.Top, .ScaleX(CSng(MonthViewReqWidth + ExtraWidth) * DpiScale, vbPixels, vbContainerSize), .ScaleY(CSng(MonthViewReqHeight + ExtraHeight) * DpiScale, vbPixels, vbContainerSize)
```

4) UserControl_Show:


```
Private Sub UserControl_Show()
oldDpi = currentDpi
currentDpi = GetDpiForWindow(UserControl.ContainerHwnd)
If currentDpi = 0 Then currentDpi = 96#
If (oldDpi <> currentDpi) Then
   DpiScale = (currentDpi / 96#)
   Call UserControl_Resize
End If
End Sub
```

5) WindowProcUserControl:


```
If wMsg = &H2E2 Then
   oldDpi = currentDpi
   currentDpi = GetDpiForWindow(hWnd)
   If (oldDpi <> currentDpi) Then
      DpiScale = (currentDpi / 96#)
      Call UserControl_Resize
   End If
End If
```

----------


## Nouyana

> Ok, but for the few times you actually look at the descriptions, isn't the time better spent on just developing new features for your applications?


For me personally, translation is a way of learning. There are many new features in  Krool controls. I hope it will keep my time in the future.




> It's a lot of work to translate all the descriptions, and in reality, not many people will use it as the object browser shows everything you need, personally as everything is in english in the IDE I have a harder time reading something if some stuff are in dutch(my native language) and most in english, so I work faster if it's just in english.. But then again, I don't have any problems with reading english..


I think it will take me about three weeks to translate 1,390 descriptions. If someone helps me it will be faster.

As I said, I want to create a documentation for the controls. Object browser shows only 5% of what I need (no examples, no restrictions, no tips). Of course, I cannot cope with this task alone. So, you may help me (programmatically creating a help file from vbccr.mdb, for example). I also want to add the examples from ComCtlsDemo.vbp to the help file. Maybe it'll be better to create a wiki-project for that purposes. Are you in?

----------


## Nouyana

> As of now (v1.7) the features are in sync between Std-EXE and OCX version. And I certainly do not foreseen to change that anymore, unless there is a good reason for..
> Bugreports however will be fixed then in both Std-EXE and OCX version.


Krool, please help me figure out how the ListBackColor and IntegralHeight properties work. I tried to use them with different operating systems and with different font sizes. There were no effect.

*Project example:*
IntegralHeight.zip

----------


## Krool

> Krool, please help me figure out how the ListBackColor and IntegralHeight properties work. I tried to use them with different operating systems and with different font sizes. There were no effect.


The ListBackColor is only in effect when the UseListBackColor property is set to True. (will return list back color brush on WM_CTLCOLORLISTBOX only when UseListBackColor is True, default is False)

What you mean with IntegralHeight ?
I think you mix up things. MSDN says about CBS_NOINTEGRALHEIGHT (equivalent of .IntegralHeight = False then CBS_NOINTEGRALHEIGHT is set)
_Specifies that the size of the combo box is exactly the size specified by the application when it created the combo box. Normally, the system sizes a combo box so that it does not display partial items._
That means the Height (!) of the drop-down list box area, not the width.

If you want to have the big size text fit into the drop-down area then try:
A) .HorizontalExtent = .GetIdealHorizontalExtent()
B) .DropDownWidth = .GetIdealHorizontalExtent() + Me.ScaleX(4, vbPixels, Me.ScaleMode) ' small extra buffer to account border widths etc.

Option A) uses CB_SETHORIZONTALEXTEND API.
MSDN: _If the width of the list box is smaller than this value, the horizontal scroll bar horizontally scrolls items in the list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden or, if the combo box has the CBS_DISABLENOSCROLL style, disabled._
You can use the .DisableNoScroll property to control whether CBS_DISABLENOSCROL is set or not.

Option B) uses CB_SETDROPPEDWIDTH API.
MSDN: _By default, the minimum allowable width of the drop-down list box is zero. The width of the list box is either the minimum allowable width or the combo box width, whichever is larger._

The .GetIdealHorizontalExtent() function is a convenient wrapper which calculates the "best" width, accounting possible WS_VSCROLL style and testing the string widths using the selected font.

----------


## Nouyana

> What you mean with IntegralHeight ?
> I think you mix up things. MSDN says about CBS_NOINTEGRALHEIGHT (equivalent of .IntegralHeight = False then CBS_NOINTEGRALHEIGHT is set)
> _Specifies that the size of the combo box is exactly the size specified by the application when it created the combo box. Normally, the system sizes a combo box so that it does not display partial items._
> That means the Height (!) of the drop-down list box area, not the width.


Krool, thanks for the detailed answer. I really mixed things up, and you helped me figure it out. But now I still want to understand how the standard IntegralHeight property works :Smilie: 

For example, when I increase the *.Font.Size* at runtime, the *.Height* also increases. This is independent of the *.IntegralHeight* value. How can I see the "partial items"?

----------


## SuperDre

> Krool, thanks for the detailed answer. I really mixed things up, and you helped me figure it out. But now I still want to understand how the standard IntegralHeight property works
> 
> For example, when I increase the *.Font.Size* at runtime, the *.Height* also increases. This is independent of the *.IntegralHeight* value. How can I see the "partial items"?


*IntegralHeight* set to _True_ just makes sure the items are completely visible, so the *Height* is always 'rounded' to a full item visible, so if you increase the size of the font it will adjust the height with it. Set it to _False_ if you don't want that, the *Height* will be as you've set it.

----------


## Nouyana

> Set it to _False_ if you don't want that, the *Height* will be as you've set it.


I thought so. But it just doesn't work this way.

----------


## SuperDre

> I thought so. But it just doesn't work this way.


Oh, you're talking about the combobox? sorry I only thought about the listbox. As far as I know, the combobox is always integral height, just like it also doesn't seem to acknowledge 3D on/off (at least not with the standard VB version).

----------


## Nouyana

> Oh, you're talking about the combobox? sorry I only thought about the listbox. As far as I know, the combobox is always integral height, just like it also doesn't seem to acknowledge 3D on/off (at least not with the standard VB version).


But the property is exist. Let's wait for the Krool's answer.

----------


## Nouyana

If it is possible, It would be great to add a LimitToList property to the ComboBoxW control like in Microsoft Access.

https://docs.microsoft.com/en-us/off...ox.limittolist

----------


## LaVolpe

> But the property is exist. Let's wait for the Krool's answer.


Depends on the combobox style. Only one of the styles supports IntegralHeight=False.
As for the LimitToList of Access? Isn't that what combobox Style 2 is?

----------


## Nouyana

> Depends on the combobox style. Only one of the styles supports IntegralHeight=False.


Are you talking about SimpleCombo style? Without any list at all?





> As for the LimitToList of Access? Isn't that what combobox Style 2 is?


I usually use Style 2. Style 0 is more flexible (you can make it autofill aware or filter the list during user typing), but user can put there any garbage and leave the control.

----------


## LaVolpe

No, style 1. Try it. Set IntegralHeight = False, increase the size of the comboxbox in design. In form load, add your items, you'll notice partial items are shown. Style 1 is like a hybrid comboxbox + listbox.

With Krool's control, you can turn AutoSelect on (Style 0) which will update the ListIndex property if the user selected something in the list, ListIndex is not -1 else it is -1. Check that property.

----------


## Nouyana

> No, style 1. Try it. Set IntegralHeight = False, increase the size of the comboxbox in design. In form load, add your items, you'll notice partial items are shown. Style 1 is like a hybrid comboxbox + listbox.


Thank you! Yes, the last item is partial. The ItemHeight property allows me to see all "partial items".




> With Krool's control, you can turn AutoSelect on (Style 0) which will update the ListIndex property if the user selected something in the list, ListIndex is not -1 else it is -1. Check that property.


Selecting something in the list manualy is not realy the AutoSelect. User can leave the control without any clicking.

----------


## Nouyana

I edited my previous post. We just posted them at the same time.

----------


## LaVolpe

> Selecting something in the list manualy is not realy the AutoSelect. User can leave the control without any clicking.


That's why you have a LostFocus and Validate event. Use it.

----------


## Nouyana

> That's why you have a LostFocus and Validate event. Use it.


I just suggested. This property is almost always used in Access.

----------


## Nouyana

Krool, why the AutoSelect property of ComboBox doesn't work when the control isn't dropped down? Was it intended?

----------


## Nouyana

> That's why you have a LostFocus and Validate event. Use it.


Maybe you are right. We have a FindItem property in the ComboBoxW control. Thus, the Validate subroutine may look very short:


VB Code:
Private Sub ComboBoxW1_Validate(Cancel As Boolean)
   With ComboBoxW1
      If .FindItem(.Text) = -1 Then Cancel = True
   End With
End Sub

----------


## Nouyana

Can anyone please explain what the PictureAndCaption property is for? Under Windows XP without comctl32.dll v.6.1 everything works fine without this property.

----------


## Krool

> Can anyone please explain what the PictureAndCaption property is for? Under Windows XP without comctl32.dll v.6.1 everything works fine without this property.


The PictureAndCaption property is meaningful only when the style property is 0 - Normal.

----------


## Nouyana

> The PictureAndCaption property is meaningful only when the style property is 0 - Normal.


Thank you. When can this be useful? Why not just use style 2?

----------


## Nouyana

> Thank you. When can this be useful? Why not just use style 2?


I meant style 1, of course.

----------


## Nouyana

Error with TextBoxW.OverTypeMode property

----------


## Krool

> Error with TextBoxW.OverTypeMode property


I cannot replicate your problem. I just tested AllowOverType property (which toggles OverTypeMode property upon Insert key) and it worked.

Please bundle a demo showing the issue. Thanks




> When can this be useful? Why not just use style 1?


Style 1 - Graphical implies the BS_OWNERDRAW window style. It's just another possibility to have picture and caption without depending on BS_OWNERDRAW.




> why the AutoSelect property of ComboBox doesn't work when the control isn't dropped down? Was it intended?


I don't know what you mean exactly. When I set the ComboBoxW1 style to 0 - DropDownCombo in the ComCtlsDemo project and I type 'charlie' it automatically becomes 'Charlie' without using the dropdown. So for me it is working. (the ListIndex is updated)
Again please provide demo so I can look what the problem is.

----------


## Nouyana

> I don't know what you mean exactly. When I set the ComboBoxW1 style to 0 - DropDownCombo in the ComCtlsDemo project and I type 'charlie' it automatically becomes 'Charlie' without using the dropdown. So for me it is working. (the ListIndex is updated)
> Again please provide demo so I can look what the problem is.


I have tested the AutoSelect property under:
1. WinXP SP3 with comctl32.dll versions 5.82.2900.6028 and 6.0.2600.0
2. Win10 x64
It was ComCtlsDemo project from v1.7.0.0

I tried two experiments. The first one:
1. I made the ComboBoxW1 *dropped down* (style 0)
2. I typed "*char*" in the text field of ComboBoxW1
3. I pressed the *Tab* key on my keyboard
4. The text field *was filled* automatically and the *ListIndex was updated*

The second experiment:
1. I made the ComboBoxW1 *closed up* (style 0)
2. I typed "*charlie*" in the text field of ComboBoxW1
3. I pressed the *Tab* key on my keyboard
4. The text field *was NOT changed* automatically and the *ListIndex = -1*






> I cannot replicate your problem. I just tested AllowOverType property (which toggles OverTypeMode property upon Insert key) and it worked.
> Please bundle a demo showing the issue. Thanks.


Here it is. Tested under WinXP SP3 with comctl32.dll version 5.82.2900.6028
CCRP v1.7.0.0

OverTypeMode.zip

----------


## Krool

> I have tested the AutoSelect property under:
> 1. WinXP SP3 with comctl32.dll versions 5.82.2900.6028 and 6.0.2600.0
> 2. Win10 x64
> It was ComCtlsDemo project from v1.7.0.0
> 
> I tried two experiments. The first one:
> 1. I made the ComboBoxW1 *dropped down* (style 0)
> 2. I typed "*char*" in the text field of ComboBoxW1
> 3. I pressed the *Tab* key on my keyboard
> ...


The ComboBoxW1 in the ComCtlsDemo project has AutoSelect property as False. Please ensure to set it to True.




> Here it is. Tested under WinXP SP3 with comctl32.dll version 5.82.2900.6028
> CCRP v1.7.0.0
> 
> OverTypeMode.zip


I could replicate it on Windows XP, but not on Windows 10.
The root cause is that there is an access violation when the edit control receives EM_REPLACESEL with a null pointer.
The RichEdit control does not crash with a null pointer and EM_REPLACESEL.

My guess is that after Windows XP there was a fix so that a null pointer in EM_REPLACESEL does not crash anymore the edit control.
I have noted this down and will probably soon make a fix that kinda looks like following for the SelText property:


```
If StrPtr(Value) = 0 Then Value = ""
```

----------


## Nouyana

> The ComboBoxW1 in the ComCtlsDemo project has AutoSelect property as False. Please ensure to set it to True.


Oh, yes. You are right. I forgot it.  :Big Grin:  But the problem is exist. When you type "charlie", it becomes "Charlie". But when you type "char", the behavior depends on the DroppedDown state. As I understand, this is not the problem of AutoSelect property. It would be nice if "Char" always became "Charlie".

----------


## Krool

> Oh, yes. You are right. I forgot it.  But the problem is exist. When you type "charlie", it becomes "Charlie". But when you type "char", the behavior depends on the DroppedDown state. As I understand, this is not the problem of AutoSelect property. It would be nice if "Char" always became "Charlie".


In a dropped down state the additional search kicks in by windows.
So all normal and no issue here.

----------


## Krool

> I could replicate it on Windows XP, but not on Windows 10.
> The root cause is that there is an access violation when the edit control receives EM_REPLACESEL with a null pointer.
> The RichEdit control does not crash with a null pointer and EM_REPLACESEL.
> 
> My guess is that after Windows XP there was a fix so that a null pointer in EM_REPLACESEL does not crash anymore the edit control.
> I have noted this down and will probably soon make a fix that kinda looks like following for the SelText property:
> 
> 
> ```
> ...


I quote myself now.. This fix has been applied now.

----------


## Nouyana

Krool, how does the FontCombo.BuddyControl property work? What kind of control should I use with this property?

----------


## Krool

> Krool, how does the FontCombo.BuddyControl property work? What kind of control should I use with this property?


The FontCombo.BuddyControl can only buddy another FontCombo control.
Means the first one has the font names and the buddied second One FontCombo the font sizes respectively.

----------


## Nouyana

> The FontCombo.BuddyControl can only buddy another FontCombo control.
> Means the first one has the font names and the buddied second One FontCombo the font sizes respectively.


Thanks!  :Smilie:

----------


## Nouyana

What about the VBFlexGrid.HitTest? This is a Sub, not a Function. But it should "return a value which indicates the element located at the specified X and Y coordinates."

The same question about the ComputeControlSize method of the ListView and MonthView controls.

----------


## Krool

> What about the VBFlexGrid.HitTest? This is a Sub, not a Function. But it should "return a value which indicates the element located at the specified X and Y coordinates."
> 
> The same question about the ComputeControlSize method of the ListView and MonthView controls.


VBFlexGrid.HitTest is a Sub. The return values are stored as property .HitResult/.HitRow/.HitCol.

ComputeControlSize is also a Sub. The params are passed ByRef. So use variables.

----------


## Tech99

I don't know is this intended or not behaviour, but...
Monthview does not refresh correctly, when multiple months are shown and selection extends to month(s) over leftmost month, which are not shown after mouseleave event.

Select range extending to second and or third month displayed.
After MouseLeave and MouseEnter events, monthview draws only leftmost month date range selection.

----------


## vbLewis

Krool, Im adding column headers and then items to the listview in report mode on form load. Im getting a Itemclick then an ItemSelect event as the first listItem is added before any following columns are even filled out or the listview is visible or the form is fully loaded. This makes my click and select code fail because of incomplete information. Is this a bug or intended behavior? I can set a flag to delay processing till initial load is done if needed but was curious...

----------


## Mustaphi

Hi Krool 
My question is about DTPicker 

I want to know if possible to  automatically move to next datepart.
I mean  selection focus moves to months (mm) after having entered the the days (dd). 
And move  to the year(yyyy) part  once the month is entered or vice versa.
thank you

----------


## Krool

> Krool, Im adding column headers and then items to the listview in report mode on form load. Im getting a Itemclick then an ItemSelect event as the first listItem is added before any following columns are even filled out or the listview is visible or the form is fully loaded. This makes my click and select code fail because of incomplete information. Is this a bug or intended behavior? I can set a flag to delay processing till initial load is done if needed but was curious...


The ItemSelect event is intended. The V6 MS.ListView behaves the same.
However, the V5 MS.ListView behaves different.

You can make the AutoSelectFirstItem property set to False (mimic V5 MS ListView behavior), then there will be no ItemSelect event fired when adding the first item. (but it is also not selected, only focused)

The ItemClick event is not fired on my side. Can you share a demo showing this ? The ListView control only raises ItemClick upon NM_CLICK, NM_RCLICK. So this should not happen during the feed of a ListView. I cannot replicate that issue for you..




> My question is about DTPicker 
> 
> I want to know if possible to  automatically move to next datepart.
> I mean  selection focus moves to months (mm) after having entered the the days (dd). 
> And move  to the year(yyyy) part  once the month is entered or vice versa.
> thank you


There is no straight forward dedicated message for that. However, you can trick the DTPicker in doing so.
move focus to the right


```
SendMessage DTPicker1.hWnd, WM_KEYDOWN, vbKeyRight, ByVal 0&
```

move focus to the left


```
SendMessage DTPicker1.hWnd, WM_KEYDOWN, vbKeyLeft, ByVal 0&
```

----------


## Mustaphi

> you can trick the DTPicker in doing so


I tested the trick but with no success
I used the code in change event and in key down event but it did not work as expected.
Anyway thank you very much

----------


## vbLewis

> The ItemSelect event is intended. The V6 MS.ListView behaves the same.
> However, the V5 MS.ListView behaves different.
> 
> You can make the AutoSelectFirstItem property set to False (mimic V5 MS ListView behavior), then there will be no ItemSelect event fired when adding the first item. (but it is also not selected, only focused)
> 
> The ItemClick event is not fired on my side. Can you share a demo showing this ? The ListView control only raises ItemClick upon NM_CLICK, NM_RCLICK. So this should not happen during the feed of a ListView. I cannot replicate that issue for you..


Krool,
Thanks for your reply. The AutoSelectFirstItem option fixed the problem. The reason i was also getting a Click event was because i was redirecting all Select() events to the Click() event. woops!
regards,
Lewis

----------


## Karl77

Dark Mode question

I have found a program which uses the windows common controls, and it can render them in other colors.
As an example I see this with Spy++:


So it _seems_ to be possible.
Or am I wrong?

----------


## Krool

> Dark Mode question
> 
> I have found a program which uses the windows common controls, and it can render them in other colors.
> As an example I see this with Spy++:
> 
> 
> So it _seems_ to be possible.
> Or am I wrong?


If turning VisualStyles to False then you can define the BackColor property on the StatusBar control. No magic in this case.

----------


## georgekar

I start using Crool's controls, and I found some not just as I expect. Tooltips are not unicode.

In my form I use Greek letters. My VB6 IDE is in a Windows 64, Greek is primary language. Also the selectet language for VB6 IDE is *Greek*
So in my machine work nice, and I get greek letters for captions and tooltip. But in another machine, which have English as primary language, tooltips are saved as ANSI, and for this reason I didn't get ? characters (code 63), but the ansi numbers (from codepage for Greek letters) as in  Western Europian codepage.

----------


## Krool

> I start using Crool's controls, and I found some not just as I expect. Tooltips are not unicode.
> 
> In my form I use Greek letters. My VB6 IDE is in a Windows 64, Greek is primary language. Also the selectet language for VB6 IDE is *Greek*
> So in my machine work nice, and I get greek letters for captions and tooltip. But in another machine, which have English as primary language, tooltips are saved as ANSI, and for this reason I didn't get ? characters (code 63), but the ansi numbers (from codepage for Greek letters) as in  Western Europian codepage.


The ToolTipText property of the main object itself (VBControlExtender, e.g. CommandButtonW1.ToolTipText etc.) are the intrinsic properties by VB6 and thus ANSI.

Only ToolTipText properties in class objects (e.g. TabStrip1.Tabs(1).ToolTipText etc.) are enhanced for Unicode and also support multi-line.

----------


## Mith

> The ToolTipText property of the main object itself (VBControlExtender, e.g. CommandButtonW1.ToolTipText etc.) are the intrinsic properties by VB6 and thus ANSI.


Why dont we extend the project and add a unicode tooltiptext class and add the property ToolTipTextW to all controls?

----------


## Schmidt

> Why dont we extend the project and add a unicode tooltiptext class and add the property ToolTipTextW to all controls?


IMO there's no need for it.

Krool could simply implement a central Window-Creation-Hook, which reacts to the old "VB6-ToolTip-ClassName",
which then activates (fires), when the VB6-runtime fires-up its own, ANSI-ToolTip-Window
(then overwriting the area of that Window with the original, but now Unicode-rendered Tooltip-Strings).

Even MultiLine-Tooltips are possible this way, when one declares a certain Char as the LineBreak-char
(in our larger VB6-App we've used the PipeChar ("|") for that, IIRC).

Olaf

----------


## Krool

IMO any hooks should reside in an App and not in this package.

So you can use the CommandButtonW.ToolTipText property and use this Code to enable Unicode and multi-line. (See bottom post by MountainMan)

----------


## Mith

> IMO any hooks should reside in an App and not in this package.


You dont need any hooks when using a *new* tooltiptext property!

For the basics just add a new public property called "ToolTextTipW" or "ToolTextTipWide" to all controls to store the unicode text displayed by the tooltiptext and use the api CreateWindowExW to create the tooltiptext. no need for any hooks. i can send you my tooltiptext class if you need the source code to do this.

This change would make the VBCCR project more complete. no more need for external classes and tooltip source code cluttered everywhere in the forms/modules.

We also can add additional tooltip properties like icon, title, multiline, forecolor, backcolor, delay time, display time...

----------


## georgekar

I am waiting for the new version with ToolTextTipW

----------


## Mith

> I am waiting for the new version with ToolTextTipW


It's quite easy to add a new basic unicode tooltiptext but it depends on krool to do this.

I could do this myself but i dont want to start a new fork of the VBCCR project...

----------


## Krool

> It's quite easy to add a new basic unicode tooltiptext but it depends on krool to do this.
> 
> I could do this myself but i dont want to start a new fork of the VBCCR project...


VBCCR17 is planned to be last major release. People also have a desire for a constant stable release.
If any bugs appear they will be of course fixed.

So feel free to make another fork..

----------


## georgekar

@Mith,
Expose your idea, for someone like me to include it in an embedded fashion use of Krools controls. So then I can place the code to any control I wish to include a Unicode tooltip.

----------


## georgekar

I have the solution for unicode tooltips. This tested for command button control.

I use from Elroy some routines, and I found a way (using mouse tracking) to enable/disable the tooltip. Also in IDE, in running or at design we get the ordinary vb6 tooltip.
My test program is in the zip file. 
We have two more properties:
ToolTipTextEx
ToolTipTextTitle

To prove the solution I place english, greek and russian to same tooltip.
Why I have a second ToolTipText?
Because if we have the original one, then that has something different from the new one, and do some conversions. So we use the second one for the unicode, and that handle the first one for using it in IDE, at design and at running status.




```
Private Sub Form_Load()
CommandButtonW1.ToolTipTextTitle = "a TITLE"
CommandButtonW1.ToolTipTextEx = CommandButtonW1.ToolTipTextEx + ListenUnicode(32, 917, 955, 955, 951, 957, 953, 954, 940) + ", " + ListenUnicode(1076, 1086, 1073, 1088, 1086, 1077, 32, 1091, 1090, 1088, 1086)


End Sub
```

Also in the example below, I have some extra:
1. A way to use a mutex to handle the unique execution of program
2. IsWine is a function to find if the program run in linux through wine
3. To place the greek and russian I use one function, listenUnicode, which get the characters by numbers. To produce these numbers, I have a module testfromclipboard, with one statement: Debug.Print SpellUnicode(GetTextData(CF_UNICODETEXT)), so we copy to clipboard text and we get the numbers in the Immediate window, to copy these as parameters in a ListenUnicode() function.


Revision 2,
I found a missing statement from Elroy's code:


```
 SendMessage hwndTT, TTM_SETMAXTIPWIDTH, 0&, 0
```

Without this we didn't get additional lines which the CreateTool introduce these on the wrapping function.

----------


## OldClock

Hey, is it possible to have columns in the treeview?

Sample image from the net attached.

----------


## OldClock

Or something like this? Looks like a listview per row within a treeview.

----------


## Niya

> Or something like this? Looks like a listview per row within a treeview.


A little off topic but one look at this post and WPF immediately came to mind. WPF can do wild and crazy stuff like this very easily. If you're like me and prone to wanting all kinds of crazy combinations of layouts and controls for your UI, you owe it to yourself to check out WPF some time in your life. You will not be disappointed.

----------


## Arnoutdv

The vsFlexGrid is capable of showing a tree in a column of the grid.
Maybe Krool will implement something like this in his vbFlexGrid control

----------


## OldClock

Thank you, but as far as I can tell, WPF is not VB6.

Is it possible to have word-wrap/newlines in a row in a VBCCR16/17 listview?

----------


## Krool

> Thank you, but as far as I can tell, WPF is not VB6.
> 
> Is it possible to have word-wrap/newlines in a row in a VBCCR16/17 listview?


No. SysListView32 does not support it.

----------


## Schmidt

> No. SysListView32 does not support it.


@OldClock

You can accomplish your desired outputs quite easily, when you use Virtual-List-Controls.

Here's two different ones, I've posted into the CodeBank (both without RichClient-dependencies, though still quite small CodeBases):
https://www.vbforums.com/showthread....TreeList-Demo)
https://www.vbforums.com/showthread....)-TileView-Ctl

HTH

Olaf

----------


## myfav

I registered the "VBCCR17.OCX" in Windows 10, and then tried to use Krool's controls in VFP 9's IDE, unfortunately, the VFP 9 crash. 
It seems that Krool's controls (OCX version) can only work with VB6, but MS common controls can support VFP, delphi or any other programming language correctly.

----------


## Semke

Hi!
I browsed through this thread which mentions that its possible to use  Transparent images with the the imagelist/toolbar.
I assume that you would need to use PNG files.
I would appreciate on some guidance on how to load PNG files, because the standard methods don't work

----------


## SuperDre

> Hi!
> I browsed through this thread which mentions that its possible to use  Transparent images with the the imagelist/toolbar.
> I assume that you would need to use PNG files.
> I would appreciate on some guidance on how to load PNG files, because the standard methods don't work


Isn't it just using a mask color for that, or Icon files?

----------


## Semke

> Isn't it just using a mask color for that, or Icon files?


mask colour is a nice way to improvise, and that's what i have been doing until now.
Using PNG files is much cleaner and in my opinion a better way to work (if it is possible).

----------


## yereverluvinuncleber

> Using PNG files is much cleaner and in my opinion a better way to work (if it is possible).


We all want VB6 to support PNGs but it is a limitation of the product.

You can incorporate La Volpe's code and then you will be able to read and display PNGs in your VB6 image controls. You can also work with GDI+ or similar as it can handle PNGs natively and display them within your VB6 program.

I have used both in my recent creations to handle PNGs. It is a considerable workaround but can be done. 

Just expanded VFP 9 to find it means Visual Fox Pro... that is not VB6. The BASIC advice will receive here will not help you much.

----------


## SuperDre

> I registered the "VBCCR17.OCX" in Windows 10, and then tried to use Krool's controls in VFP 9's IDE, unfortunately, the VFP 9 crash. 
> It seems that Krool's controls (OCX version) can only work with VB6, but MS common controls can support VFP, delphi or any other programming language correctly.


Ofcourse if the OXC crashes VFP 9's IDE there is a problem with the OCX as it should not do that. Does it crash on the usage of a specific component of the OCX or does it crash completely?

----------


## Mith

vbccr v1.7.1

i can't enter the maximum supported character length of 32K chars using the textboxW control.

i tried it with the following code:

textboxW.text = String(32000, "a")
or
textboxW.text = String(6500, "a")

none of them above filled the textbox!

but String(650, "a") works!

the maxlength property is set to 0.

Edit:
after some testing i found out that the limit is 4095 chars...

Edit2:
Problem solved: 
the property .MultiLine=True enables the support of 32K maximum characters!

----------


## Mith

vbccr v1.7.1

i load a 6 MB text file into a RichTextBox using the command:



```
rtfLog.LoadFile sLogFile, RtfLoadSaveFormatUnicodeText
```

now the size of the RichTextBox content is 3102656 bytes determined by the command:


```
Len(rtfLog.Text)
```

after that i do a word wrap with the command:



```
rtfLog.ScrollBars = vbVertical
```

after the word wrap the content of the RichTextBox is truncated: now the size is only 67731 bytes!  :Frown: 

any idea how to word wrap without cutting the content of the RichTextBox?
or is this a bug?

control properties:

----------


## Krool

> vbccr v1.7.1
> 
> i load a 6 MB text file into a RichTextBox using the command:
> 
> 
> 
> ```
> rtfLog.LoadFile sLogFile, RtfLoadSaveFormatUnicodeText
> ```
> ...


Changing the ScrollBars to vbVertical triggers internally a re-creation of the rich text box.
So try to put the code before you load the 6MB file for a quick fix.
However, I would like to test whats the problem. Can you wrap up a demo project?

----------


## Mith

> Changing the ScrollBars to vbVertical triggers internally a re-creation of the rich text box.
> So try to put the code before you load the 6MB file for a quick fix.
> However, I would like to test whats the problem. Can you wrap up a demo project?


i guess the text content get truncated somewhere at the re-creation function.

Is it really necessary to re-create the whole control when switching the scrollbars?

Isnt there any SendMessage/SetWindowLong command to hide/show the scrollbars?

Example:

Style = GetWindowLong(rtbHandle, GWL_STYLE)
Style = Style And WS_VSCROLL
SetWindowLong (rtbHandle,GWL_STYLE,Style)

----------


## Krool

> i guess the text content get truncated somewhere at the re-creation function.
> 
> Is it really necessary to re-create the whole control when switching the scrollbars?
> 
> Isnt there any SendMessage/SetWindowLong command to hide/show the scrollbars?
> 
> Example:
> 
> Style = GetWindowLong(rtbHandle, GWL_STYLE)
> ...


When you find a way of changing it without re-creation, please advise. However, I could have gone like the MS RichTextBox and throw out an error when attempting to change at runtime.

----------


## Mith

> When you find a way of changing it without re-creation, please advise.


it's not possible. i tried but after i read this at the MS doc: "After the control has been created, these styles cannot be modified, except as noted.": https://docs.microsoft.com/en-us/win...control-styles

looks like re-creation is the only way to to this...

btw, i found out that using TextMode=1 solves my problem:
the text content doesnt got manipulated after switching the scrollbars!

using TextMode=0 and switching the scrollbars to enable WordWrap truncates the text!
Maybe you will check this out.

----------


## Hosam AL Dein

Hi Krool , 
A strange behavior in ListView .
When opening some form modally by clicking a ListView column header , it does not have the (Focus) and seems as it is not mainly shown . When you click somewhere on the modal form and this point of click hits the behind column header , the column header click event is fired as if there is no form in front . Also , the form needs two interactions (Clicks) to respond to the mouse click .

I tested this in both OCX and StdExe versions . Here is a Demo to explain what I mean . You need to click any listview header >> Form2 is then shown modally >> then click on the label on Form2 . (I put some positioning code to assure that the click will hit the behind column header) .

Re-test this by opening the form with any other command (Not from Column_Click event .. Say by a command button) , the problem will not arise then . 

Wrapped Demo.zip

Edit :
Calling SetCapture API Function solves the issue of passing the click to the behind ListView , but the modal form still needs two clicks to respond and actually receives the focus .

----------


## Krool

> Hi Krool , 
> A strange behavior in ListView .
> When opening some form modally by clicking a ListView column header , it does not have the (Focus) and seems as it is not mainly shown . When you click somewhere on the modal form and this point of click hits the behind column header , the column header click event is fired as if there is no form in front . Also , the form needs two interactions (Clicks) to respond to the mouse click .
> 
> I tested this in both OCX and StdExe versions . Here is a Demo to explain what I mean . You need to click any listview header >> Form2 is then shown modally >> then click on the label on Form2 . (I put some positioning code to assure that the click will hit the behind column header) .
> 
> Re-test this by opening the form with any other command (Not from Column_Click event .. Say by a command button) , the problem will not arise then . 
> 
> Wrapped Demo.zip
> ...


I confirm the issue and clearing the mouse capture before raising the event fixes both issue you encountered. I am just double checking if this is the "correct" solution before I do an update release.
see below new code added in blue


```
Case LVN_COLUMNCLICK
    CopyMemory NMLV, ByVal lParam, LenB(NMLV)
    ReleaseCapture
    RaiseEvent ColumnClick(Me.ColumnHeaders(NMLV.iSubItem + 1))
```

----------


## Hosam AL Dein

Yes , It is clear for now  . Thanks Krool

----------


## hmnader

Attached Files Attached Files
File Type: zip ComCtlsDemo.zip (825.6 KB, 84 views)

when i opened ComCtlsDemo on vb6.0 this error ocurred
Someone knows the reason

Error screenshot :

----------


## gilman

Do you have the option "Break on all errrors" checked?, if the answer is yes, check the option "Break on unhandlled errors"

----------


## Erwin69

I've started the conversion of a project using the CC Replacements.  Initial results are good, and the unicode support of these controls are very much appreciated!

So far, I ran into two issues that I couldn't figure out:

First
===
In a frame I have 3 shapes, that visually show the status of something, traffic light style. Since shapes don't have events, I'm using the mousedown event of the frame to capture the X-, and Y-coordindates, and check those versus the position of the shapes.  This worked fine with the original Frame object, but with the FrameW object, the X and Y that the event returns, don't correspond with the coordinates of the shapes. My guess is that a different scaling is used?  Or am I missing something else?

Second
=====
With the classic graphical style command button you could assign an image, and when the button was disabled, the image would be grayed out.  There was no need to assign a DisabledPicture.  With the CommandButtonW control, the image disappears completely when the button is disabled.  Is this by design, and do I have to add a DisabledPicture, or am I missing something?


All advice is appreciated! Thanks in advance!

----------


## Erwin69

Two more questions:

#1. It seems that the Alignment of text in the TextBoxW doesn't work.  Neither setting in the IDE, nor setting it at runtime in code gives another result than left align.

#2. I have a statusbar with 5 panels.  Panels 1, 4, and 5 are fixed.  The remaining space is divided between panels 2 and 3.  For the standard CC statusbar, I updated the width of panels 2 and 3 in the form resize event.  When I do that now with the CCR statusbar, the width of the panels is not calculated correctly.

My original code:



```
    With brStatusBar
        .Panels(2).Width = (frmMain.ScaleWidth - .Panels(1).Width - .Panels(4).Width - .Panels(5).Width) / 2
        .Panels(3).Width = (frmMain.ScaleWidth - .Panels(1).Width - .Panels(4).Width - .Panels(5).Width) / 2
    End With
```

I also tried with:



```
    With brStatusBar
        .Panels(2).Width = (.Width - .Panels(1).Width - .Panels(4).Width - .Panels(5).Width) / 2
        .Panels(3).Width = (.Width - .Panels(1).Width - .Panels(4).Width - .Panels(5).Width) / 2
    End With
```


Last, but not least, I also tried moving this to the form Paint event.  Unfortunately to no avail.

Any suggestions?

----------


## Krool

> First
> ===
> In a frame I have 3 shapes, that visually show the status of something, traffic light style. Since shapes don't have events, I'm using the mousedown event of the frame to capture the X-, and Y-coordindates, and check those versus the position of the shapes.  This worked fine with the original Frame object, but with the FrameW object, the X and Y that the event returns, don't correspond with the coordinates of the shapes. My guess is that a different scaling is used?  Or am I missing something else?


I tested a shape in a FrameW control and the X and Y coordinates correspond correctly. It's origin is of course the FrameW. Like for the VB.Frame.
Please provide demo showing otherwise.




> Second
> =====
> With the classic graphical style command button you could assign an image, and when the button was disabled, the image would be grayed out.  There was no need to assign a DisabledPicture.  With the CommandButtonW control, the image disappears completely when the button is disabled.  Is this by design, and do I have to add a DisabledPicture, or am I missing something?


What do you mean? It is always better to have a DisabledPicture, instead of relying on the to gray out the Picture object by the control.

Below is a picture object where the left side has Enabled property set to True and right side set to False in a CommandButtonW. (no DisabledPicture object used here)
What's wrong with it? Please advise.






> #1. It seems that the Alignment of text in the TextBoxW doesn't work.  Neither setting in the IDE, nor setting it at runtime in code gives another result than left align.


I cannot replicate it. Please provide demo.
If you are using the OCX version, which version do you use?





> #2. I have a statusbar with 5 panels.  Panels 1, 4, and 5 are fixed.  The remaining space is divided between panels 2 and 3.  For the standard CC statusbar, I updated the width of panels 2 and 3 in the form resize event.  When I do that now with the CCR statusbar, the width of the panels is not calculated correctly.


This is complicated. I need a demo from you which has the MS statusbar and the VBCCR statusbar beneath (or each in a own Form) and showing the differences.
Thanks

----------


## Erwin69

Hi Krool, thanks for the feedback.  Find attached a small demo that shows the issues.

#1. Clicking the colored circles should move the "selector box" to the one clicked.  The messagebox shows the X and Y that are returned, which are of a totally different scale than the coordinates of the Shapes.

#2. The 5 graphical buttons have no disabled picture assigned.  Clicking the <Enabled> button on the right of the frame, displays all pictures.  Clicking the <Disabled> button, causes them to disappear completely.

#3. The three colored textboxes have been assigned the various align options.  The text still aligns to the left in all three.

#4. Both MS and VBCCR statusbars have been set up with 5 panels with widths of respectively 2000, 1275, 1440, 2000, and 2000.  On initial load, the panels in both statusbars are aligned, but as soon as the form is resized, the VBCCR panels 2 and 3 are given widths that are too large.

I'm using version 1.7.0.1 of the OCX.

CCRTest.zip

----------


## Krool

Update released.

Critical bugfix in the FrameW control.
Mouse events were scaled to pixels instead of twips.




> #1. Clicking the colored circles should move the "selector box" to the one clicked.  The messagebox shows the X and Y that are returned, which are of a totally different scale than the coordinates of the Shapes.


The ScaleMode of the UserControl was set to pixels instead of twips.
This has no affects on the ContainedControls property since the container reports always in twips.
However, this mis-setting led to wrong scaled values in the mouse events. (e.g. MouseDown)

The problem should now be resolved for the VBCCR17.OCX (1.7.3)




> #2. The 5 graphical buttons have no disabled picture assigned.  Clicking the <Enabled> button on the right of the frame, displays all pictures.  Clicking the <Disabled> button, causes them to disappear completely.


I use the DrawState API with DSS_DISABLED when no DisabledPicture is available and the control has Enabled = False.
However, it seems the API works better with DST_ICON and works not so good with DST_BITMAP.

Just a note. DSS_DISABLED will treat a white color as transparent. So you can try changing the MaskColor to white. (your picture needs to be changed of course)
Or best. You supply a proper DisabledPicture object..




> #3. The three colored textboxes have been assigned the various align options.  The text still aligns to the left in all three.


The VB.TextBox will re-create the control when the Alignment property changes.
However, the VBCCR TextBoxW uses SetWindowLong to change the Alignment.

Reason is that setting ES_CENTER or ES_RIGHT upon CreateWindowEx causes problems for a multi-line edit control which has horizontal scrollbars.
That's why it is set after CreateWindowEx via SetWindowLong.

BUT, I just noticed that prior to Windows Vista (e.g. Windows XP) the ES_CENTER and ES_RIGHT bits are NOT modified-able.
Even the comctl32.dll version 5.8x on Windows 7 (or Windows 10) does allow it.

So, I am in a dilemma right now on this where I don't know how to react to...

----------


## Erwin69

Hi Krool, thanks for the feedback.

As for #2, I'll review my approach there.

Regarding #3, I'm using a virtual machine with XP as the OS, so that might explain why it doesn't work.  There is still too much cleaning up to do after transitioning all existing conbtrols to the VBCCR ones, to do a full compile and test the behavior on Win10.  However, these textboxes are for display only, so I can do a workaround with a label with a transparent background in front of the colored textbox, which will solve my problem.  So, either way you decide to address it, will work for me.  I just wanted you to be aware of it.

Anything on #4?

Thanks,
Erwin

----------


## Krool

Update released.

Bugfix for the FrameW control related to yesterday update. (there is always something when changing something...)

@ Erwin69, OCX got updated. (1.7.4)




> Anything on #4?


Will check out soon.

----------


## Krool

> Regarding #3, I'm using a virtual machine with XP as the OS, so that might explain why it doesn't work.  There is still too much cleaning up to do after transitioning all existing conbtrols to the VBCCR ones, to do a full compile and test the behavior on Win10.  However, these textboxes are for display only, so I can do a workaround with a label with a transparent background in front of the colored textbox, which will solve my problem.  So, either way you decide to address it, will work for me.  I just wanted you to be aware of it.


It's really a pain in the ...
This here again good example. 

I am considering a small overhead (e.g. like done in the ComCtlsW2KCompatibility function)
The overhead is only once per process lifetime. It would be then a ComCtlsWXPCompatibility function.
If either W2K or WXP is true it makes ES_CENTER/ES_RIGHT upon CreateWindowEx. (With the drawback of broken horizontal scrollbar in multine, like the VB.TextBox)

If none is true (W2K and WXP both False) the current way would be applied without quirks.

I may update soon as I just proposed..

----------


## SuperDre

Just wondering, but why still support XP and W2K? who is using that for actual production with new software, even just to support the old legacy applications? I'm a VB6 developer, but we also don't support anything official below Windows 10 anymore, if it works, OK, if it doesn't that's your problem as you should have updated to a newer version of windows by now (we're a payrol application, we also have a 'modern' cloud based version now).

----------


## Erwin69

> Just wondering, but why still support XP and W2K? who is using that for actual production with new software, even just to support the old legacy applications? I'm a VB6 developer, but we also don't support anything official below Windows 10 anymore, if it works, OK, if it doesn't that's your problem as you should have updated to a newer version of windows by now (we're a payrol application, we also have a 'modern' cloud based version now).


In principle I agree that it makes most sense to only support the Windows versions that Microsoft still supports.  As a matter of fact, I've heard the same rationale about stopping to use a development tool that is from 1998...  :big yellow: 

But in reality there are many companies that lag behind in upgrading, often enough the larger ones and governments, given the costs of replacing hardware since existing PCs often are not strong enough for the newer OS.  I hear from my business partners in Asia that there still quite a few companies use XP, and I even saw an XP-based PC hooked up to training equipment at a physio therapist in Belgium last year.

I'm facing a similar question/discussion when clients/prospects "demand" that my single user Windows desktop application works being shared by multiple users in a network, or on Citrix or Remote Desktop solutions.  At some point is becomes a commercial decision between costs and opportunities.

----------


## Krool

Update released for TextBoxW control.




> In principle I agree that it makes most sense to only support the Windows versions that Microsoft still supports.  As a matter of fact, I've heard the same rationale about stopping to use a development tool that is from 1998... 
> 
> But in reality there are many companies that lag behind in upgrading, often enough the larger ones and governments, given the costs of replacing hardware since existing PCs often are not strong enough for the newer OS.  I hear from my business partners in Asia that there still quite a few companies use XP, and I even saw an XP-based PC hooked up to training equipment at a physio therapist in Belgium last year.
> 
> I'm facing a similar question/discussion when clients/prospects "demand" that my single user Windows desktop application works being shared by multiple users in a network, or on Citrix or Remote Desktop solutions.  At some point is becomes a commercial decision between costs and opportunities.


I did find a compromise now.. I really did not want to have a new overhead with some quirks...
So ES_LEFT/ES_CENTER/ES_RIGHT works now in Windows XP as it is supplied directly in dwStyle for CreateWindowEx.
However, changing the Alignment in code (run-time) is only working as of Windows Vista. (usage of SetWindowLong remains)

Of course when having vbCenter set as design-time the horizontal scrollbar is broken now. (if multiline = true and scrollbars set accordingly)
Workaround for that quirk would be to have vbLeftJustify at design-time and set at run-time (per code) the alignment to vbCenter, for instance.

----------


## newbie2

Hello Krool
Is there a way to AutoSize the Drop Down list of the combo control?
thank you

----------


## Krool

> Hello Krool
> Is there a way to AutoSize the Drop Down list of the combo control?
> thank you


Can you describe more what you mean?
If you mean to fit the longest text?

If yes, you can try .HorizontalExtent = .GetIdealHorizontalExtent()

Or .DropDownWidth = .GetIdealHorizontalExtent() + few pixels surplus maybe.

----------


## nello355

Many thanks for this great job. 

Do you have plans to add the DoubleClick event in the MonthView control?

----------


## newbie2

it worked thank you

----------


## Krool

Update released for the StatusBar control.




> #4. Both MS and VBCCR statusbars have been set up with 5 panels with widths of respectively 2000, 1275, 1440, 2000, and 2000.  On initial load, the panels in both statusbars are aligned, but as soon as the form is resized, the VBCCR panels 2 and 3 are given widths that are too large.


You could have defined panels 2 and 3 as autosize spring to solve the issue. However, I did not give the tip to you as it should also work as you did. (manually defining the "spring width")

The research took longer as I assumed a bug in a logic but to no avail. The logic was correct.

At the end it just turned out that there was a reporting bug in Width (Property Get) of a Panel which you use in your Form to do the math.
I also detected a bug in the Left (Property Get) of a Panel. (did not affect you actually, but maybe others)

Thank you. Your points actually resulted in improvements.  :Smilie:

----------


## alcpf

Hello.
Congratolations with that project. I'm new using that ocx. I'm adapting a vb project with that ocx but I see that have a lot of differences and doubts. Hope you can help me...
I use the treeview and when I select one node, my script check on the database (is via remote TCP-IP) and insert new childrens on the selected node but what is strange is that the treeview not shows it automatically. I need to click again on the same node for show the childrens. I fixed that executing the command treeview.refresh or treeview.redraw just right after insert the childrens. It works but it's normal? Doesn't exists nothing better?


```
Private Sub TreeView_NodeClick(ByVal Node As TvwNode, ByVal Button As Integer)
    FRM.LVAlert.Visible = False
    
    If TCP_NotConnected Then Exit Sub

    textExplorer.Text = Node.FullPath & "\"
    textExplorer.Tag = Node.Key

    If Node.Tag = "" Then
        'Faz busca de pastas ao cliente
        TCP.SendData EXPLORER_Folders & vbAA & textExplorer.Text & vbAABB
        Node.Tag = True 
    Else
        'Faz busca de ficheiros ao cliente
        TCP.SendData EXPLORER_Files & vbAA & textExplorer.Text & vbAABB
        lvFicheiros.ListItems.Clear
    End If
    
    Node.BackColor = &H6D6D6D
    lvFicheiros.BackColor = &H80000018
End Sub
```

And Insert here:



```
....
        If Right$(Data_Received, 1) <> vbBB Then Exit Sub
        
        s = Split(Data_Received, vbAA)
        Data_Received = vbNullString
        
        lvFicheiros.ListItems.Clear
        For x = 1 To UBound(s) - 1
            TreeView.Nodes.Add textExplorer.Tag, tvwChild, "K" & treeKEY, s(x)
            treeKEY = treeKEY + 1
        Next x
        
        TCP.SendData EXPLORER_Files & vbAA & textExplorer.Text & vbAABB
        
        TreeView.Redraw = True
....
```

Other thing:
Any click anywhere on the treeview it calls the Sub TreeView_NodeClick! But I just want accept any click when really have selected the inside of node and not outside... How can I solve this?

Also, the variable treeview.node.checked (true or false) just can change when the checkbox is enable. But with the treeview from microsoft I used it as variavel for certain intern information and not for the user. So I don't wanna see the check box at left of the node, but use it internal. But not showing the check box, it node.checked, will be all the time false and if I try change it node.checked=true, I get an error... Can I change that for use it ?

And last, the SCroll= true in design mode, shows the scroll in the treeview but all the time I open a node (clicking on +) other node close automatically... If I put scroll=false, then I can open all nodes (not close automatically) but not shows the scroll. 

I must say that the program already worked for long time withe the treeview microsoft ocx.

Hope you all understand and can help. Sorry my english is not good! Thank you

----------


## Erwin69

> Update released for the StatusBar control.
> 
> 
> 
> You could have defined panels 2 and 3 as autosize spring to solve the issue. However, I did not give the tip to you as it should also work as you did. (manually defining the "spring width")
> 
> The research took longer as I assumed a bug in a logic but to no avail. The logic was correct.
> 
> At the end it just turned out that there was a reporting bug in Width (Property Get) of a Panel which you use in your Form to do the math.
> ...


Thanks Krool.  There are so many options and improvements versus the MS common controls, and also some small but important changes, that converting an existing project is a challenge.  (Especially if you're not a dedicated professional developer, like I am not.)  I'm sure it will be easier when starting a project from scratch with your controls, or continuing after the full conversion.

One thing I found challenging is the fact that some controls have the same name as the "original" MS one.  Another challenge was the fact that the Listview control doesn't take the column definitions in the IDE.  (Unless I really missed something.)  But all in all, the conversion went rather smoothly.

There is one thing left where I "struggled": my initial work to recreate the toolbar didn't work, as the images were not displaying correctly.  So, I may post some questions about that in the future.

----------


## alcpf

Hi. 
I have a problem.
I have some script in that event TreeView_NodeSelect(ByVal Node As VBCCR17.TvwNode)... It is supposed execute just all the time I select a node, but the problem is that all the time I execute the treeview.nodes.clear, it clear all nodes but also executes the event above in the number of times it has items/nodes in the treeview ... It seems that the clear, deletes one by one, selecting the item next to the one that was deleted as if I had selected and triggers the event above ... And repeats this process until you delete all items!
How can I block the clear not triggering the above event?

I did a video to explain better:




Also the example:
Nova pasta.zip

----------


## Krool

Update released for the TreeView control.




> Any click anywhere on the treeview it calls the Sub TreeView_NodeClick! But I just want accept any click when really have selected the inside of node and not outside... How can I solve this?


True. Strange that nobody noticed so far.  :Smilie: 
The NodeClick/NodeDblClick fired whenever TVM_HITTEST returned an hItem <> 0.
However, now it requires also the hit-test flags to be TVHT_ONITEMICON or TVHT_ONITEMLABEL. (like the MS TreeView does)




> How can I block the clear not triggering the above event?


Well, as you said. The .Clear method will delete all items one by one.
The MS control has no exposed events for TVN_SELCHANGING/TVN_SELCHANGED so they did not care.
I updated the .Clear method now to set the caret item to NULL before sending the TVM_DELETEITEM.
The end result is the same (all items deleted and no caret item anymore either case).
But the change results now in no unnecessary TVN_SELCHANGING/TVN_SELCHANGED notifications.
Means no NodeSelect or NodeBeforeSelect events anymore when doing a .Clear.
In theory it should also speed up the .Clear.

----------


## alcpf

Yes I thought strange too that nobody detected that.
Anyway I tested again with the new update and now works like a charme. Thank you very much  :Smilie: 

Just one thing that for me isn't a problem but can cause problems for others:
The event TreeView_Collapse is also called with the .clear, despite of your last changes! There was in fact no collapse and depending of what we write in that event, normally to prevent anything about the collapse, we will also have to program to prevent the effect of the .clear! The variable node gives the first item index  (even if other was selected) that was before erased all, but the item will not be there anymore because .clear deleted all!

----------


## Krool

> And last, the SCroll= true in design mode, shows the scroll in the treeview but all the time I open a node (clicking on +) other node close automatically... If I put scroll=false, then I can open all nodes (not close automatically) but not shows the scroll.


I can't replicate this. Please provide a demo.

----------


## OldClock

Hey

I checked the first post and also GitHub but found no answer to these questions, could you please clarify:
1. What is the difference between VBCCR16 and 17? 
2. What is the upgrade procedure when using the ActiveX version?

Note to point 1: unfortunately git commit messages are not being used, VBCCR/ActiveX Control Version/List of revisions.txt contains no meaningful info, and VBCCR/Standard EXE Version/List of revisions.txt jumps from 18-Aug-2020 to 23-Sep-2020 with no mention of the major version change from VBCCR16 to 17. Yes I do see the individual changes, but don't get what prompted a major change in version.

Note to point 2: I am aware of MountainMan's tool, good work, but I'm asking for a human explanation of what changed and how to migrate. I don't feel safe running a third-party tool over my code and would rather change things myself.

Kind regards

----------


## MountainMan

Krool,

How do I catch a mouse scroll inside the RichTextBox? I want to zoom in/out on a muse scroll when the user has the Ctrl key down. I looked through all of the events raised by the RichTextBox control and none look like they do what I want to do. Thanks.

----------


## MountainMan

I have an question regarding the RichTextBox. When I use .SelTextSize, .SelBold, .SelItalic and/or .SelUnderline at the end of the data already in the control, all of these effects revert back to normal as soon as a CrLf is input at that point. For example, if I have set the .SelBold property and then I send the string "How now" & vbCrLf & "brown cow" to the control, the text "How now" is bolded but then "brown cow" is not. Is that the intended behavior?

----------


## MountainMan

While I am on a roll with questions, what about VBA? I know your OCX file won't work with 64-bit VBA but I think at least some of the controls will work with VBA Do you know which ones do work with 32-bit VBA? Also, other than trying out each one and seeing which ones lock up or crash the machine, how can you tell which ones will or will not work with VBA?

----------


## Karl77

> How do I catch a mouse scroll inside the RichTextBox? I want to zoom in/out on a muse scroll when the user has the Ctrl key down. I looked through all of the events raised by the RichTextBox control and none look like they do what I want to do. Thanks.


For me it works without additional code.
Another story is Ctrl and +/-.
Then you need this:



```
Private Function SetZoom(ByVal ZoomRatio As Long)

Dim Numerator   As Long
Dim Denominator As Long

Static inProc   As Boolean
'--------------------------------------------------

If inProc Then Exit Function Else inProc = True

If ZoomRatio < 10 Or ZoomRatio > 500 Then Exit Function

If ZoomRatio = 100 Then
    Numerator = 0
    Denominator = 0
Else

    If ZoomRatio < 100 Then
        Numerator = ZoomRatio
        Denominator = 100
    Else
        Numerator = ZoomRatio / 1.960784
        Denominator = 51
    End If

End If

Call SendMessage(RTF.hwnd, EM_SETZOOM, ByVal Numerator, ByVal Denominator)

inProc = False

End Function
```

----------


## Krool

> I checked the first post and also GitHub but found no answer to these questions, could you please clarify:
> 1. What is the difference between VBCCR16 and 17? 
> 2. What is the upgrade procedure when using the ActiveX version?
> 
> Note to point 1: unfortunately git commit messages are not being used, VBCCR/ActiveX Control Version/List of revisions.txt contains no meaningful info, and VBCCR/Standard EXE Version/List of revisions.txt jumps from 18-Aug-2020 to 23-Sep-2020 with no mention of the major version change from VBCCR16 to 17. Yes I do see the individual changes, but don't get what prompted a major change in version.
> 
> Note to point 2: I am aware of MountainMan's tool, good work, but I'm asking for a human explanation of what changed and how to migrate. I don't feel safe running a third-party tool over my code and would rather change things myself.


The process is this:

The Std-EXE version is the leading source. So the list of revision contains everything for it.
From time to time (in the past maybe every year or so) the latest state was bundled into a OCX.
Further bugfixes are integrated into the OCX, BUT new features weren't to not break binary compatibility.

So the difference between VBCCR16 and 17 is basically bigger. (1 year or so of new features)
To note is, when now bugs gets fixed it will only be fixed in VBCCR17. (VBCCR16 not supported anymore)

So, it might be better to switch to version 17. I basically do not plan to introduce new features, so 17 might be the last version.
However, bugfixes will be done as long as possible.  :Smilie: 

You can upgrade manually. Replacing the in the .vbp and all .frm files manually (via text editor) from 16 to 17.




> While I am on a roll with questions, what about VBA? I know your OCX file won't work with 64-bit VBA but I think at least some of the controls will work with VBA Do you know which ones do work with 32-bit VBA? Also, other than trying out each one and seeing which ones lock up or crash the machine, how can you tell which ones will or will not work with VBA?


The VBFlexGrid OCX works best in VBA as it supports accelerator keys in a VBA environment. (PreTranslateMsg function implemented)

The VBCCR OCX does not (yet) support accelerator keys. However, it is tested that they at least not crash when placed in a UserForm.




> How do I catch a mouse scroll inside the RichTextBox? I want to zoom in/out on a muse scroll when the user has the Ctrl key down. I looked through all of the events raised by the RichTextBox control and none look like they do what I want to do. Thanks.


The Scroll event is not good for you need as it works only when the RichTextBox scrolls the content.
What you need is actually a WM_MOUSEWHEEL handler.
So, just subclass the RichTextBox control and handle WM_MOUSEWHEEL accordingly.

----------


## Karl77

> So, just subclass the RichTextBox control and handle WM_MOUSEWHEEL accordingly.


But it works as wanted without doing ANYTHING...
Ctrl held down + mousewheel action zooms the viewport, as in the very most programs.
Seems I misunderstand the wish?

----------


## MountainMan

> But it works as wanted without doing ANYTHING...
> Ctrl held down + mousewheel action zooms the viewport, as in the very most programs.
> Seems I misunderstand the wish?


You are absolutely correct. Duh. I never checked that. I assumed it wouldn't do that automatically and I didn't see where anyone had brought it up in this thread so I was looking for the code to do it. Your observation makes life simpler. Thanks.

----------


## MountainMan

> Hey
> 
> I checked the first post and also GitHub but found no answer to these questions, could you please clarify:
> 1. What is the difference between VBCCR16 and 17? 
> 2. What is the upgrade procedure when using the ActiveX version?
> 
> Note to point 2: I am aware of MountainMan's tool, good work, but I'm asking for a human explanation of what changed and how to migrate. I don't feel safe running a third-party tool over my code and would rather change things myself.


In the .vbp file you have to change the reference and the GUID for the .OCX.

In each of the .frm files you have to change the reference for the .OCX at the top of the file and GUID for each instance of each control that you use.

If you use a resource file that includes a manifest, you have to edit that to change the references to the .OCX and all of the controls. Note that Krool has added some new controls so you have to know which ones he added and change those references too. I find manually editing the guts of a manifest file to be cumbersome so in my utility I borrowed some of LaVolpe's code from his Manifest Creator program to open, find the old references and save the manifest with the new references.

You may have references to controls in .bas or .cls modules to controls within the .ocx (no GUID's) so the references must be changed also.

----------


## alcpf

> I can't replicate this. Please provide a demo.


Hi Kroll.
I sent a video where I explain better. Read there the legends. It's a comparative between microsoft treeview with your treeview!




By the way, is it possible change the forecolor and backcolor in the columnheader of the listview without a lot of script and declarations?

----------


## Krool

> Hi Kroll.
> I sent a video where I explain better. Read there the legends. It's a comparative between microsoft treeview with your treeview!
> 
> 
> 
> 
> By the way, is it possible change the forecolor and backcolor in the columnheader of the listview without a lot of script and declarations?


How is the SingleSel property set?

----------


## alcpf

> How is the SingleSel property set?


 :Alien Frog:  :Alien Frog:  :Alien Frog:  

Singlesel was set as true!!!! I changed and it works as I want!  I checked almost all definitions and I don't know how missed this one!
Thank you


About the columnheader I  can change the forecolor but I don't found the backcolor!

I wrote this:
lvFiles.ColumnHeaders.Add(, , "Type", 600, LvwColumnHeaderAlignmentRight).ForeColor = &HFF
I want change the backcolor for slightly more or less dark than the body of the  listview and the text white!

----------


## Krool

> About the columnheader I  can change the forecolor but I don't found the backcolor!


This feature is not in-built included as it requires complete owner-drawing of the header items.
So, you can implement it but it requires some homework.

I can give you the starting point.

Subclass the ListView.hWnd and intercept the WM_DRAWITEM message.



```
Private Function WindowProcControl(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If wMsg = WM_DRAWITEM Then
    Dim DIS As DRAWITEMSTRUCT
    CopyMemory DIS, ByVal lParam, LenB(DIS)
    ' DIS.CtlType has undocumented &H64. Better to not rely on that.
    If DIS.hWndItem = ListView1.hWndHeader Then
        ' DIS.ItemID is the column index
        Dim Brush As Long
        Brush = CreateSolidBrush(vbBlue)
        FillRect DIS.hDC, DIS.RCItem, Brush
        DeleteObject Brush
        ' Background now filled. Now need to paint the rest...
        WindowProcControl = 1
        Exit Function
    End If
End If
[...]
```

But you need to do something in order to get WM_DRAWITEM.


```
Private Const LVCFMT_COL_HAS_IMAGES As Long = &H8000& ' Same as HDF_OWNERDRAW
```

This flag you need to set. You can only make 1 particular column header owner-drawn or all one-by-one so every column header is owner-drawn.
Below code will make column header 1 owner-drawn. For example if Index is 1.


```
Dim LVC As LVCOLUMN
With LVC
.Mask = LVCF_FMT
SendMessage ListView1.hWnd, LVM_GETCOLUMN, Index - 1, ByVal VarPtr(LVC)
.fmt = .fmt Or LVCFMT_COL_HAS_IMAGES
SendMessage ListView1.hWnd, LVM_SETCOLUMN, Index - 1, ByVal VarPtr(LVC)
End With
```

Example with column 1 and 2 owner-drawn.

----------


## OldClock

Thank you Krool and MountainMan. I documented how I upgraded from VBCCR16 to VBCCR17 here:
https://www.vbforums.com/showthread....=1#post5512259

----------


## Krool

Update released.

Harmonization in the ContextMenu events. The X and Y parameters are now always originated to the control's hWnd.

----------


## alcpf

Thank you Krool.
I'm going to try adapte it and then I publish here the result for the case someone wants it too!

----------


## Erwin69

Two additional questions:

1. Is the date/time picker supposed to pick up localized words for Today, the months and the days?  If so, how is the language selected?  Windows regional settings?

2. When using the standard common controls, I get the "modern Win10" file open dialog.  With my first attempt with the CCR common dialog I get this small, really old looking dialog.  Am I doing something wrong?

----------


## Krool

> Two additional questions:
> 
> 1. Is the date/time picker supposed to pick up localized words for Today, the months and the days?  If so, how is the language selected?  Windows regional settings?
> 
> 2. When using the standard common controls, I get the "modern Win10" file open dialog.  With my first attempt with the CCR common dialog I get this small, really old looking dialog.  Am I doing something wrong?


1.
I think it is tied to the regional settings.

2.
Be sure that .HookEvents is False. Otherwise you get the Win 3.1 style open dialog.
Or what do you mean with small old looking ? Maybe post a screenshot to explain it better..

----------


## alcpf

Hi Krool,
Exists a way of the node parent not stay so far from the left treeview box border? The indentation as I know it's just for the distance of the child relative it's parent... Because I have the treeview without border into a picturesbox, I can fix making something like treeview.left -120  and will cut the gap between the  treeview border and the node but maybe you know something better! See the image:


Other thing. I added an imagelist to the threeview with 16px icons... But if I write a key to identify the icon, when I apply the custom panel(design mode), it simply change the pixels automatically for 32px and don't let me go back again even if I delete the key of the image...  I need to delete all images and add again... But not accept the key otherwise happens again what I said. The unique way was using the index, but it's a mess if I add  a lot of images and I can't add in the middle of the others because will reorganize the index order and I need to change everywhere in the list where I use the index images... The behavior of the key above was did  by some reason or it's a bug? Or maybe could be a problem of my VB6 editor!!!!

----------


## Hosam AL Dein

Hi krool 
In listview , Underlining hot item works only when moving by mouse vertically (In the same column) . If I move mouse horizontally (Within the same row) , it is not then changed .

----------


## TheLeePiper

Issue: Toolbar control changing size properties without user action

Forgive if this has already been discussed (but I did not find any reference in the thread). I have a few projects using the VBCCR controls, and have found that certain forms want to be updated and saved by VB6 when there has been no change to the form. All that is needed to cause this is to open the form (either Code or Object) and then close it. Even a search that touches the code in the form will cause this. I have tracked it down to the Toolbar (and its button) width and height properties changing. (I made files before and after touching the form to look for changes.) There does not appear to be any functional issues with this, but it causes any form to want to be re-saved even when there have been no changes, and it always makes me go back and check it I have accidentally updated anything.

Note that none of the other controls that I have used (TextboxW, LabelW, CommandButtonW) are showing this behavior. Thanks for your help (as always)!

Don

----------


## Erwin69

> 1.
> I think it is tied to the regional settings.
> 
> 2.
> Be sure that .HookEvents is False. Otherwise you get the Win 3.1 style open dialog.
> Or what do you mean with small old looking ? Maybe post a screenshot to explain it better..



It took a while to get the feedback for #1, but I can confirm it is indeed linked to the regional settings.

As for #2, it was indeed the HookEvents setting.  The small, old looking dialog that I mentioned, was indeed the Win 3.1 style dialog.  Too long ago for me to remember it looked like that back in the days... ;-)

----------


## Erwin69

I'm wondering if I will add the option of giving the user the choice between two sizes toolbar buttons.  Let's say one based on 16x16 buttons, another based on 32x32.

What would be the best way to do that?  Create two toolbars, and switch the visual property on/off?  Stick to one toolbar, and change imagelist during runtime depending on the user's choice?

----------


## Erwin69

On the classic toolbar, there is a little space above and below the buttons.

The buttons on a CCR toolbar have also that space above them, but the bottom of each button is at the edge of the toolbar, which gives it a strange look.  Is it possible to have a little space there as well?

----------


## Erwin69

And one more question about the toolbar: do I understand correctly that tooltips don't support Unicode texts?

----------


## Krool

> Issue: Toolbar control changing size properties without user action
> 
> Forgive if this has already been discussed (but I did not find any reference in the thread). I have a few projects using the VBCCR controls, and have found that certain forms want to be updated and saved by VB6 when there has been no change to the form. All that is needed to cause this is to open the form (either Code or Object) and then close it. Even a search that touches the code in the form will cause this. I have tracked it down to the Toolbar (and its button) width and height properties changing. (I made files before and after touching the form to look for changes.) There does not appear to be any functional issues with this, but it causes any form to want to be re-saved even when there have been no changes, and it always makes me go back and check it I have accidentally updated anything.
> 
> Note that none of the other controls that I have used (TextboxW, LabelW, CommandButtonW) are showing this behavior. Thanks for your help (as always)!


That is a really good catch. Indeed there is no functional issue, but the property bag is always fooled as if there was a change.
I could fix it by adding below red code in the UserControl_WriteProperties sub.


```
.WriteProperty "ButtonHeight", Int(PropButtonHeight / PixelsPerDIP_Y()), 22
.WriteProperty "ButtonWidth", Int(PropButtonWidth / PixelsPerDIP_X()), 24
```

I check it soon for other cases and will make a bundled update soon.

*EDIT*: The above seems not to be the reason. In my further testings this has something todo with ImageList property. But I don't understand why..




> On the classic toolbar, there is a little space above and below the buttons.
> 
> The buttons on a CCR toolbar have also that space above them, but the bottom of each button is at the edge of the toolbar, which gives it a strange look.  Is it possible to have a little space there as well?


Confirm. I noted this down. It seems the MS toolbar uses TB_SETPADDING, which the CCR does not use.
I will eveluate this and set TB_SETPADDING in the CCR toolbar likewise as the MS toolbar does.

*EDIT*: TB_SETPADDING is not the cause. It just says the distance between the button edge and the inner text/image of a button.




> And one more question about the toolbar: do I understand correctly that tooltips don't support Unicode texts?


The ToolBar.Buttons(X).ToolTipText supports Unicode.


Only the VBControlExtender's ToolTipText property is VB6 in-built and thus ANSI.




> I'm wondering if I will add the option of giving the user the choice between two sizes toolbar buttons.  Let's say one based on 16x16 buttons, another based on 32x32.
> 
> What would be the best way to do that?  Create two toolbars, and switch the visual property on/off?  Stick to one toolbar, and change imagelist during runtime depending on the user's choice?


Stick to one toolbar and set the .ImageList dynamically. Thus you only need to maintain one toolbar's config.




> In listview , Underlining hot item works only when moving by mouse vertically (In the same column) . If I move mouse horizontally (Within the same row) , it is not then changed .


It seems to be an refresh issue and thus not a bug in the CCR. I did for testing a Timer with interval each second which does a .Refresh on the ListView and then the underlining hot item will change horizontally. (within same row)

----------


## Hosam AL Dein

Hi Krool ,
In ListView , Is SelectedItem absent (Destroyed) when MultiSelect prpoerty is True and there is more than one item selected ?

----------


## Krool

> Hi Krool ,
> In ListView , Is SelectedItem absent (Destroyed) when MultiSelect prpoerty is True and there is more than one item selected ?


It returns the focused item.

----------


## Hosam AL Dein

This code raises an error 91 "Object variable or With block variable not set"

In event ItemSelect ,Please put this code and hold Ctrl to select more than one Item . This will raise the previous error


```
Dim a As String

If Selected = True Then
       a = IIf(Len(Trim(Listview1.SelectedItem.text)) = 0, vbNullString, Listview1.SelectedItem.text)
End If
```

Although it does not raise an error if removed form this event and placed anywhere else and gets the last recently selected item .

----------


## Hosam AL Dein

Another Issue I found while testing , is that when I select more than one item and Unselect one of them , then the SelectedItem  reads the last Unselected Item .

This will lead me to ask what is the difference between the focused item and the selected item ?

----------


## Hosam AL Dein

Now I see that Focused is that last Selected Or the last Unselected Item . Thus for more clear understanding I can call the .SelectedItem as .FocusedItem ?
And the word Selected does not literally mean it is selected but means it is focused(Selected or UnSelected). Is that right ?

The second part of the question is , Why does this raise an error when placed in the ItemSelect event ?

----------


## Erwin69

Again thanks for the quick feedback Krool!




> Only the VBControlExtender's ToolTipText property is VB6 in-built and thus ANSI.


Is this referring to the tooltip that is used for e.g. CommandButtonW?

----------


## Adebiyi24

Hi krool
Can I automatically size the drop-down width of the comboboxw based on the width of the longest item?
thanks

----------


## Krool

@ Hosam AL Dein, the ListView.SelectedItem returns the focused item where a focus rectangle is drawn and *not* necessarily blue highlighted.




> Is this referring to the tooltip that is used for e.g. CommandButtonW?


Yes, for example.

----------


## Krool

> Hi krool
> Can I automatically size the drop-down width of the comboboxw based on the width of the longest item?
> thanks


If you want to have the big size text fit into the drop-down area then try:
A) .HorizontalExtent = .GetIdealHorizontalExtent()
B) .DropDownWidth = .GetIdealHorizontalExtent() + Me.ScaleX(4, vbPixels, Me.ScaleMode) ' small extra buffer to account border widths etc.

Option A) uses CB_SETHORIZONTALEXTEND API.
MSDN: _If the width of the list box is smaller than this value, the horizontal scroll bar horizontally scrolls items in the list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden or, if the combo box has the CBS_DISABLENOSCROLL style, disabled._
You can use the .DisableNoScroll property to control whether CBS_DISABLENOSCROL is set or not.

Option B) uses CB_SETDROPPEDWIDTH API.
MSDN: _By default, the minimum allowable width of the drop-down list box is zero. The width of the list box is either the minimum allowable width or the combo box width, whichever is larger._

The .GetIdealHorizontalExtent() function is a convenient wrapper which calculates the "best" width, accounting possible WS_VSCROLL style and testing the string widths using the selected font.

----------


## Adebiyi24

Krool 
Million thanks

----------


## Semke

is there any reason there is no MaskEditBox? i know its not part of the common controls, but it is a nice thing to have.

----------


## Hosam AL Dein

> @ Hosam AL Dein, the ListView.SelectedItem returns the focused item where a focus rectangle is drawn and *not* necessarily blue highlighted.
> .


Thanks a lot Krool . This prop name fooled me as it implies that it will get the selected item and this is my first time to know this piece of info . Thanks again .

----------


## Erwin69

Hi Krool,

Can you confirm the below conclusions on support for Unicode ToolTipTexts?

*Supported on:*
ToolBar
ListView

*Not supported on:*
ComboBoxW
CommandButtonW
ListBoxW
VBFlexGrid

Just want to be sure before I decide how to proceed.

Thanks,
Erwin

----------


## Krool

> Hi Krool,
> 
> Can you confirm the below conclusions on support for Unicode ToolTipTexts?
> 
> *Supported on:*
> ToolBar
> ListView
> 
> *Not supported on:*
> ...


VBFlexGrid has two tool tip text. The .CellToolTipText supports unicode. The VBControlExtender's ToolTipText is VB6 in-built and thus ANSI.

----------


## MountainMan

Krool,

I have a ListView control that has the possibility of needing to show over 1 million items (its in a file manager I am almost finished with). It seems like a great opportunity to use VirtualMode. However, I am not sure how to do it with your control. In .NET there is an event called RetrieveVirtualItem that notifies you when you need to feed the control more data as he user moves up/down in the control. I have looked through your parameters and I dont see an event I can use that does something similar.

Am I missing something or do I need to subclass it? Is there an example somewhere of how to use VirtualMode with your ListView control? In general I have found extremely little online about VB6 and VirtualMode. Almost everything I have fond is for .NET and without the RetrieveVirtulItem event these arent of much use to me. Thanks.

----------


## Krool

> Krool,
> 
> I have a ListView control that has the possibility of needing to show over 1 million items (its in a file manager I am almost finished with). It seems like a great opportunity to use VirtualMode. However, I am not sure how to do it with your control. In .NET there is an event called RetrieveVirtualItem that notifies you when you need to feed the control more data as he user moves up/down in the control. I have looked through your parameters and I dont see an event I can use that does something similar.
> 
> Am I missing something or do I need to subclass it? Is there an example somewhere of how to use VirtualMode with your ListView control? In general I have found extremely little online about VB6 and VirtualMode. Almost everything I have fond is for .NET and without the RetrieveVirtulItem event these arent of much use to me. Thanks.


You looked not good..
There is an event 'GetVirtualItem', 'FindVirtualItem', 'CacheVirtualItem'.
Also use the .VirtualListItems collection retrieve selected state etc. of the items.

----------


## Erwin69

Hi Krool,

Can I control which of the scrollbars are displayed in a ListView with Report style, or is that always dynamically decided based on the combined column width, and number of rows?

----------


## Krool

> Hi Krool,
> 
> Can I control which of the scrollbars are displayed in a ListView with Report style, or is that always dynamically decided based on the combined column width, and number of rows?


There is no listview message or style for this.
So, basically No.

However, some imperfect/inefficient workarounds are shown in the link below.
https://stackoverflow.com/questions/...-in-a-listview

----------


## Erwin69

Im using a ListView in report style with checkboxes.  Multiselect is False.  The idea is that there is always only one item selected, but Multiselect doesnt stop multiple items being checked.  So I added the following code to the ItemCheck event:



```
    Dim i As Integer
    'Uncheck all items
    For i = 1 To lvPositionLabels.ListItems.Count
         lvPositionLabels.ListItems(i).Checked = False
    Next
    'Check and select the clicked item
    Item.Checked = True
    Item.Selected = True
```

This worked fine with the standard ListView, but with the CCListView both checking and unchecking an item fires the ItemCheck event.  (Which is logic I guess.)

The question is though, how can I ensure only the last clicked item is checked.  Im probably missing something simple, but am stuck

----------


## Krool

> Im using a ListView in report style with checkboxes.  Multiselect is False.  The idea is that there is always only one item selected, but Multiselect doesnt stop multiple items being checked.  So I added the following code to the ItemCheck event:
> 
> 
> 
> ```
>     Dim i As Integer
>     'Uncheck all items
>     For i = 1 To lvPositionLabels.ListItems.Count
>          lvPositionLabels.ListItems(i).Checked = False
> ...


Please find below a working code snippet:


```
Private Sub ListView1_ItemCheck(ByVal Item As LvwListItem, ByVal Checked As Boolean)
If Checked = True Then
    Dim vItem As Variant, iItem As Long
    iItem = Item.Index
    With ListView1.ListItems
    For Each vItem In ListView1.CheckedIndices
        If vItem <> iItem Then .Item(vItem).Checked = False
    Next vItem
    End With
End If
End Sub
```

EDIT: Below way is even more efficient:


```
Private Sub ListView1_ItemCheck(ByVal Item As LvwListItem, ByVal Checked As Boolean)
Static iItemPrev As Long
If Checked = True Then
    If iItemPrev > 0 Then ListView1.ListItems(iItemPrev).Checked = False
    iItemPrev = Item.Index
Else
    iItemPrev = 0
End If
End Sub
```

----------


## Erwin69

Thanks for the ListView answer.  That fixed my problem!  (I really feel like an amateur here at times...  :Blush: )

I'm slowly but steadily progressing towards the full conversion to the CCR set of controls.  One area still to be addressed is the toolbars.  I've been playing around for a good few hours with the Toolbar and ImageList controls to figure out how to deal with transparent backgrounds, but haven't been able to find the best way to move forward.

Two key questions:

1. What do you recommend as the format for the images to be in?
2. What is the best way to deal with background transparency?

----------


## Karl77

Toolbar images

Erwin, here's what I do:
PNGs with transparency are stored in a ressource DLL.
On app start I fill VBCCR imagelists by code.
Then I populate the toolbars by code using the imagelists.

Populating the toolbars is very fast.
Transparency works well.
Nothing to complain.

----------


## Hosam AL Dein

Hi Krool , 
In ListView , 
1- Is it possible to add a Column_Select Event ?
2- In HitTest method , How do I get the item/subitem being clicked ? . It always returns the first column . What should I do to get the (Cell) being clicked ? . I tried various values for the SubitemIndex parameter and got the same results . I have no clue of its purpose or how it is used .
3- Is it possible to highlight only the selected (Cell) . In Full Row Select mode it selects all (Cells) and when disabled it selects the (Cell) from first column . Is it possible to add this feature or there is a workaround for this ?

----------


## Krool

> 2- In HitTest method , How do I get the item/subitem being clicked ? . It always returns the first column . What should I do to get the (Cell) being clicked ? . I tried various values for the SubitemIndex parameter and got the same results . I have no clue of its purpose or how it is used .


Below is an example of how to use the SubItemIndex parameter in the HitTest method.


```
Private Sub ListView1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim Item As LvwListItem, iSubItem As Integer
Set Item = ListView1.HitTest(X, Y, iSubItem)
If Not Item Is Nothing Then
    If iSubItem > 0 Then
        Debug.Print Item.ListSubItems(iSubItem).Text
    Else
        Debug.Print Item.Text
    End If
End If
End Sub
```




> 3- Is it possible to highlight only the selected (Cell) . In Full Row Select mode it selects all (Cells) and when disabled it selects the (Cell) from first column . Is it possible to add this feature or there is a workaround for this ?


No, maybe a grid fits for this better than a ListView.

----------


## Hosam AL Dein

Thanks for feedback , but what about point 1 ?




> 1- Is it possible to add a Column_Select Event ?

----------


## MountainMan

Krool,

I am using VirtualMode in ListView in Report mode. I need to have the capability to tell the control to refresh/update itself programatically In my file manger I have check boxes and if you turn one off for a folder I want to turn off the check boxes for the files within that folder. I looked in your code for GetVirtualItem because it is what asks me for the updated information and it is only called in the Private Function WindowProcControl which in turn is only called by ISubclass_Message. How do I tell the ListView to update itself? Thanks.

----------


## Krool

> Krool,
> 
> I am using VirtualMode in ListView in Report mode. I need to have the capability to tell the control to refresh/update itself programatically In my file manger I have check boxes and if you turn one off for a folder I want to turn off the check boxes for the files within that folder. I looked in your code for GetVirtualItem because it is what asks me for the updated information and it is only called in the Private Function WindowProcControl which in turn is only called by ISubclass_Message. How do I tell the ListView to update itself? Thanks.


Don't know what you mean. Did you set the .VirtualItemCount property?
You can also increase performance by disabling unwanted callbacks via the .VirtualDisabledInfos property.

----------


## MountainMan

Never mind. The ListView.Refresh sub does just what its name says...

----------


## MountainMan

> Don't know what you mean. Did you set the .VirtualItemCount property?
> You can also increase performance by disabling unwanted callbacks via the .VirtualDisabledInfos property.


I did set the .VirtualItemCount property. Each time you do that the control starts over and redoes the items in the display but it puts the first item in the list at the top of the display so if the user had scrolled way down in the list then this would jump it back to the top which is not what I wanted. The Refresh sub is exactly what I needed. I can change all of my virtual values (including those that will not be displayed in the current view) and then have it Refresh and it re-reads the values it needs to re-do the display leaving the entry that is at the top where it should be. I don/t know how I overlooked that sub.

Earlier I had tried to do the ListView without the virtual items and it really bogged down when the list got over 50,000 or so. With the virtual item feature it really doesn't matter how many items you have in the list, it only displays a relatively small number of them onscreen and the extra overhead of being virtual is not really noticeable.

----------


## Hosam AL Dein

Hi krool ,
It will be helpful if you declare the basis on which you ignore some replies on this thread .

----------


## Krool

> It will be helpful if you declare the basis on which you ignore some replies on this thread .


This here is all voluntary support. I can ignore or not ignore.




> In listview , Underlining hot item works only when moving by mouse vertically (In the same column) . If I move mouse horizontally (Within the same row) , it is not then changed .


I found a solution to this. The (yet unused) notification LVN_HOTTRACK comes helpful for this.
When processing LVN_HOTTRACK and a criteria is met then sending a LVM_UPDATE message will cause a re-fetch in NM_CUSTOMDRAW.
So I will bring a update soon as this seems quite a straight forward (fix) solution for this issue.




> but what about point 1 ?


What you mean. You want an event when selecting a column ?


```
ListView1.SelectedColumn = ColumnHeader
```

The column will be only selected upon code. So you have full control over it. What would an event benefit ? (beside the fact that there is no LVN_* notification for this)

----------


## Hosam AL Dein

> This here is all voluntary support. I can ignore or not ignore .


Do my words look offensive or something ? !!!

I understand this is voluntary . It is totally obvious . I did not complain that you don`t provide support . You shared VBCCR to the community and we give feedback including bugs or features . So , we expect some sort of feedback which you already do and million thanks for you efforts . I asked why in some cases you choose to ignore some replies so that I do not fall in this region of ignorance because nobody likes to be ignored , that`s it . It is your post and you are free to decide how you handle it . But this always made me prefer in most cases to not post a bug or feature request being afraid to be ignored or misunderstood . I have a lot to say in this situation but I don`t want to flood the thread with comments that are outside its main scope or purpose .

Sincere thanks , and keep up the good work .




> I found a solution to this. The (yet unused) notification LVN_HOTTRACK comes helpful for this.
> When processing LVN_HOTTRACK and a criteria is met then sending a LVM_UPDATE message will cause a re-fetch in NM_CUSTOMDRAW.
> So I will bring a update soon as this seems quite a straight forward (fix) solution for this issue.


Thanks a lot .




> What you mean. You want an event when selecting a column ?


Yes , this is what I mean .




> The column will be only selected upon code. So you have full control over it. What would an event benefit ? (beside the fact that there is no LVN_* notification for this)


The benefit is that there is some routine that I need to call every time a column is selected . Since it seems not possible , I will put that code in every situation that I need to check whether a column is selected or not .

----------


## Erwin69

> Do my words look offensive or something ? !!!


If I may put my two cents worth in: the words indeed came across offensive.

Having said that, let's all appreciate that for most of us here, English is not our native language, and that sometimes our words do not come across the way they were intended.

You clarified the misunderstanding, and joined the large group of people who explicitly expressed their gratitude to Krool for the excellent work and support he provides.  I personally hope that this is enough to go back to focus on the subject of this thread: Krool's Common Controls Replacements.

Regards,
Erwin

----------


## Shaggy Hiker

People have different opinions and read different things into words. That doesn't mean that you two should take such a long running, and clearly valuable, thread into the ditch for some personal squabble about nothing. 

Knock it off.

----------


## Erwin69

> Toolbar images
> 
> Erwin, here's what I do:
> PNGs with transparency are stored in a ressource DLL.
> On app start I fill VBCCR imagelists by code.
> Then I populate the toolbars by code using the imagelists.
> 
> Populating the toolbars is very fast.
> Transparency works well.
> Nothing to complain.


Hi Karl,

Thanks for the suggestion.  Would it be possible to share some sample code on how you populate the imagelist, and assign the images to the toolbar buttons?  (Or do you "preset" the button Image index?)

Thanks,
Erwin

----------


## Erwin69

Hi Krool,

I saw your edit on TB_SETPADDING in the CCR toolbar.  Does that mean that it is not possible to have a little space between the bottom edge of the button and the edge of the toolbar?

Regards,
Erwin

----------


## Krool

> Hi Krool,
> 
> I saw your edit on TB_SETPADDING in the CCR toolbar.  Does that mean that it is not possible to have a little space between the bottom edge of the button and the edge of the toolbar?
> 
> Regards,
> Erwin


Thanks for reminding.
Please explain the need of this. Enough space for the toolbar is assured. What's the extra space good for?
If there is a reason for it I need a way of how to get the "extra" amount..

----------


## Erwin69

Hi Krool,

Thanks for the quick reply.

I noticed that with the original toolbar, the space above and below the buttons is the same, whereas with the CCR toolbar the buttons are aligned with the bottom of the "bar".  See picture below.

Attachment 180614

Then, for some reason I haven't yet figured out, the scaling of other controls on the main screen didn't happen correctly, resulting in the bottom of the CCR being "cut off", which made it look rather strange:

Attachment 180615

However, when I force the resize again, the scaling is done corectly, and the CCR toolbar looks a lot better.

I'd still prefer the look with as much padding below as above, but that's clearly no showstopper.

Regards,
Erwin

----------


## Karl77

> Would it be possible to share some sample code on how you populate the imagelist, and assign the images to the toolbar buttons?  (Or do you "preset" the button Image index?)


Sure, if you can wait until next week - I don't have access right now.
It's really no magic.

----------


## Krool

Erwin69,
I can't view the images in your post.

----------


## Erwin69

> Erwin69,
> I can't view the images in your post.


Let's try again:

----------


## Karl77

Erwin

For me it was too cumbersome to maintain the toolbar manually.
Therefore I do it all by code.
If you have a few buttons only, then it is perhaps too much effort.

You need to use the VBCCR imagelist.
Fill it from external DLL, or use LaVolpes image library.
Or use BMP32 and load the images from files.
Many possibilities.

In my case an external DLL was wanted.

First fill the imagelist(s) on app start:



```
Private Sub InitIconsToolbars()

Dim i As VBCCR.ImageList
Dim R As New c_ResFromDLL
'--------------------------------------------------

R.LibraryFilePath = App.Path & "\RES.dll"

Set i = MF.imgl_Toolbars

StartGDIPlus

i.ListImages.Clear
i.ColorDepth = ImlColorDepth32Bit
i.ImageWidth = 0
i.ImageHeight = 0

ResDLLToImgl i, R, "new"
ResDLLToImgl i, R, "open"
'and 100's more

Set i = Nothing

StopGDIPlus

R.CloseLibrary
Set R = Nothing

End Sub
```



Filling a toolbar:



```
Set IL = MF.imgl_Toolbars
ToolbarBackColor = vbWhite

With tbr_Main
    .AllowCustomize = False
    .BackColor = ToolbarBackColor
    .Buttons.Clear
    Set .ImageList = IL
    .Divider = False
    .ShowTips = True
    .DoubleBuffer = True
    .Transparent = Not True
    .MinButtonWidth = 0
    .MaxButtonWidth = 0

    Set b = .Buttons.Add(, "new", , TbrButtonStyleDefault, "new")
    b.ToolTipText = "New"

    Set b = .Buttons.Add(, "open", , TbrButtonStyleDefault, "open")
    b.ToolTipText = "Open"

    .GetIdealSize WS, HS
    .Width = WS
    .Height = HS
     Set b = Nothing

End With
```

----------


## Erwin69

Thanks Karl.  I'll need to study this a bit more.

My app has a limited set of buttons, so manually adding these is not the issue.  The challenge is more the use of transparency.

I've taken this update as an opportunity to "modernize" the toolbar look and feel.  As part of the pre-work, I collected/designed/created a series of images that are all saved in PNG-format with transparency.  As that format unfortunately isn't supported by the VBCCR imagelist (and not by the original either), I need to figure out what the best approach is.

----------


## Krool

> Let's try again:


Ok. I am just wondering what I should do then. Just add a magic space then ?

----------


## Erwin69

> Ok. I am just wondering what I should do then. Just add a magic space then ?


Unless it's simple, and you feel that it improves the look and feel of the CCR Toolbar, I wouldn't do anything.

From my point of view it would be a small cosmic improvement that would be nice to have, but most definitely not a showstopper or worth a significant amount of effort.

----------


## Semke

Karl

could you please elaborate on lines of code you entered




```
Dim R As New c_ResFromDLL
'--------------------------------------------------

R.LibraryFilePath = App.Path & "\RES.dll"

Set i = MF.imgl_Toolbars

StartGDIPlus

i.ListImages.Clear
i.ColorDepth = ImlColorDepth32Bit
i.ImageWidth = 0
i.ImageHeight = 0

ResDLLToImgl i, R, "new"
ResDLLToImgl i, R, "open"
'and 100's more

Set i = Nothing

StopGDIPlus

R.CloseLibrary
Set R = Nothing

```

could you please point me to a link where i can get this class *c_ResFromDLL*, it would be quite helpful for me.
also the GDIPlus Library

thanks

----------


## Karl77

Here's the DLL and PNG stuff.
It is quite old and probably there are more elegant solutions.
Also it is a adjusted to my needs.

PNG_etc.zip

I think #3089 is answered when you inspect the libs.

----------


## Semke

> Here's the DLL and PNG stuff.
> It is quite old and probably there are more elegant solutions.
> Also it is a adjusted to my needs.
> 
> PNG_etc.zip
> 
> I think #3089 is answered when you inspect the libs.


Thanks, I am making good use out of it, and saved a lot of time by not doing it myself

----------


## Krool

> Unless it's simple, and you feel that it improves the look and feel of the CCR Toolbar, I wouldn't do anything.
> 
> From my point of view it would be a small cosmic improvement that would be nice to have, but most definitely not a showstopper or worth a significant amount of effort.


I would like to help you.. it's just that in this case I have not the answer..

----------


## Erwin69

Hi Krool, don't worry about the extra space below the buttons.  As said, it's a small cosmic improvement not worth a lot of trouble.  Rest assured that your help is greatly appreciated either way!

However, something is puzzling me with the Toolbar.

The layout of my main screen is a menu-bar and the toolbar on top, and a statusbar at the bottom.  In between there is a picturebox that serves as a "container" for a range of other controls.

I assigned 32x32 pixel images to the toolbar buttons using a CCR imagelist, giving the toolbar a Height of 630.  This is what I see in the IDE, and what is saved in the frm-file.  However, at application startup, the size is reported as 390, which messes up the resizing and positioning of the container and the items in it.  After the form-resize event, it actually correctly reports the height of 630 for the toolbar, so I've moved some code around to do the resizing of the other controls at a later stage.  Which works fine.

But, now I have the strange thing that the container part of the screen is not painted after the resize and reposition.  Only when I move the mouse over the toolbar, or over the statusbar at the bottom, the center of the screen is "refreshed" and properly painted.  This happens when the app is run from the IDE as well as compiled.

I realize that this is vague, and for sure don't claim it's related to the CCR toolbar, but I've been killing myself for many hours in the last several days to figure out what is causing this, and still have no clue.  Hopefully the description rings a bell for someone to point me in the right direction.

----------


## Krool

> Hi Krool, don't worry about the extra space below the buttons.  As said, it's a small cosmic improvement not worth a lot of trouble.  Rest assured that your help is greatly appreciated either way!
> 
> However, something is puzzling me with the Toolbar.
> 
> The layout of my main screen is a menu-bar and the toolbar on top, and a statusbar at the bottom.  In between there is a picturebox that serves as a "container" for a range of other controls.
> 
> I assigned 32x32 pixel images to the toolbar buttons using a CCR imagelist, giving the toolbar a Height of 630.  This is what I see in the IDE, and what is saved in the frm-file.  However, at application startup, the size is reported as 390, which messes up the resizing and positioning of the container and the items in it.  After the form-resize event, it actually correctly reports the height of 630 for the toolbar, so I've moved some code around to do the resizing of the other controls at a later stage.  Which works fine.
> 
> But, now I have the strange thing that the container part of the screen is not painted after the resize and reposition.  Only when I move the mouse over the toolbar, or over the statusbar at the bottom, the center of the screen is "refreshed" and properly painted.  This happens when the app is run from the IDE as well as compiled.
> ...


It's the ImageList. Once without (390) and then with (630).
This is a dilemma by design. The ImageList property is saved as string in the CCR ToolBar.
I cannot lookup the ImageList Object during UserControl_ReadProperties as the order in which VB loads the control cannot be influenced.
So doing the lookup in UserControl_ReadProperties would be a luck game. Can work or not.
That's why an inteenal VB.Timer is used for that (only when needed, for ImageList) and it is ensured to fire when everything is safe. However that is AFTER the Form_Load event.
You can FIX this dilemma actually by code in Form_Load:


```
Set ToolBar1.ImageList = ToolBar1.ImageList ' Force internal lookup now
```

----------


## Karl77

I use a pager for every toolbar.
This works very well and is only visible when the form is too small to show the full toolbar.
I set the buddy by code, because in the IDE it doesn't work so good.

The toolbar size is correct when I use this after populating the toolbar: 


```
.GetIdealSize WS, HS
.Width = WS
.Height = HS
```

On positioning the toolbar without a pager, I don't care about the toolbar height.
I use the first button as the reference.
This way extra space below the buttons doesn't hurt.

----------


## Erwin69

> It's the ImageList. Once without (390) and then with (630).
> This is a dilemma by design. The ImageList property is saved as string in the CCR ToolBar.
> I cannot lookup the ImageList Object during UserControl_ReadProperties as the order in which VB loads the control cannot be influenced.
> So doing the lookup in UserControl_ReadProperties would be a luck game. Can work or not.
> That's why an inteenal VB.Timer is used for that (only when needed, for ImageList) and it is ensured to fire when everything is safe. However that is AFTER the Form_Load event.
> You can FIX this dilemma actually by code in Form_Load:
> 
> 
> ```
> ...


Thanks Krool.  That fixed it, and it did also help me to find the solution for the other problem.  :Smilie:

----------


## Erwin69

Yet another question on the toolbar...

I've added image lists for the active buttons, and for disabled buttons.  I have a separate routine that enables/disables menu-items and toolbar buttons depending on availablilty of data.

It runs at app startup, after which a number of the buttons are disabled.  Then when load a file, it is run again, to enable the applicable buttons.  So far, so good.  However, after the routine is run, the toolbar is not repainted until the mouse moves over it.  Even the explicit instruction to Refresh doesn't change that behavior.

Is there a setting / instruction that I'm overlooking?

----------


## Krool

> Yet another question on the toolbar...
> 
> I've added image lists for the active buttons, and for disabled buttons.  I have a separate routine that enables/disables menu-items and toolbar buttons depending on availablilty of data.
> 
> It runs at app startup, after which a number of the buttons are disabled.  Then when load a file, it is run again, to enable the applicable buttons.  So far, so good.  However, after the routine is run, the toolbar is not repainted until the mouse moves over it.  Even the explicit instruction to Refresh doesn't change that behavior.
> 
> Is there a setting / instruction that I'm overlooking?


Can you bundle a small demo showing the problem ? I can't replicate it. Thanks

----------


## MountainMan

Version 3 of the Documentation and Compile Utility for Krool's controls has been released here.

MountainMan

----------


## Erwin69

> Can you bundle a small demo showing the problem ? I can't replicate it. Thanks


When I isolated the toolbar as the only control on a separate from, it worked correctly, so there must be something else that has an influence.  I will have to investigate further.

----------


## Erwin69

While Im finetuning the implementation of the VBCCR components in my application, I discovered a significant performance issue in one area.

Im using the following steps to show the user a combo with only unique values:

1.	All items are added to a sorted listview
2.	Then go through the listview from the top, removing double items
3.	Last, the remaining items are added to the dropdown

Using a 1000 records dataset, these were the results:

- Using a sorted Microsoft Common Controls listview, the process takes 25 milliseconds.
- Using a sorted VBCCR listview, the process takes 21030 milliseconds.
- Using a non-sorted VBCCR listview, filling it, setting sorting to true, and then do the rest of the process, takes 138 milliseconds.

The first and third approach broken down:

*Microsoft ListView*
Fill Listview            8 ms
Remove Doubles   14 ms
Fill Combo              3 ms

*VBCCR ListView*
Fill Listview             28 ms
Switch to sorted      65 ms
Remove Doubles     40 ms
Fill Combo                5 ms

The ListView basically has all properties set to False, except for Enabled, as it's only used behind the scenes, and therefore doesn't need to be displayed, refreshed, etc.

Note: no further action is expected from my side as I can live with the 138 ms, but I thought to share this to show that different approaches can make a massive difference.

----------


## Mustaphi

Please Krool help me regarding this point



> Tutorial:
> The "Development" machine needs to register the VBCCR17.OCX as usual and use the components for e.g. in a Std-EXE project.
> The source project needs to include the Side-by-side resources. (see below)
> Then on the "End user" machine you only need the VBCCR17.OCX and the .exe (Std-EXE project) on the same folder.
> It will work then without any registration.


I followed these steps for VBFlexGrid and everything is working fine on the end user machine.
However I failed to do so with common controls.
I'll tell you about all the steps I did.
I used the Resource Hacker utility to add the VBCCR17SideBySide.res to the VBFLXGRD14SideBySideAndVisualStyles.res
Once they are compiled in one file I added them to the project.
I placed the VBCCR17.OCX and the VBFLXGRD14.OCX in the .exe folder.
I still have no issue with the VBFLXGRD14 but I'm having error with the VBCCR17
Component 'VBCCR17. OCX' or one of its dependencies not correctly registered: a file is missing or invalid
On The "Development" machine, I have no issue
Thank you in advance

----------


## Krool

> While Im finetuning the implementation of the VBCCR components in my application, I discovered a significant performance issue in one area.
> 
> Im using the following steps to show the user a combo with only unique values:
> 
> 1.	All items are added to a sorted listview
> 2.	Then go through the listview from the top, removing double items
> 3.	Last, the remaining items are added to the dropdown
> 
> Using a 1000 records dataset, these were the results:
> ...


Well. The MS ListView will sort kind of "PostMessage" style so you cannot compare it directly.
I think that the VBCCR ListView will sort "directly" is rather a feature than a bug.
You do it correctly that you disable the sort while populating.
I found some spots where maybe a few milliseconds can be saved (e.g. store AddressOf in a variable etc.) When sorting after each insert. However, that fact is neglibile when sorting only once when insertions are finished.

But you can improve by eliminating the duplicates already in the recordset. Also the sorting could be outsourced to the recordset. And ultimate performance would be to make the ListView virtual and fetch the visible viewport data from the recordset only when needed.

----------


## Mith

VB6sp6
VBCCR 1.7.12

i found a autoresize-bug at the StatusBar-control.
the width of the 2. panel doesnt resize after changing the content.
i have statusbar with 3 panels:
1.panel autoresize=spring
2.panel autoresize=content
3.panel autoresize=content

example:
the 2. panel displays the text "1". after i change the text to "10000" the panel doesnt resize to the new content.
setting the autoresize property to "content" again triggers the 2. panel resize.
changing the width of the statusbar also triggers the 2. panel resize.
the 3. panel always resize correct after changing the content!

----------


## Krool

> VB6sp6
> VBCCR 1.7.12
> 
> i found a autoresize-bug at the StatusBar-control.
> the width of the 2. panel doesnt resize after changing the content.
> i have statusbar with 3 panels:
> 1.panel autoresize=spring
> 2.panel autoresize=content
> 3.panel autoresize=content
> ...


I found the bug. The blue marked code fixes the issue of not auto-resizing after changing the panel text.
Update will follow soon...


```
Friend Property Let FPanelText(ByVal Index As Long, ByVal Value As String)
If StatusBarHandle <> 0 Then
    PropShadowPanels(Index).Text = Replace$(Value, vbTab, vbNullString)
    Call SetPanelText(Index)
    If PropShadowPanels(Index).AutoSize = SbrPanelAutoSizeContent Then Call SetParts
End If
End Property
```

----------


## Erwin69

> I think that the VBCCR ListView will sort "directly" is rather a feature than a bug.


I agree.




> I found some spots where maybe a few milliseconds can be saved (e.g. store AddressOf in a variable etc.) When sorting after each insert. However, that fact is neglibile when sorting only once when insertions are finished.


I wouldn't bother if I were you.




> But you can improve by eliminating the duplicates already in the recordset. Also the sorting could be outsourced to the recordset. And ultimate performance would be to make the ListView virtual and fetch the visible viewport data from the recordset only when needed.


The dataset is a collection of a custom class, not a recordset.  There actually are multiple, but one example is CProduct, with properties like ID, Name, Supplier.  I'm using the described process with a sorted ListView to get a list of Suppliers without duplicates.  It seemed the simplest and quickest approach back in the days when I added that feature.

----------


## Erwin69

Hi Krool,

Question about the VBFlexgrid:

I switch redraw off, and add 1000 rows with 50 columns.  This takes 0.7 seconds.

Then I set sorting to one column (flexSortStringAscending).  This takes 10.1 seconds.  (With Redraw still off.)

Am I missing some setting, or is the grid sorting simply slow, and am I better of using a temp recordset in memory to sort, and the (re-)populate the grid?

Thanks,
Erwin

----------


## Krool

> Hi Krool,
> 
> Question about the VBFlexgrid:
> 
> I switch redraw off, and add 1000 rows with 50 columns.  This takes 0.7 seconds.
> 
> Then I set sorting to one column (flexSortStringAscending).  This takes 10.1 seconds.  (With Redraw still off.)
> 
> Am I missing some setting, or is the grid sorting simply slow, and am I better of using a temp recordset in memory to sort, and the (re-)populate the grid?
> ...


I just did a test with 1000 rows and 50 column. The sorting takes 0.2 seconds in *IDE*.
Can you provide a demo ?

----------


## Mith

the statusbar-panel-autoresize-bug is fixed with OCX v1.7.14!
thx you!

----------


## Erwin69

> I just did a test with 1000 rows and 50 column. The sorting takes 0.2 seconds in *IDE*.
> Can you provide a demo ?


Knowing that the grid could be fast, I investigated further and discovered that it's the SelectionMode setting that is causing the slowness.  If I set it to FlexSelectionModeFree the sorting is indeed as fast as you mentioned.  However, if I set it to FlexSelectionModeByRow it takes the 10 seconds I mentioned.  I'm treating that setting like the Redraw now, off before sorting, and then back on, and performance is good.

One additional question, when a row is selected, the cell in the first column doesn't get the background color even if SelectionMode is set to FlexSelectionModeByRow.  Is there a way around that?

*Edit*: you can ignore the additional question.  I realized that it is the FocusRect setting that was not set to None.

----------


## Semke

I have noticed on the DateTimePicker when CustomFormat is "dd/MM/yyyy hh:mm:ss", that its problematic when you try editing.
AllowUserInput is enabled, the selection of individual values (day, month, year, hour, minute, second) with the mouse selects the whole text.

----------


## Krool

> Knowing that the grid could be fast, I investigated further and discovered that it's the SelectionMode setting that is causing the slowness.  If I set it to FlexSelectionModeFree the sorting is indeed as fast as you mentioned.  However, if I set it to FlexSelectionModeByRow it takes the 10 seconds I mentioned.  I'm treating that setting like the Redraw now, off before sorting, and then back on, and performance is good.


LOL.  :Smilie: 
It's not a bug but a feature. In fact you are doing a 50 multi-column sort. You just were lucky with the selection mode 'Free' to have not a selection which spans multiple columns.

The code below will help you out to sort only a particular column (for all rows) and it works for every selection mode.



```
Dim MyColToSort As Long
MyColToSort = 5 ' or whatever else you have as input

Dim Row1 As Long, Row2 As Long, Col1 As Long, Col2 As Long
With VBFlexGrid1
Row1 = .Row: Row2 = .RowSel: Col1 = .Col: Col2 = .ColSel
.SelectRange Row1, MyColToSort, Row1, MyColToSort ' Ensure single col sort for all rows
.Sort = FlexSortStringAscending
.SelectRange Row1, Col1, Row2, Col2 ' Restore selection
End With
```




> I have noticed on the DateTimePicker when CustomFormat is "dd/MM/yyyy hh:mm:ss", that its problematic when you try editing.
> AllowUserInput is enabled, the selection of individual values (day, month, year, hour, minute, second) with the mouse selects the whole text.


Thats the point for AllowUserInput at all. To allow a text free entry. You need to parse the input accordingly in the "ParseUserInput" event.
If you don't want this turn AllowUserInput off (=False, which is the default)

----------


## Semke

> LOL. 
> Thats the point for AllowUserInput at all. To allow a text free entry. You need to parse the input accordingly in the "ParseUserInput" event.
> If you don't want this turn AllowUserInput off (=False, which is the default)


Thanks, this is when We bang our heads and say "how stupid am I"

----------


## Erwin69

> LOL. 
> It's not a bug but a feature. In fact you are doing a 50 multi-column sort. You just were lucky with the selection mode 'Free' to have not a selection which spans multiple columns.


OK, then it makes sense that it needed a bit more time to sort.  :Wink: 

I'm using version 1.04.0032 of the VBFlexgrid OCX.  SelectRange is an unknown property?

Would this approach give the same result as your code example?



```
With VBFlexGrid1
     .SelectionMode = FlexSelectionModeFree
     .Redraw = False
     .col = iColumn
     .Sort = flexSortStringAscending
     .SelectionMode = FlexSelectionModeByRow
     .Redraw = True
End With
```

----------


## Krool

> OK, then it makes sense that it needed a bit more time to sort. 
> 
> I'm using version 1.04.0032 of the VBFlexgrid OCX.  SelectRange is an unknown property?
> 
> Would this approach give the same result as your code example?
> 
> 
> 
> ```
> ...


Not assured. If the row sel "range" is more than 1 only those rows will be sorted.
So a extra .RowSel = .Row would help.

----------


## Erwin69

In my grid I have also columns with percentages (e.g. 7.3% and 54.9%) and columns with dimensions (e.g. 7.2cm and 14.6cm or 3.1" and 6.2").  MSFlexgrid sorts these without problems using the Numeric sorts, but the VBFlexGrid doesn't.  What is the recommended way to sort these?

----------


## Krool

> In my grid I have also columns with percentages (e.g. 7.3% and 54.9%) and columns with dimensions (e.g. 7.2cm and 14.6cm or 3.1" and 6.2").  MSFlexgrid sorts these without problems using the Numeric sorts, but the VBFlexGrid doesn't.  What is the recommended way to sort these?


Need to test... and if something needs to be enhanced.
Worst case "custom sort option" which raise event.

Edit: you may store the percentage as number only and use .ColFormat property to add the "%" char as formatting. Thus the sort would work as immediate solution.

Btw. you can sort also using the cell property


```
.Cell(FlexCellSort, Row1, Col1, Row2, Col2) = flexSortStringAscending
```

This way you don't need to bother change row col etc. and to restore it..

*Edit*: please continue in the VBFlexGrid thread!

----------


## Karl77

> *Edit*: please continue in the VBFlexGrid thread!


Why not combine the 2 projects?
I think it is unlikely that a VBFlexGrid user doesn't use VBCCR...
Just a thought.

----------


## Mith

> Why not combine the 2 projects?
> I think it is unlikely that a VBFlexGrid user doesn't use VBCCR...
> Just a thought.


Im a VBCCR user and i dont use VBFlexGrid and for me it looks like someone spams the forum with postings not related to VBCCR...

----------


## xiaoyao

I'm sorry about that.
I'm not dissatisfied, I'm just saying that the control is very good.It is suggested to add some transparent functions, because 99% of people do not have the ability to modify it at all.After all, all VB.NET controls are transparent.Today, 23 years later, we are developing a basic control with some new elements. Such as a transparent background or translucent mask.

----------


## xiaoyao

> Thanks Karl.  I'll need to study this a bit more.
> 
> My app has a limited set of buttons, so manually adding these is not the issue.  The challenge is more the use of transparency.
> 
> I've taken this update as an opportunity to "modernize" the toolbar look and feel.  As part of the pre-work, I collected/designed/created a series of images that are all saved in PNG-format with transparency.  As that format unfortunately isn't supported by the VBCCR imagelist (and not by the original either), I need to figure out what the best approach is.


About transparency, you can communicate with me in this respect. I also like to make the controls more beautiful.

----------


## Krool

> About transparency, you can communicate with me in this respect. I also like to make the controls more beautiful.


StdPicture objects are restricted.
They can be "enhanced" by vtable hacks to allow gdi+.
However, that is the responsibility of the app todo and not of the VBCCR.
The pictures are "owned" by the app and VBCCR just "borrows" them. It would be dangerous if there is any action on the objects which will "change" them.
And doing private copies would kill "compatibility".
Anyhow, see below for a solution:
https://www.vbforums.com/showthread....to-Support-GDI

----------


## Shadic

I have recently started using these common control replacements and have found that in the existing TabStrip control there is a way to disable 1 specific Tab to prevent it from being selected using an Enabled variable in the Tab object of the TabCollection, however I cannot clearly see a way to do so utilising the replacement, unless I rework the event handle to ignore input to that tab unless a seperate boolean is used to control the function.

Is such functionality not possible to expose, or is there a better alternative method?

----------


## Semke

the MS Common Control Tabstrip does not have an Enable Property for each tab (although I don't know why).
You are referring to the SSTab, which is a complete different control, which creates its own container for each tab.

to get around this limitation, you can use the TabBeforeClick Event.

----------


## Erwin69

> I have recently started using these common control replacements and have found that in the existing TabStrip control there is a way to disable 1 specific Tab to prevent it from being selected using an Enabled variable in the Tab object of the TabCollection, however I cannot clearly see a way to do so utilising the replacement, unless I rework the event handle to ignore input to that tab unless a seperate boolean is used to control the function.
> 
> Is such functionality not possible to expose, or is there a better alternative method?


I've been converting my application to the VBCCR Unicode controls, and added the VBFlexGrid (also by Krool) and the SSTabEx (by Eduardo) to the toolkit.  I am very happy with the quality of the controls, and the great support that is given via this forum.

https://www.vbforums.com/showthread....68#post5517568

----------


## ScriptBASIC

Krool,

I noticed there is no *List* property with your ComboBox. Is the ComboBox populated under program control only?

----------


## Krool

> Krool,
> 
> I noticed there is no *List* property with your ComboBox. Is the ComboBox populated under program control only?


There exist a List property. However, it's run-time only.

----------


## ScriptBASIC

Krool,

I'm using your tab control and no text is being shown for *Labels*. Button and textboxes seem fine. It's like the Label control will not bind to the tab page at all. Link Labels seem to work.

Using VBCCR17.

----------


## Krool

> Krool,
> 
> I'm using your tab control and no text is being shown for *Labels*. Button and textboxes seem fine. Using VBCCR17.


Labels are windowless. You need a "helper" container, such as a Frame or PictureBox.

----------


## ScriptBASIC

Okay. 

The form I'm trying to reproduce does have a frame around the controls I plan to use. I forgot to add it with the test of the tab page. 

I put Mr. Freakout back in the closet.  :Smilie:

----------


## ScriptBASIC

I set the form to use *pixel* scaling mode which has been working fine until I got to adding controls to the tab page. It looks like twips is the only scale mode the tab page accepts.

----------


## ScriptBASIC

Krool,

I decided to go with the *SSTab* control. It allows me to add controls to the pages in design time and easier to deal with. FWIW this control also only accepts twips. I guess that is just how it is.

----------


## Krool

> I set the form to use *pixel* scaling mode which has been working fine until I got to adding controls to the tab page. It looks like twips is the only scale mode the tab page accepts.


What does not work in pixel scaling mode? Demo? Code?

----------


## ScriptBASIC

Adding controls worked fine. My only comment was that if I use *pixel* scaling the tab pages only accepts twips, nothing else. As mentioned I moved to SSTab as I don't what to have to deal with separate forms for tab pages and only able to test in runtime.

----------


## Krool

> Adding controls worked fine. My only comment was that if I use *pixel* scaling the tab pages only accepts twips, nothing else. As mentioned I moved to SSTab as I don't what to have to deal with separate forms for tab pages and only able to test in runtime.


The TabStrip has no "tab pages". if you use a VB.Frame (or FrameW) then this container ("tab page") is always in twips. If you want to use pixels, then use a VB.PictureBox.

----------


## ScriptBASIC

My understanding is the tabstrip is just that. "Tab pages" are referred to as *property pages* which threw me for a loop. The *tabstrip* only shows the first page and clicking on the other tabs do nothing in the IDE. SSTab made that work like I expected. Thanks for the tip on using picturebox rather then frames to use pixel scaling.

----------


## ScriptBASIC

Hi Krool,

Here is the result of our conversations. The picturebox frame replacement to get pixel scaling and using *SSTab* saved me a ton of time with this migration project I'm doing.

Attachment 181260

----------


## Hosam AL Dein

Hi krool ,
1- In toolbar , Is there a way to assign a font for a specific button instead of affecting all the buttons ? Like the ForeColor property that is assigned for the toolbar button .
The reason , to replace button images by font icons like font awesome as an example .
This will add flexibility to color changing and the size of the button graphics .

----------


## softv

Dear Krool,

Thanks, as always, for your altruistic work.

I have been, for the first time, trying the *CoolBar* control since the past 2 or 3 days. I have an issue with *UseChevron* option.

I followed your instructions in https://www.vbforums.com/showthread....=1#post5002991, on how to avail the UseChevron option. The thing is that when the ideal width is reached, a white vertical strip appears but without the chevron symbol. When I click on that white strip, the BandChevronPushed event does get fired.

So, I experimented by ticking and unticking the various options in quite a few combinations. What worked finally was unticking the* 'VisualStyles'* option under* '*General*'* tab. But then, naturally, the visual styles are gone. I created the ComCtlsDemo.exe (with 'VisualStyles' option ticked) and tried it. Only white strip appears. Clicking on it fired the BandChevronPushed event. I tried that same ComCtlsDemo.exe in a Win7 system. There also, same result. 

So, am I missing something? How to make the chevron appear without unticking the 'VisualStyles' option? 

And, one more question. After unticking the 'VisualStyles' option and making the chevron appear, I tried it for a band with Toolbar control. When the ideal width is reached, the chevron appears. But when I clicked the chevron, the hidden items of the toolbar control do not show up. Have we to show the hidden items manually by writing code in *BandChevronPushed* event?

*Note:*
- I am using the latest version of your controls (downloaded 2 days back)
- I am on Windows 10 Home. I created the ComCtlsDemo.exe therein only.

Kind Regards.

----------


## Krool

> Hi krool ,
> 1- In toolbar , Is there a way to assign a font for a specific button instead of affecting all the buttons ? Like the ForeColor property that is assigned for the toolbar button .
> The reason , to replace button images by font icons like font awesome as an example .
> This will add flexibility to color changing and the size of the button graphics .


It's possible to return CDRF_NEWFONT on NM_CUSTOMDRAW for a toolbar. However, I can remember playing around with it and it bugged as the button size will not change accordingly.

----------


## smileyoufu

> Hi Krool,
> 
> Here is the result of our conversations. The picturebox frame replacement to get pixel scaling and using *SSTab* saved me a ton of time with this migration project I'm doing.
> 
> Attachment 181260


Your attachment link is invalid

----------


## Krool

> Dear Krool,
> 
> Thanks, as always, for your altruistic work.
> 
> I have been, for the first time, trying the *CoolBar* control since the past 2 or 3 days. I have an issue with *UseChevron* option.
> 
> I followed your instructions in https://www.vbforums.com/showthread....=1#post5002991, on how to avail the UseChevron option. The thing is that when the ideal width is reached, a white vertical strip appears but without the chevron symbol. When I click on that white strip, the BandChevronPushed event does get fired.
> 
> So, I experimented by ticking and unticking the various options in quite a few combinations. What worked finally was unticking the* 'VisualStyles'* option under* '*General*'* tab. But then, naturally, the visual styles are gone. I created the ComCtlsDemo.exe (with 'VisualStyles' option ticked) and tried it. Only white strip appears. Clicking on it fired the BandChevronPushed event. I tried that same ComCtlsDemo.exe in a Win7 system. There also, same result. 
> ...


I found the bug and know how to fix it when I have time.
Meanwhile you can workaround it by setting the conditional compilation constant 'ImplementThemedReBarFix' to False.
This results that the ForeColor property though does not work anymore for a band. Also something else does not work in exotic circumstances.
That's why I have implemented such a themed "fix" and as side effect it allows custom fore color for a band.
What I simply missed was to draw the chevron. But that will be an easy one to fix I think as the v6 rebarbandinfo has the chevron rects and states.
Be patient, thanks.

----------


## softv

> I found the bug and know how to fix it when I have time.
> Meanwhile you can workaround it by setting the conditional compilation constant 'ImplementThemedReBarFix' to False.
> This results that the ForeColor property though does not work anymore for a band. Also something else does not work in exotic circumstances.
> That's why I have implemented such a themed "fix" and as side effect it allows custom fore color for a band.
> What I simply missed was to draw the chevron. But that will be an easy one to fix I think as the v6 rebarbandinfo has the chevron rects and states.
> Be patient, thanks.


Thanks a TON, krool. I shall definitely wait. No urgency at all.


You give such fabulous controls for free! 
And, on top of it, you give 100% free support too!! 
That too, so promptly!!! 

As ever, my most humble salutes to you. For ever.


Kind regards.

----------


## Krool

Update released.

The RP_CHEVRON/RP_CHEVRONVERT parts are now included in the 'ImplementThemedReBarFix'. (reported by softv)

In this regard I found another bug. When the UseChevron property of a Band will be changed then the band's header portion will not be automatically refreshed.
As can be seen in the image below, after the UseChevron got applied, the text "asd" is truncated. Now with the bugfix the band's header portion will be refreshed. (.CXHeader member, RBBIM_HEADERSIZE, = -1)

----------


## ScriptBASIC

> Your attachment link is invalid


Strange!

The form image attachment shows fine for the post in my browser. Here it is again.

----------


## Mith

> Strange!
> 
> The form image attachment shows fine for the post in my browser. Here it is again.


Everything is fine; your attachment link at post #3137 was correct!
I guess the user smileyoufu have some problems with his browser.

----------


## softv

> Update released.
> 
> The RP_CHEVRON/RP_CHEVRONVERT parts are now included in the 'ImplementThemedReBarFix'. (reported by softv)
> 
> In this regard I found another bug. When the UseChevron property of a Band will be changed then the band's header portion will not be automatically refreshed.
> As can be seen in the image below, after the UseChevron got applied, the text "asd" is truncated. Now with the bugfix the band's header portion will be refreshed. (.CXHeader member, RBBIM_HEADERSIZE, = -1)


Dear Krool,


Warm Greetings! And, Thanks a TON for the update.


By the by, I have one more observation to share. As far as I tested (trying out various options), the *vbSizeWE* mouse pointer was *not getting set* when mouse moves over the resizing portion (dotted line) of a *child coolbar*. By child coolbar, I mean a coolbar (say, cbr2) which is nested in one of the bands of a parent coolbar (say, cbr1). I tried putting cbr2 inside a frame too (the frame being inside one of the bands of cbr1)


As of now, my workaround is as follows. My 'cbr2' has 3 bands with 3 command buttons (as a control array) in them:
--
Private Sub cbr2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  cbr2.MousePointer = vbSizeWE
End Sub


Private Sub CommandButtonW_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
  cbr2.MousePointer = vbNormal
End Sub
--


Sorry if I am wrong in my observation (which resulted in the above workaround). If there is indeed a straightforward solution, kindly let me know the same.


*Ever in gratitude to your monumental work*.


Kind regards.

----------


## sagit62

I'm sorry for my bad English.
I am a user of VB6 only as a hobby, without extensive training. I learn by doing.
I was very happy when I discovered this great project. For me it is a boon. I got there looking for both a RichText control and a slider, both of which can be modified to suit my needs.
Regarding the slider I have already found a way to implement the resizing of the cursor (Thumb - TBS_FIXEDLENGTH - TBM_SETTHUMBLENGTH), so that it is more suitable for touch screens.
Would there be a not too difficult way to change the cursor image (Thumb)? If I'm not mistaken, I've seen the possibility exists (NM_CUSTOMDRAW - TBCD_THUMB) but I just don't know how to use it.

----------


## TTn

I found and resolved several critical errors that can cause controls to crash at runtime especially with multiple instances.  Most of them are due to naming collisions with VB keywords, ie Format, Width, Height, Month, Day etc.  Microsoft warned that overriding keywords can cause runtime/designtime errors to occur.   I posted a video listing the errors that need to be addressed.  A few of them are false positives due to an earlier error in the parsing.  But, there are also false negatives hidden that appear once the original errors have been resolved.  VBCCR17 name collision errors causing random crashes at runtime

----------


## Mith

> I found and resolved several critical errors that can cause controls to crash at runtime especially with multiple instances.


What kind of multiple instances? Starting the compilied Exe multiple times?

----------


## TTn

> What kind of multiple instances? Starting the compilied Exe multiple times?


Multiple instances of a control on a form.

----------


## Krool

> By the by, I have one more observation to share. As far as I tested (trying out various options), the *vbSizeWE* mouse pointer was *not getting set* when mouse moves over the resizing portion (dotted line) of a *child coolbar*. By child coolbar, I mean a coolbar (say, cbr2) which is nested in one of the bands of a parent coolbar (say, cbr1). I tried putting cbr2 inside a frame too (the frame being inside one of the bands of cbr1)
> 
> 
> As of now, my workaround is as follows. My 'cbr2' has 3 bands with 3 command buttons (as a control array) in them:
> --
> Private Sub cbr2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
>   cbr2.MousePointer = vbSizeWE
> End Sub
> 
> ...


Update released.

If the child control is only in the CoolBar "container" then there was no issue. But if it's a child control of a band (= child of ReBarWindow32) then the issue occured.

The CoolBar has been updated so the child controls can walk up the chain properly in the WM_SETCURSOR handler.
There is no workaround needed anymore. 

I have tested it well, also in regards to Form.MousePointer in play etc. and this is the most straight forward solution for natural behavior in VB.

For those interested, the code marked in blue is the addition.



```
Case WM_SETCURSOR
    If LoWord(lParam) = HTCLIENT Then
        Dim hCursor As Long
        If MousePointerID(PropMousePointer) <> 0 Then
            hCursor = LoadCursor(0, MousePointerID(PropMousePointer))
        ElseIf PropMousePointer = 99 Then
            If Not PropMouseIcon Is Nothing Then hCursor = PropMouseIcon.Handle
        End If
        If hCursor <> 0 Then
            SetCursor hCursor
            WindowProcControl = 1
            Exit Function
        ElseIf hWnd <> wParam And wParam <> 0 Then
            ' Ensures that the cild controls can walk up the chain properly.
            WindowProcControl = DefWindowProc(hWnd, wMsg, wParam, lParam)
            Exit Function
        End If
    End If
[...]
WindowProcControl = ComCtlsDefaultProc(hWnd, wMsg, wParam, lParam)
```




> Multiple instances of a control on a form.


Can you provide samples to replicate such crashes ?

----------


## TTn

It's a random thing at runtime as I said.  Not all of the controls appear to have the problem.  The only easy solution for me was to resolve any and all naming collisions to take the load off of the designer/runtime.

Did you see the video?  

The word "Format" is causing the designer to jump to a definition in another procedure.  But then, I tested after the video, and that word jumped correctly to the right definition.

----------


## Mith

> Multiple instances of a control on a form.


I use multiple instances of the following controls on many forms and never run into any problems: labelW, textboxW, comboboxW, checkboxW, optionbuttonW, frameW

How to force this problem?

----------


## TTn

> I use multiple instances of the following controls on many forms and never run into any problems: labelW, textboxW, comboboxW, checkboxW, optionbuttonW, frameW
> 
> How to force this problem?


Again, this problem is *intermittent*, aka random at design/runtime.
Microsoft said that you should not use those reserved words because design/runtime errors can occur.

Here is a list released by MS that includes Format, Width, Height etc.




> Abs  Access  AddItem  AddNew  Alias  And  Any  App  AppActivate  Append  AppendChunk  
> Arrange  As  Asc  Atn  Base  Beep  BeginTrans  Binary  ByVal  Call  Case  CCur  CDbl  
> ChDir  ChDrive  Chr  Chr$  CInt  Circle  Clear  Clipboard  CLng  Close  Cls  Command  
> Command$  CommitTrans  Compare  Const  Control  Controls  Cos  CreateDynaset  CSng  
> CStr  CurDir$  Currency  CVar  CVDate  Data  Date  Date$  DateSerial  DateValue  Day  
> Debug  Declare  DefCur  CefDbl  DefInt  DefLng  DefSng  DefStr  DefVar  Delete  Dim  
> Dir  Dir$  Do  DoEvents  Double  Drag  Dynaset  Edit  Else  ElseIf  End  EndDoc  EndIf  
> Environ$  EOF  Eqv  Erase  Erl  Err  Error  Error$  ExecuteSQL  Exit  Exp  Explicit  
> False  FieldSize  FileAttr  FileCopy  FileDateTime  FileLen  Fix  For  Form  Format  
> ...


Trust me, it serves no good purpose to use these words as parameters etc.

----------


## TTn

Confirm the fix by changing the two/or-more affected functions in the RichTextBox module.  


```
Public Sub OLEObjectsAddFromPicture(ByVal Picture As IPictureDisp, Optional ByVal fmt As Variant)
  'new body here
  Format 'Right click Format token, then click goto definition in the object browser.  Success!
End Sub

Public Sub SaveFile(ByVal FileName As String, Optional ByVal fmt As RtfLoadSaveFormatConstants = RtfLoadSaveFormatRTF, Optional ByVal SelectionOnly As Boolean)
  'new body here
End Sub
```

Now the variable/param can't jump to another function/sub.

----------


## TTn

Just so everyone can get an idea of the various ways these manifest, take a look at line 461 in the Slider module.  


```
 
     Dim Width As Long, Height As Long
      Width = .ScaleWidth
      Height = .ScaleHeight
       'some code end with
       MoveWindow SliderHandle, 0, 0, Width, Height, 0
```

Looks ok, but it ran into a different kind of collision.  Comment out the dimensions for Width and Height.  
Now jump to definition from the param Width in the MoveWindow function.
You will end up jumping to the module property for Width, that expects an argument.
Technically, this word token should stay hidden and reserved for Width of Me.

Another kind of problem is assignments to constants not permitted.  Line 958 of module CommonDialog.
The word "Color" is a member of LoadPictureConstants.  
Line 158 of LvwColumnHeader.  The word "Checked" is a member of OLE_TRISTATE.
Code should be explicitly named not to collide, because it causes a collective load at design/runtime.

Some other words to fixup are: Month, Day, DateValue.  Some of these may have various layers of issues that can occur in different ways, because the month and day are used in a loop, and as properties, and as reserved words.

----------


## Eduardo-

Could you describe steps by steps how to reproduce a single problem? (just one case, but clear)

Are you complaining that it is confusing the object browser when you look for a definition or what?

----------


## Mith

> Could you describe steps by steps how to reproduce a single problem? (just one case, but clear)
> 
> Are you complaining that it is confusing the object browser when you look for a definition or what?


I want to see one example to reproduce this problem without altering the existing code like he described at #3157.
i only use the original compiled VBCCR OCX version and never expierend any problems.
Maybe you can run into this problem only when you use the source code?

----------


## TTn

I described enough for you to reproduce a design error that jumps between procedures.  Confirm by changing the word/function "Format" to "fmt".  I've been clear.  You're not supposed to use reserved words.  The compiler does an error parsing in a specific order, when looking for definitions deciding to filter a parsed error or not.  Errors like that can cause false results as seen, because those words are seen globally.    Why would you want to continue using the word Format if it can cause global jumps to unrelated parameters?  I've presented a clear list of words that should not be used as parameters or variables.

----------


## Eduardo-

> The compiler does an error parsing in a specific order, when looking for definitions deciding to filter a parsed error or not.


What do you mean with that?
It compiles just fine, no errors.




> Errors like that can cause false results


What do you mean by "false results"??????




> as seen


Where?
You didn't show anything. 




> Why would you want to continue using the word Format if it can cause global jumps


What do you mean with "global jumps"? How to reproduce that "issue"?

Are you willing to help or what is this about?
Because it you are trying to help, do what I asked to you: detail step by step how to reproduce *one* problem.

And don't say that you already did because you did nothing so far, only loose and ambiguous claims about alleged errors that nobody knows what you are talking about.

I think you are unable to show anything, because the best you could do so far is to say "random errors" (that of course, only allegedly happen in your machine).

----------


## yereverluvinuncleber

[Redacted as I like Eduardo]

----------


## wqweto

The name "shadowing" problems are hypothetical. Can occur if changes are made in certain way so that some hideous errors are introduced unintentionally.

Highly doubt there are any actual problems that stem from using keywords for identifiers throughout the codebase, otherwise TTn would be the first to point these out.

cheers,
</wqw>

----------


## Erwin69

> That was a bit aggressive Eduardo, no need to start a battle or a flamewar... 
> 
> This isn't Ttn's product so he doesn't have to do any work at all. He is simply raising an issue. If it was raised to me and I was the author, I would go off and do some digging myself based upon the error reported. I might ask politely for some more information if I required it but there is no onus on anyone to do anything when they are trying to help.


You are correct in the sense that there is no need to start a battle or flamewar, but I don't think that was the intention of Eduardo's post.  If anything, he may have been a bit "protective".

If you go back through the nearly 3200 posts in this thread, you'll see that Krool (= the author) not only been has been giving this great set of controls free of charge to everybody, he also has been providing a great amount of support to everyone who had questions.

I'm not in the position to judge Ttn's claims, too technical for me, but as an "educated outsider" I'd be very surprised that what is claimed to be a "fundamental design error" only pops up after 9 years where the controls have been used in a large number of projects around the globe.  I for example, have used these controls to replace 1700 controls in one of my apps, and have not experienced any problems.

Eduardo on the other hand, I think is in the position to judge Ttn's claims, as he's the author of the SSTabEx control which I see as an extension of the Krool's set of controls.  So, I think all he was trying to do, it to get to the root of the problem.

----------


## Eduardo-

> You are correct in the sense that there is no need to start a battle or flamewar, but I don't think that was the intention of Eduardo's post.  If anything, he may have been a bit "protective".


Of course I didn't and don't want to start any flame war.

The problem, and the thing that I didn't like, is that he writes like he is addressing  a serious problem, and the people that don't understand what he is saying might feel insecure using the controls, when in fact there is no problem at all.

The problem is if you modify the code without knowing what you are doing, but that's always a problem in any project.

About those words, that are not reserved keywords (otherwise VB wouldn't allow to compile) but names used by VB elsewhere, it is my personal opinion and what I usually do, is to avoid using them to avoid any possible confusion, but not because there is a real problem.

----------


## Eduardo-

In the sake of now starting any flame war, I'm out of the thread (I don't mean forever  :wave: ).

----------


## Eduardo-

Sorry, just one more message for completeness, here is a list of VB reserved keywords:




> Abs Any Array As Attribute Boolean ByRef Byte ByVal Call Case CBool CByte CCur CDate CDbl CDec CDecl CInt Circle CLng CLngLng CLngPtr Close Const CSng CStr Currency CVar CVErr Date Debug Decimal Declare DefBool DefByte DefCur DefDate DefDbl DefDec DefInt DefLng DefLngLng DefLngPtr DefObj DefSng DefStr DefVar Dim Do DoEvents Double Each Else ElseIf Empty End EndIf Enum Erase Event Exit False Fix For Friend Function Get Global GoSub GoTo If Implements In Input Input InputB Int Integer LBound Len LenB Let LINEINPUT Lock Long LongLong LongPtr Loop LSet Me New Next Nothing Null On Open Option Optional ParamArray Preserve Print Private PSet Public Put RaiseEvent ReDim Resume Return RSet Scale Scale Seek Select Set Sgn Shared Single Spc Static Stop String String Sub Tab Then To True Type UBound Unlock Until Variant VB_Base VB_Control VB_Creatable VB_Customizable VB_Description VB_Exposed VB_Ext_KEY VB_GlobalNameSpace VB_HelpID VB_Invoke_Func VB_Invoke_Property VB_Invoke_PropertyPut VB_Invoke_PropertyPutRefVB_MemberFlags VB_Name VB_PredeclaredId VB_ProcData VB_TemplateDerived VB_UserMemId VB_VarDescription VB_VarHelpID VB_VarMemberFlags VB_VarProcData VB_VarUserMemId Wend While With WithEvents Write Write


You cannot use those, VB won't allow.

Taken from here.

----------


## TTn

Step 1.  Locate the sub procedure called "OLEObjectsAddFromPicture", inside the "RichTextBox" module.
Step 2.  Right Click the Variant parameter called "Format".
Step 3.  Select "Definition" from the menu.
Step 4.  Notice that VB jumps to a parameter of a completely different procedure called "SaveFile".
Step 5.  Notice that the type of this parameter is "defined" as an emumeration not a variant:

Public Enum RtfLoadSaveFormatConstants
   RtfLoadSaveFormatRTF = 0
   RtfLoadSaveFormatText = 1
   RtfLoadSaveFormatUnicodeText = 2
End Enum

6.  Now, edit the parameter inside SaveFile, from "Format" to "fmt".
7.  Navigate back to "OLEObjectsAddFromPicture procedure, and try again.
8.  Notice that you jumped to another procedure this time called "LoadFile"
9.  Edit the parameter inside LoadFile, from Format to fmt.
10. Try again, now you finally get the correct procedure with a variant definition.

But, you're still using a reserved definition that somehow can jump out from one procedure to another as another type.  In a general use module, it would be better to clear this up.  Or be stubborn about it, your choice.  There are thousands of lines in the code, but the VBA 6.5 parser caught only a couple dozen.

----------


## yereverluvinuncleber

Quitting drinking, having a headache is a good enough reason for being grumpy on any thread... my random thought for the day.

So, if TTn is correct (and I am not qualified to say either way) then it is just a matter of whether it is important or not. If it is both correct and important then Krool can weigh up the work and decide if he wants to make the change.

----------


## wqweto

> Step 1.  Locate the sub procedure called "OLEObjectsAddFromPicture", inside the "RichTextBox" module.
> Step 2.  Right Click the Variant parameter called "Format".
> Step 3.  Select "Definition" from the menu.
> Step 4.  Notice that VB jumps to a parameter of a completely different procedure called "SaveFile".
> Step 5.  Notice that the type of this parameter is "defined" as an emumeration not a variant:
> 
> Public Enum RtfLoadSaveFormatConstants
>    RtfLoadSaveFormatRTF = 0
>    RtfLoadSaveFormatText = 1
> ...


This is a bug in the IDE. Check this out:

Step 1.  Locate the sub procedure called "OLEObjectsAddFromPicture", inside the "RichTextBox" module.
Step 2.  Rename Variant parameter called "Format" to "fmt".
Step 3.  Press F5 and get "Argument not optional" on IsMissing(Format) line

This comes to show that "Format" identifier inside "OLEObjectsAddFromPicture" is clearly not resolved as "Format" parameter neither of "SaveFile" not "LoadFile" functions. It is either a local parameter or the VBA.Format function.

VB6 parser is complicated mess. For instance in a class you can add a property called Left (like in Top, Left, Width, Height) but still in the same class in the body of its methods you can call str = Left(str, 5) to invoke VBA.Left without requiring libname prefix i.e. the compiler disambiguates on the number of parameters specifically for Left, otherwise every user-control and every user-form in every VB6 project would be mostly broken by having intrinsic Left property shadowing VBA.Left runtime function.

cheers,
</wqw>

----------


## TTn

> This is a bug in the IDE. Check this out:
> 
> Step 3.  Press F5 and get "Argument not optional" on IsMissing(Format) line


Which one of those do you think has an argument not optional?  The same original error would indicate that the VBA.Format function is still missing an argument, even though the parameter was changed to fmt.

----------


## NilsB

Hi Krool,

The CommandButtonW with Style vbButtonGraphical does not support 32bpp Icon.
The reason as far as I understand is the use of ButtonPicture.Render in the WindowProcUserControl WM_DRAWITEM.
Is it possible to use the DrawState (like you do in case the Button is disabled and no DisabledPicture is provided)?
Something like this should work (DSS_NORMAL = 0)
ElseIf ButtonPicture.Type = vbPicTypeIcon Then
    DrawState DIS.hDC, 0, 0, ButtonPicture.Handle, 0, X, Y, CX, CY, DST_ICON

This would be great!
Great Controls and Thanks.

----------


## Krool

> The CommandButtonW with Style vbButtonGraphical does not support 32bpp Icon.
> The reason as far as I understand is the use of ButtonPicture.Render in the WindowProcUserControl WM_DRAWITEM.
> Is it possible to use the DrawState (like you do in case the Button is disabled and no DisabledPicture is provided)?
> Something like this should work (DSS_NORMAL = 0)
> ElseIf ButtonPicture.Type = vbPicTypeIcon Then
>     DrawState DIS.hDC, 0, 0, ButtonPicture.Handle, 0, X, Y, CX, CY, DST_ICON


Thanks for your post. The CommandButtonW/CheckBoxW/OptionButtonW controls can now render 32bpp alpha bitmaps and icons when Style property is set to 1 - vbButtonGraphical.

----------


## softv

Dear Krool,

Warm Greetings and Thanks as always for your invaluable controls.

Attachment 181706

*Case1:
*In the above picture (of a *coolbar* control with 2 bands), I need the space pointed to by the RED arrow to be of the same size as the space pointed to by the GREEN arrow.

*Case2:
*When the 'BandBorders' option is kept ticked, the same coolbar control appears as follows. Therein too, I do not need that much space (as pointed to by the RED arrow) between the control's edge and the band border. I just need the control in band 1 to fill that space leaving only a 1 pixel gap between the control and the band border (very similar to the way the control in the 2nd band leaves only a 1 pixel gap between its edge and the coolbar border).

May be by design, the spaces are so in the above cases. But, *is there any way at all* by which I can achieve what I want in the above cases? Case1 is the most important for me. Anyway, if it is achievable in both the cases, well and good. I presume if Case2 is achievable, Case1 will automatically be achieved (with 'BandBorders' option kept UNTICKED).

----------


## NilsB

Hi Krool,

thanks again for the 32bpp alpha bitmaps and icons support in the CommandButtonW.
I have another question: Can you add an option for DoubleBuffering to the CommandButtonW?
It flickers (again with Style vbButtonGraphical + Icon) sometimes - noticeable especially once there are a bunch of Buttons on a form.
A quick test (copying the double buffering code from another of your controls) solved the problem.
Maybe there is another way to prevent the flicker - I think it has to do with the way the picture/icon is drawn onto the control.

Thanks.

Addendum:
The TextboxW with MultiLine property set to true seem to have the same flicker problem.

Addendum 2:
This affects way more controls.
A Test with the CommandButtonW (vbButtonGraphical) with the ClipControls set to false seems to solve the problem too.

----------


## nello355

Hi Krool, thanks for your work.

I am using your coolbars and statusbars and wanted to report these issues.

1) Statusbar with multiple panels including one with Autosize = Content. During the Form_Load set panel.Text with a string that exceeds the initial prefixed space and the text is cut.
At the moment I solved with:



```
StatusBar1.Panels(2).Width = TextWidth(StatusBar1.Panels(2).Text) + 120
```

2) I'm using a krool coolbar with an MS toolbar inside. But when opening the property page (to set child) I don't see the MS toolbar.
But if I add a fake krool toolbar, I can now see the MS toolbar.

Attached project with Form1 for view the bug and Form2 with workaround patch.
Krool.zip

----------


## Krool

> I am using your coolbars and statusbars and wanted to report these issues.
> 
> 1) Statusbar with multiple panels including one with Autosize = Content. During the Form_Load set panel.Text with a string that exceeds the initial prefixed space and the text is cut.
> At the moment I solved with:
> 
> 
> 
> ```
> StatusBar1.Panels(2).Width = TextWidth(StatusBar1.Panels(2).Text) + 120
> ...


1) Update released. The problem was that the internal DisplayText was not immediately updated on setting a new panel.Text. (which is used for text measurement)
This got now fixed. (highlighted in blue)


```
Friend Property Let FPanelText(ByVal Index As Long, ByVal Value As String)
If StatusBarHandle <> 0 Then
    PropShadowPanels(Index).Text = Replace$(Value, vbTab, vbNullString)
    Call SetPanelText(Index)
    Call GetDisplayText(Index, PropShadowPanels(Index).DisplayText)
    If PropShadowPanels(Index).AutoSize = SbrPanelAutoSizeContent Then Call SetParts
End If
End Property
```

2) The MS ToolBar gives a "Property is write-only" error when accessing a 'Get' ControlEnum.hWnd. Which I don't understand yet..




> *Case1:
> *In the above picture (of a *coolbar* control with 2 bands), I need the space pointed to by the RED arrow to be of the same size as the space pointed to by the GREEN arrow.
> 
> *Case2:
> *When the 'BandBorders' option is kept ticked, the same coolbar control appears as follows. Therein too, I do not need that much space (as pointed to by the RED arrow) between the control's edge and the band border. I just need the control in band 1 to fill that space leaving only a 1 pixel gap between the control and the band border (very similar to the way the control in the 2nd band leaves only a 1 pixel gap between its edge and the coolbar border).
> 
> May be by design, the spaces are so in the above cases. But, *is there any way at all* by which I can achieve what I want in the above cases? Case1 is the most important for me. Anyway, if it is achievable in both the cases, well and good. I presume if Case2 is achievable, Case1 will automatically be achieved (with 'BandBorders' option kept UNTICKED).


I don't understand what you mean. Also the attachment isn't working..




> thanks again for the 32bpp alpha bitmaps and icons support in the CommandButtonW.
> I have another question: Can you add an option for DoubleBuffering to the CommandButtonW?
> It flickers (again with Style vbButtonGraphical + Icon) sometimes - noticeable especially once there are a bunch of Buttons on a form.
> A quick test (copying the double buffering code from another of your controls) solved the problem.
> Maybe there is another way to prevent the flicker - I think it has to do with the way the picture/icon is drawn onto the control.
> 
> Thanks.
> 
> Addendum:
> ...


The TextBoxW seems to be difficult to double-buffer. However, CommandButtonW/CheckBoxW/OptionButtonW (vbButtonGraphical) can be double-buffered.
VBCCR17 ought to be the last version. Perhaps I will just make them double-buffer someday without exposing a DoubleBuffer property..

----------


## Mith

Hey guys,

just want to let you know that i tested VBCCR17 with Windows 11 Pro Insider Preview 10.0.22000.51 (x64).

The control demo looks fine and my apps are running well too!

----------


## NilsB

Hi Krool,

another request from me:
The LabelW BorderStyle single does not work anymore as it uses UserControl.Line and in a recent optimization the DrawStyle changed to Transparent.

----------


## Krool

> another request from me:
> The LabelW BorderStyle single does not work anymore as it uses UserControl.Line and in a recent optimization the DrawStyle changed to Transparent.


Update released. Thanks !

----------


## xiaoyao

> Hi Krool,
> 
> another request from me:
> The LabelW BorderStyle single does not work anymore as it uses UserControl.Line and in a recent optimization the DrawStyle changed to Transparent.


Can it be transparent? If it can be placed on top of other controls, it is still convenient. I used a lot of effort to make listview and textbox. The transparent function still has a lot of bugs.

----------


## Krool

> Can it be transparent? If it can be placed on top of other controls, it is still convenient. I used a lot of effort to make listview and textbox. The transparent function still has a lot of bugs.


The .BackStyle can still be transparent..

----------


## NilsB

> Update released. Thanks !


Hi Krool,

I looked at the git commit. You did just set the LabelW DrawStyle back to vbSolid. So this uses an additional GDI handle for the pen effectively killing the optimization that introduced the problem.
You could actually have the best of both worlds as the DrawStyle can be set at runtime! I guess since most people use the label without any border at all you could just switch the DrawStyle to vbSolid
in case someone sets the BorderStyle to Single and leave it vbInvisible in the default case. Bit more code but maybe worth it!

Thanks

----------


## softv

Dear Krool,

It is time to say my *hearty thanks*,_once again_, for your matchless contribution to the society.

Well, I noticed a few things while using *Labels in** Coolbar*.


If I have only label controls (either intrinsic or yours) placed on a coolbar (e.g. cbr1), then the labels' captions do not show up. Borders, backcolor, etc. as well.When I open the 'Properties' window of cbr1 and try to add the labels to the bands, the dropdown does not list the labels.If I add a command button extra to cbr1, then the labels get listed in the dropdown (of cbr1's Bands tab) but their properties (caption, border, etc.) still do not show up even if I add them to any of the bands.Moreover, when I try to execute my app, presence of the labels in cbr1 leads to an *error* in the following code at the line "*Set .Child = .Child*". So, effectively, I am not able to use label controls in Coolbars.



```
Private Sub TimerInitChilds_Timer()Dim Count As LongCount = Me.Bands.CountIf Count > 0 Then    Dim i As Long    If CoolBarDesignMode = False Then        For i = 1 To Count            With Me.Bands(i)            Set .Child = .Child            'Throws ERROR in this line. Run-time error '380': Invalid property value            End With        Next i    Else        Dim RBBI As REBARBANDINFO        With RBBI        .cbSize = LenB(RBBI)        .fMask = RBBIM_CHILD        For i = 0 To Count - 1            .hWndChild = 0            SendMessage CoolBarHandle, RB_SETBANDINFO, i, ByVal VarPtr(RBBI)            .hWndChild = -1            SendMessage CoolBarHandle, RB_SETBANDINFO, i, ByVal VarPtr(RBBI)        Next i        End With        Call UserControl_Resize    End IfEnd IfTimerInitChilds.Enabled = FalseEnd Sub
```

Sorry if my above observations are wrong. Kindly let me know what mistake I am doing while adding the label controls to cbr1.

Kind regards.

----------


## Krool

> Hi Krool,
> 
> I looked at the git commit. You did just set the LabelW DrawStyle back to vbSolid. So this uses an additional GDI handle for the pen effectively killing the optimization that introduced the problem.
> You could actually have the best of both worlds as the DrawStyle can be set at runtime! I guess since most people use the label without any border at all you could just switch the DrawStyle to vbSolid
> in case someone sets the BorderStyle to Single and leave it vbInvisible in the default case. Bit more code but maybe worth it!
> 
> Thanks


Good idea. Didn't thought so far. When I have some time will do it.

----------


## Krool

> I looked at the git commit. You did just set the LabelW DrawStyle back to vbSolid. So this uses an additional GDI handle for the pen effectively killing the optimization that introduced the problem.
> You could actually have the best of both worlds as the DrawStyle can be set at runtime! I guess since most people use the label without any border at all you could just switch the DrawStyle to vbSolid
> in case someone sets the BorderStyle to Single and leave it vbInvisible in the default case. Bit more code but maybe worth it!


Done. Thanks




> Well, I noticed a few things while using *Labels in** Coolbar*.


There is a small bug that a Label can be listed in the property page when there is another valid control. I noted it down for next occasion to fix.
However, what I want to mention is that a Label is windowless and therefore can never be put "on another" control. Solution would be to embed such a Label in a PictureBox and have that as a child control.

----------


## Mith

VB6 SP6 & VBCCR17

hi krool,

i got a unexpected error message when using the imagelist (32bit, 48x48px) with Windows Vista or Windows 8:


At Windows 7 & 10 everything runs fine.

I have attached a test project created under Win7:



Any idea why the ImageList is not working at Vista & Win8 using the 32bit-icon with your ImageList?

----------


## Krool

> VB6 SP6 & VBCCR17
> 
> hi krool,
> 
> i got a unexpected error message when using the imagelist (32bit, 48x48px) with Windows Vista or Windows 8:
> 
> 
> At Windows 7 & 10 everything runs fine.
> 
> ...


On which OS you load the pictures (design time) ?

----------


## Mith

> On which OS you load the pictures (design time) ?


Windows 7. 

I also get no error message using the compiled exe of the sample project with Windows 10!

----------


## Krool

> Well, I noticed a few things while using *Labels in** Coolbar*.


Bug is fixed in PPCoolBarBands. It shouldn't list anymore "valid but windowless" controls. Now it lists only "valid with window handle".
Problem was that the internal window handle variable in the enumeration was not cleared.




> Windows 7. 
> 
> I also get no error message using the compiled exe of the sample project with Windows 10!


I use the OleLoadPicturePath to load Pictures at design time in the ImageList control.
From what I have read and have as memory as well :



> On Win7, it will error out with a 32-bit icon; but on Win10 it does not


So, can you test to have Windows 10 as design time loader ?

----------


## Erwin69

It's been a while since I came by.  Interesting reading up on what happend since.

At this point I have one new question:

My app dynamically applies translations to the captions of controls.  At app startup all values are stored in a collection that is defined in a class.  When a dialog is opened, for each control the translated caption is retrieved from the collection, and applied to the control.  This is done at Form_Load.

I noticed that one dialog, with 128 controls, seemed slow to open.  Investigating further, it turns out that applying the translations to the CCR controls takes 1 second, while applying it to the the original MS controls took 0.4 seconds.  Strangely enough there are another dialogs with 213, 136, and 129 controls that only take 0.8, 0.5, and 0.6 seconds to apply the translations.

The main difference between the dialogs seems to be the number of option buttons.

Am I missing some setting that causes delays?

----------


## Mith

> I use the OleLoadPicturePath to load Pictures at design time in the ImageList control.
> From what I have read and have as memory as well :
> 
> So, can you test to have Windows 10 as design time loader ?


Sorry, i can't, i don't have VB6 installed on Win10. I only use Win7 for VB6 development.

----------


## Mith

> My app dynamically applies translations to the captions of controls.  At app startup all values are stored in a collection that is defined in a class.  When a dialog is opened, for each control the translated caption is retrieved from the collection, and applied to the control.  This is done at Form_Load.


I do exactly the same with my apps.




> I noticed that one dialog, with 128 controls, seemed slow to open.


After reading your post i was curious and added a timer and counter to my translation function:

Translating 318 VBCCR17 controls (caption & tooltiptext) on a form at the form load event took "only" 2 seconds (2964 ticks from GetTickCount).
Loading the same form without using the translation function takes 2 seconds and "only" 2730 ticks.

Tested with VB6SP6 on Win7 running the app in the IDE.

Judging by my results it looks like the bottleneck doenst come from the VBCCR controls.

----------


## chrislong2

First, thank you so much for your work with these controls - much appreciated!

A few major bugs with the RichTextBox control:

1) It it is limited to 65k text!  It can load more than this but you cannot type any more (it will block you from typing any additional characters) and if you change scrollbar setting (to turn word wrap on/off) it will truncate to 65k text.  One of the major benefits of the original RTB control was that it was NOT limited to 65k text like the standard VB textbox.  This is a major showstopper for me.  This is easy to verify with your project - open a text file with more than 65k text in Notepad and then copy into the RTB and you'll see it cuts it off.

2) There is another major difference between this control and the VB OCX.  That relates to CRLF's in selected text and the related sel properties (especially selstart, sellength etc).  Internally RichText 2.0+ only use CR or LF (I can't remember which) but not both, unlike RichText 1.0 which internally stored as CRLF (vbwrap).  The problem is that this replacement RTB uses CRLF (as it should) for display and in relation to its Text property, but the sel properties only reference the LF (or CR) since that's what it internally stores as.  But this means that SelStart will be off by 1 for every wrap (CRLF) that exists prior to SelStart and that SelLength will be off by 1 for every wrap (CRLF) that exists in the selected text.  It also means that SelText only contains the LF (or CR) but not both.  This is easy to verify.  Create a "Copy" button on the form and put this for it's code: SetClipboardText RichTextBox1.SelText
and then open project and make the text have a blank line in between lines so there are 3 lines of text with a blank line between them. Select all 3 lines and click that copy button.  Paste into Notepad.  You'll see Notepad doesn't show the blank line because it only shows CRLF's and the SelText property only uses the LF without the CR (or vice-versa, I can't remember).  If you use the right-click Edit menu or press CTRL+C (not using the SelText code) and paste into Notepad you'll see it DOES show the blank line because SelText wasn't used.  If in that same project, you highlight only the 3rd line and check the SelStart number, it will be off by 1 compared to the exact same thing using the VB RichTextBox OCX.

----------


## Krool

> First, thank you so much for your work with these controls - much appreciated!
> 
> A few major bugs with the RichTextBox control:
> 
> 1) It it is limited to 65k text!  It can load more than this but you cannot type any more (it will block you from typing any additional characters) and if you change scrollbar setting (to turn word wrap on/off) it will truncate to 65k text.  One of the major benefits of the original RTB control was that it was NOT limited to 65k text like the standard VB textbox.  This is a major showstopper for me.  This is easy to verify with your project - open a text file with more than 65k text in Notepad and then copy into the RTB and you'll see it cuts it off.
> 
> 2) There is another major difference between this control and the VB OCX.  That relates to CRLF's in selected text and the related sel properties (especially selstart, sellength etc).  Internally RichText 2.0+ only use CR or LF (I can't remember which) but not both, unlike RichText 1.0 which internally stored as CRLF (vbwrap).  The problem is that this replacement RTB uses CRLF (as it should) for display and in relation to its Text property, but the sel properties only reference the LF (or CR) since that's what it internally stores as.  But this means that SelStart will be off by 1 for every wrap (CRLF) that exists prior to SelStart and that SelLength will be off by 1 for every wrap (CRLF) that exists in the selected text.  It also means that SelText only contains the LF (or CR) but not both.  This is easy to verify.  Create a "Copy" button on the form and put this for it's code: SetClipboardText RichTextBox1.SelText
> and then open project and make the text have a blank line in between lines so there are 3 lines of text with a blank line between them. Select all 3 lines and click that copy button.  Paste into Notepad.  You'll see Notepad doesn't show the blank line because it only shows CRLF's and the SelText property only uses the LF without the CR (or vice-versa, I can't remember).  If you use the right-click Edit menu or press CTRL+C (not using the SelText code) and paste into Notepad you'll see it DOES show the blank line because SelText wasn't used.  If in that same project, you highlight only the 3rd line and check the SelStart number, it will be off by 1 compared to the exact same thing using the VB RichTextBox OCX.


1)
The RTB initial limit is 32k. EM_EXLIMITTEXT will be called at creation with 0 (default) which sets the RTB limit to 65k.
So I would suggest you calc the length of your source and set it accordingly. Or just set an crazy high value.

2)
I know this quirk and have no idea how to solve. I need help in this.

----------


## chrislong2

> 1)
> The RTB initial limit is 32k. EM_EXLIMITTEXT will be called at creation with 0 (default) which sets the RTB limit to 65k.
> So I would suggest you calc the length of your source and set it accordingly. Or just set an crazy high value.
> 
> 2)
> I know this quirk and have no idea how to solve. I need help in this.


Thanks for the reply!  :Smilie:  
1) Ok, so I set MaxLength to a really high number and it works for the initial load of text (I can now type beyond 65k), however, as soon as I change scrollbars (to control word wrapping) or otherwise refresh the control, it loses the maxlength and goes back to 65k.  So there still seems to be a bug with how MaxLength is handled where it is not always honored.

2) Well, I've managed to work around it. You might want to consider doing something of similar approach in the control itself for the returned SelStart and SelLength vars so they are correct to begin with.  First, you have to ensure that there's no word wrapping going on so scrollbars to horizontal.  See specific code below, but in general I get the GetLineFromChar with SelStart to get all the wraps prior to SelStart. And then do another GetLineFromChar for the end of the SelLength + any found wraps, and then I subtract the first GetLineFromChar value from 2nd one to obtain the number of wraps for the selected text itself.  Here's how I'm currently working around it in my code:



```
    PreSelStartLineCounts = RichTextBox1.GetLineFromChar(RichTextBox1.SelStart + 1) - 1    
    SelTStartPos = RichTextBox1.SelStart + PreSelStartLineCounts
    SelTEndPos = RichTextBox1.SelStart + RichTextBox1.SelLength + PreSelStartLineCounts    
    LineCountsInclSel = RichTextBox1.GetLineFromChar(SelTEndPos) - 1
    If PreSelStartLineCounts > 0 Then
        InSelLineCounts = LineCountsInclSel - PreSelStartLineCounts
    Else
        InSelLineCounts = LineCountsInclSel
    End If
    SelTEndPos = SelTEndPos + InSelLineCounts
```

But I'll bet there's an easier way (I just have no idea what it is!)
EDIT: Also, this only addresses the SelStart & SelLength, but doesn't address SelText itself.  I don't know how to maybe fix SelText itself except to literally go through character by character looking for character 10 (LF) and inserting a character 13 (CR) before it (if I'm remembering right that the SelText is only doing LF's and not CR's, otherwise the opposite).

----------


## Niya

You know, I think it's common practice among most S tier production level software to virtualize a control's access to data when there's a lot of it. Basically, they never load all the data into the control at once. They only take a view of the data that covers what is being displayed to the user and little before and after what is displayed. Older versions of SQL Server Management Studio did this when ever you displayed all data in a table and there's a lot of it. I seriously doubt that Word, Excel or PDF viewers try to load all the data at once whenever they encounter freakishly large documents.

If your program is loading documents so large that they are overwhelming standard controls, it might be time to take a page out of their book and think about some kind of paging system to load the data as needed.

----------


## chrislong2

> You know, I think it's common practice among most S tier production level software to virtualize a control's access to data when there's a lot of it. Basically, they never load all the data into the control at once. They only take a view of the data that covers what is being displayed to the user and little before and after what is displayed. Older versions of SQL Server Management Studio did this when ever you displayed all data in a table and there's a lot of it. I seriously doubt that Word, Excel or PDF viewers try to load all the data at once whenever they encounter freakishly large documents.
> 
> If your program is loading documents so large that they are overwhelming standard controls, it might be time to take a page out of their book and think about some kind of paging system to load the data as needed.


I appreciate that, but 65kb isn't all that large at all (I have several text documents over that), and yes, many programs including Notepad do try to load it all at once.  In any event with my program a paging system isn't really an option and in this case the issue is that the RTB replacement does not work correctly with >65k whereas the 90's era OCX does.

----------


## Niya

I've seen Notepad buckle under the weight of large documents. They just have a much higher tolerance than 65 KB. Whenever that happens to me, I just load the document in Wordpad which can easily handle a document of any size.

My point is, when your application starts falling apart like that over large documents, it might be time to roll up your sleeves and try some kind of do-it-yourself work around. I don't think MS put much thought into designing standard controls for developers to handle large data sets like that, even as small as 65 K. At least not in the days of VB6.

----------


## chrislong2

Yeah, I've seen notepad buckle under large docs too, but not usually till you get to many MB's.  65K is a small amount.  But I agree with your overall point.

Anyway, it's fine.  In line with what Krool pointed to, I've modified the RTB to just change the StreamStringIn and StreamFileIn functions to call EM_EXLIMITTEXT with PropMaxLength instead of 0 and it works fine now.  That really I think is the way it should be anyway as it should always be using the PropMaxLength value (if a value is not set, then it will default to 0 anyway so it should just call it with PropMaxLength instead of a hardcoded 0 val).  Then if anyone cares about >65k, they can just set the PropMaxLength to whatever they want.  I would argue that PropMaxLength should even be set by default to a much higher value (like 1MB).  I just tested and 1MB file was opened quick and worked with quickly on my 10yo machine.  I tried a 30MB file and that also worked but was much more sluggish a la what Notepad does.

----------


## Niya

> Anyway, it's fine.  In line with what Krool pointed to, I've modified the RTB to just change the StreamStringIn and StreamFileIn functions to call EM_EXLIMITTEXT with PropMaxLength instead of 0 and it works fine now.


The developers of Notepad probably did something similar. Would have been nice if Controls came out of the box with these things set. Oh well. World isn't perfect.

----------


## Krool

> 1) Ok, so I set MaxLength to a really high number and it works for the initial load of text (I can now type beyond 65k), however, as soon as I change scrollbars (to control word wrapping) or otherwise refresh the control, it loses the maxlength and goes back to 65k.  So there still seems to be a bug with how MaxLength is handled where it is not always honored.


I cannot replicate this bug. Can you provide a demo ?




> Anyway, it's fine.  In line with what Krool pointed to, I've modified the RTB to just change the StreamStringIn and StreamFileIn functions to call EM_EXLIMITTEXT with PropMaxLength instead of 0 and it works fine now.  That really I think is the way it should be anyway as it should always be using the PropMaxLength value (if a value is not set, then it will default to 0 anyway so it should just call it with PropMaxLength instead of a hardcoded 0 val).  Then if anyone cares about >65k, they can just set the PropMaxLength to whatever they want.  I would argue that PropMaxLength should even be set by default to a much higher value (like 1MB).  I just tested and 1MB file was opened quick and worked with quickly on my 10yo machine.  I tried a 30MB file and that also worked but was much more sluggish a la what Notepad does.


Your true. I don't know why I added those hardcoded 0&. And also calling twice on StreamFileIn.

Can you make a test and just remove all those red lines in the code and test if everything is OK ? If you report success I will initiate an update. Thanks



```
Private Function StreamStringIn(ByVal Value As String, ByVal Flags As Long) As Long
If RichTextBoxHandle <> 0 Then
[...]
    If (Flags And SF_RTF) <> 0 Then SendMessage RichTextBoxHandle, EM_EXLIMITTEXT, 0, ByVal 0&
    StreamStringIn = SendMessage(RichTextBoxHandle, EM_STREAMIN, Flags, ByVal VarPtr(REEDSTR))
    If (Flags And SF_RTF) <> 0 Then SendMessage RichTextBoxHandle, EM_EXLIMITTEXT, 0, ByVal PropMaxLength
    Call RtfStreamStringInCleanUp
End If
End Function

Private Function StreamFileIn(ByVal FileName As String, ByVal Flags As Long) As Long
If RichTextBoxHandle <> 0 Then
[...]
        If (Flags And SF_RTF) <> 0 Then SendMessage RichTextBoxHandle, EM_EXLIMITTEXT, 0, ByVal 0&
        StreamFileIn = SendMessage(RichTextBoxHandle, EM_STREAMIN, Flags, ByVal VarPtr(REEDSTR))
        If (Flags And SF_RTF) <> 0 Then SendMessage RichTextBoxHandle, EM_EXLIMITTEXT, 0, ByVal 0&
        CloseHandle hFile
    End If
End If
End Function
```

----------


## Krool

Update released.

Removal of EM_EXLIMITTEXT (Flags = SF_RTF) in internal StreamStringIn/StreamFileIn in the RichTextBox control.
It was probably put there by error or by misunderstanding of the MSDN documentation.

I could not find any reason why it should be in that function... strange.. However, now it's erased..

----------


## Mith

> Update released.


I tested the new update (.25) of the RichTextBox control with text files in several sizes using this code:



```
10 rtfTest.LoadFile sFilePath, RtfLoadSaveFormatText
20 rtfTest.SelStart = 0
30 rtfTest.SelLength = Len(rtfTest.Text)
40 rtfTest.SelColor = vbBlack
50 rtfTest.SelLength = 0
```

14,6 MB -> OK
17,2 MB -> OK
20,0 MB -> OK
32,0 MB -> OK
68,0 MB -> loading ok, but "no memory" error at line 30

after removing line 20 to 50 everything is working well:

109 MB -> OK
172 MB -> OK

Loading the files is very fast.
Should i use the command .clear before loading a file to reset the current style of the RTB?

----------


## Krool

> I tested the new update (.25) of the RichTextBox control with text files in several sizes using this code:
> 
> 
> 
> ```
> 10 rtfTest.LoadFile sFilePath, RtfLoadSaveFormatText
> 20 rtfTest.SelStart = 0
> 30 rtfTest.SelLength = Len(rtfTest.Text)
> 40 rtfTest.SelColor = vbBlack
> ...


Retrieving the Text makes again an stream out. And when you do it in the IDE the memory limit is quickly hit.

Better is just to extract the length, e.g.


```
Dim Length As Long, REGTLEX As REGETTEXTLENGTHEX
REGTLEX.Flags = GTL_PRECISE Or GTL_NUMCHARS
REGTLEX.CodePage = CP_UNICODE
Length = SendMessage(RichTextBoxHandle, EM_GETTEXTLENGTHEX, VarPtr(REGTLEX), ByVal 0&)
```

----------


## Mith

> Retrieving the Text makes again an stream out. And when you do it in the IDE the memory limit is quickly hit.
> 
> Better is just to extract the length, e.g.
> 
> 
> ```
> Dim Length As Long, REGTLEX As REGETTEXTLENGTHEX
> REGTLEX.Flags = GTL_PRECISE Or GTL_NUMCHARS
> REGTLEX.CodePage = CP_UNICODE
> ...


Thanks for the feedback!

How about we add a new function called GetTextLength to the RTB control?

----------


## xiaoyao

SOME TIMES ,I ONLY NEED TextboxW CONTROL,IT'S maked 210kb
TextboxW.OCX

only use listview control,it's used 1MB
VBCCR16.OCX 5mb size

The overall volume of an OCX is a bit larger. It is very difficult to disassemble the various controls to reduce the size of the compiled EXE.

----------


## softv

> Bug is fixed in PPCoolBarBands. It shouldn't list anymore "valid but windowless" controls. Now it lists only "valid with window handle".
> Problem was that the internal window handle variable in the enumeration was not cleared. ... .. .


Thanks a TON for the update. And, once again, thanks a TON for your beautiful and immensely beneficial controls.

One observation, my dear krool, *regarding CoolBars*.

Inside any Band of a CoolBar control:
--
Case 1. If I have a FrameW in the Band and if I place a normal Label or LabelW(yours) *inside* that* FrameW*, the *labels do not display their ToolTipText*. 

Case 2. If  I have a Frame or Picture in the band and if I place a normal Label or LabelW(yours) inside that Picture/Frame, the labels do display their ToolTipText. No issues.
--

If my observation in Case 1 is correct, then, what should I do to have the ToolTipText get displayed by Label and LabelW in Case 1.
If my observation in Case 1 is incorrect, then, what mistake am I doing? Kindly guide me.

Kind regards.

----------


## Krool

> Thanks a TON for the update. And, once again, thanks a TON for your beautiful and immensely beneficial controls.
> 
> One observation, my dear krool, *regarding CoolBars*.
> 
> Inside any Band of a CoolBar control:
> --
> Case 1. If I have a FrameW in the Band and if I place a normal Label or LabelW(yours) *inside* that* FrameW*, the *labels do not display their ToolTipText*. 
> 
> Case 2. If  I have a Frame or Picture in the band and if I place a normal Label or LabelW(yours) inside that Picture/Frame, the labels do display their ToolTipText. No issues.
> ...


Looks for me like a VB6 bug in the FrameW control, which is an ordinary ControlContainer UserControl. It does not recognize the ToolTipText from windowless contained controls.
I don't know how to fix.

----------


## softv

> 1)
> The RTB initial limit is 32k. EM_EXLIMITTEXT will be called at creation with 0 (default) which sets the RTB limit to 65k.
> So I would suggest you calc the length of your source and set it accordingly. Or just set an crazy high value.
> 
> 2)
> I know this quirk and have no idea how to solve. I need help in this.


Krool had written to me on the above as early as *2017* itself. Since that time, I have been waiting to see whether anyone can come with a solution for the quirk mentioned in the 2nd point.

Anyway, based on Krool's valuable advice (as in his 1st point), I always remember to set my *RichTextBox* controls' MaxLength to 2147483647 (the maximum limit) so that I do not ever need to worry about the text length limits of my RichTextBoxes. I also set the ScrollBar to Vertical (in order to address one issue, which I am not able to recall, as of now).

And, reg. the 2nd point, after writing very many lines of code of my own, to somehow take care of the issues related to vbCrLf (but eventually unable to take care of the issues 100% correctly), I finally decided to drop all those lines of code and just do the following alone so that I need not have to worry about those vbCrLF-related issues at all ever after. What I did was:

In the function "Private Function *StreamStringOut*(ByRef Value As String, ByVal Flags As Long) As Long", I made the following changes
--
'''''Value = StrConv(RtfStreamStringOut(), vbUnicode) 
Value = Replace$(StrConv(RtfStreamStringOut(), vbUnicode), vbCrLf, vbCr)


'''''Value = RtfStreamStringOut()
Value = Replace$(RtfStreamStringOut(), vbCrLf, vbCr)
--

In other words, in the abovementioned function, I commented out two lines (as shown above) and replaced them with my own lines (as above). In effect, *I just replaced all vbCrLf with vbCr*. For my freeware's requirements, dealing with VbCr alone was not any big problem. So, with the above changes, for the past 4 years, the vbCrLf-related issues are not present.

Just thought of sharing the above info so that it is of help to someone. Nothing else.

Thanks Krool once again, for your monumental efforts and such a stupendous service to the world society.

Kind Regards.

----------


## softv

Thanks a TON for your prompt reply, Krool. At present, as a workaround, I am placing the Labels again inside another Picture or Frame control (normal one).

Kind Regards.

----------


## softv

> ... .. . In other words, in the abovementioned function, I commented out two lines (as shown above) and replaced them with my own lines (as above). In effect, *I just replaced all vbCrLf with vbCr*. For my freeware's requirements, dealing with VbCr alone was not any big problem. So, with the above changes, for the past 4 years, the vbCrLf-related issues are not present. ... .. .


In connection with the experience I have shared above, I was just wondering whether a new property can be added to the RichTextBox control (say, "*Only vbCr*") so that based on its value, you can include my lines of code too in the *StreamStringOut* function. Thanks, Krool.

Kind Regards.

----------


## chrislong2

Hi Krool,

Sorry for the late reply.  

1) Tes, I can confirm that the Aug 10th update fixes the amount of text allowed issues (including where changing scrollbars would reset).

2) Regarding the internal only CR's, it's just a giant pain - it irritates me to no end that MS made that change starting with RichEdit 2.0 without considering the ramifications of doing so.  Anyway I've worked around it (in a different way to softv but similar idea - I just did the reverse where I kept the control as-is but created a string copy of the text with only CR's to use for figuring things out.  Horribly inefficient but the easiest way for me to deal with with my particular situation.  I do think having an option like softv mentions could be helpful.

3) I have a new 3rd issue for you.  The margin settings are set incorrectly in the CreatePrintJob sub.

The code you have as:



```
    
 .Left = PhysOffsetCX + LeftMargin
 .Right = PhysOffsetCX + PhysCX - RightMargin
 .Top = PhysOffsetCY + TopMargin
 .Bottom = PhysOffsetCY + PhysCY - BottomMargin
```

should instead be



```
    If (LeftMargin - PhysOffsetCX) > 0 Then
        .Left = LeftMargin - PhysOffsetCX
    Else
        .Left = PhysOffsetCX
    End If
    If (RightMargin - PhysOffsetCX) > 0 Then
        .Right = (PhysCX - .Left) - (RightMargin - PhysOffsetCX)
    Else
        .Right = (PhysCX - .Left) - PhysOffsetCX
    End If
    If (TopMargin - PhysOffsetCY) > 0 Then
        .Top = TopMargin - PhysOffsetCY
    Else
        .Top = PhysOffsetCY
    End If
    If (BottomMargin - PhysOffsetCY) > 0 Then
        '.Bottom = (PhysCY - .Top) - (BottomMargin - PhysOffsetCY)
        .Bottom = PhysCY - (BottomMargin - PhysOffsetCY)
    Else
        '.Bottom = (PhysCY - .Top) - PhysOffsetCY
        .Bottom = PhysCY - PhysOffsetCY
    End If
```

The bottom one SHOULD be the commented out lines in theory I believe where .top is subtracted also, but in practice there must be some other issue going on with the PhysCY or PhysOffsetCY that doesn't also happen with PhysCX or PhysOffsetCX because subtracting the top offset (margin) doesn't work like it does for the right offset and is only correct when NOT subtracting the top offset.

In any event, the original margin calculations were incorrect and resulted in noticeably wrong printed margins.

Thanks again for all your hard work with these!  :Smilie:

----------


## Mith

VBCCR 1.7.25

I use the ListView control (report mode) with 6 columns and need to detect double clicks on ListSubItems.

I can do this with the function "HitTest" but all the DblClick-events dont provide the necessary X/Y coordinates for the HitTest-function.

Can you add the missing X/Y coordinates to all DblClick-events?

----------


## Krool

> VBCCR 1.7.25
> 
> I use the ListView control (report mode) with 6 columns and need to detect double clicks on ListSubItems.
> 
> I can do this with the function "HitTest" but all the DblClick-events dont provide the necessary X/Y coordinates for the HitTest-function.
> 
> Can you add the missing X/Y coordinates to all DblClick-events?


I can't due to compatibility. But it's easy doable as below code.



```
Private Declare Function GetMessagePos Lib "user32" () As Long

Dim Pos As Long
Pos = GetMessagePos()

Debug.Print Get_X_lParam(Pos) & "/" & Get_Y_lParam(Pos)

Public Function Get_X_lParam(ByVal lParam As Long) As Long
Get_X_lParam = lParam And &H7FFF&
If lParam And &H8000& Then Get_X_lParam = Get_X_lParam Or &HFFFF8000
End Function

Public Function Get_Y_lParam(ByVal lParam As Long) As Long
Get_Y_lParam = (lParam And &H7FFF0000) \ &H10000
If lParam And &H80000000 Then Get_Y_lParam = Get_Y_lParam Or &HFFFF8000
End Function
```

----------


## Mith

> I can't due to compatibility. But it's easy doable as below code.
> 
> 
> 
> ```
> ...
> ```


Your code doesnt work for me. The X/Y coordinates are always wrong.

I use now the APIs GetCursorPos & ScreenToClient to get the correct X/Y coordinates!

----------


## Krool

> Your code doesnt work for me. The X/Y coordinates are always wrong.
> 
> I use now the APIs GetCursorPos & ScreenToClient to get the correct X/Y coordinates!


It's in pixel and already in client coords.

----------


## Mith

> It's in pixel and already in client coords.


Yes, its in pixel, same as GetCursorPos.
But the X/Y-coordinates are wrong after multiplying the return values from your function with Screen.TwipsPerPixelX/Y.
I only get the correct X/Y-coordinates using GetCursorPos & ScreenToClient & multiplying with Screen.TwipsPerPixelX/Y.

----------


## Krool

> 3) I have a new 3rd issue for you.  The margin settings are set incorrectly in the CreatePrintJob sub.
> 
> The code you have as:
> 
> 
> 
> ```
>     
>  .Left = PhysOffsetCX + LeftMargin
> ...


Thanks for this report.
I checked this topic and come to following formula which works on my end. Can you confirm ?



```
.Left = LeftMargin - PhysOffsetCX
.Top = TopMargin - PhysOffsetCY
.Right = (PhysCX - RightMargin) + PhysOffsetCX
.Bottom = (PhysCY - BottomMargin) + PhysOffsetCY
```

----------


## Krool

Update released.

Bugfix for RichTextBox done concerning wrong calculated margins in the internal CreatePrintJob method.

----------


## chrislong2

Hi Krool,

Thanks!  I am sorry for late response and I see you issued an update.  Okay, first things first.  In testing again today, I see that I made a stupid mistake when I was previously testing.  I was actually feeding the sub swapped right and top values.  So my assertion before that it was "wildly off" wasn't quite right - it was "wildly off" because I was stupid. lol

However, the old code still was not correct.  My replacement code above also was not correct - the .Right calculations in my code was wrong.

Your new code is better, but I think there is still a mistake in the .Right and .Bottom.  I believe you should be subtracting the PhysOffsetCX and PhysOffsetCY instead of adding them.

In other words it should now be:



```
    .Left = LeftMargin - PhysOffsetCX
    .Top = TopMargin - PhysOffsetCY
    .Right = (PhysCX - RightMargin) - PhysOffsetCX
    .Bottom = (PhysCY - BottomMargin) - PhysOffsetCY
```

This is basically the way my old code that I've used for years was doing it.

Note however that this code does not take into account either if the margins are less than the offsets or if the margins are not specified.  I've seen printers that have .5 inch offsets (or a little less but you get the idea).  This code would fail on that if they specified a margin say of .30 inches because it would give a negative number.  That is why I did the If/Then's.  It's not pretty, but it solves this problem.  I also think you should not be setting the default values to 0.  If margins aren't specified (they are optional in PrintDoc) then it's almost guaranteed not to be right.  Taking everything together, I believe something like the following is probably best:



```
    With .RC
    If (LeftMargin - PhysOffsetCX) > 0 Then 
         .Left = LeftMargin - PhysOffsetCX
    Else
         .Left = PhysOffsetCX
    End If
    If (TopMargin - PhysOffsetCY) > 0 Then 
         .Top = TopMargin - PhysOffsetCY
    Else
         .Top = PhysOffsetCY
    End If
    If (RightMargin - PhysOffsetCX) > 0 Then 
         .Right = (PhysCX - RightMargin) - PhysOffsetCX
    Else
         .Right = PhysCX - PhysOffsetCX
    End If
    If (BottomMargin - PhysOffsetCY) > 0 Then 
         .Bottom = (PhysCY - BottomMargin) - PhysOffsetCY
    Else
         .Bottom = PhysCY - PhysOffsetCY
    End If
    End With
```

This only sets based on the margins if the margins that were set are greater than the offsets, otherwise or if no margins were set at all, will set a default.  

Thanks again for all your work with all of these!!  :Smilie:   I appreciate you!  This stuff gets complicated and I think there was some wrong MS documentation/examples on this margin stuff too.

[Edit: Updated to fix a silly mistake in my code where I originally was setting default values for RCPage and not RC]

----------


## Krool

> Hi Krool,
> 
> Thanks!  I am sorry for late response and I see you issued an update.  Okay, first things first.  In testing again today, I see that I made a stupid mistake when I was previously testing.  I was actually feeding the sub swapped right and top values.  So my assertion before that it was "wildly off" wasn't quite right - it was "wildly off" because I was stupid. lol
> 
> However, the old code still was not correct.  My replacement code above also was not correct - the .Right calculations in my code was wrong.
> 
> Your new code is better, but I think there is still a mistake in the .Right and .Bottom.  I believe you should be subtracting the PhysOffsetCX and PhysOffsetCY instead of adding them.
> 
> In other words it should now be:
> ...


According to MS (https://docs.microsoft.com/en-us/win...-edit-controls) the cxPhysOffset/cyPhysOffset is added for right/bottom. (thus correct with my new code)
(keeping aside the extra margins which are ignored by MS, but for the principle)



```
// Set the rendering rectangle to the pintable area of the page.
fr.rc.left   = cxPhysOffset;
fr.rc.right  = cxPhysOffset + cxPhys;
fr.rc.top    = cyPhysOffset;
fr.rc.bottom = cyPhysOffset + cyPhys;
```

----------


## NilsB

Hi Krool,

I found a problem with the FrameW control. The Caption font is not rendered properly if the application runs with GDIScaling.
This is most notable if one uses a TrueType font as the ClearType/AntiAliasing is not working.
I was able to narrow the problem down to the way the FrameW uses its Picture property in the DrawFrame function:
.Cls
Set .Picture = Nothing
...
Set .Picture = .Image
Interestingly the font is smooth if the DrawText API is used instead of the DrawThemeText version.
I have a small test project in case you have a Windows 10 maschine...

Also I think there are some control which leak FontHandles. The following handles are not deleted on UserControl_Terminate:
DTPickerCalendarFontHandle
LinkLabelUnderlineFontHandle
ProgressBarFontHandle

Is it possible to maybe cache fonts? As far as I understand each call to CreateGDIFontFromOLEFont creates a new font handle...
Its not terrible but its the last place where you "waste" GID Handles.
I think most people are using more controls than they use different fonts.
But again most probably not worth any effort  :Smilie: 

Thank you very much and keep up the good work

----------


## Krool

> Also I think there are some control which leak FontHandles. The following handles are not deleted on UserControl_Terminate:
> DTPickerCalendarFontHandle
> LinkLabelUnderlineFontHandle
> ProgressBarFontHandle
> 
> Is it possible to maybe cache fonts? As far as I understand each call to CreateGDIFontFromOLEFont creates a new font handle...
> Its not terrible but its the last place where you "waste" GID Handles.


Hello, Thank!
I fixed the 3 GDI leaks. It is not a good idea to cache IFont objects as the underlying hFont is not stable. Thus I need to create new font handle which is stable and can be passed to the controls.

----------


## chrislong2

> According to MS (https://docs.microsoft.com/en-us/win...-edit-controls) the cxPhysOffset/cyPhysOffset is added for right/bottom. (thus correct with my new code)[/CODE]


I understand and certainly MS is certainly the ones to generally follow for guidance, but I've seen that code before and I'm almost certain it is wrong.  Adding the physical width offset to the physical width for a right margin means they are saying the printing extends into the offset area that the printer can't print.  That code from MS basically says that the place to stop printing on the right is equal to the entire width PLUS the offset that the printer can't print.  That's wrong - it should be subtracted from it in saying that the place to stop printing on the right is physical width (which includes the offset area) MINUS the offset so that the total area to print is only the part the printer can actually print in.  Further, their code there is horrible anyway because it doesn't even take into account any margin area at all.  Whoever coded that whipped that up but certainly weren't using it to actually print anything - it looks to me like a theoretical piece of code someone threw together but they certainly never used it to actually print anything.   I just double-checked and the code I used for 20+ years has the offset subtracted and not added and in those 20 years I never heard anyone tell me of any printing issues.  So I'm pretty sure it is supposed to be subtracted.  These days, because many printers have pretty small offsets, it's probably not a huge deal either way, but I think the correct mode is to subtract.  Microsoft failed.  I wish they hadn't removed all their comments they used to have on their pages some years back because many times people would comment the flaws with their api or example code and those could be helpful in situations like this.

----------


## Krool

> I understand and certainly MS is certainly the ones to generally follow for guidance, but I've seen that code before and I'm almost certain it is wrong.  Adding the physical width offset to the physical width for a right margin means they are saying the printing extends into the offset area that the printer can't print.  That code from MS basically says that the place to stop printing on the right is equal to the entire width PLUS the offset that the printer can't print.  That's wrong - it should be subtracted from it in saying that the place to stop printing on the right is physical width (which includes the offset area) MINUS the offset so that the total area to print is only the part the printer can actually print in.  Further, their code there is horrible anyway because it doesn't even take into account any margin area at all.  Whoever coded that whipped that up but certainly weren't using it to actually print anything - it looks to me like a theoretical piece of code someone threw together but they certainly never used it to actually print anything.   I just double-checked and the code I used for 20+ years has the offset subtracted and not added and in those 20 years I never heard anyone tell me of any printing issues.  So I'm pretty sure it is supposed to be subtracted.  These days, because many printers have pretty small offsets, it's probably not a huge deal either way, but I think the correct mode is to subtract.  Microsoft failed.  I wish they hadn't removed all their comments they used to have on their pages some years back because many times people would comment the flaws with their api or example code and those could be helpful in situations like this.


explanation would be maybe that the viewport of the printer is not 0, 0. I saw some code where it actually get substracted.


```
// offset by printing offset
printDC.SetViewportOrg (-printDC.GetDeviceCaps (PHYSICALOFFSETX),
-printDC.GetDeviceCaps (PHYSICALOFFSETY));
```

Maybe that's why in the ms doc it's added at right/bottom ?

----------


## chrislong2

Hmm, maybe, tho I wonder why anyone would want to do that.

----------


## NilsB

Hi Krool,

do you have any news on the GDIScaling problem of the FrameW?
I do understand you call Set .Picture = .Image because of the transparency of the frame.
But is it not enough to call a simple Refresh to update the persistent graphics as AutoRedraw = true?
Problem is that the GDI Scaler rescales the persistent graphics. I attached screenshots taken at 144 DPI.

Setting the picture:
Attachment 182284

Calling refresh:
Attachment 182285

Any help would be greatly appreciated

----------


## vbLewis

Hi Krool,

Ive been using the RichTextBox from ActiveX control Version 1.7. (win 10 64 bit)
 In the MS version of rtb i could set


```
rtb.selstart = Len(rtb.text)
```

and then compare equal would be true


```
If rtb.SelStart = Len(rtb.Text) Then  '<-- = True
```

however, with this rtb its behavior is different from
the MS version.

Ive done some investigating and it appears the Len(rtb.Text) includes CR-LF per line in length
but rtb.SelStart doesnt not include calculations for CR-LF line endings.
Below is a screenshot showing results of test. Would it be possible to get the same behavior as MS control?
Regards,
Lewis

(not sure why its so small)
here is link to image: https://imgur.com/a/eFrOmRB

----------


## Krool

> Hi Krool,
> 
> Ive been using the RichTextBox from ActiveX control Version 1.7. (win 10 64 bit)
>  In the MS version of rtb i could set
> 
> 
> ```
> rtb.selstart = Len(rtb.text)
> ```
> ...


I hate this quirk and it was discussed several times already.

So, to sum up. We have SelStart and SelLength and SelText (using the EM_GETSELTEXT, rich edit message only) all ignoring CR-LF and just uses CR.
The only "annyoing" part is the Text property which will use EM_STREAMOUT. And this EM_STREAMOUT put out CR-LF.
So, I could "fix" the Text property by using EM_GETTEXTEX which only returns CR (unless GT_USECRLF is used).

However, additional quirk is that EM_STREAMOUT does not output "hidden" text. This could be fixed additionally by using GT_NOHIDDENTEXT flag. (but this exists only as of rich edit version 4, thus leaving 2 and 3 in the dark...)

So, all in all it's a shame...
Or I replace all CR-LF to CR only within EM_STREAMOUT.. However, this would be an additional memory allocation exchange for the text.

Edit: the MS rtb uses the v1 which uses CR+LF internally.

----------


## vbLewis

> I hate this quirk and it was discussed several times already.
> 
> So, to sum up. We have SelStart and SelLength and SelText (using the EM_GETSELTEXT, rich edit message only) all ignoring CR-LF and just uses CR.
> The only "annyoing" part is the Text property which will use EM_STREAMOUT. And this EM_STREAMOUT put out CR-LF.
> So, I could "fix" the Text property by using EM_GETTEXTEX which only returns CR (unless GT_USECRLF is used).
> 
> However, additional quirk is that EM_STREAMOUT does not output "hidden" text. This could be fixed additionally by using GT_NOHIDDENTEXT flag. (but this exists only as of rich edit version 4, thus leaving 2 and 3 in the dark...)
> 
> So, all in all it's a shame...
> ...


Hi Krool,
Thanks for your reply. Sorry I wasnt aware others had brought it up already, I thought I was reporting a good bug LOL. Its fine if the behavior is an unintended consequence of upgrading to new api. 
I Fixed my problem by using API to get Text length to compare to SelStart and it works very well.

Maybe a non-standard function like .GetTextLength(optional param,optional param) would be a solution?

regards,
lewis

----------


## Krool

Ok, so EM_STREAMOUT will not respect hidden text on richedit20.dll.
Upon Msftedit.dll it will exclude hidden text, that's why introduced GT_NOHIDDENTEXT.

However, it is not possible to calculate via EM_GETTEXTLENGTHEX w/o hidden text as no flag exists...

So, my conclusion will then be to not bother with GT_NOHIDDENTEXT, so that a potential new Text property will be equal with a new TextLength property..

----------


## vbLewis

Krool Thanks for your insight, sorry to bother you again but this just may be something Im doing wrong....

In the event LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)
I cant seem to get the hyperlink from text using LinkStart and LinkEnd.

Private Sub rtb_LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)

    Dim Link As String

    If wMsg = 514 And wParam = 0 Then
           Link = Mid$(rtb.Text, LinkStart, (LinkEnd + 1) - LinkStart)
    End If
End Sub


The return value 'Link' is something from a random place in the text and not even close to a hyperlink.
Is this something Im doing wrong or is it maybe related to the hidden text problem?
Regards,
Lewis

----------


## Krool

> Krool Thanks for your insight, sorry to bother you again but this just may be something Im doing wrong....
> 
> In the event LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)
> I cant seem to get the hyperlink from text using LinkStart and LinkEnd.
> 
> Private Sub rtb_LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)
> 
>     Dim Link As String
> 
> ...


LinkStart/LinkEnd is a CharRange. Try using EM_GETTEXTRANGE.

I tested it with sample text and the Mid$(rtb.Text, LinkStart, (LinkEnd + 1) - LinkStart) worked. So can you provide full test sample to replicate issue ?

----------


## Krool

Update released.

Finally fixed the mismatch of the RichTextBox Text property concerning CrLf and the internal Cr only.
The RichTextBox control now uses EM_GETTEXTEX/EM_SETTEXTEX instead of EM_STREAMOUT/EM_STREAMIN for the Text property.
Included the UseCrLf property to control whether or not to apply GT_USECRLF/GTL_USECRLF on EM_GETTEXTEX.
It defaults to False and thus makes a compatibility break to the previous VBCCR which used EM_STREAMOUT (always CrLf)

Also included the TextLength property in the TextBoxW and RichTextBox control to conveniently get the length of text w/o the need of allocating memory for the Text. (like in .net)

The OCX VBCCR17 was also updated. The internal type lib version is now 1.1.


```
Object={7020C36F-09FC-41FE-B822-CDE6FBB321EB}#1.1#0; VBCCR17.OCX
```

----------


## vbLewis

Hi,

Here is a sample project that reproduces the error for me. the screenshot shows the result above after clicking the highlighted link.

----------


## Mith

> Hi,
> Here is a sample project that reproduces the error for me. the screenshot shows the result above after clicking the highlighted link.


Here is the solution for your problem:





```
Option Explicit

Private Const WM_USER = &H400
Private Const EM_GETTEXTRANGE = (WM_USER + 75)

Private Declare Function SendMessageW Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Type CHARRANGE
    cpMin As Long
    cpMax As Long
End Type
 
Private Type TEXTRANGE
    chrg As CHARRANGE
    lpstrText As String
End Type
 
Private Type SETTEXTEX
    flags As Long
    codepage As Integer
End Type


Private Sub Form_Load()
   rtb.LoadFile App.Path & "\test.rtf", RtfLoadSaveFormatRTF, False
   rtb.SelStart = 3500
   rtb.ScrollToCaret
'   Me.Show
'   DoEvents
'   MsgBox "click on nightbot links", vbInformation
End Sub

Private Sub rtb_LinkEvent(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal LinkStart As Long, ByVal LinkEnd As Long)
    If wMsg = 514 And wParam = 0 Then
        lblLink.Caption = GetLinkText(LinkStart, LinkEnd)
    End If
End Sub

Private Function GetLinkText(ByVal LinkStart As Long, ByVal LinkEnd As Long) As String
    Dim tdCharRange As CHARRANGE
    Dim tdTextRange As TEXTRANGE
    
    tdCharRange.cpMin = LinkStart
    tdCharRange.cpMax = LinkEnd
    
    tdTextRange.chrg = tdCharRange
    tdTextRange.lpstrText = Space$(256)
    
    Call SendMessageW(rtb.hWnd, EM_GETTEXTRANGE, 0&, ByVal tdTextRange)
    GetLinkText = tdTextRange.lpstrText
    
End Function
```

----------


## vbLewis

> Here is the solution for your problem:
> 
> 
> 
> 
> 
> ```
> Option Explicit
> 
> ...


Mith, thank you so much! 

just curious... Is that return text a C string or a com allocated string? wondering if sysallocatestring should be used on it?
Edit: nevermind i see you allocated it with space()

----------


## Mith

> Mith, thank you so much! 
> 
> just curious... Is that return text a C string or a com allocated string? wondering if sysallocatestring should be used on it?
> Edit: nevermind i see you allocated it with space()


Maybe you should use Space(1024) and Trim(tdTextRange.lpstrText) for long URLs.

----------


## Krool

> Maybe you should use Space(1024) and Trim(tdTextRange.lpstrText) for long URLs.


Or use LinkEnd - LinkStart to allocate just enough space.

----------


## Krool

I could have implemented in last update.. However, if I would implement anytime soon (maybe with something other so it would be worth to upgrade type lib version) then as following:



```
Public Function GetTextRange(ByVal Min As Long, ByVal Max As Long) As String
If Min > Max Then Err.Raise 380
If RichTextBoxHandle <> 0 Then
    Dim RETR As RETEXTRANGE, Buffer As String, Length As Long
    RETR.CharRange.Min = Min
    RETR.CharRange.Max = Max
    Buffer = String$(RETR.CharRange.Max - RETR.CharRange.Min + 1, vbNullChar)
    RETR.lpstrText = StrPtr(Buffer)
    Length = SendMessage(RichTextBoxHandle, EM_GETTEXTRANGE, 0, ByVal VarPtr(RETR))
    If Length > 0 Then GetTextRange = Left$(Buffer, Length)
End If
End Function
```



```
Private Type RECHARRANGE
Min As Long
Max As Long
End Type
Private Type RETEXTRANGE
CharRange As RECHARRANGE
lpstrText As Long
End Type
Private Const EM_GETTEXTRANGE as Long = (WM_USER + 75)
```

EDIT: some other implemented above function not with Min and Max but rather with Start and Length (similar to SelStart and SelLength), so Min = Start and Max = Start + Length

----------


## Mith

> Buffer = String$(*RETR.CharRange.Max - RETR.CharRange.Min + 1*, vbNullChar)


Does this calculation of the length also work if the address contains unicode characters?

----------


## Krool

> Does this calculation of the length also work if the address contains unicode characters?


The buffer is unicode. So yes.

----------


## Niya

> just curious... Is that return text a C string or a com allocated string? wondering if sysallocatestring should be used on it?


According to the documentation, this is what the TEXTRANGE structure looks like for wide strings.


```
typedef struct _textrangew {
  CHARRANGE chrg;
  LPWSTR    lpstrText;
} TEXTRANGEW;
```

Mith used SendMessageW which would would treat strings as wide strings so the above structure should be assumed. Notice the lpstrText member. It's defined as LPWSTR which means it's a pointer to a wide string. A wide string in this case would be a UTF-16 String. A VB6 String is also a UTF-16 format string but not an LPWSTR. It's a BSTR. They are kind of the same but not the same. Nonetheless what he did in code is may be correct. He defined the lpstrText as a String in VB6 and allocated space for it to be written to by SendMessageW. My only concern with that code is any potential ANSI conversion of the String before and after by VB6 when SendMessageW is called. But based on your response the code works.

----------


## chrislong2

Hi Krool,
So I have been using RTB from previous update and I have been experiencing RTL issues. 
Consider a command button with this code:
    RichTextBox1.RightToLeftMode = CCRightToLeftModeNoControl
    RichTextBox1.RightToLeft = True
    RichTextBox1.RightToLeftMode = CCRightToLeftModeVBAME
    RichTextBox1.Enabled = False
    RichTextBox1.Enabled = True
    RichTextBox1.Text = "ABC"

The enabled false/true thing I have discovered is needed to get the RTB to 'work' for a few other things too (incl update scrollbars).  Setting the RTL modes like that was also the only way I could get it to work.

Anyway, on Win7, this works where the text moves to the right margin for RTL for both MSFTEDIT and RichEdit 3.1 controls.
On Win 10/11, it does NOT work for the MSFTEDIT control, but DOES if I tell the RTB to only use the RichEdit 3.1 control.

I isolated that it DOES work correctly UNTIL you set the text property.  I can type and it will appear on the right margin, but as soon as I set that text property it loses it.

So I came here to post about it and I see you issued a new update where you changed the text in/out to use a different method than before to fix the CRLF stuff.  I was hopeful that would fix it, but when I just tried it on the same Win7 machine that worked previously, it now will not work either where the same problem occurs as on Win 10 (the old version does work for this on my Win7).  

How do I get the RTB to show assigned RTL text on the right side of the screen?  What am I missing here?

Thanks!  :Smilie:

----------


## Krool

> Hi Krool,
> So I have been using RTB from previous update and I have been experiencing RTL issues. 
> Consider a command button with this code:
>     RichTextBox1.RightToLeftMode = CCRightToLeftModeNoControl
>     RichTextBox1.RightToLeft = True
>     RichTextBox1.RightToLeftMode = CCRightToLeftModeVBAME
>     RichTextBox1.Enabled = False
>     RichTextBox1.Enabled = True
>     RichTextBox1.Text = "ABC"
> ...


I cannot reproduce it.

I have following code:


```
RichTextBox1.TextMode = RtfTextModePlainText
RichTextBox1.RightToLeftMode = CCRightToLeftModeNoControl
RichTextBox1.RightToLeft = True
RichTextBox1.Text = "ABC"
```

The text is right aligned and rtl reading is on.

Edit: OS is win 10

----------


## softv

> Update released.
> 
> Finally fixed the mismatch of the RichTextBox Text property concerning CrLf and the internal Cr only.
> The RichTextBox control now uses EM_GETTEXTEX/EM_SETTEXTEX instead of EM_STREAMOUT/EM_STREAMIN for the Text property.
> Included the UseCrLf property to control whether or not to apply GT_USECRLF/GTL_USECRLF on EM_GETTEXTEX.
> It defaults to False and thus makes a compatibility break to the previous VBCCR which used EM_STREAMOUT (always CrLf)
> 
> Also included the TextLength property in the TextBoxW and RichTextBox control to conveniently get the length of text w/o the need of allocating memory for the Text. (like in .net)
> 
> ...


*Thanks a TON*, once again, dear krool. 
Thank you very much for the UseCrLf property and also for making it default to False. I was waiting for this update like anything. 
I think I can now start thinking of using the OCX version of your controls.

Kind regards.

----------


## chrislong2

> I cannot reproduce it.
> 
> I have following code:
> 
> 
> ```
> RichTextBox1.TextMode = RtfTextModePlainText
> RichTextBox1.RightToLeftMode = CCRightToLeftModeNoControl
> RichTextBox1.RightToLeft = True
> ...


Thank you Krool!  I was not setting the text mode to plain text even though I wasn't using it for RTF.  I don't remember why I didn't set it, though I have noted that text assignment for larger Unicode files takes notably longer to load in the control with the previous version when the text mode is set.  With the new methodology for text mode in the latest release, it's quicker than it was though still less than when mode is RTF.  But perfectly fine.  Anyway when it's not set and RTF mode is used, then the RTL stuff doesn't work right although it sometimes partially does (like I said, the previous release did somewhat on Win 7). But since I don't use RTF, I've just set the text mode with newer version and it is working just as you posted.  Thanks for the response.  I haven't yet tested the CRLF stuff (I had already worked around that) so I just enabled the new UseCRLF option so it would work right away with what I'd already done, but I appreciate you addressing that!!  That was a major oddity with the RTF control and it affected lots of things where the numbers wouldn't match up.  Thanks for your continued work with these controls.

2 more things while I've got you:

1) With the RTB control, I do wish you would reconsider changing that code in CreatePrintJob from:



```
    .Left = LeftMargin - PhysOffsetCX
    .Top = TopMargin - PhysOffsetCY
    .Right = (PhysCX - RightMargin) + PhysOffsetCX
    .Bottom = (PhysCY - BottomMargin) + PhysOffsetCY
```

to



```
    If (LeftMargin - PhysOffsetCX) > 0 Then
        .Left = LeftMargin - PhysOffsetCX
    Else
        .Left = PhysOffsetCX
    End If
    If (RightMargin - PhysOffsetCX) > 0 Then
        .Right = (PhysCX - .Left) - (RightMargin - PhysOffsetCX)
    Else
        .Right = (PhysCX - .Left) - PhysOffsetCX
    End If
    If (TopMargin - PhysOffsetCY) > 0 Then
        .Top = TopMargin - PhysOffsetCY
    Else
        .Top = PhysOffsetCY
    End If
    If (BottomMargin - PhysOffsetCY) > 0 Then
        .Bottom = PhysCY - (BottomMargin - PhysOffsetCY)
    Else
        .Bottom = PhysCY - PhysOffsetCY
    End If
```

I know it doesn't look as pretty, but your current code does not work correctly when the specified margins are less than the offsets (which can happen, particularly in apps where user is able to set the margins), so that means I have to replace this part of code when you release an update.

2) For the Label control: When Auto Size and Word Wrap are enabled, if there are no spaces in a block of text (say a long spaceless path or something) then the text will not wrap and will just get cut off at the extreme edge of the form and the autosizing seems to extend beyond the form.  If there is later text after that (say it's a caption that has such text but then also has a vbcrlf and then other text), then that text also will get cut off EVEN IF that text has spaces and could wrap correctly.  It does this because the autosizing was set wrong because it was expanded out.

Anyway, there is a simple fix for this, which is to force the word wrapping to wrap even if it can't do it on spaces.  You simply use the DT_EDITCONTROL for it (Private Const DT_EDITCONTROL = &H2000&).  So:



```
If PropWordWrap = True Then Format = Format Or DT_WORDBREAK Or DT_EDITCONTROL
```

This isn't well documented, but when DT_EDITCONTROL is used with word wrapping, if word wrapping can't work because there's no spaces, then it will go ahead and force a wrap anyway.  At least I've verified that's what it does on Win7+ (haven't checked earlier OS).

I have run into this situation on 2 different projects using the Label control and have had to custom modify per the above to get it fixed.

[edit: you may want to make this DT_EDITCONTROL be used only if a new property is set to true (maybe a ForceablyWrap setting).  This way the current implementation of word wrapping (which I think does more accurately mirror what VB's internal label control does if my memory is correct) can still be as it is, but this 2nd way is an option.  To me a forceable wrap is almost always the preferable approach to just blatantly cut off text.]

[edit 2: I know there's the path elipsis options, but those are only really helpful if the text ONLY contains a path, not it might contain a path AND some other text, or just some other text that might not have spaces.]

----------


## Krool

> Thank you Krool!  I was not setting the text mode to plain text even though I wasn't using it for RTF.  I don't remember why I didn't set it, though I have noted that text assignment for larger Unicode files takes notably longer to load in the control with the previous version when the text mode is set.  With the new methodology for text mode in the latest release, it's quicker than it was though still less than when mode is RTF.  But perfectly fine.  Anyway when it's not set and RTF mode is used, then the RTL stuff doesn't work right although it sometimes partially does (like I said, the previous release did somewhat on Win 7). But since I don't use RTF, I've just set the text mode with newer version and it is working just as you posted.  Thanks for the response.  I haven't yet tested the CRLF stuff (I had already worked around that) so I just enabled the new UseCRLF option so it would work right away with what I'd already done, but I appreciate you addressing that!!  That was a major oddity with the RTF control and it affected lots of things where the numbers wouldn't match up.  Thanks for your continued work with these controls.
> 
> 2 more things while I've got you:
> 
> 1) With the RTB control, I do wish you would reconsider changing that code in CreatePrintJob from:
> 
> 
> 
> ```
> ...


Can you share the RTF so I can play around and what maybe find the issue ? Maybe there is something RTF encoded which forces the alignment...

Point 1:
For Right/Bottom I add PhysOffsetCX/CY while you substract it. So this is something to clarify before I make the change..

Point 2:
I would certainly add an additional property for that DT_EDITCONTROL. I suggest the name 'MimicTextBox'.  :Smilie:

----------


## chrislong2

> Can you share the RTF so I can play around and what maybe find the issue ? Maybe there is something RTF encoded which forces the alignment...
> 
> Point 1:
> For Right/Bottom I add PhysOffsetCX/CY while you substract it. So this is something to clarify before I make the change..
> 
> Point 2:
> I would certainly add an additional property for that DT_EDITCONTROL. I suggest the name 'MimicTextBox'.


I didn't actually use it as RTF mode.  I just never set the text mode to text only so it stayed on the default RTF mode.  The text I was assigning to the box was straight text and didn't use RTF.  That may have something to do with it.  You can try out yourself by using your code on an RTB that does not have the text mode set to text only but is using the default RTF mode.  When that is the case, the right to left stuff doesn't work (or only partially works, depending).

Point 1: See my post #3225.  You got that adding stuff from that Microsoft example, but it is not correct.  I am highly confident having tried on a couple different printers (and having wasted a lot of paper lol), that the code I posted above is correct and theirs is wrong.

Point 2: You can call it whatever you want.  :Smilie:   MimicTextBox or MimicTextBoxWrapping works.  :Smilie:  I like something about "force wrapping" because that's a tad clearer as to its actual effect. But yeah, basically it's mimicking a text box for wrapping.

----------


## Krool

> I didn't actually use it as RTF mode.  I just never set the text mode to text only so it stayed on the default RTF mode.  The text I was assigning to the box was straight text and didn't use RTF.  That may have something to do with it.  You can try out yourself by using your code on an RTB that does not have the text mode set to text only but is using the default RTF mode.  When that is the case, the right to left stuff doesn't work (or only partially works, depending).


There is a \rtlpar overriding the WS_EX_RIGHT style bit. So, that's why it is only working to change at run-time in plain text mode.

----------


## Krool

> I didn't actually use it as RTF mode.  I just never set the text mode to text only so it stayed on the default RTF mode.  The text I was assigning to the box was straight text and didn't use RTF.  That may have something to do with it.  You can try out yourself by using your code on an RTB that does not have the text mode set to text only but is using the default RTF mode.  When that is the case, the right to left stuff doesn't work (or only partially works, depending).


Fixed now. Thanks

I am confused about your proposed new calculations..

For Right you make _.Right = (PhysCX - .Left) - (RightMargin - PhysOffsetCX)_
but for Bottom you make _.Bottom = PhysCY - (BottomMargin - PhysOffsetCY)_
Why do you deduct .Left for Right and by Bottom you do not deduct .Top ?



```
    If (LeftMargin - PhysOffsetCX) > 0 Then
        .Left = LeftMargin - PhysOffsetCX
    Else
        .Left = PhysOffsetCX
    End If
    If (RightMargin - PhysOffsetCX) > 0 Then
        .Right = (PhysCX - .Left) - (RightMargin - PhysOffsetCX)
    Else
        .Right = (PhysCX - .Left) - PhysOffsetCX
    End If
    If (TopMargin - PhysOffsetCY) > 0 Then
        .Top = TopMargin - PhysOffsetCY
    Else
        .Top = PhysOffsetCY
    End If
    If (BottomMargin - PhysOffsetCY) > 0 Then
        .Bottom = PhysCY - (BottomMargin - PhysOffsetCY)
    Else
        .Bottom = PhysCY - PhysOffsetCY
    End If
```

----------


## chrislong2

> Fixed now. Thanks
> 
> I am confused about your proposed new calculations..
> 
> For Right you make _.Right = (PhysCX - .Left) - (RightMargin - PhysOffsetCX)_
> but for Bottom you make _.Bottom = PhysCY - (BottomMargin - PhysOffsetCY)_
> Why do you deduct .Left for Right and by Bottom you do not deduct .Top ?


Because I messed up in what I posted. lol So sorry!  When I was copying/pasting, I copied the code from the wrong place and mistakenly copied code I was "working on" trying a few months ago.  It should be this:



```
    If (LeftMargin - PhysOffsetCX) > 0 Then
        .Left = LeftMargin - PhysOffsetCX
    Else
        .Left = PhysOffsetCX
    End If
    If (TopMargin - PhysOffsetCY) > 0 Then
        .Top = TopMargin - PhysOffsetCY
    Else
        .Top = PhysOffsetCY
    End If
    .Right = (PhysCX - RightMargin) - PhysOffsetCX
    .Bottom = (PhysCY - BottomMargin) - PhysOffsetCY
```

This also matches the behavior of basically what I've been using for 20+ years with the old RTB.

----------


## Semke

HI!
I have a very interesting question. why don't the tabstrip *Tabs* have an *Enabled* and *Visible* Property.

I have never needed it, but today i wanted to use it, only to realize it doesn't exist

I see that the Microsoft tabstrip also doesn't have it, it would be a nice feature to add.

thanks

----------


## Krool

> HI!
> I have a very interesting question. why don't the tabstrip *Tabs* have an *Enabled* and *Visible* Property.
> 
> I have never needed it, but today i wanted to use it, only to realize it doesn't exist
> 
> I see that the Microsoft tabstrip also doesn't have it, it would be a nice feature to add.
> 
> thanks


There is no tab control item state available to visually disable a tab item.
However, you may cancel out on TabBeforeClick event.

For Visible. Hmm, then just don't add a tab item.
Again, also no state for that.

----------


## Mith

VBCCR v1.7.27

my vb6-app uses the vbccr17.ocx side-by-side without registering the OCX on the windows system.

Now one of my users got a error message when starting my app under Win10 21H1 (Build 19043.1319):



translated: "runtime error -2147221164 (80040154) class not registered"

Does someone have any experience with this error message and maybe a solution how to fix that problem?

I tried to reproduce this problem but at my Win10-PC everything runs fine...

----------


## MountainMan

I found that the new OCX version of Krools's controls caused a bit of a hiccup the other day. Normally, as long as the new VBCCRxx.OCX is in the same version number (1.7 for now), all you have to do is copy the latest one over the older one. But with the version 1.7.32 which came out this past Monday, I couldn't get it to work in VB6 without re-registering it with regsvr32. There must have been something in the new version that caused a minor incompatibility with the previous versions. Once I re-registered it then I had no problems. BTW, he came out with v1.7.34  on the 26th (3 days ago) and when I used the OCX version to overwrite the 1.7.32 version everything worked just fine. 

So the bottom line is that something changed between OCX versions 1.7.30 and 1.7.32 and later that caused me to have to re-register the OCX file one time.

----------


## Krool

> I found that the new OCX version of Krools's controls caused a bit of a hiccup the other day. Normally, as long as the new VBCCRxx.OCX is in the same version number (1.7 for now), all you have to do is copy the latest one over the older one. But with the version 1.7.32 which came out this past Monday, I couldn't get it to work in VB6 without re-registering it with regsvr32. There must have been something in the new version that caused a minor incompatibility with the previous versions. Once I re-registered it then I had no problems. BTW, he came out with v1.7.34  on the 26th (3 days ago) and when I used the OCX version to overwrite the 1.7.32 version everything worked just fine. 
> 
> So the bottom line is that something changed between OCX versions 1.7.30 and 1.7.32 and later that caused me to have to re-register the OCX file one time.


Yes. Typelib change from 1.0 to 1.1. (due to RichTextBox)
I think if minor version changes it's compatible.

----------


## Mith

i use VBCCR version 1.7.27 and i dont register the OCX on the windows system because i use SxS (side-by-side).
The manifest is included in the RES file.
Why i have to register the OCX on the system if i use SxS?

----------


## Arnoutdv

If you use SxS then you have to recreate your manifest file.

----------


## Mith

> If you use SxS then you have to recreate your manifest file.


Why should i recreate my manifest file? The manifest file (compiled in the RES) is ok because the app starts without any problems from Win7 to Win11 on all my test systems.

Currently only one user get this "strange" error message about registering the OCX when starting the app under win10...
Registering an OCX when using SxS??

----------


## Arnoutdv

No, its not fine, otherwise you shouldnt get the vbCCR ActiveX message.

----------


## Mith

> No, its not fine, otherwise you shouldnt get the vbCCR ActiveX message.


Maybe you not read what i wrote before: the app runs without any OCX error messages from win7 to win11.
For example: 999 of 1000 users have no problems running the app! Only one user get this error message.
How is this possible if the manifest is not ok? Can you explain this?

----------


## Krool

> Maybe you not read what i wrote before: the app runs without any OCX error messages from win7 to win11.
> For example: 999 of 1000 users have no problems running the app! Only one user get this error message.
> How is this possible if the manifest is not ok? Can you explain this?


My stomage says the VB.PropertyBag is corrupt at the registry of that 1 user.  :Smilie:

----------


## Arnoutdv

> I found that the new OCX version of Krools's controls caused a bit of a hiccup the other day. Normally, as long as the new VBCCRxx.OCX is in the same version number (1.7 for now), all you have to do is copy the latest one over the older one. But with the version 1.7.32 which came out this past Monday, I couldn't get it to work in VB6 without re-registering it with regsvr32. There must have been something in the new version that caused a minor incompatibility with the previous versions. Once I re-registered it then I had no problems. BTW, he came out with v1.7.34  on the 26th (3 days ago) and when I used the OCX version to overwrite the 1.7.32 version everything worked just fine. 
> 
> So the bottom line is that something changed between OCX versions 1.7.30 and 1.7.32 and later that caused me to have to re-register the OCX file one time.


This is the reason why I mentioned generating the manifest line for this control again.
Then you can manually check if there are differences.
If not then something else is happening on this single computer

----------


## Mith

> My stomage says the VB.PropertyBag is corrupt at the registry of that 1 user.


What does this mean and how is that possible?
My installer copies all 25 SxS files (DLL/OCX) onto the computer without registering them.
They are saved in a separate sub folder at the app's directory.
Only VBCCR17.ocx triggers this error message.
All the other 24 SxS files are fine, for example: RC6.DLL, cairo_sqlite.dll, msscript.ocx, mscomctl.ocx, zlibwapi.dll...
The user installed the app for the first time.
It looks like there are some special circumstances on that computer so Windows have problems to use the SxS technologie for this file.
I already know i can fix this problem by registering the file but i really want to know what causes this problem...

----------


## MountainMan

Krool says the type library has changed  so I am guessing that one or more of the GUIDs in your resource file (or manifest) needs to be changed. It has nothing to do with registering the OCX since your clients are using SxS. Perhaps Krool can provide us with updated .RES files if the GUIIDs have changed.

----------


## Krool

> Krool says the type library has changed  so I am guessing that one or more of the GUIDs in your resource file (or manifest) needs to be changed. It has nothing to do with registering the OCX since your clients are using SxS. Perhaps Krool can provide us with updated .RES files if the GUIIDs have changed.


The GUIDS have NOT changed.

----------


## chrislong2

Just a note of a problem (or perhaps just a "quirk"?) with RichTextBox: if you assign Unicode text to the RTB that is outside of the Unicode BMP (i.e. UTF-32 charcodes > 65535) while the characters may be able to display fine (Windows seems to "make it work" if it can), I discovered that if you then subsequently set the Font.Size property, it will make those characters outside of the BMP unreadable (they get changed to the standard "can't display this character rectangle symbol").  Interestingly, setting the font name property doesn't seem to cause this but only the font size.

EDIT: I take it back - It does do this if any font properties have actually changed, including name.  I guess this actually makes sense to a degree because if you assign a font or change font properties after text is assigned, it's presumably going to force the current text to take on whatever that font is which might not have the inherent support to display those characters.  However, when you load text in (or type it) where the specified font cannot support the characters in question, Windows automatically looks for a font that CAN display it and seamlessly does so.  But this same behavior doesn't occur if you set any font properties AFTER you load in/type text where any existing such characters that were displayed now become blank rectangles.  This is a problem because with an RTB where a user can set Font name/size it means that if they change the font name or even just the size, any characters outside of the BMP that were being displayed fine will no longer display correctly.

----------


## Mith

> Krool says the type library has changed  so I am guessing that one or more of the GUIDs in your resource file (or manifest) needs to be changed.


If this would be the case the app will not run anywhere w/o an error message and as i wrote before the app runs fine with 99,99% of all installations. So it is definitely not the manifest.

----------


## Krool

Exotic bugfix for ListView control.

It affects the FilterBar (edit control) not receiving focus on WM_LBUTTONDOWN when the previous focused control is a VB.CommandButton AND it is on a MDI child form.

Reason is a unknown message &H105A pending on the MDI host form which brings focus back to the ActiveControl.

Now the ListView control assures the ActiveControl is set prior the FilterBar will set the focus to the edit control so that &H105A will not disturb.

----------


## quickbbbb

Hi ~  Krool

I find a issue




```

Private Sub Form_Load()
For w = 1 To 5
ComboBoxW1.AddItem w
Next
End Sub
```


When Mouse Scroll on ComboBoxW1 List,  Editor software in background will scroll 



use ComboBoxW1.DisableNoScroll = True ?????

----------


## Mith

VBCCR 1.7.35
Win7-SP1
VB6-SP6

Im testing the controls for a Dark Mode and set the BackColor of several controls to Black and the ForeColor to White.
Setting the ForeColor doesnt work with the OptionButtonW & CheckBoxW control:



Can you fix this?

----------


## Mith

I found out that the following content of the IDE manifest file causes the problem with the OptionButtonW and CheckBoxW control:



```
  <dependency>
  	<dependentAssembly>
    	<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df"/>
  	</dependentAssembly>
  </dependency>
```

After i removed the code above the ForeColor of these controls is White again.
Do you have any idea how to fix this without removing the code from the IDE manifest file?

----------


## softv

Dear Krool,

Great to have an opportunity to thank you once again.

Well, I have the following queries with regard to *VirtualCombo*:

1) Is it possible for users to *add their own texts* to a Virtual Combo? If so, how can it be done? If not, are there any plans to add that feature?

2) What does "*ExtendedUI* = True" do in the case of a Virtual Combo? I somehow did not see any visual difference when I set it to True (from False).

3) *IncrementalSearch* event - What is it for? When is it used? When I tried out the VirtualControlsForm demo in your 'ComCtlsDemo' project, I placed breakpoints in that event's code but I did not know what I should do so that these breakpoints are reached and I get to know what your code under that event is all about.

4) How to effectively use '*AutoSelect*' property? Actually, in your demo, after setting 'AutoSelect' property to True, and after changing the style of 'VirtualCombo1' to 0 or 1, if I type 'i', it immediately selects 'item0'. Afterwards, it does not allow me to use Backspace to delete any character. If I go to the beginning and press 'Delete' key, I am able to delete all the characters but once the typing area is empty, immediately 'item0' is selected. If I select the whole 'item0' text and delete it also, immediately 'item0' reappears. So, it feels like I am stuck with 'item0'. And hence, I am unable to understand what the AutoSelect feature is exactly for?

Kind regards.

----------


## softv

Dear Krool,

I observed the following with respect to VirtualCombo.

1. In your demo, I changed the style of 'VirtualCombo1' to 0 and then ran the demo.
2. In the starting screen, I clicked the combo's chevron to see the list drop down and selected an item (say 'item6'). 
3. Then, I clicked the chevron again to close the list.
4. Then, I again clicked the chevron to see the list drop down.
5. What happens now is that the *first 2 characters* "it" get displayed (highlighted) in the typing area and 'item0' gets selected in the list.
6. If I am right, I think this happens because "VListBox1_FindVirtualItem" event gets called with SearchText as "it", when I click the chevron again (in Step 4)

I actually tried with one of my own VirtualCombos too with some words filled in it (Apple, Bag, Basket, Ball, Cat). Same thing happens. For instance, I select 'Ball' and close the list. Then, if I click the chevron again, 'Ba' appears highlighted in the typing area with 'Bag' selected in the list. 

So, *what to do* if the above issue should not arise?

Taking this opportunity to thank you once again for all your free controls. 

Kind regards.

----------


## Elroy

Hey Krool ... on your _RichTextBox_, you made the _.Text_ property accept full Unicode.  I'm wondering why you didn't do the same to the _.TextRTF_ property?

I do sometimes use something like WordPad to generate an RTF string, and then use it in my code.  I just discovered that you can't use Unicode while setting this _.TextRTF_ property.

----------


## DaveDavis

> If (PropFlags And (CdlPDReturnDC Or CdlPDReturnIC)) <> 0 Then
>     If PropDC <> 0 Then DeleteObject PropDC
>     PropDC = PDLGEX.hDC
>  End If


What is PropDC representing and purpose? I am confused with Printer.hdc

----------


## Krool

> Hey Krool ... on your _RichTextBox_, you made the _.Text_ property accept full Unicode.  I'm wondering why you didn't do the same to the _.TextRTF_ property?
> 
> I do sometimes use something like WordPad to generate an RTF string, and then use it in my code.  I just discovered that you can't use Unicode while setting this _.TextRTF_ property.


I don't know what you mean. The SF_RTF is ANSI always, also in WordPad.
The SF_UNICODE flag cannot be combined with SF_RTF.




> What is PropDC representing and purpose? I am confused with Printer.hdc


The Printer Dialog can return a hDC so you can pass it to API's.
That's often more useful as you can't use Printer.hdc in case the printer has an unicode name in VB6.
It's more flexible to be independent of the VB6 printer object.




> I found out that the following content of the IDE manifest file causes the problem with the OptionButtonW and CheckBoxW control:
> 
> 
> 
> ```
>   <dependency>
>   	<dependentAssembly>
>     	<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df"/>
>   	</dependentAssembly>
> ...


The themed button controls do ignore the ForeColor.
Blame MS as they still use DrawThemeText instead of DrawThemeTextEx in their button classes..
Workaround would be to NM_CUSTOMDRAW the buttons so the text will be theme drawed with colors.
If it's only text it would be easy but if there are pictures/image lists involved it get's complicated..




> Hi ~  Krool
> 
> I find a issue
> 
> 
> 
> 
> ```
> 
> ...


I don't get it. Can you provide a demo?
Doesn't it have something todo that on newer OS the mouse scroll receiver is nowadays the "window under cursor" instead of the "window which has focus" ?

----------


## quickbbbb

hi ~ Krool



> I don't get it. Can you provide a demo?
> Doesn't it have something todo that on newer OS the mouse scroll receiver is nowadays the "window under cursor" instead of the "window which has focus" ?



Run in  exe  + Win7_64bit

=====================

cc.zip

=====================





====================

*IF *  Run in VB IDE 
->  mouse click comboBox drop list  ( VB IDE is in background )
-> mouse start scroll on comboBox drop list  
-> mouse focus will* auto jump to* VB IDE immediately 
  , and VB IDE start scroll ( because VB IDE get focus and  goto foreground  )


======================

For w = 1 To *100   '-----> 5 change as 100*
ComboBoxW1.AddItem w
Next

if   w is from 5 change to 100 ,  the strange issue will  *disappear* 

ComboBoxW1 drop list will scroll correctly

----------


## Elroy

> Originally Posted by Elroy
> 
> 
> Hey Krool ... on your _RichTextBox_, you made the _.Text_ property accept full Unicode.  I'm wondering why you didn't do the same to the _.TextRTF_ property?
> 
> I do sometimes use something like WordPad to generate an RTF string, and then use it in my code.  I just discovered that you can't use Unicode while setting this _.TextRTF_ property.
> 
> 
> I don't know what you mean. The SF_RTF is ANSI always, also in WordPad.
> The SF_UNICODE flag cannot be combined with SF_RTF.


Ahhh, you are correct.  I didn't think it through that far.  I just took a small RTF string and used ChrW to put some Unicode characters in it, and it didn't work.  And, I now realize, per RTF specifications, it shouldn't have worked.

To see this, I just fired up WordPad and put some Unicode characters into a document and then saved it.  All I typed in was 111[alt-1234]222 and then saved it:



Here's the resulting RTF string:

{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}{\f1\fnil\fcharset204 Calibri;}}
{\*\generator Riched20 10.0.19041}\viewkind4\uc1 
\pard\sa200\sl276\slmult1\f0\fs22 111\f1\lang1049*\u1234?*\f0\lang1033 222\par
}
I bolded and made red the Unicode character.  I now see that we must use the \u escape to get unicode characters into our RTF string.

So, it's all good.

Thanks,
Elroy

----------


## softv

> Dear Krool,
> 
> I observed the following with respect to VirtualCombo.
> 
> 1. In your demo, I changed the style of 'VirtualCombo1' to 0 and then ran the demo.
> 2. In the starting screen, I clicked the combo's chevron to see the list drop down and selected an item (say 'item6'). 
> 3. Then, I clicked the chevron again to close the list.
> 4. Then, I again clicked the chevron to see the list drop down.
> 5. What happens now is that the *first 2 characters* "it" get displayed (highlighted) in the typing area and 'item0' gets selected in the list.
> ...


Dear Krool,

If and when your time permits, kindly please let me know whether any solution exists for the issue above I have observed (I have provided the steps to produce it too). 

The issue again, in a gist, is:
The selected item in a VirtualCombo changes to some other item upon DropDown of the list again. Not only that. The first two characters in the new(but wrong) item gets displayed in the typing area, in highlighted state. This issue happens when the style of the virtual combo is set to 0 (vbcStyleDropDownCombo).

Thanks and Kind regards.

----------


## MountainMan

Krool,

I used to have built-in Help for 2-3 lines for the selected control property at the bottom of the property window. Now it is gone. Do you how I can get that feature back? Thanks.

----------


## MountainMan

Never mind. I figured it out...

----------


## Eduardo-

Hello Krool,

I want to report something FYI:

I wanted to change some graphical style checkboxes in a program in order to show them themed, so I added your CheckBoxW from Elroy's splitted controls (BTW thanks Elroy for that work too).

I ran the program and then I found an error of "File not found".
The problem was your FileLen overwrite implementation, the file exists and is a mdb database file that is currently open, I'm not sure if in that option that I entered it is open exclusively or not, I can investigate that if you want.

The issue is that it raised the error as File not found at the line:



```
Err.Raise Number:=53, Description:="File not found: '" & PathName & "'"
```

I resolved the issue commenting out all the "(VB-Overwrite)" functions in your Common.bas since I don't need Unicode support in this program, but I wanted to report it to you in case you want to investigate and possibly fix this issue.

----------


## Mith

VBCCR 1.7.35

Hi krool,

i ran into a performance problem with the RichTextBox using Win10/11 with the latest updates.

Loading a 14mb unicode txt file takes forever (i killed the app after 15 minutes).
The CPU was around 40-50% and the HD was busy with loading too.

my code to load the txt file:



```
rtfLog.LoadFile sLogFile, RtfLoadSaveFormatUnicodeText
```

any idea how to fix that problem?

Does anyone know an alternative loading method to load large unicode txt files into a RichTextBox?

----------


## Mith

> Loading a 14mb unicode txt file takes forever (i killed the app after 15 minutes).


The solution for this problem was to remove the code to set the font before & after loading the text file!

Changing the font after loading a large text file and the RichTextBox-control hangs "forever"...

dunno if this can be fixed by krool or its a "feature" of the RichTextBox :|

----------


## Krool

> Hello Krool,
> 
> I want to report something FYI:
> 
> I wanted to change some graphical style checkboxes in a program in order to show them themed, so I added your CheckBoxW from Elroy's splitted controls (BTW thanks Elroy for that work too).
> 
> I ran the program and then I found an error of "File not found".
> The problem was your FileLen overwrite implementation, the file exists and is a mdb database file that is currently open, I'm not sure if in that option that I entered it is open exclusively or not, I can investigate that if you want.
> 
> ...


Thanks. I used GetFileSize API which requires a hFile handle. Which is problematic for ERROR_SHARING_VIOLATION.
So, I will change soon it to below code..



```
Private Type WIN32_FILE_ATTRIBUTE_DATA
dwFileAttributes As Long
FTCreationTime As FILETIME
FTLastAccessTime As FILETIME
FTLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
End Type
Private Declare Function GetFileAttributesEx Lib "kernel32" Alias "GetFileAttributesExW" (ByVal lpFileName As Long, ByVal fInfoLevelId As Long, ByVal lpFileInformation As Long) As Long

' (VB-Overwrite)
Public Function FileLen(ByVal PathName As String) As Variant
Dim FAD As WIN32_FILE_ATTRIBUTE_DATA
If Left$(PathName, 2) = "\\" Then PathName = "UNC\" & Mid$(PathName, 3)
If GetFileAttributesEx(StrPtr("\\?\" & PathName), 0, VarPtr(FAD)) <> 0 Then
    FileLen = CDec(0)
    VarDecFromI8 FAD.nFileSizeLow, FAD.nFileSizeHigh, FileLen
Else
    Err.Raise Number:=53, Description:="File not found: '" & PathName & "'"
End If
End Function
```

----------


## Mith

VBCCR 1.7.35

Hi krool,

i use the follwing code to set the background color to black and the text color to white before i load a text file into the RichtextBox:



```
rtf1.TextMode = RtfTextModeRichText
rtf1.Text = "Please wait..."
rtf1.BackColor = vbBlack
rtf1.SelStart = 0
rtf1.SelLength = Len(rtf1.Text)
rtf1.SelColor = vbWhite
rtf1.LoadFile sLogFile, RtfLoadSaveFormatUnicodeText
```

The code works fine using Windows 7 and the loaded text will have the correct text color: a black background with white text.

The problem comes with Windows 8/10/11: the text color of the loaded text is not white anymore; it's still black (the standard color); and now i have black text on a black background!

My questions:

1. Do you have any idea why the RichtextBox behaves different when loading a file using Win8/10/11?

2. Does anyone know a solution for Win8/10/11 to set the text color BEFORE loading a text file?

greetings Mith

PS: I already know that i can change the text color after i loaded the logfile, but this is practically impossible because it takes forever (the app hangs) to change the selected color with ".SelColor" when loading large text files (1/10/50/100mb...).

----------


## Schmidt

> PS: I already know that i can change the text color after i loaded the logfile, but this is practically impossible because it takes forever (the app hangs) to change the selected color with ".SelColor" when loading large text files (1/10/50/100mb...).


Whilst not an answer, how to fix the ".SelColor"-Problem... I'd say, 
that a RichTextBox is not the ideal Control for a "Log-Viewer-for-large-Files".

Any *virtual* Grid or List-Control (heck, even a simple PictureBox) can solve the problem of:
loading, visualizing (and scrolling through) a* 100MB-log* with a first-load-reaction-time between *0.2-0.8 seconds* 

That time mostly determined by, how fast you can load that file from SSD or Disk into a ByteArray.

Olaf

----------


## Mith

> Any *virtual* Grid or List-Control (heck, even a simple PictureBox) can solve the problem of:
> loading, visualizing (and scrolling through) a* 100MB-log* with a first-load-reaction-time between *0.2-0.8 seconds*


Thanks for the feedback Olaf.

Do you know some vb examples for the Grid/List/PictureBox solution to view large text files?

----------


## Schmidt

> Thanks for the feedback Olaf.
> 
> Do you know some vb examples for the Grid/List/PictureBox solution to view large text files?


Below comes a small example, which is able to read a *50MB LogFile* (with about 200000 Lines):
- in *PCode*/IDE-mode, taking *0.5sec* for LineParsing + first visualization
- when *native*-compiled: *0.12sec*   for LineParsing + first visualization 
- *native*-compiled, *all ext. Options*: *60millisec*  for LineParsing + first visualization 

It is based (to stay on-topic in this thread) on Krools VListBox - 
so you will need to place a VListBox1 on an otherwise empty Form:



```
 Option Explicit

Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal codePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long

Private UTF8() As Byte, Offsets() As Long

Private Sub Form_Load()
  Font.Name = "Consolas": Font.Size = 10: Set VListBox1.Font = Font 'set the Render- and TextWidth-measurement-font
  UTF8 = ReadFileBytes("c:\temp\test2.txt") 'read the File-Content into a ByteArray (we assume UTF8 here)
  VListBox1.ListCount = GetLines(UTF8, Offsets) 'set the VList-Count by parsing the LineCount from the Utf8-Bytes
End Sub

Private Sub Form_Resize()
  VListBox1.Move 0, 0, ScaleWidth, ScaleHeight
End Sub

Private Sub VListBox1_GetVirtualItem(ByVal Item As Long, Text As String)
  Text = GetLine(Item)
  If VListBox1.HorizontalExtent < TextWidth(Text) Then VListBox1.HorizontalExtent = TextWidth(Text)
End Sub

Private Function GetLines(UTF8() As Byte, Offsets() As Long) As Long
  Dim OffsUB As Long: OffsUB = 1024: ReDim Offsets(OffsUB)
  
  Dim i As Long, j As Long, LF As Byte
  For i = 0 To UBound(UTF8)
    If UTF8(i) = 13 Or UTF8(i) = 10 Then LF = UTF8(i): Exit For
  Next
  For i = 0 To UBound(UTF8)
    If UTF8(i) = LF Then
       If j >= OffsUB Then OffsUB = 1.5 * OffsUB: ReDim Preserve Offsets(OffsUB)
       j = j + 1: Offsets(j) = i
    End If
  Next
  If UTF8(i - 1) <> 13 And UTF8(i - 1) <> 10 Then
     If j >= OffsUB Then OffsUB = 1.5 * OffsUB: ReDim Preserve Offsets(OffsUB)
     j = j + 1: Offsets(j) = i
  End If
  GetLines = j
End Function

Private Function GetLine(ByVal ZeroBasedLineIdx As Long) As String
  Dim Offs As Long: Offs = Offsets(ZeroBasedLineIdx)
            If UTF8(Offs) = 13 Then Offs = Offs + 1
            If UTF8(Offs) = 10 Then Offs = Offs + 1
  Dim BLen As Long: BLen = Offsets(ZeroBasedLineIdx + 1) - Offs
      
  If BLen > 0 Then 'UTF8-to-BSTR conversion, directly from the UTF8-bytearray
     GetLine = Space$(MultiByteToWideChar(65001, 0, VarPtr(UTF8(Offs)), BLen, 0, 0))
     MultiByteToWideChar 65001, 0, VarPtr(UTF8(Offs)), BLen, StrPtr(GetLine), Len(GetLine)
  End If
End Function

Private Function ReadFileBytes(FileName As String) As Byte()
  Dim FNr As Long: FNr = FreeFile
  On Error GoTo 1
  Open FileName For Binary As FNr
       ReDim ReadFileBytes(LOF(FNr) - 1)
       Get FNr, , ReadFileBytes
1 If Err Then ReadFileBytes = StrConv(Err.Description, vbFromUnicode)
  Close FNr
End Function
```

HTH

Olaf

----------


## Mith

> Below comes a small example, which is able to read a *50MB LogFile*


That's a good start to create a text viewer for large files!

Thanks a lot for the example!

----------


## Schmidt

> That's a good start to create a text viewer for large files!


I'd think so...

Just add a little context-menu on Mouse-RightClick, which shows e.g. Options like:

> Show Line-Details... 
...(a little PopupForm, showing the current Line transposed vertically, split into Timestamp and other Info-Chunks)
> Copy +- 50 Lines to ClipBoard
> Copy this +100 additional Lines to ClipBoard
> Refresh and move to last Line (re-reading the current FileContents)

and the whole thing already becomes something useful...

Olf

----------


## Mith

> Just add a little context-menu on Mouse-RightClick, which shows e.g. Options like:Olf


I still working on the basic functions.

I have completely rewritten your code to optimize everything for Unicode.

For example, i load the file content via CreateFileWide/ReadFile to support file/dirs with unicode characters in the name.

I also added a algo to determine different file encodings:

UTF8, UTF8NoBOM, UTF16LE, UTF16LEnoBOM, UTF16BE, UTF16BEnoBOM, ANSI

I also replaced the ANSI function "TextWidth" at event "VListBox1_GetVirtualItem" with API "GetTextExtentPoint32W" to get the correct text width.
With the ANSI function the scrollbar width was mostly wrong.

Next step is to implement a search function. Later i will add different context menu actions.

btw, im not sure, but maybe this is a bug of the Virtual List Control:

When i load a file and set ListCount of the control, the event VListBox1_GetVirtualItem starts populating and the property HorizontalExtent will be set but the scrollbar doesnt show up.
I need to move the mouse cursor to the invisible horizontal scrollbar to make the bar visible.
Tested with Win7 IDE and compilied exe.
Maybe i should report this to krool (or maybe he read this) ?

----------


## Schmidt

> ... still working on the basic functions.


Sure, ... whilst Krool has a (unicode-capable) TextWidth-Method built-in on the ListView -
(which allows virtual mode as well BTW) - it is missing on the VirtualListBox 
(where it would make sense as well, as you found out).

As for the render-problems (with the H-ScrollBar) on Win7 - I don't see them on my Win10 here...

That's something for Krool to decide (whether it is worthwhile to test and fix for this older Win-OS).

Olaf

----------


## Mith

> As for the render-problems (with the H-ScrollBar) on Win7 - I don't see them on my Win10 here...


The h-scrollbar problem has nothing to do with win7. I did another test with the compiled exe under win11 and got the same result.

The H-Scrollbar is not visible until i move the cursor over the bar or i minimize & restore the window!

No h-scrollbar after setting the HorizontalExtent property:



after minimize & restore:



The left control is the VListBox and the right control is a RichtextBox (to compare the displayed text).

----------


## Mith

another win11 test, i activated the visual theme for the compiled test app via a external manifest.

the left VListBox only show the v-scrollbar and the right RichTextBox show both scrollbars:



after minimize and restore, the VListBox display both scrollbars and the RichTextBox dont show any scrollbars:



The scrollbars property of the RichTextBox is set to "3 - vbBoth".

Is the behavior of the VListBox and the RichTextBox control correct  :Confused:

----------


## Krool

Mith did you try a VListBox1.Refresh after setting the HorizontalExtent ? If this works I may enforce an "invalidation" within the HorizontalExtent property.

----------


## Mith

> Mith did you try a VListBox1.Refresh after setting the HorizontalExtent ? If this works I may enforce an "invalidation" within the HorizontalExtent property.


I tried that already inside the GetVirtualItem event but it leads to an infinitive loop of populating the control!

if i manually use .refresh via a command button after the populating is done the h-scrollbar gets visible.

i guess we need a new event like "After_Populating_Done" to trigger a refresh automatically.

----------


## Mith

no need to change or add anything, i found a easy solution for the H-Scrollbar problem:

after the code:




> vlbLog.ListCount = GetLineCountFromTextArray


i use this command now:




> vlbLog.Refresh


and voila the h-scrollbar appears!

...or maybe you should do this refresh automatically inside the .ListCount property to fix the scrollbar display problem?

----------


## softv

> Whilst not an answer, how to fix the ".SelColor"-Problem... I'd say, 
> that a RichTextBox is not the ideal Control for a "Log-Viewer-for-large-Files".
> 
> Any *virtual* Grid or List-Control (heck, even a simple PictureBox) can solve the problem of:
> loading, visualizing (and scrolling through) a* 100MB-log* with a first-load-reaction-time between *0.2-0.8 seconds* 
> 
> That time mostly determined by, how fast you can load that file from SSD or Disk into a ByteArray.
> 
> Olaf


Thanks a TON, olaf.

I had always thought that I should try loading large text files in Krool's VBFlexGrid and try but never got time for the same, as other things got up in the priority list. So, is it *possible* Olaf, *with VBFlexGrid too*?

I have not tried your VListBox code yet. I just thought of thanking you first, promptly, after reading your solution using VListBox. Will try it soon. Thanks again.

Kind Regards.

----------


## softv

> I still working on the basic functions.
> 
> I have completely rewritten your code to optimize everything for Unicode.
> 
> For example, i load the file content via CreateFileWide/ReadFile to support file/dirs with unicode characters in the name.
> 
> I also added a algo to determine different file encodings:
> 
> UTF8, UTF8NoBOM, UTF16LE, UTF16LEnoBOM, UTF16BE, UTF16BEnoBOM, ANSI
> ...


Dear Mith,

Thanks a lot. Interested in your rewritten code, if you can share it, please.

Esp. interested in your algo which can correctly determine "*UTF8 with no BOM*" too.

Kind Regards.

----------


## softv

> Dear Krool,
> 
> If and when your time permits, kindly please let me know whether any solution exists for the *issue above* I have observed (I have provided the steps to produce it too). 
> 
> The issue again, in a gist, is:
> The selected item in a *VirtualCombo* changes to some other item upon DropDown of the list again. Not only that. The first two characters in the new(but wrong) item gets displayed in the typing area, in highlighted state. This issue happens when the style of the virtual combo is set to 0 (vbcStyleDropDownCombo).
> 
> Thanks and Kind regards.


I am still very much looking forward for a solution for this from you, Krool. Would be much thankful to you if you can provide the same. Thanks in advance.

Kind regards.

----------


## MountainMan

I just updated the documentation and compile/update utility which now handles VBFLXGRDxx.OCX files up through the just-released v1.5 and VBCCRxx.OCX up through the current v1.7. It is located at the bottom of post #1 in this thread.

----------


## Mith

> Esp. interested in your algo which can correctly determine "*UTF8 with no BOM*" too.


how-to-detect-utf-8-based-encoded-strings/

----------


## softv

> how-to-detect-utf-8-based-encoded-strings/


thank you so much.

kind regards.

----------


## Mith

> thank you so much.
> 
> kind regards.


Read this too: VB6-The-case-for-UTF-8

----------


## Schmidt

> I had always thought that I should try loading large text files in Krool's VBFlexGrid and try but never got time for the same, as other things got up in the priority list. So, is it *possible* Olaf, *with VBFlexGrid too*?


Sure... relatively easy to do via the IVBFlexDataSource interface, when you implement it in a little Class like the one below.

Into a Class, named *cTextDataSource*:



```
Option Explicit

Implements IVBFlexDataSource

Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal codePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long

Private UTF8() As Byte, Offsets() As Long, LineCount As Long, LastLineIdx As Long, Line As String

Public Sub BindToTextFile(FG As VBFlexGrid, FileName As String)
  UTF8 = ReadFileBytes(FileName)
  LineCount = GetLines(UTF8, Offsets)
  LastLineIdx = -1
  
  Set FG.FlexDataSource = Me 'bind this Class (and set a few FG-defaults)
      FG.ColWidth(0) = 1800
      FG.ExtendLastCol = True
      FG.ScrollTrack = True
End Sub

Private Function ReadFileBytes(FileName As String) As Byte()
  Dim FNr As Long: FNr = FreeFile
  On Error GoTo 1
  Open FileName For Binary As FNr
       ReDim ReadFileBytes(LOF(FNr) - 1)
       Get FNr, , ReadFileBytes
1 If Err Then ReadFileBytes = StrConv(Err.Description, vbFromUnicode)
  Close FNr
End Function
 
Private Function GetLines(UTF8() As Byte, Offsets() As Long) As Long
  Dim OffsUB As Long: OffsUB = 1024: ReDim Offsets(OffsUB)
  
  Dim i As Long, j As Long, LF As Byte
  For i = 0 To UBound(UTF8)
    If UTF8(i) = 13 Or UTF8(i) = 10 Then LF = UTF8(i): Exit For
  Next
  For i = 0 To UBound(UTF8)
    If UTF8(i) = LF Then
       If j >= OffsUB Then OffsUB = 1.5 * OffsUB: ReDim Preserve Offsets(OffsUB)
       j = j + 1: Offsets(j) = i
    End If
  Next
  If UTF8(i - 1) <> 13 And UTF8(i - 1) <> 10 Then
     If j >= OffsUB Then OffsUB = 1.5 * OffsUB: ReDim Preserve Offsets(OffsUB)
     j = j + 1: Offsets(j) = i
  End If
  GetLines = j
End Function

Private Function GetLine(ByVal ZeroBasedLineIdx As Long) As String
  Dim Offs As Long: Offs = Offsets(ZeroBasedLineIdx)
            If UTF8(Offs) = 13 Then Offs = Offs + 1
            If UTF8(Offs) = 10 Then Offs = Offs + 1
  Dim BLen As Long: BLen = Offsets(ZeroBasedLineIdx + 1) - Offs
      
  If BLen > 0 Then 'UTF8-to-BSTR conversion, directly from the UTF8-bytearray
     GetLine = Space$(MultiByteToWideChar(65001, 0, VarPtr(UTF8(Offs)), BLen, 0, 0))
     MultiByteToWideChar 65001, 0, VarPtr(UTF8(Offs)), BLen, StrPtr(GetLine), Len(GetLine)
  End If
End Function

'***** Implementation of IVBFlexDataSource *****
Private Function IVBFlexDataSource_GetRecordCount() As Long
  IVBFlexDataSource_GetRecordCount = LineCount
End Function

Private Function IVBFlexDataSource_GetFieldCount() As Long
  IVBFlexDataSource_GetFieldCount = 2
End Function

Private Function IVBFlexDataSource_GetFieldName(ByVal Field As Long) As String
  Select Case Field
    Case 0: IVBFlexDataSource_GetFieldName = "TimeStamp"
    Case 1: IVBFlexDataSource_GetFieldName = "LogInfo"
  End Select
End Function

Private Function IVBFlexDataSource_GetData(ByVal Field As Long, ByVal Record As Long) As String
  If LastLineIdx <> Record Then
     LastLineIdx = Record
     Line = GetLine(Record)
  End If
  Select Case Field
    Case 0: IVBFlexDataSource_GetData = Left$(Line, 19)
    Case 1: IVBFlexDataSource_GetData = Mid$(Line, 21)
  End Select
End Function

Private Sub IVBFlexDataSource_SetData(ByVal Field As Long, ByVal Record As Long, ByVal NewData As String)
End Sub
```

And this into a Form for testing with one of your own Log- or TextFiles:
(the Form needs an instance of VBFlexgrid1, ... either in version 1.4. or in newest version 1.5)


```
Option Explicit

Const FileName = "c:\temp\test3.txt"

Private FlexDS As New cTextDataSource

Private Sub Form_Load()
    VBFlexGrid1.Font.Name = "Arial"
    FlexDS.BindToTextFile VBFlexGrid1, FileName
End Sub
 
Private Sub Form_Resize()
    VBFlexGrid1.Move 0, 0, ScaleWidth, ScaleHeight
End Sub
```

Since the FlexGrid is normally used for "Multi-Column-Data", 
I've artificially created a LogFile with a leading (ISO) Timestamp per Line, to have more than one Column "to split" for the FG.

Used the RC6 for that, with the following snippet:


```
  With New_c.StringBuilder
    Dim i As Long, D As Double: D = Now
    For i = 1 To 100000
      D = D + 1 / 86400
      .Add Format$(D, "yyyy\-mm\-dd hh\:nn\:ss")
      .AddNL " Some loooooooooooooooooonger Log-Entry-Line " & i
    Next
    New_c.FSO.WriteByteContent FileName, .ToUTF8
  End With
```

HTH

Olaf

----------


## softv

> Sure... relatively easy to do via the IVBFlexDataSource interface, when you implement it in a little Class like the one below.
> 
> Into a Class, named *cTextDataSource*:
> 
> 
> 
> ```
> Option Explicit
> 
> ...


Only just a moment ago, I posted a query in Krool's 'VBFlexGrid Control' thread about whether we can bind a VBFlexGrid to a database table (for a different purpose though). In fact, it so happened that I mentioned about you too in that post!  :Smilie:  

And, after posting it, I came here (to the 'Common Controls' thread) almost immediately to check for any new posts and I find yours on how to load large text files in the VBFlexGrid!!!!! *What a coincidence and what a joy!* Thanks a TON, Olaf. Will try it out soon in the recently released 1.5 Ocx.

In case large RichText (with all formatting - B/I/U/etc. - intact) has to be loaded and shown, then which control of Krool's will be ideal? (since VBFlexGrid or ListBox cannot show Rich Text, if I am right). Or, using PictureBox only will be the ideal one? If so, what would be the code as a startup for the same? Kindly please show me the way, since showing large RichText content also will be the case for me.

Kind regards.

----------


## Schmidt

> In case large RichText (with all formatting - B/I/U/etc. - intact) has to be loaded and shown, 
> then which control of Krool's will be ideal?


Ermm, the RichTextBox-Control?  :Wink: 

The RichTextBox-Ctl is not the right Control for "huge PlainText-Files" ...
whereas for *.rtf-files which contain extensive formatting - it simply is.

Olaf

----------


## georgekar

I use this function to detect UTF8 without BOM. Just get a max of 1000 bytes from file (if less get all bytes from file)



```
Public Function ContainsUTF8(ByRef Source() As Byte) As Boolean
  Dim i As Long, lUBound As Long, lUBound2 As Long, lUBound3 As Long
  Dim CurByte As Byte
    lUBound = UBound(Source)
    lUBound2 = lUBound - 2
    lUBound3 = lUBound - 3
    If lUBound > 2 Then
    
    For i = 0 To lUBound - 1
        CurByte = Source(i)
        If (CurByte And &HE0) = &HC0 Then
        If (Source(i + 1) And &HC0) = &H80 Then
            ContainsUTF8 = True
             i = i + 1
             Else
                ContainsUTF8 = False
                Exit For
            End If
        ElseIf (CurByte And &HF0) = &HE0 Then
        ' 2 bytes
        If (Source(i + 1) And &HC0) = &H80 Then
            i = i + 1
            If i < lUBound2 Then
            If (Source(i + 1) And &HC0) = &H80 Then
                ContainsUTF8 = True
                i = i + 1
            Else
                ContainsUTF8 = False
                Exit For
            End If
                Else
                ContainsUTF8 = False
                Exit For
            End If
        Else
            ContainsUTF8 = False
            Exit For
        End If
        ElseIf (CurByte And &HF8) = &HF0 Then
        ' 2 bytes
        If (Source(i + 1) And &HC0) = &H80 Then
            i = i + 1
            If i < lUBound2 Then
               If (Source(i + 1) And &HC0) = &H80 Then
                    ContainsUTF8 = True
                    i = i + 1
                    If i < lUBound3 Then
                       If (Source(i + 1) And &HC0) = &H80 Then
                            ContainsUTF8 = True
                            i = i + 1
                        Else
                            ContainsUTF8 = False
                            Exit For
                        End If   
                    Else
                        ContainsUTF8 = False
                        Exit For
                    End If
                Else
                    ContainsUTF8 = False
                    Exit For
                End If              
            Else
                ContainsUTF8 = False
                Exit For
            End If
        Else
            ContainsUTF8 = False
            Exit For
        End If
      End If 
    Next i
  End If
End Function
```

----------


## georgekar

This if for UTF16, if return 1 then missing BOM is &HFEFF (LE), for 2 the missing BOM is &HFFFE (BE - BOM reading from BE is &HFEFF), else no UTF16 found.


```
Public Function ContainsUTF16(ByRef Source() As Byte) As Long
  Dim i As Long, lUBound As Long, lUBound2 As Long, lUBound3 As Long
  Dim CurByte As Byte, CurByte1 As Byte
  Dim CurBytes As Long, CurBytes1 As Long
    lUBound = UBound(Source)
    If lUBound > 4 Then
    CurByte = Source(0)
    CurByte1 = Source(1)
    For i = 2 To lUBound - 1 Step 2
        If CurByte1 = 0 And CurByte < 31 Then CurBytes1 = CurBytes1 + 1
        If CurByte = 0 And CurByte1 < 31 Then CurBytes = CurBytes + 1
        If Source(i) = CurByte Then
            CurBytes = CurBytes + 1
        Else
            CurByte = Source(i)
        End If
        If Source(i + 1) = CurByte1 Then
            CurBytes1 = CurBytes1 + 1
        Else
            CurByte1 = Source(i + 1)
        End If
        
    Next i
    End If
    If CurBytes1 = CurBytes And CurBytes1 * 3 >= lUBound Then
    ContainsUTF16 = 0
    Else
    If CurBytes1 * 3 >= lUBound Then
    ContainsUTF16 = 1
    ElseIf CurBytes * 3 >= lUBound Then
    ContainsUTF16 = 2
    Else
    ContainsUTF16 = 0
    End If
    End If
End Function
```

----------


## softv

> Ermm, the RichTextBox-Control? 
> 
> The RichTextBox-Ctl is not the right Control for "huge PlainText-Files" ...
> whereas for *.rtf-files which contain extensive formatting - it simply is.
> 
> Olaf


 :Smilie:   :Smilie: 

you are right of course and I do use Krool's RichTextBox control only to show richtext. But then, the RichTextBox control takes (I am sure any RichTextBox control (rtb, for short) for that matter, not just Krool's) quite some time to load large .rtf files (for instance, it takes 5 seconds to load a 7.5MB rtf file in my system [with 16gb ram]). When the need is just to show the lengthy content of a .rtf file in the rtb and not anything much to do with the rtb's contents thereafter, I thought it will be great if the RichText content can load lightning fast (both from a large file and also by setting it a lengthy/long string), much similar to the plain text content (which you have written takes just 60millisec for LineParsing + first visualization, with your super code). 

So, the above fast loading (as in the case of a plain text) cannot be achieved for RichText too by some/any means? That was my point of interest. If you can do that, olaf (just like you did it for plain text), nothing like it. If that cannot be done, then, is buffered loading of contents possible (as the user scrolls the rtb)? If so, will it be as seamless/same as viewing/scrolling a RichTextBox with all contents loaded fully? If so, possible for you to provide a solution for the same? 

Actually, after reading your message, I thought I will re-visit that module of mine which gave me problems with RichTextBox 3 years back. The problem occurred in a specific case (of a long string) only, which took a long time to load and still further time to execute a ".SelFontCharset" on the whole text. Many a times it used to hang. I could not solve this specific case at all, after trying a lot. Finally, I just gave it up. 

And, what a blessing it turned out to be, to revisit that module of mine again! Because, I could fix the problem yesterday after lots and lots of experiments. I felt overjoyed. And, all thanks to you!!! Because, but for your message, perhaps I would not have visited that module again. Well, for a problem of this kind, a veteran like you would have fixed it in a jiffy, I am sure. But, for a person like me, I needed to work it out the hard way.  :Smilie: 

On what I did to fix my problem, I will post as a reply to Mith's message so that perhaps it can help solve his problem too (regarding '.SelColor'). 

Always remaining in gratitude to yours and Krool's invaluable contributions to this world society.

Kind regards.

----------


## softv

> VBCCR 1.7.35
> 
> Hi krool,
> 
> i use the follwing code to set the background color to black and the text color to white before i load a text file into the RichtextBox:
> 
> 
> 
> ```
> ...


Ref post: *post #3314* (my reply message to Olaf)

The problem I have referred to in my abovementioned post was to do with setting a long string to a RichTextBox (rtb, for short) and thereafter immediately selecting it fully and setting its '.SelFontCharset' and '.SelFontName'. 

It was taking nearly 1 minute (to sometimes even *1.5 minutes*) in Windows7 (with 4gb ram), for the above process to complete. That was 3 years back. Now I have a Windows 10 system (with 16gb ram). In it, it was taking *25 seconds* for the above process to complete. But, even that, it would mostly work only the first time the process took place. Other times, more often than not, it would hang, both in IDE and as an executable.

So, after lots of experiments yesterday (which continued today also), what worked finally to bring down the processing time to *5 seconds* is, the following:
--
1. *Setting the width and height of the rtb to 0* before starting the process (in addition to rtb.visible = false)

2. Once the process is over, setting back the height and width of the rtb to whatever it was earlier.

3. Doing the above was a real boon. Because, '.SelFontCharset' happened instantly, which was the one which used to hog the longest time in the whole process, without the above fix. 

4. Now, after the above fix, the one which takes the major chunk (4 seconds) of the 5 seconds is '.SelLength'. Setting the long string (lstr, for short) to the rtb takes 1 second. '.SelLength' also happens within a second, if ScrollBars property is set to 'vbBoth' but then I need my ScrollBars to be vbVertical only. So, I could not take advantage of that.

5. Actually, I do set the font of the rtb to the same '.SelFontName' (Arial Unicode MS) at the very start itself but that does not display all the Unicode characters of lstr correctly. After setting 'rtb.text = lstr', I have to necessarily select the whole text of the rtb and set '*.SelFontCharset*' to 0 and '.SelFontName' to 'Arial Unicode MS' again. Then only all the characters will display correctly, as per their glyphs. Otherwise, some of the characters in some ranges would appear as boxes only. Why it happens so, I don't know. If krool can tell why and suggest a way by which the whole above process (all that processing I have to do after setting 'rtb.text = lstr') can be avoided, that would be great.
--

*Note-1*:
I did try out '.SelColor' too on my long text since you had difficulty with *'.SelColor'*. And, the result was the same, with my fix. It *was instant*. Otherwise (without my above fix), it was taking a considerable time (6 seconds in my system) to execute.

*Note-2*: 
The lstr (long string) which I am referring to is 77K+ characters, half of which are spaces and the other half are multilingual characters. Basically, multilingual characters (from 'Arial Unicode MS') separated by spaces. 

*Note-3*: 
If you or somebody can come out with a way to reduce the time taken by 'rtb.text = lstr' and '.SelLength' too, that would be great. In effect, if somebody can provide a way to reduce the whole processing time itself, as such, to a millisecond, that would be great. Because, if it still takes 5 seconds in my 16gb system, I am sure the whole process would take more time in a 4gb system. Suppose it takes 30 seconds. Then, 30 seconds would be too long a time, I feel, to set an rtb with a string of 77k+ characters.

*Note-4*: 
Yesterday I found out that introducing 'DoEvents', at some points in the above process, seemed to smoothen out the process a bit. But, today, I found out that 'rtb.Refresh' itself (in place of DoEvents) was enough to see that bit of smoothening in the process but then using 'rtb.Refresh' was causing some mild flashes in the screen. So, finally, I tried using '*rtb.ResetUndoQueue*' before/after every .SelXyz setting and that looks promising for me. It is *very smooth* now.

I really do not know whether my fixes/findings above which worked out for me would work out for you too (in the case of your .SelColor), in a significant manner. If it does, I would be happy indeed. But, even otherwise, my fixes/findings above may be of help to somebody in this forum, now or in future, I believe. It may perhaps help krool too to come out with some *enhancements* (for instance, like the recent UseCrLf property) *to the rtb control,* in the future.

Kind regards.

----------


## softv

> I use this function to detect UTF8 without BOM. Just get a max of 1000 bytes from file (if less get all bytes from file)
> 
> 
> 
> ```
> Public Function ContainsUTF8(ByRef Source() As Byte) As Boolean
>   Dim i As Long, lUBound As Long, lUBound2 As Long, lUBound3 As Long
>   Dim CurByte As Byte
>     lUBound = UBound(Source)
> ...


Thank you ever so much, for both your codes. I think when I find time to walk through your codes, I will understand them precisely (as to how they effect their intended tasks).

Kind regards.

----------


## Eduardo-

Hello Krool,

I added a ListBoxW with Style to CheckBox, but it seems that the items selected set by code have no effect:



```
    ListBoxW1.AddItem "AAA"
    ListBoxW1.Selected(ListBoxW1.NewIndex) = True
    ListBoxW1.AddItem "BBB"
    ListBoxW1.Selected(ListBoxW1.NewIndex) = True
    ListBoxW1.AddItem "CCC"
```

Edit: I just found the new property ItemChecked. Anyway, it seems to be an issue for backward compatibility with the VB.ListBox.

----------


## Krool

> Hello Krool,
> 
> I added a ListBoxW with Style to CheckBox, but it seems that the items selected set by code have no effect:
> 
> 
> 
> ```
>     ListBoxW1.AddItem "AAA"
>     ListBoxW1.Selected(ListBoxW1.NewIndex) = True
> ...


Yes it's a difference... The VB ListBox has no way to programmatically select items.

----------


## Eduardo-

> yes it's a difference... The vb listbox has no way to programmatically select items.


Ok, thanks.

----------


## TomasEss

Hi
My project has used VBCCR11.OCX successfully :-) for a long time. Now I thought I would upgrade to 17.
My *DTPicker* controls now no longer have the *ShowCalendar* method. Is this intentional? I have not found anything about it in this thread.
Am I supposed to be able to programmatically show it some other way?

----------


## Krool

> Hi
> My project has used VBCCR11.OCX successfully :-) for a long time. Now I thought I would upgrade to 17.
> My *DTPicker* controls now no longer have the *ShowCalendar* method. Is this intentional? I have not found anything about it in this thread.
> Am I supposed to be able to programmatically show it some other way?


It must be replaced by the .DroppedDown property (get/let).

----------


## OldClock

[deleted, obsolete]

----------


## OldClock

[deleted, obsolete]

----------


## samer22

Krool
please could you tell why labelws and CommandButtonWs are showing Arabic language like this:

thanks

----------


## Mith

> please could you tell why labelws and CommandButtonWs are showing Arabic language like this:


I cant reproduce this problem here using Window 7 with VBCCR1.7:



All controls use the standard font "MS Sans Serif".

MAybe your problem has something to do with your windows unicode settings for non-unicode programs.
From my experience i can tell you that this windows setting can screw up the unicode display of vb apps.

----------


## samer22

thanks Mith  for your interest
Could you try format "Arab Egypt " and location "Egypt" in regional settings.
I'm using Window 7 with VBCCR1.7 too

----------


## Krool

It's recommended to use the better Microsoft Sans Serif font instead of MS Sans Serif.

----------


## samer22

> It's recommended to use the better Microsoft Sans Serif font instead of MS Sans Serif.


thanks but still no luck
Same issue with VbFlexgrid

----------


## Mith

> Could you try format "Arab Egypt " and location "Egypt" in regional settings.


I work with a german Windows version. You should try another format and location because i dont have any problems here  :Smilie:

----------


## Semke

how does the CommandButtonW.ImageList work with Picture DisabledPicture and DownPicture?

do i need a separate ImageList for each CommandButtonW/Picture-type

also i noticed that the MaskColor/UseMaskColor don't work when using picture without ImageList

----------


## Krool

> how does the CommandButtonW.ImageList work with Picture DisabledPicture and DownPicture?
> 
> do i need a separate ImageList for each CommandButtonW/Picture-type
> 
> also i noticed that the MaskColor/UseMaskColor don't work when using picture without ImageList


MaskColor is only applicable for Style = 1 Graphical.
Same with DownPicture and DisabledPicture.

For Style = 0 Normal you can either use Picture or ImageList.


```
' The image list should contain either a single image to be used for all states or
' individual images for each state. The following states are defined as following:
    ' PBS_NORMAL = 1
    ' PBS_HOT = 2
    ' PBS_PRESSED = 3
    ' PBS_DISABLED = 4
    ' PBS_DEFAULTED = 5
    ' PBS_STYLUSHOT = 6
```

----------


## brandoncampbell

Hey Krool - I swear I saw somewhere a discussion on adding the ability for png files but I cant find it. Can you point me in the right direction? 

Edited - I think I found it. It was a convo between you and Trick. I guess it still isn't supported.

----------


## PauloFranc

Hello,
I'm using the VBCCR16.OCX and I want to upgrade to VBCCR17.OCX but the VisualStyles.bas of the VBCCR17 doesn't include the SetupVisualStyles function or the InitVisualStyles.
With the VBCCR16, I had on the top of each form "SetupVisualStyles(me)", isn't this necessary anymore?

Thanks

----------


## Krool

> Hello,
> I'm using the VBCCR16.OCX and I want to upgrade to VBCCR17.OCX but the VisualStyles.bas of the VBCCR17 doesn't include the SetupVisualStyles function or the InitVisualStyles.
> With the VBCCR16, I had on the top of each form "SetupVisualStyles(me)", isn't this necessary anymore?
> 
> Thanks


You shall take VisualStyles.bas from the demo in post #1 of this thread.

----------


## PauloFranc

> You shall take VisualStyles.bas from the demo in post #1 of this thread.


Thanks for the reply and thanks a lot for you work  :Smilie:

----------


## Eduardo-

Hello Krool, I'm using the latest compiled version of the ocx (VBCCR17.OCX), and I'm seeing some issues regarding the CheckBoxW:

1) I find no way to disable the focus rect.
I'm using Windows 11 with visual styles enabled (I guess Windows 10 must be the same) and the original VB CheckBox does not show the focus rect when visual styles are enabled.

2) The property "Custom" that is supposed to display the property pages seems to just change the Value property.

3) The property Transparent does not work at design time, but that is probably by design.

PS: I didn't go to check the control's source code.

----------


## Krool

> Hello Krool, I'm using the latest compiled version of the ocx (VBCCR17.OCX), and I'm seeing some issues regarding the CheckBoxW:
> 
> 1) I find no way to disable the focus rect.
> I'm using Windows 11 with visual styles enabled (I guess Windows 10 must be the same) and the original VB CheckBox does not show the focus rect when visual styles are enabled.
> 
> 2) The property "Custom" that is supposed to display the property pages seems to just change the Value property.
> 
> 3) The property Transparent does not work at design time, but that is probably by design.
> 
> PS: I didn't go to check the control's source code.


Hi Eduardo,

1) When an app is themed it has no focus rect but it will show focus rects once you use the tab key once on a window. However, this does not work in VB6. That's why the focus rect are forced in the CheckBoxW control via WM_UPDATEUISTATE. Also the VisualStyles.bas uses WM_UPDATEUISTATE on the SetupVisualStyles method for the whole form.
If you have another approach in mind please let me know or discuss it.

2) The Value property is the default property. The CheckBoxW has no property page, that's why the "Custom" is falling back to the Value property.

3) Yes that's ignored at design time. The property description also tells this.

----------


## Eduardo-

> Hi Eduardo,
> 
> 1) When an app is themed it has no focus rect but it will show focus rects once you use the tab key once on a window. However, this does not work in VB6. That's why the focus rect are forced in the CheckBoxW control via WM_UPDATEUISTATE. Also the VisualStyles.bas uses WM_UPDATEUISTATE on the SetupVisualStyles method for the whole form.
> If you have another approach in mind please let me know or discuss it.


I would have to study what you are saying.
I just wanted to put some CheckBoxes with no caption, and I got this:



For now I solved it by making the CheckBoxes narrower enough.




> 2) The Value property is the default property. The CheckBoxW has no property page, that's why the "Custom" is falling back to the Value property.


When an UserControl has no property page, the "Custom" property does not appear at the property page.
I checked and the CheckBoxW has defined three property pages:

StandardFont
StandardColor
StandardPicture

The problem seems to be the call: 



```
Call SetVTableHandling(Me, VTableInterfacePerPropertyBrowsing)
```

At UserControl_Initialize.
I think one solution might be to call it at UserControl_InitProperties and UserControl_ReadProperties but only when Ambient.UserMode is False.




> 3) Yes that's ignored at design time. The property description also tells this.


OK.

Thanks  :Thumb:

----------


## Krool

> When an UserControl has no property page, the "Custom" property does not appear at the property page.
> I checked and the CheckBoxW has defined three property pages:
> 
> StandardFont
> StandardColor
> StandardPicture
> 
> The problem seems to be the call: 
> 
> ...


I found out the reason. The (Custom) item raises IPerPropertyBrowsingVB::GetPredefinedStrings with an DispID of 0.
But since the Value property is the default property it also has a DispID of 0... (const DISPID_VALUE; 0)

So, it's unfortunate but I think it can be only fixed by using an Enum (As Long) instead of having the property As Integer currently.
But that would break VBCCR17 compatibility. So it's unlikely to be changed. And it's anyway just a minor glitch as there is no real property page behind anyway.

----------


## Eduardo-

> I found out the reason. The (Custom) item raises IPerPropertyBrowsingVB::GetPredefinedStrings with an DispID of 0.
> But since the Value property is the default property it also has a DispID of 0... (const DISPID_VALUE; 0)
> 
> So, it's unfortunate but I think it can be only fixed by using an Enum (As Long) instead of having the property As Integer currently.
> But that would break VBCCR17 compatibility. So it's unlikely to be changed. And it's anyway just a minor glitch as there is no real property page behind anyway.


IDK what that call does, I mean Call SetVTableHandling(Me, VTableInterfacePerPropertyBrowsing)
What is the purpose?

----------


## Krool

> IDK what that call does, I mean Call SetVTableHandling(Me, VTableInterfacePerPropertyBrowsing)
> What is the purpose?


For example to list all ImageLists available etc. in a property

----------


## Eduardo-

> For example to list all ImageLists available etc. in a property


Ah, OK. Then my suggestion of calling it only at runtime made no sense.

----------


## Mustaphi

Does anyone know  how to set listview ColumnHeaders  width?


```
ListView1.ColumnHeaders(1).Width = 200
```

this code is throwing error

----------


## jpbro

What's the error number & message?

----------


## jpbro

I tried this and it worked as expected without error:



```
Option Explicit

Private Sub Form_Click()
   Me.ListView1.ColumnHeaders(1).Width = 10000
End Sub

Private Sub Form_Load()
   Me.ListView1.ColumnHeaders.Add , , "A"
   Me.ListView1.ColumnHeaders.Add , , "B"
   Me.ListView1.ColumnHeaders.Add , , "C"
   
   Me.ListView1.View = LvwViewReport
End Sub
```

----------


## Mustaphi

> What's the error number & message?


incorrect argument
Are you using Krool's listview?
Anyway i figured out how to do that


```
ListView1.ColumnHeaders.Add , , "Name", 2000, LvwColumnHeaderAlignmentLeft
ListView1.ColumnHeaders.Add , , "Symbol", 1200, LvwColumnHeaderAlignmentCenter
```

thank you

----------


## jpbro

> Are you using Krool's listview?


Yes, I tried it with v1.7 of the OCX version of Krool's controls and there was no problem. Maybe you are using a different version?

----------


## PauloFranc

Hi,
I have the sub main call the main form of the application, an MDI frm, but it doesn't even show the form giving "Run-time error 440: Automation error"
My problem is that this only happens on some PCs, one of them has Windows 7 and I found out that reducing the colour depth it stopped giving this problem. But I am now trying to run it on a Windows Server 2003 and can't get it to work.

Does anyone have any ideas about what can be happening?


Thanks

----------


## PauloFranc

Found it... I have a toolbar linked to imagelists with the icons I need. The last two icons had a colour depth bigger than the others and older PCs couldn't cope with that.
Since the automation error was being shown in a window with VBCCR17 in the title, I never thought that could be the problem.

----------


## hausman

Hello Krool, thanks making and maintaining these controls!  I have two questions/issues; apologies if these have been covered.

ComboBoxW - is there a reason that the Text property isn't the default?

MonthView - the latest version is better than the 1.5 version I was using previously, but when setting VisualStyles = False, the runtime size is still not quite the same size as the design-time size.  Testing at normal DPI, font = Arial Regular 10.

Thanks!
Dan

----------


## hausman

One more:

MonthView - DateDblClick

----------


## Krool

> ComboBoxW - is there a reason that the Text property isn't the default?
> 
> MonthView - the latest version is better than the 1.5 version I was using previously, but when setting VisualStyles = False, the runtime size is still not quite the same size as the design-time size.  Testing at normal DPI, font = Arial Regular 10.


ComboBoxW -  That's a bug! The VB.ComboBox has a hidden [_Default] property that redirects to the Text property. The VB.Label has the same logic and the LabelW control considered that but unfortunately not for the ComboBox...
Will look to fix that, hopefully possible for VBCCR17 without breaking.

MonthView - maybe the IDE is not manifest and links to comctl. 5.8x and the compiled executable has a manifest and is linked to comctl. 6.x. (even if both are not themed [VisualStyles = False] the controls are different)
What you mean with DateDblClick ? Please more context on that one.

----------


## Krool

Update released.

Included the GetTextRange function in the RichTextBox control.

Included [_Default] property in ComboBoxW/FontCombo/VirtualCombo/ImageCombo.
The MS ImageCombo doesn't have a default property, but I think it is of no harm to make the .Text property as the default member there as well.

The OCX VBCCR17 was also updated. The internal type lib version is now 1.2.



```
Object={7020C36F-09FC-41FE-B822-CDE6FBB321EB}#1.2#0; VBCCR17.OCX
```

----------


## hausman

> ComboBoxW -  That's a bug! The VB.ComboBox has a hidden [_Default] property that redirects to the Text property. The VB.Label has the same logic and the LabelW control considered that but unfortunately not for the ComboBox...
> Will look to fix that, hopefully possible for VBCCR17 without breaking.


FYI, I had changed the Attribute Text.VB_UserMemId = *0* to accomplish this.  Not sure which method is best.




> MonthView - maybe the IDE is not manifest and links to comctl. 5.8x and the compiled executable has a manifest and is linked to comctl. 6.x. (even if both are not themed [VisualStyles = False] the controls are different)


Sorry, yes, you are correct.  The EXE is running with a manifest, while the IDE is not.  I think I remember seeing an article about putting a manifest on the IDE EXE... I'll look into that.




> What you mean with DateDblClick ? Please more context on that one.


DateDblClick is an event in the stock MonthView control in Common Controls 2.  *Private Sub MonthView1_DateDblClick(ByVal DateDblClicked As Date)*.  It comes in handy when using the MonthView as a pop-up control, and double-clicking on the date selects it and closes the popup.

----------


## Krool

> FYI, I had changed the Attribute Text.VB_UserMemId = *0* to accomplish this.  Not sure which method is best.
> 
> DateDblClick is an event in the stock MonthView control in Common Controls 2.  *Private Sub MonthView1_DateDblClick(ByVal DateDblClicked As Date)*.  It comes in handy when using the MonthView as a pop-up control, and double-clicking on the date selects it and closes the popup.


The Text property cannot have the DISPID_TEXT and DISPID_DEFAULT at the same time. Thus the hidden helper property.

DateDblClick - ooh missed that one. However, the MonthView (SysMonthCal32 window) doesn't have the CS_DBLCLKS style, so it won't fire any WM_LBUTTONDBLCLK.

----------


## Mustaphi

hi krool
i wanted to Create a ComboBox inside a Listview as the demo in the link but it is not possible.
The demo works fine with the MS common listview

Create a ComboBox inside a Listview

the error type mismatch  occurs here


```
Public Sub GetLVCellData(pobjLV As ListView, _
                         psngX As Single, _
                         psngY As Single, _
                         ByRef pstrCellText As String, _
                         ByRef plngItemIndex As Long, _
                         ByRef plngSubItemIndex As Long)
    
    Dim HTI As LVHITTESTINFO
    Dim lst As ListItem

    With HTI
        .pt.X = (psngX \ Screen.TwipsPerPixelX)
        .pt.Y = (psngY \ Screen.TwipsPerPixelY)
        .Flags = LVHT_ONITEM
    End With
      
    SendMessage pobjLV.hwnd, LVM_SUBITEMHITTEST, 0, HTI

    If (HTI.iItem > -1) Then

        Set lst = pobjLV.ListItems(HTI.iItem + 1)

        plngItemIndex = HTI.iItem + 1
        plngSubItemIndex = HTI.iSubItem
        
        If HTI.iSubItem = 0 Then
            pstrCellText = pobjLV.ListItems(HTI.iItem + 1).Text
        Else
            pstrCellText = pobjLV.ListItems(HTI.iItem + 1).SubItems(HTI.iSubItem)
        End If
    Else
        pstrCellText = ""
        plngItemIndex = 0
        plngSubItemIndex = 0
    End If

End Sub
```

 

```
GetLVCellData lvwDemo, _
                  X, _
                  Y, _
                  mstrOriginalCellText, _
                  mlngClickedItemIndex, _
                  mlngClickedSubItemIndex
```

----------


## Krool

> hi krool
> i wanted to Create a ComboBox inside a Listview as the demo in the link but it is not possible.
> The demo works fine with the MS common listview
> 
> Create a ComboBox inside a Listview
> 
> the error type mismatch  occurs here
> 
> 
> ...


It's LvwListItem and not anymore ListItem. Also please remove the references to MS common controls.

----------


## Attilio

It's simple to implement that? 
In the past years, I had added the manifest in my project. Hower the project was too slow

----------


## Erwin69

Hi Krool, is it possible to fix columns in the listview control, like it is with the VBFlexGrid control?

----------


## Eduardo-

Hello Krool,

I think I found a bug in the ComboBoxW: the Text property cannot be changed from inside the Click event.

To test it, add a VB.Combo and a ComboBoxW to a form, default style Dropdown List, and this code:



```
Private Sub Form_Load()
    Combo1.AddItem "Item 1"
    Combo1.AddItem "Item 2"
    Combo1.AddItem "Item 3"
    
    ComboBoxW1.AddItem "Item 1"
    ComboBoxW1.AddItem "Item 2"
    ComboBoxW1.AddItem "Item 3"
End Sub

Private Sub Combo1_Click()
    Combo1.Text = Combo1.Text & " (" & Combo1.ListIndex & ")"
End Sub

Private Sub ComboBoxW1_Click()
    ComboBoxW1.Text = ComboBoxW1.Text & " (" & ComboBoxW1.ListIndex & ")"
End Sub
```

PS: I'm using the OCX

----------


## Eduardo-

Some bugs with the DTPicker:

1) The CheckBox of the DTPicker control appears too big at 120 DPI:




The other controls are from your control set too, and they display the checkbox properly.


2) The default date is not the current date.
In my user locale I have this setting: "d/m/yyyy", today it is 23/3/2022 (March 23 of 2022) and the control displays "3/ 1/2022" (January 3 of 2022)

Thanks for your work. It is becoming the default control set to use (specially for globalized programs UI, since that needs Unicode support).

----------


## Eduardo-

In the CommonDialog object, the ShowFolderBrowser method does not show the new folder button, and there is a flag, but only to hide the button: CdlBIFNoNewFolderButton.

----------


## Eduardo-

I'm using your component more and more, so I hope you don't mind if I keep reporting bugs and making suggestions.

For having full Unicode replacement, I see that the Kill Statement should be also replaced.



```
Private Declare Function DeleteFileW Lib "kernel32.dll" (ByVal lpFileName As Long) As Long

' (VB-Overwrite)
Public Sub Kill(ByVal sFileName As String)
    If DeleteFileW(StrPtr(sFileName)) = 0 Then
        Err.Raise 70
    End If
End Sub
```

----------


## clintc

Hello Krool,
I am getting error 35773 with the DTPicker when trying to enter time in 24 hour format.
How can I resolve this?
Thank you!

Edit:
Ok, I found out what is happening.
The DTP was set to use DataFormat "Time"
I was setting the DTP value to TimeSerial(), but I didn't take into consideration, that TimeSerial also returns a default date of 31-12-1899, and the MinDate property wasn't set to at least that (which may be another problem - Errors out if set less)

Otherwise, for me, it works now.

Edit again: 
I thought it was working, but the DTP MinDate property doesn't accept a date less than 31-12-*1900*.

----------


## Mith

VB6SP6, Win7, VBCCR 1.7.37

hi Krool,

i found an annoying bug using the textbox control inside a picture control:

1. The textbox has the focus with the cursor.
2. now i click on the picture control (parent)
3. The validate event of the textbox is not triggered...

If i use TAB or click on another textbox on the form the validate event of the textbox is triggered!

BTW: The VB-textbox in a picture control still triggers the validate event when i click on the picturebox!

Any ideas how to fix this?

----------


## Krool

> VB6SP6, Win7, VBCCR 1.7.37
> 
> hi Krool,
> 
> i found an annoying bug using the textbox control inside a picture control:
> 
> 1. The textbox has the focus with the cursor.
> 2. now i click on the picture control (parent)
> 3. The validate event of the textbox is not triggered...
> ...


I can't replicate with the OCX or std-exe. Can you bundle a demo?

----------


## Mith

> I can't replicate with the OCX or std-exe. Can you bundle a demo?


Attached you will find my demo project.

How to reproduce instructions:

1. click inside the TextBox*W* control
2. now click on the picture control under the TextBox*W*
3. the validate event doesnt trigger and no msgbox will show up

1. click inside the VB-TextBox control
2. now click on the picture control under the VB-TextBox
3. the validate event works and a msgbox will show up

goofy:

1. click inside the TextBox*W* control
2. now click inside the VB-TextBox control
3. now the validate event works and a msgbox will show up!

BTW:

i tested this inside the IDE and with a compiled exe. both the same results. tested with win7x64.

----------


## Krool

Mith,
it looks like a VB6 bug itself.

When I place a new innocent UserControl on a PictureBox it has the same issue.

Maybe others may comment on this VB6 bug. It should be a known issue somehow.

----------


## Mith

> it looks like a VB6 bug itself.
> When I place a new innocent UserControl on a PictureBox it has the same issue.


Thanks for the information!
In this case the use of the validate event is complete useless...
I got some bug reports from users and never understood why!
Now i understand it, because the validation code for the textbox content was never triggered!

----------


## Mith

> Maybe others may comment on this VB6 bug. It should be a known issue somehow.


i found an answer at StackOverflow

----------


## Krool

> Hello Krool,
> I am getting error 35773 with the DTPicker when trying to enter time in 24 hour format.
> How can I resolve this?
> Thank you!
> 
> Edit:
> Ok, I found out what is happening.
> The DTP was set to use DataFormat "Time"
> I was setting the DTP value to TimeSerial(), but I didn't take into consideration, that TimeSerial also returns a default date of 31-12-1899, and the MinDate property wasn't set to at least that (which may be another problem - Errors out if set less)
> ...


The MinDate for DTP is 01-01-1900 and MaxDate is 31-12-9999.




> Some bugs with the DTPicker:
> 
> 1) The CheckBox of the DTPicker control appears too big at 120 DPI:
> 
> 
> 
> 
> The other controls are from your control set too, and they display the checkbox properly.
> 
> ...


1) I have no influence about the appearance on high DPI for the DTP.

2) You may set the today's date at Form_Load.

----------


## Niya

> i found an answer at StackOverflow


That is VB.Net code. If the problem is the same one you're having then it might not even be a VB6 problem but it is instead a Windows problem, specifically a problem with the Common Controls.

----------


## Crapahute

Hi,
Ive got difficulties to print a RichTextBox on a printer.



```
    Printer.CurrentX = 800
    Printer.CurrentY = 800
    Printer.Print "x"
    
    RichTextBox1.PrintDoc Printer.hDC, False, , 700, 700, 800, 800
    
    Printer.CurrentX = 900
    Printer.CurrentY = 900
    Printer.Print "y"
    
    Printer.EndDoc
```

In this example, I would like to print x, y and RichTextBox1 on the same page, but I always get x and RichTextBox1 on one page and y on another one.

It is as if RichTextBox1.PrintDoc fires a Printer.EndDoc even if I set CallStartEndDoc to False.

What am I doing wrong ?

----------


## MSI-Packager

Hi Krool,

i have encountered some situations where case sensitive entries for Treeview were required, since they contained different data, like registry and Registry having different registry keys. This works well with the microsoft control, but not with the CCR Treeview. I am using the std exe and somehow I managed to get a working case sensitive option in the property page and the control so I am happy for now. I don't know if it could be a useful addition for other people as well.

----------


## Semke

is it possible to have a toolbar button style to be TbrButtonStyleCheck and TbrButtonStyleDropDown

----------


## Krool

> is it possible to have a toolbar button style to be TbrButtonStyleCheck and TbrButtonStyleDropDown


Unfortunately not. BTNS_CHECK and BTNS_DROPDOWN are not combinable.

----------


## Semke

is it possible to add images to Toolbar ButtonMenus

BTW: Your Project is fantastic I use a a lot, Thank you

----------


## yereverluvinuncleber

PROBLEM: I am populating a control's dragIcon from an MSCOMCTL imageList control but the resulting dragIcon is black when I use Krool's imageList. However, it all works fine with the MSCOMCTL imageList control.



BACKGROUND:
The source image is a PNG. The source image is written to a temporary picBox named picDragIcon using the picbox device context using GDI+, specifically, GdipDrawImageRectRectI. To accomplish this, I am using LaVolpe's C32dppDIP method to read PNGs into a VB6 picture control. In this case the picbox is merely a temporary holding control and I want to put that image into a dragIcon.


First step, I use an MSCOMCTL imageList and add the image from the temporary picbox as the sole image in the imageList.



```
    ImageList1.ListImages.Add , "arse", picDragIcon.Image
```

I then extract that image from the imageList and set it to be the dragIcon for the target control.



```
    picRdMap(Index).DragIcon = ImageList1.ListImages("arse").ExtractIcon
```

As a result, the dragIcon shows perfectly. Why do I use an imageList? If I load the dragIcon directly from the temporary picBox as below:



```
    picRdMap(Index).DragIcon = picDragIcon.Image ' this only works for .ico types
```

Then the dragIcon shows nothing, nothing at all. I think it is due to the fact that the temporary image is rendered using GDI+ or only handles .ico types. That is why I use the MSCOMCTL imageList as it somehow seems to convert the GDI+ rendered image on the picBox correctly to something the .dragIcon can use. Some sort of bitmap, anyhow, it does the job.

However, back to my problem. I want to use Krool's version of the imageList control. I prefer to use Krool's imageList as I have so far avoided using any control from MSCOMCTL instead using all of Krool's alternatives.



If I substitute Krool's imagelist the dragicon is a black square. Any ideas? I suspect this is because Krool's control is not expecting a transparent image in a standard picturebox. Any guidance would be useful.

----------


## Niya

My guess is that Krool's ImageList isn't converting converting the HBITMAP to an HICON properly for this specific image. Have you tried writing your own conversion?

----------


## yereverluvinuncleber

> My guess is that Krool's ImageList isn't converting converting the HBITMAP to an HICON properly for this specific image. Have you tried writing your own conversion?


I was hoping not to have to, hoping that the Krool version would simply provide the same conversion. I may have to do so though.

For the moment though I will stick with the MSCOMCTL version as it works. We'll just have to see if this is a bug in Krool's own imageList or missing functionality.

----------


## Niya

Ah ok. Fair enough.

----------


## Krool

> PROBLEM: I am populating a control's dragIcon from an MSCOMCTL imageList control but the resulting dragIcon is black when I use Krool's imageList. However, it all works fine with the MSCOMCTL imageList control.
> 
> 
> 
> BACKGROUND:
> The source image is a PNG. The source image is written to a temporary picBox named picDragIcon using the picbox device context using GDI+, specifically, GdipDrawImageRectRectI. To accomplish this, I am using LaVolpe's C32dppDIP method to read PNGs into a VB6 picture control. In this case the picbox is merely a temporary holding control and I want to put that image into a dragIcon.
> 
> 
> First step, I use an MSCOMCTL imageList and add the image from the temporary picbox as the sole image in the imageList.
> ...


Thanks for the report. I just want to test something.

Instead of


```
ImageList1.ListImages.Add , "arse", picDragIcon.Image
```

can you test following ?


```
Set picDragIcon.Picture = picDragIcon.Image
ImageList1.ListImages.Add , "arse", picDragIcon.Picture
```

If that works (if you confirm) the bugfix in the ImageList would be (in order to get your initial code to work)


```
Friend Sub FListImagesAdd(Optional ByVal Index As Long, Optional ByVal Picture As IPictureDisp)
...
    Set UserControl.Picture = Picture
    Set Picture = UserControl.Picture
    Set UserControl.Picture = Nothing
...
```

----------


## Seniorchef

Hello, Krool!

I'm trying to work with the richtext control from the replacement of the common controls, latest version.
It seems to be impossible to set the right margin so that it reflects the textwidth of a line, e.g. a right margin of 500 units should lead to a textwidth of 500 units (no left margin set), regardless of the width of the control. 
But any positive value of a right margin leads to constant space between the control's right edge and the text, wrapping the text (according to the scrollbars setting). 
How do I set a right margin to reflect the textwidth? 

Regards, Seniorchef

----------


## yereverluvinuncleber

Krool, your workaround of using set with .picture works. The resulting image is not exactly the same but it will certainly do.

With your control the .dragIcon becomes a white box surrounding the original image, which is different but perfectly acceptable for what I want to do



The MS imageList in comparison creates a dragIcon with a transparent background in BOTH cases. I suppose (as Niya suggests) that the MS version is converting it to an HIcon.

Sorry to give you more work. At least this means I can continue to avoid using MSCOMCTL except for testing.

----------


## Krool

> Krool, your workaround of using set with .picture works. The resulting image is not exactly the same but it will certainly do.
> 
> With your control the .dragIcon becomes a white box surrounding the original image, which is different but perfectly acceptable for what I want to do
> 
> 
> 
> The MS imageList in comparison creates a dragIcon with a transparent background in BOTH cases. I suppose (as Niya suggests) that the MS version is converting it to an HIcon.
> 
> Sorry to give you more work. At least this means I can continue to avoid using MSCOMCTL except for testing.


You could try setting the UseMaskColor to true and set the MaskColor accordingly. (You need to check the exact RGB, probably it's only vbWhite value)

EDIT: gonna update the fix with the UserControl.Picture and Picture object swap. (to allow passing an *.Image* picture object)

----------


## yereverluvinuncleber

I'll leave it as it is at the moment, setting the mask colour to white does the job of making the dragIcon transparent but it has side effects -  other unrelated controls on the form suddenly have their mask turned off revealing the black portions of all their transparencies.



To get around this I tried enabling and disabling the use of the mask just prior to the vbBeginDrag,

ImageList1.UseMaskColor = True

- then disabling it when the vbEndDrag has done its job, it seems that UseMaskColor is not a property that can be easily be enabled at the correct points at runtime.

For the moment the white box is a usable workaround. I'll wait for any bugfix and test for you. No hurry, I have a workaround!

----------


## Krool

> I'll leave it as it is at the moment, setting the mask colour to white does the job of making the dragIcon transparent but it has side effects -  other unrelated controls on the form suddenly have their mask turned off revealing the black portions of all their transparencies.
> 
> 
> 
> To get around this I tried enabling and disabling the use of the mask just prior to the vbBeginDrag,
> 
> ImageList1.UseMaskColor = True
> 
> - then disabling it when the vbEndDrag has done its job, it seems that UseMaskColor is not a property that can be easily be enabled at the correct points at runtime.
> ...


The fix is released.

You only need the MaskColor "active" during the .Add to the ImageList. So you can turn it on before, add picture to the ImageList, then turn off in the next code line.

Btw, UseMaskColor property is True by default. The MaskColor default is &HC0C0C0.

----------


## yereverluvinuncleber

> The fix is released.
> 
> You only need the MaskColor "active" during the .Add to the ImageList. So you can turn it on before, add picture to the ImageList, then turn off in the next code line.
> 
> Btw, UseMaskColor property is True by default. The MaskColor default is &HC0C0C0.


understood and thanks!

----------


## Seniorchef

Okay, here I am again.
My issue about the richtext-control still is unanswered.
No hints, no solutions, no questions?
Anyone out there who uses the richtextbox and margins?
Maybe I'm using the wrong documentation, but what is the right one?
Thank's

----------


## Krool

> Okay, here I am again.
> My issue about the richtext-control still is unanswered.
> No hints, no solutions, no questions?
> Anyone out there who uses the richtextbox and margins?
> Maybe I'm using the wrong documentation, but what is the right one?
> Thank's


I hate this printer margin topic on the richtextbox. It was an issue already several times and I thought now it's properly done.
So, do you have a sample demo which shows the different outcomes between MS richttextbox and VBCCR richtextbox ?
Because as of now I would first suspect a mis-use in your code and not in the routine inside the richtextbox, but I could be wrong of course.

----------


## Seniorchef

Hello, Krool!

I never mentioned a printer output.

For The sample, you need a form with a MSRichtext-control and a VBCCR-Richtext control with not extra settings.



```
Private Sub Form_Load()
   With msRtf
      .RightMargin = 2500
      .Text = "This is a sample text in the richtext control with a right margin on "
   End With
   
   With vbRtf
      .RightMargin = 2500
      .Text = "This is a sample text in the richtext control with a right margin on "
   End With
End Sub

Private Sub Form_Resize()
   msRtf.Move 30, 30, ScaleWidth, ScaleHeight / 2
   vbRtf.Move 30, ScaleHeight / 2 + 30, ScaleWidth, ScaleHeight / 2
   vbRtf.Refresh
   msRtf.Refresh
End Sub
```

Drag the window to change the width and you see the difference: the msRichtext keeps the text unchanged while the vbcontrol doesn't. The RightMargin in the MSRtf is independant from the width of the control. That's all. 

My App shows text in forms that can be formatted by the user, for which purpose ever. The formatting of paragraphs should stay even after resizing the window.

Regards

----------


## Krool

> Hello, Krool!
> 
> I never mentioned a printer output.
> 
> For The sample, you need a form with a MSRichtext-control and a VBCCR-Richtext control with not extra settings.
> 
> 
> 
> ```
> ...


I see your point. I guess that's a behavior change in the underlying richedit library. The msRichTextBox uses richedit v1.0.

----------


## Seniorchef

Ok - so I guess i will live with it.
Maybe I'll write a workaround in my code.
And again, thank you, Krool.

----------


## clintc

Hallo Krool,

https://www.vbforums.com/showthread....=1#post5563715




> The MinDate for DTP is 01-01-1900 and MaxDate is 31-12-9999.


So, this is not possible:


```
DTPicker.Value = TimeValue("07:00")
```

----------


## Mith

VB6, Win7x64

I upgraded VBCCR 1.7.37 to VBCCR 1.7.38. and now i get the error message "_object library not registered_" when i open a VB6 project that is using the ocx.

I get the same error message when i create a complete new project at the VB6-IDE and add the VBCCR17-OCX. I can add the older VBCCR16-OCX or other OCX-files without any errors.

I tried to switch back to VBCCR 1.7.37 but it doesnt help; the error message "_object library not registered_" still pops up.

I tried to unregister and re-register but nothing helps.

The vb-projects-exe-files compilied with v1.7.37 are running fine with the new VBCCR 1.7.38 OCX!

But i cant open and use any of my vb-projects anymore  :Sick: 

Im lost and need some help...

----------


## Mith

i found a solution for the "object library not registered" problem:



```
cd C:\Windows\SysWOW64
regtlib msdatsrc.tlb
```

All vb6-projects using VBCCR17 can be loaded without the error message again!

----------


## Schmidt

> i found a solution for the "object library not registered" problem:
> 
> 
> 
> ```
> cd C:\Windows\SysWOW64
> regtlib msdatsrc.tlb
> ```
> 
> All vb6-projects using VBCCR17 can be loaded without the error message again!


@Krool...

I think you should look into that (since it would break also the "regfree-mode" via manifests)...

IMO, somewhere you're probably exposing a type from msdatsrc.tlb on the OCX'es Public Interface...

Olaf

----------


## Krool

> @Krool...
> 
> I think you should look into that (since it would break also the "regfree-mode" via manifests)...
> 
> IMO, somewhere you're probably exposing a type from msdatsrc.tlb on the OCX'es Public Interface...
> 
> Olaf


Thanks for your comment.
I'm not willingly exposing it. I assume it's automagically due to DataBindingBehavior set to 1 - vbSimpleBound on some controls..

----------


## softv

Dear Krool,

*Warm Greetings!* Happy to be writing to you again, after quite some period of time, and getting the opportunity thus to thank you once again, profoundly, for your monumental efforts.

In this post, I have attached a *small project, a test app* ("1. Scrollbar issues in Richtextbox.zip") to highlight *two issues with scrollbars* which I encountered *while using the RichTextBox control*. 

A screenshot of the test app below, just after starting it.


A screenshot of the test app below, after clicking the two buttons in it, one after the other.


*Note-1*: Please do read the comments in my code, wherever they appear. Those comments are very important, as far as this 'test app' is concerned.
*
Note-2*: The scrollbars do reappear correctly in rtb1 and rtb2 once I start scrolling the texts in them.

*Note-3*: In case the scrollbars do appear correctly only, at your end, always, then kindly bear with me and *kindly let me know* what could be the mistake I am doing at my end which makes the scrollbars disappear or get painted incompletely. 

*Note-4*:
My vb6 IDE is themed. My OS is Windows10, 64-bit. Screen resolution is 1920*1080. Under 'Scale and Layout' in Display settings, it shows '100% (Recommended)'.

*Note-5*: If the above-explained issues do occur at your end too, but *if they are not due to your control*, then kindly let me know as to what I should do further. As of now, my own workarounds which I have mentioned (in the test app) do help solve the scrollbar issues in my projects. But then, for each RichTextBox, I need to necessarily have these workarounds.

*Note-6*: This is the 2nd time ever (and the first time ever, in this thread) that I am posting a project. So, if any mistake on my part in the way I have presented my project, kindly bear with me.

Kind regards.

----------


## chosk

Hi Krool,

I have been away from programming for a few years and am now back. First thing I look at is your controls and of course download the latest version. I have two computers Win 10 Pro 21H2 and since I am having this problem on only one, I know the problem is at my end. I have try for a few days but no luck so maybe I try asking here.

I am getting this error (screenshot) when I tried to open any of the Forms in the Std-Exe demo. Also has this error when I try to run the demo. Any idea where I should be looking?

Thank you.

----------


## Krool

> Hi Krool,
> 
> I have been away from programming for a few years and am now back. First thing I look at is your controls and of course download the latest version. I have two computers Win 10 Pro 21H2 and since I am having this problem on only one, I know the problem is at my end. I have try for a few days but no luck so maybe I try asking here.
> 
> I am getting this error (screenshot) when I tried to open any of the Forms in the Std-Exe demo. Also has this error when I try to run the demo. Any idea where I should be looking?
> 
> Thank you.


Just replace the OLEGuids.tlb with the latest version to your syswow64 folder.

----------


## chosk

> Just replace the OLEGuids.tlb with the latest version to your syswow64 folder.


Super. This fix it.

Thank you.

----------


## Erwin69

Hi Krool,

I'm using the ListView in Report-mode with a relatively high icon, which would allow at least 3 lines for the label.  However, even when I set LabelWrap to True, the label is displayed on one line, centered in the middle of the icon, and is cut off when it's too long for the available space.

Am I missing something, or is what I'm looking for simply not possible?

Thanks,
Erwin

----------


## Krool

> Hi Krool,
> 
> I'm using the ListView in Report-mode with a relatively high icon, which would allow at least 3 lines for the label.  However, even when I set LabelWrap to True, the label is displayed on one line, centered in the middle of the icon, and is cut off when it's too long for the available space.
> 
> Am I missing something, or is what I'm looking for simply not possible?
> 
> Thanks,
> Erwin


No, the ListView is "SingleLine" in report-mode.
The only way is the tile view mode where the sub-items are each separate lines. But it's similar to icon view.. so no report-mode style.

----------


## softv

> Dear Krool,
> 
> *Warm Greetings!* Happy to be writing to you again, after quite some period of time, and getting the opportunity thus to thank you once again, profoundly, for your monumental efforts.
> 
> In this post, I have attached a *small project, a test app* ("1. Scrollbar issues in Richtextbox.zip") to highlight *two issues with scrollbars* which I encountered *while using the RichTextBox control*. 
> 
> A screenshot of the test app below, just after starting it.
> Attachment 185088
> 
> ...


Any solution/suggestions, for the above two issues, Krool?

Just a gentle reminder only, Krool. Otherwise, I do understand your time constraints. 

Kind Regards.

----------


## Krool

softv, thranks for bringing this up again.
Should be fixed now.

----------


## Seniorchef

Hello!
As a late reply to my post #3393 (right margin in richtext) I want to share my solution for that issue with the forum.
As mentioned earlier, the right margin in the microsoft control behaves different from the right margin in the replacement control.
Here is my solution 


```
nHdc = CreateDC("Display", "", 0, 0)
SendMessage hwnd, EM_SETTARGETDEVICE, nHdc, ByVal mnRightMargin - LeftMargin
DeleteDC nHdc
```

Maybe the lines can be placed in then source of the control; I put them in my advanced usercontrol in my RightMargin Property.

Krool, if this was your intention when you mentioned the printer margin output - I got you wrong, sorry.

Anyway, I now can take full advantage of the improved control in my app.
Thanks and bye for now

----------


## cecelife

Hi Krool and thanks for your project!

I have developed for year an editing program for decoder channel list and used listview to show all data like channel, transponder, etc, i've implemented a OLE drag and drop for all listview to order manually the items and it works without no problem, setting OLEDragMode as vbOLEDragAutomatic and OLEDropMode as vbOLEDropManual. Event OLEDragDrop are raised and in OLEDragOver I can select the item over the mouse cursor. A strange problem appear when I substituted the ListView with your, version 1.7.37, using ocx control for IDE on Win 10 64. When i drag an item over the same control the cursor change do deny, Effect in OLEDragOver remain at 0 and the event OLEDragDrop are not raised, but this appens only when the property View is List or Report. I've tried to change the setting in controls demo in all mode possible but the problems remain, the correct behaviour happens only when drag an item from another control. In ListBox and TreeView instead all works properly. It's not possible with ListView to dragdrop an item in the same control when is in list or report mode? I hope that is a simple problem to solve and wait for your replay.

Thank you.

----------


## softv

> softv, thranks for bringing this up again.
> Should be fixed now.


Thanks a LOT, as always, for the update, dear Krool.

Kind Regards.

----------


## Krool

> I have developed for year an editing program for decoder channel list and used listview to show all data like channel, transponder, etc, i've implemented a OLE drag and drop for all listview to order manually the items and it works without no problem, setting OLEDragMode as vbOLEDragAutomatic and OLEDropMode as vbOLEDropManual. Event OLEDragDrop are raised and in OLEDragOver I can select the item over the mouse cursor. A strange problem appear when I substituted the ListView with your, version 1.7.37, using ocx control for IDE on Win 10 64. When i drag an item over the same control the cursor change do deny, Effect in OLEDragOver remain at 0 and the event OLEDragDrop are not raised, but this appens only when the property View is List or Report. I've tried to change the setting in controls demo in all mode possible but the problems remain, the correct behaviour happens only when drag an item from another control. In ListBox and TreeView instead all works properly. It's not possible with ListView to dragdrop an item in the same control when is in list or report mode? I hope that is a simple problem to solve and wait for your replay.


Thanks. Should be fixed now.




> Hello!
> As a late reply to my post #3393 (right margin in richtext) I want to share my solution for that issue with the forum.
> As mentioned earlier, the right margin in the microsoft control behaves different from the right margin in the replacement control.
> Here is my solution 
> 
> 
> ```
> nHdc = CreateDC("Display", "", 0, 0)
> SendMessage hwnd, EM_SETTARGETDEVICE, nHdc, ByVal mnRightMargin - LeftMargin
> ...


Ok, but EM_SETTARGETDEVICE should'nt be for margins at all. Why are you passing the margin at lParam ? It's suppossed to be a line width...

----------


## Seniorchef

So that's what I understood from MS's documentation here https://docs.microsoft.com/en-us/win...ettargetdevice. The linewidth is the width between left and right margin. When the left margion is 0 that makes the right margin the linewidth.
The code in my snippet sets the linewidth and all text in the control is wrapped at that mark, like in the MS control in my sample.
Greetings

----------


## Krool

> So that's what I understood from MS's documentation here https://docs.microsoft.com/en-us/win...ettargetdevice. The linewidth is the width between left and right margin. When the left margion is 0 that makes the right margin the linewidth.
> The code in my snippet sets the linewidth and all text in the control is wrapped at that mark, like in the MS control in my sample.
> Greetings


You seem right. The MS RichTextBox doesn't use EM_SETMARGINS, it only uses EM_SETTARGETDEVICE.
So, how shall we proceed?

My proposal would be to keep using EM_SETMARGINS and just call EM_SETTARGETDEVICE and each change of either left or right margin property.
The LineWidth is correctly the RightMargin minus LeftMargin (in Twips always)

Also 

```
CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL)
```

 seems to be the correct usage. So it also works on multiple monitors.

EDIT: If RightMargin minus LeftMargin results in 0 then the wParam (hDC) is also 0.

EDIT2: The MS RichTextBox doesn't have a LeftMargin. (only RightMargin) so a negative LineWidth never applies. Can you test if a negative LineWidth works ? E.g. RightMargin set to 0 and LeftMargin set to something menaingful.
Thanks

----------


## Seniorchef

I'm busy this morning, but give a sample later this day...
My line with createDC() works on my PC with five monitors, but nevertheless yours works too. Depends prob. on the declaration (which I forgot to copy).
Greetings

----------


## Seniorchef

Here some information:
It's true, the MS control has no left margin; this is one reason why I prefer your control.
A negative LineWidth is same like a LineWidth of 0 which cancels the WYSIWYG and makes the text wrap to the right window border.


```
'Create a new project
'Add a form
'Add the VBCCR17.OCX
'Paste this code to the form

Option Explicit

Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As Long, ByVal lpInitData As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long

Const WM_USER = &H400
Const EM_SETTARGETDEVICE = (WM_USER + 72)

Dim mnRightMargin&

Private Sub Form_Load()
   appLeftMargin = 500     'twips
   appRightMargin = 5000   'twips
   'Paste text from the clipboard to the control to make the margins usefull...
   'Resize the form to see the behavior of the control and the margins
   
End Sub

Private Sub Form_Resize()
   If ScaleHeight > 60 And ScaleWidth > 60 Then
      rtf.Move 30, 30, ScaleWidth - 60, ScaleHeight - 60
   End If
End Sub

Property Let appLeftMargin(ByVal nNewValue As Long)
On Error Resume Next
Dim nHdc&
   
   'anything to do...
   If rtf.LeftMargin <> nNewValue Then
      'set VBCCR-control new LeftValue
      rtf.LeftMargin = nNewValue
      'check rightmargin...
      If mnRightMargin > nNewValue Then
         nHdc = CreateDC("Display", "", 0&, 0&)
         'set the linewidth according the margins, make WYSIWYG
         SendMessage rtf.hwnd, EM_SETTARGETDEVICE, nHdc, ByVal mnRightMargin - nNewValue
         'clean up
         DeleteDC nHdc
      End If
   End If
End Property

Property Let appRightMargin(ByVal nNewValue As Long)
Dim nHdc As Long
Dim nLeftMargin&

   'anything to do...
   If nNewValue <> mnRightMargin Then
      nLeftMargin = rtf.LeftMargin
      'illegal RightMargin set to 0
      'take the WYSIWYG from Control...
      Select Case nNewValue
       Case Is <= nLeftMargin
         'cache RightMargin
         mnRightMargin = 0
         'reset the controls rightmargin property ...
         rtf.RightMargin = 0
         'make the VBCCR-Control wrap to window
         SendMessage rtf.hwnd, EM_SETTARGETDEVICE, 0&, 0&
       
      'set RightMargin
      Case Else
         'cache RightMargin
         mnRightMargin = nNewValue
         'make control WYSIWYG
         nHdc = CreateDC("Display", "", 0&, 0&)
         'set the linewidth according the margins, make WYSIWYG
         SendMessage rtf.hwnd, EM_SETTARGETDEVICE, nHdc, ByVal mnRightMargin - nLeftMargin
         'clean up
         DeleteDC nHdc
      End Select
   End If
End Property
```

So in my opinion leave the handling of the margins as they are. The handling of the LineWidth should be done by the calling app, even more because there is no right and left margin stored in a richtext. It should be up to the app to set and handle them.

Greetings

----------


## Seniorchef

Thinking about it, there could be a more elegant solution:
A RightMargin greater than the LeftMargin sets the LineWidth to RightMargin minus LeftMargin.
A RightMargin of zero or negative (or smaller than LeftMargin) sets the RightMargin to that (positive) value and cancels the LineWidth.
This is more or less the essence of my sample above but it also breaks the compatibility of the RightMargin Property, because negative values are legit.



```
LeftMargin=0: RightMargin=-100     'RightMargin=100 twips from the right border of the control
LeftMargin=0: RightMargin=5000     'LineWidth=5000 twips
LefMargin=100: RightMargin=2400    'LineWidth=2300 twips
LeftMargin=500: RightMargin=75      'LineWidth=0, RightMargin=75 twips from right border
```

Greetings

----------


## Seniorchef

I also implemented the event RulerScroll to my code. The Event is used to move a ruler according to the position of the scrollbars of the control. I'm using the  "VBAccelerator Subclassing adn Timer Assistent" for subclassing, so the snippets are



```
'start Subclassing
SSubTimer6.AttachMessage Me, rtf.hWndUserControl, WM_COMMAND
```

and in the queue



```
Dim ScrollPos As POINTAPI
Dim X&, Y&

   'Subclassing ...
   If iMsg = WM_COMMAND Then
       '
      Select Case Int(wParam \ &H10000)
            
         Case EN_UPDATE
            SendMessage rtf.hwnd, EM_GETSCROLLPOS, 0, ScrollPos
            X = (ScrollPos.X * Screen.TwipsPerPixelX)
            Y = (ScrollPos.Y * Screen.TwipsPerPixelY)
            RaiseEvent RulerScroll(X, Y)
...
```

The name of the event "RulerScroll" is arbitrary. I use it to scroll a ruler above the text to show the caret's position and for tabs and borders.

Greetings

----------


## Eduardo-

Hello Krool, I found an issue when an UserControl that is ControlContainer is holding a LabelW inside.
The OleDropMode can't be changed to manual, it raises an error.

Attached is a test project.

----------


## Krool

> Hello Krool, I found an issue when an UserControl that is ControlContainer is holding a LabelW inside.
> The OleDropMode can't be changed to manual, it raises an error.
> 
> Attached is a test project.


That's a VB6 bug. See below workaround I use for FrameW:



```
Public Property Get OLEDropMode() As OLEDropModeConstants
Attribute OLEDropMode.VB_Description = "Returns/Sets whether this object can act as an OLE drop target."
OLEDropMode = UserControl.OLEDropMode
End Property

Public Property Let OLEDropMode(ByVal Value As OLEDropModeConstants)
' Setting OLEDropMode to OLEDropModeManual will fail when windowless controls are contained in the user control.
Const DRAGDROP_E_ALREADYREGISTERED As Long = &H80040101
Select Case Value
    Case OLEDropModeNone, OLEDropModeManual
        On Error Resume Next
        UserControl.OLEDropMode = Value
        If Err.Number = DRAGDROP_E_ALREADYREGISTERED Then
            RevokeDragDrop UserControl.hWnd
            UserControl.OLEDropMode = Value
        End If
        On Error GoTo 0
    Case Else
        Err.Raise 380
End Select
UserControl.PropertyChanged "OLEDropMode"
End Property
```

----------


## Eduardo-

Thank you!

----------


## Erwin69

Hi Krool,

I noticed an area my having slowed down significantly after implementing the CCR statusbar.  I investigated this by simply updating two panels 10.000 times to an empty string.



```
brStatusBar.Panels(2).Text = ""
brStatusBar.Panels(3).Text = ""
```

Using the original statusbar this took 32 milliseconds.  Using the CCR statusbar it took 2505 seconds!

Is this simply the result / consequence of Unicode support, or am I doing something wrong?

Regards,
Erwin

----------


## Krool

> Hi Krool,
> 
> I noticed an area my having slowed down significantly after implementing the CCR statusbar.  I investigated this by simply updating two panels 10.000 times to an empty string.
> 
> 
> 
> ```
> brStatusBar.Panels(2).Text = ""
> brStatusBar.Panels(3).Text = ""
> ...


Thanks.
2505 seconds or milliseconds ?

----------


## Erwin69

> Thanks.
> 2505 seconds or milliseconds ?


Sorry, 2505 milliseconds.  Otherwise there would have been another problem...  :big yellow:

----------


## Krool

@Erwin69,
Do you set 10000 times the exact same text ?
Because setting each time a different text the performance of the MS StatusBar is as bad as well. However, if old and new text is equal I can of course make an improvement, if necessary.

Because changing a text the refresh is "immediately". So in below example you can look how it increments. I did the "same" in VBCCR.


```
Dim T As Single
T = Timer
Dim i As Long
For i = 1 To 10000
    StatusBar1.Panels(1).Text = "test" & i
Next i
Debug.Print Timer - T
```

----------


## Erwin69

Hi Krool,

I notice the slowness with different values as well.  I was indeed assigning the same value many times.

As background info: in this particular case, I'm updating the statusbar as part of the mouse move, so that the user knows which object the cursor is over.  For that the code cycles through several collections, some of which can have over 1000 items, and evaluates the coordinates of the item vs the mouse position. If the item being evaluated is not under the cursor, I set the two panels to "", so assigning the same value many times.

I've now fixed it by first checking the value of one panel, and only updating it when it's not "".

Regards,
Erwin

----------


## Seniorchef

Erwin69, you should only assign a value when it has changed, meaning when it is different from the value already in the panel.
Greetings 
Seniorchef

----------


## Erwin69

> Erwin69, you should only assign a value when it has changed, meaning when it is different from the value already in the panel.
> Greetings 
> Seniorchef


Well, that's what I described in my previous post as the fix.  Point is that with the standard status bar there was no delay when assigning the same value that the panel already had.  Maybe MS optimized that by only refreshing the control if the value has changed.  I thought it wise to share this info with Krool and the community.

----------


## Krool

> Well, that's what I described in my previous post as the fix.  Point is that with the standard status bar there was no delay when assigning the same value that the panel already had.  Maybe MS optimized that by only refreshing the control if the value has changed.  I thought it wise to share this info with Krool and the community.


Yes thanks. Noted.
I think it's worth to get fixed soon as well.

----------


## Krool

> I notice the slowness with different values as well.  I was indeed assigning the same value many times.


I fixed the property now in the StatusBar control. (Exit Property if new value equals old value)

----------


## Karl77

ProgressBar/StatusBar problems

A MDI form has a StatusBar.
On the first panel it shall show a ProgressBar on demand.
After progress is finished, the ProgressBar shall hide.

a)
ProgressBar.Visible has no effect.

b)
The StatusBar font size can't be changed.

---

Not sure it is a VBCCR problem.
But perhaps in VBCCR there are other means to solve the 2 'problems'?



```
VERSION 5.00
Object = "{7020C36F-09FC-41FE-B822-CDE6FBB321EB}#1.2#0"; "VBCCR17.OCX"
Begin VB.MDIForm MDIForm1 
   BackColor       =   &H8000000C&
   Caption         =   "MDIForm1"
   ClientHeight    =   3975
   ClientLeft      =   120
   ClientTop       =   465
   ClientWidth     =   7740
   LinkTopic       =   "MDIForm1"
   StartUpPosition =   2  'CenterScreen
   Begin VBCCR17.StatusBar StatusBar1 
      Align           =   2  'Align Bottom
      Height          =   495
      Left            =   0
      Top             =   3480
      Width           =   7740
      _ExtentX        =   13653
      _ExtentY        =   873
      BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
         Name            =   "Segoe UI"
         Size            =   8.25
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      AllowSizeGrip   =   0   'False
      InitPanels      =   "MDIForm1.frx":0000
   End
   Begin VB.PictureBox Picture1 
      Align           =   1  'Align Top
      BeginProperty Font 
         Name            =   "Segoe UI"
         Size            =   9.75
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   1095
      Left            =   0
      ScaleHeight     =   1035
      ScaleWidth      =   7680
      TabIndex        =   0
      TabStop         =   0   'False
      Top             =   0
      Visible         =   0   'False
      Width           =   7740
      Begin VBCCR17.ProgressBar ProgressBar1 
         Height          =   615
         Left            =   240
         Top             =   120
         Visible         =   0   'False
         Width           =   3780
         _ExtentX        =   6668
         _ExtentY        =   1085
         BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
            Name            =   "Segoe UI"
            Size            =   9.75
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         Step            =   10
      End
   End
   Begin VB.Timer Timer1 
      Enabled         =   0   'False
      Interval        =   1
      Left            =   840
      Top             =   1440
   End
End
Attribute VB_Name = "MDIForm1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Private Declare Function SetParent _
                Lib "user32" (ByVal hWndChild As Long, _
                              ByVal hWndNewParent As Long) As Long

Private Sub MDIForm_Click()

ProgressBar1.Visible = True
Timer1.Enabled = True

With ProgressBar1
    Call SetParent(.hWnd, StatusBar1.hWnd)
    .Left = 1000 'not working
    .Top = 0
    .Width = StatusBar1.Width
    .Height = StatusBar1.Height / 2
End With

End Sub

Private Sub Timer1_Timer()

With ProgressBar1

    .Value = .Value + 1
        
    If .Value >= 100 Then

        Timer1.Enabled = False
        .Value = 0
    
        .Visible = False 'not working

        'workaround
        .Width = 0
        .Height = 0
       
    End If

End With

End Sub
```

----------


## Krool

> ProgressBar/StatusBar problems
> 
> A MDI form has a StatusBar.
> On the first panel it shall show a ProgressBar on demand.
> After progress is finished, the ProgressBar shall hide.
> 
> a)
> ProgressBar.Visible has no effect.
> 
> ...


I can't check now. But the SetParent is wrong, shall be:


```
Call SetParent(.hWndUserControl, StatusBar1.hWnd)
```

----------


## Karl77

> ```
> Call SetParent(.hWndUserControl, StatusBar1.hWnd)
> ```


Oh well, yes.
Solves a).

Thank you!

----------


## Krool

> Oh well, yes.
> Solves a).
> 
> Thank you!


Good. But why you can't change the Font of the StatusBar ?
For me it works..

----------


## Karl77

I can change the font but not the font size.
Try to set Segoe UI / 10.
Reverts to 8.25.

----------


## Krool

> I can change the font but not the font size.
> Try to set Segoe UI / 10.
> Reverts to 8.25.


I can't replicate. For me it just reverts to 9.75

----------


## Erwin69

> I can't replicate. For me it just reverts to 9.75


Could this have to do with the various sizes that have been installed for the font on the PC?  I remember having had some challenges with font sizes in the past with Windows seemingly arbitrarily switching to another size than the number it was given.

Also, as youre talking about a UI font, could Windows scaling setting play a role, e.g. if its not 100%?

----------


## Karl77

> I can't replicate. For me it just reverts to 9.75


Now I have 9.75 as well after several tries.
I had to set a different font before, change the size, and then set the font.
So forget the strange effect.




> Also, as youre talking about a UI font, could Windows scaling setting play a role, e.g. if its not 100%?


Not in this case.
I work at 100% always, and alter the setting for tests only.
I never save a project when not at 100%.

----------


## Karl77

Toolbar index problem

I have a toolbar with 3 buttons.
They are added by code, using the string key of the imagelist.
All fine.

Now I have a .DisabledImagelist.
For this test the imagelist holds the same images, but in different order.
While the single image has the same key as in the normal imagelist.

When I now disable a button by key, the wrong image from the DisabledImagelist is applied.

It would be good if the image for the disabled button is fetched by the image key.

2022-08-30_Toolbar.zip

----------


## Krool

> Toolbar index problem
> 
> I have a toolbar with 3 buttons.
> They are added by code, using the string key of the imagelist.
> All fine.
> 
> Now I have a .DisabledImagelist.
> For this test the imagelist holds the same images, but in different order.
> While the single image has the same key as in the normal imagelist.
> ...


I understand.. However, the "solution" is not easy.

First of all, the TBBUTTONINFOW structure has only single iImage member.
So TB_SETIMAGELIST/TB_SETDISABLEDIMAGELIST/TB_SETHOTIMAGELIST do use the same iImage member.
That could be solved applying I_IMAGECALLBACK on iImage member and set the appropriate index at TBN_GETDISPINFO. But, that implies two possible solutions:
1. Fetch the index from the ImageList at every TBN_GETDISPINFO. (performance penalty)
2. Add new DisabledImage/HotImage in the TbrButton class. So that the index can be fetched once and used at TBN_GETDISPINFO. For back-compat reasons DisabledImage/HotImage must return the Image property in case they are not set. (empty) Which would be possible as the properties are Variants.

So I opt for solution 2. In would be possible even to incorporate this into VBCCR17 (only typelib version increments)
But that would require your code to set the possible new DisabledImage property afterwards. (an enhancement in the Buttons.Add signature is not possible as it breaks binary compatibility)
example:


```
With .Buttons.Add(, "key1", , TbrButtonStyleDefault, "a")
.DisabledImage = "a"
End With
```

What do you think ?

----------


## Karl77

Performance penalty is not my friend.
On the other hand, it depends on how often it happens and how long it takes.

Other idea:
Sorting the .DisabledImageList so that the index matches the .ImageList.
This has to be done 1x only.
(Don't know how to handle it when the DisabledImageList is shorter than .ImageList.)

A change in the source is no problem.



```
.DisabledImage = "a"
```

When using such, is the image from the .DisabledImageList?
If so, then fine.

----------


## Karl77

Regarding the imagelists:

Up to now I create the disabled images manually.
I don't do it for all normal pictures.
And I don't want do do that at all anymore.

The normal pictures get added to the imagelist by code.
The sources are PNGs with transparency in a ressource file.
Works good, no problem.

The idea is now, to read the pictures in the imagelist, make them brighter and greyscale and copy the result to a .DisabledImagelist.
Would avoid the former issue "Toolbar index problem" completely.

Before I reinvent the wheel:
Are there any functions I could use for the image processing in VBCCR?
Or another idea which is not a large additional library?

----------


## Krool

> Are there any functions I could use for the image processing in VBCCR?
> Or another idea which is not a large additional library?


No.

---

Btw(!), just noticed that DrawState API in the StatusBar *crashes* when the StrPtr() of the Text property is 0. I guess that's due to a recent MS update..
Will make a fix for that soon.

EDIT: Bugfix done.

----------


## Semke

> Here's the DLL and PNG stuff.
> It is quite old and probably there are more elegant solutions.
> Also it is a adjusted to my needs.
> 
> Attachment 180641
> 
> I think #3089 is answered when you inspect the libs.


in the Module _m_PNG_Resource_  there is a call to a function *Resize*, (it is called from a procedure _ResDLLToPicture_ ).

i can not find this function in the code you attached could you be so kind and send it to me.

----------


## Karl77

> in the Module _m_PNG_Resource_  there is a call to a function *Resize*, (it is called from a procedure _ResDLLToPicture_ ).
> 
> i can not find this function in the code you attached could you be so kind and send it to me.


Here:
m_GDIPlusResize.zip

----------


## Karl77

from (Toolbar index problem)




> I understand.. However, the "solution" is not easy.


No solution needed.
I decided for a DisabledImagelist with the same count and order as the Imagelist.

---

I didn't compare the behavior to CC5; most probably the problem is the same.

----------


## Krool

> from (Toolbar index problem)
> 
> 
> 
> No solution needed.
> I decided for a DisabledImagelist with the same count and order as the Imagelist.
> 
> ---
> 
> I didn't compare the behavior to CC5; most probably the problem is the same.


Yes the MSCOMCTL.OCX behavior is the same for the ToolBar.

So, yes. I keep everything like it is. Adding a "DisabledImage", "HotImage" property in a Button object would complicate everything and might be confusion due to the back-compat thing of the "fallback" to "Image" property.

----------


## Karl77

2 RICHTEXTBOX PROBLEMS 

1)
VBCCR17 OCX and EXE:
Make a new project and place a RichTextBox1 on the form.

RightToLeftMode = 0
RightToLeft = True

Run.

In here the whole RichTextBox1 renders *black*.


2)
I use an older version of the VBCCR RichTextBox.
The black background issue is not in it.

Question:
What should I do to add some spaces to the text?
When I put them *after* the \cf4, they do not appear.
Surprisingly the spaces are found before the text 'Boing'.
Other characters like . do work and appear at the end.
For now I *begin* with the spaces - they appear at the end (m1 in the example).
Not a good 'fix'.




```
Dim m          As String
Dim m1          As String
Dim m2          As String

Dim SomeSpaces As String
SomeSpaces = "    " '5 spaces


'spaces are after the text
m1 = "{\rtf1 " & _
   "{\colortbl ;\red227\green38\blue33;\red0\green128\blue0;\red51\green51\blue204;\red0\green0\blue0;}" & _
   "\cf1" & _
   SomeSpaces & _
   "Boing \cf2Bum \cf3Tschak\cf4 "

'spaces are before the text
m2 = "{\rtf1 " & _
   "{\colortbl ;\red227\green38\blue33;\red0\green128\blue0;\red51\green51\blue204;\red0\green0\blue0;}" & _
   "\cf1Boing \cf2Bum \cf3Tschak \cf4 " & _
   SomeSpaces

m = m1 'or m2

RichTextBox1.TextRTF = m
```


I can't compare with Richtx32.ocx, it doesn't have RTL.

----------


## Darkbob

Just a head's up.  The demo for this project still doesn't run (as I reported in 2017).  The .tbl files are included in a sub folder but they aren't registered so the reference to them fails and the demo dies at that point.  If there was a readme included that explained how to register a TBL file, it could go a long way towards fixing this.  Sadly, if the demo doesn't run, most people will quickly bail.  Which is a real shame.  This is an incredible project and it deserves to be seen and shared and used.  But as I say... with a non-functional demo, it will be only used by a handful of people who can get it working.  

That said, you can download the compiled OCX from a different thread.  Most people should know how to register an OCX even without a readme and it works fine.  Thanks for sharing this project and all the hard work that has gone into it.

----------


## fafalone

I have no problem getting the demo project to run.

TLB files (assuming that's what you mean) get registered when you add them or open a project referencing them. You might run into trouble if you have a previous version registered and the path no longer exists. In that case the new version wouldn't register. You'd have to use the old path for the tlb, or recreate it (new version is fine), unregister, then delete it and open with the new path.

----------


## Krool

> 2 RICHTEXTBOX PROBLEMS 
> 
> 1)
> VBCCR17 OCX and EXE:
> Make a new project and place a RichTextBox1 on the form.
> 
> RightToLeftMode = 0
> RightToLeft = True
> 
> ...


Update released. There was a tiny bug in the RightToLeft property which causes trouble if you set the two properties at design-time only..
That's now fixed. Please confirm.

The other question with the \cf4 I don't get..

----------


## Karl77

> Update released. There was a tiny bug in the RightToLeft property which causes trouble if you set the two properties at design-time only..
> That's now fixed. Please confirm.


Tried in the EXE project and OCX.
Blackness bug is gone.




> The other question with the \cf4 I don't get..


Simplified example:

Set a RichTextBox to RTL.


```
RichTextBox1.TextRTF = "{\rtf1Boing Bum Tschak" & "     "
```

See the right aligned words in the RichTextBox.
The spaces should come *after* Tschak.
But the spaces are *before* Boing.
You can see this easily when you CTRL+A the RichTextBox content.

Now try


```
RichTextBox1.TextRTF = "{\rtf1" & "     " & "Boing Bum Tschak"
```

The spaces are after Tschak.



---

What are the spaces for?
I want a label with right aligned colored text, RichTextBox should do it.
At the right I want a little offset from the edge.
A single space char would be enough.

----------


## Darkbob

> I have no problem getting the demo project to run.
> 
> TLB files (assuming that's what you mean) get registered when you add them or open a project referencing them. You might run into trouble if you have a previous version registered and the path no longer exists. In that case the new version wouldn't register. You'd have to use the old path for the tlb, or recreate it (new version is fine), unregister, then delete it and open with the new path.


Glad it works for you.  It definitely doesn't work for me.  I'm using a brand new laptop and it has no tlb files (that I know of) so I don't think it's an old version issue.  If anything, it's probably the opposite - it may be that you had an old version installed which allowed you to get the demo to work.

I don't think most people work with tlb files or would even know what they were or how to register one or delete one.  I know I don't and I've been using VB since VB 1.0 for DOS was released.

It's a shame this information isn't included with the demo.  That was the point of my post.

----------


## fafalone

You don't need to register them yourself, if you tried, that's probably where the problem arose.

Krool has updated the tlb in compatibility-breaking ways several times without changing the GUID (as have I with oleexp, so not complaining), so when I've upgraded, I've had to do some manual un registration to use the new version. But I also just built a new system this year so everything was new again; it ran fine.

TLBs (most of them, like OLEGuids and oleexp) are 100x easier to deal with registration wise than ocx, those are a consistent nightmare.

----------


## samer22

hi krool
I'm using your textboxes to display data in Arabic from database and they are doing very well.
However  when adding data at runtime :
eg TextBoxW1.Text = "اللغة العربية" they are showing strange characters.
as opposed  to VB textboxes which are showing data correctly at runtime but strange symbols from database.
eg Text1.Text = "اللغة العربية"
thanks

----------


## Karl77

Toolbar problem with .DisabledImagelist

When a button is set to enabled = false by code the button shows the correct image.
This does not work when the button is *TbrButtonStyleCheck* + .Value = *TbrButtonValuePressed*.

See attached sample to play with:
2022-09-16_Toolbar.zip

EDIT:
MSCOMTL's toolbar shows the same behavior as in VBCCR17.

On Enabled = false for a button, the button style has to be default.
Otherwise the image from the .DisabledImagelist is not used.

Before setting Enabled = false, style and value must be stored for Enabled = true.
I wrote a helper function that stores the style and state of a button before appling the image.
It uses the button Tag to store the values.

This kind of works ok, but the Tag property is lost for other uses.
Ok, I could use a companion list instead of the Tag.

Bad is that this list has to be refreshed on every ButtonClick.

---

The problem is solved so far, but it is a cumbersome approach.


My wish is that VBCCR17's toolbar button uses the .DisabledImageList independent from the state and style of the button.

Something to play with:
2022-09-21_Toolbar.zip

----------


## richard62

Hi Krool,

I'm new here. Here can I download the latest version of your CommonControls replacement?

Thank you

----------


## Karl77

https://www.vbforums.com/showthread....=1#post4277565

----------


## Krool

> My wish is that VBCCR17's toolbar button uses the .DisabledImageList independent from the state and style of the button.


I understand your point(s). But I see no way to fix it..  :Frown:

----------


## Karl77

> I understand your point(s). But I see no way to fix it..


This is solved by a little workaround.

I decided to store the button data in the tag of the toolbar and not in the tag of the single button.
Works ok.

Things I don't like so much:
1) Setting a button Enabled/Disabled requires a method.
2) The button state has to be stored on every button click.
3) The toolbar tag is occupied.

If someone should have the same problem:
2022-09-22_Toolbar.zip

----------


## Semke

i would like to as a SubMenu to the ToolbarButonMenu, how can i get the hMenu(hWnd) for each item

----------


## Krool

> i would like to as a SubMenu to the ToolbarButonMenu, how can i get the hMenu(hWnd) for each item


Good point. The hMenu is created on demand and not persistent.
So, a solution could be that whenever the popup menu is created a new "InitButtonMenu" event is fired with a TbrButton object and a hMenu pointer. So the developer can adjust the hMenu before it get's displayed by the ToolBar.
What you think ?

----------


## Semke

> Good point. The hMenu is created on demand and not persistent.
> So, a solution could be that whenever the popup menu is created a new "InitButtonMenu" event is fired with a TbrButton object and a hMenu pointer. So the developer can adjust the hMenu before it get's displayed by the ToolBar.
> What you think ?


I was thinking in that direction, this would also help adding picture to the menu, using ModifyMenu / MF_BITMAP

----------


## Krool

> I was thinking I that direction, this would also help adding picture to the menu, using ModifyMenu / MF_BITMAP


Ok. But then there is a problem of the ButtonMenuClick. Currently it fires if wID is > 0 and passed that n-th wID to a ButtonMenu object.
We would need to cap that, so that ButtonMenuClick only fires if wID is not higher then the ButtonMenus.Count.
If the wID is not in that range and <> 0 then a new event shall be called, let's say "ButtonSubMenuClick" which just passes the wID and the developer is then responsible for mapping it. Of course the TbrButton class can be passed also for enrichement.
Your thoughts?

----------


## Semke

> Ok. But then there is a problem of the ButtonMenuClick. Currently it fires if wID is > 0 and passed that n-th wID to a ButtonMenu object.
> We would need to cap that, so that ButtonMenuClick only fires if wID is not higher then the ButtonMenus.Count.
> If the wID is not in that range and <> 0 then a new event shall be called, let's say "ButtonSubMenuClick" which just passes the wID and the developer is then responsible for mapping it. Of course the TbrButton class can be passed also for enrichement.
> Your thoughts?


i understand that you want to apply events for the submenu, i think this would be a never ending affair, one might add subsubmenues etc. i was thinking of just using ModifyMenu/MF_POPUP and programaticly use CreatePopupMenu, AppendMenu and TrackPopupMenu

----------


## Krool

> i understand that you want to apply events for the submenu, i think this would be a never ending affair, one might add subsubmenues etc. i was thinking of just using ModifyMenu/MF_POPUP and programaticly use CreatePopupMenu, AppendMenu and TrackPopupMenu


True.
New idea, having just a new "InitButtonMenu" with ByVal hMenu As Long and a ByRef Handled As Boolean.
If you change Handled to True the ToolBar control will not go further (TrackPopupMenu) and destroys just hMenu, since you decided it's all handled.
?

----------


## samer22

> hi krool
> I'm using your textboxes to display data in Arabic from database and they are doing very well.
> However  when adding data at runtime :
> eg TextBoxW1.Text = "اللغة العربية" they are showing strange characters.
> as opposed  to VB textboxes which are showing data correctly at runtime but strange symbols from database.
> eg Text1.Text = "اللغة العربية"
> thanks


Any idea here Krool?

----------


## Krool

> Any idea here Krool?


You can't apply unicode literals in the VB6 IDE. You need to use ChrW() for each character and append them together.
I suggest you could use it for VB.TextBox because maybe your machine is in DBCS mode, so the VB6 IDE is "looks like unicode aware", but only while you are in DBCS mode. And any shipment to a computer which is not in DBCS mode will fail later.

----------


## Semke

> True.
> New idea, having just a new "InitButtonMenu" with ByVal hMenu As Long and a ByRef Handled As Boolean.
> If you change Handled to True the ToolBar control will not go further (TrackPopupMenu) and destroys just hMenu, since you decided it's all handled.
> ?


I think this would be a good start, although i haven't tested it yet, but i don't think that *TrackPopupMenu*  could be used on an existing menu. i am going to test it and/or find another method to take advantage of this.
I would rather stay away from callbacks.
maybe somebody else here could give some idea...

be that as it may, it would help for those who want to use images in the menu.

----------


## smileyoufu

Hello Krool! 
Thank you for your great contribution and developed this control, which I have been using all the time. It's great!

Now there are two questions:

1. "DTPicker" control lacks "BackColor" and "ForeColor" attributes

2. The "BackColor" and "ForeColor" properties of the "MonthView" control do not work after being set (the background color and text color will not change)



Please help us to solve the above problems.

Thank you.

----------


## Krool

> Hello Krool! 
> Thank you for your great contribution and developed this control, which I have been using all the time. It's great!
> 
> Now there are two questions:
> 
> 1. "DTPicker" control lacks "BackColor" and "ForeColor" attributes
> 
> 2. The "BackColor" and "ForeColor" properties of the "MonthView" control do not work after being set (the background color and text color will not change)
> 
> ...


1. Not possible.

2. Set VisualStyles to False.

----------


## smileyoufu

I see. Thank you very much

----------


## gaouser

So bad that crashes on Win7 Ultimate SP1  i really wanted to see MSCC6 as Manifested

----------


## fafalone

You probably saw it on the Discord but I'll add it here for tracking purposes...

Would be really nice to have an option for PictureAlignment when CommandButton style = graphical, so the image can appear to the left/right/bottom instead of just top. Setting the Alignment option has no impact.

----------


## Semke

On the toolbar Button the Style Placeholder is missing. So what I have been using until now is, to set the style as TbrButtonStyleSeparator and set the CustomWidth to the desired width.

Seems ok, But! when the toolbar Wrappable is true the button will not go immediately to the next row of the toolbar. Only after a button with the style *is not*  TbrButtonStyleSeparator which is before the placeholder has also been moved to the next row

when checking the Button .Left and .Top properties it returns 0 on both, as a result any controls which are dependent on these coordinates move to position 0,0

This will also be if there are more then one placeholders in sequence; they will not move to next row of buttons until the wrap include the button before all the placeholder(s).



I hope I explained it enough...

to test it , create a toolbar with a few buttons, create a button TbrButtonStyleSeparator and set Customwidth to 2000, Autosize= false , create a few more buttons. set toolbar Wrappable =true
create a picturbox 

in code 
set Picturebox Container = toolbar
set the picturebox cords to the button cords
resize the form to the middle of the placeholder and repeat setting the picturebox cords to the button cords (use a form resize event to see it better)


I have tested it further.
if i put a TbrButtonStyleSeparator  with Autosize=true before the placeholder then the .Left and .Top properties  remain as old, but it will not move dow until all buttons with TbrButtonStyleSeparator in the sequence don't fit on the row

----------

