Visual Basic 中学校 掲示板
投稿内容
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
>
投稿一覧
>
ラベルの文字の綺麗な縦書き表示について
タグの編集...
投稿者
東
 (高校生)   投稿日時
2016/7/27 16:18:48
自分はリッチテキストボックスに入力した文字をラベルとしてパネルに表示し、印刷するということをしています。自分はラベルのロケーションにより文字を縦書きしているのですが、印刷した時に文字が曲がってしまっています。調べては見たのですが、どれもピクチャーボックスに描画するという方法しかありません。そこでピクチャーボックスを使わずにラベルの文字を綺麗な縦書き表示にしたいのですが、わかりません。わかる方いましたらお願いします。
リッチテキストボックスで入力してパネルに表示するコードを載せておきます。
Private
Sub
Nryoku_Click(
ByVal
sender
As
Object
,
ByVal
e
As
System.Windows.Forms.MouseEventArgs)
If
Rtext.Text =
"*"
Then
MsgBox(
"テキストを入力してください"
)
Else
If
Mmax < 50
Then
Te = Rtext.Text
Me
.mozi =
New
Label()
Me
.mozi.Name =
"Text1"
Me
.mozi.Text = Te
Me
.mozi.AutoSize =
True
Me
.mozi.Font =
New
Font(
"@明朝"
, 24, FontStyle.Bold)
Me
.mozi.ForeColor = Rtext.ForeColor
Me
.mozi.BackColor = Color.Transparent
mozi.ContextMenuStrip = ContextMenuStrip1
AddHandler
mozi.MouseDown,
AddressOf
mozi_MouseDown
AddHandler
mozi.MouseMove,
AddressOf
mozi_MouseMove
AddHandler
mozi.MouseUp,
AddressOf
mozi_MouseUp
AddHandler
mozi.Click,
AddressOf
mozi_Click
Panel1.Controls.Add(
Me
.mozi)
Rtext.Clear()
Mmax = Mmax + 1
Else
MsgBox(
"これ以上配置できません"
, 16)
End
If
End
If
End
Sub
投稿者
(削除されました)
 ()   投稿日時
2016/7/28 12:32:42
(削除されました)
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2016/7/28 12:36:09
本題からは外れて、縦書きリッチテキストボックスを試作してみました。
コンパイルすると、ツールボックスに「VerticalRichTextBox」が追加されます。
'======= VerticalRichTextBox.vb =======
Imports
System.ComponentModel
Imports
System.Runtime.InteropServices
Imports
System.Windows.Forms
Imports
System.Text
Public
Class
VerticalRichTextBox
Inherits
RichTextBox
Private
Declare
Unicode
Function
LoadLibrary
Lib
"kernel32"
Alias
"LoadLibraryW"
( _
ByVal
libName
As
String
_
)
As
IntPtr
Private
Declare
Unicode
Function
SendMessage
Lib
"user32"
Alias
"SendMessageW"
( _
ByVal
hWnd
As
IntPtr, _
ByVal
Msg
As
Integer
, _
ByVal
wParam
As
IntPtr, _
ByVal
lParam
As
IntPtr _
)
As
IntPtr
Private
Declare
Unicode
Function
FreeLibrary
Lib
"kernel32"
( _
ByVal
hModule
As
IntPtr _
)
As
<MarshalAs(UnmanagedType.Bool)>
Boolean
Private
Const
ES_VERTICAL
As
Integer
= &H400000
Private
Const
EM_SETOPTIONS
As
Integer
= 1101
Private
Const
ECOOP_OR
As
Integer
= 2
Private
Const
WM_KEYDOWN
As
Integer
= &H100
Private
Const
WM_KEYUP
As
Integer
= &H101
Private
hmRichEdit
As
IntPtr = IntPtr.Zero
Public
Sub
New
()
'アジア圏の言語では、ES_VERTICAL を指定すると縦書きモードになります
SendMessage(Handle, EM_SETOPTIONS,
New
IntPtr(ECOOP_OR),
New
IntPtr(ES_VERTICAL))
End
Sub
Protected
Overrides
ReadOnly
Property
CreateParams
As
CreateParams
Get
'ES_VERTICAL は、Rich Edit 2.0 や 3.0 ではサポートされていないため、
'対応したバージョンに書き換える必要があります
hmRichEdit = LoadLibrary(
"msftedit.dll"
)
If
hmRichEdit = IntPtr.Zero
Then
MessageBox.Show(Marshal.GetLastWin32Error().ToString())
Throw
New
Win32Exception(
"内部エラー: LoadLibrary(""Msftedit.dll"")"
)
End
If
Dim
cp
As
CreateParams =
MyBase
.CreateParams
cp.ClassName =
"RICHEDIT50W"
'Rich Edit Version 4.1 を指定
Return
cp
End
Get
End
Property
Public
Overrides
Function
PreProcessMessage(
ByRef
msg
As
Message)
As
Boolean
Select
Case
msg.Msg
Case
WM_KEYDOWN, WM_KEYUP
Dim
keyCode
As
Keys =
CType
(msg.WParam, Keys)
And
Keys.KeyCode
'矢印キーの動作を90度回転させます
Select
Case
keyCode
Case
Keys.Left
msg.WParam =
New
IntPtr(Keys.Down)
Case
Keys.Right
msg.WParam =
New
IntPtr(Keys.Up)
Case
Keys.Up
msg.WParam =
New
IntPtr(Keys.Left)
Case
Keys.Down
msg.WParam =
New
IntPtr(Keys.Right)
End
Select
End
Select
Return
MyBase
.PreProcessMessage(msg)
End
Function
Protected
Overrides
Sub
OnResize(e
As
EventArgs)
Me
.Invalidate()
MyBase
.OnResize(e)
End
Sub
Protected
Overrides
Sub
Dispose(disposing
As
Boolean
)
If
Not
IntPtr.Zero.Equals(hmRichEdit)
Then
FreeLibrary(hmRichEdit)
hmRichEdit = IntPtr.Zero
End
If
MyBase
.Dispose(disposing)
End
Sub
End
Class
投稿者
東
 (高校生)   投稿日時
