ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Аноним  
Дата: 12.05.08 08:27
Оценка:
Реализован Ax (compositecontrol) RichEdit, но появилась проблема... Не доходят до этого Ax злополучные ctrl+c/v.
Что можно сделать, чтобы контейнер все-таки отдавал эти сообщения?
Re: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: algol Россия about:blank
Дата: 12.05.08 14:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Реализован Ax (compositecontrol) RichEdit, но появилась проблема... Не доходят до этого Ax злополучные ctrl+c/v.

А>Что можно сделать, чтобы контейнер все-таки отдавал эти сообщения?

Если ATL, то переопределите CComControlBase::PreTranslateAccelerator.
Re[2]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Аноним  
Дата: 13.05.08 04:38
Оценка:
Здравствуйте, algol, Вы писали:

A>Если ATL, то переопределите CComControlBase::PreTranslateAccelerator.


Да, ATL+WTL. Так и делал:

...
m_hAccTable = AtlLoadAccelerators(IDR_ACCELERATOR);
...
BOOL CMyClassCtrl::PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
{
    if(m_hAccTable)
        if(::TranslateAccelerator(m_hWnd, m_hAccTable, pMsg))
            return TRUE;
    
    return __super::PreTranslateAccelerator(pMsg, hRet);
}


Но ctrl+c даже не доходит до этого кода. Пока выкрутился комбинацией ctrl+shift+c/v, но это не очень хорошо.
Re[3]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: BigJohn  
Дата: 13.05.08 07:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, algol, Вы писали:


A>>Если ATL, то переопределите CComControlBase::PreTranslateAccelerator.


А>Да, ATL+WTL. Так и делал:


А>
А>...
А>m_hAccTable = AtlLoadAccelerators(IDR_ACCELERATOR);
А>...
А>BOOL CMyClassCtrl::PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
А>{
А>    if(m_hAccTable)
А>        if(::TranslateAccelerator(m_hWnd, m_hAccTable, pMsg))
А>            return TRUE;
    
А>    return __super::PreTranslateAccelerator(pMsg, hRet);
А>}
А>


А>Но ctrl+c даже не доходит до этого кода. Пока выкрутился комбинацией ctrl+shift+c/v, но это не очень хорошо.


Попробуй OleInitialize вызывавать вместо CoInitializeEx
Re[4]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Аноним  
Дата: 13.05.08 10:55
Оценка:
Здравствуйте, BigJohn, Вы писали:

BJ>Попробуй OleInitialize вызывавать вместо CoInitializeEx

Я ни одну из этих функций явно не вызываю.
Re[3]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: algol Россия about:blank
Дата: 13.05.08 12:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но ctrl+c даже не доходит до этого кода. Пока выкрутился комбинацией ctrl+shift+c/v, но это не очень хорошо.


А если грузить акселераторы в GetControlInfo? Пример из MSDN:

// Example for overriding IOleControlImpl::GetControlInfo()
// This example uses the accelerator table from the project resources
// with the identifier IDR_ACCELTABLE
// Define GetControlInfo() in the header of your composite 
// control class as follows:

STDMETHOD(GetControlInfo)(CONTROLINFO* pCI)
{
    // Load the accelerator table from the resource
    pCI->hAccel = LoadAccelerators(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDR_ACCELTABLE));
    if (pCI->hAccel == NULL)
        return E_FAIL;
    // Get the number of accelerators in the table
    pCI->cAccel = CopyAcceleratorTable(pCI->hAccel, NULL, 0);
    // The following is optional if you want your control
    // to process the return and/or escape keys
    // pCI.dwFlags = CTRLINFO_EATS_RETURN | CTRLINFO_EATS_ESCAPE;
    pCI->dwFlags = 0;
    return S_OK;
}
Re[5]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: BigJohn  
Дата: 13.05.08 14:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, BigJohn, Вы писали:


BJ>>Попробуй OleInitialize вызывавать вместо CoInitializeEx

А>Я ни одну из этих функций явно не вызываю.

А надо!
Re[6]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: algol Россия about:blank
Дата: 13.05.08 14:44
Оценка:
Здравствуйте, BigJohn, Вы писали:

BJ>>>Попробуй OleInitialize вызывавать вместо CoInitializeEx

А>>Я ни одну из этих функций явно не вызываю.
BJ>А надо!

А почему? Инициализация COM/OLE это проблема контейнера, а не контрола. И опять же часто вызывают явно не эти функции, а например AtlAxWinInit в ATL или AfxOleInit в MFC.
Re[4]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Аноним  
Дата: 13.05.08 16:01
Оценка:
Здравствуйте, algol, Вы писали:

A>А если грузить акселераторы в GetControlInfo?


Да тут не в акселераторах дело, имхо. У меня удалось завести акселераторы: в FinalConstruct загружаю таблицу акселераторов (повторю подробнее)

m_hAccTable = AtlLoadAccelerators(IDR_ACCELERATOR);


Потом переопределяю PreTranslateAccelerator:

BOOL CMyClassCtrl::PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
{
    if(m_hAccTable)
        if(::TranslateAccelerator(m_hWnd, m_hAccTable, pMsg))
            return TRUE;
    
    return __super::PreTranslateAccelerator(pMsg, hRet);
}


Они работаю, но работает другая комбинация — ctrl+shift+c/v, если же выставляю просто ctrl+c/v, то перестают работать. Тут, возможно, дело в контейнере??
Re[4]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Аноним  
Дата: 13.05.08 17:47
Оценка:
Здравствуйте, algol, Вы писали:

A>А если грузить акселераторы в GetControlInfo?


Или с другой стороны заходим — создаю MDI FormView MFC App проект с хостингом Ax. Все делается по-умолчанию. Вставляю реализованный Ax-контрол.
По-умолчанию MDI уже использует акселератор ctrl+c/v. Следовательно и как факт до Ax-контрола эти ctrl+c/v не доходят. Беру и меняю у MDI App акселераторы с ctrl+c/v на ctrl+o/p и только после этого Ax-контрол начинает реагировать на ctrl+c/v.

Как сделать так, чтобы при использовании этого Ax-контрола штатные (родные для MDI App) ctrl+c/v в первую очередь уходили контролу, а уже потом MDI App?
Re: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Аноним  
Дата: 14.05.08 10:55
Оценка:
Проблема все еще жутко актуальна....
Подскажите плиз в каком направлении копать.
Re[2]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 16.07.08 14:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Проблема все еще жутко актуальна....

А>Подскажите плиз в каком направлении копать.

У меня была похожая проблема, возможно это сможет натолкнуть вас на какие-то идеи ...

Таск был таков: надо было напедалить Simple ActiveX WYSIWYG HtmlEditControl, делал я его на базе стандартного активикс-элемента виндового эксплорера (IWebBrowser2), документ которого (MSHTML::IHTMLDocument2) переводился в режим редактирования. Никаких акселераторов я не использовал, в смысле собственных, просто IWebBrowser2 поддерживает такие клавиатурные сокращения, как Ctrl+B чтобы назначить выделенному тексту Bold стиль, Ctrl+I чтобы назначить выделенному тексту Italic стиль, и так далее ... Так вот, чтобы дать шанс эксплорерскому контролу обрабатывать клавиатурные события и тем самым реагировать на собственные клавиатурные сокращения, необходимо отправлять окну эксплорера ATL сообщение WM_FORWARDMSG. Например класс WebBrowserControl субклассит окно эксплорерского контрола, тогда делается так:


class WebBrowserControl
    : public CWindowImpl<WebBrowserControl, CAxWindow>
    , public CMessageFilter
{
    DECLARE_WND_CLASS(_T("WebBrowserControl"))

    BOOL PreTranslateMessage(MSG* pMsg)
    {
        if((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
            (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
            return FALSE;

        // give HTML page a chance to translate this message
        return (BOOL)SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);
    }

    // .... много всяких членов ....

private:
    IDispatchPtr              dispatchPtr_;
    MSHTML::IHTMLDocument2Ptr htmlDoc2Ptr_;
    IOleCommandTargetPtr      oleCommandTargetPtr_;
    IWebBrowser2Ptr           webBrowserPtr_;
};


Класс CHtmlEditControl — есть тот самый ActiveX, который я педалил. Он, если хочет обрабатывать клавиатурные сокращения, а также давать возможность дочернему эксплореру их обрабатывать, должен тоже предоставить подобный интерфейс:


// CHtmlEditControl
class ATL_NO_VTABLE CHtmlEditControl
    : /* бла бла бла ... всякое активиксовое наследование */
    , public CComCompositeControl<CHtmlEditControl>
    , /* бла бла бла ... всякое активиксовое наследование */
{
    // .... много всяких членов ....

    BEGIN_MSG_MAP(CHtmlEditControl)
        // .... всякие обработчики ....
        MESSAGE_HANDLER ( WM_FORWARDMSG, OnForwardMessage )
        // .... всякие обработчики ....
    END_MSG_MAP()

    // .... много всяких членов ....

    LRESULT OnForwardMessage (
        UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
    {
        MSG* pMsg = reinterpret_cast<MSG*>(lParam);
        
        if ( webBrowserControl_.PreTranslateMessage(pMsg) )
            return TRUE;

        return CComCompositeControl<CHtmlEditControl>::IsDialogMessage(pMsg);
    }

    // .... много всяких членов ....

private:
    WebBrowserControl   webBrowserControl_;
}


Теперь, ежели вставить полученный ActiveX HtmlEditControl в вижуалстудийный ActiveX test container, то ни хрена не работает Однако, если впихнуть его на хтмл страницу и отдать Интернет Эксплореру, или если поместить его в Outlook, то всё работает прекрасно. Собственно при написании приложения, использующего полученный ActiveX контрол, нужно придерживаться этой модели и посылать FORWARDMSG окну контрола во время фильтрации сообщений диалога, вот и всё.
Надеюсь, это поможет, или хотя бы навеет, какие-то мысли по поводу ...

Можно так же посетить следующие страницы: Keyboard events handling in AXControl или Hosting ActiveX Controls.
Если данный механизм не поможет, можно попытаться сделать, наподобие: Tabs and Accelerators in ATL Modeless Dialogs.

С уважением, Rakafon.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[5]: ActiveX'у не доходят WM_COPY (ctrl+c) от контейнера
От: Джо  
Дата: 19.07.08 08:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>BOOL CMyClassCtrl::PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
А>{
А>    if(m_hAccTable)
А>        if(::TranslateAccelerator(m_hWnd, m_hAccTable, pMsg))
А>            return TRUE;
    
А>    return __super::PreTranslateAccelerator(pMsg, hRet);
А>}
А>


А>Они работаю, но работает другая комбинация — ctrl+shift+c/v, если же выставляю просто ctrl+c/v, то перестают работать. Тут, возможно, дело в контейнере??


Если в контейнере Ctrl+C и Ctrl+V объявленны как акселлераторы, тогда контейнер может сам перехватывать KeyDown C,V и не пересылать их ActiveX. Похоже чтобы трюк с PreTranslateAccelerator работал, нужна специальная поддержка в контейнере, как в IE. В других контейнерах такой фичи может и не быть.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.