Artigo: 310294 - Última revisão: quinta-feira, 20 de Março de 2008 - Revisão: 3.1

Como escrever uma aplicação do Windows XP que armazena dados utilizador e a aplicação na localização correcta, utilizando o Visual C++

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
importante Este artigo contém informações sobre como modificar o registo. Certifique-se uma que a cópia de segurança do registo antes de o modificar. Certifique-se que sabe como restaurar o registo se ocorrer um problema. Para obter mais informações sobre como efectuar uma cópia de segurança, restaurar e modificar o registo, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
322756  (http://support.microsoft.com/kb/322756/ ) Como efectuar uma cópia de segurança e restaurar o registo no Windows
Nota Microsoft Visual C++ .NET 2002, Microsoft Visual C++ .NET 2003, Microsoft Visual C++ 2005 e Microsoft Visual C++ 2008 suportam o modelo de código gerido que é fornecido pelo Microsoft .NET Framework e o modelo de código do Microsoft Windows nativo não gerido. As informações contidas neste artigo aplicam-se apenas ao código de Visual C++ não gerido

Nesta página

Expandir tudo | Reduzir tudo

Sumário

Aplicações funcionam com dois tipos de documentos: aqueles que o utilizador cria e aqueles que cria a aplicação. As aplicações devem utilizar a função de shell SHGetFolderPath para obter localizações da pasta válida para armazenar dados que são específicos para o utilizador e a aplicação. Isto é essencial para aplicações do Windows XP para suportar vários utilizadores, que estiverem a utilizar o mesmo computador e para permitir aos utilizadores mudar rapidamente.

Este artigo descreve como armazenar dados de utilizador no local correcto nos passos seguintes:
  • Crie uma aplicação de Win32.
  • Adicione uma opção de Guardar como ao menu ' ficheiro '.
  • Utilize a padrão Guardar ficheiro caixa de diálogo para a predefinição para a localização correcta.
  • Verifique se o ficheiro correcto localização para guardar.
  • Lembre-se selecção anterior o utilizador.
  • Verifique se selecção anterior o utilizador.
Nos passos seguintes, este artigo também descreve onde tem de armazenar dados da aplicação e como garantir que é armazenado em localizações adequadas:
  • Classificar os dados da aplicação.
  • Armazenar dados de aplicação na localização correcta.
  • Utilize o registo cuidadosamente.

Requisitos

A lista seguinte descreve o hardware recomendado, software, infra-estrutura de rede, competências, conhecimentos e service packs que necessita:
  • Windows XP Home Edition ou Windows XP Professional
  • O Visual Studio 2008, Visual Sudio 2005 e Visual Studio .NET.
  • Conhecimento prévio da programação de aplicações do Win32

Criar uma aplicação de Win32

Inicie o Visual Studio e criar uma nova aplicação de Win32 denominada SavingData.
  • No Visual Studio. NET, clique em Projectos do Visual C++ em Project Types e, em seguida, clique em Win32 projecto em modelos . Aceite as predefinições do aplicação que apresenta o Assistente de configuração de aplicação.
  • No Visual Studio 2005 ou 2008, clique em Visual C++ em Project Types e, em seguida, clique em Win32 projecto em modelos . Aceite as predefinições de aplicação.

Adicionar um guardar como opção de menu ' ficheiro '

  1. Clique em Vista de recursos e, em seguida, faça duplo clique em IDC_SAVINGDATA .
  2. Adicione uma opção de menu Guardar como ao menu ' ficheiro '. Utilize IDM_FILE_SAVEAS como o ID do item de menu.
  3. Localize WndProc janela procedimento a aplicação dentro SavingData.cppm e adicionar um novo extrato caso na secção WM_COMMAND para processar a opção de menu Guardar como . Chame a função OnFileSaveAs , que vai criar na secção seguinte. Esta função tem sem parâmetros.

    O código deverá aparecer da seguinte forma:
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        case IDM_FILE_SAVEAS:
            OnFileSaveAs(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    

Utilize a padrão guardar ficheiro caixa de diálogo para a predefinição para a localização correcta

Quando um utilizador apresenta Guardar ficheiro ( Abrir ) caixa de diálogo ou uma aplicação pela primeira vez, a caixa de diálogo tem predefinido para a pasta Os meus documentos do utilizador (ou um descendente dos meus documentos, tais como as minhas imagens para dados de imagem e a minha música para ficheiros de áudio).

Nota : É tem código nunca permanentemente um caminho na aplicação uma vez que nunca pode garantir a respectiva localização física. Por exemplo, um administrador poderá coloque a pasta Os meus documentos para uma localização de rede.
  1. Na parte superior do SavingData.cpp, adicione o seguinte incluir instruções:
    #include <commdlg.h>   // for GetSaveFileName
    #include <shlobj.h>    // for SHGetFolderPath
    					
  2. Adicione o seguinte protótipo para a função OnFileSaveAs :
    void OnFileSaveAs( HWND hWnd );
    					
  3. Crie a nova função OnFileSaveAs . Dentro desta função, utilize a função SHGetFolderPath em conjunto com o identificador CSIDL CSIDL_MYPICTURES para obter a localização correcta para armazenar dados de imagem. Passar esta localização da pasta para a função GetSaveFileName para apresentar o padrão Guardar ficheiro caixa de diálogo.

    O código deverá aparecer da seguinte forma:
    void OnFileSaveAs(HWND hWnd)
    {
       OPENFILENAME openFile;
       TCHAR szPath[MAX_PATH];
       TCHAR szFile[MAX_PATH];
    
        // Initialize OPENFILENAME structure.
        ZeroMemory( &openFile, sizeof(OPENFILENAME) );
        openFile.lStructSize = sizeof(OPENFILENAME);
    
        szFile[0] = '\0';
        openFile.hwndOwner = hWnd;
        openFile.lpstrFile = szFile;
        openFile.nMaxFile = sizeof(szFile)/sizeof(*szFile);
    
        // Default to My Pictures. First, get its path.
        if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_MYPICTURES, 
                                              NULL, 0, szPath ) ) )
        {
           // Set lpstrInitialDir to the path that SHGetFolderPath obtains. 
           // This causes GetSaveFileName to point to the My Pictures folder.
              openFile.lpstrInitialDir = szPath;
        }
        // Display the standard File Save dialog box, defaulting to My Pictures.
        if ( GetSaveFileName( &openFile ) == TRUE )
        {
            // User clicks the Save button.
            // Save the file
        }
        else
        {
           // User cancels the File Save dialog box.
        }
    }
    

