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

回答編集履歴

1

見直しキャンペーン中

2023/07/21 10:32

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,227 +1,226 @@
1
- 「文字入力支援君」はradianさんの言うようにおそらく、
2
- 1. 対象アプリをアクティブ化
3
- 1. クリップボードに文字をコピー
4
- 1. Ctrl+Vを送る
5
-
6
- という動作をしています。
7
-
8
- 対象アプリがアクティブ化したときにカーソルがない(ボタン等にフォーカスがある)と貼り付けられないので、特に入力エリアを探したりはしていなそうです(特定アプリに特別対応があるかもしれませんが)
9
-
10
- 最低限動作確認できるサンプルを作りました。
11
- ##### 使い方
12
- 1. 支援君のようにピンクの四角を対象アプリにドラッグ&ドロップ
13
- 1. テキストボックスに何か入力
14
- 1. 貼り付けボタンを押す
15
-
16
- ##### 注意
17
- * エラーチェック一切なし
18
- * Word・Excelは手元にないので未確認
19
-
20
- Form1.cs
21
- ```C#
22
- using System;
23
- using System.Drawing;
24
- using System.Runtime.InteropServices;
25
- using System.Text;
26
- using System.Windows.Forms;
27
-
28
- namespace Questions252432
29
- {
30
- public partial class Form1 : Form
31
- {
32
- private IntPtr hWnd;
33
-
34
- public Form1() => InitializeComponent();
35
-
36
- private void Panel1_MouseDown(object sender, MouseEventArgs e)
37
- {
38
- if(e.Button == MouseButtons.Left) panel1.Capture = true;
39
- }
40
-
41
- private void Panel1_MouseUp(object sender, MouseEventArgs e)
42
- {
43
- panel1.Capture = false;
44
- var p = NativeMethods.GetCursorPos();
45
- var h = NativeMethods.WindowFromPoint(p);
46
- hWnd = NativeMethods.GetAncestor(h);
47
-
48
- label_title.Text = $"Title: {NativeMethods.GetWindowText(hWnd)}";
49
- label_class.Text = $"Class: {NativeMethods.GetClassName(hWnd)}";
50
- }
51
-
52
- private void Button1_Click(object sender, EventArgs e)
53
- {
54
- Clipboard.SetText(textBox1.Text);
55
- NativeMethods.SetForegroundWindow(hWnd);
56
- SendKeys.Send("^v");
57
- }
58
-
59
- private static class NativeMethods
60
- {
61
- [DllImport("user32")]
62
- private static extern bool GetCursorPos(out Point pPoint);
63
- public static Point GetCursorPos()
64
- {
65
- GetCursorPos(out var p);
66
- return p;
67
- }
68
-
69
- [DllImport("user32")]
70
- public static extern IntPtr WindowFromPoint(Point point);
71
-
72
- [DllImport("user32")]
73
- private static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags);
74
- public static IntPtr GetAncestor(IntPtr hWnd) => GetAncestor(hWnd, GA_ROOTOWNER);
75
- private const uint GA_ROOTOWNER = 3;
76
-
77
- [DllImport("user32", CharSet = CharSet.Unicode)]
78
- private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
79
- public static string GetWindowText(IntPtr hWnd)
80
- {
81
- var sb = new StringBuilder(100);
82
- GetWindowText(hWnd, sb, sb.Capacity);
83
- return sb.ToString();
84
- }
85
-
86
- [DllImport("user32", CharSet = CharSet.Unicode)]
87
- private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
88
- public static string GetClassName(IntPtr hWnd)
89
- {
90
- var sb = new StringBuilder(100);
91
- GetClassName(hWnd, sb, sb.Capacity);
92
- return sb.ToString();
93
- }
94
-
95
- [DllImport("user32")]
96
- public static extern bool SetForegroundWindow(IntPtr hWnd);
97
- }
98
- }
99
- }
100
- ```
101
-
102
- Form1.Designer.cs
103
- ```C#
104
- namespace Questions252432
105
- {
106
- partial class Form1
107
- {
108
- /// <summary>
109
- /// 必要なデザイナー変数です。
110
- /// </summary>
111
- private System.ComponentModel.IContainer components = null;
112
-
113
- /// <summary>
114
- /// 使用中のリソースをすべてクリーンアップします。
115
- /// </summary>
116
- /// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
117
- protected override void Dispose(bool disposing)
118
- {
119
- if(disposing && (components != null))
120
- {
121
- components.Dispose();
122
- }
123
- base.Dispose(disposing);
124
- }
125
-
126
- #region Windows フォーム デザイナーで生成されたコード
127
-
128
- /// <summary>
129
- /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
130
- /// コード エディターで変更しないでください。
131
- /// </summary>
132
- private void InitializeComponent()
133
- {
134
- this.button1 = new System.Windows.Forms.Button();
135
- this.label_title = new System.Windows.Forms.Label();
136
- this.label_class = new System.Windows.Forms.Label();
137
- this.textBox1 = new System.Windows.Forms.TextBox();
138
- this.panel1 = new System.Windows.Forms.Panel();
139
- this.SuspendLayout();
140
- //
141
- // button1
142
- //
143
- this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
144
- this.button1.Location = new System.Drawing.Point(297, 222);
145
- this.button1.Name = "button1";
146
- this.button1.Size = new System.Drawing.Size(75, 23);
147
- this.button1.TabIndex = 0;
148
- this.button1.Text = "貼り付け";
149
- this.button1.UseVisualStyleBackColor = true;
150
- this.button1.Click += new System.EventHandler(this.Button1_Click);
151
- //
152
- // label_title
153
- //
154
- this.label_title.AutoSize = true;
155
- this.label_title.Location = new System.Drawing.Point(54, 16);
156
- this.label_title.Name = "label_title";
157
- this.label_title.Size = new System.Drawing.Size(30, 12);
158
- this.label_title.TabIndex = 1;
159
- this.label_title.Text = "Title:";
160
- //
161
- // label_class
162
- //
163
- this.label_class.AutoSize = true;
164
- this.label_class.Location = new System.Drawing.Point(54, 31);
165
- this.label_class.Name = "label_class";
166
- this.label_class.Size = new System.Drawing.Size(36, 12);
167
- this.label_class.TabIndex = 2;
168
- this.label_class.Text = "Class:";
169
- //
170
- // textBox1
171
- //
172
- this.textBox1.AcceptsReturn = true;
173
- this.textBox1.AcceptsTab = true;
174
- this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
175
- | System.Windows.Forms.AnchorStyles.Left)
176
- | System.Windows.Forms.AnchorStyles.Right)));
177
- this.textBox1.Location = new System.Drawing.Point(12, 54);
178
- this.textBox1.Multiline = true;
179
- this.textBox1.Name = "textBox1";
180
- this.textBox1.Size = new System.Drawing.Size(360, 162);
181
- this.textBox1.TabIndex = 3;
182
- //
183
- // panel1
184
- //
185
- this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));
186
- this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
187
- this.panel1.Cursor = System.Windows.Forms.Cursors.Cross;
188
- this.panel1.Location = new System.Drawing.Point(12, 12);
189
- this.panel1.Name = "panel1";
190
- this.panel1.Size = new System.Drawing.Size(36, 36);
191
- this.panel1.TabIndex = 4;
192
- this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Panel1_MouseDown);
193
- this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Panel1_MouseUp);
194
- //
195
- // Form1
196
- //
197
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
198
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
199
- this.ClientSize = new System.Drawing.Size(384, 257);
200
- this.Controls.Add(this.panel1);
201
- this.Controls.Add(this.textBox1);
202
- this.Controls.Add(this.label_class);
203
- this.Controls.Add(this.label_title);
204
- this.Controls.Add(this.button1);
205
- this.Name = "Form1";
206
- this.Text = "貼り付けくん";
207
- this.ResumeLayout(false);
208
- this.PerformLayout();
209
-
210
- }
211
-
212
- #endregion
213
-
214
- private System.Windows.Forms.Button button1;
215
- private System.Windows.Forms.Label label_title;
216
- private System.Windows.Forms.Label label_class;
217
- private System.Windows.Forms.TextBox textBox1;
218
- private System.Windows.Forms.Panel panel1;
219
- }
220
- }
221
- ```
222
- ![アプリ画像](ef407a57ef15943dd18b67c9f4791ffd.png)
223
-
224
- ---
225
-
226
- SendKeysは(SendInputも)文字列自体を送ることもできますが、明らかに遅いのと改行がアプリによってうまくいかない等なかなか難しいです。
1
+ 「文字入力支援君」はradianさんの言うようにおそらく、
2
+ 1. 対象アプリをアクティブ化
3
+ 1. クリップボードに文字をコピー
4
+ 1. Ctrl+Vを送る
5
+
6
+ という動作をしています。
7
+
8
+ 対象アプリがアクティブ化したときにカーソルがない(ボタン等にフォーカスがある)と貼り付けられないので、特に入力エリアを探したりはしていなそうです(特定アプリに特別対応があるかもしれませんが)
9
+
10
+ 最低限動作確認できるサンプルを作りました。
11
+ ##### 使い方
12
+ 1. 支援君のようにピンクの四角を対象アプリにドラッグ&ドロップ
13
+ 1. テキストボックスに何か入力
14
+ 1. 貼り付けボタンを押す
15
+
16
+ ##### 注意
17
+ * エラーチェック一切なし
18
+ * Word・Excelは手元にないので未確認
19
+
20
+ ```cs:Form1.cs
21
+ using System;
22
+ using System.Drawing;
23
+ using System.Runtime.InteropServices;
24
+ using System.Text;
25
+ using System.Windows.Forms;
26
+
27
+ namespace Questions252432
28
+ {
29
+ public partial class Form1 : Form
30
+ {
31
+ private IntPtr hWnd;
32
+
33
+ public Form1() => InitializeComponent();
34
+
35
+ private void Panel1_MouseDown(object sender, MouseEventArgs e)
36
+ {
37
+ if(e.Button == MouseButtons.Left) panel1.Capture = true;
38
+ }
39
+
40
+ private void Panel1_MouseUp(object sender, MouseEventArgs e)
41
+ {
42
+ panel1.Capture = false;
43
+ var p = NativeMethods.GetCursorPos();
44
+ var h = NativeMethods.WindowFromPoint(p);
45
+ hWnd = NativeMethods.GetAncestor(h);
46
+
47
+ label_title.Text = $"Title: {NativeMethods.GetWindowText(hWnd)}";
48
+ label_class.Text = $"Class: {NativeMethods.GetClassName(hWnd)}";
49
+ }
50
+
51
+ private void Button1_Click(object sender, EventArgs e)
52
+ {
53
+ Clipboard.SetText(textBox1.Text);
54
+ NativeMethods.SetForegroundWindow(hWnd);
55
+ SendKeys.Send("^v");
56
+ }
57
+
58
+ private static class NativeMethods
59
+ {
60
+ [DllImport("user32")]
61
+ private static extern bool GetCursorPos(out Point pPoint);
62
+ public static Point GetCursorPos()
63
+ {
64
+ GetCursorPos(out var p);
65
+ return p;
66
+ }
67
+
68
+ [DllImport("user32")]
69
+ public static extern IntPtr WindowFromPoint(Point point);
70
+
71
+ [DllImport("user32")]
72
+ private static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags);
73
+ public static IntPtr GetAncestor(IntPtr hWnd) => GetAncestor(hWnd, GA_ROOTOWNER);
74
+ private const uint GA_ROOTOWNER = 3;
75
+
76
+ [DllImport("user32", CharSet = CharSet.Unicode)]
77
+ private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
78
+ public static string GetWindowText(IntPtr hWnd)
79
+ {
80
+ var sb = new StringBuilder(100);
81
+ GetWindowText(hWnd, sb, sb.Capacity);
82
+ return sb.ToString();
83
+ }
84
+
85
+ [DllImport("user32", CharSet = CharSet.Unicode)]
86
+ private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
87
+ public static string GetClassName(IntPtr hWnd)
88
+ {
89
+ var sb = new StringBuilder(100);
90
+ GetClassName(hWnd, sb, sb.Capacity);
91
+ return sb.ToString();
92
+ }
93
+
94
+ [DllImport("user32")]
95
+ public static extern bool SetForegroundWindow(IntPtr hWnd);
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ```cs:Form1.Designer.cs
102
+ namespace Questions252432
103
+ {
104
+ partial class Form1
105
+ {
106
+ /// <summary>
107
+ /// 必要なデザイナー変数です。
108
+ /// </summary>
109
+ private System.ComponentModel.IContainer components = null;
110
+
111
+ /// <summary>
112
+ /// 使用中のリソースをすべてクリーンアップします。
113
+ /// </summary>
114
+ /// <param name="disposing">マネージド リソースを破棄る場合は true を指定、その他の場合は false を指定します。</param>
115
+ protected override void Dispose(bool disposing)
116
+ {
117
+ if(disposing && (components != null))
118
+ {
119
+ components.Dispose();
120
+ }
121
+ base.Dispose(disposing);
122
+ }
123
+
124
+ #region Windows フォーム デザイナーで生成されたコード
125
+
126
+ /// <summary>
127
+ /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
128
+ /// コード エディターで変更しないでください。
129
+ /// </summary>
130
+ private void InitializeComponent()
131
+ {
132
+ this.button1 = new System.Windows.Forms.Button();
133
+ this.label_title = new System.Windows.Forms.Label();
134
+ this.label_class = new System.Windows.Forms.Label();
135
+ this.textBox1 = new System.Windows.Forms.TextBox();
136
+ this.panel1 = new System.Windows.Forms.Panel();
137
+ this.SuspendLayout();
138
+ //
139
+ // button1
140
+ //
141
+ this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
142
+ this.button1.Location = new System.Drawing.Point(297, 222);
143
+ this.button1.Name = "button1";
144
+ this.button1.Size = new System.Drawing.Size(75, 23);
145
+ this.button1.TabIndex = 0;
146
+ this.button1.Text = "貼り付け";
147
+ this.button1.UseVisualStyleBackColor = true;
148
+ this.button1.Click += new System.EventHandler(this.Button1_Click);
149
+ //
150
+ // label_title
151
+ //
152
+ this.label_title.AutoSize = true;
153
+ this.label_title.Location = new System.Drawing.Point(54, 16);
154
+ this.label_title.Name = "label_title";
155
+ this.label_title.Size = new System.Drawing.Size(30, 12);
156
+ this.label_title.TabIndex = 1;
157
+ this.label_title.Text = "Title:";
158
+ //
159
+ // label_class
160
+ //
161
+ this.label_class.AutoSize = true;
162
+ this.label_class.Location = new System.Drawing.Point(54, 31);
163
+ this.label_class.Name = "label_class";
164
+ this.label_class.Size = new System.Drawing.Size(36, 12);
165
+ this.label_class.TabIndex = 2;
166
+ this.label_class.Text = "Class:";
167
+ //
168
+ // textBox1
169
+ //
170
+ this.textBox1.AcceptsReturn = true;
171
+ this.textBox1.AcceptsTab = true;
172
+ this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
173
+ | System.Windows.Forms.AnchorStyles.Left)
174
+ | System.Windows.Forms.AnchorStyles.Right)));
175
+ this.textBox1.Location = new System.Drawing.Point(12, 54);
176
+ this.textBox1.Multiline = true;
177
+ this.textBox1.Name = "textBox1";
178
+ this.textBox1.Size = new System.Drawing.Size(360, 162);
179
+ this.textBox1.TabIndex = 3;
180
+ //
181
+ // panel1
182
+ //
183
+ this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));
184
+ this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
185
+ this.panel1.Cursor = System.Windows.Forms.Cursors.Cross;
186
+ this.panel1.Location = new System.Drawing.Point(12, 12);
187
+ this.panel1.Name = "panel1";
188
+ this.panel1.Size = new System.Drawing.Size(36, 36);
189
+ this.panel1.TabIndex = 4;
190
+ this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Panel1_MouseDown);
191
+ this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Panel1_MouseUp);
192
+ //
193
+ // Form1
194
+ //
195
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
196
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
197
+ this.ClientSize = new System.Drawing.Size(384, 257);
198
+ this.Controls.Add(this.panel1);
199
+ this.Controls.Add(this.textBox1);
200
+ this.Controls.Add(this.label_class);
201
+ this.Controls.Add(this.label_title);
202
+ this.Controls.Add(this.button1);
203
+ this.Name = "Form1";
204
+ this.Text = "貼り付けくん";
205
+ this.ResumeLayout(false);
206
+ this.PerformLayout();
207
+
208
+ }
209
+
210
+ #endregion
211
+
212
+ private System.Windows.Forms.Button button1;
213
+ private System.Windows.Forms.Label label_title;
214
+ private System.Windows.Forms.Label label_class;
215
+ private System.Windows.Forms.TextBox textBox1;
216
+ private System.Windows.Forms.Panel panel1;
217
+ }
218
+ }
219
+ ```
220
+ ![アプリ画像](ef407a57ef15943dd18b67c9f4791ffd.png)
221
+
222
+ ---
223
+
224
+ `SendKeys`は(`SendInput`も)文字列自体を送ることもできますが、明らかに遅いのと改行がアプリによってうまくいかない等なかなか難しいです。
225
+
227
226
  クリップボードが汚れるのを許容できるなら、この方式のほうがいいと思います。