VB.netでWin32APIのCreateProcess関数を呼び出す
VB.netでWin32APIのCreateProcess関数を呼び出したのでメモ。 CreateProcess関数でメモ帳を実行する。 WaitForSingleObject関数で、lngWaitForObjectTimeOut に設定した時間が経過するか、メモ帳が閉じられない限り、フォームの操作を受け付けなくする。
Form1.vb
Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim strExeFileName As String Dim strCommandLine As String Dim udtProcessAttributes As SECURITY_ATTRIBUTES Dim udtThreadAttributes As SECURITY_ATTRIBUTES Dim strCurrentDriectory As String Dim lngWaitForObjectTimeOut As Integer Dim lngWaitForObjectEvent As Integer Dim lngWin32apiResultCode As Integer Dim si As STARTUPINFO Dim pi As PROCESS_INFORMATION ' 実行可能ファイル名を指定 strExeFileName = "C:\Windows\System32\notepad.exe" ' コマンドラインを指定 strCommandLine = vbNullString ' セキュリティ構造体を初期化 udtProcessAttributes.nLength = Len(udtProcessAttributes) udtThreadAttributes.nLength = Len(udtThreadAttributes) ' カレントディレクトリを指定 strCurrentDriectory = vbNullString ' 新しいプロセスのメインウィンドウの表示状態を指定 si.cb = Len(si) ' 新しいプロセスを作成 lngWin32apiResultCode = CreateProcess(strExeFileName, strCommandLine, udtProcessAttributes, udtThreadAttributes, False, 0, 0, strCurrentDriectory, si, pi) ' 待機するタイムアウト時間を指定 lngWaitForObjectTimeOut = 6000 ' 新しいプロセスがシグナル状態になるまで待機 lngWaitForObjectEvent = WaitForSingleObject(pi.hProcess, lngWaitForObjectTimeOut) ' 待機結果を表示 Select Case lngWaitForObjectEvent Case STATUS_WAIT_0 Label4.Text = "プロセスは終了しました。" Case WAIT_TIMEOUT Label4.Text = "待機はタイムアウトしました。" Case WAIT_FAILED Label4.Text = "待機は失敗しました。" End Select End Sub End Class
Module1.vb
Option Explicit On Module Module1 ' セキュリティ属性に関する情報を定義する構造体 Structure SECURITY_ATTRIBUTES Dim nLength As Integer Dim lpSecurityDescriptor As Integer Dim bInheritHandle As Integer End Structure ' 新しいプロセスのメインウィンドウの表示状態を定義する構造体 Structure STARTUPINFO Dim cb As Integer Dim lpReserved As Integer Dim lpDesktop As Integer Dim lpTitle As Integer Dim dwX As Integer Dim dwY As Integer Dim dwXSize As Integer Dim dwYSize As Integer Dim dwXCountChars As Integer Dim dwYCountChars As Integer Dim dwFillAttribute As Integer Dim dwFlags As Integer Dim wShowWindow As Short Dim cbReserved2 As Short Dim lpReserved2 As Byte Dim hStdInput As Integer Dim hStdOutput As Integer Dim hStdError As Integer End Structure Structure PROCESS_INFORMATION Public hProcess As Integer Public hThread As Integer Public dwProcessId As Integer Public dwThreadId As Integer End Structure Declare Function CreateProcess Lib "kernel32.dll" _ Alias "CreateProcessA" ( ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByRef lpProcessAttributes As SECURITY_ATTRIBUTES, ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Integer, ByVal dwCreationFlags As Integer, ByVal lpEnvironment As Byte, ByVal lpCurrentDriectory As String, ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Integer ' オブジェクトの状態がシグナル状態あるいはタイムアウト時間が ' 経過するまで待機する関数の宣言 Declare Function WaitForSingleObject Lib "kernel32.dll" _ (ByVal hHandle As Integer, ByVal dwMilliseconds As Integer) As Integer Public Const STATUS_WAIT_0 = &H0& 'ublic Const STATUS_ABANDONED_WAIT_0 = &H80& Public Const STATUS_TIMEOUT = &H102& 'ublic Const WAIT_OBJECT_0 = ((STATUS_WAIT_0) + 0) 'ublic Const WAIT_ABANDONED = ((STATUS_ABANDONED_WAIT_0) + 0) Public Const WAIT_TIMEOUT = STATUS_TIMEOUT Public Const WAIT_FAILED = &HFFFFFFFF 'ublic Const INFINITE = &HFFFFFFFF End Module
VB.netでListViewのViewプロパティがDetailsの時、特に何もしなくても勝手にツールチップが表示された
dobon.net ↑を参考にしてあれこれ試していましたが、最終的には何もしなくても各項目の上にマウスを移動してなおかつ項目のテキストがコントロールが狭くて全部表示しきれていない場合に勝手にツールチップが表示されるという事に気づきました。 ツールチップの内容を変更して表示させたい時に参考にするかもしれないので一応、コードを保存。 ただ自分の場合は、ツールチップを自動的に表示させる機能が邪魔しているのか、うまく動きませんでした。
Public Class ListViewToolTipTestForm_ver2 Inherits Form Dim WithEvents ListView1 As New ListView Dim ToolTip1 As New ToolTip Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) Me.Text = Me.GetType.Name With Me.ListView1 .View = View.Details .Bounds = New Rectangle(100, 100, 300, 300) .Columns.Add("列1") .Columns.Add("列2") .Columns.Add("列3") Dim lvi As New ListViewItem(New String() {"日本語", "英語", "VisualBasic"}) lvi.SubItems(0).Tag = "こんにちは" lvi.SubItems(1).Tag = "Hello" lvi.SubItems(2).Tag = "Hello World!!" .Items.Add(lvi) End With Me.Controls.Add(Me.ListView1) MyBase.OnLoad(e) End Sub Dim m_lastsubitem As ListViewItem.ListViewSubItem Private Sub ListView1_MouseMove(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseMove Dim hi As ListViewHitTestInfo = Me.ListView1.HitTest(Me.ListView1.PointToClient(Control.MousePosition)) Dim si As ListViewItem.ListViewSubItem = hi.SubItem If Me.m_lastsubitem Is si Then Return If Me.ToolTip1.Active = True Then Me.ToolTip1.Active = False End If If si IsNot Nothing Then Me.ToolTip1.SetToolTip(Me.ListView1, Me.MyToString(si.Tag)) Me.ToolTip1.Active = True End If Me.m_lastsubitem = si End Sub Private Function MyToString(ByVal o As Object) As String If o Is Nothing Then Return "" Return o.ToString End Function End Class
VB.netでTreeViewのノードにコンテキストメニューを追加してメニューの「名前を変更する」をクリックするとノードの名前が入力待機状態になるようにする
↑を参考にしました
Public Class Form1 Private ctMenuStrip As New ContextMenuStrip Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load TreeView1.LabelEdit = True TreeView1.Nodes.Add("いち") TreeView1.Nodes.Add("に") TreeView1.Nodes(0).ContextMenuStrip = ctMenuStrip TreeView1.Nodes(1).ContextMenuStrip = ctMenuStrip ctMenuStrip.Items.Add("名前を変更する") AddHandler ctMenuStrip.Items(0).Click, AddressOf ctMenuStrip_0_Click End Sub Private Sub ctMenuStrip_0_Click(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles ctMenuStrip0.Click TreeView1.SelectedNode.BeginEdit() End Sub Private Sub TreeView1_NodeMouseClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseClick TreeView1.SelectedNode = e.Node TreeView1.Focus() e.Node.ContextMenuStrip.Show() End Sub End Class
VB.netでTreeViewの内容をXMLに保存したり読み出したりする
↑のサイトを参考にさせていただきました。
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load TreeView1.Nodes.Add("いち") TreeView1.Nodes(0).Nodes.Add("よん") TreeView1.Nodes(0).Nodes(0).Nodes.Add("ご") TreeView1.Nodes.Add("に") TreeView1.Nodes.Add("さん") TreeView1.ExpandAll() End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'TreeViewをXMLに保存する Dim savePath As String = Application.StartupPath & "\TreeView.xml" Dim serializer As New clsTree serializer.SerializeTreeView(Me.TreeView1, savePath) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'XMLからロードしてTreeViewに展開する Dim loadPath As String = Application.StartupPath & "\TreeView.xml" Dim serializer As New clsTree serializer.DeserializeTreeView(Me.TreeView1, loadPath) End Sub End Class
Imports System Imports System.Xml Imports System.Windows.Forms Imports System.Text Public Class clsTree '// Xml tag for node, e.g. 'node' in case of <node></node> Private Const XmlNodeTag As String = "node" '// Xml attributes for node e.g. <node text="Asia" tag="" '// imageindex="1"></node> Private Const XmlNodeTextAtt As String = "text" Private Const XmlNodeTagAtt As String = "tag" Private Const XmlNodeImageIndexAtt As String = "imageindex" 'Public Sub DeserializeTreeView(ByRef treeView As Windows.Forms.TreeView, ByVal fileName As String) Public Sub DeserializeTreeView(ByRef treeView As TreeView, ByVal fileName As String) Dim reader As XmlTextReader reader = Nothing Try '// disabling re-drawing of treeview till all nodes are added treeView.BeginUpdate() reader = New XmlTextReader(fileName) Dim parentNode As TreeNode parentNode = Nothing While (reader.Read) If reader.NodeType = XmlNodeType.Element Then If reader.Name = XmlNodeTag Then Dim newNode As TreeNode = New TreeNode() Dim isEmptyElement As Boolean = reader.IsEmptyElement '// loading node attributes Dim attributeCount As Integer = reader.AttributeCount If attributeCount > 0 Then Dim i As Integer For i = 0 To attributeCount - 1 reader.MoveToAttribute(i) SetAttributeValue(newNode, reader.Name, reader.Value) Next End If '// add new node to Parent Node or TreeView If (parentNode IsNot Nothing) Then parentNode.Nodes.Add(newNode) Else treeView.Nodes.Add(newNode) End If '// making current node 'ParentNode' if its not empty If (isEmptyElement = False) Then parentNode = newNode End If End If '// moving up to in TreeView if end tag is encountered ElseIf reader.NodeType = XmlNodeType.EndElement Then If reader.Name = XmlNodeTag Then parentNode = parentNode.Parent End If ElseIf (reader.NodeType = XmlNodeType.XmlDeclaration) Then '//Ignore Xml Declaration ElseIf reader.NodeType = XmlNodeType.None Then Exit Sub ElseIf (reader.NodeType = XmlNodeType.Text) Then parentNode.Nodes.Add(reader.Value) End If End While Catch ex As System.Exception Finally '// enabling redrawing of treeview after all nodes are added treeView.EndUpdate() reader.Close() End Try End Sub Private Sub SetAttributeValue(ByRef node As TreeNode, ByVal propertyName As String, ByVal value As String) If propertyName = XmlNodeTextAtt Then node.Text = value ElseIf propertyName = XmlNodeImageIndexAtt Then node.ImageIndex = Integer.Parse(value) ElseIf (propertyName = XmlNodeTagAtt) Then node.Tag = value End If End Sub Public Sub SerializeTreeView(ByRef TreeView As TreeView, ByVal fileName As String) Dim textWriter As New XmlTextWriter(fileName, System.Text.Encoding.Unicode) textWriter.WriteStartDocument() textWriter.WriteStartElement("TreeView") SaveNodes(TreeView.Nodes, textWriter) textWriter.WriteEndElement() textWriter.Close() End Sub Private Sub SaveNodes(ByRef nodesCollection As TreeNodeCollection, ByRef textWriter As Xml.XmlTextWriter) Dim i As Integer For i = 0 To nodesCollection.Count - 1 Dim node As TreeNode = nodesCollection.Item(i) textWriter.WriteStartElement(XmlNodeTag) textWriter.WriteAttributeString(XmlNodeTextAtt, node.Text) textWriter.WriteAttributeString(XmlNodeImageIndexAtt, node.ImageIndex.ToString()) If node.Tag IsNot Nothing Then textWriter.WriteAttributeString(XmlNodeTagAtt, node.Tag.ToString()) If node.Nodes.Count > 0 Then SaveNodes(node.Nodes, textWriter) End If textWriter.WriteEndElement() Next End Sub End Class
保存されたXMLをブラウザで開いてみたら以下のような感じになる
<?xml version="1.0" encoding="UTF-16"?> -<TreeView> -<node imageindex="-1" text="いち"> -<node imageindex="-1" text="よん"> <node imageindex="-1" text="ご"/> </node> </node> <node imageindex="-1" text="に"/> <node imageindex="-1" text="さん"/> </TreeView>
TreeViewのノードをクリックしたとき表示されるコンテキストメニューをツールボックスからのコントロールの追加ではなく、コードを書いて作成しイベントを追加する
ContextMenuStripをコントロールの追加ではなく、コードを書いて作成しています。さらに各項目がクリックされたときのイベントを追加しています。
Public Class Form1 Private ctMenuStrip As New ContextMenuStrip Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load TreeView1.Nodes.Add("いち") ctMenuStrip.Items.Add("テスト1") ctMenuStrip.Items.Add("テスト2") TreeView1.Nodes(0).ContextMenuStrip = ctMenuStrip AddHandler ctMenuStrip.Items(0).Click, AddressOf ctMenuStrip_0_Click AddHandler ctMenuStrip.Items(1).Click, AddressOf ctMenuStrip_1_Click End Sub Public Sub ctMenuStrip_0_Click(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles ctMenuStrip0.Click MessageBox.Show("テスト1がクリックされました") End Sub Public Sub ctMenuStrip_1_Click(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles ctMenuStrip0.Click MessageBox.Show("テスト2がクリックされました") End Sub End Class
VBでフォームが作成されているか確認する
フォームが作成されているかどうか確認できるようだ。
If My.Application.OpenForms("Form1") IsNot Nothing Then End If
VBで自作のクラスをソートしてみた
ファイル名をソートした時 1.jpg 10.jpg 11.jpg 12.jpg ~略~ 18.jpg 19.jpg 2.jpg 20.jpg のようにソートされてしまったのでちゃんと 1.jpg 2.jpg 3.jpg ~略~ 8.jpg 9.jpg 10.jpg 11.jpg のようにソートされるコードを書いてみました。
Public Class Product2 Implements System.IComparable Private _fullFileName As String 'String型のプロパティ Public ReadOnly Property fullFileName() As String Get Return Me._fullFileName End Get End Property Private _fileName As String Public ReadOnly Property fileName() As String Get Return Me._fileName End Get End Property Private _indexNo As Integer Public ReadOnly Property indexNo() As String Get Return Me._indexNo End Get End Property 'コンストラクタ Public Sub New(ByVal fullFileName As String, ByVal fileName As String, ByVal indexNo As Integer) Me._fullFileName = fullFileName Me._fileName = fileName Me._indexNo = indexNo End Sub '自分自身がobjより小さいときはマイナスの数、大きいときはプラスの数、 '同じときは0を返す Public Function CompareTo(ByVal obj As Object) As Integer _ Implements System.IComparable.CompareTo 'Nothingより大きい If obj Is Nothing Then Return 1 End If '違う型とは比較できない If Not Me.GetType() Is obj.GetType() Then Throw New ArgumentException("別の型とは比較できません。", "obj") End If If Me.fileName = DirectCast(obj, Product2).fileName Then Return 0 End If If Me.fileName.Length = DirectCast(obj, Product2).fileName.Length Then Dim index As Integer = 0 While index < Me.fileName.Length And Me.fileName(index) = (DirectCast(obj, Product2).fileName(index)) index = index + 1 End While Return CInt(Me.fileName(index).ToString) - CInt(DirectCast(obj, Product2).fileName(index).ToString) End If Return Me.fileName.Length - (DirectCast(obj, Product2).fileName.Length) End Function End Class
呼び出し側
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'ArrayListの作成 Dim al As New System.Collections.ArrayList() al.Add(New Product2("C:\aa\bb\3.jpg", "20.jpg", 5)) al.Add(New Product2("C:\aa\bb\22.jpg", "17.jpg", 5)) al.Add(New Product2("C:\aa\bb\3.jpg", "2.jpg", 5)) al.Add(New Product2("C:\aa\bb\1.jpg", "3.jpg", 5)) al.Add(New Product2("C:\aa\bb\7.jpg", "4.jpg", 5)) al.Add(New Product2("C:\aa\bb\15.jpg", "19.jpg", 5)) al.Add(New Product2("C:\aa\bb\11.jpg", "6.jpg", 5)) al.Add(New Product2("C:\aa\bb\15.jpg", "7.jpg", 5)) al.Add(New Product2("C:\aa\bb\11.jpg", "12.jpg", 5)) al.Add(New Product2("C:\aa\bb\1.jpg", "9.jpg", 5)) al.Add(New Product2("C:\aa\bb\7.jpg", "10.jpg", 5)) al.Add(New Product2("C:\aa\bb\15.jpg", "13.jpg", 5)) al.Add(New Product2("C:\aa\bb\1.jpg", "15.jpg", 5)) al.Add(New Product2("C:\aa\bb\7.jpg", "16.jpg", 5)) al.Add(New Product2("C:\aa\bb\22.jpg", "5.jpg", 5)) al.Add(New Product2("C:\aa\bb\22.jpg", "11.jpg", 5)) al.Add(New Product2("C:\aa\bb\3.jpg", "8.jpg", 5)) al.Add(New Product2("C:\aa\bb\11.jpg", "18.jpg", 5)) al.Add(New Product2("C:\aa\bb\11.jpg", "9.jpg", 5)) al.Add(New Product2("C:\aa\bb\1.jpg", "21.jpg", 5)) al.Add(New Product2("C:\aa\bb\15.jpg", "1.jpg", 5)) al.Add(New Product2("C:\aa\bb\7.jpg", "22.jpg", 5)) al.Add(New Product2("C:\aa\bb\22.jpg", "23.jpg", 5)) al.Add(New Product2("C:\aa\bb\3.jpg", "14.jpg", 5)) 'はじめの状態を表示 Console.WriteLine("並び替えなし") For Each c As Product2 In al Console.WriteLine("fullFileName: {0} / fileName: {1} / indexNo{2}", c.fullFileName, c.fileName, c.indexNo) Next al.Sort() Console.WriteLine("並び替え後") For Each c As Product2 In al Console.WriteLine("fullFileName: {0} / fileName: {1} / indexNo{2}", c.fullFileName, c.fileName, c.indexNo) Next End Sub
実行結果
並び替えなし fullFileName: C:\aa\bb\3.jpg / fileName: 20.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 17.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 2.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 3.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 4.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 19.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 6.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 7.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 12.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 9.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 10.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 13.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 15.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 16.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 5.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 11.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 8.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 18.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 9.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 21.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 1.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 22.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 23.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 14.jpg / indexNo5 並び替え後 fullFileName: C:\aa\bb\15.jpg / fileName: 1.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 2.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 3.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 4.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 5.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 6.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 7.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 8.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 9.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 9.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 10.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 11.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 12.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 13.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 14.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 15.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 16.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 17.jpg / indexNo5 fullFileName: C:\aa\bb\11.jpg / fileName: 18.jpg / indexNo5 fullFileName: C:\aa\bb\15.jpg / fileName: 19.jpg / indexNo5 fullFileName: C:\aa\bb\3.jpg / fileName: 20.jpg / indexNo5 fullFileName: C:\aa\bb\1.jpg / fileName: 21.jpg / indexNo5 fullFileName: C:\aa\bb\7.jpg / fileName: 22.jpg / indexNo5 fullFileName: C:\aa\bb\22.jpg / fileName: 23.jpg / indexNo5