- NSIS Discussion
- An idea for a function
Archive: An idea for a function
Afrow UK
26th June 2003 21:18 UTC
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
Joel
26th June 2003 21:40 UTC
In think that there's a "Message" for that:
See in the ${NSISDIR}\Include\WinMessages.nsh
Afrow UK
26th June 2003 22:00 UTC
Ah ok.
I have no idea what to do next however...
-Stu
Joel
26th June 2003 22:07 UTC
Maybe with the "SendMessage" use it :weird:
But, don't you need to reply that message?
brainsucker
26th June 2003 22:15 UTC
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 22:46 UTC
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 22:50 UTC
Well...don't blame me for trying :D
Afrow UK
26th June 2003 22:58 UTC
Now, how would I go about getting text from the clipboard into a string :)
-Stu
brainsucker
26th June 2003 23:19 UTC
System::Call 'user32::OpenClipboard(i 0)'
System::Call 'user32::GetClipboardData(i 1) t .r0'
System::Call 'user32::CloseClipboard()'
kichik
26th June 2003 23:31 UTC
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 23:49 UTC
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 23:56 UTC
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()'
Afrow UK
27th June 2003 10:27 UTC
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 12:49 UTC
The last one is the final for copy. The only one that was supposed to be for paste is still the final ;)
brainsucker
2nd July 2003 18:20 UTC
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.