ページ 1 / 1
SetClipBoardDataの件
Posted: 2006年10月03日(火) 08:57
by ジョン
過去ログにてクリップボードに文字列を貼り付ける幾つかの
例を拝見しました。
ファイルの内容ではなく、ファイルそのものをコピーし一時置きする
作業をしたいのですが、
1.コピーしたいファイルのフルパスとファイル名を指定。
2.クリップボードを開く
3.クリップボードを空にする
4.メモリを確保
5.メモリの先頭アドレスを取得
6.メモリの先頭アドレスを渡す
7.クリップボードを閉じる
工程の4.と5.と6.をご教授ねがいたいのです。
Re: SetClipBoardDataの件
Posted: 2006年10月03日(火) 17:17
by 7
> 1.コピーしたいファイルのフルパスとファイル名を指定。
> 2.クリップボードを開く
> 3.クリップボードを空にする
> 4.メモリを確保
> 5.メモリの先頭アドレスを取得
> 6.メモリの先頭アドレスを渡す
> 7.クリップボードを閉じる
>
> 工程の4.と5.と6.をご教授ねがいたいのです。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Dim hMem As HGLOBAL
Dim lpStr As LPSTR
' ヒープ領域から256バイト分メモリを確保
hMem=GlobalAlloc(GMEM_DDESHARE or GHND,256)
If hMem Then
' メモリブロックの先頭ポインタを取得
lpStr=GlobalLock(hMem)
If lpStr Then
'----------変数lpStrに対しメモリの操作を行う----------
'----------ここまで----------
GlobalUnlock(hMem)
If OpenClipboard(hMainWnd) Then
EmptyClipboard()
' 文字列をクリップボードに設定
SetClipboardData(CF_TEXT,hMem)
CloseClipboard()
End If
Else
GlobalFree(hMem)
End If
End If
こんな感じで分かるでしょうか?
この辺りの操作、自分もよく分からないのですけど...(汗)
> ファイルの内容ではなく、ファイルそのものをコピーし一時置きする
> 作業をしたいのですが、
クリップボードにファイルの絶対パス(文字列)を設定したいってことでしょうか?
Posted: 2006年10月10日(火) 10:48
by ジョン
遅くなりましたが、7さんありがとうございます。
7さんの予想通り、クリップボードにファイルの絶対パスを
設定し、どこでも「貼り付け」ができるようにしたいのです。
よろしくお願いします。
Posted: 2006年10月10日(火) 19:33
by 7
え~と、ご指名ありがとうございます(笑)
昔は暇さえ有ればここを見てたんですけど、最近は仕事やら夜遊びやらでそれなりに忙しい身分になれたもんで...。
ウィンドウズがどういう風にファイルのコピー&ペーストをしているかは分かりませんが、自分が実装する場合、クリップボードにファイルの絶対パスを保持(コピー)して、あとはCopyFile()関数でどうにかしようと思います。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Function SetClipboardText(ByVal hWndNewOwner As HWND,ByVal lpszStr As LPCSTR) As BOOL
Dim hMem As HGLOBAL
Dim lpStr As LPSTR
hMem=GlobalAlloc(GMEM_DDESHARE Or GHND,lstrlen(lpszStr)+1)
If hMem Then
lpStr=GlobalLock(hMem)
If lpStr Then
lstrcpy(lpStr,lpszStr)
GlobalUnlock(hMem)
If OpenClipboard(hWndNewOwner) Then
EmptyClipboard()
SetClipboardData(CF_TEXT,hMem)
CloseClipboard()
Return TRUE
End If
Else
GlobalFree(hMem)
End If
End If
Return FALSE
End Function
Function GetClipboardText(ByVal hWndNewOwner As HWND,ByRef lpStr As LPSTR) As BOOL
Dim hMem As HGLOBAL
Dim lpString As LPSTR
If OpenClipboard(hWndNewOwner) Then
hMem=GetClipboardData(CF_TEXT)
CloseClipboard()
If hMem Then
lpString=GlobalLock(hMem)
lpStr=calloc(lstrlen(lpString)+1)
lstrcpy(lpStr,lpString)
GlobalUnlock(hMem)
Return TRUE
End If
' CloseClipboard()
End If
Return FALSE
End Function
'------------------------------------------------------------
' ファイルのコピー
'------------------------------------------------------------
' 変数FileNameにファイルの絶対パスを格納する
Dim FileName[MAX_PATH-1] As Byte
' ファイルのコピーを行う。(ファイルの絶対パスをクリップボードに格納)
' メモ帳に貼り付けしてもファイルパスがペーストされるので
' RegisterClipboardFormat()関数で
' 独自のクリップボードフォーマットを作って
' そこに格納させた方が良い?
SetClipboardText(hMainWnd,FileName)
'------------------------------------------------------------
' ファイルのペースト
'------------------------------------------------------------
Dim lpStr As LPSTR
GetClipboardText(hMainWnd,lpStr)
' 同名ファイルが存在する場合、関数は失敗
CopyFile(lpStr,/* コピー先ファイルの絶対パス */,TRUE)
ByVal指定だと自分の思惑通りに動かなくなったんですけど、ActiveBasic、仕様?が変わったんでしょうか。
ByRef指定にしたら思惑通り動きました。
RegisterClipboardFormatの件
Posted: 2006年10月10日(火) 20:40
by ジョン
7さん、お忙しい中ありがとうございます。
そもそも、僕にはまだ難しいようです。
「RegisterClipboardFormat」では、新しいデータ形式を登録するようですが、
「データ形式」自体分かりません。
ただ単にマウスの右メニューで任意のファイルを「コピー」して「貼り付け」をする。
「コピー」だけはマウスを使わずにこの一連の作業を実現したかったのですが。
もし良かったら勉強のために、7さんが思惑通り動いたフルソースを
公開していただけませんか。
Re: RegisterClipboardFormatの件
Posted: 2006年10月10日(火) 21:42
by 7
> 「RegisterClipboardFormat」では、新しいデータ形式を登録するようですが、
> 「データ形式」自体分かりません。
RegisterClipboardFormat()関数は
CF_***っていう決まりきったフォーマットとは別に独自のフォーマットを定義する為に使います。
コード: 全て選択
' 独自のクリップボードフォーマット、HOGEを定義
Dim cf_hoge As DWord
cf_hoge=RegisterClipboardFormat("CF_HOGE")
あとは、
CF_TEXTを指定していた所を
cf_hogeにして、データ(とりあえず文字列)を格納するだけで良かったと思います。
> ただ単にマウスの右メニューで任意のファイルを「コピー」して「貼り付け」をする。
もしや、ファイルの絶対パス(単なる文字列)をクリップボードに格納して(コピー)、その格納された絶対パスを利用してファイルを「貼り付け」たいんじゃなくて、ファイルの絶対パスを取得する方法から知りたいんでしょうか?
そもそも、
単にマウスの右メニューで任意のファイルをコピーして貼り付けたいって、そのマウスはどこのファイルを参照すべきことになっているんでしょうか?(意味不明?)
生憎、ウィンドウズのマウスを乗っ取って(?)右クリックした場合に表示されるポップアップメニューを拡張する方法は分からないのでそこら辺は、お手上げなんですけど...。
あと、貼り付けるにも貼り付ける場所、対象となる絶対パスが必要になるんですよね。もしやその絶対パスの取得の方法も実装してないんでしょうか?
ジョンさんはファイラーを作ってるんでしょうか?例えば、リストビューにファイルが表示されてるとして、そのアイテムを右クリックした場合、ポップアップメニューを表示、その中の「コピー」っていう項目を選択されたときの動作を実装したいのであれば答えることが出来ると思うんですけど、ジョンさんがやろうとしていることがイマイチ分からないので無意味な回答になっているような気がします。
> 「コピー」だけはマウスを使わずにこの一連の作業を実現したかったのですが。
これも、失礼なんですけど意味不明な文章で、ハテナ、です...。
一度だけコピーして何度も貼り付けるってのはウィンドウズでも出来るし、...ハテナ。
コピーを選択した場合、設定されている場所(複数?)に自動的に貼り付けたいのか、ハテナ。
まぁまずはどういったソフトを開発しようとしているのか詳しくお聞かせください!さぁ!(ちょっとテンション高い)
なるほどなるほど。
Posted: 2006年10月10日(火) 23:14
by 7
よ~く分かりました。
AB側でウィンドウズの行うファイルのコピーを行い、ウィンドウズ側でもファイルの貼り付けが出来るようにしたいってことですね。
勿論、明日も仕事が有るので細かいことは明日に回すとして、とりあえず、
CF_HDROPっていうクリップボードのフォーマットを調べてみて下さい。
すると以下のようなサイトが引っかかります。
http://homepage2.nifty.com/Mr_XRAY/Halb ... /N022.html
http://homepage3.nifty.com/m-and-i/tips/copypaste.htm
http://sapporo.cool.ne.jp/tanomi/qanda/a055.html
なんとなくですが、ActiveBasic側でペーストするのは簡単そうですが、ActiveBasic側でコピーするのは難しそうです...。
AB側で
CF_HDROPというクリップボードフォーマットに沿ったデータを設定してやれば良いだけなんじゃないかと思うんですけどね。
そうするには、という話になると、DROPFILES構造体(DROP構造体?)に必要な情報を格納、その構造体のポインタを
CF_HDROPに格納、するとウィンドウズ側でペーストできるようになるんじゃないか?と思うんですけど...。
プログラミング、始めたばかりで難しいかもしれませんけど、ご自分で挑戦する姿勢も必要です。
以下の構造体について調べてみても解決の糸口が見つかるかもしれません。見つからないかもしれません。
コード: 全て選択
Type DROPFILES
pFiles As DWord
pt As POINTAPI
fNC As BOOL
fWid As BOOL
End Type
Posted: 2006年10月10日(火) 23:25
by ジョン
7さんありがとうございます。
たくさんの材料とヒントを頂き感謝です。
研究してみます。
明日の仕事頑張ってください。
Posted: 2006年10月11日(水) 19:43
by 7
http://homepage1.nifty.com/MADIA/vb/vb_ ... 80042.html
う~ん...?上記を参考にしてればいずれ出来るような気がしないでもないような...。
DROPFILES構造体にデータを格納したり、LPSTR型にでもファイル名を格納しておいて、HGLOBAL型にGlobalAlloc()関数の戻り値を格納、VoidPtr型にでもその戻り値を引数に取るGlobalLock()関数の戻り値を格納、そのメモリブロックに対して、memcpy()関数でDROPFILES構造体のデータとLPSTRのデータをコピー、SetClipboardData()関数で
CF_HDROPに対し、そのメモリブロックを設定、するとウィンドウズの「貼り付け」が有効になるような気がするんですけど...。(気がするだけです)
今夕食を食べている最中なんですけど、そうじゃなくてもプログラミングの為に割く暇が有りません...。
しかも「OLE」という嫌な単語を見かけました。OLE操作が必要になると自分の技術力ではたぶんお手上げです。
ど、どなたかバトンタッチを...!
Posted: 2006年10月12日(木) 22:58
by 7
いい感じのトコまで出来たっぽいです。
「貼り付け」を実行すると「ファイルをコピーできません。送り側のファイルまたはディスクから読み取れません。」のエラーが出ます。
急いで書いた適当なコードですのであしからず。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Type DROPFILES
pFiles As DWord
pt As POINTAPI
fNC As BOOL
fWid As BOOL
End Type
Dim df As DROPFILES
Dim FileName[MAX_PATH-1] As Byte
Dim hMem As HGLOBAL
Dim lpVoid As VoidPtr
lstrcpy(FileName,/* ファイルの絶対パス */)
df.pFiles=SizeOf(DROPFILES)
df.pt.x=0
df.pt.y=0
df.fNC=FALSE
df.fWid=TRUE
hMem=GlobalAlloc(GHND,df.pFiles+lstrlen(FileName)+1)
lpVoid=GlobalLock(hMem)
memcpy(lpVoid,VarPtr(df),df.pFiles)
memcpy(lpVoid+df.pFiles,FileName,lstrlen(FileName))
GlobalUnlock(hMem)
If OpenClipboard(hMainWnd) Then
EmptyClipboard()
SetClipboardData(CF_HDROP,hMem)
CloseClipboard()
End If
続きはまた明日。それではお休みなさいませ...。
出来ました。
Posted: 2006年10月13日(金) 20:17
by 7
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
' 変数FileNameにファイルの絶対パスを格納する
Dim FileName[MAX_PATH-1] As Byte
Dim df As *DROPFILES
Dim hMem As HGLOBAL
Dim p As LPSTR
lstrcpy(FileName,/* ファイルの絶対パス */)
hMem=GlobalAlloc(GHND,SizeOf(DROPFILES)+lstrlen(FileName)+2)
p=GlobalLock(hMem)
df=p As *DROPFILES
df->pFiles=SizeOf(DROPFILES)
df->pt.x=0
df->pt.y=0
df->fNC=TRUE
df->fWid=FALSE
p+=SizeOf(DROPFILES)
lstrcpy(p,FileName)
p+=lstrlen(p)+1
lstrcpy(p,Chr$(0))
GlobalUnlock(hMem)
If OpenClipboard(hMainWnd) Then
EmptyClipboard()
SetClipboardData(CF_HDROP,hMem)
CloseClipboard()
End If
自分の環境ではとりあえず、一つのファイルをクリップボードにコピーすることができました。ウィンドウズ側で「貼り付け」を実行できます。
よく理解しないままで書いたし、どっか間違えてるかもしれません...。