カタバミさんのプログラミングノート

日曜プログラマーがプログラミング関係のメモを記録するブログです。

C#でIEnumStringインターフェイスを実装する

C#でIEnumStringインターフェイスを実装するには、System.Runtime.InteropServices.COMTypes名前空間で定義されたC#のIEnumStringインターフェイスが利用できます。このインターフェイスを継承したクラスを実装することでCOMのIEnumStringインターフェイスを実装することができます。

IAutoCompleteインターフェイスを利用する場合はIEnumStringインターフェイスの実装が必要となりますが、上記の方法で実現することができます。

GitHubのサンプルプロジェクトリポジトリ github.com

IEnumString - ReferenceSource (Microsoft) - GitHub github.com

IShellItem.BindToHandler関数のBHID_StorageEnumとBHID_EnumItemsの違い

IShellItem.BindToHandler関数の引数にBHID_StorageEnumとBHID_EnumItemsを指定した場合、以下の点が異なります。

BHID 概要
BHID_StorageEnum 作成されたIEnumShellItemsはファイルシステムオブジェクトのみ列挙する。
BHID_EnumItems 作成されたIEnumShellItemsはファイルシステムオブジェクトと特殊オブジェクトを列挙する。

実際の取得例を改変したものを下記に示します。斜線は環境により名前が異なるものです。なお、USB接続したスマートフォンはUSBストレージではなく、メーカーの提供するドライバにより特殊なフォルダとして扱われるものです。

BHID 出力例
BHID_StorageEnum Cドライブの名前 (C:)
Dドライブの名前 (D:)
BHID_EnumItems Cドライブの名前 (C:)
Dドライブの名前 (D:)
USB接続したスマートフォン
ダウンロード
3D オブジェクト
ピクチャ
ミュージック
デスクトップ
ドキュメント
ビデオ

C#によるサンプルプロジェクトのリポジトリ github.com

WindowsのCOM関係レジストリキーの場所

WindowsのCOM関係のレジストリキーは次の場所に存在します。

ProgID、CLSID、Interfaceキー等

  1. HKEY_LOCAL_MACHINE\Software\Classes
  2. HKEY_CURRENT_USER\Software\Classes
  3. HKEY_CLASSES_ROOT

docs.microsoft.com

基本情報

  1. HKEY_CURRENT_USER\Software\Microsoft\Ole
  2. HKEY_LOCAL_MACHINE\Software\Microsoft\Ole

docs.microsoft.com

DebugObjectRPCEnabledキー

  1. HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion
  2. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion

docs.microsoft.com

ノート

  • レジストリを操作する場合はプロジェクトのビット数に注意してください。32ビットアプリケーションの場合、64ビットで登録された一部の情報を取得できない場合があります。
  • 各キーの違いについてはこちらのページをご覧ください。

参考

docs.microsoft.com

HKEY_LOCAL_MACHINE、HKEY_CURRENT_USER、HKEY_CLASSES_ROOT

本文

HKEY_LOCAL_MACHINE、HKEY_CURRENT_USER、HKEY_CLASSES_ROOTは何れもレジストリのルートキーとして扱われる定義済みキー(Predefined Keys)ですが、その内容はログインするユーザーにより異なります。HKEY_LOCAL_MACHINEはどのユーザーでログインしても同じキーですが、HKEY_CURRENT_USERはログインするユーザー毎に割り当てられており、HKEY_CLASSES_ROOTはHKEY_CURRENT_USER\Software\ClassesとHKEY_LOCAL_MACHINE\Software\Classesがマージされたキーです。詳細はリンク先のMicrosoft Docsをご覧ください。

参考

Predefined Key 概要 実体 ユーザー依存
HKEY_LOCAL_MACHINE ローカルコンピューターのレジストリ情報 HKEY_LOCAL_MACHINE なし
HKEY_CURRENT_USER 現在のログインユーザーのレジストリ情報 HKEY_USERS\Security ID (SID) あり
HKEY_CLASSES_ROOT HKEY_CURRENT_USER\Software\ClassesとHKEY_LOCAL_MACHINE\Software\Classesのマージ あり

docs.microsoft.com docs.microsoft.com docs.microsoft.com

JavaScriptのevent.targetとevent.currentTargetの違い

event.targetとevent.currentTargetの値は一般的に異なります。例えば以下のサンプルコードを実行すると次の表が得られます。ボタン2と3はどちらもA要素の子要素です。

クリックした場所 event.target event.currentTarget
ボタン1 ボタン1 ボタン1
ボタン2 ボタン2 A要素
ボタン3 ボタン3 A要素
A要素 A要素 A要素
クリックした場所 実際に押された要素 onclickイベントを持つ要素

通常(event.targetなどを使用しない)であればどちらを使用しても問題は起きませんが、クリックされた要素のカスタム属性を使用するためにgetAttribute関数を使う場合などはバグの原因となるので注意が必要です。

サンプルコード
(※Vue.jsで詰まったのでVue.jsを使っていますが、onclickに記述しても同様です)

<html lang="ja">
    <head>
        <meta charset="utf-8">
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <title></title>
    </head>
    <body style="padding:.5rem">
        <div id="app1">
            <button @click="click">ボタン1</button>
            <a @click="click" style="border:1px solid black; padding:.5rem;">
                <button>ボタン2</button>
                <button>ボタン3</button>
            </a>
        </div>
        <script>
            var app1 = new Vue({
                el: "#app1",
                methods: {
                    click: function(event) {
                       let s = "";
                       s += "target:"+event.target.constructor.name+" "+event.target.innerText;
                       s += ", ";
                       s += "currentTarget:"+event.currentTarget.constructor.name+" "+event.currentTarget.innerText;
                       console.log(s);
                    }
                }
            });
        </script>
    </body>
</html>

参考 developer.mozilla.org developer.mozilla.org