Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Restoring ctrl+c function

6 views
Skip to first unread message

James Moe

unread,
Sep 22, 2012, 2:19:57 PM9/22/12
to
Hello,
The main message window in PMMail is a container in details view. An
optional preview window is created as a MLE subclassed to the container.
The container has an accelerator key to copy a message: ctrl+c. This
overrides the standard function of the key combination which is to copy
selected text.
I have tried creating an accelerator key for the preview window
thinking it would capture the event. It did not work. The container
still gets the event first.

Other than disabling the Copy Message function, how do I capture
ctrl+c before the container processes it?

I had thought that an event originating in a subclass was passed on to
the parent. AFAICT it seems to work top down instead of bottom up. At
least that is the experience I have with ctrl+c and the subclassed MLE.
When the accelerator key in the container is removed, the text copy
works as expected in the MLE.

--
James Moe
jmm-list at sohnen-moe dot com

James Moe

unread,
Oct 8, 2012, 2:15:41 AM10/8/12
to
On 09/22/2012 11:19 AM, James Moe wrote:
>
> Other than disabling the Copy Message function, how do I capture
> ctrl+c before the container processes it?
>
No one knows how this works?

Steven Levine

unread,
Oct 8, 2012, 3:04:28 AM10/8/12
to
On Mon, 8 Oct 2012 06:15:41 UTC, James Moe
<jimoe...@sohnen-moe.com> wrote:

Hi James,

> > Other than disabling the Copy Message function, how do I capture
> > ctrl+c before the container processes it?
> >
> No one knows how this works?

I doubt that this is the case. :-) Messages get lost in the shuffle.

You need to subclass the container window so that your window
procedure sees the accelerator key message before the standard
container window procedure.

What might be causing you problems is your nomenclature. What you are
calling a subclass is not a subclass. It is a child window.
Subclassing has a very different meaning in PM. The PM docs explain
it well.

Steven

--
---------------------------------------------------------------------
Steven Levine <ste...@earthlink.bogus.net>
eCS/Warp/DIY etc. www.scoug.com www.ecomstation.com
---------------------------------------------------------------------

Paul Ratcliffe

unread,
Oct 8, 2012, 3:39:36 AM10/8/12
to
On Sun, 07 Oct 2012 23:15:41 -0700, James Moe <jimoe...@sohnen-moe.com>
wrote:

>> Other than disabling the Copy Message function, how do I capture
>> ctrl+c before the container processes it?
>>
> No one knows how this works?

Subclass it.

James Moe

unread,
Oct 8, 2012, 5:05:56 PM10/8/12
to
On 10/08/2012 12:04 AM, Steven Levine wrote:
>
> You need to subclass the container window so that your window
> procedure sees the accelerator key message before the standard
> container window procedure.
>
I believe it is subclassed:

mle = WinCreateWindow(Global.Client, WC_MLE, (PSZ) "",
WS_VISIBLE | MLS_VSCROLL | MLS_READONLY | MLS_WORDWRAP | MLS_BORDER,
0, 0, 0, 0,
Global.Client, HWND_TOP, IDW_PREVIEW_MLE, NULL, NULL);

MLEpane_parent_proc = WinSubclassWindow(mle, mainwin_pane_mle_proc);

Dave Saville

unread,
Oct 9, 2012, 8:40:10 AM10/9/12
to
And does mainwin_pane_mle_proc see the ctrl-c? What code is trying to
catch it?

--
Regards
Dave Saville

James Moe

unread,
Oct 9, 2012, 3:33:28 PM10/9/12
to
On 10/09/2012 05:40 AM, Dave Saville wrote:
>>
>> MLEpane_parent_proc = WinSubclassWindow(mle, mainwin_pane_mle_proc);
>
> And does mainwin_pane_mle_proc see the ctrl-c? What code is trying to
> catch it?
>
case WM_COMMAND:
{
int id = SHORT1FROMMP(mp1);
switch (id)
{
case IDM_COPY:
console_output("mainwin_pane_mle_proc: IDM_COPY");
break;
}
...
}

The output indicated above never happens.
IDM_COPY is the accelerator defined in the RC file to copy a message;
it re-defines ctrl+c.

Dave Saville

unread,
Oct 10, 2012, 1:49:01 PM10/10/12
to
Try this

case WM_CHAR:
if (CHARMSG(&msg)->fs & KC_CTRL && ! (CHARMSG(&msg)->fs &
KC_KEYUP) )
{
if (CHARMSG(&msg)->chr == 'c')
{
Clp_Warning(hwnd, "control c");
return 0;
}
}



