今、タイトルバーのないアプリを作っているのですが、このアプリのウインドウを別アプリから、APIのFindWindow関数で見つけたいのですが、タイトルがないのでクラス名でしか見つけれません。同じクラスのウインドウが他にもあった場合、区別が付かず困っています。
具体的に申しますと、作ったアプリに二重起動防止機能を付けたい(すでに起動されている場合はそのアプリのウインドウを元の大きさに戻してアクティブにする)のですが、そのアプリにはタイトルバーがなく、FindWindowでは見つけれない場合があります。
このような場合どうすればいいでしょうか?
よろしくお願い致します。
No.6ベストアンサー
- 回答日時:
VB6.0で2重起動のチェック&2重起動時に起動中のウィンドウを
手前に持ってくるサンプルです。
Sub Main()
Dim lngReturnValue As Long
Dim strMyTitle As String
Dim lngPrevHwnd As Long
Dim lngTopHwnd As Long
Dim lngThreadID1 As Long
Dim lngThreadID2 As Long
' 2重起動の場合は、手前に持ってきて自分自身は終了する
strMyTitle = App.Title
App.Title = "$" & App.Title
lngPrevHwnd = FindWindow("ThunderRT6Main", strMyTitle)
If lngPrevHwnd <> 0 Then
lngTopHwnd = GetLastActivePopup(lngPrevHwnd)
If IsIconic(lngTopHwnd) = WIN32API_TRUE Then
lngReturnValue = ShowWindow(lngTopHwnd, SW_NORMAL)
End If
lngThreadID1 = GetWindowThreadProcessId(GetForegroundWindow(), ByVal 0&)
lngThreadID2 = GetCurrentThreadId()
lngReturnValue = AttachThreadInput(lngThreadID2, lngThreadID1, 1)
lngReturnValue = SetForegroundWindow(lngTopHwnd)
lngReturnValue = AttachThreadInput(lngThreadID2, lngThreadID1, 0)
Exit Sub
End If
App.Title = strMyTitle
Form1.Show
End Sub
APIの定義です。
Public Const WIN32API_TRUE As Long = 1
Public Const WIN32API_FALSE As Long = 0
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function GetLastActivePopup Lib "user32" _
(ByVal hwndOwnder As Long) As Long
Public Declare Function IsIconic Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long
Public Const SW_NORMAL = 1
Public Const SW_MAXIMIZE = 3
Public Const SW_MINIMIZE = 6
Public Declare Function GetForegroundWindow Lib "user32" () As Long
Public Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Public Declare Function AttachThreadInput Lib "user32" _
(ByVal idAttach As Long, _
ByVal idAttachTo As Long, _
ByVal fAttach As Long) As Long
VB5.0の場合は、ThunderRT6Main が ThunderRT5Main だと思います。
これは、VBのEXEで実行時にクラス名が ThunderRT6Main で
キャプションがプロジェクトのプロパティの実行ファイルの作成タブの
アプリケーションのタイトル(=App.Title=タスクマネージャのタスク
に表示されるタスク名)のウィンドウが必ず存在するので
このウィンドウをチェックしています。(このウィンドウは、サイズが
0なので見えません。)
また、開発環境(IDE)で動かすとこのウィンドウは存在しないので
EXEファイルにして実行して確認してください。
うぉ~~、 すごい~!!
ありがとうございます。
ThunderRT5Mainに書き換えたら動きました。
> これは、VBのEXEで実行時にクラス名が ThunderRT6Main で
> キャプションがプロジェクトのプロパティの実行ファイルの作成タブの
> アプリケーションのタイトル(=App.Title=タスクマネージャのタスク
> に表示されるタスク名)のウィンドウが必ず存在するので
そのようなウインドウが存在するとは知りませんでした!!
App.Titleを実行中に変更できるなんて思いもしませんでした。
おかげさまでシンプルなコードになりました。
どうもありがとうございました。
尚、ここで解決とさせて頂きます。
いろいろとごご教授くださった皆様、
どうもありがとうございました。
No.5
- 回答日時:
フォームの外枠を可変にしたいのでしょうか?
そうなると ControlBoxとCaptionで操作することになりますね
固定でよいのなら BorderStyleを 0の無しに設定してみてはいかがでしょう
これなら Captionは設定してあっても タイトルバーは表示されませんよ
どうもありがとうございます。
> BorderStyleを 0の無しに設定してみてはいかがでしょう
そうすると今度はタスクバーにも表示されなくなってしまうので・・・;;
noocyteさんが教えてくださったMutexを使ったやり方はむずかしかったので、ダミーのコマンドボタンを貼り付けるやり方で実現しました。
いろいろとありがとうございました。
No.4
- 回答日時:
>>SendMessageでCaptionを取得してみましょう
>タイトルバーがないのでCaptionもなく・・・;;
タイトルバーがなくても 作成したアプリケーションのフォームのCaptionプロパティが設定されているのであれば
WM_GETTEXTで取得できる場合がありますよ
先の投稿も一応検証してから アップしております VB6ですけどね ...
何度も、ありがとうございます。
> タイトルバーがなくても 作成したアプリケーションのフォームのCaptionプロパティが設定されているのであればWM_GETTEXTで取得できる場合がありますよ
VB5でフォームのCaptionプロパティを設定するとタイトルバーがなくならないです。(私のやり方が悪いのかも。)
フォームのControlBox プロパティを False にして、Caption プロパティを ""(プロパティウインドウになにも文字列を入力しない)にすることでタイトルバーが消えてくれますが、逆に Caption プロパティを""にしてないとどうしてもタイトルバーが消えてくれないです。(ほんとただ私のやり方が悪いだけなのかも。)
Caption プロパティを設定したままタイトルバーを消す方法があるのでしょうか?
> 先の投稿も一応検証してから アップしております VB6ですけどね ...
検証までして頂いてありがとうございます。
私の場合、SendMessageでWM_GETTEXTを送ると、ファイル名なのかプロジェクト名なのかわからないような名前(例えば、「abcd~1」みたいな文字列が返ってきました。)
よくわかりませんが・・・;;
度々、ありがとうございました。
No.3
- 回答日時:
> VB5にはご紹介頂いたMutexや Eventはないようです;;
「+VB +Windows +API」で Google 検索
http://www.google.co.jp/search?sourceid=navclien …
すると,↓こんなサイトが見つかりました.
「WinAPI Database for VB Programmer」は、WindowsAPIの解説を1600以上保有するサイト。
http://www.winapi-database.com/
VB5 でも API を使えるようになるかどうかは知りませんが….
使えそうであれば,次の API を探して使ってください.
・CreateMutex()
・CreateEvent()
・SetEvent()
・ResetEvent()
Windows API の VB 用宣言を集めたファイルというのを以前どこかで
見かけたことがあるので,このサイトでも探せば見つかるかもしれません.
また,ウインドウメッセージと Event を同時に待つには,メッセージループの
中で次のどちらかの API を使えば実現できますが,VB のメッセージループを
プログラマが変更できるのか,あるいは変更できないまでも,Event を待つように
指定できるのかどうかは知りません.(ここが一番難関になりそうですが.)
・MsgWaitForMultipleObjects()
・MsgWaitForMultipleObjectsEx()
ありがとうございます。
> こんなサイトが見つかりました.
便利なサイトを教えて頂いてりがとうございます。サンプルがたくさんあってわかりやすいですね。
> VB5 でも API を使えるようになるかどうかは知りませんが
VB5 でも API は使えます。
> 次の API を探して使ってください.
そういうAPIもあるんですね。
参考にさせて頂きます。
難しそうですががんばってみます。
どうもありがとうございました。
No.2
- 回答日時:
VBはどのバージョンでしょう? VB6でしょうか ...
実行ファイルの位置(パス)が同じなら PrevInstanseで確認できます
すでに起動している自分自身を見つけるには EnumWindowsのコールバックで WM_GETTEXTを引数にしてSendMessageでCaptionを取得してみましょう
Dim buf(256) as Byte
dim s as String, n as Integer
if IsWindowVisible( hWnd ) then
' IsWindowsVisibleも WinAPIです ...
SendMessage hwnd, WM_GETTEXT, 256, buf(0)
s = StrConv( buf, vbUnicode )
n = Instr( buf, char(0) )
s = left( s, n -1 )
end if
といった具合で ...
どうもありがとうございます。
すいません、VB5です。
>SendMessageでCaptionを取得してみましょう
タイトルバーがないのでCaptionもなく・・・;;
ウインドウをウインドウテキストやクラス名以外で検索する方法が、他にあるのではないかと思って質問させて頂いたのですが、簡単に一つのAPIで検索する方法はないようですね。
ダミーのコマンドボタンを貼り付けて、そのコマンドボタンを検索することで実現しようと思います。
どうもありがとうございました。
No.1
- 回答日時:
> アプリに二重起動防止機能を付けたい
二重起動防止は,Mutex を使えばできます.
.NET TIPS:Windowsアプリケーションの多重起動を禁止するには? (VB サンプルあり)
http://www.atmarkit.co.jp/fdotnet/dotnettips/145 …
> すでに起動されている場合はそのアプリのウインドウを
> 元の大きさに戻してアクティブにする
これはやったことがないのでわかりませんし,VB を知らないので VB で使えるかどうか
も知りませんが,Windows API レベルの話をすれば,Mutex と同様に名前付き Event
を使えばできそうな気がします.
(1) (名前付き) Mutex と同様に,(名前付き) Event を作成する.
(2a) (1) に失敗 (ERROR_ALREADY_EXISTS) した場合には,既にアプリケーションが起動
されている.このとき,既に作成済の Event のハンドルが得られるので,
そのイベントをシグナル状態にすることにより,最初に起動されたアプリに
二重起動されそうになったことを知らせる.
(2b) (1) に成功した場合には,メッセージループで常に上記のイベントを監視しておき,
それがシグナル状態になったらウインドウを元の大きさに戻してアクティブにする.
Windows API のレベルでは,この方法でできると思いますが,VB で Event が使えるか,
また VB のメッセージループで Event を監視する方法があるかどうかは知りません.
どうもありがとうございます。
すいません;;、バージョンを言うのを忘れていました。VB5です。
VB5にはご紹介頂いたMutexや Eventはないようです;;
.NETにはそのような機能があるのですね。
勉強になりました。
どうもありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
都道府県穴埋めゲーム
都道府県の名前を1人1つずつ投稿してください。全ての都道府県が出たら締め切ります!
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
VB6での二重起動(複数起動)の制御について
Visual Basic(VBA)
-
VB6 二重起動確実防止について
その他(開発・運用・管理)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB.NETでMessageBoxを表示した...
-
コンソールアプリケーションの...
-
Vba アプリケーションが立ち上...
-
MFCアプリケーションでの終了コ...
-
VBSで2バイト文字の送り方の質...
-
現在起動中のアプリケーション...
-
VBSでのSendKeysでの画面の最小化
-
スクリーンセイバーのタイマー...
-
イラストレーターCS4のシリアル...
-
Accessフォームからの外部アプ...
-
他アプリケーションの終了
-
WSH(VBScript)でアプリケーショ...
-
外部アプリケーションの起動に...
-
outlookが強制終了してしまう
-
自分自身を更新するプログラム
-
Ms draw を使ってみたい
-
EXEファイルのタイトル取得
-
[Visual C++]VCが起動しません...
-
FOM出版の公認テキスト&問題集...
-
初回接続の遅い原因について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSでのSendKeysでの画面の最小化
-
Vba アプリケーションが立ち上...
-
コンソールアプリケーションの...
-
Accessフォームからの外部アプ...
-
pccNTmon.exeとntrtscan.exeの違い
-
Windowsプログラムのビジー状態...
-
自分自身を更新するプログラム
-
フレームワーク「4.8.1」で、[S...
-
VB.NETでMessageBoxを表示した...
-
C#でGUI・CUIの判断する仕方を...
-
現在起動中のアプリケーション...
-
実行時のコマンドプロンプトを...
-
VB6での二重起動(複数起動)の制...
-
VB.NETでフォームアクティブの...
-
Console Applicationをタスクト...
-
コマンドライン版ソフトの意義
-
イラストレーターCS4のシリアル...
-
MFCアプリケーションでの終了コ...
-
vb6で異なるのプロジェクト間で...
-
OSによるWinExecの動...
おすすめ情報