Легенда:
   новое сообщение
    закрытая нитка
    новое сообщение
    в закрытой нитке
    старое сообщение
         
		 | 
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
 - Новичкам также крайне полезно ознакомиться с данным документом.
   
  |   |   | 
Спасибо, посмотрю.  17.12.08 05:42  Число просмотров: 1573
 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 | 
 
| 
 | 
 
| 
<programming>
 |  
 
[c++] можно ли задвинуть callback-функцию в клас?  10.12.08 04:34   [amirul]
 Автор: Vedrus <Serokhvostov Anton> Статус: Member Отредактировано 10.12.08 04:34  Количество правок: 1
 | 
 
Хочу поместить в клас поиск окон при помощи EnumWindows и EnumChildWindows. Потребность в этом вознилка т.к. есть куча вспомогательных переменных (5 штук), которые без использованния класса висят в глобальном определении.
 
 Делаю следующее
 
class CSearchWnd
{
public:
	CSearchWnd();
	HWND SearchPlanetBoard();
private:
	BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam);
	BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
	BOOL bFound;
	BOOL bMoreOne;
	BOOL bTBoardPanel
	BOOL bTBoardGrid;
	BOOL bTMButtonBoard;
	HWND hwndPlanetBoard;
};
 ---
 
 Потом в функции SearchPlanetBoard пытаюсь обратиться к EnumWindowsProc:
 
HWND CSearchWnd::SearchPlanetBoard()
{
	hwndPlanetBoard = NULL;
	EnumWindows(&EnumWindowsProc, 0);
	return hwndPlanetBoard;
}
 ---
 Компилятор ругается, мол "error C2276: '&' : illegal operation on bound member function expression".
 
 Можно ли это как-то вылечить?
 | 
 
 
  | 
Похоже эта тема выходит за рамки моего понимания. Отложу вникание до тех пор, как доросту.  16.12.08 18:58  
 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 | 
 
| 
 | 
 
 
  |   | 
Я кстати привел готовый код. Просто компилируешь,...  17.12.08 05:23  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
| 
Я кстати привел готовый код. Просто компилируешь, расставляешь брейкпоинты и смотришь как это работает. Там все до примитивности просто, как уже заметил Den
 | 
 
 
  |   |   | 
Спасибо, посмотрю.  17.12.08 05:42  
 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 | 
 
| 
 | 
 
 
  |   | 
Да все куда проще...  16.12.08 20:17  
 Автор: Den <Денис Т.> Статус: The Elderman
 | 
 
При вызове функции-мембера объекта ака WIN32API CALLBACK , первым неявным параметром твоя функция ожидает указатель THIS на твой объект, который (указатель) WIN32API передать не в состоянии - "это раз".
 
 Второе - функция CALLBACK должна отвечать соглашению вызова STDCALL.
 | 
 
 
  | 
[C++] задвинуть можно  14.12.08 23:08  
 Автор: void <Grebnev Valery> Статус: Elderman
 | 
 
Может я и не понял что тебя волнует, но есть обычная техника, которая позволяет подружить калбяки  и прочие WINAPI вызовы с так любым сердцу ООП. Можно даже виртуальные функции вызывать:
 
class My_worker{
	static DWORD WINAPI worker_proc(LPVOID lpParam)
	{
		My_worker& worker =reinterpret_cast<My_workergt;(lpParam);
		...
		worker.work() ;
		return 0;
	}
	virtual bool  work(void)=0;
};
 ---
 Прости если не понял, что ты не понял, и написал что тебе не надо или и так известно.
 | 
 
 
  |   |   | 
Сорри, за плагиат. Не суди строго - человеку с около учёным...  15.12.08 06:13  
 Автор: void <Grebnev Valery> Статус: Elderman
 | 
 
> Только я то же самое уже написал здесь > http://bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m= > 152861 :-) Сорри, за плагиат. Не суди строго - человеку с около учёным прошлым избавиться от плагиата - что курильщику брость курить. Вот я до сих пор ни одного и не могу сделать ;-)
 | 
 
 
  |   | 
Это не те коллбэки. Я настаиваю, что в данном случае нужна именно static функция, а не ptr-to-member  10.12.08 11:00  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
Пришлось набыдлокодить примерчик:
 
 #include <windows.h>
#include <iostream>
template<typename T, size_t N>
size_t array_size(T (&arr)[N]) {return N;}
class CWinEnumerator {
public:
	CWinEnumerator() {}
	virtual ~CWinEnumerator() {}
	virtual BOOL EnumWindows() {
		return ::EnumWindows(&EnumWndProc, (LPARAM)this);
	}
private:
	static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam) {
		return ((CWinEnumerator *)lParam)->EnumWindowsProc(hwnd);
	}
	virtual BOOL EnumWindowsProc(HWND hwnd) = 0;
};
class CMyWinEnumerator: public CWinEnumerator {
public:
	CMyWinEnumerator() {}
	virtual ~CMyWinEnumerator() {}
private:
	virtual BOOL EnumWindowsProc(HWND hwnd) {
		WCHAR text[1024];
		::GetWindowText(hwnd, text, (int)array_size(text));
		std::wcout << text << std::endl;
		return TRUE;
	}
};
int
main() {
	CMyWinEnumerator enumerator;
	enumerator.EnumWindows();
	return 0;
} ---
 | 
 
 
  |   |   | 
Да, я просто увидел, что "надо поместить в класс" и подумал об объектах  10.12.08 11:19  
 Автор: Heller <Heller> Статус: Elderman
 | 
 
| 
А сам пост ничитал.
 | 
 
 
  | 
[C++] static (->beginners)  10.12.08 08:53  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
| 
 | 
 
 
  |   | 
[C++] Если функцию статиком обозвать, то и переменные тоже придётся, а надо чтобы в разных экзмеплярах класса они разные были, поэтому статик не пойдёт.  10.12.08 11:55  
 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 | 
 
| 
 | 
 
 
  |   |   | 
[C++] Пойдет-пойдет. Еще как пойдет  10.12.08 11:59  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
| 
Это только для SetTimer и прочих вызовов, которые не позволяют передать opaque указатель нужно городить отдельный огород (в самых запущенных случаях - приходится генерить заглушки для каждого коллбека, чтоб хоть как то их отличать). А в случае EnumWindows - все тривиально.
 | 
 
 
  |   |   |   | 
Если тривиально, то приведённый мной выше код должен...  11.12.08 12:20  
 Автор: Vedrus <Serokhvostov Anton> Статус: Member
 | 
 
| 
Если тривиально, то приведённый мной выше код должен работать, а он не работает.
 | 
 
 
  |   |   |   |   | 
Эх. Вот этим и отличается понимание от зазубривания  11.12.08 21:17  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
> Если тривиально, то приведённый мной выше код должен > работать, а он не работает. 
 Не должен он работать. Даже если не закапываться в дебри стандартов и несовместимых calling convention-ов, то просто банальная логика должна подсказать, что нестатический метод класса ВСЕГДА вызывается для какого либо объекта. Причем объект этот при вызове метода из внешнего по отношению к классу кода ВСЕГДА указывается ЯВНО. Для какого объекта будет вызываться метод в случае с коллбеком?
 | 
 
 
  
 
 | 
 |