サブフォームをフロントにしたい

解決


Nin  2007-12-20 18:27:40  No: 29033  IP: 192.*.*.*

Execute;でサブフォームを表示させています。

このサブフォームの入力がサブフォーム自体をクリックしないと、
制御できる状態になりません。

このExecute;は独自コンポーネントです。
サブフォームの中で自身をフロントにするやり方があれば教えてください。

初歩的な質問かもしれませんがよろしくお願いします。

編集 削除
KHE00221  URL  2007-12-20 18:58:51  No: 29034  IP: 192.*.*.*

Execute内で実際にフォームを表示する際に

Show や ShowModal で表示していると思うのですが、基本的に表示した時点
でアクティブになると思うのですが・・・

そしてアクティブになれば入力が制御できる状態になると思うのですが?

BringToFront でフロントにする事はできます。
が、これは Show 内部でやっています。

Execute 内でどのようにしてフォームを表示していますか?

編集 削除
Nin  2007-12-21 08:46:28  No: 29035  IP: 192.*.*.*

Execute内で下のような処理で制御をメイン(呼び出し元)に戻しているようです。

  // プログラムの起動
  bRet := CreateProcess(PChar(sPath + '\' + UpperCase(Program_Name) + '.EXE'), PChar(sOption), nil, nil, False, 0, nil, PChar(sPath), infStartup, infProcess) ;

  // プログラムの終了を待つ
  if Exit_Wait then begin

現在作成しているものは「 プログラムの終了を待つ」ものではなく、
制御は呼び出される側に渡したいのですが。

呼び出される側にFormShowにBringToFrontを入れてもダメでした。

編集 削除
KHE00221  2007-12-21 09:30:05  No: 29036  IP: 192.*.*.*

CreateProcessで起動した場合も起動したプロセスがアクティブになると思うのですが?

少なくとも以下のプログラムで起動した場合アクティブになり起動したプログラムのフォームにある Edit や Memo 等にカーソルがある状態になりますが

var
    PI : TProcessInformation;
    SI : TStartupInfo;
begin

   if OpenDialog1.Execute = True then
   begin
     ZeroMemory(@si,SizeOf( TStartupInfo));
     si.cb := sizeof(TStartupInfo);
     CreateProcess(nil,PChar(OpenDialog1.FileName),nil,nil,FALSE,NORMAL_PRIORITY_CLASS,nil,nil,&si,&pi);
   end;

編集 削除
KHE00221  2007-12-21 09:44:56  No: 29037  IP: 192.*.*.*

起動元からアクティブにするには SetActiveWindow(API) でする事が可能です。

CreateProcessで起動したプロセスのメインフォームを取得は

https://www.petitmonte.com/bbs/answers?question_id=5313

を参考にして下さい。

編集 削除
Nin  2007-12-21 15:54:25  No: 29038  IP: 192.*.*.*

KHE00221さんありがとう御座います。

お騒がせしました。原因が判明しました。

メニューのボタンをButtonではなくEditで作成していました。
配色とかを考えてEditをReadOnly=Trueに設定して、Clickで
サブフォームを出す仕組みとしました。

ですが、Clickを何度もしたりすると
サブフォームではなくメインフォームがアクティブになってしまってた
という現象です。

でも、こういった場合はどうしたらいいんでしょうか。

編集 削除
KHE00221  URL  2007-12-21 18:13:00  No: 29039  IP: 192.*.*.*

ダブルクリックだと
1回目のクリックで実行されアクティブになりその後2回目のクリックで
起動元がアクティブになってしまうみたいなので

ダブルクリックの際には OnClick ではなく OnDblClick で処理する必要があります



ダブルクリックした際にも OnClick は処理されてしまうので

OnClick が ダブルクリックで処理された OnClick なのかを判定しなくてはいけません

(*) ボタンならばこの問題はおきません

//CreateProcessでEXEを実行
procedure Execute;
var
    PI : TProcessInformation;
    SI : TStartupInfo;
    S : String;
begin
    S := 'notepad.exe';
    ZeroMemory(@si,SizeOf( TStartupInfo));
    si.cb := sizeof(TStartupInfo);
    CreateProcess(nil,PChar(S),nil,nil,FALSE,NORMAL_PRIORITY_CLASS,nil,nil,&si,&pi);
end;

procedure TForm3.Edit1Click(Sender: TObject);
var
    MSG : TMSG;
begin
    Sleep(GetDoubleClickTime());
    if PeekMessage(MSG,0,WM_LBUTTONDBLCLK,WM_LBUTTONDBLCLK,PM_NOREMOVE) = False then
    begin
      //Clickの場合ここで実行
      Execute;
    end
    else
    begin
      //DBClickなので処理しない
    end;
end;

procedure TForm3.Edit1DblClick(Sender: TObject);
begin
    //DBClickの場合こちらで実行
    Execute;
end;

編集 削除
Nin  2007-12-22 09:17:59  No: 29040  IP: 192.*.*.*

KHE00221さん

無事に問題を解決する事ができました。(タイミングが難しいですねえ)

ご親切にソースまでのせていただいて、感謝しております。
ありがとう御座いました。

編集 削除