Кент Рейсдорф. BORLAND C++BUILDER. Раздел 3

Кент Рейсдорф. BORLAND C++BUILDER. Страница 377

Прежде, чем мы начнем писать код, который управляет доступом к командам, давайте сначала определим те идеи, которые будут лежать в его основе. В первую очередь примем, что пункты меню Cut и Сору должны быть доступны только в том случае, если в компоненте memo выделен текст (если ничего не выделено, то нечего и вырезать/копировать). Что касается вставки, то нужно сделать так, чтобы доступ к пункту меню Paste был разрешен только при наличии текста в буфере обмена.

Итак, теперь у нас есть набор основных правил, так что можно начинать. Да, еще не все. Остается одна вещь, которую мы должны решить: когда и где мы собираемся разрешать или запрещать доступ?

Мы могли бы разрешать доступ к команде Paste, когда пользователь выбирает в меню пункт Cut или Сору. Если вы помните, у нас есть обработчик событий для пунктов меню Cut, Сору и Paste. Так что мы можем попробовать вставить код в него:

void fastcall TScratchPad::EditCutClick(TObject* Sender)

{

Memo->CutToClipboard();

EditPaste->Enabled = true;

}

Если пользователь выбирает Edit | Cut, мы знаем, что в буфере обмена что-то находится, и можем разрешить доступ к команде Paste. Но когда мы должны запретить доступ к Paste? И что произойдет, если пользователь нажмет комбинацию клавиш Ctrl+X, чтобы вырезать текст, а не воспользу­ется меню? А если пользователь скопирует текст в буфер обмена из другого приложения и захочет вставить его в Scratchpad? Похоже, что у нас появи­лись некоторые проблемы, которые придется как-то решать. Мое правило — «никогда не делай сегодня то, что можно сделать завтра», поэтому давайте отложим на время эту проблему и посмотрим, что мы можем сделать с Cut и Сору.

Команды Cut и Сору должны быть доступны после выделения текста. Это достаточно просто. Если вы посмотрите справочные файлы VCL, то обнаружите, что TMemo имеет свойство SelLength, которое содержит длину выделенного текста в компоненте memo. Таким образом, если значение SelLength больше О, это означает, что пользователь выделил некоторый текст. Вы, наверное, поду­мали: «Отлично! Это действительно очень просто!» Боюсь, что я вас разочарую. У нас нет никакого способа узнать, когда пользователь выделил текст. События OnTextSelected не существует, так что в этом случае мы не можем воспользо­ваться уведомляющими событиями. Мы могли бы использовать системный таймер, но это уж очень некрасивое решение. Кроме того, в системе не так много таймеров и нет никакой гарантии, что мы получим один из них в нужный нам момент. Мы могли бы перехватывать сообщения мыши для компонента memo. Это может сработать. Но что, если пользователь выделит текст клавиа­турой, а не мышью? Тогда мы должны перехватывать все сообщения мыши и все сообщения клавиатуры и каждый раз проверять значение SelLength. Да, решение становится все сложнее и сложнее. А ведь мы еще не разобрались с Paste. Должен же быть какой-то лучший способ! К счастью, есть.

Web-дизайн (с) 2010 All rights reserved