Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Модальное окно оказывается позади, Delphi 7 
:(
    Опции темы
Dmitry1987
Дата 28.8.2013, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 3.5.2008

Репутация: нет
Всего: нет



В приложении из основной формы вызывается модальная (ShowModal). В очень редких случаях, модальная форма оказывается позади основной и приходится с помощью Alt+Tab переключаться на другое приложение, потом обратно к своему, чтобы модальное окно стало поверх основного. Это глюк в библиотеках? Как решить эту проблему? Если после 

Код

ShowModal
 

добавить:

 
Код

SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0,
      SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOOWNERZORDER or
      SWP_NOREPOSITION or SWP_NOSIZE);


решит ли это проблему?

Это сообщение отредактировал(а) Dmitry1987 - 28.8.2013, 14:28
PM MAIL   Вверх
Poseidon
Дата 28.8.2013, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Dmitry1987 @  28.8.2013,  14:28 Найти цитируемый пост)
Это глюк в библиотеках?
 smile 

Цитата(Dmitry1987 @  28.8.2013,  14:28 Найти цитируемый пост)
решит ли это проблему?
Нет, потому как ShowModal останавливает выполнение кода до тех пор пока окно не будет закрыто. Другими словами SetWindowPos уйдет на выполнение когда окно уже закрыто.

Можно увидеть тот участок кода, где вызывается ShowModal? 



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Dmitry1987
Дата 28.8.2013, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 3.5.2008

Репутация: нет
Всего: нет



Код

function XXX_MessageDlgPosHelp(const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; HelpCtx: Longint; var X, Y: Integer;
  const HelpFileName: string): Integer;
begin
  with CreateMessageDialog(Msg, DlgType, Buttons, nil, False, '', nil, nil, '') do
    try
      HelpContext := HelpCtx;
      HelpFile := HelpFileName;
      if X >= 0 then Left := X;
      if Y >= 0 then Top := Y;
      if (Y < 0) and (X < 0) then Position := poScreenCenter;
      Result := ShowModal;
      X := Left;
      Y := Top;
    finally
      Free;
    end;
end;


Код

function CreateMessageDialog(const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; ListItems: TStrings; BoolParam: Boolean;
  BoolCaption: string; ShowEvent: TExMessageDlgShowEvent;
  IniFile: TXXX_IniFile; Section: string; MinWidth: Integer = 200;
  MinHeight: Integer = 75): TForm;
const
  mcHorzMargin = 8;
  mcVertMargin = 6;
  mcHorzSpacing = 10;
  mcVertSpacing = 10;
  mcButtonWidth = 60;
  mcButtonHeight = 14;
  mcButtonSpacing = 10;
var
  DialogUnits: TPoint;
  HorzMargin, VertMargin, HorzSpacing, VertSpacing, ButtonWidth,
  ButtonHeight, ButtonSpacing, ButtonCount, ButtonGroupWidth,
  IconTextWidth, IconTextHeight, X, ALeft, I, K, L, CheckHeight: Integer;
  B, DefaultButton, CancelButton: TMsgDlgBtn;
  IconID: PChar;
  TextRect, R: TRect;
  S: string;
