Set LPSTR from CString
Set LPSTR from CString
我正在尝试在MFC对话框中设置工具提示。我有用于从字符串资源读取工具提示的代码,并尝试将其修改为不从资源读取,而是组成工具提示。
我的实现导致垃圾显示为工具提示而不是我想要的字符串。此外,从调试器运行时会导致崩溃,但在直接运行可执行文件时不会导致崩溃(我确定存在缓冲区损坏或类似情况)
以下是相关的代码:
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 的正确方法
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->lpszText
中的指针值就不再有效。
如果文本长度少于 80 个字符,或者如果您有能力截断工具提示,则可以使用
lstrcpy(pTTT->szText, sToolTip);
否则,您需要sToolTip
CPreviewDlg
类的全局变量或成员变量。
参考:MSDN 文章。
根本问题是你从OnToolTipText
处理程序返回局部变量(sToolTip.m_pData)
的地址。当控件离开通知处理程序时,sToolTip
超出范围,其析构函数将运行,留下垃圾。
要解决此问题,您有 2 种选择:
- 将工具提示文本复制到
TOOLTIPTEXT::szText[]
数组。 - 延长返回的缓冲区的生存期,以便在系统需要时可用。生存期不需要比封闭实体(在本例中为对话框)长,因此对话框的类成员就可以了。
与您的问题无关:将指针分配给TOOLTIPTEXT::lpszText
成员时,您应该使用const_cast
而不是调用CString::GetBuffer[SetLength]()
。TOOLTIPTEXT
结构用于两个方向,以设置和检索工具提示信息。因此,成员不能被宣布为const
,即使他们是。它可能看起来很尴尬,但您更愿意执行以下操作:
pTTT->lpszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(sToolTip));
相关文章:
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 在C++中使用Cstring反转字符串
- 如何转换真实路径 CString c++
- std::async from std::async in windows xp
- __int64 CString 返回错误的值 - C++ MFC
- std::is_reference from std::any
- 如何将 SHFileOperation() 与 CString 路径一起使用
- std::time_point from and to std::string
- 在_T值中使用 CString
- 没有大小参数的CString::GetBuffer()做什么
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- std::chrono::time_point from std::string
- 如何将 CString 转换为字节 [] 数组?
- Visual accept std::string from std::byte iterator
- C++中链表的错误"Abort signal from abort(3) (sigabrt) "
- 可视化 如何将 CString 值列表添加到 MFC C++ 中的组合框中?
- C++从 std::string 创建 CString 失败
- 对树节点使用 CString 时出现内存泄漏
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- Set LPSTR from CString