Link to home
Create AccountLog in
Delphi

Delphi

--

Questions

--

Followers

Top Experts

Avatar of rogerrr
rogerrr

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_CALLWNDPROC,
GetProcAddress(GetModuleHandle('NewWndDll'),'NewWindowHookCallBack'),
GetModuleHandle('NewWndDll'), 0);
hook_on.Enabled:=False;
hook_off.Enabled:=True;
end;

procedure TForm1.hook_offClick(Sender: 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(Edit1.Text)),WM_PAINT,0,0);
end;

initialization
MessageBox(0,pchar(intToStr(LoadLibrary('NewWndDll'))),'LoadLibrary',0);


end.



*****************************************************************************
*****************************************************************************

DLL:


library NewWndDll;

uses
   Windows,SysUtils,Classes,Dialogs,Messages,Graphics;

const
   MSG_PROJECT = WM_USER + $1000;

var
  MyHook : HHook;

function NewWindowHookCallBack(pCode: 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,'Microsoft Excel - Book1.xls'); //window to capture


       if PCWP.hwnd=h then
       begin
       hdcScreen:=GetWindowDC(PCWP.hwnd);
       hdcCompatible:=CreateCompatibleDC(hdcScreen);
       GetWindowRect(PCWP.hwnd, rect);
       hbmScreen:=CreateCompatibleBitmap(hdcScreen, rect.Right - rect.Left, rect.Bottom -
       rect.Top);
       SelectObject(hdcCompatible,hbmScreen);

       SendMessage(PCWP.hwnd,WM_PRINT, 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.bmp');
       finally
       bmp.Free;
       DeleteDC(hdcScreen);
       DeleteDC(hdcCompatible);
       end;


       end;


end;
    Result:=CallNextHookEx(MyHook, 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!

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of 22661802266180🇺🇸

haven't tested your code but maybe you want to try this one:
https://www.experts-exchange.com/questions/21945203/Capture-of-a-client-form.html 
it's not that complicated as the hooking solution ;)

Avatar of rogerrrrogerrr

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.

Avatar of 22661802266180🇺🇸

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 ;)

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of rogerrrrogerrr

ASKER

OK! Thank you!

Avatar of 22661802266180🇺🇸

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?

Avatar of rogerrrrogerrr

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!

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


ASKER CERTIFIED SOLUTION
Avatar of 22661802266180🇺🇸

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

Avatar of rogerrrrogerrr

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!

Avatar of rogerrrrogerrr

ASKER

Is there any hope for me?

Avatar of 22661802266180🇺🇸

well your problem is solved. why do you want the translation anyway?

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of rogerrrrogerrr

ASKER

Hello!

Because i want to learn from the code, and my only one legal developer ambient is Delphi. :-)
Delphi

Delphi

--

Questions

--

Followers

Top Experts

Delphi is the most powerful Object Pascal IDE and component library for cross-platform Native App Development with flexible Cloud services and broad IoT connectivity. It provides powerful VCL controls for Windows 10 and enables FMX development for Windows, Mac and Mobile. Delphi is your choice for ultrafast Enterprise Strong Development™. Look for increased memory for large projects, extended multi-monitor support, improved Object Inspector and much more. Delphi is 5x faster for development and deployment across multiple desktop, mobile, cloud and database platforms including 32-bit and 64-bit Windows 10.