「マニュアル/Tips一覧/AutoHotKey/レイヤー選択さん」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
&font(25px){マウス位置にレイヤ選択リストが出ます。}
&font(25px){numpad1を押すと出ます。}
&font(25px){こんな感じ。}
#image(こんな感じ.jpg)
&font(10px){レイヤパネルを独立表示している SAI 1.1.0 専用}
&font(10px){開発中です。メモリリークしてるかもしれません。}
#highlight(lisp){{
;
;レイヤー選択さん Rev201002230500
;
; ChangeLog
; 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
Menu, Tray,Icon, LayerSan.ico
;-----------------------------------------------------------
;変数初期化
;-----------------------------------------------------------
;本体GUI関係
;GUIリスト上のレイヤ表示サイズ
iWidth:=80
iHeight:=17
;GUIのサイズ
winW:=iWidth+4
winH:=iHeight
;タイマー
TimerMenuKill:=100
TimerlistAFT:=100
;レイヤ操作時の透明度
LayerOperationTrans:=1
;SAI関係
;SAIのレイヤ1個の高さ
lHeight:=44
;SAIのレイヤ開始位置(クライアント座標)
saiLayerStartY:=166
;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,"OnNotify")
;
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,saiColSelLay,saiColSelLayS
global winW,winH,rows
global TimerMenuKill,TimerMenuKillAFT
global himl
global Lv
;レイヤーパネル確定
WinGet, temp3, ID, %TA_LAY%
hWndLAY:=temp3
;
;イメージリスト作成
;
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+(lHeight*(yPosCnt))
;バッファにBitBlt
DllCall( "BitBlt"
, UInt, hdc_buffer, Int, 0, Int, 0, Int, iWidth, Int, iHeight
, UInt, hdcLay, Int, 65, 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% AutoSize NA
} else {
Gui,Show, x%UIX% y%UIY% AutoSize
}
;更新開始
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()
}
;-----------------------------------------------------------
;選択された!
;-----------------------------------------------------------
OnNotify(w,l,m,h){
global hWndLAY,hWndSAI
global LayerOperationTrans,TimerlistAFT
global UseCheckView
if(StructGetInt(l,8)=4294967294){
;リストビューから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%
}
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 ; テスト用
}}
#comment(,disableurl)
&font(25px){マウス位置にレイヤ選択リストが出ます。}
&font(25px){numpad1を押すと出ます。}
&font(25px){こんな感じ。}
#image(こんな感じ.jpg)
&font(20px){レイヤパネルを独立表示している SAI 1.1.0 専用}
&font(20px){開発中です。メモリリークしてるかもしれません。}
#highlight(lisp){{
;
;レイヤー選択さん Rev201002230500
;
; ChangeLog
; 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
Menu, Tray,Icon, LayerSan.ico
;-----------------------------------------------------------
;変数初期化
;-----------------------------------------------------------
;本体GUI関係
;GUIリスト上のレイヤ表示サイズ
iWidth:=80
iHeight:=17
;GUIのサイズ
winW:=iWidth+4
winH:=iHeight
;タイマー
TimerMenuKill:=100
TimerlistAFT:=100
;レイヤ操作時の透明度
LayerOperationTrans:=1
;SAI関係
;SAIのレイヤ1個の高さ
lHeight:=44
;SAIのレイヤ開始位置(クライアント座標)
saiLayerStartY:=166
;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,"OnNotify")
;
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,saiColSelLay,saiColSelLayS
global winW,winH,rows
global TimerMenuKill,TimerMenuKillAFT
global himl
global Lv
;レイヤーパネル確定
WinGet, temp3, ID, %TA_LAY%
hWndLAY:=temp3
;
;イメージリスト作成
;
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+(lHeight*(yPosCnt))
;バッファにBitBlt
DllCall( "BitBlt"
, UInt, hdc_buffer, Int, 0, Int, 0, Int, iWidth, Int, iHeight
, UInt, hdcLay, Int, 65, 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% AutoSize NA
} else {
Gui,Show, x%UIX% y%UIY% AutoSize
}
;更新開始
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()
}
;-----------------------------------------------------------
;選択された!
;-----------------------------------------------------------
OnNotify(w,l,m,h){
global hWndLAY,hWndSAI
global LayerOperationTrans,TimerlistAFT
global UseCheckView
if(StructGetInt(l,8)=4294967294){
;リストビューから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%
}
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 ; テスト用
}}
#comment(,disableurl)