--
Regards
Dave Saville

James Moe

unread,
Oct 11, 2012, 7:56:45 PM10/11/12
to
On 09/22/2012 11:19 AM, James Moe wrote:
>
> Other than disabling the Copy Message function, how do I capture
> ctrl+c before the container processes it?
> I had thought that an event originating in a subclass was passed on to
> the parent.
>
By tracing the events that are received by the subclassed MLE, I have
seen this behavior. A WM_CHAR event is generated for the Control key
action. Nothing follows it; I would have expected the "C" character
since I am interested in Ctrl+C. Apparently key translation trumps
everything.
But WM_CHAR then generates the WM_TRANSLATEACCEL event. If I then
return FALSE from that event, no key translation occurs. This is a step
in the right direction even though it nixes ALL key translation.
I looked at the values mp1 and mp2. They contained nothing that could
be related to characters or command IDs.
Is there a way to prevent just the one key translation, ctrl+c, from
happening instead of the all or nothing options?

Dave Saville

unread,
Oct 12, 2012, 6:01:39 AM10/12/12
to
Did you try the code I posted in the subclass procedure? That traps
only CTRL-C. You don't need an accelerator entry either.
--
Regards
Dave Saville

Dave Saville

unread,
Oct 12, 2012, 6:04:23 AM10/12/12
to
On Thu, 11 Oct 2012 23:56:45 UTC, James Moe
<jimoe...@sohnen-moe.com> wrote:

This is what I see:

1 Frame WM_CHAR 1D011016 1016 1D01 000A0000 0000 000A
2 Frame WM_CHAR 2E011014 1014 2E01 00000063 0063 0000

line 2 is lower case c with ctrl key down.
--
Regards
Dave Saville

James Moe

unread,
Oct 12, 2012, 7:46:14 PM10/12/12
to
On 10/12/2012 03:01 AM, Dave Saville wrote:
>
> Did you try the code I posted in the subclass procedure? That traps
> only CTRL-C. You don't need an accelerator entry either.
>
If you mean looking at the events that are WM_CHAR? Yes. And only the
CTRL part of CTRL+C ever showed up.
I am assuming that the subsequently generated WM_TRANSLATEACCEL is
passed through to the parent, and any following WM_CHAR events are then
captured and translated before entering the subclass.

Dave Saville

unread,
Oct 13, 2012, 5:18:19 AM10/13/12
to
That's odd. ClipView uses MLE's for the clip text. I subclass them to
get keyboard navigation so I hacked it around to test CTRL-C. Without
the code I posted CTRL-C either does nothing or puts highlighted text
in the MLE into the clipboard. With the code I get a popup saying
CTRL-C was pressed and, assuming some highlighted text, nothing gets
put in the clipboard..

--
Regards
Dave Saville

James Moe

unread,
Oct 13, 2012, 2:49:51 PM10/13/12
to
On 10/13/2012 02:18 AM, Dave Saville wrote:
>>>
>> If you mean looking at the events that are WM_CHAR? Yes. And only the
>> CTRL part of CTRL+C ever showed up.
>
> That's odd. ClipView uses MLE's for the clip text. I subclass them to
> get keyboard navigation so I hacked it around to test CTRL-C.
>
Do you have a ctrl+c key accelerator defined for the parent window?

ACCELTABLE IDW_PMMAIL
BEGIN
/* lots of other definitions... */
"C", IDM_COPY, CONTROL
"c", IDM_COPY, CONTROL
END

Rich Walsh

unread,
Oct 14, 2012, 12:18:26 AM10/14/12
to
On Sat, 22 Sep 2012 18:19:57 UTC, James Moe wrote:

> The main message window in PMMail is a container in details view. An
> optional preview window is created as a MLE subclassed to the container.
> The container has an accelerator key to copy a message: ctrl+c. This
> overrides the standard function of the key combination which is to copy
> selected text.
> I have tried creating an accelerator key for the preview window
> thinking it would capture the event. It did not work. The container
> still gets the event first.

IIUC, you're trying override an accelerator so as to restore normal
copy-to-clipboard functionality when the MLE has the focus. However,
the relationship between the MLE and the container remains unclear.
* is the MLE really a child of the container or is it just program-
matically associated with it?
* does this MLE have a frame?

