文字列幅を知るには

[戻る]
Eriko 2008/10/10(金) 20:14:30
お世話なります
環境 WinXP VC++2008 Express Edition
デザイン Windows フォームアプリケーション
     デフォールトのフォームに
     ボタン一つ button1
コード 末尾のとおりです
状況 同じ内容の文字列(国という字を30個)を
   MS 明朝とMS P明朝で表示させました
   実際の表示幅は約一文字分違うのに
   MeasureString関数で測った値は同じでした
   正しく測れる方法をご存知ありませんでしょうか


private: System::Void button1_Click(System::Object^  sender, 
System::EventArgs^  e) {
    Graphics^ g = this->CreateGraphics();

    //文字列
    String^ str1 = "国国国国国国国国国国国国国国国国国国国国国国国国国国国
国国国";

    //フォント
    System::Drawing::Font^ Font1 = gcnew System::Drawing::Font("MS 明
朝",11.25);
    System::Drawing::Font^ Font2 = gcnew System::Drawing::Font("MS P明
朝",11.25);
    //ブラッシュ
    SolidBrush^ Brush1 = gcnew SolidBrush( Color::Black );

    //文字列描画
    float x1 = 0.0F; float y1 = 200.0F; float y2 = 215.0F;
    g->DrawString( str1, Font1, Brush1, x1,y1 );    //描画1
    g->DrawString( str1, Font2, Brush1, x1,y2 );    //描画2

    //文字列幅計測&表示
    float y3 = 250.0F;
    float TextWidth1 = g->MeasureString(str1,Font1).Width;
    float TextWidth2 = g->MeasureString(str1,Font2).Width;
    String^ str2 = String::Format("文字列1幅 = {0} \r\n文字列2幅 =
 {1}",TextWidth1,TextWidth2);
    g->DrawString( str2, Font1, Brush1, x1,y3 );    //計測地表示
}

Blue 2008/10/11(土) 02:09:01
Graphics::MeasureCharacterRangesを使う。

Graphics^ g = this->CreateGraphics();
String^ str1 = L"国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国";
Drawing::Font font1(L"MS 明朝", 9), font2(L"MS P明朝", 9);
SolidBrush brush1(Color::Black);

float x1 = 0.0f, y1 = 200.0f, y2 = 215.0f, y3 = 250.0f;
g->DrawString(str1, %font1, %brush1, x1, y1);
g->DrawString(str1, %font2, %brush1, x1, y2);

StringFormat sf;
array<CharacterRange>^ characterRanges = {CharacterRange(0, str1->Length)};
sf.SetMeasurableCharacterRanges(characterRanges);
RectangleF layoutRect1(x1, y1, 500, 100);
RectangleF layoutRect2(x1, y2, 500, 100);
array<Drawing::Region^>^ stringRegions1 =
    g->MeasureCharacterRanges(str1, %font1, layoutRect1, %sf);
array<Drawing::Region^>^ stringRegions2 =
    g->MeasureCharacterRanges(str1, %font2, layoutRect2, %sf);
String^ str2 = String::Format(L"文字列1幅 = {0} \r\n文字列2幅 = {1}",
    stringRegions1[0]->GetBounds(g).Width,
  stringRegions2[0]->GetBounds(g).Width);
g->DrawString(str2, %font1, %brush1, x1, y3);

delete g;

Blue 2008/10/11(土) 02:18:43
TextRenderer::MeasureTextでうまくいくかと思ったけど、
何がだめかわからない。

Drawing::Size ps(int::MaxValue, int::MaxValue);
String^ str2 = String::Format(L"文字列1幅 = {0} \r\n文字列2幅 = {1}", 
 TextRenderer::MeasureText(g, str1, %font1, ps, TextFormatFlags::NoPadding).Width,
 TextRenderer::MeasureText(g, str1, %font2, ps, TextFormatFlags::NoPadding).Width
);
g->DrawString(str2, %font1, %brush1, x1, y3);

参考
http://dobon.net/vb/dotnet/graphics/measurestring.html

Blue 2008/10/11(土) 02:40:39
>何がだめかわからない。
Graphics::DrawStringとTextRenderer::DrawTextの描画結果がずれているからでした。
>str1 = L"国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国";
だとTextRenderer::DrawTextはどちらのフォントにしても同じでした。

"あいうえお"
みたいなのであれば差が出ます。

Eriko 2008/10/11(土) 10:41:45
[[解決]]
blueさん ありがとうございました 教えてくださった
http://dobon.net/vb/dotnet/graphics/measurestring.html
をはじめにあちこちナビしながら
MSDNの
http://msdn.microsoft.com/ja-
jp/library/system.windows.forms.visualstyles.visualstyleelement(VS.80).aspx
を参考にTextRenderer系の
MeasureText DrawTextを使うことにしました
コードはつぎのとおりです



private: System::Void button1_Click(System::Object^  sender, 
System::EventArgs^  e)
{
    Graphics^ g = this->CreateGraphics();


    //文字列
    String^ str1 = "国国国国国国国国国国国国国国国国国国国国国国国国国国国
国国国";

    //フォント
    System::Drawing::Font^ Font1 = gcnew System::Drawing::Font("MS 明
朝",11.25);
    System::Drawing::Font^ Font2 = gcnew System::Drawing::Font("MS P明
朝",11.25);

    int Width1 = TextRenderer::MeasureText(str1,Font1).Width;
    int Width2 = TextRenderer::MeasureText(str1,Font2).Width;
    int Height1 = TextRenderer::MeasureText(str1,Font1).Height;
    int Height2 = TextRenderer::MeasureText(str1,Font2).Height;

    Rectangle Rect1 = Rectangle(0,100,Width1,Height1);
    Rectangle Rect2 = Rectangle(0,150,Width2,Height2);
    Pen^ Pen1 = gcnew Pen( Color::Black );

    g->DrawRectangle(Pen1,Rect1);
    g->DrawRectangle(Pen1,Rect2);

    //文字列描画
    TextRenderer::DrawText(g, str1,
        Font1, Rect1, Color::Blue,
        TextFormatFlags::WordBreak);
    TextRenderer::DrawText(g, str1,
        Font2, Rect2, Color::Blue,
        TextFormatFlags::WordBreak);

}

なをusing namespace はトータルとして
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    using namespace System::Text;
    using namespace System::Collections::Generic;
    using namespace System::Reflection;
    using namespace System::Windows::Forms::VisualStyles;
を使いましたが
おそらく不要なのもあると思います

では

Blue 2008/10/11(土) 15:27:03
Desposeが必要なものはdeleteしましょう。

>Graphics
>System::Drawing::Font
>Pen

私のコードはあえてgcnewをつかわなくてもよいものはそうしています。

ちなみに
>Pen^ Pen1 = gcnew Pen( Color::Black );
はPens::Blackをつかうと便利。

古いスレッドには追加発言できません。