MDIアプリでの画面表示について

解決


サトウ  2013-05-03 00:49:34  No: 44496

以下のプログラムのように
画像を複数表示するMDIアプリケーションを作成しています。
親画面の画面サイズはあらかじめ最大化しています。

画面表示はWindowTileVertical.Execute(「左右に並べて表示」)を使用して、
表示画面枠いっぱいに最大化して、3画面並ぶようにします。
「左右に並べて表示」はメニューバーに追加済みです。

procedure CreateMDIChild(image:string);
var
  Child:MDIChild;
begin
  MDIChild.Create(AOwner);
  Child.Image.Picture.LoadFromFile(pChar(image));
end;

begin
  CreateMDIChild('C:\image\aa.jpg');
  CreateMDIChild('C:\image\bb.jpg');
  CreateMDIChild('C:\image\cc.jpg');

  if MDIChildCount > 0 then 
     WindowTileVertical1.Execute;
end;

問題なのが、実行ファイルを動かして、
メニューバーから「左右に並べて表示」を行うと、問題なく
表示枠いっぱいに最大化された上で、表示されるのですが、
上記のプログラムでは最大化されずに、小さいサイズで表示されます。

こちらの回避方法と

また、小フォーム側でサイズを変更することも行なっています。

画像サイズ固定で
const
  Base_Height=3512;
  Base_Width=2486;   

procedure MDIChild.halfshow(Sender: TObject);
begin
  Image.SetBounds(0,0,
                  Round(Base_Width * 0.5),
                  Round(Base_Height * 0.5));
end;

こちらを親フォーム側から3画面ともに適用させるには
どうしたら良いのかわかりません。

解決法をご存知の方、教えてください。
よろしくお願いします。


Mr.XRAY  URL  2013-05-03 20:35:10  No: 44497

>上記のプログラムでは最大化されずに、小さいサイズで表示されます。

提示されたコードでは,再現の確認ができないので分かりません.
  Child:MDIChild; でエラーとなります.
  
>こちらを親フォーム側から3画面ともに適用させるには  
>解決法をご存知の方、教えてください。

解決方法は分かりませんが,以下のようなテストをしてみました.
動作確認環境は,Windows U64(SP1) + Delphi XE Pro です.

この程度のコードと説明内容だったら提示できそうな気がするのですが,
企業秘密かな ?

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateMDIChild('ABC.bmp');
  CreateMDIChild('ABC.bmp');
  CreateMDIChild('ABC.bmp');

  if MDIChildCount > 0 then
     WindowTileVertical1.Execute;
end;

//-----------------------------------------------------------------------------
//  Form2は,このForm1(FormStyle はfsMDIForm)の子フォームでユニット名はUnit2
//  以下の手順でプロジェクトに追加
//  (1) [新規作成][フォーム]で作成
//  (2) [プロジェクト][オプション][フォーム]で[使用可能フォーム]にする
//  (3) FormStyle をfsMDIChild にする
//  (4) TImage を 1 つ配置
//  (5) uses に Unit2 を追加
//-----------------------------------------------------------------------------
procedure TForm1.CreateMDIChild(image: string);
begin
  Form2 := TForm2.Create(Application);
  Form2.Image1.Picture.LoadFromFile(pChar(image));
end;

//-----------------------------------------------------------------------------
//  上のコードで生成した全ての子フォーム上のImage1のサイズを変更
//-----------------------------------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
var
  i : Integer;
begin
  if not Assigned(Form2) then exit;

  for i := 0 to MDIChildCount - 1 do begin
    TForm2(MDIChildren[i]).Image1.Width  := 200;
    TForm2(MDIChildren[i]).Image1.Height := 250;
  end;
end;


助監督  2013-05-03 22:13:01  No: 44498

検証してたらMr.XRAYさんとかぶってた、、、。
以下、かなり似かよった話ですが、役に立つかなー?

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

解決法は分かりません…。MDIも初めて使いました…のですが、何か参考になれば。

最小プロジェクトを作り、コピー&ペーストでそのまま動かせるコードにした方がテストする人が増えるかと。
CreateMDIChild手続き中のCreate、AOwner、pCharが???だったので、下記のコードでは適当に合わせました…。
それで検証してみると、メニューからもアクション直接Executeでも、うまくタイル状に並びました。
(Delphi6 Personal、WindowsXP)

あと、親MDIフォームから子MDIフォームへアクセスは、MDIChildrenとか配列、リストなどで出来るのでは。

Unit1
------------------------------------------------------------------------
type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    ActionList1: TActionList;
    WindowTileVertical1: TWindowTileVertical;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.dfm}

procedure CreateMDIChild(image:string);
var
  Child: TMDIChild;
begin
  Child:=TMDIChild.Create(Form1);
  Child.Image1.Picture.LoadFromFile(image);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Dir: String;
