lua学习之——有道词典“划词”的秘密

本文的目的是为了学习总结lua调用C函数的过程。文章的标题看上去过于标新立异了,其实主要是为了在Lua中获取和修改Windows的剪贴板;因为有道词典“划词”的秘密就是通过剪贴板进行字母的传递,文章的标题由此得来。先给出本文的结果

当有道词典进行“划词”(不是取词哦,取词是通过hook进行的)操作的时候,lua就会print出那个被划的字母了。

setClipBoard("");
while true do
	str = getClipBoard()
	if(str ~= "")then
		print(str)
	end
end
setClipBoard和getClipBoard并不是lua的内置函数,而是通过修改lua.c加上去的。lua提供了一套很简单的方法添加C/C++的函数,详细的描述请参看《lua程序设计》,而我只负责讲解这两个和剪贴板有关的函数。在lua工程里添加:extlua.cpp和extlua.h。

在exlua.cpp中主要实现了复制和粘贴的功能,实现如下:

#include <Windows.h>
#include "extlua.h"

bool SetClipBoard(const char * str)
{
    if(!OpenClipboard(NULL) || !EmptyClipboard())
    {
        return 0;
    }

    HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (strlen(str) + 1) * sizeof(char));

    if(!hMem)
    {  
        CloseClipboard();
        return 0;
    }
    char* lpStr = (char*)GlobalLock(hMem);
    memcpy(lpStr, str, (strlen(str)) * sizeof(char));
    lpStr[strlen(str)] = 0;
    GlobalUnlock(hMem);
    SetClipboardData(CF_TEXT, hMem);
    CloseClipboard();

    return 1;
}

char * GetClipBoard()
{
    char* lpStr;   
    if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL))   
    {    
        return "";   
    }   
        
    HGLOBAL hMem = GetClipboardData(CF_TEXT);   
    if (hMem)   
    {     
        lpStr = (char*)GlobalLock(hMem);     
        if (lpStr)   
        {   
            GlobalUnlock(hMem);    
        }   
    }    

    //change "\r\n" to "\n"
    int iStrip = 0;
    for(int i = 0; i < strlen(lpStr) - 1; i ++)
    {
        if(lpStr[i] == 0);
        else if(lpStr[i] == '\r' && lpStr[i + 1] == '\n')
        {
            lpStr[i] = '\n';
            lpStr[i+1] = 0;
            lpStr[i - iStrip] = lpStr[i];
            iStrip += 1;
        }
        else
        {
            lpStr[i - iStrip] = lpStr[i];
        }
    }
    CloseClipboard();    

    return lpStr;
}
extlua.h的实现如下:

extern char * GetClipBoard();
extern bool SetClipBoard(const char * str);
处于个人的喜好,我把lua.c改成了lua.cpp,只需将几个lua相关的头文件包含在extern "C" {}中。然后在lua.cpp中添加:

static int ext_getClipBoard(lua_State *L)
{
    lua_pushstring(L, GetClipBoard());
    return 1;
}

static int ext_setClipBoard(lua_State *L)
{
    const char * str = lua_tostring(L, 1);
    lua_pushboolean(L, SetClipBoard(str));
    return 1;
}
在int pmain函数的luaL_openlibs下面添加:

  lua_pushcfunction(L, ext_getClipBoard);
  lua_setglobal(L, "getClipBoard");
  lua_pushcfunction(L, ext_setClipBoard);
  lua_setglobal(L, "setClipBoard");


然后重新编译lua.exe就可以了。现在你也拥有了复制粘贴,你也知道了剪贴板的秘密了。

你可能感兴趣的:(lua学习之——有道词典“划词”的秘密)