• ベストアンサー

プログラムをアクティブにしないようにするにはどうするのですか?

a.exeを起動したら Aの中でshellでb.exeが起動する a.exeの上にb.exeが起動しているかたちになります。 このときにa.exeの画面をクリックしても a.exeはアクティブにならずにしたいのですがどうすればよいのか 襲えてください。 a.exeはフォームにbmpをはり各プログラムの背景画面にしたいので クリックされてもなにを反応しないようにしたいのです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.3

サンプル作りました。 さっきの書き込みのとき、しっかり読まなかったので、勘違いして回答を書いております。 それで処理内容がさっきと発言と変わっています。 サンプルでは、背景にもコマンドボタンを置いて、別のEXEを操作していますが、必要のない機能ははずしてください。 処理内容を説明します。 1.Aを起動します。 2.AからSHELLでBを起動します。 3.Bの中の処理はフォームをロードするだけで、Showを行いません。 4.Aの中にBを埋め込みます。 5.AからBの表示位置を設定します。 6.AはBを常に監視します。 以上がおおまかな流れです。 サンプルを実行するときの注意点です。 二つのEXEが必要です。 A.exeについて  必要なもの  フォーム  コマンドボタン1/2/3  標準モジュール A.exeの名前については任意です。 もうひとつのEXEの名前はB.exeにしています。(定数でCHILD_EXEの内容を変えることで、変更できます) B.exeの表示位置をピクセル単位で指定しています。[CHILD_X/CHILD_Y]が、それにあたります。サンプルでは[300,0]に設定してます。それにともない、フォームは多少大きめに、3つのコマンドボタンはふ、フォームの左端がわに縦に並ぶように配置してください。 B.exeについて  必要なもの  フォーム  標準モジュール こちらはフォームから起動しないで、標準モジュールから実行するようにしてください。 コードを見てもらえたらわかるように、フォームをロードするだけです。 フォームのキャプションを空にして、BorderStyleを[0-なし]にしてあげると、より一層別のEXEだということが感じられなくなります。 -----A.EXEのフォーム(ここから)----- Option Explicit '別EXEのファイルパス Private Const CHILD_EXE As String = "b.exe" '別EXEの表示位置X座標 Private Const CHILD_X  As Long = 300 '別EXEの表示位置Y座標 Private Const CHILD_Y  As Long = 0 'アプリケーションの終了ボタンを押されたときの処理フラグ Private bytFlg   As Byte 'bytFlgは基本的に0で、アプリケーションの終了時に0をセット Private Sub Command1_Click()   '初期化を行う   FindWinWnd = 0   FindPrs = 0   'とりあえずCHILD_EXEを起動と同時に、電卓のプロセスを得る   FindPrs = Shell(CHILD_EXE)     'プロセス=0のとき起動失敗   If FindPrs = 0 Then     MsgBox CHILD_EXE & "の起動失敗"     GoTo PGMEND   End If     'Windowsに存在する全部のハンドルから、CHILD_EXEのプロセスの一緒のハンドルを探す   Call EnumWindows(AddressOf EnumWinProc, 0&)     'もし、起動したEXEのハンドルを取得できたら   If (FindWinWnd <> 0&) Then     'CHILD_EXEを自分のフォームの中に取り込みます     Call SetParent(FindWinWnd, Me.hWnd)          'CHILD_EXEの表示位置を定め、表示を行います     Call SetWindowPos(FindWinWnd, HWND_TOP _             , CHILD_X, CHILD_Y, 0, 0, SWP_NOSIZE Or SWP_SHOWWINDOW)     'CHILD_EXEの監視を行います     Call KANSI_WINDOWS   Else     MsgBox "EXEが見つかりませんでした。"   End If   PGMEND: End Sub Private Sub Command2_Click()   '起動したEXEの終了   Call SendMessage(FindWinWnd, WM_CLOSE, 0&, 0&) End Sub Private Sub Command3_Click()   '自分自身の終了   Unload Me End Sub Private Sub Form_Load()   With Me     .Command1.Caption = "別EXEの起動"     .Command2.Caption = "別EXEの終了"     .Command3.Caption = "アプリケーションの終了"          '「別EXEの終了ボタン」を使用不可     .Command2.Enabled = False          bytFlg = 0   End With End Sub Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)   With Me     'もしCHILD_EXEを起動しているならば、終了を行う     If .Command2.Enabled Then       bytFlg = 1       Call Command2_Click     End If   End With End Sub '起動した別EXEのウィンドウを監視します。 '「別EXEの終了ボタン」のEnabledを操作します。 Private Function KANSI_WINDOWS()   With Me     '「別EXEの終了ボタン」を使用可能     .Command2.Enabled = True          '別EXEが起動しているあいだはこのループを回り続ける     Do While (IsWindow(FindWinWnd) = 1)       DoEvents     Loop          'アプリケーションが終了しないときは、「別EXEの終了ボタン」を使用不可に戻す     If bytFlg = 0 Then       .Command2.Enabled = False     End If   End With End Function -----A.EXEのフォーム(ここまで)----- -----A.EXEの標準モジュール(ここから)----- Option Explicit Public Const HWND_TOP = 0 'ZOrderのトップに置く Public Const SWP_NOSIZE = &H1 'ウインドウのサイズを変えないで移動のみ Public Const SWP_SHOWWINDOW = &H40 '再描画の時、ウインドウを再表示 Public Const WM_CLOSE = &H10 '見つかったウィンドウハンドル Public FindWinWnd As Long '探すべきプロセス Public FindPrs   As Long ' ウィンドウのプロセスIDとスレッドIDを取得する関数の宣言 Private Declare Function GetWindowThreadProcessId Lib "user32.dll" _   (ByVal hWnd As Long, lpdwProcessId As Long) As Long '親ハンドルを取得する関数の宣言 Private Declare Function GetParent Lib "user32" _   (ByVal hWnd As Long) As Long 'ウィンドウを列挙する関数の宣言 Public Declare Function EnumWindows Lib "user32" _   (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long 'ウィンドウにメッセージ定数を送る関数の宣言 Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _   (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long ' ウィンドウハンドルからウィンドウが存在するかどうか判断する関数の宣言 Public Declare Function IsWindow Lib "user32.dll" _   (ByVal hWnd As Long) As Long '指定ハンドルのウィンドウの親を変更する関数の宣言 Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long '指定ハンドルのウィンドウのサイズ、位置を変更する関数の宣言 Public Declare Function SetWindowPos Lib "user32" _   (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long 'Windowsの全ハンドルを得ることができる関数 '内部処理は、 '(1)指定のプロセスを探す '(2)見つかったプロセスのハンドルを記憶 Public Function EnumWinProc(ByVal hWnd As Long, lParam As Long) As Boolean   Dim lngTrd As Long 'スレッド   Dim lngPrs As Long 'プロセス     'Trueの間は、Windowsに存在するハンドルを最後まで取得しようとする   EnumWinProc = True     '子ウィンドウは未処理   If Not (GetParent(ByVal hWnd) = 0) Then GoTo PGMEND     'スレッドとプロセスを取得する   lngTrd = GetWindowThreadProcessId(hWnd, lngPrs)     '同じプロセスだとしたら   If lngPrs = FindPrs Then     '取得してきたハンドルを記憶     FindWinWnd = hWnd     'これ以上のハンドルは取得しないでもいいので、Falseをセット     EnumWinProc = False   End If   PGMEND: End Function -----A.EXEの標準モジュール(ここまで)----- -----B.EXEのフォーム(ここから)----- 記述する必要なし -----B.EXEのフォーム(ここまで)----- -----B.EXEの標準モジュール(ここから)----- Sub Main()   Load Form1 End Sub -----B.EXEの標準モジュール(ここまで)-----

chiba-masaru
質問者

お礼

ありがとうございました。 いちどやってみます。

その他の回答 (2)

  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.2

方法は二つあります。 1.a.exeがb.exeを起動して、状態監視をする。 2.b.exeが終了するまで待機する どちらかの方法を利用して、b.exeを常に最善面に表示するようなAPI関数を呼びます。 今は時間がないので後でサンプルを作成しますね。

  • haporun
  • ベストアンサー率40% (230/562)
回答No.1

クリックされても反応しないというのは無理ですが、クリックされたらbにフォーカスを送るというのはできますねぇ。 デスクトップでさえアクティブになりうるのですから。 bを常に手前に表示しておけば、aがクリックされたときに、bがフォーカスを失うものの、bが一瞬きえることはなしにできますよ。 背景画面をb内の別フォームすることはできないんですか? それだったら、もうちょっと簡単。 目的は満たしてないけど・・・。 MDIフォームなら、完全に目的が果たせますね。 ダメですか?