*

MFCプログラミング(2):コピー機能の実装

公開日: : C++, MFC, Windows, 開発

どもです。
前回に引き続き、今回もMFCネタです。
内容は、MFCでの「クリップボードへのデータの書き込み」についてです。

1.背景(簡単に)

入力内容を「Ctrl + c」でクリップボードに設定する際の処理でハマりました。
ネットで調べてみると、まぁ~たくさん情報が出てきます。
それらの情報を十分に吟味/検討せずに、そのまま使用してしまったのがハマった原因です。

2.内容

コピー処理を、1つのコマンドとして実装するために、対応する処理を持つ1つのクラスを定義しました。
そのクラスの中でクリップボードにデータを設定する、ということを行いました。
すると、クリップボードに設定したデータを別のアプリケーション(テキストエディタ、など)に貼り付けることができない、という現象が発生しました。

クリップボードにデータを設定するためには、以下の手順を取ります。
Step 1:クリップボードに貼り付けるデータを、グローバルブロックに設定する。
Step 2:クリップボードを開く
Step 3:クリップボードにデータを渡す
Step 4:クリップボードを閉じる

各Stepで使用する関数については、ネットで調べてみてください。
「mfc クリップボード」などで検索すると、たくさん情報が得られます。
このとき、各ステップにおいて戻り値を確認、エラーがない場合でも問題の現象が発生します。
(…問題の現象が発生している際のコードが残っていないので、具体的な実装を提示できません。ごめんなさい。)

検討段階において、CDialogクラスにボタンを貼り付け、このボタンのクリックイベントハンドラの中で同じ処理を行った場合には、問題なく動作していました。

3.原因

調べてみたところ、原因はクリップボードを開く際に使用する関数のようです。
クリップボードを開く際には、「OpenClipboard()」を使用します。
この関数は、MSDNでは下記のように定義されています。

MSDN
しかし、この関数ですが、CWndクラスでも定義されており、その定義は下記の通りです。

MSDN
多くのサンプルは、多くの場合は下側の関数を使用していました。
また、検討段階では、こちらの関数を使用していました。
あるいは、上側の関数を使用していたとしても、引数にはNULLを指定していました。
この「NULLを指定」していたことが、原因の様です。

OpenClipboard()の引数にNULLを指定した場合、処理の上では特にエラーは発生しません。
また、引数にNULLを指定してクリップボードを開いた場合、クリップボードは現在のタスクと関連付けられます。
そうした状態で開いたクリップボードに書き込んだデータは、どうやら他のアプリケーションからは参照できない様です。
(ソースコードの内容まで追えていないので、本当に正確かはわかりません。)

4.対策

対策は、実に簡単です。
OpenClipboard()関数の引数に、適切な値を設定することです。
では、「適切な値」とは何か、ですが、これも実は簡単です。
CWndクラスのOpenClipboard()関数は、下記のように定義されています。

つまり、OpenClipboard()関数に、現在のウィンドウのハンドルを指定すればよい、ということになります。
この対策を施した、具体的な実装は下記のようになるかと思います。

5.貼り付けの場合は?

本エントリのタイトルからは少し離れた内容になりますが、「貼り付け」処理の話になります。
貼り付け、即ちクリップボードからデータを取得する際にも、OpenClipboard()メソッドを使用してクリップボードを開く必要があります。
その時にも、コピー処理時と同様でOpenClipboard()の引数に現在のウィンドウのハンドルを指定します。
これで、ほかのアプリケーションでクリップボードに貼り付けたデータを取得することができます。

6.まとめ

今回は、MFCでクリップボードにデータを設定する際の処理でハマった点を書きました。
クリップボードにアクセスする処理をCWndを継承していないクラスで行う場合、処理を行うクラスを保持するダイアログのウィンドウのハンドラを指定してクリップボードを開く必要があります。

コピー機能を1つのコマンド/クラスで実装する場合には、このウィンドウのハンドルを(面倒くさがらず)必ず指定するようにしましょう、という話でした。

ではっ!

関連記事

no image

C言語でEV3開発(4)

どもです。 今回のエントリーは、前回のエントリー内容/EclipseでEV3の実行ファイルをビルド

記事を読む

iot_at_home_eye_catch

IoT開発(14)
ESP-WROOM-02の稼働時間を延ばす工夫をしてみる

どもです。この記事は、以下の続きです。 IoT開発(4)-ESP-WROOM-02を電池で駆動

記事を読む

raspberry-pi

ライブラリでRasPiのピンにアクセス(3)-SPIのインターフェース追加(その2)

どもです。 今回のエントリも、前回に引き続き、RaspberryPiのピンをより簡便に使用でき

記事を読む

no image

Windows-QtCreatorでのデバッグ

どもです。 更新の間隔が空いてしまいました。 久しぶりの更新です。 最近、Qtを触り始めま

記事を読む

raspberry-pi

ライブラリでRasPiのピンにアクセス(1)-ライブラリを作ります

どもです。 これまでこのブログでは、RaspberryPiのGPIOとかSPIを使用したアプリ

記事を読む

GitHub

Windowsでのカバレッジ測定-OpenCppCoverageを使ってみた(2)

どもです。 前回のエントリーで、OpenCppCoverageというカバレッジを測定する、フリーの

記事を読む

eclipse_oxygen

Linux/EclipseでRaspberryPiのクロス環境を構築してみた…がっ!

どもです。 前回のエントリでは、WindowsにRaspberryPi3のクロスコンパイル環境の構

記事を読む

raspberry-pi

ライブラリでRasPiのピンにアクセス(3)-割り込み対応

どもです。 少し間が空いてしまいましたが、RaspberryPiのピンをより簡便に使用するため

記事を読む

no image

C言語でEV3開発(14)-opOUTPUT_TIME_SPEEDコマンド

どもです。 今回のエントリーは、モーターを動かすコマンドである「opOUTPUT_TIME_SPE

記事を読む

MY_MFC_LOGO

MFCプログラミング(4):Enter(ESC)キーでダイアログが閉じないようにする

どもです。 今回は、キーボード入力の処理、特にEnterキー/ESCキーでダイアログが閉じられるこ

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

arduino_relay_switch_002_ae_g5v_drv_eye_catch
Arduinoでリレースイッチ(2)-AE-G5V-DRV

どもです。 前回の記事では、「フォトカプラリレー」を使用したLチ

tlp222af_001_eye_catch
Arduinoでリレースイッチ(1)-TLP222AF

どもです。 つい先日、やっとのことでリレースイッチを手に入れるこ

c_sharp_eye_catch
外部からMariaDbにアクセスする(2)-C#からMariaDbにアクセスする。

どもです。 前回のエントリで、外部からMariaDbにアクセスす

c_sharp_eye_catch
外部からMariaDbにアクセスする(1)-データベースの設定

どもです。 今回は、Linux上のMariaDbにWindows

think_about_utest
middle_unit
最小…よりも(ほんの)少し大きいテストフレームワーク

どもです。 今回は、単体テストのフレームワークについて書きます。

→もっと見る

PAGE TOP ↑