To do that, I needed a way to obtain the handle of the application window.
Windows handles
In windows.pas, handles are defined as
THandle = LongWord; // The comments say these are from WINDEF.H PHandle = ^THandle; // but they are really from winnt.h HWND = type LongWord; // from winnt.h |
where a LongWord is an unsigned 32-bit value. In winnt.h, these are defined as pointers to void - which amounts to approximately the same thing .. in a 32-bit operating system.
C++ is a case sensitive language. In it, all the native variable types are lower case and all the Microsoft defined types are uppercase. In Delphi (a case insensitive language), defined types begin with an uppercase-T (by convention).
Note that windows.pas contains data from many c++ header files and is used to define the Windows API as described in the Windows SDK. Specifically, it includes data types, constants, and function calls.
Windows commands
A window handle has the HWND data type; an application must use this type when declaring a variable that holds a window handle.
An application can use the FindWindow function to discover whether a window with the specified class name or window name exists in the system. If such a window exists, FindWindow returns the handle of the window. To limit the search to the child windows of a particular application, use the FindWindowEx function. The IsWindow function determines whether a window handle identifies a valid, existing window. |
Warning - selecting the following option crashed the application and required a full reboot to run WinSight a second time. |
These are some of the available Windows functions
FindWindow | Retrieves the handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. |
---|---|
EnumWindows | Passes the handle of each window, one at a time, to an application-defined callback. Use GetWindowText to get the text in the title bar. |
GetWindow | Returns the handle of the window in the specified z-position. Should not be used in a loop - use EnumWindows instead. |
WindowFromPoint | Returns the handle of the window that contains the specified point. |
Using a mouse
The WindowFromPoint function retrieves the handle of the window that contains the specified point. |
procedure TForm1.Some_UIButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var hnd : HWND; SourceRect : TRect; // Apparently, TRect is automatically allocated DestRect : TRect; // and these variables are actually pointers begin DestRect.TopLeft := ClientToScreen( point(Some_UIButton.Left + x, Some_UIButton.Top + y)); hnd := WindowFromPoint(DestRect.TopLeft); GetWindowRect(hnd, SourceRect); // Get SourceRect // other code to capture an image here end; |
In ClientToScreen I hardcoded the name of the button attached to the method. Generally, that is considered bad form. A more generic technique is
DestRect.TopLeft := (Sender as TControl).ClientToScreen( point(x, y) ); |
GetCursorPos
The Delphi 5 help on this is a bit confusing.
GetCursorPos Method Applies to TChart, TDBChart components Declaration function GetCursorPos:TPoint; DescriptionThe GetCursorPos function returns a TPoint record containing current mouse cursor position coordinates in pixels. It calls Windows GetCursorPos and adjusts coordinates to TChart origin position using ScreenToClient method. |
Mouse Cursor
procedure TForm1.Some_UIButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if button <> mbLeft then exit; screen.Cursor := crDefault; // other code to identify the window and capture an image here end; procedure TForm1.Some_UIButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if button = mbLeft then screen.Cursor := crHandPoint; end; |