The problem arises in making CEnterComboBox respond to the Enter Key. When
I type in the edit box portion of my control, the Edit box captures the
Enter Key. At that point, it puportedly sends a message to its parent, the
Combo Box. However, the Combo Box does not catch that message. I think I
have the appropriate entries in the message map of each of these components.
So my initial question is simply am I on the right track? If I'm doing it
right, then I must have a careless bug somewhere in my code, which I'll be
glad to share. If there is something I am missing in my logic, I assume Joe
or another kind-hearted soul will rush to my rescue.
Norm
--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com
"Norman Landis" <nla...@optonline.net> wrote in message
news:pmqQa.6537$QD2.1...@news4.srv.hcvlny.cv.net...
Norm
"Ajay Kalra" <ajay...@yahoo.com> wrote in message
news:e$7loQcSD...@TK2MSFTNGP11.phx.gbl...
--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com
"Norman Landis" <nla...@optonline.net> wrote in message
news:r6FQa.22640$QD2.3...@news4.srv.hcvlny.cv.net...
Why would I want such a design? Because the Enter Key should be associated
with the Combo Box. Why design a control, such as ComboEditBox if it is
incapable of sending a message to its parent that the edit is complete? The
alternative is to have the dialog capture the message from the EnterEdit
Control that it doesn't even know exists because it is internal to the
ComboEnterBox.
Norm
"Ajay Kalra" <ajay...@yahoo.com> wrote in message
news:ujmclElS...@TK2MSFTNGP11.phx.gbl...
What did you do to achieve it? How did you package the message? Can you show
the code which does this?
--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com
"Norman Landis" <nla...@optonline.net> wrote in message
news:x8LQa.23736$QD2.4...@news4.srv.hcvlny.cv.net...
Now, the problem. Since the CEnterComboBox is a class independent of the
application that uses it, and since I might have several such controls in an
application, and since the subclassed EditEnter box is dynamically created
at execution, what should I put in my message map?
My message map entry for the CEnterComboBox control currently looks like:
ON_CONTROL(EDIT_COMPLETE, 4080, OnEnterKey)
This is obviously not acceptable for an application-independent control. If
the CEnterComboBox class has a field
UINT edit_control_id;
where edit_contol_id is set to the Combo Box's id + 3000, what is allowable
for the id field in the message map?
Norm
"Norman Landis" <nla...@optonline.net> wrote in message
news:pmqQa.6537$QD2.1...@news4.srv.hcvlny.cv.net...
--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com
"Norman Landis" <nla...@optonline.net> wrote in message
news:ykMQa.24105$QD2.4...@news4.srv.hcvlny.cv.net...
Norm
"Ajay Kalra" <ajay...@yahoo.com> wrote in message
news:OsxmyHqS...@tk2msftngp13.phx.gbl...
>Well, Ajay, I kind of figured out my problem. When subclassing the
>CEnterEdit portion of my CEnterComboBox, I performed a GetDlgCtrlID to
>obtain a control id for the subclassed edit box. But this control id (in
>this case, 1001) conflicts with another resource id in my application.
That shouldn't matter. That editbox is a child of the combobox, and the
combobox is free to assign it whatever ID suits it.
>So I performed a SetDlgCtrlId to set it to a "unique" value.
That's a bad idea. The Windows combobox code which created the editbox just
might expect the ID not to change.
>Sure enough, by
>hard-coding inside the message map what I know the id to be in this
>application, indeed, the CEnterComboBox does in fact receive the message
>from the subclassed CEnterEdit box, which it in turn passes on to the dialog
>and is received by my application handler.
I don't get it. You've subclassed the editbox with CEnterEdit, and it
intercepts WM_KEYDOWN or whatever. It can translate that into some
user-defined message which it passes up to its parent, in this case, your
CEnterComboBox. In turn, CEnterComboBox can forward the message on to its
parent, and if the message includes a control ID, it should specify its own
control ID, i.e. the combobox control ID, since that's what the parent knows
about.
>Now, the problem. Since the CEnterComboBox is a class independent of the
>application that uses it, and since I might have several such controls in an
>application, and since the subclassed EditEnter box is dynamically created
>at execution, what should I put in my message map?
>
>My message map entry for the CEnterComboBox control currently looks like:
>
> ON_CONTROL(EDIT_COMPLETE, 4080, OnEnterKey)
Which message map contains this entry? Combobox or dialog?
What's the value of EDIT_COMPLETE? The ON_CONTROL macro translates into
WM_COMMAND, and if the embedded editbox with ID 1001 is giving you trouble
here, this suggests that EDIT_COMPLETE equals some other command
notification ID, and that the combobox/dialog is receiving WM_COMMAND
messages for another control with ID 1001. Otherwise, I don't see why you
said, "But this control id (in this case, 1001) conflicts with another
resource id in my application." Half of the solution is to this problem is
described above. The other half is to define EDIT_COMPLETE so it doesn't
conflict with other notification codes used by the control in question, and
I'm not sure how you do that. AFAIK, those ranges aren't defined. Myself, I
would forget about WM_COMMAND and define a WM_APP-based custom message or
maybe use RegisterWindowMessage.
>This is obviously not acceptable for an application-independent control. If
>the CEnterComboBox class has a field
>
> UINT edit_control_id;
>
>where edit_contol_id is set to the Combo Box's id + 3000, what is allowable
>for the id field in the message map?
That's the wrong approach. Your combobox should use its own ID in messages
it sends to its parent, replacing the editbox ID in messages it forwards.
--
Doug Harrison
Microsoft MVP - Visual C++
I understand why you say this and I do find it a bit odd. But for some
reason when the edit box had ID 1001 the Combo Box's (parent's) message
handler was not invoked, but when the ID became 4080, it was!!!!
> >Sure enough, by
> >hard-coding inside the message map what I know the id to be in this
> >application, indeed, the CEnterComboBox does in fact receive the message
> >from the subclassed CEnterEdit box, which it in turn passes on to the
dialog
> >and is received by my application handler.
>
> I don't get it. You've subclassed the editbox with CEnterEdit, and it
> intercepts WM_KEYDOWN or whatever. It can translate that into some
> user-defined message which it passes up to its parent, in this case, your
> CEnterComboBox. In turn, CEnterComboBox can forward the message on to its
> parent, and if the message includes a control ID, it should specify its
own
> control ID, i.e. the combobox control ID, since that's what the parent
knows
> about.
>
That's exactly what I do. The Combo Box's OnEnterKey() handler sends its
own message
with the ComboBox's ID to its parent dialog. It's a two-step process:
component EnterEdit
box sends an EDIT_COMPLETE message to the Combo box and then the Combo box
sends
its own message to its parent.
> >Now, the problem. Since the CEnterComboBox is a class independent of the
> >application that uses it, and since I might have several such controls in
an
> >application, and since the subclassed EditEnter box is dynamically
created
> >at execution, what should I put in my message map?
> >
> >My message map entry for the CEnterComboBox control currently looks like:
> >
> > ON_CONTROL(EDIT_COMPLETE, 4080, OnEnterKey)
>
> Which message map contains this entry? Combobox or dialog?
>
This is the CEnterComboBox's message map. The 4080 represents the control
id of
the dynamically subclassed CEnterEdit box.
The dialog in turn contains its own message map entry:
ON_CONTROL(EDIT_COMPLETE, IDC_USERS_LIST, on_user_name_entered)
where IDC_USERS_LIST is the control id of the CEnterComboBox.
> What's the value of EDIT_COMPLETE? The ON_CONTROL macro translates into
> WM_COMMAND, and if the embedded editbox with ID 1001 is giving you trouble
> here, this suggests that EDIT_COMPLETE equals some other command
> notification ID, and that the combobox/dialog is receiving WM_COMMAND
> messages for another control with ID 1001. Otherwise, I don't see why you
> said, "But this control id (in this case, 1001) conflicts with another
> resource id in my application." Half of the solution is to this problem is
> described above. The other half is to define EDIT_COMPLETE so it doesn't
> conflict with other notification codes used by the control in question,
and
> I'm not sure how you do that. AFAIK, those ranges aren't defined. Myself,
I
> would forget about WM_COMMAND and define a WM_APP-based custom message or
> maybe use RegisterWindowMessage.
>
static UINT EDIT_COMPLETE = ::RegisterWindowMessage(UWM_EDIT_COMPLETE_MSG);
So the EDIT_COMPLETE message is unique. It just seems that someone gets
confused
when it is combined with the control id of 1001, which IS used elsewhere in
the application.
The EDIT_COMPLETE notification message is the standard one I use in
CEnterEdit whenever it
detects the Enter key is hit. Very standard stuff, I believe. Of course,
WM_COMMAND combines
this message with the control id in the upper word/lower word format, so
that can't be a cause
of conflict.
> >This is obviously not acceptable for an application-independent control.
If
> >the CEnterComboBox class has a field
> >
> > UINT edit_control_id;
> >
> >where edit_contol_id is set to the Combo Box's id + 3000, what is
allowable
> >for the id field in the message map?
>
> That's the wrong approach. Your combobox should use its own ID in messages
> it sends to its parent, replacing the editbox ID in messages it forwards.
But that is exactly what I'm doing (see above.) But the Combo Box has to
get a message from
its subclassed CEnterEdit box so that it can "do its thing," and send the
appropriate message up
another level. I'm not using edit_control_id in the message the Combo Box
is setting. I'm using
it in the CEnterEdit control to send a message to the Combo Box. But then
the Combo Box has
to receive that message. So it needs an entry in its message map. That's
the one in question.
Apparently I can't stick edit_control_id as the id field of ON_CONTROL.
What DO I do?
Norm
I'm not sure I see the value in stuffing the EDIT_COMPLETE notification into
WM_COMMAND. While RegisterWindowMessage generates unique message IDs,
WM_COMMAND notification codes are not message IDs. Like I said, I don't know
how to define codes to go along with things like EN_CHANGE, because AFAIK,
the ranges aren't defined. So I would just pass EDIT_COMPLETE to the parent
window directly, instead of wrapping it up in WM_COMMAND. Should be easier,
too.
>> >This is obviously not acceptable for an application-independent control.
>If
>> >the CEnterComboBox class has a field
>> >
>> > UINT edit_control_id;
>> >
>> >where edit_contol_id is set to the Combo Box's id + 3000, what is
>allowable
>> >for the id field in the message map?
>>
>> That's the wrong approach. Your combobox should use its own ID in messages
>> it sends to its parent, replacing the editbox ID in messages it forwards.
>
>But that is exactly what I'm doing (see above.) But the Combo Box has to
>get a message from
>its subclassed CEnterEdit box so that it can "do its thing," and send the
>appropriate message up
>another level. I'm not using edit_control_id in the message the Combo Box
>is setting. I'm using
>it in the CEnterEdit control to send a message to the Combo Box. But then
>the Combo Box has
>to receive that message. So it needs an entry in its message map. That's
>the one in question.
>Apparently I can't stick edit_control_id as the id field of ON_CONTROL.
>What DO I do?
Beyond dumping WM_COMMAND as described above, I'm not sure. You definitely
do not need to change the combobox's embedded editbox control ID. I would
imagine your editbox class would do something like the following to send the
message to its parent:
GetParent()->SendMessage(EDIT_COMPLETE, GetDlgCtrlID(), extra_info);
The parent (combobox) would have a message map entry:
ON_REGISTERED_MESSAGE(EDIT_COMPLETE, OnEditComplete)
and handler:
LRESULT MyComboBox::OnEditComplete(WPARAM wp, LPARAM lp)
{
// wp holds the control ID; nothing really to do with it
return GetParent()->SendMessage(
EDIT_COMPLETE,
GetDlgCtrlID(),
extra_info);
}
And finally the dialog class would have a message map entry and handler very
much like the combobox's, except it wouldn't forward the message, of course,
and it would inspect wp to determine which control sent the message. You
could also pass the HWND instead of or in addition to the control ID if
that's more convenient.