htmlayout в QT
От: apin  
Дата: 02.10.09 14:03
Оценка:
Подскажите пожалуйста, как встроить htmlayout в QWidget.
В простейшем случае, я думаю, должно работать так:


Layout::Layout(QWidget *parent, Qt::WFlags flags)
    : QWidget(parent, flags)
    //, htmlayout::event_handler(HANDLE_ALL)
{
    setAutoFillBackground(false);
    setMouseTracking(true);

    BOOL bOk=::HTMLayoutLoadFile(winId(), L"e:\\htmlayout\\html_samples\\menu\\menu-bar.htm");
        Q_ASSERT(bOk);
}
bool Layout::winEvent( MSG * message, long * result ) 
{
    BOOL    bHandled = FALSE;
    LRESULT lr=HTMLayoutProcND(winId(),message->message,message->wParam,message->lParam, &bHandled);
    if (bHandled) return lr;
    return QWidget::winEvent(message,result);
}


но bOk всегда FALSE.

Если кто уже сталкивался помогите пожалуйста, очень нужно.
Re: htmlayout в QT
От: c-smile Канада http://terrainformatica.com
Дата: 02.10.09 16:15
Оценка:
Здравствуйте, apin, Вы писали:

A>Подскажите пожалуйста, как встроить htmlayout в QWidget.

A>В простейшем случае, я думаю, должно работать так:


A>
A>Layout::Layout(QWidget *parent, Qt::WFlags flags)
A>    : QWidget(parent, flags)
A>    //, htmlayout::event_handler(HANDLE_ALL)
A>{
A>    setAutoFillBackground(false);
A>    setMouseTracking(true);

A>    BOOL bOk=::HTMLayoutLoadFile(winId(), L"e:\\htmlayout\\html_samples\\menu\\menu-bar.htm");
A>        Q_ASSERT(bOk);
A>}
A>bool Layout::winEvent( MSG * message, long * result ) 
A>{
A>    BOOL    bHandled = FALSE;
A>    LRESULT lr=HTMLayoutProcND(winId(),message->message,message->wParam,message->lParam, &bHandled);
A>    if (bHandled) return lr;
A>    return QWidget::winEvent(message,result);
A>}

A>


A>но bOk всегда FALSE.


A>Если кто уже сталкивался помогите пожалуйста, очень нужно.


1) Проверь что HTMLayoutProcND получает события WM_CREATE и WM_DESTROY — именно по ним
создается и уничтожается instance.
2) Все обращения к engine типа HTMLayoutLoadFile должны делаться после получеия WM_CREATE —
т.е. после того как instance of the engine создан для этого окна.
Re[2]: htmlayout в QT
От: apin  
Дата: 02.10.09 17:23
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>1) Проверь что HTMLayoutProcND получает события WM_CREATE и WM_DESTROY — именно по ним

CS>создается и уничтожается instance.
CS>2) Все обращения к engine типа HTMLayoutLoadFile должны делаться после получеия WM_CREATE —
CS>т.е. после того как instance of the engine создан для этого окна.

Спасибо, простого способа перехватить WM_CREATE нет, но вот такой вариант работает:


    BOOL bHandled;
    HTMLayoutProcND(winId(),WM_CREATE,0,0, &bHandled);
    Q_ASSERT(bHandled);
    BOOL bOk=::HTMLayoutLoadFile(winId(), L"d:\\htmlayout\\html_samples\\menu\\menu-bar.htm");
Re[3]: htmlayout в QT
От: c-smile Канада http://terrainformatica.com
Дата: 02.10.09 18:19
Оценка:
Здравствуйте, apin, Вы писали:

A>Здравствуйте, c-smile, Вы писали:


CS>>1) Проверь что HTMLayoutProcND получает события WM_CREATE и WM_DESTROY — именно по ним

CS>>создается и уничтожается instance.
CS>>2) Все обращения к engine типа HTMLayoutLoadFile должны делаться после получеия WM_CREATE —
CS>>т.е. после того как instance of the engine создан для этого окна.

A>Спасибо, простого способа перехватить WM_CREATE нет, но вот такой вариант работает:


