Home > Archive > Lisp > March 2006 > Re: CLISP and win32 clipboard access
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Re: CLISP and win32 clipboard access
|
|
| tsummerall@medialab.com 2006-03-29, 8:01 am |
| I notice that this example works:
(use-package "FFI")
(def-call-out messagebox
(:name "MessageBoxA") (:library "user32.dll")
(:arguments (hwnd int) (text c-string) (capt c-string)
(type uint))
(:return-type int)
(:language :stdc))
Would it be possible to do something like this from within CLISP
without having to recompile?
I tried this but got only NIL as the return value:
(def-call-out clipget
(:name "GetClipboardData") (:library "user32.dll")
(:arguments (type uint))
(:return-type int)
(:language :stdc))
Is this the right direction to go in at least?
| |
| Pascal Bourguignon 2006-03-29, 8:01 am |
| tsummerall@medialab.com writes:
> I notice that this example works:
>
> (use-package "FFI")
> (def-call-out messagebox
> (:name "MessageBoxA") (:library "user32.dll")
> (:arguments (hwnd int) (text c-string) (capt c-string)
> (type uint))
> (:return-type int)
> (:language :stdc))
>
> Would it be possible to do something like this from within CLISP
> without having to recompile?
Yes.
> I tried this but got only NIL as the return value:
That should not possible. DEF-CALL-OUT returns the name of the lisp
function defined (a symbol, CLIPGET in this case), and the function
CLIPGET should return an integer.
> (def-call-out clipget
> (:name "GetClipboardData") (:library "user32.dll")
> (:arguments (type uint))
> (:return-type int)
> (:language :stdc))
>
> Is this the right direction to go in at least?
Yes.
--
__Pascal Bourguignon__ http://www.informatimago.com/
"This machine is a piece of GAGH! I need dual Opteron 850
processors if I am to do battle with this code!"
| |
| Pascal Bourguignon 2006-03-29, 7:03 pm |
| tsummerall@medialab.com writes:
> Okay, one down two to go. I am now getting a value from the clipboard
> by prefacing it with OpenClipboard().
>
> Any ideas how to coerce the result to a Lisp string?
I don't know anything about Microsoft Windows, but assuming this is it:
http://msdn.microsoft.com/library/d...heclipboard.asp
the first step is to know the signature of the function.
http://msdn.microsoft.com/library/d...ipboarddata.asp
Says that it's: HANDLE GetCliboardData(UINT uFormat);
with:
Return Value
If the function succeeds, the return value is the handle to a
clipboard object in the specified format.
If the function fails, the return value is NULL. To get extended
error information, call GetLastError.
So in any case, the return value is not an int, but a pointer of some kind.
After the examples linked above, it seems you'll need to use
GlobalLock to get a pointer to the data from the returned handle.
If a function returned a string, it would be a simple matter of saying so.
;; http://clisp.cons.org/impnotes/dffi.html
(ffi:def-call-out f (:name "somefun")
(:arguments (arg ffi:c-string))
(:return-type ffi:c-string))
Note that the conversion of the bytes in the c-string is governed by
the ext:*foreign-encoding*, and that the actual encoding used by
MS-Windows seems to depend on the uFormat argument.
You'll have to check MS-Windows headers to see what type a HANDLE is.
Assuming it's a void*, you could declare it as:
(ffi:def-c-type HANDLE ffi:c-pointer)
and then the correct declaration of GET-CLIPBOARD-DATA would be:
(ffi:def-call-out GET-CLIPBOARD-DATA (:name "GetClipboardData")
(:arguments (arg ffi:uint))
(:return-type HANDLE))
If you have to use a lot of MS-Windows functions, it might be
worthwhile to check SWIG to generate the FFI declarations from the
headers.
http://www.cliki.net/SWIG
http://www.cliki.net/Verrazano
http://www.cliki.net/CFFI
--
__Pascal Bourguignon__ http://www.informatimago.com/
READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
| |
| Pascal Bourguignon 2006-03-29, 7:03 pm |
| tsummerall@medialab.com writes:
> Okay, for posterity, here it is. Thank you Pascal!!
Here, I think it would be better to use unwind-protect:
> (defun get-clip-string ()
> (clip-open 0)
> (let* ((h (clip-get 1)) (s (global-lock-string h)))
> (global-unlock h) (clip-close 0) s))
>
> (defun set-clip-string (s)
> (let* ((slen (+ 1 (length s)))(newh (global-alloc 8194 slen))
> (newp (global-lock newh)))
> (memcpy newp s (+ 1 slen)) (global-unlock newh) (clip-open 0)
> (clip-set 1 newh) (clip-close 0)))
(defun get-clip-string ()
(let ((s nil))
(unwind-protect
(let* ((dummy (clip-open 0))
(h (clip-get 1)))
(unwind-protect
(setf s (global-lock-string h))
(global-unlock h)))
(clip-close 0))
s))
And similarly in set-clip-string.
--
__Pascal Bourguignon__ http://www.informatimago.com/
COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.
| |
|
|
|
|
|