[[TIPS/Programming]]

* Visual C++ 2008 によるクリップボードからの画像取得サンプルプログラム [#oc12af73]

** 概略 [#i2a53adc]
このアプリケーションは、Visual C++ 2008 でクリップボードにコピーされた
画像を読み出すためのサンプルプログラムです。

** 基本動作・機能 [#v55d821f]
このサンプルプログラムは、下記の機能を持っています。

- クリップボードにコピーされた画像を取り込み、jpegファイルに保存します。
- 保存ファイル名を自動で生成し、連続して画像を取り込み、jpegファイルに保存します。
- クリップボードに画像ファイルがコピーされたことを自動で検知し、上記動作を行います。

** 技術 [#yb23831e]
このサンプルプログラムは、下記のような技術的要素を使用しています。

- Windowsメッセージ受信
- クリップボードビューワ(ClipBoard Viewer)
- ビューワチェイン(Viewer Chain)
   
上記の技術的要素の説明は下記の通りです。
- クリップボードにデータが貼り付けられた場合、クリップボードビューワより、WM_DRAWCLIPBOARDメッセージが送られてくる。
- 仮想関数(WndProc)をオーバーライドして、WM_DRAWCLIPBOARDメッセージを受信
- WM_DRAWCLIPBOARDメッセージを、ビューワチェインを用いて、次のチェインに登録されたウィンドウに転送する。~
 ※1ビューワチェイン(Viewer Chain)とは、クリップボードを利用するウィンドウのリストです。~
 ※2クリップボードを利用する各アプリケーションは、それぞれが次のビューワチェインに登録されているウィンドウにWM_DRAWCLIPBOARDメッセージを転送する必要があります。

** 利用条件・著作権・転載などについて [#we5dfd0b]
このサンプルを使う上で、特に制限はございません。このソフトを使った事による損害などは、作者は一切関知しませんので、ご了承ください。

このサンプルを使って何らかのソフトを作って公開したり、業務で使用することにもとくに制限はございません。ただし、その場合は相互リンクなどで紹介していただけると嬉しいです。

** 実行環境(私がディバッグしていた環境です) [#s760e08e]
- OS: WindowsXP SP3
- 開発環境: Microsoft Visual C++ 2008 Express Edition


** ダウンロード [#aa7c5205]
下記のファイルをダウンロードしてください。
Visual C++ 2008 のサンプルプロジェクトを丸ごとZIPしています。ダウンロード後、解凍してソリューションファイルを開いてください。

[[ClipBoardSample100.zip(19kB)>http://www.altemasoft.com/download/ClipBoardSample100.zip]]

** ソースコード説明 [#d12a38e6]
下記に、一部の重要なソースコードを示します。
	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
			{//メッセージを受け取る。横取り?
				System::Windows::Forms::IDataObject	^data = System::Windows::Forms::Clipboard::GetDataObject();
				
				this->Form::WndProc(m);	//元の方も処理する。
				//クリップボード関連のメッセージを受け取る。
				switch(m.Msg)
				{
					//クリップボードにデータがコピーされた。
					case WM_DRAWCLIPBOARD:
							SavePictureToFile();
							//次のクリップボードチェインにメッセージを転送。
							::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;
				}
			}
	private: String^	GenerateSaveFileName(){
				 //日付と現在時刻からファイル名を生成。
				 DateTime^	dt = DateTime::Now;
				 return( dt->ToString("yyyyMMddHHmmss"));
			 }
	private: void	SavePictureToFile(){
				 //クリップボードから画像を取得し、JPEG形式で保存する。
				 System::Windows::Forms::IDataObject	^data = System::Windows::Forms::Clipboard::GetDataObject();
				 //クリップボード内にデータがあるかどうか。
					 if(data->GetDataPresent(DataFormats::Bitmap) == true)
					 {					 
						 if( (checkFileNameAutoGenerate->Checked == true) || (textFileName->Text == "")){
							textFileName->Text = GenerateSaveFileName();
							}
						 //クリップボードからデータをGETする。
						 pictureShowPicture->Image = (Image^)data->GetData(DataFormats::Bitmap);
						 //フォルダの最後の文字を "\" にする。
						 if( textFolderDestination->Text[textFolderDestination->Text->Length - 1] != '\\'){
							textFolderDestination->Text = textFolderDestination->Text + "\\";
						 }
						 //JPEG形式で保存
						pictureShowPicture->Image->Save(textFolderDestination->Text + textFileName->Text + ".jpg");
					 }
			 }
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
					 SavePictureToFile();				
				 }
	private: System::Void button1_Click_1(System::Object^  sender, System::EventArgs^  e) {
					 folderBrowserDialog->ShowDialog(this);
					 if(folderBrowserDialog->SelectedPath != ""){
						 textFolderDestination->Text = folderBrowserDialog->SelectedPath;
					 }
				 }

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS