Passing structure as argument through files/functions - vb.net

I can't get to pass structure as argument through subs/functions in different files of single vbnet project like I use to in earlier MS basic versions.
Here is short example of situation:
Module1.vb
Imports System.IO
Structure mymultitry
Dim index As Integer
<VBFixedString(6)> Dim name As String
Dim weight As Double
End Structure
Module Module1
Public mysetupfile = "mysetup.dat"
Public Sub rwfile(ByVal rw As Integer, ByVal myrecord As Integer, ByVal mmt As mymultitry)
'EDIT: Thanks to SteveDog - proper line should be:
'Public Sub rwfile(ByVal rw As Integer, ByVal myrecord As Integer, ByRef mmt As mymultitry)
Dim fnum As Integer
fnum = FreeFile()
FileOpen(fnum, mysetupfile, OpenMode.Random, OpenAccess.ReadWrite, OpenShare.Shared, Len(mmt))
If rw Then
FilePut(fnum, mmt, myrecord)
Else
FileGet(fnum, mmt, myrecord)
End If
FileClose(fnum)
End Sub
End Module
Form1.vb
Public Class Form1
Dim mmt As mymultitry
Dim mmt1 As mymultitry
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With mmt
.index = 4
.name = "Helga"
.weight = 128.1445
End With
rwfile(1, 1, mmt) 'write
rwfile(0, 1, mmt1) 'read
'all zero here !?!
Debug.Print(mmt1.index)
Debug.Print(mmt1.name)
Debug.Print(mmt1.weight)
End Sub
End Class
File "mysetup.dat" is reachable and data is saved correctly what I can see with HxD.
But read part seem's to not work as expected.
Please any help on reliable passing structure as argument without too much public elements based on upper example.

I strongly suggest you rewrite your code to use the new .NET IO methods in the System.IO.File class, but, that aside, I think your problem with your existing code is that you need to change your mmt argument from ByVal to ByRef.

Related

Receive and control serial device data in visual basic

I have a serial device which sends me data at the baudrate of 38400 and i get it like this ?#D00014C000 000. I can see data comes in on a ritchtextbox but what im trying to do is to use some characters from the string in a list box.
For example i want characters "14C" appears in the listbox3. I tried the substring and mid function but listbox lidnt work properly and losses characters or confuse them . Here is my code. Any suggestions please??
Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.IO.Ports
Public Class frmMain
Dim myPort As Array
Delegate Sub SetTextCallback(ByVal [text] As String)
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
ReceivedText(SerialPort1.ReadExisting())
End Sub
Private Sub ReceivedText(ByVal [text] As String)
If Me.rtbReceived.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.rtbReceived.Text &= [text]
Dim fine As String = Mid([text], 7, 3)
Dim list As Integer = ListBox3.Items.Add(fine)
End If
End Sub
End Class
Here isPICTURE 1 what happens
Picture2

Prevent file from being deleted but still be able to read it

I have searched this a lot but still I couldn't find something useful basically I tried changing file permissions to deny the delete option and keep modification and so many other combinations.I want something to prevent file from being deleted but still allow me to read it I did this both manually and using vb.net this is the code I used(it is not mine btw)
lets say I have a text file already created I want that file to be read but not deleted by the user
Imports System.IO
Imports System.Security.AccessControl
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim filename As String = "C:\users\mbpc\desktop\test.txt"
AddFileSecurity(filename, "Everyone", FileSystemRights.Delete, AccessControlType.Deny)
End Sub
Sub AddFileSecurity(ByVal fileName As String, ByVal account As String, _
ByVal rights As FileSystemRights, ByVal controlType As AccessControlType)
Dim fSecurity As FileSecurity = File.GetAccessControl(fileName)
Dim accessRule As FileSystemAccessRule = _
New FileSystemAccessRule(account, rights, controlType)
fSecurity.AddAccessRule(accessRule)
File.SetAccessControl(fileName, fSecurity)
End Sub
Sub RemoveFileSecurity(ByVal fileName As String, ByVal account As String, _
ByVal rights As FileSystemRights, ByVal controlType As AccessControlType)
Dim fSecurity As FileSecurity = File.GetAccessControl(fileName)
fSecurity.RemoveAccessRule(New FileSystemAccessRule(account, _
rights, controlType))
File.SetAccessControl(fileName, fSecurity)
End Sub
End Class

Replicate Windows Unhide folders and files function

I'm re-visiting a tool that I wrote in VB.Net for my helpdesk team a while back and want to add a couple of checkboxes to replicate the same function that Windows uses to show hidden files and folders / re-hide, as well as protected operating system files.
I know I can do this by editing a registry entry and restarting explorer.exe, but that closes all open Explorer Windows and I don't want that.
Does anyone know how Windows is able to do this by a simple click of a checkbox and how I may be able to code it in VB.net?
Any input on this is greatly appreciated in advance.
EDIT: So it looks like I have found a refresh method that works to refresh Windows Explorer / File Explorer which can be applied to Drarig's answer below but I am having trouble converting it to VB.net as the original example is in C#.
'Original at http://stackoverflow.com/questions/2488727/refresh-windows-explorer-in-win7
Private Sub refreshExplorer(ByVal explorerType As String)
Dim CLSID_ShellApplication As Guid = Guid.Parse("13709620-C279-11CE-A49E-444553540000")
Dim shellApplicationType As Type = Type.GetTypeFromCLSID(CLSID_ShellApplication, True)
Dim shellApplication As Object = Activator.CreateInstance(shellApplicationType)
Dim windows As Object = shellApplicationType.InvokeMember("Windows", Reflection.BindingFlags.InvokeMethod, Nothing, shellApplication, New Object() {})
Dim windowsType As Type = windows.GetType()
Dim count As Object = windowsType.InvokeMember("Count", Reflection.BindingFlags.GetProperty, Nothing, windows, Nothing)
For i As Integer = 0 To CType(count, Integer)
Dim item As Object = windowsType.InvokeMember("Item", Reflection.BindingFlags.InvokeMethod, Nothing, windows, New Object() {i})
Dim itemType As Type = item.GetType()
'Only fresh Windows explorer Windows
Dim itemName As String = CType(itemType.InvokeMember("Name", Reflection.BindingFlags.GetProperty, Nothing, item, Nothing), String)
If itemName = explorerType Then
itemType.InvokeMember("Refresh", Reflection.BindingFlags.InvokeMethod, Nothing, item, Nothing)
End If
Next
End Sub
I am getting an exception Object reference not set to an instance of an object when I set itemType as Type = item.GetType() above. I can't figure out which object isn't being created. When I step through the code it looks like windowsType contains an object for windows. Does anyone have any idea on this? Once this is worked out I can then apply it to Drarig's solution below.
Alright I wish I could have got this to you sooner, but busy lately at work. I took a little time today to figure this out as I love digging into something I have not done before. This is the whole class from a new project; didn't have time to wrap it up in a separate class. I am sure this will get you what you need. It was a little harder than I thought as getting the correct handle and then send the command, but I got it. I hope you find it useful.
P.S. Some of the things you can leave out, specifically the boolean used for loading, this was so I can pull the current value back on load and either check/uncheck the CheckBox.
Note: This is tried and tested on Windows 7, 8 and 10
Imports Microsoft.Win32
Imports System.Reflection
Imports System.Runtime.InteropServices
Public Class Form1
<Flags()> _
Public Enum KeyboardFlag As UInteger
KEYBOARDF_5 = &H74
End Enum
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function GetWindow(ByVal hl As Long, ByVal vm As Long) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
Private blnLoading As Boolean = False
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
Form1.HideFilesExtension(Me.CheckBox1.Checked)
If Not blnLoading Then NotifyFileAssociationChanged()
RefreshExplorer()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim name As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey(name, False)
blnLoading = True
Me.CheckBox1.Checked = CBool(key.GetValue("Hidden"))
key.Close()
blnLoading = False
End Sub
Private Shared Sub HideFilesExtension(ByVal Hide As Boolean)
Dim name As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey(name, True)
key.SetValue("Hidden", If(Hide, 1, 0))
key.Close()
End Sub
Public Shared Sub RefreshExplorer()
Dim clsid As New Guid("13709620-C279-11CE-A49E-444553540000")
Dim typeFromCLSID As Type = Type.GetTypeFromCLSID(clsid, True)
Dim objectValue As Object = Activator.CreateInstance(typeFromCLSID)
Dim obj4 As Object = typeFromCLSID.InvokeMember("Windows", BindingFlags.InvokeMethod, Nothing, objectValue, New Object(0 - 1) {})
Dim type1 As Type = obj4.GetType
Dim obj2 As Object = type1.InvokeMember("Count", BindingFlags.GetProperty, Nothing, obj4, Nothing)
If (CInt(obj2) <> 0) Then
Dim num2 As Integer = (CInt(obj2) - 1)
Dim i As Integer = 0
Do While (i <= num2)
Dim obj5 As Object = type1.InvokeMember("Item", BindingFlags.InvokeMethod, Nothing, obj4, New Object() {i})
Dim type3 As Type = obj5.GetType
Dim str As String = CStr(type3.InvokeMember("Name", BindingFlags.GetProperty, Nothing, obj5, Nothing))
If (str = "File Explorer") Then
type3.InvokeMember("Refresh", BindingFlags.InvokeMethod, Nothing, obj5, Nothing)
End If
i += 1
Loop
End If
End Sub
Public Shared Sub NotifyFileAssociationChanged()
'Find the actual window...
Dim hwnd As IntPtr = FindWindow("Progman", "Program Manager")
'Get the window handle and refresh option...
Dim j = GetWindow(hwnd, 3)
'Finally post the message...
PostMessage(j, 256, KeyboardFlag.KEYBOARDF_5, 3)
End Sub
End Class
Here's a solution for everything excepting the refreshing of the explorer.
I've translated the code, but I'm unable to find how to refresh the explorer/desktop without restarting it.
Const keyName As String = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Const Hidden As String = "Hidden"
Const SHidden As String = "ShowSuperHidden"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim St As Integer = GetRegValue(Hidden)
If St = 2 Then
SetRegValue(Hidden, 1)
SetRegValue(SHidden, 1)
Else
SetRegValue(Hidden, 2)
SetRegValue(SHidden, 0)
End If
End Sub
Private Function GetRegValue(valueName As String) As Integer
Return CInt(My.Computer.Registry.GetValue(keyName, valueName, 0))
End Function
Private Sub SetRegValue(valueName As String, value As Integer)
My.Computer.Registry.SetValue(keyName, valueName, value, Microsoft.Win32.RegistryValueKind.DWord)
End Sub
I have a few ideas to refresh the desktop :
Send a key to a running process. I tried this (source) :
Dim pp As Process() = Process.GetProcessesByName("explorer")
If pp.Length > 0 Then
For Each p In pp
AppActivate(p.Id)
SendKeys.SendWait("{F5}")
Next
End If
Refresh using SHChangeNotify (source),
Refresh broadcasting a WM_SETTINGCHANGE message (source),
etc.
I think you'll be forced to manually refresh or restart the explorer.

