Execute;でサブフォームを表示させています。
このサブフォームの入力がサブフォーム自体をクリックしないと、
制御できる状態になりません。
このExecute;は独自コンポーネントです。
サブフォームの中で自身をフロントにするやり方があれば教えてください。
初歩的な質問かもしれませんがよろしくお願いします。
Execute内で実際にフォームを表示する際に
Show や ShowModal で表示していると思うのですが、基本的に表示した時点
でアクティブになると思うのですが・・・
そしてアクティブになれば入力が制御できる状態になると思うのですが?
BringToFront でフロントにする事はできます。
が、これは Show 内部でやっています。
Execute 内でどのようにしてフォームを表示していますか?
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を入れてもダメでした。
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;
起動元からアクティブにするには SetActiveWindow(API) でする事が可能です。
CreateProcessで起動したプロセスのメインフォームを取得は
https://www.petitmonte.com/bbs/answers?question_id=5313
を参考にして下さい。
KHE00221さんありがとう御座います。
お騒がせしました。原因が判明しました。
メニューのボタンをButtonではなくEditで作成していました。
配色とかを考えてEditをReadOnly=Trueに設定して、Clickで
サブフォームを出す仕組みとしました。
ですが、Clickを何度もしたりすると
サブフォームではなくメインフォームがアクティブになってしまってた
という現象です。
でも、こういった場合はどうしたらいいんでしょうか。
ダブルクリックだと
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;
KHE00221さん
無事に問題を解決する事ができました。(タイミングが難しいですねえ)
ご親切にソースまでのせていただいて、感謝しております。
ありがとう御座いました。
ツイート | ![]() |