Link to home
Start Free TrialLog in
Avatar of eaka
eaka

asked on

How to getting text in any point on desktop ?

I want source code.

1. How to uses DDIHook on Delphi ?
2. How to patch export table GDI32.DLL on Delphi ?

Avatar of eaka
eaka

ASKER

All problems use in Win9x
Yep, SetDDIHook is the way to go. Here comes some help. Credits go to Mike Lischke, all the content of this comment of mine is shamelessly stolen from him...   :-)

"I managed to hook GDI under Win9x. It requires a 16 bit DLL however. The keyfunction is

DDI := SetDDIHook(0, HInstance, nil, DDIHOOK_RECORDER, DDIHookProc);

// --------------------------------------------------------------------------
//
//  WINDDI.H
//
//  Hooking mechanism to see all screen output.
//
//  NOTE:  You must include GDIDEFS.INC from the DDK to get the definitions
//  of the structures used in this file.
//
// --------------------------------------------------------------------------

#ifndef _WINDDI_
#define _WINDDI_

#if !defined(_WINDDI_)
#define WINDDIAPI   DECLSPEC_IMPORT
#else
#define WINDDIAPI
#endif

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


//
// Forward declarations of structures passed as various DDI parameters
//

typedef struct tagPDEVICE FAR*      LPPDEVICE;
typedef struct tagDRAWESCAPE FAR*   LPDRAWESCAPE;
typedef struct tagDISPVALMODE FAR*  LPDISPVALMODE;
typedef struct tagCOLORINFO FAR*    LPCOLORINFO;
typedef struct tagPPEN FAR*         LPPPEN;
typedef struct tagPBRUSH FAR*       LPPBRUSH;
typedef struct tagFONTINFO FAR*     LPFONTINFO;
typedef struct tagTEXTXFORM FAR*    LPTEXTXFORM;
typedef struct tagDEVMODE FAR*      LPDEVMODE;


typedef struct tagDDI FAR* HDDI;

//
// Classes of DDI hooks
//
#define DDIHOOK_MIN             0x0000
#define DDIHOOK_RECORDER        0x0001
#define DDIHOOK_REMOTE          0x0002
#define DDIHOOK_FONTS           0x0003
#define DDIHOOK_MAGNIFIER       0x0004
#define DDIHOOK_MAX             0x0005

//
// DDIs
//
typedef UINT    DDITYPE;
typedef LPVOID  LPDDIPARAMS;

typedef DWORD (CALLBACK* DDIHOOKPROC)(HDDI, LONG, DDITYPE, LPDDIPARAMS);


WINDDIAPI
HDDI
WINAPI
SetDDIHook(
    HDC         hdcHook,
    HMODULE     hModCode,
    LONG        lPrivateData,
    UINT        hookClass,
    DDIHOOKPROC lpfnDdiHook
);


WINDDIAPI
BOOL
WINAPI
UnhookDDIHook(
    HDDI        hddi
);


WINDDIAPI
DWORD
WINAPI
CallNextDDI(
    HDDI            hddi,
    DDITYPE         ddiType,
    LPDDIPARAMS     lpDdiParams
);


//
// The DDIs you can hook currently:
//
#define DDI_BITBLT              0x0000
typedef struct tagBITBLT_DDIPARAMS
{
    LPDRAWMODE      lpDrawMode;
    LPPBRUSH        lpPBrush;
    DWORD           dwRop;
    int             cySrc;
    int             cxSrc;
    int             ySrc;
    int             xSrc;
    LPPDEVICE       lpDevSrc;
    int             yDst;
    int             xDst;
    LPPDEVICE       lpDevDst;
}
BITBLT_DDIPARAMS, FAR* LPBITBLT_DDIPARAMS;


#define DDI_COLORINFO           0x0001
typedef struct tagCOLORINFO_DDIPARAMS
{
    LPVOID          lpPhysBits;
    DWORD           rgbColor;
    LPPDEVICE       lpDev;
}
COLORINFO_DDIPARAMS, FAR* LPCOLORINFO_DDIPARAMS;


#define DDI_CONTROL             0x0002
typedef struct tagCONTROL_DDIPARAMS
{
    LPVOID          lpOutData;
    LPVOID          lpInData;
    UINT            uCode;
    LPPDEVICE       lpDev;
}
CONTROL_DDIPARAMS, FAR* LPCONTROL_DDIPARAMS;


