|   | 
  | 
連載:アップグレード・ウィザードに学ぶVB 6→VB 2005
第2回 ClipboardオブジェクトとMy.Computer.Clipboardオブジェクト
グレープシティ株式会社 八巻 雄哉 
2007/02/20 | 
 
 | 
 今回変換するVisual Basic 6.0(以下VB 6)の特殊オブジェクトは「Clipboardオブジェクト」です。Clipboardオブジェクトは、クリップボードとデータのやりとりを行うための機能を持っています。アプリケーションの中で、主にテキストや画像のコピー、切り取り、および貼り付け機能を実装するために使われるオブジェクトです。
 それでは今回も、まずは変換する前のVB 6のサンプル・プロジェクトから見ていきます。サンプル・プロジェクトのコードがリスト1、その実行画面が図1になります。
 
' [コピー]ボタンを押したとき 
Private Sub Command1_Click() 
 
  ' クリップボードのデータを削除します。 
  Clipboard.Clear 
 
  ' クリップボードにテキストボックスのテキストを追加します。 
  Clipboard.SetText Text1.Text 
 
  ' クリップボードにピクチャーボックスの画像を追加します。 
  Clipboard.SetData Picture1.Picture 
 
End Sub 
 
' [貼り付け]ボタンを押したとき 
Private Sub Command2_Click() 
 
  ' クリップボードにテキスト・データが存在する場合には 
  ' そのデータをテキストボックスに表示します。 
  If Clipboard.GetFormat(vbCFText) Then 
    Text1.Text = Clipboard.GetText 
  End If 
 
  ' クリップボードにビットマップ・データが存在する場合には 
  ' そのデータをピクチャーボックスに表示します。 
  If Clipboard.GetFormat(vbCFBitmap) Then 
    Picture1.Picture = Clipboard.GetData 
  End If 
 
End Sub 
 | 
 
 
 | 
| リスト1 Clipboardオブジェクトを使ったVB 6のサンプル・プロジェクトのコード | 
  
 | 
| 図1 リスト1の実行画面(VB 6アプリケーション) | 
| 2つのボタンとテキストボックス、ピクチャーボックスを使用している。 | 
 このサンプル・プロジェクトは、以下の機能を持っています。
- [コピー]ボタンを押したとき、テキストボックスに入力されている文字列とピクチャーボックスに表示されている画像をクリップボードへコピーする。
 
- [貼り付け]ボタンを押したとき、クリップボード上に表示可能なデータが存在する場合にそのデータをテキストボックスとピクチャーボックスに表示する。
 
 では、このプロジェクトをアップグレード・ウィザードを使ってVisual Basic 2005(以下VB 2005)のコードに変換してみましょう。リスト1のコードを変換した結果が次のリスト2です。
 
' [コピー]ボタンを押したとき 
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click 
 
  ' [クリップボード]のデータを削除します。 
  My.Computer.Clipboard.Clear() 
 
  ' クリップボードにテキストボックスのテキストを追加します。 
  My.Computer.Clipboard.SetText(Text1.Text) 
 
  ' クリップボードにピクチャーボックスの画像を追加します。 
  My.Computer.Clipboard.SetImage(Picture1.Image) 
 
End Sub 
 
' [貼り付け]ボタンを押したとき 
Private Sub Command2_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command2.Click 
 
  ' クリップボードにテキスト・データが存在する場合には 
  ' そのデータをテキストボックスに表示します。 
  If My.Computer.Clipboard.ContainsText() Then 
    Text1.Text = My.Computer.Clipboard.GetText 
  End If 
 
  ' クリップボードにビットマップ・データが存在する場合には 
  ' そのデータをピクチャーボックスに表示します。 
  If My.Computer.Clipboard.ContainsImage() Then 
    Picture1.Image = My.Computer.Clipboard.GetImage() 
  End If 
 
End Sub 
 | 
 
 
 | 
