Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Фокус при выводе диалоговых окон в MDI приложениях [D6, Win2k]


Страницы:   1 2

Суслик ©   (2005-06-22 19:07:00) 

Есть проект, состоящий из:
1. unit1 - mdi form
2. unit2 - mdi child

На форме unit2 есть 2 кнопки. После запуска приложения фокус находится на первой кнопке. Используя клавишу tab можно преключаться между кнопками. В кнопке номер 1 есть вызов диалогового окна.

После закрытия диалогового окна пропадает фокус. Судя по результатам анализа (использовал функции winapi GetFocus и GetWindowText) фокус переходит главной форме.

ВОПРОСЫ.
1. Почему так происходит?
2. Как сделать так, чтобы фокус оставался на кнопке номер 1?

unit1.pas


unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;
type
 TForm1 = class(TForm)
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
end.


unit1.dfm

object Form1: TForm1
 Left = 397
 Top = 106
 Width = 798
 Height = 640
 Caption = 'Form1'
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 FormStyle = fsMDIForm
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 13
end


unit2.pas


unit Unit2;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
type
 TForm2 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
 end;
var
 Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
  enabled := false;
  with tform.create(application) do
  begin
     showmodal();
     free();
  end;
  enabled := true;
end;
end.


unit2.dfm


object Form2: TForm2
 Left = 370
 Top = 154
 Width = 870
 Height = 640
 Caption = 'Form2'
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 FormStyle = fsMDIChild
 OldCreateOrder = False
 Position = poDefault
 Visible = True
 PixelsPerInch = 96
 TextHeight = 13
 object Button1: TButton
   Left = 72
   Top = 64
   Width = 75
   Height = 25
   Caption = 'Button1'
   TabOrder = 0
   OnClick = Button1Click
 end
 object Button2: TButton
   Left = 176
   Top = 56
   Width = 75
   Height = 25
   Caption = 'Button2'
   TabOrder = 1
 end
end


project1.dpr


program Project1;
uses
 Forms,
 Unit1 in 'Unit1.pas' {Form1},
 Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.CreateForm(TForm2, Form2);
 Application.Run;
end.


Суслик   (2005-06-24 11:55:00) [1]


>  [35] Gero ©   (23.06.05 22:46)

Без обид :)

-------------

Всем спасибо. Я понял, что есть все-таки не вполне адекватное поведение vcl (т.е. не соотв. справке). Спасибо ИШ, пойду читать, зачем еще WM_MDIACTIVATE нужне, если в моем случае SetFocus вполне успешно работает.


Defunct   (2005-06-24 02:37:00) [2]

В MDI приложениях с Active/Focus явно есть лажа. Например: имеем несколько открытых MDI Child, при изменении размеров главной MDI формы состояние Active получает один MDI Child, при этом фокус находится совсем на другом MDI Child'e. Для лечения наверое надо начинать со свойства Active (лажа именно в нем, значение Active должно соответствовать написаному в справке, и тогда все будет работать как надо) .


Gero   (2005-06-23 22:46:00) [3]


> Суслик ©   (23.06.05 01:25)

Да я не такой тупой каким кажусь.
Может, у меня юмор слишком специфичен?

Ладно, без обид.


Игорь Шевченко   (2005-06-23 19:38:00) [4]


> Вопрос: чем нужно пользоваться функциями GetActiveWindow/SetActiveWindow
> или GetFocus/SetFocus?


Для MDI-форм посылкой сообщения WM_MDIACTIVATE окну MDIClient + SetFocus


Суслик   (2005-06-23 11:04:00) [5]

Спасибо за ответы.

Буду восстанавливать фокус с помощью winapi.

Вопрос: чем нужно пользоваться функциями GetActiveWindow/SetActiveWindow или GetFocus/SetFocus?

С уважением,
Тимохов Дмитрий


evvcom   (2005-06-23 01:56:00) [6]


> я кормиться с проекта буду еще 5 лет, или более (если борланд
> не умрет)

А борланд тут при чем? Ты ж не станешь через пару лет переписывать проект под Delphi 2007! Как видимо, не стал переписывать под D7, когда он появился. Так что жизнедеятельность этого проекта не зависит от дядьки борланда, а скорее зависит от новых идей и технологий.
Всё, я спать. Пиво выветривается, а завтра на работу. :)


Суслик   (2005-06-23 01:40:00) [7]


> evvcom ©   (23.06.05 01:29) [30]

дело не в оплате - это семейный бизнес.
вернее платят - оч хорошо :)
дело в том, что я кормиться с проекта буду еще 5 лет, или более (если борланд не умрет)


evvcom   (2005-06-23 01:29:00) [8]


> 5 не меньше (уже 5 поддерживаю).

А не засиделся ли ты, Дим, на одном месте? Или хорошо платят? Хотя недавно возле Грибоедова я подумал, что второе вроде как не подходит. :)


Суслик   (2005-06-23 01:25:00) [9]


> Gero ©   (23.06.05 01:16) [28]

таки ты не понял, что это тестовый проект дабы показать тебе и остальным суть проблемы?


