Re: Wrapping DLLs in Euphoria (was: [OT] Swap RGB)

new topic     » goto parent     » topic index » view thread      » older message » newer message

Pete Lomax wrote:

> Juergen Luethje wrote:
> > 
> > - Run the following program.
> > - Switch to any other programs, and copy _text_ to the clipboard
> >   by using CTRL+C one or more times.
> Thanks, it works exactly as advertised.
> However it doesn't work when you right click and select Copy.

This is true. Because Richardo wrote about Ctrl+C, I focussed on that.
According to my habits, I personnally never use Ctrl+C, but I use
Ctrl+Insert instead. The program does not work with Ctrl+Insert, too.
The program was just a proof-of-concept. However, in a real program
users might take advantage of such a difference: They use Ctrl+C in
order to copy text to the clipboard that shall also be written to the
regarding file, and use Ctrl+Insert or right click and select Copy for
textb that shall only be copied to the clipboard.
Anyway, at the end of this post there is another program, that should
work with any method of putting text on the clipboard.

> I didn't know about GetAsyncKeyState, when I looked it up I stumbled across
> SetClipboardViewer, I might try doing something with that.

I recently stumbled across SetClipboardViewer(), too. And I also think
that it's interesting.

> > BTW: There should be a built-in fast peek_string() function in Euphoria.
> LOL. Including this, Edita just showed me no less than 31 versions of that
> lying
> around on my disk, most duplicates, 4 distinct.

blink

> If I get round to it, I'll time
> trial them against a fast asm version sometime next week and let you know the
> results.

Yes, please. That would be interesting for me.

Here is another program for writing text, that was copied to the
clipboard, automagically to a file. Please note that in contrast to the
previous version, GetAsyncKeyState() is not actually needed here. It's
only used here to provide a simple possibility for terminating the
program.
include dll.e
include machine.e
include misc.e

--===========================[ Utilities ]==============================
-- Windows API wrappers

constant CF_TEXT = 1

atom User32
integer OpenClipboard_, GetClipboardData_, CloseClipboard_,
GetClipboardSequenceNumber_,
        GetAsyncKeyState_

if platform() = WIN32 then
   User32 = open_dll("user32.dll")
OpenClipboard_              = define_c_func(User32, "OpenClipboard",
   {C_LONG}, C_LONG)
GetClipboardData_           = define_c_func(User32, "GetClipboardData",
   {C_LONG}, C_LONG)
CloseClipboard_             = define_c_func(User32, "CloseClipboard", {},
   C_LONG)
GetClipboardSequenceNumber_ = define_c_func(User32,
   "GetClipboardSequenceNumber", {}, C_ULONG)
GetAsyncKeyState_           = define_c_func(User32, "GetAsyncKeyState",
   {C_LONG}, C_SHORT)
end if

------------------------------------------------------------------------
-- Other utilities

constant SL_CODE = allocate(26)

poke(SL_CODE, {
     -- After the routine has pushed 4 bytes on the stack, first int
     -- argument is at stack offset +8.
     #57,                        -- push   edi
     #8B, #7C, #24, #08,         -- mov    edi, [esp+8]
     #B9, #FF, #FF, #FF, #FF,    -- mov    ecx, #FFFFFFFF
     #B0, #00,                   -- mov    al, 0
     #FC,                        -- cld
     #F2, #AE,                   -- repne  scasb
     #B8, #FE, #FF, #FF, #FF,    -- mov    eax, #FFFFFFFE
     #29, #C8,                   -- sub    eax, ecx
     #5F,                        -- pop    edi
     #C2, #04, #00               -- ret    4    -- pop 4 bytes off the stack
   })

constant STRLEN = define_c_func("", SL_CODE, {C_POINTER}, C_ULONG)

-- Usage:
-- len = c_func(STRLEN, {addr})
--
-- 'addr' is a pointer to the first character of a null-terminated
-- string in memory;
-- returns the length of the string in bytes (not including the
-- terminating null character); 
-- works like the Windows API function LstrLen(), but is cross-platform


function peek_string (atom addr)
   -- read a null-terminated string, starting at address 'addr' in memory
   return peek({addr, c_func(STRLEN,{addr})})   
end function


--=========================[ Used functions ]===========================

global function clipboard_text()
   sequence ret
   atom lpszText, void

   ret = ""
   if c_func(OpenClipboard_, {NULL}) then
      lpszText = c_func(GetClipboardData_, {CF_TEXT})
      if lpszText then
         ret = peek_string(lpszText)
      end if
      void = c_func(CloseClipboard_, {})
   end if
   return ret
end function

global function is_key_down (atom key)
   return and_bits(c_func(GetAsyncKeyState_, {key}), #8000) != 0
end function


--==============================[ Demo ]================================

constant VK_ESCAPE  = #1B

sequence filename, text
atom clipNumber
integer fn

filename = "collection.txt"

fn = open(filename, "w")
if fn = -1 then
   printf(1, "Can't open '%s'.", {filename})
   if getc(0) then end if
   abort(1)
end if

clipNumber = c_func(GetClipboardSequenceNumber_, {})
while not is_key_down(VK_ESCAPE) do
   if clipNumber != c_func(GetClipboardSequenceNumber_, {}) then
      clipNumber = c_func(GetClipboardSequenceNumber_, {})
      text = clipboard_text()
      if length(text) then
         puts(fn, text & "\n")
      end if
   end if
end while
close(fn)

Regards,
   Juergen

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu