Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zapis do pliku przyciskiem WinAPI

Ostatnio zmodyfikowano 2010-12-06 22:59
Autor Wiadomość
Elaine
» 2010-12-05 23:34:19
SaveFile cieknie - jeśli plik zostanie poprawnie otwarty, a tekst do zapisania będzie pusty lub przy zapisie wystąpi błąd, to uchwyt nie zostanie zamknięty.
P-24868
wojos
» 2010-12-06 01:02:29
Racja, widzę, już poprawiam :D

EDIT:
Mało tego: teraz widzę, że cieknie też po przyciśnięciu przycisku :P Ale też już poprawiam
Nie służy mi coś pisanie na szybko :P
P-24870
Mazzir
Temat założony przez niniejszego użytkownika
» 2010-12-06 20:44:51
http://wklej.org/id/432999/

A teraz co jest źle że nie zapisuje ?
P-24893
wojos
» 2010-12-06 22:59:25
Dużo masz błędów tutaj. Zanim przeczytasz to powiem tylko, że starałem się linie dobrze odzwierciedlić ale na tym wkleju trochę rozjechały się te linie z ich własnymi oznaczeniami więc możliwe, że gdy np. piszę, że błąd jest w linii 50, to może on być tak na prawdę 49 lub 51.
Ok do rzeczy:

Po pierwsze chyba nie do końca rozumiesz na czym polega obsługa zdarzeń, cały kod z linii 79 - 114 nie ma sensu. Piszesz go przed włączeniem pętli komunikatów a więc zanim ktokolwiek jest w stanie cokolwiek napisać w Twoim okienku. Poza tym niepotrzebna jest Ci globalna hPlik. Całym zapisywaniem plików zajmuje się już funkcja SaveFile i wystarczy, że podasz jej adres i tekst do zapisania a ona całą brudną robotę odwali za Ciebie (nie wspominając o tym, że jak jesteś leniwy to po co pisać ją 150 razy dla każdego programu jak można skopiować albo zrobić sobie jako nagłówek i linkować gdzie się żywnie podoba).

Po drugie nadal nie ma zmiennej globalnej dla pola edycji. Pobierasz uchwyt do okna [HWND] w funkcji main natomiast tracisz go w obsłudze komunikatów (gdzie tak w ogóle już w pierwszej linii tej funkcji deklarujesz sobie pusty uchwyt - z pustego nawet tekstu nie pobierzesz :P) i tak na prawdę pobierasz tekst z niczego.

Po trzecie zupełnie niepotrzebne Ci jest globalny Bufor zadeklarowany w linii 37. LPSTR to jest to samo co char* a więc de facto masz tam wskaźnik, który ponadto jest na 99,99999999999999999999999999999999999999999999999999% zawsze błędny :P Następnie odwołujesz się do tego bufora w 148 i 150 co jest totalnym błędem - w najlepszym wypadku program się wysypie a skąd wiesz czy nie zacznie zmieniać danych innych programów :D Jednym słowem chaos. Masz już gotowy bufor o nazwie Buffer zadeklarowany i przygotowany na przyjęcie tekstu w linii 147. Jego [Buffer] powinieneś użyć w linii 148 i 150 zamiast Bufor. Ponadto po wykonaniu tej operacji należy zwolnić ten Buffer jednak to robisz pod koniec obsługi tego komunikatu, bardzo dobrze :D.

Po czwarte działający kod wygląda mniej więcej tak:

C/C++
#include <windows.h>
#include <string.h>

bool SaveFile( const char * Address, const char * Text ) //Address to pelna sciezka lub tylko nazwa
{
    DWORD dwSize, dwSaved;
    HANDLE hPlik;
   
    hPlik = CreateFile( Address, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL );
    if( hPlik == INVALID_HANDLE_VALUE )
         return( false );
   
    dwSize = strlen( Text );
    if( dwSize == 0 )
    {
        CloseHandle( hPlik );
        return( false );
    }
   
    if( !WriteFile( hPlik, Text, dwSize, & dwSaved, NULL ) )
    {
        CloseHandle( hPlik );
        return( false );
    }
   
    CloseHandle( hPlik );
    return( true );
}

LPCSTR NazwaKlasy = "Klasa Okienka";
MSG Komunikat;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );

HWND g_hPrzycisk;
HWND g_hText;
DWORD dwRozmiar, dwZapisane;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    // WYPEŁNIANIE STRUKTURY
    WNDCLASSEX wc;
    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 = NazwaKlasy;
    wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
   
    // REJESTROWANIE KLASY OKNA
    if( !RegisterClassEx( & wc ) )
    {
        MessageBox( NULL, "Wysoka Komisja odmawia rejestracji tego okna!", "Niestety...",
        MB_ICONEXCLAMATION | MB_OK );
        return 1;
    }
   
    // TWORZENIE OKNA
    HWND hwnd;
    hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, NazwaKlasy, "Application", WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL );
   
    if( hwnd == NULL )
    {
        MessageBox( NULL, "Okno odmówiło przyjścia na świat!", "Ale kicha...", MB_ICONEXCLAMATION );
        return 1;
    }
   
    ShowWindow( hwnd, nCmdShow ); // Pokaż okienko...
    UpdateWindow( hwnd );
    g_hText = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 628, 400, hwnd, NULL, hInstance, NULL );
    g_hPrzycisk = CreateWindowEx( 0, "BUTTON", "Zapisz", WS_CHILD | WS_VISIBLE, 250, 410, 150, 30, hwnd, NULL, hInstance, NULL );
   
   
    // Pętla komunikatów
    while( GetMessage( & Komunikat, NULL, 0, 0 ) )
    {
        TranslateMessage( & Komunikat );
        DispatchMessage( & Komunikat );
    }
    return Komunikat.wParam;
}

// OBSŁUGA ZDARZEŃ
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 );
    case WM_COMMAND:
        if( g_hPrzycisk ==( HWND ) lParam ) /*Tak w ogole to lepiej zebys nauczyl sie dawac kontrolkom
                                                                     identyfikatory i nimi rozpoznawac a nie uchwytem*/
        {
            int Length = GetWindowTextLength( g_hText ); /*Jesli nie masz identyfikatora kontrolki to
                                                                                           musisz pole tekstowe zadeklarowac jako
                                                                                           globalna zmienna*/
            char * Buffer =( char * ) GlobalAlloc( GPTR, Length + 1 );
            GetWindowText( g_hText, Buffer, Length + 1 );
           
            if( !SaveFile( "test.txt", Buffer ) )
            {
                MessageBox( hwnd, "Nie udalo sie zapisac!", "Error!", MB_ICONERROR );
            } else
            {
                MessageBox( hwnd, "Gotowe", "Zapisywanie...", MB_ICONINFORMATION );
            }
           
            GlobalFree( Buffer );
        }
        break;
       
    }
    return 0;
}
P-24894
1 « 2 »
Poprzednia strona Strona 2 z 2