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:06:54 もか 返信 削除
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
[2378] Re:クリップボード関数の謎引数
> nMode -1:バイナリモード
このモードは、ビットマップとかCF_LOCALE、他のエディタのクリップボード形式などを読み書きする時に使います。
これらの関数は、CF_TEXT/CF_UNICODETEXTでも読み書きが可能なように実装されていますが、主戦場は特殊用途です。
普通のテキストは、Get(Set)Clipboard関数を使ってください、という方針です。
サクラでは、一番使うのは矩形データの確認、登録です。

CygwinのときにCF_TEXTがUTF-8だったりします(最近は不明)。
Visual StudioのCF_TEXTもUTF-8になっているらしいです。
そういう場合には、コード指定が必要です。
参考:https://github.com/xyzzy-022/xyzzy/issues/73

また日本語環境でNEC/IBM拡張漢字を区別して扱う場合に必須です。
どういうことかというと、
1. テキストファイルにはNEC/IBM拡張漢字がある
2. サクラv2で読み込むとたぶんNECはUnicodeに変換されIBMは特殊なサロゲート断片になる
3. それをそのまま普通にコピーすると、相手のソフトでIBMがゴミとして貼り付く
4. SetClipboardByFormat(data, "CF_TEXT", 0, -1)で貼り付けると、クリップボードがIBMが元の符号位置に戻ったSJISデータになる
6. 相手に貼り付けると、無事IBM/NECが区別されるか、WindowsのCF_UNICODETEXTの自動変換で統合されて貼り付けられる
という風になっていて、データが変更されると困る用途に適しています。

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:49:42 ばぼ 返信 削除
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
[2380] Re2:クリップボード関数の謎引数
あるべき姿について、了解しました。

▼ もかさん
> 主戦場は特殊用途です。

結局、第一引数(Getのout引数)は「配列」ってことですね。


> CygwinのときにCF_TEXTがUTF-8だったりします

ぶっちゃけ、それはCygwinのバグですね。
Cygwinとの互換性は、意識的に意識しないようにしております。

元々Windows95にPOSIXレイヤを構築するプロジェクトです。
POSIX依存のプログラムをWindows95で利用するためのもので、
Windows向けに書かれたプログラムのためのものじゃないです。

もちろん、win7向けのCygwinというのも存在しますが、
「POSIXプログラムのための環境」がCygwinの本質です。
Windows向けプログラムをビルドしようとするのは誤りです。
WindowsでGCCを使うためのMinGWとは目的が違います。
目的外利用で発生した問題は、ユーザの責任じゃないっす。


> また日本語環境でNEC/IBM拡張漢字を区別して扱う場合に必須です。

この問題の対処法を「独自ロジック廃止」で考えてるから
話があわないんだろうな…と感じました(マテ


> マイクロソフトが何といってるか知りませんが、ロケールって言ってるけど、UTF-8というロケールは存在しないので「言語」で「エンコード」を縛ることはできません。

MS> ロケール関数にunicodeを指定すると失敗します。(サポートしません。)

windowsロケールはansiのmultibyteをunicodeのwidecharに変換するためのものなので、unicodeファミリ内の変換は自分でやってね、ということらしいです。その割にはAPIがCP_UTF8に対応しとるんですが。


続く...

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.010]