A>
A>    BOOL bHandled;
A>    HTMLayoutProcND(winId(),WM_CREATE,0,0, &bHandled);
A>    Q_ASSERT(bHandled);
A>    BOOL bOk=::HTMLayoutLoadFile(winId(), L"d:\\htmlayout\\html_samples\\menu\\menu-bar.htm");
A>


Ну или так. Только не забывай про WM_DESTROY, а то получишь утечку памяти.
Re[3]: htmlayout в QT
От: c-smile Канада http://terrainformatica.com
Дата: 02.10.09 20:03
Оценка:
Здравствуйте, apin, Вы писали:

A>Спасибо, простого способа перехватить WM_CREATE нет, но вот такой вариант работает:


A>

A>    BOOL bHandled;
A>    HTMLayoutProcND(winId(),WM_CREATE,0,0, &bHandled);
A>    Q_ASSERT(bHandled);
A>    BOOL bOk=::HTMLayoutLoadFile(winId(), L"d:\\htmlayout\\html_samples\\menu\\menu-bar.htm");
A>


B кстати если тебе popup нужны (menu-bar.htm) то не забудь про
HTMLayoutTranslateMessage() тоже.
Re[4]: htmlayout в QT
От: apin  
Дата: 03.10.09 06:45
Оценка:
Здравствуйте, c-smile, Вы писали:

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


A>>Спасибо, простого способа перехватить WM_CREATE нет, но вот такой вариант работает:


A>>

A>>    BOOL bHandled;
A>>    HTMLayoutProcND(winId(),WM_CREATE,0,0, &bHandled);
A>>    Q_ASSERT(bHandled);
A>>    BOOL bOk=::HTMLayoutLoadFile(winId(), L"d:\\htmlayout\\html_samples\\menu\\menu-bar.htm");
A>>


CS>B кстати если тебе popup нужны (menu-bar.htm) то не забудь про

CS>HTMLayoutTranslateMessage() тоже.


Чуть было не сдался с внедрением HTMLayout в QT, долго разбирался как QTшную прорисовку отключить, в общем надо обязательно вызвать

setUpdatesEnabled(false);

Спасибо, за советы.
Re[5]: htmlayout в QT
От: apin  
Дата: 03.10.09 07:53
Оценка:
Может быть кто знает, как сделать, чтоб QWidget не переопределял курсор, когда HTMLayout его устанавливает?
Re[4]: htmlayout в QT
От: apin  
Дата: 03.10.09 14:18
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>B кстати если тебе popup нужны (menu-bar.htm) то не забудь про

CS>HTMLayoutTranslateMessage() тоже.

Возникла еще одна проблема, которой не было со старой версией htmlayout (какой не могу сказать, но не менее года). Суть в следующем:
если компонент <select> открывать кнопкой, а не кликом в поле, то в выпадающем списке ничего нельзя выбрать.
Причем в browse.exe, это не проявляется, а вот во всех остальных демках (mfc и win32) проявляется. Проверить можно, например, в html_samples\forms\basiccontrols.htm.
Re[5]: htmlayout в QT
От: yarus23  
Дата: 03.10.09 15:03
Оценка:
http://www.rsdn.ru/forum/htmlayout/3556111.1.aspx
Автор: c-smile
Дата: 03.10.09
Re[6]: htmlayout в QT
От: apin  
Дата: 03.10.09 15:16
Оценка:
Здравствуйте, yarus23, Вы писали:

Y>http://www.rsdn.ru/forum/htmlayout/3556111.1.aspx
Автор: c-smile
Дата: 03.10.09


Остроумно.


// Main message loop:
  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    {
      if(!HTMLayoutTranslateMessage(&msg))
        TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }


это код из проекта win32. Что в нем не корректно?
Re[7]: htmlayout в QT
От: Cyberax Марс  
Дата: 03.10.09 15:20
Оценка:
Здравствуйте, apin, Вы писали:

A>
A>// Main message loop:
A>  while (GetMessage(&msg, NULL, 0, 0)) 
A>  {
A>    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
A>    {
A>      if(!HTMLayoutTranslateMessage(&msg))
A>        TranslateMessage(&msg);
A>      DispatchMessage(&msg);
A>    }
A>  }
A>