Having trouble with arguments and classes in VB

I am having trouble with getting classes to work and passing arguments for those classes. i have figured out most of the other Errors i had on my own, but there is one error that is really bugging me. the error i am getting is for "objAttendee". the error says "Argument not specified for parameter "strFirstName" of public Sub New(ByVal strFirstName As String, ByVal strLastName As String, ByVal strCourses As String, ByVal intDays As String)". i am not at all sure how to fix this problem.
can anyone help me out with this?
Option Strict On
Public Class Attendee
Dim objAttendee As New Attendee
'class variables
Private _strFirstName As String
Private _strLastName As String
Private _strCourses As String
Private _intDays As Integer
Private _decTotal As Decimal
Private _decCostPerDay As Decimal = 350D
Private _decPreConferenceCost As Decimal = 675D
Sub New(ByVal strFirstName As String, ByVal strLastName As String, ByVal strCourses As String, ByVal intDays As String)
'Contructor
_strFirstName = strFirstName
_strLastName = strLastName
_strCourses = strCourses
_intDays = Convert.ToInt32(intDays)
End Sub
Function ComputeCourseCosts() As Decimal
'Calculates the cost if a pre-conference course is not selected
_decTotal = _intDays * _decCostPerDay
Return _decTotal
End Function
Function ComputePreConferenceCosts() As Decimal
'Calculates the cost if a pre-conference course is selected
_decTotal = _intDays * _decCostPerDay + _decPreConferenceCost
Return _decTotal
End Function
End Class
"Argument not specified for parameter ".....
Plutonix told you the origin of the issue :
You're declaring a Attendee object within your Attendee Class (which doesn't really makes sense)
Public Class Attendee
Dim objAttendee As New Attendee ' <- offending code :P
But the constructor of that class is declared as follows :
Sub New(ByVal strFirstName As String, ByVal strLastName As String, ByVal strCourses As String, ByVal intDays As String)
And you don't have a constructor without any parameter like :
Public Sub New() ' No parameter required
' ...
End Sub
And you don't have to create/declare such variant of Attendee constructor, otherwise, you must have to define default values for _strFirstName, _strLastName, _strCourses and _intDays !
I think that... you were in the urge to test your Attendee class, and declared an Attendee variable inside it ;) .
No, you should declare Dim objAttendee As New Attendee(...) outside your class (in the main block of your program for example) with the appropriate parameters.
Private Sub ShowMyClass(sender As Object, e As EventArgs) Handles Button1.Click
Dim objAttendee As New Attendee("Simpson", "Homer", "Courses", "48")
MessageBox.Show(objAttendee.ComputeCourseCosts().ToString())
End Sub

