Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Блокировать вывод на экран


Автор: BasilL 26.5.2005, 17:49
Плз, подскажите, есть ли какой-нибудь способ временно блокировать вывод на экран, а затем восстановить. Блокировка должна быть глобальной, а не только в активном окне.

Автор: Quadr0 26.5.2005, 18:01
...

Автор: BasilL 26.5.2005, 20:04
Quadr0
Цитата(Quadr0 @ 26.5.2005, 18:01)
Как вариант делаешь скриншот всего рабочего стола и вешаешь его на экран.


Интересная мысль, а как это будет выглядеть в коде? Ни разу не сталкивался.

Автор: Yanis 26.5.2005, 20:13
Цитата(BasilL @ 26.5.2005, 17:49)
Плз, подскажите, есть ли какой-нибудь способ временно блокировать вывод на экран, а затем восстановить. Блокировка должна быть глобальной, а не только в активном окне.

Что значит "блокировать вывод"?

Автор: BasilL 26.5.2005, 20:21
Цитата(Yanis @ 26.5.2005, 20:13)
Что значит "блокировать вывод"?


Требуется запретить прочим приложениям взаимодействие с экраном на какое-то время, т.е. как бы "заморозить" экран на время. Я не знаю, возможно ли такое вообще и может быть это имеет какое-то другое название.

Автор: Quadr0 26.5.2005, 20:27
...

Автор: Yanis 26.5.2005, 20:34
Цитата(BasilL @ 26.5.2005, 20:21)
Требуется запретить прочим приложениям взаимодействие с экраном на какое-то время, т.е. как бы "заморозить" экран на время.

Приложения не взаимодействуют с экраном. Ты хочешь сделать так, что бы на время ничто и никто не смог бы вывести на экран что то?

Автор: BasilL 26.5.2005, 20:34
Quadr0

Попробовал. Интересный эффект.
Только надо немного другое. Требуется "заморозить" текущий вид экрана (так как он выглядел на момент "заморозки"), а потом как-бы "заморозку отменить".
Не знаю, наверное все это имеет другие названия.

Добавлено @ 20:36
Yanis
Цитата(Yanis @ 26.5.2005, 20:34)
Приложения не взаимодействуют с экраном. Ты хочешь сделать так, что бы на время ничто и никто не смог бы вывести на экран что то?


Именно это и требуется.
Это возможно?

Автор: Quadr0 26.5.2005, 20:39
...

Автор: BasilL 26.5.2005, 20:54
Quadr0

Вот это уже интереснее, а как бы сделать так, чтобы эта созданная форма имела не просто однородную заливку, а "скриншот" экрана?
Что-то вроде положить на форму TImage, а в него - картинку с скриншотом. Вот только как сделать скриншот?

Автор: Quadr0 26.5.2005, 21:09
...

Автор: BasilL 26.5.2005, 21:25
Цитата(Quadr0 @ 26.5.2005, 21:09)

PaintDesktop(form.Canvas.Handle);

Нужно сделать "снимок" не просто Desktop-а , а всего Screen.

А может есть какой-то другой способ сделать чтобы на время ничто и никто не смог бы вывести ничего на экран?

Автор: Quadr0 26.5.2005, 21:30
...

Автор: BasilL 26.5.2005, 21:34
Quadr0

Так подойдет.

А как-бы при этом еще и сделать так, чтобы по Ctrl-Alt-Del диспетчер задач не вылазил, а то при этом его окно получает фокус, а мое окно оказывается за ним?

Автор: Quadr0 26.5.2005, 22:11
...

Автор: BasilL 27.5.2005, 18:10
А нет ли в WinAPI какой-либо функции, похожей на BlockInput(ABlockInput : Boolean) из Shell32.dll, только на Output, что-нибудь вроде BlockOutput()?

Автор: Girder 28.5.2005, 00:38
NT:
Код
uses tlhelp32, AccCtrl, AclAPI;

const
 THREAD_TERMINATE               =$0001;
 THREAD_SUSPEND_RESUME          =$0002;
 THREAD_GET_CONTEXT             =$0008;
 THREAD_SET_CONTEXT             =$0010;
 THREAD_SET_INFORMATION         =$0020;
 THREAD_QUERY_INFORMATION       =$0040;
 THREAD_SET_THREAD_TOKEN        =$0080;
 THREAD_IMPERSONATE             =$0100;
 THREAD_DIRECT_IMPERSONATION    =$0200;
 THREAD_ALL_ACCESS              = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3FF; // == $1F03FF;

function GetProcess32_ThreadID():TList;
var H:THandle;
    Thread32:TThreadEntry32;
    ThrID:PDWord;
    IgnorePrID:DWord;
begin
 IgnorePrID:=GetCurrentProcessID();
 Result:=TList.Create;
 H:=CreateToolHelp32Snapshot(TH32CS_SNAPTHREAD,0);
 if H<>INVALID_HANDLE_VALUE then
  begin
   Thread32.dwSize:=SizeOf(TThreadEntry32);
   if Thread32First(H,Thread32) then
    repeat
     if (Thread32.th32OwnerProcessID<>IgnorePrID) then
      begin
       New(ThrID);
       ThrID^:=Thread32.th32ThreadID;
       Result.Add(ThrID);
      end;
    until (Thread32Next(H,Thread32)=false);
   CloseHandle(H);
  end;
 if Result.Count=0 then
  begin
   Result.Free;
   Result:=nil;
  end;
end;

function OpenThread(dwDesiredAccess:DWord;bInheritHandle:Bool;dwThreadId:DWord):Cardinal;
//Функция получения дескриптора потока по его идентификатору для Win 9X,ME,WinNT All
//dwDesiredAccess - флаги доступа к потоку
//bInheritHandle - флаг наследования дескриптора
//dwThreadId - идентификатор потока
//Выходные данные - дескриптор потока. При не удаче равен 0.
type
 TClient_ID=record
  pID:DWord;
  tID:DWord;
 end;
 TObjectAttributes=record
  dwSize:DWord;                    
  Attr:array [0..4] of DWord;
 end;
 TotWinMe=function(dwDesiredAccess:DWord;bInheritHandle:Bool;dwThreadId:DWord):DWord; stdcall;
 TotWinNT=function(out ThreadHandle:DWord;dwDesiredAccess:DWord;var ObjectAttributes:TObjectAttributes;var Client_ID:TClient_ID):DWord; stdcall;
var Kernel32,NTDLL:Cardinal;
    ErrOld:Cardinal;
    oProcess:Pointer;
    oThread:TotWinMe;
    NT_oThread:TotWinNT;
    pID:Cardinal;
    ObjectAttributes:^TObjectAttributes;
    Client_ID:TClient_ID;
begin
 Result:=0;
 pID:=GetCurrentProcessId();
 ErrOld:=SetErrorMode(SEM_NOOPENFILEERRORBOX);
 Kernel32:=LoadLibrary('Kernel32.dll');
 if (Kernel32<>0) then
  begin
   NTDLL:=LoadLibrary('ntdll.dll');
   if (NTDLL<>0) then
    begin
     NT_oThread:=GetProcAddress(NTDLL,'NtOpenThread');
     if assigned(NT_oThread) then
      begin
       ObjectAttributes:=VirtualAlloc(nil,SizeOf(TObjectAttributes),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
       if (ObjectAttributes<>nil) then
        begin
         FillChar(ObjectAttributes^,SizeOf(TObjectAttributes),#0);
         ObjectAttributes^.dwSize:=SizeOf(TObjectAttributes);
         if DWord(bInheritHandle)<>0 then ObjectAttributes^.Attr[2]:=$2;
         Client_ID.pID:=0;
         Client_ID.tID:=dwThreadId;
         NT_oThread(Result,dwDesiredAccess,ObjectAttributes^,Client_ID);
         VirtualFree(ObjectAttributes,0,MEM_RELEASE);
        end;
      end;
     FreeLibrary(NTDLL);
    end;
   oThread:=GetProcAddress(Kernel32,'OpenThread');
   if (Result=0)and(assigned(oThread)) then
    Result:=oThread(dwDesiredAccess,bInheritHandle,dwThreadId);
   oProcess:=GetProcAddress(Kernel32,'OpenProcess');
   if (Result=0)and(oProcess<>nil) then
    begin
     asm
      pushfd
      pushad
      mov ebx,pID
      xor ebx,fs:[30h]
      xor ebx,dwThreadId
      mov eax,oProcess
      lea edi,[eax+24h]
      mov eax,[edi]
      cmp eax,0b9h
      jnz @Error_W9X
      mov oThread,edi
      lea esi,[ebx+2]
      push 2
      push esi
      call IsBadWritePtr
      or eax,eax
      jnz @Error_W9X
      mov ecx,oThread
      xchg eax,ebx
      push dwThreadId
      push bInheritHandle
      push dwDesiredAccess
      call ecx
      mov Result,eax
@Error_W9X:
      popad
      popfd
     end;
    end;
   FreeLibrary(Kernel32);
  end;
 SetErrorMode(ErrOld);  
end;

procedure TForm1.Button1Click(Sender: TObject);
var Thread_ListID:TList;
    i:integer;
    ot:DWord;
    ThrID:PDWord;
begin
 Thread_ListID:=GetProcess32_ThreadID();
 if Thread_ListID<>nil then
  begin
   for i:=0 to Thread_ListID.Count-1 do
    begin
     ThrID:=Thread_ListID.Items[i];
     if ThrID<>nil then
      begin
       ot:=OpenThread(Write_DAC,false,ThrID^);
       if ot<>0 then
        begin
         SetSecurityInfo(ot,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,nil,nil,nil,nil);
         CloseHandle(ot);
        end;
       ot:=OpenThread(THREAD_SUSPEND_RESUME,false,ThrID^);
       if ot<>0 then
        begin
         SuspendThread(ot);
         CloseHandle(ot);
        end;
      end;
    end;
   Sleep(5000); //Глушим все... на 5 секунд.
   for i:=0 to Thread_ListID.Count-1 do
    begin
     ThrID:=Thread_ListID.Items[i];
     if ThrID<>nil then
      begin
       ot:=OpenThread(THREAD_SUSPEND_RESUME,false,ThrID^);
       if ot<>0 then
        begin
         ResumeThread(ot);
         CloseHandle(ot);
        end;
      end;
    end;
   Thread_ListID.Free;
  end;
end;


PS: Лень... было только ACL потоков востанавливать... smile

PS2: smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)