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

AutoHotKeyのダブルクォーテーションのエスケープ。

 ググってもChr(0s22)使えとしか出てこないのだが、""で行ける。
 例えば次のコードは、期待通りに動く。

F12::
  foo := "<a href=""../index.html"">"
  MsgBox, %foo%
return

 この情報、どこで知ったんだっけ?と思って探したら普通に書いてあったー。

AutoHotkey Wiki > #EscapeChar


[PR]
by lordnoesis | 2013-08-29 19:32 | テクノロジ | Trackback | Comments(0)

AutoHotKeyで、AzPainter2を少し便利に。

 AzPainter2を少し便利にするスクリプト作った。今回実現したのはキー操作によるカレントレイヤの切り替えと、17段階の明度切り替え。

 カーソル上下でレイヤ切り替え。スクロールには非対応。ごくまれにレイヤ順が乱れることがあるが、気にしない方向で。発動時にカーソル動かすとレイヤ移動になっちゃうので、BlockInput入れた。解除されない場合、Alt+Ctrl+Deleteで強制解除できる。AzDには標準でカレントレイヤ切り替えあるのになー。

 PgUp、PgDnで明度変更。厳密にいうとHSVモードだと明度だが、RGBモードだと青。一度実行するとAzP2が終了するまで常駐するが、常駐時はスポイト等で明度を変更しても自動的に17段階のいずれかに補正される。
 こんなんなにに使うのかというと、Seeneon用の深度マップを作るのにめっちゃ便利。17段階(-8 ~ 0 ~ +8)なのも、中央(128)が欲しかったから。

;--------------------------------------------------------------------------------------
; AzPainter2
;--------------------------------------------------------------------------------------
#IfWinActive AzPainter2 - ahk_class Main

Numpad0::Space  ; Numpad0でもスクロール

Up::  ; ひとつ上をカレントレイヤに
  ALayerChange(1)
return

Down::  ; ひとつ下をカレントレイヤに
  ALayerChange(0)
return

PGUP::
.::  ; HSVモード時、明度を上げる(17段階)
  if (CVLv < 16)
    CVLv++
  C3SetLevel(CVLv)
return

PGDN::
,::  ; HSVモード時、明度を下げる(17段階)
  if (CVLv > 0)
    CVLv--
  C3SetLevel(CVLv)
return

ALayerChange(SW) {
  IfWinNotExist, レイヤ ahk_class Layer
    return
  
  BlockInput, On
  WinGetPos, WX, WY
  ControlGetPos, CX, CY, CW, CH, LayerView1
  CX += 4,   CY -= 16
  BaseX := WX + CX,   BaseY := WY + CY
  MaxX := BaseX + CW,   MaxY := BaseY + CH

  CoordMode, Pixel
  PixelSearch, , PY, BaseX, BaseY, MaxX, MaxY, 0xC6D1FF, 0, Fast
  if ErrorLevel {
    BlockInput, Off
    return
  }
  
  LayerNum := (PY - BaseY) // 35 + 1
  
  SW ? LayerNum-- : LayerNum++
  CCY := CY + 35 * LayerNum
  ControlClick, X%CX% Y%CCY%, , , L, 1, Pos NA
  BlockInput, Off
}

CheckCV:
  IfWinNotExist, AzPainter2 - ahk_class Main
  {
    ToolTip, , , , 2
    SetTimer, CheckCV, Off
    return
  }
  
  ControlGetText, CVNum, Edit3, コントロール ahk_class #32770
  if (BefCVNum == CVNum)
    return
  BefCVNum := CVNum
  
  CVLv := CVNum // 16
  if (8 <= (CVNum - CVLv * 16))
    CVLv++
  
  C3SetLevel(CVLv)
return

C3SetLevel(CVLv) {
  IfWinNotExist, コントロール ahk_class #32770
    return

  CoordMode, ToolTip
  WinGetPos, WX, WY
  ShowCVLv := CVLv - 8
  ToolTip, %ShowCVLv%, %WX%, %WY%, 2
  SetTimer, CheckCV, 300
  
  CVNum := 16 * CVLv
  ControlSetText, Edit3, %CVNum%
}

 レイヤの数は限られてるんだし、PixelSearchで広範囲を走査するより、その数だけPixelGetColorした方が早いんじゃね?と思ったが、そんなことはなかったぜ!
 あと、PixelSearchってFastがデフォじゃないんだな。他のコマンドはデフォが高速側な印象。


[PR]
by lordnoesis | 2013-07-16 19:24 | テクノロジ | Trackback | Comments(0)

OperaNext15を試して、Chrome拡張入れてみた。

 Opera15(以下OPR)のOperaNextが出たので色々いじってみた。なおOperaNextというのは、Operaの次期バージョンのプレビュー版であり、αとかβとかウィークリービルドのたぐいであって、間違っても正式版ではないので注意。

 OPRでは、エンジンがWebKit(Blink)へと変更になるが、スタッフが「Operaらしさはそのまま」といってたもんだから、ワシは「Opera in Webkit」的なものが出てくると思っていた。だがそこに「Chromium Opera Edition」としかいいようがないものが出てきたせいで、ワシのみならず、Operaクラスタは阿鼻叫喚と化したのだった。そのあとでスタッフが「不安定な機能はまだ実装してないだけ」「高速リリース採用するので、いずれOperaらしくなるよ!」などと弁明したため、現状は様子見である。
 などといきなりdisり気味だが、現時点でもChromeの代替としては十分であり、ワシはサブとして使っていたChromeを捨てた! OPRが真にOperaの代替となるまでは、メインはOpera12が続投すればいいじゃない!

 で。OPRでは拡張機能もWebKitの物を使うことになる。Operaの拡張ストアにOPRでアクセスするとOPR対応版だけが表示されるが、その数はまだ多くはない。そこで、OPR拡張がないならChrome拡張を使えばいいじゃない!というのが本題である(前置き長ぇ。

 Download Chrome Extensionを導入することで、普通にChromeストアから拡張をインストールできる。

 普通にChromeのストアに行っても、OPRでは「Chromeに追加」が表示されないので、手動でインストールせねばならない。
 まず、crxファイルをDLする。crxはhttp://clients2.google.com/service/update2/crx?response=redirect&x=id%3D%26uc%26lang%3Den-US&prod=chromeで、IDをはさんだURLで入手できる。IDは拡張の個別ページのURLに含まれている、32文字くらいのアスキー文字列。例えばLastPassのhttps://chrome.google.com/webstore/detail/lastpass/hdokiejnpimakedhajhdlcegeplioahdならhdokiejnpimakedhajhdlcegeplioahdがそうなので、crxのURLはhttp://clients2.google.com/service/update2/crx?response=redirect&x=id%3Dhdokiejnpimakedhajhdlcegeplioahd%26uc%26lang%3Den-US&prod=chromeとなる。OPRで入力しても「Operaのストアじゃないからダメ」といわれるだけなので、IEなどで適当なフォルダに保存する。
 あとは野良拡張と同じ。OPRの拡張管理画面にドロップすると一覧に追加され確認が出るので、吹き出しの「インストール」を押せばおk。

 Opera Next 16では、opera://flags内のDynamic extension toolbar scalingを有効にすることで、アイコンの表示数を増やすことができるが、ウィンドウ幅依存なので表示しきれない可能性がある。

 ただし注意点がいくつかある。OPRの拡張バーは現状、最初の6個までしかアイコンを表示できない。非表示でも拡張自体は有効だが、アクセス手段がアイコンしかない場合は実質、利用不可能となる。アイコンの並び順=インストール順なので、アイコン必須の拡張からインストールし、一時的にアイコンが必要になった場合に上位の拡張を無効化するなどの工夫が必要となる。

 以下、試してみたよさげな拡張。

OPRストア


LastPass -- バージョン情報に「Chrome版」とある。
AdBlock

Chromeストア


はてなブックマーク GoogleChrome 拡張
Tab Manager -- タブ一覧。ファビコンのみ、あるいはファビコンとタイトル。
Tabs Outliner -- タブ一覧。ファビコンとタイトル。ポップアップでなく別ウィンドウ。OPRに未実装の「ウィンドウ間でのタブ移動」が可能。
Tab Expose -- タブ一覧。サムネイル。
theTabs -- タブ一覧。サムネイル。ポップアップでなく独立タブ。ひとつめのウィンドウのみ。
Zoom Text Only -- テキストのみ拡縮。ショートカットキーによる動作だが、設定はアイコンからしかできない。
PageRank -- Googleウェブ履歴にちゃんとタイトルが残る物の中で、シンプルなやつ。
AutoPatchWork
ToggleLink: Select Text From Link -- リンク上でshiftを叩くとただの文字列になる。5秒で元に戻る。


[PR]
by lordnoesis | 2013-06-01 13:30 | テクノロジ | Trackback | Comments(0)

AutoHotKey_Lで、EverythingSearchのカラムとウィンドウ幅を自動調整してみた。

 一般的なListView等には「Ctrl+NumpadAdd(テンキーのプラス)」でカラム(列)幅の自動調整を行うショートカットが存在するらしく、Everythingも例外ではない。だが当然ながらこの機能はカラム幅を変更するだけで、ウィンドウサイズはそのままだ。ゆえに、普段はウィンドウを小さくしている場合、面倒なことになる。
 Everythingの1.3βにはウィンドウサイズの変更ショートカットがあり、「自動」もあるのだが、この機能はマルチモニタ環境を考慮しないため、ひとつのモニタに収まりきらない可能性がある。そもそも二回もショートカット使うというのがスマートでない。自動化すべきである。

 というわけで、Everything上でCtrl+NumpadAddすると、カラム幅を自動調節したのち、それがすべて見渡せるようにウィンドウ幅も自動調節する(ウィンドウのあるモニタ幅が上限)AHKスクリプト書いた。少し変えればEverything以外にも使えるかも?

;--------------------------------------------------------------------------------------
; Everything
;--------------------------------------------------------------------------------------
#IfWinActive ahk_class ahk_class EVERYTHING

$^NumpadAdd::
  ACtrl :=
  while ("EVERYTHING_LISTVIEW1" != ACtrl) {
    ControlFocus, EVERYTHING_LISTVIEW1
    ControlGetFocus, ACtrl
  }
  Send, ^{NumpadAdd}
F12::
  WinGetPos, WinX, WinY, WinW, WinH
  WinYC := WinH // 2 + WinY, WinXC := WinW // 2 + WinX
  MntNum := 2  ; 有効なモニタ数(頻繁に変更するなら↓をアンコメント)
  ;~ SysGet, MntNum, 80
  Loop, %MntNum%
  {
    SysGet, Mnt, MonitorWorkArea, %A_Index%
    if (MntTop < WinYC) && (WinYC < MntBottom) && (MntLeft < WinXC) && (WinXC < MntRight)
      break
  }
  if (MntLeft < WinX)
    AftWinX := WinX
  else
    AftWinX := MntLeft
  AftWinW := MntRight - AftWinX
  
  Sleep, 50
  SysGet, FW, 32
  SysGet, VSW, 2
  ControlGet, Hwnd, Hwnd, , EVERYTHING_LISTVIEW1
  GetScrollInfoAll(Hwnd, SB_HORZ, , nMax)
  AftWinW2 := nMax + VSW + FW * 2 + 1
  if (AftWinW > AftWinW2)
    AftWinW := AftWinW2
  
  WinMove, , , %AftWinX%, , %AftWinW%
return

; https://sites.google.com/site/agkh6mze/strage 窓調査.ahk
GetScrollInfoAll(hwnd, type, ByRef nMin="", ByRef nMax="", ByRef nPage="", ByRef nPos="", ByRef nTrackPos="") {
    VarSetCapacity(SCROLLINFO, 7*4, 0x00)
    NumPut(28, SCROLLINFO, 0, "Int")
    NumPut(0x17, SCROLLINFO, 4, "Int") ; SIF_RANGE & SIF_PAGE & SIF_POS & SIF_TRACKPOS = 0x17
    nMin:="", nMax:="", nPage:="", nPos:="", nTrackPos:=""
    if (!DllCall("user32.dll\GetScrollInfo", "UInt", hwnd, "Int",type, "Ptr", &SCROLLINFO, "Int"))
      Return false
    nMin := NumGet(SCROLLINFO, 8, "Int")
    nMax := NumGet(SCROLLINFO, 12, "Int")
    nPage := NumGet(SCROLLINFO, 16, "Int")
    nPos := NumGet(SCROLLINFO, 20, "Int")
    nTrackPos := NumGet(SCROLLINFO, 24, "Int")
    Return true
}

 横スクロールバーの範囲を取得して、ウィンドウサイズをそれ+縦スクロールバーの幅に拡縮してるだけ。

 たまにちゃんと働かんことがあるのだが、何度か繰り返す運用でカバー。


[PR]
by lordnoesis | 2013-05-21 19:41 | テクノロジ | Trackback | Comments(0)

AutoHotKey_Lで、Operaの起動を便利にしてみた。 ver.2.3.0

 AutoHotKey_Lで、Operaの起動を便利にしてみた。をちょっと強化。AutoSave.winをブックマークに変換する際に、スタックごとにフォルダで分ける機能の追加。あと小規模改善。

; --------- --------- --------- --------- ---------
; RunOpera.ahk ver.2.3.0
; --------- --------- --------- --------- ---------

#WinActivateForce

  OperaPath := "R:\Opera"  ; Opera.exeの存在するパス。末尾"\"は不可。
  
  if %0%  ; 引数があった場合、Operaのパスと見なす
    OperaPath = %1%
  
  SessionsPath := OperaPath "\profile\sessions"  ; セッションフォルダのフルパスを指定。末尾"\"は不可。
  BookmarksPath := OperaPath "\profile\bookmarks.adr"  ; bookmarks.adrのフルパスを指定。
  
  TimeLimit := 30  ; 最終セッション退避確認ダイアログを自動でスキップするまでの秒数。
  
  AutoConvSW := 1  ; 最終セッションを退避させる場合、自動でブックマークに変換する設定。 0:変換しない。 1:変換する。
  ACMoveSW := 1  ; 自動変換(↑)したセッションを隔離する設定。 0:隔離しない。 1:隔離する。
  
  StackSW := 1  ; スタックの設定。 0:無視する。 1:スタックごとにフォルダを分ける。
  
  HisReadSW := 0  ; タブ履歴(タブで表示したページの履歴)の設定。 0:最新のみ読み込む。 1:すべて読み込む。
  His0PrefixSW := 0  ; タブ履歴がなかった場合のプレフィックスの設定。 0:なし。 1:0を明示する。
  
  WriteTrgSW := 1  ; ブックマーク情報を書き込む場所の設定。 0:セッションフォルダにテキストで保存。 1:bookmarks.adrに書き込む。
  
; --------- --------- --------- --------- ---------
  
  IfNotExist, %SessionsPath%\
  {
    MsgBox, 16, , セッションフォルダが見つかりません。`n%SessionsPath%
    ExitApp
  }
  If WriteTrgSW {
    IfNotExist, %BookmarksPath%
    {
      MsgBox, 16, , bookmarks.adrが見つかりません。`n%BookmarksPath%
      ExitApp
    }
  }
  
  IfNotExist, %SessionsPath%\autosave.win
  {
    IfExist, %SessionsPath%\autosave.win.bak
      FileMove, %SessionsPath%\autosave.win.bak, %SessionsPath%\autosave.win
  }
  IfExist, %SessionsPath%\autosave.win
  {
    FileCopy, %SessionsPath%\autosave_RunOpBak.win, %SessionsPath%\autosave_RunOpBak2.win, 1  ; ↓セッション退避etc.を実行しない時も念のため2世代バックアップ。
    FileCopy, %SessionsPath%\autosave.win, %SessionsPath%\autosave_RunOpBak.win, 1
    GoSub, SessionAnalyze
  }
  
  FileCopy, %OperaPath%\ui\fastforward_backup.ini, %OperaPath%\ui\fastforward.ini, 1  ; アップデートのたびにFastForward.iniが初期化される問題の対策。
  
  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 ErrorLevel {
    MsgBox, 48, , Sessionの読み込みに失敗しました。`n%SessionsPath%\autosave.win
    return
  }
  
  Idx := 0
  WinTitles := ""
  Loop {
    Idx := RegExMatch(OSession, "\[(\d+)history url\][\s\S]+?count=(\d+)", $, Idx + 1)
    If !Idx
      Break
    WinNum := $1
    HisNum := $2 - 1
    HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
    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 !ErrorLevel  ; 最終セッションのリネームに成功なら
        Break
      BackupName := TimeNum "_" A_Index ".win"
    }
    FileDelete, %SessionsPath%\autosave.win.bak
    If AutoConvSW
      GoSub, SessionConvert
  }
  IfMsgBox, Cancel
    ExitApp
return

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

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

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

SessionConvert:
  If WriteTrgSW
    FileCopy, %BookmarksPath%, %BookmarksPath%_%A_Now%  ; bookmarks.adrのバックアップは無制限なので注意
  
  CmdLine := SessionsPath "\" BackupName
  SplitPath, CmdLine, , , , SessionName
  Result := "#FOLDER`n  NAME=[Session] " SessionName "`n`n"
  ResultBuf := Result
  
  Idx := 0
  BefGroupNum := 0
  His0Prefix :=
  Loop {
    Idx := RegExMatch(OSession, "\[(\d+)\][\s\S]+?group=(\d+)[\s\S]+?\[\1history url\][\s\S]+?count=(\d+)", $, Idx + 1)
    If !Idx
      Break
    WinNum := $1
    GroupNum := $2
    HisNum := $3 - 1
    HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
    HisUrl := GetHisUrl(OSession, WinNum, HisNum, Idx)
    
    if StackSW
      if (BefGroupNum != GroupNum) {
        if BefGroupNum
          Result .= "-`n`n"
        if GroupNum
          Result .= "#FOLDER`n  NAME=[Stack] " GroupNum "`n`n"
        BefGroupNum := GroupNum
      }
    
    If !HisReadSW {  ; タブ履歴を無視する場合
      Result .= "#URL`n  NAME=" HisTitle "`n  URL=" HisUrl "`n`n"
      Continue
    }
    
    StringLen, HisNumLen, HisNum
    
    If !HisNum {
      if His0PrefixSW
        His0Prefix := "[" ZeroSupply(HisNum, HisNumLen) "] "
      Result .= "#URL`n  NAME=" HisPrefix 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 WriteTrgSW {
    FileRead, BMBuf, *t *P65001 %BookmarksPath%
    StringGetPos, Idx, BMBuf, #DELETED
    if !Idx {
      StringMid, BMBufP, BMBuf, 1, Idx
      StringMid, BMBufS, BMBuf, Idx + 1
      Result := BMBufP Result BMBufS
      FileDelete, %BookmarksPath%
    }
    FileAppend, %Result%, %BookmarksPath%, CP65001
  } Else {
    FileDelete, %CmdLine%.txt
    FileAppend, %Result%, %CmdLine%.txt, CP65001
  }
  
  If ACMoveSW {
    IfNotExist, %SessionsPath%\AutoConv\
      FileCreateDir, %SessionsPath%\AutoConv\
    FileMove, %CmdLine%, %SessionsPath%\AutoConv\%BackupName%
    If ErrorLevel
      MsgBox, 48, , 変換済みセッションの移動に失敗しました。`n%SessionsPath%\AutoConv\
  }
return

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

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

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

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

セッション確認ダイアログ

c0031643_22274759.png

ブックマーク変換例。

c0031643_12534236.jpg


[PR]
by lordnoesis | 2013-05-12 12:55 | テクノロジ | Trackback | Comments(0)

MultiPar同梱のpar2j.exeで任意のフォルダのリカバリファイルを作成するバッチ。

 あらかじめファイルを解析してリカバリファイル(Par形式)を作っておくことで、もしファイルが破損しても復元できるかもしれないMultiParというツールがある。リカバリファイルってのは、ファイルに対するパリティだとか、RAR書庫のリカバリレコードみたいなもんだと思っとけば、だいたいあってるんじゃないかな!

 Parは元々、転送エラー必至の通信環境でファイル転送を成功させるために作られたそうだが、耐用年数が気になる光学メディアや、S.M.A.R.T.が微妙に警告発してるようなHDDを使い続けなきゃならん環境とかでも大活躍だ。

 ただ、MultiParはGUIなんで、一括処理には向いてない。というわけで、同梱されてるCUIツール「par2j.exe」を使って、任意のフォルダのリカバリファイルを作成するバッチ書いた。

@echo off
echo ###########################################################################
echo #
echo # CreatePar2.bat
echo #
::   # MultiPar同梱の「par2j.exe」でフォルダのリカバリファイルを作成する。
::   #
::   # 引数なし:カレントフォルダ直下のフォルダを処理。
::   # 引数あり:引数のフォルダを処理。
::   #
echo ###########################################################################

if exist %1 goto arg
echo.
echo ### %cd% 直下のフォルダを処理します。 ###
echo.

for /d %%i in (*) do @call :create %%~si

goto end


:arg
for %%i in (%*) do (
cd /d %%~dpsi
echo.
echo ### %%i を処理します。 ###
echo.

@call :create %%~si
)


:end
pause
exit


:create
::↓Par2j.exeまでのフルパスにすべし。
par2j.exe c /sm16384 /sr100 /rr10 "%1\!rr10.par2" "%1\*"par2j.exe c /sr1000 /rr3 "%1\!sr1000rr3.par2" "%1\*"
exit /b

 正直、Parをぼんやりとしか理解してない輩が、英語ヘルプを機械翻訳してなんとなくで書いたのでry
 ブロック数多い方が(計算遅くなるが)、効率上がる(リカバリファイル小さくて済む)んだよ、な……? リカバリファイルは受け渡しするんでもなけりゃ、ひとつでもいいんだよな……?

 オプション変えてみた。

MultiPar -- 修復用データを作ってファイルの破損や消失に備える


[PR]
by lordnoesis | 2013-02-18 22:17 | テクノロジ | Trackback | Comments(2)

AutoHotKey_Lで、Operaの起動を便利にしてみた。 ver.2.2.0

 AutoHotkey_Lで、Opera12の起動を便利にしてみた。をちょっと改善。状況によってセッション退避やブックマーク変換が機能しない問題とか直ったはず(ちょっとしたってレベルじゃねーぞ。

 作者にもわからんくなってきたので、機能をまとめてみる。

  • Operaの起動前に、前回終了時のセッション(AutoSave.win)の内容を確認できる。
  • AutoSave.winを復元せずに、空のOperaを起動することができる。
  • 復元しない場合、AutoSave.winをブックマークに変換できる。
  • AutoSave.winの2世代バックアップ。
  • FastForward_backup.iniでFastForward.iniを上書きする(アップデート対策)。
  • 起動直後に出現するマスターパスワード入力ダイアログを最前面固定かつアクティブにする。
 ――うん、地味!

; --------- --------- --------- --------- ---------
; RunOpera.ahk ver.2.2.0
; --------- --------- --------- --------- ---------

#WinActivateForce

  OperaPath := "R:\Opera"  ; Opera.exeの存在するパス。末尾"\"は不可。

  if %0%  ; 引数があった場合、Operaのパスと見なす
    OperaPath = %1%

  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%
    ExitApp
  }
  If WriteTrgSW {
    IfNotExist, %BookmarksPath%
    {
      MsgBox, 16, , bookmarks.adrが見つかりません。`n%BookmarksPath%
      ExitApp
    }
  }

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

  FileCopy, %OperaPath%\ui\fastforward_backup.ini, %OperaPath%\ui\fastforward.ini, 1  ; アップデートのたびにFastForward.iniが初期化される問題の対策。

  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

ExitApp

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

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

  Idx := 0
  WinTitles := ""
  Loop {
    Idx := RegExMatch(OSession, "\[(\d+)history url\].+?count=(.*?)\n", $, Idx + 1)
    If !Idx
      Break
    WinNum := $1
    HisNum := $2 - 1
    HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
    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 !ErrorLevel  ; 最終セッションのリネームに成功なら
        Break
      BackupName := TimeNum "_" A_Index ".win"
    }
    FileDelete, %SessionsPath%\autosave.win.bak
    If AutoConvSW
      GoSub, SessionConvert
  }
  IfMsgBox, Cancel
    ExitApp
return

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

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

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

SessionConvert:
  If WriteTrgSW
    FileCopy, %BookmarksPath%, %BookmarksPath%_%A_Now%  ; bookmarks.adrのバックアップは無制限なので注意

  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 !Idx
      Break
    WinNum := $1
    HisNum := $2 - 1
    HisTitle := GetHisTitle(OSession, WinNum, HisNum, Idx)
    HisUrl := GetHisUrl(OSession, WinNum, HisNum, Idx)

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

    StringLen, HisNumLen, HisNum

    If !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 WriteTrgSW {
    FileRead, BMBuf, *t *P65001 %BookmarksPath%
    StringGetPos, Idx, BMBuf, #DELETED
    if !Idx {
      StringMid, BMBufP, BMBuf, 1, Idx
      StringMid, BMBufS, BMBuf, Idx + 1
      Result := BMBufP Result BMBufS
      FileDelete, %BookmarksPath%
    }
    FileAppend, %Result%, %BookmarksPath%, CP65001
  } Else {
    FileDelete, %CmdLine%.txt
    FileAppend, %Result%, %CmdLine%.txt, CP65001
  }

  If ACMoveSW {
    IfNotExist, %SessionsPath%\AutoConv\
      FileCreateDir, %SessionsPath%\AutoConv\
    FileMove, %CmdLine%, %SessionsPath%\AutoConv\%BackupName%
    If 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, NumDigit){
  StringLen, NumLen, Num
  LoopNum := NumDigit - NumLen
  Loop, %LoopNum%
    Num := 0 Num
  return, Num
}

 これまでとは逆に、OperaPath等は末尾\不可になったので注意。

セッション確認ダイアログ

c0031643_22274759.png

ブックマーク変換例(下側はHisReadSW := 1)。

c0031643_22281581.jpg


[PR]
by lordnoesis | 2013-01-23 22:32 | テクノロジ | Trackback(1) | Comments(0)

AutoHotKey_Lで、フォルダの備忘録(あとで読む)作ってみた。

 私はタブが大好きなので、エクスプローラもタブ化している。そして、タブを開いていけばやがては「当面は必要ないから閉じたいけど、閉じると作業予定も忘れちゃうだろうなー」みたいなヤツが出てくる。これがブラウザだったら、いわゆる「あとで読む」のたぐいを使えばいいのだけど――というわけで作ったった!

 ウィンドウにドロップすると記録。リスト項目をダブルクリックで開く。その際、左端のチェックボックスが非チェックなら削除。右ダブルクリックすればチェックも無視して削除(開かない)。
 終了時にリストを記録して、次回起動時に再現。以上!

;/////////////////////////////////////////////////////////////////////////////////////
;
; OpenLater.ahk
;  フォルダをあとで開く
;
;/////////////////////////////////////////////////////////////////////////////////////


  DefCheckSW := 0  ; デフォルトで保護するか否か


;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


  if DefCheckSW
    DefCheckStr := "Check"
  
  FileEncoding, UTF-8-RAW
  
  SplitPath, A_ScriptName, , , , LogName
  LogPath := A_ScriptDir "\" LogName ".log"
  
  MarginX := 10, MarginY := 5
  Gui, Add, ListView, Checked AltSubmit Grid vPathListView gPathListViewAct, ID|名前|パス
  
  Loop, Read, %LogPath%
  {
    NowID := A_Index
    StringLeft, CheckSW, A_LoopReadLine, 1
    if CheckSW
      CheckStr := "Check"
    else
      CheckStr :=
    StringTrimLeft, DirPath, A_LoopReadLine, 1
    SplitPath, DirPath, DirName
    LV_Add("Vis " CheckStr, NowID, DirName, DirPath)
    StringReplace, DirPathEsc, DirPath, `,, `,`,, All
    PathList .= DirPathEsc ","
  }
  LV_ModifyCol(1, "Logical Auto")
  LV_ModifyCol(2, "Logical 100")
  LV_ModifyCol(3, "Logical AutoHdr")
  
  Gui, +AlwaysOnTop +Resize +MinSize
  Gui, Show, w300 h168
return

GuiDropFiles:
  GuiControl, -Redraw, PathListView

  StringReplace, DropList, A_GuiEvent, `r`n, `n, All
  NowID := LV_GetCount()
  Loop, Parse, DropList, `n, \
  {
    DirPath := A_LoopField
    FileAttrib := FileExist(DirPath)
    IfNotInString, FileAttrib, D
      continue
    StringReplace, DirPathEsc, DirPath, `,, `,`,, All
    if DirPathEsc in %PathList%
      continue
    PathList .= DirPathEsc ","
    SplitPath, DirPath, DirName
    NowID++
    LV_Add("Vis " DefCheckStr, NowID, DirName, DirPath)
  }
  gosub, ColWidthReset

  GuiControl, +Redraw, PathListView
return

PathListViewAct:
  if ("R" == A_GuiEvent)
    DelSW := 1
  else
    DelSW := 0
  
  if DelSW || ("A" == A_GuiEvent) {  ; 項目ダブクリ
    TrgItemID := A_EventInfo
    LV_GetText(DirPath, TrgItemID, 3)
    if !DelSW
      IfExist, %DirPath%
        Run, open %DirPath%
    if DelSW || (TrgItemID != LV_GetNext(TrgItemID - 1, "C")) {  ; 項目削除
      GuiControl, -Redraw, PathListView
      
      LV_GetText(DelPathID, TrgItemID, 1)
      StringReplace, DirPathEsc, DirPath, `,, `,`,, All
      StringReplace, PathList, PathList, %DirPathEsc%`,
      LV_Delete(TrgItemID)
      ListLineCnt := LV_GetCount()
      Loop, %ListLineCnt% {
        LV_GetText(PathID, A_Index, 1)
        if (PathID > DelPathID)
          LV_Modify(A_Index, "", PathID - 1)
      }
      gosub, ColWidthReset
      
      GuiControl, +Redraw, PathListView
    }
  }
return

ColWidthReset:
  LV_ModifyCol(1, "Auto")
  ;~ LV_ModifyCol(2, "100")
  LV_ModifyCol(3, "AutoHdr")
return

GuiSize:
  if (1 == A_EventInfo)
    return
  EMW := A_GuiWidth - MarginX * 2
  EMH := A_GuiHeight - MarginY * 2
  
  GuiControl, Move, PathListView, W%EMW% H%EMH%
  LV_ModifyCol(3, "Logical AutoHdr")
return

GuiClose:
  GuiControl, -Redraw, PathListView
  
  LV_ModifyCol(1, "Sort")
  PathList :=
  ListLineCnt := LV_GetCount()
  Loop, %ListLineCnt% {
    LV_GetText(DirPath, A_Index, 3)
    if (LV_GetNext(A_Index - 1, "C") == A_Index)
      PathList .= "1" DirPath "`n"
    else
      PathList .= "0" DirPath "`n"
  }
  FileDelete, %LogPath%
  FileAppend, %PathList%, %LogPath%
ExitApp

 Unicodeを諦めれば(FileEncodingをコメントアウト)、AHK_Lでなくともいいはず。

 以下はOpenLater.ahkを使いやすくする常駐スクリプト。エクスプローラでフォルダ(複数可)を選択してF11を押せばそのフォルダが、なにも選択していなければカレントフォルダがOpenLaterに送られる。
 OpenLaterが最小化状態でも問題なく動作する。

;--------------------------------------------------------------------------------------
; WindowsExplorer
;--------------------------------------------------------------------------------------
#IfWinActive, ahk_class CabinetWClass

$F11::
  KeyWait, F11
  PathList := GetSelectItemPath()
  if !ErrorLevel {
    WinGetText, CurPath, A
    RegExMatch(CurPath, "([A-Z]:\\[^\r\n]*)", $)
    PathList := $1
  }
  PathListEx :=
  Loop, Parse, PathList, `n
    IfExist, %A_LoopField%
      PathListEx .= A_LoopField "`n"
  Sort, PathListEx

  Sort, PathList
  IfWinNotExist, OpenLater.ahk ahk_class AutoHotkeyGUI
    Run, open hoge\OpenLater.ahk  ; OpenLater.ahkのパス
  WinWait, OpenLater.ahk ahk_class AutoHotkeyGUI
  WinGet, Hwnd, ID
  DropFiles(Hwnd, PathListEx)
  DropFiles(Hwnd, PathList)
return

GetSelectItemPath(FldSW = 0) {  ; AutoHotkey スレッド part11 >>913
  for Window in ComObjCreate("Shell.Application").Windows
    if (Window.hwnd == WinExist()) {
      for Item in Window.Document.SelectedItems
      {
        if (FldSW && !Item.IsFolder)
          continue
        FileList .= Item.Path "`n"
        Cnt++
      }
      break
    }
  StringTrimRight, FileList, FileList, 1
  ErrorLevel := Cnt
  return, FileList
}

DropFiles(hwnd, files, ptX=0, ptY=0, fNC=False) {  ; AutoHotkey スレッド part11 >>332
  static char_type:= A_IsUnicode ? "UShort" : "UChar"
    , char_size := A_IsUnicode ? 2 : 1
    , isUnicode := A_IsUnicode ? 1 : 0
  files := RTrim(files, "`r`n`t ") . "`n`n"
  byte_length := StrLen(files) * char_size
  Loop, Parse, files
    If (A_LoopField = "`n")
      NumPut(0x00, files, (A_Index-1) * char_size, char_type)
  
  hDrop := DllCall("GlobalAlloc", "UInt", 0x42, "UInt",20 + byte_length, "Ptr")
  p := DllCall("GlobalLock", "Ptr", hDrop)
  NumPut(20 , p + 00, "Int") ; offset
  NumPut(ptX , p + 04, "Int") ; pt.x
  NumPut(ptY , p + 08, "Int") ; pt.y
  NumPut(fNC , p + 12, "Int") ; fNC
  NumPut(isUnicode, p + 16, "Int") ; fWide
  DllCall("RtlMoveMemory", "Ptr", p + 20, "Str", files, "UInt", byte_length)
  DllCall("GlobalUnlock", "Ptr", hDrop)
  PostMessage, WM_DROPFILES := 0x233, hDrop , 0, , ahk_id %hwnd%
}

 DropFiles()のあとにウィンドウを閉じてもよさげ。

c0031643_1355170.png


[PR]
by lordnoesis | 2012-12-13 22:38 | テクノロジ | Trackback | Comments(0)

AutoHotKeyで、Everythingの検索結果からEverythingを呼び出してみた。

 EverythingSearchの検索結果で項目を選択してF4を押すと、選択項目のパスを新しいウィンドウ(仮名「結果ウィンドウ」)で検索するAHKスクリプト。Explorerなどでも便利なので、適当に#IfWinActiveをいじってやってみよう!(手抜き)
 「結果ウィンドウ」は、可能な限り再利用される。ただし「結果ウィンドウ」で実行した場合は、さらに新たなウィンドウが呼び出され、今後はそちらが再利用対象になる。

 Everythingでフォルダパスを検索(=フォルダを選択してF4)した場合、結果はそのフォルダ以下のファイル一覧。ファイルパスを検索(=ファイルを選択してF4)した場合、結果はそのファイルのみ。
 フォルダパスでフォルダの中身を検索したり、ファイルパスを削って「同じフォルダの別のファイル」や「別フォルダの同じ名前のファイル」を検索したり、あるいは「F4を二度押して(ファイルのみのウィンドウを残して)、一時的なファイル備忘録として使う」など、可能性は無限大だ!

  EverythingPath := "C:\Program Files (x86)\Everything\Everything.exe"  ; Appごとに似て非なるルーチンがたくさんあるので、AutoExecuteセクションで変数に格納してる。

;--------------------------------------------------------------------------------------
; Everything
;--------------------------------------------------------------------------------------
#IfWinActive ahk_class ahk_class EVERYTHING

$F4::
  Send, ^c
  sleep, 200
  SearchWord := Clipboard

;  if RegExMatch(SearchWord, "適当に整形すればいいと思うよ!",$)
;    SearchWord := $1

  WinGet, HwndA, ID, A
  if (WinExist("ahk_id " HwndEV " ahk_class EVERYTHING") && (HwndA != HwndEV)) {
    ControlSetText, Edit1, %SearchWord%
    WinActivate
  } else {
    Run, %EverythingPath% -search "%SearchWord%"
    Loop {
      WinGet, HwndEV, ID, %SearchWord% ahk_class EVERYTHING
      if (HwndEV && (HwndEV != HwndA))
        break
      Sleep, 200
    }
  }
  WinWaitActive, ahk_id %HwndEV%
  ControlSend, EVERYTHING_LISTVIEW1, ^{NumpadAdd}  ; カラム幅自動調整
return

 WinGet, OutputVar, MinMaxで、「結果ウィンドウ」を最大化してるウィンドウに固定しても便利。最大化したら他が見えない? AeroSnapや半画面化を使うんだ!

 気づいたこと。

  • WinExist関数の対象もLastFoundWindowになるぽ? 日本語リファレンスには記載ない。
  • ExcludeTitleって文字列以外(ahk_idとか)は使えないのかー。
  • Ctrl+NumpadAddはフォーカス箇所で動作が変わる。文字欄ならEverythingの「文字拡大」、SysListView32では標準の「カラム幅自動調整」。


[PR]
by lordnoesis | 2012-11-30 22:12 | テクノロジ | Trackback | Comments(0)

AutoHotKey_Lで、マンガミーヤCEを便利にしてみた&「sz7」の読み込みに対応させたかった……。

 以前書いたマンガミーヤCE向けの「ホイールによるタブ移動」と「表示している書庫/画像のパス保存≒タブセッション保存」をクリンナップしつつ、パス保存で作ったパスリストの読み込み機能も実装してみた。

 あと、基本的なキー設定をすべてAHKでメニューID叩いて実現してみた。Win7だとキーカスタマイズができない問題があって、いちいちVMWareでXPを起動するのが面倒だったので、もう全部AHKでいいじゃん!みたいな。キー割り当てはソースを見れ。
 なお上下キーはページ移動だが、押しっぱなしにした場合の移動を、キーリピートに頼らず実現している(キーリピートだと早すぎる)。二連打でリミッター開放。

;--------------------------------------------------------------------------------------
; マンガミーヤCE MangaMeeyaCW
;--------------------------------------------------------------------------------------
#IfWinActive ahk_class MainFrameDockWindow

MCE_MenuRepeat(MenuID) {
  PostMessage, 0x111, %MenuID%, 0, , A
  RegExMatch(A_ThisHotkey, "(\w+)", $)
  if (A_PriorHotkey == A_ThisHotkey ) && (150 > A_TimeSincePriorHotkey) {
    TipView("Turbo")
    WaitTime := 1
  } else {
    WaitTime := 100
  }
  KeyWait, %$1%, T0.5
  if ErrorLevel
    while GetKeyState($1, "P") {
      PostMessage, 0x111, %MenuID%, 0, , A
      Sleep, %WaitTime%
    }
  TipView("")
}


WheelUp::  ; タブバー上ならタブ移動
  MouseGetPos, , , , Ctrl
  if Ctrl
    PostMessage, 0x111, 20128, 0, , A
  else
    Send, ^+{Tab}
return

WheelDown::  ; タブバー上ならタブ移動
  MouseGetPos, , , , Ctrl
  if Ctrl
    PostMessage, 0x111, 20127, 0, , A
  else
    Send, ^{Tab}
return

Up::MCE_MenuRepeat("20092")  ; 戻る
Down::MCE_MenuRepeat("20091")  ; 進む

left::
Numpad1::
  send, ^+{Tab}  ; 右のタブ(ビューウィンドウ)
return

right::
Numpad3::
  send, ^{Tab}  ; 左のタブ(ビューウィンドウ)
return

^left::
Numpad4::
  PostMessage, 0x111, 20093, 0, , A  ; 1p進む
return

^right::
Numpad6::
  PostMessage, 0x111, 20094, 0, , A  ; 1p戻る
return

Numpad0::PostMessage, 0x111, 20151, 0, , A  ; 新規ビューウィンドウ

NumpadDot::PostMessage, 0x111, 20170, 0, , A  ; 画像情報表示

Space::  ; 見開き切替(1p/2p/自動見開き)
  MMCESW++
  if (1 == MMCESW) {
    PostMessage, 0x111, 20041, 0, , A
    TipView("1p")
  } else if (2 == MMCESW) {
    PostMessage, 0x111, 20042, 0, , A
    TipView("2p")
  } else {
    PostMessage, 0x111, 20044, 0, , A
    TipView("Auto")
    MMCESW := 0
  }
return

s::  ; 表示画像のパスをリストに保存(書庫内パス対応)
w::  ; パス保存後、タブ移動
  WinGet, AWinID, ID, A
  if (PreAWinID != AWinID)
    Prefix := A_Now
  PreAWinID := AWinID

  PostMessage, 0x111, 20151, 0, , A
  Sleep, 100
  PostMessage, 0x111, 20151, 0, , A

  WinGetText, WinTxt, A
  RegExMatch(WinTxt, "sJS)(?:([A-Z]:\\[\S ]+).*((?1))|((?1)))", $)
  if $3
    FileAppend, %$3%`n, MCE_%Prefix%.txt
  else
    FileAppend, %$1%`n%$2%`n, MCE_%Prefix%.txt
  SplashView($1 $3 "`n" $2)

  IfWinNotExist, MCE_%Prefix%.txt
    Run, MCE_%Prefix%.txt

  if ("w" == A_ThisLabel)
    Send, ^{Tab}
return

l::
  IfWinActive, A
  MsgBox, 262179, MangaMeeyaCEでパスリストを開く, クリップボードをパスリストと見なして開きますか?`n`n「いいえ」を選択した場合、パスリスト選択ダイアログを開きます。
  
  IfMsgBox, Cancel
    return
  IfMsgBox, Yes
    PathList := Clipboard
  IfMsgBox, No
  {
    FileSelectFile, ListPath, 3, .\, パスリストを開く, *.txt; *.sz7
    if !ListPath
      return
    FileRead, PathList, *t *P932 %ListPath%
    SplitPath, ListPath, , , ListExt
  }
  if !PathList
    return
  
  WinGet, MCE_PID, PID
  wmi := ComObjGet("winmgmts:")
  queryEnum := wmi.ExecQuery(""
    . "Select * from Win32_Process where ProcessId=" . MCE_PID)
    ._NewEnum()
  if queryEnum[process] {
    RegExMatch(process.CommandLine, """?([^""]+|\S+)""?", $)
    MCE_Path := $1
  }
  wmi := queryEnum := process := ""
  
  if ("sz7" == ListExt)
    MCE2sz7(PathList, MCE_Path)
  else {
    Loop, Parse, PathList, `n, %A_Space%%A_Tab%
    {
      Run, %MCE_Path% "%A_LoopField%"
      Sleep, 100
    }
  }
return

MCE2sz7(PathList, TrgPath, TrgHwnd = 0) {  ; ※sz7疑似展開機能は書庫内パス対応不可能
  if !TrgHwnd
    TrgHwnd := WinExist()
  
  Run, %TrgPath% "Dummy"
  Sleep, 100
  
  Loop, Parse, PathList, `n, \%A_Space%%A_Tab%
  {
    FileGetAttrib, FileAttrib, %A_LoopField%
    IfInString, FileAttrib, D  ; フォルダなら無視
      continue
    if (PrePath == A_LoopField)  ; ひとつ前と同じなら無視
      continue
    PrePath := A_LoopField
    
    if FileExist(A_LoopField) {  ; 実在するパス
      DropFiles(TrgHwnd, A_LoopField)
      Cnt++
    }
  }
  return, Cnt
}

 ソースみればわかるが、以前も作成スクリプトを書いたりしてたsz7の読み込みに、疑似的に対応してみた。というか、本当はコレがメイン。
 パスリスト読み込みは「n個のパスをn個のタブで開く機能」だが、sz7読み込みは「複数のパスをひとつのタブに開く機能」。ただし書庫内パスには非対応。CEの対応ファイルが"実在"していないとならない。

 CEはSusieプラグイン非対応なのでaxpathlist2.spiが使えないが、DnDの仕様をうまく利用すればいけるんじゃね?と思いやってみたが、「書庫はDnDでもリスト追加でなく新規に開く」「無理に書庫内パスを複数渡しても、読み込みエラー」という仕様の前に敗れ去る。無念。
 冷静に考えると(今時はメモリも有り余ってるのだし)、axpathlist2.spi入れた本家マンガミーヤを複数開いて、疑似的にタブ化すればいいよねっていう……。



オマケという名の夢の跡。
[PR]
by lordnoesis | 2012-11-09 20:54 | テクノロジ | Trackback | Comments(0)
ブログトップ | ファンになる