2016-12-11 11 views
-1

, основанный на this Мой вопрос, я хочу знать, есть ли у какой-нибудь возможности узнать, создан ли случайный рабочий стол (без минимизации)?Как проверить, отображается ли «Случайный рабочий стол», созданный на WinSta0 (без минимизации)?

Поскольку при использовании этого адаптированного кода ниже, если я минимизирую новый рабочий стол, генерируется «пустой» битмап (белый захват): а OpenDesktop api терпит неудачу, когда новый рабочий стол (называемый «default_set» в коде ниже) сведен к минимуму :-(

Итак, есть как решить?

Спасибо любым предложением.

program Project1; 

{$R *.res} 

uses 
    Winapi.Windows, 
    System.SysUtils, 
    vcl.Graphics; 

function fillstrL (s: string; l: byte; c:char): string; 
    begin 
    while length(s) < l do 
     s:= c+s; 
    result:= s; 
    end; 

procedure PrintSCR; 
var 
    hWin: HWND; 
    dc: HDC; 
    bmp: TBitmap; 
    FileName: string; 
    r: TRect; 
    w: Integer; 
    h: Integer; 
begin 

    hWin := GetDesktopWindow; 

    GetWindowRect(hWin,r); 
    dc := GetWindowDC(hWin) ; 

    w := r.Right - r.Left; 
    h := r.Bottom - r.Top; 

    bmp := TBitmap.Create; 
    bmp.Height := h; 
    bmp.Width := w; 
    BitBlt(bmp.Canvas.Handle, 0, 0, w, h, DC, 0, 0, SRCCOPY); 
    FileName := 'Screenshot_'+FormatDateTime('mm-dd-yyyy-hhnnss',now()); 
    bmp.SaveToFile(Format('%s.bmp', [FileName])); 
    ReleaseDC(hwin, DC); 
    bmp.Free; 

end; 

var 
hSaveDesktop, hDesktop: HDESK; 

//////////////////////////////////////////////////////////////////////////////// 

begin 
    try 

    while True do 
    begin 

     hSaveDesktop := GetThreadDesktop(GetCurrentThreadId); 
     Win32Check(hSaveDesktop <> 0); 

     hDesktop := OpenDesktop('default_set', 0, True, GENERIC_ALL); 
     Win32Check(hDesktop <> 0); 
     try 
     Win32Check(SetThreadDesktop(hDesktop)); 
     try 
      PrintSCR; 
     finally 
      Win32Check(SetThreadDesktop(hSaveDesktop)); 
     end; 
     finally 
     Win32Check(CloseDesktop(hDesktop)); 
     end; 
     Sleep(1000); 

     PrintSCR; 

    Sleep(5000); 
    end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 

    Readln; 
end. 
+2

В любой момент на рабочем столе есть только один видимый рабочий стол. Все остальные настольные компьютеры, тем временем, сводятся к минимуму/скрыты или независимо от состояния, в котором они находятся, когда они неактивны. OpenInputDesktop предоставляет дескриптор активного рабочего стола. –

+1

BTW, я думаю, вы не обнаружили, как работает захват, это нерегулярно, но просто: вы можете в любое время захватить рабочий стол по умолчанию, будь то сведено к минимуму/скрыто или активно. Вы можете захватывать любой другой рабочий стол только тогда, когда они активны. –

+0

@Sertac, да !, рабочий стол по умолчанию возможен захват всегда правильно, когда он виден, если «новый рабочий стол» виден, также записывается отлично, но после этого его минимизируют, он захватывает белый экран ([hDesktop возвращает true, когда " новый рабочий стол "сведен к минимуму, это правильно?] (http://pastebin.com/qwRnMdYT)), потому что он больше не виден. Итак, я хочу, чтобы он только запечатлел «новый рабочий стол», когда он действительно виден пользователю. – Saulo

ответ

3

Вы можете получить дескриптор активного рабочего стола с помощью OpenInputDesktop. Все другие настольные компьютеры неакт ive (или сведено к минимуму, или скрыто, ...).

Если открыть ручку не удобно, вы можете открыть ручку и получить имя рабочего стола, а затем закрыть дескриптор, чтобы сравнить имя рабочего стола с рабочим столом, который вам интересен. Ниже в примере используется GetUserObjectInformation для извлечения имя активного/входного рабочего стола.

function GetDesktopName(Desktop: HDESK): string; 
var 
    BufSize: DWORD; 
begin 
    BufSize := 0; 
    GetUserObjectInformation(Desktop, UOI_NAME, nil, 0, BufSize); 
    Win32Check(BufSize <> 0); 
    SetLength(Result, (BufSize) div SizeOf(Char)); 
    Win32Check(GetUserObjectInformation(Desktop, UOI_NAME, Pointer(Result), 
     Length(Result) * SizeOf(Char), BufSize)); 
    Win32Check(BufSize <> 0); 
    SetLength(Result, Length(Result) - 1); 
end; 

.. 

var 
    Desktop: HDESK; 
begin 
    Desktop := OpenInputDesktop(0, False, GENERIC_READ); 
    Win32Check(Desktop <> 0); 
    try 
    // don't use ShowMessage if this is not main VCL thread 
    ShowMessage(GetDesktopName(Desktop)); 
    finally 
    Win32Check(CloseDesktop(Desktop)); 
    end; 

Если у вас уже есть ручка для любого рабочего стола, запрашивая если входной рабочий стол проще с GetUserObjectInformation (для Vista и более поздних версий).

function IsIODesktop(Desktop: HDESK): BOOL; 
var 
    BufSize: DWORD; 
begin 
    BufSize := SizeOf(Result); 
    GetUserObjectInformation(Desktop, UOI_IO, @Result, BufSize, BufSize); 
    Win32Check(BufSize <> 0); 
end; 
+0

очень приятно! отлично работает над вашим решением выше. – Saulo