What is the c approach for upgrading these c style casts for HtmlHelp
API?
void CMeetingScheduleAssistantApp::DisplayHelpTopic(CString strTopic)
{
CString strURL = _T("https://help-msa.publictalksoftware.co.uk/") strTopic;
if (theApp.UseDownloadedHelpDocumentation())
{
// CHM files use 3 letter suffix
strTopic.Replace(_T(".html"), _T(".htm"));
HtmlHelp((DWORD_PTR)(LPCTSTR)strTopic, HH_DISPLAY_TOPIC);
}
else
ShellExecute(nullptr, nullptr, strURL, nullptr, nullptr, SW_SHOWDEFAULT);
}
Specifically:
HtmlHelp((DWORD_PTR)(LPCTSTR)strTopic, HH_DISPLAY_TOPIC);
In answer to the question in the comments:
It is odd because the official docs for x86 HtmlHelpA
/ HtmlHelpW
do indicate different calls.
It doesn't seem to be listed as part of the CWinApp
class in the docs.
CodePudding user response:
reinterpret_cast
will always trigger a code analysys warning
In that case, you could invent your own pointer cast function. A smart compiler will most probably optimize this away:
#include <cstring>
template<class D, class T>
D ptr_cast(T* x) {
D rv;
static_assert(sizeof rv == sizeof x);
std::memcpy(&rv, &x, sizeof rv);
return rv;
}
Then
HtmlHelp( ptr_cast<DWORD_PTR>(strTopic.GetString()),
HH_DISPLAY_TOPIC);
In g and clang , explicitly instantiating the function
template DWORD_PTR ptr_cast<DWORD_PTR,char>(char*);
makes it into the assembly code
unsigned long ptr_cast<unsigned long, char>(char*):
mov rax, rdi
ret
When inlined and optimized (as it will be in your code) the function call is gone and only the mov
(assignment) to the destination DWORD_PTR
is left, which is exactly the trace a reinterpret_cast
would leave. In MSVC, inlining it results in the similar:
lea rdx, OFFSET FLAT:`string'
CodePudding user response:
(LPCTSTR)strTopic
calls CString::operator LPCTSTR()
. Then (DWORD_PTR)
converts pointer LPCTSTR to DWORD_PTR. There is no possible direct conversion from CString object to DWORD_PTR due to different source and target sizes.
C type casts can be the same short length as C type casts
HtmlHelp(DWORD_PTR(LPCTSTR(strTopic)), HH_DISPLAY_TOPIC);
MFC CWnd and CWinApp classes have the methods, that get the first parameter of the type DWORD_PTR
virtual void HtmlHelp(
DWORD_PTR dwData,
UINT nCmd = 0x000F);