環境:WinXP, VS2005, MFC使用
クリップボードを使いたく,その方法を検索しました.
クリップボードにテキストデータをコピーするための大まかな手順は
OpenClipboard();
EmptyClipboard();
HGLOBAL hMem=GlobalAlloc(GMEM_MOVEABLE, 必要サイズ);
hMemの領域にデータを書き込む
SetClipboardData( CF_TEXT, hMem );
CloseClipboard();
のような感じであることはわかったのですが,
検索で引っかかった多くの場所で,GlobalAllocで確保した領域は
「解放しなくてもいい」
あるいは
「解放してはならない」
という記述が見受けられました.
しかし,MSDNのSetClipboadData()の説明では
「CloseClipboard 関数を呼び出すまでは、そのハンドルを解放することや、ロックし続
けることを避けなければなりません。」
と書かれているだけで,勝手に後始末してくれるようなことは書かれていないように思い
ます…
CloseClipboard()の後で,
GlobalFree( hMem );
をするべきなのでしょうか? それともしてはいけないのでしょうか?
クリップボードを使ったのは遥か昔なので忘れてしまったが、
> をするべきなのでしょうか? それともしてはいけないのでしょうか?
してはいけないでしょう。
MSDNより
EmptyClipboard
クリップボードを空にし、クリップボード内のデータのハンドルを解放します。同時
に、クリップボードを開いたウィンドウに、クリップボードの所有権を与えます。
クリップボードの動き、とは、書き込み側が
1.OpenClipboard() // 開く
2.EmptyClipboard() // 現在の確保メモリを開放
3.GlobalAlloc()、GlobalLock() // 書き込むメモリを確保
4.上記メモリに書き込む
5.GlobalUnlock() // メモリのロックを解除
6.SetClipboardData() // メモリをクリップボードにセット
7.CloseClipboard() // 閉じる
となります。開放するのは
(A)取得側が開放した(当然メモリは無効になる)
(B)別のアプリがEmptyClipboard()した(当然メモリは無効になる)
の要件だけですので
設定側が、自ら設定したメモリを開放していけないのは当たり前ですよね(笑)。
また、(B)が可能なのはCloseClipboard()されている場合だけですので、
自分のアプリ内で整合さえしていれば、他人のやることなど
知ったことではありません(vv;)。
>「CloseClipboard 関数を呼び出すまでは、そのハンドルを解放することや、ロックし続
>けることを避けなければなりません。」
MSDNによると、この文章のちょっと前に
「SetClipboardData を呼び出した後で、システムは、hMem パラメータで指定されたオブ
ジェクトを所有します。」
とある。
つまり、「システムが所有する」ので、放置していいです。
ところでMSDNの英文だとこうなってる。
>The application may not write to or free the data
> once ownership has been transferred to the system,
>but it can lock and read from the data
>until the CloseClipboard function is called.
これ、
「データをオーナー(システム)に一旦引き渡したら、書いたり、開放してはいけない。
ですが、CloseClipboardするまでなら、ロックしたり、読み込みはしていい」
だと思うのですが・・・
VS2003のHelpは日本語と同様で
The application can read the data, but must not free the handle or leave
it locked until the CloseClipboard function is called.
(The application can access the data after calling CloseClipboard).
よく使われるAPIの説明が(ひっとしたらwin32の初めから)長期間
間違っていたのかもしれません。
皆様 ありがとうございます.
VS2005のヘルプの英文もロマ様が示して下さったものと同様であったため
CloseClipboardを呼んだ後なら解放していいのか?と思ってしまいました.