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

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

&font(20px){マウス位置にレイヤ選択リストが出ます。}
&font(20px){numpad1を押すと出ます。}
&font(20px){こんな感じ。}
#image(こんな感じ.jpg,width=400)

&font(20px){レイヤパネルを独立表示している SAI 1.1.0 専用}
&font(20px){開発中です。メモリリークしてるかもしれません。}
&font(20px){[[ダウンロード>http://www3.atwiki.jp/sai/?cmd=upload&act=open&page=%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB%2FTips%E4%B8%80%E8%A6%A7%2FAutoHotKey%2F%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC%E9%81%B8%E6%8A%9E%E3%81%95%E3%82%93&file=LayerSan_2010_0224_1346.ahk]]} - [[アイコン>http://www3.atwiki.jp/sai/?cmd=upload&act=open&page=%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB%2FTips%E4%B8%80%E8%A6%A7%2FAutoHotKey%2F%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC%E9%81%B8%E6%8A%9E%E3%81%95%E3%82%93&file=LayerSan.ico]](オプション)
- test  -- test  (2010-02-23 06:50:56)
#comment(,disableurl)

----

以下ソース

#highlight(lisp){{
;
;レイヤー選択さん
;
;	ChangeLog
;	20100224	レイヤコントロールを直接取得。クリックもWM_LBUTTONDOWNで直。
;	20100223	レイヤパネルの横幅の変化に対応
;	20100223	WM_NOTFYのlparam検出でフリーズするの修正
;	20100223	作成
;
;-----------------------------------------------------------
;設定
;-----------------------------------------------------------

;確認リスト
;	レイヤを変更した後、確認用に更新されたリストが表示できます。
;	レイヤパレットが遠い場所にある場合、近くで確認できて有効です。
;
;	使用しない	UseCheckView:=0
;	使用する	UseCheckView:=1
;
UseCheckView:=1
;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

;-----------------------------------------------------------
;変数初期化
;-----------------------------------------------------------
;タイマー
	TimerMenuKill:=100
	TimerlistAFT:=100
;レイヤ操作時の透明度
	LayerOperationTrans:=1

;SAI関係
	;SAIレイヤの表示上の縦サイズ
	lHeight:=44
	;レイヤタイトルオフセット(レイヤコントロール内)
	saiLayerTextXOffset:=60
	saiLayerTextYOffset:=2
	;SAIの選択中レイヤの色(上:通常時(濃い青紫) 下:選択範囲抽出元(濃い緑))
	saiColSelLay:=14376559
	saiColSelLayS:=6332480
	;SAIレイヤパレット検出用ワード
	TA_LAY:="レイヤー ahk_class sfl_window_class"

;-----------------------------------------------------------
;初期処理
;-----------------------------------------------------------

;-----------------------------------------------------------
;GUI生成
;-----------------------------------------------------------
	;WS_BORDER 0x800000 WS_EX_LAYOUTRTL 0x400000
	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 w640 r480 vLv -E0x00000200 HwndhListView BackgroundFF9900 Grid,getYPos
	;LVM_SETHOVERTIME = LVM_FIRST 0x1000 + 0x0047
	DllCall("SendMessage",UInt,hListView,UInt,0x001047,Int,0,UInt,5)
	;ウィンドウメッセージ処理先
	OnMessage(0x4E,"WM_NOTIFY")
	;
	Gui,+LastFound
	;GUIのハンドル
	WinGet,hMain,id
	;GUI再描画一時停止
	GuiControl,-Redraw,Lv

;-----------------------------------------------------------
;開始確認
;-----------------------------------------------------------
	MsgBox, 4160, , OKを押すとレイヤー選択さん動作開始します
return

;-----------------------------------------------------------
;リスト生成
;-----------------------------------------------------------
LayList(Mode,ShowD){
	;取り込み
		global TA_LAY
		global hMain
		global Lv
		global CheckViewX,CheckViewY
		global TimerMenuKill,TimerMenuKillAFT
		global saiLayerTextXOffset,saiLayerTextYOffset
		global saiColSelLay,saiColSelLayS
		global lHeight
	;外出し
		;レイヤパネルのハンドル
		global hwndLAY
		;レイヤコントロールのハンドル、レイヤコントロールの幅
		global layCtrlHwnd,layCtrlW
		;レイヤ文字を切り取るサイズ
		global iWidth,iHeight
		;GUIのサイズ
		global winW,winH
		;イメージリストのハンドル
		global himl
	
	;レイヤーパネル確定
	WinGet, temp3, ID, %TA_LAY%
	hWndLAY:=temp3
	
	;レイヤーコントロール確定
	ControlGet,layCtrlHwnd,Hwnd,,sfl_window_class29 ,レイヤー
		;レイヤーコントロールの位置(レイヤウィンドウに対して)
		ControlGetPos,,, layCtrlW,layCtrlH, sfl_window_class29 ,レイヤー
			;リスト行数設定
				rows:=Floor(layCtrlH/lHeight)
	;変数生成
		;リスト上のレイヤ表示サイズ
		; -17:右のスクロールバー -1:余裕(選択時に右に枠が見切れる)
		iWidth:=layCtrlW -saiLayerTextXOffset -17 -1
		iHeight:=17

	;
	;イメージリスト作成
	;
	himl:=DllCall("ImageList_Create",Int,iWidth,Int,iHeight,UInt,0x0018,Int,rows,Int,rows)
	LV_SetImageList(himl,1)

	;レイヤコントロールのデバイスコンテキスト
	hdcLay		:=DllCall("GetDC",UInt,layCtrlHwnd)

	;
	;レイヤパレットの中を1レイヤずつ縦走取得
	;
	yPosCnt:=0
	YofSelLay:=-1
	Loop,%rows%
		{
			;バッファ作成・ビットマップ作成・選択
			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:=(lHeight*(yPosCnt))
			;バッファにBitBlt
			DllCall( "BitBlt"
			, UInt, hdc_buffer, Int, 0, Int, 0, Int, iWidth, Int, iHeight
			, UInt, hdcLay,  Int, saiLayerTextXOffset, Int, getYPos+saiLayerTextYOffset, 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 )
	
	;GUI表示サイズ設定
	winW:=iWidth+4
	winH:=rows*(iHeight+1)
	
	;GUI表示位置設定
		;マウス一取得
		MouseGetPos mX,mY
		;とりあえず中心
		UIX:=mX-(winW/2)
		UIY:=mY-(winH/2)
		;選択レイヤが検出(YofSelLay)されたらマウスの位置に合わせる
		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%
	}

	;GUI更新開始
	GuiControl,+Redraw,Lv

	;GUI自動消去タイマー設定(通常時)
	if (Mode!="AFT")
		Settimer MenuKill,%TimerMenuKill%
	;確認表示時
	if (Mode ="AFT")
		Settimer MenuKill,%TimerMenuKillAFT%

return
}

;-----------------------------------------------------------
;選択された!
;-----------------------------------------------------------
WM_NOTIFY(w,l,m,h){
	;NM_CLICK = 0xFFFFFFFE
	;if(StructGetInt(l,8)=0xFFFFFFFE){
	;ほんとはlparamからNM_CLICK取り出さないといけないんだけど
	;その操作をやると稀にフリーズするのでべた打ち
	if (l=8976712){
		;レイヤパネルのハンドル
		global hWndLAY,LayerOperationTrans
		;レイヤコントロールのハンドル、レイヤコントロールの幅
		global layCtrlHwnd,layCtrlW
		;確認リストフラグ、確認リストタイマー秒
		global UseCheckView,TimerlistAFT
		
		;リストビューからY座標をもってくる
		LV_GetText(pushYPos,StructGetInt(l,12)+1,1)

		;クリック位置生成
		;レイヤウィンドウ横幅 -16:左右のウィンドウ枠 -24:右のスクロールバー -5:余裕
		saiLayerClickX:=layCtrlW -24 -5
		saiLayerClickY:=pushYPos
		;押し込む
		clickLParam := saiLayerClickX | (saiLayerClickY << 16) 

		;透過変える		0透明~255不透過
		switchTrans:=0
		WinGet, transLay , Transparent, ahk_id %hWndLAY%
		if (transLay=0){
			WinSet, Trans, %LayerOperationTrans%, ahk_id %hWndLAY%
			switchTrans:=1
		}
		
		;左ボタンDOWN WM_LBUTTONDOWN=0x201 MK_LBUTTON=0x0001
		SendMessage, 0x201, 0x0001, clickLParam ,, ahk_id %layCtrlHwnd%
			;左ボタンUP WM_LBUTTONUP  =0x202 MK_LBUTTON=0x0001
			SendMessage, 0x202, 0x0001, clickLParam ,, ahk_id %layCtrlHwnd%

		;透過戻す		0透明~255不透過
		if (switchTrans=1)
			WinSet, Trans, transLay, ahk_id %hWndLAY%

		;GUI破棄
		Close()

		;確認画面タイマー
		if UseCheckView=1
			SetTimer, listAFT, %TimerlistAFT%

	}
	return
}

;-----------------------------------------------------------
;確認表示(タイマーで発動)
;-----------------------------------------------------------
listAFT:
		;タイマー停止
		SetTimer, listAFT, Off
		;確認表示
		LayList("AFT","R")
return

;-----------------------------------------------------------
;メニュー消去
;-----------------------------------------------------------
MenuKill:
	hwndNow := DllCall("GetForegroundWindow") 
	if(hwndNow!=hMain){
		;消去
		Close()
		;タイマー無効化
		Settimer MenuKill,Off
	}
return

;消去ちゃん
Close(){
	global
	;GUI隠す
	Gui,Hide
	;イメージリスト消す
	IL_Destroy(himl)
	;リストビュー消す
	LV_Delete()
}

;-----------------------------------------------------------
;メモリ操作
;-----------------------------------------------------------
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 ; テスト用
}}

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