HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0114
こいるクリップボードにテキストをセットする際のWin32APIの使い方5解決


こいる

リンク

2021/1/14(Thu) 16:02:19|NO.92075

Win32APIを用いて、クリップボードにテキストをセットする処理について質問です。


▼1.GlobalAlloc関数などを呼び出すタイミング
メモリ確保、データをメモリにコピーするタイミングは、
OpenClipboard関数を呼び出してからなのか、呼び出す前なのか?

下記ページには、「クリップボードのオープンとクローズは一瞬のうちに行わなければならず
最低、ユーザーが他のウィンドウに移行する前にはそれを閉じる必要があります」とかいてあり、
OpenClipboardの前に確保するようにありますが、
http://wisdom.sakura.ne.jp/system/winapi/win32/win90.html

マイクロソフトのページでは、OpenClipboardの後に確保しているコードがあります。
https://docs.microsoft.com/ja-jp/office/vba/access/concepts/windows-api/send-information-to-the-clipboard

どちらが正しいのでしょうか?


▼2.GlobalAlloc関数で確保する、GMEM_FIXED(固定メモリ)と、GMEM_MOVEABLE(可動メモリ)の違い
違いと、どちらが良いのかを教えてください。


▼3.OpenClipboardの引数を0にしても、SetClipboardDataは成功する
下記のマイクロソフトのページで、
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-emptyclipboard

次のように書いてありますが、
原文「If the application specifies a NULL window handle when opening the clipboard,
EmptyClipboard succeeds but sets the clipboard owner to NULL. Note that this causes SetClipboardData to fail.」

Google翻訳「アプリケーションがクリップボードを開くときにNULLウィンドウハンドルを指定した場合、
EmptyClipboardは成功しますが、クリップボードの所有者をNULLに設定します。 これにより、SetClipboardDataが失敗することに注意してください。」


OpenClipboardの引数を0にしても、普通にSetClipboardDataは成功します。
↓確認用のスクリプトです

#uselib "kernel32.dll" #func GlobalAlloc "GlobalAlloc" sptr,sptr #func GlobalLock "GlobalLock" sptr #func GlobalUnlock "GlobalUnlock" sptr #func GlobalFree "GlobalFree" sptr #define GHND 0x42 #uselib "user32.dll" #func OpenClipboard "OpenClipboard" sptr #func EmptyClipboard "EmptyClipboard" #func SetClipboardData "SetClipboardData" sptr,sptr #func CloseClipboard "CloseClipboard" #define CF_TEXT 1 #define SET_TEXT "test" text_size = strlen(SET_TEXT)+1 hGlobalMem = GlobalAlloc(GHND, text_size) // メモリ確保 lpClipboard = GlobalLock(hGlobalMem) // ロックしてポインタ取得 // 確保したメモリに、テキストをコピー dupptr clipboard_data, lpClipboard, text_size, 2 clipboard_data = SET_TEXT GlobalUnlock hGlobalMem // ロック解除 OpenClipboard 0 // 0でも成功する if stat{ EmptyClipboard // クリップボード初期化、所有権ゲット SetClipboardData CF_TEXT, lpClipboard // クリップボードにセット CloseClipboard }else{ GlobalFree hGlobalMem // 開けなかった場合は、自分でメモリ解放する } // セットされているか確認 #include "hspext.as" sdim clipboard_text, text_size clipget clipboard_text, text_size mes "セットしたテキスト: \""+SET_TEXT+"\"" mes "クリップボードの内容: \""+clipboard_text+"\""

なぜでしょうか?
それとも、別の意味があるのでしょうか?



この記事に返信する


こいる

リンク

2021/1/15(Fri) 19:00:38|NO.92081

質問はこの3つですが、一部だけでも回答してくださると嬉しいです。



PPP

リンク

2021/1/15(Fri) 19:38:46|NO.92084

動けばよいという考えなのであまり深く考えないから真っ当な回答はできないけれど、
取り合えず2に関しては
https://rarara.org/community/programming/%E5%9B%BA%E5%AE%9A%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%A8%E7%A7%BB%E5%8B%95%E5%8F%AF%E8%83%BD%E3%83%A1%E3%83%A2%E3%83%AA/
このサイトで似たような質問があるので参考になるかも?

あとはクリップボードGlobalAlloc辺りで検索すれば回答待ちより早く情報を得ることが出来そうな気はする。



zakki

リンク

2021/1/16(Sat) 20:46:53|NO.92091

1は他アプリの動作を妨げないように極力OpenClipboard〜CloseClipboardの間隔を短くするのが行儀が良くて
可能なら事前に全部準備しておいたほうがいいのでしょうが例のような短いテキスト程度なら大きな差はなさそうです。
OpenClipboardのあとにwaitしたり長いループ回したりすると他ソフトでのコピペがその間動作しません。

3は今は動いていても、パラメーターの組み合わせや他のバージョンのWindowsで動かないことがあったり
将来のWindows Updateなどで動かなくなったりしても仕様ですってことになるのんじゃないかと。



こいる

リンク

2021/1/18(Mon) 15:48:26|NO.92099

返信ありがとうございます。
返信遅くなってすみません。


>PPPさん
リンク先のページを見て、もう少し調べたところ、
どうやら、昔は物理的な固定・可動だったけど、今はプログラムからみた仮想的な固定・可動らしく、どっちを使っても大して変わらないみたいです。
↓参考
http://www.kumei.ne.jp/c_lang/sdk/sdk_82.htm
https://okwave.jp/qa/q5468565.html

しかし、何かあっても心配なので、よく使われているGMEM_MOVEABLE(可動メモリ)の方を使いたいと思います。


>zakkiさん
なるほど。
1は、よりリスクの少ない「OpenClipboardの前」にするように、
3は、0を渡さずに、リスクの少ないhwnd(HSPのウィンドウハンドル)を渡して呼び出したいと思います。


お二人ともありがとうございました。



ウンチョコレートカカオ

リンク

2021/1/27(Wed) 16:22:07|NO.92166

hspext利用したらかんたんにできると思います



ONION software Copyright 1997-2023(c) All rights reserved.