Home > front end >  What is the c approach for upgrading these c style casts for HtmlHelp API?
What is the c approach for upgrading these c style casts for HtmlHelp API?

Time:11-26

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:

enter image description here

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);
  • Related