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 ?
1. How to uses DDIHook on Delphi ?
2. How to patch export table GDI32.DLL on Delphi ?
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_DDIPARA MS
{
LPVOID lpClientData;
FARPROC lpfnCallback;
LPSTR lpszFaceName;
LPPDEVICE lpDev;
}
ENUMDEVICEFONTS_DDIPARAMS, FAR* LPENUMDEVICEFONTS_DDIPARAM S;
#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_DDIPARAM S
{
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_DDI PARAMS, FAR* LPGETSETPALETTETRANSLATE_D DIPARAMS;
#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(DDIParam s)^ 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('DIBTODEVIC E', nil);
DDI_STRETCHBLT:
AddStringEntry('STRETCHBLT ', nil);
DDI_STRETCHDIBITS:
AddStringEntry('STRETCHDIB ITS', 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... :-)
"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_DDIPARA
{
LPVOID lpClientData;
FARPROC lpfnCallback;
LPSTR lpszFaceName;
LPPDEVICE lpDev;
}
ENUMDEVICEFONTS_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_DDIPARAM
{
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_
{
LPPDEVICE lpDevice;
LPVOID lpColorTranslateTable;
}
GETSETPALETTETRANSLATE_DDI
#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(DDIParam
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
begin
Entry := AddBlitEntry(lpDevSrc, lpDevDst, xDst - xSrc, yDst - ySrc);
end;
DDI_DIBBLT:
AddStringEntry('DIBBLT', nil);
DDI_DIBTODEVICE:
AddStringEntry('DIBTODEVIC
DDI_STRETCHBLT:
AddStringEntry('STRETCHBLT
DDI_STRETCHDIBITS:
AddStringEntry('STRETCHDIB
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... :-)
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)
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,
>> 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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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(@ ActivateHo ok, ccPascal, [], [])) then
begin
RedrawWindow(Wnd, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOCHILDREN);
Count := Call16BitRoutine(@Deactiva teHook, ccPascal, [], []);
if Count > 0 then
begin
ResultArray := AllocMem(SizeOf(ResultArra y^));
try
repeat
ResultValid := Boolean(Call16BitRoutine(@ GetNextRes ult, 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.SynchEve nt);
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
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(@
begin
RedrawWindow(Wnd, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOCHILDREN);
Count := Call16BitRoutine(@Deactiva
if Count > 0 then
begin
ResultArray := AllocMem(SizeOf(ResultArra
try
repeat
ResultValid := Boolean(Call16BitRoutine(@
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[
SmallInt(ResultArray[2]), SmallInt(ResultArray[3]));
Count := ResultArray[4];
SetString(Entry.Text, PWideChar(@ResultArray[5])
{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.SynchEve
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
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
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
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
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... ((-:
>> 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
:-) 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
ASKER
Lischke, Thank you for you source code.
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.
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.
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.
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.
OK
: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.
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.
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
Ciao, Mike
ASKER