Binärdaten aus einer Datei in ein Struct einlesen

  • angelehnt an dieses Beispiel: Link
  • Struct, was man einlesen will, definieren
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

// Daten sequentiell anordnen
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct MyStruct
{
    // String zum Einlesen von char-Arrays fester Länge nutzen, hier 32 Zeichen
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string sName;
    
    // char-Arrays können auch wie folgt eingelesen werden
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public char[] cName2;

    // int einlesen
    public Int32 iVersion;
}
  • Hilfsfunktion zum konvertieren eines Byte-Arrays in das definierte Struct
/// <summary>
/// byte[] to object De-Serialisierung
/// </summary>
/// <param name="byaRawData">Eingangsdaten als byte-Array</param>
/// <param name="tyObjectDataType">Struct-Typ, in den byaRawData konvertiert werden soll</param>
/// <returns>deserialisiertes Objekt</returns>
private object RawDeserialize(byte[] byaRawData, Type tyObjectDataType)
{
    object oRetObj = null;

    int iRawSize = Marshal.SizeOf(tyObjectDataType);

    if (iRawSize == byaRawData.Length)
    {
        IntPtr iptrBuffer = Marshal.AllocHGlobal(iRawSize);
        Marshal.Copy(byaRawData, 0, iptrBuffer, iRawSize);
        oRetObj = Marshal.PtrToStructure(iptrBuffer, tyObjectDataType);
        Marshal.FreeHGlobal(iptrBuffer);
    }

    return oRetObj;
}
  • Anwendungsbeispiel
public bool ReadFile(string sFileName)
{
    bool bRetVal = false;

    try
    {
        // Datei öffnen
        FileStream pFileStream = new FileStream(sFileName, FileMode.OpenOrCreate);

        if (pFileStream != null)
        {
            // binär lesen
            BinaryReader br = new BinaryReader(pFileStream);

            // Puffer einlesen
            byte[] buf = br.ReadBytes(Marshal.SizeOf(typeof(MyStruct)));

            // Byte-Puffer als MyStruct uminterpretieren
            MyStruct stHead = (MyStruct)RawDeserialize(buf, typeof(MyStruct));

            string sName = stHead.sName;
            Int32 iVersion = stHead.iVersion;

            // aufräumen
            pFileStream.Close();
            pFileStream.Dispose();

            bRetVal = true;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

    return bRetVal;
}

Drag und Drop II

  • im Beispiel wird zw. 2 Listviews ein String zwischen 2 ListViews per Drag & Drop ausgetauscht
  • dabei ist beim Quell-ListView das Ereignis ItemDrag zu behandeln:
private void ListViewSrc_ItemDrag(object sender, ItemDragEventArgs e)
{
    // ListView ermitteln
    ListView lvListView = sender as ListView;

    ListViewItem lviItem = null;

    if (lvListView != null)
    {
        // selektiertes Item des Listviews herausfinden,
        // hier wird nur das erste behandelt (im Falle vom
        // ListViewSrc.MultiSelect = true muss man die anderen
        // Items extra abfangen)
        if (lvListView.SelectedItems.Count == 1)
        {
            lviItem = lvListView.SelectedItems[0];
        }

        // wenn ein Item vorhanden
        if (lviItem != null)
        {
            // dann DoDragDrop des ListViews ausführen und den Text kopieren
            lvListView.DoDragDrop(lviItem.Text, DragDropEffects.Copy);
        }
    }
}
  • beim Ziel-ListView muss die Eigenschaft AllowDrop = True gesetzt sein
  • zusätzlich sind die Ereignisse DragOver und DragDrop zu behandeln:
// Was soll passieren, wenn man mit dem Mauszeiger
// ein Element auf das Listview zieht?
private void ListViewDest_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    // prüfen, ob ein Text vorhanden ist
    if (e.Data.GetDataPresent(DataFormats.Text))
    {
        e.Effect = DragDropEffects.Copy;
    }
}

// wenn das DragDrop-Element "fallen" gelassen wird
private void ListViewDest_DragDrop(object sender, DragEventArgs e)
{
    // String abholen
    string sDataString = e.Data.GetData(DataFormats.StringFormat) as string;

    bool bFound = false;

    // nachschauen, ob schon im ListView vorhanden
    foreach (ListViewItem li in ListViewDest.Items)
    {
        if (li.Text == sDataString)
        {
            bFound = true;
            break;
        }
    }

    // wenn nicht vorhanden
    if (bFound == false)
    {
        // dann neues ListViewItem einfügen
        ListViewDest.Items.Add(sDataString);
    }
}

Drag und Drop

  • im Beispiel wird zw. 2 Listviews ein Listitem per Drag & Drop ausgetauscht
  • dabei ist beim Quell-ListView das Ereignis ItemDrag zu behandeln:
private void ListViewSrc_ItemDrag(object sender, ItemDragEventArgs e)
{
    // ListView ermitteln
    ListView lvListView = sender as ListView;

    ListViewItem lviItem = null;

    if (lvListView != null)
    {
        // selektiertes Item des Listviews herausfinden,
        // hier wird nur das erste behandelt (im Falle vom
        // ListViewSrc.MultiSelect = true muss man die anderen
        // Items extra abfangen)
        if (lvListView.SelectedItems.Count == 1)
        {
            lviItem = lvListView.SelectedItems[0];
        }

        // wenn ein Item vorhanden
        if (lviItem != null)
        {
            // dann DoDragDrop des ListViews ausführen und das Item kopieren
            lvListView.DoDragDrop(lviItem, DragDropEffects.Copy);
        }
    }
}
  • beim Ziel-ListView muss die Eigenschaft AllowDrop = True gesetzt sein
  • zusätzlich sind die Ereignisse DragOver und DragDrop zu behandeln:
// Was soll passieren, wenn man mit dem Mauszeiger
// ein Element auf das Listview zieht?
private void ListViewDest_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    // wenn das Element ein ListViewItem ist
    ListViewItem lviItem = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;

    if (lviItem != null)
    {
        // dann eine Kopie davon erlauben
        e.Effect = DragDropEffects.Copy;
    }
}

