質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.33%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Q&A

解決済

1回答

295閲覧

[C#] クリップボードの操作、貼り付けがうまくいかない。

yukkuri_55

総合スコア271

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

0グッド

1クリップ

投稿2025/01/28 19:58

実現したいこと

ウィンドウフォームにあるテキストをコピーして、それを別のアプリ(例えばメモ帳)に張り付ける
方法を知りたい。

発生している問題・分からないこと

クリップボードにコピーはできていると思います。
しかし、別のアプリに張り付けしようとしても、別のアプリ(ここではメモ帳)に反応がありません。

該当のソースコード

cs

1namespace WinFormsApp1_2025_01_29_クリップボード 2{ 3 internal static class Program 4 { 5 /// <summary> 6 /// The main entry point for the application. 7 /// </summary> 8 [STAThread] 9 static void Main() 10 { 11 // To customize application configuration such as set high DPI settings or default font, 12 // see https://aka.ms/applicationconfiguration. 13 ApplicationConfiguration.Initialize(); 14 Form1 form1 = new Form1(); 15 Application.Run(form1); 16 } 17 } 18} 19

cs

1using System.Diagnostics; 2using System.Runtime.InteropServices; 3 4namespace WinFormsApp1_2025_01_29_クリップボード 5{ 6 public partial class Form1 : Form 7 { 8 // Win32 APIのインポート 9 [DllImport("user32.dll", SetLastError = true)] 10 public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 11 12 [DllImport("user32.dll", SetLastError = true)] 13 public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 14 15 [DllImport("user32.dll", SetLastError = true)] 16 public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); 17 18 const int WM_PASTE = 0x0302; // WM_PASTEメッセージ 19 20 21 private TextBox textBox1 = new TextBox(); 22 private TextBox textBox2 = new TextBox(); 23 private Button copyButton = new Button(); 24 private Button pasteButton = new Button(); 25 26 public Form1() 27 { 28 InitializeComponent(); 29 30 copyButton.Text = "コピー"; 31 copyButton.Click += (sender, e) => CopyToClipboard(textBox1.Text); 32 33 pasteButton.Text = "貼り付け"; 34 pasteButton.Click += (sender, e) => textBox2.Text = PasteFromClipboard(); 35 36 Controls.Add(textBox1); 37 Controls.Add(copyButton); 38 Controls.Add(pasteButton); 39 Controls.Add(textBox2); 40 41 textBox1.SetBounds(0, 0, 100, 100); 42 copyButton.SetBounds(0, 100, 100, 100); 43 textBox2.SetBounds(0, 200, 100, 100); 44 pasteButton.SetBounds(0, 300, 100, 100); 45 } 46 47 private void Form1_Load(object sender, EventArgs e) 48 { 49 50 } 51 52 53 54 public void CopyToClipboard(string text) 55 { 56 if ( text != null ) 57 Clipboard.SetText(text); 58 59 // メモ帳を起動 60 Process notepad = new Process(); 61 notepad.StartInfo.FileName = "notepad.exe"; 62 notepad.Start(); 63 64 // メモ帳が起動するのを待つ 65 notepad.WaitForInputIdle(); 66 67 68 // メモ帳のウィンドウハンドルを取得 69 IntPtr notepadHandle = FindWindow("Notepad", null); 70 if (notepadHandle != IntPtr.Zero) 71 { 72 // メモ帳に貼り付け 73 SendMessage(notepadHandle, WM_PASTE, IntPtr.Zero, IntPtr.Zero); 74 // (しかし、メモ帳に反応なし) 75 } 76 } 77 public string PasteFromClipboard() 78 { 79 Debug.WriteLine(Clipboard.GetText()); 80 return Clipboard.GetText(); 81 } 82 83 public void PasteToActiveWindow() 84 { 85// SendKeys.SendWait("^v"); 86 } 87 } 88 89} 90

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

AIに聞いてみたところ、プロセスを取得する方法を提示されたので、やってみましたが、
うまくいきません。
メモ帳は起動するので、// メモ帳を起動 のところはうまくいってます。
しかし、貼り付けを SendMessage()関数で実現しようとしても、反応がありません。

補足

OS: Windows 11 pro
言語: C#
FW: Windows Form
IDE: Visual Studio 2022 Community
動作を想定するのは、Windows 環境だけでいいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOZ6.0

2025/01/28 23:45

メッセージを送るべきウインドウは、メインウインドウではないかもしれません。 spy++ をインストールし、メモ帳のウインドウがどうなっているか確認してください。 「Visual Studio 2022に Spy++をインストールする手順」 https://windev.just4fun.biz/?VS/Visual+Studio+2022%E3%81%AB+Spy%2B%2B%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%89%8B%E9%A0%86 「Spy++でアプリケーション操作に必要な情報を調べる」 https://t-pirori.blogspot.com/2022/02/spy.html
TN8001

2025/01/29 10:15

新しい(タブ化された)メモ帳なのか古いメモ帳かでも変わってきますし、そもそも自身が起動したメモ帳に張り付けるのがやりたいことですか? 本当は起動中のほかのアプリや任意のアプリに、貼り付けたいのではありませんか? 対象をアクティブにしてSendKeysするほうが、まだましな気がします。
yukkuri_55

2025/01/29 18:51

>「Visual Studio 2022に Spy++をインストールする手順」 windows 11 の visual studio community 2022 には spy++ をインストールしようとしたのですが、 うまくいきませんでした。 >こちらの情報によると、「Edit」コントロール へメッセージを送信するようです 情報が欠けていてて、うまく実装することができませんでした。 >本当は起動中のほかのアプリや任意のアプリに、貼り付けたいのではありませんか? そうですね、他の起動しているアプリを選んで、送信できるのが理想ですね。 >対象をアクティブにしてSendKeysするほうが、まだましな気がします。 良い考えですね。参考にさせていただきました。
guest

回答1

0

自己解決

アクティブにして、送信するというアイデアを使わせていただきました。
現在のアプリケーション一覧を取得し、ウィンドウのタイトルをもとに、
プロセスハンドルを取得し、そのプロセスハンドルをアクティブにして、
貼り付けを送信する という手順で期待していたものができました。

色々追加する予定ですが、基礎部分はできました。
解決しました。ありがとうございました。

以下が、基礎部分のソースコードになります。

cs

1using System; 2using System.Diagnostics; 3using System.Runtime.InteropServices; 4 5namespace WinFormsApp1_2025_01_29_クリップボード 6{ 7 public partial class Form1 : Form 8 { 9 // Win32 APIのインポート 10 [DllImport("user32.dll", SetLastError = true)] 11 public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 12 13 [DllImport("user32.dll", SetLastError = true)] 14 public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 15 16 [DllImport("user32.dll", SetLastError = true)] 17 public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); 18 19 const int WM_PASTE = 0x0302; // WM_PASTEメッセージ 20 21 [DllImport("user32.dll")] 22 [return: MarshalAs(UnmanagedType.Bool)] 23 private static extern bool SetForegroundWindow(IntPtr hWnd); 24 25 26 public const int WM_CHAR = 0x0102; 27 28 29 private TextBox textBox1 = new TextBox(); 30 private TextBox textBox2 = new TextBox(); 31 private Button copyButton = new Button(); 32 private Button pasteButton = new Button(); 33 34 private IntPtr selectedHandle; 35 36 private ComboBox comboBox1 = new ComboBox(); 37 38 public Form1() 39 { 40 InitializeComponent(); 41 42 copyButton.Text = "コピー"; 43 copyButton.Click += (sender, e) => CopyToClipboard(textBox1.Text); 44 45 pasteButton.Text = "貼り付け"; 46 pasteButton.Click += (sender, e) => textBox2.Text = PasteFromClipboard(); 47 48 Controls.Add(textBox1); 49 Controls.Add(copyButton); 50 Controls.Add(pasteButton); 51 Controls.Add(textBox2); 52 Controls.Add(comboBox1); 53 54 textBox1.SetBounds(0, 0, 100, 100); 55 copyButton.SetBounds(0, 100, 100, 100); 56 textBox2.SetBounds(0, 200, 100, 100); 57 pasteButton.SetBounds(0, 300, 100, 100); 58 59 textBox1.Text = "Hello World"; 60 61 comboBox1.Items.Add(new string("ウィンドウのタイトル一覧")); 62 comboBox1.SetBounds(200, 0, 200, 100); 63 } 64 65 private void Form1_Load(object sender, EventArgs e) 66 { 67 68 } 69 70 71 72 public void CopyToClipboard(string text) 73 { 74 if (text != null) 75 Clipboard.SetText(text); 76 77 comboBox1.Items.Clear(); 78 79 // 実行中のプロセスを取得 80 Process[] processList = Process.GetProcesses(); 81 82 // 各プロセスの名前とIDを表示 83 Debug.WriteLine("実行中のアプリケーション一覧:"); 84 foreach (Process process in processList) 85 { 86 try 87 { 88 // プロセス名とプロセスIDを表示 89 Debug.WriteLine($"プロセス名: {process.ProcessName}, プロセスID: {process.Id}, ウィンドウ名:{process.MainWindowTitle}"); 90 91 if(!string.IsNullOrEmpty(process.MainWindowTitle)) 92 { 93 comboBox1.Items.Add( process.MainWindowTitle); 94 } 95 } 96 catch (Exception ex) 97 { 98 // プロセス情報の取得に失敗した場合のエラーハンドリング 99 Debug.WriteLine($"エラー: {ex.Message}"); 100 } 101 102 } 103 104 } 105 106 107 public string PasteFromClipboard() 108 { 109 string? selectedProcessName = comboBox1.SelectedItem?.ToString(); 110 111 Process[] processList = Process.GetProcesses(); 112 foreach (Process process in processList) 113 { 114 try 115 { 116 if (process.MainWindowTitle == selectedProcessName) 117 { 118 selectedHandle = process.MainWindowHandle; 119 } 120 } 121 catch (Exception ex) 122 { 123 // プロセス情報の取得に失敗した場合のエラーハンドリング 124 Debug.WriteLine($"エラー: {ex.Message}"); 125 } 126 } 127 128 Debug.WriteLine(Clipboard.GetText()); 129 Debug.WriteLine($"selectedProcessName:{selectedProcessName}"); 130 Debug.WriteLine($"selectedProcessHandle:{selectedHandle}"); 131 SetForegroundWindow(selectedHandle); 132 SendKeys.SendWait("^v"); 133 return Clipboard.GetText(); 134 } 135 } 136 137}

投稿2025/01/29 18:48

yukkuri_55

総合スコア271

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.33%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問