首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从CString设置LPSTR

从CString设置LPSTR
EN

Stack Overflow用户
提问于 2013-09-19 13:16:26
回答 2查看 1.5K关注 0票数 0

我正在尝试在MFC对话框上设置工具提示。我有从字符串资源读取工具提示的代码,并试图将其修改为不从资源读取,而是编写工具提示。

我的实现导致垃圾显示为工具提示,而不是我想要的teh字符串。此外,当从调试器运行时,它会导致崩溃,但当可执行文件直接运行时则不会(我确信存在缓冲区损坏或类似的情况)。

以下是与此相关的代码:

代码语言:javascript
复制
BOOL CPreviewDlg::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
{
    ASSERT(pNMHDR->code == TTN_NEEDTEXT);

    TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;

    if (!(pTTT->uFlags & TTF_IDISHWND))
        return FALSE;

    UINT_PTR hWnd = pNMHDR->idFrom;
    // idFrom is actually the HWND of the tool
    UINT nID = (UINT)(WORD)::GetDlgCtrlID((HWND)hWnd);

    CString sDlgItemText;
    (UINT)(WORD)::GetDlgItemText(this->GetSafeHwnd(), nID, sDlgItemText.GetBufferSetLength(50), 50);
    sDlgItemText.ReleaseBuffer();

    if(sDlgItemText.IsEmpty())
        sDlgItemText = _T("Unnamed");

    CString sToolTip = _T("");
    sToolTip.Format(_T("%s \n This is the %s control. Here we can put its description."), sDlgItemText, sDlgItemText);

    pTTT->lpszText = sToolTip.GetBufferSetLength(sToolTip.GetLength());/* MAKEINTRESOURCE(nID);*/
    pTTT->hinst = AfxGetInstanceHandle();
    sToolTip.ReleaseBuffer();
    *pResult = 0;

    // bring the tooltip window above other popup windows
    ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
        SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);

    return TRUE;    // message was handled
}

我确信错误是我试图设置pTTT->lpszText (而不是MAKEINTRESOURCE)的地方,我认为我没有得到从CString设置LPSTR的正确方法

代码语言:javascript
复制
CString sDlgItemText;
(UINT)(WORD)::GetDlgItemText(this->GetSafeHwnd(), nID, sDlgItemText.GetBufferSetLength(50), 50);
sDlgItemText.ReleaseBuffer();

if(sDlgItemText.IsEmpty())
    sDlgItemText = _T("Unnamed");

CString sToolTip = _T("");
sToolTip.Format(_T("%s \n This is the %s control. Here we can put its description."), sDlgItemText, sDlgItemText);

pTTT->lpszText = sToolTip.GetBufferSetLength(sToolTip.GetLength());/* MAKEINTRESOURCE(nID);*/
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-19 15:46:15

根本问题是,您正在返回局部变量的地址(sToolTip.m_pData)OnToolTipText处理程序中返回)。当控件离开通知处理程序时,sToolTip超出作用域并运行其析构函数,留下垃圾。

要解决这个问题,您有两个选项:

  1. 将工具提示文本复制到TOOLTIPTEXT::szText[]数组。
  2. 增加您返回的缓冲区的生存期,使其在系统需要时可用。生命周期不需要比封闭实体(本例中的对话框)更长,所以对话框的类成员就可以了。

与您的问题无关:当为TOOLTIPTEXT::lpszText成员分配指针时,您应该使用const_cast而不是调用CString::GetBuffer[SetLength]()TOOLTIPTEXT结构用于两个方向,用于设置和检索工具提示信息。因此,即使成员声明为const,也不能声明它们。这看起来可能很尴尬,但您更愿意这样做:

代码语言:javascript
复制
pTTT->lpszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(sToolTip));
票数 0
EN

Stack Overflow用户

发布于 2013-09-19 14:15:02

我认为您的问题是,一旦退出函数,pTTT->lpszText中的指针值就不再有效。

如果文本长度小于80个字符,或者如果您有能力截断工具提示,则可以使用

代码语言:javascript
复制
lstrcpy(pTTT->szText, sToolTip);

否则,需要使sToolTip成为CPreviewDlg类的全局变量或成员变量。

参考资料:MSDN文章.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18895712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档