// wenn das DragDrop-Element "fallen" gelassen wird
private void ListViewDest_DragDrop(object sender, DragEventArgs e)
{
    ListViewItem lviItem = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;

    // wenn das Element ein ListViewItem ist
    if (lviItem != null)
    {
        bool bFound = false;

        // prüfen, ob schon in der Liste von ListViewDest
        foreach (ListViewItem li in ListViewDest.Items)
        {
            if (li.Text == lviItem.Text)
            {
                bFound = true;
                break;
            }
        }

        // wenn noch nicht in ListViewDest, dann einfügen
        if (bFound == false)
        {
            ListViewDest.Items.Add(lviItem.Text);
        }
    }
}

Dateien eines Ordners in einem ListView auflisten

// füllt ListView1 mit Dateien mit der Dateiendung *.avi
private bool ListFiles(string sDir)
{
    bool bRetVal = false;

    ListView1.Items.Clear();

    try
    {
        DirectoryInfo di = new DirectoryInfo(sDir);

        FileInfo[] rgFiles = di.GetFiles("*.avi");

        foreach (FileInfo fi in rgFiles)
        {
            ListView1.Items.Add(fi.Name);
        }

        bRetVal = true;
    }
    catch (Exception e)
    {
        Console.WriteLine("Exception: " + e.Message);  
        Console.WriteLine("StackTrace: " + e.StackTrace);
    }

    return bRetVal;
}

Exception Handling

  • Allgemein
try
{
    // irgendwas löst hier eine Exception aus
}
catch (Exception e)
{
    Console.WriteLine("Exception: " + e.Message);
    Console.WriteLine("StackTrace: " + e.StackTrace);                
}
  • Speziell
try
{
    float z = 1;
    float n = 0;
    float e = z/n; // Division durch 0
}
catch (DivideByZeroException e)
{
    Console.WriteLine("Exception: " + e.Message);
    Console.WriteLine("StackTrace: " + e.StackTrace);              
}

Ordner mittels FolderBrowserDialog auswählen

// dlgOpenDir: FolderBrowserDialog
// tbDir: TextBox
private void tsbOpenDir_Click(object sender, EventArgs e)
{
    dlgOpenDir.SelectedPath = tbDir.Text; // Dialog-Pfad voreinstellen

    if (dlgOpenDir.ShowDialog() == DialogResult.OK)
    {
        tbDir.Text = dlgOpenDir.SelectedPath; // ausgewählte Directory zurückgeben
    }
}