Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > MDI и TabOrder


Автор: Serggggg 18.6.2004, 12:05
И ещё раз привет всем.
Помогите PLZZZ - на MDi-форме есть куча окошек (TEdit), у каждого из которых есть свой TAB ORDER. Однако перейти по нажатию TAB с одного окна на другое не получается - просто не работает.
Пишу обработчик нажатия клавиши TAB - типа
Код

if Key=VK_TAB then Edit2.SetFocus;


Тот же результат.
Как заставить сработать метод SetFocus?

Автор: _vova_ 18.6.2004, 12:16
А зачем SetFocus?

ActiveControl := Edit2 ;

По-моему проще и работает

Автор: Serggggg 18.6.2004, 13:03
Попробовал - не работает.
Не хочет переходить по TAB'у - хоть руками прописывай, хоть по умолчанию оставляй. sad.gif

Автор: _vova_ 18.6.2004, 13:37
А у этого Edit2 случайно TabStop<>False?

Автор: Serggggg 18.6.2004, 17:08
Пробовал и True и False - результат тот же. sad.gif
Это, наверное, какой-то глюк MDI-окон.

Автор: RA 18.6.2004, 17:36
SendMessage(Edit2.Handle, WM_SETFOCUS, 0,0);

Автор: _vova_ 18.6.2004, 17:49
Не должно такого быть.
Наваял простенкий MDI Application, натыкал целую кучу контролов и ...
все по Tab'у прыгает и туда и обратно.
Попробуй пересоздать форму по новой. У меня, при похожих глюках
этот вариант как правило спасал.

Автор: _hunter 18.6.2004, 17:56
проверил SetFocus() -- рботает без проблем --> ошибка в другом месте

ты KeyPreview установил?

Автор: RA 18.6.2004, 18:33
Во вот так должно работать (МиниЛовушка)

Код


var
 Form1: TForm1;
 hook: HHook;
implementation

{$R *.dfm}

Function hooks(Code:Integer;wParam,lParam:longint):longint; StdCall;
var c:array[0..255] of char;
   nScan:integer;
   boo,Sh:boolean;
begin
  if                                              //
( (code>=0)and(teventmsg(pointer(lparam)^).message=wm_keydown) )
  or                                                
{; Не поверите Alt c неких пор сталsyske'eм}

( (code>=0) and (teventmsg(pointer(lparam)^).message=wm_syskeydown) )
  then
    begin
    nScan:=hibyte((teventmsg(pointer(lparam)^).paramL));
    nscan:=nscan shl 16;
    end;
     GetKeyNameText(nScan,c,256);
     if 'tab'=LowerCase(c) then SendMessage(Edit2.Handle,WM_SETFOCUS,0,0);

end;


procedure TForm1.FormCreate(Sender: TObject);
begin
hook:=SetWindowsHookEx(WH_JOURNALRECORD,@hooks,hInstance,0);

end;



Автор: _vova_ 19.6.2004, 02:20
Зачем так сложно smile.gif, RAdmin.
Вопрос в том, чтобы по Tab'у поменять Control (насколько я понял).
В принцыпе все варианты рабочие и зачем городить огород?
Serggggg, сделай новую форму и все пройдёт.
Вспомни старый анекдот: "Может выйдем, зайдем она и поедет?".

Автор: <Spawn> 19.6.2004, 09:14
Для кого ты пишешь обработчик нажатия? Для формы или контрола? Если для формы, то как тут уже сказали, ставь KeyPreview в True

Автор: Serggggg 19.6.2004, 11:14
Новую форму создавал. Форма создается (просходит Create(Application)) в своем unit'е. Форма создаётся в DLL - может быть проблемы из-за этого. Тот же результат.
Пробовал KeyPreview менять - тот же результат. Только мышкой щелкать надо.
Пробовал и SendMessage(Edit2.Handle, WM_SETFOCUS, 0,0); - результат=0;
Проклятие какое-то. butbut.gif

Автор: Serggggg 19.6.2004, 11:30
Да. Проблема в DLL - я создаю простенькое окошко MDI в библиотеке - TAB не пашет. Точно такое же окно MDI в EXE-модуле - все работает, как часы - TAB работает, как и должен - по умолчанию.
Как быть?

Автор: _hunter 19.6.2004, 12:03
еще раз спрашиваю smile.gif ты KeyPreview для формы установил?

Автор: RA 19.6.2004, 12:41
Цитата(_vova_ @ 18.6.2004, 23:20)
Зачем так сложно smile.gif, RAdmin.
Вопрос в том, чтобы по Tab'у поменять Control (насколько я понял).
В принцыпе все варианты рабочие и зачем городить огород?
Serggggg, сделай новую форму и все пройдёт.
Вспомни старый анекдот: "Может выйдем, зайдем она и поедет?".

Зато 100% smile.gif , и можно работать с формой каторыя скрыта или не в фокусе.

Автор: Serggggg 19.6.2004, 13:20
_hunter, установил конечно. Form1.KeyPreview установлен в True - не пашет. Form1.KeyPreview установлен в False - не пашет.
RAdmin, а если на форме порядка 15 контролов, как в моём случае? И каждому по TAB'у надо передать управление.
Здесь что-то принципиальное, не могу въехать - что именно. MDI-форма, созданная внутри динамически подгружаемой DLL, рубит на корню все переходы по TAB'у. А та же форма (MDIChild) с теми же параметрами и свойствами, созданная в exe-шнике, работает вполне нормально - TAB отлично работает и без обработчиков нажатия кнопок. Может при Create формы ей надо какие-то ещё параметры указать?

Автор: Serggggg 19.6.2004, 13:39
Наткнулся на ещё более интересную деталь - допустим, в главной программе создаётся MDI-окно с 4-мя Edit'ами. Переход по Tab'у возможен только в порядке TabOrder.
Метод SetFocus или SendMessage() не работают. Почему?

Автор: _hunter 19.6.2004, 13:47
проверь, ты нажатие Tab ловиш?
поставь OnKeyDown и фильтр

Автор: RA 19.6.2004, 13:51
Цитата(Serggggg @ 19.6.2004, 10:39)
Наткнулся на ещё более интересную деталь - допустим, в главной программе создаётся MDI-окно с 4-мя Edit'ами. Переход по Tab'у возможен только в порядке TabOrder.
Метод SetFocus или SendMessage() не работают. Почему?

А ты попробуй эти Методы фызывать не из обработчика OnKeyPress а из контрола типа Бутон (Для теста, просто мне кажется что у тебя обработчик ослеп)


Цитата

RAdmin, а если на форме порядка 15 контролов, как в моём случае? И каждому по TAB'у надо передать управление.


Ну если ты используешь мой пример (и он у тебя работает) и у тебя 15 контролов то
подработай код малость:

Код
   
   if 'tab'=LowerCase(c) then
   begin
      if Edit1.Selected then SendMessage(Edit2.Handle,WM_SETFOCUS,0,0);
      if Edit2.Selected then SendMessage(Edit3.Handle,WM_SETFOCUS,0,0);
     
     и тд.........

  end;

Автор: Serggggg 19.6.2004, 14:19
_hunter, так и есть - не хочет обрабатывать нажатие TAB. Нажимаю TAB в нужном окошке - ShowMessage не показывается. Меняю на ENTER, INSERT - все работает.
И в программе, и в DLL. Т.е. программа тупо не замечает нажатия TAB.
Как быть?

P.S. Использовался обработчик OnKeyDown

Автор: _hunter 19.6.2004, 14:27
для начала попробуй отключить TabStop у Edit' ов
если не поможет -- запускай WinSight и смотри куда идут клавиатурные сообщения, особенно TAB

Автор: Serggggg 19.6.2004, 14:58
Отключал - не помогло.
Запускал WinSight - Log прислать не могу - не сохраняется. Скажу так - и у клавиши INSERT (для примера), и у TAB в обработчике есть ShowMessage - при нажатии INSERT WinSight прописывает 11 строчек, при TAB'е - 3.
При нажатии TAB:

WM_KEYDOWN Dispatched 09h 9d VK_TAB Scan 0Fh Down
WM_KEYUP Dispatched 09h 9d VK_TAB Scan 0Fh Up
WM_KILLFOCUS Sent Focus to hwnd 00000000

Автор: _hunter 19.6.2004, 15:06
а теперь расшифровка: smile.gif
окно 09h 9d забрало себе ( Dispatched ) сообщение о нажтии TAB и соответственно фокус стал на 00000000
так что ищи что за оно забирает сообщения

Автор: Serggggg 19.6.2004, 15:36
Глупый вопрос, но не могу понять, как именно использовать WinSight. Перестали появляться сообщения внизу. Делаю Start/Stop, а результата не вижу. withstupid.gif

Автор: _hunter 19.6.2004, 15:44
странно, все перепробывал -- воспроизвести такое не смог

у тебя винда какая?

Автор: Serggggg 19.6.2004, 15:45
2000 Server Service Pack 4

Автор: _hunter 19.6.2004, 15:51
попробуй в Messages поставить All Windows
а в Messages->Processes...->All processes
если не поможет -- переставляй винды smile.gif

Автор: Serggggg 19.6.2004, 16:15
_hunter, я уже не вижу выхода. Отказаться от DLL, наверное, надо. Слишком большие проблемы. Всем спасибо за участие.

Автор: _hunter 19.6.2004, 16:19
выход есть: поставить хук и в нем пересылать сообщеня дальше

а если можно отказаться от DLL -- отказывайся ибо всегда нужно делать проще ( KISS ) smile.gif

Автор: Serggggg 19.6.2004, 16:27
_hunter, я уже пробовал поставить хук, который прислал RAdmin - прога вообще намертво систему завесила.
Так что пойдём по пути наименьшего сопротивления.

Автор: Medved 21.6.2004, 08:12
Вот универсальный код "пробега" по реквизитам:

Код

 if Key = VK_UP then
   SelectNext(Sender as TWinControl,false,true);
 if (Key = VK_DOWN) or (Key = VK_TAB) or (Key = VK_RETURN)  then
   SelectNext(Sender as TWinControl,true,true);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)