Вероятно, это не самый качественный ответ; предложения по улучшению приветствуются.
Вы правы, предполагая, что значение HWND никогда не меняется, пока окно, на которое указывает HWND, остается активным.
Я предполагаю, что вы написали такой код:
LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HWND button;
switch (uMsg) {
case WM_CREATE:
button = CreateWindowEx(...);
break;
case WM_COMMAND:
if (lParam == (LPARAM) button)
/* button was clicked; do something */;
}
return DefWindowProc(...);
}
и удивляться, почему это не работает, но меняется
HWND button;
to
static HWND button;
исправляет это.
Это не свойство HWND. Ничто о сбое кода не связано с тем, что значение HWND изменилось. На самом деле, это вообще не имеет ничего общего с Windows, а все, что связано с C.
Причина, по которой код не работает, заключается в том, что переменная button
создается заново каждый раз при вызове функции wndproc()
. Видите ли, оконная процедура вызывается много раз, по одному разу для каждого сообщения, которое окно получает во время выполнения вашей программы. Каждый раз вы получаете совершенно новую переменную button
, а значение, которое переменная button
имела в предыдущих вызовах, теряется. Указатель все еще там, но он не хранится ни в какой переменной или в каком-либо другом месте памяти! Окно не уничтожено. Вы просто не можете добраться до него обычными средствами.
Что делает static
, так это сообщает C, что вы хотите, чтобы переменная оставалась при каждом вызове функции. Так что теперь каждый вызов вашей оконной процедуры имеет один и тот же button
, и это значение указателя больше не теряется.
Это быстрое решение, и оно не очень хорошо масштабируется для очень больших проектов. В этих случаях лучше использовать структуры, содержащие дескрипторы окон, (возможно) глобальные переменные или использование GWLP_USERDATA
или других cbWndExtra
байтов. Я предполагаю, что лучший вопрос заключается в том, почему это быстрое исправление продолжает предлагаться в качестве решения подобных проблем других людей здесь, в переполнении стека (или, по крайней мере, почему это быстрое исправление не объясняется), но это то, о чем мы должны думать как сообщество.
Просто помните, что по умолчанию в большинстве языков (не только в C и C++!) локальные переменные функции существуют только на время вызова каждой отдельной функции.
person
andlabs
schedule
17.10.2015