Re: Handling Cut (CTRL-C) in a CListCtrl dervied control
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