andersonljw 发表于 2010-8-19 09:10:13

AU3能否做出像金山词霸那样取词功能

如题,AU3能否做出像金山词霸那样取词功能,即鼠标放置于屏幕字符上
就可显示相关内容
好像是要用HOOK去做,但我一点头绪都没有
烦劳各位大侠提供思路或方法
在此感激不尽!!!

3mile 发表于 2010-8-19 09:27:33

1. 安装鼠标钩子,通过钩子函数获得鼠标消息。
2. 得到鼠标的当前位置,向鼠标下的窗口发重画消息,让它调用系统函数重画窗口。
3. 截获对系统函数的调用,取得参数,也就是我们要取的词。

andersonljw 发表于 2010-8-19 12:17:11

能否给个简单的例子
或者给个相关链接之类,感谢 送花先!{:face (310):}

andersonljw 发表于 2010-8-23 17:16:14

有没有相关HOOK的资料或例子之类的

131738 发表于 2010-8-23 17:57:59

有没有相关HOOK的资料或例子之类的
andersonljw 发表于 2010-8-23 17:16 http://www.autoitx.com/images/common/back.gif
看看有用不。。。。
http://www.autoitx.com/forum.php?mod=viewthread&tid=13128&highlight=%CA%C2%BC%FE%BC%C7%C2%BC%B9%A4%BE%DF

xyold1 发表于 2010-8-23 18:41:12

本帖最后由 xyold1 于 2010-8-23 18:44 编辑

这是一个StarDict取词代码,C的吧
好长!
引自http://www.huzheng.org/showarticle.php?category=myarticle&&docpage=0&&newsid=24TextOutSpy.c
=============================
#include "TextOutSpy.h"
#include "ThTypes.h"


const int MOUSEOVER_INTERVAL = 300;
const int WM_MY_SHOW_TRANSLATION = WM_USER + 300;

HINSTANCE g_hInstance = NULL;
HANDLE hSynhroMutex = 0;
HINSTANCE hGetWordLib = 0;
typedef void (*GetWordProc_t)(TCurrentMode *);
GetWordProc_t GetWordProc = NULL;

static void SendWordToServer()
{
        if (hGetWordLib == 0) {
                hGetWordLib = LoadLibrary(GlobalData->LibName);
                if (hGetWordLib) {
                        GetWordProc = (GetWordProc_t)GetProcAddress(hGetWordLib, "GetWord");
                }
                else {
                        hGetWordLib = (HINSTANCE)-1;
                }
        }
        if (GetWordProc) {
                GlobalData->CurMod.WND = GlobalData->LastWND;
                GlobalData->CurMod.Pt = GlobalData->LastPt;
                GetWordProc(&(GlobalData->CurMod));
                if (GlobalData->CurMod.WordLen > 0) {
                        DWORD SendMsgAnswer;
                        SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
                }
        }
}

void CALLBACK TimerFunc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)
{
        if (WaitForSingleObject(hSynhroMutex, 0) == WAIT_OBJECT_0) {
                if (GlobalData->TimerID) {
                        if (KillTimer(0, GlobalData->TimerID))
                                GlobalData->TimerID=0;
                }
                ReleaseMutex(hSynhroMutex);
        }
        if ((GlobalData->LastWND!=0)&&(GlobalData->LastWND == WindowFromPoint(GlobalData->LastPt))) {
                if (WaitForSingleObject(hSynhroMutex, 0) == WAIT_OBJECT_0) {
                        SendWordToServer();
                        ReleaseMutex(hSynhroMutex);
                }
        }
}

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
        if ((nCode == HC_ACTION) && ((wParam == WM_MOUSEMOVE) || (wParam == WM_NCMOUSEMOVE))) {
                if (WaitForSingleObject(hSynhroMutex, 0) == WAIT_OBJECT_0) {
                        if (GlobalData->TimerID) {
                                if (KillTimer(0, GlobalData->TimerID))
                                        GlobalData->TimerID=0;
                        }
                        HWND WND = WindowFromPoint(((PMOUSEHOOKSTRUCT)lParam)->pt);
                        TCHAR wClassName;
                        if (GetClassName(WND, wClassName, sizeof(wClassName) / sizeof(TCHAR))) {
                                        const char* DisableClasses[] = {
                                                "gdkWindowChild",
                                                "gdkWindowTemp",
                                        };
                                        int i;
                                        for (i=0; i<2; i++) {
                                                if (strcmp(wClassName, DisableClasses)==0)
                                                        break;
                                        }
                                        if (i<2) {
                                                ReleaseMutex(hSynhroMutex);
                                                return CallNextHookEx(GlobalData->g_hHookMouse, nCode, wParam, lParam);
                                        }
                        }
                        GlobalData->TimerID = SetTimer(0, 0, MOUSEOVER_INTERVAL, TimerFunc);
                        GlobalData->LastWND = WND;
                        GlobalData->LastPt = ((PMOUSEHOOKSTRUCT)lParam)->pt;
                        ReleaseMutex(hSynhroMutex);
                }
        }
        return CallNextHookEx(GlobalData->g_hHookMouse, nCode, wParam, lParam);
}

DLLIMPORT void ActivateTextOutSpying (int Activate)
{
        // After call SetWindowsHookEx(), when you move mouse to a application's window,
        // this dll will load into this application automatically. And it is unloaded
        // after call UnhookWindowsHookEx().
        if (Activate) {
                if (GlobalData->g_hHookMouse != NULL) return;
                GlobalData->g_hHookMouse = SetWindowsHookEx(WH_MOUSE, MouseHookProc, g_hInstance, 0);
        }
        else {
                if (GlobalData->g_hHookMouse == NULL) return;
                if (WaitForSingleObject(hSynhroMutex, 0) == WAIT_OBJECT_0) {
                        if (GlobalData->TimerID) {
                                if (KillTimer(0, GlobalData->TimerID))
                                        GlobalData->TimerID=0;
                        }
                        ReleaseMutex(hSynhroMutex);
                }
                UnhookWindowsHookEx(GlobalData->g_hHookMouse);
                GlobalData->g_hHookMouse = NULL;
        }
}


