次の方法で共有


クリップボードへのコピーと取得方法の違いについて

Cc440846.download(ja-jp,MSDN.10).gif サンプル コードのダウンロード (vbmigtips_Clipboard.exe, 94.7 KB)

テキスト等のデータをコピー、貼り付けする場合、クリップボードを利用します。そこで今回は、クリップボードへのコピー方法と、コピーされているデータの取得方法について紹介します。

まず、Visual Basic 6.0 でのコピーおよび取得方法を紹介します。図1 のテキストボックスに記述されたデータをクリップボードへコピーし、「取得」ボタンでクリップボードにコピーされているデータを取得し、ラベルに表示するアプリケーションを作成します。

 Cc440846.Clipboard_fig01(ja-jp,MSDN.10).gif
 図1

Visual Basic 6.0 では Win32API を使用します。そこでまず、クリップボードへコピーする SetClipboardData 関数やクリップボードからデータを取得する MoveMemory 関数、その他の Win32API の定義を宣言します。実装コードは以下のとおりです。

Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
Private Declare Function RegisterClipboardFormat Lib "user32" Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Long

Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Const GMEM_MOVEABLE = &H2

Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)

リスト1

リスト1 で定義した Win32API を呼び出す方法は以下のとおりです。

Private Sub Command1_Click()
Dim data() As Byte
Dim wFormat As Long
Dim hMem As Long
Dim Size As Long
Dim p As Long

wFormat = RegisterClipboardFormat(FormatName)
data = Text1.Text
If OpenClipboard(ByVal 0&) Then
EmptyClipboard
Size = UBound(data) + 1
hMem = GlobalAlloc(GMEM_MOVEABLE, Size)
p = GlobalLock(hMem)
MoveMemory p, VarPtr(data(0)), Size
GlobalUnlock hMem

SetClipboardData wFormat, hMem
GlobalFree hMem

CloseClipboard
End If
End Sub

Private Sub Command2_Click()
Dim wFormat As Long
Dim hMem As Long
Dim p As Long
Dim data() As Byte
Dim Size As Long

wFormat = RegisterClipboardFormat(FormatName)

If OpenClipboard(ByVal 0&) Then
hMem = GetClipboardData(wFormat)

If hMem Then
Size = GlobalSize(hMem)
p = GlobalLock(hMem)
ReDim data(0 To Size)
MoveMemory VarPtr(data(0)), p, Size
GlobalUnlock hMem
End If
CloseClipboard
End If
Label1.Caption = data
End Sub

リスト2

リスト2 の「Private Sub Command1_Click() ... End Sub」では、クリップボードへのコピーを実装しています。まず、「wFormat = RegisterClipboardFormat(FormatName) 」では RegisterClipboardFormat 関数を使ってクリップボードの新しい形式を登録し、「If OpenClipboard(ByVal 0&) Then」で クリップボードを開き、他のアプリケーションからクリップボードの内容を変更できないようにします。次に、EmptyClipboard 関数でクリップボードを空にします。「hMem = GlobalAlloc(GMEM_MOVEABLE, Size) 」で指定されたバイト数のメモリを確保し、「p = GlobalLock(hMem)」でメモリオブジェクトをロックしポインタに変換します。さらに「MoveMemory p, VarPtr(data(0)), Size」で指定したメモリブロックを p の位置に移動し、「GlobalUnlock hMem」でメモリオブジェクトのロックを解除します。そして、「SetClipboardData wFormat, hMem 」でクリップボードにデータをコピーし、GlobalFree 関数でグローバルメモリオブジェクトを解放。最後に CloseClipboard 関数でクリップボードを閉じます。

一方、リスト2 の「Private Sub Command2_Click() ... End Sub」では、クリップボードにあるデータの取得を実装しています。まず、「wFormat = RegisterClipboardFormat(FormatName) 」でクリップボードの新しい形式を登録し、「If OpenClipboard(ByVal 0&) Then」で クリップボードを開き、他のアプリケーションからクリップボードの内容を変更できないようにします。次に、「hMem = GetClipboardData(wFormat) 」でクリップボードからメモリブロックのハンドルを取得します。そして、「MoveMemory VarPtr(data(0)), p, Size」で指定したメモリブロックを VarPtr(data(0)) の位置に移動し、「GlobalUnlock hMem」でメモリオブジェクトのロックを解除します。最後にCloseClipboard 関数でクリップボードを閉じ、「Label1.Caption = data」で取得したデータ (data) を Label コントロールに設定します。

リスト1 とリスト2 を実装し、「コピー」ボタンをクリックするとテキストボックス内のデータがクリップボードにコピーされ、「取得」ボタンをクリックすると、クリップボードにあるデータがラベルに表示されます (図2)。

 Cc440846.Clipboard_fig02(ja-jp,MSDN.10).gif
 図2

上記で紹介したように、Visual Basic 6.0 では、Win32API を使用してクリップボードへのコピーや取得を行いました。しかし、Visual Basic .NET では、System.Windows.Forms.Clipboard クラスがサポートされているため、より簡単にクリップボードへのコピーや取得などが行えるようになりました。SetDataObject メソッドでクリップボードへのコピーを行い、GetDataObject メソッドでクリップボードにあるデータを取得します。実装コードは以下のとおりです。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
System.Windows.Forms.Clipboard.SetDataObject(New DataObject(TextBox1.Text))
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim objData As DataObject = System.Windows.Forms.Clipboard.GetDataObject()
If objData.GetDataPresent(DataFormats.StringFormat) Then
Label1.Text = objData.GetData(DataFormats.StringFormat)
End If
End Sub

リスト2

上記 (リスト2) の「System.Windows.Forms.Clipboard.SetDataObject(New DataObject(TextBox1.Text))」で、テキストボックスのデータをクリップボードへコピーします。「Dim objData As DataObject = System.Windows.Forms.Clipboard.GetDataObject()」でクリップボードにあるデータを取得し、「Label1.Text = objData.GetData(DataFormats.StringFormat)」でラベルに表示します。
リスト2 を実装し、「コピー」ボタンをクリックするとテキストボックス (図1) 内のデータがクリップボードにコピーされ、「取得」ボタンをクリックすると、図2 のようにクリップボードにあるデータがラベルに表示されます。