OK, two things I've seen here today:
1) the same old tired discussion on control arrays.
2) the missing app object (over and over and..)

The control array argument has been beaten to death (several times), and
I, along with others, have shown multiple ways to do things in .NET that
duplicate and exceed the capabilities of control arrays. In short, control
arrays give you three things:
1) the ability to dynamically add controls
2) the ability to route events from multiple controls to a single event handler
3) the ability to place controls in a list

Situation 1 doesn't even require control arrays in .NET (nor did it in VB6).
You can add new control instances directly to forms and containers

Situation 2 doesn't require control arrays in .NET. All events from *ANY*
control that has the same signature can be routed to the same event handler
in .NET. The controls do not even have to be the same type.

Situation 3 was limited in VB6 because you only had an array of controls.
You can code your own lists in VB.NET and have the option of using named-key
collections as well. The flexibility is worth the few lines of extra code,
IMO.


As for the App object, here it is (complete with periferal support code).
I wrote in about 25 minutes, and haven't thoroughly debugged it - so you
get the standard "as-is" disclaimer. I probably made the code a bit more
complicated and messy than i needed to in the rush. Just drop the code in
your project and use the app object as you normally would.
Anyway, now you have your **** App object. Stop whining. Have a nice day.

If y'all did as much coding as *****ing, there wouldn't be a problem.

-Rob

===================================================================
Option Explicit On
Option Strict On

Imports System.Reflection
Imports System.Reflection.Assembly
Imports System.Diagnostics.Process
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.IO


' In order to set/retrieve project Comments, you must add this attribute

' to your Assembly Info file.
<Serializable(), AttributeUsage(AttributeTargets.Assembly)> _
Public Class AssemblyCommentAttribute
Inherits System.Attribute

Private _comments As String

Public Sub New(ByVal Comments As String)
_comments = Comments
End Sub

Public ReadOnly Property Comments() As String
Get
Return _comments
End Get
End Property
End Class

' Create a Console or Service type application if you want a truly
' unattended process. If you want to programmatically query for
' unattended app status, add this attribute to the assembly information
' file, and pass TRUE to the constructor. Do this only if your application
' does not have a user interface.
<Serializable(), AttributeUsage(AttributeTargets.Assembly)> _
Public Class UnattendedAppAttribute
Inherits System.Attribute

Private _unattended As Boolean

Public Sub New(ByVal Unattended As Boolean)
_unattended = Unattended
End Sub

Public ReadOnly Property Unattended() As Boolean
Get
Return _unattended
End Get
End Property
End Class

Friend Enum LogModeFlags
vbLogAuto = 0 'If running on Windows 95 or later, this option logs
messages to the file specified in the LogFile property. If running on Windows
NT, messages are logged to the Windows NT Application Event Log, with "VBNET"
used as the application source and App.Title appearing in the description.

VbLogOff = 1 'Turns logging off from the App object.
VbLogToFile = 2 'Forces logging to a file.
VbLogToNT = 3 'Forces logging to the NT event log. If not running
on Windows NT, or the event log is unavailable, logging is ignored and the
property is set to vbLogOff.
VbLogOverwrite = 16 'Indicates that the logfile should be recreated each
time the application starts. This value can be combined with other mode options
using the OR operator. The default action for logging is to append to the
existing file. In the case of NT event logging, this flag has no meaning.

VbLogThreadID = 32 'Indicates that the current thread ID be prepended
to the message, in the form "[T:0nnn] ". This value can be combined with
other mode options using the OR operator.
vbLogAutoWithThreadID = VbLogThreadID
vbLogToFileAndOverwrite = 18
vbLogToFileWithThreadID = 34
vbLogToFileAndOverwriteWithThreadID = 52
vbLogToNTWithThreadID = 35
End Enum

Friend Enum VBEventType
vbLogEventTypeError = 1 'Error.
vbLogEventTypeWarning = 2 'Warning.
vbLogEventTypeInformation = 4 'Information
End Enum

Friend Structure AssemblyInfo
Friend Title As String
Friend Company As String
Friend Description As String
Friend Comments As String
Friend Product As String
Friend Copyright As String
Friend Trademark As String
Friend Unattended As Boolean
Friend PreviousInstance As Boolean
End Structure

Friend Structure Version
Friend Major As Integer
Friend Minor As Integer
Friend Build As Integer
Friend Revision As Integer
End Structure

Friend Structure OSVERSIONINFO
Friend dwOSVersionInfoSize As Integer
Friend dwMajorVersion As Integer
Friend dwMinorVersion As Integer
Friend dwBuildNumber As Integer
Friend dwPlatformId As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Friend szCSDVersion
As String
End Structure

Friend Class App

Private Const EventLogSource As String = "VBNET"
Private Const ErrOLEAutoModel As String = "Not implmented. .NET does
not use the same OLE Automation RPC model."

Public Const VER_PLATFORM_WIN32_NT As Integer = 2

Private Declare Function GetCurrentThreadId Lib "kernel32" () As Integer

Private Declare Ansi Function GetVersionEx Lib "kernel32" Alias "GetVersionExA"
(ByRef lpVersionInfo As OSVERSIONINFO) As <MarshalAs(UnmanagedType.Bool)>
Boolean


Private Shared _initialized As Boolean
Private Shared _assemblyInfo As AssemblyInfo
Private Shared _version As VBApp.Version

Private Shared _logMode As LogModeFlags
Private Shared _logPath As String
Private Shared _ranFirstFileLog As Boolean
Private Shared _eventLog As EventLog

Friend Shared ReadOnly Property PervInstance() As Boolean
Get
Return _assemblyInfo.PreviousInstance
End Get
End Property

Friend Shared ReadOnly Property TaskVisible() As Boolean
Get
Return Not Process.GetCurrentProcess.MainWindowHandle.Equals(IntPtr.Zero)
End Get
End Property

' See AssemblyCommentsAttribute for more information
Friend Shared ReadOnly Property Comments() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Comments
End Get
End Property

Friend Shared ReadOnly Property CompanyName() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Company
End Get
End Property

Friend Shared ReadOnly Property Title() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Title
End Get
End Property

Friend Shared ReadOnly Property FileDescription() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Description
End Get
End Property

Friend Shared ReadOnly Property ProductName() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Product
End Get
End Property

Friend Shared ReadOnly Property LegalCopyright() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Copyright
End Get
End Property

Friend Shared ReadOnly Property LegalTrademark() As String
Get
If Not _initialized Then InitAssemblyInfo()
Return _assemblyInfo.Trademark
End Get
End Property

Friend Shared ReadOnly Property EXEName() As String
Get
Return [Assembly].GetExecutingAssembly.GetName.Name
End Get
End Property

Friend Shared ReadOnly Property Path() As String
Get
Return [Assembly].GetExecutingAssembly.Location
End Get
End Property

Friend Shared ReadOnly Property Version() As VBApp.Version
Get
If Not _initialized Then InitAssemblyInfo()
Return _version
End Get
End Property

Friend Shared ReadOnly Property Major() As Integer
Get
Return App.Version.Major
End Get
End Property

Friend Shared ReadOnly Property Minor() As Integer
Get
Return App.Version.Minor
End Get
End Property

Friend Shared ReadOnly Property Build() As Integer
Get
Return App.Version.Build
End Get
End Property

Friend Shared ReadOnly Property Revision() As Integer
Get
Return App.Version.Revision
End Get
End Property