| リスト2 アップグレード・ウィザードで変換したVB 2005のコード | 
 前回と同様に、今回も“My”を使ったコードに変換されていることが分かります。VB 2005では、「My.Computer.Clipboardオブジェクト」を使ってクリップボードとデータのやりとりを行うことができます。VB 6のClipboardオブジェクトと比べ、My.Computer.Clipboardオブジェクトはより多くのクリップボード形式をサポートしています。
 Clipboardオブジェクトのメソッドは、次の表のようにMy.Computer.Clipboardオブジェクトのメソッドに変換されています。
| VB 6 | 
VB 2005 | 
 
| Clipboardオブジェクトのメソッド | 
My.Computer.Clipboardオブジェクトのメソッド | 
 
| Clear | 
Clear | 
 
| GetFormat | 
ContainsText | 
 
| ContainsImage | 
 
| GetText | 
GetText | 
 
| GetData | 
GetImage | 
 
| SetText | 
SetText | 
 
| SetData | 
SetImage | 
 
 
 | 
| 表 ClipboardオブジェクトとMy.Computer.Clipboardオブジェクトの各メソッドの対応 | 
 | 
 しかも、今回はアップグレードされなかったコードはありません。めでたしめでたし、これにて一件落着……となってしまってはこの記事を書く意味がありません。実は、この変換されたプロジェクトを実行してみると、2つの問題があることが分かります。
| 
 問題その1 
テキストボックスとピクチャーボックスに何もデータがない状態で[コピー]ボタンを押すと例外が発生する 
 | 
 
 
 | 
 VB 6の場合、テキストボックスに何も入力されていないと空文字がSetTextメソッドのパラメータとして渡されますが、クリップボードには何も書き込まれない(正確には空文字が書き込まれているので貼り付け操作は可能)だけで特に問題はありませんでした。
 これに対し、VB 2005のSetTextメソッドでは空文字やNothingがパラメータとして渡された場合に例外が発生するようになっています。
  
 | 
| 図2 SetTextメソッドの実行でArgumentNullExceptionが発生 | 
| テキストボックスに何も入力されていない状態で[コピー]ボタンを押した場合。VB 2005のSetTextメソッドでは空文字やNothingがパラメータとして渡された場合に例外が発生する。 | 
 同じようにSetImageメソッドもNothingがパラメータとして渡された場合に例外が発生します。
 今回の場合、テキストボックスに何も入力されないケースがあることは初めから分かっています。ですので、StringクラスのIsNullOrEmptyメソッドを使ってテキストボックスのTextプロパティの値を確認し、Textプロパティの値が空文字でもNothingでもない場合にのみSetTextメソッドを実行するように変更します。同様に、SetImageメソッドも値がNothingでない場合にのみ実行するように変更することで、この問題に対応することができます。
 Command1_Clickメソッド部分を変更したコードがリスト3になります。
 
' [コピー]ボタンを押したとき 
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click 
 
  ' クリップボードのデータを削除します。 
  My.Computer.Clipboard.Clear() 
 
  ' テキストボックスに何も入力されていない場合には 
  ' クリップボードにテキストボックスのテキストを追加します。 
  If String.IsNullOrEmpty(Text1.Text) = False Then 
    My.Computer.Clipboard.SetText(Text1.Text) 
  End If 
 
  ' ピクチャーボックスに何も設定されていない場合には 
  ' クリップボードにピクチャーボックスの画像を追加します。 
  If Picture1.Image IsNot Nothing Then 
    My.Computer.Clipboard.SetImage(Picture1.Image) 
  End If 
 
End Sub 
 | 
 
 
 | 
| リスト3 テキストボックスやピクチャーボックスに何もデータがない場合に対応したVB 2005のコード | 
| 
 問題その2 
テキストボックスとピクチャーボックスの両方にデータが存在している状態で[コピー]ボタンを押しても、画像データのみがクリップボードに書き込まれる 
 | 
 
 
 | 
 クリップボードは1つのデータを複数のデータ形式で保持することができます。VB 6のサンプル・プロジェクトを実行し、テキストボックスとピクチャーボックスの両方にデータが存在している状態で[コピー]ボタンを押したときのクリップボードをクリップブック*で確認してみると図3のようになります。
