![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Фокус при выводе диалоговых окон в MDI приложениях [D6, Win2k]
Суслик © (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;
И чего там, спрашивается, дебужить ?