Verifique se o ficheiro correcto Guardar localização

  1. Prima a tecla F5 para criar o projecto.
  2. Execute a aplicação e clique em Guardar como no menu ' ficheiro '.
  3. Certifique-se que a caixa de diálogo Guardar ficheiro padrão predefinições para a pasta as minhas imagens, como CSIDL_MYPICTURES .
  4. Clique em ' Cancelar ' para fechar a caixa de diálogo e feche a aplicação.

Lembre-se selecção anterior o utilizador

Para utilização subsequente da caixa de diálogo Guardar ficheiro (ou Abrir ficheiro ), recomenda-se que a predefinição de caixa de diálogo para o utilizador seleccionou localização.

Se não fornecer uma localização de pasta inicial na estrutura OPENFILENAME , GetSaveFileName (e GetOpenFileName ) apresentam o padrão Ficheiro guardar ou Abrir caixa de diálogo, que aponta para a pasta Os meus documentos. Além disso, se o utilizador utilizou destas caixas de diálogo anteriormente e tiver seleccionado uma pasta não predefinida, estas funções automaticamente a predefinição para a pasta utilizada anteriormente.

Para suportar o procedimento recomendado recomendado de apontar para uma localização de pasta específica (tal como as minhas imagens) pela primeira vez um utilizador guarde ou carrega um ficheiro, e por subsequentemente predefinição da localização do utilizador previamente seleccionado, deverá utilizar uma variável booleana para controlar se esta é a primeira vez que o utilizador executou a operação de abrir ou guardar.
  1. Criar uma variável estática BOOL denominada bFirstSave na função OnFileSaveAs e inicializar para TRUE .
  2. Modifique o código de OnFileSaveAs chamar SHGetFolderPath e definir o membro lpstrInitialDir da estrutura OPENFILENAME , apenas se bFirstSave for Verdadeiro .
  3. Se o utilizador clica em Guardar na caixa de diálogo Guardar ficheiro , defina bFirstSave como FALSE .

    O código deverá aparecer da seguinte forma:
    void OnFileSaveAs(HWND hWnd)
    {
        OPENFILENAME openFile;
        TCHAR szPath[MAX_PATH];
        TCHAR szFile[MAX_PATH];
        static BOOL bFirstSave = TRUE;
    
        // Initialize OPENFILENAME structure.
        ZeroMemory( &openFile, sizeof(OPENFILENAME) );
        openFile.lStructSize = sizeof(OPENFILENAME);
    
        szFile[0] = '\0';
        openFile.hwndOwner = hWnd;
        openFile.lpstrFile = szFile;
        openFile.nMaxFile = sizeof(szFile)/sizeof(*szFile);
    
        // The first time the user saves a document, default to My Pictures.
        if ( TRUE == bFirstSave )
        {
            if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_MYPICTURES, 
                NULL, 0, szPath ) ) )
            {
                // Set lpstrInitialDir to the path that SHGetFolderPath obtains.
                // This causes GetSaveFileName to point to the My Pictures folder.
                openFile.lpstrInitialDir = szPath;
            }
        }
        // Display standard File Save dialog box, defaulting to My Pictures
        // or the user's previously selected location.
        if ( GetSaveFileName( &openFile ) == TRUE )
        {
            // User clicks Save.
            // Save the file.
            bFirstSave = FALSE;
        }
        else
        {
            // User cancels the File Save dialog box.
        }
    }
    