BOOL APIENTRY DllMain (HINSTANCE hInst   /* Library instance handle. */ ,
                     DWORD reason      /* Reason this function is being called. */ ,
                     LPVOID reserved   /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
                        g_hInstance = hInst;
                        hSynhroMutex = CreateMutex(NULL, FALSE, "StarDictTextOutSpyMutex");
                        ThTypes_Init();
      break;

      case DLL_PROCESS_DETACH:
                        WaitForSingleObject(hSynhroMutex, INFINITE);
                        if (GlobalData->TimerID) {
                                if (KillTimer(0, GlobalData->TimerID))
                                        GlobalData->TimerID=0;
                        }
                        ReleaseMutex(hSynhroMutex);
                        CloseHandle(hSynhroMutex);
                        {
                        MSG msg ;
                        while (PeekMessage (&msg, 0, WM_TIMER, WM_TIMER, PM_REMOVE)) {}
                        }
                        if ((hGetWordLib != 0)&&(hGetWordLib != (HINSTANCE)(-1))) {
                                FreeLibrary(hGetWordLib);
                        }
                        Thtypes_End();
      break;

      case DLL_THREAD_ATTACH:
      break;

      case DLL_THREAD_DETACH:
      break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
=============================

TextOutSpy.h
=============================
#ifndef _TextOutSpy_H_
#define _TextOutSpy_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


DLLIMPORT void ActivateTextOutSpying (int Activate);


#endif /* _TextOutSpy_H_ */
=============================

ThTypes.c
=============================
#include "ThTypes.h"

HANDLE MMFHandle = 0;
TGlobalDLLData *GlobalData = NULL;

void ThTypes_Init()
{
        if (!MMFHandle)
                MMFHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TGlobalDLLData), "StarDictTextOutHookSharedMem");
        if (!GlobalData)
                GlobalData = MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
}

void Thtypes_End()
{
        if (GlobalData) {
                UnmapViewOfFile(GlobalData);
                GlobalData = NULL;
        }
        if (MMFHandle) {
                CloseHandle(MMFHandle);
                MMFHandle = 0;
        }
}
=============================

ThTypes.h
=============================
#ifndef _ThTypes_H_
#define _ThTypes_H_

#include <windows.h>

#ifdef __cplusplus
extern "C"
{
#endif                                /* __cplusplus */

typedef struct TCurrentMode {
        HWND WND;
        POINT Pt;
        int WordLen;
        char MatchedWord;
        int BeginPos;
} TCurrentMode;

typedef struct TGlobalDLLData {
        HWND ServerWND;
        HHOOK g_hHookMouse;
        DWORD TimerID;
        HWND LastWND;
        POINT LastPt;
        TCurrentMode CurMod;
        char LibName;
} TGlobalDLLData;

extern TGlobalDLLData *GlobalData;


void ThTypes_Init();
void Thtypes_End();

#ifdef __cplusplus
}
#endif                                /* __cplusplus */

#endif
=============================

TextOutHook.c
=============================
#include "TextOutHook.h"
#include "GetWord.h"
#include "HookImportFunction.h"


typedef BOOL WINAPI (*TextOutANextHook_t)(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString,int cbString);
TextOutANextHook_t TextOutANextHook = NULL;
typedef BOOL WINAPI (*TextOutWNextHook_t)(HDC hdc, int nXStart, int nYStart, LPCWSTR lpszString,int cbString);
TextOutWNextHook_t TextOutWNextHook = NULL;
typedef BOOL WINAPI (*ExtTextOutANextHook_t)(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCSTR lpszString, UINT cbString, CONST INT *lpDx);
ExtTextOutANextHook_t ExtTextOutANextHook = NULL;
typedef BOOL WINAPI (*ExtTextOutWNextHook_t)(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpszString, UINT cbString, CONST INT *lpDx);
ExtTextOutWNextHook_t ExtTextOutWNextHook = NULL;

typedef struct TEverythingParams {
        HWND WND;
        POINT Pt;
        int Active;
        int WordLen;
        int Unicode;
        int BeginPos;
        char MatchedWordA;
        wchar_t MatchedWordW;
} TEverythingParams;

TEverythingParams *CurParams = NULL;

static void ConvertToMatchedWordA(TEverythingParams *TP)
{
        if (TP->Unicode) {
                if (TP->WordLen>0) {
                        int BeginPos = TP->BeginPos;
                        TP->BeginPos = WideCharToMultiByte(CP_ACP, 0, TP->MatchedWordW, BeginPos, TP->MatchedWordA, sizeof(TP->MatchedWordA)-1, NULL, NULL);
                        TP->WordLen = WideCharToMultiByte(CP_ACP, 0, TP->MatchedWordW + BeginPos, TP->WordLen - BeginPos, TP->MatchedWordA + TP->BeginPos, sizeof(TP->MatchedWordA)-1 - TP->BeginPos, NULL, NULL);
                        TP->WordLen += TP->BeginPos;
                        TP->MatchedWordA = '\0';
                } else {
                        TP->MatchedWordA = '\0';
                }
                TP->Unicode = FALSE;
        } else {
                TP->MatchedWordA = '\0';
        }
}

static int MyCopyMemory(char *a, const char *b, int len)
{
        int count = 0;
        int i;
        for (i=0; ix) && (p->x<=rec.right) && (rec.top<=p->y) && (p->y<=rec.bottom)) {
                        ZeroMemory(&info, sizeof(info));
                        info.cbSize = sizeof(info);
                        info.fMask = MIIM_TYPE | MIIM_SUBMENU;
                        info.cch = 256;
                        info.dwTypeData = malloc(256);
                        GetMenuItemInfo(menu, i, TRUE, &info);
                        if (info.cch>0) {
                                if (info.cch > 255)
                                        CurParams->WordLen = 255;
                                else
                                        CurParams->WordLen = info.cch;
                                CurParams->Unicode = FALSE;
                                CurParams->WordLen = MyCopyMemory(CurParams->MatchedWordA, info.dwTypeData, CurParams->WordLen);
                                CurParams->BeginPos = 0;
                        }
                        free(info.dwTypeData);
                }
        }
}

static void GetWordTextOutHook (TEverythingParams *TP)
{
        CurParams = TP;
        ScreenToClient(TP->WND, &(TP->Pt));
        if (TP->Pt.y<0) {
                char buffer;
                GetWindowText(TP->WND, buffer, sizeof(buffer)-1);
                CurParams->Active = TRUE;
                SetWindowText(TP->WND, buffer);
                CurParams->Active = FALSE;
                HMENU menu = GetMenu(TP->WND);
                if (menu) {
                        ClientToScreen(TP->WND, &(TP->Pt));
                        IterateThroughItems(TP->WND, menu, &(TP->Pt));
                }
        }
        else {
                RECT UpdateRect;
                GetClientRect(TP->WND, &UpdateRect);
                UpdateRect.top = TP->Pt.y;
                UpdateRect.bottom = TP->Pt.y + 1;
                CurParams->Active = TRUE;
                InvalidateRect(TP->WND, &UpdateRect, FALSE);
                UpdateWindow(TP->WND);
                CurParams->Active = FALSE;
        }
        CurParams = NULL;
}

char* ExtractFromEverything(HWND WND, POINT Pt, int *BeginPos)
{
        TEverythingParams CParams;
        ZeroMemory(&CParams, sizeof(CParams));
        CParams.WND = WND;
        CParams.Pt = Pt;
        GetWordTextOutHook(&CParams);
        ConvertToMatchedWordA(&CParams);
        *BeginPos = CParams.BeginPos;
        return strdup(CParams.MatchedWordA);
}

static void IsInsidePointA(const HDC DC, int X, int Y, LPCSTR Str, int Count)
{
        SIZE Size;
        if ((Count > 0) && GetTextExtentPoint32A(DC, Str, Count, &Size)) {
                DWORD Flags = GetTextAlign(DC);
                POINT Pt;
                if (Flags & TA_UPDATECP) {
                        GetCurrentPositionEx(DC, &Pt);
                } else {
                        Pt.x = X;
                        Pt.y = Y;
                }
                if (Flags & TA_CENTER) {
                        Pt.x-=(Size.cx/2);
                } else if (Flags & TA_RIGHT) {
                        Pt.x-=Size.cx;
                }
                if (Flags & TA_BASELINE) {
                        TEXTMETRIC tm;
                        GetTextMetricsA(DC, &tm);
                        Pt.y-=tm.tmAscent;
                } else if (Flags & TA_BOTTOM) {
                        Pt.y-=Size.cy;
                }
                LPtoDP(DC, &Pt, 1);
                RECT Rect;
                Rect.left = Pt.x;
                Rect.right = Pt.x + Size.cx;
                Rect.top = Pt.y;
                Rect.bottom = Pt.y + Size.cy;
                if (((Rect.left <= Rect.right) && (CurParams->Pt.x >= Rect.left) && (CurParams->Pt.x <= Rect.right)) ||
                        ((Rect.left > Rect.right) && (CurParams->Pt.x <= Rect.left) && (CurParams->Pt.x >= Rect.right))) {
                //if (PtInRect(&Rect, CurParams->Pt)) {
                        CurParams->Active = !PtInRect(&Rect, CurParams->Pt);
                        //CurParams->Active = FALSE;
                        int BegPos = round(abs((CurParams->Pt.x - Rect.left) / (Rect.right - Rect.left)) * (Count - 1));
                        while ((BegPos < Count - 1) && GetTextExtentPoint32A(DC, Str, BegPos + 1, &Size) && (Size.cx < CurParams->Pt.x - Rect.left))
                                BegPos++;
                        while ((BegPos >= 0) && GetTextExtentPoint32A(DC, Str, BegPos + 1, &Size) && (Size.cx > CurParams->Pt.x - Rect.left))
                                BegPos--;
                        if (BegPos < Count - 1)
                                BegPos++;
                        CurParams->BeginPos = BegPos;
                        if (Count > 255)
                                CurParams->WordLen = 255;
                        else
                                CurParams->WordLen = Count;
                        CurParams->Unicode = FALSE;
                        CopyMemory(CurParams->MatchedWordA, Str, CurParams->WordLen);
                }
        }
}

static void IsInsidePointW(const HDC DC, int X, int Y, LPCWSTR Str, int Count)
{
        SIZE Size;
        if ((Count > 0) && GetTextExtentPoint32W(DC, Str, Count, &Size)) {
                DWORD Flags = GetTextAlign(DC);
                POINT Pt;
                if (Flags & TA_UPDATECP) {
                        GetCurrentPositionEx(DC, &Pt);
                } else {
                        Pt.x = X;
                        Pt.y = Y;
                }
                if (Flags & TA_CENTER) {
                        Pt.x-=(Size.cx/2);
                } else if (Flags & TA_RIGHT) {
                        Pt.x-=Size.cx;
                }
                if (Flags & TA_BASELINE) {
                        TEXTMETRICW tm;
                        GetTextMetricsW(DC, &tm);
                        Pt.y-=tm.tmAscent;
                } else if (Flags & TA_BOTTOM) {
                        Pt.y-=Size.cy;
                }
                LPtoDP(DC, &Pt, 1);
                RECT Rect;
                Rect.left = Pt.x;
                Rect.right = Pt.x + Size.cx;
                Rect.top = Pt.y;
                Rect.bottom = Pt.y + Size.cy;
                // Bug: We don't check Pt.y here, as don't call PtInRect() directly, because
                // in Title bar, Start Menu, IE, FireFox, Opera etc., the Rect.top and Rect.bottom will be wrong.
                // I try to use GetDCOrgEx(DC, &Pt), but they are not normal HDC that Pt.x and Pt.y will equal to 0 in these cases.
                // And use GetWindowRect() then get Rect.left and Rect.top is only useful on Title bar.
                if (((Rect.left <= Rect.right) && (CurParams->Pt.x >= Rect.left) && (CurParams->Pt.x <= Rect.right)) ||
                        ((Rect.left > Rect.right) && (CurParams->Pt.x <= Rect.left) && (CurParams->Pt.x >= Rect.right))) {
                //if (PtInRect(&Rect, CurParams->Pt)) {
                        CurParams->Active = !PtInRect(&Rect, CurParams->Pt);
                        //CurParams->Active = FALSE;
                        int BegPos = round(abs((CurParams->Pt.x - Rect.left) / (Rect.right - Rect.left)) * (Count - 1));
                        while ((BegPos < Count - 1) && GetTextExtentPoint32W(DC, Str, BegPos + 1, &Size) && (Size.cx < CurParams->Pt.x - Rect.left))
                                BegPos++;
                        while ((BegPos >= 0) && GetTextExtentPoint32W(DC, Str, BegPos + 1, &Size) && (Size.cx > CurParams->Pt.x - Rect.left))
                                BegPos--;
                        if (BegPos < Count - 1)
                                BegPos++;
                        CurParams->BeginPos = BegPos;
                        if (Count > 255)
                                CurParams->WordLen = 255;
                        else
                                CurParams->WordLen = Count;
                        CurParams->Unicode = TRUE;
                        CopyMemory(CurParams->MatchedWordW, Str, CurParams->WordLen * sizeof(wchar_t));
                }
        }
}

BOOL WINAPI TextOutACallbackProc(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString, int cbString)
{
        if (CurParams && CurParams->Active)
                IsInsidePointA(hdc, nXStart, nYStart, lpszString, cbString);
        return TextOutANextHook(hdc, nXStart, nYStart, lpszString, cbString);
}

BOOL WINAPI TextOutWCallbackProc(HDC hdc, int nXStart, int nYStart, LPCWSTR lpszString, int cbString)
{
        if (CurParams && CurParams->Active)
                IsInsidePointW(hdc, nXStart, nYStart, lpszString, cbString);
        return TextOutWNextHook(hdc, nXStart, nYStart, lpszString, cbString);
}

BOOL WINAPI ExtTextOutACallbackProc(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCSTR lpszString, UINT cbString, CONST INT *lpDx)
{
        if (CurParams && CurParams->Active)
                IsInsidePointA(hdc, nXStart, nYStart, lpszString, cbString);
        return ExtTextOutANextHook(hdc, nXStart, nYStart, fuOptions, lprc, lpszString, cbString, lpDx);
}

