Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "KOL";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];

Вниз

Не происходит переключение между формами   Найти похожие ветки 

 
Андрей2   (2004-06-12 23:19) [0]

Имеется три формы. После запуска они все отображаются (Visible = true). Но проблема не в этом - проблема с переключением между формами. Конкретно: при переключении между формами 2 и 3 всё происходит отлично - без глюков. Но вот при переключении на 1-ую форму спустя долю секунды фокус обратно возвращается на форму, с которой происходило переключение. Таким образом переключиться на фору 1 можно только после закрытия форм 2 и 3, хотя при двойном щелчке по заголовку 1-ой она успешно назворачивается, за заголовок успешно перемещается, но системные кнопки (свернуть, развернуть и закрыть) тоже не нажимаются. Как я понял - этот глюк происходит только с главными формами (в KOL по умолчанию 1-ая форма - главная, а остальные - её дочерние). Как исправить этот глюк? (где внести изменения в KOL.pas)


 
Dimaxx   (2004-06-13 00:02) [1]

Код приведи. Чем пользовался для открытия модальных форм?


 
SPeller ©   (2004-06-13 06:33) [2]

Есть такой глюк. Я его давно исправил, но Владимир пока не хочет вносить изменения в kol.pas. Часть внесены уже, но не полностью. Желающим могу выложить здесь все нужные изменения для тестов.


 
Vladimir Kladov   (2004-06-13 08:18) [3]

Нет такого глюка. Положить на главную форму KOLProject, закрыть проект, открыть его и сделать Project|Build.


 
Андрей2   (2004-06-13 09:37) [4]

Отвечаю Dimaxx. Формы - НЕ МОДАЛЬНЫЕ!!!


 
Андрей2   (2004-06-13 09:40) [5]

SPeller. А мне на e-mail: Andr@(собака)mail.ru прислать не можешь? (пишу "(собака)" для предотвращения действий спам-роботов по рассылке спама)


 
Андрей2   (2004-06-13 09:42) [6]

SPeller. Извини. Дал неправильный e-mail. Правильный - Andr-forum@(собака)mail.ru.


 
Андрей2   (2004-06-13 09:44) [7]

Vladimir Kladov. Я так и делаю - так написано в инструкции по использованию KOL, а инструкции я читаю. И данная проблема этим не решается.


 
Андрей2   (2004-06-13 09:44) [8]

Vladimir Kladov. Я так и делаю - так написано в инструкции по использованию KOL, а инструкции я читаю. И данная проблема этим не решается.


 
Vladimir Kladov   (2004-06-13 10:18) [9]

для немодальных не было проблем вообще: Form4.Form.Show; Если это не работает можно еще попробовать Form4.Form.BringToFront;


 
Андрей2   (2004-06-13 11:05) [10]

Vladimir Kladov. Форма отображается без проблем, но пока она отображается невозможно переключиться на главную форму - на Form1 - после кратковременной паузы фокус возвращается на форму, с которой производилось переключение - в вашем слечае на Form4. Вопрос: Как переключиться на Form1 без закрытия Form4.


 
Vladimir Kladov   (2004-06-13 11:48) [11]

Точно так же. Только не из обработчика события, по завершении которого происходит обратное переключение. По-моему, это разумеется.


 
Андрей2   (2004-06-13 12:15) [12]

Vladimir Kladov. Почему Вы меня не понимаете. У меня ПУСТОЙ проект, не ставлю обработчик ни на одно из событий - просто запускаю "три формы" и "наслаждаюсь глюками". Попробуйте сами: создаём проект, добавляем дополнительно ещё две формы (в итоге получается три формы). Переводим его в KOL (сохраняем проект, добавляем на Form1 компонент KOLProject, задаём значение свойства projectDest например Proba, далее на все без исключения формы кидаем кидаем компонент KOLForm, ещё раз сохраняем, из папки, в которую сохранили открываем файл Proba.dpr), делаем, чтобы после запуска были отображены все три формы (через Инспектор объектов или обработчик события OnCreate - не имеет значения), запускаем, пытаемся переключиться со второй или третьей формы на первую и терпим неудачу - фокус фозвращается обртно на вторую или третью (взависимости от того, с какой формы происходило переключение). После того как проделаете - поделитесь своими впечатлениями на форуме.


 
Vladimir Kladov   (2004-06-13 14:20) [13]

Не то написал я. TKOLApplet а не TKOLProject.


 
SPeller ©   (2004-06-13 14:37) [14]

Угу, если использовать аплет, то глюка нет. Только мне не понятно, почему надо заставлять использовать аплет для устранения глюка, если можно внести изменения, которые сократят размер бинарного кода в конечном файле и исправят глюк?


 
Vladimir Kladov   (2004-06-13 15:21) [15]

