Код работает в обычной винде и в виртуальных машинах с гостевой XP,windows 7,windows 8. Редко бывают какие то глюки, но это не критично.
Но вот я установил гостевую windows 10 и имеем, когда я делаю скриншот в основном потоке (скриншот окна по хендлу) то все нормально. Если я делаю этим кодом скриншоты всего рабочего стола - все нормально, но как только я пытаюсь скриншотить окно по хендлу в отдельном потоке он мне выдает какой то 1й скрин окна и все....сколько дальше он не скриншотит в результате я вижу только этот первый скрин. Причем если я перезапущу свою программу!!! т.е. в ней гарантировано все удалится, то после попытки делать скриншоты он опять покажет мне тот же самый "первый скрин" что за дела? Ранее у меня такое случалось и на windows 8, чем закончилось хз. Может что то не так с моим кодом?
procedure TScreenShot.Execute;
var
T: Cardinal;
pause: Integer;
res: boolean;
pt: TPoint;
begin
if fOfflineMode then
exit;
T := GetTickCount;
if (fType = 'Global') then
begin
fScreen.Width := screen.Width;
fScreen.Height := screen.Height;
fhSrcDC := GetDC(0);
fhDC1 := CreateCompatibleDC(fhSrcDC);
SelectObject(fhDC1, fScreen.Handle);
pt.X := 0;
pt.Y := 0;
end;
while (not Terminated) do
begin
res := true;
SimpSync.StartWrite;
if fType = 'Local' then
begin
try
res := MyFindWindow;
except
ferrorText := 'koshmar';
end;
if fClientShot then
begin
pt.X := fClR.left - R.left;
pt.Y := fClR.Top - R.Top;
end
else
begin
pt.X := 0;
pt.Y := 0;
end;
end;
if res then
begin
BitBlt(fhDC1, 0, 0, fScreen.Width, fScreen.Height, fhSrcDC, pt.X,
pt.Y, SRCCOPY);
end;
SimpSync.EndWrite;
end;
end;
Function TScreenShot.MyFindWindow(): boolean;
begin
if isWindow(FHandle) then
begin
if (not IsWindowVisible(FHandle)) or IsIconic(FHandle) then
begin
ShowWindow(FHandle, SW_SHOWNORMAL);
sleep(200);
end;
GetWindowRect(FHandle, fR);
if fR.left < 0 then
begin
result := false;
exit;
end;
if CheckSizeWindow then
begin
if fhSrcDC <> 0 then
begin
DeleteDC(fhSrcDC);
ReleaseDC(FHandle, fhDC1);
DeleteDC(fhDC1);
end;
fhSrcDC := GetwINDOWDC(FHandle);
fhDC1 := CreateCompatibleDC(fhSrcDC);
SelectObject(fhDC1, fScreen.Handle);
end;
if fClientShot then
begin
GetClientRect(FHandle, fClR);
MapWindowPoints(FHandle, 0, fClR, 2);
fScreen.Width := fClR.Width;
fScreen.Height := fClR.Height;
end
else
begin
fScreen.Width := fR.Width;
fScreen.Height := fR.Height;
end;
result := true;
exit;
end;
result := false;
WaitForSingleObject(MyMutex, INFINITE);
FHandle := FindWindowA(CNP, WNP);
ReleaseMutex(MyMutex);
if FHandle > 0 then
begin
if (fhSrcDC <> 0) then
begin
ReleaseDC(FHandle, fhDC1);
DeleteDC(fhSrcDC);
DeleteDC(fhDC1);
end;
GetWindowRect(FHandle, fR);
if fClientShot then
begin
GetClientRect(FHandle, fClR);
MapWindowPoints(FHandle, 0, fClR, 2);
fScreen.Width := fClR.Width;
fScreen.Height := fClR.Height;
end
else
begin
fScreen.Width := fR.Width;
fScreen.Height := fR.Height;
end;
If (fScreen.Width = 0) or (fScreen.Height = 0) then
Begin
ferrorText := ferrorText + 'Размер области формы равен нулю';
result := false;
exit;
End;
fhSrcDC := GetwINDOWDC(FHandle);
fhDC1 := CreateCompatibleDC(fhSrcDC);
SelectObject(fhDC1, fScreen.Handle);
if fhSrcDC > 0 then
result := true;
end;
end;