News:

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

Copying a string variable to the Win clipboard

Started by frktons, November 14, 2010, 12:12:33 PM

Previous topic - Next topic

frktons

If I'm using a Console mode application and I want to copy the content of a string
variable to the Win clipboard, can I use the OpenClipboard - EmptyClipboard
SetClipboardData - CloseClipboard  functions to do that?

Have I to compile the program with Console Assemble and Link or in Windows Subsystem mode?

Have you got a simple example of a string copied to the clipboard with these functions
or in other ways?

Thanks

Frank
Mind is like a parachute. You know what to do in order to use it :-)

frktons

#1
Well, I found this chunk of code by Magnum on the forum:


; -------------------------------------------------------------
;
;  clip.asm Use to "pre-fill the clipboard for later use
;
; -------------------------------------------------------------
    include \masm32\include\masm32rt.inc

    .data
   
  hglb dd 0
  str1 db "Have a great day,",13,10, "Andy",13,10,13,10,\
          "http://intouch.org/magazine/daily-devotional",0


    .code

start:

    ;------------------------------
    ; Place str1 on the clipboard.
    ;------------------------------

    invoke OpenClipboard,NULL
    .IF (eax)
      invoke EmptyClipboard
      invoke GlobalAlloc,GMEM_MOVEABLE,SIZEOF str1
      .IF (eax)
        mov hglb, eax
        invoke GlobalLock,hglb
          ;---------------------
          ; Pointer now in eax.
          ;---------------------
        invoke MemCopy,ADDR str1,eax,SIZEOF str1
        invoke GlobalUnlock,hglb
        invoke SetClipboardData,CF_TEXT,hglb
          ;--------------------------------------------
          ; System now owns object identified by hglb.
          ;--------------------------------------------
        .IF (eax == 0)
          print "SetClipboardData failed",13,10
        .ENDIF
      .ELSE
        print "GlobalAlloc failed",13,10
      .ENDIF
      invoke CloseClipboard
    .ELSE
      print "OpenClipboard failed",13,10
    .ENDIF

    exit
   
end start



It could be enough for my needs  :P

Frank
Mind is like a parachute. You know what to do in order to use it :-)

Magnum

I am going to convert this, to check out the size decrease.

Andy posted:

> Isn't it a bit quiet in CLAX recently ?

| Since it's been quiet.

my 32-bit environment may allow a shorter variant:

.data
msg: "I have plenty of great time because my code is short"
msgcnt: sizeof msg
origin: dd 0
.code
do_it:
mov ecx,msgcnt
cld
mov edi,clip_ptr    ;points to clipboard header
cmp [edi],ecx       ;first dw is max. clip_size
mov origin,edi      ;save clip_ptr
jc done             ;set carry if too large
lea eax,[edi+ecx+8] ;add head,size and tail
mov esi,msg
add edi,4           ;no carry to expect here
rep movsb
mov [edi],00000a0dh ;CR-LF and zero mark at end
mov clip_ptr,eax    ;make this string non-temporary
done:                ;ignore and do nothing if too large
ret


Andy posted:

> Isn't it a bit quiet in CLAX recently ?

| Since it's been quiet.

my 32-bit environment may allow a shorter variant:

.data
msg: "I have plenty of great time because my code is short"
msgcnt: sizeof msg
origin: dd 0
.code
do_it:
mov ecx,msgcnt
cld
mov edi,clip_ptr    ;points to clipboard header
cmp [edi],ecx       ;first dw is max. clip_size
mov origin,edi      ;save clip_ptr
jc done             ;set carry if too large
lea eax,[edi+ecx+8] ;add head,size and tail
mov esi,msg
add edi,4           ;no carry to expect here
rep movsb
mov [edi],00000a0dh ;CR-LF and zero mark at end
mov clip_ptr,eax    ;make this string non-temporary
done:                ;ignore and do nothing if too large
ret
Have a great day,
                         Andy

frktons

Quote from: Magnum on November 14, 2010, 11:25:33 PM
I am going to convert this, to check out the size decrease.

Andy posted:

> Isn't it a bit quiet in CLAX recently ?

| Since it's been quiet.

my 32-bit environment may allow a shorter variant:


.data
msg: "I have plenty of great time because my code is short"
msgcnt: sizeof msg
origin: dd 0
.code
do_it:
mov ecx,msgcnt
cld
mov edi,clip_ptr    ;points to clipboard header
cmp [edi],ecx       ;first dw is max. clip_size
mov origin,edi      ;save clip_ptr
jc done             ;set carry if too large
lea eax,[edi+ecx+8] ;add head,size and tail
mov esi,msg
add edi,4           ;no carry to expect here
rep movsb
mov [edi],00000a0dh ;CR-LF and zero mark at end
mov clip_ptr,eax    ;make this string non-temporary
done:                ;ignore and do nothing if too large
ret


Hi Andy.

It is doable, and probably faster than previous version. Did you try it?

Frank
Mind is like a parachute. You know what to do in order to use it :-)

Magnum

This is what I have so far.

Andy


include \masm32\include\windows.inc   
include \masm32\include\masm32.inc     

msgcnt equ sizeof msg

.data

msg    db "I have plenty of great time because my code is short.",0
origin dd 0

.code

start:

do_it:
mov ecx,msgcnt
cld
mov edi,clip_ptr    ;points to clipboard header
cmp [edi],ecx       ;first dw is max. clip_size
mov origin,edi      ;save clip_ptr
jc done             ;set carry if too large
lea eax,[edi+ecx+8] ;add head,size and tail
mov esi,msg
add edi,4           ;no carry to expect here
rep movsb
mov [edi],00000a0dh ;CR-LF and zero mark at end
mov clip_ptr,eax    ;make this string non-temporary
done:                ;ignore and do nothing if too large
ret

end start
Have a great day,
                         Andy

frktons

Well, I guess it is not ready yet.

I'm working on a viable solution as well.
When something is ready, if I have something that works, I'll post an example.

At the moment I don't know. This is the first time I use the clipboard.  :P

Frank
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

i dunno how well the clipboard will work if you have written directly to the video buffer   :P
when i copy/paste with your test bed, only the upper part is copied
i think that's the part where data has been written using StdOut - not sure
maybe it is related to the current cursor position

frktons

Quote from: dedndave on November 15, 2010, 02:33:26 AM
i dunno how well the clipboard will work if you have written directly to the video buffer   :P
when i copy/paste with your test bed, only the upper part is copied
i think that's the part where data has been written using StdOut - not sure
maybe it is related to the current cursor position

The only thing I need to know is how to copy a string inside the win clipboard, all the
remaining stuff I already know in a way or another.  :bg

I'm not at all sure about the problems you have always pointed at. In my experience
the console and the clipboard work flawlessly together.

On my system I can copy any part of the screen, the whole screen as well, without
any problem.

Others have posted the whole screen on the forum. Hutch posted the entire screen
and it shows he was using Windows XP. So you have no excuses.  :lol

http://www.masm32.com/board/index.php?topic=15317.msg124977#msg124977

I guess you should check something
about the way you set the console properties, use it and so on.
Something about that we've already discussed. If anything else doesn't work maybe you
should check something else.  ::)
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

you may be right, Frank
this drive, at the moment, has been used to test certain MS hotfixes
it does not have service pack 3 and is missing 100+ XP updates - lol
it's kind of a hodge-podge build

copying from the clipboard should be easy...

dedndave

well - a quick search of the forum   :bg

MichaelW gives an example...

http://www.masm32.com/board/index.php?topic=3879.msg28908#msg28908

not sure how many brothers he has that are named Daryl, though   :lol

frktons

#10
Quote from: dedndave on November 15, 2010, 04:11:28 AM
well - a quick search of the forum   :bg

MichaelW gives an example...

http://www.masm32.com/board/index.php?topic=3879.msg28908#msg28908

not sure how many brothers he has that are named Daryl, though   :lol

Thanks Dave, this is probably the original code from which Andy extracted his piece of code.

By the way, my experiments have given some result.

I get this through the Clipboard:

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³OS  : Microsoft Windows 7 Ultimate Edition, 64-bit (build 7600)                         ³
³CPU : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz with 2 logical core(s) with SSSE3           ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ´
³        Algorithm notes           ³Proc Size³ Test # 1 ³ Test # 2 ³ Test # 3 ³ Test # 4 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³01 Alex / MMX - PUNPCKLBW MOVQ    ³    64   ³    5.411 ³    5.400 ³    5.428 ³    5.440 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³02 Frank / 486 - MOV-BSWAP        ³    43   ³   11.858 ³   11.850 ³   11.850 ³   11.851 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³03 Frank / XMM PUNPCKLBW MOVDQA   ³    45   ³    2.341 ³    2.462 ³    2.585 ³    2.592 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³04 Alex / MMX - PUNPCKLBW MOVNTQ  ³    64   ³    7.891 ³    8.111 ³    8.005 ³    7.976 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³05 Frank / 386 - MOV-SHIFT        ³    42   ³   11.728 ³   11.602 ³   11.600 ³   11.725 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´


