teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

解決した回答の記入

2019/02/22 13:59

投稿

退会済みユーザー
answer CHANGED
@@ -1,3 +1,127 @@
1
- 自分できちんとてからもう一度質問しす。
1
+ 自分にて行錯誤したところ、windowメッセージを取得することで欲し機能を実装ることができました
2
2
 
3
+ 下記に実装したコードを記しておきます。
4
+ ```C#
5
+ class test : EditorWindow
6
+ {
7
+ [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
8
+ private static extern int SetWindowLong32(HandleRef hWnd, int nIndex, int dwNewLong);
9
+ [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
10
+ private static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, IntPtr dwNewLong);
11
+
12
+
13
+
14
+ [DllImport("user32.dll", EntryPoint = "DefWindowProcA")]
15
+ private static extern IntPtr DefWindowProc(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
16
+
17
+ [DllImport("user32.dll")]
18
+ private static extern System.IntPtr GetActiveWindow();
19
+
20
+ private HandleRef hMainWindow;
21
+ private IntPtr oldWndProcPtr;
22
+ private IntPtr newWndProcPtr;
23
+ private WndProcDelegate newWndProc;
24
+
25
+ // P/Invokeの定義 (pinvoke.net参照)
26
+ public static IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, IntPtr dwNewLong)
27
+ {
28
+ if (IntPtr.Size == 8)
29
+ return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
30
+ else
31
+ {
32
+ return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
33
+ }
34
+ }
35
+
36
+ const int WM_DEVICECHANGE = 0x0219;
37
+
38
+ [StructLayout(LayoutKind.Sequential)]
39
+ struct DEV_BROADCAST_VOLUME
40
+ {
41
+ public uint dbch_Size;
42
+ public uint dbch_Devicetype;
43
+ public uint dbch_Reserved;
44
+ public uint dbch_Unitmask;
45
+ public ushort dbch_Flags;
46
+ }
47
+
48
+ private IntPtr wndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
49
+ {
50
+ if (msg == WM_DEVICECHANGE)
51
+ {
52
+ switch ((int)wParam)
53
+ {
54
+ case 0x8000:
55
+ Debug.Log("デバイスが挿入され利用可能になりました。");
56
+ DEV_BROADCAST_VOLUME device = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_VOLUME));
57
+ uint deviceNum = device.dbch_Unitmask;
58
+ char deviceLet = (char)0;
59
+ for (int i = 0;i < 26; i++)
60
+ {
61
+ if (deviceNum == 0x01) deviceLet = (char)(i + 0x41);
62
+ deviceNum >>= 1;
63
+ }
64
+ Debug.Log(deviceLet.ToString());
65
+
66
+ break;
67
+ case 0x0007:
68
+ //Debug.Log("デバイスが追加または削除されました。");
69
+ break;
70
+ case 0x8004:
71
+ //Debug.Log("デバイスが削除されました。");
72
+ break;
73
+ default:
74
+ //Debug.Log("wndProc msg:0x" + msg.ToString("x4") + " wParam:0x" + wParam.ToString("x4") + " lParam:0x" + lParam.ToString("x4"));
75
+ break;
76
+ }
77
+
78
+ }
79
+ return DefWindowProc(hWnd, msg, wParam, lParam);
80
+ }
81
+
82
+ /// 終了
83
+ ~test()
84
+ {
85
+ Term();
86
+ }
87
+
88
+ /// 初期化(EditorWindowをShowした後にコール)
89
+ public void Init()
90
+ {
91
+ // ウインドウプロシージャをフックする
92
+ hMainWindow = new HandleRef(null, GetActiveWindow());
93
+ newWndProc = new WndProcDelegate(wndProc);
94
+ newWndProcPtr = Marshal.GetFunctionPointerForDelegate(newWndProc);
95
+ oldWndProcPtr = SetWindowLongPtr(hMainWindow, -4, newWndProcPtr);
96
+
97
+ }
98
+ public void Term()
99
+ {
100
+ SetWindowLongPtr(hMainWindow, -4, oldWndProcPtr);
101
+ hMainWindow = new HandleRef(null, IntPtr.Zero);
102
+ oldWndProcPtr = IntPtr.Zero;
103
+ newWndProcPtr = IntPtr.Zero;
104
+ newWndProc = null;
105
+ }
106
+
107
+ void OnGUI()
108
+ {
109
+ // ウィンドウハンドルが切り替わったので初期化
110
+ if (hMainWindow.Handle == IntPtr.Zero)
111
+ {
112
+ Init();
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ 上記のようにクラスを宣言し、Start関数内で下記のように呼ぶとウィンドウメッセージを取得できました。
3
- お騒がせしました。
119
+ 私の力不足でお騒がせしました。
120
+
121
+ ```c#
122
+ void Start()
123
+ {
124
+ parent = ScriptableObject.CreateInstance<test>();
125
+ parent.Init();
126
+ }
127
+ ```