BOOL WINAPI ExtTextOutWCallbackProc(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpszString, UINT cbString, CONST INT *lpDx)
{
        if (CurParams && CurParams->Active)
                IsInsidePointW(hdc, nXStart, nYStart, lpszString, cbString);
        return ExtTextOutWNextHook(hdc, nXStart, nYStart, fuOptions, lprc, lpszString, cbString, lpDx);
}

static void InstallTextOutHooks()
{
        HookAPI("gdi32.dll", "TextOutA", (PROC)TextOutACallbackProc, (PROC*)&TextOutANextHook);
        HookAPI("gdi32.dll", "TextOutW", (PROC)TextOutWCallbackProc, (PROC*)&TextOutWNextHook);
        HookAPI("gdi32.dll", "ExtTextOutA", (PROC)ExtTextOutACallbackProc, (PROC*)&ExtTextOutANextHook);
        HookAPI("gdi32.dll", "ExtTextOutW", (PROC)ExtTextOutWCallbackProc, (PROC*)&ExtTextOutWNextHook);
}

static void UninstallTextOutHooks()
{
        if (TextOutANextHook)
                HookAPI("gdi32.dll", "TextOutA", (PROC)TextOutANextHook, NULL);
        if (TextOutWNextHook)
                HookAPI("gdi32.dll", "TextOutW", (PROC)TextOutWNextHook, NULL);
        if (ExtTextOutANextHook)
                HookAPI("gdi32.dll", "ExtTextOutA", (PROC)ExtTextOutANextHook, NULL);
        if (ExtTextOutWNextHook)
                HookAPI("gdi32.dll", "ExtTextOutW", (PROC)ExtTextOutWNextHook, NULL);
}

DLLIMPORT void GetWord (TCurrentMode *P)
{
        TCHAR wClassName;
        if (GetClassName(P->WND, wClassName, sizeof(wClassName) / sizeof(TCHAR))==0)
                wClassName = '\0';
        TKnownWndClass WndClass = GetWindowType(P->WND, wClassName);
        char *p = TryGetWordFromAnyWindow(WndClass, P->WND, P->Pt, &(P->BeginPos));
        if (p) {
          P->WordLen = strlen(p);
                strcpy(P->MatchedWord, p);
                free(p);
        } else {
                P->WordLen = 0;
        }
}


BOOL APIENTRY DllMain (HINSTANCE hInst   /* Library instance handle. */ ,
                     DWORD reason      /* Reason this function is being called. */ ,
                     LPVOID reserved   /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
                        //ThTypes_Init();
                        InstallTextOutHooks();
      break;

      case DLL_PROCESS_DETACH:
                        UninstallTextOutHooks();
                        //Thtypes_End();
      break;

      case DLL_THREAD_ATTACH:
      break;

      case DLL_THREAD_DETACH:
      break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
=============================

TextOutHook.h
=============================
#ifndef _TextOutHook_H_
#define _TextOutHook_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */

#include "ThTypes.h"

char* ExtractFromEverything(HWND WND, POINT Pt, int *BeginPos);

DLLIMPORT void GetWord (TCurrentMode *P);


#endif /* _TextOutHook_H_ */
=============================

GetWord.c
=============================
#include "GetWord.h"
#include "TextOutHook.h"

TKnownWndClass GetWindowType(HWND WND, const char* WNDClass)
{
        const char* StrKnownClasses[] = {
                "RICHEDIT20A",
                "RICHEDIT20W",
                "RICHEDIT",
                "EDIT",
                "INTERNET EXPLORER_SERVER",
                "CONSOLEWINDOWCLASS", // NT
                "TTYGRAB", // 9x
                };
        TKnownWndClass KnownClasses[] = {
                kwcRichEdit,
                kwcRichEdit,
                kwcRichEdit,
                kwcMultiLineEdit,
                kwcInternetExplorer_Server,
                kwcConsole,
                kwcConsole,
        };
        int i;
        for (i=0; i<7; i++) {
                if (strcasecmp(WNDClass, StrKnownClasses)==0)
                        break;
        }
        if (i<7) {
                if (KnownClasses == kwcMultiLineEdit) {
                        if ((GetWindowLong(WND, GWL_STYLE) & ES_MULTILINE) == 0)
                                return kwcSingleLineEdit;
                }
                return KnownClasses;
        } else
                return kwcUnknown;
}

static char* ExtractWordFromRichEditPos(HWND WND, POINT Pt, int *BeginPos)
{
        return ExtractFromEverything(WND, Pt, BeginPos);
}
/*
typedef struct TEditParams {
        HWND WND;
        POINT Pt;
        char Buffer;
} TEditParams;

static int ExtractWordFromEditPosPack(TEditParams *params)
{
        int Result = 0;
        int BegPos;
        BegPos = SendMessage(params->WND, EM_CHARFROMPOS, 0, params->Pt.x | params->Pt.y << 16);
        if (BegPos == -1)
                return Result;
        int MaxLength;
        MaxLength = SendMessage(params->WND, EM_LINELENGTH, BegPos & 0xFFFF, 0);
        if (MaxLength <= 0)
                return Result;
        char *Buf;
        Buf = GlobalAlloc(GMEM_FIXED, MaxLength + 1);
        if (Buf) {
                *Buf = MaxLength;
                MaxLength = SendMessage(params->WND, EM_GETLINE, BegPos >> 16, (int)Buf);
                Buf = '\0';
                BegPos = (BegPos & 0xFFFF) - SendMessage(params->WND, EM_LINEINDEX, BegPos >> 16, 0) - 1;
                int EndPos;
                EndPos = BegPos;
                while ((BegPos >= 0) && IsCharAlpha(Buf))
                        BegPos--;
                while ((EndPos < MaxLength) && IsCharAlpha(Buf))
                        EndPos++;
                MaxLength = EndPos - BegPos - 1;
                if (MaxLength >= 0) {
                        if (255 >= MaxLength) {
                                Buf = '\0';
                                lstrcpy(params->Buffer, Buf + BegPos + 1);
                                Result = MaxLength;
                        }
                }
                GlobalFree(Buf);
        }
        return Result;
}
*/
static char* ExtractWordFromEditPos(HWND hEdit, POINT Pt, int *BeginPos)
{
        return ExtractFromEverything(hEdit, Pt, BeginPos);
/*        TEditParams *TP;
        TP = malloc(sizeof(TEditParams));
        TP->WND = hEdit;
        TP->Pt = Pt;
        TP->Buffer = '\0';
        ScreenToClient(hEdit, &(TP->Pt));
        int MaxLength;
        MaxLength = ExtractWordFromEditPosPack(TP);
        char *Result;
        if (MaxLength>0) {
                Result = strdup(TP->Buffer);
        } else {
                Result = NULL;
        }
        free(TP);
        return Result;
*/
}

static char* ExtractWordFromIE(HWND WND, POINT Pt, int *BeginPos)
{       
        return ExtractFromEverything(WND, Pt, BeginPos);
}

typedef struct TConsoleParams {
        HWND WND;
        POINT Pt;
        RECT ClientRect;
        char Buffer;
} TConsoleParams;

static int GetWordFromConsolePack(TConsoleParams *params)
{
        HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hStdOut != INVALID_HANDLE_VALUE) {
                CONSOLE_SCREEN_BUFFER_INFO csbi;
                if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {
                        COORD CurPos;
                        CurPos.X = csbi.srWindow.Left + params->Pt.x * (csbi.srWindow.Right - csbi.srWindow.Left + 1) / params->ClientRect.right;
                        CurPos.Y = csbi.srWindow.Top + params->Pt.y * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1) / params->ClientRect.bottom;
                        if ((CurPos.X >= 0) && (CurPos.X <= csbi.dwSize.X - 1) && (CurPos.Y >= 0) && (CurPos.Y <= csbi.dwSize.Y - 1)) {
                                int BegPos;
                                BegPos = CurPos.X;
                                CurPos.X = 0;
                                char *Buf = GlobalAlloc(GMEM_FIXED, csbi.dwSize.X + 1);
                                if (Buf) {
                                        DWORD ActualRead;
                                        if ((ReadConsoleOutputCharacter(hStdOut, Buf, csbi.dwSize.X, CurPos, &ActualRead)) && (ActualRead == csbi.dwSize.X)) {
                                                OemToCharBuff(Buf, Buf, csbi.dwSize.X);
                                                int WordLen;
                                                if (csbi.dwSize.X > 255)
                                                        WordLen = 255;
                                                else
                                                        WordLen = csbi.dwSize.X;
                                                strncpy(params->Buffer, Buf, WordLen);
                                                GlobalFree(Buf);
                                                return WordLen;
                                        }
                                }
                        }
                }
        }
        return 0;
}
static void GetWordFromConsolePackEnd() {}

static BOOL RemoteExecute(HANDLE hProcess, void *RemoteThread, DWORD RemoteSize, void *Data, int DataSize, DWORD *dwReturn)
{
        void *pRemoteThread = VirtualAllocEx(hProcess, NULL, RemoteSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (!pRemoteThread)
                return FALSE;
        if (!WriteProcessMemory(hProcess, pRemoteThread, RemoteThread, RemoteSize, 0)) {
                VirtualFreeEx(hProcess, pRemoteThread, RemoteSize, MEM_RELEASE);
                return FALSE;
        }
        void *pData = VirtualAllocEx(hProcess, NULL, DataSize, MEM_COMMIT, PAGE_READWRITE);
        if (!pData) {
                VirtualFreeEx(hProcess, pRemoteThread, RemoteSize, MEM_RELEASE);
                return FALSE;
        }
        if (!WriteProcessMemory(hProcess, pData, Data, DataSize, 0)) {
                VirtualFreeEx(hProcess, pRemoteThread, RemoteSize, MEM_RELEASE);
                VirtualFreeEx(hProcess, pData, DataSize, MEM_RELEASE);
                return FALSE;
        }
        // Bug: I don't know why the next line will fail in Windows XP, so get word from cmd.exe can't work presently.
        HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, pData, 0, 0);
        WaitForSingleObject(hThread, INFINITE);
        GetExitCodeThread(hThread, dwReturn);
        ReadProcessMemory(hProcess, pData, Data, DataSize, 0);
        VirtualFreeEx(hProcess, pRemoteThread, RemoteSize, MEM_RELEASE);
        VirtualFreeEx(hProcess, pData, DataSize, MEM_RELEASE);
        if (hThread) {
                CloseHandle(hThread);
                return TRUE;
        } else {
                return FALSE;
        }
}

static char* GetWordFromConsole(HWND WND, POINT Pt, int *BeginPos)
{
        TConsoleParams *TP;
        TP = malloc(sizeof(TConsoleParams));
        TP->WND = WND;
        TP->Pt = Pt;
        ScreenToClient(WND, &(TP->Pt));
        GetClientRect(WND, &(TP->ClientRect));
        DWORD pid;
        GetWindowThreadProcessId(GetParent(WND), &pid);
        DWORD MaxWordSize;
        if (pid != GetCurrentProcessId()) {
                // The next line will fail in Win2k, but OK in Windows XP.
                HANDLE ph = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);
                if (ph) {
                        if (!RemoteExecute(ph, GetWordFromConsolePack, (DWORD)GetWordFromConsolePackEnd - (DWORD)GetWordFromConsolePack, TP, sizeof(TConsoleParams), &MaxWordSize))
                                MaxWordSize = 0;
                        CloseHandle(ph);
                }
        } else {
                MaxWordSize = GetWordFromConsolePack(TP);
        }
        char *Result;
        if (MaxWordSize > 0) {
                Result = strdup(TP->Buffer);
        } else {
                Result = NULL;
        }
        free(TP);
        return Result;
}

char* TryGetWordFromAnyWindow(TKnownWndClass WndType, HWND WND, POINT Pt, int *BeginPos)
{
        typedef char* (*GetWordFunction_t)(HWND, POINT, int*);
        const GetWordFunction_t GetWordFunction[]= {
                ExtractFromEverything,
                ExtractWordFromRichEditPos,
                ExtractWordFromEditPos,
                ExtractWordFromEditPos,
                ExtractWordFromIE,
                GetWordFromConsole,
        };
        return GetWordFunction(WND, Pt, BeginPos);
}
=============================

GetWord.h
=============================
#ifndef _GetWord_H_
#define _GetWord_H_

#include <windows.h>

typedef enum TKnownWndClass {
        kwcUnknown,
        kwcRichEdit,
        kwcMultiLineEdit,
        kwcSingleLineEdit,
        kwcInternetExplorer_Server,
        kwcConsole,
} TKnownWndClass;

TKnownWndClass GetWindowType(HWND WND, const char* WNDClass);
char* TryGetWordFromAnyWindow(TKnownWndClass WndType, HWND WND, POINT Pt, int *BeginPos);

#endif
=============================

HookImportFunction.c
=============================
#include "HookImportFunction.h"
#include<tlhelp32.h>


// These code come from: http://dev.csdn.net/article/2/2786.shtm
// I fixed a bug in it and improved it to hook all the modules of a program.

#define MakePtr(cast, ptr, AddValue) (cast)((DWORD)(ptr)+(DWORD)(AddValue))

static PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule)
{
        if ((szImportModule == NULL) || (hModule == NULL))
                return NULL;
        PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER) hModule;
        if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) || (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)) {
                return NULL;
        }
        PIMAGE_NT_HEADERS pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);
        if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) || (pNTHeader->Signature != IMAGE_NT_SIGNATURE))
                return NULL;
        if (pNTHeader->OptionalHeader.DataDirectory.VirtualAddress == 0)
                return NULL;
        PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader, pNTHeader->OptionalHeader.DataDirectory.VirtualAddress);
        while (pImportDesc->Name) {
                PSTR szCurrMod = MakePtr(PSTR, pDOSHeader, pImportDesc->Name);
                if (stricmp(szCurrMod, szImportModule) == 0)
                        break;
                pImportDesc++;
        }
        if (pImportDesc->Name == (DWORD)0)
                return NULL;
        return pImportDesc;
}

static BOOL IsNT()
{
        OSVERSIONINFO stOSVI;
        memset(&stOSVI, 0, sizeof(OSVERSIONINFO));
        stOSVI.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        BOOL bRet = GetVersionEx(&stOSVI);
        if (FALSE == bRet) return FALSE;
        return (VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId);
}

static BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule, LPCSTR szFunc, PROC paHookFuncs, PROC* paOrigFuncs)
{
        if (!IsNT() && ((DWORD)hModule >= 0x80000000))
                return FALSE;
        PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetNamedImportDescriptor(hModule, szImportModule);
        if (pImportDesc == NULL)
                return FALSE;
        PIMAGE_THUNK_DATA pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->OriginalFirstThunk);
        PIMAGE_THUNK_DATA pRealThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);
        while (pOrigThunk->u1.Function) {
                if (IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)) {
                        PIMAGE_IMPORT_BY_NAME pByName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pOrigThunk->u1.AddressOfData);
                        // When hook EditPlus, read pByName->Name will case this dll terminate, so call IsBadReadPtr() here.
                        if (IsBadReadPtr(pByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
                                pOrigThunk++;
                                pRealThunk++;
                                continue;                               
                        }
                        if ('\0' == pByName->Name) {
                                pOrigThunk++;
                                pRealThunk++;
                                continue;
                        }
                        BOOL bDoHook = FALSE;
                        if ((szFunc == pByName->Name) && (strcmpi(szFunc, (char*)pByName->Name) == 0)) {
                                if (paHookFuncs)
                                        bDoHook = TRUE;
                        }
                        if (bDoHook) {
                                MEMORY_BASIC_INFORMATION mbi_thunk;
                                VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
                                VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
                                if (paOrigFuncs)
                                        *paOrigFuncs = (PROC)pRealThunk->u1.Function;
                                pRealThunk->u1.Function = (DWORD)paHookFuncs;
                                DWORD dwOldProtect;
                                VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect);
                                return TRUE;
                        }
                }
                pOrigThunk++;
                pRealThunk++;
        }
        return FALSE;
}

BOOL HookAPI(LPCSTR szImportModule, LPCSTR szFunc, PROC paHookFuncs, PROC* paOrigFuncs)
{
        if ((szImportModule == NULL) || (szFunc == NULL)) {
                return FALSE;
        }
        HANDLE hSnapshot;
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
        MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
        BOOL bOk = Module32First(hSnapshot,&me);
        while (bOk) {
                HookImportFunction(me.hModule, szImportModule, szFunc, paHookFuncs, paOrigFuncs);
                bOk = Module32Next(hSnapshot,&me);
        }
        return TRUE;
}
=============================

HookImportFunction.h
=============================
#ifndef _HookImportFunction_H_
#define _HookImportFunction_H_

#include <windows.h>


BOOL HookAPI(LPCSTR szImportModule, LPCSTR szFunc, PROC paHookFuncs, PROC* paOrigFuncs);

#endif
=============================

mouseover.c
=============================
/*
* This file part of StarDict - A international dictionary for GNOME.
* http://stardict.sourceforge.net
*
* Copyright (C) 2006 Hu Zheng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "../stardict.h"
#include "../conf.h"
#include <glib/gi18n.h>

#include "mouseover.h"
#include "ThTypes.h"

// StarDict's Mouseover feature get the example delphi source code from Mueller Electronic Dicionary.
// Homepage: http://vertal1.narod.ru/mueldic.html E-mail: svv_soft@mail.ru

const int WM_MY_SHOW_TRANSLATION = WM_USER + 300;

void Mouseover::NeedSpyDll()
{
        if (fSpyDLL == 0) {
                fSpyDLL = LoadLibrary((gStarDictDataDir+G_DIR_SEPARATOR+"TextOutSpy.dll").c_str());
                if (fSpyDLL==0) {
                        fSpyDLL = (HINSTANCE)-1;
                } else {
                        ActivateSpy_func = (ActivateSpy_func_t)GetProcAddress(fSpyDLL, "ActivateTextOutSpying");
                }
        }
}

HWND Mouseover::Create_hiddenwin()
{
        WNDCLASSEX wcex;
        TCHAR wname;

        strcpy(wname, "StarDictMouseover");

        wcex.cbSize = sizeof(WNDCLASSEX);

        wcex.style                = 0;
        wcex.lpfnWndProc        = (WNDPROC)mouseover_mainmsg_handler;
        wcex.cbClsExtra                = 0;
        wcex.cbWndExtra                = 0;
        wcex.hInstance                = stardictexe_hInstance;
        wcex.hIcon                = NULL;
        wcex.hCursor                = NULL,
        wcex.hbrBackground        = NULL;
        wcex.lpszMenuName        = NULL;
        wcex.lpszClassName        = wname;
        wcex.hIconSm                = NULL;

        RegisterClassEx(&wcex);

        // Create the window
        return (CreateWindow(wname, "", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, stardictexe_hInstance, 0));
}

void Mouseover::ShowTranslation()
{
        if (bIsPureEnglish(GlobalData->CurMod.MatchedWord)) {
                gpAppFrame->SmartLookupToFloat(GlobalData->CurMod.MatchedWord, GlobalData->CurMod.BeginPos, true);
    } else {
                char *str1 = g_locale_to_utf8(GlobalData->CurMod.MatchedWord, GlobalData->CurMod.BeginPos, NULL, NULL, NULL);
                char *str2 = g_locale_to_utf8(GlobalData->CurMod.MatchedWord + GlobalData->CurMod.BeginPos, GlobalData->CurMod.WordLen - GlobalData->CurMod.BeginPos, NULL, NULL, NULL);
                GlobalData->CurMod.BeginPos = strlen(str1);
                char *str = g_strdup_printf("%s%s", str1, str2);
                g_free(str1);
                g_free(str2);
                gpAppFrame->SmartLookupToFloat(str, GlobalData->CurMod.BeginPos, true);
                g_free(str);
        }
}

LRESULT CALLBACK Mouseover::mouseover_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
        switch (msg) {
                case WM_MY_SHOW_TRANSLATION:
                        ShowTranslation();
                        break;
                default:
                        /*nothing*/;
        }

        return DefWindowProc(hwnd, msg, wparam, lparam);
}

Mouseover::Mouseover()
{
        fSpyDLL = 0;
        ActivateSpy_func = NULL;
}

void Mouseover::Init()
{
        ThTypes_Init();
        ZeroMemory(GlobalData, sizeof(TGlobalDLLData));
        strcpy(GlobalData->LibName, (gStarDictDataDir+G_DIR_SEPARATOR+"TextOutHook.dll").c_str());
        GlobalData->ServerWND = Create_hiddenwin();
}

void Mouseover::End()
{
        if ((fSpyDLL!=0)&&(fSpyDLL!=(HINSTANCE)-1)) {
                stop();
                FreeLibrary(fSpyDLL);
        }
        DestroyWindow(GlobalData->ServerWND);
        Thtypes_End();
}

void Mouseover::start()
{
        NeedSpyDll();
        if (ActivateSpy_func)
                ActivateSpy_func(true);
}

void Mouseover::stop()
{
        if (ActivateSpy_func)
                ActivateSpy_func(false);
}
=============================

mouseover.h
=============================
#ifndef __SD_MOUSEOVER_H__
#define __SD_MOUSEOVER_H__


#include <windows.h>

class Mouseover
{
private:
        typedef void (*ActivateSpy_func_t)(bool);
        ActivateSpy_func_t ActivateSpy_func;
        HINSTANCEfSpyDLL;
        void NeedSpyDll();
        HWND Create_hiddenwin();
        static void ShowTranslation();
        static LRESULT CALLBACK mouseover_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

public:
        Mouseover();
        void Init();
        void End();
        void start();
        void stop();
};

#endif
=============================

stardict.cpp
=============================
bool AppCore::SmartLookupToFloat(const gchar* sWord, int BeginPos, bool bShowIfNotFound)
{
        if (sWord==NULL || sWord=='\0')
                return true;
        char *SearchWord = g_strdup(sWord);
        char *P1 = SearchWord + BeginPos;
        P1 = g_utf8_next_char(P1);
        while (*P1 && !g_unichar_isspace(g_utf8_get_char(P1)))
                P1 = g_utf8_next_char(P1);
        *P1='\0';
        P1 = SearchWord + BeginPos;
        if (BeginPos) {
                if (g_unichar_isspace(g_utf8_get_char(P1)))
                        P1 = g_utf8_prev_char(P1);
                while (P1>SearchWord && !g_unichar_isspace(g_utf8_get_char(g_utf8_prev_char(P1))))
                        P1 = g_utf8_prev_char(P1);
        }

        const gchar **ppWord = (const gchar **)g_malloc(sizeof(gchar *) * oLibs.ndicts());
        gchar **ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.ndicts());
       
        int SearchTimes = 2;
        while (SearchTimes) {
                glong iIndex;
                bool bFound = false;
                for (int iLib=0;iLibSearchWord && isascii(*(P3-1)) && g_ascii_isupper(*(P3-1)))
                                                        P3--;
                                        } else if (g_ascii_islower(*P2)){
                                                P2++;
                                                while (*P2 && g_ascii_islower(*P2))
                                                        P2++;
                                        }
                                        if (*P2) {
                                                *P2='\0';
                                        } else {
                                                if (P3==P1)
                                                        break;
                                        }
                                        P1=P3;
                                } else {
                                        while (P3>SearchWord && isascii(*(P3-1)) && g_ascii_isupper(*(P3-1)))
                                                P3--;
                                        if (P3==P1)
                                                break;
                                }
                        } else if (g_ascii_islower(*P2)) {
                                char *P3 = SearchWord + BeginPos;
                                while (P3>SearchWord && isascii(*(P3-1)) && g_ascii_islower(*(P3-1)))
                                        P3--;
                                if (P3>SearchWord && isascii(*(P3-1)) && g_ascii_isupper(*(P3-1)))
                                        P3--;
                                P2++;
                                while (*P2 && g_ascii_islower(*P2))
                                        P2++;
                                if (*P2) {
                                        *P2='\0';
                                } else {
                                        if (P3==P1)
                                                break;
                                }
                                P1=P3;
                        } else {
                                break;
                        }
                } else {
                        if (P1==SearchWord + BeginPos) {
                                char *EndPointer=P1+strlen(P1);
                                EndPointer = g_utf8_prev_char(EndPointer);
                                if (EndPointer!=P1) {
                                        *EndPointer='\0';
                                        SearchTimes = 2;
                                }
                                else {
                                        break;
                                }
                        } else {
                                P1 = SearchWord + BeginPos;
                                SearchTimes = 2;
                        }
                }
        }
        g_free(ppWord);
        g_free(ppWordData);
       
        // not found
        if (bShowIfNotFound) {
                ShowNotFoundToFloatWin(P1,_(""), false);
                oTopWin.InsertHisList(P1); //really need?
        }
        g_free(SearchWord);
        return false;       
}
=========================

link369 发表于 2010-8-23 22:27:59

留个脚印,研究下楼上的

pusofalse 发表于 2010-8-23 23:59:08

本帖最后由 pusofalse 于 2010-9-2 17:15 编辑

我来发个纯au3的。把鼠标移动到词的位置,然后按F3,会在edit中显示出来。#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Thread.au3>

HotKeySet("{f3}", "_HookEvent")

Global $sText

Const $pExtTextOutW = _RTGetProcAddress("Gdi32.dll", "ExtTextOutW")
Const $pSendMessageW = _RTGetProcAddress("User32.dll", "SendMessageW")

$hGUI = GUICreate("Test", 400, 300)
GUICtrlCreateEdit("", 10, 10, 380, 280)

Local $iPid, $hProcess, $pCallAddr, $bEntrypoint, $bCode

$iPid = ProcessExists("explorer.exe")
$hProcess = _RTOpenProcess($iPid)

_RTVirtualProtectEx($hProcess, $pExtTextOutW, 8)
$bEntrypoint = _RTReadProcessMemory($hProcess, $pExtTextOutW, 0, 8, "binary")
$bEntrypoint = StringTrimLeft($bEntrypoint, 2)

$pCallAddr = _RTVirtualAllocEx($hProcess, 1024)
$bJump = "0xB8" & _RTLongPtrToBytes($pCallAddr) & "FFE000"

$bCode = "0x" & _
        "55" & _
        "8BEC" & _
        "833D" & _RTLongPtrToBytes($pCallAddr + 1020) & "00" & _        ; cmp dword ptr , 0
        "74" & Hex(37, 2) & _                        ; jz $d+37
        "837D2000" & _                                ; cmp dword ptr
        "74" & Hex(31, 2) & _                        ; jz $d+31
        "8B451C" & _                                ; mov eax, dword ptr
        "803803" & _                                ; cmp byte ptr , 3
        "74" & Hex(23, 2) & _                        ; jz $d+23
        "FF751C" & _
        "FF7520" & _
        "68" & _RTUlongToBytes(0x3F77) & _
        "68" & _RTLongPtrToBytes($hGUI) & _
        "B8" & _RTLongPtrToBytes($pSendMessageW) & _
        "FFD0" & _
        "FF7524" & _
        "FF7520" & _
        "FF751C" & _
        "FF7518" & _
        "FF7514" & _
        "FF7510" & _
        "FF750C" & _
        "FF7508" & _
        "C705" & _RTLongPtrToBytes($pExtTextOutW + 0) & StringMid($bEntrypoint, 1, 8) & _
        "C705" & _RTLongPtrToBytes($pExtTextOutW + 4) & StringMid($bEntrypoint, 9, 8) & _
        "B8" & _RTLongPtrToBytes($pExtTextOutW) & _
        "FFD0" & _
        "C705" & _RTLongPtrToBytes($pExtTextOutW + 0) & StringMid($bJump, 3, 8) & _
        "C705" & _RTLongPtrToBytes($pExtTextOutW + 4) & StringMid($bJump, 11, 8) & _
        "5D" & _
        "C22000"

_RTWriteProcessMemory($hProcess, $pCallAddr, $bCode, BinaryLen($bCode), "binary")
_RTWriteProcessMemory($hProcess, $pExtTextOutW, $bJump, 8, "binary")

GUISetState()
GUIRegisterMsg(0x3F77, "_HookCallBack")

_RTCloseHandle(_RTEmptyWorkingSet())

While GUIGetMsg() <> -3
WEnd
_RTWriteProcessMemory($hProcess, $pExtTextOutW, "0x" & $bEntrypoint, 8, "binary")
_RTVirtualFreeEx($hProcess, $pCallAddr, 1024)
_RTCloseHandle($hProcess)

Func _HookCallBack($hWnd, $iMsg, $iLength, $pBuffer)
        $iLength = Number($iLength) + 1
        $pBuffer = Ptr($pBuffer)

        Local $sSubText = _RTReadProcessMemory($hProcess, $pBuffer, 0, $iLength * 256, "wstr")
        If ($sSubText) And (Not StringInStr($sText, $sSubText, 1)) Then $sText &= $sSubText & @CRLF

EndFunc        ;==>_HookCallBack

Func _HookEvent()
        Local $aXY, $hWnd, $tXY, $tRect, $hWnd1

        $aXY = MouseGetPos()
        $tXY = DllStructCreate("long X;long Y")
        DllStructSetData($tXY, "X", $aXY)
        DllStructSetData($tXY, "Y", $aXY)

        $hWnd = _WinAPI_WindowFromPoint($tXY)

        _WinAPI_ScreenToClient($hWnd, $tXY)

        $aXY = DllStructGetData($tXY, "X")
        $aXY = DllStructGetData($tXY, "Y")

        $tRect = DllStructCreate($tagRECT)
        DllStructSetData($tRect, "Left", $aXY - 1)
        DllStructSetData($tRect, "Top", $aXY - 1)
        DllStructSetData($tRect, "Right", $aXY)
        DllStructSetData($tRect, "Bottom", $aXY)

        $sText = ""
        _RTWriteProcessMemory($hProcess, $pCallAddr + 1020, 1, 4, "int*")
        _WinAPI_RedrawWindow($hWnd, $tRect, 0, 0x381)
        _RTWriteProcessMemory($hProcess, $pCallAddr + 1020, 0, 4, "int*")

        If ($sText) Then GUICtrlSetData(3, $sText & @CRLF, 1)
EndFunc        ;==>_HookEvent在XP SP3英文系统中测试成功,但可能仍旧有BUG。只能截取explorer.exe所属的窗口。

xjdjpbp 发表于 2010-8-24 00:21:28

回复 8# pusofalse

那個附件貌似多線程的函式@@?

還是......

(積分不足)
{:1_428:}

gto250 发表于 2010-8-24 21:52:24

P版
我用你的代码在win7下使用,只能取桌面上快捷方式的词,而且还是乱码
在打开的文件中取词就不能成功
我取的词就是 “新建 Microsoft Excel 工作表.xls”

pusofalse 发表于 2010-8-24 22:24:01

回复 11# gto250


    又是Win7,OMG - -|||

我写的代码好像大多数都不支持Win7,这的确挺让我郁闷的。
我一直在用XP SP3,Win7系统好像改造了很多啊,按说应该兼容才对。
对此,我很遗憾地表示我无能为力,可能等我用上Win7之后就能够解决这类的问题了。
感谢gto250兄的测试。

rolaka 发表于 2010-8-24 23:18:24

回复gto250


    又是Win7,OMG - -|||

我写的代码好像大多数都不支持Win7,这的确挺让我郁闷的。 ...
pusofalse 发表于 2010-8-24 22:24 http://www.autoitx.com/images/common/back.gif

p版 不知道"划词翻译"(选中后按快捷键取词) 怎么实现好...

wsycharles0o 发表于 2010-8-25 16:35:26

本帖最后由 wsycharles0o 于 2010-8-25 16:41 编辑

楼上的!俺有方法!!!
莫哈哈~
前两天密保盗Q时用到的技巧今天发出来:
F3 取词,F4输出,F5退出
先用F3一个个取词,找个笔记本按F4输出
方法简单:Global $WORDS,$W=0,$CLIP,$i=0

HotKeySet("{F7}","WORD()")
HotKeySet("{F8}","PRINT()")
HotKeySet("{F9}","quit()")

While 1
        Sleep(2000)
WEnd


Func quit()
                Exit 0
EndFunc
Func WORD()
                $CLIP=ClipGet()
                Send("{ctrldown}c{ctrlup}")
                $WORDS = ClipGet()
                ClipPut($CLIP)
                $W=$W+1
EndFunc

Func PRINT()
                While $i <= $W
                        Send(($i+1)&". "&$WORDS[$i]&@CRLF)
                        $i=$i+1
                WEnd
EndFunc

gto250 发表于 2010-9-5 09:13:27

$iPid = ProcessExists("explorer.exe")
$hProcess = _RTOpenProcess($iPid)

我把$pid的取得换成ie的,只要是IE界面上的文字都能取得,但是网页中flash中的文字就不能取得

mxsau3 发表于 2010-9-5 09:23:01

这么强大。
页: [1] 2
查看完整版本: AU3能否做出像金山词霸那样取词功能