Как мы можем напрямую запустить событие OnPsnHelp (или вызвать его) на странице свойств?

Я работал через свое приложение, добавляя обработчик сообщений. Это не потому, что мое приложение поддерживает контекстную справку. Скорее, я хотел перехватить клавишу F1, а затем просто вызвать существующий код «Справка», который запускается, когда затем нажимается кнопка диалогового окна или пункт меню. Пример:

      #pragma warning (suppress : 26434)
BOOL CBrotherExcludeDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{
    OnButtonHelp();

    // return CResizingDialog::OnHelpInfo(pHelpInfo);
    return TRUE;
}

Моя проблема связана со страницами недвижимости. Они обрабатывают отображение разделов справки с помощью другого механизма. Пример:

      void CCalendarSettingsGooglePage::OnPsnHelp(NMHDR* hdr, LRESULT* res)
{
    theApp.DisplayHelpTopic(_T("msa-options-calendars.html"));
}

Он использует PSN_HELPобработчик. Когда я добавляю OnHelpInfoна страницу свойств, теперь я не уверен, как просто запустить событие. Я стараюсь избегать двух мест, куда я звоню DisplayHelpTopic.

Как мы можем напрямую позвонить OnPsnHelp (например, я вызвал функцию обработчика нажатия кнопки «Справка») или вызвать ее через сообщение?


Это код котельной плиты:

      BOOL CPropertyPage::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    ASSERT(pResult != NULL);
    NMHDR* pNMHDR = (NMHDR*)lParam;

    // allow message map to override
    if (CDialog::OnNotify(wParam, lParam, pResult))
        return TRUE;

    // don't handle messages not from the page/sheet itself
    if (pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
        return FALSE;

    // handle default
    switch (pNMHDR->code)
    {
    case PSN_SETACTIVE:
        {
            CPropertySheet* pSheet = GetParentSheet();
            if (pSheet != NULL && !(pSheet->m_nFlags & WF_CONTINUEMODAL) && !(pSheet->m_bModeless) && !(pSheet->m_psh.dwFlags & PSH_AEROWIZARD))
                *pResult = -1;
            else
                *pResult = OnSetActive() ? 0 : -1;
        }
        break;
    case PSN_KILLACTIVE:
        *pResult = !OnKillActive();
        break;
    case PSN_APPLY:
        *pResult = OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
        break;
    case PSN_RESET:
        OnReset();
        break;
    case PSN_QUERYCANCEL:
        *pResult = !OnQueryCancel();
        break;
    case PSN_WIZNEXT:
        *pResult = MapWizardResult(OnWizardNext());
        break;
    case PSN_WIZBACK:
        *pResult = MapWizardResult(OnWizardBack());
        break;
    case PSN_WIZFINISH:
        *pResult = reinterpret_cast<LRESULT>(OnWizardFinishEx());       
        break;
    case PSN_HELP:
        SendMessage(WM_COMMAND, ID_HELP);
        break;

    default:
        return FALSE;   // not handled
    }

    return TRUE;    // handled
}

Так что я этого не понимаю. Если я использую SendMessage(WM_COMMAND, ID_HELP); ответ в программном обеспечении - всплывающее окно Failed to launch help.

1 ответ

Как вы упомянули в комментариях, вы можете просто вызвать свою функцию с двумя nullptrзначения, потому что эта функция на самом деле не использует эти параметры. Однако это вызывает проблемы , если в будущей версии вашего программного обеспечения он будет изменен так, чтобы он использовал их.

Таким образом, вы должны создать соответствующую структуру и передать ее адрес и допустимую переменную кода возврата в вашем «прокси» вызове OnPsnHelp. Конструкция этой структуры весьма тривиальна; это просто структура, за которой следует неиспользуемый lParamвещь.

Вот возможная реализация:

      BOOL CCalendarSettingsGooglePage::OnHelpInfo(HELPINFO*)
{
    PSHNOTIFY psns;
    psns.lParam = 0; // The docs say this contains no information.
    psns.hdr.hwndFrom = GetParent()->GetSafeHwnd(); // The parent P/Sheet
    psns.hdr.idFrom = IDHELP; // Not sure what this should REALLY be?
    #pragma warning(suppress: 26454) // For: #define PSN_HELP (PSN_FIRST-5)
    psns.hdr.code = PSN_HELP; // One would assume this is the correct code!
    LRESULT result;
    OnPsnHelp(&psns.hdr, &result); // Make the call.
    return TRUE; // Or possibly: return static_cast<BOOL>(result);
}

Из документов M/S :

лпарам

Указатель на структуру, содержащую информацию о коде уведомления. Эта структура содержит структуру в качестве своего первого члена, hdr . Элемент hwndFrom этой структуры содержит дескриптор листа свойств. Элемент lParam структуры не содержит никакой информации.


Вот определения PSHNOTIFYа также NMHDRструктуры:

      typedef struct _PSHNOTIFY
{
    NMHDR hdr;
    LPARAM lParam;
} PSHNOTIFY, *LPPSHNOTIFY;

typedef struct tagNMHDR
{
    HWND      hwndFrom;
    UINT_PTR  idFrom;
    UINT      code;         // NM_ code
}   NMHDR;
Другие вопросы по тегам