┏第63号━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         .NETプログラミング研究         ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ──<メニュー>─────────────────────── ■.NET質問箱 ・16進数、8進数、2進数の文字列を整数に変換する、整数を16進数、  8進数、2進数の文字列に変換する ・フォームの「閉じる」ボタンを無効にする ・TextBoxやRichTextBoxのタブの幅を変更する ・AutoScrollをTrueにしてスクロールバーを表示された時、指定した  位置までスクロールする ─────────────────────────────── ─────────────────────────────── ■.NET質問箱 ─────────────────────────────── 「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込 まれた.NETプログラミングに関する投稿を基に、さらに考察を加え、 Q&A形式にまとめて紹介します。 [URL]どぼん!のプログラミング掲示板 http://dobon.net/vb/bbs.html ─────────────────────────────── ●16進数、8進数、2進数の文字列を整数に変換する、整数を16進数、  8進数、2進数の文字列に変換する 【質問】 16進数、8進数、2進数を表した文字列を整数に変換するには、どのよ うにすればよいのでしょうか?また逆に整数を16進数、8進数、2進数 を表す文字列に変換するにはどのようにすればよいのでしょうか? 【回答】 基本的には、文字列を整数に変換するにはConvertクラスのToInt32メ ソッドを、整数を文字列に変換するにはConvertクラスのToStringメ ソッドを使います。しかし、これ以外の方法も考えられます。 以下に一つずつ説明していきます。 ★16進数の文字列を整数に変換 ConvertクラスのToInt32メソッド等や、Int32構造体等のParseメソッ ドを使うことにより可能です。 Convert.ToInt32メソッドを使うと、次のようになります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num16 As Integer = Convert.ToInt32("FFFF", 16) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num16 = Convert.ToInt32("FFFF", 16); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Int32のParseメソッドを使った例は、次のようなものです。なお Convert.ToInt32では変換する文字列の頭に「0x」を付けることがで きますが、Int32.Parseでは付けることができません。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num16 As Integer = Integer.Parse("FFFF", _ System.Globalization.NumberStyles.HexNumber) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num16 = int.Parse("FFFF", System.Globalization.NumberStyles.HexNumber); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ VB.NETでは、CInt関数等を使って変換することもできます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num16 as Integer = CInt("&HFFFF") ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★整数を16進数の文字列に変換 ConvertクラスのToStringメソッドや、Int32構造体等のToStringメソ ッドを使います。 Convert.ToStringを使った例は、次の通りです。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num As Integer = 65535 Dim str As String = Convert.ToString(num, 16) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num = 65535; string str = Convert.ToString(num, 16); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Int32.ToStringを使うと、次のようになります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num As Integer = 65535 Dim str As String = num.ToString("X") ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num = 65535; string str = num.ToString("X"); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ VB.NETでは、Hex関数を使うこともできます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num as Integer = 65535 Dim str as String = Hex(num) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★8進数の文字列を整数に変換 ConvertクラスのToInt32メソッド等を使うことにより、可能です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num8 As Integer = Convert.ToInt32("1750", 8) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num8 = Convert.ToInt32("1750", 8); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ VB.NETでは、CInt関数等を使って変換することもできます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num8 as Integer = CInt("&O1750") ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★整数を8進数の文字列に変換 ConvertクラスのToStringメソッドにより、可能です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num As Integer = 1000 Dim str As String = Convert.ToString(num, 8) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num = 1000; string str = Convert.ToString(num, 8); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ VB.NETでは、Oct関数を使うこともできます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num as Integer = 1000 Dim str as String = Oct(num) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★2進数の文字列を整数に変換 これも、ConvertクラスのToInt32メソッド等を使うことにより、可能 です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num2 As Integer = Convert.ToInt32("1111101000", 2) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num2 = Convert.ToInt32("1111101000", 2); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ★整数を2進数の文字列に変換 これも、ConvertクラスのToStringメソッドにより、可能です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Dim num As Integer = 1000 Dim str As String = Convert.ToString(num, 2) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ int num = 1000; string str = Convert.ToString(num, 2); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ○この記事の基になった掲示板のスレッド [題名] string "ff"を数値型の 255 に変換したい [投稿者(敬称略)] yukko, よねKEN [URL] http://dobon.net/vb/bbs/log3-7/3881.html ─────────────────────────────── ●フォームの「閉じる」ボタンを無効にする 【質問】 Windowsフォームの右上にある「閉じる」ボタン(Xボタン)を無効に したいのですが、どのようにすればよいでしょうか? 【回答】 幾つかの方法が考えられます。 まず一番単純なのは、フォームのControlBoxプロパティをFalseにし たり、FormBorderStyleプロパティをNoneにしたりすることにより、 「閉じる」ボタンを消す方法です。この場合は、最小化、最大化ボタ ン、コントロールボックスも消えてしまうという欠点があります。 また、「フォームが閉じられる時その原因を知る」と「条件によりフ ォームが閉じられないようにする」により、「閉じる」ボタンが押さ れてフォームが閉じられる場合に、フォームを閉じないようにする方 法もあります。 [URL]DOBON.NET .NET Tips - フォームが閉じられる時その原因を知 る http://dobon.net/vb/dotnet/form/unloadmode.html [URL]DOBON.NET .NET Tips - 条件によりフォームが閉じられないよ うにする http://dobon.net/vb/dotnet/form/closingcancel.html この方法を使った例は、次のようなものです。なおこの例では、シス テムメニューの「閉じる」や、「Alt」+「F4」キーも無効になります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Protected Overrides Sub WndProc( _ ByRef m As System.Windows.Forms.Message) Const WM_SYSCOMMAND As Integer = &H112 Const SC_CLOSE As Integer = &HF060 If m.Msg = WM_SYSCOMMAND And m.WParam.ToInt32() = SC_CLOSE Then Return End If MyBase.WndProc(m) End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ protected override void WndProc(ref Message m) { const int WM_SYSCOMMAND = 0x112; const int SC_CLOSE = 0xF060; if (m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE) { return; } base.WndProc (ref m); } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 補足:上の例では「条件によりフォームが閉じられないようにする」 は使いませんでした。これを使う場合は、「閉じる」ボタンが押され た時にフラッグを立てて、Closingイベントで閉じないようにします。 さらに、GotDotNetの掲示板の「Disabling the close button?」に MickDohertyさんがとてもおもしろい投稿をされています。 [URL]GotDotNet Message Boards - Disabling the close button? http://www.gotdotnet.com/Community/MessageBoard/Thread.aspx?id=248554&Page=1#248801 これはフォームのCreateParamsプロパティをオーバーライドするとい う方法で、「閉じる」ボタンが無効状態となり、押すことができなく なります。システムメニューの「閉じる」も表示されなくなり、「 Alt」+「F4」キーも無効になります。 以下にそのコードを引用させていただきます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Protected Overrides ReadOnly Property CreateParams() As _ System.Windows.Forms.CreateParams Get Const CS_NOCLOSE As Integer = &H200 Dim cp As CreateParams = MyBase.CreateParams cp.ClassStyle = cp.ClassStyle Or CS_NOCLOSE Return cp End Get End Property ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ protected override CreateParams CreateParams { get { const int CS_NOCLOSE = 0x200; CreateParams cp = base.CreateParams; cp.ClassStyle = cp.ClassStyle | CS_NOCLOSE; return cp; } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 最後にWin32 APIを使う方法も紹介しておきます。下記の方法では、 「閉じる」ボタンが無効状態となり、システムメニューの「閉じる」 が表示されなくなりますが、「Alt」+「F4」キーは有効です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Shared Function GetSystemMenu(ByVal hWnd As IntPtr, _ ByVal bRevert As Boolean) As IntPtr End Function _ Shared Function GetMenuItemCount(ByVal hMenu As IntPtr) As Integer End Function _ Shared Function DrawMenuBar(ByVal hWnd As IntPtr) As Boolean End Function _ Shared Function RemoveMenu(ByVal hMenu As IntPtr, _ ByVal uPosition As Integer, _ ByVal uFlags As Integer) As Boolean End Function Protected Overrides Sub OnLoad(ByVal e As EventArgs) MyBase.OnLoad(e) Const MF_BYPOSITION As Int32 = &H400 Const MF_REMOVE As Int32 = &H1000 Dim menu As IntPtr = GetSystemMenu(Me.Handle, False) Dim menuCount As Integer = GetMenuItemCount(menu) If menuCount > 1 Then 'メニューの「閉じる」とセパレータを削除 RemoveMenu(menu, menuCount - 1, MF_BYPOSITION Or MF_REMOVE) RemoveMenu(menu, menuCount - 2, MF_BYPOSITION Or MF_REMOVE) DrawMenuBar(Me.Handle) End If End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ [System.Runtime.InteropServices.DllImport("user32.dll")] static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [System.Runtime.InteropServices.DllImport("user32.dll")] static extern int GetMenuItemCount(IntPtr hMenu); [System.Runtime.InteropServices.DllImport("user32.dll")] static extern bool DrawMenuBar(IntPtr hWnd); [System.Runtime.InteropServices.DllImport("user32.dll")] static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags); protected override void OnLoad(EventArgs e) { base.OnLoad (e); const Int32 MF_BYPOSITION = 0x400; const Int32 MF_REMOVE = 0x1000; IntPtr menu = GetSystemMenu(this.Handle, false); int menuCount = GetMenuItemCount(menu); if (menuCount > 1) { //メニューの「閉じる」とセパレータを削除 RemoveMenu(menu, (uint) (menuCount - 1), MF_BYPOSITION | MF_REMOVE); RemoveMenu(menu, (uint) (menuCount - 2), MF_BYPOSITION | MF_REMOVE); DrawMenuBar(this.Handle); } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ○この記事の基になった掲示板のスレッド [題名] フォーム右上の閉じるボタン無効化 [投稿者(敬称略)] なかじ, 琴, NowhereMan, 管理人 [URL] http://dobon.net/vb/bbs/log3-7/3914.html ─────────────────────────────── ●TextBoxやRichTextBoxのタブの幅を変更する 【質問】 TextBoxやRichTextBoxのタブの幅(文字数)を変更することができま すか? 【回答】 RichTextBoxであれば、SelectionTabsプロパティにより、タブの位置 を設定することができます。ただしこれはタブの位置をピクセル単位 で、数値型の配列として指定するものです。 SelectionTabsプロパティを使わないのであれば、Win32 APIを使うこ とになります。EM_SETTABSTOPSメッセージを使って、タブ幅の文字数 を指定できます。 次の例では、Button1をクリックすることにより、TextBox1のタブの 幅を16にしています。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Shared Function SendMessage(ByVal hWnd As IntPtr, _ ByVal msg As Integer, ByVal wParam As Integer, _ ByVal lParam() As Integer) As IntPtr End Function Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button1.Click Const EM_SETTABSTOPS As Integer = &HCB SendMessage(TextBox1.Handle, EM_SETTABSTOPS, 1, New Integer() {16}) End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ [System.Runtime.InteropServices.DllImport("User32.dll")] static extern IntPtr SendMessage( IntPtr hWnd, int msg, int wParam, int [] lParam); private void Button1_Click(object sender, System.EventArgs e) { const int EM_SETTABSTOPS = 0x00CB; SendMessage(TextBox1.Handle, EM_SETTABSTOPS, 1, new int[] {16}); } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ○この記事の基になった掲示板のスレッド [題名] RichTextBox等のTabの幅を変えたい [投稿者(敬称略)] 春原, よねKEN [URL] http://dobon.net/vb/bbs/log3-2/983.html [題名] textBoxでTAB幅調整について [投稿者(敬称略)] てんてん, YUSK, 管理人, 花ちゃん, 秋, 小野@どっとねっとふぁん [URL] http://dobon.net/vb/bbs/log3-13/7193.html ─────────────────────────────── ●AutoScrollをTrueにしてスクロールバーを表示された時、指定した  位置までスクロールする 【質問】 フォームのAutoScrollプロパティをTrueにしてスクロールバーを表示 しているのですが、この時指定した位置までスクロールするにはどの ようにすればよいのでしょうか? 【回答】 AutoScrollPositionプロパティにより、スクロールの位置を設定する ことができます。 AutoScrollPositionプロパティにスクロール位置を設定する場合は、 スクロールの開始位置からどれだけ離れているかを正の整数で設定し ます。つまり、垂直スクロールバーでは下に、水平スクロールバーで は右に移動させるほど、大きな値を設定します。ところが AutoScrollPositionプロパティでスクロール位置を取得する時は、逆 にスクロールの開始位置からどれだけ離れているかが負の整数で取得 できます。例えばAutoScrollPositionプロパティに(100, 200)という 位置を設定した後、AutoScrollPositionを取得すると、(-100, -200) となります。 現在の位置から右、下に10ずつスクロールさせるには、次のようにし ます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ Me.AutoScrollPosition = _ New Point(-Me.AutoScrollPosition.X + 10, _ -Me.AutoScrollPosition.Y + 10) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ this.AutoScrollPosition = new Point(-this.AutoScrollPosition.X + 10, -this.AutoScrollPosition.Y + 10); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ また、ScrollControlIntoViewメソッドにより、指定したコントロー ルが表示されるようにスクロールすることができます。MSDNでは ScrollControlIntoViewメソッドについて、「このメンバは、.NET Framework インフラストラクチャのサポートを目的としています。独 自に作成したコード内で直接使用することはできません。」とありま すが、これは間違いで、問題なく使用できるようです(注)。 注:ニュースグループにマイクロソフトからの投稿があります。 [URL]microsoft.public.dotnet.framework.windowsforms - Re: how to set scroll position programatically http://groups.google.co.jp/group/microsoft.public.dotnet.framework.windowsforms/msg/d50dbbfb21b082c6?hl=ja& 補足:SB_THUMBPOSITIONやSB_THUMBTRACKメッセージによりスクロー ルさせる場合は、メッセージを送った後にSetDisplayRectLocationメ ソッドを呼び出さなければ正常に機能しないケースがあるようです。 詳しくは、次のURL先をご覧ください。 [URL]microsoft.public.dotnet.framework.windowsforms - Re: scrolling a panel http://groups.google.co.jp/group/microsoft.public.dotnet.framework.windowsforms/msg/0286f32da273504a?hl=ja& ○この記事の基になった掲示板のスレッド [題名] フォームのスクロール [投稿者(敬称略)] UMU, NowhereMan [URL] http://dobon.net/vb/bbs/log3-7/3962.html =============================== ■ここで示したコードの多くはまずC#で書き、それを「C# to VB.NET Translator」でVB.NETのコードに変換し、修正を加えたものです。 [URL]C# to VB.NET Translator http://authors.aspalliance.com/aldotnet/examples/translate.aspx ■このマガジンの購読、購読中止、バックナンバー、説明に関しては  次のページをご覧ください。  http://www.mag2.com/m/0000104516.htm ■発行人・編集人:どぼん!  (Microsoft MVP for Visual Basic, Oct 2004-Oct 2005)  http://dobon.net  dobon_info@yahoo.co.jp ■ご質問等はメールではなく、掲示板へお願いいたします。  http://dobon.net/vb/bbs.html ■上記メールアドレスへのメールは確実に読まれる保障はありません  (スパム、ウィルス対策です)。メールは下記URLのフォームメール  から送信してください。  http://dobon.net/mail.html Copyright (c) 2003 - 2006 DOBON! All rights reserved. ===============================