begin
  Result := TMessageForm.CreateNew(Application);
  with Result as TMessageForm do
  begin
    FShowEvent := ShowEvent;
    if Assigned(IniFile) and (Section <> '') then
      PosRestorerNeeded(IniFile, Section)
    else
    if (Section <> '') and Assigned(Application.MainForm) then
      with Application.MainForm do
        for I := 0 to ComponentCount - 1 do
          if Components[I] is TXXX_IniFile then
          begin
            PosRestorerNeeded(TXXX_IniFile(Components[I]), Section);
            Break;
          end;
    if Assigned(ListItems) then
    begin
      BorderStyle := bsSizeable;
      BorderIcons := [biSystemMenu];
      if Assigned(FPosRestorer) then
        FPosRestorer.RestoreSet := [riLeft, riTop, riWidth, riHeight];
    end
    else
      BorderStyle := bsDialog;
    BiDiMode := Application.BiDiMode;
    Canvas.Font := Font;
    DialogUnits := GetAveCharSize(Canvas);
    HorzMargin := MulDiv(mcHorzMargin, DialogUnits.X, 4);
    VertMargin := MulDiv(mcVertMargin, DialogUnits.Y, 8);
    HorzSpacing := MulDiv(mcHorzSpacing, DialogUnits.X, 4);
    VertSpacing := MulDiv(mcVertSpacing, DialogUnits.Y, 8);
    ButtonWidth := MulDiv(mcButtonWidth, DialogUnits.X, 4);
    I := 0;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
    begin
      if B in Buttons then
      begin
        if ButtonWidths[B] = 0 then
        begin
          TextRect := Rect(0,0,0,0);
          case B of
            mbYes:      S := btncaption_yes;
            mbNo:       S := btncaption_no;
            mbOK:       S := btncaption_ok;
            mbContinue: S := btncaption_continue;
            mbAbort:    S := btncaption_abort;
            mbRetry:    S := btncaption_retry;
            mbIgnore:   S := btncaption_ignore;
            mbAll:      S := btncaption_all;
            mbNoToAll:  S := btncaption_notoall;
            mbYesToAll: S := btncaption_yestoall;
            mbCancel:   S := btncaption_cancel;
            mbHelp:     S := btncaption_help;
            else        S := '';
          end;
          Windows.DrawText( canvas.handle,
            PChar(S), -1,
            TextRect, DT_CALCRECT or DT_LEFT or DT_SINGLELINE or
            DrawTextBiDiModeFlagsReadingOnly);
          with TextRect do ButtonWidths[B] := Right - Left + 8;
        end;
        if ButtonWidths[B] > ButtonWidth then
          ButtonWidth := ButtonWidths[B];
        Inc(I);
      end;
    end;
    ButtonHeight := MulDiv(mcButtonHeight, DialogUnits.Y, 8) * Integer(I > 0);
    ButtonSpacing := MulDiv(mcButtonSpacing, DialogUnits.X, 4);
    SetRect(TextRect, 0, 0, Screen.Width div 2, 0);
    DrawText(Canvas.Handle, PChar(Msg), Length(Msg), TextRect,
      DT_EXPANDTABS or DT_CALCRECT or DT_WORDBREAK or
      DrawTextBiDiModeFlagsReadingOnly);
    if BoolCaption <> '' then
    begin
      SetRect(R, 0, 0, Screen.Width div 2, 0);
      DrawText(Canvas.Handle, PChar(BoolCaption), Length(BoolCaption), R,
        DT_EXPANDTABS or DT_CALCRECT or DT_WORDBREAK or
        DrawTextBiDiModeFlagsReadingOnly);
      if R.Right - R.Left > TextRect.Right - TextRect.Left then
        TextRect.Right := TextRect.Left + R.Right - R.Left;
      CheckHeight := R.Bottom - R.Top;
    end
    else
      CheckHeight := 0;
    IconID := IconIDs[DlgType];
    IconTextWidth := TextRect.Right;
    IconTextHeight := TextRect.Bottom;
    if Assigned(IconID) then
    begin
      Inc(IconTextWidth, 32 + HorzSpacing);
      if IconTextHeight < 32 then IconTextHeight := 32;
    end;
    ButtonCount := 0;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then Inc(ButtonCount);
    ButtonGroupWidth := 0;
    if ButtonCount <> 0 then
      ButtonGroupWidth := ButtonWidth * ButtonCount +
        ButtonSpacing * (ButtonCount - 1);
    ClientWidth := Max(IconTextWidth, ButtonGroupWidth) + HorzMargin * 2;
    ClientHeight := IconTextHeight + ButtonHeight + VertSpacing +
      VertMargin * 2;
    Left := (Screen.Width div 2) - (Width div 2);
    Top := (Screen.Height div 2) - (Height div 2);
    case DlgType of
      mtWarning:      Caption := caption_warning;
      mtError:        Caption := caption_error;
      mtInformation:  Caption := caption_information;
      mtConfirmation: Caption := caption_confirm;
      mtCustom:       Caption := caption_other;
      else            Caption := '';
    end;
    if Caption = '' then
      Caption := Application.Title;
    if Assigned(IconID) then
      with TImage.Create(Result) do
      begin
        Name := 'Image';
        Parent := Result;
        Picture.Icon.Handle := LoadIcon(0, IconID);
        SetBounds(HorzMargin, VertMargin, 32, 32);
      end;
    with TXXX_Label.Create(Result) do
    begin
      Name := 'Message';
      Parent := Result;
      WordWrap := True;
      Caption := Msg;
      BoundsRect := TextRect;
      BiDiMode := Result.BiDiMode;
      ALeft := IconTextWidth - TextRect.Right + HorzMargin;
      if UseRightToLeftAlignment then
        ALeft := Result.ClientWidth - ALeft - Width;
      SetBounds(ALeft, VertMargin,
        TextRect.Right, TextRect.Bottom);
    end;
    if mbOk in Buttons then DefaultButton := mbOk else
      if mbYes in Buttons then DefaultButton := mbYes else
        DefaultButton := mbRetry;
    if mbCancel in Buttons then CancelButton := mbCancel else
      if mbNo in Buttons then CancelButton := mbNo else
        CancelButton := mbOk;
    X := (ClientWidth - ButtonGroupWidth) div 2;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then
        with TXXX_Button.Create(Result) do
        begin
          Name := ButtonNames[B];
          Parent := Result;
          case B of
            mbYes:      S := btncaption_yes;
            mbNo:       S := btncaption_no;
            mbOK:       S := btncaption_ok;
            mbContinue: S := btncaption_continue;
            mbAbort:    S := btncaption_abort;
            mbRetry:    S := btncaption_retry;
            mbIgnore:   S := btncaption_ignore;
            mbAll:      S := btncaption_all;
            mbNoToAll:  S := btncaption_notoall;
            mbYesToAll: S := btncaption_yestoall;
            mbCancel:   S := btncaption_cancel;
            mbHelp:     S := btncaption_help;
            else        S := '';
          end;
          Caption := S;
          ModalResult := ModalResults[B];
          if B = DefaultButton then Default := True;
          if B = CancelButton then Cancel := True;
          SetBounds(X, IconTextHeight + VertMargin + VertSpacing,
            ButtonWidth, ButtonHeight);
          Inc(X, ButtonWidth + ButtonSpacing);
          if B = mbHelp then
            OnClick := TMessageForm(Result).HelpButtonClick;
        end;

    if Assigned(ListItems) then
    begin
      ListBoxNeeded(ListItems);
      R.Top := IconTextHeight + VertMargin + VertSpacing;
      R.Left := HorzMargin;
      I := Max(ClientWidth, HorzMargin * 2 + MinWidth);
      R.Right := (I - 2 * HorzMargin);
      K := (I - ClientWidth) div 2;
      ClientWidth := I;
      R.Bottom := Max(50, MinHeight);
      L := R.Bottom + VertMargin;
      ClientHeight := ClientHeight + L;
      Result.Constraints.MinHeight := Height;
      Result.Constraints.MinWidth := Width;
      for X := 0 to ControlCount - 1 do
        if Controls[X] is TXXX_Button then
          with Controls[X] do
          begin
            Top := Top + L;
            Left := Left + K;
          end;
      with R do
        FListBox.SetBounds(Left, Top, Right, Bottom);
    end;

    if BoolCaption <> '' then
    begin
      CheckBoxNeeded(BoolCaption, BoolParam);
      I := -1;
      FCheckBox.Height := Max(FCheckBox.Height, CheckHeight);
      L := mcVertMargin + FCheckBox.Height;
      for X := 0 to ControlCount - 1 do
        if Controls[X] is TXXX_Button then
          with Controls[X] do
          begin
            I := Top;
            Top := Top + L;
          end;
      if I < 0 then
        I := ClientHeight;
      ClientHeight := ClientHeight + L;
      FCheckBox.SetBounds(mcHorzMargin, I, ClientWidth - 2 * mcHorzMargin,
        FCheckBox.Height);
      FCheckBoxY := mcVertMargin;
    end;

    if Assigned(FListBox) then
      LockListBoxBounds;
  end;
