I am trying to get screenshots of controls under the mouse pointer using ImageEnView1.IO.CaptureFromScreen:
procedure TForm1.TimerScreenshotTimer(Sender: TObject);
var
pt: Winapi.Windows.TPoint;
h, hc: Winapi.Windows.HWND;
r: TRect;
DC: HDC;
GrandchildrenList: ^TWindowHandleList;
begin
if not (GetKeyState(VK_CONTROL) < 0) then EXIT; // if not CTRL key is pressed then exit
Winapi.Windows.GetCursorPos(pt); // get mousepointer position
if Winapi.Windows.PtInRect(Self.BoundsRect, pt) then EXIT; // Exclude mouse over own window
h := Winapi.Windows.WindowFromPoint(pt); // Handle of the WINDOW under the mouse pointer
hc := Winapi.Windows.ChildWindowFromPoint(h, pt); // Handle of the WINDOW's child control
// Iterate through all the control's children (if it has any):
if GetKeyState(VK_SHIFT) < 0 then // if SHIFT key is pressed
begin
GrandchildrenCount := 0;
EnumChildWindows(Hc, @CountGrandchildrenCallback, LPARAM(@GrandchildrenCount)); // wrong GrandchildrenCount
CodeSite.Send('TForm1.TimerScreenshotTimer: GrandchildrenCount', GrandchildrenCount);
// Question: How to iterate through ALL the control's children (if it has any) with the SHIFT key?
// This only gets the control's FIRST child:
if GetKeyState(VK_SHIFT) < 0 then // if SHIFT key is pressed
hc := Winapi.Windows.GetNextWindow(hc, GW_HWNDNEXT); // Get the first grandchild
end;
// Draw a red frame around the control:
Winapi.Windows.GetWindowRect(hc, r);
DC := GetWindowDC(0);
try
// Invalidate the previous control's rectangle:
if prevHc <> 0 then
begin
Winapi.Windows.GetWindowRect(prevHc, prevR); // get previous frame
InvalidateRect(GetDesktopWindow(), @prevR, True); // remove previous frame: seems it does not work?
end;
// Draw the frame around the new control:
FrameRect(DC, r, CreateSolidBrush(RGB(255, 0, 0)));
finally
ReleaseDC(0, DC);
end;
prevHc := hc;
// Show the Control under the mouse pointer in the TImageEnView control:
if hc <> 0 then
begin
if ImageEnView1.IO.CaptureFromScreen(iecsSpecifiedWindow, -1, hc) = False then
begin
ImageEnView1.IO.CaptureFromScreen(iecsSpecifiedWindow2, -1, hc);
end;
end;
end;
It works well, but there are some problems:
1. How can I iterate through the children of the control?
2. How can I reliably draw a red frame around the control?
3. How can I make a screenshot from a PopupMenu?
Please see the attached demo project:
attach/PeterPanino/2023225113826_TestScreenshotControlUnderMouse.zip
3.2 KB