![]() |
eXeL@B —› Программирование —› GetMessage. Отрисовка окна. |
Посл.ответ | Сообщение |
|
Создано: 05 января 2009 01:08 · Поправил: Mavlyudov · Личное сообщение · #1 Столкнулся с такой проблемой. Как-то заметил, что откомпилированная программа жрет много памяти. Зашел в процессы (у меня через TaskInfo) и вот, что увидел на закладке Thread: Thread Stack:: Symbol: user32 ! PeekMessageA() + 0xa5 a + 16A3 a + 16F6 a + 2466 По разным адресам(или смещениям? например 0xa5,0x95,..) все время появляется и исчезает PeekMessageA и еще какая-то процедура. причем загрузка процессора до 80%. Посмотрел, например, для блокнота. Там(в стеке) висит TranslateMEssage. И не меняется. Программа, которую компилирую, использует модуль WinCrt. В этом модуле прорисовка окна происходит как-то не совсем понятно. Всем изветно, что создавать окно нужно примено так(последовательность): Заполнение структуры WinClass (типа TWndClass); RegisterClass(WinClass); Handle := CreateWindowEx(0, 'Class', 'Form', WS_OVERLAPPEDWINDOW or WS_VISIBLE, ....); while(GetMessage(Msg, Handle, 0, 0)) do begin TranslateMessage(Msg); //прием сообщений DispatchMessage(Msg); //удаление сообщений из очереди end; Но в модуле WinCrt это сделано иначе(см. листинг1). Там создание окна происходит в отдельной процедуре InitWinCrt, а обработка сообщений в другой процедуре (KeyPressed). Причем не через GetMessage, а через PeekMessage. Поэтому-о я и думаю, что PeekMessage, который вск время воявляется в стеке в диспетчере процессов это и есть тот, что крутится в цикле в процедуре ReadKey. Далее я создаю программу (листинг2). И в этой программе мне нужно сделать, чтобы программа ожидала от пользователя нажатие клавиши, что я и делаю(CH:=READKEY;). Но при запуске, сразу видно, чо загрузка процессора очень большая. Вот теперь и возникает вопрос: можно ли как-то оптимизировать программу (точнее модуль wincrt) так, чтобы использовать минимум ресурсов и не загружать так сильно процессор? Возможно(как один из вариантов) даже использовать вместо readkey что-то другое(альтернативную процедуру), только я не знаю что. бУду рад советам. Модуль и программу прикрепляю. Code:
Code:
![]() |
|
Создано: 05 января 2009 13:32 · Поправил: AlexZ · Личное сообщение · #2 Или я не понимаю новых технологий, или листинг 1 - чушь. Строка 20 - при каждом обращении к KeyPressed вызывается InitWinCrt. Потом, происходит постоянная дрючка PeekMessage, вот её описание: function PeekMessage(var Msg: TMsg; Wnd: HWnd; MsgFilterMin, MsgFilterMax: Word): Bool; Пpовеpяет очеpедь пpикладной задачи на сообщение и копиpует его в Msg. Если в очеpеди нет сообщений, функция выполняет немедленный возвpат и пеpедает упpавление Windows. Параметры: Msg: Пpинимающая стpуктуpа TMsg. Wnd: Окно назначения сообщения, или 0 для любого окна в пpикладной задаче, или -1 для сообщений, напpавленных функцией PostMessage. MsgFilterMin: Наименьший идентификатоp сообщения или 0, если пpедел отсутствует. MsgFilterMax: Наибольший идентификатоp сообщения или 0, если пpедел отсутствует. RemoveMsg: Один или несколько паpаметpов: pm_NoRemove, pm_NoYield или pm_Remove. См. pаздел "Паpаметpы сообщений, pm_" в главе 1. Возвpащаемое значение: Не нуль, если сообщение имеется; 0 - если нет. См. также: GetMessage, WaitMessage Функцией ReadKey вы снова продрючиваете весь клубок хитрозадых вызовов... Ну кто же так пишет? ----- Я медленно снимаю с неё UPX... *FF_User* ![]() |
|
Создано: 05 января 2009 13:42 · Личное сообщение · #3 |
|
Создано: 05 января 2009 18:04 · Поправил: Mavlyudov · Личное сообщение · #4 AlexZ пишет: Или я не понимаю новых технологий, или листинг 1 - чушь. Исходниу WinCrt.pas щел вместе с Borland Pascal или TPW - не помню точно Пробовал откомпилировать на делфи(смысла нет, но все же), компилирует, но не работает программа. Думаю, нужно как-то разобраться с отрисовкой окна. А также как-то переделать процедуру READKEY, потому что мне в моей программе эта процедура нужна. Программа должна ожидать от пользователя нажатия клавиш все время. В архиве a.exe и исходники (a.PAS, wincrt.PAS) ![]() ![]() |
|
Создано: 11 марта 2009 22:22 · Личное сообщение · #5 AlexZ Вот, ты был прав по поводу Sleep(1). Вот, куда я вставил: Code:
Хм..Получается, что "приостанавливает выполнение текущей нити" на 1 мс. Но все-таки заметны задержки. Например, при масштабировании или повороте изображения в программе, задержка чувствуется. Может быть можно добиться лучшего результата какой-то другой функцией? Думаю, что функция MsgWaitForMultipleObjects особо ничего нового не даст по сравнению со sleep. ![]() |
|
Создано: 11 марта 2009 22:47 · Поправил: Valemox · Личное сообщение · #6 Mavlyudov пишет: Думаю, что функция MsgWaitForMultipleObjects особо ничего нового не даст по сравнению со sleep. Думаю, что здесь ты всеж не прав, т.к. MsgWaitForMultipleObjects, способна "просыпаться", когда в очереди потока появляется новое сообщение и это значительнее луче, чем убогий Sleep. вличко ![]() |
|
Создано: 12 марта 2009 00:27 · Поправил: Mavlyudov · Личное сообщение · #7 |
![]() |
eXeL@B —› Программирование —› GetMessage. Отрисовка окна. |