end;


PM MAIL   Вверх
Poseidon
Дата 28.8.2013, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Dmitry1987, а если избавится от with и попробовать вызвать форму на прямую?


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Dmitry1987
Дата 28.8.2013, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 3.5.2008

Репутация: нет
Всего: нет



Цитата(Poseidon @ 28.8.2013,  13:01)
Dmitry1987, а если избавится от with и попробовать вызвать форму на прямую?

это проблему не решает.

попробую вставить Application.ProcessMessages перед вызовом ShowModal - вроде как должно помочь.
PM MAIL   Вверх
Rrader
  Дата 29.8.2013, 05:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 70
Всего: 191



Dmitry1987, два предположения, если это Delphi 7
1.
Код

// Заменить Application на форму, от которой вызывается модальное сообщение
Result := TMessageForm.CreateNew(MainForm);

2.
Код

// Фикс модальности в старых Delphi
procedure TMessageForm.FormCreate(Sender: TObject);
begin
  SetWindowLong(Handle, GWL_HWNDPARENT, MainForm.Handle);
end;



--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Dmitry1987
Дата 29.8.2013, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 3.5.2008

Репутация: нет
Всего: нет



Application.ProcessMessages решил проблему
PM MAIL   Вверх
MetalFan
Дата 29.8.2013, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



кстати, нет и нет, да иногда и у приложений, собранных в xe-xe4, такой баг проскакивает. крайне редко, но бывает....


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Dmitry1987
Дата 29.8.2013, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 3.5.2008

Репутация: нет
Всего: нет



Такая проблема наблюдается только в приложениях, написанных в delphi 7, причем не только с модальными формами, но и с MessageBox'ами. В приложениях, написанных в Delphi XE-... подобной проблемы не замечал ни я, ни клиенты.
PM MAIL   Вверх
northener
Дата 29.8.2013, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: 8
Всего: 20



Цитата(Dmitry1987 @  29.8.2013,  14:26 Найти цитируемый пост)
Такая проблема наблюдается только в приложениях, написанных в delphi 7

Никогда не держал в руках шашек Д7, а проблема была замечена неоднократно. Как со своими окнами, так и с несвоими. И без всякой логики.


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0569 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.