#define DDI_DISABLE             0x0003
typedef struct tagDISABLE_DDIPARAMS
{
    LPPDEVICE       lpDev;
}
DISABLE_DDIPARAMS, FAR* LPDISABLE_DDIPARAMS;


#define DDI_ENABLE              0x0004
typedef struct tagENABLE_DDIPARAMS
{
    LPVOID          lpDriverInfo;
    LPSTR           lpOutputFile;
    LPSTR           lpDeviceType;
    UINT            uStyle;
    LPPDEVICE       lpDev;
}
ENABLE_DDIPARAMS, FAR* LPENABLE_DDIPARAMS;


#define DDI_ENUMDEVICEFONTS     0x0005
typedef struct tagENUMDEVICEFONTS_DDIPARAMS
{
    LPVOID          lpClientData;
    FARPROC         lpfnCallback;
    LPSTR           lpszFaceName;
    LPPDEVICE       lpDev;
}
ENUMDEVICEFONTS_DDIPARAMS, FAR* LPENUMDEVICEFONTS_DDIPARAMS;


#define DDI_ENUMOBJECTS         0x0006
typedef struct tagENUMOBJECTS_DDIPARAMS
{
    LPVOID          lpClientData;
    FARPROC         lpfnCallback;
    UINT            uStyle;
    LPPDEVICE       lpDev;
}
ENUMOBJECTS_DDIPARAMS, FAR* LPENUMOBJECTS_DDIPARAMS;


#define DDI_OUTPUT              0x0007
typedef struct tagOUTPUT_DDIPARAMS
{
    LPRECT          lprcClip;
    LPDRAWMODE      lpDrawMode;
    LPPBRUSH        lpBrush;
    LPPPEN          lpPen;
    LPPOINT         lpPoints;
    UINT            uPointCount;
    UINT            uStyle;
    LPPDEVICE       lpDev;
}
OUTPUT_DDIPARAMS, FAR* LPOUTPUT_DDIPARAMS;


#define DDI_PIXEL               0x0008
typedef struct tagPIXEL_DDIPARAMS
{
    LPDRAWMODE      lpDrawMode;
    DWORD           rgbColor;
    int             y;
    int             x;
    LPPDEVICE       lpDev;
}
PIXEL_DDIPARAMS, FAR* LPPIXEL_DDIPARAMS;


#define DDI_REALIZEOBJECT       0x0009
typedef struct tagREALIZEOBJECT_DDIPARAMS
{
    LPTEXTXFORM     lpTextTransform;
    LPVOID          lpOutObject;
    LPVOID          lpInObject;
    UINT            uObjectId;
    LPPDEVICE       lpDev;
}
REALIZEOBJECT_DDIPARAMS, FAR* LPREALIZEOBJECT_DDIPARAMS;


#define DDI_STRINGBLT           0x000A
typedef struct tagSTRINGBLT_DDIPARAMS
{
    LPTEXTXFORM     lpTextTransform;
    LPDRAWMODE      lpDrawMode;
    LPFONTINFO      lpFont;
    UINT            cchText;
    LPSTR           lpszText;
    LPRECT          lprcClip;
    int             yStart;
    int             xStart;
    LPPDEVICE       lpDev;
}
STRINGBLT_DDIPARAMS, FAR* LPSTRINGBLT_DDIPARAMS;


#define DDI_SCANLEFTRIGHT       0x000B
typedef struct taSCANLEFTRIGHT_DDIPARAMS
{
    UINT            uStyle;
    DWORD           rgbSearch;
    int             yStart;
    int             xStart;
    LPPDEVICE       lpDev;
}
SCANLEFTRIGHT_DDIPARAMS, FAR* LPSCANLEFTRIGHT_DDIPARAMS;


#define DDI_DEVICEMODE          0x000C
typedef struct tagDEVICEMODE_DDIPARAMS
{
    LPSTR           lpFileName;
    LPSTR           lpDeviceName;
    HMODULE         hmod;
    HWND            hwnd;
}
DEVICEMODE_DDIPARAMS, FAR* LPDEVICEMODE_DDIPARAMS;


