マウスOnタイトルバーチェック関数(テスト版)
マウスの下にウィンドウキャプションがあるかどうかを判定する関数
qdirもどき実現のためFunction実装前からsubでチョロチョロ作ってたもの。微妙な判定位置ズレとかアイコン検出とか調整してたらかなり冗長に。もうちょい推考するつもりだったけど時間取れないので、とりあえず動くものを置いときます。
2ちゃんのAhkスレではSendMessageでもっと簡単にできそうな雰囲気なのでちょっと期待
#Persistent auto: settimer,test return test: r := CheckOnMouseTitleBarEx(rhWnd,1) tooltip,%r% return CheckOnMouseTitleBarEX(byref rhWnd, MdiChild=0, def_cmode=1) ;----------------------------------------------------------------- ; マウスがタイトルバー上の何処にあるかチェックして返す ; 対象: AHK v1.0.34以降 作成 : 2005.10.25 ; ; out rhWnd マウス下ウィンドウハンドル ; in MdiChild 1:MDI子ウィンドウを対象に含める ; def_cmode 元のマウスモード 1:Relative(デフォルト) 0:Screen ; ; 戻り値 ; 0 : タイトルバー上ではない ; 1 : タイトルバー ; 2 : 右上アイコン ; 3 : 最小化ボタン [_] ; 4 : 最大化ボタン [□] ; 5 : ヘルプボタン [?] ; 6 : 閉じるボタン [X] ;----------------------------------------------------------------- { ;--- マウス座標値直下のコントロールハンドル取得 --- CoordMode,Mouse,Screen MouseGetPos,ScreenX,ScreenY,hWnd if (MdiChild) hWnd := DllCall("WindowFromPoint",Int,ScreenX, Int,ScreenY, UInt) WinGetPos ,WinL,WinT,WinW,,ahk_id %hWnd% WinGet, WinStyle, Style, ahk_id %hWnd% WinGet, WinExStyle,ExStyle, ahk_id %hWnd% ifEqual def_cmode,1, CoordMode,Mouse,Relative ;座標モードを戻しとく ;--- マウスがタイトルバー上にあるかチェック --- if (WinStyle & 0x00C00000 <> 0x00C00000) ;WS_CAPTION return 0 ;マウス下:タイトルなし if (WinExStyle & 0x00000080) ;WS_EX_TOOLWINDOW { ;小さいツールバー SysGet, barH, 51 ;SM_CYSMCAPTION :タイトル高さ SysGet, BtnWidth, 52 ;SM_CXSMSIZE :[_][?][□][X]ボタン幅 } else { SysGet, barH, 4 ;SM_CYCAPTION :タイトル高さ SysGet, BtnWidth,30 ;SM_CXSIZE :[_][?][□][X]ボタン幅 } if (WinT + barH < ScreenY) return 0 ;タイトルバー高さ < マウスY rhWnd := hWnd if (!(WinStyle & 0x00080000)) ;WS_SYSMENU return 1 ;--- タイトルバー上のどの位置にあるかをチェック --- if (WinStyle & 0x00040000 = 0x00040000) ;WS_THICKFRAME SysGet, frameW,32 ;SM_CXSIZEFRAME 可変窓 枠幅 else SysGet, frameW,7 ;SM_CXFIXEDFRAME 不可変窓 title_R := WinL + WinW - frameW if (ScreenX > title_R - BtnWidth) return 6 ;[x] ; 右から2つ目ボタンチェック (最大化 or ToolHelpボタン) else if (ScreenX > title_R - (BtnWidth * 2)) { if (WinStyle & 0x00010000) ;WS_MAXIMIZEBOX [□] return 4 else if (WinExStyle & 0x00000400) ;WS_EX_CONTEXTHELP [?] return 5 } ; 右から3つ目ボタンチェック (最小化) else if (ScreenX > title_R - (BtnWidth * 3)) { if (WinStyle & 0x00020000) ;WS_MINIMIZEBOX [_] return 3 } /* ※※※※アイコン存在確認法テスト用 ※※※※※ ;WNDCLASSEX 構造体にセットされたアイコン GCL_HICON := DllCall("GetClassLong", Uint,hWnd, Int,-14) ;GCL_HICON GCL_HICONSM := DllCall("GetClassLong", Uint,hWnd, Int,-34) ;GCL_HICONSM ;WM_SETICON メッセージによってセットされたアイコンを取得 SendMessage,0x007F,0,0,,ahk_id %hWnd% ;ICON_SMALL ICON_SMALL := ErrorLevel SendMessage,0x007F,1,0,,ahk_id %hWnd% ;ICON_BIG ICON_BIG := ErrorLevel SendMessage,0x007F,2,0,,ahk_id %hWnd% ;ICON_SMALL2(XP) ICON_SMALL2 := ErrorLevel OutputDebug, GCL_HICON=%GCL_HICON% GCL_HICONSM=%GCL_HICONSM% ICON_BIG=%ICON_BIG% ICON_SMALL=%ICON_SMALL% ICON_SMALL2=%ICON_SMALL2% ※※※※※※※※※※※※※※※※※※※※※※※※ */ ; --- 左上アイコンチェック --- ;大きいアイコンチェック iTemp := DllCall("GetClassLong", Uint,hWnd, Int,-14) ;GCL_HICON if (!iTemp) { SendMessage,0x007F,1,0,,ahk_id %hWnd% ;ICON_BIG iTemp := ErrorLevel } /* ;小さいアイコンチェック if (!iTemp) iTemp := DllCall("GetClassLong", Uint,hWnd, Int,-34) ;GCL_HICONSM if (!iTemp) { SendMessage,0x007F,0,0,,ahk_id %hWnd% ;ICON_SMALL iTemp := ErrorLevel } if (!iTemp) { SendMessage,0x007F,2,0,,ahk_id %hWnd% ;ICON_SMALL2(XP) iTemp := ErrorLevel } */ ifEqual iTemp,0, return 1 SysGet, work, 49 ;SM_CXSMICON SysGet, work2,45 ;SM_CXEDGE if (ScreenX < WinL + work + work2 + frameW) return 2 else return 1 }
PressIt! もどき
スクリプトフォルダ整理してきたら出てきた。前に2ちゃんのAutoHotKey Threadに貼った奴、の見た目改良版。もしくはCheckBoxをトグルボタンにするサンプルとでも。コントロール系のスタイルはほとんどノーチェックだったので最近までこういうのできるって知らなかったのよ。
;---- PressIt.Ahk ---- autoexecute: gui,add,checkbox,-Wrap GPressIt 0x00001000 X1 Y3 W60 H20 , SHIFT gui,add,checkbox,-Wrap GPressIt 0x00001000 X61 Y3 W60 H20 , CTRL gui,+AlwaysOnTop -MaximizeBox -MinimizeBox ToolWindow gui,show, w125 h25 ; , Status & Toggle settimer,keywatch,100 return keywatch: ;Shift,Ctrl押下監視 GuiControl,,SHIFT,% GetKeyState("Shift") GuiControl,,CTRL, % GetKeyState("Ctrl") return PressIt: ;ボタン押下で Shift or Ctrl ON/OFFトグル ToggleKey(A_GuiControl) return ToggleKey(keyname) ;キーの押下状態を反転する関数 { if (GetKeyState(keyname)) Send,{%keyname% Up} else Send,{%keyname% Down} } GuiClose: ;押下状態にあるキーを解除してスクリプト終了 if (!GetKeyState(Shift,"P")) Send,{Shift Up} if (!GetKeyState(Ctrl,"P")) Send,{Ctrl Up} exitapp
MDIアクティブウィンドウ取得関数
ついでに、面倒なことせんでもアクティブ子ウィンドウはSendMessageで取れるらしいのでそれも上げときます。
- MdiGetActive(WinTitle="", MdiClientName="")
- MDIにおいて現在アクティブなウィンドウのハンドルを取得する
MdiGetActive(WinTitle="", MdiClientName="") ;---------------------------------------------------------------------- ; MDIにおいて現在アクティブなウィンドウのハンドルを取得する ; 対象: AHK v1.0.34以降 作成 : 2005.11.21 ; in WinTitle 対象親ウィンドウ (省略時:アクティブウィンドウ) ; MdiClientName MDIクライアント名(省略時:MdiClient1) ; 戻り値:MDI子ウィンドウハンドル ;---------------------------------------------------------------------- { ifEqual,WinTitle,, SetEnv,WinTitle,A if (MdiClientName = "") { MdiClientName := "MdiClient1" WinGetClass,cls,%WinTitle% ifEqual cls,XLMAIN, SetEnv,MdiClientName,XLDESK1 } SendMessage, 0x229 , 0, 0, %MdiClientName%, %WinTitle% ;WM_MDIGETACTIVE ifEqual ErrorLevel,FAIL, return 0 else return %ErrorLevel% }
MDI子ウィンドウ列挙関数 修正
AutoHotkeyのバージョンを0.40.08にしてから エクセルの子ウィンドウアクティブ操作に失敗するようになった。なんでかと思って調べたら自作のExcel用MDI子ウィンドウ列挙関数(GetMdiChildWindowList)で WS_VISIBLEを見てないせいで不可視の Persnal.xlsやアドインコントロールなんかまで子ウィンドウ判定してしまってたのが原因だった。(1.0.40.05 で DetectHiddenWindows OFF状態でも 非可視ウィンドウのスタイルが取れるようになってたらしい。最近バージョンアップしてなかったので気がつかなかった。)
Styleの 0x10000000 が WS_VISIBLEなんだけど、ver 1.0.40.04では Style/ExStyle値は不定値だったっぽい。
--- ahk 1.0.40.04 (DetectHiddenWindows,ON) ---
hwnd = 263050
title = Personal.xls
Style = 0x46C40000
ExStyle= 0x00000300--- ahk 1.0.40.04 (DetectHiddenWindows,OFF) ---
hwnd = 263050
title =
Style = 0x56C40000
ExStyle=
※ 上記ハンドルと同一のコントロールを抽出 Personal.xlsと推測--- ahk 1.0.40.08 (DetectHiddenWindows,OFF) ---
hwnd = 263050
title = Personal.xls
Style = 0x46C40000
ExStyle= 0x00000300
てことでhttp://d.hatena.ne.jp/eamat/20050906/:Title=9/6の分をWS_VISIBLEのビットも見るよう修正しました
パソコンテレビ GyaOを試してみた。
CM収入による運営で視聴者の皆様には一切料金はかからない。普通のTVと違うのはお好きな時間に何度でも視聴できる、とのこと。試しに一番組視聴してみたが通常のTV番組と同じように番組の合間にCM動画が入る、録画のできないTVといった印象。*1思ったよりラインナップが多くないなーと思ってよく見たら、各番組には「12月10日まで」等のラベルが貼られてる。「お好きな時間に何度でも」という謳い文句で勘違いしたが実際は期間限定での提供らしい、まぁそりゃそうか。なんていうか映像の図書館みたいなのを想像していたのでちょっと(´・ω・`) 図書館で言うところの外部持ちだし禁止の書物みたいな感じで、録画、貸出しはできないけど図書館(サイト)内でなら半永久的にいつ行っても閲覧可能、みたいな。そういうんだったら利用しがいがあるんだけどなぁ。
自分の場合そんなに積極的にテレビ見るほうじゃないので放映期間中にGyaOを訪れなければ観られないのではあんまり意味がなさそうだ。むしろ録画できる分普通のテレビのがアレかもなぁ、何て思ってしまったりして。
*1:普通にブラウザから見てる分での話。技術的にどうにかできる方法があるかは知らない。
v1.0.40.08 メモリリークバグ修正
関数の再帰コール時のメモリリークバグが修正されたっぽい。試しに再度テストしてみたが実行するごとにメモリ使用量が増えていく現象はなくなった。ただ、テストでは再帰関数とそうでない関数でメモリ使用量が倍近く変化する。
起動時 メモリ常駐: 3980kb 仮想メモリ: 2352kb
test1(通常)実行 メモリ常駐: 3988kb 仮想メモリ: 2364kb
test2(再帰)実行 メモリ常駐: 6568kb 仮想メモリ: 4972kb
test2(再帰)実行 メモリ常駐: 6572kb 仮想メモリ: 4972kb
再帰関数の方が普通よりメモリ食うってことですかね。テストの内容にもよるかもだけど
#1:: OutputDebug, % test1(2,100) #2:: OutputDebug, % test2(2,100) test1(add,cnt) { result=0 loop,%cnt% result := add + result return result } test2(add,cnt) { result=0 if (cnt > 0) result := add + test2(add,cnt-1) return result }