Visual C++ 2005 または Visual C++ .NET を使用して、ユーザーとアプリケーションのデータを適切な場所に格納する Windows XP アプリケーションを記述する方法

文書翻訳 文書翻訳
文書番号: 310294 - 対象製品
この記事は、以前は次の ID で公開されていました: JP310294
重要 : この資料には、レジストリの編集方法が記載されています。万一に備えて、編集の前には必ずレジストリをバックアップし、レジストリの復元方法を理解しておいてください。バックアップ、復元、および編集方法の詳細を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
256986 Microsoft Windows レジストリの説明
: Microsoft Visual C++ 2005、Microsoft Visual C++ .NET 2003 および Microsoft Visual C++ .NET 2002 では、.NET Framework によって提供されるマネージ コード モデルとアンマネージ ネイティブ Windows コード モデルの両方がサポートされますが、この資料の情報は、アンマネージ Visual C++ コードにのみ適用されます。
すべて展開する | すべて折りたたむ

目次

概要

アプリケーションが機能するときには、ユーザーが作成したドキュメントとアプリケーションが作成したドキュメントの 2 種類のドキュメントを使用します。アプリケーションは SHGetFolderPath シェル関数を使用して、ユーザーとアプリケーション固有のデータを格納するのに有効なフォルダの場所を取得する必要があります。Windows XP アプリケーションでは、同じコンピュータを使用する複数のユーザーをサポートし、ユーザー間をすばやく切り替えることができるため、この作業は必須です。

この資料では、ユーザー データを適切な場所に格納する方法を以下の手順で説明しています。
  • Win32 アプリケーションを作成します。
  • [ファイル] メニューに [名前を付けて保存] オプションを追加します。
  • 標準の [上書き保存] ダイアログ ボックスを使用して適切な場所をデフォルトの場所にします。
  • 適切なファイルの保存場所を指定します。
  • ユーザーの前回の選択内容を記憶します。
  • ユーザーの前回の選択内容を確認します。
この資料では、アプリケーション データを格納する場所、およびそのデータが適切な場所に格納されたことを確認する方法についても、以下の手順で説明しています。
  • アプリケーション データを分類します。
  • アプリケーション データを適切な場所に格納します。
  • レジストリを適切に使用します。

必要条件

この資料の手順に必要な、推奨するハードウェア、ソフトウェア、ネットワーク インフラストラクチャ、技術、知識、および Service Pack は次のとおりです。
  • Windows XP Home Edition または Windows XP Professional
  • Visual Studio 2005、Visual Studio .NET、または Visual Studio 6.0
  • Win32 アプリケーション開発に関する予備知識

Win32 アプリケーションを作成する

Visual Studio を起動して、SavingData という名前の新しい Win32 アプリケーションを作成します。
  • Visual C++ 6.0 では、使用可能なプロジェクトの種類の一覧から [Win32 Application] をクリックして、アプリケーションの設定ウィザードで [標準的な "Hello World" アプリケーション] をクリックします。
  • Visual Studio .NET では、[プロジェクトの種類] ボックスの一覧の [Visual C++ プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [Win32 プロジェクト] をクリックします。アプリケーションの設定ウィザードで表示されるアプリケーションのデフォルトの設定をそのまま使用します。
  • Visual Studio 2005 では、[プロジェクトの種類] ボックスの一覧の [Visual C++] をクリックし、[テンプレート] ボックスの一覧の [Win32 プロジェクト] をクリックします。アプリケーションのデフォルトの設定をそのまま使用します。

[名前を付けて保存] オプションを [ファイル] メニューに追加する

  1. [リソース ビュー] をクリックし、[Menu] フォルダにある [IDC_SAVINGDATA] をダブルクリックします。
  2. メニューの [名前を付けて保存] オプションを [ファイル] メニューに追加します。メニュー項目の ID として IDM_FILE_SAVEAS を使用します。
  3. SavingData.cpp の内部のアプリケーションの WndProc ウィンドウ プロシージャを探し、WM_COMMAND セクション内部に新しい case ステートメントを追加して、[名前を付けて保存] メニュー オプションを処理します。次のセクションで作成する OnFileSaveAs 関数を呼び出します。この関数はパラメータを受け取りません。

    コードは以下のようになります。
    case WM_COMMAND:
       wmId    = LOWORD(wParam); 
       wmEvent = HIWORD(wParam); 
       // Parse the menu selections.
       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;
    					

標準の [上書き保存] ダイアログ ボックスを使用して、適切な場所をデフォルトの場所にする

ユーザーがアプリケーションの [上書き保存] (または [ファイルを開く]) ダイアログ ボックスを初めて表示するときは、そのダイアログ ボックスで、ユーザーのマイ ドキュメント フォルダ (または、イメージ データ用のマイ ピクチャやオーディオ ファイル用のマイ ミュージックなどのマイ ドキュメントのサブフォルダ) がデフォルトの場所になっている必要があります。

: アプリケーションの物理的な場所は保証されないため、アプリケーション内部でパスをハードコードしないでください。たとえば、管理者がマイ ドキュメント フォルダをネットワーク上の場所に再配置することもあります。
  1. SavingData.cpp の先頭に、以下の include ステートメントを追加します。
    #include <commdlg.h>   // for GetSaveFileName
    #include <shlobj.h>    // for SHGetFolderPath
    					
  2. 次の OnFileSaveAs 関数のプロトタイプを追加します。
    void OnFileSaveAs();
    					
  3. 新しい OnFileSaveAs 関数を作成します。この関数の内部で、CSIDL_MYPICTURES という CSIDL 識別子と共に SHGetFolderPath 関数を使用すると、適切なフォルダの場所を取得して、画像データを格納します。このフォルダの場所を GetSaveFileName 関数に渡して、標準の [上書き保存] ダイアログ ボックスを表示します。

    コードは以下のようになります。
    void OnFileSaveAs()
    {
       OPENFILENAME openFile;
       TCHAR szPath[MAX_PATH];
    
    // Initialize OPENFILENAME structure.
    ZeroMemory( &openFile, sizeof(OPENFILENAME) );
    openFile.lStructSize = sizeof(OPENFILENAME);
    // 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.
    }
    }
    					

適切なファイルの保存場所を確認する

  1. F5 キーを押して、プロジェクトをビルドします。
  2. アプリケーションを実行して、[ファイル] メニューの [名前を付けて保存] をクリックします。
  3. CSIDL_MYPICTURES で指定されたとおりに、標準の [上書き保存] ダイアログ ボックスのデフォルトの場所がマイ ピクチャ フォルダになっていることを確認します。
  4. [キャンセル] をクリックして、ダイアログ ボックスを閉じ、アプリケーションを終了します。

ユーザーの前回の選択内容を記憶する

その後、[上書き保存] (または [ファイルを開く]) ダイアログ ボックスを使用する場合、そのダイアログ ボックスでは、ユーザーが前回選択した場所をデフォルトの場所にすることをお勧めします。

OPENFILENAME 構造体の内部で初期フォルダの場所を指定しないと、GetSaveFileName (および GetOpenFileName) は、マイ ドキュメント フォルダを指す、標準の [上書き保存] または [ファイルを開く] ダイアログ ボックスを表示します。さらに、ユーザーがそれ以前に、上記のダイアログ ボックスのいずれかを使用して、デフォルトではないフォルダを選択している場合、これらの関数は以前に使用したフォルダを自動的にデフォルトの場所にします。

ユーザーが最初にファイルの保存と読み込みを行うときに特定のフォルダの場所 (マイ ピクチャなど) を対象とする推奨事例をサポートし、その後ユーザーが選択した場所をデフォルトの場所にするには、ブール型の変数を使用します。この変数は、保存または開くという操作をユーザーが初めて実行したかどうかを監視します。
  1. OnFileSaveAs 関数に bFirstSave という名前のブール型の静的変数を作成し、その変数を TRUE に初期化します。
  2. OnFileSaveAs 内部のコードを変更して、bFirstSave が TRUE の場合のみ、SHGetFolderPath を呼び出し、OPENFILENAME 構造体の lpstrInitialDir メンバを設定します。
  3. ユーザーが [上書き保存] ダイアログ ボックスで [保存] をクリックした場合に、bFirstSave を FALSE に設定します。

    コードは以下のようになります。
    void OnFileSaveAs()
    {
       OPENFILENAME openFile;
       TCHAR szPath[MAX_PATH];
       static BOOL bFirstSave = TRUE;
    
    // Initialize OPENFILENAME structure.
    ZeroMemory( &openFile, sizeof(OPENFILENAME) );
    openFile.lStructSize = sizeof(OPENFILENAME);
    // 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.
    }
    }
    					

ユーザーの前回の選択内容を確認する

  1. プロジェクトをビルドして、アプリケーションを実行します。
  2. [ファイル] メニューの [名前を付けて保存] をクリックします。
  3. マイ ピクチャ フォルダからマイ ドキュメント フォルダを参照し、ファイルを選択して、[保存] をクリックします。
  4. 再度、[ファイル] メニューの [名前を付けて保存] をクリックします。
  5. ダイアログ ボックスで前回の選択内容がデフォルトになっていること (この場合、マイ ドキュメントを指すこと) を確認します。
  6. [キャンセル] をクリックしてダイアログ ボックスを閉じ、アプリケーションを終了します。
  7. アプリケーションを実行して、[ファイル] メニューの [名前を付けて保存] をクリックします。
  8. ダイアログ ボックスでマイ ピクチャ フォルダがデフォルトの場所に戻っていることを確認します。
  9. ダイアログ ボックスを閉じて、アプリケーションを終了します。

アプリケーション データを分類する

マイ ドキュメント フォルダにアプリケーション固有のデータ (一時ファイル、ユーザー設定ファイル、アプリケーション構成ファイルなど) を格納すべきではありません。代わりに、Windows レジストリの適切な場所 (64 KB を超えない場合)、または有効な Application Data フォルダに配置されるアプリケーション固有のファイルのいずれかを使用します。

互いのデータや設定を破損または上書きせずに、複数のユーザーが同じコンピュータを使用できるようにするためには、アプリケーション データを適切な場所に保存することが重要です。

アプリケーション データに最適な場所を判断するには、次のカテゴリを使用して、データを分類します。
  • ユーザーごとのデータ (移動する) : このカテゴリは、特定のユーザー固有のアプリケーション データを示し、ドメイン内のコンピュータ間で移動するユーザーから使用できます (ユーザー辞書など)。この設定は、ドメイン環境で実行するように設定されていないアプリケーションには適用されないことに注意してください。
  • ユーザーごとのデータ (移動しない) : このカテゴリは、特定のユーザー固有のアプリケーション データを示しますが、1 台のコンピュータのみに適用されます (ユーザー指定のモニタ解像度など)。
  • コンピュータごとのデータ (ユーザー固有ではなく、移動しない) : このカテゴリは、すべてのユーザーと特定のコンピュータに適用されるアプリケーション データを示しています (アプリケーション辞書、ログ ファイル、一時ファイルなど)。

アプリケーション データを適切な場所に格納する

SHGetFolderPath 関数を使用して、適切な Application Data フォルダを取得します。アプリケーション データをこのフォルダに直接格納しないでください。代わりに、PathAppend 関数を使用して、SHGetFolderPath が返すパスにサブフォルダを追加します。サブフォルダのパスには、次のような表記法を使用します。
Company Name\Product Name\Product Version
この結果、パスは次のようになります。
\Documents and Settings\All Users\Application Data\My Company\My Product\1.0
適切な Application Data フォルダを使用するには、アプリケーション データのカテゴリに基づいて、適切な CSIDL 値を渡します。
  • 「ユーザーごとのデータ (移動する)」のデータは、CSIDL_APPDATA 値を使用します。これは、デフォルトでは次のパスになります。
    \Documents and Settings\<User Name>\Application Data
  • 「ユーザーごとのデータ (移動なし)」のデータは、CSIDL_LOCAL_APPDATA 値を使用します。これは、デフォルトでは次のパスになります。
    \Documents and Settings\<User Name>\Local Settings\Application Data
  • 「コンピュータごとのデータ (ユーザー固有ではなく、移動しない)」のデータは、CSIDL_COMMON_APPDATA 値を使用します。これは、デフォルトでは次のパスになります。
    \Documents and Settings\All Users\Application Data
