News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Little bug in masm32.lib?

Started by ragdog, January 18, 2012, 08:33:28 PM

Previous topic - Next topic

ragdog

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,


hutch--

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 ...
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

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)

donkey

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.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

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

jj2007

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

ragdog

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

hutch--

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
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

ragdog