2012-02-23 7 views
2

Я в настоящее время делаю много использования кода, как это для того, чтобы определить местоположение элемента управления в клиентской области окна:Безопасен ли CWnd :: ScreenToClient?

CRect rect; 
GetDlgItem(IDC_CONTROL_ID)->GetWindowRect(&rect); 
ScreenToClient(&rect); 

Все работает нормально, но я обеспокоен по поводу безопасности этого кода , В частности, если пользователь перемещает окно между GetWindowRect и ScreenToClient из-за того, что поток, содержащий вышеуказанный код, приостановлен Windows, приведет ли он к неправильным результатам? Если да, есть ли лучший способ сделать это?

ответ

1

Пользователь не сможет перемещать окно вообще, пока выполняется ваш код внутри функции обработчика сообщений. Нет, это не проблема.

Пользовательский интерфейс в основном временно заморожен или приостановлен во время работы вашего кода. Технически это связано с тем, что Windows не может обрабатывать другие сообщения, пока вы не вернетесь. Цикл сообщения начинает работать снова, как только вы возвращаетесь из функции обработчика сообщений, тем самым возвращая управление.

Это, конечно, почему вы не должны выполнять код, который требует много времени для выполнения (например, сложных вычислений) внутри ваших обработчиков сообщений, поскольку пользовательский интерфейс будет заморожен до тех пор, пока он не завершится.
Вместо этого вы должны открутить отдельный поток, чтобы запускать этот материал. Поскольку вы не многопоточны здесь (и не нужно, потому что этот код занимает незначительное количество времени для выполнения), проблем с повторным подключением не будет.

+0

Более техническое объяснение: все потоки, отображающие окна, имеют связанную с ними очередь сообщений и при необходимости создаются операционной системой. Очередь сообщений принимает все сообщения, включая сообщения, созданные для событий перемещения. Очередь сообщений по существу сериализует сообщения, так что окно не перемещается, пока вы (или MFC) не обработаете сообщения перемещения. Таким образом, результаты 'GetWindowRect()' все равно будут действительны, если только он не вызывается в окне, которое нить не принадлежит. –

+0

Вы не согласны с моим ответом, @Insilico? Или просто добавить дополнительную информацию? Да, сообщения будут эффективно сериализованы, но это не повлияет на выполнение функций GetWindowRect и ScreenToClient. –

+0

Я просто добавляю немного больше информации. Я согласен с вашим ответом 100%. –

Смежные вопросы