「マニュアル/Tips一覧/AutoHotKey/レイヤー選択さん」の編集履歴(バックアップ)一覧に戻る
;
;レイヤー選択さん
;
; ChangeLog
; 20100223 レイヤパネルの横幅の変化に対応
; 20100223 WM_NOTFYのlparam検出でフリーズするの修正
; 20100223 作成
;
;-----------------------------------------------------------
;設定
;-----------------------------------------------------------
;リストの行数
; 上からこの数だけレイヤをリストアップします。
; レイヤパレットの大きさに合わせて設定してください。
rows:=18
;
;確認リスト
; レイヤを変更した後、確認用に更新されたリストが表示できます。
; レイヤパレットが遠い場所にある場合、近くで確認できて有効です。
;
; 使用しない UseCheckView:=0
; 使用する UseCheckView:=1
;
UseCheckView:=0
;UseCheckView:=0 の場合、以下の項目は無視してください。
;
;確認リスト表示位置
; リストが表示される位置を設定してください。
; 右片の中心位置を指定してください
; ┌─┐
; │リ│
; │ス*←この座標を記入
; │ト│
; └─┘
; (例) CheckViewX:=1600
; CheckViewY:=600
; この場合、1600x1200の画面で、右端&中段に表示される。
; 見やすい場所に設定してください。
;
CheckViewX:=1600
CheckViewY:=600
;
;確認リスト表示時間(ms)
; この時間が経過後、確認リストは消えます
TimerMenuKillAFT:=4000
;
;-----------------------------------------------------------
;設定ここまで
;-----------------------------------------------------------
;-----------------------------------------------------------
;AHK
;-----------------------------------------------------------
#MaxThreads 1
#MaxThreadsPerHotkey 1
#SingleInstance IGNORE
Process,Priority,,High
CoordMode, Mouse, Screen
SetDefaultMouseSpeed 0
SendMode Play
SetWorkingDir, %A_ScriptDir%
Menu, Tray,Icon, LayerSan.ico
;-----------------------------------------------------------
;変数初期化
;-----------------------------------------------------------
;GUIのサイズ(仮)
winW:=640
winH:=480
;タイマー
TimerMenuKill:=100
TimerlistAFT:=100
;レイヤ操作時の透明度
LayerOperationTrans:=1
;SAI関係
;SAIのレイヤ1個の高さ
lHeight:=44
;SAIのレイヤ開始位置(クライアント座標)
saiLayerStartY:=166
;レイヤタイトルXオフセット
saiLayerTextX:=65
;SAIの選択中レイヤの色(通常&選択範囲抽出元)
saiColSelLay:=14376559
saiColSelLayS:=6332480
;SAI検出用
TA_SAI:="SAI ahk_class sfl_window_class"
;SAIレイヤパレット検出用
TA_LAY:="レイヤー ahk_class sfl_window_class"
;-----------------------------------------------------------
;初期処理
;-----------------------------------------------------------
;SAIのハンドル検出
WinGet, temp, ID, %TA_SAI%
hWndSAI:=temp
;-----------------------------------------------------------
;GUI生成
;-----------------------------------------------------------
Gui,-0x00800000 +ToolWindow +AlwaysOnTop -0x00400000
Gui,Margin,0,0
Gui,Font,s9
;LVS_EX_TRACKSELECT 8 + LVS_EX_ONECLICKACTIVATE 40
Gui,Add,ListView, -Hdr LV0x48 0x2000 w%winW% r%rows% vLv -E0x00000200 HwndhListView BackgroundFF9900 Grid,getYPos
;LVM_SETHOVERTIME = LVM_FIRST 0x1000 + 0x0047
DllCall("SendMessage",UInt,hListView,UInt,0x001047,Int,0,UInt,5)
;WM
OnMessage(0x4E,"WM_NOTIFY")
;
Gui,+LastFound
WinGet,hMain,id
;再描画一時停止
GuiControl,-Redraw,Lv
;-----------------------------------------------------------
;開始確認
;-----------------------------------------------------------
MsgBox, 4160, , OKを押すとレイヤー選択さん動作開始します
return
;-----------------------------------------------------------
;リスト発動
;-----------------------------------------------------------
LayList(Mode,ShowD){
global CheckViewX,CheckViewY
global TA_LAY,TA_SAI
global hMain,hWndSAI,hwndLAY
global iWidth,iHeight,lHeight
global saiLayerStartY,saiLayerTextX,saiColSelLay,saiColSelLayS
global winW,winH,rows
global TimerMenuKill,TimerMenuKillAFT
global himl
global Lv
;レイヤーパネル確定
WinGet, temp3, ID, %TA_LAY%
hWndLAY:=temp3
;レイヤウィンドウ検出
WinGetPos layX, layY, layW, layH, ahk_id %hWndLAY%
;変数生成
LayerYoffset:=0
if (layW>244)
LayerYoffset:=-16
if (layW>363)
LayerYoffset:=-32
;GUIリスト上のレイヤ表示サイズ
;-16:左右のウィンドウ枠 -24:右のスクロールバー
iWidth:=layW-saiLayerTextX -16 -24
iHeight:=17
;GUIのサイズ
winW:=iWidth+4
winH:=iHeight
;
;イメージリスト作成
;
himl:=DllCall("ImageList_Create",Int,iWidth,Int,iHeight,UInt,0x0018,Int,rows,Int,rows)
LV_SetImageList(himl,1)
yPosCnt:=0
YofSelLay:=-1
;レイヤパレットの中を1レイヤずつ縦走取得
Loop,%rows%
{
;レイヤのデバイスコンテキスト
hdcLay :=DllCall("GetDC",UInt,hWndLAY)
;バッファ作成・ビットマップ作成・選択
hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC" , UInt, hdcLay )
hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap" , UInt, hdcLay, Int, iWidth, Int, iHeight )
r := DllCall( "gdi32.dll\SelectObject" , UInt, hdc_buffer, UInt, hbm_buffer )
;レイヤパレット上の起点(操作対象のレイヤ)
getYPos:=saiLayerStartY+LayerYoffset+(lHeight*(yPosCnt))
;バッファにBitBlt
DllCall( "BitBlt"
, UInt, hdc_buffer, Int, 0, Int, 0, Int, iWidth, Int, iHeight
, UInt, hdcLay, Int, saiLayerTextX, Int, getYPos, UInt, 0x00CC0020 )
;バッファ上のレイヤの色を見る。レイヤが選択中かどうか。選択中なら現在位置を記憶
col := DllCall( "GetPixel", UInt, hdc_buffer, Int,0, Int,0)
if (col=saiColSelLay or col=saiColSelLayS)
YofSelLay:=yPosCnt
;イメージリストに追加
;int ImageList_Add(
; HIMAGELIST himl, // イメージリストのハンドル
; HBITBAP hbmImage, // イメージのビットマップハンドル
; HBITMAP hbmMask // マスクのビットマップハンドル
;)
hbmMask=""
icon:=DllCall("ImageList_Add",UInt,himl, UInt,hbm_buffer, UInt,hbmMask)+1
;リストビューに画像を追加
;Y座標も追加(あとで使う)
LV_Add("Icon" . icon ,getYPos)
;現在位置加算
yPosCnt:=yPosCnt+1
;デバイスコンテキストを削除
DllCall( "gdi32.dll\DeleteDC" , "uint", hdc_buffer )
;デバイスコンテキスト破棄
DllCall( "gdi32.dll\DeleteObject", UInt, hbm_buffer )
DllCall( "gdi32.dll\DeleteDC" , UInt, hdcLay )
}
MouseGetPos mX,mY
winW:=iWidth
winH:=rows*(iHeight+1)
;GUI表示位置設定(選択レイヤが検出されたらマウスの位置に合わせる)
UIX:=mX-(winW/2)
UIY:=mY-(winH/2)
if (YofSelLay!=-1)
UIY:=mY-( (YofSelLay+1)*iHeight )
if (Mode="AFT" and ShowD="R"){
UIX:=CheckViewX-winW
UIY:=CheckViewY-(winH/2)
}
;GUIサイズ調整
GuiControl Move,LV,h%winH%
;GUI表示
if (Mode="AFT"){
Gui,Show, x%UIX% y%UIY% w%winW% h%winH% NA
} else {
Gui,Show, x%UIX% y%UIY% w%winW% h%winH%
}
;更新開始
GuiControl,+Redraw,Lv
;GUI自動消去タイマー設定(通常時)
if (Mode!="AFT")
Settimer MenuKill,%TimerMenuKill%
;確認表示時
if (Mode ="AFT")
Settimer MenuKill,%TimerMenuKillAFT%
return
}
;-----------------------------------------------------------
;メニュー消去
;-----------------------------------------------------------
MenuKill:
hwndNow := DllCall("GetForegroundWindow")
if(hwndNow!=hMain){
Close()
Settimer MenuKill,Off
}
return
Close(){
global
Gui,Hide
IL_Destroy(himl)
LV_Delete()
}
;-----------------------------------------------------------
;選択された!
;-----------------------------------------------------------
WM_NOTIFY(w,l,m,h){
;NM_CLICK = 0xFFFFFFFE
;if(StructGetInt(l,8)=0xFFFFFFFE){
;ほんとはlparamからNM_CLICK取り出さないといけないんだけど
;その操作をやると稀にフリーズするのでべた打ち
if (l=8976712){
global hWndLAY,hWndSAI
global LayerOperationTrans,TimerlistAFT
global UseCheckView
;リストビューからY座標をもってくる
LV_GetText(pushYPos,StructGetInt(l,12)+1,1)
;スクリーン座標に変換
VarSetCapacity(sPoint, 8, 0)
NumPut(135, sPoint, 0, "Int")
NumPut(pushYPos,sPoint, 4, "Int")
DllCall("ClientToScreen", "UInt", hWndLAY, "UInt", &sPoint)
x:= NumGet(sPoint, 0, "Int")
y:= NumGet(sPoint, 4, "Int")
;透過変える 0透明~255不透過
switchTrans:=0
WinGet, transLay , Transparent, ahk_id %hWndLAY%
if (transLay=0){
WinSet, Trans, %LayerOperationTrans%, ahk_id %hWndLAY%
switchTrans:=1
}
;マウス位置記憶
MouseGetPos mX , mY
;クリック
MouseClick LEFT, x,y+10
;マウス位置戻す
MouseMove mX,mY
;フォーカスをSAIに戻す
DllCall("SetForegroundWindow",UInt,hWndSAI,Int)
;GUI破棄
Close()
;透過戻す 0透明~255不透過
if (switchTrans=1){
WinSet, Trans, transLay, ahk_id %hWndLAY%
}
;確認画面タイマー
if UseCheckView=1
SetTimer, listAFT, %TimerlistAFT%
}
;tooltip muho
return
}
;-----------------------------------------------------------
;確認表示(タイマーで発動)
;-----------------------------------------------------------
listAFT:
;タイマー停止
SetTimer, listAFT, Off
;確認表示
LayList("AFT","R")
return
;-----------------------------------------------------------
;(未使用)メモリ操作
;-----------------------------------------------------------
StructGetInt(pStruct,offset)
{
DllCall("RtlMoveMemory", UIntP,val, UInt,pStruct+offset, Int,4)
return val
}
;//////////////////////////////////////////////////////////
;//////////////////////////////////////////////////////////
;//////////////////////////////////////////////////////////
#IfWinActive, ahk_class sfl_window_class
numpad1::LayList("","")
;^ESC::Reload ; テスト用
#IfWinActive
;^Esc::Reload ; テスト用