Verifique se selecção anterior o utilizador

  1. Criar o projecto e execute a aplicação.
  2. No menu ficheiro , clique em Guardar como .
  3. Navegue da pasta as minhas imagens para os meus documentos pasta, seleccione um ficheiro e clique em Guardar .
  4. A partir do ficheiro menu, clique em Guardar como novo.
  5. Certifique-se que a caixa de diálogo assume a sua selecção anterior (neste caso, os meus documentos).
  6. Clique em ' Cancelar ' para fechar a caixa de diálogo e feche a aplicação.
  7. Execute a aplicação e clique em Guardar como no menu ' ficheiro '.
  8. Certifique-se que a caixa de diálogo predefinições para as minhas imagens pasta.
  9. Feche a caixa de diálogo e sair da aplicação.

Classificar dados da aplicação

Não deve armazenar dados específicos da aplicação (tais como ficheiros temporários, as preferências do utilizador, ficheiros de configuração da aplicação e assim sucessivamente) na pasta Os meus documentos. Em vez disso, utilize uma localização adequada no registo do Windows (para dados que não excede os 64 kilobytes) ou um ficheiro específico da aplicação que está localizado um Application Data válida pasta.

É importante para armazenar dados de aplicação a localização correcta para permitir que várias pessoas a utilizar o mesmo computador sem danificar ou substituir dados e definições de cada um deles.

Para determinar a localização mais adequada para os dados da aplicação, utilize as seguintes categorias para classificar os dados:
  • para cada utilizador (roaming) : esta categoria descreve dados de aplicação é específica para um determinado utilizador e devem estar disponíveis ao utilizador como ele ou ela move-se entre computadores num domínio (por exemplo, um dicionário personalizado). Tenha em atenção que esta definição não se aplica a aplicações que não são concebidas para ser executada num ambiente de domínio.
  • para cada utilizador (não itinerantes) : esta categoria descreve dados de aplicação que é específico de um determinado utilizador, mas só se aplica a um único computador (por exemplo, uma resolução de monitor especificado pelo utilizador).
  • para cada computador (específicas do utilizador não e não guardado no servidor) : esta categoria descreve dados da aplicação que aplica-se a todos os utilizadores e a um computador específico (por exemplo, um dicionário de aplicação, um ficheiro de registo ou um ficheiro temporário).

