DLL化したフォームでPositionを有効にするには?

解決


ぴよちゃん  2006-11-14 21:21:52  No: 23927  IP: 192.*.*.*

DLL化したフォームのPosition にpoMainFormCenter  あるいは、poOwnerFormCenter を指定しているのですが
いずれの場合も、画面の中央に表示されてしまいます。
さらに、このフォームからCreateして表示されたフォームのPosition も効きません。
DLL内でフォームの表示位置を変えるには、明示的に位置を指定するしか方法はないのでしょうか。


参考までのコードを書いておきます。

function FHBody(Comp: TComponent; H: THandle): boolean;
var
  FHBody: TFHBody;
begin
  result := false;
  Application.Handle := H;

  FHBody := TFHBody.Create(Comp);    <--- Comp には、呼び出し元のSelf(Form1)が入っています。
  try
    if FHBody.ShowModal = mrOk then
      result := true
    else
      result := false;
  finally
    FHBody.Release;
  end;
end;


procedure TFHBody.Button1Click(Sender: TObject);
begin
            ・
            ・
  Form2 := TForm2.Create(Self);
            ・
            ・
end;

編集 削除
うんと  2006-11-14 21:41:52  No: 23928  IP: 192.*.*.*

> function FHBody(Comp: TComponent; H: THandle): boolean;

まず最初に、DLL にオブジェクトをわたしてはいけません。DLL がコンパイルされた
ときのライブラリと、呼びだすアプリの使っているライブラリは、たとえ同じ環境で
コンパイルされたものでも、同一ではありません。共通のパッケージを使わない
限り、DLL との間で、クラスのインスタンスの受け渡しはできません。

> いずれの場合も、画面の中央に表示されてしまいます。

それは、DLL の中でメインフォームを知る手段がないからで、当然です。

> さらに、このフォームからCreateして表示されたフォームのPosition も効きません。

これも同じ意味で当然です。

編集 削除
ぴよちゃん  2006-11-15 08:13:31  No: 23929  IP: 192.*.*.*

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

> まず最初に、DLL にオブジェクトをわたしてはいけません。
これは知りませんでした(^_^;)

上のコード内のCompについて、
TForm(Comp).Top
TForm(Comp).Left
などは、メインフォームの情報を伝えていたのですが、これはDLLと呼び出し側の環境が
たまたま一致していた、ということでしょうか。

それから、Form2 の件ですが、Form2のオーナーは、Form2 := TForm2.Create(Self); としているので、
FHBody だと思います。それなのに、なぜ、poOwnerFormCenter が効かないんでしょうか?


よろしくお願いします。

編集 削除
うんと  2006-11-15 10:42:29  No: 23930  IP: 192.*.*.*

> それなのに、なぜ、poOwnerFormCenter が効かないんでしょうか?

すみません。いまは検証できないのですが、Delphi ではDLL でない普通のフォームは
Application オブジェクトをオーナーとして作成されます。ですから、Position は
それを前提に実装されてるんじゃないですか。わかりませんが。DLL のなかにも
Application オブジェクトはありますが、呼び出し側の Application とは
同一ではありません。

編集 削除
にしの  2006-11-15 19:12:24  No: 23931  IP: 192.*.*.*

> DLL のなかにも
> Application オブジェクトはありますが、呼び出し側の Application とは
> 同一ではありません。

補足です。
DLL側にはEXE側とは違うApplicationオブジェクトがありますが、EXE側のApplicationオブジェクトをDLL側に渡して上書きすることで、強引にEXE側のApplicationオブジェクトを使用することができます。
DLL側フォームなどを作成する前に渡してください。

編集 削除
うんと  2006-11-15 22:06:03  No: 23932  IP: 192.*.*.*

> EXE側のApplicationオブジェクトをDLL側に渡して上書きすることで

これはオススメできません。理由はまえにも書きましたとおりです。
DLL でつくられたフォームは、呼び出し側からみると、たんにダイアログだと
割り切って、表示位置を設定したければ、呼び出し時にパラメータとして
渡すようにした方がいいです。

編集 削除
ぴよちゃん  2006-11-16 03:06:38  No: 23933  IP: 192.*.*.*

みなさん、ありがとうございます。

結局、うんとさんが最後におっしゃったように、呼び出し元フォームの位置情報をDLLに渡して
表示したい場所に表示するようにしました。

DLLを呼び出して表示される1次フォームについては、メインフォームが無い、ということで納得ですが、
このフォームでCreateされた2次フォームの位置に関して、明らかにオーナーがあるのに
OwnerFormCenterが効かないのは、ある意味バグかもしれませんね。

編集 削除