C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Запретить ввод из буфера в TComboBox
Gedeon
Отправлено: 20.04.2004, 14:14


Ветеран

Группа: Модератор
Сообщений: 1742



В TEdit для отключения popup достаточно этого
CODE

void __fastcall TForm1::Edit1ContextPopup(TObject *Sender,
     TPoint &MousePos, bool &Handled)
{
   Handled = true;
}
//---------------------------------------------------------------------------

а то же самое с TComboBox нихрена работать не хочет, и как отключить CTRL+V, отловить его не проблема
CODE

void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
   if(Key==86 && Shift.Contains(ssCtrl)){
       //Key = NULL;
   }
}
//---------------------------------------------------------------------------

, а как сделать, чтоб не вставляло? Key = NULL не помогает?
Gedeon
Отправлено: 20.04.2004, 14:31


Ветеран

Группа: Модератор
Сообщений: 1742



с popup проблему решил добавлением пустого TPopupMenu и присвоением его свойству PopupMenu TComboBox, но че-то не пойму, что все-таки делать с CTRL+V
Gedeon
Отправлено: 20.04.2004, 15:42


Ветеран

Группа: Модератор
Сообщений: 1742



Вот нашел решение:
В h файле:
CODE

private: // User declarations
   AnsiString OldText;
   bool WasCTRLV;
   int OldSelStart, OldSelLength;

В конструкторе формы:
CODE

   WasCTRLV = false;

Ну и в самом сср:
CODE

void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
   if(Key==86 && Shift.Contains(ssCtrl)){
       OldText = ComboBox1->Text;
       OldSelStart = ComboBox1->SelStart;
       OldSelLength = ComboBox1->SelLength;
       WasCTRLV = true;
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
   if(WasCTRLV){
       ComboBox1->Text=OldText;
       ComboBox1->SelStart=OldSelStart;
       ComboBox1->SelLength=OldSelLength;
       WasCTRLV = false;
       return;
   }
}
//---------------------------------------------------------------------------

Вот так получилось избежать вставки этими клавишами, как-то некрасиво, но как по другому не знаю.
biggrin.gif Я уже как параноик, сам спрашиваю, сам отвечаю.
olegenty
Отправлено: 21.04.2004, 12:20


Ветеран

Группа: Модератор
Сообщений: 2412



вот тебе ещё вариант, рабочий, я проверял...
1. Две формы Form1 и Form2
2. На Form2 располагается ComboBox1
3. На Form1 ApplicationEvents1
CODE

void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg,
     bool &Handled)
{
   if (Msg.message == WM_KEYDOWN) // событие нажатия на клавишу
   {
       for (int i = 0; i < Application->ComponentCount; i++) // перебираем компоненты с целью поиска Form2
       {
           if (TForm2 *f = dynamic_cast<TForm2 *>(Application->Components[i])) // нашли Form2
           {
               if (f->Active) // если как раз она и является активной
               {
                   if (f->ComboBox1->Focused()) // да при этом ещё и комба в фокусе
                   {
                       if (int(Msg.wParam == 86)) // Да ещё и "v" нажата
                       {
                           Handled = true; // Обработали
                       }
                   }
               }
           }
       }
   }
}


один минус — не проверен Ctrl...
olegenty
Отправлено: 21.04.2004, 12:22


Ветеран

Группа: Модератор
Сообщений: 2412



зато телодвижений меньше намного...
Gedeon
Отправлено: 21.04.2004, 14:13


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (olegenty @ 21/04/2004, 13:24)
зато телодвижений меньше намного...

Так-то оно так, но все равно как-то это некрасиво, ведь наверняка есть способ заставить винду не вставлять текст, вот какой?
olegenty
Отправлено: 21.04.2004, 15:33


Ветеран

Группа: Модератор
Сообщений: 2412



надо поискать инфу, как "отписать" контрол от сообщения
olegenty
Отправлено: 21.04.2004, 15:43


Ветеран

Группа: Модератор
Сообщений: 2412



как-то это должно быть можно через BEGIN_MESSAGE_MAP/END_MESSAGE_MAP.

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

может это можно в конструкторе даже сделать...
olegenty
Отправлено: 21.04.2004, 15:55


Ветеран

Группа: Модератор
Сообщений: 2412



Here is the declaration of a message handler for a user-defined message called CM_CHANGECOLOR.

CODE

#define CM_CHANGECOLOR (WM_APP + 400)
class TMyControl : public TControl

{
protected:
   void __fastcall CMChangeColor(TMessage &Message);

BEGIN_MESSAGE_MAP

 MESSAGE_HANDLER(CM_CHANGECOLOR, TMessage, CMChangeColor)
END_MESSAGE_MAP(TControl)
};

void __fastcall TMyControl::CMChangeColor(TMessage &Message)

{
 Color = Message.LParam;                   // set color from long parameter
 TControl::CMChangeColor(Message);         // call the inherited message handler
}


вот это и есть ответ на твой вопрос...
Пaxa
Отправлено: 22.04.2004, 07:30


Ученик-кочегар

Группа: Участник
Сообщений: 17



Попробуй так: работает 100%
CODE
void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
       if (Key == 86 && Shift.Contains(ssCtrl))
       {
               Clipboard()->Clear();
       }
}
Пaxa
Отправлено: 22.04.2004, 07:36


Ученик-кочегар

Группа: Участник
Сообщений: 17



в .h файле вписать smile.gif #include

Не забудь что есть еще Ctrl+"v" или "V" ну и Shift + ins
Пaxa
Отправлено: 22.04.2004, 07:53


Ученик-кочегар

Группа: Участник
Сообщений: 17



поправка на 101% smile.gif
CODE
if (ComboBox1->SelText != "")
Clipboard()->SetTextBuf(ComboBox1->SelText.c_str());
else Clipboard()->Clear();
olegenty
Отправлено: 22.04.2004, 07:55


Ветеран

Группа: Модератор
Сообщений: 2412



2Паха — может в буфере что-то нужное лежало.
По-моему это неправильно...
Пaxa
Отправлено: 22.04.2004, 07:56


Ученик-кочегар

Группа: Участник
Сообщений: 17



поправка на 101% smile.gif
CODE
if (ComboBox1->SelText != "")
Clipboard()->SetTextBuf(ComboBox1->SelText.c_str());
else Clipboard()->Clear();
Пaxa
Отправлено: 22.04.2004, 07:59


Ученик-кочегар

Группа: Участник
Сообщений: 17



Тогда у тебя та же проблема что и меня мне нужно перехватить нажатие клавиш в моем приложении и поставить на него свой обработчик. Пока в поиске...
Gedeon
Отправлено: 22.04.2004, 08:32


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (olegenty @ 22/04/2004, 08:57)
2Паха — может в буфере что-то нужное лежало.
По-моему это неправильно...


Совершенно верно, буфер трогать не хочется.

QUOTE (Пaxa @ 22/04/2004, 09:01)
Тогда у тебя та же проблема что и меня мне нужно перехватить нажатие клавиш в моем приложении и поставить на него свой обработчик. Пока в поиске...


Дело в том, что перехватить нажатие клавиш не представляет проблемы, работает и то, что я написал в самом начале и то, что приводил Olegenty. Проблема в том, что вставка текста в контрол, если он какой-то текстовый, происходит на уровне Win, отсюда и все проблемы, запретить это по правильному можно только на уровне Api, короче надо рыть MSDN.
olegenty
Отправлено: 22.04.2004, 09:04


Ветеран

Группа: Модератор
Сообщений: 2412



вот самое красивое из того, что я придумал. просто переопределение метода WndProc формы. коротко, понятно, работает. smile.gif

CODE

void __fastcall TForm1::WndProc(TMessage& Message)
{
   if (Message.Msg == WM_KEYDOWN)
   {
       if ((Message.WParam = 86) && (GetKeyState(VK_CONTROL) == -127 ||
               GetKeyState(VK_CONTROL) == -128))
       {
           ShowMessage("Õåðèì êëèïáîðä");
       } else
       {
           TForm::WndProc(Message);
       }
   } else
   {
       TForm::WndProc(Message);
   }
}
Gedeon
Отправлено: 22.04.2004, 09:29


Ветеран

Группа: Модератор
Сообщений: 1742



Вот это уже намного покрасивей, спасибо, буду пока так юзать, если еще чего-то не наковыряю.
olegenty
Отправлено: 22.04.2004, 09:35


Ветеран

Группа: Модератор
Сообщений: 2412



тьфу, это будет верно для Combo, если компонент наследник породить..., я только для формы протестировал...
Пaxa
Отправлено: 22.04.2004, 09:53


Ученик-кочегар

Группа: Участник
Сообщений: 17



Если тебе надо сделать неизменяемым комбик почитай:
Webpage
Gedeon
Отправлено: 22.04.2004, 09:55


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (olegenty @ 22/04/2004, 10:37)
тьфу, это будет верно для Combo, если компонент наследник породить..., я только для формы протестировал...

Ну это понятно, важна сама идея biggrin.gif
Gedeon
Отправлено: 22.04.2004, 10:10


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (Пaxa @ 22/04/2004, 10:55)
Если тебе надо сделать неизменяемым комбик почитай:
Webpage

Спасибо за ссылочку. Просмотр топика, плюс MSDN дал следующий результат:

CODE

void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
   if (Key == 86 && Shift.Contains(ssCtrl))
   {
       SendMessage(GetWindow(ComboBox1->Handle, GW_CHILD), EM_SETREADONLY, (WPARAM)TRUE, 0);
   }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox1KeyUp(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
   SendMessage(GetWindow(ComboBox1->Handle, GW_CHILD), EM_SETREADONLY, (WPARAM)FALSE, 0);
}
//---------------------------------------------------------------------------


Вот это решение приятно радует душу и нет ощущения, что что-то через жопу сделано. Всем спасибо. biggrin.gif
olegenty
Отправлено: 22.04.2004, 11:33


Ветеран

Группа: Модератор
Сообщений: 2412



int EnableGestureSetHRC( HRC hrc, SYV syv, BOOL fEnable )

QUOTE

The following example enables selection, Clipboard functions, and SYV_CIRCLEUPA:

EnableGestureSetHRC( hrc, GST_ALL, FALSE );     // Disable all  
EnableGestureSetHRC( hrc, GST_SEL | GST_CLIP, TRUE ); // Enable sets
EnableGestureSetHRC( hrc, SYV_CIRCLEUPA, TRUE );     // Enable circle A


вот такая функция ещё есть, но, мать её, не работает в лоб, хоть застрелись. вот если заставтить её работать, то это было бы самое красивое решение.

требуется #include
но на этапе link не находит реализации функции
Gedeon
Отправлено: 22.04.2004, 13:17


Ветеран

Группа: Модератор
Сообщений: 1742



А где она описана, не могу найти ни в MSDN, ни в хэлпе. Какой инклуд, положите в тэги, ато не видно.
olegenty
Отправлено: 22.04.2004, 13:29


Ветеран

Группа: Модератор
Сообщений: 2412



CODE

#include <panwin.h>


Описание есть в Windows SDK (только при поиске, по индексу её не видно)

Вернуться в Вопросы программирования в C++Builder