VC++2008でクリップボードの監視を行いたい

このQ&Aのポイント
  • VC++2008 Express Editionを使用して、クリップボードの監視を行いたいです。
  • クリップボードにデータがコピーされる度に、クリップボードのデータを取得する機能を実装したいです。
  • クリップボード上のデータを消さずに新しいデータがコピーされたかどうかを判断したいです。
回答を見る
  • ベストアンサー

VC++2008 で クリップボードの監視を行いたい

いつもおせわになっております。 ただいま、Visual C++ 2008 Express Edition を使いまして、クリップボード拡張アプリを作っております。 実装したい機能として・・・  A.クリップボードにデータがコピーされる度に、クリップボードのデータを取得する。  B.ただし、クリップボード上のデータは消さない。 というものがあります。 この使用を実装するために、下記のようにデータ存在の有無をタイマーな どでポーリングすれば良いと考えました。 >IDataObject ^data = System::Windows::Forms::Clipboard::GetDataObject(); >pictureShowPicture->Image->Dispose(); >if(data->GetDataPresent(DataFormats::Bitmap) == true){ しかし、この方法だと、一回でもデータがクリップボードにコピーされると、その後もずっと「データが存在する」状態となってしまい、新しいデータが来たのかどうか判断が出来ません。 クリップボード上のデータを消せば、「データが存在しない」状態となり、次にデータがコピーされたことが分かるのですが、クリップボード上のデータは消さない実装としたいのです。 このため、下記のようにすれば問題が解決できると思いました。  1.何らかの方法でクリップボードにデータがコピーされたという通知を受け取る。  2.現在のデータが直前のデータと同じか異なるかを判断する。    (ポーリングしておいて、データが異なれば新規データと判断) 上記1,2について、実現方法をご存知の方は教えていただけませんでしょうか。 ちなみに、受け取りたいデータ形式は、ビットマップ形式画像およびテキスト形式です。 お忙しいところ恐縮ですが、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんばんは。  win32APIを呼び出して良ければ、こういった手段があります。  http://wisdom.sakura.ne.jp/system/winapi/win32/win92.html  以下は、クリップボードが変更される度に、メッセージボックスを出します。参考程度に。 //メンバ変数 private: HWND m_hWndNext; //自分をクリップボードビューワに登録 private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { this->m_hWndNext = ::SetClipboardViewer(static_cast<HWND>(this->Handle.ToPointer())); } //自分をクリップボードビューワから解除 private: System::Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e) { ::ChangeClipboardChain(static_cast<HWND>(this->Handle.ToPointer()), this->m_hWndNext); } //ウィンドウプロシージャのオーバーライド public: virtual System::Void WndProc(System::Windows::Forms::Message% m) override { switch(m.Msg) { //クリップボードが更新されると此処に飛び込んでくる case WM_DRAWCLIPBOARD: { //クリップボードを開く ::OpenClipboard(static_cast<HWND>(this->Handle.ToPointer())); //クリップボードフォーマットを総当りで調べて、何か見つかれば直に中断 HANDLE hClipboard = NULL; for(UINT uFormat = ::EnumClipboardFormats(0); uFormat != 0; uFormat = ::EnumClipboardFormats(uFormat)) { hClipboard = ::GetClipboardData(uFormat); //クリップボード内にデータを発見 if(hClipboard)break; } //クリップボードを閉じる ::CloseClipboard(); if(hClipboard != NULL) System::Windows::Forms::MessageBox::Show("クリップボードにデータが来ました"); ::SendMessage(this->m_hWndNext, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32()); } break; case WM_CHANGECBCHAIN: if(this->m_hWndNext == static_cast<HWND>(m.WParam.ToPointer())) this->m_hWndNext = static_cast<HWND>(m.LParam.ToPointer()); else if(this->m_hWndNext != NULL) ::SendMessage(this->m_hWndNext, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32()); break; } this->Form::WndProc(m); }

hase-kou
質問者

お礼

早速のご回答ありがとうございます。 さっそくやってみます。

hase-kou
質問者

補足

ご回答ありがとうございます。 さっそくやってみました。 結果は・・・・いちおう思っていたことが実現できました。 ありがとうございます。 若干、コードを変えたりしたので、その部分も含めて書いて置きます。 ***stdafx.h #include <windows.h> #pragma comment(lib, "user32.lib") //このライブラリを使うように指示。これがないとリンクしてくれない。 ***Form1.h private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { //クリップボードビュワーに登録。 this->m_hWndNext = ::SetClipboardViewer(static_cast<HWND>(this->Handle.ToPointer())); } public: virtual System::Void WndProc(System::Windows::Forms::Message% m) override { System::Windows::Forms::IDataObject ^data = System::Windows::Forms::Clipboard::GetDataObject(); this->Form::WndProc(m); //ここにおかないとエラーになる。なぜだろう??? switch(m.Msg) { case WM_DRAWCLIPBOARD: if(data->GetDataPresent(DataFormats::Bitmap) == true) { textHashCode->Text = data->GetHashCode().ToString(); pictureShowPicture->Image = (Image^)data->GetData(DataFormats::Bitmap); //フォルダの最後の文字を "\" にする。 if( textFolderDestination->Text[textFolderDestination->Text->Length - 1] != '\\'){ textFolderDestination->Text = textFolderDestination->Text + "\\"; } } pictureShowPicture->Image->Save(textFolderDestination->Text + textHashCode->Text + ".jpg"); ::SendMessage(this->m_hWndNext, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32()); break; case WM_CHANGECBCHAIN: if(this->m_hWndNext == static_cast<HWND>(m.WParam.ToPointer())){ this->m_hWndNext = static_cast<HWND>(m.LParam.ToPointer()); } else if(this->m_hWndNext != NULL){ ::SendMessage(this->m_hWndNext, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32()); } break; } }

関連するQ&A

  • コンソールアプリでのクリップボードの使用について

    C#のコンソールアプリでクリップボードが使用できないです VS 2008の環境でClipbordクラスを利用しています。そのため System.Windows.Forms(.dll)を設定しているのですが 実行時にオブジェクトの参照ができないようです。 具体的には、 IDataObject oData = Clipboard.GetDataObject(); を実施してもoDataはnullのままでした。 何か他に設定が必要なのでしょうか? ちなみに、フォームアプリではClipbordクラスで問題なく使用できました。

  • VB2005でクリップボードにコピー

    VB2005でPicture1のイメージをクリップボードにコピーし Picture2.imageにペーストすると Picture2の画面がすべてブルーになつてしまいます。 プログラムはサンプル(microsoft Document explorerから)をダウンロードしべつのプログラムに貼り付けただけなのですが。 'ピクチャをピクチャ ボックスからクリップボードにコピーします My.Computer.Clipboard.SetImage(PictureBox1.Image) 'クリップボードにイメージが存在する場合、そのイメージをピクチャ ボックスに貼り付けます If My.Computer.Clipboard.ContainsImage Then PictureBox2.Image = My.Computer.Clipboard.GetImage Else MsgBox("Clipboard does not contain an image", MsgBoxStyle.Exclamation And MsgBoxStyle.OKOnly) End If

  • クリップボードからの貼り付けのフック

    VB.net、C#、.net framework2005で、 クリップボード拡張ソフトを開発しております。 クリップボードへの入出力が起こる直前にフックをかけたいです。 コピー・切り取り操作(ClipBoardへの入力)については クリップボードチェーンに自分を加え、WM_DRAWCLIPBOARDをハンドルすることで解決できました。 貼り付け(ClipBoardからの出力)についてはどのようにすれば実現できますでしょうか? 貼り付けイベントが起こった時に、チェーン内のプログラムにそれを通知するようなWindowsメッセージがあるかと思い、それらしいものを探してみたのですが、利用できそうなものがありませんでした… 具体的には、 ・入力時に、データを加工して仮想クリップボードに格納 ・出力時に、仮想クリップボード内のデータを再度加工して出力(貼り付け) という処理を実現したいです。 宜しくお願い致します。

  • pascalでのクリップボードの使い方

    pascalであらかじめ用意してある文章をクリップボードを利用して、他の場所に貼り付けができるようにするプログラムを作くろうと思っているのですが少しうまい具合にいかなくて困っています。 文章をコピーするときなのですがeditなどの一列の文はクリップボードのClipboard.AsTextで出来たのですが、memoのような改行されるようなものが出来ませんでした。改行される文をクリップボードに移したいときはどうすればよいでしょうか?

  • クリップボードの中身を判別

    PHPなどは理解しておりますが、VBに関してはまったく素人で何もわからないものです。 今回、クリップボードの中身を常に監視して、ある文字列が含まれていたらそのまま、それ以外の文字列の場合は空にするアプリが必要になりました。 そこでネットでいろいろ探して次のように作りました。 Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click End End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'クリップボードの文字列データを取得する Dim ClipBoardValue As IDataObject Dim ClipBoardString As String Dim okng As Boolean Do 'クリップボードのデータを取得() ClipBoardValue = Clipboard.GetDataObject ClipBoardString = ClipBoardValue.GetData(DataFormats.Text).ToString okng = ClipBoardString.Contains("反応あり") If (okng) Then 'クリップボードに文字列をコピーする Clipboard.SetDataObject("反応あり") Else Clipboard.SetDataObject("") End If Loop End Sub End Class 一つのフォームにボタンを一つ設置し、起動したら監視開始、ボタンをクリックしたら終了という形にしています。 動作させると、以下の問題があります。 ・どんな文字をコピーしてもすぐ空になってしまう ・フォームが表示されない ・起動時にクリップボードの中身が空だとエラーが表示される (オブジェクトのインスタンスにはnewを使用しろとかなんとか。。。) 正しい動作をするコードを教えていただけないでしょうか。 よろしくお願い致します。

  • C++/CLIを用いて画像をクリップボードにコピー

    VC++でC++/CLIでアプリケーションを作成しています。 そこで,pictureBox1の画像を,クリップボードにコピーしたいのですが,方法が分からず困っています。 Clipboard::SetDataObject(); の () の中に何を渡せばいいのでしょうか?

  • クリップボード拡張ソフト

    一度、質問したのですが、回答が一つもなく、日日が経つと全く見てくれなくなるようで閲覧数が増えず、新たに立て直しました。前回の質問が取り消しもできないようで、どうしようか悩んだ末、新たに立てた次第です。重複している状態ですが、お気を悪くしている方、いらっしゃるでしょうか。申し訳ないです。 まず簡単に説明します。パソコンで「コピー」をしたとき、Windowsではクリップボードというものに貼り付けられています。そして、「貼り付け」をしたときに、クリップボードから読みだされます。 コピーできるのは通常1つだけです。webサイトの情報をコピーすると、html形式でコピーされます。 このとき、文字色やフォントの大きさもそのままコピーされています。 クリップボード拡張ソフトは、このコピーから貼り付けまでを、拡張したものです。 だいたいのソフトが複数のコピーをクリップボードに保持できます。 私がやりたいのが、この機能なのですが、それらしいものをいくつか試したのですがhtml形式でコピーできず、テキスト形式で貼り付けになってしまうのです。 どなたか、html形式で複数コピーできるものを教えて頂けないでしょうか

  • 「クリップボードにコピーされているデータが多すぎます。」について

    大量なExcelデータを複写してAccessのテーブルに貼り付けてテーブルを 閉じたら以下のメッセージが表示されました。 「クリップボードにコピーされているデータが多すぎます。 データをクリップボードにコピーすると、オブジェクトに対する参照だけがコピーされます。 ソース ドキュメントを閉じると、ソースからすべてのデータが貼り付けられます。 データに量によっては、時間がかかる場合もあります。 このデータをクリップボードに保存しますか?」 どういう事で言っているのでしょうか? 説明して下さい。 宜しくお願いします。

  • クリップボードからファイル名を取得

    クリップボードについて教えていただきたいと思います。 コピーを行うとクリップボードにはコピーした内容が保存されます。 そのコピーを行った内容のファイル名(できればstring型で)を取得する方法を教えていただけたらと思います。 文字列・保存されていない画像の場合にはファイル名は存在しないので、ファイル名の存在する画像やファイルについての方法をお願いします。

    • ベストアンサー
    • Java
  • クリップボードにデータを送る(コピーする)には?

    vbaでクリップボードにデータを送る(コピーする)には? エクセルです。 Sub Macro() Selection.Copy End Sub で、クリップボードにデータを送ってることになりますよね? 「どこかのセルをコピーする」ではなく、例えば「abc」という文字をコピーさせて、 いつでも貼り付けられる状態にしたいのですが、vbaでそういうことは可能ですか? Sub Macro() "abc"をクリップボードに送る End Sub 的な事がしたいです。

専門家に質問してみよう