Re: How to setup a UserControl Property to Browse for a file
@fafalone. Comments follow
1. Up/Dn arrows are not applied to the listview. They are being passed to other controls. Think this could be a major issue for users.
2. Tabbing to/from the listview and/or combo could be a problem, but usually are with non-intrinsic controls
3. The 'back' button doesn't refresh the listview with the new path's items
4. When sorted by name, folders are intermixed with files and shouldn't be IMO.
5. PropertyPage_Apply should extract the selected listview item
6. Click event on the listview probably should enable the Apply ppg button. Simple enough by trapping NM_CLICK & setting PropertyPage.Changed to True
7. When done playing with it, could you strip out all the unnecessary stuff (module functions, etc) from the project? From initial appearances, module only needs to contain subclass-related stuff? And that can be replaced by a small/simple thunk in order to keep the page self-contained. Or are there other calls that require the module(s)? Also, if you press Ctrl+F5 to start the project, you'll get errors related to unused 'stuff'
Last edited by LaVolpe; Sep 16th, 2017 at 11:07 AM.
Insomnia is just a byproduct of, "It can't be done"
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by fafalone
That's the point really... there's no strikethrough on this forum so I use light gray for stuff that would otherwise be crossed out because it's no longer applicable, and just there for archive/continuity purposes. Emphasizing it in bold or bright would be the opposite effect
Hmm .. interesting approach, especially regarding your edit in post #75.
Not how I'd have done it, but does explain why.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by LaVolpe
@fafalone. Comments follow
1. Up/Dn arrows are not applied to the listview. They are being passed to other controls. Think this could be a major issue for users.
2. Tabbing to/from the listview and/or combo could be a problem, but usually are with non-intrinsic controls
3. The 'back' button doesn't refresh the listview with the new path's items
4. When sorted by name, folders are intermixed with files and shouldn't be IMO.
5. PropertyPage_Apply should extract the selected listview item
6. Click event on the listview probably should enable the Apply ppg button. Simple enough by trapping NM_CLICK & setting PropertyPage.Changed to True
7. When done playing with it, could you strip out all the unnecessary stuff (module functions, etc) from the project? From initial appearances, module only needs to contain subclass-related stuff? And that can be replaced by a small/simple thunk in order to keep the page self-contained. Or are there other calls that require the module(s)? Also, if you press Ctrl+F5 to start the project, you'll get errors related to unused 'stuff'
Yeah it's definitely a work in progress, will be addressing all those points and more. I mainly wanted to get it up now so you could see what's going to be required in terms of thunks; and also the general direction it's going with the switch to ListView.
For thunks we're still at 3:
-Combobox subclass
-ListView parent subclass (currently the frame's hwnd; for WM_NOTIFY/LVN_x+NM_x messages
-Sort callback (LVM_SORTITEMS AddressOf SortProc)
Re: How to setup a UserControl Property to Browse for a file
I fear trying to support keyboard navigation on the listivew may be a huge deal, code-wise? May require a hook or something else? The key problem is that VB doesn't know about the API-created controls; therefore, it passes keystrokes to whatever control, it knows about, has focus. Krool and others handle this, I believe, via VTable hacks.
Might want to consider this one item as a determining factor to how much you are willing to invest. If keyboard navigation is made to be "not an option", then these comments don't apply. But I personally feel that a control to be accessed by the mouse only is not a good compromise. Just my opinion.
Edited: Another observation regarding filtering. The filter should not exclude folders/drives. Otherwise, user loses ability to navigate from within the listview. Consider the functionality of the common dialog for file selection, when using filters.
Last edited by LaVolpe; Sep 16th, 2017 at 12:21 PM.
Insomnia is just a byproduct of, "It can't be done"
Re: How to setup a UserControl Property to Browse for a file
@fafalone. Maybe making this thing self-contained should no longer be an option? It would be nice if it were, but if it would be far easier to also use a class to prevent Implements issues in the property page, then that may still be very agreeable to users. And if that is the case, then don't restrict module usage either. Only make the module self-contained, i.e., no public API declarations or other public declarations that could potentially interfere with some project that your propertypage will be dropped into. In other words... private API declarations and very-uniquely named public variables as needed.
The option I submitted in post #2 is definitely not self-contained. Self-containment in my opinion is worthwhile if the workaround doesn't result in far more headaches and far more complications/code. For those that create an ocx to be compiled separately, outside of a project, and registered then self-containment is not an issue at all. For those that want to add the property page to an uncompiled usercontrol included in a project, then they may balk a bit about having to remember to include not only the propertypage, but other supporting files (bas, cls, etc). Of course the answer to that problem is always... Well then, it's just an option, you don't have to use it.
Self-containment may have been too optimistic
Insomnia is just a byproduct of, "It can't be done"
Re: How to setup a UserControl Property to Browse for a file
Well as of right now, there is nothing that uses Implements, and with the ListView we shouldn't need it either. If we're willing to add just a single bas, that would remove the need for thunks too. And it can be compacted down really well too; I did something like this in my TaskDialog project, it's got a subclass and 2 callbacks, but with a slight adjustment to the prototype, it can be redirected back to the property page in a single short line. Then collapsed down further, it turns it all into just 3 lines that's the user can even easily just move to a module they already have:
Code:
Public Function TaskDialogCallbackProc(ByVal hwnd As Long, ByVal uNotification As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal lpRefData As cTaskDialog) As Long: TaskDialogCallbackProc = lpRefData.ProcessCallback(hwnd, uNotification, wParam, lParam): End Function
Public Function TaskDialogEnumChildProc(ByVal hwnd As Long, ByVal lParam As cTaskDialog) As Long: TaskDialogEnumChildProc = lParam.ProcessEnumCallback(hwnd): End Function
Public Function TaskDialogSubclassProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As cTaskDialog) As Long: TaskDialogSubclassProc = dwRefData.ProcessSubclass(hwnd, uMsg, wParam, lParam, uIdSubclass): End Function
I'm using the same dwRefData object pointer technique already, so there shouldn't be a problem collapsing the outside .bas dependencies to a similar 3 lines. Well, the sort callback doesn't have an extra param, so that might add 3 more lines (right now, the pointer is stored as a public Long in the module to use for sort, because as mentioned before, making that ppg object public instead of per-function causes terminate to stop being called)
Regarding keystrokes, I agree it's worth pursuing, as I do lots of keyboard navigation myself, but I'll have to go study how Krool does it, because I'm not getting any keypress messages or setfocus results that are helping. One way might be to just subclass the window that's getting the keystrokes, then redirect them.
Last edited by fafalone; Sep 16th, 2017 at 04:00 PM.
Re: How to setup a UserControl Property to Browse for a file
So to sort like Windows with the folders and files not mixed, there's no equivalent to the lower level IShellFolder.CompareIDs for IShellItem, so that leaves either dropping down to that or doing it manually. After some initial trouble with it being slow, I found a new way to do it that's as fast as any other app, but there's the issue in sorting by type-- it sorts by the literal extension, like .bas is sorted as letter 'b' instead of letter 'v' from "Visual Basic Module". But that doesn't seem to be worth trying to do things manually.
Update
Ok, made some progress. The .bas depend (mPPGtest) has been reduced to the bare minimum, redirecting to the property page, but I still had to store a reference for the sort callback. But since this originates in a function, there's no issue with Terminate-- that's still called.
In fact here's the entire bas now:
Code:
Option Explicit
Private Declare Function vbaObjSetAddRef Lib "msvbvm60.dll" Alias "__vbaObjSetAddref" (ByRef objDest As Object, ByVal pObject As Long) As Long
Private ptrPPG As Long
Public Function LVSWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Object) As Long
ptrPPG = ObjPtr(dwRefData)
LVSWndProc = dwRefData.HandleListViewSubclass(hwnd, uMsg, wParam, lParam, uIdSubclass)
End Function
Public Function CBDWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Object) As Long
CBDWndProc = dwRefData.HandleComboSubclass(hwnd, uMsg, wParam, lParam, uIdSubclass)
End Function
Public Function ListViewSortProc(ByVal lParam1 As Long, ByVal lParam2 As Long, ByVal lParamSort As Long) As Long
Dim ppg As Object: vbaObjSetAddRef ppg, ptrPPG
ListViewSortProc = ppg.LVSortProc(lParam1, lParam2, lParamSort)
End Function
-Fixed the Back button (still needs work, only stores the previous entry)
-Sorted without mixing together, including when a folder loads (without clicking the button)
-Removed some unused functions, no more pEBrowse references
-Filter won't ever hide folders; zip files not counted in this regard
-Stability seems better, haven't had a crash or a Terminate failure in a while
Last edited by fafalone; Sep 16th, 2017 at 11:22 PM.
Re: How to setup a UserControl Property to Browse for a file
@fafalone. Agreed, lots better. Still something amiss. Played with property page and all went well, then opened the modPPGtest to see what changed and then tried to open the property page code and crash. While I was playing with the running property page, I did navigate to other drives, back and forth from the desktop and filters. Didn't catch whether the "terminate event" & "CDBWndProc->WM_Destroy" debug statements were printed to immediate window before crash.
I'm guessing the crash may be result of Terminate not firing then listview and/or combo being destroyed when property page code was accessed. That could make sense since... if subclass LVSWndProc and/or CBDWndProc triggered and dwRefData parameter no longer valid, a call using dwRefData likely results in memory access violation, invalid read/write pointers, etc.
The keyboard navigation is gonna be a pain I think.
P.S. Is vbaObjSetAddRef similar to ObjectFromPointer-type of functions that use CopyMemory?
Edited: Here are some changes I made that hopefully will reduce chance of crash due to propertypage being destroyed before WM_Destroy is called
Code:
' module now looks like
Option Explicit
Private Declare Function vbaObjSetAddRef Lib "msvbvm60.dll" Alias "__vbaObjSetAddref" (ByRef objDest As Object, ByVal pObject As Long) As Long
Private Declare Function RemoveWindowSubclass Lib "comctl32.dll" Alias "#412" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long) As Long
Private Declare Function DefSubclassProc Lib "comctl32.dll" Alias "#413" (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public ptrPPG As Long
Public Function LVSWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, _
ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Dim ppg As Object
If uMsg = WM_DESTROY Then
RemoveWindowSubclass hwnd, dwRefData, uIdSubclass
LVSWndProc = DefSubclassProc(hwnd, uMsg, wParam, lParam)
Else
vbaObjSetAddRef ppg, ptrPPG
LVSWndProc = ppg.HandleListViewSubclass(hwnd, uMsg, wParam, lParam, uIdSubclass)
End If
End Function
Public Function CBDWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, _
ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Dim ppg As Object
If uMsg = WM_DESTROY Then
RemoveWindowSubclass hwnd, dwRefData, uIdSubclass
CBDWndProc = DefSubclassProc(hwnd, uMsg, wParam, lParam)
Else
vbaObjSetAddRef ppg, ptrPPG
CBDWndProc = ppg.HandleComboSubclass(hwnd, uMsg, wParam, lParam, uIdSubclass)
End If
End Function
Public Function ListViewSortProc(ByVal lParam1 As Long, ByVal lParam2 As Long, ByVal lParamSort As Long) As Long
Dim ppg As Object: vbaObjSetAddRef ppg, ptrPPG
ListViewSortProc = ppg.LVSortProc(lParam1, lParam2, lParamSort)
End Function
Also had to change SubClass2 method for the tests... Above negates the Unsubclass2 method.
Code:
Private Function Subclass2(hwnd As Long, lpfn As Long, Optional uId As Long = 0&, Optional dwRefData As Long = 0&) As Boolean
If uId = 0 Then uId = hwnd
Subclass2 = SetWindowSubclass(hwnd, lpfn, uId, lpfn): Debug.Assert Subclass2
End Function
And last but not least, removed the local ptrPPG variable and made the module's ptrPPG Public, then added this in Initialize event: ptrPPG = ObjPtr(Me)
Last edited by LaVolpe; Sep 17th, 2017 at 10:06 AM.
Insomnia is just a byproduct of, "It can't be done"
Re: How to setup a UserControl Property to Browse for a file
Still getting random crashes here and there, but it's becoming less. I copied those changes into mine.
Have also since added:
-Full history support for Back
-Up one level button
-Explorer context menu on right click, with custom 'Select' entry as default
-Every click event/folder load updates or clears the selection through common sub LVSetSelection, which keeps module-level variables always up-to-date with selection
Going to spend some time tracking down instabilities before posting another update or starting up with keyboard stuff.
Re: How to setup a UserControl Property to Browse for a file
FYI: Keeping API controls in tab order can be accomplished with an intrinsic control.
For example, prefer using a picbox vs frame. Size picbox, borderless & tabstop set, on the ppg. Don't resize it in code. Make the listview a child of the picbox. Then to handle tabs... Note: You cannot set focus to the listview in Initialize event else following code in subclass generates error since picLView isn't visible yet on the ppg. Error in subclass procedure w/o error trapping = crash. If desired, set the initial control focus on SelectionChanged event?
Code:
Private Declare Function SetFocusAPI Lib "user32.dll" Alias "SetFocus" (ByVal hWnd As Long) As Long
Private Sub PicLView_GotFocus()
SetFocusAPI hLVS
End Sub
' and in the hLVS subclass procedure
Case NM_SETFOCUS ' NM_FIRST-7
If Not PropertyPage.ActiveControl Is PicLView Then
PicLView.SetFocus
End If
Similar can be used for the API combobox
A workaround for the arrows may be a hook established on NM_SETFOCUS and released on NM_KILLFOCUS (NM_FIRST-8) or subclassing the ppg parent for keystrokes between set/kill focus. Just a thought for now.
Alphanumeric keystrokes are processed by the listview. I find it a bit annoying that it appears a somewhat long delay is used between keystrokes. For example, if you have an item starting with letter F and another with P, then if the selected item is F, pressing P moves to item P. But even with a reasonable short delay, typing F generates beep (as if typing P+F quickly). Need to wait longer than what I consider normal before 'cache' clears and typing F moves to F without beep. Whether this is a result of the listview behavior or maybe the ppg intercepting and pre-processing keystrokes, don't know
Edited:
Going to spend some time tracking down instabilities...
If you can replicate the crash on demand and having problems identifying cause, post the steps needed to crash -- I and others may be able to help
Last edited by LaVolpe; Sep 17th, 2017 at 11:50 AM.
Insomnia is just a byproduct of, "It can't be done"
Re: How to setup a UserControl Property to Browse for a file
@stuck-n-past this is an assumption but I believe SHCreateItemFromIDList is a convenience function, and there are other ways to replace it's functionality.
Re: How to setup a UserControl Property to Browse for a file
Thanks DEXWERX, I was more curious then anything else as I was following along with what LaVolpe and fafalone were doing, but it all came to a end when I ran into the error.
There are a ton of Shell functions and SHCreateItemWithParent and SHCreateItemFromIDList look similar, but again I was just trying to keep up with the post so nothing too serious here.
I found a bunch of interesting stuff related to Shell functions, but what I didn't expect to find was the number of sites fighting to keep XP alive. There is one site that appears to have an updated Kernel for XP in order to keep it current including Shell functions. The only problem is that I wouldn't dare take the chance to mess with my XP by loading a 3rd party Kernel unless it was copy of my XP box I was doing it on.
I have a multi-boot system including Windows-7, but I have to admit that I prefer XP as I find it's more directed to a developer then the latest Microsoft OS's. To me it seems like they are doing all they can to move people away from the technical side of things which is fine for the casual user, but there's no reason they couldn't support multiple Desktop GUI's, one down and dirty for programmers, and a second one with all the frills.
Even with XP I've noticed a pullback from system details like with the Search program when looking for a string within files. I know for a fact that it purposely skips certain files when performing a search. I was forced to write my own Search Utility and it's amazing to see the difference when running both versions with the same criteria. My version gets a ton more hits then does the Microsoft version. Opps - sorry sort of got off topic.
So anyhow I'm not too pressed to get the Shell functions working, It was more of my hacking side thinking about nasty things such as grabbing the Shell.DLL from a later OS and changing it's name. Then try and register it and when referencing it in VB's declare statement use the new DLL name along with an Alias name if needed to try and prevent any conflicts. But I'm guessing that would be just about as ridiculous to try as it sounds.
Even if any of that would work, my guess is that the latest Shell.DLL has it's own set of dependencies and would snowball into copying DLL after DLL. I can't help it, I'm always trying to think of ways to break my system.
Re: How to setup a UserControl Property to Browse for a file
stuck-n-past, that single API is going to be the least of your problems. There's many more APIs and I believe some interfaces that aren't available in XP too. All of the functionality can be replicated in XP (save full Unicode support), by using different APIs/interfaces that are available rather than needing a depend, but it would take extensive rewrites. Not to mention MS has made this a huge pain by obnoxiously changing 'Minimum supported OS' to Windows Vista for almost everything that is in fact available earlier.
@LaVolpe, I had that thought too, but the controls don't seem to be receiving the kill focus notifications.
For setting focus, maybe do it after loading the all the items? That has to be called on startup and everything should be loaded by then. Will take a look at that tonight.
What makes most of the errors hard to find are that they don't outright crash it, just lock it up. And at both that and normal crashes are happening randomly; not directly reproducible. Like it crashed when I hit OK while the window was out of focus, and I thought 'oh ok let me take a look at that', but poof! It didn't happen again.
Update
Bug: WM_NOTIFYFORMAT is called but doesn't work; both the control and parent need to be subclassed (can be to the same procedure), but the property page needs to be subclassed before the control is even created. Had overlooked this since it was still being called.. weird. (Full unicode support in the LV depends on this message)
BTW, I'm concurrently making a UserControl version of this since it's largely identical; it can replace the DirListBox/FileListBox.
Last edited by fafalone; Sep 19th, 2017 at 05:25 AM.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by fafalone
I had that thought too, but the controls don't seem to be receiving the kill focus notifications.
Doesn't seem to be a problem on my end. Need to test for NM_KILLFOCUS, not WM_KILLFOCUS
Originally Posted by fafalone
Bug: WM_NOTIFYFORMAT is called but doesn't work; both the control and parent need to be subclassed (can be to the same procedure), but the property page needs to be subclassed before the control is even created. Had overlooked this since it was still being called.. weird. (Full unicode support in the LV depends on this message)
If the LV is assigned to the frame/picbox, then wouldn't you need to subclass that instead of the ppg? In either case, subclassing should only be needed for that call then unsubclassed after. No need to continue subclassing on the parent object if WM_NOTIFYFORMAT was the only reason for it to begin with.
Insomnia is just a byproduct of, "It can't be done"
Re: How to setup a UserControl Property to Browse for a file
I didn't read all the latest posts, and it is a somewhat related question:
I would like to ask if is there any way to make for example the property "List" or "ItemData" of for example the Krool's ComboBoxW control to behave in the property window at design time as the original ComboBox does: displaying a list.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by LaVolpe
Doesn't seem to be a problem on my end. Need to test for NM_KILLFOCUS, not WM_KILLFOCUS
If the LV is assigned to the frame/picbox, then wouldn't you need to subclass that instead of the ppg? In either case, subclassing should only be needed for that call then unsubclassed after. No need to continue subclassing on the parent object if WM_NOTIFYFORMAT was the only reason for it to begin with.
Hm I guess I was looking for the wrong message in the wrong place, will check again.
And yes it's the parent window (the frame/pp/uc) that's subclassed originally. The ListView hWnd itself doesn't need to be subclassed right now, but there's some messages we might eventually want. Like in the UC version drag&drop is more important, and WM_DROPFILES goes to the ListView hwnd (I'm most likely going to use IDropTarget but self-implementing has caused stability issues before, so the decision isn't final while I run using it a while). Edit: Forgot to mention, WM_NOTIFYFORMAT is called again right before a label edit, so couldn't remove the subclass anyway.
Also going to need yet another subclass proc in order to support renaming by label edit; the edit box that appears needs to be subclassed.
By the way, one of the random hard-to-crack errors seems to be just leaving the window open for a while results with a crash on exit, randomly. Like leaving it open for 5 minutes, not even interacting with it, then close it, and there's a 25% chance of a crash. Of course as soon as I started typing this paragraph, I got a run of no crashes, but the call stack goes vb6.exe/project1.exe->CoTaskMemFree->ntdll.dll 4 functions in, then access violation.
Bugfix
To avoid crashing/bad behavior, EnumRoot should exclude things like the Control Panel and Recycle Bin. Instead of jut SFGAO_FOLDER, also test for SFGAO_FILESYSANCESTOR. It excludes those will still including virtual objects we want, like Computer, Libraries, user folder, and Network.
Code:
siChild.GetAttributes SFGAO_FOLDER Or SFGAO_FILESYSANCESTOR, lAtr
If ((lAtr And SFGAO_FOLDER) = SFGAO_FOLDER) And ((lAtr And SFGAO_FILESYSANCESTOR) = SFGAO_FILESYSANCESTOR) Then
Last edited by fafalone; Sep 20th, 2017 at 07:02 PM.
Re: How to setup a UserControl Property to Browse for a file
Ah ok, finally got the call stack.
So it seems that as time running increases, % chance of crash increases. Again, this isn't using the control, just starting the project and letting it run.
Code:
Unhandled exception at 0x772de753 (ntdll.dll) in VB6.EXE: 0xC0000374: A heap has been corrupted.
> ntdll.dll!_RtlReportCriticalFailure@8() + 0x57 bytes
ntdll.dll!_RtlpReportHeapFailure@4() + 0x21 bytes
ntdll.dll!_RtlpLogHeapFailure@24() + 0xa1 bytes
ntdll.dll!_RtlFreeHeap@12() + 0x500a0 bytes
AcXtrnal.dll!NS_FaultTolerantHeap::APIHook_RtlFreeHeap() + 0x3e5 bytes
ole32.dll!CRetailMalloc_Free(IMalloc * pThis=0x75f566bc, void * pv=0x063cbf48) Line 687 C++
ole32.dll!CoTaskMemFree(void * pv=0x063cbf48) Line 475 C++
VBA6.DLL!0fc01d67()
VBA6.DLL!0fc01826()
VBA6.DLL!0fc01826()
VBA6.DLL!0fa9981b()
ole32.dll!CoDisconnectObject(IUnknown * pUnk=0x00000005, unsigned long dwReserved=0) Line 1173 + 0x9 bytes C++
VB6.EXE!00445e42()
VB6.EXE!004b4703()
VB6.EXE!00459ff6()
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Re: How to setup a UserControl Property to Browse for a file
Ever have a problem putting things down?
This is something like the 3rd time I've concluded that I have exhausted all possible ideas for the dreaded Ellipse button, but then before I know it, I find myself back with another post. This time my direction has completely derailed with a hack on top of hack! Purposely keeping clear of any sub-classing, I attempted an approach using Add-Ins, and surprisingly with some success until trying to access the UC's Property Bag object.
Does anybody know of a way to get / pass a reference of a UserControls PropertyBag to a basic Module?
Re: How to setup a UserControl Property to Browse for a file
Hm, I tried the usual method and got a propertybag object, but it didn't return the current values.
Code:
Public Function PlayWithPropbag(ptrPB As Long) As Long
Dim objPB As PropertyBag
vbaObjSetAddRef objPB, ptrPB
Debug.Print objPB.ReadProperty("DefaultColumns", "defval")
End Function
PlayWithPropbag ObjPtr(PropBag)
It just printed the defval instead of the actual value, which was read fine before being passed.
Re: How to setup a UserControl Property to Browse for a file
Isn't it obvious guys or am I missing something?
Code:
' In a bas Module:
Public Sub TestPB(nPB As PropertyBag)
MsgBox nPB.ReadProperty("PropName", 0)
End Sub
' From the UserControl:
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
TestPB PropBag
End Sub
Re: How to setup a UserControl Property to Browse for a file
Eduardo - Ah man, just have to laugh at myself sometimes!
These UserControls have been kicking my butt for so long that it got the better of me this time around. Typically I do something similar to the following when the need to access a UC's object in a module comes up.
The Call from inside the UserControl:
Code:
Call Module1(Me)
And the Module:
Code:
Public Sub Module1(User_Control as Object)
If (User_Control.Enabled) Then
do something...
End If
If (User_Control.OLEDropMode = vbOLEDropNone) Then
do something...
End If
Call User_Control.UC_Subroutine
End Sub
So when it came to using the PropertyBag in a Module, my mind was numb from all of my UC trauma, and the pursuing blindness limited me to trying my one and only working solutions. I didn't even try another way around, I just assumed the position of defeat.
Thanks so much for opening my eyes.
Last edited by stuck-n-past; Sep 28th, 2017 at 01:46 AM.
Re: How to setup a UserControl Property to Browse for a file
Don't feel bad I was just as bad lol.. so used to doing things with pointers, APIs, and undocumented stuff that I forget to consider if it's even needed.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by fafalone
Don't feel bad I was just as bad lol.. so used to doing things with pointers, APIs, and undocumented stuff that I forget to consider if it's even needed.
fafalone, BTW your code worked, I don't know why you said it didn't.
Re: How to setup a UserControl Property to Browse for a file
It loaded the current, user-set value, which was different from the default value?
ReadProperty returned 1,2,3 then the very next line called PlayWithPropbag, but the same ReadProperty call returned the default value ("defval" instead of the "1,2,3").
Re: How to setup a UserControl Property to Browse for a file
It's amazing that at times the simplest approach works yet it completely eludes me.
I can't tell you the number of times where I have solved my own problem just by describing it to others. Once you've fallen into this scenario its time to dazzle them with brilliance or baffle them with bullshit, in order to avoid any further indignity. The old 'I meant to do that' posture.
Last edited by stuck-n-past; Sep 28th, 2017 at 02:08 AM.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by fafalone
It loaded the current, user-set value, which was different from the default value?
Yes.
Originally Posted by fafalone
ReadProperty returned 1,2,3 then the very next line called PlayWithPropbag, but the same ReadProperty call returned the default value ("defval" instead of the "1,2,3").
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by stuck-n-past
I can't tell you the number of times where I have solved my own problem just by describing it to others.
Yes, very true, it also happens to me.
I think it is because we need to think clearly to explain it to others, and while making the effort to expose it clearly, we realize what the solution is.
Now I have another consideration: it is no wonder then that many times the questions in the forum are not very clear about what the problem is and what the OP is wanting.
Sometimes I didn't get a solution to something I asked, but after answering the questions that others trying to help in the forum ask (about the problem), I end with much more clarity about it.
At work, that role can be supplied by fellow programmers when the developer have a work team, but many of us don't have that possibility and the forum helps in that regard (just to certain degree).
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by Eduardo-
At work, that role can be supplied by fellow programmers when the developer have a work team, but many of us don't have that possibility and the forum helps in that regard (just to certain degree).
Thinking back many years when younger and things were different, I worked with a great bunch of people where we all supported one another. Odd to say it happened at work, but those times hold some of the best memories. In lieu of a work environment, having this Forum has been indispensable, and I'll never be able to properly thank all who have helped me.
Re: How to setup a UserControl Property to Browse for a file
Reminds me of what we had when I was younger... back on AOL in the VB32/VB5 chatrooms, a bunch of us teenagers solidly dedicated to learning how to use VB to make programs that ran chatroom games, kicked people off the service/crashed their client, turned e-mail into automatic warez servers and penetrated network security... you could get help 24/7 from that dedicated community
And today... does everyone else here work in programming?? I still do all my programming as a hobby save for the odd contract job fixing someones legacy VB app.
The clarity of questions here I think has a lot to do with the surprisingly high % of newcomers who don't speak English as a first language.
Re: How to setup a UserControl Property to Browse for a file
Say fafalone, back up in post 101 of yours, I was curious about the VB reference count and the life span of the Object. In rare occasions I've used vbaObjSetAddRef in similar situations and have always been worried about memory leaks! Is there any cleanup that needs to be done to release the reference created?
Re: How to setup a UserControl Property to Browse for a file
I'm still pondering if there's some way to do this that we're missing. And "this" is: Getting an ellipse button on a UC's property that we can do with what we want (via an event that it fires).
LaVolpe's approach certainly got us there, but it was quite involved. There are several ways we can "get" that ellipse button through the normal ways of doing things, but not necessarily have control of what it does: 1) custom property pages, 2) Font, 3) Color, 4) Picture, 5) DataFormat, 6) About Page.
LaVolpe actually uses #1, but he "spoofs" it to get what he wants. And that spoofing takes inserting thunks and doing subclassing.
The problems with #2, #3, #4, & #5 is that they create IDE modal forms which are difficult to take control of.
That leaves #6. Here's the Microsoft Page on the subject. By itself, this gives us a way to fire an event with the ellipse button that we can do with what we want. However, there are downsides: 1) we only get one property, 2) we can't rename the property (i.e., it's always "(About)").
So, to make it do what we'd really want (as many properties using it as we'd like, and named anything we'd like), we're probably still back to thunking, but possibly not subclassing. Using the "About" approach, we don't have to worry about getting rid of any Properties window.
It's not going to be me that digs into LaVolpe's thunk/assembly code to see if it can be "bent" to deal with these About events, but I do think it may be possible.
Just throwing it out.
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by stuck-n-past
Say fafalone, back up in post 101 of yours, I was curious about the VB reference count and the life span of the Object. In rare occasions I've used vbaObjSetAddRef in similar situations and have always been worried about memory leaks! Is there any cleanup that needs to be done to release the reference created?
Thanks.
It should be freed when it goes out of scope; but it can't hurt to manually release it by adding Set ppg = Nothing to the end of the function. In fact I had some issues with setting an object to something new without releasing it first, so there might be some memory issues. Setting to nothing is calling the objects Release method.
Re: How to setup a UserControl Property to Browse for a file
Originally Posted by stuck-n-past
Say fafalone, back up in post 101 of yours, I was curious about the VB reference count and the life span of the Object. In rare occasions I've used vbaObjSetAddRef in similar situations and have always been worried about memory leaks! Is there any cleanup that needs to be done to release the reference created?
Thanks.
Obj references always get cleaned up by runtime at the end of the routine/exiting scope. __vbaObjSetAddRef is also nice enough to remove the reference of the pointer you are assigning to, so no leak there either.
Code:
Dim o1 As Object
Set o1 = New Class1
Dim o2 As New Class2
ObjSet(o1) = ObjPtr(o2) ' releases o1
'o2 is released once out of scope
Last edited by DEXWERX; Sep 29th, 2017 at 06:50 AM.
Re: How to setup a UserControl Property to Browse for a file
The issue I was talking about, I had some shell interfaces that pointed to a file; either IShellItem or IParentAndItem were causing an issue. If you re-assigned the variable to another object without doing Set = Nothing, something wasn't getting released, and explorer.exe and every other app would hang and crash if it attempted to do certain operations like rename with a file in a folder that had been enumerated, until not only the program was ended, the VB IDE had to be closed too.