В VC++.NET явное преобразавание вообще не проходит, при...19.09.04 07:28 Число просмотров: 1517 Автор: makeworld Статус: Member Отредактировано 19.09.04 07:33 Количество правок: 1
> > можно сделать static-членом, а при желании оформить > > функцию-член-класса совместимой по > > формату-вызова/параметрам и сделать наглон > преобразование > > типа wndclassex.lpfn = > (WNDPROC)((void*)MYCLASS::myfunc) > Потому как наглое явное преобразование чревато большими > проблемами, если случайно захочется обратиться через этот > самый this к членам-данным или попробовать вызывать > функции-члены.
В VC++.NET явное преобразование вообще не проходит, при сборке выдается ошибка
Если сделать функцию обработки сообщений окна членом класса, то при создании класса окна (имеется ввиду WNDCLASSEX) выдается ошибка на строчке wndclassex.lpfnWndProc = WinProc
error C2440: '=' : cannot convert from 'LRESULT (__stdcall MYCLASS::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
(окно создается с помощью функции CreateWindowsEx, соответственно для этого окна регистрируется класс функцией RegisterClassEx, где и происходит ошибка)
Видимо потому, что каждому элементу С++ класса неявно передается дополнительный параметр this и соответственно эта функция, являяся элементом класса, под тип WNDPROC не подходит.
Так вот, можно ли как-нибудь функцию обработки сообщений окна сделать членом класса?
членом класса нет, а вот friend'ом - можно13.09.04 09:51 Автор: Killer{R} <Dmitry> Статус: Elderman
А установив SetWindowLong(hwnd,GWL_USERDATA,(DWORD)this) при создании окна в конкретном экземляре и делая GetWindowLong(hwnd,GWL_USERDATA) в оконной процедуре можно работать со "своим" объектом в процедуре.
можно сделать static-членом...13.09.04 13:37 Автор: leo <Леонид Юрьев> Статус: Elderman
можно сделать static-членом, а при желании оформить функцию-член-класса совместимой по формату-вызова/параметрам и сделать наглон преобразование типа wndclassex.lpfn = (WNDPROC)((void*)MYCLASS::myfunc)
Лучше всего делать static-ом18.09.04 15:03 Автор: amirul <Serge> Статус: The Elderman
> можно сделать static-членом, а при желании оформить > функцию-член-класса совместимой по > формату-вызова/параметрам и сделать наглон преобразование > типа wndclassex.lpfn = (WNDPROC)((void*)MYCLASS::myfunc) Потому как наглое явное преобразование чревато большими проблемами, если случайно захочется обратиться через этот самый this к членам-данным или попробовать вызывать функции-члены.
static метод класса может обращаться только к static...20.09.04 07:24 Автор: makeworld Статус: Member Отредактировано 20.09.04 07:25 Количество правок: 1
> > можно сделать static-членом, а при желании оформить > > функцию-член-класса совместимой по > > формату-вызова/параметрам и сделать наглон > преобразование > > типа wndclassex.lpfn = > (WNDPROC)((void*)MYCLASS::myfunc) > Потому как наглое явное преобразование чревато большими > проблемами, если случайно захочется обратиться через этот > самый this к членам-данным или попробовать вызывать > функции-члены. static метод класса может обращаться только к static переменным, а мне нужно из этой функции иметь доступ к некоторым переменным внутри класса. или есть способ из static метода обратиться к обычным переменным?
К сказанному Ktirf-ом добавлю22.09.04 10:15 Автор: amirul <Serge> Статус: The Elderman
> static метод класса может обращаться только к static > переменным, а мне нужно из этой функции иметь доступ к > некоторым переменным внутри класса. или есть способ из > static метода обратиться к обычным переменным? Что если ты объявишь обычную функцию-член (как __thiscall), а потом внаглую приведешь ее тип к __stdcall, то обращаться к переменным-членам все равно не сможешь. Все обращения к переменным идут неявно через this (то бишь m_Var = 10; эквивалентно this->m_Var = 10;), а если в этом this (который в том же VC передается через ecx) будет мусор, то и обращения будут в никуда. Лучше уж сразу от них отказаться.
Re: К сказанному Ktirf-ом добавлю22.09.04 15:09 Автор: leo <Леонид Юрьев> Статус: Elderman
> Что если ты объявишь обычную функцию-член (как __thiscall), > а потом внаглую приведешь ее тип к __stdcall, то обращаться > к переменным-членам все равно не сможешь. Все обращения к > переменным идут неявно через this (то бишь m_Var = 10; > эквивалентно this->m_Var = 10;), а если в этом this > (который в том же VC передается через ecx) будет мусор, то > и обращения будут в никуда. Лучше уж сразу от них > отказаться.
Конечно, если так прыгать на грабли :-)
Но можно просто объявить функцию-член как __stdcall, и всё будет хорошо если конечно this одинарный(sizeof(this) == sizeof(void*)). Сложный this может быть при множественном и/или виртуальном наследовании, но такую ситуацию можно поймать используя #pragma pointers_to_members(...).
Обычно это делается прокидыванием указателя на объект через параметры статического метода.20.09.04 11:52 Автор: Ktirf <Æ Rusakov> Статус: Elderman
Также хочу напомнить, что имея HWND, можно получить указатель на CWnd, а из него воспользовавшись динамическим приведением типа - указатель на объект нужного класса.
В VC++.NET явное преобразавание вообще не проходит, при...19.09.04 07:28 Автор: makeworld Статус: Member Отредактировано 19.09.04 07:33 Количество правок: 1
> > можно сделать static-членом, а при желании оформить > > функцию-член-класса совместимой по > > формату-вызова/параметрам и сделать наглон > преобразование > > типа wndclassex.lpfn = > (WNDPROC)((void*)MYCLASS::myfunc) > Потому как наглое явное преобразование чревато большими > проблемами, если случайно захочется обратиться через этот > самый this к членам-данным или попробовать вызывать > функции-члены.
В VC++.NET явное преобразование вообще не проходит, при сборке выдается ошибка
Если нельзя, но очень хочется,22.09.04 10:24 Автор: amirul <Serge> Статус: The Elderman
> В VC++.NET явное преобразование вообще не проходит, при > сборке выдается ошибка Дело в том, что большинство C-style преобразований понимаются компилятором как static_cast (кроме выкидывания спецификатора const, который const_cast). Если уж очень хочется выстрелить себе в ногу, можешь попробовать reinterpret_cast, или прокинуть указатель через (void *).