Using the code posted in my second post, and extracting the Text from the Screen Display with this code:


; -------------------------------------------------------------------------
; The text is extracted from the Screen Buffer and prepared to be copied
; into the Windows Clipboard  with
; LF+CR at the end of each text line.
; -------------------------------------------------------------------------

CopyScreenText PROC


    lea  esi, SavedScreen
    lea  edi, TextResults

    mov  ecx, CharNumber
   
    xor  eax, eax
    xor  ebx, ebx



NextCharText:

    mov eax, [esi]
   
    mov BYTE PTR [edi], al

    add esi, Four
    add edi, One
    inc ebx

    cmp ebx, MaxCols
    jl  GoOn

    mov BYTE PTR [edi], CR
    mov BYTE PTR [edi + 1], LF
    add edi, Two
    xor ebx, ebx

GoOn:

    dec ecx
    jnz NextCharText

SetNULL:

    mov BYTE PTR [edi], Zero

End_cycle:

    ret
   
CopyScreenText ENDP

; -------------------------------------------------------------------------



It is not yet what I want, but I'm slowly approaching the target.  :P

Probably the console uses a different codepage than the clipboard, or something else
is happening. I'll try to fix it, if it is possible.  :lol

Frank





Mind is like a parachute. You know what to do in order to use it :-)

Magnum

Quote from: dedndave on November 15, 2010, 04:11:28 AM
well - a quick search of the forum   :bg

MichaelW gives an example...

http://www.masm32.com/board/index.php?topic=3879.msg28908#msg28908

not sure how many brothers he has that are named Daryl, though   :lol

MichaelW's example may have been quick but it wasn't dirty.

Worked perfect as posted.

Have a great day,
                         Andy

dedndave


frktons

Quote from: dedndave on November 15, 2010, 12:19:02 PM
this may be a font selection issue   :P

Probably a combination of codepage and font that must be aligned in order
to have the same display on the console and on the pasted text from the clipboard.

The strange thing is when I select the text with the mouse or through the select all
of the console command menu, it works perfectly.
Not the same if I copy the text into the clipboard through code and after I paste it into the
Forum or a text editor.  ::)

Nobody has gone through this problem so far ?
Mind is like a parachute. You know what to do in order to use it :-)

frktons

#14
I think I found the solution:

instead of :

invoke SetClipboardData,CF_TEXT,hglb

I have to use:

invoke SetClipboardData,CF_OEMTEXT,hglb

and in this way I get what I want:


┌────────────────────────────────────────────────────────────────────────────────────────┐
│OS  : Microsoft Windows 7 Ultimate Edition, 64-bit (build 7600)                         │
│CPU : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz with 2 logical core(s) with SSSE3           │
├──────────────────────────────────┬─────────┬──────────┬──────────┬──────────┬──────────┤
│        Algorithm notes           │Proc Size│ Test # 1 │ Test # 2 │ Test # 3 │ Test # 4 │
├──────────────────────────────────┼─────────┼──────────┼──────────┼──────────┼──────────┤
│01 Alex / MMX - PUNPCKLBW MOVQ    │    64   │    5.428 │    5.407 │    5.435 │    5.406 │
├──────────────────────────────────┼─────────┼──────────┼──────────┼──────────┼──────────┤
│02 Frank / 486 - MOV-BSWAP        │    43   │   11.876 │   11.871 │   12.022 │   11.872 │
├──────────────────────────────────┼─────────┼──────────┼──────────┼──────────┼──────────┤
│03 Frank / XMM PUNPCKLBW MOVDQA   │    45   │    2.358 │    2.655 │    2.645 │    2.640 │
├──────────────────────────────────┼─────────┼──────────┼──────────┼──────────┼──────────┤
│04 Alex / MMX - PUNPCKLBW MOVNTQ  │    64   │    8.030 │    8.049 │    8.107 │    8.204 │
├──────────────────────────────────┼─────────┼──────────┼──────────┼──────────┼──────────┤
│05 Frank / 386 - MOV-SHIFT        │    42   │   11.566 │   11.708 │   11.563 │   11.696 │
├──────────────────────────────────┼─────────┼──────────┼──────────┼──────────┼──────────┤

:U
Mind is like a parachute. You know what to do in order to use it :-)