2016/7/28 21:19:43
作成ありがとうございました。
このコードを使ってみて何か進展があるかもしれないので、やってみたいと思います。
ありがとうございます。
投稿者
東
 (高校生)   投稿日時
2016/8/2 10:22:00
魔界の仮面弁士さんが投稿していただいたコードを使ってみてテキストボックスに縦書き表示することができました。しかしその文字をラベルに表示することができません。
よろしければ教えていただきたいです。
投稿者
東
 (高校生)   投稿日時
2016/8/2 10:22:01
魔界の仮面弁士さんが投稿していただいたコードを使ってみてテキストボックスに縦書き表示することができました。しかしその文字をラベルに表示することができません。
よろしければ教えていただきたいです。
投稿者
shu
 (社会人)   投稿日時
2016/8/2 11:16:40
N88-BASICさんが2016/7/20 13:30:12に質問された
『縦書き印字で下端を揃えたたい』
のスレッドを参考にLabelにオーナードローで描画してみるのは
どうでしょう?
投稿者
(削除されました)
 ()   投稿日時
2016/8/2 11:49:19
(削除されました)
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2016/8/2 11:56:42
Windows Forms や WPF に、縦書き表示用のコントロールはありません。
ご存知のように、そのためのコードを自身で作りこんでいく必要があります。
また、縦書き表示が目的の場合、System.Windows.Forms.Label を使うことはお勧めできません。
標準の横書き機能が実装の邪魔となり、むしろ扱いにくいと思います。
たとえば下記は、ラベルを90度回転させるサンプルです。
フォームデザイナへの対応が不十分ですし、
そもそも求めている縦書き機能とは異なると思いますが。
http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=11698&page=0
このサンプルでは、Label を継承して作成しましたが、
標準の Text プロパティが描画の邪魔になったたため、
追加の回避コードを書く手間が必要になりました。
ユーザーからの入力操作が不要で、単にテキストを表示させるだけなら
System.Windows.Forms.Label ではなく、
・System.Windows.Forms.Control
・System.Windows.Forms.UserControl
・System.Windows.Forms.PictureBox
などに描画した方が手っ取り早いかもしれません。
> どれもピクチャーボックスに描画するという方法しかありません。
ピクチャーボックスに描画できるなら、その手順を応用すれば、
それ以外のコントロールに対しても対処できそうに思います。
そのサンプルが Uniscribe API を用いているものなのか、GDI+ の Graphics.DrawString によるものなのか(StringFormatFlags.DirectionVertical)、具体的な内容は分からないので何とも言えませんが……ピクチャーボックスで無ければ描画できないような手順になっているのでしょうか?
> ピクチャーボックスを使わずに
ところで、ピクチャーボックスを使いたくない理由は何ですか?
場合によっては、コントロールを追加せずに、親コンテナ(Form とか Panel とか)に直接描画するという選択肢もありそうです。どちらが楽かは案件次第ですが。
投稿者
東
 (高校生)   投稿日時
