ページ 1 / 1
クリップボードの文字列操作
Posted: 2005年6月03日(金) 11:52
by 7
コード: 全て選択
Declare Function IsClipboardFormatAvailable Lib "user32.dll" (ByVal wFormat As Long) As Long
Class CClipboard
Protected
c_hWnd As HWND
Public
Sub CClipboard(ByVal hWnd As HWND)
c_hWnd=hWnd
End Sub
Function clear() As Long
clear=FALSE
If OpenClipboard(c_hWnd) Then
EmptyClipboard()
CloseClipboard()
clear=TRUE
End If
End Function
Function setText(ByVal lpString As BytePtr) As Long
Dim hMem As HGLOBAL
Dim lpStr As BytePtr
setText=FALSE
hMem=GlobalAlloc(GHND,lstrlen(lpString)+1)
If hMem Then
lpStr=GlobalLock(hMem)
If lpStr Then
lstrcpy(lpStr,lpString)
GlobalUnlock(hMem)
If OpenClipboard(c_hWnd) Then
EmptyClipboard()
SetClipboardData(CF_TEXT,hMem)
CloseClipboard()
setText=TRUE
End If
End If
GlobalFree(hMem)
End If
End Function
Function getText() As BytePtr
Dim hMem As HGLOBAL
getText=NULL
If IsClipboardFormatAvailable(CF_TEXT) Then
If OpenClipboard(c_hWnd) Then
hMem=GetClipboardData(CF_TEXT)
getText=GlobalLock(hMem)
GlobalUnlock(hMem)
CloseClipboard()
End If
End If
End Function
End Class
ちゃんと投稿出来るかな…。
ハイテク過ぎてよく分かりません。
コード: 全て選択
Dim cpBrd As CClipboard(NULL)
cpBrd.setText("setText")
MessageBox(0,cpBrd.getText(),"getText",MB_OK)
cpBrd.clear()
Re: クリップボードの文字列操作
Posted: 2005年6月04日(土) 17:20
by tom
7サン
こんにちは,tomです.
>Function clear() As Long
はEmptyClipboard()だだけではおかしくならないですか?
SetClipboardDataも使用しないとうまくいかなかったような・・・
>Function setText(ByVal lpString As BytePtr) As Long
のGlobalFree(hMem)は,使用しては駄目だったような気がします.
両方うろ覚えですみません(^^;;
Re: クリップボードの文字列操作
Posted: 2005年6月04日(土) 17:57
by tak
> >Function clear() As Long
> はEmptyClipboard()だだけではおかしくならないですか?
> SetClipboardDataも使用しないとうまくいかなかったような・・・
僕の環境ではEmptyClipboard()を呼び出した時点でクリップボードはクリアされました。
カーネルが違えば動作も違うかもしれないので、確実なことは言えませんが・・・
> >Function setText(ByVal lpString As BytePtr) As Long
> のGlobalFree(hMem)は,使用しては駄目だったような気がします.
確か、CloseClipboard()を呼び出してクリップボードの所有者がなくなればGlobalFree()でメモリ領域をシステムに返還しなければならなかったとおもいます。
僕の方こそうろ覚えなのですが(爆)
Re: クリップボードの文字列操作
Posted: 2005年6月04日(土) 18:38
by tom
takさん
こんばんは,tomです
> 僕の環境ではEmptyClipboard()を呼び出した時点でクリップボードはクリアされました。
> カーネルが違えば動作も違うかもしれないので、確実なことは言えませんが・・・
クリアはされるのですが,その後のクリップボード関連が変?になったと思います.
> 確か、CloseClipboard()を呼び出してクリップボードの所有者がなくなればGlobalFree()でメモリ領域をシステムに返還しなければならなかったとおもいます。
あら,そうでしたか(^^;
クリップボードの場合はGlobalFree()をしないで後ろに任せるようにしていました.
> 僕の方こそうろ覚えなのですが(爆)
本当に私もうろ覚えで申し訳ないです.
結構前にクリップボードを試しただけなので(^^;;
Re: クリップボードの文字列操作
Posted: 2005年6月04日(土) 18:44
by イグトランス
> > >Function setText(ByVal lpString As BytePtr) As Long
> > のGlobalFree(hMem)は,使用しては駄目だったような気がします.
> 確か、CloseClipboard()を呼び出してクリップボードの所有者がなくなればGlobalFree()でメモリ領域をシステムに返還しなければならなかったとおもいます。
>
> 僕の方こそうろ覚えなのですが(爆)
私もTomさんの方が正しいと思います。実際Microsoftのサンプルでもそうなっていますし。
http://msdn.microsoft.com/library/en-us ... pboard.asp
Re: クリップボードの文字列操作
Posted: 2005年6月04日(土) 19:14
by 7
> 私もTomさんの方が正しいと思います。実際Microsoftのサンプルでもそうなっていますし。
GlobalFree()してはいけないんですね。
クリップボードに文字列が設定された場合GlobalFree()しないように、setText()関数を書き換えました。
コード: 全て選択
Function setText(ByVal lpString As BytePtr) As Long
Dim hMem As HGLOBAL
Dim lpStr As BytePtr
setText=FALSE
hMem=GlobalAlloc(GHND,lstrlen(lpString)+1)
If hMem Then
lpStr=GlobalLock(hMem)
If lpStr=NULL Then
GlobalFree(hMem)
Else
lstrcpy(lpStr,lpString)
GlobalUnlock(hMem)
If OpenClipboard(c_hWnd) Then
EmptyClipboard()
SetClipboardData(CF_TEXT,hMem)
CloseClipboard()
setText=TRUE
End If
End If
End If
End Function
クリップボードの初期化についてですが(clear)、以前C++のコードで見たのをIf文を交えて再現しました。
コード: 全て選択
OpenClipboard(0)
EmptyClipboard()
CloseClipboard()
ですので、問題が有るのか分かりません…。
とりあえず、自分はクリップボードが変になることにはなっていません。
実はsetImg()関数も有ったんですが、その時はクリップボードを使おうとしたら「クリップボードの内容が可笑しい」というエラーダイアログは出ましたが…。
Re: クリップボードの文字列操作
Posted: 2005年6月04日(土) 20:33
by ゲスト
> クリップボードの初期化についてですが(clear)、以前C++のコードで見たのをIf文を交えて再現しました。
>
コード: 全て選択
OpenClipboard(0)
> EmptyClipboard()
> CloseClipboard()
> ですので、問題が有るのか分かりません…。
> とりあえず、自分はクリップボードが変になることにはなっていません。
> 実はsetImg()関数も有ったんですが、その時はクリップボードを使おうとしたら「クリップボードの内容が可笑しい」というエラーダイアログは出ましたが…。
すみません,初期化の方は私の勘違いだと思います(^^;
お手数かけました<(_ _)>
getText() As BytePtr の部分で
Posted: 2005年7月20日(水) 08:49
by 淡幻星
テストしてないので恐縮なのですが、
(Ver4.xはまだインストールしてません^^;)
Function getText() As BytePtr
の部分で
getText=GlobalLock(hMem)
ってしてますけど、GlobalUnlock()された時点で、
getText As BytePtrの有効性は不確実なものになる上に、
CloseClipboard()によって他のアプリからのアクセスが許可されるので、
getText As BytePtrが実際に利用される前に、
クリップボードの中身が書き換えられる危険性がありませんか?
そんなわけで、getText()には、有効なバッファを引数で渡すか、
コード: 全て選択
Function getText( pBuffer As BytePtr ) As Long
Dim hMem As HGLOBAL
Dim pRowClip As BytePtr
getText=FALSE
If IsClipboardFormatAvailable(CF_TEXT) Then
If OpenClipboard(c_hWnd) Then
hMem = GetClipboardData( CF_TEXT )
pRowClip = GlobalLock( hMem )
lstrcpy( pBuffer, pRowClip )
GlobalUnlock(hMem)
CloseClipboard()
getText = TRUE
End If
End If
End Function
もしくは、String型を利用した方が良いと思うのですが、どうでしょうか?
コード: 全て選択
Function getText() As String
Dim hMem As HGLOBAL
Dim pRowClip As BytePtr
getText=""
If IsClipboardFormatAvailable(CF_TEXT) Then
If OpenClipboard(c_hWnd) Then
hMem = GetClipboardData( CF_TEXT )
pRowClip = GlobalLock( hMem )
getText = pRowClip ' BytePtr型→String型の代入はlstrcpy()動作となるはず・・・。⇔逆は単純にポインタのコピー(たぶん)。
GlobalUnlock(hMem)
CloseClipboard()
End If
End If
End Function
・・・勘違いだったらすいません。
「違うよ」って言う方いらっしゃいましたら、ぜひ指摘ください。
私もよくわかっていませんので<GlobalLock周り。
Posted: 2006年6月10日(土) 19:47
by 7
自分も負けじと書いてみました。
「クリップボードの文字列操作」から離れて「クリップボードの操作」にしてしまった方が良いのかも...ということで以下のようになりました。
クリップボードビューアのことは考えていません。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Declare Function GetClipboardOwner Lib "user32" () As HWND
Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal uFormat As DWord) As BOOL
#ifndef _SEVEN_CCLIPBOARD
#define _SEVEN_CCLIPBOARD
Class CClipboard
Protected
c_hWnd As HWND
Public
Sub CClipboard(ByVal hWnd As HWND)
c_hWnd=hWnd
End Sub
Sub ~CClipboard()
c_hWnd=NULL
End Sub
' クリップボードを所有するウィンドウのハンドルを取得します。
Function getOwner() As HWND
getOwner=GetClipboardOwner()
End Function
' クリップボードをオープンし、データの書き込みや読み込みをできるようにします。
Function openClipboard() As BOOL
openClipboard=OpenClipboard(c_hWnd)
End Function
' オープンされているクリップボードをクローズします。
Function closeClipboard() As BOOL
closeClipboard=CloseClipboard()
End Function
' クリップボード内のデータをメモリから解放。
' 内容を空にしてクリップボードのオーナーになります。
Function empty() As BOOL
empty=EmptyClipboard()
End Function
' クリップボード内のフォーマット数を取得します。
Function getCountFormats() As Long
getCountFormats=CountClipboardFormats()
End Function
' クリップボード内のフォーマットを列挙します。
Function enumFormats(ByVal uFormat As DWord) As DWord
enumFormats=EnumClipboardFormats(uFormat)
End Function
' クリップボード内の指定されたフォーマットのデータを設定します。
Function setData(ByVal uFormat As DWord,ByVal hMem As HANDLE) As HANDLE
setData=SetClipboardData(uFormat,hMem)
End Function
' クリップボード内の指定されたフォーマットにデータが存在するか判断します。
Function isFormatAvailable(ByVal uFormat As DWord) As BOOL
isFormatAvailable=IsClipboardFormatAvailable(uFormat)
End Function
' クリップボード内の指定されたフォーマットのデータを取得します。
Function getData(ByVal uFormat As DWord) As HANDLE
getData=GetClipboardData(uFormat)
End Function
' クリップボードに定義されているフォーマットの名前を取得します。
Function getFormatName(ByVal uFormat As DWord,ByVal lpszFormatName As LPSTR,ByVal cchMaxCount As Long) As Long
getFormatName=GetClipboardFormatName(uFormat,lpszFormatName,cchMaxCount)
End Function
' クリップボードに新しくフォーマットを定義します。
Function registerFormat(ByVal lpszFormat As LPCSTR) As DWord
registerFormat=RegisterClipboardFormat(lpszFormat)
End Function
End Class
#endif