Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Почему функция обработки окна должна быть


Автор: Royan 12.5.2006, 13:56
Я написал обертку для класса окна. В нем у меня как полагается есть функция обработки сообщений (WindowProc) окна. Вопрос может ли она быть не статичной? Если не может то почему? Мне хотелось бы понять причины почему именно так происходит. Вот пример того о чем идет речь: http://www.codeproject.com/win32/win32windowwrapperclass.asp

Добавлено @ 14:07 
Кажется я просто не проснулся. В приведенной мною же статье есть ответ на этот вопрос. 

Автор: GremlinProg 13.5.2006, 12:42
Цитата

The main problem
When you create a WNDCLASSEX structure you need to give the structure a pointer to your window procedure in the lpfnWndProc member. The window procedure is a callback, a special kind of function called directly by Windows when needed.

To make callbacks work correctly, strict typedefs are defined in the Windows header files. If you try to use a class member as a callback, the compiler will give you an error, saying that the member prototype does not match the required typedef.

To get around this compiler error, we need to make the window procedure static. From this static method we then call another method of the class to actually handle the messages.

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

Главная же причина в том, что очень умные люди просто придумали некий стандарт, который позволяет нам встраивать в Win32 свои оконные классы и, соответственно, окна. Стандарт этот говорит нам о том, что процедура окна имеет 16 байт параметров, которые опускаются в стек, а возвращает 4-х байтовый результат, с поднятием стека на те же 16 байт. Есть несколько стандартов вызова процедур и функций: fastcall, cdecl, stdcall, thiscall, pascal(Borland придумал) и т.д. Win32 использует stdcall, поэтому мы все тоже его используем. Напишет Microsoft винду с другим интерфейсом - и нам всем придется использовать именно его. thiscall весьма похож на cdecl, но не на stdcall, поэтому нужно использовать то, что нам диктует Microsoft. 

Автор: DeadSoul 13.5.2006, 12:58
Цитата(GremlinProg @  13.5.2006,  12:42 Найти цитируемый пост)
компилятор можно всегда обмануть и указать любую другую функцию в качестве процедуры окна.

Я бы не рекомендовал это делать 

Автор: GremlinProg 13.5.2006, 13:07
ну, это я утрирую, обмануть - в этом случае значит средствами преобразования адреса, привести его к требуемому виду.
Код

union{
  A a;
  B b;
}myC = {myA};
return myC.b

это тоже преобразование, хотя и не явное. Все по закону, ни какого обмана. 
Аналогично нреобразуются 64-битные адреса в 32-битные. Не может же микрософт сама над собой глумиться. 

Автор: DeadSoul 13.5.2006, 13:19
GremlinProg, в случае с преобразованиями указателей на функции последствия могут быть очень "веселыми". Программа будет падать, а почему это происходит придется искать очень долго 

Автор: GremlinProg 13.5.2006, 13:24
Цитата

Программа будет падать, а почему это происходит придется искать очень долго

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)