Разница между дескриптором, полученным в процедуре обратного вызова окна WNDPROC, и дескриптором, возвращенным CreateWindow?

#c #winapi

#c #winapi

Вопрос:

Итак, мне было интересно, есть ли какая-либо разница между дескриптором, возвращаемым при создании окна с помощью CreateWindow/CreateWindowEx , и тем, который передается в качестве параметра в WNDPROC процедуру обратного вызова окна для соответствующего окна. Контекст этого вопроса заключается в том, что мне нужно использовать определенные функции API, которым требуется дескриптор для окна, поэтому я подумал, что вместо передачи дескриптора, полученного процедурами обратного вызова окна, я мог бы просто сохранить копию дескриптора, возвращаемого CreateWindow один раз, а затем использовать его для последовательных операций, в случае, если оба дескриптора одинаковы.

С уважением,

Devjeet

Комментарии:

1. Почему бы вам не сравнить их? Также почему вы не хотите использовать дескриптор, полученный процедурой обратного вызова окна?

2. Дело не в том, что я не хочу, просто если бы что-то можно было сделать без его передачи, это было бы лучше. Функции, которые я использую, созданы только для одной цели, и только одна оконная процедура будет его использовать. Поэтому он подумал, что было бы проще просто сохранить дескриптор сразу, не передавая его все время.

Ответ №1:

Будьте осторожны, оконная процедура используется несколькими экземплярами окна. Обратный вызов определяется значением WNDCLASSEX.lpfnWndProc, поэтому любой вызов CreateWindow / Ex(), использующий то же имя класса window, использует тот же обратный вызов. Если вы делаете это для сопоставления обратного вызова с методом экземпляра класса, то сначала вам нужно выполнить обработку, которая сопоставляет аргумент hwnd обратного вызова экземпляру класса. Конечно, делаем особый случай для WM_CREATE.

Ответ №2:

Да, они одинаковы, в этом весь смысл наличия HWND. У каждого окна есть только один дескриптор, HWND который идентифицирует его в системе и остается действительным до DestroyWindow вызова с ним. Он возвращается CreateWindow(EX) и отправляется с каждым сообщением, так что вы можете использовать его как уникальный идентификатор для вашего окна, даже если вы создаете несколько окон одного и того же класса.

Но обратите внимание, что некоторые сообщения отправляются оконной процедуре еще до CreateFunction возврата, поэтому, если вы используете глобальную переменную для хранения вашего HWND :

 HWND globalHwnd = NULL;

int main()
{
    //...
    globalHwnd = CreateWindow(...);
}

LRESULT WndProc(HWND hWnd, ...)
{
    assert(hWnd == globalHwnd); //fail!
}
  

Утверждение завершится ошибкой, потому что несколько сообщений, таких как WM_CREATE были отправлены до CreateWindow возврата, поэтому глобальная переменная еще не назначена.

Комментарии:

1. Спасибо! Кстати, я буду использовать его как член класса.