Hi,

I have a listview. Now I have two questions:

1. Is there no way to activate the right mouse button menu?

2. If I have a button, "copy", is there a way to copy a line of this listview box? Normally I would use SendMessage with WM_COPY, but there you need a handle. And I think it doesnt make sense to put in the handle of the Listview. I just need to copy the line and not the whole thing.


Am I wrong?


Hope for some enlightning

DKT
Posted on 2003-12-17 12:23:37 by Kreatief
To have a right click menu in a listview process the WM_CONTEXTMENU message and use your own. To copy the text you will have to use LVM_GETITEM to retrieve the text and copy it to the clipboard.
Posted on 2003-12-17 13:22:37 by donkey
or
i
handle the WM_NOTIFY message, wparam should be
the listview window id, lparam should point to the NMHDR struct, check the code part (+8h) for the type..
should be one of the following

NM_CLICK The user has clicked the left mouse button within the control.
NM_DBLCLK The user has double-clicked the left mouse button within the control.
NM_KILLFOCUS The control has lost the input focus.
NM_OUTOFMEMORY The control could not complete an operation because there was not enough memory available.
NM_RCLICK The user has clicked the right mouse button within the control.
NM_RDBLCLK The user has double-clicked the right mouse button within the control.
NM_RETURN The control has the input focus, and the user has pressed the ENTER key.
NM_SETFOCUS The control has received the input focus.

one thing i could never fix well was the flickering caused in scrolling the listview
you can reduce it a bit by subclassing and 'faking' the wm_erasebkgnd message which does work, but can sometimes leave undesirable smears if you scroll from one
side to the other and back quickly
Posted on 2003-12-17 14:00:43 by evlncrn8
Here, this should do it:

Create a global variable for the clipboard buffer handle

.data?

hClipData dd ?


You must process the WM_CONTEXTMENU and WM_DESTROYCLIPBOARD messages in your WindowProc:

.ELSEIF eax == WM_CONTEXTMENU

invoke ShowLVMenu,hWin ;Handle to the parent window

.ELSEIF eax == WM_DESTROYCLIPBOARD
invoke GlobalFree,hClipData


The following function assumes that you have defined hListView, and it holds the handle of the listview control. I have done the copy and paste functions I have also added support for copy and pasting sub items (common controls 4.70+)

Posted on 2003-12-17 14:05:41 by donkey
Thats very nice.

Thank you.

Btw, is there no way to use SendMessage with WM_COPY after LVM_GETITEM with SendMessage? I think the problem lies in the handle. It must be a handle to a editbox or a combobox, right? That cant be a Listview box. Am I right?

I will check that Clipboard functions.

Thank you both


DKT
Posted on 2003-12-17 14:17:49 by Kreatief
Could be that WM_COPY might be made to work but I doubt it, I have never looked at the message as I prefer to control the clipboard myself. Never trusted Windows to put in what I wanted and generally I use it only for graphics anyway.
Posted on 2003-12-17 14:22:45 by donkey
Hi Kreatief,

I tested the code a bit more tonight and there was a possibility of a GPF. I have modified the code I posted to get around this problem. You have to process an extra message and the memory is allocated differently. It is now very reliable from what I have tested.
Posted on 2003-12-18 00:21:48 by donkey
Hmm... thats alot of code for it. Its interesting that you need that much code for it. Then it might be usefull to write a dll function in general for it, for later use in several programs (just as you did)


Thank you for your help. I will try to get it to work, and to understand every single point.


DKT
Posted on 2003-12-18 09:11:02 by Kreatief
Hi Kreatief,

Yeah, it is alot of code but most of it is the structures and menus, even the msdn sample for copy and pasting from the clipboard is about 30 lines of C. There are shorter ways but if you want it robust you must allow for all eventualities like some app locking the clipboard or yours not being able to obtain ownership etc...

This code is not well suited to a DLL, it should be in your main program.
Posted on 2003-12-18 09:17:46 by donkey
Hey Donkey,

it is long time gone, but now I have time to deal with this problem again...

As I saw, the WM_COPY through SendMessage doesnt work.
Now I am trying to understand your code.

Why do we need to allocate some memory? What is the buffer to put to the clipboard? Is it a structure, no simple text buffer?

I am wondering, because I tried to simply use a text buffer, so just the buffer I wanna have in Clipboard. If this doesnt work (as it is in my case), what is the difference to allocating memory, putting the buffer (or structure?!) to it, and using this address as buffer?


And a last question: If we really need to allocate memory, is it equal to the VirtualAlloc function?


I really hope to get some answers, this all seem weired to me...


DKT
Posted on 2004-01-04 06:56:31 by Kreatief
AFAIK VirtualAlloc will not work with the clipboard, it is an old thing from the 16 bit days, in order to allow backward compatibility with older apps they left it as GlobalAlloc. The buffer is allocated in order that the data on the clipboard is also available to other applications. Yes, the clipboard is weird :), that is the main reason I posted the whole code for it including message handling instead of just using a sort of pseudo-code. The global buffer cannot be locked as Windows will relocate the buffer into system memory space accessible by all applicaitons (hence the GlobalUnlock) text buffers in your program are always locked so they will not work. The clipboard is a dinosaur that we have to deal with in Win32 programming:

GlobalAlloc from MSDN
Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE, the clipboard functions, and OLE data objects
Posted on 2004-01-04 12:57:38 by donkey
The buffer is allocated in order that the data on the clipboard is also available to other applications.



Does that mean, I am not allowed to free the allocated memory with GlobalFree? I searched the board and found some examples, and as far as I could see, they werent freed up after using...


But thanks for the information. Its really good to know such things... That is another reason to dislike Microsofts work of programming...


Thank you Donkey, now this topic should be done...


