カテゴリ:テクノロジ( 198 )

AutoHotKey_Lで、Explorerのファイル操作を便利に。

 エクスプローラで「カレントフォルダ/選択ファイルのフルパスをコピー」「選択アイテムを上のフォルダへ移動」「選択フォルダの中身を吸い上げる」のみっつを実現してみた。アンドゥ/リドゥ対応。

$F12::
  PathList := GetSelectItemPath()
  if PathList {
    SplashView(PathList)
    Clipboard := PathList
  } else {
    WinGetText, CurPath, A
    RegExMatch(CurPath, "([A-Z]:\\[^\r\n]*)", $)
    SplashView($1)
    Clipboard := $1
  }
return

^u::
  PathList := GetSelectItemPath()
  if !PathList
    return
  Loop, Parse, PathList, `n, %A_Space%%A_Tab%
  {
    SendPath := A_LoopField
    break
  }
  SplitPath, SendPath, , SendPath
  SplitPath, SendPath, , SendPath
  MsgBox, 292, 選択中のアイテムを上のフォルダへ移動, 以下のフォルダ・ファイルを上のフォルダへ移動します。`n`n%PathList%
  IfMsgBox, No
    return

  Loop, Parse, PathList, `n, %A_Space%%A_Tab%
  {
    SendDir := ComObjCreate("Shell.Application").NameSpace(SendPath)
    SendDir.moveHere(A_LoopField)
  }
  SendDir :=
return

^r::
  PathList := GetSelectItemPath()
  if !PathList
    return
  Loop, Parse, PathList, `n, %A_Space%%A_Tab%
  {
    SendPath := A_LoopField
    break
  }
  SplitPath, SendPath, , SendPath
  MsgBox, 292, 選択中のフォルダの中身を上のフォルダへ移動, 以下のフォルダの中身をこのフォルダに移動します。`n`n%PathList%
  IfMsgBox, No
    return

  ShellApp := ComObjCreate("Shell.Application")
  SendDir := ShellApp.NameSpace(SendPath)
  Loop, Parse, PathList, `n, %A_Space%%A_Tab%
  {
    FileGetAttrib, FileAttrib, %A_LoopField%
    IfNotInString, FileAttrib, D  ; フォルダでなければ無視
      continue
    
    SendDir.moveHere(ShellApp.NameSpace(A_LoopField).Items)
    
    If CheckBlankDir(A_LoopField)
      FileRemoveDir, %A_LoopField%
  }
  ShellApp :=, SendDir :=
return

GetSelectItemPath() {  ; AutoHotkey スレッド part11 >>913
  for Window in ComObjCreate("Shell.Application").Windows
    if ( Window.hwnd == WinExist() ){
      for Item in Window.Document.SelectedItems
        FileList .= Item.Path "`n"
      break
    }
  StringTrimRight, FileList, FileList, 1
  return, FileList
}

