Using nested structures - or am I barking up the wrong tree?

RyanH9876

New member
Joined
Mar 1, 2010
Messages
1
Programming Experience
3-5
Greetings all, this is my first post.

I am building a custom OCR program to grab data from the screen. I am a self taught programmer and have learned things as I needed them but I believe I'm struggling with properly using Object-Oriented principles in my code.

I have been able to build a solution using separate single column arrays to hold my data and they are linked by the index number but I keep thinking that if can get classes/structures nailed down, the code will be much neater.

Here's how I want my data to look.

Screen Number --> Has position properties and can contain multiple Tables
Table Number --> Has various properties and can contain multiple zones
Zone Number --> Has various properties

I have tried using structures and have some non-working code below that I think gives the sense of what I'm trying to do.

I want to be able to reference things like:

ScreenNo(1).XaxisPixelPosition = 1440
and
ScreenNo(1).TablesCount(1).CharHeight = 7


The data is basically properties that are constantly referred to that tell the OCR functions which pixels to grab. I need to be able to add new screens if necessary which will contain new tables and zones.

My knowledge of classes and structures is really weak. I would appreciate any pointers to tutorials but if you can see what I'm trying to do from my description here and can advise that would be great.


VB.NET:
Imports System

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim ScreenNo() As New ScreenID
        ScreenNo(1).TablesCount(1).CharHeight = 7

    End Sub

    Public Structure ScreenID
        Public TablesCount() As TableID
        Public PixX As Integer
        Public PixY As Integer
    End Structure

    Public Structure TableID
        Public ZonesCount() As ZoneID
        Public PixX As Integer
        Public PixY As Integer
        Public CharHeight As Integer 'Width in pixels
        Public CharWidth As Integer 'Width in pixels
        Public RowHeight As Integer 'Height in pixels
        Public RowCount As Integer
    End Structure

    Public Structure ZoneID
        Public PixX As Integer
        Public PixY As Integer
        Public CharsCount As Integer 'Number of characters per row in zone (eg. time "12:34:01" has 8 chars)
    End Structure

End Class
 
to be honest, from what I can gather from your post, structures is not what you need.
Create a class library and call it Common, in there create seperate classes for what you need.
Here is an example.

VB.NET:
Public Class Item
    Private _id As Integer
    Private _requiredItemID As Integer
    Private _usedinItemID As Integer
    Private _icon As String
    Private _name As String
    Private _price As Integer
    Private _locationID As Integer
    Private _location As String
    Private _shortDescription As String
    Private _description As String
    Private _effectName As String
    Private _effectDescription As String

    Public Property ID() As Integer
        Get
            Return _id
        End Get
        Set(ByVal value As Integer)
            _id = value
        End Set
    End Property

    Public Property RequiredItemID() As Integer
        Get
            Return _requiredItemID
        End Get
        Set(ByVal value As Integer)
            _requiredItemID = value
        End Set
    End Property

    Public Property UsedInItemID() As Integer
        Get
            Return _usedinItemID
        End Get
        Set(ByVal value As Integer)
            _usedinItemID = value
        End Set
    End Property

    Public Property Icon() As String
        Get
            Return _icon
        End Get
        Set(ByVal value As String)
            _icon = value
        End Set
    End Property

    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Public Property Price() As Integer
        Get
            Return _price
        End Get
        Set(ByVal value As Integer)
            _price = value
        End Set
    End Property

    Public Property LocationID() As Integer
        Get
            Return _locationID
        End Get
        Set(ByVal value As Integer)
            _locationID = value
        End Set
    End Property

    Public Property Location() As String
        Get
            Return _location
        End Get
        Set(ByVal value As String)
            _location = value
        End Set
    End Property

    Public Property ShortDescription() As String
        Get
            Return _shortDescription
        End Get
        Set(ByVal value As String)
            _shortDescription = value
        End Set
    End Property

    Public Property Description() As String
        Get
            Return _Description
        End Get
        Set(ByVal value As String)
            _Description = value
        End Set
    End Property

    Public Property EffectName() As String
        Get
            Return _effectName
        End Get
        Set(ByVal value As String)
            _effectName = value
        End Set
    End Property

    Public Property EffectDescription() As String
        Get
            Return _effectDescription
        End Get
        Set(ByVal value As String)
            _effectDescription = value
        End Set
    End Property
End Class

and then create a collection like so:

VB.NET:
Public Class ItemCollection
    Inherits System.Collections.CollectionBase

    Default Public Property Item(ByVal index As Integer) As Item
        Get
            Return CType(List(index), Item)
        End Get
        Set(ByVal value As Item)
            List(index) = value
        End Set
    End Property

    Public Function Add(ByVal value As Item) As Integer
        Return List.Add(value)
    End Function

    Public Function IndexOf(ByVal value As Item) As Integer
        Return List.IndexOf(value)
    End Function

    Public Sub Insert(ByVal index As Integer, ByVal value As Item)
        List.Insert(index, value)
    End Sub

    Public Sub Remove(ByVal value As Item)
        List.Remove(value)
    End Sub

    Public Function Contains(ByVal value As Item) As Boolean
        Return List.Contains(value)
    End Function
