[スレッド全体]

2016/8/26 (金) 17:31:08 ばぼ  
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
[2377] クリップボード関数の謎引数
愚痴です。
v2.1で実装されたマクロ専用関数の引数定義が
「なんかおかしくね?」というネタなので、
大多数のユーザーには関係のない話かと思います。

CClipboard::GetClipboradByFormat
CClipboard::SetClipboradByFormat

nMode -2:通常のサクラの処理, -1:バイナリモード, それ以外:文字コード
nEndMode -1:文字コードに依存 0:GlobalSize 1:strlen 2:wcslen 4:wchar32_tの文字列

nMode==-2は良いのです。
通常のサクラ=unicode、ですから。
nMode==-1が存在する理由と、文字コードの意味が分からんとです。

windowsはCF_UNICODETEXT形式が存在する場合、
CF_TEXT形式を要求したUNICODE非対応アプリに対して、
ACPによる自動変換を提供します。
つまり、自前で変換する必要はありません。
自前で変換してCF_TEXTを突っ込むと副作用もありますし。

サクラはwindowsロケールが対応しないコードページの、
いくつかに対応しています。(JisとかEucとかUnicodeとか)

SetClipboradByFormat("美乳", "CF_TEXT", 2, -1)
※"美乳"はEUCにしか存在しないコード値を持つ。

とした場合、windowsはCF_TEXTにEUCの"美乳"を突っ込みます。
この状態でCF_UNICODETEXTを要求した場合、
windowsによる自動変換は"ja-JP.932"で行われます。
当然、化けますよね。。。
アプリの作りとしては、windowsロケールが対応しないコードページを使っている場合には、引数指定をガン無視してUNICODEで突っ込む対応が必要になるような気がするのです。

でも、そうすると引数の存在意義が…
「意味わからん」というのはそういうことです。

nEndModeについては存在意義が不明です。
CF_TEXTとCF_UNICODETEXTを指定した場合のデータサイズは、
それぞれcharとwchar_tのNUL終端までと決まっています。
これはWindowsAPIの仕様なので勝手に処理してはいかんです。
windowsロケールはunicodeファミリを扱えないので、
UTF32を扱うにはUTF16BEに変換し、unicodeとして突っ込むべきです。


ググってみた感じだと
nMode=0(SJIS)、
nEndMode=-1(文字コード依存)
で使われているみたいです。
※このマクロ関数が実装されてるのはv2系なので
 常に無駄な変換(U→A)が発生するが、
 windowsが勝手に登録するCF_LOCALEは矛盾しないので問題ない。

取得、設定するデータに「文字列以外」を扱えるなら
別な突っ込みになるんですけど、
定義を見る限り、第一引数はVT_BSTR想定だし。。。

第一引数がVT_ARRAYを受け付ける前提で、
nMode==-1(バイナリ)、かつ
nEndMode==0(サイズをGlobalSizeで取得)な場合だけ
意味があるnEndModeの存在意義。

かと言って、VT_ARRAYにして
CF_DIBとか使えるようにしたとして、
そういうマクロを書く人がいるのかどうかとか、
すっごく微妙。。。



2016/8/26 (金) 20:08:53 もか  
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
[2379] Re:クリップボード関数の謎引数
(続き)
>SetClipboradByFormat("美乳", "CF_TEXT", 2, -1)
>当然、化けますよね。。。

EUC-jpをCF_TEXTに突っ込むのは想定外ですが、そういうアプリが存在していてもおかしくないのです。
例えば、存在するかしりませんがEUC-JPに設定されたCygwinとか。
var s = GetClipboradByFormat("CF_TEXT", 2, -1)
InsText(s);
で「美乳」が貼り付けられるので、そういう変なアプリと通信したい場合には、これでいいと思います。
もちろんCF_UNICODETEXTで読み書きするとおかしいですが、それは想定内です。
CF_UNICODETEXTでも同時に読み書きができるようにしたければ、自分でCF_UNICODETEXTを設定すれば問題ないです。
マイクロソフトが何といってるか知りませんが、ロケールって言ってるけど、UTF-8というロケールは存在しないので「言語」で「エンコード」を縛ることはできません。

汎用的なnModeの使い方としては、
SetClipboardByFormat(data, "HTML Format", 4, -1);
が代表例です。HTML FormatはUTF-8と決まっています。

>nEndMode
他のエディタを見れば分かりますが
「クリップボードを最後まで読み込む」関数と
「クリップボードをNUL文字まで読み込む」関数
が用意されていることがあります。それに対応するための処置です。
WindowsのCF_(UNICODE)TEXTではNUL文字までと決まっていますが、実情はそうとは限りません。
あとは独自フォーマットでは、NUL終端の後に違うデータが続いていることもあります。
例えば、サクラが設定したCF_(UNICODE)TEXT形式では途中にNUL文字が含まれることがあります。
UTF-32についてはおまけですが、独自形式のフォーマットがUTF-32形式互換である場合を想定していて、
決してCF_(UNICODE)TEXTで使うためではありません。

SetClipboradByFormatでCF_TEXTを登録するとき、サクラがCF_LOCALEを正しく登録しないのは、
うまく動くか分かりませんが、"CF_LOCALE"も使えるようになっているので、自分で設定すればいいんだと思います。

とりあえず、引数に意味不明な組み合わせがあることは確かです。
そのへんは、汎用性のために犠牲になったと思ってください。

2016/8/27 (土) 13:50:52 ばぼ  
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
[2381] Re2:クリップボード関数の謎引数
そういえば、visual studioでコピーすると、
Rich Text Formatなデータも追加されるんですが、
サクラはこれには対応しないんでしょうか?

(続き)

> 汎用的なnModeの使い方としては、
> SetClipboardByFormat(data, "HTML Format", 4, -1);
> が代表例です。HTML FormatはUTF-8と決まっています。


CF_HTMLはテキストじゃないので自動変換されないです。
ビットマップとかと同じバイナリデータ。

たしかにjavascript内でutf8作るとかありえませんし、便利ですね。
ただ、4=UTF-8を覚えるには熟練を要しそうです。
文字列リテラルによる指定を可能にする改善提案…(何を受け付けるかでモメそうですが)

> >nEndMode
> 他のエディタを見れば分かりますが


「他のエディタが対応してるから」は
機能が適切かどうかの指標にならんとです。
たぶんそういう場合、本来のネイティブデータが
別形式で登録されているはずなので、
そちらに対応するのが正しいあり方な気がします。
というか、エディタ側にはその機能ありませんよね(ご愛敬)

> "CF_LOCALE"も使えるようになっているので、
> 自分で設定すればいいんだと思います。


サイズとエンディアンの問題があるので
スクリプトから突っ込もうとすると微妙な感じになります。

uint32_t lcid = 0x411; //日本語
char pLcid1[] = { 0x11, 0x04, 0, 0 }; //普通のCPU
char pLcid2[] = { 0, 0, 0x04, 0x11 }; //古いmacとかサーバー機
SetClipboardByFormat(data, "CF_LOCALE", -1, 0);

powerpc搭載型の旧式macは無視してよいので、
pLcid1の値をdataに埋め込んでやれば一応動く...


> とりあえず、引数に意味不明な組み合わせがあることは確かです。
> そのへんは、汎用性のために犠牲になったと思ってください。


というわけで、思いついたときに「見直し」をかけて
パラメタチェックを追加してみたりするのもいいんではないかと。。。(鬼

[▼次のスレッド]
INCM/CMT
Cyclamen v3.81
[ut:0.010][st:0.000]