# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  VBFlexGrid Control (Replacement of the MSFlexGrid control)

## Krool

This project is intended to replace the MSFlexGrid control for VB6.

The "MSFLXGRD.OCX" can be replaced completly.

Even though some enhancements of the MS*H*FlexGrid control are included, it can't replace it completly (yet).
But there are also new features included that are not available on both MSFlexGrid and MSHFlexGrid.

The VBFlexGrid supports *Unicode* and is *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.

In order to use the DataSource/DataMember property a reference to msdatsrc.tlb (pre-installed since Win2k) is required.

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.

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

*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
- Added FlexTextAsCheckBox/FlexDisabledTextAsCheckBox enum to FlexCheckBoxConstants.
  This maps the cell text to a check box state dynamically.
  Empty text (like DBNull) as grayed state, else text to boolean conversion to either checked or unchecked state.
  The application is responsible to react on CellCheck event to update the cell text to the new state.
  Furthermore the cell text gets hidden/not drawn. Also the label info is as if the cell has no text.
07-Jan-2023
- Included the parameter 'Reason As FlexCellCheckReasonConstants' in the CellBeforeCheck event.
- Checkboxes now react on double click.
02-Jan-2023
- ComboCue/CheckBox now hot-tracked when MouseTrack property is set to True.
30-Dec-2022
- Included the ColNumericPrecision/ColNumericScale property. (As Byte)
  Included the ColDataCapacity property. (As Long)
  Setting ADO DataSource will predefine the column numeric precision/scale and data capacity.
  It's an information property only, but useful to better format text or restrict max length in a column. (ColFormat/EditMaxLength property)
29-Dec-2022
- DIP metrics are converted to pixels now only once at UserControl_Initialize in new internal TPIXELMETRICS structure.
28-Dec-2022
- Improved AutoSize/FormatString to resize based on best fit rather than text measure only.
  Best fit means to include ComboCue, CheckBox, Picture (NoOverlap align only) and ColSortArrow.
  ColSortArrow was previously included in the internal GetTextSize (CX/CY) function which could be misleading.
  Now included new internal GetBestWidth function and renamed GetTextHeight to GetBestHeight.
- Included BestFitMode property which defaults to 0 - TextOnly. (used for AutoSize/FormatString)
22-Dec-2022
- Added FlexDisabledUnchecked/FlexDisabledChecked/FlexDisabledGrayed enum to FlexCheckBoxConstants.
- New hit result FlexHitResultCheckBoxDisabled.
20-Dec-2022
- Included the Checkboxes feature. (CellChecked property)
  Added enum FlexCellChecked for the Cell property.
  Added hit result enum FlexHitResultCheckBox.
  Included the CellBeforeCheck/CellCheck event.
  This fires only by mouse click or space key. (not by code via CellChecked property)
17-Dec-2022
- The TextRect in the internal GetLabelInfo/GetTextHeight function now adjusted for potential ComboCue.
12-Dec-2022
- Cell flooding now also fills on selected cells.
  Changed default FloodColor from &H80FF80 to &HC0& to be better readable on selections. (like vsFlexGrid)
11-Dec-2022
- Included the parameter 'CtlType As Long' in the ComboButtonOwnerDraw event.
09-Dec-2022
- Included the cell flooding feature. (CellFloodPercent/CellFloodColor/FloodColor property)
  Added enum FlexCellFloodPercent and FlexCellFloodColor for the Cell property.
26-Nov-2022
- Minor bugfix in the internal GetLabelInfo method. (related to the ShowLabelTips property only)
16-Nov-2022
- Added enum 2 - IncludeFixedColumns and 3 - IncludeFixedAll for the ClipCopyMode property.
- Included the AutoClipboard property.
13-Nov-2022
- Included the ClipPasteMode property. Currently only 0 - Normal and 1 - AutoSelection.
10-Nov-2022
- Included the ClipSeparatorCol/ClipSeparatorRow run-time property. These default to vbTab and vbCr.
  It can be useful to change the default and to support more than one character.
  Example is the row separator vbCrLf for better MS Excel exchange.
  However, if ClipSeparators property is set, then that will be used. (overwriting the default but limited to 1 character per)
09-Nov-2022
- Included the Copy/Cut/Paste/Delete method.
- Included the ClipCopyMode property. Currently only 0 - Normal and 1 - IncludeFixedRows.
  This value affects the Copy method and the Clip Get-Property. (not the Clip Let-Property)
  To have Clip Get/Let behave the same keep it as 0 - Normal.
23-Aug-2022
- The pen style for FlexFocusRectFlat uses now a NULL_BRUSH.
22-Aug-2022
- Bugfix in the RemoveItem method and Rows/Cols property.
08-Jun-2022
- Bugfix in the .RowPosition() and .ColPosition() property.
  Now it is a round trip swap instead of a direct swap between index and value.
  This behavior matches now to the MS(H)FlexGrid control.
30-May-2022
- Setting .FlexDataSource to nothing will invalidate the grid now and does not cause an immediate redraw anymore.
10-Jan-2022
- Bugfix in the AddItem method.
22-Dec-2021
- FlexAlignmentGeneral now aligns for dates to the right. (Like MS(H)FlexGrid)
  Though FlexSortGenericAscending/FlexSortGenericDescending still sort either text or numeric number. (no dates like in MS(H)FlexGrid)
  For dates keep using FlexSortDateAscending/FlexSortDateDescending.
13-Dec-2021
- Included the ComboButtonAlignment/ColComboButtonAlignment property.
  ComboButtonAlignment defaults to 1 - Right and ColComboButtonAlignment defaults to -1 (inherit from ComboButtonAlignment).
  This may be useful for right-to-left reading-order properties.
10-Dec-2021
- Included the MirrorAlignGeneral property.
  This may be useful for right-to-left reading-order properties.
08-Dec-2021
- Included the ColDataType property. (As Integer; not restricted to an enum)
  Setting ADO DataSource will predefine the column data type. (.ColDataType(i) property)
  It's an information property only, intended to free the ColData property for other use cases.
07-Dec-2021
- Included the FixGridLineOffsets property.
  It defaults to False to ensure visual compatibility with the MS(H)FlexGrid control.
01-Dec-2021
- Some minor internal improvements.
30-Nov-2021
- Merged rows/cols now drawn correctly in the freezing pane. (bugfixes in the internal DrawGrid routine)
29-Nov-2021
- User resizing of rows/columns not restricted to client rect bottom/right anymore.
  This makes it easier to enlarge the last row/column beyond the client rect.
26-Nov-2021
- Included the GridColorFrozen/GridLinesFrozen/GridLineWidthFrozen property.
  The GridLineWidthFrozen has an default value of -1, which means it exposes GridLineWidthFixed or GridLineWidth.
25-Nov-2021
- Included the SheetBorder property.
  The default value is True which draws a border around the sheet. (Like MSFlexGrid)
  When set to False it draws no such border. (Like MSHFlexGrid)
23-Nov-2021
- Included the GridLineWidthFixed property.
  Like in the MSHFlexGrid it has an default value of -1, which means that it exposes the GridLineWidth property in that case.
- Included the FocusRectWidth property.
  This has only an effect for FlexFocusRectFlat.
20-Nov-2021
- User now able to freeze even when fixed rows/cols are 0 and frozen rows/cols are 0.
19-Nov-2021
- The pen style for FlexFocusRectFlat is now PS_INSIDEFRAME instead of PS_SOLID.
  PS_INSIDEFRAME is same as PS_SOLID but it keeps inside a given rectangle regardless of the pen width.
18-Nov-2021
- Included enum FlexFocusRectFlat for the FocusRect property.
  It draws a solid rectangle (BackColorSel) instead of using the DrawFocusRect API.
16-Nov-2021
- Included the AllowMultiSelection property.
  This property can only be set to True for SelectionMode 1 - ByRow or 3 - FreeByRow.
- Included the RowSelected/SelectedRow/SelectedRows run-time property.
  These are automatically set when AllowMultiSelection is set to True.
  However, they can be set by code even when AllowMultiSelection is set to False.
- Improved AllowSelection property (when set to False) to not restrict..
  - ColSel for SelectionMode 1 - ByRow
  - RowSel for SelectionMode 2 - ByColumn
10-Nov-2021
- Included the AllowScrollLock property.
  When the scroll lock key is toggled on it allows the user to use the arrow keys to scroll. (like in Excel)
- SB_PAGE* scrolling fixed! (regression since 08-Sep-2021)
- Starting edit mode will now cancel any ongoing divider drag operation.
09-Nov-2021
- Escape key now cancels any ongoing divider drag operation.
08-Nov-2021
- Added edit reason enum FlexEditReasonComboCueAltUpDown.
06-Nov-2021
- Included the AllowUserFreezing property and the AfterUserFreeze event.
- Included a new AfterUserResizeEnd event. Unlike AfterUserResize which is before commit (ByRef NewSize As Long) this event is after the commit.
03-Nov-2021
- Minor performance improvement for the internal GetHitTestInfo function.
- Combo button now reacts to STN_DBLCLK.
02-Nov-2021
- Added combo cue enum FlexComboCueDisabledDropDown and FlexComboCueDisabledButton.
- Added hit result enum FlexHitResultComboCueDisabled.
- Included the CellComboCue property. (plus corresponding enum FlexCellComboCue)
  This let's you define a fixed combo cue for an individual cell or a range of cells.
- Included the ComboCueRow/ComboCueCol property which sets the row and column where the combo cue is displayed.
  Default internal value is -1 as an alias for the current focused cell. (.Row/.Col)
29-Oct-2021
- DC viewport for the ComboCue draw now set as 0, 0. (affects the ComboButtonOwnerDraw event)
28-Oct-2021
- Included the ComboCue property. (FlexComboCueConstants - which is 0 - None, 1 - DropDown or 2 - Button)
- New edit reason enum FlexEditReasonComboCueClick, FlexEditReasonComboCueDblClick and FlexEditReasonComboCueF4.
- New hit result enum FlexHitResultComboCue.
22-Oct-2021
- Added a new FlexComboModeCalendar enum that allows to use a drop-down calendar functionality when editing a cell.
  The application must verify on ValidateEdit that the input is valid and also a unique format can be applied there. (see demo project)
18-Oct-2021
- Included the ColSortArrowAlignment property.
- Bugfix for the DoubleBuffer property and when both RightToLeft/RightToLeftLayout got toggled.
  The DoubleBufferDC was not changed to either LAYOUT_RTL or 0 on WM_STYLECHANGED.
10-Oct-2021
- Included the ComboBeforeDropDown event.
09-Oct-2021
- The ellipsis on a ComboButton can now drawn with COLOR_GRAYTEXT when it is disabled.
05-Oct-2021
- Renamed FlexColSortArrowConstants into FlexSortArrowConstants.
04-Oct-2021
- Renamed enum FlexColSortArrowUp to FlexColSortArrowAscending and FlexColSortArrowDown to FlexColSortArrowDescending.
- Included the RowSortArrows property.
- Included the SortArrowColor property.
03-Oct-2021
- Included the ColSortArrowColor property.
01-Oct-2021
- Included the ColSortArrow property.
22-Sep-2021
- Performance improvement in the internal BubbleSortIter/InplaceMergeSort method. (UDT assignment)
18-Sep-2021
- Included the FlexSortCustomText enum with corresponding CompareText event.
10-Sep-2021
- Minor internal improvements in the internal SetScrollBars method.
08-Sep-2021
- Proportional thumb for the ScrollBars.
07-Sep-2021
- Included the ExtendLastCol property.
18-Aug-2021
- Bugfixes (side-effects) related of FrozenRows/FrozenCols for BottomRow/RightCol property.
- Bugfix in the internal GetHitTestInfo function.
  Now an adjustment is done between the leftmost/topmost column/row and the non-scrollable columns/rows.
  This affecty only for hit tests of divider column left and row top. (divider column right and row bottom not affected)
03-May-2021
- Removed WS_EX_NOPARENTNOTIFY in the window creation as this causes a MDI child window to not get activated.
26-Mar-2021
- UserControl.DrawStyle set to 5 = Transparent to avoid a wasted/unused GDI pen handle.
17-Mar-2021
- Improved CreateGDIFontFromOLEFont function.
12-Mar-2021
- Included the SelectRange method.
  This method selects a range of cells or a cell (by omitting RowSel/ColSel) with a single command.
08-Mar-2021
- AutoSize method works now as expected if WordWrap = True and Mode = FlexAutoSizeModeRowHeight.
- AutoSize method works now also as expected if SingleLine = True.
06-Mar-2021
- Bugfixes (side-effects) related of FrozenRows/FrozenCols for other properties.
- Included FrozenRowsVisible/FrozenColsVisible property.
- Included the enum FlexAutoSizeScopeMovable/FlexAutoSizeScopeFrozen in the AutoSize method.
  FlexAutoSizeScopeScrollable will not autosize the frozen cells.
  FlexAutoSizeScopeMovable contains both frozen and scrollable cells.
- Included the enum FlexClearMovable/FlexClearFrozen in the Clear method.
  FlexClearScrollable will not clear the frozen cells.
  FlexClearMovable contains both frozen and scrollable cells.
05-Mar-2021
- Included the FrozenRows/FrozenCols property.
- Bugfix in the ValidateEdit event when showing a message box inside the event.
02-Mar-2021
- The TextHeight function does not return 0 anymore when passing an empty string.
  Instead it returns TMHeight (TEXTMETRIC). TextWidth is unchanged and keeps returning 0 on an empty string.
  This behavior is now the same as in a VB.Form's TextHeight/TextWidth function.
28-Feb-2021
- Included new enum 'FlexMousePointerConstants' which the MousePointer property now uses.
  Reason is that the VBA environment does not support IPerPropertyBrowsing.
- Included the EditContextMenu event.
27-Feb-2021
- Bugfix in the AutoSize method when using IVBFlexDataSource.
- FindItem function can now be used (not disabled anymore) when using IVBFlexDataSource.
- Some minor internal improvements.
25-Feb-2021
- Some minor internal improvements.
26-Jan-2021
- FixedRows property now using RCPF_FORCETOPROWMASK.
- FixedCols property now using RCPF_FORCELEFTCOLMASK.
- Rows/Cols/FixedRows/FixedCols property now using RCPF_FORCEREDRAW.
17-Nov-2020
- Setting ADO DataSource will predefine the column keys. (.ColKey(i) property)
14-Nov-2020
- Exception for Rows/Cols property to be able to scroll, if necessary.
  This is related to 13-Nov-2020 update.
13-Nov-2020
- Bugfix that the ScrollBars property did not made a limitation for the scrolling.
  This is the same behavior now as in the in the MS(H)FlexGrid control.
11-Aug-2020
- Bugfix in the ForeColorFixed property.
09-Aug-2020
- OCX supports accelerator keys in a VBA environment.
02-Aug-2020
- Internal function ComboShowDropDown will call RefreshMousePointer function when current hCursor is NULL.
05-Jul-2020
- The ellipsis on a ComboButton can now drawn with COLOR_HOTLIGHT when mouse is over it.
  This only affects when visual styles are off.
28-May-2020
- WM_UNICHAR handler now supports surrogate pairs. (UTF32 conversion)
26-May-2020
- Massive performance boost for Get .Clip property.
  The string concatenation was done by using small buffer chunks putting together.
  Now the VB6 poor man's string builder is used from wqweto. (but using a string array instead of a collection)
13-May-2020
- Performance boost for drawing custom cell background colors.
11-May-2020
- CS_VREDRAW and CS_HREDRAW are not specified anymore as entire redraw upon resize is not necessary.
10-May-2020
- Performance boost for drawing the grid.
  - ~2% for using of Polyline API (not PolylineTo !) instead of MoveToEx and LineTo. (for the grid lines)
    Polyline is at device driver level, thus faster than LineTo and it doesn't change current position.
  - ~1% for using of PatBlt API instead of FillRect. (FillRect is a wrapper of PatBlt SelectObject'ing the specified Brush)
  - ~5% by preserving the memory bitmap (DoubleBuffer) for WM_PAINT and re-create only upon WM_SIZE.
26-Apr-2020
- Bugfix in the GetClipboardText function in Common.bas.
19-Apr-2020
- Internal improvement in VBFlexGridBase.bas.
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.
- Returning a zero KeyChar in the EditKeyPress event will not cause anymore a beep. (like in a TextBox control)
09-Apr-2020
- Bugfix in the CellPicture property. It now returns as 'IPictureDisp' instead of 'IPicture'.
07-Apr-2020
- Major internal improvement as no WM_MOUSEACTIVATE overhead necessary anymore.
  This results for 'FlexTopParentValidateControls' being obselete and was removed!
31-Mar-2020
- Bugfix in the internal MoveNextRow and MoveNextCol function.
22-Mar-2020
- Bugfix in the CreateGDIFontFromOLEFont function. (Common.bas)
24-Feb-2020
- Bugfix in the ShowLabelTips property that it didn't show on fixed cells.
06-Feb-2020
- Improvement (cosmetic, not a bug) in VTableHandle.bas so that IOleControl do not disturb anymore in IDE on debugging.
  This affects only the Std-EXE version (not OCX) and only when setting breakpoints. (F9, F8 etc.)
05-Jan-2020
- Improvement in VTableHandle.bas as IPerPropertyBrowsing must NOT be subclassed anymore.
  No VTable remains subclassed, therefore VTableSubclass.cls got obselete and was removed!
- Modified OLEGuids.tlb as following: (compiled with same uuid)
  - bugfix interface IPerPropertyBrowsing.
  Unregister to old OLEGuids.tlb is not necessary, just overwrite the file.
03-Jan-2020
- Improvement in VTableHandle.bas as IOleControl must NOT be subclassed anymore.
  It is necessary to replace also all controls. (.ctl)
23-Dec-2019
- Major performance boost for the 'DataSource' property. (ADO's GetRows method now used)
09-Oct-2019
- Change of how to achieve DPI-awareness to the controls for non-integral DPI.
  It's just a better technique now which reduces the number of resizes.
  However, the change has no visible impact for the end-user.
19-Aug-2019
- Minor internal improvement for ValidateEdit behavior.
27-Jul-2019
- Included the DirectionAfterReturn property. It allows to move the position of the current cell when the user presses return (Enter) key.
  This property works in conjunction with the WrapCellBehavior property. (like the TabBehavior property does)
16-Jul-2019
- Included the WantReturn property. Indicates when the user presses RETURN to perform the default button or to allow the flex grid to handle the return key.
  But it applies only when there is any default button on the form.
17-Jun-2019
- Included the ColFormat run-time property.
- Included additional FlexEditReasonBackSpace enum const. Pressing the backspace key then starts cell editing and removes all content.
14-Jun-2019
- Included additional PictureAlignment enum constants to allow pictures to not overlap with the text.
03-Jun-2019
- If drop-down list extends beyond bottom edge of the screen (MonitorFromWindow API) then it will be displayed above the edit window.
  Just like a normal ComboBox would behave.
23-May-2019
- Usage of SPI_GETFOCUSBORDERWIDTH/SPI_GETFOCUSBORDERHEIGHT for correct focus rect drawing.
- Minor bugfix related to 14-May-2019 update.
22-May-2019
- Included the ComboMode/ColComboMode run-time property that allows to use combo functionality when editing a cell, it returns/sets.
  - FlexComboModeNone -> Normal editing.
  - FlexComboModeDropDown -> Allows to modify by drop-down list only.
  - FlexComboModeEditable -> Allows to modify by normal editing and drop-down list.
  - FlexComboModeButton -> Allows to modify by button only, which is a request to open a custom editor.
- Included the ComboButtonValue run-time property which sets the value of the combo button by code, it returns/sets:
  - FlexComboButtonValueUnpressed -> Normal.
  - FlexComboButtonValuePressed -> Shows drop-down list or raises ComboButtonClick. (depending on ComboMode)
  - FlexComboButtonValueDisabled -> Cannot click, grayed and closes up drop-down list if necessary.
- Included ComboItems/ColComboItems run-time property defines the strings to be used for a drop-down list.
  Each item is separated with "|". If ComboMode property is Button then this property is ignored.
- ComboList/ComboListCount/ComboListIndex run-time property are helping to interact with the drop-down list by code.
- ComboDropDown/ComboCloseUp event, which occurs only when ComboMode is DropDown or Editable.
- ComboButtonClick event, which occurs only when ComboMode is Button.
- Included ComboButtonDrawMode run-time property and corresponding ComboButtonOwnerDraw event.
19-May-2019
- Bugfix in the Picture property. (related to 08-May-2019 update)
14-May-2019
- Eliminated run-time limitation of no support for having fixed cell(s) without cell(s). (e.g. FixedRows = 1 and Rows = 1)

[...]

14-Jun-2017
- First release.
```

----------


## Krool

*List of enhancements and improvements in relation to the MSFlexGrid and/or MSHFlexGrid control:*


```
- Scrolling beyond 65,535 rows possible. (16-bit barrier in MSHFlexGrid)
- Changing Row/Col property will respect the selection mode. (bug in MSFlexGrid and MSHFlexGrid)
- MouseWheel can be used to scroll. (limitation in MSFlexGrid and MSHFlexGrid)
- No cell count limit of 350000, only available memory space determines the cell count limit. (limitation in MSFlexGrid)
- FrozenRows/FrozenCols property included.
- AllowUserFreezing property included.
- AfterUserFreeze event included.
- RowSizingMode property included. (like in MSHFlexGrid)
- Align property included.
- DisableNoScroll property included.
- Added the Col param in the Compare event as it helps when doing multi-column sorts.
- WM_ERASEBKGND can be intercepted in a subclass to fill a custom background, if necessary.
- BackColorAlt property included to set alternate row back colors. (setting BackColor automatically sets BackColorAlt to the same value)
- DoubleBuffer property included.
- RightToLeft property included.
- AllowMultiSelection property included with related RowSelected/SelectedRow/SelectedRows property.
- AllowSelection property included.
- TabBehavior property included.
- DirectionAfterReturn property included.
- WantReturn property included.
- ExtendLastCol property included.
- SheetBorder property included. (Default is True to behave like MSFlexGrid else no border like MSHFlexGrid)
- WrapCellBehavior property included.
- ClipSeparators property included.
- ClipSeparatorCol/ClipSeparatorRow property (run-time only) included to change the defaults and to support more than 1 character for a separator.
- ClipMode property included to include (default) or exclude hidden cells in a clip command.
- ClipCopyMode property included to determine what parts are copied to the clipboard or returned by a clip command.
- ClipPasteMode property included to determine how content is pasted from the clipboard or by doing a clip command.
- ShowInfoTips, ShowLabelTips and CellToolTipText property included.
- EllipsisFormat/EllipsisFormatFixed property included.
- Dashes/Dots enum included in the GridLine property. (like in MSHFlexGrid)
- FontFixed property included. (like in MSHFlexGrid)
- GridLineWidthFixed property included. (like in MSHFlexGrid)
- FixGridLineOffsets property included.
- MirrorAlignGeneral property included.
- SingleLine property included.
- Flat enum included in the FocusRect property.
- Cell property included which allows to get or set cell settings directly for an arbitrary cell or range of cells without selecting them.
- CellTextStyle returns the TextStyle/TextStyleFixed from the Control when not preset instead of 0.
- CellAlignment returns the alignment from the column (ColAlignment or FixedAlignment) when not preset instead of 0.
- CellBackColor/CellForeColor returns the BackColor/ForeColor from the Control when not preset instead of 0.
- CellTextStyle/CellAlignment/CellBackColor/CellForeColor are not preset anymore when setting a value of -1.
- CellChecked property for checkboxes along with CellBeforeCheck/CellCheck event.
- ColWidthMin property included. (analogous to the RowHeightMin property)
- RowHeightMax/ColWidthMax property included.
- MouseEnter/MouseLeave event included.
- HitTest method included with a specified X and Y. The return values are in the HitRow/HitCol/HitRowDivider/HitColDivider/HitResult property.
- FindItem function included.
- FixedAlignment property accepts an index of -1 (like ColAlignment) to apply the value to all columns.
- FixedAlignment is not preset anymore when setting a value of -1.
- Mouse cursor is now clipped when user resizing rows and columns.
- CellEnsureVisible method included with optional visibility parameter. (default is FlexVisibilityCompleteOnly)
- BottomRow/RightCol property included with optional visibility parameter. (default is FlexVisibilityPartialOK)
- RowsVisible/ColsVisible/FixedRowsVisible/FixedColsVisible/FrozenRowsVisible/FrozenColsVisible property with an optional visibility parameter. (default is FlexVisibilityCompleteOnly)
- RowIsVisible/ColIsVisible property optional visibility parameter included. (default is FlexVisibilityPartialOK)
- RowHidden/ColHidden property included. (same as RowHeight/ColWidth set to 0, but this approach preserves the original setting)
- ColKey/ColIndex and RowID/RowIndex property included. (used to identify specified column/row)
- ColDataType/ColNumericPrecision/ColNumericScale/ColDataCapacity property.
- RowsPerPage/ColsPerPage property included that returns the number of non-fixed columns/rows displayed on the current page to scroll through. (no visibility parameter here)
- GetSelRange method included to retrieve selection range of cells ordered so that Row1 <= Row2 and Col1 <= Col2.
- SelectRange method which selects a range of cells or a cell (by omitting RowSel/ColSel) with a single command.
- GetMergedRange method included to retrieve the merged cells on a given row/col.
- SelChange event is also fired while the user extends the selection with the mouse. (limitation in MSFlexGrid and MSHFlexGrid)
- Scroll event is fired whenever the TopRow/LeftCol property changes. (limitation in MSFlexGrid and MSHFlexGrid)
- BeforeUserResize/AfterUserResize/AfterUserResizeEnd event included.
- BeforeRowColChange/BeforeSelChange event included.
- Copy/Cut/Paste/Delete method and related AutoClipboard property.
- Clear method optional Where/What parameter included.
- When MergeCells is set to a value other than 0 (Never), selection highlighting is still possible. (limitation in MSFlexGrid and MSHFlexGrid)
- MergeCells can span multiple rows and columns together. (limitation or bug in MSFlexGrid and MSHFlexGrid)
- FixedOnly enum included in the MergeCells property.
- UseColSort enum included in the Sort property and corresponding ColSort property included.
- ColSortArrow/ColSortArrowAlignment/ColSortArrowColor property included.
- SortArrowColor/RowSortArrows property included.
- CurrencyAscending/CurrencyDescending and DateAscending/DateDescending enum included in the Sort/ColSort property.
- CellFloodPercent/CellFloodColor/FloodColor property included.
- AutoSize method included.
- BestFitMode property included which is used for AutoSize/FormatString.
- TextWidth/TextHeight function included.
- DividerDblClick event included.
- DataRefresh method included.
- FlexDataSource property (run-time only) included to set a custom data source via the IVBFlexDataSource interface.
- AllowUserEditing property included with many events and run-time properties. (in-cell editing functionality)
- AllowScrollLock property to check the toggled state of vbKeyScrollLock to let the users use the arrow keys to scroll. (like in Excel)
- Some other minor improvements.
```

*List of incompatibilities in relation to the MSFlexGrid control:*


```
- FontWidth and CellFontWidth property not implemented.
```

----------


## ChenLin

Very much and need this OCX to support print preview and paging? There is a great need for this feature: you can directly set the image read from the database and display it in each cell.

----------


## Krool

> Very much and need this OCX to support print preview and paging?


There will be no OCX for the moment as I want to wait a certain period for potential bugfixes etc. (trial period)
You can make your own Print Preview. You can extract via the .Picture property a StdPicture object which holds a "printed" content of the grid.
However it prints always the whole grid (like in MSFlexGrid). However, when there is a need to include optional parameters to "print" only a part (e.g. current view) then we can look further.
What do you mean by paging?
Again this is certainly a job for the app to break according to printer settings etc.

----------


## ChenLin

Paging I have done using SQL SERVER, the main thing is to show the image in the database, MSHFLEXGRID is not very convenient to display the image in the database.

----------


## ChrisE

Hello Krool,

I just tried your VBFlexGrid, I was surprised how easy it was to change
my code from MsFlexGrid to VBFlexgrid. And the Project executed with now faults.

here is what I tried out and what I had to change, I marked my changes
like this:
 '// had to change this
            '.CellAlignment = flexAlignCenterCenter
            '// to :

in Modul:


```
Option Explicit

Public Sub KalenderFlexShow(Flex As VBFlexGrid, Jahr As Long)
   Dim i As Long, j As Long
   Dim Days As Long
   Dim Datum As Date
      With Flex
         .Redraw = False
         .Rows = 33
         .Cols = 14
         .FixedCols = 0
         .FixedRows = 2
         .Clear
         .TextMatrix(0, 0) = CStr(Jahr - 1)
         .TextMatrix(1, 0) = MonthName(12)
         For i = 1 To 12
            .TextMatrix(0, i) = CStr(Jahr)
            .TextMatrix(1, i) = MonthName(i)
         Next
         .TextMatrix(0, 13) = CStr(Jahr + 1)
         .TextMatrix(1, 13) = MonthName(1)
         .Row = 0
         For i = 0 To .Cols - 1
            .Col = i
            '// had to change this
            '.CellAlignment = flexAlignCenterCenter
            '// to :
            .CellAlignment = FlexAlignmentCenterCenter
         Next
         For i = 1 To 12
            KalenderFlexMonat Flex, i, Jahr, i
         Next
         KalenderFlexMonat Flex, 12, Jahr - 1, 0
         KalenderFlexMonat Flex, 1, Jahr + 1, 13
         If Jahr = Year(Now) Then
            .Col = Month(Now)
            .Row = Day(Now) + 1
         ElseIf (Jahr = Year(Now) - 1) And (Month(Now) = 12) Then
            .Col = 0
            .Row = Day(Now) + 1
         ElseIf (Jahr = Year(Now) + 1) And (Month(Now) = 1) Then
            .Col = 13
            .Row = Day(Now) + 1
         Else
            .Col = 1
            .Row = 0
         End If
         .Redraw = True
      End With
End Sub

Private Sub KalenderFlexMonat(Flex As VBFlexGrid, Monat As Long, _
                              Jahr As Long, Col As Long)

   Dim Days As Long, i As Long
   Dim Datum As Date
   Dim s As String
      Datum = DateSerial(Jahr, Monat, 1)
      Days = Day(DateAdd("m", 1, Datum) - 1)
      With Flex
         .Col = Col
         For i = 1 To Days
            .Row = i + 1
            s = Format(i, "00") & Space(2)
            If Weekday(Datum, vbMonday) = 7 Then
               s = s & Format(Datum, "ddd")
               .CellForeColor = vbRed
            Else
               s = s & Format(Datum, "ddd")
               .CellForeColor = vbBlack
            End If
            .Text = s
           '// had to change this
            '.CellAlignment = flexAlignLeftCenter
            '// to :
            .CellAlignment = FlexAlignmentLeftCenter
            Datum = Datum + 1
         Next
      End With
End Sub
```

in Form:


```
Option Explicit
Private Sub Command1_Click()
   Dim s As String
      s = InputBox("Jahr eingeben", "Kalender", Year(Now))
      If Len(s) = 0 Then
         Exit Sub
      ElseIf Not IsNumeric(s) Then
         Exit Sub
      End If
      KalenderFlexShow VBFlexGrid1, Val(s)
End Sub

Private Sub Form_Load()
      With VBFlexGrid1
       '  .FocusRect = flexFocusHeavy
         .FocusRect = FlexFocusRectHeavy
         .BackColorBkg = Me.BackColor
         .AllowBigSelection = False
        ' .SelectionMode = flexSelectionFree
         .SelectionMode = FlexSelectionModeFree
      End With
      KalenderFlexShow VBFlexGrid1, Year(Now)
End Sub

Private Sub Form_Resize()
      If Me.WindowState = vbMinimized Then
         Exit Sub
      End If
      On Error Resume Next
      With VBFlexGrid1
         .Top = 300
         .Left = 0
         .Width = Me.ScaleWidth
         .Height = Me.ScaleHeight - .Top
      End With
      On Error GoTo 0
End Sub
```

I haven't looked threw your complete List of enhancements and improvements
but for the first test I am impressed!!!!!!!

regards
Chris

----------


## DEXWERX

2 questions:
Are you going to implement data binding?
How would you implement a virtual/on demand data source?

----------


## Krool

> 2 questions:
> Are you going to implement data binding?
> How would you implement a virtual/on demand data source?


It is planned to be implemented.

1. Making the UserControl.DataBindingBehavior set to 'vbComplexBound' and provide a 'DataSource' and 'DataMember' property. (like in MSHFlexGrid, only ADO)
However, that needs to include the 'msdatsrc.tlb' type library and expose its DataSource interface. (=*Dependency*; as exposed publicly)
So I need to check if there would be no issue to make such a "dependency" with the 'msdatasrc.tlb' type library. It is part of MDAC, which should be pre-installed since Windows 2000. Or am I wrong?

2. Providing a run-time .Recordset property (Also like in MSHFlexGrid, could be 'As Object' thus supporting both DAO and ADO Recordsets)

----------


## Arnoutdv

I'm using the vsFlexGrid control and this control has quick access to ranges of cells to change the layout and content.
So instead of settings ROW, COL, ROWSEL, COLSEL and FILLSTYLE you just specify the range of the cells on which a method is executed, advantage that you don't have to change the active selection to modify cell content/layout.

Idea for vbFlexGrid replacements for Cell* with Range* like:
RangeFontBold(Row1, Col1, Row2, Col2)
RangeForeColor(Row1, Col1, Row2, Col2)

PS
The vsFlexGrid control uses a different method using a single .Cell() method, in which you also specify what you want to do.

----------


## Krool

> So instead of settings ROW, COL, ROWSEL, COLSEL and FILLSTYLE you just specify the range of the cells on which a method is executed, advantage that you don't have to change the active selection to modify cell content/layout.


Good idea, thanks. Update released.

Included the Cell property which allows to get or set cell settings directly for an arbitrary cell or range of cells without selecting them.
However, when setting a range of cells via the Cell property it is dependent like in the normal Cell* properties how the FillStyle property is defined.
So if FillStyle is Single you can select a range via the Cell property it will only set the arbitrary cell and not the selection. (Exception is when setting the Clip property via the Cell property)

----------


## ChrisE

Hello Krool

would it make sense to Hardcode some Funtions in the Grid ?

like the Routine I used to create the Calendar, you would the just call somthing like



```
  VBFlexGrid1.KalenderFlexShow,Year(Now)
```

in regards to loading Data from a Database, I would do the same thing
one for ADO Recordsets and one for DAO.

something like this..


```
'ADO Version
Public Function FlexFillFromRs(Rs As ADODB.Recordset, _
                               Flex As MSFlexGrid)
'loading Recordset
   Dim i As Long
   Dim j As Long
   Dim breit As Single
      
      With Flex
         .Redraw = False
         .AllowBigSelection = True
         .AllowUserResizing = flexResizeBoth
         .Appearance = flex3D
         .FocusRect = flexFocusNone
         .FixedRows = 1
         .FixedCols = 1
         'count cols
         .Cols = Rs.Fields.Count
         'Headers
         For i = 0 To Rs.Fields.Count - 1
            .TextMatrix(0, i) = Rs.Fields(i).Name
         Next
         'count rows
         .Rows = .FixedRows + Rs.RecordCount + 1
                                                      
         'fill Flex
         Do While Not Rs.EOF
            'Records
           i = Rs.AbsolutePosition
            For j = 0 To Rs.Fields.Count - 1
               'Abfrage auf NULL
               If Not IsNull(Rs.Fields(j).Value) Then
                  .TextMatrix(i, j) = Rs.Fields(j).Value
               End If
            Next
            Rs.MoveNext
         Loop
         
         'optimise width
         For i = 0 To .Cols - 1
            breit = 0
            For j = 0 To .Rows - 1
               If Me.TextWidth(.TextMatrix(j, i)) > breit Then
                  breit = Me.TextWidth(.TextMatrix(j, i))
               End If
            Next
            .ColWidth(i) = breit + 120
         Next
         .Redraw = True
      End With
End Function
```

then you would just have to pass a valid ADO Recordset and Connection to the Grid like..



```
 VBFlexGrid1.FlexFillFromRs(myADORecordset)
```

just an Idea

regards
Chris

----------


## Bobbles

I just downloaded and tried  - VERY NICE
There may be quite a few of us that don't need Unicode, and thus may not have bothered downloading your contribution.
However if the title of your thread had been -
VBFlexGrid User Control (Replacement of the MSFlexGrid control)
And there had been a bit more emphasis on NO DEPENDENCIES
I would have downloaded it before the ink on your OP had dried  

Thanks for sharing,
Rob
PS The Printscreen to Clipboard ain't too shabby either

----------


## ChrisE

> I would have downloaded it before the ink on your OP had dried


I agree;-))

----------


## Krool

> There may be quite a few of us that don't need Unicode, and thus may not have bothered downloading your contribution.
> However if the title of your thread had been -
> VBFlexGrid User Control (Replacement of the MSFlexGrid control)
> And there had been a bit more emphasis on NO DEPENDENCIES
> I would have downloaded it before the ink on your OP had dried


It is not only for Unicode. For me personally it was important to get some annoying bugs fixed and be indepedent of any OCX. And of course the additional features.
For the thread title: UserControl would be even more directly, True. But I want to keep the wording dual-use as after this Std-EXE version there will also be an ActiveX Version (OCX), after a certain trial period.

----------


## DEXWERX

can you add a VirtualMode to the demo when it's ready?

ie: let's say you're scrolling through a half a million records, but you really only want to provide the data to the control when it's scrolled into view.

----------


## Schmidt

> can you add a VirtualMode to the demo when it's ready?
> 
> ie: let's say you're scrolling through a half a million records, but you really only want to provide the data to the control when it's scrolled into view.


To properly implement that, I'd suggest the exact same Interface (also IID-wise), as the vsFlexGrid is using
(*IVSFlexDataSource*, ...it is a nice and small one - despite being universal for all kinds of "Data with Header-Descriptions"):



```
[
  odl,
  uuid(8E203240-537D-11D3-BD8C-000000000000),
  dual,
  oleautomation
]
interface IVSFlexDataSource : IUnknown {
    [id(0x00000001)]
    HRESULT GetFieldCount([out, retval] long* pFields);
    [id(0x00000002)]
    HRESULT GetRecordCount([out, retval] long* pRecords);
    [id(0x00000003)]
    HRESULT GetFieldName(
                    [in] long Field, 
                    [out, retval] BSTR* pFieldName);
    [id(0x00000004)]
    HRESULT GetData(
                    [in] long Field, 
                    [in] long Record, 
                    [out, retval] BSTR* pData);
    [id(0x00000005)]
    HRESULT SetData(
                    [in] long Field, 
                    [in] long Record, 
                    [in] BSTR newData);
};
```

In the vsFlexGrid, VB6-Classes which implement it, are then used together with the vsFG.*FlexDataSource*-Property (of Type *IVSFlexDataSource*),
to address external Data of DAO-, ADO- or SQLite-Recordsets, or just plain String- or Variant-Arrays outside the Control.

Note that the vsFlexGrid.FlexDataSource-Prop is exposed as only a Get/Let-pair (just mentioning it,
since that might irritate some VB6-devs, because it's a bit unusual, not being allowed to use a Property *Set* 
when passing an Object into a Control (so, perhaps best, to implement it as a "full VB6-Triple-Prop" Get/Let/Set)...

Olaf

----------


## Krool

> To properly implement that, I'd suggest the exact same Interface (also IID-wise), as the vsFlexGrid is using
> (*IVSFlexDataSource*, ...it is a nice and small one - despite being universal for all kinds of "Data with Header-Descriptions"):
> 
> 
> 
> ```
> [
>   odl,
>   uuid(8E203240-537D-11D3-BD8C-000000000000),
> ...


Good suggestion, thanks. _But_ exposing an type lib interface with a public property brings type lib dependency in a later potential OCX...

IMO would be a simple classic "event mechanism" for virtual data be sufficient? or would I overlook something in that case?
Or put the type lib interface in a "like-wise" VB6 class.

----------


## Schmidt

> Good suggestion, thanks. _But_ exposing an type lib interface with a public property brings type lib dependency in a later potential OCX...
> 
> IMO would be a simple classic "event mechanism" for virtual data be sufficient? or would I overlook something in that case?
> Or put the type lib interface in a "like-wise" VB6 class.


The latter one (a simple interface-defining VBClass with the name IVSFlexDataSource would be sufficient) -
I've just looked into our Project-Codes, the implementing Classes are all quite small Private ones in our Projects, 
so the exact same IID of the original Interface wouldn't be that important in our cases as I thought, 
 just "Signature compatibility" would be enough).

A (Latebound working) Event-mechanism could also do (performance not being such a critical factor here,
since the "visible Rows and Cols" of the currently scrolled "ViewPort" are not all that many...

In case of an (then earlybound) true Interface-Class, you could also enclose the points where you expect an "IVSFlexDataSource"-
implementing Object in compiler-conditionals (#If CompileWithFlexDataSourceSupport .... or something, in the non-OCX-version).

Olaf

----------


## Krool

> A (Latebound working) Event-mechanism could also do (performance not being such a critical factor here,
> since the "visible Rows and Cols" of the currently scrolled "ViewPort" are not all that many...


When there is a "search" trough a find function does it callback all items via GetData or is there is special callback (like LVN_ODFINDITEM style) where the client is responsible to return the found row/index?

----------


## DEXWERX

I've always had to code custom search/find for the MSHFlexGrid anyway. (not sure)
For efficiency I would think the LVN_ODFINDITEM approach would be best.

----------


## Krool

> I've always had to code custom search/find for the MSHFlexGrid anyway. (not sure)
> For efficiency I would think the LVN_ODFINDITEM approach would be best.


And the same for a Sort?

----------


## Schmidt

> And the same for a Sort?


I'd not bother with Find and Sort (delegations) in case of external FlexDataSource-Data.

The reason a developer is working with such an external DataSource is (beside others),
that he probably wants to sort, filter, search the external containers much more comfortably (and faster) on their own
(without any "help from a Grid-control").

A Grid is mainly for managing and rendering the ViewPort, nothing much else.

If I want external Data sorted in the vsFlexGrid I do it on the Rs or the Array itself - 
and then refresh the DataSource (which in this case only enforces a new rendering of the viewport).

Olaf

----------


## Krool

> I'd not bother with Find and Sort (delegations) in case of external FlexDataSource-Data.
> 
>  The reason a developer is working with such an external DataSource is (beside others),
>  that he probably wants to sort, filter, search the external containers much more comfortably (and faster) on their own
>  (without any "help from a Grid-control").
> 
>  A Grid is mainly for managing and rendering the ViewPort, nothing much else.
> 
>  If I want external Data sorted in the vsFlexGrid I do it on the Rs or the Array itself - 
>  and then refresh the DataSource (which in this case only enforces a new rendering of the viewport).


Exactly. Just like in a ListBox with LBS_NODATA it is not possible to add LBS_SORT.
Therefore in the FlexGrid the .FindItem and .Sort functionality just needs to be "disabled" by an error raise in case VirtualMode is turned on. (=Solved)

----------


## DEXWERX

That works, and is in line with how MS handled mshflxgd also.

----------


## Krool

One further question for VirtualMode layout.
What Schmidt suggested for the FlexDataSource interface means actually always 1 fixed row (field name) and 0 fixed columns.
The GetFieldCount method would define the number of columns and the GetRecordCount the number of rows.
However, that means I also need to disable the Rows/Cols and FixedRows/FixedCols properties.
OR instead they are allowed (flexible) and just a 'RetrieveVirtualItem' event would be fired for all cells in viewport, regardless if they are 2 fixed rows or none. I think that would be a very flexible approach?

----------


## DEXWERX

yes, you definitely don't want to lock fixed cells. 
Fixed cells are often used for row numbers or other indicators, which also need to be populated in virtualmode.

It's a good idea to use the event/callback for all cells including fixed. 

you could also use a single call for the entire window update - as opposed to each cell. (just an idea)

----------


## Schmidt

> The GetFieldCount method would define the number of columns and the GetRecordCount the number of rows.
> However, that means I also need to disable the Rows/Cols and FixedRows/FixedCols properties.
> OR instead they are allowed (flexible) and just a 'RetrieveVirtualItem' event would be fired for all cells in viewport, ...


Sure, the vsFlexGrid allows free settings on the FixedRows/FixedCols also in "FlexDataSource"-mode...
(the FixedRows-setting not affecting the Zerobased "Record-Param" which is passed into the Callback).



```
Private Function IVSFlexDataSource_GetData(Byval Field As Long, ByVal Record As Long) As String
  IVSFlexDataSource_GetData = RsSQLite.ValueMatrix(Record, Field) 'example for providing the Data from an SQLite-Recordset
End Function
```

It's just that the CallBack-Function in IVSFlexDataSource will be called for *only* the currently *visible* cells 
of the (potentially scrolled) Viewport-area (leaving "skipped gaps" between the zerobased FixedCol-indexes and the 
Col (Field) indexes of the scrollable Cells).

You have to manage these "skips" internally when raising your Event or Callback (so that the Callback is not 
called unnecessarily for any cells which are currently not scrolled into the ViewPort).

Olaf

----------


## Krool

Updated released.

Included the DataSource/DataMember property. The properties can be set at design-time and/or at run-time.
The Adodc control, an DateEnvironment designer and a ordinary ADODB.Recordset object have been tested and are thus supported.

If somebody don't want to use the new feature and want to avoid a reference to msdatsrc.tlb (pre-installed since Win2k) the whole thing can be turned off by setting the new conditional compilation constant 'ImplementDataSource' to False.
When doing so (turn off) the 'DataBindingBehavior' might be changed back from 'vbComplexBound' to 'vbNone'.

What is still missing is a run-time only 'Recordset' property. (like in MSHFlexGrid)
But here I am still uncertain of how to best implement it and if and how to interact with the now implemented 'DataSource' property.

----------


## ChenLin

This OLEGuids.tlb is 32 and cannot be referenced in win10 64.

----------


## Krool

> This OLEGuids.tlb is 32 and cannot be referenced in win10 64.


Did you put the OLEGuids.tlb in the SysWOW64 system folder?
Also try to reference the file with Browse..

----------


## ChenLin

> Did you put the OLEGuids.tlb in the SysWOW64 system folder?
> Also try to reference the file with Browse..


That's already done, but still not. The prompt version is incompatible, unable to register, and cannot refer to this TLB in VB6K.
I referenced other OLEGuids.tlb, except for the function of "Show Property Pages".

----------


## Krool

> That's already done, but still not. The prompt version is incompatible, unable to register, and cannot refer to this TLB in VB6K.
> I referenced other OLEGuids.tlb, except for the function of "Show Property Pages".


Which other OLEGuids?
In case you have multiple versions you can name this version OLEGuids2 and reference accordingly.
This version is equal to the ComCtls version.
Last year there was a new version released with new uuid. If you have an older version you might "unregister" that first.

----------


## chosk

Actually, I also have problem registering OLEGuids.tlb on Win10 x64.

----------


## Krool

Regsvr32 is wrong. Just let VB register it.
There is a also a tool for registeeing type libs (and unregister)
http://www.vbaccelerator.com/home/VB...y/article.html

----------


## chosk

Oh, I did not know VB can register it. I just tried and it works.

I also use CCRP Reg Util to register tlb (it has a choice for tlb) and it works on Win7 but not on Win10.

----------


## Krool

> Oh, I did not know VB can register it. I just tried and it works.


Glad to hear. Does the vbAccelerator tool also work?

----------


## chosk

The vbAccelerator tool... I tried download on 2 computers but file is invalid.

----------


## chosk

I found it in my backup. I have forgotten I downloaded perhaps years back.

It can register but unregister gives a 8002801C error.

----------


## ChenLin

> Which other OLEGuids?
> In case you have multiple versions you can name this version OLEGuids2 and reference accordingly.
> This version is equal to the ComCtls version.
> Last year there was a new version released with new uuid. If you have an older version you might "unregister" that first.


TLB the problem is solved, and I did this: use this TLB to override the TLB in the system.

----------


## ChenLin

> Actually, I also have problem registering OLEGuids.tlb on Win10 x64.


Try my way: use this TLB to override the TLB in the system

----------


## ChenLin

I do not know if this is a bug: Change BackColor when the BackColorAlt also changed, need to re-set BackColorAlt.

----------


## Krool

> I do not know if this is a bug: Change BackColor when the BackColorAlt also changed, need to re-set BackColorAlt.


That is not a bug, it's a feature.  :Smilie: 
Since in the original MSFlexGrid is no such BackColorAlt property it must be changed synchronous whenever the BackColor changes to maintain compatibility.

----------


## Karl77

Awesome work!
And great to have a better grid in future.

I use MSFlexgrid quite often, and that is really cumbersome (mousewheel etc.).
Also I don't like the dependency to MSFLXGRD.OCX.

---

"- FormatString property not implemented"

Before I change my code in dozens of places:
Is FormatString not implemented YET or will it not happen?

---

Do you plan to implement something like AutoSizeColWidth?
Today I have to put the col content into a label, AutoSize=true, read the width, and then set the col width.
That is the opposite of fast and cumbersome as well.

----------


## Krool

Here also some minor "DPI Aware" updates. Mainly in the internal drawing routines.
There is only a very minor further tweak possible, namely the DrawFocusRect API.
Currently is still done by assuming as 1px thick.
So here could be done a minor further improvement by taking SPI_GETFOCUSBORDERWIDTH/SPI_GETFOCUSBORDERHEIGHT with SystemParametersInfo into account.
Has somebody expierence with this? I mean is this really related to high DPI? Or is this just a system setting that can be set to whatever regardless of DPI?
The documentation is not clear about this..




> "- FormatString property not implemented"
> 
> Before I change my code in dozens of places:
> Is FormatString not implemented YET or will it not happen?


I wanted to avoid to implement such a cumbersome property. (in my opinion)
But I can imagine that for many migration purposes it would be indeed easier to have it.
So yes, it is not YET implemented.  :Big Grin: 




> Do you plan to implement something like AutoSizeColWidth?


AutoSize features are needed, so yes planning to do so.

----------


## Krool

Update released.

Included the ClipSeparators property.
The two distinct characters will be used as column (first character) and row (second character) separators in clip strings. (.Clip property and .AddItem method)
If the property is set to empty, the defaults vbTab and vbCr are used.

While vbTab and vbCr (defaults) are useful when interacting between Excel spreadsheet and the flex grid it becomes a obstacles when dealing with a Recordset.
For instance when you use the 'GetString' method in a Recordset you can define a custom Column and Row delimiter. Now you can apply the same delimiters in the ClipSeperators property.
Reason: The delimiter vbTab and vbCr can also be contained within some text fields in the Recordset. So in most cases it is better to define other delimiters to circumvent that issue.

----------


## Krool

Update released.

Bugfix concerning the FixedAlignment property.
When not preset (internal value of -1) it returns now the ColAlignment property. (like in MSFlexGrid)
Also the CellAlignment (when not preset) returns then the ColAlignment or the FixedAlignment (if fixed cell and preset) property.
Unlike in the MSFlexGrid the FixedAlignment can be turned back to not preset by setting a value of -1.




> "- FormatString property not implemented"
> 
> Before I change my code in dozens of places:
> Is FormatString not implemented YET or will it not happen?


FormatString property is now implemented. I would appreciate if you could test it extensively.

----------


## chosk

Hi Krool,

I have tried to look for but not able how to go about doing this.

I have 1 fixed column on the left.
a) When I click on any cell in the fixed column, I want to set the SelectionMode to 1-ByRow and highlight and select that row. This will allow an option to Insert or Add a row.
b) Click on any other cell, I change to SelectionMode to 0-Free and select that cell for editing.

I have problem to capture the click on the left fixed column cell. Is this possible?

Edit:
If I can capture the click on the left fixed column cell, I can do the rest.

----------


## chosk

I found it. MouseCol and MouseRow.

----------


## Tech99

Downloaded and briefly fiddled with this - looks very promising. Do you plan to support in-cell editing?

----------


## chosk

Have not use FlexGrid before, not even MS. This is first time so a lot of features to get familiar with.

No need to change SelectionMode. This will do it. 



```
Private Sub FlexGrid_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    With FlexGrid
        If .MouseCol = 0 Then
            .Row = .MouseRow
            .Col = .MouseCol
            .RowSel = .Row
            .ColSel = .Cols - 1
        End If
    End With
    
    If Button = 2 Then
        'ToDo
        'Popup menu to InsertRow and AddRow
    End If
End Sub
```

----------


## Krool

@ Chosk, you can achieve what you want with .AllowBigSelection = True without any additional code. Of course for showing the Popup you need to handle like you did.




> Do you plan to support in-cell editing?


Yes, first point was to achieve an replacement. But of course more features will be added by the time.

----------


## chosk

> @ Chosk, you can achieve what you want with .AllowBigSelection = True without any additional code. Of course for showing the Popup you need to handle like you did.


Thanks, Krool.

Will check it out.

----------


## chosk

Hi Krool,

Re: .AllowBigSelection = True.

I read up on this. Actually nothing much to read - very simple.
https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx

So I play around with this property.

When True:
I can only select Column but cannot select Row.
Can also select entire grid by clicking on the Top Left cell where both Headers meet, like in Excel.

When False:
The cell immediately below the Column Header is selected (normal). Spariodically, the cell below the Column Header get highlighted and scroll up one row when a random Column Header is clicked.  Nothing happen when I click on Row Header.

----------


## Krool

> Hi Krool,
> 
> Re: .AllowBigSelection = True.
> 
> I read up on this. Actually nothing much to read - very simple.
> https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx
> 
> So I play around with this property.
> 
> ...


I can select the row when .AllowBigSelection = True.
Did you try in the VBFlexGridDemo if you can do select the row?

----------


## chosk

I forgot about the demo. Yes, I can select row when .AllowBigSelection = True. I will see what I have done differently.

----------


## chosk

I found out what is causing this ".AllowBigSelection = True" not working for row. When AllowUserResizing is 0-None or 1-Column then it won't work.

----------


## Krool

> I found out what is causing this ".AllowBigSelection = True" not working for row. When AllowUserResizing is 0-None or 1-Column then it won't work.


Update released. There was indeed an minor bug in an internal function (GetHitTestInfo).
Now it should work as expected. Thanks for reporting.

----------


## chosk

Thanks, Krool.

----------


## chosk

Hi Krool,

When .AllowBigSelection = False:
Spariodically, the cell below the Column Header get highlighted and scroll up one row when a Column Header is clicked.

----------


## Krool

> Hi Krool,
> 
> When .AllowBigSelection = False:
> Spariodically, the cell below the Column Header get highlighted and scroll up one row when a Column Header is clicked.


That behavior is expected and equals to MSFlexGrid. The "spariodically" is because you slightly move the mouse after your click, that's why it is scrolling up while your moving. (which is also expected and no bug)

----------


## chosk

Removed

----------


## chosk

Removed

----------


## chosk

Hi Krool,

Sorry for the trouble. I removed my earlier 2 posts because after giving some thoughts, maybe the ListView is more appropriate for my use. I want to be able to select only rows and not columns and only use the scrollbar to scroll the rows. The auto-scrolling of the rows in only one direction - upwards - may pose a problem for me.

Now I just go find a way to simulate ListView column one (ListItem) fixed and not editable. I hope can be done.

----------


## Krool

> Hi Krool,
> 
> Sorry for the trouble. I removed my earlier 2 posts because after giving some thoughts, maybe the ListView is more appropriate for my use. I want to be able to select only rows and not columns and only use the scrollbar to scroll the rows. The auto-scrolling of the rows in only one direction - upwards - may pose a problem for me.
> 
> Now I just go find a way to simulate ListView column one (ListItem) fixed and not editable. I hope can be done.


Try following before you switch to ListView:

SelectionMode = 1 - ByRow
AllowBigSelection = False

and add following Code:


```
Private Sub VBFlexGrid1_BeforeRowColChange(ByVal NewRow As Long, ByVal NewCol As Long, Cancel As Boolean)
If NewRow < VBFlexGrid1.TopRow Then
    VBFlexGrid1.Row = VBFlexGrid1.TopRow
    Cancel = True
End If
End Sub

Private Sub VBFlexGrid1_BeforeSelChange(ByVal NewRowSel As Long, ByVal NewColSel As Long, Cancel As Boolean)
If NewRowSel < VBFlexGrid1.TopRow Then
    VBFlexGrid1.RowSel = VBFlexGrid1.TopRow
    Cancel = True
End If
End Sub
```

----------


## chosk

Hi Krool,

Thanks for the suggestions. I have been playing around with it today and I think if I can do just 1 thing and the VBFlexGrid will be perfect for the job.

To explain...
I need :
AllowBigSelection = True
SelectionMode = 0-Free

Reasons:
I need to be able to select single row or multiple rows.
I need to be able to go to any cell and edit (I will implement the edit myself until you are ready).

I have this in MouseMove to disable selecting column:


```
Private Sub FlexGrid_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    With FlexGrid
        If (.MouseRow = 0) And (.MouseCol <> 0) Then
            .AllowBigSelection = False
        Else
            .AllowBigSelection = True
        End If
    End With
End Sub
```

With your codes suggestion, I am getting there but not quite. If I were to left-click and hold on the column header, the row will still scroll up but very slowly and the cells in that column that scroll will be selected. I want to prevent this.

So actually in short, what I want to achieve is to just ignore the left mouse click (and also click and hold) on the column header, just like with the present behavior of right mouse click. The selected cell remain where it is and not moved.

If maybe you can point me to where in your code I can 'rem' out the appropriate part then I don't have to trouble you. The default behavior of your VBFlexGrid will then remains as it is.

Thanks.

----------


## Krool

> If maybe you can point me to where in your code I can 'rem' out the appropriate part then I don't have to trouble you. The default behavior of your VBFlexGrid will then remains as it is.


I am thinking of including a 'Flags' property with enum constants which will control various behaviors.
If 0 -None it will equal to MSFlexGrid and by the time maybe more flags will get included.
Do you have an idea how to call your behavior change?
Maybe 'FlexFlagDisableNonBigSelectionFixedRowMouseMoveScroll' ?  :Big Grin: 

Edit: And of course it would be designed that in future multiple flags can be set together. (Like in MsgBox)

----------


## chosk

'FlexFlagDisableNonBigSelectionFixedCellClickScroll'. This is so funny. :Thumb:  :Big Grin: 

How about "AllowBigSelectionMode"
0 - FlexFlagAllowBigSelectionFixedCellClickScrollBoth (Default)  :Big Grin: 
1 - FlexFlagAllowBigSelectionFixedCellClickScrollHorizontalOnly  :Big Grin: 
2 - FlexFlagAllowBigSelectionFixedCellClickScrollVerticalOnly  :Big Grin: 

No lah.  :Big Grin: 

Copying the idea from SelectionMode:
0 - FlexBigSelectionModeBoth (Default)
1 - FlexBigSelectionModeByRow
2 - FlexBigSelectionModeByColumn

"AllowBigSelectionMode" because then it will be just below "AllowBigSelection" in the Properties List:
AllowBigSelection
AllowBigSelectionMode

And maybe also something like this group together with the Scroll properties: 

ScrollByHeader
0 - True (Default)
1 - False

----------


## Krool

Ok, I postpone the Flags idea.  :Wink: 
Then let's just introduce a new property called 'AllowDragScroll'.
It can then be set to following:
FlexAllowDragScrollEverywhere = 0 (default)
FlexAllowDragScrollNever = 1
FlexAllowDragScrollFixed = 2
FlexAllowDragScrollScrollable = 3

In your case you would then set to 'FlexAllowDragScrollScrollable' since you want to block the Fixed cells.
I think a differantiation between Rows and Column is not necessary because who would want to be drag scrolling in the scrollable area only by rows and not for columns?

And about the 'AllowBigSelectionMode'. Nice idea that would allow more detailed configuration for Both, ByRow or ByColumn of big selection.

----------


## chosk

> In your case you would then set to 'FlexAllowDragScrollScrollable' since you want to block the Fixed cells.
> I think a differantiation between Rows and Column is not necessary because who would want to be drag scrolling in the scrollable area only by rows and not for columns?


Yes.
Thanks.

----------


## Krool

Chosk, I would like to discard the new AllowDrag.. property.

Actually there is only a minor change necessary.
Currently the "DragSelection" is running immediately. (just like in MSFlexGrid)
But it would be better behavior to go into "DragSelection" mode when dragging the mouse out of the first captured cell. That behavior change would not make any difference in the scrollable cells, but especially for the fixed headers.

We could make this minor change and break behavior to MSFlexGrid for the better or we could make some other property (or Flag 'FlexFlagNoImmediateDragSelection' ?  :Big Grin:  ) to control if "DragSelection" will start immediately or when first move out of captured cell. You get it?

----------


## chosk

Hi Krool,

I manged to get the "customized" behavior I looking for so you need not do anything and can leave the behavior per default to MSFlexGrid.

This is what I did in WindowProcControl:


```
        Case WM_LBUTTONDOWN
            '======================
            'Disable LButtonDown on Fixed Row
            With HTI
                Pos = GetMessagePos()
                .PT.X = Get_X_lParam(Pos)
                .PT.Y = Get_Y_lParam(Pos)
                ScreenToClient hWnd, .PT
                Call GetHitTestInfo(HTI)
                If .MouseRow = 0 And .MouseCol <> 0 Then
                    VBFlexGridRowSel = VBFlexGridRow
                    VBFlexGridColSel = VBFlexGridCol
                    Exit Function
                End If
            End With
            '=====================
            SetCapture hWnd
            Call ProcessLButtonDown(GetShiftStateFromParam(wParam), Get_X_lParam(lParam), Get_Y_lParam(lParam))
```

Thanks for the help.

----------


## Krool

> Hi Krool,
> 
> I manged to get the "customized" behavior I looking for so you need not do anything and can leave the behavior per default to MSFlexGrid.
> 
> This is what I did in WindowProcControl:
> 
> 
> ```
>         Case WM_LBUTTONDOWN
> ...


Small suggestion to you to change little bit: (to be clean)


```
        Case WM_LBUTTONDOWN
            '======================
            'Disable LButtonDown on Fixed Row
            With HTI
                Pos = GetMessagePos()
                .PT.X = Get_X_lParam(Pos)
                .PT.Y = Get_Y_lParam(Pos)
                ScreenToClient hWnd, .PT
                Call GetHitTestInfo(HTI)
                If .HitRow = 0 And .HitCol <> 0 And .HitResult = FlexHitResultCell Then
                    Me.RowSel = Me.Row
                    Me.ColSel = Me.Col
                    Exit Function
                End If
            End With
            '=====================
            SetCapture hWnd
            Call ProcessLButtonDown(GetShiftStateFromParam(wParam), Get_X_lParam(lParam), Get_Y_lParam(lParam))
```

Edit:
I could include an 'BeforeMouseDown' event with Cancel parameter? (Similar to like in vsFlexGrid)

----------


## chosk

> I could include an 'BeforeMouseDown' event with Cancel parameter? (Similar to like in vsFlexGrid)


And I can do this to ignore the left mouse button. Great! Then I don't have to remember to insert my code every new update.

Thank you.



```
Private Sub FlexGrid_BeforeMouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean)
    With FlexGrid
        If (Button = 1) And (.MouseRow = 0) And (.MouseCol <> 0) Then Cancel = True
    End With
End Sub
```

----------


## Krool

Included the BeforeMouseDown event.

@ chosk, I would suggest to you to process the BeforeMouseDown as following:


```
Private Sub VBFlexGrid1_BeforeMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single, Cancel As Boolean)
With VBFlexGrid1
If Button = vbLeftButton And .AllowBigSelection = False Then
    .HitTest X, Y
    If .HitResult = FlexHitResultCell Then ' We still allow divider dragging, if applicable
        If .HitRow = 0 And .HitCol > 0 Then Cancel = True
    End If
End If
End With
End Sub
```

----------


## chosk

Hi Krool,

Thank you. Working great.

----------


## Krool

Bugfix in the generic sorting. It is now differentiating between text and numbers. Just like the MSFlexGrid control does.

----------


## MountainMan

Krool,

When do you plan to release the OCX version? I'd like to try this out in VBA but I have to have the OCX version. I thought about making my own but it seemed like this was relatively short-term for you so I have held off doing that, especially after seeing the hassle that Hosam had trying to make a new OCX out of your CCR controls...

----------


## Krool

> Krool,
> 
> When do you plan to release the OCX version? I'd like to try this out in VBA but I have to have the OCX version. I thought about making my own but it seemed like this was relatively short-term for you so I have held off doing that, especially after seeing the hassle that Hosam had trying to make a new OCX out of your CCR controls...


Yes, of course.
I thought to wait until "FlexDataSource" (VirtualMode) property is included.
But I could release VBFLXGRD10.OCX now and include such new features in a next OCX version.

----------


## MountainMan

If it is going to be 6 months then an OCX release now with a later update would work well. If it is a matter of a few days or weeks then I'll be patient and wait for FlexDataSource (VirtualMode) to be included. thanks for all your work.

----------


## Krool

> If it is going to be 6 months then an OCX release now with a later update would work well. If it is a matter of a few days or weeks then I'll be patient and wait for FlexDataSource (VirtualMode) to be included. thanks for all your work.


I will release an OCX version shortly. There are some nasty pitfalls for VBA compatibility. I did now a few internal improvements to solve some issues. However, there still issue left and I need some time to solve it. So be patient.  :Smilie:

----------


## MountainMan

Patience is a virtue and I like to think I'm virtuous so I'll wait... Thanks.

----------


## Krool

ActiveX Control Version released. It can run in the VBA environment from the beginning.

However, there is the VBA mysterious arrow key shift control focus issue.
Due to the fact that IOleInPlaceActiveObject::TranslateAccelerator is not catched by VBA. (same "issue" with the VBCCR ActiveX)

If somebody has an solution please let me know. But at least all can "run" in VBA without crashes.

----------


## darjeeling

Hi Krool,
A ScaleMode property will be useful.

----------


## Karl77

What do you need it for?
Just curious.

----------


## Karl77

FORMATSTRING ISSUE

The FormatString doesn't work for me.
See attached example.
Grid1.zip

Thank you

----------


## Karl77

REMARKS/QUESTIONS

A)
Can I get the width of the vertical scrollbar?
(Now I get it using GetSystemMetrics - perhaps there is a property in the Grid I don't know of?)

B)
An AutoSizeColumn feature would be highly appreciated.

C)
AutoSizeColumn could also work on a doubleclick between columns.

D)
I think GridLines/GridLinesFixed is mixed, or I get the meaning wrong.

E)
Something like IntegralHeight would be useful.
Now I do: .Height = ((Int(.Height / .CellHeight)) * .CellHeight)

---

Otherwise, the grid works great, it is also quite fast.
A very good replacement for the old MsFlexGrid.


Karl

----------


## Karl77

SCROLL PROBLEM / RANGE

See attached project.
Grid1b.zip

F)
Click 'Fill'.
Click below the last row.
See the whole grid scrolling to the left.
Not wanted of course...


```
.Cell(FlexCellLeft, .Rows - 1, .Cols - 1)
```

Seems to be the cause.

G)
Click 'Make cell range red'.
A single cell becomes red, but not the range.
.Cell(FlexCellBackColor, 1, 0, 3, 3) = vbRed
I understand row #1, col #0 to row #3 to col #3.
But setting the range has no effect.
My misunderstanding or a bug?

Karl

----------


## Krool

> FORMATSTRING ISSUE
> 
> The FormatString doesn't work for me.
> See attached example.
> Grid1.zip
> 
> Thank you


It's not a bug, it's a feature.  :Smilie: 

Reason is because the FormatString needs a FixedRow.
In the VBFlexGrid it is not possible to have fixed rows and no cells.

So, instead of:



```
Private Sub Command1_Click()

With VBFlexGrid1
    .Clear
    .Rows = 1
    .Cols = 3
    .FixedCols = 1
    '.Redraw = False
End With

VBFlexGrid1.FormatString = Headline

End Sub
```

do:



```
Private Sub Command1_Click()

With VBFlexGrid1
    .Clear
    .Rows = 2
    .Cols = 3
    .FixedCols = 1
    .FixedRows = 1
    '.Redraw = False
End With

VBFlexGrid1.FormatString = Headline

End Sub
```

I added this point in the incompatibilities. (that it is not possible to have fixed rows and no cells)




> F)
> Click 'Fill'.
> Click below the last row.
> See the whole grid scrolling to the left.
> Not wanted of course...
> 
> 
> ```
> .Cell(FlexCellLeft, .Rows - 1, .Cols - 1)
> ...


Stupid behavior issue.
The MSFlexGrid does scrolling to current cell. Similar to the .CellEnsureVisible method in the VBFlexGrid.
So in order to be compatible I also do a .CellEnsureVisible when calling .CellLeft. (or indirectly via .Cell)




> G)
> Click 'Make cell range red'.
> A single cell becomes red, but not the range.
> .Cell(FlexCellBackColor, 1, 0, 3, 3) = vbRed
> I understand row #1, col #0 to row #3 to col #3.
> But setting the range has no effect.
> My misunderstanding or a bug?


Not a bug. Just make .FillStyle = FlexFillStyleRepeat and then it works.[/QUOTE]




> A)
> Can I get the width of the vertical scrollbar?
> (Now I get it using GetSystemMetrics - perhaps there is a property in the Grid I don't know of?)


Could be included. Have noted .ScrollBarSize like in the SysInfo control.
Or maybe ScrollBarWidth and ScrollBarHeight to have CX and CY values...




> B)
> An AutoSizeColumn feature would be highly appreciated.


Already noted from your previous posts.




> C)
> AutoSizeColumn could also work on a doubleclick between columns.


Yes yes, there would be a lot more possible.  :Wink: 
First goal was to have a working replacement in place so I can migrate projects.




> D)
> I think GridLines/GridLinesFixed is mixed, or I get the meaning wrong.


GridLines is for the cells and GridLinesFixed for the fixed cells. I see no problem there. Can you explain more?




> E)
> Something like IntegralHeight would be useful.
> Now I do: .Height = ((Int(.Height / .CellHeight)) * .CellHeight)


Yes your manual way works as the heights of the cells are equal.
But how to manage integral height when all the cell heights are different?




> it is also quite fast.


That was my priority from the beginning. To have it efficient and fast. At least not slower than MSFlexGrid.

----------


## Krool

_double post removed_

----------


## Karl77

> Stupid behavior issue.
> The MSFlexGrid does scrolling to current cell. Similar to the .CellEnsureVisible method in the VBFlexGrid.
> So in order to be compatible I also do a .CellEnsureVisible when calling .CellLeft. (or indirectly via .Cell)


Hmm, not so cool.
I thought the .Cell feature advantage is that we don't have to change the selection in order to get or set cell properties.
So I would expect .Cell doesn't do stupid things.
We don't have such a comfy .Cell thing in the original.
Seeing this, can't we avoid stupidity?




> Could be included. Have noted .ScrollBarSize like in the SysInfo control.
> Or maybe ScrollBarWidth and ScrollBarHeight to have CX and CY values...


I didn't think of the SysInfo control.
That's enough, no need for such a property.




> Already noted from your previous posts.


Sorry for the repeat, I should have known you don't forget.




> First goal was to have a working replacement in place so I can migrate projects.


Up to now there are only minor obstacles.
And easy to deal with with your assistance.




> Yes your manual way works as the heights of the cells are equal.
> But how to manage integral height when all the cell heights are different?


Yes, you are right.
So forget it, to do it manually (with the same cell height) is not that much effort and good enough.

----------


## Karl77

CELL FONT

When I do this:



```
With VBFlexGrid1
.Cell(FlexCellFontName, 1, 0) = "Marlett"
.Cell(FlexCellText, 1, 0) = "a"
Debug.Print "Font: ", .Cell(FlexCellFontName, 1, 0)
End With
```

The cell seems to have got the font.

It should show a check mark.
Instead it shows "a".

What do I do wrong?

----------


## Krool

> Hmm, not so cool.
> I thought the .Cell feature advantage is that we don't have to change the selection in order to get or set cell properties.
> So I would expect .Cell doesn't do stupid things.
> We don't have such a comfy .Cell thing in the original.
> Seeing this, can't we avoid stupidity?


The (obvious) reason why .CellLeft is scrolling the focused cell into view is that .CellLeft is used to place a TextBox or ProgressBar (or whatever) control in this cell rectangle.
And of course that makes only sense when the cell is in view (visible)
In this context it actually _does_ make sense to keep this logic in .Cell.
Because what makes it a difference when I want to put a TextBox (or whatever) control on the focused cell (.CellLeft) or an arbitrary cell (.Cell)?
What you are looking for is the current extent location of the cell, even if it is far beyond the current client edge.
This you could calculate by a workaround to sum up the Width's of the fixed columns and from the .LeftCol to your actual cell column.
Than you have your .Left you need.

----------


## Karl77

> What you are looking for is the current extent location of the cell, even if it is far beyond the current client edge.
> This you could calculate by a workaround to sum up the Width's of the fixed columns and from the .LeftCol to your actual cell column.


What I really want to detect is if I clicked outside a cell.
The dark grey area:


The Width sum works fine for the X direction.
For Y I need the position of the cell.
And when I ask for the Top, the same effect kicks in.
When I sum up the cell heights, I don't have the correct position.

Or is it all too complicated what I want, and there is a better method that I don't see?

----------


## Krool

> What I really want to detect is if I clicked outside a cell.
> The dark grey area:
> 
> 
> The Width sum works fine for the X direction.
> For Y I need the position of the cell.
> And when I ask for the Top, the same effect kicks in.
> When I sum up the cell heights, I don't have the correct position.
> 
> Or is it all too complicated what I want, and there is a better method that I don't see?


What about the .HitTest method and check .HitResult = FlexHitResultNoWhere? (Not available in MSFlexGrid, but here in VBFlexGrid.

----------


## Karl77

> What about the .HitTest method and check .HitResult = FlexHitResultNoWhere? (Not available in MSFlexGrid, but here in VBFlexGrid.


Excellent!

Thank you.

----------


## Karl77

> CELL FONT
> 
> When I do this:
> 
> 
> 
> ```
> With VBFlexGrid1
> .Cell(FlexCellFontName, 1, 0) = "Marlett"
> ...


I also tried WingDings - no success.
When I set WingDings for the whole VBFlexGrid, it works.
But not for a single cell.
Other fonts, e.g. Times New Roman or Courier New do work ok.

----------


## Krool

> When I do this:
> 
> 
> 
> ```
> With VBFlexGrid1
> .Cell(FlexCellFontName, 1, 0) = "Marlett"
> .Cell(FlexCellText, 1, 0) = "a"
> Debug.Print "Font: ", .Cell(FlexCellFontName, 1, 0)
> ...


Ok, here comes an additional issue in place. In VBFlexGrid is a CellFontCharset property available, whereas in MSFlexGrid this is not available.

Solution for your problem would be to change not only the FontName but also the FontCharset, like following:



```
Const SYMBOL_CHARSET As Long = 2
With VBFlexGrid1
.Cell(FlexCellText, 1, 0) = "a"
.Cell(FlexCellFontName, 1, 0) = "Marlett"
.Cell(FlexCellFontCharset, 1, 0) = SYMBOL_CHARSET
Debug.Print "Font: ", .Cell(FlexCellFontName, 1, 0)
End With
```

Possible bugfix would be that the FontCharset will be overwritten automatically when changing the FontName and not that later the FontCharset breaks up the FontName.

----------


## MountainMan

Krool,

if the control uses Unicode (actually UCS-2) then of what value is it to have FontCharset?

----------


## Krool

Update released.

FontCharset issue resolved. Whenever the FontName is changed the FontCharset will be amended as well by default. Thus always working.
However, afterwards the FontCharset can be changed manually, if necessary.

Second fix is actually more important. By update on 23-Nov-2017 (VBA support) it caused an huge performance drop. Reason was that in VBA another extra refresh is necessary. However, this caused the control in VB6 to make the refresh always immediately and resulted finally in 2x draws.
This fix should improve the performance of the control a lot. A big lot.  :Wink:

----------


## Karl77

> FontCharset issue resolved.


Great, works as expected now.




> This fix should improve the performance of the control a lot. A big lot.


It was quite fast before the fix, and now even better.




> FormatString property is now implemented. I would appreciate if you could test it extensively.


You asked in #46.
I couldn't find issues with it, it works the same as in MSFlexgrid (except the 'no cells issue', but no problem at all).

----------


## 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)

----------


## immortalx

Krool, thank you very much for this absolutely amazing control!
I have a weird issue with mouse wheel scrolling. I thought it wasn't supported at all, until i tried to swipe the wheel really hard!
To best describe the issue, it only works when you make a single fast full 360 rotation of the wheel. Anything less than a full rotation (no matter how fast) has no effect.

----------


## Karl77

> To best describe the issue, it only works when you make a single fast full 360 rotation of the wheel. Anything less than a full rotation (no matter how fast) has no effect.


I use the control because it supports the mouse wheel, and MSFLEXGRID not.
There are other reasons, too.
In short, scrolling works perfect in vertical direction.

Immortal, can you post a small sample project, so that we can see the error?

Karl

----------


## immortalx

Thanks Karl, that's why I want to use it as well and avoid the hook methods.
I've attached a sample for the ActiveX version. I also tried the included example in the Std-EXE version and it has the same effect.
Also, there's no difference whether it runs in the IDE or compiled.

----------


## chosk

Running your sample, I have no problem with mousewheel scrolling.

----------


## Karl77

> Thanks Karl, that's why I want to use it as well and avoid the hook methods.
> I've attached a sample for the ActiveX version. I also tried the included example in the Std-EXE version and it has the same effect.
> Also, there's no difference whether it runs in the IDE or compiled.


Same as chosk says: No problem with your sample.

----------


## immortalx

chosk & karl, thanks for testing it guys.
That's odd. I installed VB on my work PC and it works perfectly. At home I use a Microsoft wireless mouse that's been rock solid for years and works with every application without a hitch. It also works with other controls that support the mousewheel, and within the IDE itself with the mousewheelfix. I'll try my work mouse at home and will report back.
Again, thank you very much for the help!

----------


## Schmidt

> ...At home I use a Microsoft wireless mouse ...


Bought the same thing about 3 years ago - and encountered the same "issues"...
in short - the MS-MouseDrivers are more "fine-grained" and require an accumulation 
of the incoming (smaller) Rotation-delta-values.

@Krool (maybe that gives you some ideas)
Below is a little Helper-Function I had to write for the RC5-Form- and -WidgetEngine
(which is doing the accumulation in a Static-Variable at function-level):



```
Public Function GetMouseWheelLineOffset(ByVal MouseKeys As Long, ByVal Rotation As Long) As Long
  Static Delta As Long, LastRotation As Long
  If Sgn(Rotation) <> Sgn(LastRotation) Then Delta = 0
  Delta = Delta + Rotation
  If Abs(Delta) >= 120 Then
    GetMouseWheelLineOffset = IIf(MouseKeys And &H1000, Delta \ 120, -Delta \ 120)
    Delta = Delta - (Delta \ 120) * 120
  End If
  LastRotation = Rotation
End Function
```

Olaf

----------


## immortalx

Schmidt, it seems you're absolutely right. I just tried my work mouse and works as expected. However, I just read a Microsoft document describing that some applications misinterpret partial (30) events as full-line (120) or completely ignore them.

----------


## Krool

> @Krool (maybe that gives you some ideas)
> Below is a little Helper-Function I had to write for the RC5-Form- and -WidgetEngine
> (which is doing the accumulation in a Static-Variable at function-level):
> 
> 
> 
> ```
> Public Function GetMouseWheelLineOffset(ByVal MouseKeys As Long, ByVal Rotation As Long) As Long
>   Static Delta As Long, LastRotation As Long
> ...


Thanks.
Before I put an update out I want to be sure if it works as I cannot test this. (I do not have a mouse for testing that has a finer-resolution wheel)

Before:


```
Case WM_MOUSEWHEEL
    If VBFlexGridWheelScrollLines > 0 Then
        Dim WheelDelta As Long, WheelDeltaPerLine As Long
        WheelDelta = HiWord(wParam)
        If Abs(WheelDelta) >= 120 Then
            WheelDeltaPerLine = (WheelDelta / VBFlexGridWheelScrollLines)
            If Sgn(WheelDelta) = -1 Then
                While WheelDelta <= WheelDeltaPerLine
                    SendMessage hWnd, WM_VSCROLL, MakeDWord(SB_LINEDOWN, 0), ByVal 0&
                    WheelDelta = WheelDelta - WheelDeltaPerLine
                Wend
            Else
                While WheelDelta >= WheelDeltaPerLine
                    SendMessage hWnd, WM_VSCROLL, MakeDWord(SB_LINEUP, 0), ByVal 0&
                    WheelDelta = WheelDelta - WheelDeltaPerLine
                Wend
            End If
        End If
        WindowProcControl = 0
        Exit Function
    End If
```

After: (suggestion)


```
Case WM_MOUSEWHEEL
    If VBFlexGridWheelScrollLines > 0 Then
        Static WheelDelta As Long, LastWheelDelta As Long
        If Sgn(HiWord(wParam)) <> Sgn(LastWheelDelta) Then WheelDelta = 0
        WheelDelta = WheelDelta + HiWord(wParam)
        If Abs(WheelDelta) >= 120 Then
            Dim WheelDeltaPerLine As Long
            WheelDeltaPerLine = (WheelDelta / VBFlexGridWheelScrollLines)
            If Sgn(WheelDelta) = -1 Then
                While WheelDelta <= WheelDeltaPerLine
                    SendMessage hWnd, WM_VSCROLL, MakeDWord(SB_LINEDOWN, 0), ByVal 0&
                    WheelDelta = WheelDelta - WheelDeltaPerLine
                Wend
            Else
                While WheelDelta >= WheelDeltaPerLine
                    SendMessage hWnd, WM_VSCROLL, MakeDWord(SB_LINEUP, 0), ByVal 0&
                    WheelDelta = WheelDelta - WheelDeltaPerLine
                Wend
            End If
        End If
        LastWheelDelta = HiWord(wParam)
        WindowProcControl = 0
        Exit Function
    End If
```

Can you please confirm? Thanks again for your help.

----------


## DEXWERX

> Schmidt, it seems you're absolutely right. I just tried my work mouse and works as expected. However, I just read a Microsoft document describing that some applications misinterpret partial (30) events as full-line (120) or completely ignore them.


I believe this is because even the original MSDN examples didn't correctly account for partial scrolls, or bother retrieving the global setting, and the rest of the internet has copied the error for decades.

another thing people never acount for is that if you retrieve a -1 from the global scroll size setting, that means to scroll by 1 page. Once upon a time, on another far away site, i posted a proper example for scrolling a flexgrid.

here's essentially how i handled it back then.


```
        Case WM_MOUSEWHEEL
            FlexWheelScroll m_Grid, CSng(GET_WHEEL_DELTA_WPARAM(wParam)) / WHEEL_DELTA
            Exit Function
```



```
Private Function FlexWheelScroll(Grid As MSHFlexGrid, ByVal Rotation As Single) As Long
    Const SPI_GETWHEELSCROLLLINES As Long = &H68
    Static ScrollLines As Long
    If ScrollLines = 0 Then SystemParametersInfoW SPI_GETWHEELSCROLLLINES, 0, ScrollLines, 0
    Dim StepSize As Long
    If ScrollLines < 0 Then
        StepSize = FlexPageSize(Grid, True)
    Else
        StepSize = ScrollLines
    End If
    If Grid.Rows - Grid.FixedRows = 0 Then Exit Function
    Dim NewRow As Long
    NewRow = Grid.TopRow - Rotation * StepSize
    Dim MaxRow As Long
    MaxRow = Grid.Rows - FlexPageSize(Grid, True)
    If NewRow > MaxRow Then
        Grid.TopRow = MaxRow
    ElseIf NewRow < Grid.FixedRows Then
        Grid.TopRow = Grid.FixedRows
    Else
        Grid.TopRow = NewRow
    End If
End Function
```

although looking at it now - using a single probably wouldn't really work. You probably have to accumulate rotation as Schmidt has shown.

----------


## immortalx

@Krool I confirm it works perfectly!

@DEXWERKS that's some very useful info.

----------


## Karl77

While we are at the scrolling.

We can scroll vertical only, which is ok so far.
Recently I discovered that in Paint.NET, when the mouse is over a horizontal scrollbar, the wheel acts this scrollbar.
Perhaps a nice addition to the VBFlexGrid, and for VBCCR as well.

---
Some years ago I had such a MS mouse, and I thought it is broken.
I bought another one...

----------


## Krool

Updated released for supporting fine-grained wheel changes. Thanks to Schmidt for pointing this out.

----------


## Krool

> An AutoSizeColumn feature would be highly appreciated.


I want to start working on such a functionality. But I want to put out a question in the room for some feedback.

Similar like in the ListView I want to be able to auto size in two ways. 'ToItems' and 'ToHeader'
So which font should be considered by the auto size method?

'ToItems' it should consider of course the .Font property. But what about the .CellFont ? Ignore or also consider such exceptions.

'ToHeader' it should consider the .FontFixed (if applied) and else the .Font property. But again what about .CellFont exceptions?

Thanks

----------


## Karl77

> I want to start working on such a functionality. But I want to put out a question in the room for some feedback.
> 
> Similar like in the ListView I want to be able to auto size in two ways. 'ToItems' and 'ToHeader'
> So which font should be considered by the auto size method?
> 
> 'ToItems' it should consider of course the .Font property. But what about the .CellFont ? Ignore or also consider such exceptions.
> 
> 'ToHeader' it should consider the .FontFixed (if applied) and else the .Font property. But again what about .CellFont exceptions?
> 
> Thanks


Oh sorry, I saw this very late.
The .CellFont should be in the calculation.
(While I use only the same font for all cells.)

Karl

----------


## Krool

Update released.

Included the TextWidth/TextHeight function that calculates for the current or an arbitrary cell the width and height length.
For multiline text the heights are cumulated and for the width the line with the greatest width is taken. Similar to VB.Form's TextWidth function.

Example:

Takes current cell font. However text must be passed in any case.


```
MsgBox VBFlexGrid1.TextWidth("abc" & vbLf & "abcdef")
```

Takes cell matrix 2,2.


```
MsgBox VBFlexGrid1.TextWidth("abc" & vbLf & "abcdef", 2, 2)
```

If you want to get text for current cell and text of that cell just do:


```
MsgBox VBFlexGrid1.TextWidth(VBFlexGrid1.Text)
```




> Do you plan to implement something like AutoSizeColWidth?
> Today I have to put the col content into a label, AutoSize=true, read the width, and then set the col width.
> That is the opposite of fast and cumbersome as well.


Now instead using a label control control you can use the new TextWidth function.
However, an handy autosize functionality will follow soon. But this for now enables manual handling of such things and is very general for many scenarios.

----------


## Karl77

> Now instead using a label control control you can use the new TextWidth function.
> However, an handy autosize functionality will follow soon. But this for now enables manual handling of such things and is very general for many scenarios.


Thank you, good to know.

For me, it makes no sense to switch over to the new functionality.
The new TextWidth function requires more effort than just using a label, I would have to track the maximum width.
With a label, this is automatic (AutoSize).

So I'll wait for what will follow...

----------


## Krool

Included the AutoSize method.

.AutoSize(RowOrCol1 As Long, [RowOrCol2 As Long = -1], [Mode As FlexAutoSizeModeConstants], [Scope As FlexAutoSizeScopeConstants], [Equal As Boolean], [ExtraSpace As Long])

If RowOrCol2 is omitted only RowOrCol1 is processed, else the range between RowOrCol1 and RowOrCol2 is processed.
The Mode argument specifies if column widths or row heights are adjusted.
The Scope argument indicates if all cells, only fixed cells or only scrollable cells are evaluated.
Equal argument, if True, the range between RowOrCol1 and RowOrCol2 are set to the same sizes.
ExtraSpace argument allows to specify extra spacing, in twips, which can be useful when picture dimensions need to be taken into consideration.

----------


## immortalx

Krool I noticed that properties RowIsVisible, ColIsVisible return always true, no matter if the respective Row or Col are hidden or not.
Or maybe I'm doing something wrong?

----------


## Krool

> Krool I noticed that properties RowIsVisible, ColIsVisible return always true, no matter if the respective Row or Col are hidden or not.
> Or maybe I'm doing something wrong?


VBFlexGrid1.RowHidden(0) = True is just an "extended" way of VBFlexGrid1.RowHeight(0) = 0.
Thus like in original MSFlexGrid those zero height rows will still be return True by RowIsVisible if the row is within client rect, even if it's height is zero.

Even in the *VS*FlexGrid control it says: _If a row has zero height or is hidden but is within the scrollable area, RowIsVisible will return True._

So I won't change the behavior in order to be full compatible.

However, you can make your own workaround helper function as following:


```
Public Function FlexGridRowIsVisible(ByRef FlexGrid As VBFlexGrid, ByVal Row As Long) As Boolean
If FlexGrid.RowIsVisible(Row) = True And FlexGrid.RowHidden(Row) = False Then FlexGridRowIsVisible = True
End Function
```

----------


## immortalx

Thank you very much for the explanation Krool. I didn't know that was the case for MSFlexGrid too and certainly I'd never ask you to change this behavior! I was just curious as a beginner and the original property names RowIsVisible/RowHidden were a bit misleading to me  :Big Grin: 
Also thank you for the helper function and for all your contributions to this community. Much appreciated!

----------


## gibra

Good work, Krool.

There is a VerticalAlignment, for Text cell (Top, Middle, Bottom) ?

----------


## Krool

> There is a VerticalAlignment, for Text cell (Top, Middle, Bottom) ?


The .CellAlignment is used for both, horizontal and vertical text alignment.

----------


## gibra

> The .CellAlignment is used for both, horizontal and vertical text alignment.


Now I have found it, and it's very simple to use.   :Cool: 
Great!!!


It would also be nice to have a *FilterBar* (like the ComponentOne TrueDBGrid control).
Have you ever thought about implementing it?

----------


## Krool

Update released.

The FlexSortCustom was totally broken. This fact appeared when I needed in a case a custom sorting and I noticed that Row1 in the Compare event was correct but Row2 was totally off.
Row2 had two errors, one could be fixed but the other is kind of impossible due to the partial temp out-of-place sorting in the recursive stable merge sort.

So now, whenever a custom sort is invoked an optimized stable bubble sort is performed internally. This ensure that the Row1/Row2/Col text matrix subscripts is meaningful and properly. Because bubble sort is full in-place and is swapping one by one. So .TextMatrix is always up to date. So no problem for the Compare event anymore.

If no custom sort is applied, then the fast and efficient stable merge sort is again internally used.

In order to decrease the need of custom sorting I have included now the possibility to sort by currency and date. (FlexCurrencyAscending/FlexCurrencyDescending and FlexDateAscending/FlexDateDescending)
These new enum flag can be set to both Sort and ColSort property. (Info: In order to use ColSort set FlexUseColSort enum into the Sort property)

----------


## Krool

Most stupid bugfix ever... related to yesterday bugfix and new bubble sort for custom sorting.

In the internal method BubbleSortIter it should be


```
If Cmp > 0 Then
```

and not


```
If Cmp >= 0 Then
```

Now, equal items (Cmp = 0) won't be sorted. (which is wanted)

----------


## Krool

DividerDblClick event included.

This convenient event can be a very quick helper for implementing an "user auto auto-sizing" functionality.

Example usage:


```
Private Sub VBFlexGrid1_DividerDblClick(ByVal Row As Long, ByVal Col As Long)
If Row = -1 Then
    VBFlexGrid1.AutoSize Col, , FlexAutoSizeModeColWidth
ElseIf Col = -1 Then
    VBFlexGrid1.AutoSize Row, , FlexAutoSizeModeRowHeight
End If
End Sub
```

Like in the ListView control it only fires on left mouse button.

----------


## Krool

Updated released.

Optimized the divider row/col dragging.

This means that now the splitter rect displayed during the divider row/col dragging starts not anymore at the current mouse position.
It now starts exactly at the divider line and calculates internally an offset to the current mouse position.
Of course when moving and releasing the mouse the offset is also considered.

The benefit of this optimization is a more precise dragging and no mini pixel movings anymore when pressing and releasing the mouse without moving.


Included the HitRowDivider/HitColDivider property which returns the divider row/col from the last invoked .HitTest.

The difference between HitRowDivider/HitColDivider and the normal HitRow/HitCol is an offset applied.
Also either HitRowDivider and HitColDivider is set to -1 or both. Never both can be higher than -1. Unlike HitRow/HitCol where both are usually higher than -1.
The offset accounts following:
Normally for FlexHitResultDividerRowTop/FlexHitResultDividerColumnLeft an offset of -1 must be applied to shift to the actual row/col.
For FlexHitResultDividerRowBottom/FlexHitResultDividerColumnRight an offset was never necessary.
In addition (new feature) the offset also accounts for hidden rows and cols. Though zero width rows/cols are not accounted to preserve MSFlexGrid compatibility.
Example: In MSFlexGrid a zero width row/col can be resized (unhide). This is also possible in VBFlexGrid.
Only when using ColHidden/RowHidden the hidden rows/cols cannot be resized anymore as they were offset.

----------


## Krool

Update released.




> FontCharset issue resolved. Whenever the FontName is changed the FontCharset will be amended as well by default. Thus always working.
> However, afterwards the FontCharset can be changed manually, if necessary.


Now that fix applies also for FlexFillStyleRepeat instead of FlexFillStyleSingle only. (FlexFillStyleRepeat was skip by an oversight..)

----------


## Krool

I find the .Clip property useful for copy/paste between grid and excel for example.
I also use RowHidden/ColHidden often to filter stuff out of sight.

Therefore the question in the room:
May the .Clip property skip hidden rows/cols by get and also set? (Kind of intuitive feature)
Or bring out a further property that controls such new behavior?

----------


## DEXWERX

> I find the .Clip property useful for copy/paste between grid and excel for example.
> I also use RowHidden/ColHidden often to filter stuff out of sight.
> 
> Therefore the question in the room:
> May the .Clip property skip hidden rows/cols by get and also set? (Kind of intuitive feature)
> Or bring out a further property that controls such new behavior?


I vote for a new property. While the intuitive behavior works from an end user point of view (this is how excel works), it may not be obvious to a programmer.  :Smilie:

----------


## ChenLin

Who has the VBFlexGrid drag and drop example? How can I not use the following example?

Private m_bDragOK As Boolean
Private m_iDragCol As Integer
Private xdn As Integer, ydn As Integer

Private Sub VBFlexGrid1_DragDrop(Source As Control, X As Single, Y As Single)
    If m_iDragCol = -1 Then Exit Sub
    If VBFlexGrid1.MouseRow <> 0 Then Exit Sub
    With VBFlexGrid1
        .Redraw = False
        .ColPosition(m_iDragCol) = .MouseCol
        .Redraw = True
    End With
End Sub

Private Sub VBFlexGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    xdn = X
    ydn = Y
    m_iDragCol = -1     ' 清除拖拽标志
    m_bDragOK = True
End Sub

Private Sub VBFlexGrid1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    m_bDragOK = False
End Sub

----------


## ChenLin

I uploaded an example that can be dragged but cannot adjust the column width. This example is normal when using MSHFLEXGRID.

----------


## Krool

Update released.




> I uploaded an example that can be dragged but cannot adjust the column width. This example is normal when using MSHFLEXGRID.


This is now fixed. Thanks for bringing this up!

----------


## ChenLin

Thank you Krool. The problem is solved. I hope this drag and drop attribute is the default, and no user need to write the code again. That's the best thing to do.

----------


## Krool

> I vote for a new property. While the intuitive behavior works from an end user point of view (this is how excel works), it may not be obvious to a programmer.


Update, included ClipMode property that determines whether to include (default) or to exclude hidden cells in a clip command.

----------


## Krool

Further question in the room:

The AutoSize feature does not currently allow to exclude hidden rows or cols in it's calculation.
This can be disturbing in a filtered grid and you double click on a divider to autosize and it sizes larger as it should be visibly due to hidden cells that are larger in it's content.
So bring out a new parameter for this or rely on what is set in the new ClipMode property? (Kind of half intiutive)

----------


## ChenLin

Hi Krool, How to achieve multi-selection by pressing ctrl or shift? At the same time to know which line is selected.

----------


## amitabh srivastav

Dear Krool, Excellent Grid control. I have tested the Demo with some variations and it works well. But when I compile the OCX, I am unable to register it on windows 10 (It is saying some dll library file is missing)  or use it in my other applications. Where I could be going wrong?

----------


## amitabh srivastav

Dear Krool, How do I distribute this wonderful OCX with my VB6 application. I am using Inno Setup5.

----------


## gibra

> But when I compile the OCX, I am unable to register it on windows 10 (It is saying some dll library file is missing)


On latest builds of windows 10, in order to compile OCX/DLL, you need to run VB6 As Administrator.

----------


## ChenLin

Hi Krool,I want to implement the following functions:

    For i = 1 To VBFlexGrid1.Rows - 1Set the backcolor and forecolor of each row according to the conditions
        If VBFlexGrid1.TextMatrix(i, 3) = -1 Then
            VBFlexGrid1.RowBackColor(i) = vbRed
            VBFlexGrid1.RowForeColor(i) = vbWhite
        Else
            BFlexGrid1.RowBackColor(i) = vbBlue
            VBFlexGrid1.RowForeColor(i) = vbYellow
        End If
    Next i
    VBFlexGrid1.AllowMultiSelection = TrueTo press Ctrl and Shift to implement multiple selection

Can you implement this in the new version?

----------


## Krool

@ ChenLin,

you could make a helper function like following:



```
Private Sub RowBackColor(ByVal FlexGrid As VBFlexGrid, ByVal iRow As Long)
Dim OldFillStyle As FlexFillStyleConstants
With FlexGrid
OldFillStyle = .FillStyle
.FillStyle = FlexFillStyleRepeat
.Cell(FlexCellBackColor, iRow, .FixedCols, , .Cols - 1) = vbRed
.FillStyle = OldFillStyle
End With
End Sub
```

Same then analog with ForeColor.

----------


## ChenLin

Thanks Krool. The problem has been solved. I modify the color parameters and specify the colors directly:



```
Private Sub Command19_Click()
    RowBackColor Me.VBFlexGrid1, 8
    RowForceColor Me.VBFlexGrid1, 8
    RowBackColor Me.VBFlexGrid1, 9, vbBlue
    RowForceColor Me.VBFlexGrid1, 9, vbGreen
    RowBackColor Me.VBFlexGrid1, 10, vbGreen
    RowForceColor Me.VBFlexGrid1, 12, vbRed
End Sub

Private Sub RowBackColor(ByVal FlexGrid As VBFlexGrid, ByVal iRow As Long, Optional ByVal lColor As Long = vbRed)
    Dim OldFillStyle As FlexFillStyleConstants
    With FlexGrid
        OldFillStyle = .FillStyle
        .FillStyle = FlexFillStyleRepeat
        .Cell(FlexCellBackColor, iRow, .FixedCols, , .Cols - 1) = lColor
        .FillStyle = OldFillStyle
    End With
End Sub

Private Sub RowForceColor(ByVal FlexGrid As VBFlexGrid, ByVal iRow As Long, Optional ByVal lColor As Long = vbBlack)
    Dim OldFillStyle As FlexFillStyleConstants
    With FlexGrid
        OldFillStyle = .FillStyle
        .FillStyle = FlexFillStyleRepeat
        .Cell(FlexCellForeColor, iRow, .FixedCols, , .Cols - 1) = lColor
        .FillStyle = OldFillStyle
    End With
End Sub
```

Attachment 159099

----------


## ChenLin

Press Ctrl and Shift MultiSelection to solve the problem (of course you can also use BigSelection to achieve), I hope useful to you.

Attachment 159115



```
Private Sub VBFlexGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim i As Long, j As Long
    If Button = 1 Then
        If Shift = 2 Then '按Ctrl键
            With VBFlexGrid1
                If .CellBackColor = &H8000000D Then
                    '取消选择这行
                    RowBackColor VBFlexGrid1, VBFlexGrid1.Row, IIf((i Mod 2) <> 0, &H80000005, RGB(227, 239, 218)) '修正点击后颜色不正确问题
                    RowForeColor VBFlexGrid1, VBFlexGrid1.Row, &H80000008
                    .RowData(.Row) = 0
                Else
                    '选择这行
                    RowBackColor VBFlexGrid1, VBFlexGrid1.Row
                    RowForeColor VBFlexGrid1, VBFlexGrid1.Row
                    .RowData(.Row) = 1
                End If
            End With
        ElseIf Shift = 1 Then '按Shift键
            With VBFlexGrid1
                If .Row <= .RowSel Then
                    For i = .Row To .RowSel
                        RowBackColor VBFlexGrid1, i
                        RowForeColor VBFlexGrid1, i
                        .RowData(i) = 1
                    Next
                Else
                    For i = .Row To .RowSel Step -1
                        RowBackColor VBFlexGrid1, i
                        RowForeColor VBFlexGrid1, i
                        .RowData(i) = 1
                    Next
                End If
            End With
        Else
        '正常点击
        End If
    End If
End Sub

Private Sub VBFlexGrid1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim i As Integer
    Dim lngRow As Long, lngRowSel As Long
    
    If Shift = 0 Then
        With VBFlexGrid1
            .Redraw = False
            lngRow = .Row
            lngRowSel = .RowSel
            For i = 1 To .Rows - 1
                If i <> lngRowSel And .RowData(i) = 1 Then
                    RowBackColor VBFlexGrid1, i, IIf((i Mod 2) <> 0, &H80000005, RGB(227, 239, 218)) '修正点击后颜色不正确问题
                    RowForeColor VBFlexGrid1, i, &H80000008
                    .RowData(i) = 0
                End If
            Next
            
            .Row = lngRow
            
            If .Row <= lngRowSel Then
                For i = lngRow To lngRowSel
                    .RowData(i) = 1
                    RowBackColor VBFlexGrid1, i
                    RowForeColor VBFlexGrid1, i
                Next
            Else
                For i = lngRow To lngRowSel Step -1
                    .RowData(i) = 1
                    RowBackColor VBFlexGrid1, i
                    RowForeColor VBFlexGrid1, i
                Next
            End If
            .Redraw = True
        End With
    End If
End Sub

Public Sub RowBackColor(ByVal FlexGrid As VBFlexGrid, ByVal iRow As Long, Optional ByVal lColor As Long = &H8000000D)
    Dim OldFillStyle As FlexFillStyleConstants
    With FlexGrid
        OldFillStyle = .FillStyle
        .FillStyle = FlexFillStyleRepeat
        .Cell(FlexCellBackColor, iRow, .FixedCols, , .Cols - 1) = lColor
        .FillStyle = OldFillStyle
    End With
End Sub

Public Sub RowForeColor(ByVal FlexGrid As VBFlexGrid, ByVal iRow As Long, Optional ByVal lColor As Long = &H8000000E)
    Dim OldFillStyle As FlexFillStyleConstants
    With FlexGrid
        OldFillStyle = .FillStyle
        .FillStyle = FlexFillStyleRepeat
        .Cell(FlexCellForeColor, iRow, .FixedCols, , .Cols - 1) = lColor
        .FillStyle = OldFillStyle
    End With
End Sub
```

----------


## ChenLin

Who has a good sorting method, please? I used to use it on Mshflexgrid, but I can't use it normally. Is it because I use Chinese characters?

----------


## ChenLin

TopRow Add a New line to prevent errors when the mouse is rolled up.
Do not know if my method is wrong or a bug?



```
Public Property Let TopRow(ByVal Value As Long)
    If Value < 0 Then Value = 0 'Add
    If Value < 0 Or Value > (PropRows - 1) Then
        err.Raise Number:=30009, Description:="Invalid Row value"
    End If

    Dim RCP As TROWCOLPARAMS
    With RCP
        .Mask = RCPM_TOPROW
        .Flags = RCPF_CHECKTOPROW
        .TopRow = Value
        Call SetRowColParams(RCP)
    End With
End Property
```

----------


## Krool

> Who has a good sorting method, please? I used to use it on Mshflexgrid, but I can't use it normally. Is it because I use Chinese characters?


When you use any of FlexSortString... constants it should work as Wide API lstrcmp/lstrcmpi is used. What kind of problem do you have?

----------


## gibra

> Downloaded and briefly fiddled with this - looks very promising. Do you plan to support in-cell editing?


See this project with in-cell editing and formulas (Excel-like):
http://www.vbforums.com/showthread.p...=1#post5290223 

P.S. VBFlexGrid OCX version

----------


## ChenLin

> When you use any of FlexSortString... constants it should work as Wide API lstrcmp/lstrcmpi is used. What kind of problem do you have?


example code:

The problem is solved, the use is FlexSortStringNoCaseAscending, it is recommended that Chinese characters use this, numbers and money to use FlexSortCurrencyAscending




```
'排序函数
Public Sub Sort(Sgrd As VBFlexGrid)
    IntSort = IntSort + 1
    With Sgrd
        If .MouseRow <> 0 Then Exit Sub '如果不是标题行就不排序
        .Col = .MouseCol
        Dim i As Integer
        If IsNumeric(Sgrd.TextMatrix(1, Sgrd.MouseCol)) = True Then
            .Sort = FlexSortCurrencyAscending + IntSort Mod 2  '按金额排序
        Else
            .Sort = FlexSortStringNoCaseAscending + IntSort Mod 2 '按字符排序
        End If
        .Col = 0 '这个为0避免排序后当前列之前为白色……
    End With
End Sub
```

Welcome everyone to propose a better way!

----------


## Karl77

Basic question

In a populated grid, a left mouse click fires a SelChange.
Is there a _simple_ way to fire the Selchange with the right mouse button as well?


Thanks
Karl

----------


## Krool

> Basic question
> 
> In a populated grid, a left mouse click fires a SelChange.
> Is there a _simple_ way to fire the Selchange with the right mouse button as well?


I'm not sure what your goal is but it looks like you want to have a convenient way of span selection ranges with the right mouse button (?)
If yes here is a proposal:


```
Private Sub VBFlexGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbRightButton Then
    With VBFlexGrid1
    .HitTest X, Y
    If .HitResult = FlexHitResultCell Then
        If .HitRow > (.FixedRows - 1) And .HitCol > (.FixedCols - 1) Then
            .RowSel = .HitRow
            .ColSel = .HitCol
        End If
    End If
    End With
End If
End Sub
```

If not, please advise.

----------


## Karl77

Sorry for the unclear description.

It is about a single cell only.
I want to invoke a context menu.
This works ok now when I first select the cell by left click, and then do a right click.

If I right click only, then I get my context menu, but the cell where the click happened doesn't get selected before.

----------


## dreammanor

In Farpoint Spread and my own Spread control, I can achieve Karl77's purpose by the following method:



```
Private Sub fpSpread1_RightClick(ByVal ClickType As Integer, ByVal Col As Long, ByVal Row As Long, ByVal MouseX As Long, ByVal MouseY As Long)
    
    If ClickType = 1 Then       '--- 0: MouseDown,  1: MouseUp ---
        fpSpread1.SetActiveCell Col, Row
        
        PopupMenu MnuTools
        
    End If
    
End Sub
```

Maybe Krool could add the RightClick event for VBFlexGrid.

----------


## Arnoutdv

The MS(H)FlexGrid control has MouseRow/MouseCol properties, these return the row/col which the mouse is hovering, without the need for a click or selecting the cells.

----------


## Krool

Just replaced RowSel to Row and ColSel to Col to get behavior of right click activating cell.
Also MouseUp instead MouseDown.

This should work, please try:


```
Private Sub VBFlexGrid1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbRightButton Then
    With VBFlexGrid1
    .HitTest X, Y
    If .HitResult = FlexHitResultCell Then
        If .HitRow > (.FixedRows - 1) And .HitCol > (.FixedCols - 1) Then
            .Row = .HitRow
            .Col = .HitCol
            PopupMenu MnuTools
        End If
    End If
    End With
End If
End Sub
```

----------


## Karl77

> This should work, please try:
> 
> 
> ```
>         If .HitRow > (.FixedRows - 1) And .HitCol > (.FixedCols - 1) Then
>             .Row = .HitRow
>             .Col = .HitCol
> ```


Perfect.
Thank you.

----------


## ChenLin

Can anyone have a way to convert this to a VB.NET version? My VB.NET is still learning and currently has no ability to solve the problems that arise in the conversion.

----------


## Karl77

Before I add the functionality by myself, a question.

Is there an edit function in the works?
I mean a textbox in a cell.

If not, it is ok.
To make the edit function is not so much effort.
I only don't want to re-invent the wheel if it's already in Krool's garage.

----------


## Karl77

A next question.

In Excel etc., when a cell is selected, the fixed rows/cols do highlight the cell coordinate.
Like this:

And when the control lost the focus, it should go away.

Would it be possible to have such a function inside the control?

----------


## gibra

> Is there an edit function in the works?
> I mean a textbox in a cell.


Already there. See:

http://www.vbforums.com/showthread.p...=1#post5290225

 :Wink:

----------


## Karl77

> Already there. See:


Aha, very cool.
A "bit" more than I wanted, but even better.
Thank you.

----------


## Krool

> A next question.
> 
> In Excel etc., when a cell is selected, the fixed rows/cols do highlight the cell coordinate.
> Like this:
> 
> And when the control lost the focus, it should go away.
> 
> Would it be possible to have such a function inside the control?


Yes, you can implement such feature by following code addition into your Form:



```
Private Sub VBFlexGrid1_GotFocus()
Call SetRowColColorIndicator
End Sub

Private Sub VBFlexGrid1_LostFocus()
Call SetRowColColorIndicator(True)
End Sub

Private Sub VBFlexGrid1_RowColChange()
Call SetRowColColorIndicator
End Sub

Private Sub SetRowColColorIndicator(Optional ByVal Clear As Boolean)
Static LastRow As Long, LastCol As Long, InitDone As Boolean
With VBFlexGrid1
If InitDone = True Then
    If LastRow > -1 Then .Cell(FlexCellBackColor, LastRow, 0) = -1
    If LastCol > -1 Then .Cell(FlexCellBackColor, 0, LastCol) = -1
End If
If Clear = False Then
    If .FixedCols > 0 Then
        .Cell(FlexCellBackColor, .Row, 0) = vbRed
        LastRow = .Row
    Else
        LastRow = -1
    End If
    If .FixedRows > 0 Then
        .Cell(FlexCellBackColor, 0, .Col) = vbRed
        LastCol = .Col
    Else
        LastCol = -1
    End If
    InitDone = True
Else
    LastRow = -1
    LastCol = -1
    InitDone = False
End If
End With
End Sub
```

----------


## Krool

_double posted by error_

----------


## Karl77

```
Private Sub SetRowColColorIndicator
```

That works great.
I thought of adding such a feature into the control itself.
Now as I see it is a few lines only, it is very ok to have it in the form code.
Thank you.

Regarding the edit field the same applies.
It is, as said, not so much to do in the form code.

----------


## Krool

Update released.

Internal GDI leak fixed. E.g. happen when the grid is loaded and unloaded dynamically many times.

----------


## Krool

Important update released.

The internal TEXTMETRIC structure was declared as ANSI and not as WIDE.
This bug has no functional effect on Unicode since the corrupted declaration is below the used section.
However, the WIDE API expects a larger structure than declared which is then a memory risk because the API will fill data beyond the declared structure. (not good)

----------


## Jonney

> Important update released.
> 
> The internal TEXTMETRIC structure was declared as ANSI and not as WIDE.
> This bug has no functional effect on Unicode since the corrupted declaration is below the used section.
> However, the WIDE API expects a larger structure than declared which is then a memory risk because the API will fill data beyond the declared structure. (not good)


also affects CommonControls?

----------


## Krool

> also affects CommonControls?


Yes, but only ListBoxW Style <> Normal and new FontCombo.

----------


## Krool

Update released.

Major performance boost in the internal GetHitTestInfo function.

This boost is only noticeable in very large grids, e.g. 500,000 rows.

Now the GetHitTestInfo function is same fast in a 500,000 rows grid then in a 100 rows grid.

Problem was if X or Y is below 0 then unnecessary iterations were performed. And the larger the grid the slower it gets. But this got now fixed.

----------


## Krool

Minor bugfix (1px miscalc) related to todays release for performance boost in the internal GitHitTestInfo function.

Worth mention is that the overall performance is boosted as the internal function is called often internally.
Therefore a 500,000 rows grid performs now quite good.

Next step is then virtual mode via custom data source to eliminate the long populate for such big row numbers.

----------


## Krool

I'm working currently with the FlexDataSource functionality where a custom data source can be set via IVBFlexDataSource interface.

As previously discussed in page 1 it's only for display of the viewport. (like virtual mode)
Therefore the Find and Sort functionality must be turned off as this is managed by the custom data source.

However, what about other functionalities like .Clip, .FormatString, .AddItem, .Clear, .TextMatrix ?

There would be a little overhead as it needs to be evaluated whether to call IVBFlexDataSource::GetData or read internal TCELL.
Or also disable .Clip, .FormatString etc. when custom data source is set ?

Anyhow, .TextMatrix needs to be kept as setting .TextMatrix could then invoke IVBFlexDataSource::SetData. If not there where else ?

Maybe Schmidt (Olaf) can advise how this works exactly in the vsFlexGrid.

----------


## Schmidt

> I'm working currently with the FlexDataSource functionality where a custom data source can be set via IVBFlexDataSource interface.
> 
> As previously discussed in page 1 it's only for display of the viewport. (like virtual mode)
> Therefore the Find and Sort functionality must be turned off as this is managed by the custom data source.
> 
> However, what about other functionalities like .Clip, .FormatString, .AddItem, .Clear, .TextMatrix ?
> 
> There would be a little overhead as it needs to be evaluated whether to call IVBFlexDataSource::GetData or read internal TCELL.
> Or also disable .Clip, .FormatString etc. when custom data source is set ?
> ...


Can't say much with regards to .TextMatrix-Delegations (in both, read- and -write-directions),
because the whole point of an external DataSource is, to "not bother with storing data inside the Grid via TextMatrix".

And yes, sorting is done on the external Container (usually an Rs) - the only thing from the Grid we used 
to trigger that, was "a Header-Click-Event".
And the "write-direction" of the external  DS (::SetData) was triggered by "InCell-Edits" (not .TextMatrix)
(which the "big FlexGrid" allows).
Formatting was done via FlexGrid-Methods though (but not much - alternating Row-Colors mostly, along with ColWidth-settings).

We had only one case, where we needed "extensive Formatting" - and for that case we enabled 
*also* the OwnerDraw-Mode on the Flex (in addition with using the external DS).

Olaf

----------


## miquel

Great work Krool. I have replaced completely the MS flexgrid with yours and it's working great.




> Update, included ClipMode property that determines whether to include (default) or to exclude hidden cells in a clip command.


I tested this funcionality in the EXE version but in my programs I am using the ActiveX version and it is not included yet. Would you be so kind to add it in future versions ?

Thanks again, Miquel.

----------


## Krool

> Can't say much with regards to .TextMatrix-Delegations (in both, read- and -write-directions),
> because the whole point of an external DataSource is, to "not bother with storing data inside the Grid via TextMatrix".
> 
> And yes, sorting is done on the external Container (usually an Rs) - the only thing from the Grid we used 
> to trigger that, was "a Header-Click-Event".
> And the "write-direction" of the external  DS (::SetData) was triggered by "InCell-Edits" (not .TextMatrix)
> (which the "big FlexGrid" allows).
> Formatting was done via FlexGrid-Methods though (but not much - alternating Row-Colors mostly, along with ColWidth-settings).
> 
> ...


Currently an intrinsic in-cell editing is not yet developed.
But for sure I would include ::SetData to be prepared interface wise already.
But can you maybe test in vsFlexGrid if a .TextMatrix delegation does fire a ::SetData ?
Because most MSFlexGrid users (which might migrate to VBFlexGrid) handle there in-cell edit by placing a external TextBox in cell location and need .TextMatrix therefore and for this case a call to ::SetData would be needed.

Another question: is the 'Record' Long param in ::GetData 1-based? The 'Field' param is for sure 0-based.

Thanks




> Great work Krool. I have replaced completely the MS flexgrid with yours and it's working great.
> 
> 
> 
> I tested this funcionality in the EXE version but in my programs I am using the ActiveX version and it is not included yet. Would you be so kind to add it in future versions ?
> 
> Thanks again, Miquel.


Yes, of course. In version 1.2.
But first a few other features need to be ready before.

----------


## Schmidt

- Interface-Callback and mapping-wise it is all Zero-Based...
- FG.TextMatrix, as well as FG.Clip (and probably all other stuff) is routed to GetData/SetData of the DS-implementation, as soon as this was set.

Here is Test-Code for a small Form (which only contains a VSFlex, named F).


```
Private SArr As New cStringArrayDS

Private Sub Form_Load()
  F.ColWidth(-1) = 1500
  SArr.BindTo F, 3, 10
  
  Dim x, y
  For y = 0 To SArr.Rows - 1: For x = 0 To SArr.Cols - 1
    SArr.Matrix(x, y) = "Row " & y & ", Col " & x
  Next x, y
  
  Debug.Print F.TextMatrix(2 + F.FixedRows, 2)
  F.TextMatrix(2 + F.FixedRows, 2) = "2,2"
  Debug.Print F.TextMatrix(2 + F.FixedRows, 2)
End Sub
```

Here a ScreenShot (with FixedCols an FixedRows both at 1):


As one can see above, the TextMatrix-call is only matching with the SArr.Matrix-call,
when the current F.FixedRows are added to the Index-Position (in case F.FixedRows is > 0).
Only in x-Direction (addressing Cols), the zerobased indexes for SArr.Matrix and F.TextMatrix are matching -
so the DataSource ignores any current FixedRows-Header-Settings, whilst .TextMatrix wants the Header included in the x, y Offsets.


Ok, below is Code for the Binding-Class (named cStringArrayDS), which encapsulates a zerobased StringArray as the DataSource.



```
Option Explicit

Implements IVSFlexDataSource
Private mArr() As String

Public Sub BindTo(F As VSFlexGrid, ByVal Cols As Long, ByVal Rows As Long)
  ReDim mArr(0 To Cols - 1, 0 To Rows - 1)
  F.FlexDataSource = Me
End Sub

Public Property Get Rows() As Long
  Rows = UBound(mArr, 2) + 1
End Property
Public Property Get Cols() As Long
  Cols = UBound(mArr, 1) + 1
End Property

Public Property Get Matrix(ByVal xIdx As Long, ByVal yIdx As Long) As String
  Matrix = mArr(xIdx, yIdx)
End Property
Public Property Let Matrix(ByVal xIdx As Long, ByVal yIdx As Long, RHS As String)
  mArr(xIdx, yIdx) = RHS
End Property

'simple IVSFlexDataSource-implementation, which works against the internal array
Private Function IVSFlexDataSource_GetFieldName(ByVal Field As Long) As String
  IVSFlexDataSource_GetFieldName = "ColHdr_" & Field
End Function

Private Function IVSFlexDataSource_GetFieldCount() As Long
  IVSFlexDataSource_GetFieldCount = UBound(mArr, 1) + 1
End Function
Private Function IVSFlexDataSource_GetRecordCount() As Long
  IVSFlexDataSource_GetRecordCount = UBound(mArr, 2) + 1
End Function

Private Function IVSFlexDataSource_GetData(ByVal Field As Long, ByVal Record As Long) As String
  IVSFlexDataSource_GetData = mArr(Field, Record)
End Function
Private Sub IVSFlexDataSource_SetData(ByVal Field As Long, ByVal Record As Long, ByVal newData As String)
  mArr(Field, Record) = newData
End Sub
```

HTH

Olaf

----------


## Krool

That's strange that the vsFlexGrid doesn't offset the FixedCols in the FlexDataSource.
When using the applying the DataSource (ADO recordset) then the fixed cols are also taken in consideration.
But for sake of compatibility I will replicate the behavior as like in the vsFlexGrid.

Thanks Schmidt for testing/pointing out the details.

----------


## ChrisE

Hi,

I like to see the selected Row/Col change in width.

here is what I added



```
'in the Form Header section:
Private DoColumnsResize As Boolean

'also 
Private Sub Form_Activate()
   DoColumnsResize = True
End Sub

'the Function:
Private Function mFlex_ColumnResize() As Boolean

   Dim i As Long
   Dim w As Single
   Dim Row As Long
   Dim Col As Long
   Static backColor As Long
   
   
      With VBFlexGrid1
         .Redraw = False
         Row = .Row
         Col = .Col
         'play with Value / 12 for width
         w = (.Width - .ColWidth(0) - 290) / 12
         .Row = 0
         For i = 1 To .Cols - 1
            .Col = i
            If i <> Col Then
               If .ColWidth(i) <> w Then
                  .ColWidth(i) = w
                  .CellForeColor = &H80000008
               End If
            Else
               If .ColWidth(i) <> w * 2 Then
                  .ColWidth(i) = w * 2
                  .CellForeColor = vbBlue
               End If
            End If
         Next
         .Col = 0
         For i = 1 To .Rows - 1
            .Row = i
            .CellBackColor = .BackColorFixed
            If i = Row Then
               .CellBackColor = &H80000018
            End If
         Next
         .Row = Row
         .Col = Col
         .Redraw = True
      End With
End Function

'and:
Private Sub VBFlexGrid1_RowColChange()
   'set the widht
      If DoColumnsResize Then
         DoColumnsResize = False
         mFlex_ColumnResize
         DoColumnsResize = True
      End If
End Sub
```

just my taste

regards
Chris

----------


## Krool

Important bugfix concerning info tips and in-place label tips.

The internal tooltip had two problems. I described the second problem earlier in this thread. Both were solved by adding the WS_EX_TRANSPARENT style bit. It allows all mouse events to pass through.
1. When control A has focus and user hovers over the flexgrid B which shows a info tip or in-place label tip and the user clicks on that tip then the focus was not changing from A to B.
2. In Win10 the mouse wheel scroll did not work when the mouse hovered over an in-place tip.

----------


## Krool

> FG.TextMatrix, as well as FG.Clip (and probably all other stuff) is routed to GetData/SetData of the DS-implementation, as soon as this was set.


Can you also please check if, once an DS-implementation is set, it is still possible to modify the '.Rows' property or to call 'AddItem'/'RemoveItem' because that would interfere in the number of records indicated by the DS-implementation and could raise an outer bound error?
Thanks

----------


## Krool

Update released.

Beside other small new features this update includes the FlexDataSource (run-time only) property which allows to define a custom (private) data source via the IVBFlexDataSource interface.
The definitions are equally to vsFlexGrid (IVSFlexDataSource) and hopefully also the behavior. The behavior in regard to row/col offset should match.
Concerning the behavior of the limitation (function disabling) I am not sure. However, they are now as following:
- Sort not possible
- Clear method is restricted. (not possible to clear text, only to clear formatting is possible)
- FindItem not possible

Everything else is redirected to/from the custom data source. (GetData/SetData)
Even changing the Rows/Cols is possible. Also to call AddItem/RemoveItem.
It is up to the application to sync that change to the custom data source. If that's not done an out of bounds error can happen or the change will be reversed after a .DataRefresh.

----------


## Krool

Included optional argument Direction in the FindItem function. (Down or Up)
Now it's very easy to use and apply the "Find and replace" Common Dialog with the .FindItem function.


Also the FindItem cannot be used anymore now on a fixed row. This was not a problem at all without the Wrap or DirectionUp search.
But now you wouldn't want to search from bottom to up and get a hit by the column name by coincidence..
So that limitation is cosmetic to avoid this issue right away.
VBFLXGRD11.OCX will not be commited with that cosmetic limitation since it does not have Wrap or DirectionUp anyway.

----------


## dreammanor

In FarpointSpread and my own Spread, ColHeaderRows and RowHeaderCols are separate from normal grid cols and rows, that is, changing ColHeaderRows and RowHeaderCols does not affect normal grid cols/rows. This design makes the source code and data storage structure more complicated, but it's also more user-friendly and more flexible.

----------


## Krool

VBFLXGRD12.OCX is now released.

----------


## ChenLin

Hi Krool,  if I want to use another free registration OCX, how do I generate tblid in RES? Thank you!

----------


## Eduardo-

> Hi Krool,  if I want to use another free registration OCX, how do I generate tblid in RES? Thank you!


You can use ResourceHacker to edit the *.res* file.

----------


## Eduardo-

I) Hello Krool, I want to report two differences that I found between VBFlexGrid and MS ones:
The first is how it draws the vertically centered texts when they don't fit in the row:



II) And the second is that in MS FlexGrids the CellFontSize value take some "stepped" values, but in the VBFlexGrid it doesn't.

For example, I select a cell, then set the size FlexGrid1.CellFontSize = 22
When I select the cell again, in the MS ones when I get back that value I get 22.2, but with the VBFlexGrid I get 22.
I could say that the VBFlexGrid is more "exact", but still that makes a difference that in some cases cause visible differences (that it would be long to explain now).

III) I have another question: is there any way to know what cells have particular formatting without having to navigate each one? I mean something like a property Get FormattedCellsMatrix(Row, Col) As Boolean

TIA

----------


## Krool

> I) Hello Krool, I want to report two differences that I found between VBFlexGrid and MS ones:
> The first is how it draws the vertically centered texts when they don't fit in the row:


Hello Eduardo,
thanks for your report. I will process issue 1 first. (step by step)

Yes. I was certainly aware and could reproduce the behavior now again. Let's explain little bit:

If you set on the MS control the WordWrap property to True it will behave exactly like VBFlexGrid. Only if WordWrap is False the behavior is "little bit" different.
That's because the MS control will use DT_SINGLELINE for DrawText when WordWrap is False.
I explicity avoided that because else having WordWrap or multiline text are two things and should not be dependent on. I wanted to allow multiline text even if WordWrap is False.

Below would be the code modification marked as red in internal sub 'DrawCell' (not yet implemented; to be discussed) to replicate exact behavior for both WordWrap False/True:


```
If PropWordWrap = True Then Format = Format Or DT_WORDBREAK Else Format = Format Or DT_SINGLELINE
[...skipped part for here...]
Dim CalcRect As RECT, Height As Long, Result As Long
Select Case Alignment
    Case FlexAlignmentLeftCenter, FlexAlignmentCenterCenter, FlexAlignmentRightCenter, FlexAlignmentGeneral
        LSet CalcRect = TextRect
        Height = DrawText(hDC, StrPtr(Text), -1, CalcRect, Format Or DT_CALCRECT)
        If PropWordWrap = True Then
            Result = (((TextRect.Bottom - TextRect.Top) - Height) / 2)
        Else
            Format = Format Or DT_VCENTER
        End If
    Case FlexAlignmentLeftBottom, FlexAlignmentCenterBottom, FlexAlignmentRightBottom
        LSet CalcRect = TextRect
        Height = DrawText(hDC, StrPtr(Text), -1, CalcRect, Format Or DT_CALCRECT)
        If PropWordWrap = True Then
            Result = ((TextRect.Bottom - TextRect.Top) - Height)
        Else
            Format = Format Or DT_BOTTOM
        End If
End Select
If Result > 0 Then TextRect.Top = TextRect.Top + Result
```

As you see here comes DT_SINGLELINE in place which I want to avoid. DT_BOTTOM and DT_VCENTER are only supported when DT_SINGLELINE is set.

Currently always DT_TOP is applied in both (no DT_SINGLELINE at all) and the vertical adjustment is done manually. That's no issue as DrawText will be clipped to not go beyond the cell rectangle. However, in order to have the manual vertical adjustment to work with DT_TOP I would need to have the text rectangle less beyond the cell rectangle, which would look like this:

Possible solution (fix) would be to create a region and clip the DC accordingly while doing that.
That would solve the issue?
Or going the exact replicate behavior and use DT_SINGLELINE ? I want to discuss this first before implementing.

Thanks

----------


## Eduardo-

OK, Krool. It is not an "issue", at least not now.
Showing texts in the cells exceeding the height of the cells as I did is not a normal thing to do.
I found this difference only by chance while testing other things, but this code is not in an actual real life program.
Now thinking in your explanation of wordbreak <> multiline it makes sense to perhaps leave it as it is now.
Or wait to see if it is an issue for someone else. Now I can't think of a situation where it could be actually a problem.

Or perhaps (I'm not saying you to do it, but just something to think about whether it is a good idea or not) you could have a property where can be set compatibility flags, and where such differences could be avoided.
Let's suppose there are a couple more of this improvements that change the old behavior.

It could be a property named for example OldFlexBehavior.
It would have a Long type value. The default value being 0.
Let's suppose there are three flags: 1, 2 and 4.
7 means full MS emulation.

Then if (mOldFlexBehavior and 1) = 1 it means when WordWrap is False to write in single lines as MS does.

But the question is: does it worth the effort? Will someone ever benefit from that?
If it were me, perhaps I would wait until someone actually needs it.

----------


## Krool

> However, in order to have the manual vertical adjustment to work with DT_TOP I would need to have the text rectangle less beyond the cell rectangle, which would look like this:
> 
> Possible solution (fix) would be to create a region and clip the DC accordingly while doing that.


I think that way would be best to have same behavior when WordWrap is True or False. But allowing multiline always (no DT_SINGLELINE when WordWrap is False)
My last concern is that this clipping region for every cell would slow down the drawing..

EDIT:
Or keep as is.. and just include a new MultiLine property which controls DT_SINGLELINE to use or not.
Then if WordBreak is False and MultiLine is False also DT_VCENTER and DT_BOTTOM come into play to have same behavior as MS. Else have "manual" vertical offset adjustment with DT_TOP. (Like now as is, support multiline text)
This way it's separated and more specific under control.

----------


## Eduardo-

> My last concern is that this clipping region for every cell would slow down the drawing..


Yes, I don't think that would be a good idea.




> EDIT:
> Or keep as is.. and just include a new MultiLine property which controls DT_SINGLELINE to use or not.
> Then if WordBreak is False and MultiLine is False also DT_VCENTER and DT_BOTTOM come into play to have same behavior as MS. Else have "manual" vertical offset adjustment with DT_TOP. (Like now as is, support multiline text)
> This way it's separated and more specific under control.


I vote for that.

----------


## Krool

> I vote for that.


Great. I will call the property 'SingleLine'. So False being the default.
I just need to ensure to make a restriction that WordWrap and SingleLine cannot be both set to True.
That's it. Update will follow accordingly soon after careful testing. (Also that LabelTip will be in sync etc.)

----------


## ChenLin

> You can use ResourceHacker to edit the *.res* file.


Thank you. I want to know how to get tblid.

----------


## Eduardo-

> Thank you. I want to know how to get tblid.


What is tblid?

The XML information needed in the manifest for SxS installations?

----------


## ChenLin

Yes, should this information be exempt from registration? And CLSID。

Please see the picture, which is the red line information.

----------


## Eduardo-

There are several programs that people use for getting that information.
I use one that was made by dilettante (a forum member) but it is not available any more in the web site it used to be because it is not currently developed and not published any more from the original author (it was available with source code).
It is called MMM or "Make My Manifest". I found a version here in GitHub.
There is also another one called UMMM. It is from wqweto, another forum member.

There are also others that are commercial. So far I only used MMM. It is not perfect. I have a couple of versions and both produce (different) errors, mainly because of Service Packs that are installed. But I manage to make them work by editing the XML text by hand.
Perhaps UMMM is better.

Or perhaps someone else has another one to recomend.

----------


## ChenLin

Neither of them tested successfully, gave up testing, and now uses the shell "regsvr32 /s " & App.Path & "\MSHFLXGD.OCX", vbHide method in the program startup.

Still thank you for your reply.

----------


## Eduardo-

> Neither of them tested successfully, gave up testing, and now uses the shell "regsvr32 /s " & App.Path & "\MSHFLXGD.OCX", vbHide method in the program startup.
> 
> Still thank you for your reply.


But that does a very different thing. That registers the ocx in Windows. It is the same that an installer would do. 
And I don't know if that would work in 64 bits Windows.

The manifest thing is somethign else. It is not registering the ocx in Windows, but making it work without registering it (and just with that program).

----------


## ChenLin

Maybe I didn't use it well, it just generated a file like this: 



```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <assemblyIdentity name="BVO Computing Services.MMM" processorArchitecture="X86" type="win32" version="0.12.0.311" />
    <description>XCopy Packager for VB 6.0</description>
    <file name="MMM.exe">
    </file>
</assembly>
```

it doesn't include files like TYPEID or clsid.

----------


## Eduardo-

> Maybe I didn't use it well, it just generated a file like this: 
> 
> 
> 
> ```
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
>     <assemblyIdentity name="BVO Computing Services.MMM" processorArchitecture="X86" type="win32" version="0.12.0.311" />
>     <description>XCopy Packager for VB 6.0</description>
> ...


That's not right (what you did), but I think you should open a new thread in the Visual Basic 6 and Earlier because it is not really a question of VBFlexGrid.

----------


## Krool

Minor update.

RowID/RowIndex property included. The usage is similar to the ColKey/ColIndex property.
RowIndex returns a row given its ID, whereas RowID returns/sets the ID given its row.

In fact RowID can be abused to be as a "second RowData" property or as a helper for identification.
Normally RowData could be used to identify rows but maybe this property is already used by something other, that's the reason for this feature.

Example for a helper of identification could be on sorting rows:


```
Dim Row1 As Long, Row2 As Long
Dim Col1 As Long, Col2 As Long
With VBFlexGrid1
.GetSelRange Row1, Col1, Row2, Col2
.RowID(.Row) = 1 ' Temporary identification
.Sort = [whatever]
.Row = .RowIndex(1)
.RowID(.RowIndex(1)) = 0 ' Remove temporary identification
.CellEnsureVisible
If Row1 <> Row2 Then .RowSel = IIf(Row1 < .Row, Row1, Row2)
If Col1 <> Col2 Then .ColSel = IIf(Col1 < .Col, Col1, Col2)
End With
```

Because the row number will be the same before and after sorting. But the actual row information is moved.
This helps you to identify the old "new" row number.

----------


## DaveDavis

> Minor update.
> 
> RowID/RowIndex property included. The usage is similar to the ColKey/ColIndex property.
> RowIndex returns a row given its ID, whereas RowID returns/sets the ID given its row.
> 
> In fact RowID can be abused to be as a "second RowData" property or as a helper for identification.
> Normally RowData could be used to identify rows but maybe this property is already used by something other, that's the reason for this feature.
> 
> Example for a helper of identification could be on sorting rows:
> ...


why not RowKey for uniform with ColKey? Normally, Grid provides RowKey and RowTag, not RowID.

----------


## Krool

> why not RowKey for uniform with ColKey? Normally, Grid provides RowKey and RowTag, not RowID.


Because for columns a string representation is better (e.g. field name) whereas by rows a number representing fits better (e.g. primary key)
Also Long (4 bytes) * rows is smaller than String (4 bytes + lenb()) * rows.
Having RowTag as Variant (16 bytes) * rows would be huge memory consumption.

----------


## Krool

Update released.

Internal improvement concerning divider drag of the last row or col. (or can be said bugfix also)

The last col (or last row) could only be dragged from within the grid (green area) and not from outside of the grid. (red area)

----------


## Krool

Bugfix released to yesterday update. Sorry for that.  :Sick: 

The other minor internal improvement is also related to divider drag:
If a cell is not wide enough to consider the full divider spacings then it is now more fine-graned allocated.
Example:
the fixed cell in the middle is 2px. Previously the divider spacing (DIVIDER_SPACING_DIP = 2px) was allocated full for left and right (or top and bottom) side, thus overriding one side. Resulting that when clicking on 1st px is same as 2nd px, left col (or top row) was dragged.
The improvement now checks if the cell is capable to consider full spacing. If not then just divide the area into two.
If the fixed cell in the middle would be 3px (not even) then a remainder would exist and this will be just put to right (or bottom) side. (equal to MSFlexGrid control behavior)

I think that's it and no more issues should arise concerning divider drag..

----------


## temp24202

Hi, my first post here, so excuse the silly questions  :Stick Out Tongue: ,  but I have a (old) application which is Visual C++ / MFC and uses the MSflexgrid active X control  that I've migrated to VS2017.  I was not sure if the Exe ver or ActiveX Control would work in this environment? So I tried to install the active X object and can put into the toolbox in VS2017, but when trying to add to my form I get an error (cannot instantiate or similar)...  So my questions:  Is it currently only possible to use this object in VB6 (i tested there and it works).  Or will it work in other environments (VS 2017 - currently not working or I do something incorrectly?).  If only VB6 what is the difficulty to make this usable in VS2017 or is it even possible?  The main reason I was looking for an update is the MSflexgrid causes much flicker in my application which runs off a fast timer (< 100ms).  I can't find a way to get rid of this flicker easily and hoped your control would be better for this since it has been updated and give the programmer more control over what is happening....  
Thanks for any help you can provide, have a nice day.  :Smilie: 

PS - i attached the msflexgrid.h and .cpp if that would be interesting for anyone to view

----------


## jpbro

Hi Krool,

Excellent work as usual, so thanks for this gift to the community.

I've been working with your control for a project published here, and I had a question that I hope you might take a look at (no rush of course):

Is there any way to ensure the last column always takes up the available width of the control after taking into account the width of the previous columns? If not, is this a feature you might consider? The VSFlexGrid control has an ExtendLastCol property for this, and I use it frequently.

Thanks a lot, and Happy New Year!

----------


## Krool

> Is there any way to ensure the last column always takes up the available width of the control after taking into account the width of the previous columns? If not, is this a feature you might consider? The VSFlexGrid control has an ExtendLastCol property for this, and I use it frequently


Yes, ok. It says:
_Returns or sets whether the last column should be adjusted to fit the control's width.
This property only affects painting. It does not modify the ColWidth property of the last column._

What does that mean? If the ColWidth is not modified (only painting) what will hit-testing report? Please try to report all details as I have no vsFlexGrid at hand.
Thanks

----------


## jpbro

Thanks for considering the ExtendLastCol feature request, and Happy New Year! Sorry I took so long to reply, I've been quite sick with the flu for a few days (feeling much better today, thankfully).

I do find the VSFlexGrid decision re: column width to be a bit strange, but maybe others will have a good explanation. Personally I think it would make more sense to return the actual column width after extending it.

That said, I did run a little test and here are the results:



The main takeaway is that even though the ColWidth property returns the originally set value of 920 twips, the control seems to use the full column width in every other way (mouse over, drawing text, etc...)

Hope that helps, but please let me know if you need me to run any other tests.

Thanks!

----------


## southmark

Can this be used in Excel/VBA? Are there step by step instructions? Apologies if I'm missing something. Thank you!

----------


## Krool

> Can this be used in Excel/VBA? Are there step by step instructions? Apologies if I'm missing something. Thank you!


Yes, you can. But only the OCX version and office 32-bit.

----------


## southmark

> Yes, you can. But only the OCX version and office 32-bit.


Thanks for the reply.

Office 32 bit (under Program Files x86)
Copied OLEGuid.tlb into the windows system directory.
Ran regsvr32 on the ocx (but it failed). 
Tried to download the VB6 Register TypeLib Utility.zip file but the zip appears corrupted (from http://www.vbaccelerator.com/home/VB...b_Utility.html)
Added references to the tlb and ocx in the vba editor but did not see the control in the toolbox (additional controls)

Where am I going wrong please?

----------


## jpbro

AFAIK you don't need the TLB when using the OCX.

What error code did you get when you tried to register the OCX? Did you attempt to register it in an elevated command prompt?

----------


## Krool

Right. You don't need the tlb.
Copy the OCX to SysWow64 folder and run cmd as administrator and cd to SysWow64 and regsvr32 it.

----------


## southmark

> Right. You don't need the tlb.
> Copy the OCX to SysWow64 folder and run cmd as administrator and cd to SysWow64 and regsvr32 it.


'The module "VBFLXGRD12.OCX": was loaded but the call to DllRegisterServer failed with error code 0x80004005.'

I did right-click the command prompt and run as administrator.
Thank you.

----------


## southmark

I was able to register the ocx control successfully.
I can add it to the pallete and to a form in Excel.
However, when I try to run that form I am now seeing:

Run-time error '50003'.
Unexpected error.

When I clear that dialog I get another one:

License information for this component was not found. You do not have an appropriate license to use this functionality in the design environment.

Help appreciated :-)

----------


## Krool

> I was able to register the ocx control successfully.
> I can add it to the pallete and to a form in Excel.
> However, when I try to run that form I am now seeing:
> 
> Run-time error '50003'.
> Unexpected error.
> 
> When I clear that dialog I get another one:
> 
> ...


I could replicate the issue and update released. Please re-download the OCX.

Also please ensure to delete the *VBFLXGRD12.exd* file in:


```
C:\Documents and Settings\[YOUR USERNAME]\Application Data\Microsoft\Forms
C:\Users\[YOUR USERNAME]\AppData\Local\Temp\VBE
```

----------


## southmark

> I could replicate the issue and update released. Please re-download the OCX.
> 
> Also please ensure to delete the *VBFLXGRD12.exd* file in:
> 
> 
> ```
> C:\Documents and Settings\[YOUR USERNAME]\Application Data\Microsoft\Forms
> C:\Users\[YOUR USERNAME]\AppData\Local\Temp\VBE
> ```



Working in Windows 10, thank you! I look forward to trying it out.

More a FYI, in Windows XP regsvr32 returns "VBFLXGRD12.OCX is not an executable file and no registration helper is registered for this filetype"

----------


## Krool

> Working in Windows 10, thank you! I look forward to trying it out.
> 
> More a FYI, in Windows XP regsvr32 returns "VBFLXGRD12.OCX is not an executable file and no registration helper is registered for this filetype"


Do you use the 32-bit regsvr32 in SysWow64 folder?
That solution is coming when I put your message to google..
On the other side this means you have windows xp x64?

----------


## southmark

> Do you use the 32-bit regsvr32 in SysWow64 folder?
> That solution is coming when I put your message to google..
> On the other side this means you have windows xp x64?


Windows 10, syswow64, works. My Windows XP is a 32-bit VirtualBox VM. I've also tried a couple of (physical) 64-bit Windows 7 machines, where I'm getting the 'The module "VBFLXGRD12.OCX": was loaded but the call to DllRegisterServer failed with error code 0x80004005.' message.

----------


## Krool

> Windows 10, syswow64, works. My Windows XP is a 32-bit VirtualBox VM. I've also tried a couple of (physical) 64-bit Windows 7 machines, where I'm getting the 'The module "VBFLXGRD12.OCX": was loaded but the call to DllRegisterServer failed with error code 0x80004005.' message.


Did you start cmd as admin ? (Run as administrator)

----------


## Karl77

PERFORMANCE QUESTION

I have a problem that I can't really describe very well, but I'll try:

Let's say I have 10.000 rows in a grid, 4 cols.
It is super fast to fill.
Then I fill the same grid with 100 rows only.
This takes quite long.
I already inspected my code to see what the bottleneck could be, nothing special found so far.

I have the _feeling_ that the effect is related to the 'destroy a lot of classes is slow' problem in VB6.
Can that be?
And if so, is there a way around it?

----------


## Krool

> PERFORMANCE QUESTION
> 
> I have a problem that I can't really describe very well, but I'll try:
> 
> Let's say I have 10.000 rows in a grid, 4 cols.
> It is super fast to fill.
> Then I fill the same grid with 100 rows only.
> This takes quite long.
> I already inspected my code to see what the bottleneck could be, nothing special found so far.
> ...


There are no classes, so no problem for that like in ListView (without VirtualMode).

Though it would make a difference between 1x = .Rows set 100 vs. 100x .AddItem.
Also it makes a slight difference when first setting rows and then cols.
The row increase is more performant than increase cols. That's due to the fact that the 2d struct internally is done with two arrays in combination instead of one array. But that's sbsolutely necessary.
So better first set the cols and then mess around with rows.

----------


## Karl77

(PERFORMANCE QUESTION)




> There are no classes, so no problem for that like in ListView (without VirtualMode).


You are completely right with all you said.
There is no performance issue with the VBFlexGrid.

I have found the bottleneck in my code now.
*Sorry* for asking too early.

Again, VBFlexGrid is super fast!

----------


## southmark

> Did you start cmd as admin ? (Run as administrator)


Hi Krool, sorry for the late reply - I went on holiday. I do appreciate your feedback.

Yes - as admin. There seems to be a group policy on the Windows 7 machines that prevents the installation but I don't have permissions to view it.

----------


## Krool

1.
Update, convenient CellClick and CellDblClick event included.

2.
Open question relating to an behavior change in the user interaction:

Currently the behavior and user interaction is equal to the MS(H)FlexGrid.
However, I do find the keyboard user interaction very cumbersome in SelectionMode ByRow or ByCol.

Example:
You have SelectionMode ByRow and more columns than the screen allows to display at once.
So a horizontal scrollbar is displayed. Fine, the only way to scroll horizontal is by mouse.
Wouldn't it be better to allow the left and right keys to scroll horizontal ? (like in the ListView control)

Of course it would be better. (also "analog" when ByCol)
But there are two optinos of how I could implement it:
A: Just implement the new behavior
B: Provide a new "ExtendedUI" or "CompatibilityMode" property (other naming ideas?) to determine if the control should be forced to match MSFlexGrid or to allow user interaction enhancements. (maybe possible other behavior changes in future)

The problem I do see with option A is that maybe somebody in their app already noticed this lack and filled this with own code in the key events to allow scrolling horizontal by key inputs.
Then with a next update of option A (in case an app fills the lack) is that suddenly with left and right keys the control would scroll twice in SelectionMode ByRow or ByCol.

That's why I would personally prefer option B.
But I want to be sure and await possible feedbacks about this approach.

----------


## ChenLin

convenient CellClick and CellDblClick event included.

This is a very convenient function! In the past, you had to write a function to get cell events, but now you don't need it.

Thank you!

----------


## DaveDavis

> 1.
> Update, convenient CellClick and CellDblClick event included.
> 
> 2.
> Open question relating to an behavior change in the user interaction:
> 
> Currently the behavior and user interaction is equal to the MS(H)FlexGrid.
> However, I do find the keyboard user interaction very cumbersome in SelectionMode ByRow or ByCol.
> 
> ...


Move focus (focused cell) in selected row to Left or Right in result of horizontal scrolling when selection mode is ByRow.

----------


## dreammanor

> 1.
> Update, convenient CellClick and CellDblClick event included.


The Click event of Farpoint Spread and my Spread is like this:



```
Private Sub fpSpread1_Click(ByVal Col As Long, ByVal Row As Long)

End Sub
```




> 2.
> Open question relating to an behavior change in the user interaction:
> 
> Currently the behavior and user interaction is equal to the MS(H)FlexGrid.
> However, I do find the keyboard user interaction very cumbersome in SelectionMode ByRow or ByCol.
> 
> Example:
> You have SelectionMode ByRow and more columns than the screen allows to display at once.
> So a horizontal scrollbar is displayed. Fine, the only way to scroll horizontal is by mouse.
> ...


I just tested your VBFlexGrid. When "SelectionMode = FlexSelectionModeByRow", the Focused Cell is always in the first column (column A). IMO, this is unreasonable and should allow the user to select different active cell in the current row.

If the above problem is solved, then moving the active cell with the key left-arrow or right-arrow and causing horizontal scrolling is the best solution.

(The RowMode of Farpoint Spread is also not convenient, I improved it.)

----------


## Arnoutdv

I assume the vbFlexGrid also has the MouseRow and MouseCol properties.
These contain the current Row/Col position for the mouse pointer location.

----------


## Krool

> The Click event of Farpoint Spread and my Spread is like this:
> 
> 
> 
> ```
> Private Sub fpSpread1_Click(ByVal Col As Long, ByVal Row As Long)
> 
> End Sub
> ```
> ...


You suggest even changing the col when ByRow selection mode?
But then the whole row does not look like full selected. Or the drawing routine needs to be adjusted so that the full row looks selected. You basically mean a mix of Free and ByRow, right?
However, option A or B?
I think for such a big behavior change a new ExtendedUI property would be needed?

----------


## dreammanor

> You suggest even changing the col when ByRow selection mode?
> But then the whole row does not look like full selected. Or the drawing routine needs to be adjusted so that the full row looks selected. You basically mean a mix of Free and ByRow, right?
> However, option A or B?
> I think for such a big behavior change a new ExtendedUI property would be needed?


I mean, when a *single* row is full selected (in Row-Mode), the Focused Cell (Active Cell) is allowed to move left and right in this row, but the row is still selected (except for the Focused Cell, other cells are still blue backcolor and  white forecolor).

----------


## Krool

> I mean, when a *single* row is full selected (in Row-Mode), the Focused Cell (Active Cell) is allowed to move left and right in this row, but the row is still selected (except for the Focused Cell, other cells are still blue backcolor and  white forecolor).


I understood it this way. However you agree another property is needed to control this behavior?

----------


## dreammanor

> I understood it this way. However you agree another property is needed to control this behavior?


There is no need to add a property for a small behavior change. My suggestion is to add an enum value to SelectionMode, such as: *FlexSelectionModeBySingleRow* or FlexSelectionModeByRowEx or FlexSelectionModeByRowEnhanced, among which *FlexSelectionModeBySingleRow* makes more sense and more valuable.

----------


## Krool

> There is no need to add a property for a small behavior change. My suggestion is to add an enum value to SelectionMode, such as: *FlexSelectionModeBySingleRow* or FlexSelectionModeByRowEx or FlexSelectionModeByRowEnhanced, among which *FlexSelectionModeBySingleRow* makes more sense and more valuable.


Maybe "FlexSelectionModeByRow*Free*"
Beside that I would also like to improve behavior for the "old" selection modes.
It cannot be that horizontal scrolling is not possible by cursor keys in SelectionByRow.
Therefore I may add a "CompatibilityMode" property to allow certain behavior improvements or to enforce full behavior synchronicity to not break old code base. (As such default value will be True)
In future other behavior change might be covered as well by that property.
What you mean?

----------


## DaveDavis

> Maybe "FlexSelectionModeByRow*Free*"
> Beside that I would also like to improve behavior for the "old" selection modes.
> It cannot be that horizontal scrolling is not possible by cursor keys in SelectionByRow.
> Therefore I may add a "CompatibilityMode" property to allow certain behavior improvements or to enforce full behavior synchronicity to not break old code base. (As such default value will be True)
> In future other behavior change might be covered as well by that property.
> What you mean?


Most of Grid doesn't have such "FlexSelectionModeByRow". As we suggested, A focused Cell (ActiveCell) can be changed by arrows is the common behaviour.

----------


## Krool

_removed_

----------


## dreammanor

> Maybe "FlexSelectionModeByRow*Free*"
> Beside that I would also like to improve behavior for the "old" selection modes.
> It cannot be that horizontal scrolling is not possible by cursor keys in SelectionByRow.
> Therefore I may add a "CompatibilityMode" property to allow certain behavior improvements or to enforce full behavior synchronicity to not break old code base. (As such default value will be True)
> In future other behavior change might be covered as well by that property.
> What you mean?



In Farpoint Spread and my Spread, there are not only the SelectionMode (SelectBlockOptions, which is more powerful than the SelectionMode of VBFlexGrid) property, but also the *OperationMode* property, whose values are: OperationModeNormal, OperationModeRead, OperationModeRow, OperationModeSingle, OperationModeMulti, OperationModeExtended.

When OperationMode=OperationModeRow, the spread is in single-row selection mode, which is a very useful mode. That's why I recommend adding an enum value FlexSelectionModeBySingleRow to your VBFlexGrid.

If you want to add a property, I suggest you add the *OperationMode* property instead of CompatibilityMode. The name CompatibilityMode is too abstract and can be confusing to the users.

----------


## Eduardo-

> A: Just implement the new behavior
> B: Provide a new "ExtendedUI" or "CompatibilityMode" property (other naming ideas?) to determine if the control should be forced to match MSFlexGrid or to allow user interaction enhancements. (maybe possible other behavior changes in future)
> 
> The problem I do see with option A is that maybe somebody in their app already noticed this lack and filled this with own code in the key events to allow scrolling horizontal by key inputs.
> Then with a next update of option A (in case an app fills the lack) is that suddenly with left and right keys the control would scroll twice in SelectionMode ByRow or ByCol.
> 
> That's why I would personally prefer option B.
> But I want to be sure and await possible feedbacks about this approach.


My vote is for Option A. Implement the new behavior and do not add any new property.
If there are two or three VB6 programmers in the world that added code to fix that bug of the origonal FlexGrids and they decide to replace the controls with your Flex version, if they are lucky they'll read somewhere about the new behaviour and remove their fixing code (unlikely to happen) and if not, they at some point will notice the strange behavior and will realize that they must remove their fixing code because your control doesn't have the bug.

Adding new properties for things like this is confusing for the majority of people that never knew about the bug.
For example I use FlexGrids since many years ago but I never realized about this bug.

Because, let's see:
Lets suppose that the CompatibilyMode is False by default.
All the people that will use your Flex version will have the bug, unless they read somewhere that they must switch that property to True. Then 99.9% of the people will have the bug as the original had because almost nobody reads such things.
On the other hand, if the CompatibilityMode is True by default, the problem will be for the two or three in the whole world that wrote code to fix that bug (but just in the case that these 2 or 3 find your control and decide to replace the old ones with yours). Because the same thing: nobody reads about such things.
And in the case that it happens to some final users, what would be the "big problem"? It is only that with the keyboard the user will scroll two rows instead of one. 
If it happens that might be one program goes out with that "problem", perhaps three or four final users will notice the weirdness of the scroll with the keyboard and decide to use the mouse instead.

----------


## Krool

> My vote is for Option A. Implement the new behavior and do not add any new property.
> If there are two or three VB6 programmers in the world that added code to fix that bug of the origonal FlexGrids and they decide to replace the controls with your Flex version, if they are lucky they'll read somewhere about the new behaviour and remove their fixing code (unlikely to happen) and if not, they at some point will notice the strange behavior and will realize that they must remove their fixing code because your control doesn't have the bug.
> 
> Adding new properties for things like this is confusing for the majority of people that never knew about the bug.
> For example I use FlexGrids since many years ago but I never realized about this bug.
> 
> Because, let's see:
> Lets suppose that the CompatibilyMode is False by default.
> All the people that will use your Flex version will have the bug, unless they read somewhere that they must switch that property to True. Then 99.9% of the people will have the bug as the original had because almost nobody reads such things.
> ...


Good arguments of how it works in the pactice.. Only in a perfect world it would work.  :Big Grin: 

So, I improved then with today's update (when SelectionMode is ByRow/ByCol) the cursor key navigating. (also when shift or ctrl key is concerned)
No new property is included. It's just as is.

----------


## Krool

This update is not a real bugfix, but rather a compatibility fix in regard to MSFlexGrid.

In VBFlexGrid and MSFlexGrid the CellLeft/CellTop property returns the real X/Y coord of an cell.
However, for CellWidth/CellHeight the behavior was different.
The VBFlexGrid returned the real CX/CY values whereas the MSFlexGrid has an offset of -1 for each.

Reason is that the CellWidth/CellHeight are designed to be used in combination with placing a TextBox on a cell. With that -1 offset it looks better.
So in order to be compatible I also made now the -1 offset.
Of course there is then the fact that a row or col with an real height/width of 0 (not visible) will return a negative width. (-1)
But MSFlexGrid is doing the same so..

----------


## Krool

Bugfix in FormatString property.

When no alignment prefix for a column was specified (no '<', '^' or '>') then FlexAlignmentGeneral should have been used instead FlexAlignmentLeftCenter.

Now with FlexAlignmentGeneral it equals MSFlexGrid behavior.

----------


## Krool

Further bugfix. This time CellWrapBehavior property was affected.
The cursor keys move the focus accordingly in the grid and skips hidden or zero height/width rows/cols.
However, that "skip movement" did not work for CellWrapBehavior when the first or last scrollable (non-fixed) rows/cols were hidden or zero height/width.
That's now fixed.

----------


## smileyoufucn

undefined Code:
Dim k As Long
For k = 0 To Me.VBFlexGrid1.Cols - 1
Debug.Print "Debug.Print ColIndex= " & k & "   GetColKeyByIndex =  " & Me.VBFlexGrid1.ColKey(k)
Next  
'Debug.Print ColIndex= 0   GetColKeyByIndex =
'Debug.Print ColIndex= 1   GetColKeyByIndex =
'Debug.Print ColIndex= 2   GetColKeyByIndex =
'Debug.Print ColIndex= 3   GetColKeyByIndex =
'Debug.Print ColIndex= 4   GetColKeyByIndex =
'Debug.Print ColIndex= 5   GetColKeyByIndex =
'Debug.Print ColIndex= 6   GetColKeyByIndex =
'Debug.Print ColIndex= 7   GetColKeyByIndex =
'Debug.Print ColIndex= 8   GetColKeyByIndex =
'Debug.Print ColIndex= 9   GetColKeyByIndex =
'Debug.Print ColIndex= 10   GetColKeyByIndex =
'Debug.Print ColIndex= 11   GetColKeyByIndex =
'Debug.Print ColIndex= 12   GetColKeyByIndex =
'Debug.Print ColIndex= 13   GetColKeyByIndex =
'Debug.Print ColIndex= 14   GetColKeyByIndex =
'Debug.Print ColIndex= 15   GetColKeyByIndex =
'Debug.Print ColIndex= 16   GetColKeyByIndex =
'Debug.Print ColIndex= 17   GetColKeyByIndex =
'Debug.Print ColIndex= 18   GetColKeyByIndex =
'Debug.Print ColIndex= 19   GetColKeyByIndex =

Debug.Print "Debug.Print ColIndex= " & k & "   GetColKeyByIndex =  " & Me.VBFlexGrid1.ColKey(k)=Null ?

----------


## Krool

> undefined Code:
> Dim k As LongFor k = 0 To Me.VBFlexGrid1.Cols - 1Debug.Print "Debug.Print ColIndex= " & k & "   GetColKeyByIndex =  " & Me.VBFlexGrid1.ColKey(k)Next  'Debug.Print ColIndex= 0   GetColKeyByIndex ='Debug.Print ColIndex= 1   GetColKeyByIndex ='Debug.Print ColIndex= 2   GetColKeyByIndex ='Debug.Print ColIndex= 3   GetColKeyByIndex ='Debug.Print ColIndex= 4   GetColKeyByIndex ='Debug.Print ColIndex= 5   GetColKeyByIndex ='Debug.Print ColIndex= 6   GetColKeyByIndex ='Debug.Print ColIndex= 7   GetColKeyByIndex ='Debug.Print ColIndex= 8   GetColKeyByIndex ='Debug.Print ColIndex= 9   GetColKeyByIndex ='Debug.Print ColIndex= 10   GetColKeyByIndex ='Debug.Print ColIndex= 11   GetColKeyByIndex ='Debug.Print ColIndex= 12   GetColKeyByIndex ='Debug.Print ColIndex= 13   GetColKeyByIndex ='Debug.Print ColIndex= 14   GetColKeyByIndex ='Debug.Print ColIndex= 15   GetColKeyByIndex ='Debug.Print ColIndex= 16   GetColKeyByIndex ='Debug.Print ColIndex= 17   GetColKeyByIndex ='Debug.Print ColIndex= 18   GetColKeyByIndex ='Debug.Print ColIndex= 19   GetColKeyByIndex =
> 
> Debug.Print "Debug.Print ColIndex= " & k & "   GetColKeyByIndex =  " & Me.VBFlexGrid1.ColKey(k)=Null ?


And what?

----------


## Krool

> In Farpoint Spread and my Spread, there are not only the SelectionMode (SelectBlockOptions, which is more powerful than the SelectionMode of VBFlexGrid) property, but also the *OperationMode* property, whose values are: OperationModeNormal, OperationModeRead, OperationModeRow, OperationModeSingle, OperationModeMulti, OperationModeExtended.
> 
> When OperationMode=OperationModeRow, the spread is in single-row selection mode, which is a very useful mode. That's why I recommend adding an enum value FlexSelectionModeBySingleRow to your VBFlexGrid.
> 
> If you want to add a property, I suggest you add the *OperationMode* property instead of CompatibilityMode. The name CompatibilityMode is too abstract and can be confusing to the users.


I want to come back to this topic.
On 02-Mar-2019 I fixed some cumbersome behavior already for ByRow/ByCol selection mode in regard to scrolling with the arrow keys.

I would like to add a selection mode where the active cell (focused cell) can be changed by the arrow keys within that "full row/col selection".
However, I want to keep that behavior for ByRow/ByCol that changing the focused cell is not possible. To maintain compatibility to MSFlexGrid. That's why I need new enum values for SelectionMode or another property controlling it.

So how to name it the best? You suggested to add something like "FlexSelectionModeBySingleRow". But SingleRow sounds for me like the current ByRow behavior (where focused cell cannot be moved both directions) and not the new behavior ?

Maybe "FlexSelectionMode*Free*ByRow" ? That would sound for me like the desired behavior, a mix of Free and ByRow combined into one.
It would work like FlexSelectionModeFree, but just drawing the full row (or full column) as selected.

----------


## smileyoufucn

Please forgive me for not speaking English. Content can only be sent using Google Translate.
Problem: The value cannot be obtained normally through the ColKey property
Is this my method problem or bug?

----------


## dreammanor

FlexSelectionModeByRow*Extended* Or FlexSelectionModeByRow*Ex*

FlexSelectionModeByColumn*Extended* Or FlexSelectionModeByColumn*Ex*

----------


## Krool

> Problem: The value cannot be obtained normally through the ColKey property
> Is this my method problem or bug?


Your usage is wrong. See below illustration how it can be used.



```
Private Sub CommandTest_Click()
Dim Col As Long
Col = 5
MsgBox VBFlexGrid1.ColKey(Col) ' will return blank
VBFlexGrid1.ColKey(Col) = "my key"
MsgBox VBFlexGrid1.ColIndex("my key") ' will return 5
MsgBox VBFlexGrid1.ColIndex("my key") ' will return again 5
MsgBox VBFlexGrid1.ColKey(Col) ' will return 'my key'
End Sub
```




> FlexSelectionModeByRow*Extended* Or FlexSelectionModeByRow*Ex*
> 
> FlexSelectionModeByColumn*Extended* Or FlexSelectionModeByColumn*Ex*


Thanks. However, I think will gonna stick to wording 'FlexSelectionMode*Free*ByRow' and 'FlexSelectionMode*Free*ByColumn'.
I do find correct wordings quite important and feel that this would express the behavior more exactly instead of Extended.

----------


## Krool

> Is there an edit function in the works?


Update released. Now the in-cell editing functionality is finally implemented.

The new AllowUserEditing property determines if the start of the edit is handled automatically.
It will then be start automatically when:
- F2 key
- Space key
- Keystroke/typing
- Double click

It can also be started by code using the StartEdit method, even if AllowUserEditing is False.

The edit will end when:
- Losing focus
- Escape key
- Return key
- Tab/ShifTab key (meaningful only when TabBehavior <> Controls; otherwise it's just a LostFocus)
- Navigation key (four Arrow keys, PageUp, PageDown, Home and End keys)

The edit can also be ended by code using the CancelEdit or CommitEdit method.
CancelEdit discard the changes whereas CommitEdit saves the changes.

There are several read-only run-time properties:
- hWndEdit As Long
- EditRow As Long
- EditCol As Long
- EditReason As FlexEditReasonConstants
- EditCloseMode As FlexEditCloseModeConstants

And following run-time properties which are not read-only:
- EditText As String
- EditMaxLength As Long
- EditSelStart As Long
- EditSelLength As Long
- EditSelText As String

The chart below will illustrate the flow of the various events:



To note is that when invoking by code the CommitEdit event that the ValidateEdit event is still triggered.
Inside ValidateEdit you can force validation by again calling CommitEdit even when Cancel parameter should be True.
Or calling CancelEdit inside ValidateEdit when the Cancel parameter is True to just discard the changes and not to keep in edit mode.
Also to note is that EditQueryClose event will not be called in case of LostFocus.

Sample usage included in the demo project. (UserEditingForm.frm)

----------


## Carlos Rocha

Are you sure that the keys Home and End should end the edit mode?
I don't know if it's the standard behavior but seems strange to me. Imo these keys should put the cursor in the start/end of the text.

Just my 0.02

----------


## Krool

> Are you sure that the keys Home and End should end the edit mode?
> I don't know if it's the standard behavior but seems strange to me. Imo these keys should put the cursor in the start/end of the text.
> 
> Just my 0.02€


That is the case. Only when the caret is on specific position it will end edit mode.
If needed it can be prohibited in EditQueryClose event.

----------


## Carlos Rocha

> That is the case. Only when the caret is on specific position it will end edit mode.
> If needed it can be prohibited in EditQueryClose event.


Perfect, thank you  :Smilie:

----------


## DaveDavis

I suggest using pure Owner-Draw usercontrol instead of using CreateWindowEx from VBFlexGridWndClass. We know you have all technoques and skiils to do so.
IMO,I hate mouse moving scrollbar but not updating Grid.

----------


## Krool

> I suggest using pure Owner-Draw usercontrol instead of using CreateWindowEx from VBFlexGridWndClass. We know you have all technoques and skiils to do so.
> IMO,I hate mouse moving scrollbar but not updating Grid.


The problem is that UserControl is an ANSI window so user input chars are not unicode.
For mouse moving scrollbar and not updating grid. What you mean? Doesn't ScrollTrack property set to True resolve this?

----------


## DaveDavis

> The problem is that UserControl is an ANSI window so user input chars are not unicode.


Input Chars is done by your TextBoxW which is unicode.



> For mouse moving scrollbar and not updating grid. What you mean? Doesn't ScrollTrack property set to True resolve this?


oops, I ignored this property. But the scrollbar has strange behavior. I tested in UserEditingForm. It's very obvious, you can reproduce.

----------


## Krool

> Input Chars is done by your TextBoxW which is unicode.


The grid itself also receives input chars, even if there is no default processing. you could catch KeyPress with unicode chars to make your own incremental search or whatever. (As example)

----------


## Krool

Edit: or bigger example. The grid receives first input char to start editing and forwards the first char to the TextBox. If the grid window is not unicode this would be not possible to enter first char as unicode

----------


## DaveDavis

> Edit: or bigger example. The grid receives first input char to start editing and forwards the first char to the TextBox. If the grid window is not unicode this would be not possible to enter first char as unicode


We can subclass IME as olaf did.

----------


## dreammanor

> Update released. Now the in-cell editing functionality is finally implemented.
> 
> The new AllowUserEditing property determines if the start of the edit is handled automatically.
> It will then be start automatically when:
> - F2 key
> - Space key
> - Keystroke/typing
> - Double click
> 
> ...


I quickly tested the cell editing functionality, which is a good start.

(1) The characters position change (offset to the left) after entering the edit mode.
(2) Maybe you could add a property *EditPermanent* to make the grid always in the edit state.
(3) In addition, when the cell editing functionality is added, you should probably allow users to control the movement of the edit-box via vbKeyReturn and vbKeyTab or other keys.

----------


## Krool

> But the scrollbar has strange behavior. I tested in UserEditingForm. It's very obvious, you can reproduce.


I see. I didn't notice this on Windows 7 as there the scrolling is done on the focused window, whereas on Windows 10 the scrolling is done under the window from the mouse pointer.
I will fix this asap.

Regarding the grid window. I don't see the issue with VBFlexGridWndClass. At least then I have full control of everything. Just my opinion.

----------


## Krool

Update released.




> But the scrollbar has strange behavior. I tested in UserEditingForm. It's very obvious, you can reproduce.


That's now fixed. The edit window position/size is now updated when scrolling while in edit mode.






> (1) The characters position change (offset to the left) after entering the edit mode.


Should be doable to adjust this little offsets with EM_SETMARGINS. I will take a look soon.




> (2) Maybe you could add a property *EditPermanent* to make the grid always in the edit state.


You could handle EnterCell or RowColChange event to manually call .StartEdit.




> (3) In addition, when the cell editing functionality is added, you should probably allow users to control the movement of the edit-box via vbKeyReturn and vbKeyTab or other keys.


I didn't get it. Please explain again.
The enter key will end edit mode, except when using shift, ctrl or alt key while pressing enter key. Doing so will insert a line break. Do you mean that?

----------


## DaveDavis

> That's now fixed. The edit window position/size is now updated when scrolling while in edit mode.


Scrollbar still has problem which is hard to describe. In UserEditngForm, You can reproduce by clicking middle of VScrollbar (.ScrollTrack = True), thumb jumps to bottom. Look like Thumb size is too small as usual meanings the scrollbar algorithm is different with C# GridView control.

----------


## ChenLin

I tested and found that in windows server 2012 and windows 2017 system, mouse scrolling is invalid after entering edit mode.

----------


## dreammanor

> I didn't get it. Please explain again.
> The enter key will end edit mode, except when using shift, ctrl or alt key while pressing enter key. Doing so will insert a line break. Do you mean that?


When in the *Editing-Permanent* state, pressing the Return or Tab key will move the active editing cell to the next column of the current row, or the next row of the current column.

----------


## Krool

> I tested and found that in windows server 2012 and windows 2017 system, mouse scrolling is invalid after entering edit mode.


What you mean with invalid? You can't scroll with left button clicks on scrollbar?
For mousewheel for example in some windows version it's scrolling focused window vs. on other the windows version it's scrolling the window under the pointer.(WindowFromPoint so to say)




> When in the *Editing-Permanent* state, pressing the Return or Tab key will move the active editing cell to the next column of the current row, or the next row of the current column.


When the TabBehavior property is <> Controls you could replicate the editing permament manually.
However, there is no ReturnBehavior and WantReturn property yet. If that would be there you could build your own editing permanent style by code.

----------


## Krool

> (1) The characters position change (offset to the left) after entering the edit mode.


That cosmetic issue is now resolved by internally using EM_SETMARGINS upon edit window creation. Thanks.

----------


## Krool

> FlexSelectionModeByRow*Extended* Or FlexSelectionModeByRow*Ex*
> 
> FlexSelectionModeByColumn*Extended* Or FlexSelectionModeByColumn*Ex*


I'm still hesitating to just add enums for SelectionMode. Maybe I want to add other modes later on like in vsFlexGrid. (ListBox style selection etc.)

Therefore I suggest to add another property called 'SelectionUnit'.


```
Public Enum FlexSelectionUnitConstants
FlexSelectionUnitCell = 0
FlexSelectionUnitFullRow = 1
FlexSelectionUnitFullColumn = 2
End Enum

Returns/sets a value indicating which type of unit is used for selections in the flex grid.
```

So FlexSelectionUnitCell would mean that the selection is really based on the range of .Row/.Col and .RowSel/.ColSel

Whereas FlexSelectionUnitFullRow/FlexSelectionUnitFullColumn would mean to extend the selection to full rows/columns regardless of .RowSel/.ColSel.
Only .Row/.Col would be taken into account for "displaying" (drawing) full selection on row/column.
.RowSel/.ColSel can still be used; but are controlled then by SelectionMode.

What do you think?

Example:
- Having .SelectionMode set to 'Free' and .SelectionUnit to 'FullRow'
- .Rows is 100 and .Cols is 100
- .Row is 1 and .RowSel is 2
- .Col is 1 and .ColSel is 2
-> Two full row selection would be drawn even if Col and ColSel are not spanning the whole set of columns. (100)

----------


## dreammanor

If you add the *OperationMode* property, things are easily solved:



```
Enum SelectBlockOptionsConstants
    SelectBlockOptionsNone = 0
    SelectBlockOptionsColumns = 1
    SelectBlockOptionsRows = 2
    SelectBlockOptionsBlocks = 4
    SelectBlockOptionsSheet = 8
    SelectBlockOptionsAll = 15
End Enum

Enum OperationModeConstants
    OperationModeNormal = 0
    OperationModeRead = 1
    OperationModeRow = 2
    OperationModeSingle = 3
    OperationModeMulti = 4
    OperationModeExtended = 5
End Enum
```

----------


## Krool

The next OCX version is still not released..
So I took the chance to change the 'interface' of the BeforeEdit event. The Row/Col params are now ByRef instead of ByVal.
This gives an app more flexibility, if necessary. Or in other words, maybe an unecessary limitation was just removed.

----------


## Karl77

I have found something.

In the Demo project set AllowBigSelection = False, and set AllowSelection = False in the IDE.
Start the project.
Scroll down the grid by mouse wheel.

Place the mouse on the fixed row.
Press and hold the left button.

The grid begins to scroll.
I can't imagine that is intended.
Or?

----------


## Krool

> I have found something.
> 
> In the Demo project set AllowBigSelection = False, and set AllowSelection = False in the IDE.
> Start the project.
> Scroll down the grid by mouse wheel.
> 
> Place the mouse on the fixed row.
> Press and hold the left button.
> 
> ...


That's intended.  :Smilie: 
However, you can change with following code block the behavior which I think you want to have:


```
Private Sub VBFlexGrid1_BeforeMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single, Cancel As Boolean)
With VBFlexGrid1
.HitTest X, Y
If .HitResult = FlexHitResultCell Then
    If .HitCol > (.FixedCols - 1) And .HitRow < .FixedRows Then
        .Row = .TopRow
        .Col = .HitCol
        Cancel = True
    End If
End If
End With
End Sub
```

----------


## Krool

Update released.

Added enum FlexSelectionModeFreeByRow and FlexSelectionModeFreeByColumn in the SelectionMode property.
It's like a mix between FlexSelectionModeFree and FlexSelectionModeByRow or FlexSelectionModeByColumn.

----------


## ChenLin

How to easily achieve multiple choices? For example, drag the mouse to select the row, press CTRL to select the row that is not continuous, and press SHIFT to select the continuous row.
And can get which rows are selected.

----------


## Krool

> How to easily achieve multiple choices? For example, drag the mouse to select the row, press CTRL to select the row that is not continuous, and press SHIFT to select the continuous row.
> And can get which rows are selected.


The vsFlexGrid has a 'ListBox' style selection mode. Which is like 'ByRow' but supports multiselection. Selected rows can be retrieved via an .RowSelected property.
I might include something similar in future.

----------


## Krool

Update released.

Internal restructuring for drawing. The average performance boost in my tests were about 20%.

The 1.2 OCX will not be updated by this restructuring, because soon the new 1.3 version will be anyway released.

----------


## ChenLin

Hi Krool:

If you press the following settings after the update, it will not display properly:
VBFlexGrid1.FixedCols = 0
VBFlexGrid1.MergeCells = FlexMergeCellsFree
VBFlexGrid1.MergeCol(3) = True


This means that VBFlexGrid1.FixedCols = 0 and VBFlexGrid1.MergeCells cannot be set at the same time. This is the latest version, and the previous version is still normal.

----------


## Krool

> Hi Krool:
> 
> If you press the following settings after the update, it will not display properly:
> VBFlexGrid1.FixedCols = 0
> VBFlexGrid1.MergeCells = FlexMergeCellsFree
> VBFlexGrid1.MergeCol(3) = True
> 
> 
> This means that VBFlexGrid1.FixedCols = 0 and VBFlexGrid1.MergeCells cannot be set at the same time. This is the latest version, and the previous version is still normal.


Thanks for reporting. It's kinda normal that after a restructuring new bugs appear.  :Wink: 
Update released. Now it should be all fine.

----------


## Krool

Update released.

Included the EditDropDownList run-time property to enrich the in-cell editing functionality.

The EditDropDownList may be set at the BeforeEdit event, either to vbNullstring (default; off) or to a string each item separated by pipe characters. ("|")
It works similar to the ComboList Property of the vsFlexGrid.
However, I don't use the ComboBox class. I rely on the edit window and extended the combo functionality as can be seen at following screen:


So everything works as normal with just some additional windows. The dropdown button is a Static control with SS_OWNERDRAW and SS_NOTIFY which can't get focus. So the edit window will not get destroyed by a lost focus.
The actual dropdown window is a ComboLBox class window with WS_POPUP style. It also don't receive focus and can't be activated, it just "captures" the mouse and key inputs.

Depending on how the EditDropDownList property is set it imitates a "Dropdown Combo" or "Dropdown List" style ComboBox.
"Dropdown List": (Edit window with ES_READONLY; DroppedDown immediately)


```
EditDropDownList = "ListItem 1|ListItem 2"
```

"Dropdown Combo": (Edit window unchanged; certain behavior adjustments)


```
EditDropDownList = "|ListItem 1|ListItem 2"
```

The additional EditDroppedDown run-time property can programmatically expand or collapse the dropdown list by code. In normal cases not needed.

----------


## Krool

Updated released.

The following point now got removed from the "List of incompatibilities in relation to the MSFlexGrid control"


```
- Fixed cell(s) without cell(s). (e.g. FixedRows = 1 and Rows = 1)
```

Thus at run-time it is now supported to have following code with the possibility where RecordCount is *0*:


```
VBFlexGrid1.Rows = VBFlexGrid1.FixedRows + RecordCount
```

Thus the FixedRows is equal of Rows, having no scrollable rows in fact. (when RecordCount was 0)

The same applies of course for the cols.

This was one of the last steps before I release the next OCX version. I just wait for a while awaiting possible bug reports before I deploy the 1.3 OCX version.

----------


## Krool

Update related to 13-May-2019 update. (renamings)

Sorry for this inconvenience caused but I still had the chance to rename something before next OCX, so I did.  :Smilie: 

Following run-time properties got renamed:
EditDropDownList -> ComboList
EditDroppedDown -> ComboDroppedDown
hWndEditButton -> hWndComboButton
hWndEditList -> hWndComboList

This way everything related to the drop-down list has the prefix "Combo" and everything related to the text box has the prefix "Edit".
Doing this way it's cleaner seperated.

Included ComboCount/ComboItem/ComboIndex run-time properties helping to interact with the drop-down list during edit.

Included ComboDropDown/ComboCloseUp event. (like in a normal ComboBox)

Included ColComboList run-time property. It works similar to the ComboList property, except it applies to entire columns.
If both are defined then ComboList has precedence over ColComboList. (ComboList > ColComboList)

----------


## dreammanor

If were me, I prefer to name them like this:

ComboEditable
ComboButtonWnd
ComboListWnd

----------


## Krool

> If were me, I prefer to name them like this:
> 
> ComboEditable
> ComboButtonWnd
> ComboListWnd


OK, I would propose following renamings then:
ComboList -> ComboEditable
ColComboList -> ColComboEditable
ComboItem -> ComboList
ComboCount -> ComboListCount
ComboIndex -> ComboListIndex

hWndComboButton and hWndComboList I want to keep as I used always the prefix "hWnd"... for such things, also in VBCCR.

----------


## Krool

Update released.

Final renamings now again..

ComboList -> ComboEditable
ColComboList -> ColComboEditable
ComboItem -> ComboList
ComboCount -> ComboListCount
ComboIndex -> ComboListIndex

The ComboEditable features comes in two flavor. Either as DropDownCombo or as DropDownList. The DropDownCombo already implemented auto selecting as the user types. However, the DropDownList now also supports incremental search as you type. So in both modes you can just start editing by typing, below image illustrates:

----------


## Krool

Update released.

bugfix concerning right-to-left and the combo button and combo list for the in-cell editing window.

Also the combo button window is now being hot-tracked and drawn accordingly.
For this I have a open question:

Currently the combo button is drawn via DrawFrameControl with the old grayish look even when theming is enabled.
Should I keep it like this? It would fit in the overall look of the grid control?
Or use uxtheme and draw proper dropdown button ? (CP_DROPDOWNBUTTON with CBXS_DISABLED, CBXS_HOT, CBXS_NORMAL, CBXS_PRESSED)

----------


## Schmidt

> Or use uxtheme and draw proper dropdown button ? (CP_DROPDOWNBUTTON with CBXS_DISABLED, CBXS_HOT, CBXS_NORMAL, CBXS_PRESSED)


I'd use uxtheme internally - but would also raise an event to the outside, to give the user a chance to ownerdraw this thing,
in case the Button shall be used for ones own Cell-Dialogue-PopUps or something (which is not a ComboDropDown)...

Event OwnerDrawCellButton(hDC, Width, Height, State)

The hDC:
- represents the "rectangular button-canvas-area to draw to" 
- it could be pre-filled with the internal rendering (in case the user does not want to overdraw it completely, but just wants to "add little indicator-drawings")
- it should be properly clipped and translated (so that its origin is at 0,0)

Olaf

----------


## Eduardo-

I think I would add a Style property that could set all the colors, border (flat or not and the thickness) to some predefined settings.
And add another property named VisualStyles that could set the colors to the Windows theme when is set to True (the same that you already did for other controls). And also set the border, line colors and such according to the theme.

About the drop down buttons:
When the user clicks a drop down button, I would raise an event and allow to cancel the display of the Combo list (adding a Cancel parameter ByRef) and then allow to handle the operation "manually", for example showing a custom form with some custom rules (and may be validations).
That would give much power to what can be done.

----------


## Schmidt

> When the user clicks a drop down button, I would raise an event and allow to cancel the display of the Combo list (adding a Cancel parameter ByRef) and then allow to handle the operation "manually", for example showing a custom form with some custom rules (and may be validations).
> That would give much power to what can be done.


Yep, that was my thought behind the OwnerDrawEvent for this Button (to be able to signalize, "that other things will pop-up or drop-down").

And in case the "regular DropDown-List" is shown - 
is this already a separate instance of the GridControl itself which hosts the Item-Listing?

If not, I would switch to that behaviour - since this allows (in the vsFlex) to render MultiColumn-DropDownLists
(when an appropriate MultiColumn-DataSource-Container was prepared beforehand)

Olaf

----------


## Eduardo-

I think it also would worth checking what other grids controls do, I mean mostly commercial controls (may be even for other languages).
To see if there is any standard in how they do the things.
For this feature and for any feature with which the Flex grid is improved/added.

----------


## Eduardo-

Along with the "styles" another feature that is nice sometimes to have is the ability to set alternate colors for the rows.
The property could be named perhaps AlternateRowsBackColor or AlternatingRowsBackColor.
In case you decide to implement predefines "styles" it could be part of what is preset.
This helps the user to visually follow the rows when the grids are wide without going up or down to a wrong row.

PS: the 'Printscreen To Clipboard' button in your demo doesn't work, the .Picture property returns just a 1x1 bitmap with a black pixel.

----------


## Krool

> Along with the "styles" another feature that is nice sometimes to have is the ability to set alternate colors for the rows.
> The property could be named perhaps AlternateRowsBackColor or AlternatingRowsBackColor.
> In case you decide to implement predefines "styles" it could be part of what is preset.
> This helps the user to visually follow the rows when the grids are wide without going up or down to a wrong row.
> 
> PS: the 'Printscreen To Clipboard' button in your demo doesn't work, the .Picture property returns just a 1x1 bitmap with a black pixel.


There is already a 'BackColorAlt' property.
Thanks about the printscreen bug advise. Will check soon.




> About the drop down buttons:
> When the user clicks a drop down button, I would raise an event and allow to cancel the display of the Combo list (adding a Cancel parameter ByRef) and then allow to handle the operation "manually", for example showing a custom form with some custom rules (and may be validations).
> That would give much power to what can be done.


Good idea. Will include a Cancel parameter in the ComboDropDown event.




> I'd use uxtheme internally - but would also raise an event to the outside, to give the user a chance to ownerdraw this thing,
> in case the Button shall be used for ones own Cell-Dialogue-PopUps or something (which is not a ComboDropDown)...
> 
> Event OwnerDrawCellButton(hDC, Width, Height, State)


That sounds easier than providing a ton of properties to control customized extra wishes. Will check soon.

----------


## Eduardo-

> There is already a 'BackColorAlt' property.


Ah OK, very good.

----------


## Krool

> the 'Printscreen To Clipboard' button in your demo doesn't work, the .Picture property returns just a 1x1 bitmap with a black pixel.


Update released. Fixed.




> I think it also would worth checking what other grids controls do, I mean mostly commercial controls (may be even for other languages).
> To see if there is any standard in how they do the things.
> For this feature and for any feature with which the Flex grid is improved/added.


The vsFlexGrid seems to have an alias in their ComboList property.

Translated to VBFlexGrid this would mean following:
If the ComboEditable (or ColComboEditable) is either "..." or "|..." then a pop-up button is shown, else a drop-down button.
The difference between "..." and "|..." is that the first one would be read-only edit window and the second one a normal edit window.
Clicking on the pop-up button would fire an CellButtonClick event.

I think that's a good approach, no?

----------


## Eduardo-

> OK, I would propose following renamings then:
> ComboList -> ComboEditable
> ColComboList -> ColComboEditable
> ComboItem -> ComboList
> ComboCount -> ComboListCount
> ComboIndex -> ComboListIndex
> 
> hWndComboButton and hWndComboList I want to keep as I used always the prefix "hWnd"... for such things, also in VBCCR.


If it is not set in stone already, I would like to say that I don't agree with those changes.
These property names are not intuitive for what they are or they do, at least to me.

I was trying to figure how to use them and what each one does, and to compare to the vsFlexGrid... (in order to form an opinion to answer your last message)

Why at least not to stick to the names already used by vsFlexGrid?

About to set the style of the dropdown button, the "standard" options would be arrow down (like a combobox), horizontal ellipsis, and not it is becoming popular also the vertical ellipsis used by Google (mostly in Android, but also in Google Chrome for Windows):           ⁝

Also, here I found documentation of the vsFlexGrid, it could be useful.

----------


## ChenLin

VBFlexGrid1.Col = 0
VBFlexGrid1.Row = 1
VBFlexGrid1.ColSel = VBFlexGrid1.Cols - 1
VBFlexGrid1.RowSel = VBFlexGrid1.Rows - 1

These codes can select the specified line. What if you cancel the selection of one line or all(Other lines remain selected)?

----------


## Krool

> If it is not set in stone already, I would like to say that I don't agree with those changes.
> These property names are not intuitive for what they are or they do, at least to me.
> 
> I was trying to figure how to use them and what each one does, and to compare to the vsFlexGrid... (in order to form an opinion to answer your last message)
> 
> Why at least not to stick to the names already used by vsFlexGrid?
> 
> About to set the style of the dropdown button, the "standard" options would be arrow down (like a combobox), horizontal ellipsis, and not it is becoming popular also the vertical ellipsis used by Google (mostly in Android, but also in Google Chrome for Windows):           ⁝
> 
> Also, here I found documentation of the vsFlexGrid, it could be useful.


As long as the 1.3 OCX is not released I can change names. However, the names used by the vsFlexGrid are also not always intuitive.

We can agree for the in-cell editing drop-down functionality the prefix "Combo" should be used.
A normal ComboBox has a List, ListCount and ListIndex property.
So in order to assume the same output the grid's properties are then ComboList, ComboListCount and ComboListIndex.
In order to enable the drop-down functionality the property ComboEditable (or ColComboEditable) is used.
If it's empty the combo is not used, else it contains the strings used for populating the list. (separated by pipe chars)
So in fact the ComboEditable works like the ComboList property in vsFlexGrid. But I don't find ComboList intuitive, as the List property in a ComboBox returns a item by a given index.




> VBFlexGrid1.Col = 0
> VBFlexGrid1.Row = 1
> VBFlexGrid1.ColSel = VBFlexGrid1.Cols - 1
> VBFlexGrid1.RowSel = VBFlexGrid1.Rows - 1
> 
> These codes can select the specified line. What if you cancel the selection of one line or all(Other lines remain selected)?


The VBFlexGrid (same as MSFlexGrid) does not support multi-selection blocks. It's either single or all.
What might be added in future is a special SelectionMode 'ListBox' which can work in conjunction with a RowSelected property to allow partial selections by rows. (like a ListBox can do)




> is this already a separate instance of the GridControl itself which hosts the Item-Listing?


What do you mean exactly?




> I'd use uxtheme internally


Done.

----------


## Eduardo-

> As long as the 1.3 OCX is not released I can change names. However, the names used by the vsFlexGrid are also not always intuitive.
> 
> We can agree for the in-cell editing drop-down functionality the prefix "Combo" should be used.
> A normal ComboBox has a List, ListCount and ListIndex property.
> So in order to assume the same output the grid's properties are then ComboList, ComboListCount and ComboListIndex.
> In order to enable the drop-down functionality the property ComboEditable (or ColComboEditable) is used.
> If it's empty the combo is not used, else it contains the strings used for populating the list. (separated by pipe chars)
> So in fact the ComboEditable works like the ComboList property in vsFlexGrid. But I don't find ComboList intuitive, as the List property in a ComboBox returns a item by a given index.


I totally agree, vsFlexGrid's Combo* property names are not intuitive either. My point was that the people will have only one set of unintuitive properties and not two.

I'll tell you my experience: yesterday (or may be the day before), I downloaded your control to take a look to what you have added lately. I remembered you have been working in the editing feature, so I wanted to check it.
Then I went to the middle of the property window and looked for a property with "E", something like "Editable", "Edit*" . I found nothing. Then I looked really quicky to see if I saw any property name that can be for editing and I found nothing. I opened the property pages, again navigated all the pages and took a quick look to all the properties, but I found nothing that could be intended for editing. 
I thought "it is still not implemented in this version".

After that, I downloaded the vsFlexGrid to study some things. I went to the "E" and found the property "Editable".

After a while, reading here this thread I found that the property was named "AllowUserEditing", that seems fine now that I think... but I didn't find it at first.

Another thing that I noticed is that your property is Boolean whilst the vs has two options for editing. From their names it seems that one is by keyboard and the other by mouse. But in practice I didn't find a difference.

Another difference that I found is that with the vbFlexGrid you require double click to enter the edit mode whilst the vs enters the edit mode with just one click.
I think it would be nice to have both options.

With the vs one Enter keystroke over a cell means to enter the Edit mode. With yours I didn't find a way to enter the edit mode with the keyboard.

In regard to property names. I see it is difficult to find good property names for these properties.
After thinking a bit, an option could be:

Editable (or EditMode) with three options: no, simple click, double click
EditDropList or EditDropPipedList or EditModeList or EditModePipedList
EditDropListCount or EditModeListCount
EditDropListIndex or EditModeListIndex

After considering, I think I prefer:

EditMode
EditModeList (but still considering EditModePipedList)
EditModeListCount
EditModeListIndex

That's my opinion.

----------


## Krool

> After a while, reading here this thread I found that the property was named "AllowUserEditing", that seems fine now that I think... but I didn't find it at first.


The intention about "AllowUserEditing" is that it enables the end-user to initiate editing by keyboard or mouse.
It is however always possible to start editing by code, even if AllowUserEditing is False.
Having a Editable property would sound that even by code it's not possible..




> Another difference that I found is that with the vbFlexGrid you require double click to enter the edit mode whilst the vs enters the edit mode with just one click.
> I think it would be nice to have both options.
> 
> With the vs one Enter keystroke over a cell means to enter the Edit mode. With yours I didn't find a way to enter the edit mode with the keyboard.


It's possible to start editing by keystroke.

It has following starting modes: (in bold the ones for keyboard)

FlexEditReasonCode = 0
FlexEditReason*F2* = 1
FlexEditReason*Space* = 2
FlexEditReason*KeyPress* = 3
FlexEditReasonDblClick = 4

It is easy to enhance it so editing can be started by an return key:


```
Private Sub VBFlexGrid1_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then VBFlexGrid1.StartEdit
End Sub
```

Or to allow a simple click, instead of double click:


```
Private Sub VBFlexGrid1_CellClick(ByVal Row As Long, ByVal Col As Long, ByVal Button As Integer)
If Row >= VBFlexGrid1.FixedRows And Col >= VBFlexGrid1.FixedCols Then VBFlexGrid1.StartEdit Row, Col
End Sub

Private Sub VBFlexGrid1_BeforeEdit(Row As Long, Col As Long, ByVal Reason As FlexEditReasonConstants, Cancel As Boolean)
If Reason = FlexEditReasonDblClick Then Cancel = True
End Sub
```

As you see there is a set of standard implementation, but it's easy to change it.

----------


## Krool

Update released.

For the namings I made now following decision:

Removed ComboEditable/ColComboEditable property as it got now replaced by two new properties.

The two new properties are:
ComboMode/ColComboMode As FlexComboModeConstants
ComboItems/ColComboItems As String

The ComboMode property is defining the combo functionality mode:
- FlexComboModeNone -> No combo button, normal editing
- FlexComboModeDropDown -> Allows to modify by drop-down list only (edit field is read-only)
- FlexComboModeEditable -> Allows to modify by edit field and drop-down list, some specific behavior.

The ComboItems property defines the list items to be used for the drop-down list. (each item seperated by "|")

It is possible to have ComboMode <> FlexComboModeNone and ComboItems = "". This results then in a drop-down list with no items.

This architecture is more clear and doesn't requires cumbersome aliases for the string property that defines the drop-down list.

Also it is then easier to include new modes, e.g. FlexComboModePopUp.
FlexComboModePopUp would be just a combo button without any drop-down list. (Thus ComboItems would be ignored)
In FlexComboModePopUp the combo button would then be a normal button with ellipsis ("...")

Again, doing this way no aliases are necessary and gives better understanding even without reading any documentation. Because it is really cumbersome without reading any documentation or the demo project to know what aliases would be necessary to have a specific mode, like the vsFlexGrid do.

----------


## Schmidt

[built-in drop-down-listings]



> What do you mean exactly?


I've not played around with the newer versions of the VBFlexGrid, but it seems (from the ScreenShots),
that ComboList-DropDown-areas can be shown when interacting with the Grid...

My suggestion was, to not show "normal Combo-Dropdown-areas", but instead show your own Popup-Window,
which doesn't contain a DropDown-Listing via CommonControls-functionality (or whatever is in use currently), 
but instead shows a (VB-)PopUp-Window, with a dynamically created extra-Instance of the VBFlexGrid on it 
(to easier support Multi-Column-DropDowns).

As for the vsFlex... and its Button- and DropDown-support...
This always seemed to me, like it didn't get much love from the developers (after the main-functionality was finished) -
 meaning that it could be done nicer ... so, implementing it exactly as in the vsFlex would be worthwhile only,
when "strict vsFlex-compatibility" is a long-term-goal...

Olaf

----------


## polytron

Hello,

I am using this control without problems in Windows 7 and Windows 10 64-bit.
But I found an error 50003 when using thsi control with Windows 10 Pro 32-bit.
Could you check this and make a new release?









> This project is intended to replace the MSFlexGrid control for VB6.
> 
> The "MSFLXGRD.OCX" can be replaced completly.
> 
> Even though some enhancements of the MS*H*FlexGrid control are included, it can't replace it completly (yet).
> But there are also new features included that are not available on both MSFlexGrid and MSHFlexGrid.
> 
> The VBFlexGrid supports *Unicode* and is *DPI-Aware*.
> 
> ...

----------


## polytron

Hello,

i found an error 50003 when using this control with Windows 10 Pro 32-Bit.
Could you check thsi and release an update?

----------


## Krool

Update released to cleanup the combo functionality and make definitive decision about the namings.

The ComboMode/ColComboMode run-time property allows to use combo functionality when editing a cell, it returns/sets.
- FlexComboModeNone -> Normal editing.
- FlexComboModeDropDown -> Allows to modify by drop-down list only.
- FlexComboModeEditable -> Allows to modify by normal editing and drop-down list.
- FlexComboModeButton -> Allows to modify by button only, which is a request to open a custom editor.

The ComboButtonValue run-time property which sets the value of the combo button by code, it returns/sets:
- FlexComboButtonValueUnpressed -> Normal.
- FlexComboButtonValuePressed -> Shows drop-down list or raises ComboButtonClick. (depending on ComboMode)
- FlexComboButtonValueDisabled -> Cannot click, grayed and closes up drop-down list if necessary.

ComboItems/ColComboItems run-time property is the definition of the strings to be used for the drop-down list.
Each item is separated with "|". If ComboMode property is Button then this property is ignored.

ComboList/ComboListCount/ComboListIndex run-time property are helping to interact with the drop-down list by code.

ComboDropDown/ComboCloseUp event, which occurs only when ComboMode is DropDown or Editable.

ComboButtonClick event, which occurs only when ComboMode is Button.

ComboButtonDrawMode run-time property and corresponding ComboButtonOwnerDraw event.

----------


## polytron

Hello,

will the new release also solve the mentioned run time error 50003?

----------


## Krool

> Hello,
> 
> will the new release also solve the mentioned run time error 50003?


Did you use google? It seems a registration issue on your machine.

----------


## Krool

OCX version 1.3 released.

----------


## Krool

Update released.

If drop-down list extends beyond bottom edge of the screen (MonitorFromWindow API) then it will be displayed above the edit window.
Just like a normal ComboBox would behave.

----------


## ChenLin

hi Krool,Can I specify a format for the column? For example



```
Set vbgflexgrid.DataSource = adoGh
Vbgflexgrid.colformat(1,"0.00")
```

----------


## Krool

Update released.

Included additional PictureAlignment enum constants to allow pictures to not overlap with the text.

Red ones are new and blue ones are the related "normal" enums.
So the normal enum + 20 is the NoOverlap range. I reserved some space to maybe also allow Center* pictures to have no overlap counterpart, but I think there is no need for it. (?)
And for Stretch or Tile it never makes sense to have a NoOverlap counterpart.


```
Public Enum FlexPictureAlignmentConstants
FlexPictureAlignmentLeftTop = 0
FlexPictureAlignmentLeftCenter = 1
FlexPictureAlignmentLeftBottom = 2
FlexPictureAlignmentCenterTop = 3
FlexPictureAlignmentCenterCenter = 4
FlexPictureAlignmentCenterBottom = 5
FlexPictureAlignmentRightTop = 6
FlexPictureAlignmentRightCenter = 7
FlexPictureAlignmentRightBottom = 8
FlexPictureAlignmentStretch = 9
FlexPictureAlignmentTile = 10
FlexPictureAlignmentLeftTopNoOverlap = 20
FlexPictureAlignmentLeftCenterNoOverlap = 21
FlexPictureAlignmentLeftBottomNoOverlap = 22
FlexPictureAlignmentRightTopNoOverlap = 26
FlexPictureAlignmentRightCenterNoOverlap = 27
FlexPictureAlignmentRightBottomNoOverlap = 28
End Enum
```

Illustration to show the difference: (Alignment of the text is in both cases left; so to effectively see the difference)


This way the CellPicture behaves more like an 'icon' instead like a background picture.




> Can I specify a format for the column?


Noted. Feature will be added soon. (ColFormat property)
In the meantime you may loop the column and format each cell manually. (via .TextMatrix)

----------


## Krool

> Can I specify a format for the column? For example
> 
> 
> 
> ```
> Set vbgflexgrid.DataSource = adoGh
> Vbgflexgrid.colformat(1,"0.00")
> ```


Done.

----------


## ChenLin

Already tested and successful, thank you @Krool

----------


## ChenLin

Another idea: If you have a lot of columns, maybe adding a freeze pane will make it easier to view, just like Excel does.

----------


## dreammanor

> Another idea: If you have a lot of columns, maybe adding a freeze pane will make it easier to view, just like Excel does.


Good suggestion. In Farpoint Spread and my Spread, there are ColsFrozen and RowsFrozen properties. Maybe Excel uses different names.

----------


## Arnoutdv

Same for the vsFlexGrid control.

----------


## yokesee

Hi.
some time ago it worked for me but now it does not compile or run in the ide closes everything completely.
commoncontrol does not work as it closes.
the reference is correct OLEGuids\OLEGuids.tlb
use windows 10 home

a greeting and forgiveness for the language

----------


## Krool

DirectionAfterReturn property included.

This is actually a simple feature and long overdue..
It allows to move the position of the current cell when the user presses return (Enter) key.
It also works in conjunction with the WrapCellBehavior property. (like the TabBehavior property does)

----------


## SPB-667

Krool, thank you for this grid. Could you activate property AllowUserEditing? I would like to forbid cell's editing.

----------


## Krool

> Could you activate property AllowUserEditing? I would like to forbid cell's editing.


I don't understand. If you want to forbid cell's editing then set AllowUserEditing to False (Default)

----------


## SPB-667

> Krool, thank you for this grid. Could you activate property AllowUserEditing? I would like to forbid cell's editing.


Nevermind. I found it )
But I have another question: can you add autosave of data from grid to database (like MS DataGrid 6.0) after changing cells.

----------


## SPB-667

> I don't understand. If you want to forbid cell's editing then set AllowUserEditing to False (Default)


Nevermind. I found it already)
But I have another question: can you add autosave of data from grid to database (like MS DataGrid 6.0) after changing cells.

----------


## Krool

> But I have another question: can you add autosave of data from grid to database (like MS DataGrid 6.0) after changing cells.


This a replacement for the FlexGrid control and not for the DataGrid control. There is no direct binding available in the MSFlexGrid control, so the VBFlexGrid doesn't either.
However, in my opinion, it is anway better to have the database unbound to the grid. If you change something in the grid it's in your control what happens after that in the database.

----------


## leifmb

Hi,

I've tried this on 2 different machines, both Win 10 64bit, but the IDE just crashes when I run, compile or try to view MainForm.
I've put the OLEGuids files in SysWOW64 and the IDE looks to find them OK. I have not registered them in any way. Just overwrote the old OLEGuids I had there.

Any ideas?


Update: removed "MainForm" and changed Sub Main() to show "UserEditingForm" instead and then the program runs fine.

-Leifster

----------


## Krool

> I've tried this on 2 different machines, both Win 10 64bit, but the IDE just crashes when I run, compile or try to view MainForm.
> I've put the OLEGuids files in SysWOW64 and the IDE looks to find them OK. I have not registered them in any way. Just overwrote the old OLEGuids I had there.
> 
> Any ideas?
> 
> 
> Update: removed "MainForm" and changed Sub Main() to show "UserEditingForm" instead and then the program runs fine.


To be honest. I understanding nothing what you are describing.
For me the MainForm works. And that only UserEditingForm works but not MainForm is an indication that it's not the VBFlexGrid's nor OLEGuids.tlb's fault.

----------


## leifmb

I guess it's something wrong with my VB6 setup/installation then. I've seen similar behavior once or twice before.
Just tested on my 3rd VB6 machine and it has the very same problem :-(

Off topic: There are many different guides on how to install VB6 on Windows 10, all with some variations. Is there a definitive guide somewhere?

----------


## Eduardo-

> I guess it's something wrong with my VB6 setup/installation then. I've seen similar behavior  once or twice before.
> Just tested on my 3rd VB6 machine and it has the very same problem :-(
> 
> Off topic: There are many different guides on how to install VB6 on Windows 10, all with some variations. Is there a definitive guide somewhere?


I suggest to ask this question in the general forum.

If it is of any comfort to you, from time to time (may be every two or three months) I need to uninstall and reinstall VB6 because I start to experience quasi random crashes of the IDE (I have Windows 10 - 64 bits).
I usually also clean the registry with a registry cleaner after uninstalling and before reinstalling (but I don't know if that is necessary).

----------


## Krool

Often I need to indicate "sort arrows".
I would like to integrate such thing as a default in-built feature to reduce code lines on form level etc.
Any suggestions how to look like and integration?
I thought maybe with a .ColSortArrow property with enums None, Up and Down.
But how to draw, default or app should provide picture? How to align? (Text truncate problem?)

Thanks

----------


## Krool

Update released.

The 'DataSource' property for reading ADO recordsets is now much faster reading the data.

Instead of looping trough all records/fields, the .GetRows method is used to extract all into an array.

In addition the cursor position does not need to be modified anymore as 'adBookmarkFirst' is used on .GetRows method.

----------


## Krool

Updated released. (also for OCX)

No VTable subclassing anymore at all. VTableSubclass.cls got removed.

----------


## Krool

OCX 1.4 released.

Both versions are now in sync. (Std-EXE)

----------


## dreammanor

> Updated released. (also for OCX)
> 
> No VTable subclassing anymore at all. VTableSubclass.cls got removed.


Hi Krool, Could you explain why the new subclassing is better?

----------


## Eduardo-

> Hi Krool, Could you explain why the new subclassing is better?


Hello, the explanation is in post # 2472 of the CCR thread.

----------


## Krool

Update released.

Bugfix in the ShowLabelTips property.

That property is intended to show tooltips on folded cells. However, it didn't show on fixed cells even though it was designed to work also on fixed cells.
The small bug was in the internal GetLabelInfo function.

----------


## SamOscarBrown

I am using this grid in a program where I need to format (color) certain words in a cell (but not all).  Possible?  (I started a thread in VB6 And Earlier about (erroneously) RTBs.)

----------


## Krool

Update released.

Stupid bugfix in the internal MoveNextRow and MoveNextCol function. It could malfunction on a filtered grid and on the last row/col.

----------


## newbie2

Hi Krool,
I'm binding VBFlexGrid to sqlite database


```
Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
```

However it is Impossile to sort columns order
I got a message: This funtionality is disabled when custom datasource is set
is there a work around? 
thanks

----------


## Krool

> Hi Krool,
> I'm binding VBFlexGrid to sqlite database
> 
> 
> ```
> Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
> ```
> 
> However it is Impossile to sort columns order
> ...


The error says "functionality is disabled".
Reason is crystal clear as you have a virtual binding to a sqlite recordset.
If you want sorting - fine. Just append a "ORDER BY ..." in your sqlite SELECT statement.

----------


## newbie2

> The error says "functionality is disabled".
> Reason is crystal clear as you have a virtual binding to a sqlite recordset.
> If you want sorting - fine. Just append a "ORDER BY ..." in your sqlite SELECT statement.


Thank you.
In fact I need to sort them after having fed the flexgrid control.
I have two command buttons. 
one is 

```
VBFlexGrid1.Sort = FlexSortGenericAscending
```

and the other is VBFlexGrid1.Sort = FlexSortGenericDescending

----------


## Krool

> Thank you.
> In fact I need to sort them after having fed the flexgrid control.
> I have two command buttons. 
> one is 
> 
> ```
> VBFlexGrid1.Sort = FlexSortGenericAscending
> ```
> 
> and the other is VBFlexGrid1.Sort = FlexSortGenericDescending


In virtual bindig the grid is never fed. It just reads the data needed for the current view.

When you need to sort after binding then re-fetch the data again in your custom data source (SELECT statement with ORDER BY) and make a .Refresh on the VBFlexGrid so it reads the new current view.

----------


## newbie2

very clear
 thank you Krool

----------


## newbie2

very clear
 thank you Krool

----------


## newbie2

Krool
Sorry to bother you again
Does VBFlexGrid support checkbox?
I need to delete multiple records from VBFlexGrid
thank you

----------


## Krool

> Krool
> Sorry to bother you again
> Does VBFlexGrid support checkbox?
> I need to delete multiple records from VBFlexGrid
> thank you


http://www.vbforums.com/showthread.p...-in-MsFlexGrid

----------


## newbie2

thanks again
I tested the two methods in the link provided but unluckily none of them succeeded
One method is not possible with virtual binding 
And the the other method failed because VBFlexGrid seems not supporting CellPicture property.

Edit
I jus noticed in your Demo that CellPicture property is supported but in the sample demo provided in the link I get  Method or Data member not found in the line

```
 if VBFlexGrid1.CellPicture = picChecked then
```

----------


## Krool

> thanks again
> I tested the two methods in the link provided but unluckily none of them succeeded
> One method is not possible with virtual binding 
> And the the other method failed because VBFlexGrid seems not supporting CellPicture property.
> 
> Edit
> I jus noticed in your Demo that CellPicture property is supported but in the sample demo provided in the link I get  Method or Data member not found in the line
> 
> ```
> ...


I cannot reproduce your error. Please provide a demo.
I also recommend you to set CellPictureAlignment to 'FlexPictureAlignmentLeftCenterNoOverlap'.

----------


## newbie2

> I cannot reproduce your error. Please provide a demo.
> I also recommend you to set CellPictureAlignment to 'FlexPictureAlignmentLeftCenterNoOverlap'.


Hello Krool
Here is the demo
I should note that with the MSFlexGrid control doesn't throw the error

----------


## Krool

> Here is the demo
> I should note that with the MSFlexGrid control doesn't throw the error


Thanks. I found the error.. Update released.

In the internal structure the cell picture is stored as 'IPictureDisp'.
However, somehow I exposed the cell picture back to the outside as 'IPicture'. (.CellPicture property)
And that 'IPicture' is not "comparable" via "If Pic1 = Pic2 Then".

I also updated the OCX version. Even as it was a "technical compatibility break" I choosed the "Preserve Compatibility (Advanced)" option.
Because in "real" it's not a compatibility break. Any app will continue to run as before.

So I encourage you to upgrade your 1.3 OCX you are currently using to the 1.4 OCX. (because 1.3 is not maintaned anymore)

If you want to stick with the 1.3 version there is this little workaround you can do:


```
Dim CellPic As IPictureDisp
Set CellPic = VBFlexGrid1.CellPicture
If CellPic = picChecked Then
```

If you go to 1.4 the above workaround is not necessary anymore. There you can do directly:


```
If VBFlexGrid1.CellPicture = picChecked Then
```

----------


## newbie2

Thank you Krool  for all these efforts you are doing.
I registrered the 1.4 OCX . I could avoid the error but 
i still can't check / uncheck as I do with the MsFlexGrid.
I attached the wo demos. one is working fine with the MsFlexGrid and the other is not working as expected with the VBFlexGrid
Thank you

----------


## newbie2

I'm sorry
I should have set the VBFlexGrid in the control property to:  Col = 1 Row = 1 FixedRows and Cols = 0
But something very strange is happening with virtual binding
I'm getting type mismatch error in 


```
Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
```

When I drop version 1.4 and place Version 1.3, everything is OK

----------


## Krool

> I'm sorry
> I should have set the VBFlexGrid in the control property to:  Col = 1 Row = 1 FixedRows and Cols = 0
> But something very strange is happening with virtual binding
> I'm getting type mismatch error in 
> 
> 
> ```
> Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
> ```
> ...


You need to change in your DataSource class the reference from IVBFlexDataSource from 1.3 to 1.4.

----------


## newbie2

> You need to change in your DataSource class the reference from IVBFlexDataSource from 1.3 to 1.4.


There is no reference to the control version in the class


```
Option Explicit

Implements IVBFlexDataSource
Private mRs As cRecordset

'a Public Method, to allow Binding to an outside DataSource (in this case an SQLite-cRecordset)
Public Function BindTo(Rs As cRecordset) As IVBFlexDataSource
  Set mRs = Rs
  Set BindTo = Me 'return a reference of our Class-instance to the outside
End Function

'and the whole interface-implementation, which works against our internal SQLite-Recordset
Private Function IVBFlexDataSource_GetRecordCount() As Long
  IVBFlexDataSource_GetRecordCount = mRs.RecordCount
End Function
Private Function IVBFlexDataSource_GetFieldCount() As Long
  IVBFlexDataSource_GetFieldCount = mRs.Fields.Count
End Function
Private Function IVBFlexDataSource_GetFieldName(ByVal Field As Long) As String
  IVBFlexDataSource_GetFieldName = mRs.Fields(Field).Name
End Function
Private Function IVBFlexDataSource_GetData(ByVal Field As Long, ByVal Record As Long) As String
  IVBFlexDataSource_GetData = mRs.ValueMatrix(Record, Field)
End Function
Private Sub IVBFlexDataSource_SetData(ByVal Field As Long, ByVal Record As Long, ByVal NewData As String)
  mRs.ValueMatrix(Record, Field) = NewData
End Sub
```

----------


## Krool

> There is no reference to the control version in the class
> 
> 
> ```
> Option Explicit
> 
> Implements IVBFlexDataSource
> Private mRs As cRecordset
> 
> ...


Does your vbp file references both 1.3 and 1.4?

----------


## newbie2

> Does your vbp file references both 1.3 and 1.4?


yes it does
Now I removed the reference to 1.3 and it worked
thank you a lot

----------


## Karl77

Hello

I need this selection rule by mouse or keyboard:

a)
single click into cell = single cell selected
mouse down and drag = select cells in the column (!) only, same for shift+cursor

b)
click on fixed row's cell
select the whole column

I already tried different combinations of the selection-related properties.
And couldn't find a combination.

What can I do  to get the desired selection "mode"?

Thank you
Karl

----------


## Krool

> b)
> click on fixed row's cell
> select the whole column


You need to have the .AllowBigSelection set to True. Then a click on a fixed row's cell automatically selects the whole column.




> a)
> single click into cell = single cell selected
> mouse down and drag = select cells in the column (!) only, same for shift+cursor


To restrict a "mouse selection dragging" only to the current column you can use following code sample:



```
Private LButtonPressed As Boolean

Private Sub VBFlexGrid1_BeforeSelChange(ByVal NewRowSel As Long, ByVal NewColSel As Long, Cancel As Boolean)
If LButtonPressed = True Then
    If NewColSel <> VBFlexGrid1.ColSel Then Cancel = True
End If
End Sub

Private Sub VBFlexGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then LButtonPressed = True
End Sub

Private Sub VBFlexGrid1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
LButtonPressed = False
End Sub
```

The extension to include also shift+cursor would look like:


```
Private LButtonPressed As Boolean
Private ShiftPressed As Boolean

Private Sub VBFlexGrid1_BeforeSelChange(ByVal NewRowSel As Long, ByVal NewColSel As Long, Cancel As Boolean)
If LButtonPressed = True Or ShiftPressed = True Then
    If NewColSel <> VBFlexGrid1.ColSel Then Cancel = True
End If
End Sub

Private Sub VBFlexGrid1_KeyDown(KeyCode As Integer, Shift As Integer)
ShiftPressed = CBool((Shift And vbShiftMask) <> 0)
End Sub

Private Sub VBFlexGrid1_KeyUp(KeyCode As Integer, Shift As Integer)
ShiftPressed = CBool((Shift And vbShiftMask) <> 0)
End Sub

Private Sub VBFlexGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then LButtonPressed = True
End Sub

Private Sub VBFlexGrid1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
LButtonPressed = False
End Sub
```

----------


## Karl77

> You need to have the .AllowBigSelection set to True. Then a click on a fixed row's cell automatically selects the whole column.


Yes, I knew, I mentioned it only because I didn't want to lose this functionality along with the new 'mode'.




> To restrict a "mouse selection dragging" only to the current column you can use following code sample:
> 
> The extension to include also shift+cursor would look like:
> 
> 
> ```
> Private LButtonPressed As Boolean
> Private ShiftPressed As Boolean
> 
> ...


Works exactly as expected.
Thanks for you support Krool.

----------


## 0xDEADC0DE55

Thank you for this great grid.
I found a bug in the latest version. If I set SelectionMode to any other value then Free and I have AllowUserEdit set to True, with a double click, I can only edit the first cell in the row or column and not the cell I double clicked.

And there is one property missing. There is now BackgoundColorAlt, but no ForegroundColorAlt.

----------


## Krool

> Thank you for this great grid.
> I found a bug in the latest version. If I set SelectionMode to any other value then Free and I have AllowUserEdit set to True, with a double click, I can only edit the first cell in the row or column and not the cell I double clicked.
> 
> And there is one property missing. There is now BackgoundColorAlt, but no ForegroundColorAlt.


It's not a bug, it's a feature.

For SelectionMode Free, FreeByRow, FreeByCol it works as you desire.
For ByRow and ByCol it takes the first cell at it is the "focused" cell.
You can change behavior by code at the BeforeEdit event.
Check the "Reason" param for FlexEditReasonDblClick and as the Row and Col param in the event are "ByRef" you can make a .HitTest and apply .HitRow and .HitCol to it. (Or more convenient use .MouseRow and .MouseCol)
Everyone has different desires, therefore there is a strict flat default behavior and such extra things need to be done via code.

----------


## Krool

Update released.

Significant performance boost for the drawing operation.

~2% for
Usage of Polyline API (not PolylineTo !) instead of MoveToEx and LineTo. (for the grid lines)
Polyline is at device driver level, thus faster than LineTo and it doesn't change current position.

~1% for
Usage of PatBlt API instead of FillRect. (FillRect is a wrapper of PatBlt SelectObject'ing the specified Brush)
Of course when each cell has a different backcolor the effect is equal to FillRect.

~5% for
Preserving the memory DC & Bitmap (DoubleBuffer) for WM_PAINT and purge only upon WM_SIZE. (and cleanup on destroy window)

----------


## IliaPreston

I just downloaded the package (VBFlexGridDemo.zip) attached to post #1

There is no ocx file in it.

----------


## MountainMan

Post #1 in this thread has the built-in code for the VB6 control as shown in the zip file (built-in controls ahe an extension of .ctl. When you put a .ctl file in your code and then compile, the final .exe file will actually have the control included in the exe file and there is no additional file (such as an .ocx) that needs to go along with it. Using the .ctl file in your code makes your final product not have any dependencies but the downside is that each time you compile your program you also have a bit of extra time required to compile the .ctl file into your code. The alternative is to use an.ocx file (it is just the same as the .ctl file but it has been pre-compiled). Your compilations go a bit faster because the control is already compiled but the drawback is that the .ocx file has to accompany your .exe if/when you distribute it.

Look again at Krools first post. Ib abut the 9th line you will see:

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

The link for Version 1.4 is the thread that contains the latest ocx file if that' what you want to use.

BTW, in the parent thread about Common Control replacement there is a link in Krool's first post to a utility I wrote that enables you to use the .ocx file for development and then switch to the .ctl file at the end to have a final file that has no .ocx dependency. I hope that will be of benefit to you (it works with the flexgrid control as well as the larger one).

----------


## Krool

Update released.

Major speed improvement for drawing custom cell background colors.

In the past the custom cell background was drawn via FillRect and by creating a temporary Brush.


```
Brush = CreateSolidBrush(WinColor(.BackColor))
If Brush <> 0 Then
    FillRect hDC, CellRect, Brush
    DeleteObject Brush
End If
```

However, the new approach is at least 4 times(!) faster.


```
OldBkColor = SetBkColor(hDC, WinColor(.BackColor))
ExtTextOut hDC, 0, 0, ETO_OPAQUE, CellRect, 0, 0, 0
SetBkColor hDC, OldBkColor
```

----------


## jedifuk

any chance this flexgrid have footer bar (for total lines) and request for filter bar below header so user can input like Excel. perhaps...

really appreciated this amazing control

----------


## Krool

Update released.

Massive performance boost for Get .Clip property. (the larger the range the bigger the performance difference)

The string concatenation was done previously by using small buffer chunks putting together when the buffer chunks reach a certain size.

However, compared to the VB6 poor man's string builder from wqweto this is light years of speed difference.

Just as a hint. A very large grid took me before 16 seconds to get the .Clip string. Now it takes just 1 full second.

EDIT: using now a string array instead of a collection for the poor man's string builder for some extra speed gain.

----------


## Semke

is it possible add to SelectionMode it should behave like a ListBox (FlexSelectionModeListBox)

thanks

----------


## Krool

> is it possible add to SelectionMode it should behave like a ListBox (FlexSelectionModeListBox)


Yes, I thought of something like this also. (kind of multi-selection)
Thanks for bringing this back up.

The vsFlexGrid does have such a feature, right ?

So you don't determine the selection via Row and RowSel but rather via a dedicated IsSelected(Row As Long) property.

How does it behaves there? I mean a ListBox can be set to different selection styles also.
Also is the focus rect "free" or aligned like on "ByRow" ? What do .RowSel report? Is it returning always same as .Row or a "disabled alias" of -1 ?

Maybe I shall make a SelectioMode "ListBox" (similar to "ByRow") and "FreeListBox" (similar to "FreeByRow")
Just thoughts..

----------


## ChenLin

I made a demonstration of multiple selections, supporting mouse selection, ctrl+mouse, Shift+mouse selection.

All demo codes are included in sub VBFlexGrid1_MouseDown VBFlexGrid1_MouseUp Sub RowBackColor Sub RowForeColor。

----------


## Krool

> I made a demonstration of multiple selections, supporting mouse selection, ctrl+mouse, Shift+mouse selection.
> 
> All demo codes are included in sub VBFlexGrid1_MouseDown VBFlexGrid1_MouseUp Sub RowBackColor Sub RowForeColor。


Please just post code snippets and not entire duplicate of the demo project. In 1 year or so it may be outdated and can cause confusion.

----------


## tnrprog

My project has a large grid with input and calculation data, cells with different colors and pictures. When user changes the data of one cell, the content and appearance of other cells changes accordingly. So every time I have to set redraw=false, fill cells with values ​​and color, and then set redraw=true. This works fine with MSHFLXGD even if I completely clear the grid structure. Instantly and without flickering.

However, to support Unicode and DPI-aware, I switched to VBFLXGRD14. And now, at the time of setting redraw=true there is a flicker (like a flash of the backcolor). The grid disappears for milliseconds and appears again. The larger the table, the longer the flash.

What can be done? I don't want to return to MSHFLXGD. Maybe some speccial API call (not LockWindowUpdate)? Or can I hope for VBFLXGRD update without this issue?

----------


## Krool

> My project has a large grid with input and calculation data, cells with different colors and pictures. When user changes the data of one cell, the content and appearance of other cells changes accordingly. So every time I have to set redraw=false, fill cells with values ​​and color, and then set redraw=true. This works fine with MSHFLXGD even if I completely clear the grid structure. Instantly and without flickering.
> 
> However, to support Unicode and DPI-aware, I switched to VBFLXGRD14. And now, at the time of setting redraw=true there is a flicker (like a flash of the backcolor). The grid disappears for milliseconds and appears again. The larger the table, the longer the flash.
> 
> What can be done? I don't want to return to MSHFLXGD. Maybe some speccial API call (not LockWindowUpdate)? Or can I hope for VBFLXGRD update without this issue?


Just a question at first: Do you have .DoubleBuffer set to True ?

----------


## tnrprog

> Just a question at first: Do you have .DoubleBuffer set to True ?


I tried several options with .DoubleBuffer=True/False, .VisualStyles=True/False etc. The result is the same

----------


## Krool

@ tnrprog,
Can you put together a small demo showing your issue? So I have a better picture and don't fix something in the dark.

----------


## tnrprog

> @ tnrprog,
> Can you put together a small demo showing your issue? So I have a better picture and don't fix something in the dark.


My attempt to write a demo that demonstrates an issue has failed. No repaint issue occurred in the demo application, and your control shows amazing rendering quality.
Perhaps there is a tricky API conflict in my project. Something updates the window forcibly. I will let you know if I find anything.

So far my problem has been resolved by LockWindowUpdate().

----------


## ScriptBASIC

Hi Krool,

I'm new to the FlexGrid control and looking for an example how to use it. I'm assuming at this point that column widths and titles have to be set via code. There is a property page for global settings but nothing to control each column wdith. 

I tried to run the .exe example that came in the download but I get the following error when I try to run it in the IDE. Here is the line it stops on.

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

> Hi Krool,
> 
> I'm new to the FlexGrid control and looking for an example how to use it. I'm assuming at this point that column widths and titles have to be set via code. There is a property page for global settings but nothing to control each column wdith. 
> 
> I tried to run the .exe example that came in the download but I get the following error when I try to run it in the IDE. Here is the line it stops on.
> 
> 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.

----------


## ScriptBASIC

Thanks Krool!

That solved the problem.




More good news. Updating *OLEGuids.tlb* now allows me to use *VBCCR16*  :Thumb:

----------


## Krool

> More good news. Updating *OLEGuids.tlb* now allows me to use *VBCCR16*


Normally the OLEGuids.tlb is not needed for a compiled VBCCR16.

----------


## danoe

Hello, I am new with using VBFlexGrid. I would like to select multiple cells with highlightin. Is tis possible? Are there any code snippets, how to do this, maybe? Thanks!

----------


## Krool

> Hello, I am new with using VBFlexGrid. I would like to select multiple cells with highlightin. Is tis possible? Are there any code snippets, how to do this, maybe? Thanks!


Not yet in-built possible. The plan is to include in future a SelectionMode enum "ListBox" which allows multiple selection (but per full row). (and helper property .RowSelected(Index))
If you want a workaround mimic multi highlighting just search in google for such feature with "MSFlexGrid". You could apply likewise that code to the VBFlexGrid then.

----------


## ChenLin

@Krool:

      How to get the column index value according to the column heading, and not affected by drag and drop.

----------


## Krool

> @Krool:
> 
>       How to get the column index value according to the column heading, and not affected by drag and drop.


When you populate your grid use .ColKey to define the column headings as keys.
After you messed up the grid with drag drop you can use .ColIndex(_Key_) to get the related column index.

----------


## danoe

@krool: thanks for your reply. Is it possible to handle the arrow down key to select a cell in the line below the current selected cell? Currently it is working with arrow right, left and up keys.

----------


## Krool

> @krool: thanks for your reply. Is it possible to handle the arrow down key to select a cell in the line below the current selected cell? Currently it is working with arrow right, left and up keys.


Don't know what you mean. Please be as precise as possible. For me the arrow down key works as expected.

----------


## danoe

> Don't know what you mean. Please be as precise as possible. For me the arrow down key works as expected.


Sorry. I have an Userform with an VBFlexGrid item and a button. If there is an active button in the userform, if I am going the use key down, it sets the focus to the button. If there isn't a button, it works like you described. The selection mode is FlexSelectionModeFree.

----------


## Krool

> Sorry. I have an Userform with an VBFlexGrid item and a button. If there is an active button in the userform, if I am going the use key down, it sets the focus to the button. If there isn't a button, it works like you described. The selection mode is FlexSelectionModeFree.


Yes it's a known issue. Contrary to a VB.Form the VBA.UserForm doesn't implement IOleInPlaceActiveObject. That's why it doesn't get the "pre" accelerator keys.

*EDIT*:
I successfully "workarounded" the VB*A* issue with a WH_GETMESSAGE hook and a helper message (RWM_PRETRANSLATEMSG).
I need some time to put this clean together and will soon release an update.

----------


## Krool

Update, the OCX supports now accelerator keys in a VBA environment.



In order to replace to the new version of the OCX it is strongly recommended to *delete* certain cache files for MS Office:



```
C:\Users\<username>\AppData\Local\Temp\VBE\VBFLXGRD14.exd
```



```
C:\Users\<username>\Application Data\Microsoft\Forms\VBFLXGRD14.exd
```

Those cache files do only exist when previously loaded VBFLXGRD14 into the toolbox on a UserForm.
Then replace the new VBFLXGRD14.OCX in the system directory..

The new conditional compilation const 'ImplementPreTranslateMsg' is set to True in the OCX project and False in the Std-EXE project.
If True (OCX only) the PreTranslateMsg mechanism is used only if the host does not support IOleInPlaceActiveObject.
So the OCX will work unmodified in a VB6 environment like before.
The extension is only used in a VBA environment.

As the OCX can not own or access the message bump in a VBA environment via IOleInPlaceActiveObject, there is no other choice than using a WH_GETMESSAGE hook.
That hook procedure is considered as the "PreTranslateMessage" function. (like c++ mfc)

Also (as side-effect) the WantReturn will work when setting to True. (eating the return key)
This is crucial for the DirectionAfterReturn property to work also. (when it is defined to something other than 0 - None)

----------


## ChenLin

> When you populate your grid use .ColKey to define the column headings as keys.
> After you messed up the grid with drag drop you can use .ColIndex(_Key_) to get the related column index.


Thank you @Krool, I used the following method before. I don't know which of the two methods is better.



```
Public Function GetColIDVB(Sgrd As VBFlexGrid, ByVal ColCaption As String)
    Dim i As Integer
    On Error GoTo CErr
    For i = 0 To Sgrd.Cols - 1
        If Sgrd.TextMatrix(0, i) = ColCaption Then GetColIDVB = i
    Next i
    Exit Function
CErr:     ' MsgBox Err.Description & i
End Function
```

----------


## cliv

I have to maintain an old application that uses DAO recordset (using vsFlexGrid DAO version). I want to change with VBFlexGrid to support unicode. Application is too large to move to ADO.
Can be implemented a property _DAODataSource_?

----------


## Krool

> I have to maintain an old application that uses DAO recordset (using vsFlexGrid DAO version). I want to change with VBFlexGrid to support unicode. Application is too large to move to ADO.
> Can be implemented a property _DAODataSource_?


The best is to use the VBFlexGrid in a "virtual" way.
Means using the .FlexDataSource property. Schmidt provided a sample project somewhere showing how to use it for a SQLite Recordset.
It would be kind of easy to swap it with a DAO recordset.
Also performance and memory wise it is better - the data is loaded only once and not shovel over again from the recordset to the grid.

----------


## cliv

> Schmidt provided a sample project somewhere showing how to use it for a SQLite Recordset..


found here:
https://www.vbforums.com/showthread....te-Recordsets)

thank you...and by the way _ForeColorFixed_ not working.

----------


## Krool

> and by the way _ForeColorFixed_ not working.


Thanks. Fixed!

In the internal DrawFixedCell method was a stupid bug due to a change.



```
If Not .ForeColor = -1 Then
    OldTextColor = SetTextColor(hDC, WinColor(PropForeColorFixed))
Else
    OldTextColor = SetTextColor(hDC, WinColor(.ForeColor))
End If
```

I must have swapped the content of the two branches (for performance) as it is more likely to have no defined custom cell fore color.
And by the swapping I forgot to remove the "Not" to reverse the logic.

In the likewise internal DrawCell method the "Not" got removed..

However, now ForeColorFixed property works now again as expected.

----------


## softv

Dear Krool,


Once again, thanks a million for your work. For ever. Mighty helpful for my freeware and thus the society which avails it freely.


Well, this message of mine is regarding a common issue in both the VBFlexGrid and the RichTextBox of yours. In both cases, I have worked only with the "Std-EXE" version so far. I presume this same issue would exist with the ocx version too.


Two days back, I was displaying all the characters from "Unifont Upper" font in VBFlexGrid. I was displaying each character in a separate cell. Initially, it looked like all characters were getting displayed correctly in their respective cells. But, on closer scrutiny, I found out that for some random ranges of Unicode points, the characters were not getting displayed. Only square boxes were getting printed. For instances:


1)
69216 to 69246
69216 is U+10E60 RUMI DIGIT ONE
69246 is U+10E7E RUMI FRACTION TWO THIRDS


2)
129280 to 129291
(129280 is U+1F900 CIRCLED CROSS FORMED WITH FOUR DOTS)
129291 is U+1F90B DOWNWARD FACING NOTCHED HOOK WITH DOT


Now, for the above ranges, if I copy/paste the characters from VBFlexGrid to MSWord, the characters get displayed correctly in "UniFont Upper". This is to assure you that I did form the surrogate pairs properly for the non-displaying characters too. 


So, what really is happening? Is some kind of font-fallback happening for some code points and hence the grid is showing boxes for them?. Can you kindly enlighten me on this? 


Actually, I have seen this same issue with the RichTextBox (of VBCCR std-exe version, I mean) too, 2 or 3 years back itself, and it still persists in Windows7. This issue is not present in Windows10 though; mighty happy about it. Well, the issue in Windows 7 is - if I gather all the characters from a particular Unicode font (e.g. Siddhanta) in a string array (say 's'), and finally set the string returned by a JOIN of 's' to RichTextBox1.text, then, for some ranges of code points alone (for e.g. 7376 to 7409), only boxes would get printed (in Windows7). The only workaround I could get to solve this issue at that point of time (and even now, in Windows7) was/is the following. 


With RichTextBox1
  .SelStart = 0
  .SelLength = Len(.Text)
  .SelFontCharset = 0
  .SelFontName = .Font.Name
  .SelStart = 0
End With


But, doing the above will take a long time to finish for fonts like 'Arial Unicode MS' which have more than 38K characters. Sometimes, it would put the application in 'Not responding' mode too.


I thought the VBFlexGrid would solve the above problem in both Windows7 and Windows10 but I see that VBFlexGrid too has the same issue in both OSes.


Actually, I tried a similar approach (setting FontCharset to 0) in VBFlexGrid but it did not work out. I tried copy/pasting the aforesaid range of characters from MS Word to VBFlexGrid. Then also, it did not work. Only square boxes were displayed for these characters.


Actually, in Windows 7, for 'Unifont Upper', the characters at 69635 to 69709 (and many more following characters) also get displayed as two boxes only, in VBFlexGrid. These same characters were getting displayed correctly in VBFlexGrid in Windows10.


Is the above issue of some characters not getting displayed in VBFlexGrid, a limitation of the VBFlexGrid control in Windows7 and Windows10? 


Same way, the issue of some characters alone not getting displayed in RichTextBox in Win7, a limitation of the RichTextBox control in Windows7? 


Well, I do not know. May be there is some mistake in the fonts themselves (Unifont Upper, Siddhanta, etc.) in their encodings inside them. May be I am doing a mistake somewhere too. So, if you can either kindly point out the mistake I am committing OR confirm that it is a limitation of the controls in different operating systems, I would be grateful to you. If at all you can provide a permanent solution for the above issue, somehow, it would be simply superb, Krool.


Note: I have talked about the issue in RichTextBox control in this thread itself since I felt that the issues in the VBFlexGrid and RichTextBox are similar. I also felt that if I shared the issues I faced in RichTextBox with you, it may throw some light^^ on solving the VBFlexGrid issue too. However, if you feel that the issues are different, then kindly let me know whether I have to post my query regarding the issue in RichTextBox control in the main VBCCR thread. 


(^^) General observations
As far as I have seen, in Windows 7 (64-bit), if a character gets displayed in VBFlexGrid (for 'Unifont Upper'), it gets displayed in RichTextBox also. e.g. code point 118847 (BYZANTINE MUSICAL SYMBOL ICHADIN). If a character does not get displayed in VBFlexGrid (for 'Unifont Upper'), it does not get  displayed in RichTextBox also. e.g. code point 69216 (RUMI DIGIT ONE).


In Windows10 (64-bit), RichTextBox displays all characters (unlike VBFlexGrid) of 'Unicode Upper' font but has issues in the proper rendering of certain characters (for e.g. displaying the character at codepoint 69632 - BRAHMI SIGN CANDRABINDU). But then, it should be noted that VBFlexGrid itself renders such characters in the same improper way only. And, whenever such a character is displayed in a RichTextBox (in 'Unicode Upper' font), thereafter (i.e. when handling subsequent characters), the RichTextBox could not display all the characters of 'Unifont Upper'. It was able to display only  those characters which were displayed by VBFlexGrid. Whatever characters were displayed as boxes in VBFlexGrid were displayed as boxes in RichTextBox too.


Well, just before completing the drafting of this message, I thought I would just check with the latest ".Net Core" C# gui controls. In my sample test (in Windows 10), the RichTextBox and DataGridView of C+ behaved exactly the same way like your RichTextBox and VBFlexGrid in every case (incl. what happens subsequently after the character at 69632 is displayed). So, wonder now, whether after all, the underlying COM (or library interfaces or whatever) of MS itself has problems. Anyway, I am not an expert in C#. Just for a quick test, I created a simple form with just two controls (RichTextBox and DataGridView) and copy/pasted the characters from your VBFlexGrid control onto these two controls.


As far as I can say, MS Word (I have only Word 2007) has no issues in displaying any character, in both Windows 7 and Windows10, correctly. A software like BabelMap or a font manager like MainType also show all the characters of a font like 'Unifont Upper' perfectly, in their own respective Grid displays. Probably these applications are drawing the character glyphs using some other methodology? If (and only if) so, can the same approach be used for your/our VBFlexGrid also? It would be of immense benefit to the society.


Thanks a TON once again, dear Krool, for your monumental work.


Prayers and Kind Regards.

----------


## Krool

> Well, just before completing the drafting of this message, I thought I would just check with the latest ".Net Core" C# gui controls. In my sample test (in Windows 10), the RichTextBox and DataGridView of C+ behaved exactly the same way like your RichTextBox and VBFlexGrid in every case (incl. what happens subsequently after the character at 69632 is displayed). So, wonder now, whether after all, the underlying COM (or library interfaces or whatever) of MS itself has problems.


That indicates that there is a problem in the underlying API.

Somehow MS Word (and others) maybe renders differently and don't rely on OS API's.

If that's true then I cannot help you because I can only use the OS API's for rendering and don't have another option.

----------


## ScriptBASIC

> Normally the OLEGuids.tlb is not needed for a compiled VBCCR16.


Krool,

When I updated the OLEGuids.tbl from vintage VBCCR14 the VBFlexGrid demo is giving the same error I posted above. (worked withe VBCCR14 OLEGuids.tbl) Do you have a VBFlexGrid demo that works with the current OLEGuids.tbl?

BTW:

Using VBCCR16 with my AxtiveX DLL portable GUI forms works great. They callback to ScriptBasic for events and the ScriptBasic COM/OLE extension module communicates with it calling methods and GET/SET properties I've defined as class functions / properties. The *Auto* and *Select* button callbacks create ScriptBasic threads which communicate via common memory variables and a VB timer control that updates the form every 2.5 seconds.

----------


## Krool

> When I updated the OLEGuids.tbl from vintage VBCCR14 the VBFlexGrid demo is giving the same error I posted above. (worked withe VBCCR14 OLEGuids.tbl) Do you have a VBFlexGrid demo that works with the current OLEGuids.tbl?


Something is wrong on your side. The OLEGuids.tlb is 1:1 the same for VBFlexGrid and for the VBCCR controls.
Maybe you have an outdated VBFlexGrid download prior to 15-Apr-2020..

On a PC without OLEGuids.tlb I can load and run VBFLXGRD14 and VBCCR16/VBCCR17 in the IDE without a problem. Also the executable dealing with the OCX just runs fine.
You only need the OLEGuids.tlb when using the Std-EXE version of the controls(!) and then for compilation only.
A Std-EXE version using the OCX does not even need the OLEGuids.tlb for compilation.

----------


## ScriptBASIC

Krool,

I have been searching far and wide and can't find out how to disable columns from being edited. I only have one column out of 6 I need to edit and get a callback that it changed. Can you point me to an example how this is done? 

Thanks!

BTW: Downloading the latest VBFlexGridDemo is working with my VBCCR16 and dependencies. (Windows 10 Pro)

John

----------


## Krool

> I have been searching far and wide and can't find out how to disable columns from being edited. I only have one column out of 6 I need to edit and get a callback that it changed. Can you point me to an example how this is done?


You can disable a column from being edited by handling the BeforeEdit event and return Cancel = True.

The chart will illustrate the flow of the various events: Attachment 167489

----------


## ScriptBASIC

Krool,

Brilliant and simple, THANK YOU!

Events can be your friend.  :Wink:

----------


## ScriptBASIC

Krool,

Is the code demo for multi-row select as shown in post #367 available anywhere? I read through the complete thread and didn't find anything about how to do multi-row / random selects other than post #367 but no code attached.

----------


## ScriptBASIC

Krool,

I was able to get my random row select working with the *CellClick* event. I use the left mouse button to select a cell (changing background) and right mouse button to reset it. I keep an array of the selected rows.

----------


## SPB-667

Is It possible to know indexes of all selected rows (without mouse properties)?

----------


## ScriptBASIC

Hi Krool,

Is there a way to disable horizontal scrolling of the VBFlexGrid? When I click on the last (right most) column it shifts my first column off the grid screen and displays a dark grey area as a next column that doesn't exist. Attached is how I would like to keep the grid positioned.

----------


## Krool

> Hi Krool,
> 
> Is there a way to disable horizontal scrolling of the VBFlexGrid? When I click on the last (right most) column it shifts my first column off the grid screen and displays a dark grey area as a next column that doesn't exist. Attached is how I would like to keep the grid positioned.


This is a bug. I see in the screen that you have the .ScrollBars property set to 'Vertical'.
In the normal MS(H)FlexGrid this will result that the LeftCol will not change upon mouse clicks and key movements. (Even not when changing by code - very strict therefore)

Currently the VBFlexGrid will behave always as if .ScrollBars is set to 'Both'.

I noted it down and will be fixed soon. Thanks!

EDIT:
Bugfix done. Small change done in the internal SetRowColParams method with a big effect. (marked as blue)
It's a very strict way of disabling it but it seems the MS(H)FlexGrid doing the same thing. (Not even allowing .LeftCol changed by code when .ScrollBars is set to 'Vertical' for instance)


```
Private Sub SetRowColParams(ByRef RCP As TROWCOLPARAMS)
[...]
Select Case PropScrollBars
    Case vbSBNone
        If (.Mask And RCPM_TOPROW) = RCPM_TOPROW Then .Mask = .Mask And Not RCPM_TOPROW
        If (.Mask And RCPM_LEFTCOL) = RCPM_LEFTCOL Then .Mask = .Mask And Not RCPM_LEFTCOL
    Case vbHorizontal
        If (.Mask And RCPM_TOPROW) = RCPM_TOPROW Then .Mask = .Mask And Not RCPM_TOPROW
    Case vbVertical
        If (.Mask And RCPM_LEFTCOL) = RCPM_LEFTCOL Then .Mask = .Mask And Not RCPM_LEFTCOL
End Select
[...]
```

----------


## Krool

Update related to yesterday's bugfix.

Included new flags RCPF_FORCETOPROWMASK and RCPF_FORCELEFTCOLMASK which is used in the internal SetRowColParams method.


```
Private Sub SetRowColParams(ByRef RCP As TROWCOLPARAMS)
[...]
Select Case PropScrollBars
    Case vbSBNone
        If Not (.Flags And RCPF_FORCETOPROWMASK) = RCPF_FORCETOPROWMASK Then
            If (.Mask And RCPM_TOPROW) = RCPM_TOPROW Then .Mask = .Mask And Not RCPM_TOPROW
        End If
        If Not (.Flags And RCPF_FORCELEFTCOLMASK) = RCPF_FORCELEFTCOLMASK Then
            If (.Mask And RCPM_LEFTCOL) = RCPM_LEFTCOL Then .Mask = .Mask And Not RCPM_LEFTCOL
        End If
    Case vbHorizontal
        If Not (.Flags And RCPF_FORCETOPROWMASK) = RCPF_FORCETOPROWMASK Then
            If (.Mask And RCPM_TOPROW) = RCPM_TOPROW Then .Mask = .Mask And Not RCPM_TOPROW
        End If
    Case vbVertical
        If Not (.Flags And RCPF_FORCELEFTCOLMASK) = RCPF_FORCELEFTCOLMASK Then
            If (.Mask And RCPM_LEFTCOL) = RCPM_LEFTCOL Then .Mask = .Mask And Not RCPM_LEFTCOL
        End If
End Select
[...]
```

This way there is a internal way of forcing a scroll, even if there is no scrollbar. (of course the 'Scroll' event will not be fired as no scrollbar exist)

Reason for such a forcing is that when changing the Rows/Cols property and the current TopRow/LeftCol is > Rows/Cols and the scrollbar do not exist accordingly then no cells are visible anymore (only fixed cells)
The MS(H)FlexGrid behaves in this way to "scroll" so that at least one row/column is shown. (even if there is no scrollbar)
Therefore such flags are now used in the Rows/Cols property.

Who knows, maybe somebody finds out that another property also needs such exception. Then the flag is already available and easy fix-able.

----------


## smileyoufucn

Sorry：

Compile Error
Subroutine or function is not defined

----------


## Krool

> Sorry：
> 
> Compile Error
> Subroutine or function is not defined


You use an outdated "Startup.bas".
Please download the complete VBFlexGridDemo and replace everything. (FlexInitIDEStopProtection does not exist anymore since a while)

----------


## smileyoufucn

> You use an outdated "Startup.bas".
> Please download the complete VBFlexGridDemo and replace everything. (FlexInitIDEStopProtection does not exist anymore since a while)


vbforums:     "VBFlexGridDemo.zip"   and   "ComCtlsDemo.zip"    and  ActiveX Control Version OK   
github:   "VBFLXGRD-master\Standard EXE Version\VBFlexGridDemo.vbp"   and "VBCCR-master\Standard EXE Version"    NG

Suggest update

----------


## Krool

> vbforums:     "VBFlexGridDemo.zip"   and   "ComCtlsDemo.zip"    and  ActiveX Control Version OK   
> github:   "VBFLXGRD-master\Standard EXE Version\VBFlexGridDemo.vbp"   and "VBCCR-master\Standard EXE Version"    NG
> 
> Suggest update


Thanks. Done

----------


## smileyoufucn

Use Set VBFlexGrid1.DataSource = rst
Must use assignment code: ColKey(i) = strKey,
Otherwise, an error will be prompted: Invalid col Value

Is my usage method wrong?



```
Option Explicit
Public Cnn As New ADODB.Connection
Private Sub Form_Load()
    Dim i As Long
    Dim strSQL As String
    Dim strKey As String
    Dim rst As ADODB.Recordset
    OpenConn App.Path & "\Data.mdb"
    strSQL = "SELECT * FROM Sys_tblUsers"
    Set rst = GetRs(strSQL)
    Set VBFlexGrid1.DataSource = rst
    Set rst = GetRs(strSQL)
    i = VBFlexGrid1.Cols - 1
    With VBFlexGrid1
        For i = 0 To i - 1
            strKey = rst.Fields(i).Name
'            .ColKey(i) = strKey'Invalid col Value
            Debug.Print "VBFlexGrid2  i=" & i & "  = " & .ColKey(.ColIndex(strKey)); ""
        Next
    End With
End Sub


Public Sub OpenConn(mdbFileName As String)
    Cnn.CursorLocation = adUseClient
    Cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & mdbFileName
End Sub

Public Function GetRs(Query As String) As ADODB.Recordset
    Set GetRs = New ADODB.Recordset
    GetRs.Open Query, Cnn, adOpenStatic, adLockOptimistic
End Function
```

Test1:




Test2:



Test3:



Demo File:
VFGColKeyTest.zip



```
Public Property Set DataSource(ByVal Value As MSDATASRC.DataSource)
    Set PropDataSource = Value
    If VBFlexGridDesignMode = False Then
        If Not PropDataSource Is Nothing Then
            If PropRecordset Is Nothing Then Set PropRecordset = CreateObject("ADODB.Recordset")
            With PropRecordset
                If .State <> 0 Then .Close
                If StrPtr(PropDataMember) = 0 Then .DataMember = "" Else .DataMember = PropDataMember
                Set .DataSource = PropDataSource
                If .State <> 0 Then
                    If .RecordCount > -1 Then         '  The cursor type of the Recordset affects whether the number of records can be determined.
                        Me.Rows = PropFixedRows + .RecordCount
                        Me.Cols = PropFixedCols + .Fields.Count
                        Dim iRow As Long, iCol As Long
                        If PropFixedRows > 0 Then
                            For iCol = 0 To (.Fields.Count - 1)
                                Me.TextMatrix(0, iCol + PropFixedCols) = .Fields(iCol).Name
                                 '''''''''''''''''''''''''Add'''''''''''''''''''''''''''''''''''
                                VBFlexGridColsInfo(iCol + PropFixedCols).Key = .Fields(iCol).Name
                                 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                            Next iCol
                        End If
                        If .RecordCount > 0 Then
                            Dim ArrRows As Variant
                            ArrRows = .GetRows(, 1)   ' adBookmarkFirst
                            Dim LBoundCols As Long, UBoundCols As Long
                            LBoundCols = LBound(ArrRows, 1)
                            UBoundCols = UBound(ArrRows, 1)
                            Dim LBoundRows As Long, UBoundRows As Long
                            LBoundRows = LBound(ArrRows, 2)
                            UBoundRows = UBound(ArrRows, 2)
                            For iRow = LBoundRows To UBoundRows
                                For iCol = LBoundCols To UBoundCols
                                    If Not IsNull(ArrRows(iCol, iRow)) Then
                                        Me.TextMatrix((iRow + (0 - LBoundRows)) + PropFixedRows, (iCol + (0 - LBoundCols)) + PropFixedCols) = ArrRows(iCol, iRow)
                                    Else
                                        Me.TextMatrix((iRow + (0 - LBoundRows)) + PropFixedRows, (iCol + (0 - LBoundCols)) + PropFixedCols) = vbNullString
                                    End If
                                Next iCol
                            Next iRow
                        End If
                    End If
                End If
            End With
        Else
            Set PropRecordset = Nothing
        End If
    End If
    UserControl.PropertyChanged "DataSource"
End Property
```

----------


## Krool

When you use .ColIndex and did not assign .ColKey before then you get the error.
Your Test 2 is the correct approach.
Test 3 is also ok. But on each update you need to keep your changes in mind.

----------


## smileyoufucn

thank you very much
VSFLEXGRID.ocx defaults to the TEST3 scheme.
Is MSFLEXGRID.ocx the TEST2 solution by default?
If the TEST3 scheme is used by default in the project, will there be any incompatibility with MSFLEXGRID.ocx?
If there is no compatibility problem, then using the Test3 solution in the project should be easier and more convenient to use.

----------


## Krool

> thank you very much
> VSFLEXGRID.ocx defaults to the TEST3 scheme.
> Is MSFLEXGRID.ocx the TEST2 solution by default?
> If the TEST3 scheme is used by default in the project, will there be any incompatibility with MSFLEXGRID.ocx?
> If there is no compatibility problem, then using the Test3 solution in the project should be easier and more convenient to use.


MSFlexGrid has no .ColKey/.ColIndex ...
So if VSFlexGrid behave as Test 3 then I will check this out soon and maybe implement your change into the "master" version.

----------


## smileyoufucn

> MSFlexGrid has no .ColKey/.ColIndex ...
> So if VSFlexGrid behave as Test 3 then I will check this out soon and maybe implement your change into the "master" version.


Krool, thank you very much
If it can be updated to the project, it will be more convenient to use.

Add VSFlexGrid1 Test：






```
Option Explicit
Public Cnn As New ADODB.Connection
Private Sub Form_Load()
    Dim i As Long
    Dim strSQL As String
    Dim strKey As String
    Dim rst As ADODB.Recordset
    OpenConn App.Path & "\Data.mdb"
    strSQL = "SELECT * FROM Sys_tblUsers"
    Set rst = GetRs(strSQL)
    Set VBFlexGrid1.DataSource = rst
    i = VBFlexGrid1.Cols - 1
    With VBFlexGrid1
        For i = 0 To i - 1
            strKey = rst.Fields(i).Name
            .ColKey(i) = strKey  'VBFlexGrid2
            Debug.Print "VBFlexGrid2  i=" & i & "  = " & .ColKey(.ColIndex(strKey)); ""
        Next
    End With
    ''''''''''''Add New VSFlexGrid1 Test ''''
    Set VSFlexGrid1.DataSource = rst                  '
    i = VSFlexGrid1.Cols - 1
    With VSFlexGrid1
        For i = 0 To i - 1
            strKey = rst.Fields(i).Name
            '''              .ColKey(i) = strKey '''VSFlexGrid1 No need for this line of code
            Debug.Print "VSFlexGrid1  i=" & i & "  = " & .ColKey(.ColIndex(strKey)); ""
        Next
    End With
End Sub
```


VFGColKeyAndVSFlexGrid1Test.zip

----------


## Schmidt

A bit late, but just stumbled over it (post #336 and following ones, about Sorting Data in the VBFlex)




> The error says "functionality is disabled".
> Reason is crystal clear as you have a virtual binding to a sqlite recordset.
> If you want sorting - fine. Just append a "ORDER BY ..." in your sqlite SELECT statement.





> In fact I need to sort them after having fed the flexgrid control.


That's possible, by using the Sort-Property of the (bound) SQLite-Rs ... in the same way as with ADO-Rs
This way one can avoid additional roundtrips over the DB (or the DB-Server) just for ordering-purposes.

To be able to reach the Sort-Property (behind your Binding-Class), one can simply expose the internal mRs via a Property Get:



```
Option Explicit

Implements IVBFlexDataSource
Private mRs As cRecordset

'a Public Method, to allow Binding to an outside DataSource (in this case an SQLite-cRecordset)
Public Function BindTo(Rs As cRecordset) As IVBFlexDataSource
  Set mRs = Rs
  Set BindTo = Me 'return a reference of our Class-instance to the outside
End Function

Public Property Get Rs() As cRecordset 'expose mRs to the outside
  Set Rs = mRs
End Property

'*** Ok, finally the 5 method Implementations of IVBFlexDataSource
Private Function IVBFlexDataSource_GetFieldCount() As Long
  IVBFlexDataSource_GetFieldCount = mRs.Fields.Count
End Function
Private Function IVBFlexDataSource_GetFieldName(ByVal Field As Long) As String
  IVBFlexDataSource_GetFieldName = mRs(Field).Name
End Function
Private Function IVBFlexDataSource_GetRecordCount() As Long
  IVBFlexDataSource_GetRecordCount = mRs.RecordCount
End Function

Private Function IVBFlexDataSource_GetData(ByVal Field As Long, ByVal Record As Long) As String
  If Record < mRs.RecordCount Then IVBFlexDataSource_GetData = mRs.ValueMatrix(Record, Field) 
End Function
Private Sub IVBFlexDataSource_SetData(ByVal Field As Long, ByVal Record As Long, ByVal NewData As String)
  If Record < mRs.RecordCount Then mRs.ValueMatrix(Record, Field) = NewData
End Sub
```

A "sort-switching by ColumnName" would then be possible in the Form-Code via a Helper like the one below:
(passing an empty String, to restore the original Sort-Order, as it was coming from the DB-Select)


```
Private Sub SwitchSorting(FieldName As String, Optional ByVal Descending As Boolean)
  myDataSource.Rs.Sort = FieldName & IIf(Descending, " Desc", "")
  myVBFlexGrid.Refresh
End Sub
```

HTH

Olaf

----------


## Krool

> If it can be updated to the project, it will be more convenient to use.


Done.  :Smilie: 

The blue marked code was now inserted into the DataSource property.



```
If PropFixedRows > 0 Then
    For iCol = 0 To (PropFixedCols - 1)
        VBFlexGridColsInfo(iCol).Key = vbNullString
    Next iCol
    For iCol = 0 To (.Fields.Count - 1)
        Me.TextMatrix(0, iCol + PropFixedCols) = .Fields(iCol).Name
        VBFlexGridColsInfo(iCol + PropFixedCols).Key = .Fields(iCol).Name
    Next iCol
End If
```

----------


## smileyoufucn

> Done. 
> 
> The blue marked code was now inserted into the DataSource property.
> 
> 
> 
> ```
> If PropFixedRows > 0 Then
>     For iCol = 0 To (PropFixedCols - 1)
> ...


Krool：
The test is OK. Thank you very much for your help!

----------


## ScriptBASIC

Krool,

Thanks for the fix for horizontal scrolling!

----------


## TheLeePiper

Hating to add a question given your substantial contributions already made, but my search through the thread did not yield an answer. In short, is there a way to land on a cell that has been set as a dropdown combo and have it not drop the list, just shot the text and the button. (We are hoping to use this as a container for editable fields of a variety of different types. Thanks!

Don

----------


## Krool

> Hating to add a question given your substantial contributions already made, but my search through the thread did not yield an answer. In short, is there a way to land on a cell that has been set as a dropdown combo and have it not drop the list, just shot the text and the button. (We are hoping to use this as a container for editable fields of a variety of different types. Thanks!
> 
> Don


Use the .ComboButtonValue property and set to 'FlexComboButtonValueUnpressed' to collapse the drop-down list.
At best you place that line of code in the "EnterEdit" event.

----------


## TheLeePiper

> Use the .ComboButtonValue property and set to 'FlexComboButtonValueUnpressed' to collapse the drop-down list.
> At best you place that line of code in the "EnterEdit" event.


I had just what you mentioned, but in the EnterCell function. When moved to EnterEdit, it quickly drops the list then closes it again. I'll pay with the order of calls to see if I can make that stop. Thanks!

----------


## Krool

> I had just what you mentioned, but in the EnterCell function. When moved to EnterEdit, it quickly drops the list then closes it again. I'll pay with the order of calls to see if I can make that stop. Thanks!


To avoid the "flash" catch the "EditSetupWindow" event and set the .ComboButtonValue to 'FlexComboButtonValueDisabled'.
This will avoid that the drop-down list will be shown initially. Then at the "EnterEdit" event change the .ComboButtonValue property back to 'FlexComboButtonValueUnpressed'.

----------


## TheLeePiper

Thanks again. That did the trick. I am now struggling with capturing text during editing. For background, I am implementing a migration from a very old control (Protoview DataTable) to VBFlexGrid. So far, things are going well. However, we require a bit of key press trapping for a numeric properties check on data entry, such as restricting only numbers, decimals, and math operators (for an inline equation editor). This works great for all of our other controls, but the behavior in VBFlexGrid is not allowing me to do this, so I am hoping that you can provide a little advice. Here is a typical scenario:

We are calling the checking function in Grid_EditKeyPress and are getting the correct key. However, if you select an entire editable text field (say that was originally "0000") then typed the number two, the Text property is still "0000" but the EditSelStart and EditSelLength are both zero at that point. I would have assumed that the Text would either be null at that point or the Sel properties would indicate zero and four for the selected text that was being over-written. Also, I see no way to identify the cursor position at the point of EditKeyPress, which I could then use to work around the above.

Thx.

----------


## Krool

> Thanks again. That did the trick. I am now struggling with capturing text during editing. For background, I am implementing a migration from a very old control (Protoview DataTable) to VBFlexGrid. So far, things are going well. However, we require a bit of key press trapping for a numeric properties check on data entry, such as restricting only numbers, decimals, and math operators (for an inline equation editor). This works great for all of our other controls, but the behavior in VBFlexGrid is not allowing me to do this, so I am hoping that you can provide a little advice. Here is a typical scenario:
> 
> We are calling the checking function in Grid_EditKeyPress and are getting the correct key. However, if you select an entire editable text field (say that was originally "0000") then typed the number two, the Text property is still "0000" but the EditSelStart and EditSelLength are both zero at that point. I would have assumed that the Text would either be null at that point or the Sel properties would indicate zero and four for the selected text that was being over-written. Also, I see no way to identify the cursor position at the point of EditKeyPress, which I could then use to work around the above.
> 
> Thx.


Use the .EditText property. :-)
The .Text property is still original text while editing and will be updated once editing was validated.

----------


## TheLeePiper

> Use the .EditText property. :-)
> The .Text property is still original text while editing and will be updated once editing was validated.


Tried that originally, but EditText was always empty (at least in the immediate window in VB6). Could it be that losing the focus from the control (back to VB6) is clearing the EditText?

----------


## TheLeePiper

Just replaced Text with EditText and it looks like things are back on track! I cannot do any debugging within the IDE (per the comments above), but given that the function was already fully worked out for the other controls with luck we won't need to do any. Thanks!

----------


## Krool

> Tried that originally, but EditText was always empty (at least in the immediate window in VB6). Could it be that losing the focus from the control (back to VB6) is clearing the EditText?


Yes, as soon the edit looses focus (hWndEdit destroyed = 0) the .EditText returns a NullString.

----------


## vb56390

Hi，Krool:
    is there a simple way to add a Checkbox or DTpicker to the VBFlexGrid just like this

----------


## vb56390

Hi, Krool:
    how about to add some methods like MSHFlexgrid which can Expand or Collapse it's Items 


Attachment 179769
this attachment didn't have the "NotrhWind.mdb" file you can download it from "http://down2.opdown.com:8019/opdown/northwind.mdb.zip"

----------


## softv

> Update related to yesterday's bugfix.
> 
> Included new flags RCPF_FORCETOPROWMASK and RCPF_FORCELEFTCOLMASK which is used in the internal SetRowColParams method.
> 
> 
> ```
> Private Sub SetRowColParams(ByRef RCP As TROWCOLPARAMS)
> [...]
> Select Case PropScrollBars
> ...


Dear Krool,


Thanks a TON, as ever, for your wonderful contributions to the society.


Well, you have written as follows in your above quoted post (Dt. Nov 14th, 2020)
// This way there is a internal way of forcing a scroll, even if there is no scrollbar. (of course the 'Scroll' event will not be fired as no scrollbar exist) //


But then Krool, I did not know how to force the scroll by studying your code. Can you kindly show me an example code snippet please, to force a scroll, even if there there are no visible scrollbars (both vertical and horizontal).


Basically, I wish to allow my users to use the mouse to scroll up and down the VBFlexgrid, fully, even when the 'ScrollBars' property is set to vbSBNone(0) in the 'Properties' sheet. Actually I achieved this by writing suitable code (under Case WM_MOUSEWHEEL) in the WindowProcControl function of the FlexGrid control and it works well too but what you have written seems to suggest a very simple and straightforward method. So, kindly let me know how to effect the same. Thanks in advance.


Prayers and Kind Regards.

----------


## Krool

Update released.

Bugfix in the Rows/Cols/FixedRows/FixedCols property.
The effect is mostly when having the ScrollBars property set to 0 - None.

FixedRows/FixedCols need the RCPF_FORCETOPROWMASK/RCPF_FORCELEFTCOLMASK flag due to the 13-Nov-2020 update.

The other flag RCPF_FORCEREDRAW existed already before and is now applied to those properties to "ensure" redrawing.

----------


## IT_Researcher

Is  VBFlexGrid Control - .Net upgraded version available ? 
(Or is there any other .net version like grid without any events).
We are trying to inherit grid into our class to store data.

----------


## newbie2

Hello 
I would like to know if there a way i can change the Height  the VBFlexGrid Control rows without increasing the font size
thanks

----------


## Krool

> Hello 
> I would like to know if there a way i can change the Height  the VBFlexGrid Control rows without increasing the font size
> thanks


RowHeightMin property.
Or "manually" each row via RowHeight property.

----------


## newbie2

Nice job man thank you

----------


## samer22

Hi krool
Is it  possible to auto adjust the row height depending on the content of the cell?
thank you

----------


## Krool

> Hi krool
> Is it  possible to auto adjust the row height depending on the content of the cell?
> thank you


Yes, use the .AutoSize method.

----------


## samer22

> Yes, use the .AutoSize method.


thank you
would you please show me how to use the .AutoSize  method?


```
VBFlexGrid.AutoSize
```

 does not seem to be supported.

----------


## Krool

> thank you
> would you please show me how to use the .AutoSize  method?
> 
> 
> ```
> VBFlexGrid.AutoSize
> ```
> 
>  does not seem to be supported.


I love it when somebody wants to be spoon-feeded.

I don't know what you exactly need. So below some possible scenarios.

1. Only single row auto-size. In this example row #5


```
VBFlexGrid1.AutoSize 5, , FlexAutoSizeModeRowHeight
```

2. All scrollable rows. (two methods)
either


```
VBFlexGrid1.AutoSize VBFlexGrid1.FixedRows, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight
```

or


```
VBFlexGrid1.AutoSize 0, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight, FlexAutoSizeScopeScrollable
```

3. All rows


```
VBFlexGrid1.AutoSize 0, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight
```

EDIT:
Sometimes a grid is filtered using the RowHidden() function. You can exclude the hidden rows in the auto-sizing as well.
Example:


```
VBFlexGrid1.AutoSize 0, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight, ExcludeHidden:=True
```

----------


## samer22

thank you Krool
Please excuse my ignorance
I tested all methods but unfortunately no success. Perhaps because I'm not using the last version.


```
VBFlexGrid1.AutoSize 0, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight, FlexAutoSizeScopeScrollable
```

This method is throwing Mismatch error.
Besides I'm not using any RowHidden() function.
In fact what I'm asking about is something like this:
Attachment 180329

----------


## Schmidt

@Krool (regarding AutoSize)

It might be worth mentioning, that samer22 is probably using your Grid in bound mode
(via IVBFlexDataSource).

On my system, when I use such a Binding - and then call AutoSize in this way (for Col-Autosizing, after setting the Binding):

FG.AutoSize 0, FG.Cols - 1, FlexAutoSizeModeColWidth, FlexAutoSizeScopeAll

It seems to use the right "internal Measurement-Texts" only for the Header-Row  
(probably because it did buffer these texts internally already, after retrieving them via IVBFlexDataSource_*GetFieldName*).

The "CellTexts below the Header" (corresponding with IVBFlexDataSource_*GetData*) -
 are apparently not requested when it comes to further Text-measurings "down the lines".

On another note (not really related to the IVBFlexDataSource-problems above)...
Is it intentional, that an AutoSize-Call like:

FG.AutoSize 0 'which leaves the second optional Param at -1

currently does have the same effect as: FG.AutoSize 0, 0 

I'm aware that this is probably meant to work this way (to affect only a single column).
What "threw me off" is the "-1" in the optional second param, which usually means "all of them".

so, the behaviour I expected, leaving the second param out, was: FG.AutoSize 0, FG.Cols - 1

Olaf

----------


## Krool

> @Krool (regarding AutoSize)
> 
> It might be worth mentioning, that samer22 is probably using your Grid in bound mode
> (via IVBFlexDataSource).
> 
> On my system, when I use such a Binding - and then call AutoSize in this way (for Col-Autosizing, after setting the Binding):
> 
> FG.AutoSize 0, FG.Cols - 1, FlexAutoSizeModeColWidth, FlexAutoSizeScopeAll
> 
> ...


Thanks for your comments.

It is indeed a bug. The AutoSize should fetch the data via IVBFlexDataSource_*GetData*, if applicable.
I will fix it soon.

Concerning the second optional param.
Well, it is meant to affect only a single row or column if the second parameter is omitted.
Maybe it would be "nicer" to have the second parameter as a Variant and to check with IsMissing().
That way the -1 in the intellisense would not "mislead" somebody.
However, I will keep it unchanged to not break compatibility.

----------


## Krool

Update released.

The AutoSize method now works when using a custom data source. (IVBFlexDataSource)

In addition I allowed the FindItem function when using a custom data source.
So, of course it is the best to perform searches directly in the custom data source.
However, when switching a VBFlexGrid from "normal" to "virtual" (IVBFlexDataSource) then it may be easier to allow the FindItem function.
Anyhow, better allow and support something (even when it makes maybe not 100% sense) then to restrict it.

The only thing which remains restricted now for a custom data source is the sorting functionality.
Of course, it will keep restricted as sorting must be done in the custom data source. It can't be done in the grid.

----------


## samer22

Hello Krool
Thank you very much for the efforts you are doing.
Excuse me I have no experience with the Flexgrid control.
I have downloaded the new version and began testing the autosize codes you provided.


```
VBFlexGrid1.Clear
VBFlexGrid1.Refresh
    With VBFlexGrid1
    .AddItem ""
 .TextMatrix(1, 1) = "test data"
.TextMatrix(1, 2) = "test data"
    
 .AddItem ""
.TextMatrix(2, 1) = "test data test data test data test data  test data"
.TextMatrix(2, 2) = "test data test data test data test data  test data"
.AddItem ""
.TextMatrix(3, 1) = "test data test data test data test"
.TextMatrix(3, 2) = "test data test data test data test"
End With
```

Then I tested all your codes hoping to get this:
Attachment 180344

unfortunately no success.

----------


## Arnoutdv

Where do you call the autosize method?

----------


## samer22

> Where do you call the autosize method?


after the code of populating the VBFlexGrid

----------


## Arnoutdv

Better create a new thread and then show the code you use currently and doesnt work for you

----------


## samer22

> Better create a new thread and then show the code you use currently and doesnt work for you


Have you tested the autosize codes?
Did they work for you?
thank you
This what I have done


```
With VBFlexGrid1
  .AddItem ""
 .TextMatrix(1, 1) = "test data"
.TextMatrix(1, 2) = "test data"  
 .AddItem ""
.TextMatrix(2, 1) = "test data test data test data test data  test data"
.TextMatrix(2, 2) = "test data test data test data test data  test data"
.AddItem ""
.TextMatrix(3, 1) = "test data test data test data test"
.TextMatrix(3, 2) = "test data test data test data test"
.AutoSize 0, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight
'.AutoSize VBFlexGrid1.FixedRows, VBFlexGrid1.Rows - 1, FlexAutoSizeModeRowHeight
End With
```

This is what I get



But this is what I expect



Edit:
I noticed that the codes work when adding carriage return.


```
.TextMatrix(2, 1) = "test data test" & vbNewLine & " data test data" & vbNewLine & " test data  test data"
.TextMatrix(2, 2) = "test data test" & vbNewLine & " data test data" & vbNewLine & " test data  test data"
```

I wonder if it is possible to adjust the height without inserting the carriage return as I'm feeding my grid from database.

----------


## Krool

> What "threw me off" is the "-1" in the optional second param, which usually means "all of them".
> 
> so, the behaviour I expected, leaving the second param out, was: FG.AutoSize 0, FG.Cols - 1


Obviously the vsFlexGrid handles it the same way.




> Col2 is optional. If it is omitted, only Col1 is resized.




```
[form!]VSFlexGrid.AutoSize Col1 As Long, [ Col2 As Long ], [ Equal As Boolean ], [ ExtraSpace As Single ]
```

http://helpcentral.componentone.com/...sizemethod.htm

So, it's all good as it is..

----------


## Krool

Update released.

There will be a next 1.5 OCX of the VBFlexGrid in future. Some features in mind are planned to be added, e.g. FrozenRows/Cols, ListBox style SelectionMode etc...
As first step the MousePointer property is not anymore 'As Integer' with IPerPropertyBrowsing.
It now uses a straight 'FlexMousePointerConstants' enum which will work in a VBA environment. (IPerPropertyBrowsing not supported in VBA)

Also a first new feature the EditContextMenu event is added. The Handled parameter can be set to True to suppress the default text box style dropdown menu. (in order to provide an own menu, e.g. Me.PopupMenu xyz)

----------


## Krool

> I noticed that the codes work when adding carriage return.
> 
> 
> ```
> .TextMatrix(2, 1) = "test data test" & vbNewLine & " data test data" & vbNewLine & " test data  test data"
> .TextMatrix(2, 2) = "test data test" & vbNewLine & " data test data" & vbNewLine & " test data  test data"
> ```
> 
> I wonder if it is possible to adjust the height without inserting the carriage return as I'm feeding my grid from database.


Yes, word wrapping is not "considered" in the grid's TextWidth/TextHeight functions. (Which the AutoSize function uses)

But there are reasons that it is good like that, e.g. to auto size a column wide enough that word wrapping is not needed anymore.

I need to think about additional functionality to solve your problem, which returns then the "ideal text height" incl. word wrapping.

*EDIT*: Bugfix in the TextHeight function. It returned 0 on an empty string. But it must return TMHeight (TEXTMETRIC) in that case.
TextWidth remains unchanged and keeps returning 0 on empty strings.

----------


## jedifuk

> Update released.
> 
> There will be a next 1.5 OCX of the VBFlexGrid in future. Some features in mind are planned to be added, e.g. FrozenRows/Cols, ListBox style SelectionMode etc...
> As first step the MousePointer property is not anymore 'As Integer' with IPerPropertyBrowsing.
> It now uses a straight 'FlexMousePointerConstants' enum which will work in a VBA environment. (IPerPropertyBrowsing not supported in VBA)
> 
> Also a first new feature the EditContextMenu event is added. The Handled parameter can be set to True to suppress the default text box style dropdown menu. (in order to provide an own menu, e.g. Me.PopupMenu xyz)


may i request filterbar in top of column, much like excel style, maybe we can programmatically code on event filterbar

----------


## Krool

> may i request filterbar in top of column, much like excel style, maybe we can programmatically code on event filterbar


If the Frozen rows/cols are implemented such a filter bar could be done "manually". (In conjunction with AllowUserEditing)

----------


## jedifuk

> If the Frozen rows/cols are implemented such a filter bar could be done "manually". (In conjunction with AllowUserEditing)


nice to know about it..let me take a look

----------


## Krool

Major update released.

FrozenRows/FrozenCols property now included. (editable but non-scrollable cells)

I investigated quite a time for that new feature. However, it may be possible that it may have initial bugs as it is in it's infancy.
Please report any mis-behavior. Thanks

Also please advise if any specific related properties directly related to frozen cells are needed/wanted. Currently it shares all "formatting" from the normal (scrollable) cells.

----------


## Krool

> I wonder if it is possible to adjust the height without inserting the carriage return as I'm feeding my grid from database.


You need basically the "label height" as the grid uses for drawing.
I struggle currently how to "expose" this functionality?
Adding a mode enum in the AutoSize method "IdealRowHeight". (Beside the existing "ColWidth" and "RowHeight" modes)
Or?

----------


## Arnoutdv

Hi Krool,

The vsFlexGrid also has an .AutoSize method.
If the .WordWrap property is set to True and you use .AutoSizeMode = flexAutoSizeRowHeight and then call .AutoSize the RowHeights will be adapted to the needed height to fit the cell content.



> Resizes column widths or row heights to fit cell contents.
> 
> Syntax
> 
> [form!]VSFlexGrid.AutoSize Col1 As Long, [ Col2 As Long ], [ Equal As Boolean ], [ ExtraSpace As Single ]
> 
> Remarks
> 
> The parameters for the AutoSize method are described below:
> ...

----------


## Krool

Update released.

AutoSize method works now as expected if WordWrap = True and Mode = FlexAutoSizeModeRowHeight.

AutoSize method works now also as expected if SingleLine = True. (Bugfix in the internal 'GetTextSize' function)

Some additional info
New internal function added 'GetTextHeight' which the AutoSize method now uses for Mode = FlexAutoSizeModeRowHeight.
The internal function 'GetTextSize' (CX and CY) remains unchanged. The AutoSize method for Mode = FlexAutoSizeModeColWidth will still use the CX member of the 'GetTextSize' function. (which is intended to be)
If WordWrap = False the CY member of 'GetTextSize' and the result of 'GetTextHeight' is the same.

@Samer22, your auto sizing should work now as expected.

----------


## Black_Storm

hi,this is my quesion  in *Thread: am looking for convert ansi to windows-1256 or utf-8 to wndows-1256 without digit prb* 

somebody in my thread told about use inkedit for show unicode now my problem is about show that data in grid,i searched for a datagird support unicode and find this thread,inkedit saved my data like as rtf i showed in #24 in my thread
like as  


```
{\rtf1\fbidis\ansi\ansicpg1256\deff0\deflang1065{\fonttbl{\f0\fnil\fcharset178{\*\fname Tahoma;}Tahoma (barnameha.net);}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\ltrpar\qr\f0\rtlch\fs18\'c2\'81\'c7\'d1\'ca\'e3\'c7\'e4 \u1785?\u1782? \'e3\'ca\'d1 \'cf\'d1 \'d4\'d1\u1740?\'da\'ca\u1740?\par
}
```

and will be show in inkedit like as :


```
{"date":"۳ روز پیش"}
```

 but how can show this data in this grid? or any sample to i can save unicode ( utf-8)  data in access database and show it in datagrid?

----------


## Krool

Any ideas which features you miss?
I have only ListBox style SelectionMode on my list. However, maybe the list can get longer. (?)

----------


## Black_Storm

all my description :

i am use adodc1 linked to a simple datagrid and some textboxes with datasource and datafield properties.
so when i clicked on movenext or movefirst or ... on adodc,datagrid can move automatically to move first or next record or ...

i searched for datagrid support unicode and a simple sample to how save and show in grid.
but i can find trial or unsupport unicode or unsupport datasource properties like as datagrid.
i like free userconrrol listview or datagrid to show like as this :

https://10tec.com/activex-grid/extra-samples.aspx  section *RTF text cells*


its igrid but not free and its not user control , this is jst ocx.this is a sample for custom draw.
its show rtf too but its ok if i cant show rtf but its important to i can show in listview or grid and can link to adodc for naviagte automatically with adodc1 move records.

or i checked by  *LynxGrid vb6* and bind controls :

images attached :

Attachment 180537
Attachment 180538
Attachment 180539


but this usr control have problem because LynxGrid can bind controls for when i want edit some cells not like as show normal in rows and have another bug too.


my iedea is about like as igrid can support custom draw and bind controls for normal show or editable show.


if u can send a sample with your list view and jst like this:
-used 1adodc linked to listview and for navigation between records.
-1 textbox linked to adodc datafield for show unicode or enter unicode data
-and a button for add  and save a record .

or for better simple: just send a sample project to how use your listview for show add unicode data in  access database  and show in list view linked to adodc or any your idea


i need just sample project about how save and show unicode data in list view or girds

----------


## Krool

I think an Copy method would be good.
Also a ClipboardCopyMode property in conjunction. (specifies if copying only movable cells or also fixed cells)

Currently I handle it manually, copy to clipboard (via KeyDown, vbKeyC). Also manually copying the fixed header text if vbKeyC + Shift.
This all could be automized by the control itself, reducing then (at least for me) some app specific coding.

Question: Would be a Copy method sufficient or is there also a need to get the "CopyText" so that the app can put it in the clipboard by his own ?

----------


## Schmidt

> I think an Copy method would be good.
> ...
> Question: Would be a Copy method sufficient or is there also a need to get the "CopyText" so that the app can put it in the clipboard by his own ?


I'd say, that's already covered by the existing .Clip-Method(s) (in conjunction with ClipMode and ClipSeparators)...

Maybe check, whether the .Clip-method will work properly also in IVBFlexDataSource-Binding-mode...

IIRC, Clip works on a range, which has to be set explicitely beforehand via:
.Row = ...
 .Col = ...
 .Rows = ...
 .Cols = ...

To make Clip (and other methods which work on a selected Range) more convenient, a Range-Select-method like:
 SelectRange(Row, Col, Optional Byval Rows& = -1, Optional Byval Cols& = -1)
would be nice.

Olaf

----------


## Krool

> I'd say, that's already covered by the existing .Clip-Method(s) (in conjunction with ClipMode and ClipSeparators)...
> 
> Maybe check, whether the .Clip-method will work properly also in IVBFlexDataSource-Binding-mode...
> 
> IIRC, Clip works on a range, which has to be set explicitely beforehand via:
> .Row = ...
>  .Col = ...
>  .Rows = ...
>  .Cols = ...
> ...


Yes. Maybe extending the ClipMode property would be sufficient, e.g. FixedRows/FixedCols ?

----------


## Schmidt

> Yes. Maybe extending the ClipMode property would be sufficient, e.g. FixedRows/FixedCols ?


If you're searching for an easy way, to include the FixedRows/Cols in the Clip,
then why not add this new "clever" SelectRange-method...

Currently (to include the Headers in a "full Clip"), I have to write:


```
  FG.Row = 0
  FG.Col = 0
  FG.RowSel = FG.Rows - 1
  FG.ColSel = FG.Cols - 1
  Debug.Print FG.Clip
```

With the new Method I could write (to include the Headers in a full Clip):


```
  FG.SelectRange 0, 0 'leaving the last two optional Params out, selects "all the rest"
  Debug.Print FG.Clip
```

Or in case I want to exclude the Headers from a full Clip:


```
  FG.SelectRange FG.FixedRows, FG.FixedCols 'leaving the last two optional Params out, selects "all the rest"
  Debug.Print FG.Clip
```

All ensured with minimal fuss (no extra ClipMode-Enum-members needed) via this new SelectRange-Method
(which, as said, will probably come in handy also for "larger formatting-ops", not only for clipping).

Olaf

----------


## Krool

> If you're searching for an easy way, to include the FixedRows/Cols in the Clip,
> then why not add this new "clever" SelectRange-method...
> 
> Currently (to include the Headers in a "full Clip"), I have to write:
> 
> 
> ```
>   FG.Row = 0
>   FG.Col = 0
> ...


The vsFlexGrid's Select method will select only a single cell when the two optional parameter's are omitted. So what now?

Your sample will get clip text "all". But what about getting only the current selection + field captions from a Clip.
Imagine I copy 1 row in the middle of a grid into excel. I want the fixed rows field name plus the 1 selected row.

----------


## Schmidt

> The vsFlexGrid's Select method will select only a single cell when the two optional parameter's are omitted. So what now?


Since you remained compatible to the vsFlex also in the AutoSize-Method already, 
you should probably "keep that compatibility up" consistently (was not aware about the Select-Method on the vsFlex).




> Your sample will get clip text "all". But what about getting only the current selection + field captions from a Clip.
> Imagine I copy 1 row in the middle of a grid into excel. I want the fixed rows field name plus the 1 selected row.


Ah, ... if that's the scenario you planned to use these new Enum-Values for -
then "why not" (I thought only about "consecutive selections without gaps").

An enum would also work easier, when you want to support Ctrl+C directly within the Control.

Olaf

----------


## Black_Storm

> I think an Copy method would be good.
> Also a ClipboardCopyMode property in conjunction. (specifies if copying only movable cells or also fixed cells)
> 
> Currently I handle it manually, copy to clipboard (via KeyDown, vbKeyC). Also manually copying the fixed header text if vbKeyC + Shift.
> This all could be automized by the control itself, reducing then (at least for me) some app specific coding.
> 
> Question: Would be a Copy method sufficient or is there also a need to get the "CopyText" so that the app can put it in the clipboard by his own ?





i said what i need in #460.
its ok for use any way but i need sample project just a access database,adodc and your list view (show utf and save in database).
my language is not english so i cant understand some descriptions.but i am waiting jst for any sample project or any other way for fix this problem like as use others user controls if exist or ....

----------


## Arnoutdv

The codebank is not the place in which you can ask for a complete sample project with such a lot of requirements.
Better create a thread in the normal forum in which you ask if someone can help you with a sample project which uses the vbFlexGrid (it's not a ListView!!!) and UTF8.

----------


## Black_Storm

am still waiting here for a simple sample ...

----------


## Black_Storm

> The codebank is not the place in which you can ask for a complete sample project with such a lot of requirements.
> Better create a thread in the normal forum in which you ask if someone can help you with a sample project which uses the vbFlexGrid (it's not a ListView!!!) and UTF8.


you should be read #458 i asked with that links and its not about just complete samples,i send texts like as any sample code or any simple or any other way and ... that means any sample codes or simple use or like this ..., and yes i can ask about vbFlexGrid and utf-8 or ... but i ask here because its about this grid because its support utf-8.i will be ask if i cant find a way here.

----------


## Schmidt

> you should be read #458 ...


When you ask about (virtual) DataBinding of Krools VbFlexgrid (to Recordsets) - 
that's possible without larger efforts via the IVBFlexDataSource interface.

Not sure, whether somebody already wrote a Binding-example for ADO-Rs - 
but for SQLite-Rs I've posted several already... the most recent one here:
https://www.vbforums.com/showthread....=1#post5514140

As for your "utf-8"-stuff... 
UFT-8 is just "a leaner encoding-variant" (compared to UTF-16, which is directly supported by BStrings/WStrings and the usual *W-APIs of the system).

The VBFlexGrid is Unicode-aware (capable to render the UTF16-content, which is usually contained in VB-Strings) -
 period... as are ADO- or SQLite-Recordsets when they transport String-Data back and forth from/to the underlying DB-Engines...

It is entirely up to you, to "not mess up the String-handling-chain"...
meaning that, when you put an "already wrongly decoded String" into the DB in the first place,
then neither an unicode-aware Recordset, nor an unicode-aware Grid-Rendering can fix that faulty String-content.

And BTW, the MS-ADODC-Control you are using is *not* unicode-aware (it messes up the String-content, even when Unicode-aware ADO-Rs and Unicode-aware TextBox-Controls are connected over it).

I've addressed that with an alternative (Unicode-aware) Binding-mechanism here:
https://www.vbforums.com/showthread....inding-Control

Olaf

----------


## lizano diaz

Hello Krool, excellent grid control, what I would suggest is to add very important functions such as:
1.- That you have the option of sorting in ascending and descending order by clicking on the column header.

2.- A very important one that acquires the windows theme regardless of the version for a better appearance.

3.- The selectionbyrow row that is in the style of windows 7.

4.- add Extendedlastcol to the property. equal to that of the VsFlexgrid8.

Thank you very much for your effort and your work.

----------


## xiaoyao

The cell is set with a picture background, and the words cant be seen clearly. Shadow font or luminous font?
How to set the control to be transparent?
How to set the overall background image of the control

----------


## Krool

> The cell is set with a picture background, and the words cant be seen clearly. Shadow font or luminous font?
> How to set the control to be transparent?
> How to set the overall background image of the control


for CellPictureAlignemnt 9 - Stretch there is no "NoOverlap" variant. Maybe some of these are suitable?


```
FlexPictureAlignmentLeftTopNoOverlap = 20
FlexPictureAlignmentLeftCenterNoOverlap = 21
FlexPictureAlignmentLeftBottomNoOverlap = 22
FlexPictureAlignmentRightTopNoOverlap = 26
FlexPictureAlignmentRightCenterNoOverlap = 27
FlexPictureAlignmentRightBottomNoOverlap = 28
```

The control can't be transparent/overall background image. However, if you want you can subclass WM_ERASEBKGND and draw a fake replica of the underlying image/overall background image.
The control is designed to react properly when an app handles WM_ERASEBKGND.
WM_ERASEBKGND is only for the part that is covered by the "BackColorBkg" portion.

However, if you want an overall background image for the cell contents, there is no possibility yet. (like an watermark in the ListView)
Will keep that in mind..

----------


## Krool

Updated released. (bugfix)

When having two MDI child forms each having a VBFlexGrid, then clicking on the other VBFlexGrid in the other MDI child form will get focused but the MDI child window is not "activated".
I was baffled that it boiled down to the WS_EX_NOPARENTNOTIFY bit set in the window creation. It got now removed.

----------


## xiaoyao

how to use WM_ERASEBKGND?
if i put control in picturebox,backimage is PICTUREBOX -PICTURE

IF PUT ON FORM1,IT'S form1.picture?
if i want to change by code ,how to do?
because i will change form backround img for more times

----------


## xiaoyao

if i use cell back picture,font need two color,like black color,and with White or yellow border, realize the function of shadow font。
textout for two times?

----------


## xiaoyao

> for CellPictureAlignemnt 9 - Stretch there is no "NoOverlap" variant. Maybe some of these are suitable?
> 
> 
> ```
> FlexPictureAlignmentLeftTopNoOverlap = 20
> FlexPictureAlignmentLeftCenterNoOverlap = 21
> FlexPictureAlignmentLeftBottomNoOverlap = 22
> FlexPictureAlignmentRightTopNoOverlap = 26
> FlexPictureAlignmentRightCenterNoOverlap = 27
> ...


Very Nice,Transparent user control by vb6-VBForums
https://www.vbforums.com/showthread....control-by-vb6
Inspired by you, I wrote a module, you can see if you can add it



```
hDC = GetDC(0)
BitMap = CreateCompatibleBitmap(hDC, WinRect1.Right - WinRect1.Left, WinRect1.Bottom - WinRect1.Top)
Call ReleaseDC(0, hDC)
memDC = CreateCompatibleDC(0)
oldBitMap = SelectObject(memDC, BitMap)
Call SendMessage(ParentHwnd, WM_ERASEBKGND, memDC, 0)
Call SendMessage(ParentHwnd, WM_PAINT, memDC, 0)
```

 Case WM_PAINT
if SendMessage(hWnd, WM_ERASEBKGND, hDCBmp, ByVal 0&) = 0 Then
 If VBFlexGridBackColorBkgBrush <> 0 Then FillRect hDCBmp, VBFlexGridClientRect, VBFlexGridBackColorBkgBrush

14000 lines of code, my ability is limited and I cant modify it. Could you please help me to see if there is a place to add a background image, or copy the image of the parent object

----------


## lizano diaz

Hi Kroll, Could you please implement these details in the VBFlexgrid? quoted in this thread:
https://www.vbforums.com/showthread....=1#post5519010

Thank you

----------


## Arnoutdv

> 1.- That you have the option of sorting in ascending and descending order by clicking on the column header.
> 
> 2.- A very important one that acquires the windows theme regardless of the version for a better appearance.
> 
> 3.- The selectionbyrow row that is in the style of windows 7.
> 
> 4.- add Extendedlastcol to the property. equal to that of the VsFlexgrid8.


1. This you can implement yourself using the sort methods and properties and using the MouseUp/MouseDown/Click events provided by the grid.
2 & 3, that's very specific for your use case maybe
4. That would be convenient  :Smilie:

----------


## xiaoyao

> Hello Krool, excellent grid control, what I would suggest is to add very important functions such as:
> 1.- That you have the option of sorting in ascending and descending order by clicking on the column header.
> 
> 2.- A very important one that acquires the windows theme regardless of the version for a better appearance.
> 
> 3.- The selectionbyrow row that is in the style of windows 7.
> 
> 4.- add Extendedlastcol to the property. equal to that of the VsFlexgrid8.
> 
> Thank you very much for your effort and your work.


This theme of some modern latest operating systems, as well as the UI style.Need developers with strong graphic design skills. I also need to know more about all kinds of knowledge. You can also use some other way to achieve, such as picture frame and so on.This is more difficult.

----------


## R.J. Dunnill

Great work, Krool! 

May we ask the licensing terms for this control?

----------


## Krool

> 4.- add Extendedlastcol to the property. equal to that of the VsFlexgrid8.


I'm willing to include that feature, as version 1.5 OCX will emerge anyway someday.
I have not an vsFlexGrid at hand (anymore) so I cannot test it. What makes me wonder in the documentation of VsFlexGrid is following remark.



> This property only affects painting. It does not modify the ColWidth property of the last column.


This would be possible to replicate. However, what is the behavior for example for column re-sizing ? I would be confusion to have something "only painted" but not based upon "facts".
You get it? What shall I do? Thanks




> May we ask the licensing terms for this control?


What do you mean? It's for free.

----------


## Arnoutdv

I think they mean if you add an additional column add the end, then the previous last column gets it's original width.

I use the vsFlexGrid in multiple applications and when simulating lists with it then I always set the .ExtendLastCol property.
I also set the gridlines to none (or the same color as the cell background).
Resizing of columns is still possible, but I never use the .ColWidth property for anything is this scenario.

----------


## Schmidt

> This would be possible to replicate. However, what is the behavior for example for column re-sizing?


In ExtendedLastCol-mode, "Mouse-based"-resizing will not be possible (on the current last Column).

And "Program-code-based"-ColWidth-changes on the current "last-column" will happily accept the new value, 
but without affecting the "visual auto-stretching" (which simply ignores the current ColWidth-value of that last-column).

Only when you add - or better; "allow an additional column" in a given Grid-View to be the "new last-column", 
will the current ColWidth-setting (of the former last-column) be respected in the rendering-output.

Olaf

----------


## Krool

Thanks Olaf for explanation.
One further question: Does it refer to the last visible* column (ColHidden = False and ColWidth > 0) or to the last physical column (no matter what) ?

*technically visible, does not matter if currently "visible" in current viewport.

----------


## Arnoutdv

Do you want me to test somethings using the vsFlexGrid8?

----------


## Krool

> Do you want me to test somethings using the vsFlexGrid8?


Thanks. What is .MouseCol reporting when you are in the "painted only" area?

----------


## jpbro

It returns the last column index. For example, in a 3 column grid with ExtendLastCol=True, .MouseCol will return 2 when the mouse moves over the extended area.

Note: Focus rectangle also draws the full painted/extended width of the column even though .ColWidth returns a lesser width:

----------


## lizano diaz

Thanks Krool for reading the comment, regarding VsFlexgrid 8 here, its properties: http://helpcentral.componentone.com/...andmethods.htm
It would be very interesting for our VbFlexgrid control to implement as the ExtendLastCol. and another also that takes the Windows theme regardless of the version of it to be able to give greater and elegance to the control.
Attachment 181317

----------


## xiaoyao

If each cell can set a different font. And you can set the font shadow.You can set a transparent background image for a cell.

Set up a background image to the entire form or screenshots behind the controls as a background. (The principle is equivalent to hiding the control there in the control above the control over the control.)This makes a perfect transparency effect. It's like the IOS cell phone.We can understand that he is a form.
Microsoft's operating system desktop, he is also a table.Each cell contains a picture plus text.

----------


## xiaoyao

Attachment 181319
Can EXCEL set up a background picture? Simulate an apple phone desktop with a table.
A background picture wallpaper, add a lot of icons and names for applications.
Just like the resource manager folder, you first have a background image, and the thumbnail plus text is displayed in each file.

----------


## xiaoyao

????
Or set a semi-translucent shadow of a pure color, and the transparency can be adjusted.
Because there is a cell background picture, the text may not be clear above, so you need to set the shadow to the text, just like the subtitles of the movie.
For example, a background image whose main color is black, if the text above is black, you need to add a white font border.

i have not tested your control carefully.If it can be set above a few rows, the left few columns are fixed.For example, you can add a sequence number to the left. Also add a row of additional data at the top. Like ABCD.And the table inside Binding data recordset ado.This is like an excel control.Directly modify the cell automatically updated to the database inside.

----------


## xiaoyao

> Patience is a virtue and I like to think I'm virtuous so I'll wait... Thanks.


My patience is not enough. It is often desirable for the inventor of the control to add more functionalityNext, I hope to contribute some source code to add to it.

Control is the accumulation of human knowledge wealth.Many times, only the author can add those features.Just like VB6 has stopped updating for many years.Even if you get the source code, not everyone can directly improve it.So in the author is very interested, have time to do control upgrade, we have to work together as much as possible to complete this work.

----------


## DaveDavis

This post by lizano diaz (ID: 5520898) gives the authorization code directly, which violates the authors intellectual property rights. Admin, Please delete it asap.

----------


## lizano diaz

Hi, so how could I implement the selectionmode: FlexSelectionmodefreebyRow property of the VbFlexgrid in an MshFlexgrid of Vb 6.0 more specifically how I can move the focus between columns but at the same time be selected the row.

Thanks

Attachment 181320

----------


## MountainMan

> My patience is not enough. It is often desirable for the inventor of the control to add more functionalityNext, I hope to contribute some source code to add to it.
> 
> Control is the accumulation of human knowledge wealth.Many times, only the author can add those features.Just like VB6 has stopped updating for many years.Even if you get the source code, not everyone can directly improve it.So in the author is very interested, have time to do control upgrade, we have to work together as much as possible to complete this work.


xiaoyao, I understand that English is not your first language but I have to say I am disturbed by your approach here and some other threads. It is not clear to me that your goal is to help all of us make a better and more useful product or whether it is to attempt to get some members here to switch to VBF. There is another set of threads in this forum to post comments about other flavors of VB but you seem intent to make your pitch for VBF throughout the VB6 threads.

Let's assume for a minute that you really want a better VB6 product. You seem to be demanding in an aggressive way that Krool address your imorivement suggestions. In this thread and the VBCCR thread we have a programmer (Krool) who has spent countless hours of his own free time over the past 10 years to make these controls. He doesn't have to do this. He doesn't get paid for his efforts. You are out of line by demanding improvements. We all should be incredibly grateful for his efforts that we benefit from. If we get anything more than what he has done to date then that is even better. There are many authors on this site that give freely of their time whether it is providing guidance or providing usable code we can all use. I am not a moderator but I think you are getting very close to being banned.

If you want improvements from an author it is up to you to sell your vision to the author so he/she can decide to spend the extra time to address what you want. Alternatively you can write the code yourself.

Be thankful for what we get from this site. It is truly a gift and you would benefit from a bit of patience...

----------


## xiaoyao

You didn't see my effort.I'm just suggesting. Add the function of transparency.After I came up with the idea. It took me a few days to realize this function.Then send the source code up, equivalent to several people to complete this function。
I also spent half a day to try to add my code into the results can not be done completely, because this more than 14, 000 lines of code, I simply do not understand.

A lot of people are simply making random statements without any testing.
I've made some things very clear.It is not easy for the author to develop such a great control.Others want to modify many situations, 99% of people can not do it.


So what we can do is to actively contribute our own code while the author is still updating it frequently. Minimize his stress. It's equivalent to everyone developing this thing together.

I'm just proposing a generic module where each control can have a transparent background.
If every writer came to study it, maybe a minute could be added.I hope that eventually my module will allow these authors to configure it in ten seconds.
Just like VB.NET, it can choose the background color of the control or be directly transparent.


There are about twenty pages of replies to this topic. I showed him half awake and half asleep in the morning.
I also developed a lot of small controls. Also like to do a lot of control encapsulation. So I'm reading every page of your comments carefully.

----------


## xiaoyao

It is too much to say that I force the author to add functions?
I just wish I could be a Contributor. I've already written some code, and I don't know how to incorporate it.

If you want this control to be more powerful, it's best to track it all the way back to the first version. If can see every word, oneself also add code, such was best.
But many people's level is completely out of reach. The simplest original version can not be modified. Personal programming level, experience varies too much.

----------


## R.J. Dunnill

> What do you mean? It's for free.


My company is interested in using the VBFlexGrid to overcome issues with the MSFlexGrid which the posting in GitHub at https://github.com/Kr00l/VBFLXGRD seems to have addressed. We do not find or see any mention of a copyright or Open-Source License agreement at either the GitHub site or in the code files at the GitHub site. As a software company we recognize the rights of authors, even those that have posted without copyright or Open-Source licenses, and therefore would like to request express permission from you, the author, to use and distribute this VBFlexGrid to address the issues posed by the MSFlexGrid. Please let us know that we have your express permission.

----------


## Krool

> My company is interested in using the VBFlexGrid to overcome issues with the MSFlexGrid which the posting in GitHub at https://github.com/Kr00l/VBFLXGRD seems to have addressed. We do not find or see any mention of a copyright or Open-Source License agreement at either the GitHub site or in the code files at the GitHub site. As a software company we recognize the rights of authors, even those that have posted without copyright or Open-Source licenses, and therefore would like to request express permission from you, the author, to use and distribute this VBFlexGrid to address the issues posed by the MSFlexGrid. Please let us know that we have your express permission.


Permission granted.

----------


## R.J. Dunnill

> Permission granted.


Thank you so much!

----------


## R.J. Dunnill

> Permission granted.


With your permission, I will fork the GitHub project to a VBFLXGRD.NET open-source project (which we would be pleased to develop in parallel with the VBFLXGRD).

----------


## xiaoyao

> With your permission, I will fork the GitHub project to a VBFLXGRD.NET open-source project (which we would be pleased to develop in parallel with the VBFLXGRD).


WHICH URL ABOUT VBFLXGRD.NET?
What is the difference between it and our control?

----------


## R.J. Dunnill

> I'm willing to include that feature, as version 1.5 OCX will emerge anyway someday.
> I have not an vsFlexGrid at hand (anymore) so I cannot test it. What makes me wonder in the documentation of VsFlexGrid is following remark.
> 
> This would be possible to replicate. However, what is the behavior for example for column re-sizing ? I would be confusion to have something "only painted" but not based upon "facts".
> You get it? What shall I do? Thanks
> 
> 
> 
> What do you mean? It's for free.





> WHICH URL ABOUT VBFLXGRD.NET?
> What is the difference between it and our control?


It will be migrated to VB.NET and WinForms, and be 64-bit compatible. (VB6 ActiveX UI controls don't work with 64-bit processes.)

----------


## Krool

> It will be migrated to VB.NET and WinForms, and be 64-bit compatible. (VB6 ActiveX UI controls don't work with 64-bit processes.)


I recommend to base on the "Standard EXE" version as this is the leading source.
From time to time it derives to the ActiveX control version when enough new features were bundled.
For example. The "standard exe" version now allows frozen rows/cols. This is not in place yet for the ActiveX version 1.4 as it will derive when version 1.5 is put in place.

----------


## R.J. Dunnill

> I recommend to base on the "Standard EXE" version as this is the leading source.
> From time to time it derives to the ActiveX control version when enough new features were bundled.
> For example. The "standard exe" version now allows frozen rows/cols. This is not in place yet for the ActiveX version 1.4 as it will derive when version 1.5 is put in place.


Thank you!

----------


## R.J. Dunnill

Hi, Krool:

I submitted a request to company Legal to use the migrated VBFlexGrid in our product, and they pushed back with this:




> Thank you for granting permission to use the VBFlexGrid . Weve consulted our Legal department and per their response on usage and advice, Copyright is an automatic right and therefore you, the author of this code, hold the copyright for it. Unless you, the author, take the action to publish the code under an open-source license, such as MIT or Apache 2.0, the code cannot be classified as open-source licensed. We could still use the code in the situation that it is not licensed under an open-source license (MIT or Apache 2.0), but *we would need you, the copyright holder, to provide us some terms of use above permission granted*. 
> 
> We believe the easiest way to overcome this licensing issue presented by our Legal department is if your intention is for third parties to freely use the code, then *adding a LICENSE field/file in the GitHub repository indicating that usage is allowed under a permissive open-source license such as MIT, Apache 2.0., etc. would resolve the issue*. We also have open-source software that we offer, and we use the MIT license.


Would this be a problem? (For convenience, please find attached a blank MIT license.) license.txt

----------


## xiaoyao

> Thanks Krool for reading the comment, regarding VsFlexgrid 8 here, its properties: http://helpcentral.componentone.com/...andmethods.htm
> It would be very interesting for our VbFlexgrid control to implement as the ExtendLastCol. and another also that takes the Windows theme regardless of the version of it to be able to give greater and elegance to the control.
> Attachment 181317Attachment 181425


which is bbs page?it's look nice

----------


## Krool

> Would this be a problem? (For convenience, please find attached a blank MIT license.)


I added now for both VBCCR and VBFLXGRD a MIT license.md file in the GitHub repo.

----------


## R.J. Dunnill

> I added now for both VBCCR and VBFLXGRD a MIT license.md file in the GitHub repo.


Thanks again!

----------


## R.J. Dunnill

Posted deleted.

----------


## softv

> Dear Krool,
> 
> 
> Thanks a TON, as ever, for your wonderful contributions to the society.
> 
> 
> Well, you have written as follows in your above quoted post (Dt. Nov 14th, 2020)
> // This way there is a internal way of forcing a scroll, even if there is no scrollbar. (of course the 'Scroll' event will not be fired as no scrollbar exist) //
> 
> ...


Dear Krool,

I am very much awaiting your reply for my above question (posted in Jan 2021). In case you have answered and I have missed it, I am really very sorry. Kindly bear with me. Please let me know the link to your answer. 

*My question in a nutshell* is: 
How to scroll the VBFlexGrid with mouse, even when the 'ScrollBars' property is set to vbSBNone(0)? 

In case a simple and straightforward method does not exist and writing suitable code (under Case WM_MOUSEWHEEL) in the WindowProcControl function of the FlexGrid control is the only way to go, kindly confirm the same.

I very much understand how difficult it is to develop such intricate controls and also answer members'/users' queries. That's why I am writing to you again only after 4 months.

Thanks a TON ever ever ever, for your stupendous free controls, Krool. I simply adore your selfless nature.

Kind Regards.

----------


## xiaoyao

I tested a virtual table Listview yesterday. It has a scroll bar, in fact it does not load any data. When the scroll bar scrolls, it automatically reads an array or dynamically assigns data.


I don't know if this control has this method?
For example, specify an array of one million rows. In fact, only the data of the first page is displayed. If scrolling to the 80th page, it only shows the data on that page.

----------


## Krool

> How to scroll the VBFlexGrid with mouse, even when the 'ScrollBars' property is set to vbSBNone(0)?


Not possible. Even if you handle something by code or subclass. The LeftCol/TopRow are locked when vbSBNone is set.




> I don't know if this control has this method?
> For example, specify an array of one million rows. In fact, only the data of the first page is displayed. If scrolling to the 80th page, it only shows the data on that page.


The VBFlexGrid supports virtual data source via it's .FlexDataSource property. (IVBFlexDataSource must be implemented in the source)

----------


## xiaoyao

Is there a simple test project?
about**:The VBFlexGrid supports virtual data source via it's .FlexDataSource property. (IVBFlexDataSource must be implemented in the source)

If a two-dimensional array has 300,000 rows of data, 20 columns。
If we modify the length of this array in the middle, it will become 400000 rows of data.
Suppose the first row of the control is already the last row of the last 300, 000 data.After the data capacity is increased, if flex control displays 40 pieces, it will display another 39 pieces of data.Then the maximum value of the scroll bar is increased by another one hundred thousand.

----------


## Krool

> Is there a simple test project?
> about**:The VBFlexGrid supports virtual data source via it's .FlexDataSource property. (IVBFlexDataSource must be implemented in the source)
> 
> If a two-dimensional array has 300,000 rows of data, 20 columns。
> If we modify the length of this array in the middle, it will become 400000 rows of data.
> Suppose the first row of the control is already the last row of the last 300, 000 data.After the data capacity is increased, if flex control displays 40 pieces, it will display another 39 pieces of data.Then the maximum value of the scroll bar is increased by another one hundred thousand.


There is a good demo already -> VB6 VBFlexGrid (virtual DataBinding to SQLite-Recordsets)

----------


## SearchingDataOnly

> Not possible. Even if you handle something by code or subclass. The LeftCol/TopRow are locked when vbSBNone is set.


IMO, LeftCol and TopRow should not be locked  when Scrollbars = ScrollBarsNone.

----------


## xiaoyao

> There is a good demo already -> VB6 VBFlexGrid (virtual DataBinding to SQLite-Recordsets)


it's bind to rc6.record,how to bind vb6 adodb.recordset?
how to bind vb6 array?
like
dim Arr()
redim arr(rows-1,cols-1)
bind to array

The design is very good, and there are many common interfaces. They should all be implemented. It is a matter of time.

----------


## Mustaphi

Hi Krool
I was using the VbFlexgrid 1.3 ocx and I wasable to use the datasource property without issue


```
Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
```

Now I'm using the VbFlexgrid 1.4 ocx, I get error type mismath.
thank you

----------


## Krool

> Hi Krool
> I was using the VbFlexgrid 1.3 ocx and I wasable to use the datasource property without issue
> 
> 
> ```
> Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
> ```
> 
> Now I'm using the VbFlexgrid 1.4 ocx, I get error type mismath.
> thank you


Is the 1.3 de-referenced in your project?

----------


## Mustaphi

> Is the 1.3 de-referenced in your project?


Yes
Now I removed reference and it works
thanks a lot
Please Krool could you please help me in this issue?
I need to use the first column of my VbFlexgrid as autoincrement Is this possible  and then sort the items on that column?


```
Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
 For i = VBFlexGrid1.FixedRows To VBFlexGrid1.Rows - 1
 VBFlexGrid1.TextMatrix(i, 0) = i
Next i
i = i + 1
```

Many thanks

----------


## Schmidt

> I need to use the first column of my VbFlexgrid as autoincrement Is this possible  and then sort the items on that column?
> 
> 
> ```
> Set VBFlexGrid1.FlexDataSource = DataSource.BindTo(Rs)
>  For i = VBFlexGrid1.FixedRows To VBFlexGrid1.Rows - 1
>  VBFlexGrid1.TextMatrix(i, 0) = i
> Next i
> i = i + 1
> ```


When you use a bound (SQLite-)cRecordset in your DataSource,
then the Sorting will have to be done on the Recordset itself (followed by a vbFlexGrid.Refresh).

Here is a thread with an example (in post #6) - how you can do that (using a slightly enhanced Binding-Class):
https://www.vbforums.com/showthread....=1#post5514140

And of course there's also the option, to already start-out with an Rs (in your Binding-call), 
which comes (pre-)sorted by the initial SQL-query ... (via a normal Order By Clause).

Olaf

----------


## Mustaphi

Olaf
The sample you submitted is fabulous.
I tested it and it is really marvellous work.
However in my case here I need to add a new auto increment column based on the number of items in the flexgrid.
I wonder if this is possible when using the bound method.
thanks

----------


## Schmidt

> However in my case here I need to add a new auto increment column based on the number of items in the flexgrid.


The Binding-method can only reflect, what priorily exists as Field-data in your Rs.

So, if you don't have interest in the "real (Auto)ID-Column" of your Table (because it might contain "gaps"),
but need a simple, increasing "Row-Number" instead, then you have to ensure such an Output in your Rs beforehand -
directly via SQL, e.g. instead of: 
"Select * From YourTable Order By SomeField"
You can enhance the Result by a leading Extra-Field, named RowNr like this:
"Select ROW_NUMBER() Over(Order By SomeField) As RowNr, * From YourTable"

Note, how in the above - the Order By definition was moved from the end - 
into the Over(...) part of the Row_Number Window-Function.

Olaf

----------


## Mustaphi

```
"Select ROW_NUMBER() Over(Order By SomeField) As RowNr, * From YourTable"
```

It did the job
Million thanks

----------


## lizano diaz

Hello, Krool here is listed some issues, which still need to be corrected, especially the windows issue. Also missing would be the ExtendLastCol, and the FocusRect, if an expert could still implement that part. 
It is also necessary to order alphabetically when clicking on the header.

Thank you

----------


## Krool

> Hello, Krool here is listed some issues, which still need to be corrected, especially the windows issue. Also missing would be the ExtendLastCol, and the FocusRect, if an expert could still implement that part. 
> It is also necessary to order alphabetically when clicking on the header.
> 
> Thank you


the zip file is invalid.

----------


## jpbro

> the zip file is invalid.


Opened OK for me?

----------


## lizano diaz

Use please last program WinRAR

----------


## lizano diaz

> the zip file is invalid.


Corrected some errors, it is missing to take the theme of the operating system and highlight the colors when hovering the mouse over the header, it would also lack the alphabetical ordering either descending or ascending when clicking on the header, and improve the data loading speed in the grid.
Likewise, it is necessary to implement the focusrect and ExtendLastCol

to open the tablet use the latest version of winrar.

----------


## wqweto

@lizano diaz: You can use https://github.com/Kr00l/VBFLXGRD to fork repo and submit PRs so your changes can be conveniently discussed and approved there.

Submitting changes in a zip file to a discussion forum is generraly a PITA and will probably discourage maintainer (@Krool) from chasing diffs or any new implementations you introduced.

IMO now your effort is close to wasted unless maintainer is super motivated to deal with any changes in the form they are submitted now.

cheers,
</wqw>

----------


## Krool

I have a question..

Currently the BackColorAlt property applies right after the fixed rows.
However, with the introduction of the frozen rows/cols it can cause side-effects when scrolling and having frozen rows.

Left side (1) is the current situation and right side (2) would be a tweak to have the BackColorAlt only applying right after the fixed + frozen rows.



_(in the above image, there are 2 frozen rows and the cell between 2 and 4 is scrolled out)_

What you think ?

----------


## lizano diaz

> I have a question..
> 
> Currently the BackColorAlt property applies right after the fixed rows.
> However, with the introduction of the frozen rows/cols it can cause side-effects when scrolling and having frozen rows.
> 
> Left side (1) is the current situation and right side (2) would be a tweak to have the BackColorAlt only applying right after the fixed + frozen rows.
> 
> 
> 
> ...




Hi, it seems correct to me


I was trying to do the ExtendLastCol, but I can't, also I would have wanted to add properties such as percentages in the cells, a drop-down grid similar to the VsFlexgrid winforms ... what do you think my friend Krool

----------


## Krool

> Hi, it seems correct to mel


Which one? 1 or 2?

----------


## lizano diaz

The one

----------


## lizano diaz

Friend Krool for when would you be launching another version of the Grid, with various improvements?

----------


## lizano diaz

> Which one? 1 or 2?


...  1

----------


## 7edm

As I understand it, the alternate back color in grids/tables is there to make it easier to read row by row, thus it should apply to every odd or even row that is displayed, so neither 1 or 2 is correct/optimal in my view.

----------


## lizano diaz

> Which one? 1 or 2?


Attachment 181867

Hi, colleagues, the header themes have already been fixed, the extendlastcol is missing, and other properties such as chart in cells (percentages), icons, tree, and display grid for details, please colleagues help us with those. Krool colleague would appreciate any comments or additions for the control. 
Thank you

----------


## Arnoutdv

The source is available.
Why demand all this functionality? Just stay with vsFlexgrid if that control has all needed functionality

----------


## Mith

Im looking for Tree Grid control with unicode support. (Tree Grid = Tree nodes that can be expanded/collapsed in the first column)

Is this possible with the VBFlexGrid Control ?

----------


## R.J. Dunnill

> I added now for both VBCCR and VBFLXGRD a MIT license.md file in the GitHub repo.


I have the VBFLXGRD working in 64-bit WinForms, but there are still issues so I haven't check the code in to GitHub. 

The WinForms version is intended to be compatible with the MSFLXGRD, and to that end implements the IMSFlexGrid and DMSFlexGridEvents interfaces.

----------


## lizano diaz

Dear Krool, I wanted to ask you a great favor, the following, it would be possible to implement the ExtendLastCol of the VBFlexgrid, also taking into account if in case the last column is hidden (which would normally be the one with the ExtendLastCol) it will pass the ExtendLastCol to the penultimate column. Example we have 5 Columns if by one case it happens to hide column 5, then the ExtendLastCol would occupy column 4, and if I show column 5, column 5, it would become the one with the ExtendLastCol.

I greatly appreciate the sacrifice of your person for the good of the forum. I say goodbye to you awaiting your prompt response.

----------


## sstairs82

Has anyone had success getting this control to work with Access 2007 or higher? If so - how?

I've been able to get it to work in a VB6 app or an Access 2003, but upon trying to use it in Access 2007 by creating a new form and adding the control to the form, it immediately crashes the application. 
I've also tried creating the form in Access 2003 and opening in Access 2007 - but it still crashes when I try to open the form.

----------


## Krool

> Has anyone had success getting this control to work with Access 2007 or higher? If so - how?
> 
> I've been able to get it to work in a VB6 app or an Access 2003, but upon trying to use it in Access 2007 by creating a new form and adding the control to the form, it immediately crashes the application. 
> I've also tried creating the form in Access 2003 and opening in Access 2007 - but it still crashes when I try to open the form.


Do you have 2003 and 2007 in parallel in 1 system? Maybe some temp files by office are disturbing each other.

----------


## xiaoyao

What Datagrid control supports DAO objects?-VBForums

https://www.vbforums.com/showthread....ts-DAO-objects

VBFlexGrid Control ,dose it support dao 3.6?

----------


## sstairs82

> Do you have 2003 and 2007 in parallel in 1 system? Maybe some temp files by office are disturbing each other.


I only had VB6 and Access 2007 installed when trying to use the control in Access 2007.

I tried it in Access 2007 first by registering the OCX, then creating a new mdb file and a new form.
As soon as I try to drop the VBFlexGrid control onto the form, Access crashes.

I then created a new VB6 EXE and added the control.  It worked.

I thought maybe I could add it in Access 2003 - so I installed Access 2003 alongside of Access 2007.
I created a new mdb and a new form and then added the control.  It was successful.

Since this worked - I thought maybe I could open the MDB in Access 2007 - so I tried that - and the file opens, but upon opening the form, it crashes.

Event Viewer has this logged each time it crashes:

Faulting application name: MSACCESS.EXE, version: 12.0.6735.5000, time stamp: 0x561e089f
Faulting module name: ntdll.dll, version: 10.0.19041.1110, time stamp: 0x8a32a22a
Exception code: 0xc0000374
Fault offset: 0x000e6c23
Faulting process id: 0x2974
Faulting application start time: 0x01d792e9d2914d82
Faulting application path: C:\Program Files (x86)\Microsoft Office\Office12\MSACCESS.EXE
Faulting module path: C:\WINDOWS\SYSTEM32\ntdll.dll
Report Id: 7bfb5f4e-a6c5-4c5c-ac72-db2a584a693a
Faulting package full name: 
Faulting package-relative application ID:

----------


## Krool

I tested office 2002 (XP), 2010, 2016, 2019 and they worked.
You confirmed it works on 2003. So I have no possibility to test 2007.
Last try is to delete some temp files for VBFLXGRD in



```
C:\Users\<username>\AppData\Local\Temp\VBE\
```



```
C:\Users\<username>\Application Data\Microsoft\Forms\
```

----------


## sstairs82

> I tested office 2002 (XP), 2010, 2016, 2019 and they worked.
> You confirmed it works on 2003. So I have no possibility to test 2007.
> Last try is to delete some temp files for VBFLXGRD in
> 
> 
> 
> ```
> C:\Users\<username>\AppData\Local\Temp\VBE\
> ```
> ...


I will try what you suggest - but if you have gotten it to work on Access 2010 - I will try it on another machine that has 2010 and see if it works for me.  I will let you know.

----------


## sstairs82

> I will try what you suggest - but if you have gotten it to work on Access 2010 - I will try it on another machine that has 2010 and see if it works for me.  I will let you know.


I tried it with 2010 and it still crashes for me (with the same exception).  I'm wondering if my environment is not setup correctly...

Is this control designed as 32-bit, or 64-bit?
When you were successful in having it work, were you testing with 32-bit or 64-bit versions of Office?
Were there any specific steps you took when using this control?
I copied the OCX to my Windows\SYSWOW64 folder and registered it using RegSvr32, then tried to add it to a new form as an ActiveX control - Am I missing a step or doing something wrong?

All of my Office installations are 32-bit running on a 64-bit machine, so I'm wondering if I might be missing something or not have something setup correctly?

----------


## Krool

Update released.

Bugfix for BottomRow/RightCol property related to FrozenRows/FrozenCols.

Also bugfix in the internal GetHitTestInfo function.
An adjustment was missing between the leftmost/topmost column/row and the non-scrollable columns/rows.
This affecty only for hit tests of divider column left and row top. (divider column right and row bottom not affected)

----------


## Krool

> I tried it with 2010 and it still crashes for me (with the same exception).  I'm wondering if my environment is not setup correctly...
> 
> Is this control designed as 32-bit, or 64-bit?
> When you were successful in having it work, were you testing with 32-bit or 64-bit versions of Office?
> Were there any specific steps you took when using this control?
> I copied the OCX to my Windows\SYSWOW64 folder and registered it using RegSvr32, then tried to add it to a new form as an ActiveX control - Am I missing a step or doing something wrong?
> 
> All of my Office installations are 32-bit running on a 64-bit machine, so I'm wondering if I might be missing something or not have something setup correctly?


Yes, only office 32 bit works.

Most office installs are 64-bit, but I found one which is 32-bit Excel 2016.
And it works... (just tested)

I never tried MS Access though. Maybe there is something.. Can you test if on your side Excel is working? To have a common starting point and ensure no other issues.



*EDIT*: Tested on MS Access 2016 and it crashes. (clicking the "add ActiveX control")
Don't know what's going on..

----------


## sstairs82

> Yes, only office 32 bit works.
> 
> Most office installs are 64-bit, but I found one which is 32-bit Excel 2016.
> And it works... (just tested)
> 
> I never tried MS Access though. Maybe there is something.. Can you test if on your side Excel is working? To have a common starting point and ensure no other issues.
> 
> 
> 
> ...


I appreciate the quick responses! I tested in Excel and it works for me in the later versions as well. However, I'd really like to use the control in Access 2010 or higher (we have a program that was developed for Access 2010 that wouldn't work well with an Excel User Form).  Let me know if you find anything out.

----------


## R.J. Dunnill

> Yes, only office 32 bit works.
> 
> Most office installs are 64-bit, but I found one which is 32-bit Excel 2016.
> And it works... (just tested)
> 
> I never tried MS Access though. Maybe there is something.. Can you test if on your side Excel is working? To have a common starting point and ensure no other issues.
> 
> 
> 
> ...


The VBFlexGrid.NET project was launched with Office 64-bit specifically in mind. We have now migrated a 22-year-old Excel-based application to managed code, and need a replacement for the MSFLXGRD. So far, so good: the VBFlexGrid.NET is working embedded in an ATL dialog in glorious x64. 



Currently, only a subset of the VBFLXGRD functionality is fully migrated. When I have all the key functionality working, I'll upload it to the GitHub project.

----------


## Krool

> The VBFlexGrid.NET project was launched with Office 64-bit specifically in mind. We have now migrated a 22-year-old Excel-based application to managed code, and need a replacement for the MSFLXGRD. So far, so good: the VBFlexGrid.NET is working embedded in an ATL dialog in glorious x64. 
> 
> 
> 
> Currently, only a subset of the VBFLXGRD functionality is fully migrated. When I have all the key functionality working, I'll upload it to the GitHub project.


Yes great. Thanks

You migrate 1.4 OCX version?
Do you include bugfixes? Like yesterday fixes.
When 1.5 OCX version comes out you migrate also?

----------


## Krool

Here is an experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.
I don't have a VSFlexGrid to test out all the details so I made this now according to my gut feeling.

So please everyone interested in the ExtendLastCol. Please make extensive testings and report any misbehavior etc.
Thanks

Edit: Attachment removed to save space.

----------


## R.J. Dunnill

> Yes great. Thanks
> 
> You migrate 1.4 OCX version?
> Do you include bugfixes? Like yesterday fixes.
> When 1.5 OCX version comes out you migrate also?


Edit: I am trying to migrate both versions. I haven't added the bug fixes (but I will). I have a bunch of bugs from the migration I need to deal with, too. 

I will migrate to the 1.5 versions when they are available.

And currently, the VBFlexGrid.NET is (almost) drop-in compatible with the MSFLXGRD. It embeds the MSFLXGRD type library and implements the IMSFlexGrid and DMSFlexGridEvents interfaces, although, unless the VBFlexGrid.NET type library is custom-edited and registered, the enumeration values are mis-named. (That's a shortfall of a COM-callable wrapper.)

----------


## lizano diaz

> Here is an experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.
> I don't have a VSFlexGrid to test out all the details so I made this now according to my gut feeling.
> 
> So please everyone interested in the ExtendLastCol. Please make extensive testings and report any misbehavior etc.
> Thanks
> 
> Edit: Attachment removed to save space.


Dear Krool, glad to hear from you.
Regarding the tests on the ExtendLastCol, it turns out:
1. At design time I set the ExtendLastcol property to the vbFlexgrid true, I execute it and I maximize it to the form and there is the first "error" as in the picture. A double line of the last visible column is created, and if you resize it, several lines appear.
Taking advantage of the message my friend Krool how can I solve this problem that I have, of the Zip attachment. what I am looking for is to order in ascending and descending order of any column but for a strange reason it does not allow me. Attachment 182139


to which I mean the order of the example is in the form = "UserEditingForm"Attachment 182139

----------


## lizano diaz

> Dear Krool, glad to hear from you.
> Regarding the tests on the ExtendLastCol, it turns out:
> 1. At design time I set the ExtendLastcol property to the vbFlexgrid true, I execute it and I maximize it to the form and there is the first "error" as in the picture. A double line of the last visible column is created, and if you resize it, several lines appear.
> Taking advantage of the message my friend Krool how can I solve this problem that I have, of the Zip attachment. what I am looking for is to order in ascending and descending order of any column but for a strange reason it does not allow me. Attachment 182139
> 
> 
> to which I mean the order of the example is in the form = "UserEditingForm"Attachment 182139


Attachment 182142

----------


## Krool

Here is an updated (v2) experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.

Please everyone interested in the ExtendLastCol. Please make extensive testings and report any bugs/misbehavior etc.
The behavior is most important as this was done according to my gut feeling. I don't have a vsFlexGrid to compare the behavior.
Thanks

Edit: Removed attachment to save space.

----------


## lizano diaz

> Here is an updated (v2) experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.
> 
> Please everyone interested in the ExtendLastCol. Please make extensive testings and report any bugs/misbehavior etc.
> The behavior is most important as this was done according to my gut feeling. I don't have a vsFlexGrid to compare the behavior.
> Thanks


Dear Krool thank you very much for the update, the Extend LastCol seems to work fine. There is a small detail you can see in the attached picture. Apart from this, I wanted to take advantage of asking, how would it be done to sort (ascending, descending) when clicking on the header of the grid, regardless of whether the data in the columns are of type date, string, etc. Thank you very much for your answers.Attachment 182148

----------


## Krool

> Dear Krool thank you very much for the update, the Extend LastCol seems to work fine. There is a small detail you can see in the attached picture. Apart from this, I wanted to take advantage of asking, how would it be done to sort (ascending, descending) when clicking on the header of the grid, regardless of whether the data in the columns are of type date, string, etc. Thank you very much for your answers.Attachment 182148


I can't replicate your picture issue and with rows set to 300.

Concerning your sorting. Below is a code example showing how it can be done. Please note to fill in .ColData() on all columns on your data population with the VarType values. (e.g. vbString, vbDate)


```
Private LastColSort As Long

Private Sub Form_Load()
LastColSort = -1
End Sub

Private Sub VBFlexGrid1_BeforeMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single, Cancel As Boolean)
With VBFlexGrid1
.HitTest X, Y
If .HitResult = FlexHitResultCell And .HitRow < .FixedRows And .HitCol > .FixedCols - 1 Then
    If (Button And vbLeftButton) = vbLeftButton Then
        .Sort = FlexSortNone
        If LastColSort > -1 And LastColSort <> .HitCol Then .ColSort(LastColSort) = FlexSortNone
        LastColSort = .HitCol
        Call FlexSetColSort(VBFlexGrid1, LastColSort, True)
        .Cell(FlexCellSort, .FixedRows, LastColSort, .Rows - 1, LastColSort) = FlexSortUseColSort
        Cancel = True
    End If
End If
End With
End Sub

Public Sub FlexSetColSort(ByRef This As VBFlexGrid, ByVal iCol As Long, ByVal Toggle As Boolean)
With This
Select Case .ColData(iCol)
    Case vbString
        If Toggle = True Then
            If .ColSort(iCol) = FlexSortStringAscending Then
                .ColSort(iCol) = FlexSortStringDescending
            Else
                .ColSort(iCol) = FlexSortStringAscending
            End If
        Else
            If .ColSort(iCol) <> FlexSortStringDescending Then .ColSort(iCol) = FlexSortStringAscending
        End If
    Case vbDate
        If Toggle = True Then
            If .ColSort(iCol) = FlexSortDateAscending Then
                .ColSort(iCol) = FlexSortDateDescending
            Else
                .ColSort(iCol) = FlexSortDateAscending
            End If
        Else
            If .ColSort(iCol) <> FlexSortDateDescending Then .ColSort(iCol) = FlexSortDateAscending
        End If
    Case vbCurrency
        If Toggle = True Then
            If .ColSort(iCol) = FlexSortCurrencyAscending Then
                .ColSort(iCol) = FlexSortCurrencyDescending
            Else
                .ColSort(iCol) = FlexSortCurrencyAscending
            End If
        Else
            If .ColSort(iCol) <> FlexSortCurrencyDescending Then .ColSort(iCol) = FlexSortCurrencyAscending
        End If
    Case vbDecimal, vbDouble, vbSingle, vbLong, vbInteger, vbByte
        If Toggle = True Then
            If .ColSort(iCol) = FlexSortNumericAscending Then
                .ColSort(iCol) = FlexSortNumericDescending
            Else
                .ColSort(iCol) = FlexSortNumericAscending
            End If
        Else
            If .ColSort(iCol) <> FlexSortNumericDescending Then .ColSort(iCol) = FlexSortNumericAscending
        End If
    Case Else
        If Toggle = True Then
            If .ColSort(iCol) = FlexSortGenericAscending Then
                .ColSort(iCol) = FlexSortGenericDescending
            Else
                .ColSort(iCol) = FlexSortGenericAscending
            End If
        Else
            If .ColSort(iCol) <> FlexSortGenericDescending Then .ColSort(iCol) = FlexSortGenericAscending
        End If
End Select
End With
End Sub
```

----------


## lizano diaz

> I can't replicate your picture issue and with rows set to 300.
> 
> Concerning your sorting. Below is a code example showing how it can be done. Please note to fill in .ColData() on all columns on your data population with the VarType values. (e.g. vbString, vbDate)
> 
> 
> ```
> Private LastColSort As Long
> 
> Private Sub Form_Load()
> ...


Thank you very much for your answer, friend Krool, Taking advantage of the message, for when would you be launching new updates like, CheckBox, progress in cells, a drop-down Grid (for teacher - detail)?

----------


## Krool

I still wait for behavior (and bugs of course) feedback for the ExtendLastCol. Preferable from somebody who has a vsFlexGrid. Thanks

----------


## lizano diaz

> I still wait for behavior (and bugs of course) feedback for the ExtendLastCol. Preferable from somebody who has a vsFlexGrid. Thanks


My dear Krool, apparently the Extend LastCol code works correctly as far as I tested it, just notice in the appearance of the grid the following (attached picture), the one above is the VbFlexgrid and the one below is the vsFlexgrid:
1. When hovering the mouse over the line in the last column, the tip of the mouse appears in the shape of an arrow, on the other hand that arrow does not appear in the vsflexgrid.
2. When sorting by column in the vbflexgrid, it would be necessary to draw that arrow that indicates in which position it is ordered (red color of the picture).
3. The scrollbars are different in the two grids, the vbflexgrid is small and the vsflexgrid is large in proportion to the content (in pink).Attachment 182160

----------


## Arnoutdv

Its a different control. You cant expect it to be on the pixel the same as some other control.
If you like the vsFlexGrid so much why dont you keep using it.

----------


## lizano diaz

> Its a different control. You cant expect it to be on the pixel the same as some other control.
> If you like the vsFlexGrid so much why dont you keep using it.


Hello dear
because the question is simple.
1.- Krool I was wondering if the extendlastcol presents any problem so that he can correct and give way to other properties.
2.- Krool and several contributors to the code what we are looking for is a similarity to VsFlexgrid in its properties and add many more functions.

quite apart from that Vsflexgrid will no longer have new improvements, instead our VbFlexgrid is open source and can have many more improvements.

----------


## Arnoutdv

If its open source you can either contribute or create your own fork and add your specific requirements

----------


## Krool

> My dear Krool, apparently the Extend LastCol code works correctly as far as I tested it, just notice in the appearance of the grid the following (attached picture), the one above is the VbFlexgrid and the one below is the vsFlexgrid:
> 1. When hovering the mouse over the line in the last column, the tip of the mouse appears in the shape of an arrow, on the other hand that arrow does not appear in the vsflexgrid.
> 2. When sorting by column in the vbflexgrid, it would be necessary to draw that arrow that indicates in which position it is ordered (red color of the picture).
> 3. The scrollbars are different in the two grids, the vbflexgrid is small and the vsflexgrid is large in proportion to the content (in pink).Attachment 182160


1. I don't know what you mean. On the blurry screenshots I see nothing.
2. Good idea. There are "sort arrow" chars that can be printed from a new property .ColSortArrow() which can be none, up or down. Leaving it to the app to deal with.
3. The scroll bar on vbFlexGrid is by column count. The nPage for proportional scroll bar is not used as this would require equal sized column widths.
Is the vsFlexGrid pixel based on the scrolling? If yes than nPage is easy to determine as it's just the client rect.

----------


## xiaoyao

What features are beyond MSFlexGrid?

----------


## xiaoyao

In order to use the DataSource/DataMember property a reference to msdatsrc.tlb (pre-installed since Win2k) is required.

The same principle, how to select other controls in the property settings of the control?
For example, to develop a control ABC, add two control forms (names ABC1, ABC2), develop a control ccc, and want to set an attribute in control B2, you can choose ABC1 or ABC2. How to achieve this?

----------


## lizano diaz

> My dear Krool, apparently the Extend LastCol code works correctly as far as I tested it, just notice in the appearance of the grid the following (attached picture), the one above is the VbFlexgrid and the one below is the vsFlexgrid:
> 1. When hovering the mouse over the line in the last column, the tip of the mouse appears in the shape of an arrow, on the other hand that arrow does not appear in the vsflexgrid.
> 2. When sorting by column in the vbflexgrid, it would be necessary to draw that arrow that indicates in which position it is ordered (red color of the picture).
> 3. The scrollbars are different in the two grids, the vbflexgrid is small and the vsflexgrid is large in proportion to the content (in pink).Attachment 182160


Hello Krool, thank you very much for your reply.
What I'm trying to do now is to implement the code from post # 563 about column ordering in the same control, in such a way that the end user would only add the control in the form and in "load_form" the user could define its data type of columns
(example: Form_Load ()
VBFlexGrid1.ColData (1) = vbString
VBFlexGrid1.ColData (2) = vbInteger
VBFlexGrid1.ColData (3) = vbDate
VBFlexGrid1.ColData (4) = vbString
)
What do you think of the idea friend? At the moment I am indisposed due to health problems in the Bronchi.
I sincerely thank you for your support to the vb 6.0 community

----------


## Krool

> 1. When hovering the mouse over the line in the last column, the tip of the mouse appears in the shape of an arrow, on the other hand that arrow does not appear in the vsflexgrid.


Ah. I maybe get what you want to say. Do you mean the resize arrows ?
You mean the vsFlexGrid does not allow to resize the last column in ExtendLastCol mode ?

----------


## lizano diaz

> Ah. I maybe get what you want to say. Do you mean the resize arrows ?
> You mean the vsFlexGrid does not allow to resize the last column in ExtendLastCol mode ?


Hello friend Krool,
The Vsflexgrid when hovering the mouse over the last line, the mouse pointer changes to normal mode (Highlighted in the picture with the red box) and does not allow changing the size of the column from the last line, that is, from right to left, the other functions if normal.

Attachment 182173

----------


## Krool

Here is an updated (v3) experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.

Internal fix (subscript out of range) and the extended last column cannot be user resized anymore.

Please everyone interested in the ExtendLastCol. Please make extensive testings and report any bugs/misbehavior etc.
The behavior is most important as this was done according to my gut feeling. I don't have a vsFlexGrid to compare the behavior.
Thanks

Edit: Removed attachment to save space.

----------


## lizano diaz

> Here is an updated (v3) experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.
> 
> Internal fix (subscript out of range) and the extended last column cannot be user resized anymore.
> 
> Please everyone interested in the ExtendLastCol. Please make extensive testings and report any bugs/misbehavior etc.
> The behavior is most important as this was done according to my gut feeling. I don't have a vsFlexGrid to compare the behavior.
> Thanks


Hi Krool, excellent update now if it works perfect, you are a programming genius.
Friend a question: when would a new version be maybe already included (Progressbar, checkbox; in the cells, also a master-type drop-down grid would be excellent - detail, example picture attached).
My sincere thanks and a big hug to your person.

----------


## DaveDavis

> Hi Krool, excellent update now if it works perfect, you are a programming genius.
> Friend a question: when would a new version be maybe already included (Progressbar, checkbox; in the cells, also a master-type drop-down grid would be excellent - detail, example picture attached).
> My sincere thanks and a big hug to your person.


Remove your attachment, the screenshot is 10xxx Grid.

----------


## lizano diaz

> Remove your attachment, the screenshot is 10xxx Grid.


Hi there. Everything is an example, it is also available to all public; That does not mean exactly that everything is being done the same as the grid shown. There are several demo grid of similar characteristics

----------


## xiaoyao

No one control contains all functions. If some functions are not too difficult, adding some is good.
In the end we still had to use multiple OCX controls.

----------


## Adebiyi24

Krool 
Is there a way to sort items when clicking the column header?
thanks

----------


## lizano diaz

> Krool 
> Is there a way to sort items when clicking the column header?
> thanks


Hello, there is one of this form exposed in # 563.

but the ideal thing would be that everything goes within the same control and when loading the form - client the user can indicate what type of values ​​are in each column of the grid and when clicking on the header of the grid indicate whether it is ascending or descending ( an arrow)

----------


## Adebiyi24

lizano diaz
thank you sir

----------


## smileyoufu

> Here is an updated (v3) experimental version (VBFlexGrid.ctl only) for the ExtendLastCol property.
> 
> Internal fix (subscript out of range) and the extended last column cannot be user resized anymore.
> 
> Please everyone interested in the ExtendLastCol. Please make extensive testings and report any bugs/misbehavior etc.
> The behavior is most important as this was done according to my gut feeling. I don't have a vsFlexGrid to compare the behavior.
> Thanks



--------------------------------------------------------------------------------------
If you need a comparison of VSFLEXGRID, there is an official trial version download link of the VSFLEXGRID control below. I hope it can be helpful to you.

Thank you very much Krool!



License conditions:

ComponentOne has a user-friendly distribution policy. We want every programmer to obtain a copy of VSFlexGrid 8.0 to try for as long as they wish. Those who like the product and find it useful may buy a license for a reasonable price. The only restriction is that unlicensed copies of VSFlexGrid 8.0 will display a ComponentOne banner every time they are loaded to remind developers to license the product.




Download link:
http://download3.componentone.com/pu...flex8/Updates/

----------


## xiaoyao

ComponentOne creates a Gantt chart integrated with Microsoft Project. This company is very powerful, far more than just form controls like VSFLEXGRID. Report printing, flowcharts, brain maps, almost omnipotent, as well as the web version of the WEB report.
The advantage of the .NET or ocx version is that you can add N different controls on one interface, visualize operations, and set any properties, and you can see the effect immediately.
Page web version echarts report and other controls or jquery.js
It lacks functions such as control combination, visual operation, binding, and smart code prompting.

The IDE made by web version JS, if you want to achieve similar functions of VB6, it may cost 100 billion US dollars.

----------


## xiaoyao

Is there a flicker-free data refresh function and data cache function?
Ordinary DATAGRID or VSLEXGRID controls will redraw the entire control when refreshed, resulting in no data update or individual field values being modified, the controls are refreshed frequently, and the eyes are tired.

The desired function, refresh the data as little as possible, use less redrawing, and reduce flicker.
For example, to bind an ADO data record set, there are 3000 rows of data, and the visible part is 40 rows (the current cursor is 101-140 rows), if you want to refresh the control
If the data does not change, the UI control interface does not refresh. If only a few cells change, refresh the local cell text and redraw.
If the binding is a two-dimensional array, if there is only a small number of row and column changes, the grid control can reduce the refresh or only partial redraw, it is even more powerful.

----------


## lizano diaz

> Is there a flicker-free data refresh function and data cache function?
> Ordinary DATAGRID or VSLEXGRID controls will redraw the entire control when refreshed, resulting in no data update or individual field values being modified, the controls are refreshed frequently, and the eyes are tired.
> 
> The desired function, refresh the data as little as possible, use less redrawing, and reduce flicker.
> For example, to bind an ADO data record set, there are 3000 rows of data, and the visible part is 40 rows (the current cursor is 101-140 rows), if you want to refresh the control
> If the data does not change, the UI control interface does not refresh. If only a few cells change, refresh the local cell text and redraw.
> If the binding is a two-dimensional array, if there is only a small number of row and column changes, the grid control can reduce the refresh or only partial redraw, it is even more powerful.


Hello, I was just wondering, I don't know how that functionality could be done, if you can do it in any way, please, I would appreciate it if you could publish it.

----------


## Krool

Update released.

ExtendLastCol property finally included.

----------


## lizano diaz

> Update released.
> 
> ExtendLastCol property finally included.


Friend Krool thank you very much for your contribution, one more question taking advantage of the thread: how could the exposed in # 564 be integrated for the ascending and descending ordering within the CTL (control) and on the other hand also that exposed in No. 586 , to update the data without having to redraw the grid ?.

Friend Krool thanks and greetings from a distance.

----------


## lizano diaz

> Is there a flicker-free data refresh function and data cache function?
> Ordinary DATAGRID or VSLEXGRID controls will redraw the entire control when refreshed, resulting in no data update or individual field values being modified, the controls are refreshed frequently, and the eyes are tired.
> 
> The desired function, refresh the data as little as possible, use less redrawing, and reduce flicker.
> For example, to bind an ADO data record set, there are 3000 rows of data, and the visible part is 40 rows (the current cursor is 101-140 rows), if you want to refresh the control
> If the data does not change, the UI control interface does not refresh. If only a few cells change, refresh the local cell text and redraw.
> If the binding is a two-dimensional array, if there is only a small number of row and column changes, the grid control can reduce the refresh or only partial redraw, it is even more powerful.


Hello again, what I was able to get from the grid function is a data refresh if I blink like this:

tuGrid.DataRefresh

----------


## Krool

Update released.

Proportional thumb for the ScrollBars.




> 3. The scrollbars are different in the two grids, the vbflexgrid is small and the vsflexgrid is large in proportion to the content (in pink).Attachment 182160


This is now fixed. I previously said this is not possible, but it was actually very easy...

the nPage member of the scrollinfo was set to 0.
Actually for the ScrollBar it has following formula for the maximum value.


```
nMax - max( nPage  1, 0)
```

So, having an nPage of 1 or 0 is no difference.
The VBFlexGrid now sets it to 1, thus the thumb appears proportional.  :Smilie:

----------


## lizano diaz

> Update released.
> 
> Proportional thumb for the ScrollBars.
> 
> 
> 
> This is now fixed. I previously said this is not possible, but it was actually very easy...
> 
> the nPage member of the scrollinfo was set to 0.
> ...


Hello friend, it does work well for the horizontal scrollbar, but it would still be missing for the Vertical scrollbar.
on the other hand you could help me with the code:

                        Select Case wMsg
                            Case WM_LBUTTONUP
                                RaiseEvent CellClick(.HitRow, .HitCol, vbLeftButton)



                                '''''''''''''''''''''''''''''''''''''''''''''''''

                                Me.HitTest X, y


                                '--- ORDENAR''''''''
                                'If .HitRow = 0 And .HitCol <> 0 Then
                                If .HitRow = 0 Then

                                    Dim Row1 As Long, Row2 As Long
                                    Dim Col1 As Long, Col2 As Long

                                    Me.GetSelRange Row1, Col1, Row2, Col2
                                    Me.RowID(Me.Row) = 1 ' Temporary identification

 If (mlLastColumnOrder <> .HitCol) Or (mbOrdDesc) Then
                                        'Me.Sort = FlexSortStringAscending ' = FlexSortStringNoCaseAscending

If Me.HitResult = FlexHitResultCell And Me.HitRow < Me.FixedRows And Me.HitCol > Me.FixedCols - 1 Then
    If (vbLeftButton) = vbLeftButton Then
        Me.Sort = FlexSortNone
'        If LastColSort > -1 And LastColSort <> Me.HitCol Then Me.ColSort(LastColSort) = FlexSortNone
        If LastColSort > -1 And LastColSort <> Me.HitCol Then Me.ColSort(LastColSort) = FlexSortNone

        mlLastColumnOrder = Me.HitCol
        Call FlexSetColSort(Me.VBFlexGrid1, LastColSort, True)
        Me.Cell(FlexCellSort, Me.FixedRows, LastColSort, Me.Rows - 1, LastColSort) = FlexSortUseColSort
        Cancel = True
    End If
End If


                                  mbOrdDesc = False
                                    Else

                                       ' Me.Sort = FlexSortStringDescending ' = FlexSortStringNoCaseDescending
If .HitResult = FlexHitResultCell And .HitRow < Me.FixedRows And .HitCol > Me.FixedCols - 1 Then
    If (vbLeftButton) = vbLeftButton Then
        Me.Sort = FlexSortNone
        If LastColSort > -1 And LastColSort <> .HitCol Then Me.ColSort(LastColSort) = FlexSortNone
        LastColSort = .HitCol
        Call FlexSetColSort(VBFlexGrid1, LastColSort, True)
        Me.Cell(FlexCellSort, Me.FixedRows, LastColSort, Me.Rows - 1, LastColSort) = FlexSortUseColSort
        Cancel = True
    End If
End If

                                    mbOrdDesc = True
                                    End If
                                    mlLastColumnOrder = .HitCol

                                    Me.Row = Me.RowIndex(1)
                                    Me.RowID(Me.RowIndex(1)) = 0 ' Remove temporary identification
                                    Me.CellEnsureVisible

                                    If Row1 <> Row2 Then Me.RowSel = IIf(Row1 < Me.Row, Row1, Row2)
                                    If Col1 <> Col2 Then Me.ColSel = IIf(Col1 < Me.Col, Col1, Col2)

                                End If



                                '-------'FIN ORDENAR''''''''

''''

what I am looking for is that the ascending and descending order is within the control (ctl)Attachment 182281

----------


## lizano diaz

> Hello friend, it does work well for the horizontal scrollbar, but it would still be missing for the Vertical scrollbar.
> on the other hand you could help me with the code:
> 
>                         Select Case wMsg
>                             Case WM_LBUTTONUP
>                                 RaiseEvent CellClick(.HitRow, .HitCol, vbLeftButton)
> 
> 
> 
> ...



Hello, the function of ascending or descending order is already integrated in the control, the end user will only have to add the control to his form and declare:
private form_load ()
grid.coldata (1) = vbInteger, etc. according to your type of load data in your grid.

- Friend krool rather we could advance with progressbar in the cells, icons in the cells, similar to what is stated in: # 577.

thank you very much kroolAttachment 182282

----------


## Krool

> Hello friend, it does work well for the horizontal scrollbar, but it would still be missing for the Vertical scrollbar.


It's also for the vertical scrollbar but most of the cases the thumb is small as the row count is large.

----------


## Seniorchef

Hello Krool!
Thank you for your excellent work and this control. I'd really love to include this grid in my software.

Attachment 182286

But I'm still using the msHFlexGrid control, because I need a multicolumn sort like showed in the example above. As you see the columns are sorted ascending and descending depending on other columns left or right. The title of each column shows the level (dots) and the order (up/down) of the columns sorting. The columns may be in any order as the user can easily rearrange them without affecting the sorted order. 
Can we solve this sorting example in the vbFlexGrid?

Regards 
Seniorchef

----------


## Krool

> Hello Krool!
> Thank you for your excellent work and this control. I'd really love to include this grid in my software.
> 
> Attachment 182286
> 
> But I'm still using the msHFlexGrid control, because I need a multicolumn sort like showed in the example above. As you see the columns are sorted ascending and descending depending on other columns left or right. The title of each column shows the level (dots) and the order (up/down) of the columns sorting. The columns may be in any order as the user can easily rearrange them without affecting the sorted order. 
> Can we solve this sorting example in the vbFlexGrid?
> 
> Regards 
> Seniorchef


The attachment does not work. But multi column sort is possible.

----------


## Seniorchef

Hello, Krool!
I'm an unexperienced forum user. in preview mode i can see my uploaded image, also when i click 'Attachment 182286'. What am I doing wrong?
Greetings
Seniorchef

----------


## Arnoutdv

It seems you can't see attachments from other users.
Some kind of forum bug I assume.

----------


## Seniorchef

Ok - I'll try it in words.

I am quite sure the grid supports multicolumn sort. Here the columns to sort are not simply from left to right nor beneath each other.
E.g. a grid with 5 columns 'City' 'Name' 'Firstname' 'Street' 'Record' are to be sorted like a phonebook. That is 'City', 'Name', 'Firstname' - no matter what column number 'City' or 'Name' etc. are. I've seen the properties Grid.ColSort and Grid.ColData, but I guess I need a way to tell the sorting routine the order 'City' - 'Name' - 'Firstname' or better, the indices of the columns, not the range like Grid.Col and Grid.ColSel. 

Greetings
Seniorchef

----------


## lizano diaz

> The attachment does not work. But multi column sort is possible.


Dear Krool, please, how could you adapt these features to the VbFlexgrid (attached image).

Thank you very much for your replyAttachment 182314

----------


## Krool

> Ok - I'll try it in words.
> 
> I am quite sure the grid supports multicolumn sort. Here the columns to sort are not simply from left to right nor beneath each other.
> E.g. a grid with 5 columns 'City' 'Name' 'Firstname' 'Street' 'Record' are to be sorted like a phonebook. That is 'City', 'Name', 'Firstname' - no matter what column number 'City' or 'Name' etc. are. I've seen the properties Grid.ColSort and Grid.ColData, but I guess I need a way to tell the sorting routine the order 'City' - 'Name' - 'Firstname' or better, the indices of the columns, not the range like Grid.Col and Grid.ColSel. 
> 
> Greetings
> Seniorchef


If the columns are not "range-able" (Col to ColSel) then you might to sort manually each column.
If you want to sort by order of 'City' 'Name' 'Firstname' 'Street' 'Record' then you sort in reverse order to achieve "multi-column" sort.

So first sort by 'Record', then by 'Street' and so on until 'City'.

----------


## Seniorchef

Thank you, Krool - I'll give it a try.
With the msHFlexGrid I sort with flexSortCustom and the compare event, but unfortunately the VBFlexgrid is very slow in using this method. 
Regards
Seniorchef

----------


## Krool

> Thank you, Krool - I'll give it a try.
> With the msHFlexGrid I sort with flexSortCustom and the compare event, but unfortunately the VBFlexgrid is very slow in using this method. 
> Regards
> Seniorchef


Yes..

MergeSort is used for automatic sorting as it is fast and stable.

BubbleSort is used for custom sorting as row1/row2 for text matrix must be meaningful in the 'Compare' event.

If a faster replacement for the custom sorting is possible I am eager to read about.

----------


## lizano diaz

Hello friend Krool, how can I do? to be able to have cells with progressBar in the VbFlexgrid.
Please I need your support.

Attachment 182323

----------


## lizano diaz

Dear Krool I found a problem in the grid, this happens when you add the grid in a form, and you put it in properties:
FixedRos = 1
rows = 2
fixedcol = 0

You close the form and open the form again and Vb 6.0 hangs (does not respond).

attached image

Attachment 182325

----------


## Krool

> Dear Krool I found a problem in the grid, this happens when you add the grid in a form, and you put it in properties:
> FixedRos = 1
> rows = 2
> fixedcol = 0
> 
> You close the form and open the form again and Vb 6.0 hangs (does not respond).
> 
> attached image
> 
> Attachment 182325


I can't replicate. Please review.

----------


## Seniorchef

Hello, Krool!
Sorry for my late answer, but I wanted to test the issue before I report. 
I don't know how, but the custom sort of the msHFlexgrid is way faster than the custom sort of the vbFlexGrid - it's about the factor 30 on a single column sort. So they have either a different way to sort customly or a faster algorithm.
Just a thought. I would love to replace the msHFlexGrid with the VBFlexGrid, but the custom sort is a real killjoy.
Thanks for your efforts anyway. I really appreciate your work very well.
Regards
Seniorchef

----------


## Arnoutdv

How many records are you talking about?

How do you initially fill the grid?
If it's from a query then you could add sorting to the query.
If it's from some other dataset then you could do a sort on your data first, before assigning it to the grid.

----------


## Seniorchef

Hello, Arnoutdv!
In this test it's 600 records - it becomes worse with more records (obviously). 
On my pc it took 6 sec with vbFlexGrid and 0.2 sec with msHFlexgrid. 
The grid is filled already, and I sort per mouseclick on columnheader. The data is unbound. 
Greetings
Seniorchef

----------


## Krool

> Hello, Arnoutdv!
> In this test it's 600 records - it becomes worse with more records (obviously). 
> On my pc it took 6 sec with vbFlexGrid and 0.2 sec with msHFlexgrid. 
> The grid is filled already, and I sort per mouseclick on columnheader. The data is unbound. 
> Greetings
> Seniorchef


6 sec with 600 records?
Can you share the code? (Maybe there is a late-bound inefficiency)

Also, what kind of custom sort you are doing?
For instance VbFlexGrid has an enum for date sort (thus fast as not custom) maybe I can add an enum for your use-case.

I also check if I can change the BubbleSort to a GnomeSort for custom sorting. (It should perform a little bit better) Lets see..

----------


## Seniorchef

Hello, Krool!
I know - 6 seconds is a long time compared to 0.2 seconds. 
Even if it is a slow pc and there is a lot of overhead while sorting, this is valid for both grids. The code I use to test is identical (except the compare-event for each grid has one different argument). 

I'm doing the custom sort to achive multicolumn sort, ascending, descending in flexible order (see my post #601).
I know about the built-in sort abilities, but they cannot sort as flexible as I need to. On the other hand, the custom sort works really fine and is exactly what I need, but it is slow.

It is the BubbleSortIter() Sub. I'm not experienced in sorting algorithms, but maybe it should be replaced by a faster one.
If we knew the way the msHflexGrid handles this we had the solution, I'm sure.
Maybe there is a user who can tell us. 

Greetings
Seniorchef

----------


## Arnoutdv

Bubblesort is stable, but very slow, sorting method
Mergesort is also stable and much faster.

@Seniorchef, have you tried it compiled or only from within the IDE?

Mergesort implementation:
http://www.vb-helper.com/howto_mergesort.html

----------


## Krool

> Bubblesort is stable, but very slow, sorting method
> Mergesort is also stable and much faster.


I use MergeSort already.

However, for custom sort (firing Compare event where Text Matrix of row1/row2 are valid) the Merge Sort is not possible, thus BubbleSort for that.

If there is a working/valid alternative possible please let me know.

----------


## Seniorchef

Hello, Arnoutdv!
Honestly, I tested it in the IDE. But after your post I compiled it and - the result stays the same.
Btw, thank you for the link - MergeSort is already in the VBFlexGrid Sort routine, and, if possible and his time permits, it should be adapted by Krool for the custom sort.
Either way, I don't want to rush the issue, and maybe he'll find another way to speed up the routine.
Regards
Seniorchef

----------


## Krool

> Hello, Arnoutdv!
> Honestly, I tested it in the IDE. But after your post I compiled it and - the result stays the same.
> Btw, thank you for the link - MergeSort is already in the VBFlexGrid Sort routine, and, if possible and his time permits, it should be adapted by Krool for the custom sort.
> Either way, I don't want to rush the issue, and maybe he'll find another way to speed up the routine.
> Regards
> Seniorchef


Again, it's logical NOT POSSIBLE to use merge sort for custom sort.

----------


## Arnoutdv

And that's because you can not just pass the 2 values to compare, but because the sorted items can also be things like the backcolor of the cell or it's custom data property?

----------


## Krool

> And that's because you can not just pass the 2 values to compare, but because the sorted items can also be things like the backcolor of the cell or it's custom data property?


Well yes... The MS(H)FlexGrid also passes row1/row2.
If I would pass Text1/Text2 to Compare event the MergeSort would work.

----------


## Arnoutdv

Maybe an additional event CompareValues and an additional sort method, CustomValue

----------


## lizano diaz

Please krool could you support me with the request of: # 604

Please thank you very much

----------


## Seniorchef

Hello and good morning.
Ok, this morning I woke up and I think I got a solution for my problem. If it works, there will be no need for the custom sort event cause I'll enhance the regular sort routine. I'll try it and tell the results. 
Greetings
Seniorchef

----------


## Arnoutdv

I tested the following:


```
' VBFlexGrid.ctl

Private FlexSortNone, FlexSortGenericAscending, FlexSortGenericDescending, FlexSortNumericAscending, FlexSortNumericDescending, FlexSortStringNoCaseAscending, FlexSortStringNoCaseDescending, FlexSortStringAscending, FlexSortStringDescending, FlexSortCustom, FlexSortCustomValue, FlexSortUseColSort, FlexSortCurrencyAscending, FlexSortCurrencyDescending, FlexSortDateAscending, FlexSortDateDescending

Public Enum FlexSortConstants
FlexSortNone = 0
FlexSortGenericAscending = 1
FlexSortGenericDescending = 2
FlexSortNumericAscending = 3
FlexSortNumericDescending = 4
FlexSortStringNoCaseAscending = 5
FlexSortStringNoCaseDescending = 6
FlexSortStringAscending = 7
FlexSortStringDescending = 8
FlexSortCustom = 9
FlexSortUseColSort = 10
FlexSortCurrencyAscending = 11
FlexSortCurrencyDescending = 12
FlexSortDateAscending = 13
FlexSortDateDescending = 14
FlexSortCustomValue = 15
End Enum

Public Event CompareValue(Value1 As String, Value2 As String, ByRef Cmp As Long)

Private Sub InplaceMergeSort(ByVal Left As Long, ByVal Middle As Long, ByVal Right As Long, ByVal Col As Long, ByRef Data() As TCOLS, ByVal Sort As FlexSortConstants)
'
' 
    Select Case Sort
        Case FlexSortCustomValue
          RaiseEvent CompareValue(Data(i).Cols(Col).Text, Temp(j).Cols(Col).Text, Cmp)
```



```
' MainForm
Private Sub VBFlexGrid1_Compare(ByVal Row1 As Long, ByVal Row2 As Long, ByVal Col As Long, Cmp As Long)
  Dim dValue1 As Double, dValue2 As Double
  dValue1 = CDbl(VBFlexGrid1.TextMatrix(Row1, Col))
  dValue2 = CDbl(VBFlexGrid1.TextMatrix(Row2, Col))
  If dValue1 > dValue2 Then Cmp = 1 Else Cmp = -1
End Sub

Private Sub VBFlexGrid1_CompareValue(Value1 As String, Value2 As String, Cmp As Long)
  If CDbl(Value1) > CDbl(Value2) Then Cmp = 1 Else Cmp = -1
End Sub


Private Sub Command17_Click()
Dim Row1 As Long, Row2 As Long
Dim Col1 As Long, Col2 As Long
With VBFlexGrid1
.GetSelRange Row1, Col1, Row2, Col2
.RowID(.Row) = 1 ' Temporary identification
.Sort = FlexSortCustomValue
'.Sort = VBA.Choose(Combo2.ListIndex + 1, FlexSortGenericAscending, FlexSortNumericAscending, FlexSortStringNoCaseAscending, FlexSortStringAscending, FlexSortCurrencyAscending, FlexSortDateAscending)
.Row = .RowIndex(1)
.RowID(.RowIndex(1)) = 0 ' Remove temporary identification
.CellEnsureVisible
If Row1 <> Row2 Then .RowSel = IIf(Row1 < .Row, Row1, Row2)
If Col1 <> Col2 Then .ColSel = IIf(Col1 < .Col, Col1, Col2)
End With
End Sub
```

It's running in full speed on the sample VBFlexGridDemo with 600 rows  :Smilie: 
I first sort Column 1 with the Dates Descending with SortType "String"
Then a numeric value column with Sort Asc, which has a hardcoded  .Sort = FlexSortCustumValue

----------


## Krool

@ Arnoutdv,

good idea with a second custom sort which can be based on the merge sort.

However, why CustomValue/CompareValue (Value1/Value2) ? I would like CustomText/CompareText (Text1/Text2) more..

----------


## Arnoutdv

*Text instead of *Value is indeed better, much more obvious what is going on.

----------


## Krool

Even VSflexGrid admits that it's of magnitude slower the Compare event.
http://helpcentral.componentone.com/...mpareevent.htm
So I'm wondering what the heck msHFlexGrid is doing..

----------


## Krool

Update released.




> *Text instead of *Value is indeed better, much more obvious what is going on.


Included the FlexSortCustomText enum with corresponding CompareText event.

----------


## Krool

I found a way to "improve" the bubble sort.

Let's take the demo example (rows increased from 150 to 600)

The original version takes 11 seconds in the IDE. The new modified version takes 3.5 seconds.

The green part is old and commented out. The blue part is added.
The red part is the time safer. The ReDim needs to be done only 1 time.



```
Private Sub BubbleSortIter(ByVal First As Long, ByVal Last As Long, ByVal Col As Long, ByRef Data() As TCOLS)
Dim Swap As TCOLS, Cmp As Long
ReDim Swap.Cols(0 To (PropCols - 1)) As TCELL
Dim i As Long, j As Long, iCol As Long
Do While Last > First
    i = First
    For j = First To Last - 1
        Cmp = 0
        RaiseEvent Compare(j, j + 1, Col, Cmp)
        If Cmp > 0 Then
'            LSet Swap = Data(j + 1)
'            LSet Data(j + 1) = Data(j)
'            LSet Data(j) = Swap
            LSet Swap.RowInfo = Data(j + 1).RowInfo
            LSet Data(j + 1).RowInfo = Data(j).RowInfo
            LSet Data(j).RowInfo = Swap.RowInfo
            For iCol = 0 To (PropCols - 1)
                LSet Swap.Cols(iCol) = Data(j + 1).Cols(iCol)
                LSet Data(j + 1).Cols(iCol) = Data(j).Cols(iCol)
                LSet Data(j).Cols(iCol) = Swap.Cols(iCol)
            Next iCol
            i = j
        End If
    Next j
    Last = i
Loop
End Sub
```

What you think ?

EDIT: _(revised version, to be released soon)_


```
Private Sub BubbleSortIter(ByVal First As Long, ByVal Last As Long, ByVal Col As Long, ByRef Data() As TCOLS)
Dim SwapRowInfo As TROWINFO, SwapCell As TCELL, Cmp As Long
Dim i As Long, j As Long, iCol As Long
Do While Last > First
    i = First
    For j = First To Last - 1
        Cmp = 0
        RaiseEvent Compare(j, j + 1, Col, Cmp)
        If Cmp > 0 Then
            LSet SwapRowInfo = Data(j + 1).RowInfo
            LSet Data(j + 1).RowInfo = Data(j).RowInfo
            LSet Data(j).RowInfo = SwapRowInfo
            For iCol = 0 To (PropCols - 1)
                LSet SwapCell = Data(j + 1).Cols(iCol)
                LSet Data(j + 1).Cols(iCol) = Data(j).Cols(iCol)
                LSet Data(j).Cols(iCol) = SwapCell
            Next iCol
            i = j
        End If
    Next j
    Last = i
Loop
End Sub
```



```
Private Sub InplaceMergeSort(ByVal Left As Long, ByVal Middle As Long, ByVal Right As Long, ByVal Col As Long, ByRef Data() As TCOLS, ByVal Sort As FlexSortConstants)
Dim Temp() As TCOLS, Cmp As Long, Dst As Long
Dim i As Long, j As Long, iCol As Long
Dim Dbl1 As Double, Dbl2 As Double
ReDim Temp(Middle - Left) As TCOLS
j = 0
For i = Left To Middle
    LSet Temp(j) = Data(i)
    j = j + 1
Next i
j = 0
Dst = Left
Do While i <= Right And j <= UBound(Temp)
    Cmp = 0
    Select Case Sort
        Case FlexSortGenericAscending, FlexSortGenericDescending
            If Not IsNumeric(Data(i).Cols(Col).Text) Or Not IsNumeric(Temp(j).Cols(Col).Text) Then
                If Data(i).Cols(Col).Text < Temp(j).Cols(Col).Text Then
                    Cmp = -1
                ElseIf Data(i).Cols(Col).Text > Temp(j).Cols(Col).Text Then
                    Cmp = 1
                End If
            Else
                Dbl1 = Empty: Dbl2 = Empty
                On Error Resume Next
                Dbl1 = CDbl(Data(i).Cols(Col).Text)
                Dbl2 = CDbl(Temp(j).Cols(Col).Text)
                On Error GoTo 0
                Cmp = Sgn(Dbl1 - Dbl2)
            End If
            If Sort = FlexSortGenericDescending Then Cmp = -Cmp
        Case FlexSortNumericAscending, FlexSortNumericDescending
            Dbl1 = Empty: Dbl2 = Empty
            On Error Resume Next
            Dbl1 = CDbl(Data(i).Cols(Col).Text)
            Dbl2 = CDbl(Temp(j).Cols(Col).Text)
            On Error GoTo 0
            Cmp = Sgn(Dbl1 - Dbl2)
            If Sort = FlexSortNumericDescending Then Cmp = -Cmp
        Case FlexSortStringNoCaseAscending, FlexSortStringNoCaseDescending
            Cmp = lstrcmpi(StrPtr(Data(i).Cols(Col).Text), StrPtr(Temp(j).Cols(Col).Text))
            If Sort = FlexSortStringNoCaseDescending Then Cmp = -Cmp
        Case FlexSortStringAscending, FlexSortStringDescending
            Cmp = lstrcmp(StrPtr(Data(i).Cols(Col).Text), StrPtr(Temp(j).Cols(Col).Text))
            If Sort = FlexSortStringDescending Then Cmp = -Cmp
        Case FlexSortCurrencyAscending, FlexSortCurrencyDescending
            Dim Cur1 As Currency, Cur2 As Currency
            Cur1 = Empty: Cur2 = Empty
            On Error Resume Next
            Cur1 = CCur(Data(i).Cols(Col).Text)
            Cur2 = CCur(Temp(j).Cols(Col).Text)
            On Error GoTo 0
            Cmp = Sgn(Cur1 - Cur2)
            If Sort = FlexSortCurrencyDescending Then Cmp = -Cmp
        Case FlexSortDateAscending, FlexSortDateDescending
            Dim Date1 As Date, Date2 As Date
            Date1 = Empty: Date2 = Empty
            On Error Resume Next
            Date1 = CDate(Data(i).Cols(Col).Text)
            Date2 = CDate(Temp(j).Cols(Col).Text)
            On Error GoTo 0
            Cmp = Sgn(Date1 - Date2)
            If Sort = FlexSortDateDescending Then Cmp = -Cmp
        Case FlexSortCustomText
            RaiseEvent CompareText(Data(i).Cols(Col).Text, Temp(j).Cols(Col).Text, Col, Cmp)
    End Select
    If Cmp < 0 Then
        LSet Data(Dst).RowInfo = Data(i).RowInfo
        For iCol = 0 To (PropCols - 1)
            LSet Data(Dst).Cols(iCol) = Data(i).Cols(iCol)
        Next iCol
        i = i + 1
    Else
        LSet Data(Dst).RowInfo = Temp(j).RowInfo
        For iCol = 0 To (PropCols - 1)
            LSet Data(Dst).Cols(iCol) = Temp(j).Cols(iCol)
        Next iCol
        j = j + 1
    End If
    Dst = Dst + 1
Loop
Do While j <= UBound(Temp)
    LSet Data(Dst).RowInfo = Temp(j).RowInfo
    For iCol = 0 To (PropCols - 1)
        LSet Data(Dst).Cols(iCol) = Temp(j).Cols(iCol)
    Next iCol
    Dst = Dst + 1
    j = j + 1
Loop
End Sub
```

----------


## Krool

Updated BubbleSortIter/InplaceMergeSort for better performance on UDT assignment.

----------


## southmark

_Also posted in the [VB6] variant thread (just saw this one):_




> Does this work in Excel? Does anyone have an example of how to get this up and running in an Excel form? 
> 
> I added a reference to the ocx and tlb but cannot see a control to add to the palette in the form builder. What are the steps please?


Thank you!

----------


## Krool

Question..
For a potential .ColSortArrow property should I use a fixed image for up/down arrow or just draw with same cell font as unicode char U+25B2 (▲) and U+25BC (▼) ?

----------


## MountainMan

> Question..
> For a potential .ColSortArrow property should I use a fixed image for up/down arrow or just draw with same cell font as unicode char U+25B2 (▲) and U+25BC (▼) ?


How about using the Unicode characters unless they are not present in whatever font you are using in which case you switch to a fixed image?

----------


## Krool

> How about using the Unicode characters unless they are not present in whatever font you are using in which case you switch to a fixed image?


Using Unicode character is easier at it scales according to size/dpi etc.
So unless a Wingdings font is used this works great. And it works back to Win XP, no? (Need to test)
Also the fore color works in sync

----------


## Krool

Update released.

Included the ColSortArrow property. I decided to just draw a triangle to be independent of fonts. Also it ensures to work then in Windows XP.
However, the triangle is calculated upon TEXTMETRICS so it scales accordingly..

The internal GetTextSize and GetLabelInfo considers the triangle accordingly.

The triangle is only drawn on the first fixed row.



This code will conveniently remove (quickly) all sort arrows on each column.


```
VBFlexGrid1.ColSortArrow(-1) = FlexSortArrowNone
```

----------


## Krool

Currently the sort arrow is drawn right or left aligned depending on the text alignment. When text is left or centered the sort arrow is right, else left.
I may include another ColSortArrowAlignment property which could be set to 0 - NoControl, 1 - Right and 2 - Left...

----------


## Krool

Included the ColSortArrowColor property.

The default value on each column is -1. This means the applied text color of that cell is used as color for the sort arrow.
This property allows to specify an explicit color.

----------


## Krool

Some finetuning for ColSortArrowColor property.

When set to -1 the get property will not return -1 anymore and just fallback to the color that will be used then for drawing.
This is then in line with the other color properties and the fallbacks accordingly.

----------


## Krool

Update released.

Renamed enum FlexColSortArrowUp to FlexColSortArrowAscending and FlexColSortArrowDown to FlexColSortArrowDescending.
This is then easier to use (not to think about if up is ascending and down is descending) and also in harmony with the general sort enums.

Included the RowSortArrows property. The default value is 0 for the first fixed row. This property may be modified to display the sort arrows on a different fixed row.

----------


## Krool

Introduced now a SortArrowColor property which defaults to vbGrayText.

It's in practise easier to have a global color property which can be set at design time. Because ColSortArrowColor needs to be set by code and when a grid erases (e.g. Rows = 0) the values are lost.

So, ColSortArrowColor still exists now and when set to -1 it fallbacks to the global SortArrowColor.
This is much cleaner and more predictable than the previous two cases fallback between cell forecolor and forecolor fixed.

----------


## softv

Dear krool,

As always, my thanks in TONS to you for your free contribution to this world society. And, special thanks for the sort arrow with color, default color, alignment, etc. I was using my own simple arrow earlier. Your work with so many options makes it all so easy now. I have not explored them fully yet. Will do soon but lot many thanks in advance.

Well, is there a page which explains the meaning of all (or the most important) properties of your VBFlexGrid control? For instance, intuitively, I thought .colsvisible will just give me the number of columns which are not hidden in a grid (i.e. total number of columns minus the columns with .colhidden = true) but it was not so. Object browser told me that .colsvisible "Returns the total number of columns or rows visible in the flex grid."

To understand the above statement from the Object Browser better, I just experimented with a sample 10*10 flex grid. I realised that even if I hide some columns (say 1, 2 and 3) and reduce the width of the grid to show only 2 columns (i.e. only column 0 and column 4), then also .colsvisible will return 5 and not 2. Is it so by design? Just a clarification. Thats all. 

.rowsvisible also behaves similarly with a similar experiment as above. So, just wanted to clarify whether .colsvisible and .rowsvisible are designed to report values in the above manner only.

I have some clarifications regarding how and where to avail ComboListCount, ComboListIndex, ComboList, etc. Will ask them in a separate message.
Thanks again.

Kind regards.

----------


## softv

Dear krool,

This is in continuation of my last message (in which I have requested your clarification on .colsvisible and .rowsvisible). 

And, reg. the *various ComboList values,* I am sorry that I am not that very clear in my understanding of them.

So, via the following cases, I am trying to understand them in the right way from you. So, kindly please help.


*Case 1)*
In your VBFlexGrid demo, in *UserEditingForm*, I have the following lines at the end of the Form_Load event.



```
Debug.Print VBFlexGrid1.ComboListCount
Debug.Print VBFlexGrid1.ComboListIndex
Debug.Print VBFlexGrid1.ComboList(10) & "Z"
Debug.Print VBFlexGrid1.ColComboItems(10)
```

The above print '0', '0', 'Z' and 'Arnold|Bob|Charlie|David|Elena|Felix|Greg|Hanna|Ivan|Jacob'

a) Why '0' got printed for .*ComboListCount*? Why *.ComboList(10)* prints empty string?
b) Even if I make the rows count as 2 for VBFlexGrid1 and select 'Ivan' (instead of the default Arnold) in both the 10th and 11th columns, then also .*ComboListIndex* is printed as '0' only. Why? 
c) Perhaps .ComboList, .ComboListCount and .ComboListIndex carry meaning only when they are used in specific events like VBFlexGrid1_EnterEdit(), VBFlexGrid1_LeaveEdit(), etc.? If so, *in which all events they carry meaning*? Please let me know.


*Case 2)*
At the end of the VBFlexGrid1_EnterEdit() event, I have the following lines.


```
Debug.Print VBFlexGrid1.ComboListCount
Debug.Print VBFlexGrid1.ComboListIndex
'''''Debug.Print VBFlexGrid1.ComboList(10) & "Z"
Debug.Print VBFlexGrid1.ColComboItems(10)
```

And, when I double click a cell in the 10th column where 'Charlie' is present, what get printed are:
'10', '2' and 'Arnold|Bob|Charlie|David|Elena|Felix|Greg|Hanna|Ivan|Jacob'

I had to comment out the 3rd line above because it caused a *run time error* (Invalid procedure call or argument).

a) Why the 3rd line caused an error? Please educate me. Is it that it cannot or should not be used in certain events?
b) Where then should (or where all I can) use that line so that it will show some output?
c) *What actually is .ComboList(10) supposed to show?* Is it supposed to show the same output of ColComboItems(10) but without the '|' and all the 10 names displayed one after the other, in 10 lines?


*Case 3)*
At the end of the VBFlexGrid1_LeaveEdit() event, I have the following lines. 


```
Debug.Print VBFlexGrid1.ComboListCount
Debug.Print VBFlexGrid1.ComboListIndex
'Debug.Print VBFlexGrid1.ComboList(10) & "A"
Debug.Print VBFlexGrid1.ColComboItems(10)
VBFlexGrid1.ComboListIndex = 9
Debug.Print "yes"; VBFlexGrid1.ComboListIndex
```

And, when I double click a cell in the 10th column where Charlie is present and select Charlie itself again, what get printed are:
'10', '2', 'Arnold|Bob|Charlie|David|Elena|Felix|Greg|Hanna|Ivan|Jacob' and 'yes 9'

a) I had to keep the 3rd line commented out here also since it caused the same run time error (Invalid procedure call or argument). 
b) Though I changed the .ComboListIndex to 9, the selection remained at 'Charlie' only. 
c) So, where and how should I use .ComboListIndex *so that I can "programmatically" change/select the ComboList item* in any cell in the 10th column (ComboDropDown) without having to manually double click a cell and select a particular item in the list.


Thanks a TON once again for your contribution to the world society.

Kind regards.

----------


## softv

Dear krool,

One more thing. Can there be a '*ExtendThisCol = <Col No.>*' property too? 

For instance, say my design requires me to have a chunk of text in the 1st column of a 3-column grid and fixed width values in the 2 and 3rd columns. 

Then, I would not like to extend my last column. I would like to *extend my first column* only. So, in such cases, 'ExtendThisCol' property will be very helpful I thought. Of course, I can do this via code itself. In fact, I was already achieving 'EntendLastCol' through my own code only. But, a properly like 'EntendLastCol' introduced by you is easier and thus very helpful. That's why my suggestion for ExtendThisCol too. 

Kind regards.

----------


## Krool

> Dear krool,
> 
> This is in continuation of my last message (in which I have requested your clarification on .colsvisible and .rowsvisible). 
> 
> And, reg. the *various ComboList values,* I am sorry that I am not that very clear in my understanding of them.
> 
> So, via the following cases, I am trying to understand them in the right way from you. So, kindly please help.
> 
> 
> ...


ColComboItems is similar to the ComboItems property, except it applies to entire columns. This is often more convenient that using the ComboItems property because you may set the ColComboItems property once for each column, whereas the ComboItems property normally needs to be set in the BeforeEdit event.

ComboListCount, ComboListIndex and ComboList(x) are properties to extract info from a once defined ColComboItems/ComboItems.

So, ComboList(x) is to extract x entry for the current column. X is not the column, that's why you had an error.

----------


## softv

Dear krool,

As in the case of 'sort', is it possible to *show a chevron* (inside a square preferably) by the side of the cells of the column whose .ColComboMode is set to FlexComboModeDropDown (or) FlexComboModeEditable? Because, this way, a user will readily know that there is a *ComboList existing* in the cells of that column. 

If the above is not possible, then what is the easiest way to indicate to the user by text that there is a ComboList existing in those cells? Anyway, since indication via picture is the best way, what is the easiest way to make a chevron get displayed by the side of all such ComboList cells? Draw a picture using ".Cell(FlexCellPicture)"? If so, what would be the best way to draw the chevron pictures so that they appear correctly in all resolutions, etc.? And, will it be possible to act upon click events on those chevron pictures? If not, capturing mouse click events on X,Y coordinates of those chevrons is the only way? Well, *any suggestions are welcome*. Thanks in advance.

Kind regards.

----------


## softv

> ColComboItems is similar to the ComboItems property, except it applies to entire columns. This is often more convenient that using the ComboItems property because you may set the ColComboItems property once for each column, whereas the ComboItems property normally needs to be set in the BeforeEdit event.
> 
> ComboListCount, ComboListIndex and ComboList(x) are properties to extract info from a once defined ColComboItems/ComboItems.
> 
> So, ComboList(x) is to extract x entry for the current column. X is not the column, that's why you had an error.


ComboList(x). Thanks a lot, krool. Understood. I think I have understood difference between ColComboItems and ComboItems too. If there are doubts, I shall write again.

As of now, can you kindly let me know whether it is possible to *programmatically change/select the ComboList item* in any cell of a column whose ColComboMode is set to FlexComboModeDropDown (or  FlexComboModeEditable)? If so, can you kindly give me a code sample please?

Kind regards.

----------


## Krool

> ComboList(x). Thanks a lot, krool. Understood. I think I have understood difference between ColComboItems and ComboItems too. If there are doubts, I shall write again.
> 
> As of now, can you kindly let me know whether it is possible to *programmatically change/select the ComboList item* in any cell of a column whose ColComboMode is set to FlexComboModeDropDown (or  FlexComboModeEditable)? If so, can you kindly give me a code sample please?
> 
> Kind regards.


Use ComboListIndex to change the selected list item.

----------


## softv

> Use ComboListIndex to change the selected list item.


I had already tried it but did not succeed. But, after seeing your instruction, I tried again and achieved it. *Thanks a TON*. 

However, I request you to tell me whether there is a better way to achieve it than the way I have adopted below. The code I used (in a button click) was:


```
  With VBFlexGrid1
    .Row = 2
    .Col = 10
    .StartEdit
    .ComboListIndex = 5
    '''''.CommitEdit
  End With
  SendKeys vbLf
```

The above worked like a charm, to programmatically select a list item. Thanks a TON once again. 
But, I feel there must be a better alternative to 'SendKeys vbLf'. 
That's why I tried VBFlexGrid1.CommitEdit, but it did not change the ComboListIndex to 5. The dropdown just closed. Kindly suggest me an alternative to 'SendKeys vbLf', if any. Thanks in advance.

Kind regards.

----------


## Krool

> I had already tried it but did not succeed. But, after seeing your instruction, I tried again and achieved it. *Thanks a TON*. 
> 
> However, I request you to tell me whether there is a better way to achieve it than the way I have adopted below. The code I used (in a button click) was:
> 
> 
> ```
>   With VBFlexGrid1
>     .Row = 2
>     .Col = 10
> ...


The .ComboListIndex = 5 works as it should. What do you want to achieve, to just avoid user selection and commit list entry 5 ?
The below code will do it without SendKeys vbLf...


```
VBFlexGrid1.EditText = VBFlexGrid1.ComboList(5)
VBFlexGrid1.CommitEdit
```

----------


## softv

> ... .. .
> The below code will do it without SendKeys vbLf...
> 
> 
> ```
> VBFlexGrid1.EditText = VBFlexGrid1.ComboList(5)
> VBFlexGrid1.CommitEdit
> ```


Perfect, Krool. Thank you so much.  :Smilie: 

Kind regards.

----------


## softv

Dear krool,

is it possible to freeze rows (one or more) from the bottom rows of a grid? If so, what should I do? Thanks.

As of now, just to freeze the very last row of the grid is enough for me so that when user scrolls up and down, the last row is always visible.

Kind regards.

----------


## Krool

> Dear krool,
> 
> is it possible to freeze rows (one or more) from the bottom rows of a grid? If so, what should I do? Thanks.
> 
> As of now, just to freeze the very last row of the grid is enough for me so that when user scrolls up and down, the last row is always visible.
> 
> Kind regards.


Not possible. Even Excel doesn't allow it.
What you want actually? Maybe there is an alternative..

----------


## softv

> Not possible. Even Excel doesn't allow it.
> What you want actually? Maybe there is an alternative..


Oh okay, krool. Understood.

I just wanted to show the number of records (at any point of time in the grid) in the last row of the grid itself.
Right now, I am using an alternative only. I am showing the records count in a separate control placed below the grid. If there is a better alternative, kindly let me know.

I just felt that showing the records count (which will be just .rows-1, in my grid's case) inside the grid itself in a frozen last row will be ideal. That's all.

Kind regards.

----------


## Krool

> Dear krool,
> 
> As in the case of 'sort', is it possible to *show a chevron* (inside a square preferably) by the side of the cells of the column whose .ColComboMode is set to FlexComboModeDropDown (or) FlexComboModeEditable? Because, this way, a user will readily know that there is a *ComboList existing* in the cells of that column. 
> 
> If the above is not possible, then what is the easiest way to indicate to the user by text that there is a ComboList existing in those cells? Anyway, since indication via picture is the best way, what is the easiest way to make a chevron get displayed by the side of all such ComboList cells? Draw a picture using ".Cell(FlexCellPicture)"? If so, what would be the best way to draw the chevron pictures so that they appear correctly in all resolutions, etc.? And, will it be possible to act upon click events on those chevron pictures? If not, capturing mouse click events on X,Y coordinates of those chevrons is the only way? Well, *any suggestions are welcome*. Thanks in advance.
> 
> Kind regards.


There is no "picture click" event.
What's the use-case you want to achieve?

----------


## softv

> There is no "picture click" event.
> What's the use-case you want to achieve?


Dear krool,

As written earlier, the use-case is for the user to readily know that a drop down list is present in the cells of a particular column. Obviously, I cannot have column names as DropDown Combo, etc. So, there should be some pictorial indication somewhere to the user so that he knows immediately on seeing the grid that there is a drop down available in the cells of a particular column. Any kind of suggestions towards achieving this (in whatever manners possible) is welcome. Thanks in advance.

Kind regards.

----------


## Krool

Update released.




> In short, is there a way to land on a cell that has been set as a dropdown combo and have it not drop the list, just shot the text and the button. (We are hoping to use this as a container for editable fields of a variety of different types. Thanks!


The workaround with .ComboButtonValue to 'FlexComboButtonValueDisabled' is not needed anymore. There is a new event now 'ComboBeforeDropDown'.
So you can achieve the wanted behavior now easily by following code:



```
Private Sub VBFlexGrid1_ComboBeforeDropDown(ByVal Reason As FlexComboDropDownReasonConstants, Cancel As Boolean)
If Reason = FlexComboDropDownReasonInitialize Then Cancel = True
End Sub
```

----------


## Krool

> Dear krool,
> 
> As written earlier, the use-case is for the user to readily know that a drop down list is present in the cells of a particular column. Obviously, I cannot have column names as DropDown Combo, etc. So, there should be some pictorial indication somewhere to the user so that he knows immediately on seeing the grid that there is a drop down available in the cells of a particular column. Any kind of suggestions towards achieving this (in whatever manners possible) is welcome. Thanks in advance.
> 
> Kind regards.


That's an interesting question. So, a visual cue that a dropdown will appear when attempting to edit.
The not disturbing approach would be not to always show such a "chevron" but only when that cell is selected. Using the RowColChange event.
However, using a picture with right align and no overlap would be the easiest and dynamically set/clear upon RowColChange.
Difficult part is to create such a dynamic scaled picture at run-time. (Using DrawFrameControl etc.)

----------


## R.J. Dunnill

> Yes great. Thanks
> 
> You migrate 1.4 OCX version?
> Do you include bugfixes? Like yesterday fixes.
> When 1.5 OCX version comes out you migrate also?


I have suspended work on the VBFlexGrid.NET for now and have pivoted to migrating the VBFlexGrid to a native ActiveX control written with C++ and ATL. 

A native ActiveX control should work better with traditional ActiveX consumers like VB6, there being no interop or .NET Framework issues, while providing 64-bit compatibility for modern Office.

RD

----------


## Krool

Update released.

Included the ColSortArrowAlignment property, which is either left or right (default). This way it's explicit and cleaner.

Also, there was a bug in the DoubleBuffer property when changing RightToLeft/RightToLeftLayout at run-time.

The DoubleBufferDC is initially correctly setup thanks to CreateCompatibleDC. However, when the layout changes to RTL then the DoubleBufferDC was not updated.
Now, it's set via SetLayout API to LAYOUT_RTL or 0 on WM_STYLECHANGED to fix this.

----------


## Krool

I'm having the idea of including a 'ComboModeCalendar' which has as drop-down client a SysMonthCal32.
However, parsing the date to the MonthView is done with IsDate() and CDate(). If date is invalid it has then today's date as current selection in the drop-down window.
Problem is how to put back the date into text?

I'm thinking of a ComboFormat property which can be set. If empty it just passes Text = Date. Else uses Format$().

Or is it too much and discard the idea? The vsFlexGrid also does not have it.
Though I could find useful use for such a mode..

----------


## DaveDavis

> I'm having the idea of including a 'ComboModeDTPicker' which has as drop-down client a SysMonthCal32.
> However, parsing the date to the MonthView is done with IsDate() and CDate(). If date is invalid it has then today's date as current selection in the drop-down window.
> Problem is how to put back the date into text?
> 
> I'm thinking of a ComboFormat property which can be set. If empty it just passes Text = Date. Else uses Format$().
> 
> Or is it too much and discard the idea? The vsFlexGrid also does not have it.
> Though I could find useful use for such a mode..


I suggest a public enum and Format$ with an optional separator string "-" or "/":


```
Public Enum DateFormatEnum

    YMD = 0 'YYYY-MM-DD
    MDY = 1 'MM-DD-YYYY
    DMY = 2 'DD-MM-YYYY
    System = 3

End Enum
```

----------


## Krool

> I suggest a public enum and Format$ with an optional separator string "-" or "/":
> 
> 
> ```
> Public Enum DateFormatEnum
> 
>     YMD = 0 'YYYY-MM-DD
>     MDY = 1 'MM-DD-YYYY
>     DMY = 2 'DD-MM-YYYY
> ...


Thanks for feedback. I may consider just to cast .EditText = Date from the calendar. (System format then)
The app can use the ValidateEdit event to modify .EditText with a Format of choice before the commit to the cell is done.

----------


## Krool

Update released.

Included enum FlexComboModeCalendar.



To ensure unique format you may put following in ValidateEdit event.


```
If Cancel = False Then
    ' Ensure unique date format before commit. (override possible custom format of the text box)
    VBFlexGrid1.EditText = VBFlexGrid1.ComboCalendarValue
End If
```

Beside ComboCalendarValue, there is also ComboCalendarMinDate/ComboCalendarMaxDate available.

----------


## softv

> Update released.
> 
> Included enum FlexComboModeCalendar.
> 
> ... .. .
> 
> To ensure unique format you may put following in ValidateEdit event.
> 
> 
> ...


Amazing, Krool. The project I am currently working on involves having dates in combo columns. While I was happy filling the combo column cells with dates itself, you have provided a calendar too additionally! Wow!!! Thanks a TON. I think I will be able to find a case to avail the calendar combo too in my project now!

Kind regards.

----------


## softv

> That's an interesting question. So, a visual cue that a dropdown will appear when attempting to edit.
> The not disturbing approach would be not to always show such a "chevron" but only when that cell is selected. Using the RowColChange event.
> However, using a picture with right align and no overlap would be the easiest and dynamically set/clear upon RowColChange.
> Difficult part is to create such a dynamic scaled picture at run-time. (Using DrawFrameControl etc.)


With respect to the above, can there be a boolean property in the vbFlexGrid (say 'ComboVisualCue') so that making it true will show the chevron while mouse hovers on the combo cells? Well, I understand the difficulty factor you mention in drawing the chevron during run-time, but since it is just for one cell only at any point of time, if and when you hit upon a way to achieve drawing the 'dynamically scaled' chevron in an easier manner, you may kindly think of my suggestion for a ComboVisualCue property. Thanks in advance.

And, I take this opportunity to once again thank you for the UseCrLf property in RichTextBox.

Kind regards.

----------


## softv

> Dear krool,
> 
> ... .. . Object browser told me that .colsvisible "Returns the total number of columns or rows visible in the flex grid."
> 
> To understand the above statement from the Object Browser better, I just experimented with a sample 10*10 flex grid. I realised that even if I hide some columns (say 1, 2 and 3) and reduce the width of the grid to show only 2 columns (i.e. only column 0 and column 4), then also .colsvisible will return 5 and not 2. Is it so by design? Just a clarification. Thats all. 
> 
> .rowsvisible also behaves similarly with a similar experiment as above. So, just wanted to clarify whether .colsvisible and .rowsvisible are designed to report values in the above manner only. ... .. .


I await your clarification on the above, Krool. In other words, suppose I have 20 columns in a grid; I set '.ColHidden = True' for  columns 2 to 19; make columns 1 and 20 only visible to user, then also .ColsVisible reports 20 and not 2? Is that correct?

Kind regards.

----------


## Krool

> I await your clarification on the above, Krool. In other words, suppose I have 20 columns in a grid; I set '.ColHidden = True' for  columns 2 to 19; make columns 1 and 20 only visible to user, then also .ColsVisible reports 20 and not 2? Is that correct?
> 
> Kind regards.


20 are count before the first "non-visible".
Technically it is correct. What's your need?

----------


## softv

> 20 are count before the first "non-visible".
> Technically it is correct. What's your need?


Dear Krool,

Kindly please consider the 2 cases (Case 1 and Case 2) in the following code, for a 20 columns grid. As mentioned by me (in two of the comments in the following code), .ColsVisible prints "20" in both cases, whereas logically I was expecting only "2" to be printed, since I have hidden the other 18 columns. In other words, in my form itself, only 2 columns from the grid will be visible in both the cases.

So, I am honestly not able to understand why .ColsVisible should print "20" and not "2"? Is printing "20" only technically correct by design itself? I mean, .ColsVisible will always ignore hidden columns in its count? I just want your clarification/confirmation on this. Thanks.



```
  For i = 2 To 19 'i.e. I have made 0th and 1st indexed columns alone to be visible in the grid. I have kept other columns hidden by setting .ColHidden = true for them
    flx1000.ColHidden(i) = True
  Next i
  flx1000.TextMatrix(0, 0) = "Column 0"
  flx1000.TextMatrix(0, 1) = "Column 1"
  Debug.Print vbCrLf
  Debug.Print "No. of visible columns in flx1000, in Case 1 = ", flx1000.ColsVisible
  'the above prints "20" and not "2"
  
  With flx1000
    .ColHidden(.Cols - 1) = False '19th indexed column is made visible again
    For i = 1 To 18 'i.e. I have made 0th and 19th indexed columns (in other words, first and last columns) alone to be visible in the grid. I have kept 1st to 18th indexed columns hidden
      .ColHidden(i) = True
    Next i
    .TextMatrix(0, 0) = "Column 0"
    .TextMatrix(0, 19) = "Column 19"
  End With
  Debug.Print "No. of visible columns in flx1000, in Case 2 = ", flx1000.ColsVisible
  'the above also prints "20" and not "2"
```

Kind regards.

*EDIT-1* (to add further more clarity [hopefully] to my query):
Suppose my code is just the following one line alone (_i.e. completely ignoring the above code and the 2 cases in it_), then, if I keep the width of my *20 columns grid* in such a way that the first 2 columns alone are fully visible in my form, then flx1000.ColsVisible prints "2" which is correct, because out of the 20 columns, I have kept the width of the grid in such a way that the first 2 columns alone are fully visible in my form. 


```
  Debug.Print "No. of visible columns in flx1000 = ", flx1000.ColsVisible
  'this prints "2" which is correct
```


Now, suppose I keep the width of my *20 columns grid* in such a way that the first 5 columns alone are fully visible in my form. Then, flx1000.ColsVisible prints "5" which is again correct, because out of the 20 columns, I have kept the grid's width in such a way that the first 5 columns (0th to 4th indexed columns) alone are fully visible in my form. 


But, if I *hide columns 1 to 2* (i.e. for 1st and 2nd indexed columns, I set .ColHidden = True) and keep the width of my *20 columns grid* in such a way that only 5 columns are visible (i.e. the* 0th, 3rd, 4th, 5th and 6th indexed columns are only fully visible*), then flx1000.ColsVisible prints "7" (and not "5") which, personally for me, sounds logically incorrect since I have already kept the width of the grid in such a way that only 5 columns are fully visible. Please see screenshot below.



The thing is that _though ".ColHidden" has been set to "True" for 1st and 2nd indexed columns_, they have also been included in the .ColsVisible count. Please see code below. But, if this is how .ColsVisible is set to behave technically, by design, then no issues at all. But, I just wanted a confirmation on that. That's all. Nothing else. Thanks. 



```
  With flx1000
    For i = 1 To 2
      .ColHidden(i) = True
    Next i
    .TextMatrix(0, 0) = "Column 0"
    .TextMatrix(0, 1) = "Column 1"
    .TextMatrix(0, 2) = "Column 2"
    .TextMatrix(0, 3) = "Column 3"
    .TextMatrix(0, 4) = "Column 4"
    .TextMatrix(0, 5) = "Column 5"
    .TextMatrix(0, 6) = "Column 6"
    Debug.Print vbCrLf, Now
    Debug.Print "No. of visible columns in flx1000 = ", .ColsVisible
  End With
  'the above prints 7 and not 5
```

Kind Regards.

----------


## Krool

> Dear Krool,
> 
> Kindly please consider the 2 cases (Case 1 and Case 2) in the following code, for a 20 columns grid. As mentioned by me (in two of the comments in the following code), .ColsVisible prints "20" in both cases, whereas logically I was expecting only "2" to be printed, since I have hidden the other 18 columns. In other words, in my form itself, only 2 columns from the grid will be visible in both the cases.
> 
> So, I am honestly not able to understand why .ColsVisible should print "20" and not "2"? Is printing "20" only technically correct by design itself? I mean, .ColsVisible will always ignore hidden columns in its count? I just want your clarification/confirmation on this. Thanks.
> 
> 
> 
> ```
> ...


That's discuss-able what is "correct".
However, the behavior is similar to the .ColIsVisible property.
Check this out in MS(H)FlexGrid what it prints on a column that is "hidden" (ColWidth = 0) but between two "visible" cols.
It returns True..

----------


## softv

> That's discuss-able what is "correct".
> However, the behavior is similar to the .ColIsVisible property.
> Check this out in MS(H)FlexGrid what it prints on a column that is "hidden" (ColWidth = 0) but between two "visible" cols.
> It returns True..


Oh okay, Krool. So, it is like that, by design. Understood. No issues then. Thanks a TON.

Kind regards.

----------


## R.J. Dunnill

Deleted

----------


## Krool

Update released.

Thanks to inspiration by softv I introduced now the ComboCue property.

It needs to be set at run-time to either 0 - None, 1 - DropDown or 2 - Button.

The demo project was updated to use this new functionality.



This is how it needs to be set. As you see below the ComboCue and the actual ComboMode for editing are independent of each other.
So, it is the app responsobility to apply the correct ComboCue upon RowColChange event.



```
Private Sub VBFlexGrid1_RowColChange()
' The combo cue can only be displayed on the current cell.
If VBFlexGrid1.Row >= VBFlexGrid1.FixedRows Then
    Select Case VBFlexGrid1.Col
        Case COL_CALENDARVALIDATION, COL_COMBODROPDOWN, COL_COMBOEDITABLE
            VBFlexGrid1.ComboCue = FlexComboCueDropDown
        Case COL_COMBOBUTTON
            VBFlexGrid1.ComboCue = FlexComboCueButton
        Case Else
            VBFlexGrid1.ComboCue = FlexComboCueNone
    End Select
Else
    VBFlexGrid1.ComboCue = FlexComboCueNone
End If
End Sub
```

The new hit result enum FlexHitResultComboCue helps to identify the graphical cue.

However, it is not only a cue. It makes it also easier to start editing.
When a cue is displayed and you click on it then the editing is started and the drop-down list will be shown.

The new edit reason enums FlexEditReasonComboCueClick, FlexEditReasonComboCueDblClick and FlexEditReasonComboCueF4 helps for this.

What's missing (for now):
Like for ComboButtonValueDisabled maybe a disabled graphical cue might be helpful.
For ComboCueDropDown the alt-down arrow key may also start editing. (enum FlexEditReasonComboCueAltKey ?)
Hot-tracking for the graphical cue.

----------


## softv

> Update released.
> 
> Thanks to inspiration by softv I introduced now the ComboCue property.
> 
> It needs to be set at run-time to either 0 - None, 1 - DropDown or 2 - Button.
> 
> The demo project was updated to use this new functionality.
> 
> 
> ...


Dear krool,

*Infinite Thanks to God. Infinite Thanks to you*. The cue and the provision for easier editing are excellent! Absolutely Excellent!

God is Great. Just yesterday only I was thinking of writing to you today, requesting for the ComboCalendar to pop down immediately on a single click, if at all possible. And, to my pleasant surprise, you have paved the way for the same already! Great, krool. Great. Through hot-tracking (which you have kept in your pipeline), I was able to just single click (much similar to combo boxes) and make the ComboCalendar to pop down. i.e. Hover -> See the Cue -> Click the Cue -> Pop Down. That's all. 

I just tried a similar code as the one you have given above, in the 'Mouse_Move event' (after MouseTrack = true) of the gird, just for a single Combo Cell, and I could make the ComboCue appear on mouse hover and thereafter the ComboCalendar to pop down with a single click on the ComboCue. *Thanks in TONs* again*.* Of course I would still await your ideal and professional approach to achieve the hot-tracking of ComboCue. As of now, I am just informing you that I experimented, found it working for a single Combo cell and my joy and gratitude knew no bounds.  :Smilie: . For the time being, I will try to extend my logic to cover any Combo cell and use the same. Once you release your own perfect hot-tracking code, I would adopt the same, of course, obviously.

And, until I extend my abovementioned logic, I will continue using my current code (as given below) for achieving the ComboCalendar to pop down (with a single click on the Cue area). I am having the following code in the 'CellClick' event of a grid (say flx1, whose .ColComboMode(1) = FlexComboModeCalendar). There must be a better way of course (than the following code) but the following code itself suits my requirements. You must be able to suggest a better way though.



```
If col = 1 Then
    flx1.StartEdit
    Call MouseClick 'simulates a single left click on the cell's ComboCue.
End If
```

Apart from 'mouse hover' ComboCue, personally, for my own requirements, I thought that perhaps having the ComboCue permanently on the topmost cell of a ComboColumn (i.e. in the top row alone) also would be helpful, from users' point of view. That is also possible for me to achieve now with your ComboCue property.  :Smilie: . *Thanks a TON* again.

May be a boolean property (say 'ComboCueInTopRow') to do the above automatically would be helpful too but this is just a very small and random thought. 

Well, once again thanking you, in TONS - not only for ComboCue, but for every bit of matchless goodness you have given to this world society through your free controls. *God Bless you! God Bless all!*

Kind regards.

----------


## Krool

softv,
With hot-tracking I mean to hotlight the button.

What you mean is to display the ComboCue on the MouseRow/Col instead of the current focused Row/Col, right?

How did you make it? Change code?

----------


## Krool

> ```
> If col = 1 Then
>     flx1.StartEdit
>     Call MouseClick 'simulates a single left click on the cell's ComboCue.
> End If
> ```


Make instead of Call MouseClick the following.


```
flx1.ComboButtonValue = FlexComboButtonValuePressed
```

----------


## softv

> softv,
> With hot-tracking I mean to hotlight the button.
> 
> What you mean is to display the ComboCue on the Mouse Row/Col instead of the current focused Row/Col, right?
> 
> How did you make it? Change code?


Dear Krool,

How divinely fortunate that I thought that by 'Hot-Tracking' you meant 'Mouse Hover' ComboCue! Because, because of that only, I started writing code to show the ComboCue on MouseHover. 

Well, first of all, sorry for the delay in posting this reply. The reason was when you posted your above reply I had tried writing code locally only. i.e. for showing ComboCue (on mouse hover) for any particular grid's Combo cells in my own forms only (via the MouseMove event). I had not written a global code which would show the ComboCue for any ComboCell in any grid in any form in any project. Since you asked me 'Change code?', I just presumed it to mean that you are asking me whether I changed the code in the VBFlexGrid.ctl itself. And, since you asked me 'How did you make it?', I thought I will do the global code also and provide both the codes to you (i.e. local and global). Hence, the delay.

The *local code* (in the 'MouseMove' event of any particular grid in a form). 


```
  With VBFlexGrid1
    'Debug.Print .MouseCol, .ColComboMode(.MouseCol)
    Select Case .ColComboMode(.MouseCol)
    Case FlexComboModeCalendar, FlexComboModeDropDown, FlexComboModeEditable
      .Row = .MouseRow
      .Col = .MouseCol
      .ComboCue = FlexComboCueDropDown
    Case Else
      .ComboCue = FlexComboCueNone
    End Select
  End With
```

The *global code* in the WM_MouseMove of WindowProcControl function in VBFlexGrid.ctl


```
        Dim flx As Control
        Set flx = GetControlFromhWnd(hWnd) 
        'Debug.Print "here outside", flx.Name, flx.Row, flx.Col, UserControl.Ambient.DisplayName
        With flx
          Select Case .ColComboMode(.MouseCol)
          Case FlexComboModeCalendar, FlexComboModeDropDown, FlexComboModeEditable
            'Debug.Print "here inside", Now, .MouseRow, .MouseCol, .ColComboMode(.MouseCol), flx.Name
            .Row = .MouseRow
            .Col = .MouseCol
            .ComboCue = FlexComboCueDropDown
            'Debug.Print "yes"
          Case Else
            .ComboCue = FlexComboCueNone
          End Select
        End With
```


I wrote the global code only because you asked me and thus inspired me. Otherwise, as written already, you are the best one to effect the global code in the right way (in the most ideal, perfect, concise and optimal manner). 

Actually, I have just like that placed the above code before the following line


```
Call ProcessMouseMove(GetMouseStateFromParam(wParam), Get_X_lParam(lParam), Get_Y_lParam(lParam))
```

I don't know whether placing my global code in the above manner would affect the call to 'ProcessMouseMove' or not. I see that my global code is working for me as of now. But, as written earlier, I await your ideal code (placed ideally). Thanks in advance. 

Thanks a TON once again for all your free controls. God Bless you! God Bless all!

Kind regards.

*EDIT-1*:
The following "seems" to be enough (instead of "Set flx = GetControlFromhWnd(hWnd)", where GetControlFromhWnd is my own function). So, I am quite happy that I could get a much faster/straightforward way to get the control's reference. There still might be a more straightforward way to get the control's reference, which I am missing somehow. So, I await your most ideal and optimal code eagerly.  :Smilie: 


```
Set flx = Parent().Controls(UserControl.Ambient.DisplayName)
```

*EDIT-2:*
On further exploring, I understood and learnt that the following simple and straightforward code itself will do (as the *global code*), instead of my above-given global code. Thanks Krool, for inspiring persons like me to explore and learn more.


```
Select Case ColComboMode(MouseCol)
Case FlexComboModeCalendar, FlexComboModeDropDown, FlexComboModeEditable
  Row = MouseRow
  Col = MouseCol
  ComboCue = FlexComboCueDropDown
Case Else
  ComboCue = FlexComboCueNone
End Select
```

Kind regards.

----------


## softv

> Make instead of Call MouseClick the following.
> 
> 
> ```
> flx1.ComboButtonValue = FlexComboButtonValuePressed
> ```


Worked like a charm! Thanks a TON, as always.  :Smilie: 

Kind regards.

----------


## Krool

Update released. Included the ComboCueRow/ComboCueCol property which lets you determine where to display the combo cue.

It's possible to reset the ComboCueRow/ComboCueCol to -1 so that it is always the current focused cell. (equal .Row/.Col)

To have this "hot-tracking" behavior. Ensure VBFlexGrid.MouseTrack is True and have following code.


```
Private Sub VBFlexGrid1_MouseLeave()
VBFlexGrid1.ComboCue = FlexComboCueNone
VBFlexGrid1.ComboCueRow = -1
VBFlexGrid1.ComboCueCol = -1
End Sub

Private Sub VBFlexGrid1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
VBFlexGrid1.HitTest X, Y
If VBFlexGrid1.HitResult = FlexHitResultNoWhere Then
    VBFlexGrid1.ComboCue = FlexComboCueNone
    VBFlexGrid1.ComboCueRow = -1
    VBFlexGrid1.ComboCueCol = -1
    Exit Sub
End If
If VBFlexGrid1.HitRow >= VBFlexGrid1.FixedRows Then
    Select Case VBFlexGrid1.HitCol
        Case COL_CALENDARVALIDATION, COL_COMBODROPDOWN, COL_COMBOEDITABLE
            VBFlexGrid1.ComboCue = FlexComboCueDropDown
            VBFlexGrid1.ComboCueRow = VBFlexGrid1.HitRow
            VBFlexGrid1.ComboCueCol = VBFlexGrid1.HitCol
        Case COL_COMBOBUTTON
            VBFlexGrid1.ComboCue = FlexComboCueButton
            VBFlexGrid1.ComboCueRow = VBFlexGrid1.HitRow
            VBFlexGrid1.ComboCueCol = VBFlexGrid1.HitCol
        Case Else
            VBFlexGrid1.ComboCue = FlexComboCueNone
            VBFlexGrid1.ComboCueRow = -1
            VBFlexGrid1.ComboCueCol = -1
    End Select
Else
    VBFlexGrid1.ComboCue = FlexComboCueNone
    VBFlexGrid1.ComboCueRow = -1
    VBFlexGrid1.ComboCueCol = -1
End If
End Sub
```

----------


## softv

> Update released. Included the ComboCueRow/ComboCueCol property which lets you determine where to display the combo cue.
> 
> It's possible to reset the ComboCueRow/ComboCueCol to -1 so that it is always the current focused cell. (equal .Row/.Col) ... .. .


Thanks a TON, krool. 

Earlier, while I was exploring, I tried HitTest (in my global code) also but when I set the row and col, it started highlighting the rows and columns until the cell where the ComboCue got displayed. So, though the ComboCue got displayed, it was highlighting many other cells upto it. Now, I understand why. Thanks for the ComboCueRow and ComboCueCol properties. I will try with them now. I think the highlighting issue won't arise now (in my global code). Thanks again.

Kind regards.

*EDIT-1*:
yes, highlighting issue does not arise while using ComboCueRow and ComboCueCol after HitTest. Thanks.
And, I just now see that you have added one more enhancement (if I am right, this was not present when I first posted my above message), which is "Included the CellComboCue property. (plus corresponding enum FlexCellComboCue). This let's you define a fixed combo cue for an individual cell or a range of cells.". *This is* *fantastic*. If my understanding of what you have written is correct, I think with this I can now show a ComboCue always for the cells at the top row. Thank you soooooooooooooooo much. Let me try it out and write back.

Kind regards.

----------


## Krool

> *EDIT-1*:
> yes, highlighting issue does not arise while using ComboCueRow and ComboCueCol after HitTest. Thanks.
> And, I just now see that you have added one more enhancement (if I am right, this was not present when I first posted my above message), which is "Included the CellComboCue property. (plus corresponding enum FlexCellComboCue). This let's you define a fixed combo cue for an individual cell or a range of cells.". *This is* *fantastic*. If my understanding of what you have written is correct, I think with this I can now show a ComboCue always for the cells at the top row. Thank you soooooooooooooooo much. Let me try it out and write back.
> 
> Kind regards.


Yes, the ComboCue is dynamic. Like for focused/hot-track.
The new CellComboCue can be used to place fixed spots or even an entire column (set FillStyle to repeat for effectiveness) to a combo cue.

----------


## softv

> ... .. . place fixed spots or even an entire column (set FillStyle to repeat for effectiveness) to a combo cue.


just a while ago, tried it. Its all SUPERB. So, all the requirements I requested for have been provided by you, as of now. *Infinite thanks*.
Thanks for the tip on FillStyle. Otherwise, I would have forgotten. You have magnanimously provided (and keep providing) so many properties and functions for each free control that sometimes I forget about one or more of them.  :Smilie: 

Kind regards.

----------


## Krool

Update again for combo cue.

Added enum FlexComboCueDisabledDropDown and FlexComboCueDisabledButton.

This is just to reflect the counterpart for FlexComboButtonValueDisabled. (Edit portion possible but dropdown button deactivated)

The new hit result FlexHitResultComboCueDisabled helps to differentiate it. The normal one triggers an edit operation and this here just eat's the button down.

----------


## Krool

Experimental feature 'AllowUserFreezing'.

Please test and report any behavior mismatch or suggestions.

After feedback it will be integrated into the current version.

Thanks

----------


## DaveDavis

> Update released. Included the ComboCueRow/ComboCueCol property which lets you determine where to display the combo cue.
> 
> It's possible to reset the ComboCueRow/ComboCueCol to -1 so that it is always the current focused cell. (equal .Row/.Col)
> 
> To have this "hot-tracking" behavior. Ensure VBFlexGrid.MouseTrack is True and have following code.
> 
> 
> ```
> Private Sub VBFlexGrid1_MouseLeave()
> ...


After picking a dropdown ComboBox item, focus goes to mouse Cell, should stay at last dropdown cell, logically.

----------


## Krool

> After picking a dropdown ComboBox item, focus goes to mouse Cell, should stay at last dropdown cell, logically.


Easy to make. Use .ComboCue and .CellComboCue at the same time. See code below.



```
Private Sub VBFlexGrid1_RowColChange()
Static LastRow As Long, LastCol As Long
VBFlexGrid1.Cell(FlexCellComboCue, LastRow, LastCol) = FlexComboCueNone
If VBFlexGrid1.Row >= VBFlexGrid1.FixedRows Then
    Select Case VBFlexGrid1.Col
        Case COL_CALENDARVALIDATION, COL_COMBODROPDOWN, COL_COMBOEDITABLE
            VBFlexGrid1.Cell(FlexCellComboCue, VBFlexGrid1.Row, VBFlexGrid1.Col) = FlexComboCueDropDown
        Case COL_COMBOBUTTON
            VBFlexGrid1.Cell(FlexCellComboCue, VBFlexGrid1.Row, VBFlexGrid1.Col) = FlexComboCueButton
        Case Else
            VBFlexGrid1.Cell(FlexCellComboCue, VBFlexGrid1.Row, VBFlexGrid1.Col) = FlexComboCueNone
    End Select
Else
    VBFlexGrid1.Cell(FlexCellComboCue, VBFlexGrid1.Row, VBFlexGrid1.Col) = FlexComboCueNone
End If
LastRow = VBFlexGrid1.Row
LastCol = VBFlexGrid1.Col
End Sub

Private Sub VBFlexGrid1_MouseLeave()
VBFlexGrid1.ComboCue = FlexComboCueNone
VBFlexGrid1.ComboCueRow = -1
VBFlexGrid1.ComboCueCol = -1
End Sub

Private Sub VBFlexGrid1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
VBFlexGrid1.HitTest X, Y
If VBFlexGrid1.HitResult = FlexHitResultNoWhere Then
    VBFlexGrid1.ComboCue = FlexComboCueNone
    VBFlexGrid1.ComboCueRow = -1
    VBFlexGrid1.ComboCueCol = -1
    Exit Sub
End If
If VBFlexGrid1.HitRow >= VBFlexGrid1.FixedRows Then
    Select Case VBFlexGrid1.HitCol
        Case COL_CALENDARVALIDATION, COL_COMBODROPDOWN, COL_COMBOEDITABLE
            VBFlexGrid1.ComboCue = FlexComboCueDropDown
            VBFlexGrid1.ComboCueRow = VBFlexGrid1.HitRow
            VBFlexGrid1.ComboCueCol = VBFlexGrid1.HitCol
        Case COL_COMBOBUTTON
            VBFlexGrid1.ComboCue = FlexComboCueButton
            VBFlexGrid1.ComboCueRow = VBFlexGrid1.HitRow
            VBFlexGrid1.ComboCueCol = VBFlexGrid1.HitCol
        Case Else
            VBFlexGrid1.ComboCue = FlexComboCueNone
            VBFlexGrid1.ComboCueRow = -1
            VBFlexGrid1.ComboCueCol = -1
    End Select
Else
    VBFlexGrid1.ComboCue = FlexComboCueNone
    VBFlexGrid1.ComboCueRow = -1
    VBFlexGrid1.ComboCueCol = -1
End If
End Sub
```

----------


## DaveDavis

> Easy to make. Use .ComboCue and .CellComboCue at the same time. See code below.
> 
> 
> 
> ```
> Private Sub VBFlexGrid1_RowColChange()
> Static LastRow As Long, LastCol As Long
> VBFlexGrid1.Cell(FlexCellComboCue, LastRow, LastCol) = FlexComboCueNone
> If VBFlexGrid1.Row >= VBFlexGrid1.FixedRows Then
> ...


Yes. work as EXPECT. The hot tracking cue will shift to new mouse-on cell after selection, not the current editing cell because mouse is no more on last editing cell...It could confuse user on which is last editing cell.
IMO, keep cue indication is an another option, I prefer.

----------


## softv

> Experimental feature 'AllowUserFreezing'.
> 
> Please test and report any behavior mismatch or suggestions.
> 
> After feedback it will be integrated into the current version.
> 
> Thanks


Thanks for this easy mode of freezing rows and/or columns. I tried each of the 'AllowUserFreezing' values (0 to 3) and all of them performed as expected. 

Kind regards.

----------


## softv

Dear Krool,

The fixed ComboCue (and DynamicCue on MouseMove too) is visible only if 'AllowUserEditing' is true. Is it possible to have fixed ComboCue visible even if 'AllowUserEditing' is false? Or, is it possible to have AllowUserEditing for a particular column alone?

Actually, in my grid, I want to allow only one column's cells (say 1st column's) to be editable by user. All other columns are non-editable. So, I want to keep 'AllowUserEditing' false and when 1st column cell is clicked, write my own processing code starting with ".StartEdit". But, I want the fixed ComboCue to be visible even before the 1st column cell is clicked. Also, in MouseMove event of 1st column, I want the ComboCues to be shown in the cells of the 1st column (i.e. even when 'AllowUserEditing' is false). Possible?

If not possible, as of now, then what is the best way to allow editing only in 1st column cells and disallow editing in all other columns' cells?

As of now, what I am doing is keeping 'AllowUserEditing' true (so that the ComboCues - both fixed and dynamic - show up normally) and when double-click happens on other columns' cells, I issue a .CancelEdit as follows. 



```
Private Sub flx2_EnterEdit()
  
  If flx2.Col <> 1 Then
    flx2.CancelEdit
  End If
  
End Sub
```

One problem with the above way to disallow editing is that the blue highlight shows up for a micro second, when I double-click on a cell.

1) Is there a "better" way to achieve what I require (than what I am doing)? I feel that there must be surely a better way out.
2) In case if my method is the way out, then how to avoid the blue highlighting for a microsecond? Not a major issue for me but just wish to know if it can be avoided.

Kind regards.

----------


## Arnoutdv

Is there also a BeforeEdit event in which you can cancel the input for given cells?

----------


## Krool

Yes, use the BeforeEdit event. Check Row/Col and set Cancel to True to avoid that the edit will be initiated at all.

----------


## Krool

Update released.

AllowUserFreezing property now included.

Also the new AfterUserFreeze event fires after a user changed the number of frozen rows or columns.
A BeforeUserFreeze event is not included as it makes no sense. There is only 1 solid line for either frozen rows or columns.
So a cancelling is not meaningful as just setting AllowUserFreezing to Row only, Column only or Both is enough.

Included the new AfterUserResizeEnd event.
The AfterUserResize event has a ByRef NewSize As Long parameter where the app can influence the width/height that will be committed. (like in the ListView control)
However, it may be necessary to synchronize something after the new width/height got applied. This is now where the AfterUserResizeEnd fires.

----------


## Krool

Update released.

The escape key now cancels any ongoing divider drag operation.

This change will also be applied to the (yet already outdated) VBFLXGRD14.OCX.

----------


## lizano diaz

> Update released.
> 
> The escape key now cancels any ongoing divider drag operation.
> 
> This change will also be applied to the (yet already outdated) VBFLXGRD14.OCX.


Thanks Krool, what I was wondering is how to do a Drag and Drop per column, also implement the same (per row and column) to another vbflexgrid (from vbFlexgrid1 to VbFlexgrid2)

----------


## Krool

Dumb bug fixed.

SB_PAGE* scrolling now working propertly! (regression since 08-Sep-2021)

This affects mouse scrolling on the scrollbar only. (not page up/down keys)

----------


## Krool

Included the AllowScrollLock property.

When the scroll lock key is toggled on it allows the user to use the arrow keys to scroll.
The new property defaults to False to not break compatibility or causing surprises by an accidently activate scroll lock.
Also the "overhead" of checking the toggled state for vbKeyScrollLock on all arrows keys input is only when AllowScrollLock is set to True.

The behavior is like in Excel, means arrows keys with..
.. shift state 0 and ctrl state 0 will scroll like a SB_LINE*
.. shift state <> 0 and ctrl state 0 will do nothing.
.. shift state 0 and ctrl state <> 0 will scroll like a SB_PAGE*
.. shift state <> 0 and ctrl state <> 0 will behave normal

----------


## Semke

Hi! Krool,

your Grid control seems to be better then the ComponentOne grid control, however ComponentOne  has the facility to print and save as pdf their control with the vsPrinter and vsPDF8 control.

Also SelectionMode has an option  SelectionListBox (so when allowselection = false, the control will work a bit like a listbox, where you can select one row at a time. etc..)

do you have any plans of producing something like that.

----------


## softv

> Included the AllowScrollLock property.
> 
> When the scroll lock key is toggled on it allows the user to use the arrow keys to scroll.
> The new property defaults to False to not break compatibility or causing surprises by an accidently activate scroll lock.
> Also the "overhead" of checking the toggled state for vbKeyScrollLock on all arrows keys input is only when AllowScrollLock is set to True.
> 
> The behavior is like in Excel, means arrows keys with..
> .. shift state 0 and ctrl state 0 will scroll like a SB_LINE*
> .. shift state <> 0 and ctrl state 0 will do nothing.
> ...


Thanks krool for this nice add-on feature.

Kind regards.

----------


## Krool

> Also SelectionMode has an option  SelectionListBox (so when allowselection = false, the control will work a bit like a listbox, where you can select one row at a time. etc..)


Yes, that's planned. (Multi-selection on rows)
The idea is to have a selected state bit for a row. (RWIS_SELECTED)
This comes along then with a RowSelected r/w property and read only SelectedRow/SelectedRows property. (For enum like in vsFlexGrid)

What I'm not sure if I should add a selection mode ListBox/FreeListBox or have another boolean property "MultiSelect" which is only allowed for selection modes ByRow/FreeByRow.
This would keep a possibility open for CLIS_SELECTED maybe. (Multi select columns)
..

----------


## Krool

_removed_

----------


## Krool

Update released.

Included the AllowMultiSelection property. This property can only be set to True for SelectionMode 1 - ByRow or 3 - FreeByRow.

Included the RowSelected/SelectedRow/SelectedRows run-time property. These are automatically set when AllowMultiSelection is set to True.
However, they can be set by code even when AllowMultiSelection is set to False.

Improved AllowSelection property (when set to False) to not restrict..
- ColSel for SelectionMode 1 - ByRow
- RowSel for SelectionMode 2 - ByColumn

To note is that AllowMultiSelection and AllowSelection property are working together and do not restrict each other.
So, in fact it is a legal behavior to have AllowSelection = False and AllowMultiSelection = True.

EDIT:
Below an example to enumerate the selected rows. There are two possible ways.

#1


```
For i = 0 To VBFlexGrid1.Rows - 1
    If VBFlexGrid1.RowSelected(i) = True Then
        Debug.Print "Row: " & i
    End If
Next i
```

#2


```
Dim i As Long
For i = 0 To VBFlexGrid1.SelectedRows - 1
    Debug.Print "Row: " & VBFlexGrid1.SelectedRow(i)
Next i
```

----------


## Krool

Included enum FlexFocusRectFlat for the FocusRect property.
It draws a solid rectangle (BackColorSel) instead of using the DrawFocusRect API.



The border width is determined by the GridLineWidth property and not by influenced by SPI_GETFOCUSBORDERWIDTH/SPI_GETFOCUSBORDERHEIGHT.

----------


## Krool

Update released.

When there are no frozen rows/cols (yet) and there are also no fixed rows/cols the user was not able to "UserFreeze" (AllowUserFreezing = True)

This has been fixed now.

----------


## Krool

Open question:

When GridLines are None or Raised the focus rect is in either case 1 pixel off. That's the same behavior as in MS(H)FlexGrid.
Shall this be fixed? (Not only focus rect, also in-place editing affected)
If yes, silent fix or by another property?

----------


## Elroy

> Open question:
> 
> When GridLines are None or Raised the focus rect is in either case 1 pixel off. That's the same behavior as in MS(H)FlexGrid.
> Shall this be fixed? (Not only focus rect, also in-place editing affected)
> If yes, silent fix or by another property?


Personally, I'd like to see you leave it _exactly_ the same as the Microsoft version.  Or, if you do fix it, _fix it with an option_, possibly with a True/False property that's named something like _FixGridLinesOffset_, and have it default to False.

And here's one rationale for that.  I personally have custom controls that use the MSFlexGrid that have overlay textboxes and comboboxes for data entry.  If/When I completely switch to your controls, I'd like to be able to do it with a straightforward "drop in", with no tweaking whatsoever.

----------


## Krool

Update released.

Included the SheetBorder property.
The default value is True which draws a border around the sheet. (Like MSFlexGrid)
When set to False it draws no such border. (Like MSHFlexGrid)

In vsFlexGrid this 'SheetBorder' specifies just a color, here a boolean.
I found it important to keep full compatibility with MSFlexGrid. Therefore it can't be a color, as the MSFlexGrid uses the fixed pen. (GridColorFixed)

And in vsFlexGrid to have "no border" the dev should set SheetBorder and BackColorBkg to the same color.
Here with the boolean it's truly no border and to behave like a MSHFlexGrid control.

Side question:
Is there a need to customize the appearance of the freeze pane borderlines? (E.g. GridLinesFrozen, GridColorFrozen)
Here I could enhance as no compatibility issue..
Currently it just uses the fixed pen.

----------


## Elroy

> Is there a need to customize the appearance of the freeze pane borderlines? (E.g. GridLinesFrozen, GridColorFrozen)
> Here I could enhance as no compatibility issue..
> Currently it just uses the fixed pen.


Personally, I'll take all the options I can get.  I already subclass the MS ListView to make it do several things it doesn't natively do ... specifically related to the color of things.  I don't use MSFlexGrid nearly as much as I use ListView, but I do use it.  The more options (especially in terms of style and colors), always the better.

----------


## Krool

Update released.




> Personally, I'll take all the options I can get.  I already subclass the MS ListView to make it do several things it doesn't natively do ... specifically related to the color of things.  I don't use MSFlexGrid nearly as much as I use ListView, but I do use it.  The more options (especially in terms of style and colors), always the better.


Thank you. Done. (GridColorFrozen/GridLinesFrozen/GridLineWidthFrozen)

----------


## Krool

EDIT:

The FocusRectWidth property has now a default value of -1, which exposes SPI_GETFOCUSBORDERWIDTH in that case. (affects only FlexFocusRectFlat)

----------


## Elroy

> Another question:
> 
> FocusRectWidth property is recently added for FlexFocusRectFlat.
> 
> That FocusRectWidth has a default value of 1 currently.
> 
> What about changing the default value to -1 and exposing either SPI_GETFOCUSBORDERHEIGHT or SPI_GETFOCUSBORDERWIDTH in that case ? (Either the higher or lesser of these two)


That's getting pretty esoteric for me ... and I'm not sure I've got an opinion at this time.  I certainly don't currently use the FocusRectWidth property, so I've got no opinion on changing how that behaves.  I've certainly got no objection to exposing some read-only properties.

----------


## Krool

> I certainly don't currently use the FocusRectWidth property, so I've got no opinion on changing how that behaves.


Nevermind.

----------


## Krool

Update released.

Bugfix in the internal DrawGrid routine. Merged rows/cols were just discarded partially in the freezing pane.
This is now fixed.

----------


## Krool

> Personally, I'd like to see you leave it _exactly_ the same as the Microsoft version.  Or, if you do fix it, _fix it with an option_, possibly with a True/False property that's named something like _FixGridLinesOffset_, and have it default to False.
> 
> And here's one rationale for that.  I personally have custom controls that use the MSFlexGrid that have overlay textboxes and comboboxes for data entry.  If/When I completely switch to your controls, I'd like to be able to do it with a straightforward "drop in", with no tweaking whatsoever.


I don't see a compatibility break, just a visual difference.

I just released an update so that all places take the offsets now from a central routine to make this more transparent.


```
Private Sub GetGridLineOffsets(ByVal iRow As Long, ByVal iCol As Long, ByRef GridLineOffsets As TGRIDLINEOFFSETS)
' The grid line offsets in MS(H)FlexGrid are hard-coded for all scenarios as per below values.
' However, in future these could be fixed by an opt-in property to get the correct values.
GridLineOffsets.LeftTop.CX = 0
GridLineOffsets.LeftTop.CY = 0
GridLineOffsets.RightBottom.CX = 1
GridLineOffsets.RightBottom.CY = 1
End Sub
```

Currently these are the values to be "visual compatible" with the MS(H)FlexGrid.

However, fixing this in future with an "FixGridLineOffsets" is perhaps the best idea.

----------


## Daniel Duta

> Is there also a BeforeEdit event in which you can cancel the input for given cells?


I know you've been using the vsflexgrid for a long time and you have a good knowledge of its functionality in terms of events, methods and properties. I wonder to what extent this new control manages to reproduce the vsflexgrid features. Does this control allow you to merge cells, autosize rows and columns or other stuff such as Sort, BindToArray, GetMergedRange, LoadArray, SaveGrid etc. ? I am curious which is your opinion.

----------


## Arnoutdv

I've not replaced the vsFlexGrid by the vbFlexGrid. There is also no need for me, because the vsFlexGrid does what it needs to do.

My experience with the vbFlexGrid is thus very limited.

----------


## Krool

Update released.

FixGridLineOffsets property included. It defaults to False to match behavior of the MS(H)FlexGrid control.

My own "todo" list is almost finished now so I may release OCX version 1.5 soon..

----------


## softv

> Update released.
> 
> FixGridLineOffsets property included. It defaults to False to match behavior of the MS(H)FlexGrid control.
> 
> My own "todo" list is almost finished now so I may release OCX version 1.5 soon..


Looking forward to 1.5, krool. Thanks a TON.

Kind regards.

----------


## Krool

One open question. (concerning right-to-left)

The Alignment enum FlexAlignmentGeneral says that numbers and dates are left-aligned and otherwise right-aligned.
When RightToLeftLayout is True this is of course flipped.

However, when only RightToLeft is True (and RightToLeftLayout is False, means only RTL-Reading) then it is up to the coder to either right or left align accordingly.
But for FlexAlignmentGeneral there is no way to flip the alignment in that case.

Should I include an 'FlexAlignmentGeneralMirror' enum to have a solution in that case ?

----------


## Krool

> One open question. (concerning right-to-left)
> 
> The Alignment enum FlexAlignmentGeneral says that numbers and dates are left-aligned and otherwise right-aligned.
> When RightToLeftLayout is True this is of course flipped.
> 
> However, when only RightToLeft is True (and RightToLeftLayout is False, means only RTL-Reading) then it is up to the coder to either right or left align accordingly.
> But for FlexAlignmentGeneral there is no way to flip the alignment in that case.
> 
> Should I include an 'FlexAlignmentGeneralMirror' enum to have a solution in that case ?


I answer this to myself now.
Having 2 General enums causes other issues.
So I decided to include a new property 'MirrorAlignGeneral'.

----------


## Krool

Included now ComboButtonAlignment/ColComboButtonAlignment property.
This may be helpful for right-to-left properties. For RightToLeftLayout = True it should stay as 1 - Right as the mirror placement flips it anyway. So this is just a need for rtl reading only.

----------


## Krool

OCX 1.5 released.

----------


## softv

> OCX 1.5 released.


Thanks a lot, Krool.

----------


## 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 the post #1 in this thread.

----------


## softv

*Dear all,*

Is it possible to bind (in some way or other) the *VBFlexGrid* to a database table so that as I scroll the grid, only the data pertaining to the visible rows get displayed in the VBFlexGrid? The other rows should not hold any data internally. Otherwise, I see (via task manager) that the memory used jumps up greatly. For my purposes, the non-visible rows not containing data is not an issue. 


In fact, if the rows of the grid can be always set and maintained to a fixed value, equal to the number of visible rows (say 30),  but *corresponding data* can still be *shown* (_from the database table_) *just for visible rows alone* [with col(0) showing the varying row(record) number, say 31 to 60 or 1100 to 1029 or 329001 to 329030 or ... or ..., as user scrolls the grid] that is even more ideal since I see that even empty rows (without any data) occupy a chunk of memory. 


Of course, I can write code to achieve the above (I have some ideas on how to go about it) but just wanted to know whether any direct or a 'short and easy' method is already available so that I need not invest time to write my aforesaid code (which I think I might take some considerable time to develop, to get it running to perfection, since I am not anywhere near the experts like many of you here, to churn out the fastest and shortest codes, that too in so quick a time!, whenever the need arises).

Thanks in advance.

And, I take this opportunity to once again thank you Krool and all other great souls like you here in this Forum - Olaf and many more... *God bless you all!*


Kind regards.

----------


## Krool

I noticed a bug for 'FlexAlignmentGeneral'.

Currently it right aligns for numbers and left aligns for text.

However, it should right align for numbers and dates !

It's embarrassing that it could withstand since initial release.. so now it is fixed.

Generic sorting will still sort only numbers and strings. (no dates; like in MS(H)FlexGrid)
So keep using FlexSortDateAscending/FlexSortDateDescending for dates.

----------


## Schmidt

> I noticed a bug...


Found an additional one in 1.5.1, I think - not showing a HScrollbar, when .Cols < 3 
e.g. with Cols = 2 ... and ColWidth(1) via code set larger than the Grid-Width -
(generally, not only when working in IVBFlexDataSource-Mode).

Olaf

----------


## Krool

> Found an additional one in 1.5.1, I think - not showing a HScrollbar, when .Cols < 3 
> e.g. with Cols = 2 ... and ColWidth(1) via code set larger than the Grid-Width -
> (generally, not only when working in IVBFlexDataSource-Mode).
> 
> Olaf


How is FixedCols set?

----------


## Schmidt

> How is FixedCols set?


The Fixed-Props are at their defaults: 1

Olaf

----------


## Krool

> The Fixed-Props are at their defaults: 1
> 
> Olaf


Ok then it's by design to have no H-Scrollbar since there is only 1 scrollable col, which extends beyond client rect. It simply can't scroll..

----------


## Schmidt

> Ok then it's by design to have no H-Scrollbar since there is only 1 scrollable col, which extends beyond client rect. It simply can't scroll..


Right, sorry for the noise... 
(forgot, that the Flex does not support Pixel-based HScrolling, but scrolls "integral, whole Cols" instead)

Olaf

----------


## jffortier

Hi,

(Newbie here !!)

I notice a change in behaviour with msflexgrid, this code was written 30 years ago by someone else for the old grid32. I converted it to msflexgrid, but since the redraw screen on win10 on some occasion was flashy and long, I decided to test this version.

In the previous control, a fix column will obey the Grid1.ColAlignment(0) = 4 (FlexAlignmentCenterCenter) , but with the current it's not, I remove the fix column = 1 argument and it works.

Maybe there's another function to call to align a fix column? but the way I see it, it's not a direct replacement then !

Thanks

----------


## Krool

> Hi,
> 
> (Newbie here !!)
> 
> I notice a change in behaviour with msflexgrid, this code was written 30 years ago by someone else for the old grid32. I converted it to msflexgrid, but since the redraw screen on win10 on some occasion was flashy and long, I decided to test this version.
> 
> In the previous control, a fix column will obey the Grid1.ColAlignment(0) = 4 (FlexAlignmentCenterCenter) , but with the current it's not, I remove the fix column = 1 argument and it works.
> 
> Maybe there's another function to call to align a fix column? but the way I see it, it's not a direct replacement then !
> ...


There is ColAlignment and FixedAlignment.
ColAlignment overwrites the FixedAlignment when FixedAlignment is not explicitly set.
Can you share the code so I can replicate the potential issue?
Thanks

----------


## lizano diaz

First of all, wish you a great new year.
Ask him about drag and drop between columns, outside and inside a vbgrid to another vbgrid (grid1 to grid2) and about the merged cell, to be able to build a kanban. Thanks a lot

----------


## Eduardo-

Hello Krool,

I'm testing the VBFlexGrid, I'm doing it with the ocx version (latest, 1.5), and I found that when there are no rows, the AddItem method raises an error.
To test it, with a new added VBFlexGrid control to a form, this is the code:



```
Private Sub Form_Load()
    VBFlexGrid1.FixedRows = 0
    VBFlexGrid1.Rows = 0
End Sub

Private Sub Command1_Click()
    VBFlexGrid1.AddItem "AA" & vbTab & "BB"
    VBFlexGrid1.Refresh
End Sub
```

The same code works with the MSHFlexGrid without raising an error.

Also, I noticed that if I don't add the VBFlexGrid1.Refresh, the grid is not visually updated until I click on it, unlike the MSHFlexGrid.

I don't know whether these differences are on purpose or a bug.
Thanks.

----------


## Krool

> Hello Krool,
> 
> I'm testing the VBFlexGrid, I'm doing it with the ocx version (latest, 1.5), and I found that when there are no rows, the AddItem method raises an error.
> To test it, with a new added VBFlexGrid control to a form, this is the code:
> 
> 
> 
> ```
> Private Sub Form_Load()
> ...


Good catch. That's a bug. Fixed now.
Thanks

----------


## JT870

Hi Krool,
   I don't know how to make a allowed formated input,for example, allow a float number with "+" or "-" or a scientific ... can I?
   Thanks in advance.

----------


## JT870

Hi Krool,
   How  to make a formated input , such as  add a float number with "+", or "-", or a scientific ...
   Thanks.

----------


## Black_Storm

hi,i have a simple form with adodc control and this gird

i want set datasource of this gird to adodc1 and then

how can add new record synced with grid or delete or refresh or edit used by grid

i did not find any sample about example use access data with this girl in download folder.

any body can send a simple project to can work with access binded to gird here ?

----------


## Schmidt

> ...how can add new record synced with grid or delete or refresh or edit used by grid


The Grid supports an IVBFlexDataSource interface for such Binding-scenarios.
This interface operates only on "simple string-types" (not specific Recordset-Types).
So, you can bind not only Recordsets, but also "any 2D-Array" or "JSON-Collection" or whatever.

A small example-implementation (which does a binding to SQLite-Recordsets) can be studied here:
https://www.vbforums.com/showthread....te-Recordsets) 

Olaf

----------


## Black_Storm

why datasource property designed in this grid control but i should be use like as ur class and use IVBFlexDataSource ?!!
if  this property designed  for bind to any data control so how can use it ? any sample?
do u have any simple sample to i jst set this property to a adodc1?


i did see your topic before i ask my question here but i don't want fill my grid with coding and run query for each update or delete and like these actions,i want use like as data grid and binded automatically to adodc1

for example can i set this grid.DataSource = adodc1 in design and then just work with adodc1 like as adodc1.recordset.addnew or update or refresh or movefirtst move last and etc automatically binded to gird ?and i did not see retrieve field on rightclick on grid or change captions or fields binded and like these options...

so i think i can use bind between this grid and adodc or ... just with coding and do I have to do this for anything I need?  .
if u know any datagrid (not like as vhflexgrid) to support cool theme (skins)  and righttoleft layout?

i dont know yet maybe this grid support change skin or theme with coding if possible any sample code?
i found some but they have problem with righttoleft layout (like as jgrid or something better than jgrid) or trials...

----------


## Krool

> why datasource property designed in this grid control but i should be use like as ur class and use IVBFlexDataSource ?!!
> if  this property designed  for bind to any data control so how can use it ? any sample?
> do u have any simple sample to i jst set this property to a adodc1?
> 
> 
> i did see your topic before i ask my question here but i don't want fill my grid with coding and run query for each update or delete and like these actions,i want use like as data grid and binded automatically to adodc1
> 
> for example can i set this grid.DataSource = adodc1 in design and then just work with adodc1 like as adodc1.recordset.addnew or update or refresh or movefirtst move last and etc automatically binded to gird ?and i did not see retrieve field on rightclick on grid or change captions or fields binded and like these options...
> 
> ...


The .DataSource property is not binding for CRUD.
It's just reading a recordset and filling the grid.

----------


## logley

Krool,

Several 'Pages' ago in the thread, you spoke about altering the ClipMode options, so that Fixed Cols/Rows could be included/excluded as required.  Is this something still on the cards.

Am looking at migrating my system to use the new grid, and am slowly updating my 'helper' functions to work with the new grid.  Now looking at my function to send the whole grid to excel.  I'm hoping this will be a lot neater using the Clip function, but I would like the header to be copied across. I can do this in code, but if the ClipMode alterations are still on the to-do list that would make it easier/neater

Thanks

Lee.

----------


## Mustaphi

Krool,
when I fill the VBFlexGrid  from database the records are displayed fine.
but when I fill by code it is showing strange symbols.
I'm using Arabic Egypt in  regional setting.
Is there a workaround?

----------


## Krool

> Krool,
> when I fill the VBFlexGrid  from database the records are displayed fine.
> but when I fill by code it is showing strange symbols.
> I'm using Arabic Egypt in  regional setting.
> Is there a workaround?


Use a different font. E.g. Microsoft Sans Serif instead of MS Sans Serif.

----------


## Mustaphi

> Use a different font. E.g. Microsoft Sans Serif instead of MS Sans Serif.


thanks but it didn'thelp
still strange symbols

----------


## Arnoutdv

> Krool,
> when I fill the VBFlexGrid  from database the records are displayed fine.
> but when I fill by code it is showing strange symbols.
> I'm using Arabic Egypt in  regional setting.
> Is there a workaround?


How do you obtain the information to be put in the vbFlexGrid?

----------


## Mustaphi

> How do you obtain the information to be put in the vbFlexGrid?


With VBFlexGrid1
    .AddItem ""
 .TextMatrix(1, 1) = "test data"
.TextMatrix(1, 2) = "test data"

End With

----------


## Arnoutdv

That's just hardcoded plain ASCII text.
How do you obtain your Arabic texts? 
From a text file? From user input?

----------


## Mustaphi

> That's just hardcoded plain ASCII text.
> How do you obtain your Arabic texts? 
> From a text file? From user input?


in fact  I'm binding the grid to database


```
Set .FlexDataSource = DataSource.BindTo(Rs)
```

I just need to hardcode the columnheders.


```
.TextMatrix(0, 1) = "الرقم"
.TextMatrix(0, 2) = "التاريخ"
.TextMatrix(0, 3) = "الاسم"
```

thanks

----------


## Krool

> in fact  I'm binding the grid to database
> 
> 
> ```
> Set .FlexDataSource = DataSource.BindTo(Rs)
> ```
> 
> I just need to hardcode the columnheders.
> 
> ...


Maybe your PC (non-unicode language settings) is in Arabic, thus DBCS mode is on. That's why you can place "fake" unicode in the VB6 IDE but in fact in other language (non-DBCS mode) will fail .
It's just a guess out of the blue..

----------


## Mustaphi

hi krool
I'm using this code to send data from VBFlexGrid  to excel.
The vb6 FlexGrid is showing Arabic quite normal in theexcel sheet but VBFlexGrid  is showing strange symbols.



```
Private Sub FlexToExcel()
Dim xlObject    As Excel.Application
Dim xlWB        As Excel.Workbook
        
    Set xlObject = New Excel.Application 
 
    'This Adds a new woorkbook, you could open the workbook from file also
    Set xlWB = xlObject.Workbooks.Add 
                
    Clipboard.Clear 'Clear the Clipboard
    With MSFlexGrid1
        'Select Full Contents (You could also select partial content)
        .Col = 1               'From first column
        .Row = 0               'From first Row (header)
        '.ColSel = .Cols - 1    'Select all columns
        .RowSel = .Rows - 1    'Select all rows
        Clipboard.SetText .Clip 'Send to Clipboard
    End With
            
    With xlObject.ActiveWorkbook.ActiveSheet
        .Cells(1, 1)Select 'Select Cell A1 (will paste from here, to different cells)
        .Paste              'Paste clipboard contents
        .Columns(1).Font.Bold = True
         .Columns(1).HorizontalAlignment = xCenter
    End With
 
'-------------------------------------------------
 
    Clipboard.Clear 'Clear the Clipboard
    With MSFlexGrid1
        'Select Full Contents (You could also select partial content)
        .Col = 4               'From first column
        .Row = 0               'From first Row (header)
        '.ColSel = .Cols - 1    'Select all columns
        .RowSel = .Rows - 1    'Select all rows
        Clipboard.SetText .Clip 'Send to Clipboard
    End With
            
    With xlObject.ActiveWorkbook.ActiveSheet
        .Cells(1, 2)Select 'Select Cell A1 (will paste from here, to different cells)
        .Paste              'Paste clipboard contents
        .Columns(2).Font.Bold = True
         .Columns(2).HorizontalAlignment = xCenter
    End With    
 
    ' This makes Excel visible
    xlObject.Visible = True
End Sub
```

----------


## Mustaphi

I noticed that if the input /keyboard language is Arabic everything is OK.
But if the the input language is english,  it shows as weird characters in excel sheet.
 I'm referring to the Keyboad language (the one in the right bottom of the screen) not in regional settings.

----------


## Erwin69

Hi,

I'm using MouseRow to detect the row the user is clicking on.  With the left mouse click, this returns the correct row.  However, if I right mouse click on a row, MouseRow returns the currently selected row.  For example: I have a grid with the first row fixed as column headers, and 4 rows with data below that.  The last row is selected, i.e. MouseRow returns 4.  If I right mouse click on another row, MouseRow will always return 4, while a left mouse click would return the correct rownumber.

Am I doing something wrong, or am I missing something?

Thanks,
Erwin

[Edit] Additional info

I have a VBFlexGrid called grdFixtureList with a fixed header row, and several rows of data.  The below code creates a popup menu depending on where the user clickied.  A strange thing happens if I place a breakpoint on the line "If .Row < .RowSel Then".  I right mouse clicked on another row than the one that was selected.  Now, if I move the mouse cursor over the first instance of .MouseRow above the comment _User clicked selected area_) the labeltip give me another value than when I place the mouse over the last instance of .MouseRow below the comment _User clicked a new row_.

One property having two different values at the same time?  Something strange is happening.



```
Private Sub grdFixtureList_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)

    Dim iStartRow As Integer
    Dim iEndRow As Integer
    Dim iSelectedPopUpMenuItem As Integer
    
    If (Button = vbRightButton) And (grdFixtureList.Rows > 1) Then
        'Select the row the user clicked on
        With grdFixtureList
            'If the user clicked on one or more selected Fixtures, pop up the menu, otherwise select the row
            If .Row < .RowSel Then
                iStartRow = .Row
                iEndRow = .RowSel
            Else
                iStartRow = .RowSel
                iEndRow = .Row
            End If
            
            If (.MouseRow >= iStartRow) And (.MouseRow <= iEndRow) Then
                'User clicked selected area
                If iStartRow = iEndRow Then
                    'Only one item selected, show/hide appropriate menu-items
                    iSelectedPopUpMenuItem = CreateMenuPopUpFixtureList(LIST_POPUP_MENU_SINGLE_ITEM)
                Else
                    'Multiple items selected, show/hide appropriate menu-items
                    iSelectedPopUpMenuItem = CreateMenuPopUpFixtureList(LIST_POPUP_MENU_MULTIPLE_ITEMS)
                End If
            Else
                'User clicked a new row. Simulate a click to have the item selected in the floorplan and then show the menu
                .Row = .MouseRow
                Call grdFixtureList_Click
                iSelectedPopUpMenuItem = CreateMenuPopUpFixtureList(LIST_POPUP_MENU_SINGLE_ITEM)
            End If
        End With
        
        'Process the selected menuitem
        Select Case iSelectedPopUpMenuItem
            Case 0
                'User didn't select any menu
            Case 1
                Call mnuPopUpChangeFixture_Click
            Case 2
                Call mnuPopUpDuplicateFixture_Click
            Case 3
                Call mnuPopUpRemoveFixture_Click
            Case 4
                Call mnuPopUpRemoveFixture_Click
        End Select
    
    End If
End Sub
```

----------


## lizano diaz

There is a problem in Win10 with the DPI, other than that how would I send a regular size file? I have vbflexgrid with some more features, but it is impossible for me to upload to the server

----------


## lizano diaz

Excuse me group, will there be a group like Whatsapp or Telegram?

----------


## fengzhongxia

Add a Row use "Additem". I want to Add a Col.What I use?

----------


## Eduardo-

> Add a Row use "Additem". I want to Add a Col.What I use?




```
VSFlexGrid1.Cols =  number_of_columns_that_you_want
```

----------


## SearchingDataOnly

Hi Krool,

I'm thinking about a question, can we develop a VBFlex-like control without subclassing and VTable? In other words, what features/functions in the subclass cannot be replaced by other technologies?

----------


## lizanodiaz

Hi: Krool  
please visit url: https://github.com/lizanodiaz/vbflexgrid

there are many improvements that you can implement in your vbflexgrid, like progress bars, toggle button, etc. The purpose is to have a good, more powerful and functional grid (note the original grid has some DPI problems in windows 10).

----------


## Krool

Small update release.

Setting .FlexDataSource to nothing will invalidate the grid now and does not cause an immediate redraw anymore.

I got a scenario where that forced complete redraw is annyoing. So having just the invalidation is fine.
If somebody want's to continue to have an immediate redraw, one can do so by a following .Refresh code line.

----------


## Seniorchef

Hello, Krool.

The colPosition() and rowPosition() properties should move the column resp. row not swap them.
Is this by design? If so, could you implement the 'original' behavior to the VBFlexgrid?
Thanks

----------


## Krool

> Hello, Krool.
> 
> The colPosition() and rowPosition() properties should move the column resp. row not swap them.
> Is this by design? If so, could you implement the 'original' behavior to the VBFlexgrid?
> Thanks


There is the RowPos() and RowPosition() properties (and Col resp.) and they already behave like in msFlexGrid.

----------


## Seniorchef

Hello!
No, the don't.
The colPosition() in VBFl,exGrid swaps two columns:
colPosition(6)=10 in VBFlexGrid results in columns 5,10,7,8,9,6,11 ...
colPosition(6)=10 in MSHFlexGrid results in columns 5,7,8,9,10,6,11...
rowPosition() behave the same.
Greetings


That is colPosition(6)=10 cols 6 and 10 get swapped, nothing else changes. MSFlexGrid moves column 6 behind column ten, so the new order is 5,7,8,9,10,6,11

----------


## Seniorchef

Oops, sorry for the lines after greetings :-)

----------


## Seniorchef

I changed the ColPosition/RowPosition as follows (quick and dirty):


```
Public Property Let ColPosition(ByVal Index As Long, ByVal Value As Long)
If (Index < 0 Or Index > (PropCols - 1)) Or (Value < 0 Or Value > (PropCols - 1)) Then Err.Raise Number:=381, Description:="Subscript out of range"
If Index = Value Then Exit Property
'Bisher:
Dim i As Long, Swap1 As TCELL, Swap2 As TCOLINFO
On Error Resume Next

'For i = 0 To (PropRows - 1)
'    With VBFlexGridCells.Rows(i)
'    LSet Swap1 = .Cols(Index)
'    LSet .Cols(Index) = .Cols(Value)
'    LSet .Cols(Value) = Swap1
'    End With
'Next i
'LSet Swap2 = VBFlexGridColsInfo(Index)
'LSet VBFlexGridColsInfo(Index) = VBFlexGridColsInfo(Value)
'LSet VBFlexGridColsInfo(Value) = Swap2

'SeniorChef...
Dim nCol&
If Index < Value Then
   
   For i = 0 To PropRows - 1
      With VBFlexGridCells.Rows(i)
         LSet Swap1 = .Cols(Index)
         For nCol = Index To Value - 1
            LSet .Cols(nCol) = .Cols(nCol + 1)
         Next
         LSet .Cols(Value) = Swap1
      End With
   Next
   LSet Swap2 = VBFlexGridColsInfo(Index)
   For nCol = Index To Value
      LSet VBFlexGridColsInfo(nCol) = VBFlexGridColsInfo(nCol + 1)
   Next
   LSet VBFlexGridColsInfo(Value) = Swap2
   
ElseIf Index > Value Then
   For i = 0 To PropRows - 1
      With VBFlexGridCells.Rows(i)
         LSet Swap1 = .Cols(Index)
         For nCol = Index To Value + 1 Step -1
            LSet .Cols(nCol) = .Cols(nCol - 1)
         Next
         LSet .Cols(Value) = Swap1
      End With
   Next
   LSet Swap2 = VBFlexGridColsInfo(Index)
   For nCol = Index To Value Step -1
      LSet VBFlexGridColsInfo(nCol) = VBFlexGridColsInfo(nCol - 1)
   Next
   LSet VBFlexGridColsInfo(Value) = Swap2
End If
'End SeniorChef


Dim RCP As TROWCOLPARAMS
With RCP
.Mask = RCPM_LEFTCOL
.Flags = RCPF_CHECKLEFTCOL Or RCPF_SETSCROLLBARS Or RCPF_FORCEREDRAW
.LeftCol = VBFlexGridLeftCol
Call SetRowColParams(RCP)
End With
End Property

Public Property Let RowPosition(ByVal Index As Long, ByVal Value As Long)
If (Index < 0 Or Index > (PropRows - 1)) Or (Value < 0 Or Value > (PropRows - 1)) Then Err.Raise Number:=381, Description:="Subscript out of range"
If Index = Value Then Exit Property
Dim Swap As TCOLS
'bisher:
'With VBFlexGridCells
'LSet Swap = .Rows(Index)
'LSet .Rows(Index) = .Rows(Value)
'LSet .Rows(Value) = Swap
'End With

'SeniorChef:
With VBFlexGridCells
LSet Swap = .Rows(Index)
Dim nRow&
If Index < Value Then
   For nRow = Index To Value - 1
      LSet .Rows(nRow) = .Rows(nRow + 1)
   Next
ElseIf Index > Value Then
   For nRow = Index To Value + 1 Step -1
      LSet .Rows(nRow) = .Rows(nRow - 1)
   Next
End If
LSet .Rows(Value) = Swap
End With
'End SeniorChef

Dim RCP As TROWCOLPARAMS
With RCP
.Mask = RCPM_TOPROW
.Flags = RCPF_CHECKTOPROW Or RCPF_SETSCROLLBARS Or RCPF_FORCEREDRAW
.TopRow = VBFlexGridTopRow
Call SetRowColParams(RCP)
End With
End Property
```

----------


## Seniorchef

BTW, regarding my posts #595 ff I also implemented in my personal vbFlexGrid a method to sort the grid by cols that are not beneath each other, and also mix ascending and descending. It's about 30 lines of code:


```

'Add Enum 
Public Enum FlexSortConstants
...
FlexSortUseIndex = 15
End Enum

'Add Array
Private FlexGridSortCols() As Long 

'Quick and dirty properties
Public Property Get SortColIndex(ByVal Index As Long) As Long
   If Index < 0 Or Index > (PropCols - 1) Then Err.Raise Number:=30010, Description:="Invalid SortCol value"
   SortColIndex = FlexGridSortCols(Index)
End Property

'There are better ways to fill the array and check the bounds
'SeniorChef
Public Property Let SortColIndex(ByVal Index As Long, ByVal Value As Long)
If Index <> -1 And (Index < 0 Or Index > (PropCols - 1)) Then Err.Raise Number:=30010, Description:="Invalid SortColIndex value"
If Value < 0 Or Value > (PropCols - 1) Then Err.Raise Number:=30010, Description:="Invalid SortCol value"

   'set a value, one after the other, this is not time critical, so redim preserve is ok...
   If Index > -1 Then
      ReDim Preserve FlexGridSortCols(Index)
      FlexGridSortCols(Index) = Value
   Else
      'clear Array
      ReDim FlexGridSortCols(0)
   End If
End Property

'the improved sort method:
Public Property Let Sort(ByVal Value As FlexSortConstants)

#If ImplementFlexDataSource Then

If Not VBFlexGridFlexDataSource Is Nothing Then Err.Raise Number:=5, Description:="This functionality is disabled when custom data source is set."

#End If

Select Case Value
'changes from Seniorchef
'added FlexSortIndex as a legal Value

    Case FlexSortNone, FlexSortGenericAscending, FlexSortGenericDescending, _
         FlexSortNumericAscending, FlexSortNumericDescending, _
         FlexSortStringNoCaseAscending, FlexSortStringNoCaseDescending, _
         FlexSortStringAscending, FlexSortStringDescending, FlexSortCustom, _
         FlexSortUseColSort, FlexSortCurrencyAscending, FlexSortCurrencyDescending, _
         FlexSortDateAscending, FlexSortDateDescending, FlexSortUseIndex
         
        VBFlexGridSort = Value
        If VBFlexGridSort = FlexSortNone Then Exit Property
        
        If (VBFlexGridRow < 0 Or VBFlexGridRowSel < 0) Or (VBFlexGridCol < 0 Or VBFlexGridColSel < 0) Then
            ' Error shall not be raised. Do nothing in this case.
            Exit Property
        End If
        Dim SelRange As TCELLRANGE, iCol As Long, Sort As FlexSortConstants
        Call GetSelRangeStruct(SelRange)

'changes from Seniorchef 
'Doing the FlexSortIndex-Sort by taking the column to be sorted from the array FlexGridSortCols()
'rather than using Col and Colsel properties.
'SeniorChef
        If VBFlexGridSort = FlexSortUseIndex Then
            Dim iIndex As Long
            For iIndex = UBound(FlexGridSortCols) To 0 Step -1
               iCol = FlexGridSortCols(iIndex)
               Sort = VBFlexGridColsInfo(iCol).Sort
               ' MergeSort is used for automatic sorting as it is fast and reliable.
               If VBFlexGridRow = VBFlexGridRowSel Then
                  Call MergeSortRec(PropFixedRows, PropRows - 1, iCol, VBFlexGridCells.Rows(), Sort)
               Else
                  Call MergeSortRec(SelRange.TopRow, SelRange.BottomRow, iCol, VBFlexGridCells.Rows(), Sort)
               End If
            Next iIndex
        Else
'no more changes 

        ' The keys used for sorting are determined by the Col and ColSel properties.
        ' To specify the range to be sorted, set the Row and RowSel properties.
        ' Sorting is always done in a left-to-right direction. (Technically the sorting is performed from right-to-left)
        For iCol = SelRange.RightCol To SelRange.LeftCol Step -1
            If VBFlexGridSort <> FlexSortUseColSort Then Sort = VBFlexGridSort Else Sort = VBFlexGridColsInfo(iCol).Sort
            ' MergeSort/BubbleSort are used as they are 'stable sort' algorithms.
            If Sort <> FlexSortCustom Then
                ' MergeSort is used for automatic sorting as it is fast and reliable.
                If VBFlexGridRow = VBFlexGridRowSel Then
                    Call MergeSortRec(PropFixedRows, PropRows - 1, iCol, VBFlexGridCells.Rows(), Sort)
                Else
                    Call MergeSortRec(SelRange.TopRow, SelRange.BottomRow, iCol, VBFlexGridCells.Rows(), Sort)
                End If
            Else
                ' BubbleSort is used for custom sorting as row1/row2 for text matrix must be meaningful in the 'Compare' event.
                If VBFlexGridRow = VBFlexGridRowSel Then
                    Call BubbleSortIter(PropFixedRows, PropRows - 1, iCol, VBFlexGridCells.Rows())
                Else
                    Call BubbleSortIter(SelRange.TopRow, SelRange.BottomRow, iCol, VBFlexGridCells.Rows())
                End If
            End If
        Next iCol
        End If
        Dim RCP As TROWCOLPARAMS
        With RCP
        .Mask = RCPM_TOPROW
        .Flags = RCPF_CHECKTOPROW Or RCPF_SETSCROLLBARS Or RCPF_FORCEREDRAW
        .TopRow = VBFlexGridTopRow
        End With
        If VBFlexGridIndirectCellRef.InProc = False Then
            Call SetRowColParams(RCP)
        Else
            LSet VBFlexGridIndirectCellRef.RCP = RCP
            VBFlexGridIndirectCellRef.SetRCP = True
        End If
    Case Else
        Err.Raise 380
End Select
' Action-type property. Not real property.
End Property
```



```
'To sort a grid on columns 8, 6, 3, 9:
With VBFlexGrid
.sortColIndex(0)=8
.sortColIndex(1)=6
.sortColIndex(2)=3
.sortColIndex(3)=9

'How to sort each column
.colSort(8)=FlexSortStringNoCaseAscending
.colSort(6)=FlexSortDateDescending
.colSort(3)=FlexSortNumericAscending
.colSort(9)=FlexSortNUmericDescending

'Finally...
.sort = flexSortUseIndex
End with
```

Feel free to use this in the next update.

Thanks

----------


## Krool

Update released.

Bugfix in the .RowPosition() and .ColPosition() property. (thanks to Seniorchef for reporting this)

Now it is a round trip swap instead of a direct swap between index and value.

This behavior matches now to the MS(H)FlexGrid control.

----------


## Krool

Thanks for your below suggestion. I think it's not necessary.
The below code would do the same:


```
With VBFlexGrid1
.ColSort(8) = FlexSortStringNoCaseAscending
.ColSort(6) = FlexSortDateDescending
.ColSort(3) = FlexSortNumericAscending
.ColSort(9) = FlexSortNumericDescending
.Cell(FlexCellSort, .FixedRows, 8, .Rows - 1) = FlexSortUseColSort
.Cell(FlexCellSort, .FixedRows, 6, .Rows - 1) = FlexSortUseColSort
.Cell(FlexCellSort, .FixedRows, 3, .Rows - 1) = FlexSortUseColSort
.Cell(FlexCellSort, .FixedRows, 9, .Rows - 1) = FlexSortUseColSort
End With
```

or (alternatively)


```
With VBFlexGrid1
.Cell(FlexCellSort, .FixedRows, 8, .Rows - 1) = FlexSortStringNoCaseAscending
.Cell(FlexCellSort, .FixedRows, 6, .Rows - 1) = FlexSortDateDescending
.Cell(FlexCellSort, .FixedRows, 3, .Rows - 1) = FlexSortNumericAscending
.Cell(FlexCellSort, .FixedRows, 9, .Rows - 1) = FlexSortNumericDescending
End With
```




> BTW, regarding my posts #595 ff I also implemented in my personal vbFlexGrid a method to sort the grid by cols that are not beneath each other, and also mix ascending and descending. It's about 30 lines of code:
> 
> 
> ```
> 
> 'Add Enum 
> Public Enum FlexSortConstants
> ...
> FlexSortUseIndex = 15
> ...

----------


## Seniorchef

Yep - the results seem the same. 
It's really hard to know all the possibilities of the control. 
Thank's for your efforts in this point.
And of course thank's for the control!
Regards

----------


## fengzhongxia

Use RemoveItem ，Wheel will invalid！
please fix it !

----------


## Krool

> Use RemoveItem ，Wheel will invalid！
> please fix it !


Please more context.

----------


## lizano diaz

Mr. Krool, why don't you use the files that I shared? Progress cells, chart cells, and many other things would have already been done. I hope you reconsider, thanks

----------


## Krool

> Use RemoveItem ，Wheel will invalid！
> please fix it !


Update released. Fixed.

----------


## Krool

Bugfix for FlexFocusRectFlat. The pen style uses now a NULL_BRUSH to not affect custom background color/picture.

----------


## TheLeePiper

Love the CellComboCue. Question - is there a way for this to be persistent in a cell? My understanding is that it is a dynamic cue on a cell event. We are considering the case of new users that might benefit from the persistent visual cue of the dropdown button. Thanks!

----------


## Krool

> Love the CellComboCue. Question - is there a way for this to be persistent in a cell? My understanding is that it is a dynamic cue on a cell event. We are considering the case of new users that might benefit from the persistent visual cue of the dropdown button. Thanks!


It can be dynamic or persistent. Both ways are possible.
ComboCue/ComboCueRow/Col are dynamic.
CellComboCue is persistent. Best way to FillStyle that for whole Column via .Cell property (virtual selection)

----------


## TheLeePiper

Got it. Fantastic. Thanks so much for the assist and your efforts at large.

----------


## TheLeePiper

Question regarding the ComboDropDown function. I have set up a cell as a DropDown with the Cue working great. If I click the body of the cell, it properly drops the list, and grid.Row correctly is the current grid row of the DropDown cell. However, if I drop the list using the button itself, grid.Row is the previously entered grid row (and not the DropDown grid row). Is this the expected behavior? (Also note that the ValidateEdit function is also subsequently fired with the correct grid.Row in both cases.)

Additionally, if I click on the list item that is the current ComboListIndex, neither of these evens are fired. For example, say I have a list A & B, and A was previously selected. If I select A again, the events are not fired. If I select B, they are fired. Expected behavior? (This is less of an issue because data doesn't change, but it is curious that the events didn't fire.)

Thanks!

----------


## Krool

> Question regarding the ComboDropDown function. I have set up a cell as a DropDown with the Cue working great. If I click the body of the cell, it properly drops the list, and grid.Row correctly is the current grid row of the DropDown cell. However, if I drop the list using the button itself, grid.Row is the previously entered grid row (and not the DropDown grid row). Is this the expected behavior? (Also note that the ValidateEdit function is also subsequently fired with the correct grid.Row in both cases.)
> 
> Additionally, if I click on the list item that is the current ComboListIndex, neither of these evens are fired. For example, say I have a list A & B, and A was previously selected. If I select A again, the events are not fired. If I select B, they are fired. Expected behavior? (This is less of an issue because data doesn't change, but it is curious that the events didn't fire.)
> 
> Thanks!


Yes, grid.Row is the current focused cell. If you click the combo cue, the focus doesn't change. So, you might use the grid.EditRow function.
The ValidateEdit event is fired only when the text has changed, that's by design. It's an event to validate changes.
You might check the LeaveEdit or AfterEdit event if that fits your needs.

----------


## TheLeePiper

Understood, thanks!

----------


## Krool

Update released.

Included the Copy/Cut/Paste/Delete method. This is just a simple wrapper to put .Clip property to the clipboard or set the .Clip property from the clipboard.

Also included the ClipCopyMode property. 0 - Normal and 1 - IncludeFixedRows for the moment only.
This value affects the Copy method and the Clip Get-Property. (not the Clip Let-Property)
To have Clip Get/Let property to behave the same keep it as 0 - Normal. (default)

----------


## fabel358

I need in one of my projects to write normal text and bold text within the same grid cell, or texts of different colors. Does your Vbflexgrid allow it?

----------


## Arnoutdv

No it does not support in-cell markup.
All font styles apply to the complete cell.

----------


## Krool

Update released.

Included the ClipSeparatorCol/ClipSeparatorRow run-time property.
These properties expose the default separators vbTab and vbCr. Thus the defaults can be changed.
Also, it provides a way to support more than 1 character for a separator.
This may be useful for the row separator vbCrLf to better exchange with MS Excel.

However, for back-compatibility. If the ClipSeparators property is set, then that will be used.
But that is consistent, if ClipSeparators is empty the defaults are used. (ClipSeparatorCol/ClipSeparatorRow)
ClipSeparators is just limited to 1 character per separator.

So, during a Form_Load one can change the default value:


```
VBFlexGrid1.ClipSeparatorRow = vbCrLf
```

----------


## Krool

Included Delete method. Also Cut/Paste/Delete method will scroll to the current cell, if necessary. (CellEnsureVisible)

Included AutoClipboard property.

----------


## Krool

Update released.

Minor bugfix for the ShowLabelTips property. The cell text was considered falsely as "folded" in case the cell rect was partially clipped by the border of the client rect.
That resulted in showing the label tooltip when in fact the text was fully visible.

The 1.5 OCX was also updated with this fix.

----------


## AlKalm

Thank You for Your great job!

By the way, I can't find any documentation or some description of the functions and its parameters... Do You have plans for it? It would be very useful!

Thanks!

----------


## Krool

Updated released.

Included the cell flooding feature to display like a progress bar in cells. (CellFloodPercent/CellFloodColor/FloodColor property)
Like in the vsFlexGrid a positive FloodPercent will be from left to right and a negative from right to left.

Also added enum FlexCellFloodPercent and FlexCellFloodColor to enrich the Cell property.

----------


## Krool

Update released.

The Checkboxes feature is now included via the CellChecked property.



The new events CellBeforeCheck/CellCheck event helps to react to user interaction.
These are not fired by code, only by mouse click or the space key.

New hit result enum FlexHitResultCheckBox for obvious reason.

The alignment of the checkbox can be either left-center, center-center or right-center and is linked to the CellPictureAlignment property. (!)

----------


## DaveDavis

> It can be dynamic or persistent. Both ways are possible.
> ComboCue/ComboCueRow/Col are dynamic.
> CellComboCue is persistent. Best way to FillStyle that for whole Column via .Cell property (virtual selection)


Can we have an option to have HotTracking, Specifically for Cue button? By doing so, the Cue is lively interaction.

----------


## Krool

> Can we have an option to have HotTracking, Specifically for Cue button? By doing so, the Cue is lively interaction.


The Combo button is already hot-tracked. But yes, the combo cue isn't as it's drawn built in by the grid.
So, yes. I wouldn't want to have mouse track on by default always for the grid itself.
Thus having a new "HotTracking" property would be ideal.
If set to true, all checkboxes and combo cues are being drawn "hot" when the mouse is over them.
Beside those items, how to react to normal cells? Hotlight the cell text?

----------


## DaveDavis

> The Combo button is already hot-tracked. But yes, the combo cue isn't as it's drawn built in by the grid.
> So, yes. I wouldn't want to have mouse track on by default always for the grid itself.
> Thus having a new "HotTracking" property would be ideal.
> If set to true, all checkboxes and combo cues are being drawn "hot" when the mouse is over them.
> Beside those items, how to react to normal cells? Hotlight the cell text?


HotTracking: Gets or sets a value determining whether the cell's buttons, column headers, and scroll bar elements indicate hot state.

----------


## Krool

Update released.

Improved AutoSize/FormatString to resize based on best fit rather than text measure only.
Best fit means to include ComboCue, CheckBox, Picture (NoOverlap align only) and ColSortArrow.
ColSortArrow was previously included in the internal GetTextSize (CX/CY) function which could be misleading.
Now included new internal GetBestWidth function and renamed GetTextHeight to GetBestHeight.

The public exposed functions TextWidth/TextHeight still use the internal GetTextSize function. (but now text only, means without ColSortArrow)

Included BestFitMode property which defaults to 0 - TextOnly (used for AutoSize/FormatString) to behave like intended.
Else you can choose between 1 - Full, 2 - SortArrowText or 3 - OtherText.
Having 2 - SortArrowText is the same as previous behavior, means leaving the other contents (checkbox, combocue) un-measured.

----------


## hl88

I copy a range from A1 to C3 in excel, then select 3x3 grids in VBflexgrid and click Paste Button (VBFlexgrid1.Paste). data only pasted to second and third column, the second and third row of first column is empty

----------


## Krool

> I copy a range from A1 to C3 in excel, then select 3x3 grids in VBflexgrid and click Paste Button (VBFlexgrid1.Paste). data only pasted to second and third column, the second and third row of first column is empty


Apply following code in Form_Load


```
VBFlexGrid1.ClipSeparatorRow = vbCrLf
```

----------


## Krool

Update released.




> Can we have an option to have HotTracking, Specifically for Cue button? By doing so, the Cue is lively interaction.


There is now no new hot-tracking option. It just simply now get's hot-tracked when the MouseTrack property is True.

----------


## DaveDavis

> Update released.
> 
> 
> 
> There is now no new hot-tracking option. It just simply now get's hot-tracked when the MouseTrack property is True.


very useful,  thanks[thumbsup]

----------


## Krool

Updated released.

Support for dynamic checkboxes which are based on the cell text. (added FlexTextAsCheckBox/FlexDisabledTextAsCheckBox enum to FlexCheckBoxConstants)

Empty text (like DBNull) as grayed state, else text to boolean conversion to either checked or unchecked state.
The application is responsible to react on CellCheck event to update the cell text to the new state.
Furthermore the cell text gets hidden/not drawn. Also the label info is as if the cell has no text.

Currently the text is still measured for those cells which has "hidden text". (e.g. GetTextSize/GetBestHeight/GetBestWidth)
This may change in future.. though the vsFlexGrid does also still measure. (there is dynamic approach on ColDataType = boolean)

----------