次のコードは、CSIDL_COMMON_APPDATA にある一時ログ ファイルを開く方法を示しています。
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.
      PathAppend( szPath, "\\My Company\\My Product\\1.0\\" );
      // Generate a temporary file name within this folder.
      if (GetTempFileName( szPath, 
                           "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 );
         }
      }
   }
}
				

レジストリを適切に使用する

警告 : レジストリ エディタの使い方を誤ると、深刻な問題が発生することがあります。最悪の場合、オペレーティング システムの再インストールが必要になることがあります。マイクロソフトは、レジストリ エディタの誤用により発生した問題に関しては、一切責任を負わないものとします。レジストリ エディタは、自己の責任においてご使用ください。

レジストリを使用して、少量のアプリケーション データを格納することもできます。データが 64 KB を超える場合は、Application Data フォルダを使用する必要があります。レジストリを使用してアプリケーション データを格納する場合、次のガイドラインに従います。
  • 少量のユーザー データの場合は、HKEY_CURRENT_USER (HKCU) レジストリ キーを使用します。
  • 少量のコンピュータ データの場合は、HKEY_LOCAL_MACHINE (HKLM) レジストリ キーを使用します。デフォルトでは、管理者以外のユーザーには HKLM ツリーに読み取り専用のアクセス許可しかないため、アプリケーションは実行時に HKLM に書き込むべきではありません。
  • アプリケーションのインストール時に、HKCU と HKLM 全体で合計 128 KB 以上を格納してはいけません。
  • コンポーネント オブジェクト モデル (COM) コンポーネントは HKEY_CLASSES_ROOT (HKCR) レジストリ キーに登録されます。最大値 128 KB には、HKCR は含まれません。
  • HKLM または HKCU に書き込むとき、会社名、製品名、および製品のバージョン番号を次のように作成する必要があります。
    HKLM\Software\Company Name\Product Name\Product Version
    HKCU\Software\Company Name\Product Name\Product Version
  • (RegCreateKeyEx や RegSetValueEx などの) レジストリ関数を使用して、レジストリ エントリの読み取りと書き込みを行います。

トラブルシューティング

  • Windows XP 以外に、旧バージョンの Windows でアプリケーションを実行できるようにするには、常に Shfolder.dll の SHGetFolderPath にリンクします。Windows XP は Shell32.dll の SHGetFolderPath を持っていますが、旧バージョンの Windows の中にはこのダイナミック リンク ライブラリ (DLL) 内部の関数をサポートしないものがあります。
  • Shfolder.dll は再配布可能なコンポーネントなので、アプリケーションと共に配布できます。
  • 長期間アプリケーションを使用している間に、ユーザーまたは管理者がマイ ドキュメント フォルダを再配置する可能性があるため、最近使用したファイルの一覧など、アプリケーション固有の場所にあるマイ ドキュメント フォルダ (またはその他のシステム フォルダ) へのフルパスを保存しないでください。

関連情報

その他のよく参照される「サポート技術情報」 (Microsoft Knowledge Base) の資料については、次のマイクロソフト Web サイトの Visual C++ .NET Support Center にアクセスしてください。
Visual C++ .NET (2002) Support Center
http://support.microsoft.com/default.aspx?xmlid=fh%3BEN-US%3Bvcnet
Visual C++ .NET に関する一般的な情報については、次の Usenet ニュースグループを参照してください。
http://www.microsoft.com/japan/msdn/newsgroups/default.mspx?dg=microsoft.public.jp.dotnet.languages.vc
SHGetFolderPath が識別できるフォルダのセットの詳細については、次の Microsoft Platform SDK (ソフトウェア開発キット) のマニュアルを参照してください。
CSIDL
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp
シェル プログラミング全般の詳細については、以下の MSDN (Microsoft Developer Network) Web サイトを参照してください。
Shell Programmers Guide
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/Shell/programmersguide/shell_intro.asp

プロパティ

文書番号: 310294 - 最終更新日: 2006年2月6日 - リビジョン: 2.1
この資料は以下の製品について記述したものです。
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
  • Microsoft Visual C++ .NET 2002 Standard Edition?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
キーワード:?
kbhowtomaster kbnewsgrouplink KB310294
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com