Мне непонятно, зачем вносить массу изменений и провоцировать новые возможные глюки, которые обязательно появятся при этом, если есть решение, придуманное изначально: Applet для того и предназначался, чтобы играть роль менеджера форм, и я вляется в этом смысле полным аналогом TApplication в VCL.


 
SPeller ©   (2004-06-13 15:23) [16]

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

Всё началось с того, что когда мне понадобились модальные формы, то я столкнулся с рядом проблем, таких как "хитрые" вызов и скрытие модальной формы, описанный выше глюк с фокусом, и ещё пара попутных глюков. После некоторого времени поисков решения и оптимизации я это всё нашёл. Кроме того, моё решение меньше увеличивает размер конечного ЕХЕ.

Доказательство о меньшем размере:
Я сравнивал,  всё в pas-версии, так как моей функции в асм-версии нет, и размер её, естественно, будет больше исходного варианта. Для испытания использовал проект без аплета с тремя формами. На формах кроме стандартных кнопок ничего нет. Для испытаний я сделал следующее:
Разбил свои добавления в kol.pas на части. Условно обозначил их так:

Реализация ShowModalParented - "Parented";
Всё что относится к SetModalResult - "SetMR";
Мой вариант обработчика WM_CLOSE в TControl.WndProc - "WM_CLOSE";

оба куска такого кода в wndprocapp и wndprocform:
   if Self_.fModalForm <> nil then
     SetFocus( Self_.fModalForm.fHandle )
   else
   if (Self_.FCurrentControl <> nil) and not(Self_.fCurrentControl.IsForm xor Self_.fIsApplet) then

заменяющих в обычных условиях такую строку:
   if Self_.FCurrentControl <> nil then
я обозначил как "xor".

А исходный вариант ShowModal - так и оставил "ShowModal".

SetModalResult это write-метод свойства ModalResult и предназначен для гарантированного скрытия формы с экрана при установке ModalResult. Причина в том, что если ModalResult станет отличным от нуля, но при этом в очередь сообщений потока не придёт ниодного сообщения, то форма так и будет висеть на экране. SetmodalResult просто устанавливает нужное значение результата и отправляет окну нейтральное сообщение.

Ниже получил размеры ЕХЕ. Использовалось Delphi 6 + SysDcu. Запись +ХХХ означает подключение части ХХХ моего кода в ЕХЕ.

Что включено:           Размер ЕХЕ:
--------------------------------------------
[ничего]                     24064
+ShowModal                   25600  <---
+WM_CLOSE                    24064
+Parented                    24576
+SetMR                       24576
+xor                         24576
+WM_CLOSE+Parented           25088
+xor+WM_CLOSE+Parented       25088
+xor+WM_CLOSE+Parented+SetMR 25088  <---
 

Выводы делайте сами. Я так думаю, что можно переходить полностью на мой вариант. Для экономии кода я думаю отказаться от SetModalResult вовсе, либо заключить его в скобки вроде {USE_SETMODALRESULT}. Вот мои изменения
полностью:

function WndProcApp
...
 WM_SETFOCUS:
   {$IFDEF NEW_MODAL}
   if Self_.fModalForm <> nil then
     SetFocus( Self_.fModalForm.fHandle )
   else
   if (Self_.FCurrentControl <> nil) and not(Self_.fCurrentControl.IsForm xor Self_.fIsApplet) then
   {$ELSE not_NEW_MODAL}
   if Self_.FCurrentControl <> nil then
   {$ENDIF not_NEW_MODAL}
   begin
     Self_.FCurrentControl.CreateWindow; //virtual!!!
...
end;

function WndProcForm
...
 // with _Self^ do
 WM_SETFOCUS:
   begin
     {$IFDEF NEW_MODAL}
     if fModalForm <> nil then
       SetFocus( fModalForm.fHandle )
     else
     if (FCurrentControl <> nil) and not(fCurrentControl.IsForm xor fIsApplet) then
     {$ELSE not NEW_MODAL}
     if FCurrentControl <> nil then
     {$ENDIF}
     begin
       FCurrentControl.CreateWindow; //virtual!!!
...
end;

{$IFNDEF NEW_MODAL}
function TControl.ShowModalParented(const AParent: PControl): Integer;
begin
 Result := 0;
end;

{$ELSE NEW_MODAL defined}

function TControl.ShowModalParented(const AParent: PControl): Integer;
var FL: PList;
   OldMF,
   F: PControl;
   I: Integer;