Gero   (2005-06-23 01:16:00) [10]


Суслик ©   (22.06.05 19:07)
> Есть проект, состоящий из:
> 1. unit1 - mdi form
> 2. unit2 - mdi child



Суслик ©   (23.06.05 01:05)
>  свой продукт по моим расчетам я буду еще поддерживать лет
> 5 не меньше (уже 5 поддерживаю).


Вот это и вправду круто. Где ж ты такого работодателя-то нашел?

:)


evvcom   (2005-06-23 01:12:00) [11]

Тем лучше. Вот за последующие 5 лет, если вдруг что всплывет, нам и расскажешь, а пока не бери в голову. :) Извини, я сам не люблю относиться типа "работает, и слава богу", но в данном случае... Если через WinAPI работает, а по другому нет, то это явные глюки используемых компонент, пусть даже VCL. Необязательно об этом кричать на всех углах, но тем не менее, даже Билл Гейтс не безгрешен, и в WinAPI люди находят ошибки...


Суслик   (2005-06-23 01:05:00) [12]


> evvcom ©   (23.06.05 01:01) [25]

Проблема в том, что свой продукт по моим расчетам я буду еще поддерживать лет 5 не меньше (уже 5 поддерживаю). Так, что это не то, что сказал ЮЗ: откомпилил, работает, и слава богу. Это надолго. Поэтому нужно "в точку".


evvcom   (2005-06-23 01:01:00) [13]

Если этот "глюк" не приводит к краху в последующей работе твоего алгоритма, то это вовсе не глюк, это маленькая "фичка". :) Не бери в голову.


Суслик   (2005-06-23 00:54:00) [14]

Я бы хотел несколько пояснить свою позицию.

Одно дело, когда ты нашел глюк (как тебе кажется), обошел его, а в перспективе получил еще больший глюк. А все дело в том, что исходный глюк не глюк, а твое ламерство.

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

Об этом и речь. Хотелось бы уяснить систематичность найденной мной проблемы.


evvcom   (2005-06-23 00:48:00) [15]

Да, Дим. Все равно генофонд править бессмысленно. Прими его как есть и обойди.


Суслик   (2005-06-23 00:41:00) [16]


> Игорь Шевченко ©   (23.06.05 00:34) [21]

Да....согласен. Так и делаю. А в группы я все же запостю....т.к. я думаю, что сказал - либо дока виновата, либо код...


Игорь Шевченко   (2005-06-23 00:34:00) [17]

Суслик ©   (23.06.05 00:15) [20]


> Все же продолжу утверждать, что реакция vcl на такое с ней
> обращение неадекватна


Дима, хочешь хороший совет ? Не надо возмущаться недостатками VCL - воспринимай ее (VCL), как данность, ищи обходные пути, все равно все в Windows упрется, а он (Windows) написан и протестирован людьми, коих было гораздо больше, чем писателей VCL. Не так давно я тебе приводил пример некорректности (с моей точки зрения) поведения в VCL, однако ж, выход нашел и забыл про это поведение. Советую и тебе идти тем же путем - энтропия во вселенной не так сильно возрастет.

Удачи!


Суслик   (2005-06-23 00:15:00) [18]

>>> Игорь Шевченко

Судя по всему реакция vcl в данному случаена непосредственный вызов winapi происходит не тольков том куске, который ти привел, а в обработчике WM_ACTIVATE.

---------------
Все же продолжу утверждать, что реакция vcl на такое с ней обращение неадекватна. Она была бы адекватна, если бы либо я получал, что хочу (т.е. не поднимал данного топика :))), либо active у формы стал бы вообще = false (но он то равен true), т.е. vcl считает, что форма в фокусе и вызов tcustomform.setfocus не имет эффекта. Мое мнение, что тут есть недостаток документации в области preconditions для ShowModal.


Суслик   (2005-06-23 00:08:00) [19]


> И чего там, спрашивается, дебужить ?

ты, например, видишь где тут выставляется fActive?
Думаю, что не видишь. Значит нужно дебужить. В доке то этого точно нет.


Игорь Шевченко   (2005-06-22 23:52:00) [20]


> Пойду дебужить, реакцию формы на wm_setfocus и прочих контролов
> на wm_killfocus


procedure TCustomForm.WndProc(var Message: TMessage);
var
 FocusHandle: HWND;
....
   case Msg of
     WM_ACTIVATE, WM_SETFOCUS, WM_KILLFOCUS:
       begin
         if not FocusMessages then Exit;
         if (Msg = WM_SETFOCUS) and not (csDesigning in ComponentState) then
         begin
           FocusHandle := 0;
           if FormStyle = fsMDIForm then
           begin
             if ActiveMDIChild <> nil then FocusHandle := ActiveMDIChild.Handle;
           end
           else if (FActiveControl <> nil) and (FActiveControl <> Self) then
             FocusHandle := FActiveControl.Handle;
           if FocusHandle <> 0 then
           begin
             Windows.SetFocus(FocusHandle);
             Exit;
           end;
         end;
       end;

И чего там, спрашивается, дебужить ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо