タブファイラー開発ブログ

Tablacus ExplorerやX-Finderの作者のブログ

EverythingでもMigemoを使えるようになりました。 - Tablacus Explorer

EverythingアドオンでもMigemoを使えるようになりました。

前回のブログで紹介したようにMigemoアドオンをインストールしてから…

Everythingアドオンのオプションの「Regular Expression/Migemo」にチェックして下さい。

f:id:tablacus:20151022230619p:plain

フィルターバーと同じ要領ですね。

 

前回書き忘れた 正規表現/Migemo インクリメンタルサーチ の機能

インクリメンタルサーチ中に「PGDN」キーで当てはまる次の項目に移動し、「PGUP」キーで当てはまる前の項目に移動します。

 

ローマ字で日本語検索 Migemo - Tablacus Explorer

Migemo: ローマ字のまま日本語をインクリメンタル検索 がTablacus Explorerでも使えるようになりました。

Tablacus Explorerでは JavaScript/Migemo のJavaScriptで実装したMigemoエンジンを使用しています。

 

インストール方法

まず、アドオンの「Migemo」をインストールします。

f:id:tablacus:20151021234446p:plain

次にMigemoのオプションを開き、

f:id:tablacus:20151021234509p:plain

「インストール」を押せば、上記のサイトからMigemoエンジンと辞書をダウンロードしてインストールできます。

f:id:tablacus:20151021234526p:plain

テストの場所でローマ字入力をして、Regular Expressionの場所に日本語を含む正規表現が表示されればOKです。

f:id:tablacus:20151021234720p:plain

Migemoでリスト上での検索を行う場合は、「正規表現/Migemo インクリメンタルサーチ」をインストールして下さい。

f:id:tablacus:20151021234741p:plain

Migemoでフィルタリングしたい場合は、フィルターバー(Innerフィルターバー)のオプションに入り

f:id:tablacus:20151021234809p:plain

「Regular Expression/Migemo」にチェックして下さい。

f:id:tablacus:20151021234938p:plain

日本語のファイルを扱う際に便利ですね。

Migemoの原作者の高林様、JavaScript版の作者のふるかわ様、便利な機能の公開ありがとうございます。

フォルダ ツリーの自動更新の強化2 - INameSpaceTreeControl

前回のふたつ目はAs/Rの作者さんにこちらでOS安定稼動を考えると良くないとアドバイスを頂いたので、Tablacus Explorer 15.10.5から別の方法で実装してみました。

今回の実装は

SHChangeNotifyDeregisterでInterruptレベルの通知をキャッチして………

ツリーに項目を追加する場合は INameSpaceTreeControl::SetItemState(IShellItem *, NSTCIS_EXPANDED, NSTCIS_EXPANDED) で追加する。

ツリーから項目を削除等する場合は NamespaceTreeControl のウインドウに WM_USER + 1 でメッセージを横流しする。

追加の方はまだ良いとして、削除などの方はOSのバージョンアップ等で仕様が変わったらアウトなんですが、SHChangeNotifyで投げるのに比べたら他のアプリに影響しないのでマシかなと。

 ついでに、みもふたもない言い方になりますが、そもそもDOSコマンドのmkdirとか「シェル通知を送らないことで高速化している」という側面もあるので、そっとしておいてあげた方が良いんじゃね?という考え方もあります。

エクスプローラーはmkdir等も対応してて自動的に追加されたりするので、「エクスプローラーはちゃんと動くんですが………」等と言われちゃいがちなのでなんとかしたいなと………

 

機会がありましたら、一緒にご飯したいですね。

フォルダ ツリーの自動更新の強化 - INameSpaceTreeControl

Windows Vista以降の場合、X-Finderのシステム互換やTablacus Explorerのフォルダ ツリーではINameSpaceTreeControlというVistaで追加されたツリーコントロールを使ってフォルダ ツリーを表示しています。

このツリーコントロールは自動でいろいろやってくれて便利なんですが、すでに展開しているフォルダで新規フォルダを作成しても追加されない場合があります。
例えば、コマンドラインの「mkdir フォルダ」としてフォルダを追加しても素のINameSpaceTreeControlではフォルダが追加されません。

f:id:tablacus:20150906230158p:plain

いろいろ試してみたところ、自動的に更新させる方法を2つ発見しました。

1.Windows 7で追加されたインターフェイスのINameSpaceTreeControl2のSetControlStyle2でNSTCS2_INTERRUPTNOTIFICATIONSを指定

INameSpaceTreeControl2 *pNSTC2;
if SUCCEEDED(m_pNameSpaceTreeControl->QueryInterface(IID_PPV_ARGS(&pNSTC2))) {
 pNSTC2->SetControlStyle2(NSTCS2_INTERRUPTNOTIFICATIONS, NSTCS2_INTERRUPTNOTIFICATIONS);
 pNSTC2->Release();

これだけで、Windows 7以降ではフォルダが追加されるようになりました。

ただ、Tablacus Explorerではこの方法は使わずコメントアウトしています。

何故かと言うと、私の環境では更新通知されすぎるのか、ちょっとしたファイル変更の度に更新してツリーが重くなってしまったからです。

TablacusExplorer/TE.cpp at master · tablacus/TablacusExplorer · GitHub


2.SHChangeNotifyDeregisterで通知をキャッチしてSHChangeNotifyで投げる

INameSpaceTreeControlではInterruptレベルの通知はキャッチしないが、Shellレベルの通知はキャッチしているようなので、SHChangeNotifyDeregisterでInterruptレベルの通知をキャッチしてSHChangeNotifyでShellレベルで投げる方法を考えました。

※SHChangeNotifyRegister定義でフォルダ関連のInterruptレベルの通知をキャッチ

Addons.TreeView.uRegisterId = api.SHChangeNotifyRegister(te.hwnd, SHCNRF_InterruptLevel | SHCNRF_NewDelivery, SHCNE_MKDIR | SHCNE_DRIVEREMOVED | SHCNE_MEDIAREMOVED | SHCNE_NETUNSHARE | SHCNE_RENAMEFOLDER | SHCNE_RMDIR | SHCNE_SERVERDISCONNECT | SHCNE_UPDATEDIR, Addons.TreeView.WM, ssfDESKTOP, true);

※通知をキャッチしてSHChangeNotifyでそのまま投げる

AddEvent("AppMessage", function (Ctrl, hwnd, msg, wParam, lParam)
{
 if (msg == Addons.TreeView.WM) {
  var pidls = {};
  var hLock = api.SHChangeNotification_Lock(wParam, lParam, pidls);
  if (hLock) {
   api.SHChangeNotify(pidls.lEvent, SHCNF_IDLIST, pidls[0], pidls[1]);
   api.SHChangeNotification_Unlock(hLock);
  }
  return S_OK;
 }
});

上記をTreeviewアドオンのscript.jsで行っています。

TablacusExplorerAddons/script.js at master · tablacus/TablacusExplorerAddons · GitHub

なおこの方法も副作用があります。SHChangeNotifyで投げているのでTablacus Explorerだけでなく他のアプリにも影響してしまいます。

例えば、Tablacus Explorerとツリーアドオン使用時はINameSpaceTreeControlを使っていると思われるAs/Rも、フォルダの追加等で自動的に更新されるようになります。

本当は自分だけ更新する方法があれば他のソフトへの悪影響の心配もなく良いのですが…

アドオン クリップボードの履歴 - Tablacus Explorer

アドオンのクリップボードの履歴ではファイル・フォルダのカットとコピーの一覧を作成します。

カスタマイズしていない場合はバックグラウンドでの右クリックメニューにクリップボードの履歴が出ます。

f:id:tablacus:20150822232858p:plain

クリップボードの履歴の項目を選ぶと右ドラッグと同じメニューが出ますので、コピー、移動、ショートカットの作成等を選びます。

f:id:tablacus:20150822232910p:plain

独自関連付け・マウス・キーをメニューで選ぶ - Tablacus Explorer

Tablacus Explorer 15.8.16で独自関連付け等をメニューで選んで実行できるようになりました。

例えば、htmlファイルをダブルクリックすると「ブラウザ」と「メモ帳」のメニューが表示され、選んで実行するという感じです。

 

設定方法はツール(T)→オプション(O)→メニュー→既定

フィルタを「*.html」

タイプを「メニュー」

オプションを「開く」にします。

f:id:tablacus:20150816231743p:plain

その下にメニューで表示させて実行する項目を作成します。

f:id:tablacus:20150816231937p:plain

f:id:tablacus:20150816232025p:plain

最後にタイプを「メニュー」にし、オプションを「閉じる」にするとそこまでがメニューになります。

f:id:tablacus:20150816232342p:plain

 

同様にマウスで項目のない場所をホイールクリックした場合にメニューを表示するには

f:id:tablacus:20150816232252p:plain

マウス欄がメニューに表示される名前になります。

f:id:tablacus:20150816232457p:plain

最後にタイプを「メニュー」にし、オプションを「閉じる」にするとそこまでがメニューになります。

f:id:tablacus:20150816232529p:plain

 

同様にShift+1でドライブCとドライブDのメニューを表示させて選べるようにするには

f:id:tablacus:20150816232659p:plain

キー欄がメニューに表示される名前になります。

f:id:tablacus:20150816232721p:plain

英数字の前に「&」を入れると、メニューを表示している時に前の文字を押すだけで実行できるようになります。

f:id:tablacus:20150816232815p:plain

最後にタイプを「メニュー」にし、オプションを「閉じる」にするとそこまでがメニューになります。

f:id:tablacus:20150816233226p:plain

ちょっとしたスクリプト - Tablacus Explorer

某所で要望のあったスクリプトを3つ書いてみました。

・フォルダ構成のみクリップボードにコピー

var CreateFolderOnly2 = function (path, dest, Items, nAdd)
{
  api.SetWindowText(te.hwnd, path);
  CreateFolder(dest);
  if (nAdd == 0) {
    Items.AddItem(dest);
  }
  var wfd = api.Memory("WIN32_FIND_DATA");
  var hFind = api.FindFirstFile(path + "\\*", wfd);
  var bFind = hFind != INVALID_HANDLE_VALUE;
  while (bFind) {
    if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
      var fn = wfd.cFileName;
      if (fn != "." && fn != "..") {
        CreateFolderOnly2(fso.BuildPath(path, fn), fso.BuildPath(dest, fn), Items, nAdd - 1);
      }
    }
    bFind = api.FindNextFile(hFind, wfd);
  }
  api.FindClose(hFind);
};

var CreateFolderOnly = function (Item, Items, temp, nAdd)
{
  var path = api.GetDisplayNameOf(Item, SHGDN_FORPARSING);
  if (/^[A-Z]:\\|^\\/i.test(path)) {
    var fn = fso.GetFileName(path);
    if (fn && fso.FolderExists(path)) {
      var dest = fso.BuildPath(temp, fn);
      CreateFolderOnly2(path, dest, Items, nAdd);
    }
  }
};

var title = api.GetWindowText(te.hwnd);
var temp = fso.BuildPath(fso.GetSpecialFolder(2).Path, "tablacus");
if (!IsExists(temp)) {
  CreateFolder(temp);
}
temp += "\\folder";
DeleteItem(temp);
CreateFolder(temp);

var FV = GetFolderView(Ctrl, pt);
var Items = te.FolderItems();
var Selected = FV.SelectedItems();
if (Selected) {
  for (var i = 0; i < Selected.Count; i++) {
    CreateFolderOnly(Selected.Item(i), Items, temp, 0);
  }
}
if (Items.Count == 0) {
  CreateFolderOnly(FV, Items, temp, 1);
}
api.OleSetClipboard(Items);
api.SetWindowText(te.hwnd, title);

f:id:tablacus:20150714222903p:plain

長いしフォルダがたくさんあると時間が掛るので、WSHにするとか、アドオンにしてマルチプロセスにする方が良さそうな感じですが…

 

1階層上に送る

var FV = GetFolderView(Ctrl, pt);
var Selected = FV.SelectedItems();
if (Selected) {
    var oDest = sha.NameSpace(fso.GetParentFolderName(api.GetDisplayNameOf(FV, SHGDN_FORPARSING)));
    if (oDest) {
        oDest.MoveHere(Selected, FOF_ALLOWUNDO);
    }
}

f:id:tablacus:20150714223605p:plain

 

・1階層下から吸い出す

 

var FV = GetFolderView(Ctrl, pt);
var path = OpenDialog(fso.GetParentFolderName(api.GetDisplayNameOf(FV, SHGDN_FORPARSING)));
if (path) {
    FV.Folder.MoveHere(path, FOF_ALLOWUNDO);
}

f:id:tablacus:20150714224256p:plain