Hi
I have needed for my project a function to copy a text to Clipboard
and i have try to use SetClipboardText from Masm32.lib
and have found a little error
I copy a text to the Clipboard from Listview item
and i try to copy a other text from listview item delete this SetClipboardText not the old text from Clipoard.
Why it have not this function EmptyClipboard
SetClipboardText proc ptxt:DWORD
LOCAL hMem :DWORD
LOCAL pMem :DWORD
LOCAL slen :DWORD
invoke StrLen, ptxt ; get length of text
mov slen, eax
add slen, 64
invoke GlobalAlloc,GMEM_MOVEABLE or \
GMEM_DDESHARE,slen ; allocate memory
mov hMem, eax
invoke GlobalLock,hMem ; lock memory
mov pMem, eax
cst pMem, ptxt ; copy text to allocated memory
invoke OpenClipboard,NULL ; open clipboard
invoke EmptyClipboard ;<<<<<<<<<<<<<<<<<<<<<<<<<<
invoke SetClipboardData,CF_TEXT,pMem ; write data to it
invoke CloseClipboard ; close clipboard
invoke GlobalUnlock,hMem ; unlock memory
invoke GlobalFree,hMem ; deallocate memory
ret
SetClipboardText endp
Greets,
Looks familiar (http://www.masm32.com/board/index.php?topic=17279.0) :(
Shrug,
IF 0 ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL hCB :DWORD
fn SetClipboardText,cfm$("Test1\n")
mov hCB, rv(GetClipboardText)
print hCB
free hCB
fn SetClipboardText,cfm$("Test2\n")
mov hCB, rv(GetClipboardText)
print hCB
free hCB
fn SetClipboardText,cfm$("Test3\n")
mov hCB, rv(GetClipboardText)
print hCB
free hCB
fn SetClipboardText,cfm$("Test4\n")
mov hCB, rv(GetClipboardText)
print hCB
free hCB
fn SetClipboardText,cfm$("Test5\n")
mov hCB, rv(GetClipboardText)
print hCB
free hCB
fn SetClipboardText,cfm$("Test6\n")
mov hCB, rv(GetClipboardText)
print hCB
free hCB
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Output,
Test1
Test2
Test3
Test4
Test5
Test6
Press any key to continue ...
Hutch,
It works, but the question is valid: Do we really need EmptyClipboard?
It seems that everybody uses it, googling doesn't help, but as a matter of fact if you don't use it, you can selectively copy text to the clipboard while leaving other app's images etc there. The question is really whether this is legal. Microsoft is vague and mute as usual :8)
Quote from: jj2007 on January 19, 2012, 10:23:48 AM
Hutch,
It works, but the question is valid: Do we really need EmptyClipboard?
It seems that everybody uses it, googling doesn't help, but as a matter of fact if you don't use it, you can selectively copy text to the clipboard while leaving other app's images etc there. The question is really whether this is legal. Microsoft is vague and mute as usual :8)
It needs to be emptied. The EmptyClipboard function gives control of the clipboard to the calling window, OpenClipboard does not. If you do not empty the clipboard after an OpenClipboard it is locked for exclusive access to your process but has no owner window and may not be properly released when you're finished with it causing all clipboard functions by other processes to fail until your program terminates and the clipboard is forcibly released. This is not always the case since Windows has gotten pretty smart since 3.0 but its best not to rely too heavily on the ability of Windows to correct your mistakes.
MSDN gives complete code - and it uses EmptyClipboard
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx
also, OpenClipboard remarks section...
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649048%28v=vs.85%29.aspx
QuoteAn application should call the CloseClipboard function after every successful call to OpenClipboard.
The window identified by the hWndNewOwner parameter does not become the clipboard owner unless the EmptyClipboard function is called.
If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.
although - i was never able to verify the last paragraph :P
Quote from: donkey on January 19, 2012, 10:35:16 AM
... best not to rely too heavily on the ability of Windows to correct your mistakes.
It's not a mistake, it's the attempt to add a missing feature - why should other apps' images and other goodies be destroyed for a little text of mine?? :bg
Quote from: dedndave on January 19, 2012, 12:28:05 PM
Quote
If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.
although - i was never able to verify the last paragraph :P
Indeed, it works, at least under XP - and how else should a console app use the clipboard?
QuotehWndNewOwner [in, optional]: If this parameter is NULL, the open clipboard is associated with the current task.
Another interesting info:
QuoteThe data for private clipboard formats is not freed by the system when the clipboard is emptied.
The documentation is bloody ambiguous, as usual :tdown
Hmm yes Hutch
This console App works under Win7
Test1
Test2
Test3
Test4
Test5
Test6
Press any key to continue ...
But in my Win32 app with copy listview Items works not
This Clipord contain only the first copy entry not the second ....
CopySubItem proc uses edi SubItem:DWORD
LOCAL lvi :LV_ITEM
LOCAL lpszText [256]:dword
invoke SendMessage,hList,LVM_GETNEXTITEM, -1, LVNI_ALL or LVNI_SELECTED
mov lvi.iItem, eax
mov lvi.imask, LVIF_TEXT
lea edi, lpszText
invoke RtlZeroMemory, edi, 256
mov lvi.pszText, edi
mov lvi.cchTextMax,256
mov eax,[SubItem]
mov lvi.iSubItem,eax
invoke SendMessage,hList,LVM_GETITEM, 0, addr lvi
invoke SetClipboardText,addr lpszText
ret
CopySubItem endp
And this works for me
;------------------------------------------------------------;
; This procedure is used to copy text to the Clipboard so ;
; that it is available for pasting in the Console window. ;
;------------------------------------------------------------;
SetTextOut PROC USES ebx esi String:DWORD
;---------------------------------------
xor ebx, ebx ; 0 byte length (returned value)
invoke OpenClipboard, NULL
cmp eax, 0
je Exit
invoke EmptyClipboard
cmp eax, 0
je Close_Clipboard
invoke lstrlen, String
cmp eax, 0
je Close_Clipboard
add eax, 1 ; Including termination character [0]
xor esi, esi
invoke GlobalAlloc, GMEM_MOVEABLE, eax
cmp eax, NULL
je Close_Clipboard
mov esi, eax ; esi = Memory object handle
invoke GlobalLock, esi
cmp eax, NULL
je Close_Clipboard
invoke lstrcpy, eax, String ; eax = Memory pointer
mov ebx, eax
invoke GlobalUnlock, esi
invoke SetClipboardData, CF_TEXT, esi
cmp eax, NULL
jne Close_Clipboard
xor ebx, ebx
Close_Clipboard:
invoke CloseClipboard
.if esi != NULL
invoke GlobalFree, esi
.endif
Exit:
mov eax, ebx
ret
;---------------------------------------
SetTextOut ENDP
Hate to tell you this but the simple test piece runs as multiple instance with the correct output and a separate copy also produces the correct output. The 2 procedures do what they are supposed to do.
If you have a different requirement, as usual write your own. :bg
Is ok Hutch :wink