<Obsolete(".NET does not use the Component Manager or the VB5/6 Forms
classes. Therefore, non-modal forms in libraries are always allowed.")> _
Friend Shared ReadOnly Property NonModalAllowed() As Boolean
Get
Return True
End Get
End Property

Friend Shared ReadOnly Property hInstance() As IntPtr
Get
Return GetCurrentProcess.Handle
End Get
End Property

Friend Shared ReadOnly Property ThreadID() As Integer
Get
Return GetCurrentThreadId()
End Get
End Property

' See UnattendedAppAttribute for more details
Friend Shared ReadOnly Property UnattendedApp() As Boolean
Get
Return _assemblyInfo.Unattended
End Get
End Property

<Obsolete("Option doesn't exist. If you are creating remoting objects,
the host keeps the application alive.")> _
Friend Shared ReadOnly Property RetainedPoject() As Boolean
Get
Return False
End Get
End Property

<Obsolete("Option doesn't exist.")> _
Friend Shared ReadOnly Property StartMode() As Integer
Get
Return 0
End Get
End Property

<Obsolete("Each form can now have a help file referred to by a HelpProvider
component. This method shows only the help file for the main form.")> _
Friend Shared ReadOnly Property HelpFile() As String
Get
Dim f As Form = DirectCast(Form.FromHandle(Process.GetCurrentProcess.MainWindowHandle),
Form)
If Not f Is Nothing Then
Dim fi() As FieldInfo
Dim i As Integer

fi = f.GetType.GetFields(BindingFlags.Instance Or BindingFlags.NonPublic)

For i = 0 To fi.GetUpperBound(0)
If fi(i).FieldType.Name = "HelpProvider" Then
Return DirectCast(fi(i).GetValue(f), HelpProvider).HelpNamespace()
End If
Next i
End If
End Get
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleRequestPendingMsgText() As String
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As String)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleRequestPendingMsgTitle() As String
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As String)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleRequestPendingTimeout() As Integer
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As Integer)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleServerBusyMsgText() As String
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As String)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleServerBusyMsgTitle() As String
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As String)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleServerBusyRaiseError() As Boolean
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As Boolean)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property

<Obsolete(ErrOLEAutoModel)> _
Public Property OleServerBusyTimeout() As Integer
Get
Throw New NotImplementedException(ErrOLEAutoModel)
End Get
Set(ByVal Value As Integer)
Throw New NotImplementedException(ErrOLEAutoModel)
End Set
End Property



<Obsolete("Use the EventLog classes for more flexibility.")> _
Friend Shared ReadOnly Property LogMode() As LogModeFlags
Get
Return _logMode
End Get
End Property

<Obsolete("Use the EventLog classes for more flexibility.")> _
Friend Shared ReadOnly Property LogPath() As String
Get
Return _logPath
End Get
End Property

<Obsolete("Use the EventLog classes for more flexibility.")> _
Friend Shared Sub LogEvent(ByVal LogBuffer As String, ByVal EventType
As VBEventType)

Dim threadText As String

If (_logMode Or LogModeFlags.VbLogThreadID) = LogModeFlags.VbLogThreadID
Then
threadText = "Thread ID: " + ThreadID.ToString
End If

If (_logMode And LogModeFlags.VbLogToNT) = LogModeFlags.VbLogToNT
Then
Dim logEntryType As EventLogEntryType

Select Case EventType
Case VBEventType.vbLogEventTypeError
logEntryType = EventLogEntryType.Error
Case VBEventType.vbLogEventTypeInformation
logEntryType = EventLogEntryType.Information
Case VBEventType.vbLogEventTypeWarning
logEntryType = EventLogEntryType.Warning
End Select

_eventLog.WriteEntry("VBNET", _
"The VB.NET Application identified by the event source logged
this Application event" + _
vbCrLf + Title + threadText + " ,Logged: " + LogBuffer _
, logEntryType, 1)
Exit Sub
End If

If (_logMode And LogModeFlags.VbLogToFile) = LogModeFlags.VbLogToFile
Then
Dim fs As FileStream
Dim sw As StreamWriter
Dim eventTypeText As String

Try
If _ranFirstFileLog Then
fs = File.Open(_logPath, FileMode.Append)
Else
If (_logMode And LogModeFlags.VbLogOverwrite) = LogModeFlags.VbLogOverwrite
Then
If File.Exists(_logPath) Then
File.Delete(_logPath)
End If
fs = File.Open(_logPath, FileMode.CreateNew)
Else
fs = File.Open(_logPath, FileMode.OpenOrCreate Or
FileMode.Append)
End If
_ranFirstFileLog = True
End If
sw = New StreamWriter(fs)
Select Case EventType
Case VBEventType.vbLogEventTypeError
eventTypeText = "Error "
Case VBEventType.vbLogEventTypeInformation
eventTypeText = "Information "
Case VBEventType.vbLogEventTypeWarning
eventTypeText = "Warning "
End Select

