Q&A-プロセス・スレッド編 |
プロセス、スレッドやプロセス間通信に関する質問をまとめました。
ウィンドウ・アプリケーションを起動してから終了するまで待つ
関連付けられたファイルを起動し終了するまで待つ
実行時のコマンドライン引数を取得するには
VBのアプリケーションの戻り値によってバッチファイルで分岐するには?
二重起動を防止するには、どうすれば良いでしょうか?
SendKeys で DOSプロンプトに文字を送るには?
アプリケーションのアクティブ、非アクティブを知るには?
Q ウィンドウ・アプリケーションを起動してから終了するまで待つ
ウィンドウ・アプリケーションを起動して、終了するまで待つにはどうするのですか?
A APIの
CreateProcess と WaitForSingleObject を使用します
まず、標準モジュールに以下の定数と宣言を入れます。
(注意) APIビューワでの入力とは、宣言や定数が幾つか異なります。
Option Explicit
'==============================
'CreateProcess 関連の宣言
'==============================
'作成フラグ
Public Const CREATE_DEFAULT_ERROR_MODE = &H4000000
Public Const CREATE_NEW_CONSOLE = &H10&
Public Const CREATE_NEW_PROCESS_GROUP = &H200&
Public Const CREATE_SEPARATE_WOW_VDM = &H800&
Public Const CREATE_SHARED_WOW_VDM = &H1000&
Public Const CREATE_SUSPENDED = &H4&
Public Const CREATE_UNICODE_ENVIRONMENT = &H400&
Public Const DEBUG_PROCESS = &H1&
Public Const DEBUG_ONLY_THIS_PROCESS = &H2&
Public Const DETACHED_PROCESS = &H8&
'優先順位クラスフラグ
Public Const HIGH_PRIORITY_CLASS = &H80&
Public Const IDLE_PRIORITY_CLASS = &H40&
Public Const NORMAL_PRIORITY_CLASS = &H20&
Public Const REALTIME_PRIORITY_CLASS = &H100&
Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Type STARTUPINFO
cb As Long
lpReserved As Long
lpDesktop As Long
lpTitle As Long
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _
ByVal lpApplicationName As String, _
ByVal lpCommandLine As String, _
lpProcessAttributes As Any, _
lpThreadAttributes As Any, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
lpEnvironment As Any, _
ByVal lpCurrentDriectory As String, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION _
) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'==============================
'WaitForSingleObject 関連の宣言
'==============================
Public Const INFINITE = &HFFFF ' Infinite timeout
Public Const STATUS_WAIT_0 = 0&
Public Const STATUS_TIMEOUT = &H102&
Public Const STATUS_ABANDONED_WAIT_0 = &H80&
Public Const WAIT_OBJECT_0 = ((STATUS_WAIT_0) + 0&)
Public Const WAIT_ABANDONED = ((STATUS_ABANDONED_WAIT_0) + 0&)
Public Const WAIT_TIMEOUT = STATUS_TIMEOUT
Declare Function WaitForSingleObject Lib "kernel32" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long _
) As Long
Declare Function GetLastError Lib "kernel32" () As Long
ウィンドウ・アプリケーションを起動するところで、以下の CreateProcess を呼んでください。
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
Dim r As Long
si.cb = LenB(si)
r = CreateProcess( _
"C:\WINNT\SYSTEM32\notepad.exe", _
"", _
ByVal 0&, _
ByVal 0&, _
0, _
NORMAL_PRIORITY_CLASS, _
ByVal 0&, _
vbNullString, _
si, _
pi _
)
If r = 0 Then
MsgBox "CreateProcess Error"
Exit Sub
End If
ここで、CreateProcess の最初の引数である
"C:\WINNT\SYSTEM32\notepad.exe"
に起動したいアプリケーションを指定します。
2番目の引数は、実行するアプリケーションのパラメータを指定できます。
アプリケーションが終了するまで待つには、CreateProcessで取得した
pi.hProcess を指定して以下の WaitForSingleObject と CloseHandle
を呼んでください。
r = WaitForSingleObject(pi.hProcess, INFINITE)
If r <> WAIT_OBJECT_0 Then
MsgBox "WaitForSingleObject Error"
Exit Sub
End If
CloseHandle pi.hProcess
WaitForSingleObject の2番目の引数で、 INFINITE
と指定していますが、この引数は、アプリケーションの待ち時間を
ms(ミリセカンド)で指定することができます。ただし、 INFINITE
を指定した場合は、起動したアプリケーションが終了するまで
WaitForSingleObject から制御を戻しません。
また、INFINITE
を指定した場合、アプリケーションを起動した側のプログラムには、制御が戻らないので、起動側のプログラムがフリーズしたようになります。起動プログラムに制御を戻したい場合、以下のように
INFINITE
の代わりに、待ち時間を指定し、タイムアウトでなくなるまでループします。
Do
r = WaitForSingleObject(pi.hProcess, 300) ' 300ms 待ちます
DoEvents
Loop Until r <> STATUS_TIMEOUT
If r <> WAIT_OBJECT_0 Then
MsgBox "WaitForSingleObject Error"
Exit Sub
End If
CloseHandle pi.hProcess
(注意)このページの内容は、Visual
Basic5.0(SP3)
を対象に記述されています。他のバージョンでは、対応できないこともあるので、ご注意願います。
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。
".TXT" で Notepad 、".HTM" で Internet Explorer
を起動するように、関連付けられたファイルを起動して、終了するまで待つにはどうするのですか?
A APIの
ShellExecute と WaitForSingleObject を使用します
まず、標準モジュールに以下の定数と宣言を入れます。
(注意) APIビューワでの入力とは、宣言や定数が幾つか異なります。
Option Explicit
'==============================
'ShellExecute 関連の宣言
'==============================
Public Const SW_SHOWNORMAL = 1
Public Const SEE_MASK_CLASSKEY = &H3
Public Const SEE_MASK_CLASSNAME = &H1
Public Const SEE_MASK_CONNECTNETDRV = &H80
Public Const SEE_MASK_DOENVSUBST = &H200
Public Const SEE_MASK_FLAG_DDEWAIT = &H100
Public Const SEE_MASK_FLAG_NO_UI = &H400
Public Const SEE_MASK_HOTKEY = &H20
Public Const SEE_MASK_ICON = &H10
Public Const SEE_MASK_IDLIST = &H4
Public Const SEE_MASK_INVOKEIDLIST = &HC
Public Const SEE_MASK_NOCLOSEPROCESS = &H40
Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
' Optional fields
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type
Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" ( _
lpExecInfo As SHELLEXECUTEINFO _
) As Long
Public Const ERROR_FILE_NOT_FOUND = 2&
Public Const ERROR_PATH_NOT_FOUND = 3&
Public Const ERROR_DDE_FAIL = 1156&
Public Const ERROR_NO_ASSOCIATION = 1155&
Public Const ERROR_ACCESS_DENIED = 5&
Public Const ERROR_DLL_NOT_FOUND = 1157&
Public Const ERROR_CANCELLED = 1223&
Public Const ERROR_NOT_ENOUGH_MEMORY = 8
Public Const ERROR_SHARING_VIOLATION = 32&
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'==============================
'WaitForSingleObject 関連の宣言
'==============================
Public Const INFINITE = &HFFFF ' Infinite timeout
Public Const STATUS_WAIT_0 = 0&
Public Const STATUS_TIMEOUT = &H102&
Public Const STATUS_ABANDONED_WAIT_0 = &H80&
Public Const WAIT_OBJECT_0 = ((STATUS_WAIT_0) + 0&)
Public Const WAIT_ABANDONED = ((STATUS_ABANDONED_WAIT_0) + 0&)
Public Const WAIT_TIMEOUT = STATUS_TIMEOUT
Declare Function WaitForSingleObject Lib "kernel32" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long _
) As Long
Declare Function GetLastError Lib "kernel32" () As Long
関連付けられたファイルを起動するところで、以下の ShellExecuteEx を呼んでください。
Dim ei As SHELLEXECUTEINFO
Dim r As Long
ei.cbSize = LenB(ei)
ei.fMask = SEE_MASK_NOCLOSEPROCESS
ei.hwnd = Me.hwnd
ei.lpVerb = "Open"
ei.lpFile = "C:\WINNT\Readme.txt"
ei.lpParameters = ""
ei.lpDirectory = ""
ei.nShow = SW_SHOWNORMAL
r = ShellExecuteEx(ei)
If r = 0 Then
MsgBox "ShellExecuteEx Error"
Exit Sub
End If
ここで、Dim ei As
SHELLEXECUTEINFO で定義された ei の lpFile に起動したいファイル(ここでは、"C:\WINNT\Readme.txt" )を指定します。ei.lpParameters
は、実行するアプリケーションのパラメータを指定できます。
アプリケーションが終了するまで待つには、ShellExecuteEx
で取得した ei.hProcess を指定して以下の WaitForSingleObject
と CloseHandle を呼んでください。
r = WaitForSingleObject(ei.hProcess, INFINITE)
If r <> WAIT_OBJECT_0 Then
MsgBox "WaitForSingleObject Error"
Exit Sub
End If
CloseHandle pi.hProcess
WaitForSingleObject の2番目の引数で、 INFINITE
と指定していますが、この引数は、アプリケーションの待ち時間を
ms(ミリセカンド)で指定することができます。ただし、 INFINITE
を指定した場合は、起動したアプリケーションが終了するまで
WaitForSingleObject から制御を戻しません。
また、INFINITE
を指定した場合、アプリケーションを起動した側のプログラムには、制御が戻らないので、起動側のプログラムがフリーズしたようになります。起動プログラムに制御を戻したい場合、以下のように
INFINITE
の代わりに、待ち時間を指定し、タイムアウトでなくなるまでループします。
Do
r = WaitForSingleObject(ei.hProcess, 300) ' 300ms 待ちます
DoEvents
Loop Until r <> STATUS_TIMEOUT
If r <> WAIT_OBJECT_0 Then
MsgBox "WaitForSingleObject Error"
Exit Sub
End If
CloseHandle pi.hProcess
(注意)このページの内容は、Visual
Basic5.0(SP3)
を対象に記述されています。他のバージョンでは、対応できないこともあるので、ご注意願います。
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。
VBで作成した実行可能なプログラムの起動時に指定されたコマンドラインの引数を取得するにはどうするのですか?
A Command
関数で取得できます
VBで作成した実行可能なプログラムを起動時する時に以下のようなパラメータを指定する場合があります。
APP.EXE /F:TEMP.TXT
この引数を取得するには、Command
という関数で取得できます。ただし、デバッグ時には、一見なにも
Command
に入っていないようですが、実行可能なプログラムにすれば、Command
にコマンドラインの引数が入ります。
デバッグ時に Command に文字列を入れたい場合は、メニューの [プロジェクト]-[XXXX
のプロパティ]を選択して、[実行可能ファイルの作成]タグを選択してください。「コマンドライン引数」という入力欄があるので、そこに入力すれば
Command に文字列が入ります。
(注意)このページの内容は、Visual
Basic5.0(SP3)
を対象に記述されています。他のバージョンでは、対応できないこともあるので、ご注意願います。
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。
Q VBのアプリケーションの戻り値によってバッチファイルで分岐するには?
MS-DOSで作成したアプリケーションでは、終了時に終了コードを指定すれば、バッチファイルの
ERRORLEVEL によってプログラムを分岐できましたが、VBのアプリケーションの戻り値によってバッチファイルを分岐させる事はできるのでしょうか?
A
ファイル経由で分岐できます。
まず、VBから ERRORLEVEL
の設定はすることができません。そこで他の方法を考えると、バッチファイルの
IF
文で使用できるのは環境変数か、ファイルの存在のチェックだけです。簡単な方法としては、ファイルを
VBで作成して、それを IF 文で判別させるのが良いと思います。
例として、3つのボタン配列を作成して、押されたボタンによってバッチファイルを分岐させてみましょう。
まづ、VB側のプログラムです。
Private Sub Command1_Click(Index As Integer)
On Error Resume Next
Kill "C:\TEMP\0.TMP"
Kill "C:\TEMP\1.TMP"
Kill "C:\TEMP\2.TMP"
Open "C:\TEMP\" & Format$(Index, "0") & ".TMP" For Output As #1
Close #1
End
End Sub
見ても分かるように、まず Kill
で以前に作られたファイルを削除してから、 Index
に渡された値によって、"C:\TEMP\0.TMP"、"C:\TEMP\1.TMP"、"C:\TEMP\2.TMP"
のいずれかのファイルを作成します。ファイルを作成したらすぐに
End で終了します。
次にバッチファイルですが、次のようなバッチファイルを作成します。
START /W Project1.exe
IF EXIST C:\TEMP\0.TMP GOTO LABEL0
IF EXIST C:\TEMP\1.TMP GOTO LABEL1
IF EXIST C:\TEMP\2.TMP GOTO LABEL2
:LABEL0
ECHO Return = 0
PAUSE
EXIT
:LABEL1
ECHO Return = 1
PAUSE
EXIT
:LABEL2
ECHO Return = 2
PAUSE
EXIT
最初の START というコマンドは、/W
というオプションをつけると、/W
以降に書かれたプログラムを実行して、終了するまで待ってくれます。前述のVBのプログラムを
Project1.exe とすれば、押されたボタンによって、"C:\TEMP\0.TMP"、"C:\TEMP\1.TMP"、"C:\TEMP\2.TMP"
のいずれかが作成されているはずです。作成されたファイルによって、LABEL0、LABEL1、LABEL2のいずれかにジャンプして
ECHO で Return = 0 等を表示します。
(注意)このページの内容は、Visual
Basic5.0(SP3)
を対象に記述されています。他のバージョンでは、対応できないこともあるので、ご注意願います。
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。
Q 二重起動を防止するには、どうすれば良いでしょうか?
VBで作成したEXEが、2つ同時に起動するのを防ぐにはどうしたら良いでしょうか?
A
App.PrevInstance を使えば簡単にできますが...
単純に、同じプログラムが起動されたら終了するだけならば、Form_Load で以下のようなコーディングをすれば、二重起動を防止できます。
Private Sub Form_Load()
If App.PrevInstance Then
End
End If
End Sub
この App.PrevInstance
は、最初にプルグラムが起動された時には False
が返されます。次に、同じプログラムが起動されると、この値は
True
となってプログラムが終了します。メッセージを表示したい場合には、End
の前に MsgBox を入れれば表示できます。
(注意) App.PrevInstance
は、プログラムが実行形式(EXE)になった場合のみ値が変ります。開発環境上では値は変りません。
次に、もうちょっと工夫して、同じプログラムを起動した場合には、最初に動いたプログラムをアクティブにして終了してみましょう。
Private Sub Form_Load()
Dim strCaption As String
If App.PrevInstance Then
'現在のキャプションを保存
strCaption = Me.Caption
'キャプションとタイトルをダミーの文字列に設定
Me.Caption = "$$$"
App.Title = "$$$"
'以前のウィンドウをアクティブにする
AppActivate strCaption
'Alt+SPACE と R を送って元のサイズに戻す
SendKeys "% R", True
End If
End Sub
まず最初に、このプログラムのキャプションを保存して、後から起動したウィンドウのキャプションを
"$$$" という文字に変えます。これは、次の AppActivate
で後から起動したプログラムをアクティブにしない為です。
AppActivate
では、保存したキャプション(すなわち、最初に起動したプログラムのキャプション)のプログラムをアクティブにします。最後に
SendKey ですが、Alt+SPACE を送ってコントロールボックスを開き、
"R" を送って、「元のサイズに戻す」を選択してます。この
SendKey で、アイコン化されたプログラムも元のサイズに戻ります。
最後に、APIを使って開発環境でも使用できる方法を説明します。まず、標準モジュールに以下の定数と宣言を入れます。
(注意) APIビューワでの入力とは、宣言や定数が幾つか異なります。
Public Const MUTANT_ALL_ACCESS = &H1F0001
Declare Function OpenMutex Lib "kernel32" Alias "OpenMutexA" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal lpName As String) As Long
Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" ( _
ByVal lpMutexAttributes As Long, _
ByVal bInitialOwner As Long, _
ByVal lpName As String) As Long
Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long) As Long
Declare Function ReleaseMutex Lib "kernel32" ( _
ByVal hMutex As Long) As Long
Public Const SW_SHOWNORMAL = 1
Declare Function ShowWindow Lib "user32" ( _
ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long
Form_Load 、Form_QueryUnload に以下のようなコーディングを書きます。
Dim m_hMutex As Long
Private Sub Form_Load()
Dim PrevhMutex As Long
PrevhMutex = OpenMutex(MUTANT_ALL_ACCESS, 0, Me.Caption)
If PrevhMutex Then
CloseHandle PrevhMutex
End
End If
m_hMutex = CreateMutex(0, 0, Me.Caption)
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
ReleaseMutex m_hMutex
End
End Sub
これは、ミューテックスという手法を使用して、Windows
のメモリ上に Me.Caption をキーとした領域を作成しています。最初の
OpenMutex で、Me.Caption をキーとした領域があれば、PrevhMutex に 0
以外の数字が入ります。この領域があれば、既にプログラムが起動されたということで、この領域を
CloseHandle
でクローズして終了します。領域が無い場合は、まだ、このプログラムは起動されていないので、CreateMutex
で Me.Caption
をキーとした領域を作成して通常に起動します。プログラムの終了時に、ReleaseMutex
でこの領域を消せば、次に起動したプログラムには領域が残っていないので、通常に起動します。
この方法は、開発環境で使用できるばかりでなく、本当に同じプログラムでなくとも、同じキーを使用したミューテックス同士で起動を制御する事ができます。
(注意)プログラムの終了は、Unload.Me
等を使用して、必ず Form_QueryUnload 経由で終了してください。
(注意)このページの内容は、Visual
Basic5.0(SP3)
を対象に記述されています。他のバージョンでは、対応できないこともあるので、ご注意願います。
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。
Q SendKeys で DOSプロンプトに文字を送るには?
起動したDOSプロンプトに、SendKeys
で文字を送っても、入力されません。どうしたら良いでしょうか?
A
クリップボード経由で送れます
初めに、この方法は NT4.0(SP4) で cmd.exe
を起動した場合には、必要ありません。そのまま、SendKeys
でDOSプロンプトに文字を送ることができます。
Win98等のその他のバージョンの場合は、DOSプロンプトに送りたい文字をクリップボードにセットして、DOSプロンプトのメニューの貼付けを
SendKeys で実行すれば、文字を送ることができます。
さっそくサンプルですが、以下の通りです。
Private Sub Command1_Click()
Dim r
'予め、送りたい文字をクリップボードにセット
Clipboard.Clear
Clipboard.SetText "Dir" & vbCr
'DOSプロンプトを起動する
r = Shell("command.com", vbNormalFocus)
AppActivate r
' ALT+" "、"e"、"p" を送る(貼付けを実行)
SendKeys "% ep", True
End Sub
このサンプルでは、DOSプロンプトが起動して、"Dir"
が実行されます。
また、タイミングによって AppActivate
がエラーになる場合は、以下のようにループさせればOKです(^^
On Error Resume Next
Do
Err = 0
AppActivate r
If Err = 0 Then Exit Do
Loop
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。
アプリケーションがアクティブになったり、非アクティブになったときに、画面の表示を止めるなどの処理を行いたい場合がありますが、Activate
や Deactivate
イベントはアプリケーションのアクティブ、非アクティブでは発生しません。どのようにして取得するのでしょうか?
A
サブクラスを使用します
アプリケーションのアクティブ、非アクティブを知るには、APIを使用して、ウィンドウのメッセージを横取りすれば判別できます。この方法をサブクラス化と言います。
サブクラス化では、APIを使用して、ウィンドウのメッセージを横取りする関数を指定します。タイミングとしては、フォームのLoadイベント等で、以下のように設定します。
Private Sub Form_Load()
lpDefaultProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
ここで、WindowProc は横取りする関数の関数名です。また、lpDefaultProc は最後に横取りした関数を、元のウィンドウの関数に戻すための変数です。lpDefaultProc は標準モジュールに Public で宣言してください。
Public lpDefaultProc As Long
元のウィンドウの関数に戻すには、フォームのUnloadイベント等で以下のように指定します。
Private Sub Form_Unload(Cancel As Integer)
Call SetWindowLong(Me.hWnd, GWL_WNDPROC, lpDefaultProc)
End Sub
あとは、横取りした関数を作成します。この関数は、標準モジュールに作成してください。
(注意)この関数にバグがある場合には、実行するとVBごと飛びます。必ず作成したプログラムを保存してから実行してください。
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_ACTIVATE Then
If wParam = WA_INACTIVE Then
'非アクティブの処理
Else
'アクティブの処理
End If
End If
'デフォルトのウィンドウ関数を呼び出す
WindowProc = CallWindowProc(lpDefaultProc, hWnd, uMsg, wParam, lParam)
End Function
uMsg が WM_ACTIVATE の場合、アクティブ、非アクティブが切替っています。その時、wParam には以下の状態が返されます。
wParam | 意味 |
WA_ACTIVE | アクティブとなった(クリックの場合以外) |
WA_CLICKACTIVE | クリックされてアクティブとなった |
WA_INACTIVE | 非アクティブとなった |
コメントでアクティブの処理、非アクティブの処理と書かれたところに、各処理を記述します。
以下は、宣言部です。標準モジュールに入れてください。
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
ByVal lpPrevWndFunc As Long, _
ByVal hWnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Const WM_ACTIVATE = &H6
Public Const WA_ACTIVE = 1
Public Const WA_INACTIVE = 0
Public Const WA_CLICKACTIVE = 2
Public Const GWL_WNDPROC = (-4)
(注意)くどいようですが(^^;
このプログラムにバグがある場合には、実行するとVBごと飛びます。必ず作成したプログラムを保存してから実行してください。
(注意)このページの内容は、Visual
Basic6.0(SP3)
を対象に記述されています。他のバージョンでは、対応できないこともあるので、ご注意願います。
(注意)
ここでの情報については、あくまでも各自の責任にて、充分にテストを行ってご使用ください。内容に関する質問については、回答できる保証がありませんので、予めご了承願います。