AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 08.08.10 14:01
Оценка:
Мне нужно реализовать переход в полноэкранный режим из оконного и обратно, но при изменении стиля окна происходит вот что:

Unhandled exception at 0x64865a31 in Milena_C++.exe: 0xC0000005: Access violation reading location 0x00000008.

Всё это останавливается на
TranslateMessage(&msg);
DispatchMessage(&msg);


Причём, сообщение, насколько я выяснил, всегда WM_LBUTTONUP. Я думаю, проблема в том, что изменение стиля окна происходит при нажатии пункта меню (когда я меняю стиль окна из lua-скрипта такого не происходит. логично, сообщения-то не было).

HTMLayout использует уже созданное окно, как показано в примере win32, тоесть
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    LRESULT lResult;
    BOOL bHandled;
    lResult = HTMLayoutProcND(hWnd, message, wParam, lParam, &bHandled);
    if (bHandled)
        return lResult;

    switch (message)
    ...



Стиль окна я меняю так:

Для полноэкранного
SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);
SetWindowLong(winHandle, GWL_EXSTYLE, WS_EX_TOPMOST);
ShowWindow(winHandle, SW_SHOWMAXIMIZED);


Для обычного
SetWindowLong(winHandle, GWL_STYLE, WS_OVERLAPPEDWINDOW);
SetWindowLong(winHandle, GWL_EXSTYLE, 0L);
ShowWindow(winHandle, SW_SHOWNORMAL);
Re: AV при попытке перехода в полноэкранный режим
От: c-smile Канада http://terrainformatica.com
Дата: 08.08.10 18:28
Оценка:
Здравствуйте, Александр Граф, Вы писали:

АГ>Мне нужно реализовать переход в полноэкранный режим из оконного и обратно, но при изменении стиля окна происходит вот что:


АГ>Unhandled exception at 0x64865a31 in Milena_C++.exe: 0xC0000005: Access violation reading location 0x00000008.


Ни о чём не говорит. Что такое Milena_C++.exe? Это твое что-то? Если да то говори имя функции вместо "at 0x64865a31".

АГ>Всё это останавливается на

АГ>
АГ>TranslateMessage(&msg);
АГ>DispatchMessage(&msg);
АГ>


АГ>Причём, сообщение, насколько я выяснил, всегда WM_LBUTTONUP. Я думаю, проблема в том, что изменение стиля окна происходит при нажатии пункта меню (когда я меняю стиль окна из lua-скрипта такого не происходит. логично, сообщения-то не было).


При нажатии пункта меню где? меню системное или описанное в html?
Re[2]: AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 09.08.10 01:58
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Ни о чём не говорит. Что такое Milena_C++.exe? Это твое что-то? Если да то говори имя функции вместо "at 0x64865a31".


Извиняюсь. Это моё, имя функции — InitInstance, где создаётся окно и запускается цикл отлова сообщений.
В редких случаях остановка происходит и в WinProc сразу после

lResult = HTMLayoutProcND(hWnd, message, wParam, lParam, &bHandled);


CS>При нажатии пункта меню где? меню системное или описанное в html?


Меню описано в html, выглядит примерно так:

<menu>
<li link="action://milena.window.fullscreen = not milena.window.fullscreen">На весь экран\\в окне</li>
<menu>


milena.window.fullscreen = not milena.window.fullscreen


Это на LUA, меняет режим окна.
Re[3]: AV при попытке перехода в полноэкранный режим
От: c-smile Канада http://terrainformatica.com
Дата: 09.08.10 05:06
Оценка:
Здравствуйте, Александр Граф, Вы писали:

CS>>При нажатии пункта меню где? меню системное или описанное в html?


АГ>Меню описано в html, выглядит примерно так:


АГ>
АГ><menu>
АГ><li link="action://milena.window.fullscreen = not milena.window.fullscreen">На весь экран\\в окне</li>
АГ><menu>
АГ>


АГ>
АГ>milena.window.fullscreen = not milena.window.fullscreen
АГ>


АГ>Это на LUA, меняет режим окна.


Ну тогда рассказывай как и когда точно твой <li link> активирует твой код.
Т.е. какое точно DOM событие вызывает вот это вот:
SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);
SetWindowLong(winHandle, GWL_EXSTYLE, WS_EX_TOPMOST);
ShowWindow(winHandle, SW_SHOWMAXIMIZED);

Какие стили окно имеет до того? Этот winHandle это htmlayout окно или его родитель?
Если htmlayout то как насчет WS_EX_LAYERED и прочих непотребств.

Короче: любую деталь полезную следствию.
Re[4]: AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 09.08.10 05:30
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Ну тогда рассказывай как и когда точно твой <li link> активирует твой код.

CS>Т.е. какое точно DOM событие вызывает вот это вот:
CS>
CS>SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);
CS>SetWindowLong(winHandle, GWL_EXSTYLE, WS_EX_TOPMOST);
CS>ShowWindow(winHandle, SW_SHOWMAXIMIZED);
CS>

CS>Какие стили окно имеет до того? Этот winHandle это htmlayout окно или его родитель?
CS>Если htmlayout то как насчет WS_EX_LAYERED и прочих непотребств.

CS>Короче: любую деталь полезную следствию.


winHandle это htmlayout, он присваивается в WM_CREATE уже после того, как вызван HTMLayoutProcND с сообщением WM_CREATE.
Окно-родитель имеет стиль WS_OVERLAPPEDWINDOW.

Отлавливаю HANDLE_BEHAVIOR_EVENT, передаю параметры события и элемент, над которым производится действие в луа-скрипт(у меня луа-обёртка над HELEMENT).
Там проверяется событие MENU_ITEM_CLICK, и если оно имело место, срабатывает какой-то код (не обязательно смена стиля окна). Так вот. Если код изменяет стиль окна, или посылает какое-нибудь событие, происходит этот самый AV.

Возможно, мне следует попробовать слать сообщения окну-родителю?
Re[5]: AV при попытке перехода в полноэкранный режим
От: c-smile Канада http://terrainformatica.com
Дата: 09.08.10 06:05
Оценка:
Здравствуйте, Александр Граф, Вы писали:

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


CS>>Ну тогда рассказывай как и когда точно твой <li link> активирует твой код.

CS>>Т.е. какое точно DOM событие вызывает вот это вот:
CS>>
CS>>SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);
CS>>SetWindowLong(winHandle, GWL_EXSTYLE, WS_EX_TOPMOST);
CS>>ShowWindow(winHandle, SW_SHOWMAXIMIZED);
CS>>

CS>>Какие стили окно имеет до того? Этот winHandle это htmlayout окно или его родитель?
CS>>Если htmlayout то как насчет WS_EX_LAYERED и прочих непотребств.

CS>>Короче: любую деталь полезную следствию.


АГ>winHandle это htmlayout, он присваивается в WM_CREATE уже после того, как вызван HTMLayoutProcND с сообщением WM_CREATE.

АГ>Окно-родитель имеет стиль WS_OVERLAPPEDWINDOW.

Т.е. winHandle есть окно у которого есть WS_CHILD стиль, так?
А что этот твой код:
SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);

должен сделать с WS_CHILD?

АГ>Отлавливаю HANDLE_BEHAVIOR_EVENT, передаю параметры события и элемент, над которым производится действие в луа-скрипт(у меня луа-обёртка над HELEMENT).

АГ>Там проверяется событие MENU_ITEM_CLICK, и если оно имело место, срабатывает какой-то код (не обязательно смена стиля окна). Так вот. Если код изменяет стиль окна, или посылает какое-нибудь событие, происходит этот самый AV.

Что точно значит "посылает какое-нибудь событие, происходит этот самый AV"? Что такое "посылать событие" в данном случае?

АГ>Возможно, мне следует попробовать слать сообщения окну-родителю?


То тебе решать. Я лично не знаю как оно у тебя там устроено.
Re[6]: AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 09.08.10 06:39
Оценка:
CS>Т.е. winHandle есть окно у которого есть WS_CHILD стиль, так?
CS>А что этот твой код:
CS>
CS>SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);
CS>

CS>должен сделать с WS_CHILD?

Честно говоря, я не думал, что что у htmlayout есть стиль WS_CHILD. Получается, что этот стиль убирается, что происходит дальше я не знаю.

CS>Что точно значит "посылает какое-нибудь событие, происходит этот самый AV"? Что такое "посылать событие" в данном случае?


Послать событие это SendMessage. (перепутал событие и сообщение).

Кстати, htmlayout же передаёт необработанные (обработанные тоже?) сообщения окну-родителю?

Тоесть, если я пошлю htmlayout WM_DESTROY, он уничтожится сам, и уничтожит родителя?
Re[7]: AV при попытке перехода в полноэкранный режим
От: c-smile Канада http://terrainformatica.com
Дата: 09.08.10 07:14
Оценка:
Здравствуйте, Александр Граф, Вы писали:

CS>>Т.е. winHandle есть окно у которого есть WS_CHILD стиль, так?

CS>>А что этот твой код:
CS>>
CS>>SetWindowLong(winHandle, GWL_STYLE, WS_POPUPWINDOW);
CS>>

