Archive: An idea for a function


An idea for a function
I was trying to find a way to copy a string to the Windows clipboard using the System plugin, but was unable to find a way (I'm no C++ programmer see!)
I was wondering how this would be achieved?

When I mean "Windows clipboard" I mean so that the user can do a Ctrl+V and the string is copied automatically (without the user doing a Ctrl+C before hand)

-Stu


In think that there's a "Message" for that:
See in the ${NSISDIR}\Include\WinMessages.nsh


Ah ok.
I have no idea what to do next however...

-Stu


Maybe with the "SendMessage" use it :weird:
But, don't you need to reply that message?


System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::EmptyClipboard()'
System::Call '*(&t1024 "Just a clipboard demo!") i.r0'
System::Call 'user32::SetClipboardData(i 1, i r0)'
System::Call 'user32::CloseClipboard()'
System::Free $0


Originally posted by Lobo Lunar
Maybe with the "SendMessage" use it :weird:
But, don't you need to reply that message?
Well duh.
Thanks for the System dll way - that's the kind of way which I was trying to find.

-Stu

Well...don't blame me for trying :D


Now, how would I go about getting text from the clipboard into a string :)

-Stu


System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::GetClipboardData(i 1) t .r0'
System::Call 'user32::CloseClipboard()'


brainsucker, according to MSDN you are not supposed to free the memory of the clipboard data, and if allocated it should use GMEM_MOVEABLE. So the code should probably look like this:

StrCpy $0 "string to put in clipboard"
System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::EmptyClipboard()'
StrLen $1 $0
System::Call 'kernel32::GlobalAlloc(i 2, i $1) i.r1'
System::Call 'kernel32::lstrcpyA(i $1, t $0)'
System::Call 'user32::SetClipboardData(i 1, i r1)'
System::Call 'user32::CloseClipboard()'

Also, SetClipboardData and CloseClipboard both return a value. Does System.dll default to int return value if nothing is specified?


MSDN: The application can read the data, but must not free the handle or leave it locked until the CloseClipboard function is called. (The application can access the data after calling CloseClipboard).
"Can access" could mean 'free', imho.
No considirations about GMEM_MOVEABLE, anyway your way is more correct, but my way works to :) for strings at least ;)

Functions/Procedures return values in registers, and it doesn't matter how we process it... So if we don't specify return type system plugin just skips the converting step...


MSDN example doesn't free the memory, so I guess we shouldn't too. But it does something else that I have forgotten in my code, it uses GlobalLock. Complete code should be:

StrCpy $0 "string to put in clipboard"
System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::EmptyClipboard()'
StrLen $1 $0
System::Call 'kernel32::GlobalAlloc(i 2, i $1) i.r1'
System::Call 'kernel32::GlobalLock(i $1) i.r2'
System::Call 'kernel32::lstrcpyA(i $2, t $0)'
System::Call 'kernel32::GlobalUnlock(i $1)'
System::Call 'user32::SetClipboardData(i 1, i r1)'
System::Call 'user32::CloseClipboard()'


So, which are the final two scripts?
I'd like to add them to the archive when I get back home...

-Stu


The last one is the final for copy. The only one that was supposed to be for paste is still the final ;)


Thanks!
http://nsis.sourceforge.net/archive/...ances=0,11,122

-Stu :)


I've missed some 'tips' in Kichik's script, the right version should look like:


StrCpy $0 "string to put in clipboard"
System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::EmptyClipboard()'
StrLen $1 $0
IntOp $1 + 1
System::Call 'kernel32::GlobalAlloc(i 2, i r1) i.r1'
System::Call 'kernel32::GlobalLock(i r1) i.r2'
System::Call 'kernel32::lstrcpyA(i r2, t r0)'
System::Call 'kernel32::GlobalUnlock(i r1)'
System::Call 'user32::SetClipboardData(i 1, i r1)'
System::Call 'user32::CloseClipboard()'


All changes of $n to rn are non fatal, beside the line with lstrcpy,
where $0 shouldn't and couldn't work right.