Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: CALLBACK использование методов класса  (Прочитано 8938 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Гость
Гость
« : 09-10-2003 06:52 » 

Собственно Subj. А если конкретнее то, не подскажет ли достопочтимая публика, как использовать в различных, предлагаемых MFC (WinAPI),методах сортировки и обработчиках событий элементов управления в качестве функции обратного вызова, методы совершенно другого класса. Я понимаю что данная реализация расчитана на стандарт С, но все в мире взаимосвязанно, и при разработке стандартов С++, должна была хотя-бы преусмотренна хотя какая-нибудь реализация для использования разименованных указателей на методы класса. Может ли кто поделиться своими знаниями, а лучше опытом, только не мыслями (их и в других форумах достаточно:). Заранее благодарен и извините за "полет мысли".
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 09-10-2003 07:30 » 

В болшенстве случаев достаточно определить метод класса как static:

static DWORD WINAPI ThreadProcStatic (CPortLpt* lpParam);

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

// пример использования:
CPortLpt::CPortLpt(int nPortType)
{
   // Create a new Thread
   m_hThread = CreateThread(NULL, 0,                 (LPTHREAD_START_ROUTINE)ThreadProcStatic,  //
                        this, 0 ,&m_dwThreadId);
}

Так-же можно использовать глобальные функции:

Пример для сортировки в MFC CListCtrl

static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
...
}


void CMyListCtrl::OnSortItems()
{
       SortItems(MyCompareProc, (LPARAM) pmyListCtrl);
}
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
NetRaider
Гость
« Ответ #2 : 09-10-2003 08:16 » 

Можно так.  Идея наглым образом сперта из ATL Улыбаюсь.

Код:
#include <windows.h>

#pragma pack(push,1)
struct _ProcThunk
{
   DWORD   m_mov;         
   DWORD   m_this;         
   BYTE    m_jmp;         
   DWORD   m_relproc;     
};
#pragma pack(pop)

class ProcThunk
{
public:
union
{
_ProcThunk thunk;
};
void Init(void* proc, void* pThis)
{
thunk.m_mov = 0x042444C7;
thunk.m_this = (DWORD)pThis;
thunk.m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_ProcThunk));
FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk));
}
};

__declspec (naked) void* _cdecl pvoid_cast(...)
{
_asm
{
mov eax, [esp+4]
ret
}
}

class Thread
{
ProcThunk thunk_;
public:
DWORD Worker(void* p)
{
::MessageBox("Thread", "Thread::Worker", 0, 0);
return 0;
}

Thread()
{
thunk_.Init(pvoid_cast(Worker), (void*)this);
}

operator LPTHREAD_START_ROUTINE()
{
return (LPTHREAD_START_ROUTINE)&(thunk_.thunk);
}
};

int main(int argc, char* argv[])
{
Thread t;

HANDLE hThread = CreateThread(NULL, 0, t, NULL, 0, 0 );

WaitForSingleObject(hThread, INFINITE);

return 0;
}

PS Вообще это грязный хак...
« Последнее редактирование: 20-11-2007 17:37 от Алексей1153++ » Записан
Viktor Denk
Участник

de
Offline Offline

« Ответ #3 : 16-10-2003 11:02 » 

Цитата: Джон
В болшенстве случаев достаточно определить метод класса как static:


Da, ja by perefraziroval - v men'shinstve sluchaev. V seti sushchestvuet kakoe - to kolichestvo statej, sejchas u menja ix net pod rukoj, no esli nado to najdu. Ja sdelal eto ne ochen' krasivo, no rabotaet, tak kak static bylo dlja menja ochen' sil'nym ogranicheniem. Vyrezal i privozhu kod, sut' zadachi - v dll chto - to pojavljaetsja i nado dergat' app, nel'zja bylo s pomoshch'ju Win Message i COM - point( poslednee na RSDN xorosho opisano):
// iz DLL
typedef void ( WINCALLBACKBCOM) (int nStatus, int nTracks);

WINCALLBACKBCOM* cb_func;
int openReadDevice( int typ, WINCALLBACKBCOM* cbf, void* param=NULL)
{
   cb_func = NULL;
  if( cbf != NULL)
  {
    cb_func = cbf;
    ...
  }
  else
  {
    ...
  }
  return ...
}

// na App storone: dialog - bazirte prilozhenie
CUsbComAppDlg* own_win = NULL;

volatile int m_err, m_track;

UINT DisconnectThread( LPVOID param)
{
   TRACE("DisconnectThread %d %d\n", m_err, m_track);
   if( own_win != NULL)
   {
      own_win->WorkEvent( m_err, m_track) ;
   }
   return 0;
}
void call_back_event( int err, int track)
{
   TRACE("call_back_event start %d %d\n", err, track);
   m_err = err;
   m_track = track;
   if( own_win != NULL)
   {
      AfxBeginThread( DisconnectThread, NULL);
   }
}

/////////////////////////////////////////////////////////////////////////////
BOOL CUsbComAppDlg::OnInitDialog()
{
   CDialog::OnInitDialog();
   ...
   own_win = this;
  ...
  // otkryvaju dll i zooovy s peredachej
   int err = openReadDevice( 0, call_back_event, NULL);
   return TRUE;  // return TRUE  unless you set the focus to a control
}
void CUsbComAppDlg::WorkEvent( int err, int track)
{
  // chto - to delaju s DLL-Funkcijami
}


Esli chto - to zabyl, to voprosy ili prjamo v mylo.

vetoshkin@lycos.de
Записан

A u nas v Sibiri!
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines