BringWindowToTopを使用して、指定のWindowを1番手前に表示したいのですが、VBからソースで起動すると上手くいくんですが、実行ファイル(EXE)から起動すると上手くいきません。
関数自体は正常終了しているようなんですが…。
知っている方がいらしたら教えてください。
お願いします。
以下ソースです。
Private Sub Main()
Dim ExePath As String
Dim lRet As Long
ExePath = "C:\WINNT\system32\calc.exe"
lRet = FindWindow(vbNullString, "電卓")
If lRet = 0 Then
strWork = Shell(ExePath, vbNormalFocus)
Else
If BringWindowToTop(lRet) = 0 Then
End
End If
End If
End Sub
APIのSetWindowPosをつかいます。
ポピュラーなんで、あっちこっちのVBサイトにサンプルのってます。
たとえば、VBラボ
http://www.remus.dti.ne.jp/~y-mac/apiidx.html
めんどくさい場合はこちらをどうぞ、
menu.checkedとそのままつなげてもいいので、たぶんらく。
APIのSetWindowPosと
定数のSWP_SHOWWINDOWとSWP_NOMOVEとSWP_NOSIZEは、
APIびゅーあーなどで宣言してください。
あ、でもここのサンプルにもありましたよね。
Public Sub Toppos(hwnd As Long, Top As Boolean)
If Top = True Then
SetWindowPos hwnd, -1, 0, 0, 0, 0, SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
Else
SetWindowPos hwnd, -2, 0, 0, 0, 0, SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
End If
End Sub
ところで、ものによっては、ほかの前面表示を無視して、何よりも前に出る"強力最前面表示"がありますけど、
あれってどうするんでしょうかねぇ?
えーっと、たとえばスクリーンセーバー表示中でも出てる時計とか…。
第一引数に0とか-3とか入れてみたんですけど…。
タイマイベントで
HWND_TOPMOST を
設定しまくる、という手はあるけど・・・
特に時計だったら・・・。
すみません。説明が足りなかったみたいです。
ずっと手前に表示するんではなくて、その時1度だけでいいんです。
そうするとやはりBringWindowToTopだと思うんですが??
SetWindowPosだと、ずっと手前に表示されるみたいなので…。
> タイマイベントで
> HWND_TOPMOST を
> 設定しまくる、という手はあるけど・・・
そ、それもありそうですけど…^^;
でも、スクリーンセーバー表示中に、最前面表示する?
なんだかちがう定数か、ちがうAPIのような…。
でも、さっきAPIびゅーあーでHWNDを検索したら…。
もしかしたらこれかも。
Private Const HWND_BROADCAST = &HFFFF&
っと、ほんだい。
一時的に最前面表示するのって、ここのAPIサンプルにあったような…。
後は、一時的に最前面表示して、すぐ切ることもできるし。
え〜と、たしかにここのAPIサンプルにあるんですけど、あれを参考に1番最初に書いたソースでEXEファイルを作ったんですが…。
できれば、上のソースをコピーしてやってみてもらえませんか?
標準モジュールに貼り付けるだけですので。
やってみると、ソースだと上手くいくんですが、EXEファイルにすると上手くいかないんです…。
ソースの書き方が悪いでんしょうか?
たとえばこうするとか・・・
Private Declare Function BringWindowToTop Lib "user32.dll" _
(ByVal hWnd As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hWnd As Long) As Long
Private Sub Form_Load()
Dim ExePath As String
Dim lRet As Long
ExePath = "C:\WINNT\system32\calc.exe"
lRet = FindWindow(vbNullString, "電卓")
If lRet = 0 Then
strWork = Shell(ExePath, vbNormalFocus)
Else
If BringWindowToTop(lRet) = 0 Then
End
ElseIf SetForegroundWindow(lRet) = 0 Then
End
End If
End If
End Sub
ま、フォーカスやれば前面にくるという・・・・
解決しました!
SetForegroundWindowを使うと上手くできました。
BringWindowToTopにこだわりすぎたようです…。
(というよりもSetForegroundWindowを知りませんでした)
皆さん、ありがとうございました。
ツイート | ![]() |