C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: 文字サイズに合わせてフォームサイズを調整


(過去ログ 172 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■99265 / inTopicNo.1)  文字サイズに合わせてフォームサイズを調整
  
□投稿者/ エックス (1回)-(2022/03/01(Tue) 20:20:46)

分類:[.NET 全般] 

VB.NETを使ってメッセージボックスを表示したいのですが、
規定のMessageboxでは表示できるアイコンが限られているため、
自作したいと考えています。

一つ問題は、既存のMessageboxに似せるために
Lable上にメッセージを表示することになりますが、
Labelのも文字数や文字サイズに応じて、
Labelのサイズだけでなく、フォームのサイズも調整したいのですが、
どのようにすれば良いですか?


Pictureboxなら、文字列のサイズを測定することができるので
こちらを使用すべきでしょうか?


引用返信 編集キー/
■99268 / inTopicNo.2)  Re[1]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ 魔界の仮面弁士 (3301回)-(2022/03/01(Tue) 23:02:15)
No99265 (エックス さん) に返信
> VB.NETを使ってメッセージボックスを表示したいのですが、
> 規定のMessageboxでは表示できるアイコンが限られているため、
> 自作したいと考えています。

MessageBox の情報は、 Ctrl+C を使ってクリップボードに取り込むことができます。

長いメッセージの記録などに便利なので、自分が作る場合はそれを真似て、
クリップボードにコピーする機能も実装するようにしています。
(リサイズ可能なフォームと、スクロール可能な ReadOnly TextBox を利用することもあります)


> Labelのも文字数や文字サイズに応じて、
> Labelのサイズだけでなく、フォームのサイズも調整したいのですが、
> どのようにすれば良いですか?

そもそも、サイズをどのように定義したいのでしょうか?

「フォームの横幅を固定し、長い文字列を折り返した上で、フォームの高さを調整」なのか、
「自動折り返しはしない。複数行なら改行コードを含む文字列を明示的に渡す」とか、
「長い文字列はフォントサイズを下げて縮小表示」などなど、
自動調整といっても、いろいろなパターンがあるかと思います。


とりあえず、Label の AutoSize に任せてみる手抜き実装案。
アイコンやタイトルバー、閉じるボタンなどの制御は省略しています。


'CustomMeessageBox.vb
' フォーム.Padding = 5,5,5,5
' Label1.AutoEllipsis = False
' Label1.AutoSize = True
' Label1.Dock = Fill
' Label1.UseMnemonic = False


Public Class CustomMeessageBox
  Private Sub New()
    InitializeComponent()
  End Sub

  Public Shared Function ShowMessage(msg As String) As DialogResult
    Return ShowMessage(Nothing, msg)
  End Function

  Public Shared Function ShowMessage(owner As IWin32Window, msg As String) As DialogResult
    Using dlg As New CustomMeessageBox()
      dlg.Label1.Text = msg
      dlg.ClientSize = Drawing.Size.Add(dlg.Label1.Size, New Drawing.Size(10, 10))
      Return dlg.ShowDialog(owner)
    End Using
  End Function
End Class



Public Class Form1
  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    CustomMeessageBox.ShowMessage(Me, TextBox1.Text)
  End Sub
End Class
引用返信 編集キー/
■99269 / inTopicNo.3)  Re[1]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ KOZ (225回)-(2022/03/02(Wed) 00:47:56)
No99265 (エックス さん) に返信
> VB.NETを使ってメッセージボックスを表示したいのですが、
> 規定のMessageboxでは表示できるアイコンが限られているため、
> 自作したいと考えています。

アイコンを変更するだけなら、MessageBoxIndirect を使う方法があります。

Win32リソースを埋め込む必要がありますので

「Win32リソースを実行ファイルに埋め込む」
https://dobon.net/vb/dotnet/programing/embedwin32resource.html

を参照してください。

このとき設定したリソースIDを MSGBOXPARAMS 構造体の lpszIcon メンバの値に指定することになります。

Imports System.Reflection
Imports System.Runtime.InteropServices

Public Class Form1

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
    Private Class MSGBOXPARAMS
        Public cbSize As Integer
        Public hwndOwner As IntPtr
        Public hInstance As IntPtr
        Public lpszText As String
        Public lpszCaption As String
        Public dwStyle As Integer
        Public lpszIcon As IntPtr
        Public dwContextHelpId As IntPtr
        Public lpfnMsgBoxCallback As IntPtr
        Public dwLanguageId As Integer
        Public Sub New()
            cbSize = Marshal.SizeOf(Me)
        End Sub
    End Class

    <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    Private Shared Function MessageBoxIndirect(lpMsgBoxParams As MSGBOXPARAMS) As DialogResult
    End Function

    Private Const MB_USERICON As Integer = &H80

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim msg As New MSGBOXPARAMS With {
            .hwndOwner = Me.Handle,
            .lpszText = "いろはにほへとちりぬるを",
            .hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()(0)),
            .lpszCaption = "Caption",
            .dwStyle = MB_USERICON Or MessageBoxButtons.OKCancel,
            .lpszIcon = New IntPtr(101) ' ID_ICON1
            }
        Dim result As DialogResult = MessageBoxIndirect(msg)
    End Sub
