|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
VB6 : Attach Event Handlers to Dynamically Generated ControlsOn our current project we would like to implement a flexible design, based on form controls generation in regards of data structures retrieved from a database. For instance, if we have two fields in a table (say employee and date), we would like our program to automatically populate a form with two fields (employee and date). We've been successful so far with this approach, but we've encountered a problem while trying to bind handlers for events of these generated controls; when the number of controls is known, using a WithEvents declaration works fine, but in our case we don't know the number of controls (it's dynamic), hence we cannot make the appropriate declaration (WithEvents doesn't work with arrays, or the like). We've looked the archives for VB6 reflection, or for an Excel-like OnAction event - without success. However we've come across an interesting thread located at <URL:http://groups.google.fr/group/microsoft.public.vb.general.discussion/browse_frm/thread/406d8a574bec6e84/dbf90a95081f2e20> ....with a post by Mr. Jeff Johnson who, while stating that the problem cannot be solved directly, suggests that there are alternate ways which could be used, without unfortunately discussing them much. We'd be grateful for any hint/example which could help us into solving this issue (or advice on better ways to achieve our goal). Thanks in advance. Regards, Yep. Make a wrapper for a Textboxcontrol:
------- Private WithEvents moTextbox As TextBox Private moForm As Form Public Sub Create(ByVal voTextbox As TextBox, voForm As Form) Set moTextbox = voTextbox Set moForm = voForm End Sub Private Sub moTextbox_Click() Call moForm.DoSomeCommonEvent End Sub -------- Add for each dynamic created control the wrapper to a collection to hold a reference to the wrapper: set oWrapper = new Wrapper oWrapper.Create(oTextbox, me) call oSomeCollection.Add(oWrapper) ML Show quoteHide quote "Yep" <y-e.pe***@em-lyon.com> schreef in bericht <URL:http://groups.google.fr/group/microsoft.public.vb.general.discussion/brnews:1127218162.117587.275570@g49g2000cwa.googlegroups.com... > Hi, > > On our current project we would like to implement a flexible design, > based on form controls generation in regards of data structures > retrieved from a database. > > For instance, if we have two fields in a table (say employee and date), > we would like our program to automatically populate a form with two > fields (employee and date). > > We've been successful so far with this approach, but we've encountered > a problem while trying to bind handlers for events of these generated > controls; when the number of controls is known, using a WithEvents > declaration works fine, but in our case we don't know the number of > controls (it's dynamic), hence we cannot make the appropriate > declaration (WithEvents doesn't work with arrays, or the like). > > We've looked the archives for VB6 reflection, or for an Excel-like > OnAction event - without success. However we've come across an > interesting thread located at > > owse_frm/thread/406d8a574bec6e84/dbf90a95081f2e20> Show quoteHide quote > > ...with a post by Mr. Jeff Johnson who, while stating that the problem > cannot be solved directly, suggests that there are alternate ways which > could be used, without unfortunately discussing them much. > > We'd be grateful for any hint/example which could help us into solving > this issue (or advice on better ways to achieve our goal). > > Thanks in advance. > > > Regards, > Yep. > Yep wrote:
Show quoteHide quote > Hi, As an alternative to Martin's approach, you could create at design time> > On our current project we would like to implement a flexible design, > based on form controls generation in regards of data structures > retrieved from a database. > > For instance, if we have two fields in a table (say employee and date), > we would like our program to automatically populate a form with two > fields (employee and date). > > We've been successful so far with this approach, but we've encountered > a problem while trying to bind handlers for events of these generated > controls; when the number of controls is known, using a WithEvents > declaration works fine, but in our case we don't know the number of > controls (it's dynamic), hence we cannot make the appropriate > declaration (WithEvents doesn't work with arrays, or the like). one of each control that you might want to create dynamically, with Visible set to False, and Index set to zero. Then just Add to these control arrays as you create new controls dynamically - they will all use the same event handler. -- Larry Lard Replies to group please "Yep" <y-e.pe***@em-lyon.com> wrote in message I guess you're referring to this statement:news:1127218162.117587.275570@g49g2000cwa.googlegroups.com... > We've looked the archives for VB6 reflection, or for an Excel-like > OnAction event - without success. However we've come across an > interesting thread located at > > <URL:http://groups.google.fr/group/microsoft.public.vb.general.discussion/browse_frm/thread/406d8a574bec6e84/dbf90a95081f2e20> > > ...with a post by Mr. Jeff Johnson who, while stating that the problem > cannot be solved directly, suggests that there are alternate ways which > could be used, without unfortunately discussing them much. ------------- I am sorely disappointed with what I thought would be a really powerful way of building a dynamic interface, and I have yet to find ANY way to create a "pluggable" interface that doesn't suffer from some sort of glitch. ------------- Being over two years ago and being that even then whatever I had tried was probably a year or two prior, I don't remember what "alternate ways" I've looked at; I've simply given up on it in VB. Did you look at the link mentioned by Ken Halter in the next post in that thread?
Show quote
Hide quote
"Jeff Johnson [MVP: VB]" <i.get@enough.spam> wrote in message Darn link in that post went stale on us <g> Here's the updated link.news:uIZpIlevFHA.2792@tk2msftngp13.phx.gbl... > > I guess you're referring to this statement: > > ------------- > I am sorely disappointed with what I thought would be a really powerful > way of building a dynamic interface, and I have yet to find ANY way to > create a "pluggable" interface that doesn't suffer from some sort of > glitch. > ------------- > > Being over two years ago and being that even then whatever I had tried was > probably a year or two prior, I don't remember what "alternate ways" I've > looked at; I've simply given up on it in VB. Did you look at the link > mentioned by Ken Halter in the next post in that thread? EventCollection Class v2.0 - Add event support to Collections http://www.mvps.org/emorcillo/en/code/vb6/index.shtml .....and, here's my attempt..... uses arrays instead of collections. Add Controls at Runtime With Events (kind of) http://www.vbsight.com/Code.htm -- Ken Halter - MS-MVP-VB - http://www.vbsight.com DLL Hell problems? Try ComGuard - http://www.vbsight.com/ComGuard.htm Please keep all discussions in the groups.. The easiest solution is to use control array. At design time add all the
controls that you could possibly use, set Index to 0, and Visible to False. Use Load statement at runtime to add more controls. Some solutions depends on the fact that ObjPtr() does not increase the reference count of an object. The pointer is added as a text to a collection and used later to refer to the object. See the comments about ObjPtr here: http://support.microsoft.com/default.aspx?scid=kb;en-us;199824 While playing with these ideas, you may find the following code useful, which came from another poster. It lets you see the reference count. I modified it a little since I found a variable that was not declared. If the compiler complains about "IUnknown", make sure that you have "OLE Automation" in the list of references. Source: http://groups.google.com/group/microsoft.public.vb.com/browse_thread/thread/9ab3e23591a2ea8e/7db48efc98f6a4ee Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long) Public Function GetRefCount(ByVal unk As IUnknown) As Long Dim RefCountAddr As Long Dim RefCounter As Long RefCountAddr = ObjPtr(unk) + 4 If RefCountAddr = 4 Then ' Object was not set GetRefCount = 0 Exit Function End If CopyMemory RefCounter, ByVal RefCountAddr, 4 GetRefCount = RefCounter - 2 End Function Public Sub AddRef(ByVal unk As IUnknown) Dim RefCountAddr As Long Dim RefCounter As Long RefCountAddr = ObjPtr(unk) + 4 If RefCountAddr = 4 Then ' Object was not set Exit Sub End If CopyMemory RefCounter, ByVal RefCountAddr, 4 RefCounter = RefCounter + 1 CopyMemory ByVal RefCountAddr, RefCounter, 4 End Sub Public Sub ReleaseRef(ByVal unk As IUnknown) Dim RefCountAddr As Long Dim RefCounter As Long RefCountAddr = ObjPtr(unk) + 4 If RefCountAddr = 4 Then RefCounter = 0 Exit Sub End If CopyMemory RefCounter, ByVal RefCountAddr, 4 RefCounter = RefCounter - 1 CopyMemory ByVal RefCountAddr, RefCounter, 4 End Sub Show quoteHide quote "Jeff Johnson [MVP: VB]" <i.get@enough.spam> wrote in message news:uIZpIlevFHA.2792@tk2msftngp13.phx.gbl... > > "Yep" <y-e.pe***@em-lyon.com> wrote in message > news:1127218162.117587.275570@g49g2000cwa.googlegroups.com... > >> We've looked the archives for VB6 reflection, or for an Excel-like >> OnAction event - without success. However we've come across an >> interesting thread located at >> >> <URL:http://groups.google.fr/group/microsoft.public.vb.general.discussion/browse_frm/thread/406d8a574bec6e84/dbf90a95081f2e20> >> >> ...with a post by Mr. Jeff Johnson who, while stating that the problem >> cannot be solved directly, suggests that there are alternate ways which >> could be used, without unfortunately discussing them much. > > I guess you're referring to this statement: > > ------------- > I am sorely disappointed with what I thought would be a really powerful > way of building a dynamic interface, and I have yet to find ANY way to > create a "pluggable" interface that doesn't suffer from some sort of > glitch. > ------------- > > Being over two years ago and being that even then whatever I had tried was > probably a year or two prior, I don't remember what "alternate ways" I've > looked at; I've simply given up on it in VB. Did you look at the link > mentioned by Ken Halter in the next post in that thread? > "Someone" <nob***@cox.net> wrote in message news:l4WXe.44103$ct5.11378@fed1read04...> The easiest solution is to use control array. At design time add all the What I wanted most was to be able to add ANY control dynamically (including > controls that you could possibly use, set Index to 0, and Visible to > False. Use Load statement at runtime to add more controls. UserControls that may or may not even have been developed when the parent app was first written) and hook it up to an event handler so that I could take advantage of VB's "internal plumbing" for events. Such a thing just isn't to be found in VB6. I'll hand it to .NET: they made this a snap. Yep wrote:
Hi, > On our current project we would like to implement a flexible design, First thank you all; not only has our problem been solved by your> based on form controls generation in regards of data structures > retrieved from a database. suggestions, but some of the ideas proposed have made us think about new ways to solve other problems. Martin/Larry : We've been able to build quick test cases with your suggestions, and both work perfectly; Martin's pattern is excellent (I'll keep that at hand) and Larry's usage of the language is quite clever - thank you very much! Jeff/Ken: First sorry for the incomplete quote, the paragraph you're quoting, Jeff, is exactly the one I was referring to. I'd tried the link but it was 404 at the time, with Ken's updating I've been able to retrieve his work. I'm currently reading the code (and will probably spend more time on the website on my free time), and we might go for it as it is nicely implemented (that would save us the time to build our own encapsulation of any of Martin's or Larry's technique). Again, thank you all for your time and insightful suggestions. Cheers, Yep.
Show quote
Hide quote
On 20 Sep 2005 05:09:22 -0700, "Yep" <y-e.pe***@em-lyon.com> wrote: <snip>>Hi, > >On our current project we would like to implement a flexible design, >based on form controls generation in regards of data structures >retrieved from a database. > >For instance, if we have two fields in a table (say employee and date), >we would like our program to automatically populate a form with two >fields (employee and date). > >We've been successful so far with this approach, but we've encountered >a problem while trying to bind handlers for events of these generated >controls; when the number of controls is known, using a WithEvents >declaration works fine, but in our case we don't know the number of >controls (it's dynamic), hence we cannot make the appropriate >declaration (WithEvents doesn't work with arrays, or the like). Personally I would use Control Arrays - just plant one on the Form, set its Index property to 0 - and then load as many intances as you need This is the most easy way of doing it. But the controls have the same
container. Show quoteHide quote "J French" <erew***@nowhere.uk> schreef in bericht news:43310baf.83664437@news.btopenworld.com... > On 20 Sep 2005 05:09:22 -0700, "Yep" <y-e.pe***@em-lyon.com> wrote: > > >Hi, > > > >On our current project we would like to implement a flexible design, > >based on form controls generation in regards of data structures > >retrieved from a database. > > > >For instance, if we have two fields in a table (say employee and date), > >we would like our program to automatically populate a form with two > >fields (employee and date). > > > >We've been successful so far with this approach, but we've encountered > >a problem while trying to bind handlers for events of these generated > >controls; when the number of controls is known, using a WithEvents > >declaration works fine, but in our case we don't know the number of > >controls (it's dynamic), hence we cannot make the appropriate > >declaration (WithEvents doesn't work with arrays, or the like). > > <snip> > > Personally I would use Control Arrays > - just plant one on the Form, set its Index property to 0 > - and then load as many intances as you need On Wed, 21 Sep 2005 10:51:37 +0200, "Martin" <ML@community.nospam> You can change the container at run timewrote: >This is the most easy way of doing it. But the controls have the same >container. - but not the Parent - without using APIs |
|||||||||||||||||||||||