Armazenar dados da aplicação na localização correcta

Utilizar a função SHGetFolderPath para obter a pasta Application Data correcta. Não armazene dados da aplicação directamente existentes nesta pasta. Em vez disso, utilize a função PathAppend para acrescentar uma subpasta para o caminho que SHGetFolderPath devolve. Certifique-se que utiliza a seguinte convenção:
Empresa Name\Product Name\Product versão
Por exemplo, o caminho completo resultante pode aparecer da seguinte forma:
\Documents and Settings\All Users\Application Data\My Company\My Product\1.0
Para localizar a pasta Application Data correcta, passar o valor CSIDL adequado, com base na categoria dos dados da aplicação.
  • Para cada utilizador de dados (roaming), utilizar o valor CSIDL_APPDATA . Isto assume o seguinte caminho:
    \Documents and Settings\ < nome de utilizador > \Application Data
  • Para cada utilizador dados (não itinerantes), utilize o valor CSIDL_LOCAL_APPDATA . Isto assume o seguinte caminho:
    \Documents and Settings\ < nome de utilizador > \Local Settings\Application dados
  • Cada computador (específicas do utilizador não e não guardado no servidor) de dados, utilize o valor CSIDL_COMMON_APPDATA . Isto assume o seguinte caminho:
    \Documents and Settings\All Users\Application dados
O seguinte fragmento de código demonstra como abrir um ficheiro temporário de registo, que se encontra abaixo CSIDL_COMMON_APPDATA :
include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")
void CreateTemporaryFile()
{
   TCHAR szPath[MAX_PATH];
   // Get path for each computer, non-user specific and non-roaming data.
   if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_COMMON_APPDATA, 
                                    NULL, 0, szPath ) ) )
   {
      TCHAR szTempFileName[MAX_PATH];
      // Append product-specific path - this path needs to already exist
      // for GetTempFileName to succeed.
      PathAppend( szPath, _T("\\My Company\\My Product\\1.0\\") );
      // Generate a temporary file name within this folder.
      if (GetTempFileName( szPath, 
                           _T("PRE"),
                           0,
                           szTempFileName ) != 0 )
      {
         HANDLE hFile = NULL;
         // Open the file.
         if (( hFile = CreateFile( szTempFileName, 
                                   GENERIC_WRITE, 
                                   0, 
                                   NULL, 
                                   CREATE_ALWAYS, 
                                   FILE_ATTRIBUTE_NORMAL, 
                                   NULL )) != INVALID_HANDLE_VALUE )
         {
            // Write temporary data (code omitted).
            CloseHandle( hFile );
         }
      }
      else
          DWORD err = GetLastError();
   }
}

Utilizar o registo cuidadosamente

