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

質問編集履歴

7

修正

2020/04/29 10:50

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
File without changes
body CHANGED
@@ -142,6 +142,9 @@
142
142
  public ClassApp WindowTitleList()
143
143
  {
144
144
  count = 1;
145
+ _hWndList = new ClassApp();
146
+ _hWndList.Interface = new InnerClass[1];
147
+
145
148
  EnumWindows(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero);
146
149
 
147
150
  return _hWndList;

6

リスト修正しました

2020/04/29 10:50

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
File without changes
body CHANGED
@@ -61,7 +61,7 @@
61
61
  このまま走らせても、「インデックスが配列の境界外」というエラーになってしまいます。
62
62
 
63
63
 
64
- '''VBA
64
+ ```VBA
65
65
  Sub Vba()
66
66
 
67
67
  Set DLL = New ExcelVbaExt.WindowWhnd

5

rev

2020/04/29 10:34

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
File without changes
body CHANGED
@@ -57,6 +57,22 @@
57
57
 
58
58
  #現在のコード
59
59
 
60
+ もちろん、呼び出しのエントリポイントの外にクラス宣言があり
61
+ このまま走らせても、「インデックスが配列の境界外」というエラーになってしまいます。
62
+
63
+
64
+ '''VBA
65
+ Sub Vba()
66
+
67
+ Set DLL = New ExcelVbaExt.WindowWhnd
68
+ Dim com As Variant
69
+ Set com = DLL.WindowTitleList
70
+ c = com.Interface
71
+
72
+ End Sub
73
+
74
+ ```
75
+
60
76
  ```C#
61
77
  using System;
62
78
  using System.Runtime.InteropServices;

4

rev

2020/04/29 09:34

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
File without changes
body CHANGED
@@ -52,4 +52,108 @@
52
52
  他の言語では、
53
53
  サンプル: "列挙(コールバック)時の情報を列挙後へ渡す"
54
54
  の例がありましたが、C#のソースがあれば紹介いただきたいです。
55
- [リンク内容](http://delfusa.main.jp/delfusafloor/archive/www.nifty.ne.jp_forum_fdelphi/samples/01094.html)
55
+ [リンク内容](http://delfusa.main.jp/delfusafloor/archive/www.nifty.ne.jp_forum_fdelphi/samples/01094.html)
56
+
57
+
58
+ #現在のコード
59
+
60
+ ```C#
61
+ using System;
62
+ using System.Runtime.InteropServices;
63
+ using System.Text;
64
+
65
+ namespace ExcelVbaExt
66
+ {
67
+ [ComVisible(true)]
68
+ [ClassInterface(ClassInterfaceType.AutoDual)]
69
+ public class InnerClass
70
+ {
71
+ public int WHnd;
72
+ public string APPName;
73
+ public int Left;
74
+ public int Top;
75
+ public int Right;
76
+ public int Bottom;
77
+ }
78
+
79
+ [ComVisible(true)]
80
+ [ClassInterface(ClassInterfaceType.AutoDual)]
81
+ public class ClassApp
82
+ {
83
+ public InnerClass[] Interface;
84
+ }
85
+
86
+ [ComVisible(true)]
87
+ [InterfaceType(ComInterfaceType.InterfaceIsDual)]
88
+ public interface IWindowWhnd
89
+ {
90
+ ClassApp WindowTitleList();
91
+ }
92
+
93
+ [ClassInterface(ClassInterfaceType.None)]
94
+ public class WindowWhnd : IWindowWhnd
95
+ {
96
+ public static ClassApp _hWndList = new ClassApp();
97
+ public static int count;
98
+
99
+ [DllImport("user32.dll")]
100
+ private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
101
+
102
+ [StructLayout(LayoutKind.Sequential)]
103
+ private struct RECT
104
+ {
105
+ public int left;
106
+ public int top;
107
+ public int right;
108
+ public int bottom;
109
+ }
110
+
111
+ [DllImport("user32.dll")]
112
+ [return: MarshalAs(UnmanagedType.Bool)]
113
+ private extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam);
114
+
115
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
116
+ private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
117
+
118
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
119
+ private static extern int GetWindowTextLength(IntPtr hWnd);
120
+
121
+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
122
+ private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
123
+
124
+ private delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam);
125
+
126
+ public ClassApp WindowTitleList()
127
+ {
128
+ count = 1;
129
+ EnumWindows(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero);
130
+
131
+ return _hWndList;
132
+ }
133
+
134
+ private static bool EnumWindowCallBack(IntPtr hWnd, IntPtr lparam)
135
+ {
136
+ int textLen = GetWindowTextLength(hWnd);
137
+ if (0 < textLen)
138
+ {
139
+ StringBuilder tsb = new StringBuilder(textLen + 1);
140
+ GetWindowText(hWnd, tsb, tsb.Capacity);
141
+
142
+ RECT rect;
143
+ bool flag = GetWindowRect(hWnd, out rect);
144
+
145
+ count += 1;
146
+ Array.Resize(ref _hWndList.Interface, count);
147
+ _hWndList.Interface[count] = new InnerClass();
148
+ _hWndList.Interface[count].WHnd = (int)hWnd;
149
+ _hWndList.Interface[count].APPName = tsb.ToString();
150
+ _hWndList.Interface[count].Left = rect.left;
151
+ _hWndList.Interface[count].Top = rect.top;
152
+ _hWndList.Interface[count].Right = rect.right;
153
+ _hWndList.Interface[count].Bottom = rect.bottom;
154
+ }
155
+ return true;
156
+ }
157
+ }
158
+ }
159
+ ```

3

rev

2020/04/29 09:31

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
File without changes
body CHANGED
@@ -32,7 +32,7 @@
32
32
  ```
33
33
 
34
34
  リストを見ると、コールバック関数を使っているのですが、
35
- main関数の戻り値は、常にBOOLしか戻ってこない状態で、
35
+ EnumWindows関数の戻り値は、常にBOOLしか戻ってこない状態で、
36
36
  取得したいハンドル名を、WINDOWSコンソールに吐き出されています。
37
37
 
38
38
  #知りたいこと

2

rev

2020/04/29 09:07

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
@@ -1,1 +1,1 @@
1
- C#でのウィンドウ名取得について
1
+ C#でのウィンドウ名取得について EnumWindows
body CHANGED
@@ -2,7 +2,7 @@
2
2
  C#でウィンドウのハンドルを取得する検討しています。
3
3
 
4
4
  参考ソース
5
- [リンク内容](https://docs.microsoft.com/ja-jp/dotnet/framework/interop/how-to-implement-callback-functions)
5
+ [EnumWindows](https://docs.microsoft.com/ja-jp/dotnet/framework/interop/how-to-implement-callback-functions)
6
6
 
7
7
 
8
8
  ```C#

1

初回

2020/04/29 09:06

投稿

yuujiMotoki
yuujiMotoki

スコア90

title CHANGED
File without changes
body CHANGED
@@ -4,25 +4,7 @@
4
4
  参考ソース
5
5
  [リンク内容](https://docs.microsoft.com/ja-jp/dotnet/framework/interop/how-to-implement-callback-functions)
6
6
 
7
- リストを見ると、コールバック関数を使っているのですが、
8
- main関数の戻り値は、常にBOOLしか戻ってこない状態で、
9
- 取得したいハンドル名を、WINDOWSコンソールに吐き出されています。
10
7
 
11
- #知りたいこと
12
-
13
- 最終的にはDLLとして、配列変数にして戻したいと思っています。
14
-
15
- 方法としては
16
-
17
- 1)コンソールの出力をテキストにして戻す
18
-  → DLLを呼ぶ側に解読するソースをつけないと行けないので、不細工です。
19
-
20
- 2)メインの外にグローバル配列変数を作る
21
-  → そもそも関数の戻り値として、DLLの呼び出し側に返信できるのか疑問。
22
-
23
- C#の使い方としては、もっとスマートな方法は無いものでしょうか?
24
-
25
-
26
8
  ```C#
27
9
  using System;
28
10
  using System.Runtime.InteropServices;
@@ -47,4 +29,27 @@
47
29
  return true;
48
30
  }
49
31
  }
50
- ```
32
+ ```
33
+
34
+ リストを見ると、コールバック関数を使っているのですが、
35
+ main関数の戻り値は、常にBOOLしか戻ってこない状態で、
36
+ 取得したいハンドル名を、WINDOWSコンソールに吐き出されています。
37
+
38
+ #知りたいこと
39
+
40
+ 最終的にはDLLとして、配列変数にして戻したいと思っています。
41
+
42
+ 方法としては
43
+
44
+ 1)コンソールの出力をテキストにして戻す
45
+  → DLLを呼ぶ側に解読するソースをつけないと行けないので、不細工です。
46
+
47
+ 2)メインの外にグローバル配列変数を作る
48
+  → そもそも関数の戻り値として、DLLの呼び出し側に返信できるのか疑問。
49
+
50
+ C#の使い方としては、もっとスマートな方法は無いものでしょうか?
51
+
52
+ 他の言語では、
53
+ サンプル: "列挙(コールバック)時の情報を列挙後へ渡す"
54
+ の例がありましたが、C#のソースがあれば紹介いただきたいです。
55
+ [リンク内容](http://delfusa.main.jp/delfusafloor/archive/www.nifty.ne.jp_forum_fdelphi/samples/01094.html)