#define DDI_EXTTEXTOUT          0x000D
typedef struct tagEXTTEXTOUT_DDIPARAMS
{
    UINT            uOptions;
    LPRECT          lprcOpaque;
    LPINT           lpCharWidths;
    LPTEXTXFORM     lpTextTransform;
    LPDRAWMODE      lpDrawMode;
    LPFONTINFO      lpFont;
    int             cchText;
    LPSTR           lpszText;
    LPRECT          lprcClip;
    int             yStart;
    int             xStart;
    LPPDEVICE       lpDev;
}
EXTTEXTOUT_DDIPARAMS, FAR* LPEXTTEXTOUT_DDIPARAMS;


#define DDI_GETCHARWIDTH        0x000E
typedef struct tagGETCHARWIDTH_DDIPARAMS
{
    LPTEXTXFORM     lpTextTransform;
    LPDRAWMODE      lpDrawMode;
    LPFONTINFO      lpFont;
    UINT            ichLast;
    UINT            ichFirst;
    LPVOID          lpWidths;
    LPPDEVICE       lpDev;
}
GETCHARWIDTH_DDIPARAMS, FAR* LPGETCHARWIDTH_DDIPARAMS;


#define DDI_DEVICEBITMAP        0x000F
typedef struct tagDEVICEBITMAP_DDIPARAMS
{
    LPVOID          lpBits;
    LPVOID          lpBitmap;
    UINT            uCommand;
    LPPDEVICE       lpDev;
}
DEVICEBITMAP_DDIPARAMS, FAR* LPDEVICEBITMAP_DDIPARAMS;


#define DDI_FASTBORDER          0x0010
typedef struct tagFASTBORDER_DDIPARAMS
{
    LPRECT          lprcClip;
    LPDRAWMODE      lpDrawMode;
    LPPBRUSH        lpPBrush;
    LPPDEVICE       lpDev;
    DWORD           dwRop;
    UINT            cyBorder;
    UINT            cxBorder;
    LPRECT          lprcFrame;
}
FASTBORDER_DDIPARAMS, FAR* LPFASTBORDER_DDIPARAMS;


#define DDI_SETATTRIBUTE        0x0011
typedef struct tagSETATTRIBUTE_DDIPARAMS
{
    DWORD           dwAttribute;
    UINT            uIndex;
    UINT            uStateNum;
    LPPDEVICE       lpDev;
}
SETATTRIBUTE_DDIPARAMS, FAR* LPSETATTRIBUTE_DDIPARAMS;


#define DDI_DIBBLT              0x0012
typedef struct tagDIBBLT_DDIPARAMS
{
    LPCOLORINFO     lpColorInfo;
    LPDRAWMODE      lpDrawMode;
    LPBITMAPINFO    lpBitmapInfo;
    LPVOID          lpBits;
    UINT            cScans;
    UINT            iScan;
    BOOL            fGet;
    LPPDEVICE       lpDev;
}
DIBBLT_DDIPARAMS, FAR* LPDIBBLT_DDIPARAMS;


#define DDI_CREATEDIBITMAP      0x0013
typedef struct tagCREATEDIBITMAP_DDIPARAMS
{
    DWORD       dwDummyNotReallyHere;
}
CREATEDIBITMAP_DDIPARAMS, FAR* LPCREATEDIBITMAP_DDIPARAMS;


#define DDI_DIBTODEVICE         0x0014
typedef struct tagDIBTODEVICE_DDIPARAMS
{
    LPCOLORINFO     lpColorInfo;
    LPBITMAPINFO    lpBitmapInfo;
    LPVOID          lpBits;
    LPDRAWMODE      lpDrawMode;
    LPRECT          lprcClip;
    UINT            cScans;
    UINT            iScan;
    int             yStart;
    int             xStart;
    LPPDEVICE       lpDev;
}
DIBTODEVICE_DDIPARAMS, FAR* LPDIBTODEVICE_DDIPARAMS;


#define DDI_SETPALETTE          0x0015
#define DDI_GETPALETTE          0x0016
typedef struct tagGETSETPALETTE_DDIPARAMS
{
    LPPDEVICE       lpDevice;
    LPVOID          lpPalette;
    UINT            cEntries;
    UINT            iEntryStart;
}
GETSETPALETTE_DDIPARAMS, FAR* LPGETSETPALETTE_DDIPARAMS;


