Мне нужно использовать clipboard для сохранения данных в собственном формате и я хочу для этого написать набор процедур ввода/вывода с использованием потоков (streams). Возможно ли создать объект TMemoryStream, эаполнить его и поместить в Clipboard?

 

Hе только возможно, именно так поступают функции Clipboard.GetComponent и Clipboard.SetComponent. Сначала вы должны зарегистрировать свой собственный формат данных для Clipboard с помощью функции RegisterClipboardFormat:

Code:

//Ctrl+C, Strg+C:

 

keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);

keybd_event(Ord('C'), MapVirtualKey(Ord('C'), 0), 0, 0);

keybd_event(Ord('C'), MapVirtualKey(Ord('C'), 0), KEYEVENTF_KEYUP, 0);

keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0)

 

 

 

//Ctrl+V, Strg+V:

 

keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);

keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), 0, 0);

keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), KEYEVENTF_KEYUP, 0);

keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0)

 

В качестве параметров передаются:

AHandle - хэндл окна, скриншот которого мы хочем получить

CompressPercent - процент сжатия картинки

AImage - картинка, в которую будет помещено изображение

в случае успешного скриншота функция вернет True  {©Drkb v.3}

 

надо его вручную дорисовать

Code:

procedure GetScreenImage(bmp: TBitmap);

var

CI: TCursorInfo;

Icon: TIcon;

II: TIconInfo;

r: TRect;

begin

bmp.Width:= Screen.Width;

bmp.Height:= Screen.Height;

BitBlt(bmp.Canvas.Handle,0,0,Screen.Width,Screen.Height,

GetDC(GetDesktopWindow),0,0,SRCCopy);

//дорисуем курсор

Icon:=TIcon.Create;

r:=Rect(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));

CI.cbSize:=SizeOf(CI);

if (GetCursorInfo(CI)) and (CI.flags=CURSOR_SHOWING) then

begin

Icon.Handle:=CopyIcon(CI.hCursor);

if GetIconInfo(Icon.Handle,II) then

bmp.Canvas.Draw(ci.ptScreenPos.x - Integer(II.xHotspot) - r.Left, ci.ptScreenPos.y - Integer(II.yHotspot) - r.Top, Icon);

end;

end;

 Автор P.O.D        

На форме у меня стоит TImage (его можно сделать невидимым)

 

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

 

Я хочу представить простой мульти-экран эмулятор, написанный на Delphi.

Он состоит в небольшой форме размещения в правом нижнем углу экрана, прямо над трее, которая состоит из 5 кнопок.

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

и так далее с другими кнопками. Когда я вернусь к одной из кнопок,  Я буду видеть только заявки, открытые в этом конкурсе без других.

Фокус состоит в том, чтобы сделать следующие шаги непосредственно перед нажатием другой кнопки:

 

сode:

var

Image3: TImage;

 

procedure TSaverForm.CopyScreen;

var

 

DeskTopDC: HDc;

DeskTopCanvas: TCanvas;

DeskTopRect: TRect;

begin

 

Image3 := TImage.Create(SaverForm);

with Image3 do

begin

   Height := Screen.Height;

   Width := Screen.Width;

end;

Image3.Canvas.copymode := cmSrcCopy;

DeskTopDC := GetWindowDC(GetDeskTopWindow);

DeskTopCanvas := TCanvas.Create;

DeskTopCanvas.Handle := DeskTopDC;

Image3.Canvas.CopyRect(Image3.Canvas.ClipRect, DeskTopCanvas,

   DeskTopCanvas.ClipRect);

Image2.Picture.Assign(Image3.Picture);

{image2 расположен на целевой форме и выровнен по области клиента}

end;

 

procedure TSaverForm.FormClose(Sender: TObject; var Action: TCloseAction);

begin

 

Image3.Free;

end;

 

 

Code:

type

TSaveRedir = packed record

   Addr: Pointer;

   Bytes: array[0..4] of Byte;

end;

PSaveRedir = ^TSaveRedir;

 

procedure RedirectCall(FromAddr, ToAddr: Pointer; SaveRedir: PSaveRedir);

var

OldProtect: Cardinal;

NewCode: packed record

   JMP: Byte;

   Distance: Integer;

end;

begin

if not VirtualProtect(FromAddr, 5, PAGE_EXECUTE_READWRITE, OldProtect) then

   RaiseLastWin32Error;

if Assigned(SaveRedir) then

begin

   SaveRedir^.Addr := FromAddr;

   Move(FromAddr^, SaveRedir^.Bytes, 5);

end;

NewCode.JMP := $E9;

NewCode.Distance := PChar(ToAddr) - PChar(FromAddr) - 5;

Move(NewCode, FromAddr^, 5);

if not VirtualProtect(FromAddr, 5, OldProtect, OldProtect) then

   RaiseLastWin32Error;

end;

 

procedure UndoRedirectCall(const SaveRedir: TSaveRedir);

var

OldProtect: Cardinal;

begin

if not VirtualProtect(SaveRedir.Addr, 5, PAGE_EXECUTE_READWRITE, OldProtect) then

   RaiseLastWin32Error;

Move(SaveRedir.Bytes, SaveRedir.Addr^, 5);

if not VirtualProtect(SaveRedir.Addr, 5, OldProtect, OldProtect) then

   RaiseLastWin32Error;

end;

 

 

// Example: Replace Application.MessageBox with your own.

 

function MyNewMessageBox(Self: TApplication; const Text, Caption: PChar;

Flags: Longint): Integer;

begin

ShowMessage('New Messagebox');

//....

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

Application.MessageBox('You`ll never see this Text /

   Diesen Text wirst du nie sehen', '...', MB_OK);

end;

 

var

S: TSaveRedir;

 

initialization

RedirectCall(@TApplication.MessageBox, @MyNewMessageBox, @S);

 

finalization

UndoRedirectCall(S);

 

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

 Уверен, что каждый из Вас уже хоть раз видел что-то подобное в действии. При запуске, программа берёт изображение десктопа и разделяет его на определённое количество прямоугольных частей (одинакового размера). После этого часть блоков случайным образом перемещается со своего первоначального места.

 

  

Моя обзорная статья на тему вариантов использования динамически компонуемых библиотек (DLL) вызвала множество вопросов, большая часть которых касалась использования глобальных ловушек (Hook) и размещению разного рода ресурсов в DLL. О ресурсах поговорим в следующий раз, а пока попробуем разобраться с ловушками.

Сразу хочу сделать несколько оговорок: речь в дальнейшем пойдёт только о 32-х разрядной Windows и о глобальных ловушках, т.к. именно при их программировании возникает большинство ошибок; все примеры будут даваться на Delphi, т.к. примеров и описаний для любителей С++ достаточно.