CheckBlankDir(TrgDir) {
  Loop, %TrgDir%/*, 1
    return, 0
  return, 1
}

SplashView(TextBuf, Timer = 1500) {
  Progress, B1 ZH0 W800, %TextBuf%
  SetTimer, SplashClose, %Timer%
}

SplashClose:
  SetTimer, SplashClose, Off
  Progress, Off
return

 "Loop, Parse"~のとこは、正規表現で取り出した方がいいのかなー? 正規表現だと負荷高そう(※個人の思い込みです)。

 エクスプローラのアンドゥ/リドゥが使いたくてCOM使ってみたのだが、このあたりが素人の限界か。一度のアンドゥ/リドゥで、任意の(ワイルドカードで示せない)複数ファイルを操作するにはどうすりゃいいんだ?


[PR]
by lordnoesis | 2012-10-14 22:24 | テクノロジ | Trackback | Comments(0)

AutoHotKeyで、KbMediaPlayerを少し便利に。

 KbMediaPlayerが7年ぶりにバージョンアップされたが、メニューのIDが変わって今までのスクリプトで問題が出たので、更新がてらPOSTしてみる。「2.51beta.2012.0930」向け。

;--------------------------------------------------------------------------------------
; KbMediaPlayer
;--------------------------------------------------------------------------------------
#IfWinActive - KbMedia Player - ahk_class TFrmMIDI

F1::return
F2::PostMessage, 0x111, 24, 0, , A  ; 単曲再生
F3::PostMessage, 0x111, 21, 0, , A  ; 単曲リピート
F4::PostMessage, 0x111, 22, 0, , A  ; リピート
F6::
  PostMessage, 0x111, 16, 0, , A  ; フェードアウト
  Sleep, 3500
  PostMessage, 0x111, 15, 0, , A  ; 停止
return
F7::PostMessage, 0x111, 25, 0, , A  ; 連続再生
F8::PostMessage, 0x111, 26, 0, , A  ; ランダム再生
F9::PostMessage, 0x111, 29, 0, , A  ; 未再生の曲だけ


#IfWinActive Error ahk_class #32770, ファイルは削除または移動されました。

; 「ファイルが見つからん」ダイアログでスペースを打鍵すると、以後自動で閉じるように。
$Space::
  SetTimer, Check_KB, 500
return

Check_KB:
  IfWinExist, Error ahk_class #32770, ファイルは削除または移動されました。
  {
    ControlSend, , {Enter}
    WinWaitClose, , , 1
    PostMessage, 0x111, 18, 0, , ahk_class TFrmMIDI  ; 次の曲
  }
  IfWinNotExist, ahk_class TFrmMIDI
    SetTimer, Check_KB, Off
return

 どのキーがどの機能か覚えられない人は、スキンにでも書いておくとよい。

 後半のは、音楽ファイルのあるNASが停止中に「次の曲」した時にダイアログ頻発するの対策。ダイアログが出てると(Kbの)ホットキー効かなくなるから、致命的に邪魔なんだあれ……。

 ダイアログ閉じるだけでなく、正常に次の曲が読み込まれるまで繰り返すようにしてみた。


[PR]
by lordnoesis | 2012-09-30 19:41 | テクノロジ | Trackback | Comments(0)

AutoHotKeyで、Operaの拡張管理を開いてもKbMedia Playerが停止しないようにしてみた。

 KbMedia Playerでホットキーを有効にしてるとそちらが優先されて、Operaで拡張管理を開くショートカットが効かなくなるので、AHKで対策。
 打鍵で拡張管理を開き、長押しでKb停止。

#IfWinActive ahk_class OperaWindowClass
$^+E::
  KeyWait, E, T0.8
  if ErrorLevel
    Send, ^+E
  else
    SendPlay, ^+E
  KeyWait, E
return

 SendとSendPlayを逆にした方が(長押しで拡張管理にした方が)使いやすいかも。Kbはグローバルホットキーだし。


[PR]
by lordnoesis | 2012-09-13 20:42 | テクノロジ | Trackback | Comments(0)

AutoHotKeyで、.sz7を生成してみたり+α。

 axpathlist2.spiとat_picture、それとLeeyesを利用して、.sz7で方々のファイルを上手いことまとめる手法を補助するAHKスクリプト群。

axpathlist2.spi形式の.sz7を生成するAHKスクリプト

 コマンドラインオプションでファイルパス(書庫内書庫対応)を指定すると、ファイルの存在するフォルダor実在書庫と同じ名前の.sz7ファイルを生成する。既に存在した場合は追記。複数パスを一度に渡すとソートしてから登録する。起動してからウィンドウにファイルをドロップしても登録できるが、DnDで書庫内パスを渡すアプリはないだろうなぁ。

;/////////////////////////////////////////////////////////////////////////////////////
;
; Add sz7
;
;/////////////////////////////////////////////////////////////////////////////////////

  Heading1 := "Drop && Run"
  Heading2 := "Running..."
  ErrMsg := ""

  if (1 > %0%) {
    Gui, Add, Text, vHeading, %Heading1%
    Gui, Add, Edit, vErrMsg Multi ReadOnly, %ErrMsg%
    Gui, +AlwaysOnTop
    Gui, +Resize
    Gui, +MinSize
    Gui, Show, W200 H113,
  } else {
    gosub, main
    ExitApp
  }
return

GuiDropFiles:
  StringReplace, FileList, A_GuiEvent, `r`n, `n, 1
  0 := A_EventInfo  ; ドロップされたファイル数を代入
  Loop, Parse, FileList, `n, \
    %A_Index% := A_LoopField

main:
  GuiControl, Text, Heading, %Heading2%
  PathList := ""
  Loop, %0%
  {
    Cmdline := %A_Index%
    loop, %Cmdline%
      Cmdline := A_LoopFileLongPath  ; ロングパス化
    PathList .= Cmdline "`n"
  }
  StringTrimRight, PathList, PathList, 1

  Sort, PathList, CL

  Loop, Parse, PathList, `n
  {
    ArchivePath := GetArchivePath(A_LoopField)
    if ErrorLevel
      SplitPath, ArchivePath, , ArchivePath
    SplitPath, ArchivePath, , ArchiveDir, , Sz7Name
    FileAppend, %A_LoopField%`n, %ArchiveDir%\%Sz7Name%.sz7
  }

  MaxNum = %0%
  SplashView(Sz7Name ".sz7 へ " MaxNum " 個のアイテムを登録しました。")

  if ErrCnt {  ; Errがあったら
  }
  GuiControl, Text, Heading, %Heading1%
return

;/////////////////////////////////////////////////////////////////////////////////////

GetArchivePath(TrgPath = "") {
  ErrorLevel := 0
  if ("" != FileExist(TrgPath))
    ErrorLevel := 1
  loop {
    if ("" != FileExist(TrgPath))
      break
    idx := InStr(TrgPath, ".", 0, 0)
    if !idx
      return
    idx := InStr(TrgPath, "\", 0, %idx%)
    if idx
      StringMid, TrgPath, TrgPath, 1, idx - 1
  }
  return, TrgPath
}

;/////////////////////////////////////////////////////////////////////////////////////

GuiSize:
  if (1 == A_EventInfo)
    return

  EMW := A_GuiWidth - 20, EMH := A_GuiHeight -35
  GuiControl, Move, ErrMsg, W%EMW% H%EMH%
return

GuiClose:
  GUI, Destroy
  Sleep, 2000
  ExitApp

;/////////////////////////////////////////////////////////////////////////////////////

SplashView(TextBuf, Timer = 1500) {
  Progress, B1 ZH0 W600, %TextBuf%
  SetTimer, SplashClose, %Timer%
}

SplashClose:
  SetTimer, SplashClose, Off
  Progress, Off
return

 テキスト表示欄使ってないのは自作テンプレートそのまま使いまわした将来的な拡張余地!

AtPicture2での.sz7の保存を少し便利に。

 .sz7はAtPictureの「ファイルから画像をリストアップ」で開けばグラフィカルに編集できるが、保存がちょっと面倒なので、簡略化するAHKスクリプト。
 F12を押すとAddSz7.ahkと同じく、画像の存在するフォルダor実在書庫と同名の.sz7を上書き保存する。

;--------------------------------------------------------------------------------------
; AtPicture2
;--------------------------------------------------------------------------------------
#IfWinActive ahk_class atpicture2

F12::
  KeyWait, Shift
  KeyWait, Ctrl
  KeyWait, Alt
  BlockInput, On
  WinGetTitle, Title, A
  RegExMatch(Title, "([a-zA-Z]:\\.*)\.[^.]+$", $)
  PostMessage, 0x111, 10102, 0, , A
  WinWait, パスリストを保存 ahk_class #32770
  Control, EditPaste, %$1%.sz7, Edit1
  Send, {Enter}
  WinWait, 名前を付けて保存の確認 ahk_class #32770, , 1
  if !ErrorLevel
    Send, y
  BlockInput, Off
return

Leeyesで.sz7を扱う。

 axpathlist.spiをLeeyesに認識させれば、.sz7を書庫として扱える。

 AddSz7.ahkは、Leeyesの外部アプリケーションに登録しておくと便利。登録は右クリックから。その際、「書庫内のファイルは書庫内のパスを含めて渡す」を有効にすること。

 AtPicture2も登録しておけば、編集したい時に便利。


[PR]
by lordnoesis | 2012-08-24 21:30 | テクノロジ | Trackback(1) | Comments(0)

AutoHotKeyで、Leeyesをちょっと便利にしてみた。

 Leeyesで複数ファイルをDELキーで削除しようとすると時間がかかる。どうも、ひとつ削除しては画面更新という動作を繰り返しているのが原因っぽい。メニューなどから削除を選択した場合は、普通に一括削除するので問題ない。というわけで、DELを削除コマンドに割り当てるAHK。

;--------------------------------------------------------------------------------------
; Leeyes
;--------------------------------------------------------------------------------------
#IfWinActive Leeyes
Del::
  PostMessage, 0x111, 46, 0, , A
return

 大抵の場合――ショートカットファイルや「書庫内の項目がフォルダひとつの場合は自動で開く」を活用していると特に、「一つ上の階層へ」より「前へ戻る」の方が便利。だが、キー/マウスカスタマイズでこのコマンドは利用できない。というわけで、画像ビューのダブルクリックあたりを「登録アプリケーションの実行」にして、以下のAHKスクリプトを登録すればOK。力技。

  send, !{Left}

 なんか2回やらないと上手く戻れない時があるな?


[PR]
by lordnoesis | 2012-08-24 21:15 | テクノロジ | Trackback | Comments(0)

AutoHotkey_Lで、Opera12の起動を便利にしてみた。

 前ver.のOpera12対応版。前ver.からフォークしたRamDisk運用補助の小規模改善も反映済み。

 Opera12対応は「マスターパスワードダイアログのタイトル変更に追従」「マスターパスワードダイアログを最前面表示するように」。Operaのver.によって最前面でなくなるのはなんなの、うっかりなの?

 ちなみに小規模改善の内容は「FastForward.ini初期化の対策」「autosave.winの2世代バックアップ」「セッション退避ダイアログのカウントダウン」。
 FastForward.ini初期化対策は、同じ場所にFastForward_backup.iniがあれば上書きするよってだけの機能。

; --------- --------- --------- --------- ---------
; RunOpera.ahk ver.2.1.0
; --------- --------- --------- --------- ---------

#WinActivateForce

  OperaPath := ""  ; Opera.exeのフルパス。末尾は"\"。

  SessionsPath := OperaPath "profile\sessions\"  ; セッションフォルダのフルパスを指定。末尾は"\"。
  BookmarksPath := OperaPath "profile\bookmarks.adr"  ; bookmarks.adrのフルパスを指定。

  TimeLimit := 30  ; 最終セッション退避確認ダイアログを自動でスキップするまでの秒数。

  AutoConvSW := 1  ; 最終セッションを退避させる場合、自動でブックマークに変換する設定。 0:変換しない。 1:変換する。
  ACMoveSW := 1  ; 自動変換(↑)したセッションを隔離する設定。 0:隔離しない。 1:隔離する。

  HisReadSW := 0  ; タブ履歴(タブで表示したページの履歴)の設定。 0:最新のみ読み込む。 1:すべて読み込む。
  WriteTrgSW := 1  ; ブックマーク情報を書き込む場所の設定。 0:セッションフォルダにテキストで保存。 1:bookmarks.adrに書き込む。

; --------- --------- --------- --------- ---------

  IfNotExist, %SessionsPath%
  {
    MsgBox, 16, , セッションフォルダが見つかりません。`n%SessionsPath%
    
    Exit
  }
  If (1 == WriteTrgSW) {
    IfNotExist, %BookmarksPath%
    {
      MsgBox, 16, , bookmarks.adrが見つかりません。`n%BookmarksPath%
      Exit
    }
  }

  IfExist, %SessionsPath%autosave.win
    GoSub, SessionAnalyze

  FileCopy, %OperaPath%ui\fastforward_backup.ini, %OperaPath%ui\fastforward.ini, 1  ; FastForward.ini初期化の対策。

  FileCopy, %SessionsPath%autosave_RunOpBak.win, %SessionsPath%autosave_RunOpBak2.win, 1  ; ↓セッション退避etc.を実行しない時も念のため2世代バックアップ。
  FileCopy, %SessionsPath%autosave.win, %SessionsPath%autosave_RunOpBak.win, 1

    Run, %OperaPath%opera.exe, , , OpPid
    WinWait, ahk_pid %OpPid%, , 60
    if !ErrorLevel {
      ifWinExist, Opera へようこそ ahk_pid %OpPid%
      {
        WinActivate
        WinWaitClose
      }
    } else {
      return
    }


    WinWait, マスターパスワードを入力してください ahk_pid %OpPid%, , 5
    If ErrorLevel
      return

    WinSet, Topmost, ON
    WinActivate
    Sleep, 300

ExitApp

; --------- --------- --------- --------- ---------

SessionAnalyze:
  FileRead, OSession, *P65001 *t %SessionsPath%autosave.win
  If (0 != ErrorLevel) {
    MsgBox, 48, , Sessionの読み込みに失敗しました。`n%SessionsPath%autosave.win
    return
  }

  Idx := 0
  WinTitles := ""
  Loop {
    Idx := RegExMatch(OSession, "\[(\d+)history url\].+?count=(.*?)\n", $, Idx + 1)
    If (0 == Idx)
      Break
    WinNum := $1
    HisNum := $2 - 1
    HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
    WinTitles := WinTitles " " HisTitle "`n"
  }
  If("" == WinTitles)
    return

  SetTimer, RenewCount, 1000
  MsgBox, 259, 退避確認(30秒後に通常起動), 起動時に最終セッションを退避しますか?`n`n◆最終セッションの内容◆`n%WinTitles%, %TimeLimit%
  SetTimer, RenewCount, Off
  IfMsgBox, Yes
  {
    TimeNum := A_Now
    BackupName := TimeNum ".win"
    Loop {
      FileMove, %SessionsPath%autosave.win, %SessionsPath%%BackupName%
      If(0 == ErrorLevel)
        Break
      BackupName := TimeNum "_" A_Index ".win"
    }
    If (1 == AutoConvSW)
      GoSub, SessionConvert
  }
  IfMsgBox, Cancel
    Exit

return

; --------- --------- --------- --------- ---------

RenewCount:
  IfWinExist, 退避確認( ahk_class #32770
  {
    TimeLimit--
    WinSetTitle, 退避確認(%TimeLimit%秒後に通常起動)
    if !TimeLimit
      SetTimer, RenewCount, Off
  }
return

; --------- --------- --------- --------- ---------

SessionConvert:
  If (1 == WriteTrgSW)
    FileCopy, %BookmarksPath%, %BookmarksPath%_%A_Now%

  CmdLine := SessionsPath BackupName
  SplitPath, CmdLine, , , , SessionName
  Result := "#FOLDER`n  NAME=[Session] " SessionName "`n`n"
  ResultBuf := Result

  Idx := 0
  Loop {
    Idx := RegExMatch(OSession, "\[(\d+)history url\].+?count=(.*?)\n", $, Idx + 1)
    If (0 == Idx)
      Break
    WinNum := $1
    HisNum := $2 - 1

    HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
    HisUrl := GetHisUrl(OSession, WinNum, HisNum, Idx)

    If (0 == HisReadSW) {  ; タブ履歴を無視する場合
      Result .= "#URL`n  NAME=" HisTitle "`n  URL=" HisUrl "`n`n"
      Continue
    }

    StringLen, HisNumLen, HisNum

    If (0 == HisNum) {
      Result .= "#URL`n  NAME=[" ZeroSupply(HisNum, HisNumLen) "] " HisTitle "`n  URL=" HisUrl "`n`n"
      Continue
    }
    Result .= "#FOLDER`n  NAME=" HisTitle "`n`n#URL`n  NAME=[" ZeroSupply(HisNum, HisNumLen) "] " HisTitle "`n  URL=" HisUrl "`n`n"

    Loop, %HisNum% {
      HisNum--
      HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
      HisUrl := GetHisUrl(OSession, WinNum, HisNum, Idx)
      Result .= "#URL`n  NAME=[" ZeroSupply(HisNum, HisNumLen) "] " HisTitle "`n  URL=" HisUrl "`n`n"
    }
    Result .= "-`n`n"
  }

  If (ResultBuf == Result)
    return
  Result .= "-`n`n"

  If (1 == WriteTrgSW) {
    FileAppend, %Result%, %BookmarksPath%, CP65001
  } Else {
    FileDelete, %CmdLine%.txt
    FileAppend, %Result%, %CmdLine%.txt, CP65001
  }

  If (1 == ACMoveSW) {
    IfNotExist, %SessionsPath%AutoConv\
      FileCreateDir, %SessionsPath%AutoConv\
    FileMove, %CmdLine%, %SessionsPath%AutoConv\%BackupName%
    If (0 != ErrorLevel)
      MsgBox, 48, , 変換済みセッションの移動に失敗しました。`n%SessionsPath%AutoConv\
  }
return

; --------- --------- --------- --------- ---------

GetHisTitle(OSession, WinNum, HisNum, Idx){
  RegExMatch(OSession, "\[" WinNum "history title\].+?" HisNum "=(.*?)\n", $)
  return $1
}

GetHisUrl(OSession, WinNum, HisNum, Idx){
  RegExMatch(OSession, "\[" WinNum "history url\].+?" HisNum "=(.*?)\n", $)
  return $1
}

ZeroSupply(Num, Digit){
  StringLen, NumLen, Num
  LoopNum := Digit - NumLen
  Loop, %LoopNum%
    Num := "0" Num
  return, Num
}

 Opera12、タブ大量でも起動が軽くなったのがいいね。でもUJS Managerが使えなくなったのが痛い。というか標準で実装しろと。エクステンション作れ/使えってか。ごもっとも。


[PR]
by lordnoesis | 2012-06-24 10:43 | テクノロジ | Trackback(1) | Comments(2)

AutoHotKeyでOperaの「新規ウィンドウ」をちょっと便利に+α

 せっかくマルチモニタ環境なのに、「新しいウィンドウ」が同じモニタに出現するのはもったいないので、「最大化時にCtrl+Nしたら、出現する新しいウィンドウを別のモニタに移動する」AHKスクリプト書いた。

#IfWinActive ahk_class OperaWindowClass

^n::
  WinGet, AWinMax, MinMax, A
  if (1 != AWinMax) {
    Send, ^n
    return
  }

  WinGet, AWinID, ID, A
  WinGetPos, AWinX, AWinY, AWinW, AWinH, A
  AWinX := AWinW // 2 + AWinX
  AWinY := AWinH // 2 + AWinY

  Loop, 2
    SysGet, Mnt%A_Index%, MonitorWorkArea, %A_Index% - 1

  if ((Mnt1Top < AWinY) && (AWinY < Mnt1Bottom) && (Mnt1Left < AWinX) && (AWinX < Mnt1Right))
    SendX := Mnt2Left, SendY := Mnt2Top
  else
    SendX := Mnt1Left, SendY := Mnt1Top

  Send, ^n
  WinWait, ahk_class OperaWindowClass, , 0, ahk_id %AWinID%
  WinRestore
  WinMove, , , %SendX%, %SendY%
return

 以下オマケ。

#IfWinActive ahk_class OperaWindowClass

F1::^w  ; タブ閉じ。
F2::^+Tab  ; 左のタブ。
F3::^Tab  ; 右のタブ。
F5::^r  ; F5禁止対策。

^Numpad0::^t

 Ctrl+1~9がスピードダイアルなら、Ctrl+0はズームリセットでなく新規タブだろJK。

 というか、新規タブからのアドレスバー検索が便利なことに今更気づいたので。検索バーのが便利だと思ってたのだけど(最大の理由は「タブの再利用」が嫌いだから)、アドレスバーは新規タブ開くだけでフォーカス当たるし、ブックマークや履歴も検索できる。新規タブだから、「タブの再利用」も問題ない。
 それに、エクステンション入れるとアドレスバーを圧迫するから、検索バー消したいし。メイン以外の検索エンジンはウェブ検索パネル使えばいいよね。

 Googleの検索結果にGoogleブックマークが表示されなくなった改悪も、これで解決ですね。


[PR]
by lordnoesis | 2012-06-20 17:40 | テクノロジ | Trackback | Comments(0)

Windows7を64bit版にしたらExplorerが……。

 Win7機をリカバリするついでに、せっかくなのでx64入れてみたのだが、Explorer x86が使えない=従来のエクスプローラ拡張が使えないという恐るべき罠が。Vista x64ではExplorer x86も用意されてたじゃないですかーやだー!

ファイラを求めて

 というわけでExplorerに見切りをつけて、適当なファイラを探すことに。そうしてなんとなくTablacus Explorerを試してみたらこやつ、リストビューとコンテキストメニューでエクスプローラ拡張が動く。なにこれすごい。64bit版も32bit版もあるから完璧や。
 でもワシ、Explorer+ClassicShell+QTTabBarに慣れきってるから、ちょっと使い勝手がなー。

 というか、目的のひとつが「サムネイル表示をSPIで拡張したい」なんだけど、Explorerの"縮小版"はキャッシュを優先するから、こいつでキャッシュ作れば、あとはExplorerでも表示できるな。よしExplorerに戻ろう(出戻りすぎる。

ふたつのQTTB

 そうなると問題なのが、Qちゃん版Pちゃん版、どちらのQTTabBarを入れるか。まずQちゃんのver.8を試してみたのだが、プレビューチップがかなり強化されてていい感じ。でもQちゃん版は、ウィンドウの取り込みが完全じゃないからなー。Everythingからフォルダ開くと、すべて別ウィンドウになる。今はまだPちゃん版だなぁ。

 それに、Pちゃん版は「古いリストビューコントロールを使用する」が便利すぎる。Win7ではExplorerのリストビューがDirectUIHWNDに覆われていて、外部から干渉できないのだけど、この設定ONにすると従来のSysListView32になる。AHK使いとしてこれは外せん。

 というか、今まで効果も理解せずにONにしてたので、そもそも邪魔者DirectUIHWNDの存在を知らなかった。

64bit版OSに32bit版CBX Shellを入れる

 Tablacus Explorer x86のために、CBX Shellもx86版も入れたいのだが、64bit/32bit共通インストーラーなので、x64環境ではx86版が入れられない。インストーラーを32bitで起動してもダメ。というわけでx86環境からDLLをこちらに持ってきて、regsvr32 CBXShell.dllで対応。


[PR]
by lordnoesis | 2012-06-16 14:06 | テクノロジ | Trackback | Comments(0)

AutoHotKey_Lで、関連付けを動作中のアプリケーションで開くツール作った。

 動作中のプロセスからリストにあるものを探し出して引数(コマンドラインオプション)を転送するS2WAを、改めてAHKで作り直してみた。
 これによってリストがUnicodeになり、また、250文字を超える引数に対応した。

; ////////////////////////////////////////////////////////////////////////////////
;
; S2WA.ahk ver.2.0.0
;
; ////////////////////////////////////////////////////////////////////////////////

  FileEncoding, CP1200

  IfNotExist, %A_ScriptDir%\AppList.txt
  {
    MsgBox, %A_ScriptDir%\AppList.txt が存在しません!
    ExitApp
  }

  for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
    ProcessList := ProcessList "`n" process.ExecutablePath

  TrgExe := ""
  Loop, Read, %A_ScriptDir%\AppList.txt
  {
    if ("" == A_LoopReadLine)
      continue
    StringLower, SearchExe, A_LoopReadLine
    Loop, Parse, ProcessList, `n, `r" "
    {
      StringLower, TipProcess, A_LoopField
      if (SearchExe == TipProcess) {
        TrgExe := TipProcess
        break
      }
    }
    if ("" != TrgExe)
      break
  }

  If ("" == TrgExe)
    FileReadLine, TrgExe, %A_ScriptDir%\AppList.txt, 1

  Loop, %0%
  {
    CmdlineBuf := %A_Index%
    Run, %TrgExe% "%CmdlineBuf%"
    Sleep, 1000
  }

 これをAhk2ExeでExe化し、関連付けすれば便利。例えば.htmlやHTTPに関連付け、リストにブラウザを列挙することで、起動済みのブラウザや、軽量なブラウザで開けるようになる。例えばっていうか、それしか思いつかないので、他に便利な使い道があったら教えてください(お。

 なお、Windows7でHTTPなどのプロトコルを関連付けするにはレジストリをいじる必要がある。

Windows Vista 既定のプログラム 関連付け レジストリ とかの話



REGファイルはじめました。
[PR]
by lordnoesis | 2012-06-09 19:19 | テクノロジ | Trackback | Comments(0)

AutoHotKey_Lで、OperaのRamDisk運用を便利にしたかった……。

 前回の更新直後に「コピーのタイミングってWindowsの起動/終了時でいいんじゃ……」と遅まきながら気づいてしまい、レストア/バックアップ機能だけ取り出し強化したのだが、結局、「バッチでXCOPY使えばいい」の域を出られなかった残念なAHKスクリプト。

 一応、起動時にOperaをRamDiskにコピーし、Opera終了時/Windows終了時には自動でバックアップしてくれる。――のだが、バックアップ対象を絞らないと30秒ほどかかるので、レジストリで「応答のないアプリケーションを自動で終了する」をONにしてると間に合わない。

 グループポリシーが使える環境の人は、シャットダウンスクリプトでXCOPY使うのが正解。でなければ、RamDiskを自動バックアップ対応のものに変えれ。

; --------- --------- --------- --------- ---------
;
; CopyOpera.ahk
;
; ・起動時にOperaをRamDiskにコピー(レストア)する。
; ・常駐中はOperaを監視し、隙あらばHDDにコピー(バックアップ)する。
;  ・Operaが終了した時や、Windowsが終了する時など。
; ・指定フォルダの除外コピーが可能(cacheフォルダやmailフォルダなど)
;
; --------- --------- --------- --------- ---------

#Persistent

  OperaPath := "C:\Program Files\Opera\Opera"  ; Opera.exeの存在するフルパスを指定。
  RamPath := "R:\Opera"  ; Operaのコピー先となるフルパスを指定。

  NGPathR := "profile\cache | profile\icons | profile\mail | profile\opcache | profile\temporary_downloads"  ; レストアしないディレクトリをOperaPathからの相対パスで指定
  NGPathB := NGPathR  ; バックアップしないディレクトリを、RamPathからの相対パスで指定

; --------- --------- --------- --------- ---------

  OperaPath := CutLastDelimiter(OperaPath), RamPath := CutLastDelimiter(RamPath)
  NGPathR := ConvList(NGPathR), NGPathB := ConvList(NGPathB)

  OpBackupSW := 0

  gosub, OpRestore

  SplashView("OperaReady!")

  OnExit, ExitOp
  SetTimer, CheckOp, 5000
return

; --------- --------- --------- --------- ---------

ExitOp:
  if OpBackupSW {
    Process, WaitClose, opera.exe
    gosub, OpBackup
    SplashView("OperaBackup!")
    Sleep, 3000
  }
ExitApp

; --------- --------- --------- --------- ---------

CheckOp:
  Cnt++
  if (30 < Cnt) {
    Cnt := 0
    FileCopy, %RamPath%\profile\sessions\autosave.win, %OperaPath%\profile\sessions\autosave.win, 1
  }

  Process, WaitClose, opera.exe, 1
  if (0 == ErrorLevel) { ; Operaが動いていなければ
    if OpBackupSW {  ; まだバックアップされていなければ
      gosub, OpBackup
      SplashView("OperaBackup!")
      OpBackupSW := 0
    }
  } else{  ; Operaが動いていれば
    OpBackupSW := 1
  }
return

OpRestore:
  DirList := DigDirList(OperaPath, OperaPath, NGPathR)
  DirSet(RamPath, DirList)
  DirListCopy(DirList, OperaPath, RamPath)
return

OpBackup:
  DirList := DigDirList(RamPath, RamPath, NGPathB)
  DirSet(OperaPath, DirList)
  DirListCopy(DirList, RamPath, OperaPath)
return

; --------- --------- --------- --------- ---------

ConvList(FileList) {
  Res := ""
  Loop, Parse, FileList, |, %A_Space% \
  {
    if ("" == A_LoopField)
      continue
    FieldBuf := CutLastDelimiter(A_LoopField)
    result := result FieldBuf "`n"
  }
  return, CutLastNL(result)
}

GetDirList(TrgDir, RootPath , NGList) {
  if ("" == TrgDir)
    return
  result := ""
  LoopPattern := RootPath "\" CutRootPath(TrgDir, RootPath) "\*"
  Loop, %LoopPattern%, 2, 0
  {
    GetDir := CutRootPath(A_LoopFileLongPath, RootPath)
    if !NGCheck(GetDir, NGList) 
      result := result GetDir "`n"
  }
  return, CutLastNL(result)
}

DigDirList(TrgPath, RootPath, NGList) {
  DirList := "`n"
  TrgDirList := GetDirList(TrgPath, RootPath, NGList) "`n"
  ResDirList := ""
  Loop {
    Loop, Parse, TrgDirList, `n
    {
      ResDir := GetDirList(A_LoopField, RootPath, NGList)
      if ("" != ResDir)
        ResDirList := ResDirlist ResDir "`n"
    }
    DirList := DirList TrgDirList
    TrgDirList := ResDirList
    ResDirList := ""
    if ("" == TrgDirList)
      break
  }
  return, CutLastNL(DirList)
}

DirSet(TrgPath, DirList) {
  Loop, Parse, DirList, `n
    FileCreateDir, %TrgPath%\%A_LoopField%
  return
}

DirListCopy(DirList, RootPath, SendPath) {
  Loop, Parse, DirList, `n
    FileCopy, %RootPath%\%A_LoopField%\*, %SendPath%\%A_LoopField%, 1
  return
}

NGCheck(Keyword, NGList) {
  Loop, Parse, NGList, `n
  {
    if (1 == RegExMatch(Keyword, "s)^" EscRegEx(A_LoopField)))
      return, 1
  }
  return, "0"
}

CutLastDelimiter(TrgPath) {
  StringRight, CharBuf, TrgPath, 1
  if ("\" == CharBuf)
    StringTrimRight, TrgPath, TrgPath, 1
  return, TrgPath
}

CutLastNL(TrgPath) {
  result := RegExReplace(TrgPath, "s)[\r\n]+\z", "", $, 1)
  return, Result
}

CutRootPath(TrgPath, RootPath) {
  return, RegExReplace(TrgPath, "s)^" EscRegEx(RootPath) "(\\)?", "", $, 1)
}

EscRegEx(trg) {
  EscList := "\`n.`n*`n?`n+`n[`n]`n{`n}`n|`n(`n)`n^`n$"
  Loop, Parse, EscList, `n
    StringReplace, trg, trg, %A_LoopField%, \%A_LoopField%, 1
  return, trg
}

; --------- --------- --------- --------- ---------

SplashView(TextBuf, Timer = 3000) {
  Progress, B1 ZH0 W800, %TextBuf%
  SetTimer, SplashClose, %Timer%
}

SplashClose:
  SetTimer, SplashClose, Off
  Progress, Off
return

 下位フォルダをいじるスクリプトに流用できるから、無駄死にではないぞ。ま、負け惜しみじゃないんだからっ。

 PCの突然死対策に、2分半に一度、autosave.winだけバックアップするようにしてみた。というか使うだけならバックアップするのこれだけでよさげ。


[PR]
by lordnoesis | 2012-04-16 22:39 | テクノロジ | Trackback | Comments(0)
ブログトップ | ファンになる