┏第54号━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         .NETプログラミング研究         ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ──<メニュー>─────────────────────── ■お知らせ ・CodeZineがプレオープン ■.NET質問箱 ・表示色を反転して線を引くには? ・クリップボードにファイルをコピーする、またはクリップボードか  らファイルを取得するには? ・システム時計の日時を設定するには? ・DataGridコントロールの列の幅をユーザーが変更できないようにす  るには? ─────────────────────────────── ─────────────────────────────── ■お知らせ ─────────────────────────────── ●CodeZineがプレオープン 開発者のための実装系Webマガジン「CodeZine」がプレオープンしま した。CodeZineは今までの日本のサイトにはあまりない一般読者が記 事を投稿できるタイプのサイトで、.NET関係のカテゴリも用意されて います。私「どぼん!」も記事を登録させていただいていますので、 興味のある方はぜひ覗いてみてください。 [URL]CodeZine http://codezine.jp/ 以下が私の書いた記事です。 [URL].NETによるプラグイン機能を持つテキストエディタの作成 http://codezine.jp/a/article.aspx?aid=1 [URL]TCPを利用した複数クライアント接続可能なチャットアプリケー ションの作成 http://codezine.jp/a/article.aspx?aid=22 [URL]DataGridにComboBoxを表示可能な列を作る http://codezine.jp/a/article.aspx?aid=3 ─────────────────────────────── ■.NET質問箱 ─────────────────────────────── 「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込 まれた.NETプログラミングに関する投稿を基に、さらに考察を加え、 Q&A形式にまとめて紹介します。 [URL]どぼん!のプログラミング掲示板 http://dobon.net/vb/bbs.html ─────────────────────────────── ●表示色を反転して線を引くには? 【質問】 VB6では、ピクチャボックスのDrawModeプロパティをvbInvert(6)とし てから線を描画することにより表示色を反転して出力できましたが、 同じことを.NETで行うにはどのようにしたらよいのでしょうか? 【回答】 .NETでは、ControlPaintクラスのDrawReversibleLineメソッドを使う ことにより、表示色を反転して線を引くことができます。また、 ControlPaintクラスのDrawReversibleFrameメソッドにより枠を、 FillReversibleRectangleメソッドにより塗りつぶされた四角を描く ことができます。 [URL]DOBON.NET .NET Tips - コントロールを描画する http://dobon.net/vb/dotnet/graphics/drawcontrols.html なおこれらのメソッドは画面に描画するもので、指定する座標も画面 座標です。よって例えばPictureBoxでの座標を指定したい場合は、 PointToScreenメソッドなどでクライアント座標から画面座標を計算 しなければなりません。 次の例では、ピクチャボックス「PictureBox1」の座標(20, 10)-(200, 100)に反転した線を引いています。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'PictureBox1の(20, 10)-(200, 100)に反転した線を引く 'PictureBox1上の座標を画面座標に変換する Dim startPoint As Point = PictureBox1.PointToScreen(New Point(20, 10)) Dim endPoint As Point = PictureBox1.PointToScreen(New Point(200, 100)) '黒で反転した線を引く ControlPaint.DrawReversibleLine(startPoint, endPoint, Color.Black) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //PictureBox1の(20, 10)-(200, 100)に反転した線を引く //PictureBox1上の座標を画面座標に変換する Point startPoint = PictureBox1.PointToScreen(new Point(20, 10)); Point endPoint = PictureBox1.PointToScreen(new Point(200, 100)); //黒で反転した線を引く ControlPaint.DrawReversibleLine(startPoint, endPoint, Color.Black); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ○この記事の基になった掲示板のスレッド [題名] Xorペン [投稿者(敬称略)] ぼろん, よねKEN [URL] http://dobon.net/vb/bbs/log3-2/983.html [題名] Drawmode=6 [投稿者(敬称略)] ぱーやん, 管理人 [URL] http://dobon.net/vb/bbs/log3-7/3762.html [題名] DrawMode = vbInvert機能 [投稿者(敬称略)] NINE, テラオメガ, 深山 [URL] http://dobon.net/vb/bbs/log3-8/4830.html ─────────────────────────────── ●クリップボードにファイルをコピーする、またはクリップボードから ファイルを取得するには? 【質問】 エクスプローラでコピーしたファイルのパスを取得するにはどのよう にすればよいのでしょうか?また、指定したファイルをクリップボー ドへコピーすることはできますか? 【回答】 DOBON.NET .NET Tipsの「クリップボードに文字列をコピー、クリッ プボードから文字列を取得」で紹介しているのと同じように、 Clipboard.GetDataObjectメソッドを使うことにより、エクスプロー ラでコピーしたファイルのパスを取得できます。IDataObject. GetDataメソッドでデータを抽出する際にはDataFormats.FileDropデー タ形式を指定し、文字列配列として取得します。 [URL]DOBON.NET .NET Tips - クリップボードに文字列をコピー、ク リップボードから文字列を取得 http://dobon.net/vb/dotnet/string/clipboard.html 次のコードでは、クリップボードにファイルがコピーされている時に そのパスを取得し、出力しています。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'クリップボードのデータを取得する Dim iData As IDataObject = Clipboard.GetDataObject() 'クリップボードにファイルドロップ形式のデータがあるか確認 If iData.GetDataPresent(DataFormats.FileDrop) Then 'データを取得する Dim fileNames As String() = _ CType(iData.GetData(DataFormats.FileDrop), String()) '取得したファイル名を列挙する Dim fileName As String For Each fileName In fileNames Console.WriteLine(fileName) Next fileName End If ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //クリップボードのデータを取得する IDataObject iData = Clipboard.GetDataObject(); //クリップボードにファイルドロップ形式のデータがあるか確認 if (iData.GetDataPresent(DataFormats.FileDrop)) { //データを取得する string[] fileNames = (string[]) iData.GetData(DataFormats.FileDrop); //取得したファイル名を列挙する foreach (string fileName in fileNames) { Console.WriteLine(fileName); } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ファイルをクリップボードにコピーする時も同様に、Clipboard. SetDataObjectメソッドを使用し、DataFormats.FileDropデータ形式 のDataObjectオブジェクトをクリップボードに貼り付けます。この様 にしてクリップボードに貼り付けたファイルはエクスプローラでペー ストできます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'コピーするファイルのパス Dim fileNames As String() = {"C:\1.txt", "C:\2.txt", "C:\3.txt"} 'ファイルドロップ形式のDataObjectを作成する Dim iData = New DataObject(DataFormats.FileDrop, fileNames) 'クリップボードにコピーする Clipboard.SetDataObject(iData) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //コピーするファイルのパス string[] fileNames = {"C:\\1.txt", "C:\\2.txt", "C:\\3.txt"}; //ファイルドロップ形式のDataObjectを作成する IDataObject iData = new DataObject(DataFormats.FileDrop, fileNames); //クリップボードにコピーする Clipboard.SetDataObject(iData); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ○この記事の基になった掲示板のスレッド [題名] コードからクリップボードへファイルをコピー(配置)する方法 [投稿者(敬称略)] とざマン [URL] http://dobon.net/vb/bbs/log3-2/1018.html ─────────────────────────────── ●システム時計の日時を設定するには? 【質問】 システム時計の日時を設定するには、どのようにすればよいのでしょ うか? 【回答】 システム日時を勝手に変更してしまうことがよいことかという議論は 置いておき、システム日時を変更する方法を2つ紹介します。 VB.NETでは、Todayプロパティ及びDateStringプロパティでシステム 日付を、TimeOfDayプロパティ及びTimeStringプロパティでシステム 時刻を設定できます。VB.NET以外でもMicrosoft.VisualBasic.dllを 参照することにより、これらのプロパティにアクセスできます。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 'システム日付を2005/1/2にする Today = New DateTime(2005, 1, 2, 0, 0, 0) 'システム日付を2005/2/3にする DateString = "2005-2-3" 'システム時刻を6:15:30にする TimeOfDay = New DateTime(2000, 1, 1, 6, 15, 30) 'システム時刻を8:25:45にする TimeString = "8:25:45" ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //システム日付を2005/1/2にする Microsoft.VisualBasic.DateAndTime.Today = new DateTime(2005, 1, 2, 0, 0, 0); //システム日付を2005/2/3にする Microsoft.VisualBasic.DateAndTime.DateString = "2005-2-3"; //システム時刻を6:15:30にする Microsoft.VisualBasic.DateAndTime.TimeOfDay = new DateTime(2000, 1, 1, 6, 15, 30); //システム時刻を8:25:45にする Microsoft.VisualBasic.DateAndTime.TimeString = "8:25:45"; ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ また、Win32 APIのSetLocalTime関数を使用してシステム日時を変更 することもできます。下のSetNowDateTimeメソッドは、DateTime型で 日時を指定してシステム日時を変更するメソッドです。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ _ Public Structure SystemTime Public wYear As Short Public wMonth As Short Public wDayOfWeek As Short Public wDay As Short Public wHour As Short Public wMinute As Short Public wSecond As Short Public wMiliseconds As Short End Structure _ Public Shared Function SetLocalTime( _ ByRef sysTime As SystemTime) As Boolean End Function ''' ''' 現在のシステム日時を設定する ''' ''' 設定する日時 Public Shared Sub SetNowDateTime(ByVal dt As DateTime) 'システム日時に設定する日時を指定する Dim sysTime As New SystemTime sysTime.wYear = dt.Year sysTime.wMonth = dt.Month sysTime.wDay = dt.Day sysTime.wHour = dt.Hour sysTime.wMinute = dt.Minute sysTime.wSecond = dt.Second sysTime.wMiliseconds = dt.Millisecond 'システム日時を設定する SetLocalTime(sysTime) End Sub ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct SystemTime { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMiliseconds; } [DllImport("kernel32.dll")] public static extern bool SetLocalTime( ref SystemTime sysTime); /// /// 現在のシステム日時を設定する /// /// 設定する日時 public static void SetNowDateTime(DateTime dt) { //システム日時に設定する日時を指定する SystemTime sysTime = new SystemTime(); sysTime.wYear = (ushort) dt.Year; sysTime.wMonth = (ushort) dt.Month; sysTime.wDay = (ushort) dt.Day; sysTime.wHour = (ushort) dt.Hour; sysTime.wMinute = (ushort) dt.Minute; sysTime.wSecond = (ushort) dt.Second; sysTime.wMiliseconds = (ushort) dt.Millisecond; //システム日時を設定する SetLocalTime(ref sysTime); } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ○この記事の基になった掲示板のスレッド [題名] システム時計について [投稿者(敬称略)] カー君, よねKEN [URL] http://dobon.net/vb/bbs/log3-2/1156.html ─────────────────────────────── ●DataGridコントロールの列の幅をユーザーが変更できないように するには? 【質問】 System.Windows.Forms.DataGridコントロールの列の幅をユーザーが 変更できないようにできますか? 【回答】 これに関しては、「Windows Forms FAQ」が参考になります。 [URL]Windows Forms FAQ - How can I prevent my user from sizing columns in my datagrid? http://www.syncfusion.com/faq/winforms/search/872.asp この記事で紹介されている方法は、DataGridクラスの派生クラスを作 成し、OnMouseMoveとOnMouseDownメソッドをオーバーライドし、マウ スが列ヘッダの境界線上にあるときは何もしないようにするというも のです。 この方法によるサンプルを以下に示します。このDataGridExクラスを System.Windows.Forms.DataGridの代わりに使用してください。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ''' ''' 列ヘッダの幅をユーザーが変更することができないDataGrid ''' Public Class DataGridEx Inherits System.Windows.Forms.DataGrid Protected Overrides Sub OnMouseMove( _ ByVal e As System.Windows.Forms.MouseEventArgs) '列ヘッダの境界線上にマウスがあるときは何もしない Dim hti As System.Windows.Forms.DataGrid.HitTestInfo = _ Me.HitTest(New System.Drawing.Point(e.X, e.Y)) If hti.Type = _ System.Windows.Forms.DataGrid.HitTestType.ColumnResize Then Return End If MyBase.OnMouseMove(e) End Sub Protected Overrides Sub OnMouseDown( _ ByVal e As System.Windows.Forms.MouseEventArgs) '列ヘッダの境界線上にマウスがあるときは何もしない Dim hti As System.Windows.Forms.DataGrid.HitTestInfo = _ Me.HitTest(New System.Drawing.Point(e.X, e.Y)) If hti.Type = _ System.Windows.Forms.DataGrid.HitTestType.ColumnResize Then Return End If MyBase.OnMouseDown(e) End Sub End Class ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ /// /// 列ヘッダの幅をユーザーが変更することができないDataGrid /// public class DataGridEx : System.Windows.Forms.DataGrid { protected override void OnMouseMove( System.Windows.Forms.MouseEventArgs e) { //列ヘッダの境界線上にマウスがあるときは何もしない System.Windows.Forms.DataGrid.HitTestInfo hti = this.HitTest(new System.Drawing.Point(e.X, e.Y)); if(hti.Type == System.Windows.Forms.DataGrid.HitTestType.ColumnResize) { return; } base.OnMouseMove(e); } protected override void OnMouseDown( System.Windows.Forms.MouseEventArgs e) { //列ヘッダの境界線上にマウスがあるときは何もしない System.Windows.Forms.DataGrid.HitTestInfo hti = this.HitTest(new System.Drawing.Point(e.X, e.Y)); if(hti.Type == System.Windows.Forms.DataGrid.HitTestType.ColumnResize) { return; } base.OnMouseDown(e); } } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 掲示板では、こど。さんが列の幅が変更された時に列の幅を元に戻す という方法を紹介されています。詳しくは、下の「カラムヘッダの固 定に関して」をご覧ください。 ○この記事の基になった掲示板のスレッド [題名] カラムヘッダの固定に関して [投稿者(敬称略)] 咲くら, こど。 [URL] http://dobon.net/vb/bbs/log3-4/2044.html [題名] DetaGlidの列幅を操作不可にしたいです。 [投稿者(敬称略)] こう, 管理人, java.lang.Nullpo [URL] http://dobon.net/vb/bbs/log3-12/7060.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 - 2005 DOBON! All rights reserved. ===============================