- 題名: TreeViewのテキスト表示部分の右
- 日時: 2003/09/24 18:54:39
- ID: 717
- この記事の返信元:
- (なし)
- この記事への返信:
- [727] Re[1]: TreeViewのテキスト表示部分の右2003/09/26 3:21:53
- ツリーを表示
2003/09/29(Mon) 23:22:34 編集(投稿者)
>>次のURLが参考になりそうです。
>>C# Help - Outlook Style Tree View
>>http://www.csharphelp.com/archives2/archive286.html
> ありがとうございます。
> このサンプルが目的としている動作そのものです。
> C#のプログラムとしてきちんと動作も確認できました。
> と、よろこんでいたのもつかのまでして、
> VBのコードにうまく直せません。
提示URLのC#コードから、ざっくりと修正してVB版を作成してみました。
かなりいい加減なのでひょっとすると落ちるかもしれません。
(2,3度動かした範囲ではC#版と同様の動きで動いていますが)
'------------------------------------------------------------
Imports System
Imports System.Drawing
Imports System.Runtime.InteropServices
Namespace TB
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows フォーム デザイナで生成されたコード "
Public Sub New()
MyBase.New()
' この呼び出しは Windows フォーム デザイナで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後に初期化を追加します。
End Sub
' Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
' Windows フォーム デザイナで必要です。
Private components As System.ComponentModel.IContainer
' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
'Windows フォーム デザイナを使って変更してください。
' コード エディタを使って変更しないでください。
Friend WithEvents treeView1 As System.Windows.Forms.TreeView
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.treeView1 = New System.Windows.Forms.TreeView
Me.SuspendLayout()
'
'treeView1
'
Me.treeView1.Dock = System.Windows.Forms.DockStyle.Fill
Me.treeView1.ImageIndex = -1
Me.treeView1.Location = New System.Drawing.Point(0, 0)
Me.treeView1.Name = "treeView1"
Me.treeView1.Nodes.AddRange( _
New System.Windows.Forms.TreeNode() { _
New System.Windows.Forms.TreeNode("My TreeView Today ", _
New System.Windows.Forms.TreeNode() { _
New System.Windows.Forms.TreeNode("Node1")}), _
New System.Windows.Forms.TreeNode("Node2"), _
New System.Windows.Forms.TreeNode("Node3"), _
New System.Windows.Forms.TreeNode("Node4", _
New System.Windows.Forms.TreeNode() { _
New System.Windows.Forms.TreeNode("Node5", _
New System.Windows.Forms.TreeNode() { _
New System.Windows.Forms.TreeNode("Node6", _
New System.Windows.Forms.TreeNode() { _
New System.Windows.Forms.TreeNode("Node7", _
New System.Windows.Forms.TreeNode() { _
New System.Windows.Forms.TreeNode("Node8")})})})})})
Me.treeView1.SelectedImageIndex = -1
Me.treeView1.Size = New System.Drawing.Size(152, 273)
Me.treeView1.TabIndex = 1
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
Me.ClientSize = New System.Drawing.Size(152, 273)
Me.Controls.Add(Me.treeView1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
#End Region
Private Const WM_NOTIFY As Integer = 78
Private ReadOnly NM_CUSTOMDRAW As UInt32 = Convert.ToUInt32(4294967284)
Private Const CDDS_ITEMPREPAINT As Integer = 65537
Private Const CDRF_NOTIFYSUBITEMDRAW As Integer = 32
Protected Overrides Sub WndProc(ByRef m As Message)
Dim lp2 As NMCUSTOMDRAW
Dim lp As NMHDR
If (m.Msg = WM_NOTIFY) Then
lp = Marshal.PtrToStructure(m.LParam, lp.GetType())
If (lp.code.CompareTo(NM_CUSTOMDRAW) = 0) Then
lp2 = Marshal.PtrToStructure(m.LParam, lp2.GetType())
If (lp2.dwDrawStage = CDDS_ITEMPREPAINT) Then
MyBase.WndProc(m)
TreeViewPaint(m)
m.Result = IntPtr.Zero
Return
Else
m.Result = New IntPtr(CDRF_NOTIFYSUBITEMDRAW)
End If
End If
End If
MyBase.WndProc(m)
End Sub
Public Sub TreeViewPaint(ByRef m As Message)
Dim lp2 As NMCUSTOMDRAW
Dim g As Graphics
Dim node As TreeNode
Dim strText As String '//Text to draw
Dim x1, y1 As Long '//coordinates there we will paint
lp2 = Marshal.PtrToStructure(m.LParam, lp2.GetType())
g = System.Drawing.Graphics.FromHwnd(Me.treeView1.Handle)
node = Me.treeView1.GetNodeAt(CInt(lp2.x1) + 1, CInt(lp2.y1) + 1)
x1 = lp2.x1 + node.Bounds.X + node.Bounds.Width + 5
y1 = lp2.y1
strText = "( " + node.Index.ToString() + " )"
g.DrawString(strText, Me.treeView1.Font, System.Drawing.Brushes.DarkBlue, x1, y1, System.Drawing.StringFormat.GenericTypographic)
Return
End Sub
<STAThread()> _
Public Shared Sub Main()
Application.Run(New Form1)
End Sub
End Class
Public Structure NMHDR
Public hwndFrom As IntPtr
Public idFrom As Integer
Public code As UInt32
End Structure
Public Structure NMLVCUSTOMDRAW
Public hdr As NMCUSTOMDRAW
Public clrText As Integer
Public clrTextBk As Integer
Public iSubItem As Integer
End Structure
Public Structure NMCUSTOMDRAW
Public hdr As NMHDR
Public dwDrawStage As Integer
Public hdc As Integer
Public x1 As Integer
Public y1 As Integer
Public x2 As Integer
Public y2 As Integer
Public dwItemSpec As Integer
Public uItemState As Integer
Public lItemlParam As Integer
End Structure
End Namespace
'------------------------------------------------------------
> 定数宣言の部分を
> Private WM_NOTIFY As System.UInt32 = 78
> と書いてみたところ
> 「定数はclass、structure、または array型ではなく、組み込み型または列挙型でなければなりません。」
> というエラーがでます。
Constが抜けていますが、Const指定で定数にしようとしたんですよね?
VBのConstステートメントはVBの組み込み型しか型として使えないようなので、
UInt32の場合はConstステートメントは使えません。
ほとんどの場合はUInt32はIntegerで代用できます。
(どちらも32ビット整数で変数のサイズが同じでメモリ上でのイメージに違いがないためです)
定数NM_CUSTOMDRAWに関してはIntegerでは扱えない数値なので、
UInt32を使うためにConstのかわりにReadOnly指定を使ってみました。
> このあとには、WndProc関数内で使用しているポインタをどういう風に
> 書けばいいのかわかりません、という悩みが発生しそうです。
TreeViewのカスタムドローのときにWndProcメソッドのm.LParamで渡されるものは、
各構造体のポインタになっているので、ポインタから構造体への変換は、
MarshalクラスのPtrToStructureメソッドで行っています。
#MarshalクラスはSystem.Runtime.InteropServices名前空間のため
#Imports System.Runtime.InteropServicesを追加してます。
どうもです。
VB.NETで、TreeViewコントロールのTextプロパティの表示部分の後に
OutlookExpressの未読メールカウントのような
フォントの違う文字を表示するにはどうしたらよいのでしょうか?
受信トレイ (2)
↑この「受信トレイ」が普通(黒字)で、「(2)」が青太字みたいに表示したい
よろしくお願いします。