#define DDI_SETPALETTETRANSLATE 0x0017
#define DDI_GETPALETTETRANSLATE 0x0018
typedef struct tagGETSETPALETTETRANSLATE_DDIPARAMS
{
    LPPDEVICE       lpDevice;
    LPVOID          lpColorTranslateTable;
}
GETSETPALETTETRANSLATE_DDIPARAMS, FAR* LPGETSETPALETTETRANSLATE_DDIPARAMS;


#define DDI_UPDATECOLORS        0x0019
typedef struct tagUPDATECOLORS_DDIPARAMS
{
    LPPDEVICE       lpDevice;
    LPCOLORINFO     lpColorInfo;
    int             cyUpdate;
    int             cxUpdate;
    int             yStart;
    int             xStart;
}
UPDATECOLORS_DDIPARAMS, FAR* LPUPDATECOLORS_DDIPARAMS;


#define DDI_STRETCHBLT          0x001A
typedef struct tagSTRETCHBLT_DDIPARAMS
{
    LPRECT          lprcClip;
    LPDRAWMODE      lpDrawMode;
    LPPBRUSH        lpPBrush;
    DWORD           dwRop;
    int             cySrc;
    int             cxSrc;
    int             ySrc;
    int             xSrc;
    LPPDEVICE       lpDevSrc;
    int             cyDst;
    int             cxDst;
    int             yDst;
    int             xDst;
    LPPDEVICE       lpDevDst;
}
STRETCHBLT_DDIPARAMS, FAR* LPSTRETCHBLT_DDIPARAMS;


#define DDI_STRETCHDIBITS       0x001B
typedef struct tagSTRETCHDIBITS_DDIPARAMS
{
    LPRECT          lprcClip;
    LPDRAWMODE      lpDrawMode;
    LPPBRUSH        lpPBrush;
    DWORD           dwRop;
    LPCOLORINFO     lpColorInfo;
    LPBITMAPINFO    lpBitmapInfo;
    LPVOID          lpBits;
    int             cySrc;
    int             cxSrc;
    int             ySrc;
    int             xSrc;
    int             cyDst;
    int             cxDst;
    int             yDst;
    int             xDst;
    BOOL            fGet;
    LPPDEVICE       lpDevDst;
}
STRETCHDIBITS_DDIPARAMS, FAR* LPSTRETCHDIBITS_DDIPARAMS;


#define DDI_SELECTBITMAP        0x001C
typedef struct tagSELECTBITMAP_DDIPARAMS
{
    DWORD           dwFlags;
    LPVOID          lpBitmap;
    LPVOID          lpPrevBitmap;
    LPPDEVICE       lpDev;
}
SELECTBITMAP_DDIPARAMS, FAR* LPSELECTBITMAP_DDIPARAMS;


#define DDI_BITMAPBITS          0x001D
typedef struct tagBITMAPBITS_DDIPARAMS
{
    LPVOID          lpBitmap;
    DWORD           dwByteCount;
    DWORD           dwFlags;
    LPPDEVICE       lpDev;
}
BITMAPBITS_DDIPARAMS, FAR* LPBITMAPBITS_DDIPARAMS;


#define DDI_REENABLE            0x001E
typedef struct tagREENABLE_DDIPARAMS
{
    LPGDIINFO       lpGdiInfo;
    LPPDEVICE       lpDev;
}
REENABLE_DDIPARAMS, FAR* LPREENABLE_DDIPARAMS;


#define DDI_GAMMARAMP           0x001F
typedef struct tagGAMMARAMP_DDIPARAMS
{
    LPVOID          lpGammaRamp;
    BOOL            fSet;
    LPPDEVICE       lpDev;
}
GAMMARAMP_DDIPARAMS, FAR* LPGAMMARAMP_DDIPARAMS;


#define DDI_ICMCOLORINFO        0x0020
typedef struct tagICMCOLORINFO_DDIPARAMS
{
    LPVOID          lpColorTransform;
    LPVOID          lpColor;
    DWORD           rgbColor;
    LPPDEVICE       lpDev;
}
ICMCOLORINFO_DDIPARAMS, FAR* LPICMCOLORINFO_DDIPARAMS;


