#onKeyPressed:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

#onKeyPressed:

Louis Sumberg
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Andy Bower
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
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
>
>


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Bill Schwab
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]


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Andy Bower
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Bill Schwab
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]


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Louis Sumberg
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Andy Bower
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

David Simmons
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
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
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Chris Uppal-2
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Andy Bower
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
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
> >
> >
> >
>
>


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

David Simmons
"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
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
> > 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
> > >
> > >
> > >
> >
> >
>
>


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Blair McGlashan
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Louis Sumberg
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Blair McGlashan
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Keith Alcock
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


Reply | Threaded
Open this post in threaded view
|

Re: #onKeyPressed:

Louis Sumberg
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