-
перехватываю комбинацию в onkeydown контрола мне необходимо чтобы работала моя вставка в clipboard, а не системная
if (ssCtrl in Shift) and (Key = Ord('C')) then
begin
Clipboard.Clear;
MYPasteToClipBoard;
end; такой код не фурычит в OnKeyUP - работает - но нужно долго держать клавиши и отпускать в определенной последовательности, сначала 'С' затем Ctrl. С помощью таймера можно заставить работать но это блин смешно и криворуко. Существует ли корректный код для запрета CTRL+C (именно чтобы система не лезла в буфер)?
-
> allrussia (21.05.10 05:07)
> перехватываю комбинацию в onkeydown контрола
WM_COPY ?
-- Regards, LVT.
-
брось на форму edit положми в него текст потом Edit.Selettall. edit.copytoclipbord попробуй мож пойдет
-
тю ты чота я не о том :) если тебе нужно чтоб твои компоненты не реагировали на комбинацию клавишь, то key:=#0 в конце onkeydown ну а если не в твоем окне то только хук на систему вешать.
-
> [0] allrussia (21.05.10 05:07) > перехватываю комбинацию в onkeydown контрола > мне необходимо чтобы работала моя вставка в clipboard, а не системная
IMHO, достаточно перехватить две ф-ии: SetClipboardData, EmptyClipboard Во всяком случае, мне в похожей задачке этого хватило.
-
> Leonid Troyanovsky
> WM_COPY ?
Вы вопрос поняли? Мне нужно чтобы по нажатию Ctrl+C на любом контроле вистема не копировала содержимое в буфер обмена. (Это примерно то же самое что перехват Ctrl+Alt+Del, просто здесь библиотека не участвует) Как скопировать содержимое я знаю.
MKC
если тебе нужно чтоб твои компоненты не реагировали на комбинацию клавишь, то key:=#0 в конце onkeydown
вы тоже особо не поняли видимо: #0 - Это тип Char, а не Word, во вторых - это все равно не поможет (сама система ОС Windows перехватывает CTRL+С, не делфи)
Riply
> IMHO, достаточно перехватить две ф-ии: SetClipboardData, > EmptyClipboard > Во всяком случае, мне в похожей задачке этого хватило.
Прекрасно - подскажите как или привдите рабочий пример
достаточно будет нажать CTRL+C на TEdit или TMemo и чтобы буфер обмена оказался пустым или с предыдущими данными
-
> [5] allrussia (21.05.10 16:25) > Riply > Прекрасно - подскажите как или привдите рабочий пример
"Подсказать как" что ? Как перехватывать API ? Если да, то это хорошо расписано у Рихтера и даже с примерами :), а если нет, то что именно подсказать ?
> достаточно будет нажать CTRL+C на TEdit или TMemo > и чтобы буфер обмена оказался пустым или с предыдущими данными
Эмн... а к чему эта фраза, да еще и выделенная ? Разве данные операции работают не через SetClipboardData, EmptyClipboard ?
-
> onkeydown > OnKeyUP
ну - попробуй onkeypress до кучи if( key = ^c )then begin ... key: = #0; end;
-
> Эмн... а к чему эта фраза, да еще и выделенная ? > Разве данные операции работают не через SetClipboardData, > EmptyClipboard ? спасибо, вот что удалось надыбать function NewMemoProc(wnd:HWND; uMsg:UINT; wParam:WPARAM; lParam:LPARAM):integer; stdcall;
begin
if (uMsg = WM_CUT) or (uMsg = WM_COPY) then uMsg := 0;
result:=CallWindowProc(Pointer(GetWindowLong(wnd,GWL_USERDATA)),wnd,uMsg,wParam, lParam)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(Memo1.Handle,GWL_USERDATA,SetWindowLong(Memo1.Handle, GWL_WNDPROC, LPARAM(@NewMemoProc)))
end;
собственно вопрос: 1. как сделать чтобы применялось для всех edit-, memo-, text-контролов? 2. корректен ли этот код и можно ли избежать такой громоздкости? for i:= 0 to ComponentCount -1 do SetWindowLong(component[i].handle,GWL_USERDATA,SetWindowLong(component[i].handle , GWL_WNDPROC, LPARAM(@NewMemoProc)))
-
han_malign
спасибо вариант хороший, но 1 проблема: когда отпускаешь первым Ctrl начинают вводиться буквы 'C'
2 придется русками везде прописывать на всех контролах и ctrl +C и Ctrl+X (с отловом позиции курсора, а ведь есть еще ctrl+Ins и пр...) + проблема 1
-
тебе надо перехватывать WM_COPY.
В древнем Китае желающим странного отрубали голову. Весьма эффективный метод, надо признать.
-
> Игорь Шевченко © (21.05.10 19:49) [10] > > тебе надо перехватывать WM_COPY.
не тебе, а вам. спасибо за экскурс в историю
а это что (21.05.10 17:11) [8],не перехват WM_COPY? Появились другие вопросы в [8] и [9].
-
allrussia (21.05.10 19:54) [11]
> не тебе, а вам
а нам это нафиг не сдалось
> корректен ли этот код и можно ли избежать такой громоздкости?
Для решения тупой задачи вполне годится такой тупой код.
Но гораздо проще надписать компоненты и в них заменять оконную процедуру на нужную (как это неоднократно демонстрируется в stdctrls.pas)
-
Игорь Шевченко > Для решения тупой задачи вполне годится такой тупой код.
поясните, почему тупой... вы не пользуетесь CTRL+C,CTRL+V? :))
в целом задача такова: корректное копирование русского текста в буфер при нажатии комбинации клавиш CTR+C, Ins в Vista, 7, 2008 из контролов Delphi, не поддерживающих юникод
-
-
Игорь Шевченко
> тоже способ предлагают, без перехвата.
спасибо, но у меня оба эти линка постоянно открыты :) и не только эти, а еше как минимум 3 способа RUSClip - например ничего не дает и не обрабатывается вручную (например через попап меню) скопировать корректно текст не проблема
основная проблема заключается в перехвате CTRL+C
-
allrussia (21.05.10 20:32) [15] Проблема заключается в том, чтобы установить корректную кодовую страницу в Clipboard. Перехватывать кучу клавиатурных комбинаций - это не всегда и не совсем удобно. Можно конечно пробегаться по формам и переустанавливать оконные процедуры, но типов контролов много (кстати, сами формы (RTFS: Dialogs.TMessageForm) тоже могут быть скопированы по Ctrl+C, не только Edit-ы и их производные, и результаты копирования подчиняются тем же правилам кодовой страницы) и для каждого переопределять оконную процедуру, мягко говоря, не очень разумно. Если перехватывать, то лучше надписывать компоненты (можно по способу Geo http://www.interface.ru/home.asp?artId=16753) и в их обработчике WM_COPY, WM_CUT устанавливать нужную кодовую страницу.
-
> allrussia (21.05.10 16:25) [5]
> Вы вопрос поняли? Мне нужно чтобы по нажатию Ctrl+C на любом > контроле вистема не копировала содержимое в буфер обмена. > (Это примерно то же самое что перехват Ctrl+Alt+Del, просто
Вопрос мы поняли. Не надо - не копируй. Хотя, про любой - это, дейс-но, новость.
Перехватом же Ctrl+Alt+Del мы и не заморачиваемся.
-- Regards, LVT.
-
Игорь Шевченко > Проблема заключается в том, чтобы установить корректную > кодовую страницу в Clipboard.
Это я знаю и добиваюсь. Перехватывать кучу клавиатурных комбинаций - это не всегда и не совсем удобно.
Неудобно. Но рука тянется к клавишам, а не ПКМ. Хочется нормальный русский текст по CTRL+C. > Если перехватывать, то лучше надписывать компоненты (можно > по способу Geo http://www.interface.ru/home.asp?artId=16753) >
как "надписывание" поможет перехватить CTRL+С? вы можете показать хоть 1 рабочий пример, где происходит корректное копирование/вставка в/из Memo в/из буфер обмена с помощью системных комбинаций клавиш Ctrl,Shift,C,Ins? вот так?
procedure TForm1.WndProc (var message: TMessage);
begin
if (message.Msg = WM_COPY) or (message.Msg = WM_CUT) then
else
inherited
end; тишина
-
allrussia (21.05.10 22:51) [18] > вы можете показать хоть 1 рабочий пример, где происходит > корректное копирование/вставка в/из Memo в/из буфер обмена > с помощью системных комбинаций клавиш Ctrl,Shift,C,Ins?
Могу показать 1 пример: TForm1 = class(TForm)
Edit1: TEdit;
Memo1: TMemo;
private
FOldMemoWndProc: TWndMethod;
FOldEditWndProc: TWndMethod;
procedure MemoWndProc (var Message: TMessage);
procedure EditWndProc (var Message: TMessage);
end;
var
Form1: TForm1;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
FOldMemoWndProc := Memo1.WindowProc;
Memo1.WindowProc := MemoWndProc;
FOldEditWndProc := Edit1.WindowProc;
Edit1.WindowProc := EditWndProc;
Memo1.Lines.Text := 'Это русский текст';
end;
procedure TForm1.MemoWndProc(var Message: TMessage);
var
LKL: array [0..1023] of char;
begin
if Message.Msg = WM_COPY then
begin
GetKeyboardLayoutName(LKL);
LoadKeyboardLayout('00000419',KLF_ACTIVATE);
end;
FOldMemoWndProc(Message);
if Message.Msg = WM_COPY then
LoadKeyboardLayout(LKL,KLF_ACTIVATE);
end;
procedure TForm1.EditWndProc(var Message: TMessage);
var
LKL: array [0..1023] of char;
begin
if Message.Msg = WM_COPY then
begin
GetKeyboardLayoutName(LKL);
LoadKeyboardLayout('00000419',KLF_ACTIVATE);
end;
FOldEditWndProc(Message);
if Message.Msg = WM_COPY then
LoadKeyboardLayout(LKL,KLF_ACTIVATE);
end; В случае надписанного же компонента в его обработчике сообщений WM_COPY/WM_CUT будет такая же операция мамбл-ванго, как в примере, вызов inherited для обработки сообщения родным контролом и восстановление раскладки.
|