(-: Fibergeek's Blog :-)
Inhoud blog
  • Python 2 of 3
  • IDA-python: GetStructureIdAt
  • Geslaagd in Microsoft's 70-680 examen
  • minibio: kort vervolg
  • miniboa: een voorbeeld
    Zoeken in blog

    Categorieën
  • Code: C/C++ (2)
  • Code: Powershell (1)
  • Code: Python (8)
  • Code: WPF (2)
  • Programmeren (5)
  • 10-06-2011
    Klik hier om een link te hebben waarmee u dit artikel later terug kunt lezen.Console-applicaties starten in C en de invoer/uitvoer (Clean Code-variant)
    Deze C++ code doet exact hetzelfde als de vorige versie van het programma (zie mijn vorige blog). Echter, ik heb het programma proberen te herschrijven volgens de richtlijnen uit het boek Clean Code: A Handbook of Agile Software Craftsmanship van Robert C. Martin. Wat zeker nog ontbreekt is het vrijgeven van het geheugen en het vrijgeven van de handles (zowel de Pipes als de Process-handle) (dit ontbreekt ook in the originele versie). Zelfs buiten dat, ben ik nog niet volledig overtuigd dat het programma klaar is. Misschien volgt een nieuwe versie als ik het boek uitgelezen heb?...

    #include "stdafx.h"

    #include <windows.h>

     

    // SecurityAttribute-stuff (needed for the Pipes)

    class SecurityAttributes

    {

    private:

      SECURITY_ATTRIBUTES security_attributes;

     

    public:

      SecurityAttributes();

      LPSECURITY_ATTRIBUTES GetPointer();

    };

     

    // Pipe-stuff

    typedef struct

    {

      HANDLE Read;

      HANDLE Write;

    } PipeHandlePair;

     

    typedef struct

    {

      PipeHandlePair input;

      PipeHandlePair output;

      PipeHandlePair error;

    } PipeHandles;

     

    void CreatePipes(PipeHandles &ThePipeHandles);

    void CreatePipe(PipeHandlePair &PipePair, SecurityAttributes &TheSecurityAttributes);

    void SendTextMessageToPipe(HANDLE PipeHandle, LPCSTR Message);

    DWORD GetAmountOfDataAvailableOnPipe(HANDLE PipeHandle);

    DWORD ReadDataFromPipe(HANDLE PipeHandle, LPBYTE Buffer, DWORD BytesToRead);

    LPSTR ReadStringDataFromPipe(HANDLE PipeHandle, DWORD StringLength);

    LPSTR ReadAvailableDataFromPipeAsString(HANDLE PipeHandle);

    void ReadAndDisplayOutputFromPipes(PipeHandles &ThePipeHandles);

     

    // ProcessStartupInfo-stuff (needed for the Processes)

    class ProcessStartupInfo

    {

    private:

      STARTUPINFO startup_info;

     

    public:

      ProcessStartupInfo(const PipeHandles &ThePipeHandles);

      LPSTARTUPINFO GetPointer();

    };

     

    // Process-stuff

    void WaitForProcessToEnd(HANDLE ProcessHandle);

    void WaitForProcessToEnd(PROCESS_INFORMATION &process_info);

    bool CreateProcess(PROCESS_INFORMATION &process_info, LPCSTR CommandLine, PipeHandles &ThePipeHandles);

    bool CreateProcessAndWaitForItToEnd(LPCSTR CommandLine, PipeHandles &ThePipeHandles, LPCSTR OptionalInputToSend = NULL);

     

    // Other stuff

    void SimpleMessageBox(LPCSTR Title, LPCSTR Content);

    void DisplayNormalOrErrorOutput(LPSTR OutputString, LPSTR ErrorString);

     

    int main()

    {

      PipeHandles OurPipeHandles;

      CHAR InputToSend[] = "";

     

      CreatePipes(OurPipeHandles);

      if(CreateProcessAndWaitForItToEnd("cmd /C "echo Test"", OurPipeHandles, InputToSend))

        ReadAndDisplayOutputFromPipes(OurPipeHandles);

     

      return 0;

    }

     

    void CreatePipes(PipeHandles &ThePipeHandles)

    {

      SecurityAttributes TheSecurityAttributes;

      CreatePipe(ThePipeHandles.output, TheSecurityAttributes);

      CreatePipe(ThePipeHandles.input,  TheSecurityAttributes);

      CreatePipe(ThePipeHandles.error,  TheSecurityAttributes);

    }

     

    void CreatePipe(PipeHandlePair &PipePair, SecurityAttributes &TheSecurityAttributes)

    {

      CreatePipe(&PipePair.Read, &PipePair.Write, TheSecurityAttributes.GetPointer(), 0);

    }

     

    bool CreateProcess(PROCESS_INFORMATION &process_info, LPCSTR CommandLine, PipeHandles &ThePipeHandles)

    {

      ProcessStartupInfo StartupInfo(ThePipeHandles);

      return CreateProcess(NULL, (LPSTR) CommandLine, NULL, NULL, TRUE, 0, NULL, NULL, StartupInfo.GetPointer(), &process_info) != FALSE;

    }

     

    bool CreateProcessAndWaitForItToEnd(LPCSTR CommandLine, PipeHandles &ThePipeHandles, LPCSTR OptionalInputToSend)

    {

      PROCESS_INFORMATION process_info;

     

      if(!CreateProcess(process_info, CommandLine, ThePipeHandles))

        return false;

      SendTextMessageToPipe(ThePipeHandles.input.Write, OptionalInputToSend);

      WaitForProcessToEnd(process_info.hProcess);

      return true;

    }

     

    void SendTextMessageToPipe(HANDLE PipeHandle, LPCSTR Message)

    {

      if(Message && *Message) // Is valid?

      {

        DWORD bytes_written = 0;

        WriteFile(PipeHandle, Message, strlen(Message), &bytes_written, NULL);

      }

    }

     

    void WaitForProcessToEnd(HANDLE ProcessHandle)

    {

      WaitForSingleObject(ProcessHandle, INFINITE);

    }

     

    void WaitForProcessToEnd(PROCESS_INFORMATION &process_info)

    {

      WaitForSingleObject(process_info.hProcess, INFINITE);

    }

     

    DWORD ReadDataFromPipe(HANDLE PipeHandle, LPBYTE Buffer, DWORD BytesToRead)

    {

      DWORD BytesRead = 0;

      if(BytesToRead)

        ReadFile(PipeHandle, Buffer, BytesToRead, &BytesRead, NULL);    

      return BytesRead;

    }

     

    void ReadAndDisplayOutputFromPipes(PipeHandles &ThePipeHandles)

    {

      CHAR *OutputString = ReadAvailableDataFromPipeAsString(ThePipeHandles.output.Read);

      CHAR *ErrorString  = ReadAvailableDataFromPipeAsString(ThePipeHandles.error.Read);

      DisplayNormalOrErrorOutput(OutputString, ErrorString);

    }

     

    LPSTR ReadAvailableDataFromPipeAsString(HANDLE PipeHandle)

    {

      DWORD BytesAvailable = GetAmountOfDataAvailableOnPipe(PipeHandle);

      LPSTR StringData = ReadStringDataFromPipe(PipeHandle, BytesAvailable);

      return StringData;

    }

     

    DWORD GetAmountOfDataAvailableOnPipe(HANDLE PipeHandle)

    {

      DWORD BytesToRead = 0;

      if(!PeekNamedPipe(PipeHandle, NULL, 0, NULL, &BytesToRead, NULL))

        return 0;

      return BytesToRead;

    }

     

    LPSTR ReadStringDataFromPipe(HANDLE PipeHandle, DWORD StringLength)

    {

      CHAR *ReturnBuffer = new CHAR[StringLength + 1];

      if(ReturnBuffer)

      {

        DWORD BytesRead = ReadDataFromPipe(PipeHandle, (LPBYTE) ReturnBuffer, StringLength);

        ReturnBuffer[BytesRead] = 0;

      }

      return ReturnBuffer;

    }

     

    void DisplayNormalOrErrorOutput(LPSTR OutputString, LPSTR ErrorString)

    {

      if(OutputString && ErrorString)

      {

        if(*ErrorString)

          SimpleMessageBox("There were errors!", ErrorString);
        
    else

          SimpleMessageBox("Output code", OutputString);

      }

    }

     

    void SimpleMessageBox(LPCSTR Title, LPCSTR Content)

    {

      MessageBox(HWND_DESKTOP, Content, Title, MB_OK);

    }

     

    SecurityAttributes::SecurityAttributes()

    {

      security_attributes.nLength              = sizeof(SECURITY_ATTRIBUTES);

      security_attributes.bInheritHandle       = TRUE;

      security_attributes.lpSecurityDescriptor = NULL;

    }

     

    LPSECURITY_ATTRIBUTES SecurityAttributes::GetPointer()

    {

      return &security_attributes;

    }

     

    ProcessStartupInfo::ProcessStartupInfo(const PipeHandles &ThePipeHandles)

    {

      ZeroMemory(&startup_info, sizeof(STARTUPINFO));

      startup_info.cb         = sizeof(STARTUPINFO);

      startup_info.hStdInput  = ThePipeHandles.input.Read;

      startup_info.hStdOutput = ThePipeHandles.output.Write;

      startup_info.hStdError  = ThePipeHandles.error.Write;

      startup_info.dwFlags    = STARTF_USESTDHANDLES;

    }

     

    LPSTARTUPINFO ProcessStartupInfo::GetPointer()

    {

      return &startup_info;

    }

    10-06-2011, 00:00 Geschreven door Fibergeek  


    Categorie:Code: C/C++
    09-06-2011
    Klik hier om een link te hebben waarmee u dit artikel later terug kunt lezen.Console-applicaties starten in C en de invoer/uitvoer

    Het onderstaande programma is een voorbeeld van hoe een console-applicatie op te starten, en van hoe de uitvoer van dit programma uit te lezen en weer te geven. Alles gebeurt via de 3 standaard-handles: stdout, stdin en stderr (via Pipes).

    #include
    "stdafx.h"

    #include <windows.h>

     

    int main()

    {

      HANDLE input_PipeRead;

      HANDLE input_PipeWrite;

      HANDLE output_PipeRead;

      HANDLE output_PipeWrite;

      HANDLE error_PipeRead;

      HANDLE error_PipeWrite;

     

      CHAR message[] = "";

     

      PROCESS_INFORMATION process_info;

      STARTUPINFO startup_info;

      SECURITY_ATTRIBUTES security_attributes;

     

      // Set the security attributes for the pipe handles created

      security_attributes.nLength              = sizeof(SECURITY_ATTRIBUTES);

      security_attributes.bInheritHandle       = TRUE;

      security_attributes.lpSecurityDescriptor = NULL;

     

      // Create the pipes used for the communication

      CreatePipe(&output_PipeRead, &output_PipeWrite, &security_attributes, 0);

      CreatePipe(&input_PipeRead,  &input_PipeWrite,  &security_attributes, 0);

      CreatePipe(&error_PipeRead,  &error_PipeWrite,  &security_attributes, 0);

     

      // Prepare the startup structure for the child process

      ZeroMemory(&startup_info, sizeof(STARTUPINFO));

      startup_info.cb         = sizeof(STARTUPINFO);

      startup_info.hStdInput  = input_PipeRead;

      startup_info.hStdOutput = output_PipeWrite;

      startup_info.hStdError  = error_PipeWrite;

      startup_info.dwFlags    = STARTF_USESTDHANDLES;

     

      // Create the child process

      if(!CreateProcess(NULL, "cmd /C "echo Test"", NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info))

        return 0;

     

      // Write a message to the child process

      if(*message)

      {

        DWORD bytes_written = 0;

        WriteFile(input_PipeWrite, message, strlen(message), &bytes_written, NULL);

      }

     

      // Wait for the process to end

      WaitForSingleObject(process_info.hProcess, INFINITE);

     

      // Read the message from the child process

      DWORD output_BytesToRead = 0, error_BytesToRead = 0;

      if(  !PeekNamedPipe(output_PipeRead, NULL, 0, NULL, &output_BytesToRead, NULL)
         || 
           !PeekNamedPipe(error_PipeRead, NULL, 0, NULL, &error_BytesToRead, NULL))

        return 0;

     

      CHAR *output_Buffer = new CHAR[output_BytesToRead + 1];

      CHAR *error_Buffer = new CHAR[error_BytesToRead + 1];

      if(output_Buffer && error_Buffer)

      {

        DWORD tmp_BytesRead;

     

        // Read the output code

        tmp_BytesRead = 0;

        if(output_BytesToRead)

          ReadFile(output_PipeRead, output_Buffer, output_BytesToRead, &tmp_BytesRead, NULL);

        output_Buffer[tmp_BytesRead] = 0;

     

        // Read any errors

        tmp_BytesRead = 0;

        if(error_BytesToRead)

          ReadFile(error_PipeRead, error_Buffer, error_BytesToRead, &tmp_BytesRead, NULL);

        error_Buffer[tmp_BytesRead] = 0;

     

        // Output

        if(*error_Buffer)

          MessageBox(NULL, error_Buffer,  "There were errors!", MB_OK);

        else

          MessageBox(NULL, output_Buffer, "Output code",        MB_OK);

      }

     

      return 0;

    }

     

    09-06-2011, 00:00 Geschreven door Fibergeek  


    Categorie:Code: C/C++
    08-06-2011
    Klik hier om een link te hebben waarmee u dit artikel later terug kunt lezen.Mijn begin met WPF (INotifyPropertyChanged)
    Een van de leuke dingen van WPF is dat de UI automatisch kan aangepast worden als de data veranderd (en omgekeerd ook). In het onderstaande voorbeeld wordt de test-tekst omgedraaid als er op geklikt wordt:

    <Application x:Class="Application"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                
    StartupUri="MainWindow.xaml">
    </
    Application>
    <
    Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
           
    Title="Een simpele test" Height="350" Width="525">
      <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"
                 MouseDown="OnEvent__TextBlock_MouseDown"
                
    Text="{Binding Path=TestTekst}"
                />
    </
    Window>

    De bijhorende code:

    Imports

    System.ComponentModel

    Class

    MainWindow
      Implements INotifyPropertyChanged

      Public Property TestTekst As String = "Dit is een simpele test..."

      Private
    Sub OnEvent__TextBlock_MouseDown(ByVal sender As System.Object,
                                              
    ByVal e As System.Windows.Input.MouseButtonEventArgs)
        TestTekst = StrReverse(TestTekst)
        NotifyPropertyChanged(
    "TestTekst")
      End Sub

    #Region

    "INotifyPropertyChanged implementation"
      Private Event PropertyChanged(ByVal sender As Object,
                                   
    ByVal e As System.ComponentModel.PropertyChangedEventArgs)
                    
    Implements INotifyPropertyChanged.PropertyChanged

      Protected Sub NotifyPropertyChanged(ByVal sender As Object, ByVal propertyName As String)
        RaiseEvent PropertyChanged(sender, New PropertyChangedEventArgs(propertyName))
      End Sub
      Private Sub NotifyPropertyChanged(ByVal propertyName As String)
        NotifyPropertyChanged(
    Me, propertyName)
      End Sub
    #End
    Region
    End
    Class


    In het bovenstaande voorbeeld is de OnEvent_TextBlock_MouseDown-functie verantwoordelijk voor het aanroepen van de NotifyPropertyChanged-functie. We kunnen deze verantwoordelijkheid ook geven aan de TestTekst-Property als volgt:

    Imports System.ComponentModel

    Class MainWindow
      Implements INotifyPropertyChanged

      Protected _TestTekst As String = "Dit is een simpele test..."

      Public
    Property TestTekst As String
        Get
          Return _TestTekst
        End Get
        Set(ByVal value As String)
          _TestTekst = value
          NotifyPropertyChanged(
    "TestTekst")
        End Set
      End Property


      Private
    Sub OnEvent__TextBlock_MouseDown(ByVal sender As System.Object,
                                              
    ByVal e As System.Windows.Input.MouseButtonEventArgs)
        TestTekst = StrReverse(TestTekst)
        NotifyPropertyChanged(
    "TestTekst")
      End Sub

    #Region

    "INotifyPropertyChanged implementation"
      Private Event PropertyChanged(ByVal sender As Object,
                                   
    ByVal e As System.ComponentModel.
    PropertyChangedEventArgs)
                    
    Implements
    INotifyPropertyChanged.PropertyChanged

      Protected Sub NotifyPropertyChanged(ByVal sender As Object, ByVal propertyName As String)
        RaiseEvent PropertyChanged(sender, New PropertyChangedEventArgs(propertyName))
      End Sub
      Private Sub NotifyPropertyChanged(ByVal propertyName As String)
        NotifyPropertyChanged(
    Me, propertyName)
      End Sub
    #End
    Region
    End
    Class

    08-06-2011, 00:00 Geschreven door Fibergeek  


    Categorie:Code: WPF
    07-06-2011
    Klik hier om een link te hebben waarmee u dit artikel later terug kunt lezen.Mijn begin met WPF (Data Binding)
    Het is nu al bijna een jaar geleden dat ik met WPF (Windows Presentation Foundation) begonnen ben. Echter, ik ben het meeste al weer vergeten. Het is aanpassen . Eens de "basics" van Data-Binding herbekijken...

    Een simpel programma, een tekst in het midden van het scherm:

    <

    Application x:Class="Application"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                
    StartupUri="MainWindow.xaml">
    </
    Application>
    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns
    :x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Een simpele test" Height="350" Width="525">
           
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25">
             
    Dit is een simpele test...
           
    </TextBlock>
    </
    Window>


    Dit is dezelfde versie van het programma, maar de tekst is nu verhuist naar een Resource-blok op het Window-niveau:

    <Application x:Class="Application"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                
    StartupUri="MainWindow.xaml">
    </
    Application>
    <

    Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:s="clr-namespace:System;assembly=mscorlib"
            Title="Een simpele test" Height="350" Width="525">
      <Window.Resources>
        <s:String x:Key="TestTekst">Dit is een simpele test...</s:String>
      </Window.Resources>
      <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"
                 Text="{Binding Source={StaticResource TestTekst}}"
                />
    </
    Window>


    We kunnen de TestTekst-variable ook verhuizen naar het Application-blok (met als voordeel dat deze variable nu gebruikt kan worden in andere schermen):

    <Application x:Class="Application"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:s="clr-namespace:System;assembly=mscorlib"
                
    StartupUri="MainWindow.xaml">
      <Application.Resources>
        <s:String x:Key="TestTekst">Dit is een simpele test...</s:String>
      </Application.Resources>
    </
    Application>
    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Een simpele test" Height="350" Width="525">
      <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"
                 Text="{Binding Source={StaticResource TestTekst}}"
                />
    </
    Window>


    Het is ook mogelijk om deze tekst te laten komen uit een variable uit de bijhorende Window-class. De DataContext van het window moet dan naar zichzelf wijzen:

    <Application x:Class="Application"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                
    StartupUri="MainWindow.xaml">
    </
    Application>
    <

    Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
           
    Title="Een simpele test" Height="350" Width="525">
      <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"
                
    Text="{Binding Path=TestTekst}"
                />
    </
    Window>

    De bijhorende classe-code:

    Class

    MainWindow
     
    Public Property TestTekst As String = "Dit is een simpele test..."
    End Class


    Maar omdat de Designer nu de inhoud van de TestTekst zelf niet kan bepalen wordt deze niet weergegeven. Vreed lastig dus tijdens de ontwikkeling van de schermen. Dit kan men oplossen door een FallbackValue in te stellen. Hetzelfde programma als hierboven maar het TextBlock in het Window-blok is een klein beetje aangepast:

    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
           
    Title="Een simpele test" Height="350" Width="525">
      <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"
                 T
    ext="{Binding Path=TestTekst,FallbackValue='(hier komt de TestTekst)'}"
                />
    </
    Window>

    07-06-2011, 00:00 Geschreven door Fibergeek  


    Categorie:Code: WPF
    Archief per week
  • 25/11-01/12 2013
  • 05/11-11/11 2012
  • 07/05-13/05 2012
  • 05/03-11/03 2012
  • 20/02-26/02 2012
  • 13/02-19/02 2012
  • 30/01-05/02 2012
  • 12/12-18/12 2011
  • 05/12-11/12 2011
  • 19/09-25/09 2011
  • 15/08-21/08 2011
  • 01/08-07/08 2011
  • 04/07-10/07 2011
  • 06/06-12/06 2011

    E-mail mij

    Druk op onderstaande knop om mij te e-mailen.


    Gastenboek

    Druk op onderstaande knop om een berichtje achter te laten in mijn gastenboek


    Blog als favoriet !


    Blog tegen de wet? Klik hier.
    Gratis blog op https://www.bloggen.be - Meer blogs