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.
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'