Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.11.2009, 07:45   #1
Ivan_32
somewhere else
Участник клуба
 
Аватар для Ivan_32
 
Регистрация: 17.07.2008
Сообщений: 1,409
По умолчанию Проблема с суб-классированием в классе

Делаю свой класс для работы с контролами. В числе фич числится сабклассинг процедуры. Собственно все вроде бы уже сделано(правдами и неправдами) но настораживает вот что:
В режиме отладки вылетает вот такая штука: "Необработанное исключение в "0xbaadf00d" в "_HKP.exe": 0xC0000005: Access violation." - тогда как если просто запустить проект то ничего не случится, программа работает без нареканий, но настораживает одна вещь, судя по всему новая процедура установки сообщений просто не устанавливается:
Код:
LRESULT WINAPI messageHandler(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
	{	
		MessageBox(hWnd,L"Proc",0,0);
		return CallWindowProc(original,hWnd,message,wParam,lParam);
	};
Я должен был бы увидеть массу MessageBox-ов, но их собственно говоря нет, ни одного.

Что может быть не так с моим классом?

Код:
class Control
class Control
{
public:
	HWND hHandle;
	UINT ucID;
	LRESULT (*customProc)(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
	LRESULT (CALLBACK* original)(HWND, UINT, WPARAM, LPARAM);
	LRESULT WINAPI messageHandler(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
	{	
		MessageBox(hWnd,L"Proc",0,0);
		return CallWindowProc(original,hWnd,message,wParam,lParam);
	};
	static const void InitControl()
	{
		counter=1000;
	}
	Control(HWND hParent,LPUSTR lpClassName,LPUSTR lpName,DWORD wStyle,int x,int y,int w,int h)
	{
		DWORD wss=wStyle|WS_VISIBLE|WS_CHILD;
		this->hHandle=CreateWindow(lpClassName,lpName,wss,\
			x,y,w,h,hParent,(HMENU)counter,0,0);
		SendMessage(this->hHandle,WM_SETFONT,(WPARAM)hFont,0);
		InvalidateRect(this->hHandle,0,true);
		this->original=(WNDPROC)GetWindowLong(this->hHandle,GWL_WNDPROC);
		SetWindowLong(this->hHandle,GWL_WNDPROC,(LONG)this->customProc);
		if((int)original!=NULL)
		MessageBox(0,L"Constructor",0,0);
		ucID=counter++;		
	}
	~Control()
	{
		DestroyWindow(this->hHandle);
	}
};
PS: Если нужно, могу привести весь листинг программы.
PPS: Нет все таки этот ООП явно от лукавого - столько нервов уже потратил, а ради чего спрашивается...
"Тяжело в учении, легко в бою" - А.В. Суворов

Последний раз редактировалось Stilet; 30.11.2009 в 12:46.
Ivan_32 вне форума Ответить с цитированием
Старый 30.11.2009, 12:30   #2
lennon
Заблокирован
 
Регистрация: 18.11.2007
Сообщений: 254
По умолчанию

весь листинг, а лучше всего файлы проекта, если это VS
Цитата:
но настораживает одна вещь, судя по всему новая процедура установки сообщений просто не устанавливается
В примеведенном вами коде, messageHandler нигде не используеться, тогда с чего бы ему устанавливаться? хотя может быть я чегото недосмотрел
lennon вне форума Ответить с цитированием
Старый 30.11.2009, 13:26   #3
Ivan_32
somewhere else
Участник клуба
 
Аватар для Ivan_32
 
Регистрация: 17.07.2008
Сообщений: 1,409
По умолчанию

Да тут я ошибся немного Потому то оно собственно и скомпилировалось.
На эту строку:
PHP код:
SetWindowLong(this->hHandle,GWL_WNDPROC,(LONG)this->messageHandler); 
Компилятор реагирует очень резко:
main.cpp(64) : error C2440: приведение типов: невозможно преобразовать 'LRESULT (__stdcall Control::* )(HWND,UINT,WPARAM,LPARAM)' в 'LONG'
1> Не существует контекста, в котором такое преобразование возможно
Вложения
Тип файла: rar _HKP.rar (139.4 Кб, 7 просмотров)
"Тяжело в учении, легко в бою" - А.В. Суворов
Ivan_32 вне форума Ответить с цитированием
Старый 30.11.2009, 14:06   #4
lennon
Заблокирован
 
Регистрация: 18.11.2007
Сообщений: 254
По умолчанию

все правильно ) должно ругаться =) ищите класс FastDelegate, он вам поможет.
дело в том, что так дял компилтора выглядит ваша функция
LRESULT WINAPI Control::messageHandler(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
а аргумент функции требует LRESULT WINAPI messageHandler(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
вам нужно адресс функции, но компилятор все равно будет ругаться. А если вы все таки решите сделать приведение типов (между функциями) то вас поджидает ошибка с памятью.

SetWindowLong системная процедура... забудьте про FastDelegate, щас помогу

Последний раз редактировалось Stilet; 30.11.2009 в 14:28.
lennon вне форума Ответить с цитированием
Старый 30.11.2009, 14:38   #5
lennon
Заблокирован
 
Регистрация: 18.11.2007
Сообщений: 254
По умолчанию

Код:
class Control
{
public:
	HWND hHandle;
	UINT ucID;
	LRESULT (*customProc)(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
	LRESULT (CALLBACK* original)(HWND, UINT, WPARAM, LPARAM);

	typedef LRESULT (WINAPI Control::*FuncPtr)(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

	LRESULT WINAPI messageHandler(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
	{	
		return CallWindowProc(original,hWnd,message,wParam,lParam);
	}

	Control()
	{
		FuncPtr ptr = &Control::messageHandler;
		SetWindowLong(this->hHandle,GWL_WNDPROC,(DWORD)&ptr);
	}
	~Control()
	{
		DestroyWindow(this->hHandle);
	}
};
компилируеться, должно работать.
lennon вне форума Ответить с цитированием
Старый 30.11.2009, 15:01   #6
Ivan_32
somewhere else
Участник клуба
 
Аватар для Ivan_32
 
Регистрация: 17.07.2008
Сообщений: 1,409
По умолчанию

По сути проблема в том что в данном контексте оно не может найти адрес функции?(вот бред то... взял смещение от начала объект и все замечательно...) А что если пронаследовать класс от интерфейса с набором нужных функций - тогда проблема исчезнет? (вот уж не знаю каким боком это поможет...)

С моим линкером что то явно не так:

Код:
virtual class A
{
public:
	virtual LRESULT WINAPI messageHandler(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
};
error LNK2001: неразрешенный внешний символ ""public: virtual long __stdcall A::messageHandler(struct HWND__ *,unsigned int,unsigned int,long)" (?messageHandler@A@@UAGJPAUHWND__@@ IIJ@Z)"

С моим линкером явно уже что то не так... с чего бы это он не принимает функцию из интерфейса? Кстати даже если убрать реализацию функции - проблема не исчезнет. Да кстати он вылетает через раз - началось это на Win 7 уже.


UPDATE: Огромное спасибо
UPDATE2:
Точно так как вы и говорили - 0xC000005 , наверно мне лучше оставить эту затею с ООП - не мое это явно
"Тяжело в учении, легко в бою" - А.В. Суворов

Последний раз редактировалось Ivan_32; 30.11.2009 в 15:06.
Ivan_32 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
pointeur на функцию в классе ciaonataha Общие вопросы C/C++ 11 21.04.2009 15:25
Динамическое создание "суб-меню" из файлов в заданном каталоге Abhorrer Общие вопросы Delphi 5 14.03.2009 21:47
константность в классе softrix Общие вопросы C/C++ 1 17.06.2008 00:21
Экзамен в 9 классе по ИВТ NecRoMat Свободное общение 6 11.06.2008 11:56