2016/8/2 12:56:25
ラベルにしたかったのはピクチャーボックスだと複数作った時に重くなると思ったからです。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2016/8/2 15:15:36
RichTextBox では、文字単位でフォントや色を変えられますよね。
それと同様、一つの大きなコントロールを用意して、
その中に何行もの縦書き文字列を表示するという手もありますよ。
> 印刷するということをしています。
印刷というと、PrintDocument クラスのことでしょうか。
それとも、Graphics.CopyFromScreen などで画面をキャプチャして
画像ファイルとしてから、別のソフトで印刷するのでしょうか。
あるいは、印刷用のコンポーネントを別途用いているとか?
たとえば Word を印刷ツールとして使えば、縦書き印刷も可能ですね。
> ラベルに表示することができません。
ご存知のように、Label 自体には縦書き機能がありません。
また、「っゃゅょ」「“”()」「ー~」「、。」などのことを考えると、
文字単位の改行や位置調整だけでは対処しきれません。
となると、ラベルが持つ本来の機能を使わないようにした上で、
画面への『描画処理』を独自に上書きするほかありません。
(たとえば、先述した DirectionVertical などを使うなど)
そして、その『描画処理』を実装するために
Paint イベント/OnPaint メソッドを用いるのだとしたら、
Label よりも UserControl や PictureBox の方が良いと思います。
あるいは、Panel 上に直接描いてしまうという手もありますね。
また、描画内容があまり変動しない場合には、Bitmap に動的に描画してから、
それを Image プロパティに割り当てるという手もあります。
Image プロパティとは別に、BackgroundImage プロパティに割り当てることもできます。
(BackgroundImage は、プロパティ一覧からは隠されています)
いずれにせよ、Label に描画処理を実装するのであれば、
Text プロパティを空にしておいてください。そうしないと、
自身の描画処理にテキストが被って表示されてしまうことになります。
> 複数作った時に
同時に表示する個数はどの程度でしょうか。
5個? 50個? 500個?
> 重くなると思ったからです。
同じ数だけ貼り付けた場合、それぞれどの程度重くなるのか、
事前に検証してみましたか?
重いとみなすか軽いとみなすかは、PC スペックにもよりますし、
「縦書き」のためのコードの有無によっても異なるでしょうから、
単純に比較することは出来ませんが…手元の環境で
下記を実行した限りは、どちらも大差無い程度に感じました。
Public
Class
Form1
Private
panel1
As
FlowLayoutPanel
Private
Sub
Form1_Load(sender
As
Object
, e
As
EventArgs)
Handles
MyBase
.Load
panel1 =
New
FlowLayoutPanel()
panel1.Dock = DockStyle.Fill
panel1.AutoScroll =
True
panel1.FlowDirection = FlowDirection.LeftToRight
'AppendGreenLabel(200)
'AppendBluePictureBox(200)
'AppendGreenLabel(400)
'AppendBluePictureBox(400)
Controls.Add(panel1)
End
Sub
Private
Sub
AppendGreenLabel(count
As
Integer
)
Dim
lbl
As
Label
For
n = 1
To
count
lbl =
New
Label()
lbl.BackColor = Color.FromArgb(32, (n
Or
&H80)
And
&HFF, 0)
lbl.AutoSize =
False
lbl.Size =
New
Size(70, 30)
lbl.BorderStyle = BorderStyle.Fixed3D
lbl.Margin =
New
Padding(3)
panel1.Controls.Add(lbl)
Next
End
Sub
Private
Sub
AppendBluePictureBox(count
As
Integer
)
Dim
pic
As
PictureBox
For
n = 1
To
count
pic =
New
PictureBox()
pic.BackColor = Color.FromArgb(32, 0, (n
Or
&H80)
And
&HFF)
pic.Size =
New
Size(70, 30)
pic.BorderStyle = BorderStyle.Fixed3D
pic.Margin =
New
Padding(3)
panel1.Controls.Add(pic)
Next
End
Sub
End
Class
投稿者
東
 (高校生)   投稿日時
2016/8/4 19:31:28
仮面弁士さんのを参考にしていろいろやってみたらできました。
いろいろ面倒くさくてすみませんでした。
ありがとうございました。