importante Esta secção, método ou tarefa contém passos que indicam como modificar o registo. No entanto, poderão ocorrer problemas graves se modificar o registo de forma incorrecta. Por conseguinte, certifique-se de que segue estes passos cuidadosamente. Criar uma para protecção adicional, cópia de segurança do registo antes de o modificar. Em seguida, pode restaurar o registo se ocorrer um problema. Para obter mais informações sobre como efectuar uma cópia de segurança e restaurar o registo, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
322756  (http://support.microsoft.com/kb/322756/ ) Como efectuar uma cópia de segurança e restaurar o registo no Windows

Também pode utilizar o registo para armazenar pequenas quantidades de dados da aplicação. Para dados que excede os 64 kilobytes (KB), tem de utilizar uma pasta de dados da aplicação. Observe as seguintes directrizes quando utiliza o registo para armazenar dados da aplicação:
  • Para pequenas quantidades de dados do utilizador, utilize a chave de registo HKEY_CURRENT_USER ( HKCU ).
  • Para pequenas quantidades de dados do computador, utilize a chave de registo HKEY_LOCAL_MACHINE ( HKLM ). A aplicação deverá não escrever HKLM em tempo de execução porque, por predefinição, os utilizadores não administradores só têm acesso só de leitura à árvore de HKLM .
  • Durante a instalação, a aplicação tem não armazenar mais de um total de 128 KB em HKCU e HKLM .
  • Componente componentes de Object Model (COM) são registados sob a chave de registo HKEY_CLASSES_ROOT ( HKCR ). O máximo de 128 KB não inclui HKCR .
  • Quando escreve HKLM ou HKCU , tem de criar chaves para o nome da empresa, nome do produto e produto de versão, da seguinte forma:
    HKLM\Software\Company Name\Product Name\Product versão
    HKCU\Software\Company Name\Product Name\Product versão
  • Utilize as funções registo (como, por exemplo, RegSetValueEx e RegCreateKeyEx ) para ler e escrever entradas de registo.

Resolução de problemas

  • Para ajudar a garantir que as aplicações é executada em versões anteriores do Windows juntamente com o Windows XP, ligar sempre a implementação de SHGetFolderPath no shfolder.dll. Apesar do Windows XP inclui SHGetFolderPath no ficheiro Shell32.dll, versões anteriores do Windows poderão não suportar a função dentro desta biblioteca de ligação dinâmica (DLL).
  • Shfolder.dll é um componente redistribuível e pode ser distribuído com as aplicações.
  • Não armazenar caminhos totalmente qualificados para os meus documentos pasta (ou outras pastas de sistema) dentro de um local específico da aplicação como uma lista de ficheiro de mais ficheiros utilizados recentemente uma vez que um utilizador ou administrador poderá reposicionar estas pastas entre sucessivas utilizações da aplicação.

Referências

Para outros superior-acerto Visual C++ .NET da base de dados de conhecimento da Microsoft artigos, visite o Centro de suporte .NET no seguinte Web site da Microsoft do Visual C++:
Centro de suporte do Visual C++ .NET (2002)
http://support.microsoft.com/default.aspx?xmlid=fh%3BEN-US%3Bvcnet (http://support.microsoft.com/default.aspx?xmlid=fh%3ben-us%3bvcnet)
Para mais informações gerais sobre Visual C++. NET, visite o newsgroup Microsoft Usenet seguinte:
Microsoft.public.dotnet.languages.vc (http://msdn.microsoft.com/newsgroups/default.aspx?query=Microsoft.public.dotnet.languages.vc&dg=&cat=en-us-msdn&lang=en&cr=US&pt=&catlist=774F24A2-F71F-425F-AC2B-DC48AB0DA5C9&dglist=&ptlist=&exp=&sloc=en-us)
Para mais informações sobre o conjunto completo das pastas que possa identificar SHGetFolderPath , consulte o software de plataforma Microsoft seguinte documentação Development Kit (SDK):
CSIDL
http://msdn.microsoft.com/en-us/library/bb762494.aspx (http://msdn.microsoft.com/en-us/library/bb762494.aspx)
Para obter mais informações sobre a shell de programação em geral, consulte o seguinte Web site da Microsoft Developer Network (MSDN):
Guia de programadores da shell
http://msdn2.microsoft.com/en-us/library/bb776778.aspx (http://msdn2.microsoft.com/en-us/library/bb776778.aspx)

A informação contida neste artigo aplica-se a:
  • Microsoft Visual C++ 2008 Express Edition
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition nas seguintes plataformas
    • the operating system: Microsoft Windows XP
  • Microsoft Visual C++ .NET 2002 Standard Edition nas seguintes plataformas
    • the operating system: Microsoft Windows XP
Palavras-chave: 
kbmt kbhowtomaster kbnewsgrouplink KB310294 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 310294  (http://support.microsoft.com/kb/310294/en-us/ )