#include <iostream>
#include <Windows.h>
#include <process.h>
#include "Thunk.h"
#include "resource.h"
using namespace std;

/////////////////////////////////////////////////////////
//第一个:__cdecl 回调类型
/////////////////////////////////////////////////////////

typedef int (__cdecl* CB)(int n);

void output(CB cb)
{
	for(int i=0; i<3; i++){
		cb(i);
	}
}

class ACDCEL
{
public:
	ACDCEL()
	{
		void* pthunk = m_Thunk.Cdeclcall(this,&ACDCEL::callback);
		::output(CB(pthunk));
	}

private:
	int __cdecl callback(int n)
	{
		cout<<"n:"<<n<<endl;
		return n;
	}

private:
	AThunk m_Thunk;
};

/////////////////////////////////////////////////////////
//第二个:__stdcall 回调类型:封装窗口类
/////////////////////////////////////////////////////////
class ASTDCALL
{
public:
	ASTDCALL()
	{
		void* pthunk = m_Thunk.Stdcall(this,&ASTDCALL::DialogProc);
		DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)pthunk,0);
	}
	
private:
	INT_PTR CALLBACK DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		switch(uMsg)
		{
		case WM_CLOSE:
			EndDialog(hWnd,0);
			return 0;
		}
		return 0;
	}
private:
	AThunk m_Thunk;
};

/////////////////////////////////////////////////////////
//第三个:__stdcall 回调类型:内部线程
/////////////////////////////////////////////////////////
class AThread
{
public:
	AThread()
	{
		void* pthunk = m_Thunk.Stdcall(this,&AThread::ThreadProc);
		HANDLE handle = (HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall*)(void*))pthunk,(void*)5,0,NULL);
		WaitForSingleObject(handle,INFINITE);
		CloseHandle(handle);
	}
	
private:
	unsigned int __stdcall ThreadProc(void* pv)
	{
		int i = (int)pv;
		while(i--){
			cout<<"i="<<i<<endl;
		}
		return 0;
	}
private:
	AThunk m_Thunk;
};

int main(void)
{
	ASTDCALL as;
	ACDCEL ac;
	cout<<endl;
	AThread at;
	return 0;
}