Object reference not set to an instance of an object. visual basic vb

Public Class Population
Dim tours() As Tour ' Tour is a class and I have to make and object array
Public Sub New(ByVal populationSize As Integer, ByVal initialise As Boolean)
Dim tours As New Tour(populationSize) '
If initialise Then
' Loop and create individuals
For i As Integer = 0 To (populationSize - 1)
Dim newTour As New Tour()
newTour.generateIndividual()
saveTour(i, newTour)
Next i
End If
End Sub
Public Sub saveTour(ByVal index As Integer, ByVal tour As Tour)
tours(index) = tour ' getting error in this line
End Sub
same code in java is in this link
It's been a while that I've done VB but I think your DIM-statement in the New-method creates a new local variable tours that hides the global variable tours.
Try this:
Public Class Population
Dim tours() As Tour
Public Sub New(ByVal populationSize As Integer, ByVal initialise As Boolean)
tours = New Tour(populationSize) '
If initialise Then
' Loop and create individuals
For i As Integer = 0 To (populationSize - 1)
Dim newTour As New Tour()
newTour.generateIndividual()
saveTour(i, newTour)
Next i
End If
End Sub
Public Sub saveTour(ByVal index As Integer, ByVal tour As Tour)
tours(index) = tour
End Sub
Try,
Public Sub New(ByVal populationSize As Integer, ByVal initialise As Boolean)
ReDim tours(populationSize)
If initialise Then
' Loop and create individuals
For i As Integer = 0 To (populationSize - 1)
Dim newTour As New Tour()
newTour.generateIndividual()
saveTour(i, newTour)
Next i
End If
End Sub