News:

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

Getting Handle to Memory Block

Started by raleeper, September 19, 2009, 12:41:45 PM

Previous topic - Next topic

raleeper

I want to copy memory from eg. lpSTART to lpEND to the clipboard.  This is part of a larger block previously allocated using VirtualAlloc.

To do this it seems I must use SetClipboardData, which, however, requires as a parameter-in a handle rather than start and end, or a start and size.

I suppose I could use GlobalAlloc to create a new block of the required size and copy the source range to it, but that seems grossly inefficient, since presumably it will have to be copied again by the SetClipboardData function.

Is there a better way?

Thanks,

Robert

donkey

The clipboard is a legacy function so you need to use GlobalAlloc for any data you want to copy to it. Also you will have to lock the memory before you copy to it and unlock it when you are done.

Copy to clipboard
invoke OpenClipboard, [hWin]
or eax,eax
jz >>.DONE
invoke EmptyClipboard
invoke GlobalAlloc,GMEM_MOVEABLE + GMEM_ZEROINIT,4096
mov [hClipData],eax
invoke GlobalLock,[hClipData]

// Copy any data to the handle stored in EAX

invoke GlobalUnlock,[hClipData]
invoke SetClipboardData, CF_TEXT, [hClipData] // Be sure to use the right format here (CF_xxxx)
invoke CloseClipboard


Paste from clipboard
invoke IsClipboardFormatAvailable, CF_TEXT
or eax,eax
jz >>.DONE
invoke OpenClipboard, [hWin]
or eax,eax
jz >>.DONE
invoke GetClipboardData, CF_TEXT
or eax,eax
jz >P1
push eax
invoke GlobalLock,eax

// Copy the data from the handle in EAX to your buffer

pop eax
invoke GlobalUnlock,eax
P1:
invoke CloseClipboard
"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

raleeper

OK.  Thank you for the code!

The term "legacy" and the tone of the SDK documentation suggest that there might be some newer and better way to transfer data from one application to another, but I take it that is not so.

Thanks again,

Robert

Quote from: donkey on September 19, 2009, 02:51:48 PM
The clipboard is a legacy function so you need to use GlobalAlloc for any data you want to copy to it. Also you will have to lock the memory before you copy to it and unlock it when you are done.

Copy to clipboard
invoke OpenClipboard, [hWin]
or eax,eax
jz >>.DONE
invoke EmptyClipboard
invoke GlobalAlloc,GMEM_MOVEABLE + GMEM_ZEROINIT,4096
mov [hClipData],eax
invoke GlobalLock,[hClipData]

// Copy any data to the handle stored in EAX

invoke GlobalUnlock,[hClipData]
invoke SetClipboardData, CF_TEXT, [hClipData] // Be sure to use the right format here (CF_xxxx)
invoke CloseClipboard


Paste from clipboard
invoke IsClipboardFormatAvailable, CF_TEXT
or eax,eax
jz >>.DONE
invoke OpenClipboard, [hWin]
or eax,eax
jz >>.DONE
invoke GetClipboardData, CF_TEXT
or eax,eax
jz >P1
push eax
invoke GlobalLock,eax

// Copy the data from the handle in EAX to your buffer

pop eax
invoke GlobalUnlock,eax
P1:
invoke CloseClipboard


raleeper

Am I correct that there is no better way to determine the size of the buffer needed than to do a

    mov ecx, eax
    mov edi, eax
    xor al, al
    repnz scasb
    sub ecx, edi
    neg ecx

after the GlobalLock?

Thank you,

Robert

                ----

donkey wrote: [: September 19, 2009, 10:51:48 am »]

...

Paste from clipboard
Code:
invoke IsClipboardFormatAvailable, CF_TEXT
or eax,eax
jz >>.DONE
invoke OpenClipboard, [hWin]
or eax,eax
jz >>.DONE
invoke GetClipboardData, CF_TEXT
or eax,eax
jz >P1
push eax
invoke GlobalLock,eax

// Copy the data from the handle in EAX to your buffer

pop eax
invoke GlobalUnlock,eax
P1:
invoke CloseClipboard


hutch--

Robert,

The clipboard is a useful technique but its not really designed for direct application to application data transfer, its more directly pointed at the user who can move data manually using the clipboard. The trick is to use a memory mapped file and write the code between apps that responds to "SendMessage,HWND_BROADCAST, etc ..." so that the caller creates the memory mapped file, the other end can receive the message from the caller then open the same memory mapped file and read the data.

To select a range in the memory mapped file, all you need is the starting OFFSET within the address and the length from that offset to know what data to send.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

raleeper

I accidently posted the next message twice.

Now I can't find how to delete the surplus copy.

So please ignore this one

Thank you,

Robert

qWord

You can use GlobalSize(hGlbMem) to determinate the size of an memory-block returned by GetClipboardData().
FPU in a trice: SmplMath
It's that simple!

hutch--

Robert,

Is there anty particular reason why you need to mix clipboard memory with any other type ? General drift is read the data from the clipboard into the required GlobalAlloc() memory then copy it to wherever you like. Copying the memory to a location is nothing more that knowing the offset from start that you want and calculating if the buffer you originally allocated is big enough.

This allows you to seperate the clipboard allocation from what you app uses internally.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

raleeper

Quote from: qWord on October 14, 2009, 02:10:27 PM
You can use GlobalSize(hGlbMem) to determinate the size of an memory-block returned by GetClipboardData().

Thanks.  That's just what I needed!

ecube

i'd be careful with HWND_BROADCAST, its dangerous from what i've read at a couple sites, such as http://www.codeguru.com/forum/showthread.php?t=440788

raleeper

Quote from: hutch-- on October 14, 2009, 02:14:40 PM
Robert,

Is there anty particular reason why you need to mix clipboard memory with any other type ? General drift is read the data from the clipboard into the required GlobalAlloc() memory then copy it to wherever you like. Copying the memory to a location is nothing more that knowing the offset from start that you want and calculating if the buffer you originally allocated is big enough.

This allows you to seperate the clipboard allocation from what you app uses internally.

Hutch,

I'm not sure I understand.  Mp app is a sort of text processor, so I want to copy text to and from any other app [word, firefox, explorer, many others] that uses text and supports the clipboard - including anything with a dialog box.

For pasting, of course the clipboard data is "mixed" with the preexisting text.

Perhaps I should add that my app keeps text memory in a single contiguous block - I realize that it may be better, for many reasons, to use pointers, but there are advantages to the single block too, so for now that's what I'm doing.

Thanks,

Robert

hutch--

Robert,

It sounds like you need a memory INSERT strategy. With all data in one allocation, extend the allocated memory by at least the amount you are going to insert, move the data from the insertion point onwards back by the size of the clipboard data then write the cpliboard data at the insertion point. It may also be a worthwhile strategy to keep some spare memory allocated at the end of your main block and use a lazy allocate technique where the block is auto-extended when the word processor is idling. A megabyte of so would be no big deal these days with modern computers.

Cube,

You are safe with HWND_BROADCAST as long as you use it in conjunction with a private message, using it with a common message would be very risky.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

raleeper

Thank you for all your assistance on this topic;

donkey and qWord - you've saved me a lot of time and probably prevented me from making costly mistakes.
But I apologize, since this is stuff  I ought to have at least made a greater effort to get out of the SDK documentation before crying for help.

hutch - (and Cube) I haven't finished analysing and digesting your posts, but I think they may take me into fruitful new areas I would not have found on my own.

The MASM Forum rules!

Thanks again,

Robert
ral@raleeper.com