Есть у меня небольшой проект, по историческим причинам не использующий ни Qt, ни GTK, ни чего-либо другого. Только WinAPI или общение с WM через X11 под линем. И, хотя X11 не лишен недостатков, не буду оригинальным - WinAPI хуже его раз в стопятьсот.
Это не относится к новомодному интерфейсу Metro и его API - честно говоря, не трогал и не имею желания. Просто потому что тайловые WM давно уже изобрели, и я нахожу подобные закосы либо шагом назад, либо желанием выпендритьсяшагом назад.
Сейчас Windows и WinAPI не ругал только ленивый, см. [1] [2] [3] и в этом я особо не оригинален. По последней ссылке, кстати есть некоторый список конкретных недостатков. Однако, мне довелось встретиться с несколько другими, значительно более раздражающими, и этот пост будет посвящен им. Замечу, что все они решаемые, но красоте коду они не прибавляют.
В первую очередь, SetWindowLong с GWL_STYLE - это просто хаос и угар. Некоторые комбинации его флагов могут реально поломать окно ко всем чертям, в зависимости от версии Windows. К примеру, есть популярный хак вида
Ещё в недрах WinAPI есть замечательное событие WM_MOUSELEAVE . Ну, думается, если есть WM_MOUSEMOVE, который работает всегда и ловит перемещение мыши - оный должен работать также. Ничего подобного, если не вызвать TrackMouseEvent - сообщений не будет. Конечно, в X11 флаги перемещения мыши, входа и выхода из клиентской области задаются отдельно. НО! Ни один из них не включен по умолчанию.
Определённое неудобство может доставить функция PeekMessage . Обратите внимание на второй аргумент её. В него должен передаваться дескриптор окна, для которого получается сообщение. Так вот, в него всегда надо передавать NULL. Иначе у вас не будет работать смена раскладки окна. Проверял на Windows XP, 7, 8 - нигде это не работает. Вообще, если сообщение всегда получается для окна текущего потока, имеет смысл задать себе - как часто у вас несколько окон обрабатывается в одном потоке?
UPD: Оказывается в этом есть логика, см. статью. И она тесно связана со следующим фактом, а именно...
CreateWindow, который создает не только окна, но и двери, шпаклевки, кирпичи, натяжные потолки - это классика нарушения принципа единственной обязанности и кроме как легаси не объясним.
Подводя итог, хочу сказать - используйте Qt, GTK, JUCE, whatever. А WinAPI - нет.
Это не относится к новомодному интерфейсу Metro и его API - честно говоря, не трогал и не имею желания. Просто потому что тайловые WM давно уже изобрели, и я нахожу подобные закосы либо шагом назад, либо желанием выпендриться
Сейчас Windows и WinAPI не ругал только ленивый, см. [1] [2] [3] и в этом я особо не оригинален. По последней ссылке, кстати есть некоторый список конкретных недостатков. Однако, мне довелось встретиться с несколько другими, значительно более раздражающими, и этот пост будет посвящен им. Замечу, что все они решаемые, но красоте коду они не прибавляют.
В первую очередь, SetWindowLong с GWL_STYLE - это просто хаос и угар. Некоторые комбинации его флагов могут реально поломать окно ко всем чертям, в зависимости от версии Windows. К примеру, есть популярный хак вида
SetWindowLong(handle, GWL_STYLE, oldstyle & ~WS_THICKFRAME);
Он запрещает пользователю изменять размеры окна (почему вообще нет функции для этого?). В Windows 8 он ломает работу glViewport из-за того, что клиентская область начинает вычисляться неверно. И да, рамку она не убирает. Но более того - некоторые безобидные комбинации флагов стилей в вызове этой функции приводят к тому, что окно просто превращается в КРОВЬ КИШКИ МЯСО.Ещё в недрах WinAPI есть замечательное событие WM_MOUSELEAVE . Ну, думается, если есть WM_MOUSEMOVE, который работает всегда и ловит перемещение мыши - оный должен работать также. Ничего подобного, если не вызвать TrackMouseEvent - сообщений не будет. Конечно, в X11 флаги перемещения мыши, входа и выхода из клиентской области задаются отдельно. НО! Ни один из них не включен по умолчанию.
Определённое неудобство может доставить функция PeekMessage . Обратите внимание на второй аргумент её. В него должен передаваться дескриптор окна, для которого получается сообщение. Так вот, в него всегда надо передавать NULL. Иначе у вас не будет работать смена раскладки окна. Проверял на Windows XP, 7, 8 - нигде это не работает. Вообще, если сообщение всегда получается для окна текущего потока, имеет смысл задать себе - как часто у вас несколько окон обрабатывается в одном потоке?
UPD: Оказывается в этом есть логика, см. статью. И она тесно связана со следующим фактом, а именно...
CreateWindow, который создает не только окна
Подводя итог, хочу сказать - используйте Qt, GTK, JUCE, whatever. А WinAPI - нет.