PDA

View Full Version : An idea for a function


Afrow UK
26th June 2003, 20:18
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

Joel
26th June 2003, 20:40
In think that there's a "Message" for that:
See in the ${NSISDIR}\Include\WinMessages.nsh

Afrow UK
26th June 2003, 21:00
Ah ok.
I have no idea what to do next however...

-Stu

Joel
26th June 2003, 21:07
Maybe with the "SendMessage" use it :weird:
But, don't you need to reply that message?

brainsucker
26th June 2003, 21:15
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

Afrow UK
26th June 2003, 21:46
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

Joel
26th June 2003, 21:50
Well...don't blame me for trying :D

Afrow UK
26th June 2003, 21:58
Now, how would I go about getting text from the clipboard into a string :)

-Stu

brainsucker
26th June 2003, 22:19
System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::GetClipboardData(i 1) t .r0'
System::Call 'user32::CloseClipboard()'

kichik
26th June 2003, 22:31
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?

brainsucker
26th June 2003, 22:49
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...

kichik
26th June 2003, 22:56
MSDN example (http://msdn.microsoft.com/library/en-us/winui/WinUI/WindowsUserInterface/DataExchange/Clipboard/UsingtheClipboard.asp?frame=true) 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()'

Afrow UK
27th June 2003, 09:27
So, which are the final two scripts?
I'd like to add them to the archive when I get back home...

-Stu

kichik
27th June 2003, 11:49
The last one is the final for copy. The only one that was supposed to be for paste is still the final ;)

Afrow UK
27th June 2003, 15:25
Thanks!
http://nsis.sourceforge.net/archive/nsisweb.php?page=338&instances=0,11,122

-Stu :)

brainsucker
2nd July 2003, 17:20
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.