sw.WriteLine(eventTypeText + "Application " + _logPath +
": " + threadText + " ,Logged: " + LogBuffer)
sw.Flush()
sw.Close()
Catch ex As Exception
_logMode = LogModeFlags.VbLogOff
Finally
If Not sw Is Nothing Then
sw.Close()
End If
End Try
End If
End Sub

<Obsolete("Use the EventLog classes for more flexibility.")> _
Friend Shared Sub StartLogging(ByVal LogTarget As String, ByVal LogModes
As LogModeFlags)
_logPath = LogTarget

Select Case LogModes
Case LogModeFlags.VbLogOff, LogModeFlags.VbLogToFile, LogModeFlags.vbLogToFileAndOverwrite,
LogModeFlags.vbLogToFileAndOverwriteWithThreadID
_logMode = LogModes
Case LogModeFlags.vbLogAuto, LogModeFlags.vbLogAutoWithThreadID
If IsNT4OrHigherOS() Then
_logMode = LogModeFlags.VbLogToNT
StartNTLog()
Else
_logMode = LogModeFlags.VbLogToFile
End If
If (LogModes And LogModeFlags.VbLogThreadID) = LogModeFlags.VbLogThreadID
Then
_logMode = (_logMode Or LogModeFlags.VbLogThreadID)
End If

Case LogModeFlags.VbLogToNT, LogModeFlags.vbLogToNTWithThreadID
If IsNT4OrHigherOS() Then
StartNTLog()
_logMode = LogModes
Else
_logMode = LogModeFlags.VbLogOff
End If

Case Else
_logMode = LogModeFlags.VbLogOff
End Select
End Sub

Private Shared Function IsNT4OrHigherOS() As Boolean
Dim osv As OSVERSIONINFO
osv.dwOSVersionInfoSize = Marshal.SizeOf(osv)
If GetVersionEx(osv) Then
If osv.dwPlatformId = VER_PLATFORM_WIN32_NT Then
Return True
End If
End If
End Function

Private Shared Sub StartNTLog()
If Not _eventLog Is Nothing Then
_eventLog = New EventLog("Application", ".", EventLogSource)
End If
End Sub

Private Shared Sub InitAssemblyInfo()
Dim assemblyCompany As AssemblyCompanyAttribute()
assemblyCompany = DirectCast(GetExecutingAssembly.GetCustomAttributes(GetType(AssemblyCompanyAttribute),
True), AssemblyCompanyAttribute())
If Not ((assemblyCompany Is Nothing) OrElse (assemblyCompany.Length
= 0)) Then
_assemblyInfo.Company = assemblyCompany(0).Company
220 41821 <3cf6aa23$1@10.1.10.29> article retrieved - head and body follows
From: "Rob Teixeira" <RobTeixeira@@msn.com>
Sender: "Rob Teixeira" <vb.@127.0.0.1>
Reply-To: "Rob Teixeira" <RobTeixeira@@msn.com>
Subject: Re: The Classic VB Programmer vs the VB.NET Programmer
Newsgroups: vb.dotnet.discussion
X-User-Info: 208.143.222.25 208.143.222.25 vb.
References: <3cf69b1c$1@10.1.10.29> <3cf6a4f6$1@10.1.10.29>
NNTP-Posting-Host: 127.0.0.1
Message-ID: <3cf6aa23$1@10.1.10.29>
Date: 30 May 2002 15:39:31 -0800
X-Trace: 30 May 2002 15:39:31 -0800, 127.0.0.1
Lines: 10
Path: 10.1.10.29
Xref: 10.1.10.29 vb.dotnet.discussion:41821



Code more, ***** less, and you wouldn't be in that predicament.

-Rob

"Dave Doknjas" <dave_doknjas@yahoo.ca> wrote:
>
>Yeah, I guess I'm just itching for a fight...