Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.06.2009, 14:59   #1
8alig8
Пользователь
 
Аватар для 8alig8
 
Регистрация: 03.06.2008
Сообщений: 11
Восклицание Старая песня об активации MDI Child на новый лад

Здравствуйте. Последние несколько дней активно разрабатываю тему по MDI формам. Уже решил несколько проблем, набрал разгон - и стукнулся об стенку проблемы активации MDI Child окна.

Посмотрел я несколько форумов, здесь перелопатил все темы, которые мне выдал поисковик по запросу "mdi" и выяснилось, что тема очень заежженая, но так конкретно и не решенная.

Я попробывал все предлагаемые способы активации дочернего окна. Опишу их на основе используемой мной конструкции.
Алгоритм: ищем среди созданных child окно с заданым Caption(кстати по Name искать не хочет)->если нету такого - то создаем, если есть - то активируем.
Кстати сказать активировать child я собираюсь тоже из child, а не с главной формы. Для этого я просто в разделе Implemintation прописал
uses Main;

Способ 1. Метод show.

Код:
procedure TFormPNakl.cxgrdbclmnDoctexttovarnamePropertiesButtonClick(
  Sender: TObject; AButtonIndex: Integer);
var
  i : Integer;
  Flag : Boolean;
  FmTovarNames : TFormTovarNames;
begin
//Активируем окно выбора товара
  for i := 0 to MainForm.MDIChildCount - 1 do
    begin
      if MainForm.MDIChildren[i].Caption = 'Товары' then
        begin
          MainForm.MDIChildren[i].Show;
          Flag := True;
          Break;
        end;
    end;
  if not Flag then
    begin
      FmTovarNames := TFormTovarNames.Create(Application);
      FmTovarNames.Name := 'fmTovarNames';
      MainForm.AdvOfficeMDITabSet1.AddTab(FmTovarNames);
    end
end;
Скомпилив, получаем: если FmTovarNames создана, то на MainForm.MDIChildren[i].Show; вылезает Access violitation.

Способ 2. ActiveMDIChild;

Хотя подозреваю, что так делать нельзя, но напишу, что видел
Заменяем строку
Код:
MainForm.MDIChildren[i].Show;
на
Код:
MainForm.MDIChildren[i].ActiveMDIChild;
F9 -> Access violitation.

Способ 3. Обратимся к WinAPI.
Собственно, опять заменяем строку
Код:
MainForm.MDIChildren[i].Show;
на
Код:
ShowWindow(MainForm.MDIChildren[i].Handle,WM_MDIACTIVATE);
Я пробовал вместо WM_MDIACTIVATE использовать WM_SHOW и WM_MDIRESTORE.
Все приводит к одному: Access violitation.

Помогите пожалуйста, а то уже отчаялся.
8alig8 вне форума Ответить с цитированием
Старый 23.06.2009, 15:39   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Слущай а прикрепи ка чюда свой проект в архиве.
Так будет проще анализировать.

Вот впрочем даю такое:
Проект:
Код:
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.
Главная форма:
Код:
unit Unit1;

interface

uses      unit2,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 FormStyle:=fsMDIForm;
end;

procedure TForm1.Button1Click(Sender: TObject);
var f:tform2; i:integer;
begin
   f:=TForm2.Create(form1);
   f.Parent:=self;
   f.Caption:=TimeToStr(now);
   f.Show;
 ListBox1.AddItem(f.Caption,f);
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var f:TForm2;
begin
 f:=TForm2(ListBox1.Items.Objects[ListBox1.itemindex]);
 if (f<>nil) then begin
  f.BringToFront;
  f.WindowState:=wsNormal;
 end;
end;

end.
здесь я в Листбоксе выбираю нужное окно и его привожу "наверх"

Это подчиненные окна
Код:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
 FormStyle:=fsMDIChild;
end;

end.
Пояснения нужны?
I'm learning to live...

Последний раз редактировалось Stilet; 23.06.2009 в 15:46.
Stilet вне форума Ответить с цитированием
Старый 23.06.2009, 16:11   #3
8alig8
Пользователь
 
Аватар для 8alig8
 
Регистрация: 03.06.2008
Сообщений: 11
По умолчанию

Код предельно ясен, сейчас попробую.
8alig8 вне форума Ответить с цитированием
Старый 11.08.2015, 15:40   #4
le7o
Форумчанин
 
Регистрация: 19.05.2011
Сообщений: 116
По умолчанию

А как в данном случае удалить из ListBox item при закрытии выбранной формы?

Цитата:
Сообщение от Stilet Посмотреть сообщение
Слущай а прикрепи ка чюда свой проект в архиве.
Так будет проще анализировать.

Вот впрочем даю такое:
Проект:
Код:
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.
Главная форма:
Код:
unit Unit1;

interface

uses      unit2,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 FormStyle:=fsMDIForm;
end;

procedure TForm1.Button1Click(Sender: TObject);
var f:tform2; i:integer;
begin
   f:=TForm2.Create(form1);
   f.Parent:=self;
   f.Caption:=TimeToStr(now);
   f.Show;
 ListBox1.AddItem(f.Caption,f);
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var f:TForm2;
begin
 f:=TForm2(ListBox1.Items.Objects[ListBox1.itemindex]);
 if (f<>nil) then begin
  f.BringToFront;
  f.WindowState:=wsNormal;
 end;
end;

end.
здесь я в Листбоксе выбираю нужное окно и его привожу "наверх"

Это подчиненные окна
Код:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
 FormStyle:=fsMDIChild;
end;

end.
Пояснения нужны?
le7o вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача параметров между MDI Child 8alig8 Общие вопросы Delphi 7 22.06.2009 16:39
Старая тема bumbarashko Помощь студентам 0 08.04.2009 05:31
Старая тема bumbarashko Помощь студентам 0 04.04.2009 03:25
Ошибка создания MDI Child формы VVVadim Общие вопросы Delphi 7 05.06.2008 19:25
MDI Child форма в единственном екземпляре VVVadim Общие вопросы Delphi 3 29.02.2008 18:18