#define DDI_DRAWESCAPE          0x0021
typedef struct tagDRAWESCAPE_DDIPARAMS
{
    LPDRAWESCAPE    lpDrawEscape;
}
DRAWESCAPE_DDIPARAMS, FAR* LPDRAWESCAPE_DDIPARAMS;


#define DDI_MAX                 0x0022


#ifdef __cplusplus
}
#endif  // __cplusplus

#endif  // !_WINDDI_

--------------------------------------------------------------------------------


Since I found no entry for SetDDIHook in any MSDN file (searched even the libs) I think you need some more information to successfully create the hook. The 3 functions involved here are exported by GDI.dll with ordinal numbers:

function SetDDIHook index 750
function UnhookDDI index 751
function CallNextDDI index 752


You ask about how to specify what to hook? Well, you cannot specify this. Your hook is called for every (!) GDI output (and even things like text size determination). You need to examine ddiType to learn what is currently going on. Just use a switch statement similar to this code (sorry only in Delphi, but should be too hard to understand):

function DDIHookProc(DDI: HDDI; PrivateData: Pointer; DDIType: TDDIType; DDIParams: PDDIParams): DWORD; export;

var I, Count: Integer;
    Buffer: PWordArray;
    Entry: PDDIResult;

begin
  case DDIType of
    DDI_EXTTEXTOUT:
        with PTextOutDDIParams(DDIParams)^ do
        begin
          {a value < 0 specifies to calculate the text extent, a value = 0 specifies to fill the opaquing rectangle}
          if cchText > 0 then
          begin
            if cchText > MaxCharCount then Count := MaxCharCount
                                      else Count := cchText;
            GetMem(Buffer, 2 * (Count + 1));
            if (uOptions and ETO_GLYPH_INDEX) <> 0 then
            begin
              {string is stored with 2 byte per entry}
              for I := 0 to Count - 1 do
                Buffer^[I] := PWordArray(lpszText)^[I] + GlyphOffset;
            end
            else
            begin
              {string is stored with 1 byte per entry}
              for I := 0 to Count - 1 do
                Buffer^[I] := PByteArray(lpszText)^[I];
            end;
            {add a terminating 0}
            Buffer^[Count] := 0;
            AddTextEntries(Buffer, DDIParams);
            FreeMem(Buffer, 2 * Count + 2);
          end;
        end;
    DDI_BITBLT:
      with PBitBltDDIParams(DDIParams)^ do
      begin
        Entry := AddBlitEntry(lpDevSrc, lpDevDst, xDst - xSrc, yDst - ySrc);
      end;
    DDI_DIBBLT:
      AddStringEntry('DIBBLT', nil);
    DDI_DIBTODEVICE:
      AddStringEntry('DIBTODEVICE', nil);
    DDI_STRETCHBLT:
      AddStringEntry('STRETCHBLT', nil);
    DDI_STRETCHDIBITS:
      AddStringEntry('STRETCHDIBITS', nil);
  end;
  Result := CallNextDDI(DDI, DDIType, DDIParams);
end;"

Regards, Madshi.

P.S: In case Mike joins this question, please give the points to him, if the help is satisfying for you... Otherwise I'll be glad to get the points as well, of course...   :-)
Avatar of eaka

ASKER

Thank you for your source code. *BUT*
What is GlyphOffset ?
Please show detail of your variables , types and function Ex. GlyphOffset ,  AddBlitEntry, HDDI, AddStringEntry, PBitBltDDIParams,  PDDIParams, TDDIType, AddTextEntries, PTextOutDDIParams, PDDIResult ?
and In C (above) you define DWORD is  Pointer to DDIHOOKPROC but why in Delphi you use DWORD is cardinal ?
and I think you source code work in Delphi 1. but no other way ? I haven't delphi 1. I have Delphi 5. ( ex. use kernel32.QT_Thunk, kernel32.GetProcAddress16, kernel32.LoadLib16)
>> In C (above) you define DWORD is  Pointer to DDIHOOKPROC

No no. I think you didn't understand that C part alright. You mean this line I guess?

