Russian Qt Forum

Компиляторы и платформы => Windows => Тема начата: Alex Custov от Январь 03, 2013, 19:34



Название: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Январь 03, 2013, 19:34
Программа с пустым окошком взлетает за ~10 мс. Начал использовать LoadKeyboardLayout() - стала запускаться ~500 мс. Qt 4.8.4, Windows 7. Причём сама функция отрабатывает быстро, а тормоз происходит где-то позже, но до paintEvent(). Что за фигня никто не знает?

Код
C++ (Qt)
#include <QtGui>
 
#include <windows.h>
 
class W : public QWidget
{
public:
   W() : QWidget()
   {
       m_kl = LoadKeyboardLayout(TEXT("00000409"), 0);
   }
 
private:
   HKL m_kl;
};
 
int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
 
   qint64 v = QDateTime::currentMSecsSinceEpoch();
 
   W *w = new W;
   w->show();
 
   qDebug("Initialized in %ld ms.", static_cast<long int>(QDateTime::currentMSecsSinceEpoch() - v));
 
   return app.exec();
}
 

Выводит:

Цитировать
Initialized in 540 ms.


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: kambala от Январь 03, 2013, 21:04
на мсдне в комментах:
Цитировать
The documentation lacks a reference to ActivateKeyboardLayout
Starting from Windows 7/2008, calling ActivateKeyboardLayout can be quite slow (around 0.5 second on our tests). It should therefore not be used frequently. Instead, it should be called once when the application is loaded, and store the returned HKL on some globally accessible location. Then, whenever the layout should be changed, ActivateKeyboardLayout should be called with the appropriate HKL. The performance difference is huge!

For more, read discussion on LoadKeyboardLayout is very slow on Windows 7 in the MSDN app compat. forum.

как вариант, можно загрузку раскладки засунуть в QTimer::singleShot()


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Январь 03, 2013, 23:16
так в моём примере ActivateKeyboardLayout не используется


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Bepec от Январь 03, 2013, 23:34
Кхм. Разумный же вроде человек.

Сделай отдельный слот и засунь в конструктор QTimer::singleShot.

Это должно решить твою проблему.


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Январь 03, 2013, 23:38
Bepec Я не спрашивал как мне это починить, я спрашивал почему так происходит. И проблему это не решит, т.к. программа, которая значительно больше этого примера, сразу начинает свои визуальные действия (отрисовку графики и т.д.), которые зависают на полсекунды. Тут как минимум поток нужен с синхронизацией, если это вообще поможет.


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Bepec от Январь 04, 2013, 00:30
Ну дай боже, возьми отладчик да пройди по конструктору.

Это же winApi я так понимаю? значит % на 90 ты ответа не найдешь. Ибо у них обычно вызывается до 3-5 дополнительных функций.

Скинь минимальный пример и я посмотрю. И ещё кто нить посмотрит. И возможно даст ответ на твой сложный и нужный вопрос.


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Январь 04, 2013, 02:04
Скинь минимальный пример и я посмотрю. И ещё кто нить посмотрит.

Минимальный пример есть в первом посте


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: kambala от Январь 04, 2013, 02:13
так в моём примере ActivateKeyboardLayout не используется
ну почему-то эта функция упомянута именно в LoadKeyboardLayout(), да и время задержки как раз совпадает. может она вызывается закулисно?


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Bepec от Январь 04, 2013, 10:35
Кхм.

Я наверно повторюсь, но.. Где минимально компилируемый пример млиать :D В котором можно проверить эмм.. работоспособность твоей конструкции?

Ту хрень без инклудов дополнительных из первого поста я посмотрел. Вердикт - в функции Show имеется вызов winApi, который и тормозит вашу превосходную программу.

Я незнаю, что делает ваша
Цитировать
LoadKeyboardLayout(TEXT("00000409"), 0);

Я не имею ни малейшего желания это выяснять.

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

PS Если мои реплики вам не по нраву, вы скажите, они перестанут появляться :D


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Igors от Январь 04, 2013, 13:01
Программа с пустым окошком взлетает за ~10 мс. Начал использовать LoadKeyboardLayout() - стала запускаться ~500 мс. Qt 4.8.4, Windows 7. Причём сама функция отрабатывает быстро, а тормоз происходит где-то позже, но до paintEvent(). Что за фигня никто не знает?
Никто не горит особым желанием узнать :) Цитата из MSDN (что привел kambala) выглядит вполне убедительно, вполне возможно задержка неизбежна. Ситуация типовая - напр загрузка и компиляция GLSL шейдеров может занимать неск секунд и более. Или приложение на старте грузит плагины что также может быть совсем не быстро. Ну значит splash screen с отображением прогресса = нормальное, стандартное решение


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Январь 04, 2013, 13:22
Я наверно повторюсь, но.. Где минимально компилируемый пример млиать :D В котором можно проверить эмм.. работоспособность твоей конструкции?

Минимально компилируемый пример - это файл main.cpp, который я добавил в начале поста. Он компилируется и запускается, неужели так сложно понять, что я должен по три раза писать как новичкам?

Ту хрень без инклудов дополнительных из первого поста я посмотрел.

Какие тебе ещё инклуды нужны кроме тех, что там есть?

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

Этот код уже дан! Достаточно закомментировать вызов LoadKeyboardLayout() и программа взлетает мгновенно.

PS Если мои реплики вам не по нраву, вы скажите, они перестанут появляться :D

твои реплики только замусорили тему, лучше не пиши вообще


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Январь 04, 2013, 13:25
ну почему-то эта функция упомянута именно в LoadKeyboardLayout(), да и время задержки как раз совпадает. может она вызывается закулисно?

Так вся морковка как раз в том, что ActivateKeyboardLayout() вызывается по флагу KLF_ACTIVATE, который не задан. Это значит, что в LoadKeyboardLayout() добавили каких-то багов в Win7. Нашёл на MSDN Social похожую тему, там решения нет, "высокие умы" сказали, что так есть и ничего не поделаешь, нда.


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Bepec от Январь 04, 2013, 19:28
Был бы у вас разум, вы бы поняли крутую вещь, которую вам с начала темы твердят, а так да :) Умолкаю.


Название: Re: LoadKeyboardLayout() на Windows 7 тормозит загрузку проги
Отправлено: Alex Custov от Июнь 19, 2013, 15:45
Я нашёл только одно решение через события, которое возможно подойдёт другим (потому что я меняю раскладку в чужом окне, а не своём):

Код
C++ (Qt)
SendMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET, 0x04090409);