* クリップブックを実行するには、[スタート]−[ファイル名を指定して実行]を実行し、表示されるダイアログで「clipbrd」と入力し、[OK]ボタンをクリックします。 
 | 
  
 | 
| 図3 VB 6のサンプル・プロジェクトではテキストとビットマップの両方のデータが存在 | 
| [表示]メニューの項目に「テキスト」と「ビットマップ」が存在することから、クリップボードにはテキストとビットマップが格納されていることが分かる。 | 
 この場合、テキストとビットマップの両方のデータがクリップボードに書き込まれていることが[表示]メニューの項目から分かります。VB 6のSetTextメソッドやSetDataメソッドは、クリップボードの中身をいったん消去するという動作を行わずに、単純にクリップボードの指定された形式部分にデータを追加する形で書き込むからです。そのため、新規にクリップボードに書き込む場合には、最初にClearメソッドを実行してクリップボードのデータを消去しておく必要がありました。
 これに対してVB 2005のSetTextメソッドやSetImageメソッドは、クリップボードの中身をいったん消去してからデータを書き込みます。そのため、上記のリスト2やリスト3のようなコードの場合、SetImageメソッドで書き込んだデータがSetTextメソッドで書き込んだデータを上書きしてしまい、クリップボードにはビットマップのデータのみが存在することになります。
 変換したVB 2005のサンプル・プロジェクトでテキストボックスとピクチャーボックスの両方にデータが存在している状態で[コピー]ボタンを押したときのクリップボードをクリップブックで確認した結果が図4です。確かにクリップボードにはビットマップしか存在していません。
  
 | 
| 図4 VB 2005のサンプル・プロジェクトではビットマップのデータのみが存在 | 
 | 
 VB 2005でクリップボードに複数形式のデータを書き込むには、複数のデータを格納可能なDataObjectクラス(System.Windows.Forms名前空間)を使います。
 DataObjectクラスを使ってクリップボードに書き込むためのデータを作成しておき、そのDataObjectオブジェクトをClipboardクラスのSetDataObjectメソッドで書き込むという手順になります。DataObjectオブジェクトにデータを“追加”するには、SetDataメソッドを使います。
 この方法を適用したCommand1_Clickメソッド部分のコードがリスト4になります。
 
' [コピー]ボタンを押したとき 
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click 
 
  ' クリップボードのデータを削除します。 
  My.Computer.Clipboard.Clear() 
 
  ' 複数のデータを格納するために 
  ' DataObjectオブジェクトを使います。 
  Dim clipData As DataObject = New DataObject 
 
  ' DataObjectオブジェクトにテキストボックスのテキストを 
  ' “追加”します。 
  clipData.SetData(Text1.Text) 
 
  ' DataObjectオブジェクトにピクチャーボックスの画像を 
  ' “追加”します。 
  clipData.SetData(Picture1.Image) 
 
  ' クリップボードにDataObjectを書き込みます。 
  ' 第2パラメータをTrueに設定することで、 
  ' アプリケーションが終了した後も 
  ' データをクリップボードに残すようにします。 
  Clipboard.SetDataObject(clipData, True) 
 
End Sub 
 | 
 
 
 | 
| リスト4 VB 2005でクリップボードに複数形式のデータを書き込む場合 | 
 リスト4のコードに変更したサンプル・プロジェクトを実行し、同じようにクリップブックで確認すると、今度はテキスト・データもクリップボードに書き込まれていることが分かります。
  
 | 
| 図5 リスト4のサンプル・プロジェクト実行後のクリップブック | 
 | 
■
 以上、今回はClipboardオブジェクトに関するコードの変換を行いました。VB 2005でもそれほど変わらないコードでクリップボードを操作できること、その動作には若干の違いがあることがお分かりいただけたかと思います。
 VB 2005のMy.Computer.Clipboardオブジェクトでは、エクスプローラからコピーしたファイルの一覧を扱うことができるFileDrop形式など、VB 6にはなかった形式もサポートされています。ほかの形式でも扱い方に違いはありませんので、時間のある方はぜひ試してみてください。では、次回をお楽しみに。