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;

这是我在带有中断、继续、忽略按钮的弹出框中不断出现的错误:

notepadpremium.exe 中 0x7597d298 处的未处理异常:0xC0000005:访问冲突读取位置 0xcccccccc。

我正在使用 MS Visual C++ Express 2010。

我还有一个列表框,其中的文件名也显示扩展名(几乎就像 notepad++ 文档切换器),并通过消息尝试了 LB_GETITEMDATA,但始终返回空白。我认为那是因为我使用 LB_ADDSTRING 将其添加到列表框中。(列表框和选项卡是相互关联的,当您单击列表框中的文件时,它会变为相应的选项卡)。为什么我的代码没有按应有的方式工作?

4

1 回答 1

3

阅读文档

产品类型:LPTCITEM

指向 TCITEM 结构的指针,该结构指定要检索的信息并接收有关选项卡的信息。发送消息时,掩码成员指定要返回的属性。如果 mask 成员指定 TCIF_TEXT 值,则 pszText 成员必须包含接收项目文本的缓冲区的地址,而 cchTextMax 成员必须指定缓冲区的大小。

您根本没有初始化TCITEM。您需要告知TabCtrl_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;

至于您的 ListBox 问题,您说您LB_ADDSTRING用于将字符串添加到 ListBox,但LB_GETITEMDATA用于检索它们。那是错的。您需要使用LB_GETTEXTLENandLB_GETTEXT来代替。LB_GETITEMDATA用于检索使用 . 添加到 ListBox 的用户定义数据LB_SETITEMDATA

于 2013-11-19T20:49:22.620 回答