JavascriptProva

domenica 27 ottobre 2013

Registrazione della finestra

La procedura principale è la WinMain.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
...durante la quale, per prima cosa si definisce la variabile wc di tipo WNDCLASSEX, che è una struttura.
Quindi si "registra" la wc.

.....

 WNDCLASSEX wc;

.....

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }


E questo è il primo passo.

Una finestra Win32

Bene.
Basta a pazzià!!!
Cerchiamo di andare su linguaggi più ponderosi.

Ecco una finestra con la sintassi del C++:
#include 

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
Bene, adesso vediamo come si rimaneggia tutto questo...

giovedì 10 ottobre 2013

Metodi di lettura di uno stream.

Non capisco.
Dunque, riepiloghiamo: uno stream può essere letto con metodi diversi:
  • Read, che ha bisogno di un buffer;
  • ReadByte, che legge un byte alla volta;
  • Per mezzo di un Reader, che è un oggetto a parte.
Sparo di aver capito... La cosa mi è un po' ostica!

Lettura in un buffer di un file wav mediante il metodo Read

Ecco, con questo codice leggo una parte di un file WAV. E ottengo la conferma che si tratta di un file WAV in quanto ne riconosco l'header:
Imports System.IO
Module Module1
    Dim corrente As New FileStream("c:\users\antonello\desktop\voce.wav", FileMode.Open)

    Dim destinazione(&H100) As Byte
    Sub Main()
        
        corrente.Read(destinazione, 0, destinazione.Length)

        For n = 0 To destinazione.Length - 1
            Console.Write(Chr(destinazione(n)))
        Next

        Console.ReadKey()
    End Sub

End Module
RIFFD☻☺ WAVEfmt ►   ☺ ☺ ◄+  ◄+  ☺ data ☻☺ ????⌂???????????????????⌂??????????⌂⌂⌂
????⌂???????????????????⌂??⌂???????⌂???⌂?⌂?????⌂??????⌂????????⌂⌂???????????⌂???
????????????⌂????⌂⌂???⌂?⌂???⌂??????????????????????????????????⌂???????????⌂???⌂
⌂????⌂??????⌂⌂?


Lettura di un file wav in un buffer mediante il metodo .Read

Ecco, con questo codice leggo una parte di un file WAV. E ottengo la conferma che si tratta di un file WAV in quanto ne riconosco l'header:
Imports System.IO
Module Module1
    Dim corrente As New FileStream("c:\users\antonello\desktop\voce.wav", FileMode.Open)

    Dim destinazione(&H100) As Byte
    Sub Main()
        
        corrente.Read(destinazione, 0, destinazione.Length)

        For n = 0 To destinazione.Length - 1
            Console.Write(Chr(destinazione(n)))
        Next

        Console.ReadKey()
    End Sub

End Module
RIFFD☻☺ WAVEfmt ►   ☺ ☺ ◄+  ◄+  ☺ data ☻☺ ????⌂???????????????????⌂??????????⌂⌂⌂
????⌂???????????????????⌂??⌂???????⌂???⌂?⌂?????⌂??????⌂????????⌂⌂???????????⌂???
????????????⌂????⌂⌂???⌂?⌂???⌂??????????????????????????????????⌂???????????⌂???⌂
⌂????⌂??????⌂⌂?


Ancora lettura e scrittura da MemoryStream

Imports System.IO
Module Module1
    Dim corrente As New MemoryStream
    Dim sorgente() As Byte = {1, 4, 65, 3, 7}
    Dim destinazione(5) As Byte
    Sub Main()
        corrente.Write(sorgente, 0, sorgente.Length)
        corrente.Position = 0
        corrente.Read(destinazione, 0, sorgente.Length)

        For n = 0 To sorgente.Length - 1
            Console.WriteLine(destinazione(n))
        Next
        Console.ReadKey()
    End Sub

End Module
Ecco come scrivo con Write e leggo con Read.

WriteByte e ReadByte, invece, servono per leggere singoli bytes.

mercoledì 9 ottobre 2013

Lettura e scrittura da MemoryStream

Sempre per leggere e scrivere dagli streams.
Uso un MemoryStream.

Imports System.IO
Module Module1
    Dim corrente As New MemoryStream
    Dim sorgente() As Byte = {1, 2, 3, 4, 5}
    Sub Main()
        corrente.Write(sorgente, 0, 3)
        Dim result As Integer
        corrente.Position = 1
        result = corrente.ReadByte()
        Console.WriteLine(result)
        Console.ReadKey()
    End Sub

End Module
Ho scritto sullo stream prelevando da una matrice di bytes.
In blocco. Quindi ho usato Write.
Write accetta come parametri la matrice da cui leggere, la posizione iniziale e la quantità di bytes. Legge solo da una matrice di bytes.

Per la lettura ho usato ReadByte che legge un byte alla volta.
Se invece avessi voluto leggere in blocco dentro una matrice di bytes, avrei dovuto usare Read.

Seguendo un esempio visto in rete, ho usato il tipo Integer per la variabile result in cui leggere il byte.
Ma potrei usare anche un tipo Byte?

Imports System.IO
Module Module1
    Dim corrente As New MemoryStream
    Dim sorgente() As Byte = {1, 2, 3, 4, 5}
    Sub Main()
        corrente.Write(sorgente, 0, 3)
        Dim result As Byte
        corrente.Position = 1
        result = corrente.ReadByte()
        Console.WriteLine(result)
        Console.ReadKey()
    End Sub

End Module
Sì, ottengo sempre risultati pertinenti.

Ho ottenuto un errore, prima, usando il tipo Byte in questo modo:
    Sub Main()
        corrente.Write(sorgente, 0, 3)
        Dim result As Byte
        result = corrente.ReadByte()
        Console.WriteLine(result)
        Console.ReadKey()
    End Sub
Il tipo di errore era questo:
Eccezione first-chance di tipo 'System.OverflowException' in Streams.exe
che, usando un tipo Integar, non veniva più segnalato:
    Sub Main()
        corrente.Write(sorgente, 0, 3)
        Dim result As Integer
        result = corrente.ReadByte()
        Console.WriteLine(result)
        Console.ReadKey()
    End Sub
ottenendo però questo risultato:
-1


Il problema era che non avevo reimpostato la posizione di lettura dell'oggetto MemoryStream, per cui la posizione, una volta effettuata la scrittura, restava impostata sull'ultimo byte, e il valore successivo era -1, che non può essere rappresentato in un tipo Byte, che è senza segno.
Invece il tipo Integer può rappresentare i numeri negativi:
1111 1111 1111 1111 1111 1111 1111 1111
dovrebbe essere la rappresentazione di -1 in un tipo Integer.
Usando un tipo che non può essere con segno, invece, ottengo un errore.
La riprova di questo la ottengo usando un tipo Integer senza segno:
    Sub Main()
        corrente.Write(sorgente, 0, 3)
        Dim result As UInt32
        result = corrente.ReadByte()
        Console.WriteLine(result)
        Console.ReadKey()
    End Sub
Ed ottengo sempre:
Eccezione first-chance di tipo 'System.OverflowException' in Streams.exe
come volevasi dimostrare.

Il fatto che ottengo -1 è dovuto al fatto che non ho resettato la posizione.
Rimedio subito e posso usare anche Byte (o anche Uint32):
    Sub Main()
        corrente.Write(sorgente, 0, 3)
        Dim result As Byte
        corrente.Position = 1
        result = corrente.ReadByte()
        Console.WriteLine(result)
        Console.ReadKey()
    End Sub
Ed ecco:
2


Okay!

martedì 8 ottobre 2013

Lettura e scrittura di bytes su uno stream

Ho creato un oggetto MemoryStream.
Imports System.IO
Public Class Form1
    Dim memoria As Stream
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        memoria = New MemoryStream


    End Sub
End Class
Ora devo vedere come si scrive e si legge da questo stream...

        memoria = New MemoryStream
        memoria.WriteByte(12)
Come si legge dallo stream?

        memoria = New MemoryStream
        memoria.WriteByte(12)

        Dim risultato As Integer
        memoria.Position = 0
        risultato = memoria.ReadByte()
        MsgBox(risultato)
E ottengo 12.

Scrivo due bytes.
        memoria = New MemoryStream
        memoria.WriteByte(12)
        memoria.WriteByte(4)
Leggo il byte in posizione 1.
                memoria = New MemoryStream
        memoria.WriteByte(12)
        memoria.WriteByte(4)

        Dim risultato As Integer
        memoria.Position = 1
        risultato = memoria.ReadByte()
        MsgBox(risultato)
E ottengo 4.

E finora ho capito come "funziona"!

martedì 1 ottobre 2013

BitsPerSample, BlockAlign, SampleRate, BytesPerSecond

1760:0100  52 49 46 46 05 2A 00 00-57 41 56 45 66 6D 74 20   RIFF.*..WAVEfmt
1760:0110  10 00 00 00 01 00 01 00-11 2B 00 00 11 2B 00 00   .........+...+..
1760:0120  01 00 08 00 64 61 74 61-E1 29 00 00 80 80 7F 80   ....data.)......
1760:0130  80 80 80 7F 80 80 80 80-80 80 80 80 80 80 80 80   ................
1760:0140  80 80 7F 80 80 80 80 80-80 80 80 80 81 80 7F 80   ................
1760:0150  80 80 80 80 80 80 80 80-80 80 80 80 80 80 80 80   ................
1760:0160  80 80 7F 80 80 80 80 80-80 80 80 80 80 80 80 80   ................
1760:0170  81 80 80 80 80 80 80 80-81 80 80 80 81 81 80 80   ................
Queste sono le voci dell'header del file WAV che esprimono rispettivamente:
11 2B 00 00 sample rate
11 2B 00 00 bytes per secondo
01 00 block align (bytes per campione) 
08 00 averageBitsPerSample (bits per campione per canale)
Le ultime due voci sono strettamente correlate: i bits per campione per canale, ridotti a bytes e moltiplicati per il numero dei canali, sono la quantità di informazione che deve essere creata per ogni campionamento. Moltiplicata per la frequenza di campionamento (Sample rate, in arancio, esprime i bytes per secondo (la voce in rosso).
Tutto qui.

In questo caso, essendoci 2B11H (11025) campioni al secondo e 2B11H (11025) bytes al secondo, è ovvio che per ogni campione ci sarà un byte, e quindi il numero di canali è 1 e il Block ALign è 1, essendo BitsPerSample 8, come risulta dall'header.