From: Oliver Regenfelder on
Hello,

I have a CListCtrl derived control which presents some data.

Now, I want to add handling of CTRL-C:
When the user presses CTRL-C the text of the currently selected
item should be copied to the clippboard.

As far as I figured, accelerators are my best option? Am I
right or is there an 'easy' neat whay like some OnCTRLCPressed
messages?

Best regards,

Oliver
From: David Lowndes on
>I have a CListCtrl derived control which presents some data.
>
>Now, I want to add handling of CTRL-C:
>When the user presses CTRL-C the text of the currently selected
>item should be copied to the clippboard.
>
>As far as I figured, accelerators are my best option?

Maybe - it depends. If you're doing this from the context of your
application rather than as a stand-alone reusable control, then the
accelerator option to invoke a command in your application may be a
good approach. The alternative is to catch the WM_KEYUP keystroke in a
subclassed (derived MFC class) list control.

Dave
From: Oliver Regenfelder on
Hello,

David Lowndes wrote:
>> Now, I want to add handling of CTRL-C:
>> When the user presses CTRL-C the text of the currently selected
>> item should be copied to the clippboard.
>>
>> As far as I figured, accelerators are my best option?

> Maybe - it depends. If you're doing this from the context of your
> application rather than as a stand-alone reusable control, then the
> accelerator option to invoke a command in your application may be a
> good approach.

The control is not a stand-alone reusable contorl but implemented
directly in the applications code base.

> The alternative is to catch the WM_KEYUP keystroke in a
> subclassed (derived MFC class) list control.

What would be the problem with using accelerators in a stand-alone
control?

Is there now abstract way of catching CTRL-C/CTRL-V like things?

Best regards,

Oliver
From: Joseph M. Newcomer on
There is no specific mechanism for doing this. And you need to understand what you will
do with the copied (not cut) information.

I tend to do this by subclassing the control and handling WM_KEYDOWN or WM_CHAR messages.
Ctrl+C is character code 0x03.

If what I want is text (suitable for pasting into Word, NotePad, etc.) then I will
typically loop over the selected entries (I usually do this when there is a multi-select
capability); essentially, I just extract the text in some useful form and just
concatenate each item with a CRLF sequence to form a multi-line string, then put that
string in the clipboard. For a list control, I would put a TAB between each column; not
the most elegant solution, but one which can work acceptably in a variety of contexts.
Your Mileage May Vary. You may just want to put spaces between, or do something else that
makes sense for your app. If I want to paste it into another list control in my app, I
might create a new clipboard format, CF_MYLISTCTRL, and register it; and in this, I will
create something interesting, perhaps just a sequence of lines separated by CRLF and
colums separated by tabs, and the PASTE operation will know how to handle this and do the
paste correctly.

Think about "undo" if you implement "cut" rather than just "copy". I've found a one-level
undo is often sufficient (multi-level undo is complex and if you need it, be prepared to
do a lot of work)
joe

On Fri, 21 May 2010 17:05:51 +0200, Oliver Regenfelder <oliver.regenfelder(a)gmx.at> wrote:

>Hello,
>
>I have a CListCtrl derived control which presents some data.
>
>Now, I want to add handling of CTRL-C:
>When the user presses CTRL-C the text of the currently selected
>item should be copied to the clippboard.
>
>As far as I figured, accelerators are my best option? Am I
>right or is there an 'easy' neat whay like some OnCTRLCPressed
>messages?
>
>Best regards,
>
>Oliver
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Oliver Regenfelder on
Hello,

Joseph M. Newcomer wrote:
> There is no specific mechanism for doing this. And you need to understand what you will
> do with the copied (not cut) information.

Yes I meant copy not cut.

> I tend to do this by subclassing the control and handling WM_KEYDOWN or WM_CHAR messages.
> Ctrl+C is character code 0x03.

Is it portable to use character code 0x03. In my solution I use KEYDOWN
and KEYUP to keep track of the CTRL key and when c/C comes in while ctrl
is pressed I call my OnCopy method.

> If what I want is text (suitable for pasting into Word, NotePad, etc.) then I will
> typically loop over the selected entries (I usually do this when there is a multi-select
> capability); essentially, I just extract the text in some useful form and just
> concatenate each item with a CRLF sequence to form a multi-line string, then put that
> string in the clipboard. For a list control, I would put a TAB between each column; not
> the most elegant solution, but one which can work acceptably in a variety of contexts.
> Your Mileage May Vary. You may just want to put spaces between, or do something else that
> makes sense for your app. If I want to paste it into another list control in my app, I
> might create a new clipboard format, CF_MYLISTCTRL, and register it; and in this, I will
> create something interesting, perhaps just a sequence of lines separated by CRLF and
> colums separated by tabs, and the PASTE operation will know how to handle this and do the
> paste correctly.

After I got the CTRL-C done I found out (with horror) about the
clipboard. But I only need to cut text for now and although it is a
ListCtrl the requirement is to only copy the items name so I do not
have to deal with the columns (yet). But it is good to know about the
problems in advance.

I used the following code to access the clipboard:

::OpenClipboard(NULL);

ItemData *item_data = reinterpret_cast<ItemData*>(GetItemData(index));

HANDLE hMem = ::GlobalAlloc(0
, (item_data->epc.GetLength() + 1)* sizeof(TCHAR));

if(hMem == NULL) {
::CloseClipboard();
return;
}

LPVOID lptstrCopy = ::GlobalLock(hMem);
::memcpy(lptstrCopy, item_data->epc, (item_data->epc.GetLength() + 1) *
sizeof(TCHAR));
::GlobalUnlock(hMem);

::SetClipboardData(CF_TEXT, hMem);

::CloseClipboard();


It bothers me just now, when I am using CF_TEXT has this to be ASCII or
unicode?

> Think about "undo" if you implement "cut" rather than just "copy". I've found a one-level
> undo is often sufficient (multi-level undo is complex and if you need it, be prepared to
> do a lot of work)

Luckily I do not need any cut so there is (not yet) any need for an
undo.

Best regards,

Oliver