CS>>должен сделать с WS_CHILD?

АГ>Честно говоря, я не думал, что что у htmlayout есть стиль WS_CHILD. Получается, что этот стиль убирается, что происходит дальше я не знаю.


HTMLayout окно создается как child window?

CS>>Что точно значит "посылает какое-нибудь событие, происходит этот самый AV"? Что такое "посылать событие" в данном случае?


АГ>Послать событие это SendMessage. (перепутал событие и сообщение).


И какое сообщение например ты посылаешь?

АГ>Кстати, htmlayout же передаёт необработанные (обработанные тоже?) сообщения окну-родителю?


Это еще зачем?

АГ>Тоесть, если я пошлю htmlayout WM_DESTROY, он уничтожится сам, и уничтожит родителя?


Посылать WM_DESTROY message любому окну это "shoot yourself in the foot" причем в особенно злостной форме.
::DestroyWindow(hwnd) это правильный способ борьбы с окнами.
Re[8]: AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 09.08.10 07:35
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>HTMLayout окно создается как child window?


Оно же создаётся при вызове HTMLayoutProcND с сообщением WM_CREATE? Насколько я прочитал в туториале. А какие свойства оно имеет я не знаю.

CS>И какое сообщение например ты посылаешь?


Так, было WM_DESTROY, но ниже ты уже написал, что это не очень хорошо, ещё было WM_SYSCOMMAND с wparam = WM_SC_MAXIMIZE, но это после смены стиля (или смена стиля происходила прямо в WinProc, что тоже, как мне кажется, не очень хорошая практика), так что дело не в посылке сообщения.

АГ>>Кстати, htmlayout же передаёт необработанные (обработанные тоже?) сообщения окну-родителю?


CS>Это еще зачем?


Точно, незачем.

АГ>>Тоесть, если я пошлю htmlayout WM_DESTROY, он уничтожится сам, и уничтожит родителя?


CS>Посылать WM_DESTROY message любому окну это "shoot yourself in the foot" причем в особенно злостной форме.

CS>::DestroyWindow(hwnd) это правильный способ борьбы с окнами.

Понятно, будем делать правильно.
Re[8]: AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 09.08.10 12:13
Оценка:
Ничего не изменилось. Послал сообщение об изменении стиля окну-родителю. AV в том же месте. Поменял SendMessage с WM_DESTROY на DestroyWindow, всё осталось по прежнему. Причём, вылетает только когда изменения происходят по нажатию пункта в выпадающем меню.
Если стиль меняется после нажатия на кнопку или ссылку, всё работает отлично.

Приходит вот такое сообщение:


msg    {msg=0x00000202 wp=0x00000000 lp=0x006d008f}    tagMSG
hwnd    0x00050592 {unused=???}    HWND__ *
message    514    unsigned int
wParam    0    unsigned int
lParam    7143567    long
time    1681796    unsigned long
pt    {x=301 y=342}    tagPOINT


Насколько я понял, окна с таким handle не существует. Может быть это окно выпадающего меню?
Re[9]: AV при попытке перехода в полноэкранный режим
От: c-smile Канада http://terrainformatica.com
Дата: 09.08.10 17:49
Оценка:
Здравствуйте, Александр Граф, Вы писали:

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


CS>>HTMLayout окно создается как child window?


АГ>Оно же создаётся при вызове HTMLayoutProcND с сообщением WM_CREATE? Насколько я прочитал в туториале. А какие свойства оно имеет я не знаю.


Ох...

Еще раз: есть окно HWND — это системный handle системной же конструкции.

И есть мой внутренняя сущность под названием html::view. Это не окно (в смысле не HWND).

Когда ты зовешь
HTMLayoutProcND(hwnd,WM_CREATE,p1,p2,&handled) я для окна hwnd создаю внутри у себя экземпляр html::view.
В случае
HTMLayoutProcND(hwnd,WM_DESTROY,p1,p2,&handled) я убиваю экземпляр html::view созданный для окна hwnd.
В случае
HTMLayoutProcND(hwnd,WM_PAINT,p1,p2,&handled) я нахожу экземпляр html::view для окна hwnd и если он есть рисую то что загружено в html::view.
и т.д.

т.е. вызовы HTMLayoutProcND это делегация части функциональности станадратного окна функциям htmlayout.

Никаких окон (кроме popup, например — menu) я не создаю.

Давай договоримся: htmlayout window — это окно в WinProc которого выполняются вызовы моей HTMLayoutProcND.
Т.е. это любой HWND для которого создан экземпляр html::view.

Сам по себе HWND может быть как handle of desktop window так и handle of child window (которое живет на своем desktop window).

