在项目开发中,在MFC下生成的文件,需要用VB.net进行读取;MFC是用CFile类生成的记录式文件,每条记录是一个结构体。
代码开放,遵循但不限于PCL协议,给予代码复制者商业软件使用特权;但是使用者必须是开源社区忠实拥护和推广者,即代码必须免费开放。
1.首先加载一个模块;在模块中对MFC的结构体进行复制定义,源码如下:
Imports System.Runtime.InteropServices
Imports System.IO
Module Module1
'**************读取文件结构体*********************
‘结构体声明必须加上这个属性定义语句,整个定义如下:
<StructLayoutAttribute(LayoutKind.Sequential, CharSet:=CharSet.Auto, Size:=96)> _
Public Structure tagTestDatas
Dim dTemperature As Double
Dim dHumidity As Double
Dim dEnvHumidity As Double
Dim dFlowRate As Double
Dim dOxyAD As Double
Dim dOTR As Double
Dim dppm As Double
Dim dtime As Double
Dim dValtage As Double
Dim dVsteam As Double
Dim dZeroppm As Double
Dim dStandardOTR As Double
End Structure
Public TestData As tagTestDatas
'**************************************************
'##################结构体和字节数组的转换##########
Public Sub StructToBytes(ByVal objStruct As Object, ByRef bytes() As Byte)
'得到结构体长度
Dim size As Integer = Marshal.SizeOf(objStruct)
'重新定义数组大小
ReDim bytes(size)
'分配结构体大小的内存空间
Dim ptrStruct As IntPtr = Marshal.AllocHGlobal(size)
'将结构体放入内存空间
Marshal.StructureToPtr(objStruct, ptrStruct, False)
'将内存拷贝到字节数组
Marshal.Copy(ptrStruct, bytes, 0, size)
'释放内存空间
Marshal.FreeHGlobal(ptrStruct)
End Sub
' 字节数组bytes()转化为结构体
Public Function BytesToStruct(ByRef bytes() As Byte, ByVal mytype As Type) As Object
'获取结构体大小
Dim size As Integer = Marshal.SizeOf(mytype)
'bytes数组长度小于结构体大小
If (size > bytes.Length) Then
'返回空
Return (Nothing)
End If
'分配结构体大小的内存空间
Dim ptrStruct As IntPtr = Marshal.AllocHGlobal(size)
'将数组拷贝到内存
Marshal.Copy(bytes, 0, ptrStruct, size)
'将内存转换为目标结构体
Dim obj As Object = Marshal.PtrToStructure(ptrStruct, mytype)
'释放内存
Marshal.FreeHGlobal(ptrStruct)
Return (obj)
End Function
' 从文件中读取结构体
Public Function FileToStruct(ByVal strPath As String, ByVal mytype As Type) As Object
'获得结构体大小
Dim size As Integer = Marshal.SizeOf(mytype)
'打开文件流
Dim fs As New FileStream(strPath, FileMode.Open)
'读取size个字节
Dim bytes(size) As Byte
fs.Read(bytes, 0, size)
'将读取的字节转化为结构体
Dim obj As Object = BytesToStruct(bytes, mytype)
fs.Close()
Return (obj)
End Function
'从文件读取二进制流返回字节数组
Public Function ReadInfo(ByVal strPath As String) As Byte()
Try
Dim fs As New FileStream(strPath, FileMode.Open)
Dim br As BinaryReader = New BinaryReader(fs)
Dim bt() As Byte = br.ReadBytes(fs.Length)
br.Close()
fs.Close()
Return bt
Catch ex As Exception
Return Nothing
End Try
End Function
'################################################
Public StrFileName As String = ""
’项目启动设为sub main(),这是带参数的main()函数定义格式:
Sub main(ByVal args() As String)
If UBound(args) >= 0 Then
StrFileName = args(0).ToString
Else
StrFileName = ""
End If
‘application.run()运行程序才能改变项目启动项,窗体程序才能从sub main()启动项目中启动运行。
Dim frm1 As New Form1
Application.Run(frm1)
End Sub
End Module
2.加载一个窗体,进行文件读取和显示;我的项目是在CE5.0下的,这个窗体的作用是读取MFC文件内容给自定义画曲线控件,完成曲线绘制功能。代码如下:
Imports System.Runtime.InteropServices
Imports System.IO
Public Class Form1
'程序运行目录
Public curDir As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase().ToString())
Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
Me.CeGraphCurve1.Dispose()
Me.Close()
Me.Dispose()
GC.Collect()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Location = New Point((Screen.PrimaryScreen.WorkingArea.Width - Me.ClientSize.Width) / 2, (Screen.PrimaryScreen.WorkingArea.Height - Me.ClientSize.Height) / 2)
Me.TopMost = True
Me.CeGraphCurve1.YAxisTitle = "Red:Temp(℃)---Green:RH(%)"
Me.Button1.Location = New Point((Me.Width - Me.Button1.Width) / 2, Me.Button1.Location.Y)
End Sub
Private Sub Form1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.LostFocus
Me.TopMost = True
End Sub
//读取文件主要模块代码
Private Sub InitGraph()
If System.IO.File.Exists(curDir & "\data\" & StrFileName) = True Then
'开始读取文件
Dim bt() As Byte = ReadInfo(curDir & "\data\" & StrFileName)
Dim pointsX() As Single
Dim pointsY() As Single
pointsX = Nothing
pointsY = Nothing
Dim HpointsX() As Single
Dim HpointsY() As Single
HpointsX = Nothing
HpointsY = Nothing
If IsNothing(bt) = False Then
Dim structSize As Integer = Marshal.SizeOf(GetType(tagTestDatas))
Dim num As Integer = (UBound(bt)+1) / structSize
ReDim pointsX(num - 1)
ReDim pointsY(num - 1)
ReDim HpointsX(num - 1)
ReDim HpointsY(num - 1)
For i As Integer = 0 To num - 1
Dim temp(structSize - 1) As Byte
Array.Copy(bt, i * structSize, temp, 0, structSize)
TestData = BytesToStruct(temp, GetType(tagTestDatas))
pointsX(i) = TestData.dtime
pointsY(i) = Format(TestData.dTemperature, "0.00")
HpointsX(i) = TestData.dtime
HpointsY(i) = Format(TestData.dHumidity, "0.00")
Next
Me.CeGraphCurve1.AddPointPairs(pointsX, pointsY)
Me.CeGraphCurve1.AddPointPairs(HpointsX, HpointsY)
Me.CeGraphCurve1.DrawCurve()
pointsX = Nothing
pointsY = Nothing
HpointsX = Nothing
HpointsY = Nothing
GC.Collect()
End If
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If StrFileName <> "" Then
Me.Button1.Enabled = False
Me.CeGraphCurve1.ClearPoints()
InitGraph()
Me.Button1.Enabled = True
Else
MsgBox("No Chance File!", MsgBoxStyle.Information, "Info")
End If
End Sub
End Class