すみません。
昨日書いたのにバグがあったので修正しました。
#include "kernel32.as"
#include "user32.as"
#module "topmostmod"
#uselib "kernel32.dll"
#func QueryFullProcessImageName "QueryFullProcessImageNameA" int, int, int, int
#uselib "psapi.dll"
#func EnumProcessModules "EnumProcessModules" int, int, int, int
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, int, int
#define PROCESS_VM_READ 0x10
#define PROCESS_QUERY_INFORMATION 0x400
#define PROCESS_NAME_NATIVE 0x00000001
#define GWL_EXSTYLE 0xFFFFFFEC
#define WS_EX_TOPMOST 0x00000008
#define GW_HWNDFIRST 0
#define GW_HWNDNEXT 2
// Vista以降か調査
#defcfunc isVista local lpVersionInfo
dim lpVersionInfo,37
lpVersionInfo(0) = 148
GetVersionExA varptr(lpVersionInfo)
return(6 <= lpVersionInfo(1))
// ハンドル から ファイルパス を取得
#defcfunc getProcessPath int handle,local pid,local hsnap,local hprocess,local hmod,local nneed,local out
sdim out, 260
GetWindowThreadProcessId handle, varptr(pid)
OpenProcess PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid
hprocess = stat
if(hprocess!=0){
if(isVista()) {
// Vista以降の環境
size = 260
QueryFullProcessImageName hprocess, 0, varptr(out), varptr(size)
}else {
// XP以前の環境
hmod = 0:nneed = 0
EnumProcessModules hprocess, varptr(hmod), 4, varptr(nneed)
if(stat!=0){
GetModuleFileNameEx hprocess, hmod, varptr(out), 260
}
}
CloseHandle hprocess
}
return(out)
// 全てのトップレベルウィンドウのハンドルのリストを取得
#deffunc getHwndList array hwndarray,local prm
dim codeenumwnd, 10
codeenumwnd( 0) = $0824448b, $3b08488b, $067c0448, $08488941, $108b0eeb, $24748b56
codeenumwnd( 6) = $8a348908, $5e0840ff, $c240c033, $00000008
VirtualProtect varptr(codeenumwnd), 40, $40, AZSD
prm = 0, 0, 0
EnumWindows varptr(codeenumwnd), varptr(prm)
dim hwndarray, prm(2)
prm = varptr(hwndarray), prm(2), 0
EnumWindows varptr(codeenumwnd), varptr(prm)
return(hwndarray)
// 文字列の語尾が一致しているかどうか
#defcfunc isEndsWith str target,str suffix,local x
if(strlen(target) < strlen(suffix)) {
return(0)
}
x = target
return(strmid(x, strlen(target) - strlen(suffix), strlen(suffix)) == suffix)
// ハンドルが常に最前面表示されているかどうか
#defcfunc isTopMost int handle
GetWindowLongA handle, GWL_EXSTYLE
return((stat & WS_EX_TOPMOST) != 0)
// ハンドルが可視かどうか
#defcfunc isVisble int handle
IsWindowVisible handle
return(stat != 0)
// 指定した実行ファイルのハンドルのリストを取得
#deffunc getHwndListByPath array list, str path, local hwndarray, local buff, local len
getHwndList hwndarray
len = 0
dim buff, length(hwndarray)
repeat length(hwndarray)
if isVisble(hwndarray(cnt)) {
if isEndsWith(getProcessPath(hwndarray(cnt)), path) {
buff(len) = hwndarray(cnt)
len++
}
}
loop
dim list, len
memcpy list, buff, 4 * len
return
// 指定したハンドルより上のハンドルのリストを取得
#deffunc getPrevHwndList array list, int handle, local buff, local len, local x
GetWindow handle, GW_HWNDFIRST
x = stat
dim buff, 512
len = 0
repeat
GetWindow x, GW_HWNDNEXT
if(stat == handle)||(stat == x) {
break
}
x = stat
if(isVisble(x)) {
buff(len) = x
len++
}
loop
dim list, len
memcpy list, buff, 4 * len
return
// 指定したハンドルのバウンディングボックスを取得する
#deffunc getBBList array list, array rect
dim rect, 4, length(list)
repeat length(list)
GetWindowRect list(cnt), varptr(rect(0, cnt)) ;min_x,min_y,max_x,max_y
loop
return
#define min_x 0
#define min_y 1
#define max_x 2
#define max_y 3
// バウンディングボックスと点との当たり判定
#defcfunc isContains int A, int x, int y,local box
dupptr box, A, 4 * 4, vartype("int")
return((box.min_x < x) & (x < box.max_x) & (box.min_y < y) & (y < box.max_y))
// バウンディングボックス同士の当たり判定
#defcfunc isIntersectBB int A, int B,local box1,local box2
dupptr box1, A, 4 * 4, vartype("int")
dupptr box2, B, 4 * 4, vartype("int")
if(box1.min_x >= box2.max_x) { return(0)
}else:if(box1.max_x <= box2.min_x) { return(0)
}else:if(box1.min_y >= box2.max_y) { return(0)
}else:if(box1.max_y <= box2.min_y) { return(0)
}else { return(1) }
// 指定したハンドルが、他のハンドルとぶつかっているかどうか調べる
#deffunc isHitHandle array list, int handle,local MYBB,local TARGETBB,local ishittt
dim MYBB, 4
GetWindowRect handle, varptr(MYBB)
getBBList list, TARGETBB
ishittt = 0
repeat length(list)
ishittt = isIntersectBB(varptr(MYBB), varptr(TARGETBB(0, cnt)))
if(ishittt) {
break
}
loop
return(ishittt)
// 指定したファイルのソフトの画面がほかのウィンドウに重なっていないか調べる
#defcfunc isKasanatteinai str path,local list,local prevlist,local kasanatteinai
getHwndListByPath list, path
kasanatteinai = 0
repeat length(list)
getPrevHwndList prevlist, list(cnt)
isHitHandle prevlist, list(cnt)
if(stat == 0) {
kasanatteinai = 1
break
}
loop
return(kasanatteinai)
#global
exec "calc"
filename = "\\calc.exe"
repeat
redraw 1:wait 5:redraw 0
pos 0,0:color 255,255,255:boxf:color
if(isKasanatteinai(filename)) {
mes filename
mes "ソフトのウィンドウの上に、何も重なっていません"
mes "ここに処理内容を書く"
}
loop