A>это код из проекта win32. Что в нем не корректно?
Вот так оно будет правильно:

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0)) 
{
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    {
         if(!HTMLayoutTranslateMessage(&msg))
            TranslateMessage(&msg);
     }

    DispatchMessage(&msg);

}
Sapienti sat!
Re[8]: htmlayout в QT
От: apin  
Дата: 03.10.09 16:12
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Вот так оно будет правильно:


C>
C>// Main message loop:
C>while (GetMessage(&msg, NULL, 0, 0)) 
C>{
C>    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
C>    {
C>         if(!HTMLayoutTranslateMessage(&msg))
C>            TranslateMessage(&msg);
C>     }
C>
C>    DispatchMessage(&msg);
C>
C>}
C>


Спасибо, недоглядел. Теперь буду думать, как в QT это сделать.
Вот такая конструкция не работает:


bool Layout::winEvent( MSG * message, long * result ) 
{
    HTMLayoutTranslateMessage(message);

    BOOL    bHandled = FALSE;
    LRESULT lr=HTMLayoutProcND(winId(),message->message,message->wParam,message->lParam, &bHandled);
    if (bHandled) return lr;

    return QWidget::winEvent(message,result);
    
}
Re[9]: htmlayout в QT
От: Cyberax Марс  
Дата: 03.10.09 16:33
Оценка:
Здравствуйте, apin, Вы писали:

A>
A>bool Layout::winEvent( MSG * message, long * result ) 
A>{
A>    HTMLayoutTranslateMessage(message);

A>    BOOL    bHandled = FALSE;
A>    LRESULT lr=HTMLayoutProcND(winId(),message->message,message->wParam,message->lParam, &bHandled);
A>    if (bHandled) return lr;

A>    return QWidget::winEvent(message,result);
    
A>}
A>

Похоже, проблема в том, что QT транслирует событие раньше HTMLayout. У меня оно в Java в SWT почему-то так же себя ведёт, сегодня попробую отладить.
Sapienti sat!
Re[10]: htmlayout в QT
От: apin  
Дата: 03.10.09 16:43
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Похоже, проблема в том, что QT транслирует событие раньше HTMLayout. У меня оно в Java в SWT почему-то так же себя ведёт, сегодня попробую отладить.


в QT вообще TranslateMessage не вызывается, из форума trolltech:

TranslateMessage translates keystrokes to hotkey commands. There is no
need for such a function in Qt. Use QAccel, or handle the QKeyEvent in
your own event handler.
Re[11]: htmlayout в QT
От: c-smile Канада http://terrainformatica.com
Дата: 03.10.09 18:06
Оценка:
Здравствуйте, apin, Вы писали:

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


C>>Похоже, проблема в том, что QT транслирует событие раньше HTMLayout. У меня оно в Java в SWT почему-то так же себя ведёт, сегодня попробую отладить.


A>в QT вообще TranslateMessage не вызывается, из форума trolltech:


A>TranslateMessage translates keystrokes to hotkey commands. There is no

A>need for such a function in Qt. Use QAccel, or handle the QKeyEvent in
A>your own event handler.

Вот эти два метода:

class QCoreApplication
{
  ...
  EventFilter setEventFilter ( EventFilter filter )
  virtual bool winEventFilter ( MSG * msg, long * result )
  ...
}


представляются близкими к теме куда вставить HTMLayoutTranslateMessage.

По смыслу winEventFilter это оно.

Если не получится то придется ставить hook. Посмотри вот этот топик:
http://rsdn.ru/forum/htmlayout/3536222.flat.aspx#3536222
Автор: Nikolaz
Дата: 14.09.09
Re[12]: htmlayout в QT
От: apin  
Дата: 03.10.09 19:06
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Вот эти два метода:


CS>
CS>class QCoreApplication
CS>{
CS>  ...
CS>  EventFilter setEventFilter ( EventFilter filter )
CS>  virtual bool winEventFilter ( MSG * msg, long * result )
CS>  ...
CS>}
CS>


CS>представляются близкими к теме куда вставить HTMLayoutTranslateMessage.


CS>По смыслу winEventFilter это оно.


CS>Если не получится то придется ставить hook. Посмотри вот этот топик:

CS>http://rsdn.ru/forum/htmlayout/3536222.flat.aspx#3536222
Автор: Nikolaz
Дата: 14.09.09


