0

基本的なメモ帳プログラムを作成しています。ユーザーが閉じるをクリックすると、開いている現在のドキュメントを保存するかどうかをユーザーに尋ねます。タブ付きのインターフェイスを使用していて、ファイル名 (タブのテキスト) を取得しようとしているので、「保存しますか: untitled.txt」などのメッセージ ボックスがあります。ファイル名が分からなくて困っています。これは私が現在持っているものです:

case ID_FILE_CLOSE:  // When the close button is clicked
  {
    HWND hEdit, hTabs;
    hTabs = GetDlgItem( hwnd, IDC_MAIN_TAB );
    int curTab = TabCtrl_GetCurSel( hTabs );

    TCITEM curtitem;
    TabCtrl_GetItem( hTabs, curTab, &curtitem );

    // Check for file name
    MessageBox( hwnd, curtitem.pszText, "Test", MB_OK );
  }
  break;

これは、Break、Continue、Ignore ボタンのあるポップアップ ボックスに表示されるエラーです。

notepadpremium.exe の 0x7597d298 で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0xcccccccc。

MS Visual C++ Express 2010 を使用しています。

拡張子も表示するファイル名のリストボックスもあり ( notepad++ document switcher のように)、メッセージを介して LB_GETITEMDATA を試しましたが、常に空白が返されました。LB_ADDSTRING を使用してリストボックスに追加したためだと思います。(リストボックスとタブは相互に接続されており、リストボックス内のファイルをクリックすると、対応するタブに変わります)。コードが正常に動作しないのはなぜですか?

4

1 に答える 1

3

ドキュメントを読む

ピテム タイプ: LPTCITEM

取得する情報を指定し、タブに関する情報を受け取る TCITEM 構造体へのポインター。メッセージが送信されると、マスク メンバーは返す属性を指定します。mask メンバーが TCIF_TEXT 値を指定する場合、pszText メンバーには項目テキストを受け取るバッファーのアドレスが含まれている必要があり、cchTextMax メンバーはバッファーのサイズを指定する必要があります。

をまったく初期化していませんTCITEMTabCtrl_GetItem()どのデータを取得するかを指定する必要があります。さらに重要なのは、そのデータを受け取るために提供するバッファを指定することです。あなたはそれを何もしていません。ランダムなデータを に渡してTabCtrl_GetItem()いるため、クラッシュします。

代わりにこれを試してください:

case ID_FILE_CLOSE:  // When the close button is clicked
  {
    HWND hTabs = GetDlgItem( hwnd, IDC_MAIN_TAB );

    int curTab = TabCtrl_GetCurSel( hTabs );
    TCHAR szFileName[MAX_PATH+1] = {0};

    TCITEM curtitem = {0};
    curitem.mask = TCIF_TEXT;
    curitem.pszText = szFileName;
    curitem.cchTextMax = MAX_PATH;

    if (TabCtrl_GetItem( hTabs, curTab, &curtitem ))
    {
      // also from the documentation:
      //
      // "the control may change the pszText member of the structure
      // to point to the new text instead of filling the buffer with
      // the requested text. The control may set the pszText member
      // to NULL to indicate that no text is associated with the item."
      //
      // which means you cannot rely on the szFileName[] buffer actually
      // containing the filename, you have to use whatever buffer the
      // TCITEM is actually pointing at, which may or may not be the
      // szFileName buffer...

      MessageBox( hwnd, curitem.pszText, TEXT("Test"), MB_OK );
    }
  }
  break;

LB_ADDSTRINGListBox の問題については、ListBox に文字列を追加するために使用していると言いましたが、LB_GETITEMDATAそれらを取得するために使用しています。それは間違いです。LB_GETTEXTLEN代わりにandを使用する必要がありますLB_GETTEXTLB_GETITEMDATAを使用して ListBox に追加されたユーザー定義データを取得するために使用されますLB_SETITEMDATA

于 2013-11-19T20:49:22.620 に答える