Как скинуть в буфер обмена(Ctrl+C) текстовую информацию?
volvo
16.09.2006 0:42
Ты имеешь в виду программно? Или чтоб скопировать текст программы из окна в ClipBoard? Программно - надо смотреть (опять же, программа оконная или консоль)... Если чтоб скопировать - то Edit -> Copy To Windows
Bokul
16.09.2006 0:44
Надо програмно из консоля. Возможно?
volvo
16.09.2006 0:45
Я думаю, да... Сейчас гляну...
volvo
16.09.2006 1:49
Значится, так:
первая часть реализована у Vit-а в DRKB: Системные функции и WinAPI -> Windows -> Консольные приложения -> Как захватить весь вывод в консоли? (с незначительными переделками возвращает строку, содержащую все, что было записано в консоль), а вот со второй частью (а именно - сам процесс копирования в ClipBoard) есть проблемы... Нужно передавать в OpenClipboard() Application.Handle, которого, как ты понимаешь, у консольного приложения нет в том виде, как у приложения оконного... Да и юнита ClipBrd нет в FreePascal-е, ибо это часть VCL...
virt
16.09.2006 2:01
volvo
а в fcl или lcl аналог есть? В fcl нашел только clipboard в gtk2 и под morphos.
rd: LongWord; buf: array[0 .. pred(size)] of char;
function GetConsoleWindow: THandle; var S: AnsiString; C: Char; begin Result := 0; Setlength(S, MAX_PATH + 1); if GetConsoleTitle(PChar(S), MAX_PATH) <> 0 then begin C := S[1]; S[1] := '$'; SetConsoleTitle(PChar(S)); Result := FindWindow(nil, PChar(S)); S[1] := C; SetConsoleTitle(PChar(S)); end; end;
procedure grabber(); var Data: THandle; DataPtr: Pointer; len: integer;
chiBuffer := chiBuffer + buf[i]; if succ(i) mod 80 = 0 then chiBuffer := chiBuffer + #13#10;
end;
if OpenClipboard(GetConsoleWindow) then try { opening clipboard succeeded... } len := Length(chiBuffer) + 1; Data := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE, len); try
{ Заполняем чем-то экран } for i := 1 to 10 do writeln('Wow !!! Wow !!! Wow !!! ', i);
{ и забираем его содержимое в буфер } grabber;
end.
Bokul, Единственный недостаток программы (кстати, можно попробовать его избежать как - догадайся сам) - при копировании ВСЕ строки содержат по 80 символов, и если из них "нужных" - 10, то 70 остальных - пробелы...
Да... Еще кое-что... Надо бы добавить программное определение числа символов в строке, а то мало ли, может у кого-то 40 установлено, будет некорректно работать...
Bokul
16.09.2006 8:53
Ух, спасибо большое , сейчас буду разбираться, только не мог бы ты выложить файл с исходником - при копирование форматирования пропадает.
Bokul
16.09.2006 9:55
Компиляция не проходит... Ide ругается на 66 строчку - Move(pchar(chiBuffer)^, DataPtr^, len);
Цитата
Error: Illegal type conversion: 'ShortString' to '^Char'
Добавил потом: наконец-то разобрался как работает этот код! И всего-то спустя 2 часа, но почему возникает ошибка, я так и не понял. Почему вообще компилятор проверяет тип переменных в этой функции? В справке написано, что не должен...
volvo
16.09.2006 16:11
А у тебя совместимость с Delphi установлена в настройках? Если нет, то первой строкой программы добавляй
{$mode DELPHI}
Bokul
16.09.2006 22:04
Спаибо Volvo, теперь все работает . Компилятор и раньше писал что-то про mode, только я поставил вместо {$mode DELPHI} {$mode ObjFpc}.
Осталось несколько моментов, которые я не понял:
Цитата
Setlength(S, MAX_PATH + 1);
Откуда взялась переменная MAX_PATH? Или это константа? Чему она ровна?
Цитата
C := S[1]; S[1] := '$'; --------- S[1] := C;
Для чего сначала первому символу строки присваивать символ '$', а потом возвращать предыдущее значение? Чтобы снизить вероятность нахождения другого окна с тем же именем?
Цитата
chiBuffer: string; ---------------------- for i := 0 to pred(rd) do begin chiBuffer := chiBuffer + buf[i];
Сколько символов помещается в string? Я думал 255... а тут получается больше 400 - rd = size = 80 * 50, да плюс еще 50 раз по #13#10. Получается 500 символов. Я не прав?
volvo
16.09.2006 22:51
Цитата(Bokul @ 16.09.2006 18:04)
Откуда взялась переменная MAX_PATH? Или это константа? Чему она ровна?
Константа... Описана в модуле SysUtils, в свою очередь равна константе MaxPathLen (из модуля System) = 256 (зависит от ОС)
Цитата(Bokul @ 16.09.2006 18:04)
Для чего сначала первому символу строки присваивать символ '$', а потом возвращать предыдущее значение? Чтобы снизить вероятность нахождения другого окна с тем же именем?
Именно так... Вообще Microsoft в этом случае рекомендует заменить заголовок окна на сгенерированный GUID, чтобы вообще исключить возможность присутствия второго такого же заголовка, но я думаю, это лишнее
Цитата(Bokul @ 16.09.2006 18:04)
Сколько символов помещается в string? Я думал 255... а тут получается больше 400 - rd = size = 80 * 50, да плюс еще 50 раз по #13#10. Получается 500 символов. Я не прав?
К сожалению, нет Или к счастью... В FPC String = AnsiString в режиме совместимости с Дельфи, а
Цитата(ref.pdf)
3.2.4 Ansistrings Ansistrings are strings that have no length limit. They are reference counted and null terminated.
P.S. Кстати, чтобы убрать лишние пробелы (о чем я говорил выше), достаточно сделать так:
{ Это уже есть в программе ... } chiBuffer := ''; for i := 0 to pred(rd) do begin
chiBuffer := chiBuffer + buf[i]; if succ(i) mod 80 = 0 then chiBuffer := chiBuffer + #13#10;
end;
{ А вот это надо добавить ... } while pos(' '#13#10, chiBuffer) > 0 do chibuffer := stringreplace(chibuffer, ' '#13#10, #13#10, [rfreplaceall]); ...
Bokul
16.09.2006 23:12
Цитата
while pos(' '#13#10, chiBuffer) > 0 do chibuffer := stringreplace(chibuffer, ' '#13#10, #13#10, [rfreplaceall]);
Круто, классный способ! Я знал, что надо делать и где надо исправлять, но как определить, какие пробелы надо удалять еще надо было подумать.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.