begin
  Dir:=ExtractFilePath(Application.ExeName);
  CreateMDIChild(Dir+'Test1.jpg');
  CreateMDIChild(Dir+'Test2.jpg');
  CreateMDIChild(Dir+'Test3.jpg');

  if MDIChildCount > 0 then
    WindowTileVertical1.Execute; // 常に機能した
    //N1.Click; //OnShowでのみ機能せず
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  I: Integer;
begin
  for I:=0 to Self.MDIChildCount-1 do begin
    (Self.MDIChildren[I] as TMDIChild).halfshow();
  end;
end;

Unit2
------------------------------------------------------------------------
type
  TMDIChild = class(TForm)
    Image1: TImage;
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    procedure halfshow();
  end;

var
  MDIChild: TMDIChild;

implementation

{$R *.dfm}

const
   Base_Height=100;
   Base_Width=100;

procedure TMDIChild.halfshow();
begin
  Image1.SetBounds(0,0,
                   Round(Base_Width * 0.5),
                   Round(Base_Height * 0.5));
end;


サトウ  2013-05-05 20:47:56  No: 44499

Mr.XRAY様、助監督様

サンプルありがとうございます。
また、申し訳ございません。

プログラムの方を簡略化した為に、
わかりにくくなりました。
いろいろ裏でやってるもんですから、部分的に抽出しました。

親MDIフォームから子MDIフォームへアクセスについては、

  for i := 0 to MDIChildCount - 1 do begin
    TForm2(MDIChildren[i]).Image1.Width  := 200;
    TForm2(MDIChildren[i]).Image1.Height := 250;
  end;
end;

  for I:=0 to Self.MDIChildCount-1 do begin
    (Self.MDIChildren[I] as TMDIChild).halfshow();
  end;

で解決しました。ありがとうございます。助かります。

今回のプログラムで、
片方のアプリからMDIアプリを呼び出すということをやってます。

CreateMDIChildは、
アプリが立ち上がっていた時はWMCopyMessageの中、
アプリが立ち上がってなかった時は、OnShow時にやってます。

このOnShow時に

  if MDIChildCount > 0 then
     WindowTileVertical1.Execute;

をやると、助監督様の方でのご指摘のように機能しないのです。

CreateのイベントでCreateMDIChildを行うことができませんで、
OnShow時にやっているのですが、こちらのほうが最大化しないのです。

すっごい重要なところ抜けてました。申し訳ございません。

アプリが立ち上がっていた時は最大化するのですが、
Createされた場合の初期値として、最大化させる方法がわかりませんで、
質問させて頂きました。


  2013-05-05 21:37:17  No: 44500

「delphi mdi 最大化」で出ませんか?


Mr.XRAY  2013-05-05 23:27:58  No: 44501

>いろいろ裏でやってるもんですから、部分的に抽出しました。

この掲示板でも,私を含め,多くの方が,指摘していますが,
(今回も助監督さんが書いています)
何か問題を解決するには,新規にプロジェクトを作成して,
その問題となる処理だけをテストすることです.
そうすれば,レスする人が,問題点を指摘することも可能です.

と書いたら,何万行もあるプロジェクトなので,そういうことはできません.
と反応している方がいましたが,私はそうは思いません.
今回も,

>「delphi mdi 最大化」で出ませんか?

というレスがあります.
もしかしたら,そういうことをしたくない場合もあるかも知れません.
処理を簡略化しても,理解できるようなエスパーのような方,
頭のいい方は,多分,この掲示板でレスする中にはいないと思います.
(あくまでも,多分です,多分.... レスはしないけど,見ている方の中にはいるかも知れません)

例えば,以下のようなコードでも,別アプリである ABC.exe を最大化して
表示することができます.
もちろん,他にもあります.

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShellExecute(Handle, 'open', 'ABC.exe', nil, nil, SW_SHOWMAXIMIZED);
end;


Mr.XRAY  2013-05-05 23:32:47  No: 44502

>Createのイベント

どのユニットの Create イベントなのか分かりません.
「できない」「うまくいかない」
と書くより,コードのを方が,確実に相手に伝わります.


サトウ  2013-05-06 02:57:10  No: 44503

あ様

レスありがとうございます。

MDIアプリケーションで子ウィンドウを最大化するには?
https://www.petitmonte.com/bbs/answers?question_id=2211

の方で解決いたしました。

またMr.XRAY様のおっしゃるように、
コードを書くほうが伝わるということは
よくわかります。

今回、新規にプロジェクトを作成して、ということは
サボりましたので、次回ありましたら、
そうするように心がけたいと思います。

皆様ありがとうございました。


Mr.XRAY  2013-05-06 03:17:25  No: 44504

ありゃ,子ウィンドウの最大化だったんですか.
子ウィンドウは,3 つ並べて表示とか書いてあった記憶があるので,
最大化するのは,親ウィンドウかと思ってしまいました.
う〜む.失敗,恥さらしでした.スミマセン.


助監督  2013-05-06 06:59:30  No: 44505

あの、サトウさん、結局どのようにして解決できたのか、概要とポイントだけでも
書いてもらえませんでしょうか。

リンク先の過去ログはそのものズバリの内容ではないので、見ても今ひとつピンと来ないのです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加