UNICODEの場合の印字長 – プログラミング – Home

通知
すべてクリア

[解決済] UNICODEの場合の印字長


aharen
 aharen
(@aharen)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

WindowsXP VC++6.0SP6 SDK(アップデート版)
プロジェクトの設定は C/C++タブに _UNICODE リンクのアウトプットに
wWinMainCRTStartupです
スケルトンは SDIです

CString s1,s2;
int x1,x2,y1,y2,len;

void CTestView::OnDraw(CDC* pDC){

なにがしかの処理の後
pDC->TextOut(x1,y1,s1);

なにがしかの処理の後 同じ行の異なる位置に
pDC->TextOut(x2,y1,s2);

その後なにがしかの処理

}

pDC->TextOut(x1,y1,s1);によりs1を印字(画面上に表示するのも便宜上印字ということ
ばを
                    使わせていただきます)
  したあとそのすぐ右の位置から
pDC->TextOut(x2,y1,s2);によりs2を印字するのが目的です

MBCSの場合ですと len = s1.GetLength()でながさを取得してそれに
半角1文字の印字幅( ここではhabaとします )かけて すなわち

len * haba で計算できるのですが

UNICODEだとどのようにすればよろしいのでしょうか


引用未解決
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

すぐ右でいいなら発想を逆にして s1+s2 を TextOut すれば簡単


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> MBCSの場合ですと len = s1.GetLength()でながさを取得してそれに
> 半角1文字の印字幅( ここではhabaとします )かけて すなわち
> len * haba で計算できるのですが

等幅フォント決めうちならそれでいいかもしれんけど、
そうじゃなかったら iiiii と MMMMM の幅はふつー異なりますけども…


返信引用
aharen
 aharen
(@aharen)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

説明不足だったようです

たとえば一例として s1 = _T(abc東京); だったとしますと

印字長 は haba * 7 になりますが

この 7 に相当する数値を得たいわけです

これを len となづけて

x2 = x1 + len; と計算して

pDC->TextOut(x2,y1,s2);

とすればよいと考えているわけです

それから一回きりだったら tetrapodさんがおっしゃるようにできますが
ひとつ上の目的としては

int Next_X_Position,Next_Y_Position;
void CTestView::DisplayString(CString InputString){

}
Next_X_Position,Next_Y_Position はすでに表示してある文字列の
すぐ右の位置を示します InputStringには表示したい文字列をいれます
int Next_X_Position,Next_Y_PositionはInputStringをもとに
この関数が更新します
DisplayStringのなかをコーディングするのに
質問したことが必要になると考え質問したわけです


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>この 7 に相当する数値を得たいわけです
単にバイト数がほしいならば、Shift_JISコードに変換して算出するんですかね。
ただ、Unicodeなんで対応していない文字があると思います。
(1文字ずつ見て、Shift_JISコードでの半角に当たるかどうかチェックするのが妥当か
な。)


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

別解:

byteを要求されるCDC::TextOutでなく、
文字数を渡す::TextOut (UNICODE版)を使う。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

最終的に表示幅が欲しいなら、GetTextExtent でよいのでは。

または、位置更新モードで TextOut して、
GetCurrentPosition で次の表示位置を得るとか。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

出力位置を計算するのに,不確かな方法を使うのではなく,
出力幅を得るCDC::GetTextExtentのような関数を使って計算するようにすればよいので
は?
# そもそも記号はFIXED_PITCHでも幅が異なるものですし。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

むっちゃ御意。GetTextExtent32 のほうが良いらしいけど。

それとは別に
DisplayString(const CString& InputString) のほうが良いかもしれない。
個人的には DisplayString(const TCHAR* s) も欲しい気がする。
# っていうか後者があれば前者はイラン


返信引用
aharen
 aharen
(@aharen)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

> 等幅フォント決めうちならそれでいいかもしれんけど、
> そうじゃなかったら iiiii と MMMMM の幅はふつー異なりますけども…

そうですね プロポーショナルの場合など幅は一定ではないですね

> 単にバイト数がほしいならば、Shift_JISコードに変換して算出するんですかね。

そうですね MBCSに変換したと仮定したときのバイト数がわかれば
問題解決と思っていました
調べてみましたら それは WideCharToMultiByte や wcstombs など使えば解決するよ
うです
ところが上記に指摘されたように幅が一定でない場合もありますので
この方法は使えないようです

> GetTextExtent
> または、位置更新モードで TextOut して、GetCurrentPosition で次の表示位置を得る
とか。

あとでも述べますがこの二つはいまのところ必要不可欠のようです

> 出力位置を計算するのに,不確かな方法を使うのではなく,
> 出力幅を得るCDC::GetTextExtentのような関数を使って計算するようにすればよいので
は?
> # そもそも記号はFIXED_PITCHでも幅が異なるものですし。

上記と同様 おっしゃるとおりです

> むっちゃ御意。GetTextExtent32 のほうが良いらしいけど。

GetTextExtentと使いくらべてみます

> それとは別に
> DisplayString(const CString& InputString) のほうが良いかもしれない。

関数(const CString& InputString)
関数(CString InputString)
のちがい(どこにどういう影響のちがいがでるのか)が私にはまだよく
わからないので勉強します(値渡しと参照渡しのちがいかな)

> 個人的には DisplayString(const TCHAR* s) も欲しい気がする。
> # っていうか後者があれば前者はイラン

わたくしには CString型のほうが扱いやすいようです

-----------------------------------------------------------------------------
ご指摘をふまえ その後調べた結果をご報告します

(1)pDC->SetTextAlign(TA_UPDATECP);
   で自動更新を設定すれば文字幅は気にせずに
   pDC->TextOut(0,0,s);
   でどんどん文字列を追加表示して良いようです

(2)ただし 右端で折り返してくれないので
   GetCurrentPositionやGetTextExtentを使って
   情報を取得して
   必要とあらば行を改めることをします

(3)改行または任意の位置から始めたいときには
   MoveToなどを使います

個々にご芳名は挙げませんが皆様大変ありがとうございました


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました