Использование события KeyDown в родительском окне приложения Delphi Mdi - PullRequest
1 голос
/ 22 октября 2008

Как заставить событие KeyDown работать в родительском окне MDI-приложений Delphi (2007), даже если дочернее окно имеет фокус?

Я хотел бы реализовать комбинацию клавиш (F1), которая вызывает экран справки в приложении MDI. Я добавил процедуру KeyDown в родительское окно MDI и включил KeyPreview в родительском и дочернем окнах, но это не работает, как ожидалось.

Если я поставлю точку останова в коде родителя KeyDown, я увижу, что он никогда не выполняется, даже если дочерние окна не открыты. Но если я добавлю тот же код в дочернее окно, он будет работать нормально.

Есть ли способ заставить родительское окно получать нажатия клавиш, даже если дочернее окно имеет фокус, так как добавление кода в 25+ швов форм немного расточительно?

Ответы [ 4 ]

4 голосов
/ 22 октября 2008

У меня была точно такая же проблема на этой неделе! Я исправил это, создав действие в ActionManager в основной форме. Это действие открывает файл справки и для него назначается комбинация клавиш F1. Это также работает для всех дочерних экранов MDI.

2 голосов
/ 22 октября 2008

Как заставить событие KeyDown работать в родительском окне MDI-приложений Delphi (2007), даже если дочернее окно имеет фокус?

В качестве более общего решения (для приложений, отличных от F1 для справки), я использую код, подобный этому, чтобы перехватить событие нажатия клавиш в основной форме. Это получает все ключи, независимо от того, что, даже когда дочерний элемент MDI активен. В этом примере я делаю противоположное тому, что вы пытаетесь сделать (я хочу, чтобы сообщение обрабатывалось моей дочерней формой, а не основной формой), но концепция перехвата ключей в родительской форме та же).

Application.OnMessage := AppMessage;

procedure TMainForm.Appmessage(var Msg: TMsg; var Handled: Boolean);
var
  message: TWMKey;
begin
  If (msg.message = WM_KEYDOWN) and
     ( LoWord(msg.wparam) = VK_TAB ) and
     (GetKeyState( VK_CONTROL ) < 0 ) and
     Assigned( ActiveMDIChild ) then
  Begin
    Move( msg.message, message.msg, 3*sizeof(Cardinal));
    message.result := 0;
    Handled := ActiveMDIChild.IsShortcut( message );
  End;
end;
2 голосов
/ 22 октября 2008

Вы можете использовать локальный (глобальный не требуется) хук клавиатуры . Вы также можете извлечь все ваши дочерние MDI-формы из базового класса формы signle и реализовать его там один раз. Вы обнаружите, что этот дизайн пригодится и для других проблем.

редактировать

Горячие клавиши / ярлыки для приложений также могут быть реализованы с помощью события TApplication.OnShortCut. Смотри http://delphi.about.com/od/adptips2004/a/bltip0904_3.htm

F1 уже является стандартным справочным ярлыком, который запускает TApplication.OnHelp. Так, может быть, вы хотите использовать событие OnHelp? А если вы используете свойства HelpFile, HelpContext, HelpType и HelpKeyword, вам, вероятно, даже не потребуется реализовывать какой-либо код вообще.

1 голос
/ 22 октября 2008

F1 справочная обработка встроена в Delphi, поэтому все, что вам нужно сделать, это правильно обрабатывать справочные сообщения. Это может быть так же мало, как установка свойства справочного файла для приложения. Вы можете установить определенные страницы с помощью формы? свойства.

В основном, просто используйте предоставленную справочную систему и забудьте о нажатиях клавиш. Это Delphi - вам не нужно много работать.

...