マウス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
}