Помогите!
Есть класс. В нем создается диалог, через DialogBox. В параметрах указывается процедура обработки сообщений, которая должна быть методом класса. Я ее объявил как static — она работает, но в самой процедуре использовать другие методы (не статические нельзя, т.е. можно, но для этого нужно объявить переменную класса и с ней работать).
Как можно объявить данную процедуру методом класса, чтобы можно было в ней работать как в нормальном методе?
Здравствуйте Maxud, Вы писали:
M>Помогите! M>Есть класс. В нем создается диалог, через DialogBox. В параметрах указывается процедура обработки сообщений, которая должна быть методом класса. Я ее объявил как static — она работает, но в самой процедуре использовать другие методы (не статические нельзя, т.е. можно, но для этого нужно объявить переменную класса и с ней работать). M>Как можно объявить данную процедуру методом класса, чтобы можно было в ней работать как в нормальном методе? :???:
Процедуру — никак, она обязана быть обычной статической функцией.
Но Вам никто не запретит из этой статической функции вызывать метод Вашего класса, только для этого Вам необходимо иметь указатель на экземпляр этого класса (а хранить его можно, например, в области данных самого окна диалога, тогда прямо в это статической функции его можно будет оттуда вытаскивать и вызывать по нему необходимый метод).
Здравствуйте Maxud, Вы писали:
M>Помогите! M>Есть класс. В нем создается диалог, через DialogBox. В параметрах указывается процедура обработки сообщений, которая должна быть методом класса. Я ее объявил как static — она работает, но в самой процедуре использовать другие методы (не статические нельзя, т.е. можно, но для этого нужно объявить переменную класса и с ней работать). M>Как можно объявить данную процедуру методом класса, чтобы можно было в ней работать как в нормальном методе?
Интересное решение. Я обычно использую SetWindowLong()/GetWindowLong(). Но при этом приходится объявлять процедуру как friend, что не всегда возможно. У тебя же в этом плане все честно — то есть, процедура окна является настоящим мембером. Проблема в другом. Насколько это переносимо и компиляторно-зависимо? Будет ли работать с Intel C++ и с g++ под cygwin (я тут случайно обнаружил, что cygwin имеет windows.h и прочие API файлы и виндовые приложения собираются g++ на ура).
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте McSeem2, Вы писали:
MS>Здравствуйте Ed.ward, Вы писали:
MS>[. . .]
EW>>примерно так
MS>Интересное решение. Я обычно использую SetWindowLong()/GetWindowLong(). Но при этом приходится объявлять процедуру как friend, что не всегда возможно. У тебя же в этом плане все честно — то есть, процедура окна является настоящим мембером. Проблема в другом. Насколько это переносимо и компиляторно-зависимо? Будет ли работать с Intel C++ и с g++ под cygwin (я тут случайно обнаружил, что cygwin имеет windows.h и прочие API файлы и виндовые приложения собираются g++ на ура).
По идее это не должно зависить от компилятора, потому как код там на ассемблере
Все это работает только пока вызов функции-члена оформляется так, как это у тебя записано:
EW> addr.method = ( TMFP )method; EW> m_mov = 0xB9; EW> m_this = ( DWORD )pThis; EW> m_jmp = 0xE9; EW> m_relproc = addr.func — ( DWORD )( this + 1 );
Тем не менее в Стандарте ничего такого нет, и нигде не сказано, что this должен неявно идти первым параметром функции. И компилятор может оформлять функции-члены так, как ему заблагорассудится. А твое решение целиком на этом покоится.
Так что если человек сидит под одним компилятором (и под одной его версией) и не собирается никогда компилировать свою программу на других компиляторах/платформах (т.е. сидит дома и пишет для себя и своих друзей), тогда это — приемлемое решение.
Если же ты должен отдать заказчику программу в исходниках — тогда то, что ты автоматически вылетаешь за рамки языка, используя асм, ни к чему хорошему не приведет.
Что еще хуже, такой код не портируем без аналогичного хака.
Кому охота извращаться — кто ж ему запретит?
Я лично предпочту независимое от компилера/платформы решение.
P.S. 2 Ed.ward: Можешь мне за это соoбщение еще один ноль вкатить ;)
Я в курсе, что это из ATL — я сам на ней писал в свое время, к тому же этот хак уже обсуждался в этом форуме.
А в квалификации мелкософтовских программеров я не сомневаюсь — только я не думаю, что они хоть сколько-нибудь озабочены переносимостью, другими компилерами, Стандартом С++ и прочими не относящимися к win32 и .NET вещами.
Здравствуйте jazzer, Вы писали:
J>Здравствуйте Ed.ward, Вы писали:
J>Тем не менее в Стандарте ничего такого нет, и нигде не сказано, что this должен неявно идти первым параметром функции. И компилятор может оформлять функции-члены так, как ему заблагорассудится. А твое решение целиком на этом покоится.
облажался, каюсь, про this, то я позабыл
J>P.S. 2 Ed.ward: Можешь мне за это соoбщение еще один ноль вкатить
ноль я поставил за категоричность "Процедуру — никак, она обязана быть обычной статической функцией."
Человек же не спрашивал про переносимость и совместимость, а ты ему в лоб "никак". Может он пишет исключительно на M$ VC++ и просто мечтал а таком хаке.
а за это сообщение ноль нельзя ставить, это впору мне ноль ставить за предыдущее, потому как неправ.
Здравствуйте Ed.ward, Вы писали:
EW>ноль я поставил за категоричность "Процедуру — никак, она обязана быть обычной статической функцией." EW>Человек же не спрашивал про переносимость и совместимость, а ты ему в лоб "никак". Может он пишет исключительно на M$ VC++ и просто мечтал а таком хаке.
согласен, нужно было написать "никак, если пользоваться только средствами стандартного С++". Потому как бинарная совместимость — за пределами Стандарта.