When PM has a character message for the focus window, it first sends
a WM_TRANSLATEACCEL msg to that window; mp1 points to a QMSG struct
containing the proposed WM_CHAR msg. Typically, WM_TRANSLATEACCEL
gets passed up the chain of parent windows until it reaches a frame.
The frame then calls WinTranslateAccel() with its *own* HWND as an
argument. If the key-combo matches an accelerator entry or a menu
item, the QMSG's hwnd, msg, mp1, and mp2 all get modified. Regardless
of the outcome, the contents of QMSG are then posted to QMSG.hwnd.

Given that, there are a couple of reasons this isn't working for you:
* you can't associate an accelerator table with an MLE - it has to
be associated with a frame. If you're calling WinSetAccelTable()
using the MLE's hwnd, it should be failing.
* if the msg is translated, QMSG.hwnd gets changed to the frame's
hwnd, so the WM_COMMAND is posted to the frame. The frame then
passes the msg to FID_CLIENT. Unless the MLE has its own frame,
the msg gets passed (presumably) to the container.

Final question: why bother with all this crap anyway? If your
subclassed MLE proc sees the WM_TRANSLATEACCEL for ctrl+c, then
translate the msg yourself. Leave hwnd as-is, change msg to
MLM_COPY, zero-out mp1 and mp2, then return TRUE. If the MLE
doesn't see that msg, then your container's subclass proc will
have to take one of two different actions when it receives your
IDM_COPY command depending on whether the MLE has the focus.


--
== == almost usable email address: Rich AT E-vertise DOT Com == ==

Dave Saville

unread,
Oct 14, 2012, 11:14:36 AM10/14/12
to
No.
--
Regards
Dave Saville

James Moe

unread,
Oct 15, 2012, 3:25:36 PM10/15/12
to
On 10/13/2012 09:18 PM, Rich Walsh wrote:
>
> IIUC, you're trying override an accelerator so as to restore normal
> copy-to-clipboard functionality when the MLE has the focus. However,
> the relationship between the MLE and the container remains unclear.
> * is the MLE really a child of the container or is it just program-
> matically associated with it?

It is explicitly subclassed.

> * does this MLE have a frame?
>
No.

> When PM has a character message for the focus window, it first sends
> a WM_TRANSLATEACCEL msg to that window; mp1 points to a QMSG struct
> containing the proposed WM_CHAR msg. Typically, WM_TRANSLATEACCEL
> gets passed up the chain of parent windows until it reaches a frame.
> The frame then calls WinTranslateAccel() with its *own* HWND as an
> argument. If the key-combo matches an accelerator entry or a menu
> item, the QMSG's hwnd, msg, mp1, and mp2 all get modified. Regardless
> of the outcome, the contents of QMSG are then posted to QMSG.hwnd.
>
Thank you for this clear explanation. It has provided the necessary
insight I needed to accomplish what I wished to do.

> Final question: why bother with all this crap anyway? If your
> subclassed MLE proc sees the WM_TRANSLATEACCEL for ctrl+c, then
> translate the msg yourself. Leave hwnd as-is, change msg to
> MLM_COPY, zero-out mp1 and mp2, then return TRUE. If the MLE
> doesn't see that msg, then your container's subclass proc will
> have to take one of two different actions when it receives your
> IDM_COPY command depending on whether the MLE has the focus.
>
Another option is to simply return FALSE on detecting ctrl+c.

Paul Ratcliffe

unread,
Oct 15, 2012, 6:30:48 PM10/15/12
to
On Mon, 15 Oct 2012 12:25:36 -0700, James Moe <jimoe...@sohnen-moe.com>
wrote:

>> When PM has a character message for the focus window, it first sends
>> a WM_TRANSLATEACCEL msg to that window; mp1 points to a QMSG struct
>> containing the proposed WM_CHAR msg. Typically, WM_TRANSLATEACCEL
>> gets passed up the chain of parent windows until it reaches a frame.
>> The frame then calls WinTranslateAccel() with its *own* HWND as an
>> argument. If the key-combo matches an accelerator entry or a menu
>> item, the QMSG's hwnd, msg, mp1, and mp2 all get modified. Regardless
>> of the outcome, the contents of QMSG are then posted to QMSG.hwnd.
>>
> Thank you for this clear explanation. It has provided the necessary
> insight I needed to accomplish what I wished to do.

Yes, it's kind of what you wished IBM had put in the docs. but failed
to do so.
Probably the person writing the docs. (I doubt it would be the
developers) had no idea how it worked either and just glossed over
it.

Windows/MSDN is just as bad. Vague, incomplete, woolly definitions
and no examples. Just what you need when you don't quite know what
you are doing or how something is supposed to work...
0 new messages