Kurz1 - Kapitola12

17. června 2007 v 16:06 | http://www.sweb.cz/kurz_evt/ |  Programování pro WinCE

3.6 Otevření souboru

Do tohoto okamžiku jsme si v programu prohlíželi pouze provizorní data vytvořená v bufferu, což by asi nebylo moc užitečné... :-)
Nastal tedy čas, abychom se podívali na obsah skutečného souboru. Využijeme doposud vytvořený program na to, aby se nám s co nejmenším počtem úprav na displeji objevila data obsažená ve vybraném souboru.
Prvním krokem bude doplnění volby souboru. Nový soubor se bude otvírat pomocí volby Open z vybrané v nabídce (menu). Do menu programu vložte novou položku pod File - Open. Její ID by mělo být ID_FILE_OPEN. Volba File teď obsahuje dvě položky - Open a Exit.
Protože využijeme na získání jména souboru standardní dialog Windows, přidáme na úvod programu hlavičkový soubor:
#include <commdlg.h>
Tento hlavičkový soubor umožňuje práci s běžnými dialogy, které se vyskytují ve Windows.
Dále přidejte globální proměnné...
#define FILE_NAME_DIM 256
TCHAR szFileName[FILE_NAME_DIM]; // Jmeno otevreneho souboru
HANDLE hFile; // Handle na tento soubor
...a také něco lokálních proměnných:
// Pro soubor
OPENFILENAME of;
DWORD dwBuduCist,dwCteno;
Nyní již lze ve zpracování zprávy WM_COMMAND doplnit novou možnost:
case ID_FILE_OPEN:
// Nastavime pozadovane parametry otviraneho souboru
szFileName[0] = '\0';
memset(&of, 0, sizeof(of));
of.lStructSize = sizeof(of);
of.hwndOwner = hWnd;
of.nMaxFile = FILE_NAME_DIM;
of.lpstrFilter = TEXT("All files (*.*)\0*.*\0\0");
of.lpstrFile = szFileName;
of.lpstrInitialDir = NULL;
// Pokud ziskame vhodne jmeno, zkusime jej vytvorit ...
if (GetOpenFileName(&of))
{
if (hFile)
CloseHandle(hFile);
hFile = CreateFile (szFileName,GENERIC_READ,FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// ... nepovedlo se
if (hFile == INVALID_HANDLE_VALUE)
{
hFile = 0;
szFileName[0] = '\0';
}
// ... povedlo se a nastavim si podle souboru potrebne promenne
else
{
nMaxPocet = GetFileSize(hFile, NULL);
nZobrByte = 0;
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = nMaxPocet - 1 + nSloupce;
SetScrollInfo (hwndScroll,SB_CTL,&si,FALSE);
PostMessage(hWnd,WM_APP,0,0);
// a soucasne vykreslim novy soubor
InvalidateRect(hWnd,NULL,TRUE);
}
}
break;
Otevírání souboru se skládá ze tří kroků:
  1. Nejprve se v proměnné of nastaví požadované parametry pro dialog otevírání souboru. Funkce GetOpenFileName získá jméno souboru.
  2. Pokud funkce GetOpenFileName uspěla, pokusí se funkce CreateFile otevřít soubor takového jména (když před tím zavřela handle případného předcházejícího otevřeného soboru).
  3. Jestliže uspěla i CreateFile, nastaví se posuvník, proměnné a vykreslí se okno.
Abychom nemuseli příliš měnit zobrazovací část, využijeme dosavadní buffer. Před každým zobrazením (zpracování WM_PAINT) pouze ze souboru z pozice dané nZobrByte načteme funkcí ReadFile potřebný počet bajtů do bufferu.
Ve zprávě WM_PAINT doplníme nebo upravíme pouze 7 řádků. Pro informaci je zobrazena celá zpráva WM_PAINT, změněné nebo doplněné řádky jsou očíslovány v komentáři.
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if (hFile) // !1
{ // !2
hPuvodFont = (HFONT)SelectObject(hdc,hFontPS);
// Nastavime pointer na misto souboru, kde zobrazujeme
SetFilePointer(hFile,(LONG)nZobrByte,NULL,FILE_BEGIN); // !3
// Potrebny pocet Byte presuneme do bufferu
dwBuduCist = ((nSloupce*nLinek)<(nMaxPocet-nZobrByte))?(nSloupce*nLinek):(nMaxPocet-nZobrByte); // !4
ReadFile(hFile,pBuffer,dwBuduCist,&dwCteno,NULL); // !5
// Nastavime ukazatele, odkud zaciname zobrazovat
pPomUkaz1 = pPomUkaz2 = pBuffer; // !6
y = rctKlient.top;
// Zobrazime jednotlive radky na obrazovce
for (j=0; j < nLinek; j++) {
nZacRadku = (((nZobrByte + j*nSloupce) > nMaxPocet) ? nMaxPocet : (nZobrByte + j*nSloupce));
// Kolik Byte bude zobrazeno na tomto radku
nByteLin = (((nMaxPocet - nZacRadku) > nSloupce) ? nSloupce : (nMaxPocet - nZacRadku));
// Zobraz adresu prvniho Byte radku
wsprintf (szOut, TEXT ("%08X| "), nZacRadku);

for (i = 0; i < nByteLin; i++) {
wsprintf (szTmp, TEXT ("%02X"), *pPomUkaz1++);
lstrcat (szOut, szTmp);
if ((i == 7) && (nByteLin>8))
lstrcat (szOut, TEXT ("."));
else
lstrcat (szOut, TEXT (" "));
}
// Doplnek mezer na radku, ktery neni uplny
if (nByteLin<nSloupce)
for (i = 0; i < nSloupce-nByteLin; i++) {
wsprintf (szTmp, TEXT (" "));
lstrcat (szOut, szTmp);
}
// Zde je pridano zobrazovani textu v prave polovine obrazovky
if (nByteLin) lstrcat (szOut, TEXT ("|"));
if (bSTextem)
for (i = 0; i < nByteLin; i++) {
bZnak=*pPomUkaz2++;
cZnak = bZnak>31 ? bZnak : 46;
wsprintf (szTmp, TEXT ("%c\0"), cZnak);
lstrcat (szOut, szTmp);
}
// ... a zbyva radek zobrazit
if (nByteLin) ExtTextOut(hdc, 0, y, 0, NULL, szOut, lstrlen(szOut), NULL);
y += nVyskaRadku;
}
SelectObject(hdc,hPuvodFont);
} // !7
EndPaint(hWnd, &ps);
break;
Zbývá ve zprávě WM_DESTROY zrušit handle...
    if (hFile) CloseHandle(hFile);
... a smazat z WM_CREATE cyklus pro naplnění bufferu čísly.
Nyní si již můžeme prohlížet první soubory:

obr. 29 Volba otevření souboru

Co bychom si měli z této lekce zapamatovat?

  • Pro použití společných dialogů slouží hlavičkový soubor commdlg.h.
  • Jméno otevíraného souboru lze získat funkcí GetOpenFileName resp. GetSaveFileName.
  • Soubor se otvírá funkcí CreateFile.
  • Velikost souboru zjistí funkce GetFileSize.
  • Ukazatel v souboru nastaví SetFilePointer.
  • Číst resp. zapsat data lze funkcí ReadFile resp. WriteFile.
 

Buď první, kdo ohodnotí tento článek.

Nový komentář

Přihlásit se
  Ještě nemáte vlastní web? Můžete si jej zdarma založit na Blog.cz.