FAQ一覧へ
インデックスへ
サブフォーム起動で二重起動防止し、さらに二重起動時にパラメーターを送
質問
サブフォーム起動で二重起動防止し、さらに二重起動時にパラメーターを送
るにはどうすればいいですか?
答え
二重起動防止に、
>#22 七☆星 さん、[FAQ]Delphi2.0(Win32)での二重起動の防止
を使われていらっしゃる方、多いと思います。わたくしも大変重宝しており
ます。七☆星 さん、ありがとうございました。
さて、二重起動を防止したときに、二重起動をファイルドロップなどで行
う場合、ここの方法は、旧モジュールのウインドウを見つけてフォーカスを
移す、ということですので、このパラメータ(ドロップファイル)は、アプ
リケーション間のデータ送信を行って、旧モジュールで受信してやる必要が
あります。
(1) クリップボード
(2) グローバルアトム
(3) WM_COPYDATA メッセージ
が考えられます。(1) は簡単ですが、クリップボードを使いながら二重起動
してるとき、クリップボードのデータが勝手に変えられるのは好ましくない
かも知れません。(2)は、SBORLAND 旧 MES 9
>#21710 KHB05271 瑠瓏 さん、RE^3:二重起動防止時のハ゜ラメータ (96/12/18)
で紹介されていますが、ここでの、サブフォーム起動では、やり方が悪いの
か、うまく行かず、代わって、同じツリーの、
>#21698 GFC03235 HATENA さん、RE^2:二重起動防止時のハ゜ラメータ (96/12/17)
> そこで、ここの過去のログを探してみると、#20072 で WM_COPYDATA
> についての記述を発見しました。これを使うとバッチリ文字列を渡すこ
> とができました。
(改行位置変えました)
で成功しました。以下の例でそれを挙げます。
例
プロジェクトファイル:SubFirst.Prj
メインフォーム: SubF1.Pas(フォーム名:SubFF1)
サブフォーム: SubF2.Pas(フォーム名:SubFF2)
やりたいこと:
(1) 単体起動(こんな言い方でいいですか)、つまり単に実行ファイルやそ
のショートカットファイルをクリックして起動する場合はメインフォームを
表示。
(2) 二重起動防止
(3) ファイルをドロップして起動したとき、サブフォームを表示する。
(4) サブフォームが表示されているとき、ファイルドロップ起動すると、そ
のパラメータをサブフォームに渡してフォーカスする。
(i) プロジェクトファイル:SubFirst.Prj
>#22 七☆星 さん、[FAQ]Delphi2.0(Win32)での二重起動の防止
のコードを入れます。
begin
(..略..)
if hMutex <> 0 then begin
(..略..)
Wnd := FindWindow('TSubFF2', nil); {ここではサブフォーム}
if Wnd<>0 then begin
if ParamCount>0 then {ドロップ二重起動}
iShow:=2; {グローバル変数のセット}
(..略..)
SetForegroundWindow(Wnd); {前面に移動してアクティフ゛化}
if ParamCount>0 then
CopyDataToOld(Wnd,iShow,ParamCount);
{旧モジュールにパラメータ送信}
(..略..)
end;
{ミューテックスを閉じる}
CloseHandle(hMutex);
end else begin
{以下は通常通りの処理を行う}
Application.Initialize;
Application.CreateForm(TSubFF1, SubFF1);
Application.CreateForm(TSubFF2, SubFF2);
iShow:=0;
if ParamCount>0 then begin {ドロップ起動}
Application.ShowMainForm:=false; {メインフォーム非表示}
iShow:=1; {グローバル変数セット}
end;
Application.Run;
end;
end.
(ii) メインフォーム:SubF1.Pas(フォーム名:SubFF1)
設計時 Visible=false など
>[FAQ]起動直後にサブフォームを開きたい
のコードを入れます。
(ii) サブフォーム:SubF2.Pas(フォーム名:SubFF2)
procedure TSubFF2.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if (GetForeGroundWindow=SubFF2.Handle) then
if (iShow=1) then begin
{..処理..}
end;
end.
など、ドロップ起動時のコードを、
>[FAQ]起動直後にサブフォームを開きたい
にならって入れます。
次に、ドロップでの二重起動時のデータ受信ですが、
private
{ Private 宣言 }
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
を使います。
データは、
PChar(Msg.CopyDataStruct^.lpData)
に入ってきます。
データ送信、(i)の CopyDataToOld(Wnd,iShow,ParamCount); は、
acData: array[0..255] of char;
に送りたいデータを入れて、
CDS.cbData:=SizeOf(acData);
CDS.lpData:=@acData;
SendMessage(Wnd,WM_COPYDATA,0,LongInt(@CDS));
{Wnd はサブフォームのウィンドウハンドル}
で送信できます。