Я уже пробовал, winEventFilter и setEventFilter(EventFilter), по сути одно и тоже, сделано чтоб не переопределять QApplication.
Не работает.
Re[12]: htmlayout в QT
От: apin  
Дата: 03.10.09 19:14
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Если не получится то придется ставить hook. Посмотри вот этот топик:

CS>http://rsdn.ru/forum/htmlayout/3536222.flat.aspx#3536222
Автор: Nikolaz
Дата: 14.09.09


За ссылку спасибо, должно получиться. Завтра попробую, сегодня уже голова бобо.
Re[13]: htmlayout в QT
От: c-smile Канада http://terrainformatica.com
Дата: 03.10.09 22:36
Оценка:
Здравствуйте, apin, Вы писали:

A>Здравствуйте, c-smile, Вы писали:


CS>>Вот эти два метода:


CS>>
CS>>class QCoreApplication
CS>>{
CS>>  ...
CS>>  EventFilter setEventFilter ( EventFilter filter )
CS>>  virtual bool winEventFilter ( MSG * msg, long * result )
CS>>  ...
CS>>}
CS>>


CS>>представляются близкими к теме куда вставить HTMLayoutTranslateMessage.


CS>>По смыслу winEventFilter это оно.


CS>>Если не получится то придется ставить hook. Посмотри вот этот топик:

CS>>http://rsdn.ru/forum/htmlayout/3536222.flat.aspx#3536222
Автор: Nikolaz
Дата: 14.09.09


A>Я уже пробовал, winEventFilter и setEventFilter(EventFilter), по сути одно и тоже, сделано чтоб не переопределять QApplication.

A>Не работает.

В файле /corelib/kernel/qeventdispatcher_win.cpp я вижу такой фрагмент:

                if (!filterEvent(&msg)) {
                    TranslateMessage(&msg);
                    QT_WA({
                        DispatchMessage(&msg);
                    } , {
                        DispatchMessageA(&msg);
                    });
                }


Вот в этот filterEvent(&msg) или что-то от него вызываемое и надо вставить мой вызов.
Re[14]: htmlayout в QT
От: apin  
Дата: 04.10.09 05:01
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>В файле /corelib/kernel/qeventdispatcher_win.cpp я вижу такой фрагмент:


CS>
CS>                if (!filterEvent(&msg)) {
CS>                    TranslateMessage(&msg);
CS>                    QT_WA({
CS>                        DispatchMessage(&msg);
CS>                    } , {
CS>                        DispatchMessageA(&msg);
CS>                    });
CS>                }

CS>


CS>Вот в этот filterEvent(&msg) или что-то от него вызываемое и надо вставить мой вызов.


Уфф. Все оказалось не так очевидно, как кажется:
в main()

   QApplication a(argc, argv);
   QAbstractEventDispatcher::instance()->setEventFilter(myEventFilter);



bool myEventFilter(void *message)
{
    HTMLayoutTranslateMessage((MSG*)message);
    return false;
}

если возвращать return HTMLayoutTranslateMessage((MSG*)message);
как написано в комментах, к HTMLayoutTranslateMessage
* if( !HTMLayoutTranslateMessage(&msg) )
* TranslateMessage(&msg);
то не работает.

вопрос к c-smile — Вы считаете разумным прогонять все события довольно большого приложения, через HTMLayoutTranslateMessage, даже если htmlayout используется эпизодически как диалог настройки например? Не внесет ли это лишние "тормоза"? Как вариант ставить фильтр при открытии окна и снимать при закрытии, но тогда придется отслеживать все открытые окна, вводить счетчик. Это все конечно дело техники , т.к. Вам виднее.
Re[6]: htmlayout в QT
От: apin  
Дата: 04.10.09 06:24
Оценка:
A>Может быть кто знает, как сделать, чтоб QWidget не переопределял курсор, когда HTMLayout его устанавливает?

Надо сделать так:

bool Layout::winEvent( MSG * message, long * result ) 
{
    BOOL    bHandled = FALSE;
    LRESULT lr=HTMLayoutProcND(winId(),message->message,message->wParam,message->lParam, &bHandled);
    if (bHandled) return lr;

    QRect rect=contentsRect();
    QPoint pos=mapFromGlobal(QPoint(message->pt.x,message->pt.y));
    if (rect.contains(pos) && (message->message >= WM_MOUSEFIRST) && (message->message <= WM_MOUSELAST))
        return true;
    
    return QWidget::winEvent(message,result);
}


