마음의 안정을 찾기 위하여 - ClickThereItIs! - Whose Window this is ?
2278085
793
743
관리자새글쓰기
태그위치로그방명록
별일없다의 생각
dawnsea's me2day/2010
색상(RGB)코드 추출기(Color...
Connection Generator/2010
최승호PD, '4대강 거짓말 검...
Green Monkey**/2010
Syng의 생각
syng's me2DAY/2010
천재 작곡가 윤일상이 기획,...
엘븐킹's Digital Factory/2010
ClickThereItIs! - Whose Window this is ?
분류없음 | 2005/01/11 11:48





ClickThereItIs! - Whose Window this is ?







history href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

2003/11/22:作成
2004/10/27: href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#d20041027"
target=_blank>更新

最新版。 href="http://www.geocities.jp/fjtkt/problems/2003_0001/20041027ModuleView.zip"
target=_blank> color=#0033cc>20041027ModuleView.zip(191,113bytes)






memo href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

とりあえずテストプログラム第1弾です。

あるタイミングにおいて(ってこのタイミングが非常に難しいんですが)、マウスの直下にあるウィンドウを捜します。これは大丈夫です。WindowFromPoint(うろ覚え)を使います。

でとりあえずテストなので、ボタンのMouseUpイベントをそのタイミングとします。ボタンの上でマウスの左ボタンをを押してそのままドラッグして別の場所で左ボタンを離すと、デスクトップの任意の場所にマウスがある状態で自作のアプリケーションがイベントを拾えます。で、このときのマウスの位置をそれなりにスクリーン座標に変換しその直下のウィンドウを見つけるというわけです。

それだけではなくて、今度はそのウィンドウを所有しているプログラム(アプリケーション)を捜します。たとえば自分の作ったアプリケーションなら"Project1.exe"とかデスクトップなら"Explorer.exe"とかフォルダを開いているのならやっぱり"Explorer.exe"とか。もちろんフルパスで。

本当の目的は開いているフォルダのフルパスをとりたいのですが、とりあえずそのウィンドウが何らかのアプリケーションなのかエクスプローラなのかを判断する必要があるかと。そしてもちろんエクスプローラなら、開いているフォルダのパスを取得したいと。ただこっちの方はさらに先の話になるかと思います。

とか書いてますが、実際には、マウスの下のウィンドウの持ち主は取得できています。以下にコードを示します。誰かの役にも自分の役にも立ちますように。

問題は、使用しているAPIが「psapi.dll」なんていう見たこともないDLLを使用していてこれがまたNT系でしか使用できないときた。嫌な感じだ。






screen shot href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

Button1を押したまま(左ボタンを離さずに)で、エクスプローラで開いたフォルダの上でマウスを離した状態です。1行目にその時のスクリーン座標、2行目にその場所にあったウィンドウを実行しているプロセス、で関連するモジュールが表示されています。モジュールの最初には大本のアプリケーションが表示されるようです。

src="http://www.geocities.jp/fjtkt/problems/2003_0001/ClickHereItIs_001.png"
width=448>






code href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

unit Main;

interface

uses
Windows, SysUtils, Classes, Controls, Forms, StdCtrls, Buttons, ExtCtrls;

type
TMainForm = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
Button1: TButton;
procedure Button1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private

public

end;

var
MainForm: TMainForm;

implementation

{$R *.dfm}

uses
psapi;

(*
===========================================================================
プロセスIDに関係するモジュールフルパス
---------------------------------------------------------------------------
XP, 2003, 2000(Pro/Svr), NT(WS/Svr) 限定
---------------------------------------------------------------------------
ms-help://MS.PSDK.1033/perfmon/base/enumerating_all_modules_for_a_process.htm
===========================================================================
*)

procedure PrintModules(AProcID: Cardinal; AResults: TStrings);
const
MAX_HMODULE = 1024;
var
DesiredAccess: Cardinal; // フラグ
ModHandle : array[0..MAX_HMODULE-1] of HMODULE; // モジュールハンドル
ProcHandle: THandle; // プロセスハンドル
cbNeeded : DWORD; // 配列の大きさ
i : integer;
p : PChar;
ModNameLen: integer; // モジュール名長
ModName : string; // モジュール名
begin
// とりあえずプロセスIDを出力しておく
AResults.Add(Format('Process ID: %d', [AProcID]));
// プロセスのハンドルを取り出す
DesiredAccess := PROCESS_QUERY_INFORMATION or PROCESS_VM_READ;
ProcHandle := OpenProcess(DesiredAccess, false, AProcID);
// 失敗?
if (ProcHandle = INVALID_HANDLE_VALUE) then
begin
Exit;
end
// 成功!
else
begin
try
// このプロセスの全てのモジュールのリストを取得する(pspi.dll)
if (EnumProcessModules(ProcHandle, @ModHandle, MAX_HMODULE, cbNeeded)) then
begin
// モジュールの個数だけ繰り返しましょう
for i := 0 to (cbNeeded div sizeof(HMODULE)) - 1 do
begin
// メモリ確保
GetMem(p, MAX_PATH);
// モジュールファイルのフルパス取得
ModNameLen := GetModuleFileNameEx(ProcHandle, ModHandle[i], p, MAX_PATH);
// 長さ調節
SetString(ModName, p, ModNameLen);
// メモリ解放
FreeMem(p);
// リストに追加
AResults.Add(Format('%s (%8d)', [ModName, ModHandle[i]]));
end;
end;
finally
// 開けたら閉める
CloseHandle(ProcHandle);
end;
end;
end;

(*
===========================================================================
マウスの下にあるウィンドウのプロセスIDに関連するモジュール名称
===========================================================================
*)

procedure TMainForm.Button1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Pnt : TPoint;
WH : HWND;
ProcessID{, ThreadID}: integer;
begin
// うっとおしいのでクリア
Memo1.Lines.Clear;
// マウスを放したときの座標
Pnt := Point(X, Y);
// その座標をスクリーン座標に変換する
Pnt := TControl(Sender).ClientToScreen(Pnt);
// 変換した座標を表示する
Memo1.Lines.Add(Format('Mouse X:%3.3d Y:%3.3d', [Pnt.X, Pnt.Y]));
// その位置にあるウィンドウのハンドルを取る
WH := WindowFromPoint(Pnt);
// 有効ですか?
if (WH <> 0) then
begin
// そのウィンドウのプロセスIDは?
{ThreadID := }GetWindowThreadProcessId(WH, @ProcessID);
// でそのモジュール名は?
PrintModules(ProcessID, Memo1.Lines);
end;
end;

end.






Delphi 6 Personal dpr/dfm/pas href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

href="http://www.geocities.jp/fjtkt/problems/2003_0001/20031122ClickHereItIs_001.zip"
target=_blank> color=#0033cc>20031122ClickHereItIs_001.zip(2,918bytes)






2004/10/27 href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

ほんの少し変更しました。本当にどうでもよい変更ですが。

src="http://www.geocities.jp/fjtkt/problems/2003_0001/20041027ModuleView_001.png"
width=382>

白いパネルでマウスを押し、そのままマウスを移動させると調べようとするウィンドウを点滅させます。ただ、点滅はウィンドウなんですが、実際に調べるのはそのウィンドウの親をてっぺんまでさかのぼったウィンドウになります。出力するのは、そのウィンドウが使用しているDLL全て(のはず)です。

図は、自分自身を調べた状態です。ところで、変更箇所というのは、ウィンドウの点滅機能です。

実行ファイルとソースコード。 href="http://www.geocities.jp/fjtkt/problems/2003_0001/20041027ModuleView.zip"
target=_blank> color=#0033cc>20041027ModuleView.zip(191,113bytes)






EOF href="http://www.geocities.jp/fjtkt/problems/2003_0004.html#page_top"
target=_blank>TOP

*01/11/2005 10:30:22
* href="http://www.geocities.jp/fjtkt/problems/2003_0004.html"
target=_blank>BlueLeaf1336-PROBLEMS-2003_0004 >
Whose Window this is ? :: ClickThereItIs! - Whose Window this is
?

*<a target="link"
href="http://www.geocities.jp/fjtkt/problems/2003_0004.html">BlueLeaf1336-PROBLEMS-2003_0004
> Whose Window this is ? :: ClickThereItIs! - Whose Window this is
?</a>


:script -->

:script -->
:script --> src="http://visit.geocities.jp/visit.gif?&r=http%3A//www.geocities.jp/fjtkt/download/overview.html&b=Microsoft%20Internet%20Explorer%204.0%20%28compatible%3B%20MSIE%206.0%3B%20Windows%20NT%205.1%3B%20SV1%29&s=1024x768&o=Win32&c=32&j=true&v=1.2"
border=0>
2005/01/11 11:48 2005/01/11 11:48
이 글의 관련글 이글의 태그와 관련된 글이 없습니다.
Article tag list
 
Go to top
View Comment 0
Trackback URL :: 이 글에는 트랙백을 보낼 수 없습니다
 
 
 
 
: [1] ... [1008][1009][1010][1011][1012][1013][1014][1015][1016] ... [1317] :
«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
전체 (1317)
출판 준비 (0)
My-Pro... (41)
사는 ... (933)
블로그... (22)
My Lib... (32)
게임 ... (23)
개발관... (3)
Smart ... (1)
Delphi (93)
C Builder (0)
Object... (0)
VC, MF... (10)
Window... (1)
Open API (3)
Visual... (0)
Java, JSP (2)
ASP.NET (0)
PHP (5)
Database (12)
리눅스 (29)
Windows (25)
Device... (1)
Embedded (1)
게임 ... (0)
Web Se... (2)
Web, S... (21)
잡다한... (6)
프로젝트 (0)
Personal (0)
대통령... (13)
Link (2)