End Class

and then to get the data from the database like so:

VB.NET:
Imports HoN.Common
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Public Class ItemData
    Inherits BaseDataAccess

    Public Shared Function GetAllItems() As ItemCollection
        ' Declare our Stored Procedure
        Dim colItem As New ItemCollection
        Dim sCommand As New SqlCommand()
        sCommand.CommandType = CommandType.StoredProcedure
        sCommand.CommandText = "dbo.HoN_GetAllItems"
        SetConnectionString = ConfigurationManager.ConnectionStrings("myConnection").ConnectionString

        ' Try
        Try
            ' Fill our DataSet
            Dim ds As New DataSet
            ds = FillDataSet(sCommand)

            ' For each Row
            For Each dRow As DataRow In ds.Tables(0).Rows
                ' Parse
                colItem.Add(ParseItems(dRow))
            Next
        Catch ex As Exception
            ' Throw an Exception
            Throw New Exception(ex.ToString)
        End Try

        Return colItem
    End Function

    Public Shared Function GetItem(ByVal pID As Integer) As Item
        ' Declare our Stored Procedure
        Dim sCommand As New SqlCommand()
        sCommand.CommandType = CommandType.StoredProcedure
        sCommand.CommandText = "dbo.HoN_GetItem"
        sCommand.Parameters.Add("@ID", SqlDbType.Int).Value = pID
        SetConnectionString = ConfigurationManager.ConnectionStrings("myConnection").ConnectionString

        ' Try
        Try
            ' Fill our DataSet
            Dim ds As New DataSet
            ds = FillDataSet(sCommand)

            ' Parse
            Return ParseItems(ds.Tables(0).Rows(0))

        Catch ex As Exception
            ' Throw an Exception
            Throw New Exception(ex.ToString)
        End Try
    End Function

    Private Shared Function ParseItems(ByVal pDR As DataRow) As Item
        Dim newItem As New Item

        With newItem
            .ID = pDR("id")
            .Icon = Trim(pDR("icon"))
            .Name = Trim(pDR("name"))
            .Price = pDR("item_price")
            .LocationID = pDR("location_id")
            .Location = Trim(pDR("location"))
            .ShortDescription = Trim(pDR("short_description"))
            .Description = Trim(pDR("item_description"))
            .EffectName = Trim(pDR("effect_name"))
            .EffectDescription = Trim(pDR("effect_description"))
        End With

        Return newItem
    End Function
End Class

and the inherited BaseDataAccess just looks like:

VB.NET:
Imports System.Data
Imports System.Data.SqlClient

Public Class BaseDataAccess
    Private Shared mstrConnectionString As String
    Private Shared mConn As SqlConnection

    Public Shared WriteOnly Property SetConnectionString() As String
        Set(ByVal value As String)
            mstrConnectionString = value
        End Set
    End Property

    Shared Function FillDataSet(ByVal pSQLCmd As SqlCommand) As DataSet
        Dim ds As New DataSet
        Dim da As New SqlDataAdapter
        If mstrConnectionString <> "" Then
            OpenConnection()
            pSQLCmd.Connection = mConn
            da.SelectCommand = pSQLCmd
            da.Fill(ds)
            da.Dispose()
            CloseConnection()
        Else
            Throw New ApplicationException("Connection String has not been set")
        End If
        Return ds
    End Function

    Shared Sub ExecuteNonSelect(ByVal pSQLCmd As SqlCommand)
        If mstrConnectionString <> "" Then
            OpenConnection()
            pSQLCmd.Connection = mConn
            pSQLCmd.ExecuteNonQuery()
            CloseConnection()
        Else
            Throw New ApplicationException("Connection String has not been set")
        End If
    End Sub

    Shared Function ExecuteScalar(ByVal pSQLCmd As SqlCommand)
        Dim sReturn

        If mstrConnectionString <> "" Then
            OpenConnection()
            pSQLCmd.Connection = mConn
            sReturn = pSQLCmd.ExecuteScalar()
            CloseConnection()
        Else
            Throw New ApplicationException("Connection String has not been set")
        End If

        Return sReturn
    End Function

    Private Shared Sub OpenConnection()
        mConn = New SqlConnection
        mConn.ConnectionString = mstrConnectionString
        mConn.Open()
    End Sub

    Private Shared Sub CloseConnection()
        If mConn.State = ConnectionState.Open Then
            mConn.Close()
            mConn.Dispose()
        End If
    End Sub

End Class

I hope that helps :)
 
Back
Top