Было бы, конечно, если это не связанно с объективными причинами, неплохо чтоб HTMLayoutProcND возвращал bHandled=true, если курсор в области htmlayout
Re[15]: htmlayout в QT
От: c-smile Канада http://terrainformatica.com
Дата: 04.10.09 06:30
Оценка:
Здравствуйте, apin, Вы писали:

A>Здравствуйте, c-smile, Вы писали:


CS>>В файле /corelib/kernel/qeventdispatcher_win.cpp я вижу такой фрагмент:


CS>>
CS>>                if (!filterEvent(&msg)) {
CS>>                    TranslateMessage(&msg);
CS>>                    QT_WA({
CS>>                        DispatchMessage(&msg);
CS>>                    } , {
CS>>                        DispatchMessageA(&msg);
CS>>                    });
CS>>                }

CS>>


CS>>Вот в этот filterEvent(&msg) или что-то от него вызываемое и надо вставить мой вызов.


A>Уфф. Все оказалось не так очевидно, как кажется:

A>в main()

A>
A>   QApplication a(argc, argv);
A>   QAbstractEventDispatcher::instance()->setEventFilter(myEventFilter);
A>



A>
A>bool myEventFilter(void *message)
A>{
A>    HTMLayoutTranslateMessage((MSG*)message);
A>    return false;
A>}
A>

A> если возвращать return HTMLayoutTranslateMessage((MSG*)message);
A>как написано в комментах, к HTMLayoutTranslateMessage
A>* if( !HTMLayoutTranslateMessage(&msg) )
A>* TranslateMessage(&msg);
A>то не работает.

Круто. Круче (в смысле замороченней) чем в MFC (которая к слову тоже multiplatform framework).

A>вопрос к c-smile — Вы считаете разумным прогонять все события довольно большого приложения, через HTMLayoutTranslateMessage, даже если htmlayout используется эпизодически как диалог настройки например? Не внесет ли это лишние "тормоза"? Как вариант ставить фильтр при открытии окна и снимать при закрытии, но тогда придется отслеживать все открытые окна, вводить счетчик. Это все конечно дело техники , т.к. Вам виднее.


Что такое "довольно большого приложения"?
В любом случае количество окон в приложении как бы не увеличивает количество сообщений которые
постятся в input queue. Например при проносе мыши над окном ты получишь примерно одинаковое количество WM_MOUSEMOVE в случае отсутствия children или их наличия в количестве 10штук. Если я правильно понял вопрос.
При отсутствии popup или tool окон HTMLayoutTranslateMessage ничего не делает и так.
Re[16]: htmlayout в QT
От: apin  
Дата: 04.10.09 07:35
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Что такое "довольно большого приложения"?

CS>В любом случае количество окон в приложении как бы не увеличивает количество сообщений которые
CS>постятся в input queue. Например при проносе мыши над окном ты получишь примерно одинаковое количество WM_MOUSEMOVE в случае отсутствия children или их наличия в количестве 10штук. Если я правильно понял вопрос.
CS>При отсутствии popup или tool окон HTMLayoutTranslateMessage ничего не делает и так.

У меня довольно много анимации, т.е WM_PAINT посылается часто. Я наверное буду, вставлять обработчик только если открыт htmlayout, так как то спокойнее .
Спасибо за помощь.

P.S. Вы все же поосторожнее, когда меняете поведение. У меня в behavior:grid перестали столбцы мышкой растягиваться.
Re[16]: htmlayout в QT
От: apin  
Дата: 04.10.09 08:05
Оценка:
Вот конгломерат всей работы:

http://files.rsdn.ru/72620/layout.cpp
http://files.rsdn.ru/72620/layout.h
Re[17]: htmlayout в QT
От: yarus23  
Дата: 04.10.09 17:14
Оценка:
A>P.S. Вы все же поосторожнее, когда меняете поведение. У меня в behavior:grid перестали столбцы мышкой растягиваться.

а и не должны
behavior: column-resizer;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.