i cant edit my own post to add a attachment...:mad:
attached you will find a example project to test the FindItem method of the ListView.
Printable View
i cant edit my own post to add a attachment...:mad:
attached you will find a example project to test the FindItem method of the ListView.
Remarks on the CommandButtonW
Attachment 151339
The CommandButtonW shall show a picture, so an imagelist is defined. Works fine.
A:
The caption starts right after the image border.
ImageListMargin seems to work on the left edge only.
Ok, I could make a special image for the button.
It would be good if it would work on the right edge too.
B:
LabelW and other controls have the wonderful EllipsisFormat.
Could we have it for a CommandButtonW as well?
Thank you.
You want to search for subitems which is not supported by API LVM_FINDITEM.
Anyway I do find the MS ListView FindItem method with lvwSubItem more or less stupid as you don't can search for a specific subitem or has an indication on which subitem the search was successful.
That's why I have excluded the 'Where' parameter in my FindItem method.
I could include a new function 'FindSubItem' (wrapper function) where it would be possible to specify a search on a specific subitem or when that param is missing do a search on all subitems. But that function would be performed 'manual' and not done by an API call.
A: In order to work the ImageListMargin on the right edge you need to change ImageListAlignment to 'Right'.
B: Not possible to include EllipsisFormat property to common CommandButtonW. However, it could work for a 'Graphical' Style CommandButtonW? Would that be sufficient?
-
Is there a need for a property page for the LabelW control? This would allow to make multiple lines of text in the caption property in design time.
Also is there a need for a ColumnHeaders property page in the ListView control? This would allow to setup the ColumnHeaders at design-time.
Major update released.
This time the Font properties are affected.
Whenever a new control is placed on a Form the new control will inherit the Font of the Form. (Ambient.Font)
When closing the Form the control's Font properties should normally not be saved into the property bag when it is equal with the Ambient.Font. (MS controls behavior)
This has the advantage that later on you can modify the ".frm" and change the Font of the Form and all controls will be loaded then with the new Ambient.Font.
Note that this trick does not work when changing the Form's Font property in the IDE as then the controls have already loaded the Font.
However, in my controls the control's Font properties are always saved to the property bag.
That's why the trick with modifiyng the ".frm" file does not work, unless you change all occurrences of the Font and change them, which is not comfortable.
It seemed that
does not do what I thought it would do. I thought there would be nothing saved when the Font equals the DefaultValue of Ambient.Font.Code:.WriteProperty "Font", PropFont, Ambient.Font
But of course it does not work as the Font's are always "different" due to different object instances. ("If PropFont Is Ambient.Font" will not work)
Solution was to make the "equal test" task in a separate new function 'OLEFontIsEqual' and saving the property like this:
Of course the opposite side has also been tweaked toCode:.WriteProperty "Font", IIf(OLEFontIsEqual(PropFont, Ambient.Font) = False, PropFont, Nothing), Nothing
So now when the Font equals the Ambient.Font there will nothing be saved into the property bag. And on loading the Font will be Nothing in the first place.Code:Set PropFont = .ReadProperty("Font", Nothing)
But of course when the Font will be assigned and it is Nothing the Ambient.Font will be taken.
In order to realize this update into existing projects an "Update UserControls" task is necessary. Also ensure that "Lock Controls" is not active while doing so.Code:Public Property Set Font(ByVal NewFont As StdFont)
If NewFont Is Nothing Then Set NewFont = Ambient.Font
Attachment 151395
Hi Krool, I think, this is wrong for many reason...
The Default property should be the "default" value of the OCX or, in this case, the VbDefault Value,
i.e.: MS Sans Serif
From my own experience, I found out the best way to use them in the Write/Read property is as followed:
Code:1. define a global var like
Private gfntDefault As StdFont
2. in UserControl_Terminate()
Private Sub UserControl_Terminate()
Set gfntDefault = nothing
End Sub
3. in UserControl_Initialize()
Private Sub UserControl_Initialize()
SET gfntDefault = new StdFont
gfntDefault.Name = "MS Sans Serif"
gfntDefault.Size = 9
gfntDefault.Bold = False
gfntDefault.Italic = False
gfntDefault.Strikethrough = False
gfntDefault.Underline = False
End Sub
4. Finally...
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Font", PropFont, gfntDefault
End Sub
Hi Krool,
I found out a weird bug with ComboBoxW
When Using the MoveWindow() Api, even if you don't move, don't resize the control, the DropDown Windows appear somewhere else.
Further more, you cannot Click the Control anymore.
Here a picture, Since you can't click the Control aftter MoveWindow(), I used CB_SHOWDROPDOWN to show where the DropDown appear.
Attachment 151405
What I was trying to achieve was to set the Height Property so the DropDown list would have a different size.
However, I learned later, this trick only work when the App is NOT using comctl32.dll version 6
Furthermore:
Using original Vb6 Control
#1 When using comctl32.dll version 5 (Default Vb6, IDE not patched, no manifest)
ComboBox DropDown box is limited to 8 items You can use the MoveWindow() trick to change that behavior.
#2 When using comctl32.dll version 6 (IDE patched, or manifest)
if you put a lot (let's say 50) item in the ComboBox, the DropDown box will fill out the available screen region.
This seem to be a bug. The compiled program is OK
Attachment 151403
in Themed app, the proper way is CB_SETMINVISIBLE but I was attempting to make a code that would work either it is themed or not...
Is there a way from IDE/EXE to detect if this is the case ?
There is already a 'MaxDropDownItems' property available which takes care of that mess in the ComboBoxW and ImageCombo control.
And concerning MoveWindow() its normal. The VB.ComboBox has the coords of the Form, whereas my ComboBoxW control is a child of a UserControl and therefore has the coords of the UserControl and not the Form. Like SetParent API, use .hWndUserControl for such things.
100% agree if your tools are meant as a replacement, but next quote below breaks this behavior...
However, this appears to be contrary to some (if not all) intrinsic controls behavior. VB seems to always write the intrinsic control font name if not MS Sans Serif, at least it does with Command buttons. It appears intrinsic controls fonts are compared with a hard coded font.Quote:
So now when the Font equals the Ambient.Font there will nothing be saved into the property bag. And on loading the Font will be Nothing in the first place
I had to go back and re-read your summary of changes regarding the font. I must have read it incorrectly at first and better understand your logic, which I agree with. My bad.
Then the whole image is on the right side.
I was after having a distance to the text on the right side of the image, a padding around all borders of the image.
In the meantime I had a too simple idea to have it: A leading space in the caption. Done.
No, I consider the graphical style useless at all.Quote:
B: Not possible to include EllipsisFormat property to common CommandButtonW. However, it could work for a 'Graphical' Style CommandButtonW? Would that be sufficient?
A toolbar with one button only is better, it has the Ellipsis thing.
But it has not the appearance of a button, except VisualStyles=False, and this doesn't look good.
In the end I think I have to fake the Ellipsis format myself (it's not so hard).
No.Quote:
Is there a need for a property page for the LabelW control? This would allow to make multiple lines of text in the caption property in design time.
Hi Krool,
is there any chance that u add a background color property for a complete row (item+subitems) at the listview (report mode)? :)
here you can find a code example:
background-color-for-a-listview-item
...or ist this already possible? i didnt see any property for this...
At first, I don't know if my question is related to Krools controls in particular
because of my missing knowledge here.
So, please excuse if you think that I'm hijacking this thread.
ListViewW question:
Is there any way for fast clearing the Listview?
Background:
A ListView with four columns (Headers:StrLen, Type, Size,DirectoryContent).
Purpose is to load an array with directory/volume contents into it (using FindFirstFileW/FindNextFileW/FindClose).
When trying to load an array that contains all files and folders of volume "C:\" (about 350000 entries for me)
the approximated time is about 35 secs on my personal pc (this is acceptable I think).
But time to clear this list (lvwdata.ListItems.Clear) feels like eternities (about 2-3 minutes). This is really annoying.
In comparison, using a ListBoxW to load this data, LstData.Clear blanks the list nearly immediately.
I wanna stay at the ListViewW control because of some of its features.
So, is there any way to clear a huge list faster? Or did I miss a specific method?
Thanks much in advance for any reply.
@ Mith, I have now included the 'FindSubItem' function in the ListView control.
Short explanation of the usage:
When doing a search on all sub items:
When only searching on a specific sub item:Code:Dim ListItem As LvwListItem, SubItemIndex As Long
Set ListItem = ListView1.FindSubItem("test123", , SubItemIndex)
If Not ListItem Is Nothing Then
MsgBox "Found: " & ListItem.ListSubItems(SubItemIndex).Text
End If
So in fact if the param "SubItemIndex" was passed with 0 a search on all sub items will be performed and the return sub item index will be passed back.Code:Dim ListItem As LvwListItem
Set ListItem = ListView1.FindSubItem("test123", , 1)
If Not ListItem Is Nothing Then
MsgBox "Found: " & ListItem.ListSubItems(1).Text
End If
If it was passed > 0 then only on that specific sub item index will be searched.
The rest works likewise to the FindItem function. (Partial, Wrap)
I have no quick answer to that. Normally in my tests the clearing takes a few seconds in the demo project when containing 100,000 rows.
So the best is maybe you provide a demo showing the 2-3 minutes. Maybe something different can also be improved.
You're right of course... (there is a missing step in my example where I initialized the Usercontrol property with thoses provided as default)
what I so badly attempted to point out is the fact that using a value other then the "default" value as the third param in property save/read is always leading to strange result in the long run, especially if that parameter value is not fixed from 1 run to another like when you're using Ambient.
but again... I should not intrude on that. You made excellent work.
Some people like Lavolpe (see post #1613) have a knack to politely show what could be seen as other mistake without provocation. Unfortunately I apparently lack this aptitude and I apologize.
and I thanks Lavolpe for pointing out my error so delicately.
Hi Krool...
a little back on the Calendar bug I described early...
First, I went back to developping (IDE) without manifest and only compile with manifest.
IDE with manifest (Theme) has too much bug (like the color palette unavailable)
anyway, I'm not sure if it'S the fact of not using the manifest for vb6.exe but now I got the proper circle instead of the rectangle for the date
and the "aujourd'hui" word is placed properly too.
However, I noticed something knew...
here the picture.
can you reproduce ?
Attachment 151475
I don't know, but could it be something like this?Quote:
I have no quick answer to that. Normally in my tests the clearing takes a few seconds in the demo project when containing 100,000 rows.
So the best is maybe you provide a demo showing the 2-3 minutes. Maybe something different can also be improved.
http://www.vbforums.com/showthread.p...ry-slow-in-VB6
I fell into this trap several times.
lets say i have report with 4 columns and 100.000 rows and the word "findme" stays at the first row at the last column.
does this mean i have to run a search with FindItem through all 100.000 rows and then run a search with FindSubItem and the SubItemIndex 0 to get the back the first row?
what i want to say is that it would be more efficent to have one Search-Function that check the item&subitems of each row at one time and not check all existing items first and later check the subitems again...
Thanks Krool for having a look.
I admire your patience and willingness to answer all requests in this thread.
Attached is a project sample to address the issue mentioned in my previous post.
I tried to remove everything not needed from my orig. project.
As usual, remove the docx extension of the attached file.
Some environmental information that might be of help?:
OS: Win10Pro v.1703 x64; OLEGuids.odl/tlb in "SysWOW64" folder.
Mainboard: AsusP8Z68-V-LE
Proc: Pentium i7
RAM: 32GB
HD:NVMe Samsung SSD 950 Pro (OverProvisioning enabled)
If compiled, getting the filelist and loading it into the ListView takes about 35 secs. Deletion takes about 90-120 secs.
In IDE loading takes about 70-80 secs and deletion about 120 to150 secs.
Hi Krool
The second screenshot of the first post shows a nice-looking listview with sortable columns, so I would like to try this replacement out. However two bits of information are missing:
1. What licence does ComCtls use?
2. Where does one download it? There are a few links, one is a "demo" of something, the other is an "ActiveX version" and you used the capitalized phrase "Registration-Free". These things could be interpreted to mean very different things.
Could you please add an unambiguous link to the latest vanilla version, and state the licence this project is released under?
Critical update released.
UserControl_ReadProperties crashes in the LabelW control. Very sorry for this stupid bug.
In the Demo is no LabelW on the form, that's why it just got to my attention now later..
Also all controls have now MouseEnter/MouseLeave events. The IPAddress was the last control that now got the additional mouse events..
the forecolor for link label does never change
I have now looked into your case and must say I don't know how to improve that case.
Some explanation about the current logic:
Per "Row" in the ListView is 1 LvwListItem class stored. This is necessary to store the whole data and also to allow "If ThisItem Is ThatItem Then".
The LvwListSubItems and LvwListSubItem classes are only created when needed, so there is a no issue with "VB class-unloading". All data for the sub items is stored in a UDT array, which is certainly the fastest approach on unloading. (Erase)
So my guess is that it is VB6 fault that it takes so long to destroy 1 LvwListItem class object per "Row".
I guess there is some sort of "exponential" reason behind this. At some point when you increase with factor of 10, the unloading takes more than factor of 10.
1. no license, free.
2. "Registration-Free" means an SxS manifest approach to allow using the ActiveX Control without "regsvr32" first. What you mean with unambiguous link?
Thank you Krool
It would prevent such confusion for others if you added "Licence: public domain" to the first post.Quote:
Originally Posted by Krool
The post currently links to a "This Demo", links to a "Version 1.4", and has an attached "ComCtlsDemo.zip.docx" with no version in its filename. I'm confused.Quote:
Originally Posted by Krool
To make this clear, I would suggest writing something like this:
The latest version is 06-Sep-2017
Download SxS: [download]
Download ActiveX: [download]
Or if the download includes both:
The latest version is 06-Sep-2017
Download: [download]
(includes both ActiveX and SxS)
Download sample projects:
1. How to make the ToolBar control accessible per shortcut key on a MDIForm: [Download]
2. How to foo bar something else: [Download]
Making the download links clearly tell me the version and what they are would clear this up.
Speaking of versions, one of the links in your post mentions "1.4", while the changelog makes no mention of any such version (or any numeric version at all) and instead uses dates. So which is the latest, is it 1.4 or is it 06-Sep-2017? This would need to be cleared up as well.
@ OldClock,
(Copy&Paste from ActiveX Thread)
The development state of the ActiveX Control version does not necessarily match to the Std-EXE version.
That comes because the Std-EXE version is the "leading source" and the ActiveX Control version is derived from the Std-EXE version after a certain time.
Reason why is that it is not practicable to release a new ActiveX Control after each new feature.
However, certain bugfixes can and will be implemented into the current ActiveX Control version. (Revision)
1.4 is the version of the ActiveX project. The Std-EXE project gets frequently updated and does not have an internal versioning.
If you like you can put a "timestamp" on the downloaded Std-EXE project..
Exactly because of this effect I had to give up on using classes when it comes to large counts.
UDTs are the only way for better performance.
This is a really weak spot in VB6.
IMO classes are only useful when the count is low.
Olaf pointed out a method to get class destroying faster.
But that is a LOT of effort.
'Changing' such scenarios to UDT has it's obstacles and is effort as well.
The reward is a performance boost of factor >1000.
Karl
Again, thank you Krool.
I expected (and feared) this kind of answer.
@Karl77,
I'm also very interested in providing the thread link.
The thread can be found here.
I have now (quick and dirty) test implemented the approach and the unloading took now 2 secs. (instead of 27 secs, in IDE)
The loading is nearly unchanged at 80 secs.. (in IDE)
EDIT: But I encounter an "memory leak". When using the fast approach by Olaf I have not the same memory usage after .Clear then before loading..
It looks like the only caveat is a lack of event support. and since Class_Initialize/Terminate are events, those need to be sidestepped too, which doesnt seem to be a problem for LvwListItem/LvwListSubItem.