DKT
Posted on 2004-01-04 13:04:14 by Kreatief
You must free the memory once the clipboard is done with it, you will be sent a WM_DESTROYCLIPBOARD message when it is time to free the memory (see my code above). When your program exits it will decrement the reference count on that buffer and the clipboard will free it for you if your program does not expressly free it before exit.
Posted on 2004-01-04 13:07:19 by donkey
well,
u don't have to Free the handler if its LOCAL handler cuz it will an exception if u do
at least it has here.
Posted on 2004-01-16 18:42:08 by wizzra
Hi Wizzra,

Could you explain what happened, I tested this thoroughly (Win98SE & 2K) and I am using it in some of my applications. If there is a problem I would really like to know. In MSDN it was not clear if you had to free the memory or not, the example they gave frees the memory on a WM_DESTROYCLIPBOARD message. My tests showed that the memory you allocate to the clipboard is not freed even when ownership is tranferred to another application. I have never gotten an exception but I have never stress tested it either. Could you try the attached program and see if it throws an exception, it is the listview copy routine but that uses my standard clipboard functions:

I have moved this file to my website
Posted on 2004-01-16 19:23:27 by donkey
Hi Donkey,

your copy routine doesn't crash.
i wasn't telling it crashes on ur code specificly.
the prob i am getting is while coping several selected lines in the listview (VC++ App),
i always get execptions playing with that damn clipboard and global allocated vars ... ;)
Posted on 2004-01-16 20:39:50 by wizzra
Hi Wizzra,

Ah, I see. My routine was never designed to handle multiple lines as you know so it doesn't apply. Whew ! I thought I had a lot of code to modify tonight in about 20 applicaitons :) BTW I have gotten around to fixing up the header sort images to work with my sort routine, I have uploaded it to the post in this thread, you might like it as it now works exactly as it is expected to. That is the arrow is only visible on one header item at a time and it calls the sort routine to sort in the proper direction. I will also upload it to the proper thread on the other board.
Posted on 2004-01-16 20:44:42 by donkey
btw,
how much can bytes can i copy to the clipboard?
it seems that if i copy from my listview allot of lines, it will get truncked when i paste it.

test 1, copying 20 lines...


; ===========[ Program Entry Point ]===========
00401000 6A00 PUSH 00
00401002 68 00304000 PUSH 00403000 ;ASCIIZ: "Iczelion's tutorial no.2"
00401007 68 19304000 PUSH 00403019 ;ASCIIZ: "Win32 Assembly is Great!"
00401013 6A00 PUSH 00
00401015 E8 06000000 CALL kernel32!ExitProcess
0040101A FF2508204000 JMP [user32!MessageBoxA]
00401020 FF2500204000 JMP [kernel32!ExitProcess]
00401026 0000 ADD BYTE PTR DS:[EAX],AL
00401028 0000 ADD BYTE PTR DS:[EAX],AL
0040102E 0000 ADD BYTE PTR DS:[EAX],AL
00401034 0000 ADD BYTE PTR DS:[EAX],AL
00401038 0000 ADD BYTE PTR DS:[EAX],AL
0040103A 0000 ADD BYTE PTR DS:[EAX],AL
0040103E 0000 ADD BYTE PTR DS:[EAX],AL
00401040 0000 ADD BYTE PTR DS:[EAX],AL
00401044 0000 ADD BYTE PTR DS:[EAX],AL
00401046 0000 ADD BYTE PTR DS:[EAX],AL
00401048 0000 ADD BYTE PTR DS:[EAX],AL
0040104A 0000 ADD BYTE PTR DS:[EAX],AL


test 2, copying 21 lines:


; ===========[ Program Entry Point ]===========
00401000 6A00 PUSH 00
00401002 68 00304000 PUSH 00403000 ;ASCIIZ: "Iczelion's tutorial no.2"
00401007 68 19304000 PUSH 00403019 ;ASCIIZ: "Win32 Assembly is Great!"
00401013 6A00 PUSH 00
00401015 E8 06000000 CALL kernel32!ExitProcess
0040101A FF2508204000 JMP [user32!MessageBoxA]
00401020 FF2500204000 JMP [kernel32!ExitProcess]
00401026 0000 ADD BYTE PTR DS:[EAX],AL
00401028 0000 ADD BYTE PTR DS:[EAX],AL
0040102E 0000 ADD BYTE PTR DS:[EAX],AL
00401034 0000 ADD BYTE PTR DS:[EAX],AL
00401038 0000 ADD BYTE PTR DS:[EAX],AL
0040103A 0000 ADD BYTE PTR DS:[EAX],AL
0040103E 0000 ADD BYTE PTR DS:[EAX],AL
00401040 0000 ADD BYTE PTR DS:[EAX],AL
00401044 0000 ADD BYTE PTR DS:[EAX],AL
00401046 0000 ADD BYTE PTR DS:[EAX],AL
00401048 0000 ADD BYTE PTR DS:[EAX],AL
0040104A 0000 ADD BYTE PTR DS:[0040104C 0000 ADD BYTE PTR DS:[EAX],AL


1024 is the max bytes? :( :(
iv checked with an ClipSpy..very weird it wont copy more than 1024bytes..
any walk around?
:confused:
Posted on 2004-01-17 07:57:29 by wizzra
Well, obviously there is something wrong there as notepad et al use the clipboard to move much much more than 1024 bytes.
Posted on 2004-01-17 11:32:56 by donkey
yup..
Hidden NULLs inside the text buffers kept it from growing and became fixed size.
problem solved..nothing wrong with clipboard..my bad :)
the operation of storing entire ListItem is very slow..
consider 300,000 items :)
onto Thread...
Posted on 2004-01-17 16:21:30 by wizzra