begin
 Result := 0;
 if (AParent = nil) then Exit;

 Inc( fModal );
 FL := NewList;
 OldMF := AParent.fModalForm;
 AParent.fModalForm := @Self;

 if AParent.fIsApplet or (AParent.IsMainWindow and AParent.fIsForm) then
 begin
   for I := 0 to AParent.ChildCount - 1 do
   begin
     F := AParent.fChildren.Items[ I ];
     if (F <> @Self) and F.fIsForm and F.fEnabled and F.fVisible then
     begin
       FL.Add( F );
       F.Enabled := FALSE;
     end;
   end;
 end;

 if AParent.fIsForm and AParent.Enabled then
 begin
   FL.Add( AParent );
   AParent.Enabled := FALSE;
 end;

 ModalResult := 0;
 Show;
 while not AppletTerminated and (ModalResult = 0) do
 begin
   WaitMessage;
   AParent.ProcessMessages;
   {$IFNDEF NOT_USE_OnIdle}
   ProcessIdle( @Self );
   {$ENDIF}
 end;

 AParent.fModalForm := OldMF;
 Dec( fModal );
 for I := 0 to FL.Count - 1 do
   PControl( FL.Items[ I ] ).Enabled := True;
 FL.Free;
 Hide;
 Result := ModalResult;
end;
{$ENDIF NEW_MODAL}


Изменения WM_CLOSE уже есть в kol.pas.

В пользу моего варианта есть ещё и тот момент, что в исходном баг: в модальной форме при закрытии никогда не вызывается обработчик OnClose.

Теперь вопрос, который наверняка возник: почему ShowModalParented? Потому что существуют ситуации, когда в приложении нужно показать модальную форму только относительно определенного окна, которое и станет недоступным, а не относительно всего проекта, когда недоступными становятся все окна программы. Запись ShowModalParented( Applet ) в таком случае будет эквивалентна нынешнему ShowModal.

Что конкретно дают мои зменения?
1) Алгоритм вызова модальной формы не зависит от наличия отдельного объекта Applet;
2) Вызов модальной формы производится единственной строкой
  Form.ShowModalParented( SomeFormOrApplet );
Больше не требуется обсолютно никаких действий чтобы вызов и завершение формы были правильными.
3) В модальной форме нет необходимости назначать обработчик OnClose для того чтобы предотвратить уничтожение объекта формы
4) Нет глюка с фокусом. В случае модальных форм — когда Аплет не используется, то при закрытии модальной формы главная никак не может получить фокус, точно так же как описывает здесь автор сабжа.


 
SPeller ©   (2004-06-13 15:28) [17]


> Vladimir Kladov   (13.06.04 15:21) [15]

Дык, можно ведь всё новое заключить в скобки условной компиляции и включать когда захочется. Да и откуда глюки, если программист может ошибиться только в написании строки Form.ShowModal или Form.ShowModalParented? Я ведь исправил два серьёзных глюка - с фокусом и с вызовом OnClose, в придачу уменьшил размер, занимаемый, кодом для модальности, а вы продолжаете говорить что надо использовать Аплет.


 
Андрей2   (2004-06-13 15:37) [18]

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


 
Vladimir Kladov   (2004-06-13 18:56) [19]

добавление TKOLApplet увеличивает код на 300 байт, а всего этого - на 1К. Кроме того, нет асм-кода. Кто его будет писать? Замечу что переход от асм-кода к пас-коду добавляет весьма ощутимо - на пустом проекте.

И вообще KOL.TApplet - это не исправление глюка, а опциональная фича, ее использование изначально было запланировано. Отсутствие его предполагалось только для проектов простейших, из 1 формы.


 
SPeller ©   (2004-06-14 16:11) [20]


> Vladimir Kladov   (13.06.04 18:56) [19]

Неправду говорите. 1Кбайт - это вы преувеличили, потому что 1К - это код для обеспечения модальности. Ваш код ещё больше занимает. А вот та часть кода, которая исправляет глюк с фокусом, которую я обозначал "xor", НИЧЕГО не добавляет (по крайней мере ничтожно мало). И уж гораздо меньше чем Аплет.

-----------------
[ничего]    17920
+Applet     18432
+xor        17920


Ну и где же мой килобайт? А глюк исправлен.


 
Андрей2   (2004-06-30 22:08) [21]

SPeller. Попытался я разобрать ваш код, однако не всё в нём понял - понял только как исправить глюк с переключением на не главные формы. Но мне также хотелось бы и узнать как без глюков отображать модальные формы. Пожалуйста, можно по подробнее? - выложите на форум пояснения к вашему коду или вышлюте мне на e-mail: Andr-forum@(собака)mail.ru (пишу "(собака)" для предотвращения действий спам-роботов) Ваш исправленный вариант KOL.pas. Заранее спасибо.


 
Gandalf ©   (2004-07-02 19:17) [22]

Желательно бы окончательный вариант сюда бросить чтоб оно потом в FAQ ушло.



Страницы: 1 вся ветка

Форум: "KOL";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.035 c
1-1105454109
odessey
2005-01-11 17:35
2005.01.30
А если принтеров несколько. Как назначить нужный?


14-1105389929
palva
2005-01-10 23:45
2005.01.30
Наезд на авторов толстой книги


10-1082451010
Dmitrij_K
2004-04-20 12:50
2005.01.30
Word Basic


1-1105634593
emfw
2005-01-13 19:43
2005.01.30
Движки


1-1105894004
slart
2005-01-16 19:46
2005.01.30
Подскажите компонент





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский