マニュアル > Tips一覧 > AutoHotKey > レイヤー選択さん

「マニュアル/Tips一覧/AutoHotKey/レイヤー選択さん」の編集履歴(バックアップ)一覧に戻る
マニュアル/Tips一覧/AutoHotKey/レイヤー選択さん」を以下のとおり復元します。
&font(25px){マウス位置にレイヤ選択リストが出ます。}

&font(20px){numpad1を押すと出ます。}
&font(20px){こんな感じ。}
#image(こんな感じ.jpg,width=400)

&font(20px){レイヤパネルを独立表示している SAI 1.1.0 専用}
&font(20px){開発中です。メモリリークしてるかもしれません。}
&font(20px){[[ダウンロード>LayerSan_2010_0223.ahk]]}

- test  -- test  (2010-02-23 06:50:56)
#comment(,disableurl)

----

以下ソース

#highlight(lisp){{
;
;レイヤー選択さん
;
;	ChangeLog
;	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
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,"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,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()
}

;-----------------------------------------------------------
;選択された!
;-----------------------------------------------------------
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 ; テスト用
}}

復元してよろしいですか?