End Class

引用返信 編集キー/
■99280 / inTopicNo.4)  Re[2]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ エックス (3回)-(2022/03/02(Wed) 20:16:44)
No99269 (KOZ さん) に返信

ありがとうございます。

魔界の仮面弁士 さんの方法よりもこちらの方が簡単な気がしたので
先に試してみたのですが、
教えてくださったコードをそのまま貼り付けて使用したのですが、
メッセージボックスは表示されるものの、
アイコンは表示されませんでした。

自分で埋め込んだリソースファイルを指定しようとも思ったのですが、
リソースIDの確認方法が分かりません。

ソリューションエクスプローラーで画像ファイルを選択し。
プロパティのビルドアクションを埋め込みリソースに設定したのですが、
リソースIDはどこで確認すれば良いでしょうか?

引用返信 編集キー/
■99281 / inTopicNo.5)  Re[3]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ 魔界の仮面弁士 (3302回)-(2022/03/02(Wed) 20:33:31)
No99280 (エックス さん) に返信
>> Win32リソースを埋め込む必要がありますので
> ソリューションエクスプローラーで画像ファイルを選択し。
> プロパティのビルドアクションを埋め込みリソースに設定したのですが、

それは「Win32 リソース」ではありません。

No99269 で紹介された記事は
http://dobon.net/vb/dotnet/programing/vsresource.html
ではなく
https://dobon.net/vb/dotnet/programing/embedwin32resource.html
ですよね。
引用返信 編集キー/
■99282 / inTopicNo.6)  Re[4]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ エックス (4回)-(2022/03/02(Wed) 21:02:33)
No99281 (魔界の仮面弁士 さん) に返信

そうでしたか、
以前、Win32リソースを埋め込んだことがあるのですが、
ビルドするのが異様に時間がかかるようになってしまったのでできれば、これを使わない方が良いと考えています。

いま、魔界の仮面弁士 さんの方法を試しているのですが、
既存のメッセージボックスと同様に、Labelの文字数が少ない場合には、Labelの幅に合わせてウインドウサイズを調整
ある程度、大きくなると、フォームの横幅を固定し、長い文字列を折り返した上で、フォームの高さを調整
に切り替えたいと思います。
恐らく、ご提示のコードだと、「自動折り返しはしない。複数行なら改行コードを含む文字列を明示的に渡す」
になっていると思いますが
どのようにすれば、このようなことができますでしょうか?
引用返信 編集キー/
■99283 / inTopicNo.7)  Re[5]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ KOZ (226回)-(2022/03/03(Thu) 00:10:05)
No99282 (エックス さん) に返信
> 以前、Win32リソースを埋め込んだことがあるのですが、
> ビルドするのが異様に時間がかかるようになってしまったのでできれば、これを使わない方が良いと考えています。

プロジェクトファイルにリソースファイルを指定する方法を試しましたが、特に遅くなったという感じはありません。
異様に時間がかかるようになったというのは、どのくらいの時間なんでしょうか?
また、どのように埋め込んだのでしょう?
引用返信 編集キー/
■99308 / inTopicNo.8)  Re[6]: 文字サイズに合わせてフォームサイズを調整
□投稿者/ エックス (5回)-(2022/03/07(Mon) 18:39:13)
ありがとうございます。

ただ、やはり、魔界の仮面弁士の方法でいけるなら
こちらを試したいと考えております。


> 既存のメッセージボックスと同様に、Labelの文字数が少ない場合には、Labelの幅に合わせてウインドウサイズを調整
> ある程度、大きくなると、フォームの横幅を固定し、長い文字列を折り返した上で、フォームの高さを調整

を実現するためには、LabelのMaximumSizeに
400,0のようなSizeを設定しておけば、
幅が400以下なら自動で調節、それ以上なら400で固定で自動で改行してくれることに気が付きました。


そのため、以下のようなコードでうまくいくことが分かりました。

    Public Shared Function ShowMessage(owner As IWin32Window, msg As String) As DialogResult
        Using dlg As New Form1()

            dlg.Label1.MaximumSize = New Size(400, 0)
            dlg.Label1.Text = msg

            dlg.ClientSize = Drawing.Size.Add(dlg.Label1.Size, New Drawing.Size(60 + 6, 76))

            Return dlg.ShowDialog(owner)
        End Using
    End Function


ただ、問題は、PictureBoxやButtonを配置するために、Tablelayoutpanel内にLableを配置すると、
メッセージボックス内の文字数が増えた際に、
Labelの高さが190を超えた辺りで、Labelの高さが飽和してしまい、
それ以上大きくならなくなり、全ての文字列がウインドウに表示されません。

Tablelayoutpanelを描画した後でないといけないのではないかと思い、
MyBase.Shownで


            dlg.ClientSize = Drawing.Size.Add(dlg.Label1.Size, New Drawing.Size(60 + 6, 76))

を実行してみると、多少は上限値が改善されたのですが
やはり、文字数が多いと文字列が全て描画されません。

Tablelayoutpanel内にLableを入れなければ
うまくいくのですが、どのようにすればTablelayoutpanelに入れた状態で機能させることができますか?



引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -