JAK: Pisanie aplikacji systemu Windows XP, która przechowuje dane użytkownika i aplikacji we właściwej lokalizacji, za pomocą programu Visual C++ .NET

WAŻNE: Ten artykuł zawiera informacje na temat edytowania Rejestru. Przed edycją Rejestru upewnij się, że wiesz, jak go przywrócić w przypadku pojawienia się problemu. Informacje o przywracaniu Rejestru można znaleźć w temacie „Przywracanie Rejestru” w Pomocy programu Regedit.exe lub w temacie „Przywracanie klucza Rejestru” w Pomocy programu Regedt32.exe.

W TYM ZADANIU

Streszczenie

Aplikacje pracują z dwoma typami dokumentów: tworzonymi przez użytkownika i tworzonymi przez aplikację. Aplikacje powinny używać funkcji powłoki
SHGetFolderPath
do pobierania prawidłowych lokalizacji folderów, w których są przechowywane dane właściwe dla użytkownika i dla aplikacji. W przypadku aplikacji systemu Windows XP ma to podstawowe znaczenie, jeśli chodzi o obsługę wielu użytkowników, którzy używają tego samego komputera, i umożliwienie użytkownikom szybkiego przełączania się.


W tym artykule opisano, jak zapewnić, że dane użytkowników będą przechowywane we właściwym miejscu, wykonując następujące kroki:
  • Utworzenie aplikacji interfejsu Win32
  • Dodanie opcji
    Zapisz jako
    do menu
    Plik.
  • Użycie standardowego okna dialogowego
    Zapisywanie pliku
    do domyślnego ustawienia właściwej lokalizacji.
  • Sprawdzenie poprawności lokalizacji zapisywanych plików.
  • Zapamiętanie poprzedniego wyboru użytkownika.
  • Sprawdzenie poprzedniego wyboru użytkownika.
W tym artykule opisano również, gdzie trzeba przechowywać dane aplikacji i jak zapewnić, że będą one przechowywane w odpowiednich lokalizacjach:
  • Klasyfikowanie danych aplikacji.
  • Przechowywanie danych aplikacji we właściwej lokalizacji.
  • Rozsądne korzystanie z Rejestru.

Wymagania

Oto lista wymaganych elementów, takich jak sprzęt, oprogramowanie, infrastruktura sieci, umiejętności, wiedza i dodatki Service Pack:
  • System Windows XP Home Edition lub Windows XP Professional.
  • Program Microsoft Visual Studio .NET lub Visual Studio 6.0.
  • Umiejętność projektowania aplikacji interfejsu Win32

Utworzenie aplikacji interfejsu Win32

Uruchom program Visual Studio i utwórz nową aplikację interfejsu Win32 o nazwie SavingData
  • W programie Visual C++ 6.0 kliknij projekt Win32 Application na liście dostępnych projektów, a następnie wybierz opcję A typical "Hello World" application w kreatorze Application Setup Wizard.
  • W programie Visual Studio .NET kliknij węzeł
    Visual C++ Projects
    w folderze
    Project Types, a następnie kliknij pozycję
    Win32 Project
    w folderze
    Templates. Zaakceptuj domyślne ustawienia aplikacji wyświetlane przez kreatora Application Setup Wizard.

Dodanie opcji Zapisz jako do menu Plik

  1. Kliknij folder
    Resource View, a następnie kliknij dwukrotnie pozycję
    IDC_SAVINGDATA.
  2. Dodaj opcję menu
    Zapisz jako
    do menu
    Plik. Użyj opcji
    IDM_FILE_SAVEAS
    jako identyfikatora elementu menu.
  3. Zlokalizuj procedurę okna
    WndProc
    aplikacji w pliku SavingData.cppm i dodaj nową instrukcję
    case
    w sekcji
    WM_COMMAND, aby przetworzyć opcję menu
    Zapisz jako. Wywołaj funkcję
    OnFileSaveAs, którą utworzysz w następnej sekcji. Ta funkcja nie ma parametrów.


    Kod powinien wyglądać następująco:
    case WM_COMMAND:
    wmId = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    // Analizuj opcje menu.
    switch (wmId)
    {
    case IDM_ABOUT:
    DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
    break;
    case IDM_EXIT:
    DestroyWindow(hWnd);
    break;
    case IDM_FILE_SAVEAS:
    OnFileSaveAs();
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;

Użycie standardowego okna dialogowego Zapisywanie pliku do domyślnego ustawienia właściwej lokalizacji

Gdy użytkownik po raz pierwszy wyświetla okno dialogowe
Zapisywanie pliku
(lub
Otwieranie pliku) aplikacji, musi ono domyślnie wskazywać folder Moje dokumenty użytkownika (lub podfolder folderu Moje dokumenty, na przykład Moje obrazy dla obrazów lub Moja muzyka dla plików audio).


UWAGA: Nigdy nie należy trwale kodować ścieżki w aplikacji, ponieważ nigdy nie można zagwarantować jej fizycznej lokalizacji. Administrator może na przykład zmienić lokalizację folderu Moje dokumenty na lokalizację sieciową.
  1. Na początku pliku SavingData.cpp dodaj następujące instrukcje include:
    #include <commdlg.h>   // dla funkcji GetSaveFileName
    #include <shlobj.h> // dla funkcji SHGetFolderPath
  2. Dodaj następujący prototyp dla funkcji
    OnFileSaveAs:
    void OnFileSaveAs();
  3. Utwórz nową funkcję
    OnFileSaveAs. W tej funkcji użyj funkcji
    SHGetFolderPath
    w połączeniu z identyfikatorem
    CSIDL
    CSIDL_MYPICTURES
    w celu pobrania właściwej lokalizacji folderu do przechowywania obrazów. Przekaż tę lokalizację folderu do funkcji
    GetSaveFileName, aby wyświetlić standardowe okno dialogowe
    Zapisywanie pliku.


    Kod powinien wyglądać następująco:
    void OnFileSaveAs()
    {
    OPENFILENAME openFile;
    TCHAR szPath[MAX_PATH];

    // Zainicjuj strukturę OPENFILENAME.
    ZeroMemory( &openFile, sizeof(OPENFILENAME) );
    openFile.lStructSize = sizeof(OPENFILENAME);
    // Ustaw domyślnie na folder Moje obrazy. Najpierw pobierz ścieżkę.
    if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_MYPICTURES,
    NULL, 0, szPath ) ) )
    {
    // Ustaw element lpstrInitialDir na ścieżkę pobieraną przez funkcję SHGetFolderPath.
    // Powoduje to, że funkcja GetSaveFileName wskazuje folder Moje obrazy.
    openFile.lpstrInitialDir = szPath;
    }
    // Wyświetl standardowe okno dialogowe Zapisywanie pliku ustawione domyślnie na folder Moje obrazy.
    if ( GetSaveFileName( &openFile ) == TRUE )
    {
    // Użytkownik klika przycisk Zapisz.
    // Zapisz plik
    }
    else
    {
    // Użytkownik anuluje okno dialogowe Zapisywanie pliku.
    }
    }

Sprawdzenie poprawności lokalizacji zapisywanych plików

  1. Naciśnij klawisz F5, aby skompilować projekt.
  2. Uruchom aplikację i kliknij polecenie Zapisz jako w menu Plik.
  3. Sprawdź, czy standardowe okno dialogowe
    Zapisywanie pliku
    jest domyślnie ustawione na folder Moje obrazy, jak to określa identyfikator
    CSIDL_MYPICTURES.
  4. Kliknij przycisk
    Anuluj, aby zamknąć okno dialogowe, i zamknij aplikację.

Zapamiętanie poprzedniego wyboru użytkownika

W przypadku następnego użycia okna dialogowego
Zapisywanie pliku
(lub
Otwieranie pliku) zaleca się, aby domyślnie wskazywało ono lokalizację poprzednio wybraną przez użytkownika.


Jeśli nie podasz początkowej lokalizacji folderu w strukturze
OPENFILENAME,
funkcja GetSaveFileName
(i
GetOpenFileName) wyświetla standardowe okno dialogowe
Zapisywanie pliku
lub
Otwieranie pliku, które wskazuje folder Moje dokumenty. Ponadto, jeśli użytkownik używał uprzednio jednego z tych okien dialogowych i wybrał inny folder niż domyślny, te funkcje automatycznie wskazują uprzednio używany folder.


Aby obsłużyć zalecaną praktykę ustawiania określonej lokalizacji folderu (na przykład Moje obrazy), gdy użytkownik po raz pierwszy zapisuje lub ładuje plik, a następnie domyślnego ustawiania uprzednio wybranej przez użytkownika lokalizacji, należy użyć zmiennej logicznej do stwierdzenia, czy dana operacja zapisu lub otwarcia pliku jest pierwszą tego typu operacją.
  1. Utwórz zmienną typu
    static BOOL
    o nazwie
    bFirstSave
    w funkcji
    OnFileSaveAs
    i ustaw jej początkową wartość na
    TRUE.
  2. Zmodyfikuj kod w funkcji
    OnFileSaveAs, tak aby wywoływać funkcję
    SHGetFolderPath
    i ustawiać element
    lpstrInitialDir
    struktury
    OPENFILENAME
    tylko w wypadku, gdy wartością zmiennej
    bFirstSave
    jest
    TRUE.
  3. Jeśli użytkownik kliknie przycisk
    Zapisz
    w oknie dialogowym
    Zapisywanie pliku, ustaw zmienną
    bFirstSave
    na wartość
    FALSE.


    Kod powinien wyglądać następująco:
    void OnFileSaveAs()
    {
    OPENFILENAME openFile;
    TCHAR szPath[MAX_PATH];
    static BOOL bFirstSave = TRUE;

    // Zainicjuj strukturę OPENFILENAME.
    ZeroMemory( &openFile, sizeof(OPENFILENAME) );
    openFile.lStructSize = sizeof(OPENFILENAME);
    // Jeśli użytkownik po raz pierwszy zapisuje dokument, ustaw domyślnie na folder Moje obrazy.
    if ( TRUE == bFirstSave )
    {
    if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_MYPICTURES,
    NULL, 0, szPath ) ) )
    {
    // Ustaw element lpstrInitialDir na ścieżkę pobieraną przez funkcję SHGetFolderPath.
    // Powoduje to, że funkcja GetSaveFileName wskazuje folder Moje obrazy.
    openFile.lpstrInitialDir = szPath;
    }
    }
    // Wyświetl standardowe okno dialogowe Zapisywanie pliku ustawione domyślnie na folder Moje obrazy
    // lub na lokalizację poprzednio wybraną przez użytkownika.
    if ( GetSaveFileName( &openFile ) == TRUE )
    {
    // Użytkownik klika przycisk Zapisz.
    // Zapisz plik.
    bFirstSave = FALSE;
    }
    else
    {
    // Użytkownik anuluje okno dialogowe Zapisywanie pliku.
    }
    }

Sprawdzenie poprzedniego wyboru użytkownika

  1. Skompiluj projekt i uruchom aplikację.
  2. W menu Plik kliknij polecenie Zapisz jako.
  3. Przejdź z folderu Moje obrazy do folderu Moje dokumenty, zaznacz plik i kliknij przycisk
    Zapisz.
  4. W menu Plik kliknij polecenie Zapisz jako.
  5. Sprawdź, czy okno dialogowe wskazuje domyślnie poprzedni wybór (w tym wypadku folder Moje dokumenty).
  6. Kliknij przycisk
    Anuluj, aby zamknąć okno dialogowe, i zamknij aplikację.
  7. Uruchom aplikację i kliknij polecenie Zapisz jako w menu Plik.
  8. Sprawdź, czy okno dialogowe ponownie wskazuje folder Moje obrazy.
  9. Zamknij okno dialogowe i aplikację.

Klasyfikowanie danych aplikacji

W folderze Moje dokumenty nie należy przechowywać danych właściwych dla aplikacji (takich jak pliki tymczasowe, preferencje użytkownika, pliki konfiguracji aplikacji itp.). Zamiast niego należy użyć albo odpowiedniej lokalizacji w Rejestrze systemu Windows (dla danych o rozmiarze nie przekraczającym 64 kilobajtów) albo właściwego dla aplikacji pliku przechowywanego w prawidłowym folderze Dane aplikacji.


Istotne znaczenie ma przechowywanie danych aplikacji we właściwej lokalizacji, tak aby kilku użytkowników korzystających z tego samego komputera nie uszkadzało i nie zastępowało wzajemnie swoich danych i ustawień.


Aby określić najodpowiedniejszą lokalizację dla danych aplikacji, użyj następujących kategorii do sklasyfikowania danych:
  • Dla każdego użytkownika (dane mobilne): Ta kategoria opisuje dane aplikacji, które są właściwe dla określonego użytkownika i powinny być dostępne dla tego użytkownika, gdy przechodzi on między komputerami w domenie (na przykład niestandardowy słownik). Zauważ, że to ustawienie nie dotyczy aplikacji, które są nie są przeznaczone do uruchamiania w środowisku domeny.
  • Dla każdego użytkownika (dane niemobilne): Ta kategoria opisuje dane aplikacji, które są właściwe dla określonego użytkownika, ale dotyczą tylko jednego komputera (na przykład określona przez użytkownika rozdzielczość ekranu).
  • Dla każdego komputera (dane, które nie są właściwe dla użytkownika ani mobilne): Ta kategoria opisuje dane aplikacji, które dotyczą wszystkich użytkowników i określonego komputera (na przykład słownik aplikacji, plik dziennika lub plik tymczasowy).

Przechowywanie danych aplikacji we właściwej lokalizacji

Funkcja
SHGetFolderPath
umożliwia pobranie właściwego folderu danych aplikacji. Nie przechowuj danych aplikacji bezpośrednio w tym folderze. Zamiast tego użyj funkcji
PathAppend, aby dołączyć podfolder do ścieżki zwróconej przez funkcję
SHGetFolderPath. Upewnij się, że stosujesz następującą konwencję:
Nazwa firmy\Nazwa produktu\Wersja produktu
Wynikowa pełna ścieżka mogłaby wyglądać następująco:
\Documents and Settings\Wszyscy użytkownicy\Dane aplikacji\Moja firma\Mój produkt\1.0
Aby zlokalizować właściwy folder danych aplikacji, przekaz odpowiednią wartość
CSIDL
na podstawie kategorii danych aplikacji.
  • Dla danych każdego użytkownika (mobilnych) użyj wartości
    CSIDL_APPDATA. Daje to następującą ścieżkę domyślną:
    \Documents and Settings\<Nazwa użytkownika>\Dane aplikacji
  • Dla danych każdego użytkownika (niemobilnych) użyj wartości
    CSIDL_LOCAL_APPDATA. Daje to następującą ścieżkę domyślną:
    \Documents and Settings\<Nazwa użytkownika>\Ustawienia lokalne\Dane aplikacji
  • Dla danych każdego komputera (które nie są właściwe dla użytkownika ani mobilne) użyj wartości
    CSIDL_COMMON_APPDATA. Daje to następującą ścieżkę domyślną:
    \Documents and Settings\Wszyscy użytkownicy\Dane aplikacji
Następujący fragment kodu pokazuje, jak otworzyć tymczasowy plik dziennika, który znajduje się w folderze określonym przez wartość
CSIDL_COMMON_APPDATA:
void CreateTemporaryFile()
{
TCHAR szPath[MAX_PATH];
// Pobierz ścieżkę dla każdego komputera (dane, które nie są właściwe dla użytkownika ani mobilne).
if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_COMMON_APPDATA,
NULL, 0, szPath ) ) )
{
TCHAR szTempFileName[MAX_PATH];
// Dołącz ścieżkę właściwą dla produktu.
PathAppend( szPath, "\\Moja ścieżka\\Mój produkt\\1.0\\" );
// Wygeneruj nazwę pliku tymczasowego w tym folderze.
if (GetTempFileName( szPath,
"PRE",
0,
szTempFileName ) != 0 )
{
HANDLE hFile = NULL;
// Otwórz plik.
if (( hFile = CreateFile( szTempFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL )) != INVALID_HANDLE_VALUE )
{
// Zapisz dane tymczasowe (kod pominięto).
CloseHandle( hFile );
}
}
}
}

Rozsądne korzystanie z Rejestru

OSTRZEŻENIE: Nieprawidłowe wykorzystanie Edytora Rejestru może być przyczyną poważnych problemów, które spowodują, że konieczna może być ponowna instalacja systemu operacyjnego. Firma Microsoft nie może zagwarantować, że możliwe będzie rozwiązanie problemów spowodowanych niepoprawnym użyciem Edytora Rejestru. Możesz używać Edytora Rejestru na własną odpowiedzialność.

Informacje o edytowaniu Rejestru można znaleźć w temacie „Zmienianie kluczy i wartości” w Pomocy Edytora Rejestru (Regedit.exe) lub w tematach „Dodawanie i usuwanie informacji w Rejestrze” i „Edytowanie danych Rejestru” w Pomocy programu Regedt32.exe. Należy pamiętać o wykonaniu kopii zapasowej Rejestru przed jego edycją. Używając systemu Windows NT lub Windows 2000, należy również zaktualizować Awaryjny dysk naprawczy.

Rejestru można używać do przechowywania małych ilości danych aplikacji. W przypadku danych, których rozmiar przekracza 64 kilobajty (KB), trzeba użyć folderu danych aplikacji. Używając Rejestru do przechowywania danych aplikacji, należy przestrzegać następujących wskazówek:
  • W przypadku małych ilości danych użytkownika używaj klucza Rejestru
    HKEY_CURRENT_USER
    (HKCU).
  • W przypadku małych ilości danych komputera używaj klucza Rejestru
    HKEY_LOCAL_MACHINE
    (HKLM). Aplikacja nie powinna zapisywać danych do drzewa
    HKLM
    w czasie wykonania, ponieważ domyślnie użytkownicy, którzy nie są administratorami, mają jedynie dostęp tylko do odczytu do drzewa
    HKLM.
  • W czasie instalacji aplikacja nie może zapisać łącznie więcej niż 128 KB danych w drzewach
    HKCU
    i
    HKLM.
  • Składniki COM (Component Object Model) są rejestrowane w kluczu Rejestru
    HKEY_CLASSES_ROOT
    (HKCR). Limit 128 KB nie obejmuje drzewa
    HKCR.
  • Zapisując dane do drzewa
    HKLM
    lub
    HKCU, trzeba utworzyć klucze dla nazwy firmy, nazwy produktu i numeru wersji produktu, jak następuje:
    HKLM\Software\Nazwa firmy\Nazwa produktu\Wersja produktu

    HKCU\Software\Nazwa firmy\Nazwa produktu\Wersja produktu
  • Do odczytywania i zapisywania wpisów Rejestru używaj funkcji Rejestru (takich jak
    RegCreateKeyEx
    i
    RegSetValueEx).

Rozwiązywanie problemów

  • Aby pomóc zapewnić, że aplikacje będą działały również w starszych wersjach systemu Windows niż Windows XP, zawsze konsoliduj je z implementacją funkcji
    SHGetFolderPath
    z biblioteki Shfolder.dll. Chociaż system Windows XP obejmuje funkcję
    SHGetFolderPath
    w bibliotece Shell32.dll, starsze wersje systemu Windows mogą nie obsługiwać funkcji z tej biblioteki DLL.
  • Biblioteka Shfolder.dll jest składnikiem, który można rozpowszechniać z własnymi aplikacjami.
  • Nie przechowuj pełnych ścieżek do folderu Moje dokumenty (lub innych folderów systemowych) w miejscu właściwym dla aplikacji, takim jak lista niedawno używanych plików, ponieważ użytkownik lub administrator może zmieniać lokalizacje tych folderów między różnymi instalacjami aplikacji.

Materiały referencyjne

Aby uzyskać więcej informacji o pełnym zestawie folderów, które identyfikuje funkcja
SHGetFolderPath, zobacz następującą dokumentację zestawu Microsoft Platform Software Development Kit (SDK):
Aby uzyskać więcej informacji dotyczących ogólnego programowania powłoki, odwiedź następującą witrynę MSDN w sieci Web:
Aby uzyskać więcej ogólnych informacji o programie Visual C++ .NET, zobacz następującą grupę dyskusyjną Usenet:
Odwiedź Centrum pomocy programu Visual C++ .NET w następującej witrynie firmy Microsoft w sieci Web:
Centrum pomocy programu Visual C++ .NET (2002)

http://support.microsoft.com/default.aspx?xmlid=fh%3BEN-US%3Bvcnet
Właściwości

Identyfikator artykułu: 310294 — ostatni przegląd: 11.06.2002 — zmiana: 1

Opinia