![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание процедуры "копирование" [D7]
Lyonux © (2009-12-27 08:52:00)Здраствуйте! Подскажите пожалуйста, как написать процедуру копирования в буфер таким образом, чтобы копировать можно было из всех edit и memo на форме?
Clipboard.SetTextBuf(PChar( {компонент}.SelText)); - вот как будет осуществляться копирование в буфер. Нужно оптимизировать его для всех компонентов на форме. Вот :) помогите, кто чем может! Пожалуйста! Голову уже сломала(
Делфиец (2009-12-27 20:28:00) [1]Копи-паст из моей коллекции.
{ **** UBPFD *********** by delphibase.endimus.com ****
>> Поместить/получить строку из буфера обмена (Заплатка к стандартным)
Под Win2k попытка вставить русскую строку в Clipboard ClipBoard.AsText:='Проба'
с последующей вставкой в Word'е показывает кракозябрики..
Расследование показало, что виноваты мелкомягкие (как обычно :) )
С целью нивелирования различий между всеми Win-платформами были написаны эти 2 ф-ции..
Принимают на вход/возвращают строку в Unicode - WideString..
но не надо беспокоиться, Дельфи сам вставит при необходимости
конвертацию в/из AnsiString.
Если платформа поддерживает уникод (NT), то используется этот формат,
иначе вызываются стандартные процедуры/ф-ции.
Удачи!
Зависимости: ClipBrd
Автор: Shaman_Naydak, shanturov@pisem.net
Copyright: Shaman_Naydak
Дата: 26 июня 2002 г.
***************************************************** }
Unit UBPFD;
interface
uses windows, ClipBrd;
procedure PutStringIntoClipBoard(const Str: WideString);
function GetStringFromClipboard: WideString;
implementation
procedure PutStringIntoClipBoard(const Str: WideString);
var
Size: Integer;
Data: THandle;
DataPtr: Pointer;
begin
Size := Length(Str);
if Size = 0 then
exit;
if not IsClipboardFormatAvailable(CF_UNICODETEXT) then
Clipboard.AsText := Str
else
begin
Size := Size shl 1 + 2;
Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Size);
try
DataPtr := GlobalLock(Data);
try
Move(Pointer(Str)^, DataPtr^, Size);
Clipboard.SetAsHandle(CF_UNICODETEXT, Data);
finally
GlobalUnlock(Data);
end;
except
GlobalFree(Data);
raise;
end;
end;
end;
function GetStringFromClipboard: WideString;
var
Data: THandle;
begin
if not IsClipboardFormatAvailable(CF_UNICODETEXT) then
Result := Clipboard.AsText
else
begin
Clipboard.Open;
Data := GetClipboardData(CF_UNICODETEXT);
try
if Data <> 0 then
Result := PWideChar(GlobalLock(Data))
else
Result := '';
finally
if Data <> 0 then
GlobalUnlock(Data);
Clipboard.Close;
end;
end;
end;Unit UBPFD;
interface
uses windows, ClipBrd;
procedure PutStringIntoClipBoard(const Str: WideString);
function GetStringFromClipboard: WideString;
implementation
procedure PutStringIntoClipBoard(const Str: WideString);
var
Size: Integer;
Data: THandle;
DataPtr: Pointer;
begin
Size := Length(Str);
if Size = 0 then
exit;
if not IsClipboardFormatAvailable(CF_UNICODETEXT) then
Clipboard.AsText := Str
else
begin
Size := Size shl 1 + 2;
Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Size);
try
DataPtr := GlobalLock(Data);
try
Move(Pointer(Str)^, DataPtr^, Size);
Clipboard.SetAsHandle(CF_UNICODETEXT, Data);
finally
GlobalUnlock(Data);
end;
except
GlobalFree(Data);
raise;
end;
end;
end;
function GetStringFromClipboard: WideString;
var
Data: THandle;
begin
if not IsClipboardFormatAvailable(CF_UNICODETEXT) then
Result := Clipboard.AsText
else
begin
Clipboard.Open;
Data := GetClipboardData(CF_UNICODETEXT);
try
if Data <> 0 then
Result := PWideChar(GlobalLock(Data))
else
Result := '';
finally
if Data <> 0 then
GlobalUnlock(Data);
Clipboard.Close;
end;
end;
end;
end.
end.
Lyonux (2009-12-27 20:20:00) [2]За этот день я узнала полезного о работе с компонентами больше, чем за год программировании в делфи! Никакие книги и электронные справочники не могут объяснить лучше, чем человек. Премного благодарна всем, кто ответил и помог с моей проблемой =) Когда я задавала вопрос, я дажеи подумать не могла, что проблема может иметь такое краткое и изящное решение.
Спасибо, господа! =)
KilkennyCat (2009-12-27 19:50:00) [3]и прочих наследников
Anatoly Podgoretsky (2009-12-27 19:16:00) [4]> {RASkov} (27.12.2009 19:03:32) [32]
Это лучше, поскольку включает и TEdit и TMemo
{RASkov} (2009-12-27 19:03:00) [5]> [17] Lyonux © (27.12.09 13:40)
> If Sender is TEdit then
> Clipboard.AsText:=TEdit(sender).SelText
> else Clipboard.AsText:=TMemo(sender).SelText;
можно заменить на:
If Sender is TCustomEdit then
Clipboard.AsText:=TCustomEdit(sender).SelText;
Lyonux (2009-12-27 18:57:00) [6]вооот оно что..спасибо. не знала.
Anatoly Podgoretsky (2009-12-27 18:46:00) [7]> Lyonux (27.12.2009 18:15:27) [27]
Ну если тебе вставка не нужна, просто игнорируй предложение.
KilkennyCat (2009-12-27 18:20:00) [8]
> исключит возможность вставки, если не текст.
разумеется, если таковая потребуется. Т.е. это он вперед думает.
KilkennyCat (2009-12-27 18:19:00) [9]
> У меня предполагается только пункт "Копировать" в контекстном
> меню,
Это у тебя. А у других приложений свое мнение, но тот же самый клипбоард, в котором может быть что угодно, не только текст. Предложенная Анатолием проверка исключит возможность вставки, если не текст.
Lyonux (2009-12-27 18:15:00) [10]
buf:=TEdit(sender).SelText;
PopupMenu1.Items[0].Enabled := TEdit(sender).SelText <> '';
Clipboard.AsText:=buf;
да не было этого, когда буфер начал очищаться сам собой. это просто была попытка что-то исправить, естесственно, неудачная и безуспешная.
Там же и по поводу пункта "Вставить"
пункт.Enabled := Clipboard.HasFormat(CF_TEXT) ;
Не понимаю. По поводу какого "Вставить"? У меня предполагается только пункт "Копировать" в контекстном меню, если вы об этом.
Anatoly Podgoretsky (2009-12-27 17:03:00) [11]> Lyonux (27.12.2009 16:51:25) [25]
buf:=TEdit(sender).SelText;
PopupMenu1.Items[0].Enabled := TEdit(sender).SelText <> '';
--> Clipboard.AsText:=buf;
Вот поэтому
Теперь по поводу OnChange отмени совет, это я с другим перепутал, в Edit1ContextPopup было правильно. Там же и по поводу пункта "Вставить"
пункт.Enabled := Clipboard.HasFormat(CF_TEXT) ;
Lyonux (2009-12-27 16:51:00) [12]
> Anatoly Podgoretsky © (27.12.09 16:34) [24]
Конечно буфер очищать незачем, это я уяснила ещё на 15м посту данной темы. Но он очищается самостоятельно, когда я нажимаю правую кнопку мыши в edit, не выделив текст. И хуже всего то, что я представления не имею, почему, как и из-за чего это происходит..
Anatoly Podgoretsky (2009-12-27 16:34:00) [13]> Lyonux (27.12.2009 16:16:23) [23]
Непонятно говоришь, о какой очистке буфера ты говоришь и зачем его очищать?
Во вторых в OnChange нужно только запрещать или разрешать пункт меню. Никчему при каждом чихе загонять в буфер новое значение. Обычно копирование в буфер делает пользователь, явно, за прочее бьют автора программ. В данном варианте буфером невозможно пользоваться по назначению.
Lyonux (2009-12-27 16:16:00) [14]
> Anatoly Podgoretsky © (27.12.09 15:49) [22]
СПАСИБО! Ну, наконец-то оно заработало почти как надо. Только я совершенно упустила момент, когда очищается буфер, а делает он это при пустом TEdi(sender).SelText. Что же мне теперь, на onChange ставить строковую переменную и:
procedure TForm1.Edit1Change(Sender: TObject);
var buf:string;
begin
buf:=TEdit(sender).SelText;
PopupMenu1.Items[0].Enabled := TEdit(sender).SelText <> '';
Clipboard.AsText:=buf;
end;
Или я ошибаюсь насчёт очищения буфера и оно происходит при вызове контекстного меню?
Anatoly Podgoretsky (2009-12-27 15:49:00) [15]> Lyonux (27.12.2009 13:40:17) [17]
Это правильно, только это надо делать в обработчике OnChange и в форме
PopupMenu1.Items[0].Enabled := TEdit(sender).SelText <> '';
Anatoly Podgoretsky (2009-12-27 15:46:00) [16]
> зачем лишнюю проверку, события сами собой не назначаются
Это ты расскажешь когда получишь исключение.
Lyonux (2009-12-27 15:42:00) [17]KilkennyCat, Вы не могли бы объяснить смысл данных перестановок и преобразований?
KilkennyCat (2009-12-27 14:46:00) [18]и еще лучше так:
procedure TForm1.Edit1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
begin
If Sender is TEdit then begin
PopupMenu1.Items[0].Enabled:= not (TEdit(sender).SelText = '');
Clipboard.AsText:=TEdit(sender).SelText;
end else Clipboard.AsText:=TMemo(sender).SelText;
end;
KilkennyCat (2009-12-27 14:44:00) [19]
> Вот как-то так
не так.
procedure TForm1.Edit1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
begin
If Sender is TEdit then begin
If TEdit(sender).SelText = '' then PopupMenu1.Items[0].Enabled:=False
else PopupMenu1.Items[0].Enabled:=True;
Clipboard.AsText:=TEdit(sender).SelText;
end else Clipboard.AsText:=TMemo(sender).SelText;
end;
Lyonux (2009-12-27 13:40:00) [20]KilkennyCat прав, но такую проверку можно применить чтобы впихнуть в одну процедуру и действие с Memo, которое так же имеется у меня на форме)
procedure TForm1.Edit1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
begin
If TEdit(sender).SelText = '' then PopupMenu1.Items[0].Enabled:=False
else PopupMenu1.Items[0].Enabled:=True;
If Sender is TEdit then
Clipboard.AsText:=TEdit(sender).SelText
else Clipboard.AsText:=TMemo(sender).SelText;
end;
А проверка
"If TEdit(sender).SelText = ''"
теперь предназначен для того, чтобы показать невозможность копирования "пустоты", как во всех текстовых редакторах.
Вот как-то так оно и получается.