|
|
2013/5/25(Sat) 10:43:19|NO.54277
フォルダ・ファイルをクリックするだけでパス名を表示したいです。
【例】
HSPが監視しています。
HSPから外れて電卓をクリックするとHSPにパス名が表示される
C:\Users\ユーザー名\Desktop\calc.exe
D:\calc.exe
のような感じ。
どこにファイルがあってもパス名を取得できるようなものを作れる方いたらサンプルソースお願いします!!
|
|
2013/5/26(Sun) 12:34:23|NO.54306
フォルダ・ファイルなら、マウス右クリックの[プロパティ]でわかるのではないでしょうか?
また、電卓に送られるマウスクリックをフックするのは困難というか、行儀が悪いとおもいます。
サンプルスクリプトでは、以下の手順で、マウス下のウィンドウの実行ファイルのパス名を表示します。
① ginfo(0) とginfo(1) でマウス位置を監視する
② WindowFromPoint と GetWindowLong でウィンドウハンドルを取得
③ GetWindowThreadProcessId でプロセスIDを取得
④ OpenProcess でプロセスハンドルを取得
⑤ EnumProcessModules でモジュールハンドルを列挙
⑥ GetModuleFileNameEx でモジュールのファイルのパスを取得 → .exeファイルを検索
#uselib "user32.dll"
#func WindowFromPoint "WindowFromPoint" sptr,sptr
#func GetWindowLong "GetWindowLongA" sptr,sptr
; HWND hWnd, ウィンドウのハンドル
; int nIndex 取得する値のオフセット
#const GWL_HWNDPARENT $FFFFFFF8 ; -8 親ウィンドウのハンドル
#cfunc GetWindowThreadProcessId "GetWindowThreadProcessId" sptr,sptr ;ウィンドウを作成したスレッドの ID が返ります。
; HWND hWnd, ウィンドウのハンドル
; LPDWORD lpdwProcessId プロセス ID
; ↑指定すると、それが指す変数にプロセス ID がコピーされます。
; NULL を指定した場合は、プロセス ID の取得は行われません。
; 戻り値はウィンドウを作成したスレッドの ID が返ります。
#uselib "KERNEL32.DLL"
#func CloseHandle "CloseHandle" int
#func OpenProcess "OpenProcess" int,int,int
; DWORD dwDesiredAccess, // アクセスフラグ
; BOOL bInheritHandle, // ハンドルの継承オプション
; DWORD dwProcessId // プロセス識別子
#const PROCESS_QUERY_INFORMATION 0x0400
#const PROCESS_VM_READ 0x0010
#uselib "psapi.dll"
#func EnumProcessModules "EnumProcessModules" sptr,sptr,sptr,sptr
; HANDLE hProcess, // プロセスのハンドル
; HMODULE * lphModule, // モジュールハンドルを受け取る配列
; DWORD cb, // 配列のサイズ
; LPDWORD lpcbNeeded // 必要なバイト数
#func GetModuleFileNameEx "GetModuleFileNameExA" sptr,sptr,sptr,sptr
; HANDLE hProcess, // プロセスのハンドル
; HMODULE hModule, // モジュールのハンドル
; LPTSTR lpFilename, // パスを受け取るバッファ
; DWORD nSize // 取得したい文字の最大の長さ
screen 0,300,100,0,ginfo_dispx-305,5
gsel 0,2
file_path="" : mesbox file_path ,300,100,0 : id_mesbox=stat
*mainloop
wait 10
x_mouse=ginfo(0) : y_mouse=ginfo(1)
title "マウスX座標"+x_mouse+" マウスY座標"+y_mouse
if (x_mouse != x_mouse_old) | (y_mouse != y_mouse_old) {
x_mouse_old=x_mouse : y_mouse_old=y_mouse
hwnd_under=0 : pid_under=0 : thr_under=0 : hProcess=0 : hModule=0 : sdim file_path, 256
WindowFromPoint x_mouse, y_mouse : hwnd_under=stat
GetWindowLong hwnd_under,GWL_HWNDPARENT : if stat != 0 : hwnd_under=stat
thr_under=GetWindowThreadProcessId(hwnd_under,varptr(pid_under))
if pid_under {
OpenProcess PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid_under : hProcess=stat
if hProcess {
EnumProcessModules hProcess,varptr(hModule),4,varptr(size)
if stat {
dim v_hModule,size/4 ;: list_hModule=""+size/4+"\n"
EnumProcessModules hProcess, varptr(v_hModule), size, varptr(size)
repeat size/4
;list_hModule+=""+v_hModule.cnt+"\n"
GetModuleFileNameEx hProcess, v_hModule.cnt, varptr(file_path), 256
newcom oReg,"VBScript.RegExp"
oReg("Pattern")=".exe$" ; 検索パターン <= .exeファイルを検索する
oReg("IgnoreCase")=1 ; 大文字小文字を区別しない
val_mach=oReg("Test", file_path)
delcom oReg
if val_mach {
objprm id_mesbox,"ウィンドウハンドル:"+hwnd_under+"\nプロセスID:"+pid_under+"(スレッドID:"+thr_under+")\nプロセスハンドル:"+ hProcess+"\nモジュールハンドル:"+v_hModule.cnt+"\n"+file_path+"\n";+size
}
loop
;dialog "モジュールハンドル("+size/4+"個)"+list_hModule
}
CloseHandle hProcess
}
}
}
goto *mainloop

