┏第27号━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         .NETプログラミング研究         ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜メニュー ■ピンポイントリンク ・Docking Windowを使う ■.NET質問箱 ・VarPtr, StrPtr, ObjPtr関数の代わりになるものは? ・DataGridコントロールのセル内でのキーイベントを補足するには? ・DataGridコントロールのAllowSortingプロパティをFalseにしても並  べ替えができてしまう 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜メニュー ─────────────────────────────── ■ピンポイントリンク ─────────────────────────────── ●Docking Windowを使う Visual Studio .NETのメインウィンドウの上下左右には、ツールボッ クス、ソリューションエクスプローラ、プロパティウィンドウなどが くっついており、これらはドラッグすることにより、分離させてウィ ンドウにしたり、別の位置にドッキングさせたり、サイズを変えたり することが出来るようになっています。このようなウィンドウを Docking Windowと呼びます。ここでは、.NETでDocking Windowを可能 にするライブラリを紹介します。(ここでは無料で使用できるものし か紹介しません。) 何をおいてもまず初めに紹介しなければならないのが、Phil Wrightさ んの「Magic Library」にある「Magic Docking」です。 ・The Code Project - Magic Docking - VS.NET Style http://www.codeproject.com/cs/miscctrl/magicdocking.asp Magic Dockingは、オープンソースの.NET用IDEとして有名な「 SharpDevelop」でも使用されており、そのVisual Studio .NETとそっ くりなユーザーインターフェイスに大いに貢献しています。 ・SharpDevelop http://www.icsharpcode.net/OpenSource/SD/ Magic Dockingはとにかく高機能です。Visual Studio .NETのDocking Windowと見た目が似ているだけでなく、「自動的に隠す」機能(右上 のピンのマークをクリックすることにより、Windowが自動的に隠れ、 マウスを持っていくことにより、再び表示できる機能)や、タブとし てドッキングさせる機能、Docking Windowの状態をXMLファイルやバイ ト型配列に保存し、復元する機能など、申し分ありません。 使い方も簡単です。「MagicLibrary.DLL」を「参照設定」に追加し、 次のようなコードをフォームのLoadイベントハンドラ(またはコンス トラクタ)に書くだけで、Docking Windowができてしまいます。(た った4行!!) //[C#]・・・・・・・・・・・・・・・・・・・・・・・・・・・・ //using Crownwood.Magic.Common; //using Crownwood.Magic.Docking; //が宣言されているものとする private DockingManager _dockingManager = null; //フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //DockingManagerオブジェクトの作成 _dockingManager = new DockingManager(this, VisualStyle.IDE); //Contentとして新しく作成したRichTextBoxコントロールを追加 _dockingManager.Contents.Add(new RichTextBox(), "RichTextBox"); //Contentを表示 _dockingManager.ShowContent( _dockingManager.Contents["RichTextBox"]); } //・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ '[VB.NET]・・・・・・・・・・・・・・・・・・・・・・・・・・ 'Imports Crownwood.Magic.Common 'Imports Crownwood.Magic.Docking 'が宣言されているものとする Private _dockingManager As DockingManager = Nothing 'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'DockingManagerオブジェクトの作成 _dockingManager = New DockingManager(Me, VisualStyle.IDE) 'Contentとして新しく作成したRichTextBoxコントロールを追加 _dockingManager.Contents.Add(New RichTextBox, "RichTextBox") 'Contentを表示 _dockingManager.ShowContent( _ _dockingManager.Contents("RichTextBox")) End Sub '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ このようにMagic Dockingの使用は決して難しいものではありませんが、 Visual Studio .NETのフォームデザイナを使って設定できるようにな ればもっと便利になるかもしれません。それを可能にするのが、 Jerry Maguireさんの「DockingManagerExtender」です。これを使えば、 コードを自分で一行も書く必要がなくなります。 ・The Code Project - Magic Library Docking Manager Designer http://www.codeproject.com/cs/miscctrl/dockingmanagerextender.asp 使い方は、「MagicLibrary.DLL」が「参照設定」に追加された状態で、 「ツールボックス」の「コンポーネント」に「 DockingManagerExtender.DLL」を追加し、これをフォームに貼り付け るだけです。フォームに貼り付けたDockingManagerExtenderの ContainerControlプロパティを適当に設定し(通常は貼り付けたフォー ムとなるでしょう)、Docking Windowとするコントロールの「 DockingManagerExtenderのADockingEnable」プロパティをTrueとすれ ば、Docking Windowが出来上がります。 このようにMagic Dockingは、まさに最強といえますが、残念なことに、 Magic Libraryは有料化され、「DotNetMagic」となりました。(有料 化は私個人としては残念ですが、商用で使用する人にとってみれば、 サポートが受けられるようになったという点で、よかったのかもしれ ません。) ・DotNetMagic http://www.dotnetmagic.com/ バージョン1.7.4までのMagic Libraryは今まで通り無料で使用できま すが、少なくともバージョン1.7.4は私の知る限り、どこにも公開され ていないようです。(上記「The Code Project - Magic Docking - VS.NET Style」からバージョン1.7.0がダウンロードできるようです。) MagicLibrary.DLLはSharpDevelopなどに含まれているので、今のとこ とは簡単に入手できます。 Magic Dockingと同様の見た目と機能を持つライブラリに、Weifen Luoさんの、「DockManager Control」があります。DockManager ControlはMDIフォームに対するドッキングを可能とすることを目的と しているそうです。(最新バージョンは1.2.3。) ・The Code Project - DockManager Control http://www.codeproject.com/cs/miscctrl/DockManager.asp ・DockManager Control http://www.freewebs.com/weifenluo/DockManager.htm ・GotDotNet User Sample: DockManager Control http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=BD028D17-5E18-472E-9022-E7A4D9CDE263 DockManager Controlでは、Docking WindowとなるContentクラスが System.Windows.Forms.Formクラスを継承しているため、Docking Windowのデザインをフォームデザイナで行えます。 DockManager Controlの簡単な使い方を紹介しましょう。まず、「ツー ルボックス」の「コンポーネント」に「WeifenLuo.WinFormsUI.dll」 を追加します。「DockManager」をフォームに貼り付け、Dockプロパテ ィをFillにしておきます(しなくても結構です)。このDockManagerの 部分にDocking Windowがドッキングされます。 次にDocking Windowを作成します。「新しい項目の追加ダイアログ」 を表示し、「継承されたフォーム」を選択後、「開く」をクリックし ます。「継承ピッカー」の「参照」をクリックし、「WeifenLuo. WinFormsUI.dll」を選択後表示される「Content」を選択し、OKをクリ ックします。これで作成されるフォームがDocking Windowとなりますの で、フォームデザイナで適当にデザインしましょう。 作成したDocking Windowを表示させるには、Showメソッドを使用しま す。次の例では、DockManagerオブジェクトdockManager1に、Docking WindowのForm2を左端にドッキングされた状態で表示させています。 //[C#]・・・・・・・・・・・・・・・・・・・・・・・・・・・・ //Docking WindowのForm2オブジェクトの作成 Form2 f2 = new Form2(); //dockManager1の左端にドッキングされて表示する f2.Show(dockManager1, WeifenLuo.WinFormsUI.DockState.DockLeft); //・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ '[VB.NET]・・・・・・・・・・・・・・・・・・・・・・・・・・ 'Docking WindowのForm2オブジェクトの作成 Dim f2 As New Form2 'dockManager1の左端にドッキングされて表示する f2.Show(dockManager1, WeifenLuo.WinFormsUI.DockState.DockLeft) '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ DockManager ControlはMagic Dockingと互角の機能をもっており、便 利なコントロールですが、まだまだバグが多いようです。 Docking Windowを可能にするライブラリはまだまだあります。以下に ずらずら並べてみます。(ほとんどが私は実際に試していません。) ・A Docking control that can be dragged and resized by the user By Phil Wright http://www.codeproject.com/cs/menu/dockingcontrol.asp これは、Magic Dockingの作者Phil Wrightさんがそれ以前に作成した コントロールであるようです。 ・Docking control with tear-away frame tool windows By Iridar http://www.codeproject.com/cs/miscctrl/docking_control.asp フォームデザイナでフォームに貼り付け、デザインできます。機能は 少なく、バグも多いようです。 ・Docking Control By rovshan876 http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=c0e032b6-96a2-4416-9004-bbd1cd6f1fe1 「This is a docking control like in IDE.」とのことです。 ・divil.co.uk - Docking Suite http://www.divil.co.uk/net/controls/dockingsuite/ 非商用での使用のみ無料で使用できるようです。 有料のものを含め、「Windows Forms」でもいくつか紹介されています。 ・Windows Forms : Control Gallery - Docking Windows http://www.windowsforms.net/ControlGallery/default.aspx?Category=7&tabindex=9 なお、ここで紹介されていないものをご存知の方は、ぜひご連絡くだ さい。 ─────────────────────────────── ■.NET質問箱 ─────────────────────────────── ●VarPtr, StrPtr, ObjPtr関数の代わりになるものは? 質問: Visual Basic 6.0のVarPtr, StrPtr, ObjPtr関数がVB.NETではなくな りましたが、何か代わりになるものはないでしょうか? 答え: VB6のVarPtr, StrPtr, ObjPtr関数は変数の下位のメモリアドレスを取 得するためのドキュメント化されていない関数です。「Visual Basic .NET へのアップグレードを円滑に行うための Visual Basic 6.0 アプ リケーションの準備」や「VB 6.0 ユーザーのための VB .NET 移行ガ イド - レガシー機能」によると、これらの関数はVB.NETではサポート されていないとのことです。 ・Visual Basic .NET へのアップグレードを円滑に行うための Visual Basic 6.0 アプリケーションの準備 http://www.microsoft.com/japan/msdn/vs/vb6/vb6tovbdotnet.asp ・VB 6.0 ユーザーのための VB .NET 移行ガイド - レガシー機能 http://www.microsoft.com/japan/msdn/net/vbtransitionguide/chapter4/chapter4_16.asp .NETではこれらの機能が必要になる機会はそうはないでしょうが、 .NETでもオブジェクトのアドレスを取得することは可能です。しかしこ のとき問題になるのは、アドレスを取得し、それを使用する間、共通 言語ライブラリ(CLR)によってこのアドレスが変更されないことを確実 にしなければならないということです。共通言語ライブラリはガベー ジコレクタによって、効率化のためにオブジェクトをメモリ内で移動 しているのです。 そのため、オブジェクトのアドレスはGCHandle.AddrOfPinnedObjectメ ソッドで取得し、このときに必要なハンドルはGCHandle.Allocメソッ ドで取得します。使い終わった後はGCHandle.Freeメソッドによりハン ドルを解放します。 次のサンプルは、オブジェクト"obj"のアドレスを取得するものです。 //[C#]・・・・・・・・・・・・・・・・・・・・・・・・・・・・ //using System.Runtime.InteropServices; //が宣言されているものとする //ガベージコレクタがオブジェクトを移動できないようにする GCHandle gch = GCHandle.Alloc(obj, GCHandleType.Pinned); //固定オブジェクトのアドレスを取得する int address = gch.AddrOfPinnedObject().ToInt32(); //ハンドルを解放する //オブジェクトの移動ができるようになる gch.Free(); //・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ '[VB.NET]・・・・・・・・・・・・・・・・・・・・・・・・・・ 'Imports System.Runtime.InteropServices 'が宣言されているものとする 'ガベージコレクタがオブジェクトを移動できないようにする Dim gch As GCHandle = GCHandle.Alloc(obj, GCHandleType.Pinned) '固定オブジェクトのアドレスを取得する Dim address As Integer = gch.AddrOfPinnedObject().ToInt32() 'ハンドルを解放する 'オブジェクトの移動ができるようになる gch.Free() '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 参考: ・developer.com - The Book of VB .NET: Migrating to Visual Basic .NET, Part 2 (By Matthew MacDonald) http://www.developer.com/tech/article.php/1007901 掲示板過去ログ: http://dobon.net/vb/bbs/log3-1/50.html ─────────────────────────────── ●DataGridコントロールのセル内でのキーイベントを補足するには? 質問: DataGridコントロール(System.Windows.Forms)のセル内でキーをたた いた時のKeyDownイベントを捕捉したいのですが、DataGridのKeyDown イベントでは認識してくれません。どのようにすればよいのでしょう か? 答え: DataGridコントロールのKeyDownイベントではなく、セルのTextBoxの KeyDownイベントを捕捉するようにします。セルのTextBoxオブジェク トは列スタイルDataGridTextBoxColumnのTextBoxプロパティから取得 できます。 次の例では、DataGridコントロールDataGrid1にテーブルスタイル "DataTable1"が設定されているものとし、その1列目のセルでの KeyDownイベントを捕捉しています。 //[C#]・・・・・・・・・・・・・・・・・・・・・・・・・・・・ //フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //DataGrid1にはテーブルスタイル"DataTable1"が //設定されているものとする //テーブルスタイルの取得 DataGridTableStyle ts; ts = DataGrid1.TableStyles["DataTable1"]; //DataGridTextBoxColumnの取得 DataGridTextBoxColumn cs = (DataGridTextBoxColumn) ts.GridColumnStyles[0]; //TextBoxの取得 TextBox tb = cs.TextBox; //KeyDownイベントハンドラを追加 tb.KeyDown += new KeyEventHandler(tb_KeyDown); } //KeyDownイベントハンドラ private void tb_KeyDown(object sender, KeyEventArgs e) { //押されたキーを表示 Console.WriteLine("キー({0})が押されました。", e.KeyCode); } //・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ '[VB.NET]・・・・・・・・・・・・・・・・・・・・・・・・・・ 'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'DataGrid1にはテーブルスタイル"DataTable1"が '設定されているものとする 'テーブルスタイルの取得 Dim ts As DataGridTableStyle ts = DataGrid1.TableStyles("DataTable1") 'DataGridTextBoxColumnの取得 Dim cs As DataGridTextBoxColumn = _ CType(ts.GridColumnStyles(0), DataGridTextBoxColumn) 'TextBoxの取得 Dim tb As TextBox = cs.TextBox 'KeyDownイベントハンドラを追加 AddHandler tb.KeyDown, AddressOf tb_KeyDown End Sub 'KeyDownイベントハンドラ Private Sub tb_KeyDown(ByVal sender As Object, _ ByVal e As KeyEventArgs) '押されたキーを表示 Console.WriteLine("キー({0})が押されました。", e.KeyCode) End Sub '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 掲示板過去ログ: http://dobon.net/vb/bbs/log3-1/31.html ─────────────────────────────── ●DataGridコントロールのAllowSortingプロパティをFalseにしても 並べ替えができてしまう 質問: DataGridコントロール(System.Windows.Forms)のAllowSortingプロパ ティをFalseにしても、列カラムをクリックすると並び替えされてしま います。なぜでしょうか? 答え: DataGridコントロールにテーブルスタイルが設定されていないか確か めてください。DataGridコントロールにテーブルスタイルが設定され ている時、並び替えの許可、不許可はDataGridコントロールの AllowSortingプロパティで設定するのではなく、使用している DataGridTableStyleのAllowSortingプロパティで設定する必要があり ます。 よってDataGridコントロールにテーブルスタイルが設定されていると きは、設定されているDataGridTableStyleのAllowSortingプロパティ をFlaseにします。ほとんどの場合、これで解決できるでしょう。 次の例では、DataGridコントロールDataGrid1にテーブルスタイル "DataTable1"が設定されている時に、列ヘッダのクリックで並び替え をできないようにしています。 //[C#]・・・・・・・・・・・・・・・・・・・・・・・・・・・・ //DataGrid1にはテーブルスタイル"DataTable1"が //設定されているものとする //テーブルスタイルの取得 DataGridTableStyle ts; ts = DataGrid1.TableStyles["DataTable1"]; //並び替えできないようにする ts.AllowSorting = false; //・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ '[VB.NET]・・・・・・・・・・・・・・・・・・・・・・・・・・ 'DataGrid1にはテーブルスタイル"DataTable1"が '設定されているものとする 'テーブルスタイルの取得 Dim ts As DataGridTableStyle ts = DataGrid1.TableStyles("DataTable1") '並び替えできないようにする ts.AllowSorting = False '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 掲示板過去ログ: http://dobon.net/vb/bbs/log3-1/157.html =============================== ■このマガジンの購読、購読中止、バックナンバー、説明に関しては  次のページをご覧ください。  http://www.mag2.com/m/0000104516.htm ■発行人・編集人:どぼん!  (Microsoft MVP for Visual Basic, Oct 2003-Oct 2004)  http://dobon.net  dobon_info@yahoo.co.jp ■ご質問等はメールではなく、掲示板へお願いいたします。  http://dobon.net/vb/bbs.html ■上記メールアドレスへのメールは確実に読まれる保障はありません  (スパム、ウィルス対策です)。メールは下記URLのフォームメール  から送信してください。  http://dobon.net/mail.html Copyright (c) 2003 - 2004 DOBON! All rights reserved. ===============================