rogerrr
asked on
Feng Yuan's WM_PAINT hook code in Delphi
Hello!
I tried to capture the image of a foreign window but my
attempt is not perfect because the captured image is not similar
to the original window's image. For example like Microsoft Excel's window.
See example: http://img3.freeimagehosting.net/image.php?6a8267869d.jpg
My hook code is the following:
Project:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
const
MSG_PROJECT = WM_USER + $1000;
type
TForm1 = class(TForm)
hook_on: TButton;
hook_off: TButton;
send_wm_paint: TButton;
Edit1: TEdit;
procedure hook_onClick(Sender: TObject);
procedure hook_offClick(Sender: TObject);
procedure MSGHOOK(var Msg: TMessage); message MSG_PROJECT;
procedure send_wm_paintClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
gp: TPoint;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var hook : integer;
procedure TForm1.MSGHOOK(var Msg: TMessage);
begin
//if Msg.WParam<>0 then
end;
procedure TForm1.hook_onClick(Sender : TObject);
begin
hook:=SetWindowsHookEx(WH_ CALLWNDPRO C,
GetProcAddress(GetModuleHa ndle('NewW ndDll'),'N ewWindowHo okCallBack '),
GetModuleHandle('NewWndDll '), 0);
hook_on.Enabled:=False;
hook_off.Enabled:=True;
end;
procedure TForm1.hook_offClick(Sende r: TObject);
begin
UnhookWindowsHookEx(hook);
hook_off.Enabled:=False;
hook_on.Enabled:=True;
end;
procedure TForm1.send_wm_paintClick( Sender: TObject);
begin
SendMessage(FindWindow(nil ,PChar(Edi t1.Text)), WM_PAINT,0 ,0);
end;
initialization
MessageBox(0,pchar(intToSt r(LoadLibr ary('NewWn dDll'))),' LoadLibrar y',0);
end.
************************** ********** ********** ********** ********** ********** *
************************** ********** ********** ********** ********** ********** *
DLL:
library NewWndDll;
uses
Windows,SysUtils,Classes,D ialogs,Mes sages,Grap hics;
const
MSG_PROJECT = WM_USER + $1000;
var
MyHook : HHook;
function NewWindowHookCallBack(pCod e: Integer; pHandle: WPARAM; pWindow: LPARAM): LRESULT; stdcall;
var
PCWP : ^CWPSTRUCT;
h: Hwnd;
hbmScreen: HBitmap;
hdcScreen, hdcCompatible : HDC;
rect: TRect;
bmp: TBitmap;
begin
PCWP:= Pointer(pWindow);
if PCWP^.Message = WM_PAINT then begin
h:=FindWindow(nil,'Microso ft Excel - Book1.xls'); //window to capture
if PCWP.hwnd=h then
begin
hdcScreen:=GetWindowDC(PCW P.hwnd);
hdcCompatible:=CreateCompa tibleDC(hd cScreen);
GetWindowRect(PCWP.hwnd, rect);
hbmScreen:=CreateCompatibl eBitmap(hd cScreen, rect.Right - rect.Left, rect.Bottom -
rect.Top);
SelectObject(hdcCompatible ,hbmScreen );
SendMessage(PCWP.hwnd,WM_P RINT, hdcCompatible,PRF_CHILDREN or PRF_CLIENT or PRF_ERASEBKGND or
PRF_NONCLIENT or PRF_OWNED);
bmp:=TBitmap.Create;
try
bmp.Handle:=hbmScreen;
BitBlt(bmp.Canvas.Handle, 0, 0, rect.Right - rect.Left,rect.Bottom - rect.Top, hdcScreen, 0,
0, SRCCOPY);
ReleaseDc(0, hdcScreen);
bmp.SaveToFile('C:\shot.bm p');
finally
bmp.Free;
DeleteDC(hdcScreen);
DeleteDC(hdcCompatible);
end;
end;
end;
Result:=CallNextHookEx(MyH ook, pCode, pHandle, pWindow);
end;
exports NewWindowHookCallBack index 1 name 'NewWindowHookCallBack';
end.
************************** ********** ********** ********** ********** ********** *
************************** ********** ********** ********** ********** ********** *
I found an article/code about WM_PAINT hook by Feng Yuan.
http://www.fengyuan.com/article/wmprint.html
Dll code: http://www.fengyuan.com/article/capture.zip
But this code written in VC++ and i don't understand it because it contains some unknown things for me and i'm not feel at home in VC++. Please help me to translate this code to Delphi.
Thanks in advance!
I tried to capture the image of a foreign window but my
attempt is not perfect because the captured image is not similar
to the original window's image. For example like Microsoft Excel's window.
See example: http://img3.freeimagehosting.net/image.php?6a8267869d.jpg
My hook code is the following:
Project:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
const
MSG_PROJECT = WM_USER + $1000;
type
TForm1 = class(TForm)
hook_on: TButton;
hook_off: TButton;
send_wm_paint: TButton;
Edit1: TEdit;
procedure hook_onClick(Sender: TObject);
procedure hook_offClick(Sender: TObject);
procedure MSGHOOK(var Msg: TMessage); message MSG_PROJECT;
procedure send_wm_paintClick(Sender:
private
{ Private declarations }
public
{ Public declarations }
gp: TPoint;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var hook : integer;
procedure TForm1.MSGHOOK(var Msg: TMessage);
begin
//if Msg.WParam<>0 then
end;
procedure TForm1.hook_onClick(Sender
begin
hook:=SetWindowsHookEx(WH_
GetProcAddress(GetModuleHa
GetModuleHandle('NewWndDll
hook_on.Enabled:=False;
hook_off.Enabled:=True;
end;
procedure TForm1.hook_offClick(Sende
begin
UnhookWindowsHookEx(hook);
hook_off.Enabled:=False;
hook_on.Enabled:=True;
end;
procedure TForm1.send_wm_paintClick(
begin
SendMessage(FindWindow(nil
end;
initialization
MessageBox(0,pchar(intToSt
end.
**************************
**************************
DLL:
library NewWndDll;
uses
Windows,SysUtils,Classes,D
const
MSG_PROJECT = WM_USER + $1000;
var
MyHook : HHook;
function NewWindowHookCallBack(pCod
var
PCWP : ^CWPSTRUCT;
h: Hwnd;
hbmScreen: HBitmap;
hdcScreen, hdcCompatible : HDC;
rect: TRect;
bmp: TBitmap;
begin
PCWP:= Pointer(pWindow);
if PCWP^.Message = WM_PAINT then begin
h:=FindWindow(nil,'Microso
if PCWP.hwnd=h then
begin
hdcScreen:=GetWindowDC(PCW
hdcCompatible:=CreateCompa
GetWindowRect(PCWP.hwnd, rect);
hbmScreen:=CreateCompatibl
rect.Top);
SelectObject(hdcCompatible
SendMessage(PCWP.hwnd,WM_P
PRF_NONCLIENT or PRF_OWNED);
bmp:=TBitmap.Create;
try
bmp.Handle:=hbmScreen;
BitBlt(bmp.Canvas.Handle, 0, 0, rect.Right - rect.Left,rect.Bottom - rect.Top, hdcScreen, 0,
0, SRCCOPY);
ReleaseDc(0, hdcScreen);
bmp.SaveToFile('C:\shot.bm
finally
bmp.Free;
DeleteDC(hdcScreen);
DeleteDC(hdcCompatible);
end;
end;
end;
Result:=CallNextHookEx(MyH
end;
exports NewWindowHookCallBack index 1 name 'NewWindowHookCallBack';
end.
**************************
**************************
I found an article/code about WM_PAINT hook by Feng Yuan.
http://www.fengyuan.com/article/wmprint.html
Dll code: http://www.fengyuan.com/article/capture.zip
But this code written in VC++ and i don't understand it because it contains some unknown things for me and i'm not feel at home in VC++. Please help me to translate this code to Delphi.
Thanks in advance!
ASKER
Hello ciuly!
Thanks but your code is not perfect for me. :-( My code (vide supra) works even if the captured window is obscured by other windows and/or visible partially (hang out the desktop)...
(I know the PrintWindow api too, but i want to try the Feng Yuan's solution.)
Thanks.
Thanks but your code is not perfect for me. :-( My code (vide supra) works even if the captured window is obscured by other windows and/or visible partially (hang out the desktop)...
(I know the PrintWindow api too, but i want to try the Feng Yuan's solution.)
Thanks.
you can always bring forward the needed window :P
if no one takes the hit on this question until the weekend, post a reminder message and I'll try a translation ;)
if no one takes the hit on this question until the weekend, post a reminder message and I'll try a translation ;)
ASKER
OK! Thank you!
just looked over the c++ code. what a mess. quote from page:
Limitation
The Hook function only handles exported function whose first instruction is "MOV EAX, <DWORD_constant>". So the implementation shown here only applies to Windows NT/2000. Refer to Chapter 4 for more generic of restrictive API hooking solutions.
that doesn't look to good. anyway, just for hooking purposes we can use madshi madhook component.
but before getting into teh real deal, don't want to waste time translating something that does not work, so I have to ask: did you try it out? does it do what you want?
Limitation
The Hook function only handles exported function whose first instruction is "MOV EAX, <DWORD_constant>". So the implementation shown here only applies to Windows NT/2000. Refer to Chapter 4 for more generic of restrictive API hooking solutions.
that doesn't look to good. anyway, just for hooking purposes we can use madshi madhook component.
but before getting into teh real deal, don't want to waste time translating something that does not work, so I have to ask: did you try it out? does it do what you want?
ASKER
Hello!
Sorry for slow reply!
"did you try it out? does it do what you want?"
Yes, some days ago i did try a compiled verison (comiled by a friend) and the captured image was true. I think (and according to others too) Feng Yuan's solution is the best way to capture a window.
Thank you!
Sorry for slow reply!
"did you try it out? does it do what you want?"
Yes, some days ago i did try a compiled verison (comiled by a friend) and the captured image was true. I think (and according to others too) Feng Yuan's solution is the best way to capture a window.
Thank you!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
:-( Yes the compiled dll is applicable in my application too, but i'd like to see the full code in 'Delphi language'. Please help me i can't translate it...plese!
Thanks!
Thanks!
ASKER
Is there any hope for me?
well your problem is solved. why do you want the translation anyway?
ASKER
Hello!
Because i want to learn from the code, and my only one legal developer ambient is Delphi. :-)
Because i want to learn from the code, and my only one legal developer ambient is Delphi. :-)
https://www.experts-exchange.com/questions/21945203/Capture-of-a-client-form.html
it's not that complicated as the hooking solution ;)