>> typedef DWORD (CALLBACK* DDIHOOKPROC)(HDDI, LONG, DDITYPE, LPDDIPARAMS);

This means the following in Delphi:

type TDDIHookProc : function(DDI: HDDI; PrivateData: Pointer; DDIType: TDDIType; DDIParams: PDDIParams): DWORD;

In Delphi(4&5) dword is identical to longWord or cardinal.

There's no other way to use Delphi1, I'm sorry. But isn't it on your D5 CD? I've had versions D1 - D5 and if I remember right D1 was on at least the D2 CD, too. Please look, perhaps it's also on your D5 CD...

What is GlyphOffset? I don't know. As I said, this code is not written by me. And it's not the code you'll need most probably, it should just show the framework about how your DDIHook proc should look like.

Regards, Madshi.
ASKER CERTIFIED SOLUTION
Avatar of Lischke
Lischke

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of eaka

ASKER

Lischke, Please explain again.
Do you use QT_Thunk or FT_Thunk ?
How to use it ? and I must compile by use Delphi 1 ?
I don't understand.

and Thank you very much Lischke and Madshi for your answer.
interested in "thunking" :-)
Actually I use QT_Thunk (IIRC then I have fixed some small problems, but I am not sure). This is needed to call 16bit functions from the 32bit DLL (to pass the results around. This is like:

procedure ReadTextAt9x(Wnd: HWND; P: TPoint);

// tries to retrieve the text under the current cursor position using a 16bit DDI hook DLL and a thunking layer
// to provide pointers accessible by both 32bit code and 16bit code.

const
  Hook16 = 'DDIHOOK.DLL';

type
  PResultArray = ^TResultArray;
  TResultArray = array[0..2047] of Word;

var R: TRect;
    Count: Cardinal;
    Entry: PDiversionResult;
    Lib: THandle;
    ClientPoint: TPoint;

    // 16 bit functions; could be simply declared as pointer, but to have a lookup for parameters
    // I have declared them as they are in the 16 bit DLL
    ActivateHook: function: Boolean;
    DeactivateHook: function: DWORD;
    GetNextResult: function(P: PResultArray): Boolean;
    ResultValid: Boolean;
    ResultArray: PResultArray;

begin
  // the word list must be created here to ensure it is valid in the context of the process
  // which will also do the text output
  TextList := TList.Create;

  // try loading 16bit DDI hook DLL
  Lib := LoadLibrary16(Hook16);
  if Lib <> 0 then
  begin
    // gather function addresses
    ActivateHook := GetProcAddress16(Lib, ...);
    DeactivateHook := GetProcAddress16(Lib, ...);
    GetNextResult := GetProcAddress16(Lib, ...);
    if Assigned(ActivateHook) and
      Assigned(DeactivateHook) and
      Assigned(GetNextResult) then
    begin
      // convert mouse position to local coordinates of the target window
      ClientPoint := P;
      MapWindowPoints(0, Wnd, ClientPoint, 1);

      // invalidate a small line to cause the window to redraw its text at this point
      GetClientRect(Wnd, R);
      R.Top := ClientPoint.y - 1;
      R.Bottom := ClientPoint.y + 1;
      if Boolean(Call16BitRoutine(@ActivateHook, ccPascal, [], [])) then
      begin
        RedrawWindow(Wnd, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOCHILDREN);

        Count := Call16BitRoutine(@DeactivateHook, ccPascal, [], []);
        if Count > 0 then
        begin
          ResultArray := AllocMem(SizeOf(ResultArray^));
          try
            repeat
              ResultValid := Boolean(Call16BitRoutine(@GetNextResult, ccPascal, [ResultArray], [SizeOf(TResultArray)]));
              if ResultValid then
              begin
                New(Entry);
                Entry.Flags := 0;
                // bounds can actually be negative if the string is partially out off the screen
                Entry.Bounds := Rect(SmallInt(ResultArray[0]), SmallInt(ResultArray[1]),
                                     SmallInt(ResultArray[2]), SmallInt(ResultArray[3]));

                Count := ResultArray[4];
                SetString(Entry.Text, PWideChar(@ResultArray[5]), Count);
                {with Entry.Bounds do
                  Entry.Text := Format('(%d, %d, %d, %d) ', [Left, Top, Right, Bottom]) + Entry.Text;}
                TextList.Add(Entry);
              end;
            until not ResultValid;
          finally
            FreeMem(ResultArray);
          end;

          // prepare the result
          if TextList.Count > 0 then
          begin
            PrepareResults(P);
            TextList.Clear;
            // mark that a result is available
            SetEvent(HookInfo.SynchEvent);
          end;
        end;
      end
      else OutputDebugString('DDI activation failed'#10);
      FreeLibrary16(Lib);
    end
    else OutputDebugString('DDI DLL addresses not found'#10);
  end
  else OutputDebugString('DDI DLL not found'#10);
  TextList.Free;
end;

Ciao, Mike
gandalf_the_white, what you can see here is all I used regarding thunking. Since I did not need more of the stuff I did also not care about it :-) However I will try to answer your questions the best I can (perhaps making a new question at EE?).

Ciao, Mike
Great! I hoped you would join us, Mike...   :-)

Hmmm... Does DDIHook really only work process wide (because you're using a SetWindowsHookEx hook)? That's sad. I hoped it would be system wide...   :-(   BTW, does a 32bit SetWindowsHookEx hook also hook 16bit Windows programs (windows 3.1 programs)? If not, then your DDIHook solution works only for 32bit windows programs, right?

Regards, Madshi.

P.S: Gandalf: About thunking look here:

http://www.itecuk.com/delmag/thunk95.htm
listening....
thanks to you both
its more like the interest of a blind in colors ;-)
i don't need them for my actual projects

but in programming it's always good to know more than you need
about the language and the compiler and more than you want
about the system
Madshi, I have never thought about a system wide DDI hook. It should be system wide because it hooks the central entry point of the GDI driver, but it would be difficult to inject the 16 bit DLL. I was interested only for text for a very short interval, so my solution was to inject the DLL by my global system hook.

Ciao, Mike
>> It should be system wide

Hmmm...   :-))   Yam yam, I think I'll add it to my madCodeHook component...   ((-:

>> but it would be difficult to inject the 16 bit DLL

What do you mean with that? I mean if SetDDIHook is really system wide then it should be enough to use LoadLibrary16 in our process, or am I wrong?

Regards, Madshi.
>> Hmmm...   :-))   Yam yam, I think I'll add it to my madCodeHook component...   ((-:

:-) Meanwhile you should have almost all the code I used for text capturing.

>> it should be enough to use LoadLibrary16 in our process

Right but if your program exits then the DLL is unloaded too (not sure about that, however, as you could leave the DLL in memory and I don't know what happens then with 16bit DLLs, just try it out).

Ciao, Mike
Avatar of eaka

ASKER

Lischke, Thank you for you source code.
Avatar of eaka

ASKER

Great !!!!!!
:-) glad to help
>> :-) Meanwhile you should have almost all the code I used for text capturing.

Hehe...  :-)  Well, if I decide to add the DDIHook stuff to my components, then it will be in a way, that you think, you would hook e.g. TextOutA Detours-like, but instead it will internally go over DDIHook. So it will surely be no copy of your text capturing sources...  (-:

Regards, Madshi.
Hi Lischke and Madshi.

I have some problem. I think there have some things about this question. Please explain to me.

1. How to I get image on hidden form or any hidden control in my application ?? Must I hook graphic output ( Paint() ) to my bitmap ??

Thank you.

Madshi, I know :-) You don't need to explain this. You are like japanese people. They take the best of all worlds and make it even better ;-)

todsawat, believe me, invisible means usually unexistent. Content of windows is drawn on demand. The only stuff which is stored are bitmaps, but you cannot rely on this generally.

Ciao, Mike

BTW: You should create your  own question instead "reusing" existing ones.
:O))
Hi Lischke,

Please send DDIHOOK.DLL and source code to me by email ( todsawat@thailand.net ).
Because I don't have delphi 1.

Thank you very much.
:-) no way, 70 points and source code which is property of the company I work for. Sorry...

Ciao, Mike

PS: DDI hooks require Delphi 1, so if you don't have it (what about the CD?) then forget the DDI hooks.
Ooops, sorry, I did not see the acceptance. Please see your inbox...

Ciao, Mike