Andy and Blair,
Try as I may Try as I might I just can't get this <expletive deleted> ComboBox To work out right. I'm trying to capture a character entered in the edit portion of the combo box, whether through onKeyPressed:, onKeyReleased: or onKeyTyped:. I've looked through DSDN and seen and tried lots of things -- pretranslate, oninputmask, wmgetdlgcode, I don't even remember them all. I've seen posts from other people who've tried the above also and it hasn't worked for them. Either I'm missing something or there's something somewhere (in Windows or in Dolphin) that really is gobbling up these little things (in shell views, not just dialog views). Keith Alcock previously put it well (14 August 2000 13:08 in DSDN): "I have reviewed the discussion of the dropdown combobox and the associated edit box, but to little avail. While it is possible to add CBN_EDITCHANGE and CBN_EDITUPDATE to CbnMap in the class initialization function, and then instance methods cbnEditChange and cbnEditUpdate to receive notification of any changes, it is not possible to react on the enter, tab, or esc keys." Thank you for a little more illumination on this. -- Louis |
Louis,
I suspect the difficulties with ComboBox stem from it's strange structure as a Windows control. If I remember correctly it's something like this : ComboBox ->child list box ->child edit control ->child drop down button The window procedure provided by Windows that supplies the default behaviour basically concentrates on it's nature as a list. Therefore most of the list events are propagated up to the top level control (the combo box itself). I'm not sure whether the #onKeyPressed event handler will respond to key presses in the list or, perhaps, none at all, but my guess is that the child edit control doesn't get a look in. One other thing has bothered me about the editable ComboBox. This is that, it is difficult to see how this can be treated correctly as a ListBox (something with an indexable selection) when the user is allowed to type his or her own entry that isn't in the list at all. All this makes me suspect that, for it's existing place in the view hierarchy, only #simple or #dropDownList modes (the non editable ones should be allowed). If we made this restriction, then the next thing would be to create another version of the combo box control under TextEdit that inherits the basic behaviour of a single line editor (the control would end up being a text value control with a list of predefined "hints" provided by the drop down list). Now this is easier said than done. Whoever implements this will have to create the combo box and hold onto the handle for this inside the new TextEditList (or whatever). You will then have to locate the child handle for the edot control and make this the handle of the TextEditList itself. Once this is done you'll have to install the Dolphin window procedure so the the WM_Xxxx messages are run through Dolphin. You can probably use #subclassWindow to do this. That should keep someone going over the weekend - personally I'm going to buy the Christmas tree! Best Regards, Andy Bower Dolphin Support "Louis Sumberg" <[hidden email]> wrote in message news:[hidden email]... > Andy and Blair, > > Try as I may > Try as I might > I just can't get this <expletive deleted> ComboBox > To work out right. > > I'm trying to capture a character entered in the edit portion of the combo > box, whether through onKeyPressed:, onKeyReleased: or onKeyTyped:. I've > looked through DSDN and seen and tried lots of things -- pretranslate, > oninputmask, wmgetdlgcode, I don't even remember them all. I've seen > from other people who've tried the above also and it hasn't worked for them. > Either I'm missing something or there's something somewhere (in Windows or > in Dolphin) that really is gobbling up these little things (in shell views, > not just dialog views). > > Keith Alcock previously put it well (14 August 2000 13:08 in DSDN): > "I have reviewed the discussion of the dropdown combobox and the associated > edit box, but to little avail. While it is possible to add CBN_EDITCHANGE > and CBN_EDITUPDATE to CbnMap in the class initialization function, and then > instance methods cbnEditChange and cbnEditUpdate to receive notification of > any changes, it is not possible to react on the enter, tab, or esc keys." > > Thank you for a little more illumination on this. > > -- Louis > > |
Andy,
> Now this is easier said than done. Whoever implements this will have to > create the combo box and hold onto the handle for this inside the new > TextEditList (or whatever). You will then have to locate the child handle > for the edot control and make this the handle of the TextEditList itself. > Once this is done you'll have to install the Dolphin window procedure so the > the WM_Xxxx messages are run through Dolphin. You can probably use > #subclassWindow to do this. Would it not be easier to build a composite presenter from a drop down list box and a text edit? Then the synchronization of the controls could be done somewhere other than Redmond :) The only straggling issue is that, AFAIK, there is no supported way to make a composite presenter behave as a value presenter. The last time I tried it, it seemed deceptively difficult, but, I was working on a fairly complicated problem, so the real problem might have been elsewhere. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Bill,
> Would it not be easier to build a composite presenter from a drop down list > box and a text edit? Then the synchronization of the controls could be done > somewhere other than Redmond :) The only straggling issue is that, AFAIK, > there is no supported way to make a composite presenter behave as a value > presenter. The last time I tried it, it seemed deceptively difficult, but, > I was working on a fairly complicated problem, so the real problem might > have been elsewhere. Well it might be easier but you'd be building a non-native widget with all the maintenance and useability nightmares that this involves. In general, this is against the "spirit of Dolphin", which is to make use of native widgets where they exist. However, if I was going to implement a ComboBox built as a composite then I'd probably do this all on the view side. There's surely no point creating a new type of composite presenter ... what you really want is a new type of TextEdit view that can be clipped onto a TextPresenter. Best Regards Andy Bower Dolphin Support |
Andy,
> Well it might be easier but you'd be building a non-native widget with all > the maintenance and useability nightmares that this involves. With respect, given the trouble that we've had with rich text controls, the nightmares seem to be worse when native widgets change out from under us. Something that we built is much less likely to cause trouble, and if it does, we can fix it rather than scrambling to find a way to compensate for changes outside of our control. Of course, I'm not suggesting a Smalltalk rich text control because that would be a performance nightmare, and in fairnes, a rich text control is a whole lot more complicated than a combo box, so it's more likely to cause interfacing problems. Howver, a not-quite-combo box seems a good candidate for emulation, especially given the oddities of Microsoft's implementation. Actually, I'm not sure I'd call what I have in mind "emulation", because it's really composing native widgets to work as desired as opposed to using a different native widget that's not quite right for the job. > In general, > this is against the "spirit of Dolphin", which is to make use of native > widgets where they exist. Good point. However, I've had to deviate from this already for performance reasons when dealing with 100 or more visible controls (easier to reach than one might initially suspect), and the genie just won't go back in/ the bottle. > However, if I was going to implement a ComboBox > built as a composite then I'd probably do this all on the view side. There's > surely no point creating a new type of composite presenter ... what you > really want is a new type of TextEdit view that can be clipped onto a > TextPresenter. Interesting! Would that be the preferred way to create any kind of composite value widget? If so, I'll keep that in mind for the next time I have trouble with the app that got me thinking about all of this. Another thing I'd like to have is a labeled text edit. I spend a fair amount of time positioning static text and text edit pairs, and it would be nice to have a "composite" to do the job. I've never messed with it because I didn't want the overhead of a composite presenter and layout manager for each text edit, and because I didn't see how to make the result compatible with a text edit; this migth be the answer. Might an example find its way into the MVP Night School? Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Andy Bower
Andy,
While I understood some of what you said, a lot of it was Greek to me, although I did get the impression that you were confirming that indeed, the current Dolphin implementation of ComboBox does not, and can not, respond to onKeyPressed: Windows messages. My gut reaction is "Well heck, OA should be supplying a combo box that works like it's been working in Windows programs all these years -- we're not talking about a new widget after all. This is basic widget set stuff." I'm not a C/C++ or Windows programmer -- when you say "The window procedure provided by Windows that supplies the default behaviour basically concentrates on it's nature as a list" it sounds like you're pointing the finger at Windows, but that also makes it sound like each vendor of tools has to get around this default behavior and somehow achieve the behavior that is commonly recognized in combo boxes. As for the seeming inconsistency of a user being able to type something in the edit portion that is not in the listbox portion, that doesn't seem to be a conceptual problem to me. After all, a listbox can have no selection, so why not the listbox portion of a combo box. I'd much rather see ComboBox work correctly than have two classes of ComboBox. Finally, regarding the phrase "Whoever implements this ...", obviously I'd like that "Whoever" to be OA. I haven't a clue where to begin or what to do. I remember seeing in DSDN that Blair had mentioned back in 1998 that he was working on, or thinking of working on, a writeup on the path that messages take in Dolphin, but I haven't seen that. I think it would be very helpful for a number of things, though it might not make much of a difference in this particular instance -- just thought I'd mention it anyway. Thanks again. -- Louis |
Louis,
> While I understood some of what you said, a lot of it was Greek to me, > although I did get the impression that you were confirming that indeed, the > current Dolphin implementation of ComboBox does not, and can not, respond to > onKeyPressed: Windows messages. My gut reaction is "Well heck, OA should be > supplying a combo box that works like it's been working in Windows programs > all these years -- we're not talking about a new widget after all. This is > basic widget set stuff." As far as I'm aware the existing ComboBox funnctions exactly like the Windows "COMBOBOX" control. That's what it is, an instance of a COMBOBOX window wrapped by Dolphin. Show me the C/C++ that allows a Windows COMBOBOX respond to WM_XXXX messages for key presses and we'll be able to make the Dolphin equivalent do the same. > I'm not a C/C++ or Windows programmer -- when you say "The window procedure > provided by Windows that supplies the default behaviour basically > concentrates on it's nature as a list" it sounds like you're pointing the > finger at Windows, but that also makes it sound like each vendor of tools > has to get around this default behavior and somehow achieve the behavior > that is commonly recognized in combo boxes. The Windows (editable) COMBOBOX is a list that wraps an edit control. The functionality being requested is, effectively, an edit control wrapping a list. As I say, I think it's probably possible to implement this but I doubt it's trivial. > As for the seeming inconsistency of a user being able to type something in > the edit portion that is not in the listbox portion, that doesn't seem to be > a conceptual problem to me. After all, a listbox can have no selection, so > why not the listbox portion of a combo box. I'd much rather see ComboBox > work correctly than have two classes of ComboBox. Normally, a list has an integer selection index or 0 meaning no selection. If I have a combo box containing a list "Alf, Bert, Fred" and I type "Charlie", what integer selection should the list portray, 0? How would you acces that from a ListPresenter. Surely the point is that most people use a list to control the possible entries to ensure they are valid. With an editable combobox you can't do this. No, I think it would be much more consistent to treat an editable combo an a text editor with a number of preconfiguired entries and the value would be suitable for connection to a TextPresenter. Best regards, Andy Bower Dolphin Support |
Andy,
Take a look inside the beta version of QKS Smalltalk for Win32. It may have examples you could leverage to build a Dolphin solution. The technique is to extract the edit control from the within the combo-box... Here are some snippets I grabbed from our old Win32 codebase <?method [ editHWnd ^<<ChildWindowFromPoint(self,1,1):address>>. ]?> <?method [ editWindow “Validate the edit-window sub-component” (editWindow isNil or: [editWindow isExternalized not]) ifTrue: [ “Hack it together” (editWindow := TextField new) container: self; hWndSpecial: self editHWnd. ]. “And return it” ^editWindow ]?> -- Dave Simmons [www.qks.com / www.smallscript.com] "Effectively solving a problem begins with how you express it." "Andy Bower" <[hidden email]> wrote in message news:91h8gr$433no$[hidden email]... > Louis, > > > While I understood some of what you said, a lot of it was Greek to me, > > although I did get the impression that you were confirming that indeed, > the > > current Dolphin implementation of ComboBox does not, and can not, respond > to > > onKeyPressed: Windows messages. My gut reaction is "Well heck, OA should > be > > supplying a combo box that works like it's been working in Windows > programs > > all these years -- we're not talking about a new widget after all. This > is > > basic widget set stuff." > > As far as I'm aware the existing ComboBox funnctions exactly like the > Windows "COMBOBOX" control. That's what it is, an instance of a COMBOBOX > window wrapped by Dolphin. Show me the C/C++ that allows a Windows > respond to WM_XXXX messages for key presses and we'll be able to make the > Dolphin equivalent do the same. > > > I'm not a C/C++ or Windows programmer -- when you say "The window > procedure > > provided by Windows that supplies the default behaviour basically > > concentrates on it's nature as a list" it sounds like you're pointing the > > finger at Windows, but that also makes it sound like each vendor of tools > > has to get around this default behavior and somehow achieve the behavior > > that is commonly recognized in combo boxes. > > The Windows (editable) COMBOBOX is a list that wraps an edit control. The > functionality being requested is, effectively, an edit control wrapping a > list. As I say, I think it's probably possible to implement this but I doubt > it's trivial. > > > As for the seeming inconsistency of a user being able to type something in > > the edit portion that is not in the listbox portion, that doesn't seem to > be > > a conceptual problem to me. After all, a listbox can have no selection, > so > > why not the listbox portion of a combo box. I'd much rather see ComboBox > > work correctly than have two classes of ComboBox. > > Normally, a list has an integer selection index or 0 meaning no selection. > If I have a combo box containing a list "Alf, Bert, Fred" and I type > "Charlie", what integer selection should the list portray, 0? How would you > acces that from a ListPresenter. Surely the point is that most people use a > list to control the possible entries to ensure they are valid. With an > editable combobox you can't do this. No, I think it would be much more > consistent to treat an editable combo an a text editor with a number of > preconfiguired entries and the value would be suitable for connection to a > TextPresenter. > > Best regards, > > Andy Bower > Dolphin Support > > > |
In reply to this post by Bill Schwab
> Would it not be easier to build a composite presenter from a drop down
list > box and a text edit? I'll leap on-board at this point. I've no idea whether Louis's original requirements force the use of a combo-box, but in the interests of Keeping It Simple, I'll mention another possibility: just use an ordinary text field with it a dynamically-created context menu. It doesn't have the visual feedback that a ComboBox has, but it is (I think) a fairly normal Windows idiom. (You may also think -- with me -- that the standard Combo Box is a terrible bit of UI design, in which case you'll welcome an excuse not to use it ;-) -- chris |
In reply to this post by David Simmons
David,
This is effectively what I was suggesting in my original reply. BTW, could one not use the id of the edit control to locate it rather than ChildWindowFromPoint? That's what first came to mind when I was considering it the other day? Best Regards, Andy Bower Dolphin Support "David Simmons" <[hidden email]> wrote in message news:DoZ_5.39018$[hidden email]... > Andy, > > Take a look inside the beta version of QKS Smalltalk for Win32. It may have > examples you could leverage to build a Dolphin solution. The technique is > to extract the edit control from the within the combo-box... > > Here are some snippets I grabbed from our old Win32 codebase > > <?method [ > editHWnd > > ^<<ChildWindowFromPoint(self,1,1):address>>. > ]?> > > <?method [ > editWindow > > "Validate the edit-window sub-component" > (editWindow isNil or: [editWindow isExternalized not]) ifTrue: > [ > "Hack it together" > (editWindow := TextField new) > container: self; > hWndSpecial: self editHWnd. > ]. > > "And return it" > ^editWindow > ]?> > > -- Dave Simmons [www.qks.com / www.smallscript.com] > "Effectively solving a problem begins with how you express it." > > "Andy Bower" <[hidden email]> wrote in message > news:91h8gr$433no$[hidden email]... > > Louis, > > > > > While I understood some of what you said, a lot of it was Greek to me, > > > although I did get the impression that you were confirming that > > the > > > current Dolphin implementation of ComboBox does not, and can not, > respond > > to > > > onKeyPressed: Windows messages. My gut reaction is "Well heck, OA > should > > be > > > supplying a combo box that works like it's been working in Windows > > programs > > > all these years -- we're not talking about a new widget after all. > > is > > > basic widget set stuff." > > > > As far as I'm aware the existing ComboBox funnctions exactly like the > > Windows "COMBOBOX" control. That's what it is, an instance of a COMBOBOX > > window wrapped by Dolphin. Show me the C/C++ that allows a Windows > COMBOBOX > > respond to WM_XXXX messages for key presses and we'll be able to make the > > Dolphin equivalent do the same. > > > > > I'm not a C/C++ or Windows programmer -- when you say "The window > > procedure > > > provided by Windows that supplies the default behaviour basically > > > concentrates on it's nature as a list" it sounds like you're pointing > the > > > finger at Windows, but that also makes it sound like each vendor of > tools > > > has to get around this default behavior and somehow achieve the > > > that is commonly recognized in combo boxes. > > > > The Windows (editable) COMBOBOX is a list that wraps an edit control. The > > functionality being requested is, effectively, an edit control wrapping a > > list. As I say, I think it's probably possible to implement this but I > doubt > > it's trivial. > > > > > As for the seeming inconsistency of a user being able to type something > in > > > the edit portion that is not in the listbox portion, that doesn't seem > to > > be > > > a conceptual problem to me. After all, a listbox can have no selection, > > so > > > why not the listbox portion of a combo box. I'd much rather see > ComboBox > > > work correctly than have two classes of ComboBox. > > > > Normally, a list has an integer selection index or 0 meaning no selection. > > If I have a combo box containing a list "Alf, Bert, Fred" and I type > > "Charlie", what integer selection should the list portray, 0? How would > you > > acces that from a ListPresenter. Surely the point is that most people use > a > > list to control the possible entries to ensure they are valid. With an > > editable combobox you can't do this. No, I think it would be much more > > consistent to treat an editable combo an a text editor with a number of > > preconfiguired entries and the value would be suitable for connection to a > > TextPresenter. > > > > Best regards, > > > > Andy Bower > > Dolphin Support > > > > > > > > |
"Andy Bower" <[hidden email]> wrote in message
news:91lf48$4eds8$[hidden email]... > David, > > This is effectively what I was suggesting in my original reply. > > BTW, could one not use the id of the edit control to locate it rather than > ChildWindowFromPoint? That's what first came to mind when I was considering > it the other day? Honestly I can't remember why I chose ChildWindowFromPoint. ---------------- BEGIN BACKGROUND ---------------- The QKS Smalltalk's user interface architecture allows all <UIComponents> to catch all the window messages. All Smalltalk <UIComponents> are native Win32 windows but the design and architecture has two layers where the top layer is portable. This abstraction was the result of a lot of experience in developing cross-platform facilities for our Mac version's framework. I.e., the component architecture has both a portable (layer) interface and implementation contract, and a native (layer) interface and implementation contract. The portable layer is built on the native layer. The Win32 architecture was basically taken from our Mac version where you have: UIFramer "wrappering" UIComponent "and a" <Positioner> "class family for constraint management" a) Like the Macintosh, when a top level window is created Win32 requires that a "WNDPROC" be provided. Our "single" generic Smalltalk WNDPROC intercepts all child window create messages and re-routes them through the Smalltalk native layer. One of the messages that gets sent to parent windows is notification that a child has been created. We use that as a hook to attach our generic window proc (via "GWL_WNDPROC") to them. This allows all messages to be seen and potentially intercepted by Smalltalk code via the our generic "WNDPROC". Most of the WM_... messages propagate through the native layer on up to the portable layer for possible handling. b) There is a lot of complex knowledge and my experience with portable ui wrapped in the internals of the (sophisticated architecture) design of the <UIComponent> system. Especially in the internals of the design of the <UIFramer> delegation and <UIComponent> message routing. This ui architecture will be further documented and carried forward into the SmallScript system. The architecture abstracts the notion of keyboards and keyboard events, as well as the processes of window frame creation, rendering, calculation, and updating/dirty-facilities. c) The AOS object model underlying SmallScript and QKS Smalltalk allows dynamic attachment of event/message/property handlers to any object and that is how custom behavior can be added on a per-instance basis. There is also pretty rich and extensible (class based) framework for layering the various unique ui messaging responsibilities of individual/native Win32 ui components. However, some controls like the ComboBox have internal/hidden components whose creation is hidden. So we don't see them without playing the game I described in the orignal post for getting the HWND -- which also gets played for root-level components like dialog boxes created via various Win32 calls. -------------- END BACKGROUND -------------- Anyway, I don't know how Dolphin's design works for handling the low level window lifecycle stuff and messaging architecture. But, given the comments regarding both linux and access to some additional features of the metal of Win32, I thought it might be of some sort of value to know a bit more about how I had designed the QKS Smalltalk frameworks to achieve the goals of supporting both portability and native extensibility/interoperability. For those who think this kind of vendor collaboration or information exchange/interaction is weird; you should understand that I love Smalltalk and I want to do all I can to maintain and extend its reputation and capabilities vis-a-vis other languages. On a case-by-case basis, I'm happy to provide my experience and know-how where it might be able to enhance the base of commercial Smalltalk offerings because that strengthens the Smalltalk marketplace. -- Dave Simmons [www.qks.com / www.smallscript.com] "Effectively solving a problem begins with how you express it." > > Best Regards, > > Andy Bower > Dolphin Support > > "David Simmons" <[hidden email]> wrote in message > news:DoZ_5.39018$[hidden email]... > > Andy, > > > > Take a look inside the beta version of QKS Smalltalk for Win32. It may > have > > examples you could leverage to build a Dolphin solution. The technique > > to extract the edit control from the within the combo-box... > > > > Here are some snippets I grabbed from our old Win32 codebase > > > > <?method [ > > editHWnd > > > > ^<<ChildWindowFromPoint(self,1,1):address>>. > > ]?> > > > > <?method [ > > editWindow > > > > "Validate the edit-window sub-component" > > (editWindow isNil or: [editWindow isExternalized not]) ifTrue: > > [ > > "Hack it together" > > (editWindow := TextField new) > > container: self; > > hWndSpecial: self editHWnd. > > ]. > > > > "And return it" > > ^editWindow > > ]?> > > > > -- Dave Simmons [www.qks.com / www.smallscript.com] > > "Effectively solving a problem begins with how you express it." > > > > "Andy Bower" <[hidden email]> wrote in message > > news:91h8gr$433no$[hidden email]... > > > Louis, > > > > > > > While I understood some of what you said, a lot of it was Greek to > > > > although I did get the impression that you were confirming that > indeed, > > > the > > > > current Dolphin implementation of ComboBox does not, and can not, > > respond > > > to > > > > onKeyPressed: Windows messages. My gut reaction is "Well heck, OA > > should > > > be > > > > supplying a combo box that works like it's been working in Windows > > > programs > > > > all these years -- we're not talking about a new widget after all. > This > > > is > > > > basic widget set stuff." > > > > > > As far as I'm aware the existing ComboBox funnctions exactly like the > > > Windows "COMBOBOX" control. That's what it is, an instance of a > > > window wrapped by Dolphin. Show me the C/C++ that allows a Windows > > COMBOBOX > > > respond to WM_XXXX messages for key presses and we'll be able to make > the > > > Dolphin equivalent do the same. > > > > > > > I'm not a C/C++ or Windows programmer -- when you say "The window > > > procedure > > > > provided by Windows that supplies the default behaviour basically > > > > concentrates on it's nature as a list" it sounds like you're > > the > > > > finger at Windows, but that also makes it sound like each vendor of > > tools > > > > has to get around this default behavior and somehow achieve the > behavior > > > > that is commonly recognized in combo boxes. > > > > > > The Windows (editable) COMBOBOX is a list that wraps an edit control. > The > > > functionality being requested is, effectively, an edit control > a > > > list. As I say, I think it's probably possible to implement this but I > > doubt > > > it's trivial. > > > > > > > As for the seeming inconsistency of a user being able to type > something > > in > > > > the edit portion that is not in the listbox portion, that doesn't seem > > to > > > be > > > > a conceptual problem to me. After all, a listbox can have no > selection, > > > so > > > > why not the listbox portion of a combo box. I'd much rather see > > ComboBox > > > > work correctly than have two classes of ComboBox. > > > > > > Normally, a list has an integer selection index or 0 meaning no > selection. > > > If I have a combo box containing a list "Alf, Bert, Fred" and I type > > > "Charlie", what integer selection should the list portray, 0? How > > you > > > acces that from a ListPresenter. Surely the point is that most people > use > > a > > > list to control the possible entries to ensure they are valid. With an > > > editable combobox you can't do this. No, I think it would be much more > > > consistent to treat an editable combo an a text editor with a number of > > > preconfiguired entries and the value would be suitable for connection to > a > > > TextPresenter. > > > > > > Best regards, > > > > > > Andy Bower > > > Dolphin Support > > > > > > > > > > > > > > > |
Dave
You in message news:RKv%5.3836$[hidden email]... >> BTW, could one not use the id of the edit control to locate it rather than >> ChildWindowFromPoint? That's what first came to mind when I was >> considering it the other day? > > Honestly I can't remember why I chose ChildWindowFromPoint. I seem to remember there being a couple of mentions of it on MSDN as a technique for getting hold of the edit control child. Ah yes, I see it also says that the edit box always has ID 1001. >... Like the Macintosh, when a top level window is created Win32 requires > that a "WNDPROC" be provided. Our "single" generic Smalltalk WNDPROC > intercepts all child window create messages and re-routes them through the > Smalltalk native layer... Dolphin does exactly the same. I suspect it is the standard pattern for OO libraries layered on top of native widgets, with some variation in the detail of how control windows' event handling procedures are overridden ("subclassed" in Windows terminology), how the original window procedure is stored and invoked, whether events are handled synchronously (as they should be on Windows) or dequeued and processed asynchronously when one can "get away" with that, etc. >... One of the messages that gets sent to parent windows > is notification that a child has been created. We use that as a hook to > attach our generic window proc (via "GWL_WNDPROC") to them. This allows all > messages to be seen and potentially intercepted by Smalltalk code via the > our generic "WNDPROC".... But surely if you use that technique alone then you will not be receiving all the messages? A number of messages are sent to a new child control before its parent is notified. I never seen precise documentation for this, but a simple empirical test reveals that WM_NCCREATE, WM_NCCALCSIZE, WM_CREATE, WM_SIZE and WM_MOVE are sent to a new child before WM_PARENTNOTIFY is sent to its parent. Relying on the parent notification also requires that one has subclassed the parent, which in certain rare cases one might not want (or be able) to do, for example the parent belongs to another application or process, the parent is the desktop, etc. We use an alternative technique that I first saw in MFC, namely using the system CBT hook which is called before any window is created, giving one an opportunity to subclass new controls before any messages are sent to them. This is a bit grungy, but is necessary because Win32 doesn't provide a parameter/structure member to allow one to subclass a window in the call to CreateWindow(Ex). Since the advent of 32-bit Windows I believe it has been possible to subclass entire Window/control classes on an application specific basis, but I have never experimented with this. >... > However, some controls like the ComboBox have internal/hidden components > whose creation is hidden. So we don't see them without playing the game I > described in the orignal post for getting the HWND -- which also gets played > for root-level components like dialog boxes created via various Win32 calls. True, certainly for the edit control part of a Combobox. The CBT hook technique works for dialogs too though. > ... > Anyway, I don't know how Dolphin's design works for handling the low level > window lifecycle stuff and messaging architecture. But, given the comments > regarding both linux and access to some additional features of the metal of > Win32, I thought it might be of some sort of value to know a bit more about > how I had designed the QKS Smalltalk frameworks to achieve the goals of > supporting both portability and native extensibility/interoperability. > > For those who think this kind of vendor collaboration or information > exchange/interaction is weird; you should understand that I love Smalltalk > and I want to do all I can to maintain and extend its reputation and > capabilities vis-a-vis other languages. On a case-by-case basis, I'm happy > to provide my experience and know-how where it might be able to enhance the > base of commercial Smalltalk offerings because that strengthens the > Smalltalk marketplace. Here, here. Regards Blair McGlashan www.object-arts.com |
I haven't given up yet on this little beast. I managed a kluge which sort
of recognizes a backspace or delete key, so the editable combobox I'm using meets my needs. (I updated the end of PersonalMoney extended tutorial part 6.) However, in the meantime I've gotten fixated on doing it right, which seems like I need to subclass the edit portion of the combobox and that's out of my league right now. Getting the Windows handle of the edit portion of the combo box using David Simmons' approach works, as evidenced by this code in a workspace: listP := ListPresenter show: 'Combo box'. extH := UserLibrary default childWindowFromPoint: listP asParameter point: (1@1) asParameter. UserLibrary default sendMessage: extH msg: (Win32Constants at: 'WM_CHAR') wParam: $m codePoint lParam: 0. (In the above, listP is a ListPresenter whose view is a ComboBox. listP asParameter is the Windows handle of listP's view/ComboBox. extH is an ExternalHandle that contains the Windows handle of the edit portion of the combo box. The sendMessage line sticks the character m directly in the edit portion of the combo box.) After reading Andy's original reply in this thread, I took a closer look at the MSDN documentation with what he said in mind and yes, I see where the default behavior of a combobox is to essentially discard keystroke messages (events) in favor of edit change notification. However, there's an example given in MDSDN, the one that Keith referenced in his post awhile back, of subclassing the edit portion of the combobox control. The example focuses on capturing 3 particular keystrokes (e.g., Enter key) which are not passed on through the default windows proc -- it sounds like this is the only way to capture WM_CHAR messages (in the combo's edit control). That same example (in MSDN) uses the Windows function ChildWindowFromPoint, so that may be where David got the idea. I don't know C/C++ or Windows programming, so although I understand to some degree what that example is talking about, I really don't know how to proceed, and that's why what I say might sound naive, stupid, unreasonable, etc. I tried looking for examples of subclassing Windows controls in the base image, tracing definitions and references of messages that might be relevant (e.g., subClassWindow, setWindowLong*, createAt:*, and *wndproc*) but didn't get anywhere. I assume I want to do something like when the combo box is created, subclass the edit portion, where 'subclass' means to substitute my own procedure for the default windows procdure. How is this done in Dolphin? My latest attempt at what seems futility was to create a new class under ComboBox, called ComboBox2, with the following methods: editHWnd ^UserLibrary default childWindowFromPoint: self asParameter point: (1@1) asParameter onFullyCreated | callback | super onFullyCreated. callback := ExternalCallback block: [ :message :lParam :wParam | self defaultWindowProcessing: message lParam: lParam wParam: wParam] argumentTypes: 'handle sdword sdword'. UserLibrary default setWindowLong: self editHWnd nIndex: GWL_WNDPROC dwNewLong: callback asParameter This does not work. What I'm trying to do is to wait for the Windows ComboBox control to be created, and then in onFullyCreated, do the subclassing. From the MSDN documentation, it sounds like this is a doable time. I couldn't figure out a way to pass an address to subclass the edit control, so I'm trying to use UserLibrary>>setWindowLong: directly, because I can't figure out what else to use. Even then I can't use a method name, but from the Dolphin Reference on External stuff, it seemed like I should be able to use an ExternalCallback, which is what that's doing there (even though in this example it doesn't do anything but send the message on to the default -- it probably should have some sort of trigger notification in the block.) I don't know if callback is the way to go, because I don't get to see it used, since this code doesn't even like callback asParameter as an address, in the call to setWindowLong:. Any pointers would be appreciated. Happy New Year to everyone! -- Louis |
Louis
You wrote in message news:[hidden email]... > I haven't given up yet on this little beast. I managed a kluge which sort > of recognizes a backspace or delete key, so the editable combobox I'm using > meets my needs. (I updated the end of PersonalMoney extended tutorial part > 6.) However, in the meantime I've gotten fixated on doing it right, which > seems like I need to subclass the edit portion of the combobox and that's > out of my league right now. > ... You were on the right lines when you mentioned #subclassWindow. File in the attached, and then evaluate: c := ListPresenter show: 'Combo box' c view editView when: #keyTyped: send: #bell to: Sound This should beep, even when you press Enter. The ComboBox>>editView implementation should probably cache the TextEdit view in an instance variable for efficiency, but the implementation I attach doesn't require any system class changes. I opted to use GetDlgItem() to retrieve the edit field (according to MSDN it always has the id 1001) rather than ChildWindowFromPoint(), as the latter seems a rather unreliable method (pass 1@1 and you'll get back the handle of the combobox itself not the edit field, at least on Win2k with IE5.5) as well as being aesthetically unpleasing. Regards Blair ----------------------------------------------------------- !ComboBox methodsFor! editHwnd "Private - Answer an <ExternalHandle> that is the handle of the Edit control belonging to the receiver." ^self getItemHandle: 1001 ifAbsent: [self error: 'No Edit child found']! editView "Answer the <TextEdit> that represents the Edit control belonging to the receiver." | hWnd editView | hWnd := self editHwnd. editView := View withHandle: hWnd. editView isNil ifTrue: [ editView := TextEdit new. editView parentView: self; attachHandle: hWnd; subclassWindow]. ^editView! ! !ComboBox categoriesFor: #editView!accessing!public! ! !ComboBox categoriesFor: #editHwnd!accessing!private! ! begin 666 comboedit.st M(4-O;6)O0F]X(&UE=&AO9'-&;W(A#0H-"F5D:71(=VYD#0H)(E!R:79A=&4@ M+2!!;G-W97(@86X@/$5X=&5R;F%L2&%N9&QE/B!T:&%T(&ES('1H92!H86YD M;&4@;V8@=&AE($5D:70@8V]N=')O; T*"6)E;&]N9VEN9R!T;R!T:&4@<F5C M96EV97(N(@T*#0H)7G-E;&8@9V5T271E;4AA;F1L93H@,3 P,2!I9D%B<V5N M=#H@6W-E;&8@97)R;W(Z("=.;R!%9&ET(&-H:6QD(&9O=6YD)UTA#0H-"F5D M:716:65W#0H)(D%N<W=E<B!T:&4@/%1E>'1%9&ET/B!T:&%T(')E<')E<V5N M=',@=&AE($5D:70@8V]N=')O;"!B96QO;F=I;F<@=&\@=&AE(')E8V5I=F5R M+B(-"@T*"7P@:%=N9"!E9&ET5FEE=R!\#0H):%=N9" Z/2!S96QF(&5D:71( M=VYD+@T*"65D:716:65W(#H](%9I97<@=VET:$AA;F1L93H@:%=N9"X-"@EE M9&ET5FEE=R!I<TYI;"!I9E1R=64Z(%L-"@D)961I=%9I97<@.CT@5&5X=$5D M:70@;F5W+@T*"0EE9&ET5FEE=PT*"0D)<&%R96YT5FEE=SH@<V5L9CL-"@D) M"6%T=&%C:$AA;F1L93H@:%=N9#L-"@D)"7-U8F-L87-S5VEN9&]W72X-"@E> M961I=%9I97<A("$-"B%#;VUB;T)O>"!C871E9V]R:65S1F]R.B C961I=%9I M97<A86-C97-S:6YG(7!U8FQI8R$@(0T*(4-O;6)O0F]X(&-A=&5G;W)I97-& D;W(Z("-E9&ET2'=N9"%A8V-E<W-I;F<A<')I=F%T92$@(0T* ` end |
In reply to this post by Louis Sumberg
Louis,
Thanks for revisiting this topic and everyone else, thanks for the helpful suggestions. I have been too busy to try out any of the proposed solutions, but it looks like the problem has been solved. Yippee! Keith Alcock Louis Sumberg wrote: > Andy and Blair, > > Try as I may > Try as I might > I just can't get this <expletive deleted> ComboBox > To work out right. > > I'm trying to capture a character entered in the edit portion of the combo > box, whether through onKeyPressed:, onKeyReleased: or onKeyTyped:. I've > looked through DSDN and seen and tried lots of things -- pretranslate, > oninputmask, wmgetdlgcode, I don't even remember them all. I've seen posts > from other people who've tried the above also and it hasn't worked for them. > Either I'm missing something or there's something somewhere (in Windows or > in Dolphin) that really is gobbling up these little things (in shell views, > not just dialog views). > > Keith Alcock previously put it well (14 August 2000 13:08 in DSDN): > "I have reviewed the discussion of the dropdown combobox and the associated > edit box, but to little avail. While it is possible to add CBN_EDITCHANGE > and CBN_EDITUPDATE to CbnMap in the class initialization function, and then > instance methods cbnEditChange and cbnEditUpdate to receive notification of > any changes, it is not possible to react on the enter, tab, or esc keys." > > Thank you for a little more illumination on this. > > -- Louis |
In reply to this post by Blair McGlashan
Blair,
You wrote in message news:92vvna$8a8o8$[hidden email]... regarding using #sublassWindow. First of all, thank you for your quick response -- your #editView is one nifty method. I tried your suggestions but ran into some unexpected behavior. For one thing, once I subclass the control, I can't get focusLost to work. For example, evaluate the following two lines: c := ListPresenter show: 'Combo box'. c when: #focusLost send: #bell to: Sound. If you then click in the combo box and then tab or click outside of the window, a beep sounds. But after you evaluate the following (which, as you know, does the subclassing in the #editview message), it doesn't work: c view editView when: #keyTyped: send: #bell to: Sound. I tried evaluating "c view editView when: #focusLost send: #bell to: Sound" but that didn't restore it. Another problem is that once the edit control is sublassed, the dropdown list doesn't work properly. You can use the up and down arrows to cycle through a selection, but clicking on the dropdown widget portion of the combobox does nothing. There may be another oddity related to what is selected when you tab into the edit portion (after it's subclassed), but I'm not sure of that one. The final thing, for me at least, is that I don't really understand what's going on. I was hoping there was a way to substitute my own Smalltalk method/proc/whatever, intercepting things, but #subclassWindow doesn't seem to provide that. Fortunately, like I said, the kluge I wrote in the tutorial seems to meet my needs (and hopefully others too). Thanks again. -- Louis |
Free forum by Nabble | Edit this page |