vb2010で別のアプリの新しいウィンドウが開いた時の取得方法は?

タグの編集
投稿者 紅孔雀  (その他) 投稿日時 2010/6/13 20:22:40
こんにちは。

vb2010で在中ソフトを作ってみようと思ってるのですが、他のアプリ内の新しいウィンドウが開かれた時にそのウィンドウ名を取得するような事は可能でしょうか? プロセスで試した結果、新しいウィンドウが開かれても変化無しでした。 当然と言えば当然なのかも知れないですけど・・・。

あるアプリが起動していて、その中のツールウィンドウなどが開かれた時にウィンドウ名を取得したいのですけど、このツールウィンドウはタスクに表示されないウィンドウですが、取得は可能でしょうか?

参考になりそうなサイトやサンプルを提供出来るようでしたらお願いいたします。
投稿者 daive  (社会人) 投稿日時 2010/6/14 03:55:23
まずは、SPY++や、互換機能の、プログラムで、そのウィンドを調べてみてください。
そこで、ウィンドハンドルや、ウィンド名が取得できれば、判別が可能です。
ウィンド上のオブジェクトも、コントロール名が取得できれば、
外部から操作が、可能な場合もあります。
それらで、取得できるという事は、何らかの方法があるという事ですよね?

面倒だったり、工夫が必要な部分は、OSや、.NETが管理していますので、
OSや、.NETについて勉強してください。
場合によっては、Windows-APIでの方が、簡単な場合もあります。

>タスクに表示されないウィンドウですが
曖昧な表現です。
タスクバーに表示されないだけなのか?
=タスクマネージャの、アプリケーションタブに表示されないだけなのか?
それとも、
プロセスタブに表示されないのか?→ステルスウィルスや、過去SONYのCDで使われましたねぇ。

>他のアプリ内の新しいウィンドウが開かれた時に
>そのウィンドウ名を取得するような事は可能でしょうか?
その瞬間に判別したいのか、それとも、?
瞬間であれば、Windowsの管理を横取りする事になります。→VBだと難しいかも。
  興味があるのであれば、Windows フック、Windows フック 書換 で、調べてください。
  ウィルスチェッカが、何故Windowsのファイルシステムより前に、ファイルをチェック出来るのかの
  答えの一部です。
瞬間でなく大まかでよければ、プログラムで定期的に、
ウィンドハンドルから調べて行く方法が取れます。
投稿者 るきお  (社会人) 投稿日時 2010/6/14 13:26:52
CBTフックでできるんじゃないかと思いますが、サンプルを書いてみるとうまく動かず中断しました。
具体的なことかけないですいません。
SetWindowsHookExやCBTフック、WH_CBTなどをキーワードに調べてみてください。

誰かVBでほかのプロセスに対してCBTフックするサンプルを書ける人はぜひ投稿してください。
投稿者 あにす  (社会人) 投稿日時 2010/6/15 07:34:39
VBのみでのCBTフックは動きません。C、C++等でCBTフックするDLLを作って、何らかの方法でVBから呼び出す必要があります。ちょっと以前に書いたコードを探してみます。
投稿者 あにす  (社会人) 投稿日時 2010/6/15 08:23:40
以前に書いたコードを切り貼りしてみました。ウィンドウタイトルの取得が上手くいってませんが、ウィンドウが生成されたタイミングは取得出来ています。
ただ、トップレベルウィンドウだけではなく全てのウィンドウ(VBでいうコントロール等を含む)生成のタイミングでフックが発生するようです。EnumWindows関数を等間隔で呼び出した方がいいかも知れませんね。

【main.h】
#define DllExport    __declspec( dllexport )
#define USER_MESSAGE_CREATE (WM_USER + 0x774)

DllExport void CALLBACK sethook(void);//FocusProc);
DllExport void CALLBACK freehook(void);


【main.c】
#include <windows.h>
#include "main.h"

HHOOK hHookWnd = 0;

HINSTANCE hdll;

BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD reason, LPVOID lpReserved)
{
    (void)lpReserved;
    if(reason==DLL_PROCESS_ATTACH){
        hdll=hInstance;     //DLLのハンドルを保存する
    }
    return  TRUE;
}

LRESULT CALLBACK CBTProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    if(nCode == HCBT_CREATEWND){
        PostMessage(FindWindow(NULL,TEXT("VB中学校")),USER_MESSAGE_CREATE,wParam,lParam);
    }

return CallNextHookEx(NULL, nCode, wParam, lParam); //次のフックを呼ぶ
}

//フックを組み込む
void CALLBACK sethook(void)//FocusProc focusProc)
{
    hHookWnd = SetWindowsHookEx(WH_CBT,CBTProc, hdll, 0);
}

//フックを解除する
void CALLBACK freehook(void)
{
    UnhookWindowsHookEx(hHookWnd);
}


【main.def】
LIBRARY "WindowHook";

EXPORTS
    sethook
    freehook


【Form1.vb】
Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1

    Private Const WM_USER As Integer = &H400
    Private Const USER_MESSAGE_CREATE As Integer = WM_USER + &H774

    Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
        Me.Text = "VB中学校"
        sethook()
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case USER_MESSAGE_CREATE
                Dim newWndHandle As Integer = m.WParam
                Dim windowText As New StringBuilder(256)
                GetWindowText(newWndHandle, windowText, windowText.Capacity)
                Me.ListBox1.Items.Add(windowText.ToString())
        End Select

        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As System.ObjectByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
        freehook()
    End Sub

    <DllImport("WindowHook.dll")> _
    Private Shared Sub sethook()
    End Sub

    <DllImport("WindowHook.dll")> _
    Private Shared Sub freehook()
    End Sub

    <DllImport("User32")> _
    Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As IntegerAs Integer
    End Function
End Class
投稿者 紅孔雀  (その他) 投稿日時 2010/6/16 18:40:04
こんにちは。

返事遅くなってすみません。
みなさん解答ありがとうございます。
みなさんがおっしゃるように、検索などして調べてみます。
あにすさん、サンプルの提供ありがとうございます。
色々と試行錯誤してみます。

自分には難しそうですが、頂いた情報などを有効に活用してみたいと思います。