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

Problem z obsługą plików w WinAPI

Ostatnio zmodyfikowano 2011-12-23 11:04
Autor Wiadomość
DanX95X
Temat założony przez niniejszego użytkownika
Problem z obsługą plików w WinAPI
» 2011-12-23 10:22:02
Cześć ostatnio bawię się trochę z obsługą plików w WinAPI. I mam pewien problem. Konkretnie nie mogę otworzyć pliku przy próbie zapisu danych. Zamieszczam kod. Byłbym wdzięczny gdyby ktoś mi pomógł.

C/C++
#include <Windows.h>

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );

void file_open( HWND );
void file_write( HWND );

HWND hWnd;
HWND hText;
HWND hStatic;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
   
   
    WNDCLASSEX wc;
   
    ZeroMemory( & wc, sizeof( WNDCLASSEX ) );
   
    wc.cbSize = sizeof( WNDCLASSEX );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = L"class";
    wc.style = CS_HREDRAW | CS_VREDRAW;
   
    RegisterClassEx( & wc );
   
    hWnd = CreateWindowEx( NULL,
    L"class", L"Pliki",
    WS_OVERLAPPEDWINDOW,
    0, 0,
    640, 480,
    NULL, NULL,
    hInstance, NULL );
   
    hText = CreateWindowEx( WS_EX_CLIENTEDGE,
    L"EDIT", NULL,
    WS_CHILD | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | WS_VISIBLE,
    10, 10,
    200, 200,
    hWnd, NULL,
    hInstance, NULL );
   
    hStatic = CreateWindowEx( WS_EX_CLIENTEDGE,
    L"STATIC", NULL,
    WS_CHILD | WS_VISIBLE | WS_BORDER,
    300, 10, 100, 100,
    hWnd, NULL,
    hInstance, NULL );
   
    ShowWindow( hWnd, nCmdShow );
   
   
    MSG msg;
   
    while( TRUE )
    {
        while( PeekMessage( & msg, NULL, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( & msg );
            DispatchMessage( & msg );
        }
        if( msg.message == WM_QUIT ) break;
       
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch( message )
    {
    case WM_DESTROY:
        {
            PostQuitMessage( 0 );
            return 0;
        } break;
    case WM_COMMAND:
        {
            if(( HWND ) lParam == hText )
                 file_write( hText );
           
            file_open( hStatic );
        } break;
    }
    return DefWindowProc( hWnd, message, wParam, lParam );
}

void file_open( HWND hStatic )
{
    LPSTR buffer; //wskaźnik do bufora
    DWORD size, read; //zmienne przechowujące rozmiar pliku i ilość przeczytanych danych
    HANDLE hFile; //uchwyt do pliku
   
    //1-nazwa pliku, 3-współdzielenie pliku; 5-tryb otwierania pliku; 6-flagi dostępu;7- zawsze NULL
    hFile = CreateFile( L"file.txt", GENERIC_READ /*odczytywanie*/, 0 /*lub FILE_SHARE_READ\WRITE*/, NULL, OPEN_EXISTING /*jeśli plik nie istnieje to wywala błąd*/, 0, NULL );
    size = GetFileSize( hFile, NULL ); //1-uchwyt pliku;2-argument do pobierania większych plików
    buffer =( LPSTR ) GlobalAlloc( GPTR, size + 1 ); //alokowanie dynamicznych zmiennych; wymagana konwersja do LPSTR;1-oznacza to wypełnienie zmiennej zerami, GMEM_FIXED ustawia na NULL;2-rozmiar zmiennej do zaalokowania; można użyć LocalAlloc(dodawać 1);
    ReadFile( hFile, buffer, size, & read, NULL ); //wczytanie zawartości pliku do zmiennej read; 1-uchwyt pliku;2-bufor;3-liczba bajtów do wczytania;4-zmienna przechowująca zawartość pliku;5-struktura przechowująca dane, jeśli 4 jest różne od NULL to 5 jest NULL i na odwrót
    buffer[ size ] = 0; //dopisanie końca wczytywania stringa na końcu stringa
    SetWindowTextA( hStatic, buffer ); //funkcja wyświetlająca tekst na pasku nazwy; 1 - okno; 2 - string do wyświetlenia
    GlobalFree( buffer ); //zdealokowanie zmiennej globalnej; można użyć LocalFree
    CloseHandle( hFile ); //zamknięcie uchwytu pliku
}

void file_write( HWND hText )
{
    LPSTR Bufor;
    DWORD dwRozmiar, dwZapisane;
    HANDLE hPlik;
   
    hPlik = CreateFile( L"file.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL );
    if( hPlik == INVALID_HANDLE_VALUE )
    {
        MessageBox( NULL, L"Nie można otworzyć pliku.", L"A to pech!", MB_ICONEXCLAMATION ); //To się pokazuje
        PostQuitMessage( 0 );
    }
   
    dwRozmiar = GetWindowTextLength( hText );
    if( dwRozmiar == 0 )
    {
        MessageBox( NULL, L"Nieprawidłowy rozmiar pliku!", L"Niedobrze...", MB_ICONEXCLAMATION );
        PostQuitMessage( 0 );
    }
   
    Bufor =( LPSTR ) GlobalAlloc( GPTR, dwRozmiar + 1 );
    if( Bufor == NULL )
    {
        MessageBox( NULL, L"Za mało pamięci!", L"Ale wiocha...", MB_ICONEXCLAMATION );
        PostQuitMessage( 0 );
    }
   
    GetWindowTextA( hText, Bufor, dwRozmiar );
    Bufor[ dwRozmiar ] = 0;
   
    if( !WriteFile( hPlik, Bufor, dwRozmiar, & dwZapisane, NULL ) )
    {
        MessageBox( NULL, L"Błąd zapisu do pliku", L"Dupa blada!", MB_ICONEXCLAMATION );
        PostQuitMessage( 0 );
    }
   
    GlobalFree( Bufor );
    CloseHandle( hPlik );
}
P-46129
xevuel
» 2011-12-23 10:32:36
Co dostajesz? Jakiś komunikat?
P-46132
DanX95X
Temat założony przez niniejszego użytkownika
» 2011-12-23 10:38:30
Wyskakuje mi ten MessageBox "Nie można otworzyć pliku" a potem pokazuje się

Windows has triggered a breakpoint in Pliki.exe.

This may be due to a corruption of the heap, which indicates a bug in Pliki.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Pliki.exe has focus.

The output window may have more diagnostic information
P-46133
xevuel
» 2011-12-23 10:45:43
skoro najpierw otwierasz plik i nie pozwalasz na jego odczyt innym
C/C++
hFile = CreateFile( L"file.txt", GENERIC_READ, 0 /* o tutaj */, NULL, OPEN_EXISTING, 0, NULL );
, to co się dziwisz, że nie można go otworzyć? Używaj [MSDN] GetLastError()
P-46134
DanX95X
Temat założony przez niniejszego użytkownika
» 2011-12-23 11:01:23
Dzięki teraz działa. Po prostu robiłem zgodnie z tutorialem, w którym było napisane żeby lepiej ustawiać na 0. Temat można zamknąć
P-46135
xevuel
» 2011-12-23 11:04:52
Bo jak nie chcesz żeby inna aplikacja Ci modyfikowała plik w tym momencie, to tak ustawiasz. A w twoim przypadku to lepiej by było żebyś uchwyt do pliku zapamiętał w jednej zmiennej i nie pobierał go za każdym razem, bo to jest bez sensu. I wtedy mógłbyś to 0 tam pozostawić.

PS. Tam na dole jest taki przycisk 'Zamknij temat'.
P-46136
« 1 »
  Strona 1 z 1