| |
|
2013/5/26(Sun) 14:49:52|NO.54312
長いソースありがたいですが、クリックしたときにほしいです。。
|
|
2013/5/26(Sun) 14:53:37|NO.54313
GetActiveWindowを監視すればフック無しでも可能ですね。
|
|
2013/5/26(Sun) 15:46:35|NO.54315
>if (x_mouse != x_mouse_old) | (y_mouse != y_mouse_old) {
これの代わりにgetkeyとかstickのアクティブチェックOFFで
クリック監視すれば良いだけじゃ?
wait 10だと反応鈍くなるからその辺も変えて
|
|
2013/5/26(Sun) 16:11:37|NO.54317
GetActiveWindow
はもう起動済みですよね。
フォルダやファイルを起動しようとするときクリックしますよね。
そのクリックした奴のパス名がほしいんです。
|
|
2013/5/26(Sun) 17:34:32|NO.54319
開いている電卓のウィンドウをマウスクリックしたとき、電卓の実行モジュール(.exeファイル)のパス名が知りたいというふうに理解しましたが、どうなのでしょうか?
他ウィンドウのマウスクリックは暇人さんのご指摘のように、getkeyとかstickのアクティブチェックOFFで知りえます。
ht.さんのご指摘のとおりGetActiveWindowをつかってみましたが、うまくいきません。
どろなわですが、以下参考までにスクリプト。
#uselib "user32.dll"
#func GetActiveWindow "GetActiveWindow"
#cfunc GetForegroundWindow "GetForegroundWindow"
#func WindowFromPoint "WindowFromPoint" sptr,sptr
#func GetWindowLong "GetWindowLongA" sptr,sptr
; HWND hWnd, ウィンドウのハンドル
; int nIndex 取得する値のオフセット
#const GWL_HWNDPARENT $FFFFFFF8 ; -8 親ウィンドウのハンドル
#cfunc GetWindowThreadProcessId "GetWindowThreadProcessId" sptr,sptr ;ウィンドウを作成したスレッドの ID が返ります。
; HWND hWnd, ウィンドウのハンドル
; LPDWORD lpdwProcessId プロセス ID
; ↑指定すると、それが指す変数にプロセス ID がコピーされます。
; NULL を指定した場合は、プロセス ID の取得は行われません。
; 戻り値はウィンドウを作成したスレッドの ID が返ります。
#uselib "KERNEL32.DLL"
#func CloseHandle "CloseHandle" int
#func OpenProcess "OpenProcess" int,int,int
; DWORD dwDesiredAccess, // アクセスフラグ
; BOOL bInheritHandle, // ハンドルの継承オプション
; DWORD dwProcessId // プロセス識別子
#const PROCESS_QUERY_INFORMATION 0x0400
#const PROCESS_VM_READ 0x0010
#uselib "psapi.dll"
#func EnumProcessModules "EnumProcessModules" sptr,sptr,sptr,sptr
; HANDLE hProcess, // プロセスのハンドル
; HMODULE * lphModule, // モジュールハンドルを受け取る配列
; DWORD cb, // 配列のサイズ
; LPDWORD lpcbNeeded // 必要なバイト数
#func GetModuleFileNameEx "GetModuleFileNameExA" sptr,sptr,sptr,sptr
; HANDLE hProcess, // プロセスのハンドル
; HMODULE hModule, // モジュールのハンドル
; LPTSTR lpFilename, // パスを受け取るバッファ
; DWORD nSize // 取得したい文字の最大の長さ
screen 0,300,100,0,ginfo_dispx-305,5
file_path="" : mesbox file_path ,300,90,0 : id_mesbox=stat
gsel 0,2
*@
wait 10 ; <= この程度でも反応に問題ない
getkey stat_key,1
if stat_key {
;GetActiveWindow : hwnd_under=stat ; <= コレはNG(うまくいかない)
;hwnd_under=GetForegroundWindow() ; <= コレはそこそこ(エクスプローラとかで反応いまいち)
WindowFromPoint ginfo(0),ginfo(1) : hwnd_under=stat ; <= コレはOK
if hwnd_under {
pid_under=0 : thr_under=0 : hProcess=0 : hModule=0 : sdim file_path, 256
GetWindowLong hwnd_under,GWL_HWNDPARENT : if stat != 0 : hwnd_under=stat
thr_under=GetWindowThreadProcessId(hwnd_under,varptr(pid_under))
if pid_under {
OpenProcess PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid_under : hProcess=stat
if hProcess {
EnumProcessModules hProcess,varptr(hModule),4,varptr(size)
if stat {
dim v_hModule,size/4
EnumProcessModules hProcess, varptr(v_hModule), size, varptr(size)
repeat size/4
GetModuleFileNameEx hProcess, v_hModule.cnt, varptr(file_path), 256
newcom oReg,"VBScript.RegExp"
oReg("Pattern")=".exe$" ; 検索パターン <= .exeファイルを検索する
oReg("IgnoreCase")=1 ; 大文字小文字を区別しない
val_mach=oReg("Test", file_path)
delcom oReg
if val_mach {
objprm id_mesbox,"ウィンドウハンドル:"+hwnd_under+"\nプロセスID:"+pid_under+"(スレッドID:"+thr_under+")\nプロセスハンドル:"+ hProcess+"\nモジュールハンドル:"+v_hModule.cnt+"\n"+file_path+"\n";+size
}
loop
}
CloseHandle hProcess
}
}
}
}
goto *@b

| |
|
2013/5/26(Sun) 21:21:58|NO.54331
woodfieldsさん長々としたソースありがとうございます。
ですが、私の求めてるのは『フォルダやファイルを起動しようとするときクリックしますよね。
そのクリックした奴のパス名がほしいんです。』
例にデスクトップにフォルダがありますよねそれにはパスがありますよね。
それを取得したいんです
|
|
2013/5/27(Mon) 18:26:43|NO.54363
起動するまでパスの取得はできない
|
|
2013/5/27(Mon) 19:33:58|NO.54366
>フォルダやファイルを起動しようとするときクリックしますよね。
そのクリックした奴のパス名がほしいんです
ファイルをウィンドウにD&Dさせるのがアリなら、
サンプルのdragdrop.hspを読めばすぐに解決なんだけどね……
以下、転載。
; Windowへのドラッグ&ドロップsample
; http://quasiquote.org/hspwiki/
; thanks ちょくと さん
; http://yokohama.cool.ne.jp/chokuto/urawaza/dragdrop.html
;
#uselib "shell32.dll"
#func DragAcceptFiles "DragAcceptFiles" int,int
#func DragQueryFile "DragQueryFileA" int,int,int,int
#func DragQueryPoint "DragQueryPoint" int,int
#func DragFinish "DragFinish" int
#define WM_DROPFILES 0x0233
; WM_DROPFILES メッセージハンドラを設定
oncmd gosub *OnDropFiles, WM_DROPFILES
; ファイルをドラッグ&ドロップできるように設定
DragAcceptFiles hwnd, 1
title "ウィンドウにファイルをドロップしてください"
stop
*OnDropFiles
; --- ファイルがドロップされたとき ---
; ドロップされたファイルの数を取得する
hdrop = wParam ; ドロップファイル情報のハンドル
DragQueryFile hdrop, -1, 0, 0
ndrop = stat ; ファイルの数
; 画面をクリア
syscolor 5 : boxf
syscolor 8 : pos 0,0
; ファイル名を取得して表示
sdim filename, 260
repeat ndrop
DragQueryFile hdrop, cnt, varptr(filename), 260
mes filename
loop
; ドロップファイル情報をクリア (これをしないとメモリリークになる)
DragFinish hdrop
return

| |
|
2013/5/27(Mon) 19:43:09|NO.54367
なるほど。ですがクリックではなくてデスクトップのフォルダは全て参照できました
これをクリックしたときにクリックしたフォルダのみを表示とか
できないですかね・・・
screen 0,500,800
font "",10
chdir dirinfo(0x10000)
sdim list, 256
dirlist list,"*.*", 1
mes list
|
|
2013/5/27(Mon) 20:29:50|NO.54373
どの ファイルorフォルダ (のアイコン) が「クリック」や「選択」されているのか ということは、
「explorer」というプログラムだけが知っているのではないでしょうか?
私の認識では、デスクトップ上に表示されているアイコンもこのプログラムが表示・管理しているのだと思います。
私の勝手な想像になりますが、他のプログラム (今回はHSP製ですね。) からその情報を取得する
ことは、そもそもできないんじゃないかと思います。
ファイルマネージャやデスクトップシステム自体を自作するのが根本的な解決策になるんじゃない
かなと思います。
具体的なアドバイスになっていなくて申し訳ないです。
|
|
2013/5/27(Mon) 21:35:46|NO.54374
FunnyMakerさん
なるほどですね。。。。
やっぱり無理ですかねえ。。。
ふむふむ。困ったものですね;;
どうにかしたいですが今回ばかりはあきらめますかね^^
回答者の皆さんありがとうございました^^
|
|
2013/5/28(Tue) 01:14:23|NO.54382
解決!
|
|