Т.е. мой вопрос "HTMLayout окно создается как child window?" про тот that_hwnd который ты подставляешь в
вызовах HTMLayoutProcND(that_hwnd,...)

Итак, ты мне можешь сказать style и style_ex этого окна? Т.е. фактически параметры HWND that_hwnd = CreateWindowEx(...).

CS>>И какое сообщение например ты посылаешь?


АГ>Так, было WM_DESTROY, но ниже ты уже написал, что это не очень хорошо, ещё было WM_SYSCOMMAND с wparam = WM_SC_MAXIMIZE, но это после смены стиля (или смена стиля происходила прямо в WinProc, что тоже, как мне кажется, не очень хорошая практика), так что дело не в посылке сообщения.


Я не понял пассаж про WM_SYSCOMMAND с wparam = WM_SC_MAXIMIZE... Ну да ладно ...

Basics что называется:

Закрытие desktop windows выполняется путем посылки им запроса на закрытие:

::PostMessage(hwnd, WM_CLOSE, ... );

Получая WM_CLOSE функция окна может отменить закрытие или пропустить
обработку дальше в DefWindowProc(). DefWindowProc() по получению WM_CLOSE вызывает ::DestroyWindow().
А ::DestroyWindow(hwnd) соотв. начинается с того что функции окна посылается *нотификация* WM_DESTROY.
В талмуде сказано

WM_DESTROY is used to free the allocated memory object associated with the window.

что я и делаю в HTMLayoutProcND. Того же и тебе желаю.

Т.е. когда ты в скажем notepad.exe нажимаешь "крестик" в углу окна то эта кнопка инициирует
посылку WM_CLOSE. И соотв. если документ изменен то ты получаешь Save/Discard диалог.
Т.е. WM_DESTROY для тебя это момент когда ты должен освободить все ресурсы. И WM_NCDESTROY это последнее сообщение что ты получишь в
своей функции окна для этого hwnd.

АГ>>>Тоесть, если я пошлю htmlayout WM_DESTROY, он уничтожится сам, и уничтожит родителя?


CS>>Посылать WM_DESTROY message любому окну это "shoot yourself in the foot" причем в особенно злостной форме.

CS>>::DestroyWindow(hwnd) это правильный способ борьбы с окнами.

АГ>Понятно, будем делать правильно.


Правильно это так:
1) иницировать закрытие посылакой PostMessage(WM_CLOSE). Внимание: PostMessage()!
2) обрабатывать WM_CLOSE путем вызова в scriptе функции view.closing() { return true or false }; и если true то
2.a) зовем view.closed() где скрипт закрывает весь свой stuff.
2.b) пропускаем эту WM_CLOSE в DefWindowProc которая уже и удалит окно.

Так во всяком случае происходит в Sciter.
Re[10]: AV при попытке перехода в полноэкранный режим
От: Александр Граф  
Дата: 09.08.10 18:10
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Итак, ты мне можешь сказать style и style_ex этого окна? Т.е. фактически параметры HWND that_hwnd = CreateWindowEx(...).


Ну так с чего всё и начиналось — WS_OVERLAPPED и 0.

CS>Правильно это так:

CS>1) иницировать закрытие посылакой PostMessage(WM_CLOSE). Внимание: PostMessage()!
CS>2) обрабатывать WM_CLOSE путем вызова в scriptе функции view.closing() { return true or false }; и если true то
CS> 2.a) зовем view.closed() где скрипт закрывает весь свой stuff.
CS> 2.b) пропускаем эту WM_CLOSE в DefWindowProc которая уже и удалит окно.

CS>Так во всяком случае происходит в Sciter.


Sciter я не пользуюсь, но спасибо за небольшой гид.
В общем-то проблема решилась, и она была не в htmlayout, а в связке мой код-htmlayout-lua. Правда, теперь приходится пропускать некоторые сообщения от htmlayout, типа POPUP_DISMISSED, но, в принципе, для моих целей оно и не надо.

Спасибо за помощь и за прекрасный компонент!
Re[11]: AV при попытке перехода в полноэкранный режим
От: c-smile Канада http://terrainformatica.com
Дата: 09.08.10 19:54
Оценка:
Здравствуйте, Александр Граф, Вы писали:

АГ>В общем-то проблема решилась, и она была не в htmlayout, а в связке мой код-htmlayout-lua. Правда, теперь приходится пропускать некоторые сообщения от htmlayout, типа POPUP_DISMISSED, но, в принципе, для моих целей оно и не надо.


Замечательно. Если бы более вразумительно проблемы описывались — еще бы и время сэкономили.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.