Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Создание процедуры "копирование" [D7]


Страницы:   1 2

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 = ''"
теперь  предназначен для того, чтобы показать невозможность копирования "пустоты", как во всех текстовых редакторах.
Вот как-то так оно и получается.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо