﻿#include "LuaDll.h"
#include "lua_dll_resource.h"
#include <process.h> // _beginthreadex
#include "CommCtrl.h"
#define GSTR_APPNAME    ("lua_gdb_test")

extern HWND hGwnd;
extern HINSTANCE hInstanceDll;
HWND hwndDllDlg;
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#include <vector>
// extern bool(*chkIsDlgMsg)(MSG *msg);
std::vector<HWND>  hWnd_vec;
bool checkIsDialogMessage(MSG *msg){
	int sz = hWnd_vec.size();
	for (int i = 0; i<sz; i++){
		if (hWnd_vec[i] && IsDialogMessage(hWnd_vec[i], msg))
			return true;
	}
	return false;
}

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static bool tracebackEnabled = true;

// HWND hwndDlg = NULL;
static lua_State *luaState = NULL;

void luaDll_get_State(lua_State *L){
	luaState = L;
}

inline void raise_error(lua_State *L, const char *errMsg = NULL){
	luaL_where(L, 1);
	if (errMsg){
		lua_pushstring(L, errMsg);
	} else {
		lua_insert(L, -2);
	}
	lua_concat(L, 2);
	lua_error(L);
}

static int cf_setCheckIsDialogMessage(lua_State *L){
	const int selfArg = 0;
	if (lua_isinteger(L, selfArg + 1)){
		lua_Integer  addrOfChkIsDlgMsg = luaL_checkinteger(L, selfArg + 1);
		*(bool(**)(MSG *))addrOfChkIsDlgMsg = checkIsDialogMessage;
		// *(void **)addrOfChkIsDlgMsg = (void *)checkIsDialogMessage;
	} else {
		raise_error(L, "String argument required for property access");
	}
	return 0;
}

static int cf_vec_metatable_erase(lua_State *L){
	const int selfArg = 0;
	if (lua_isinteger(L, selfArg + 1)){
		int i = luaL_checkinteger(L, selfArg + 1);
		if (lua_isinteger(L, selfArg + 2)){
			int j = luaL_checkinteger(L, selfArg + 2);
			hWnd_vec.erase(hWnd_vec.begin()+i, hWnd_vec.begin()+j);
		}
		else{
			hWnd_vec.erase(hWnd_vec.begin()+i);
		}
	} else {
		raise_error(L, "String argument required for property access");
	}
	return 0;
}
static int cf_vec_metatable_size(lua_State *L){
	//const int selfArg = lua_isuserdata(L, 1) ? 1 : 0;
	lua_pushinteger(L, (lua_Integer)hWnd_vec.size());
	return 1;
}

static int cf_vec_metatable_clear(lua_State *L){
	hWnd_vec.clear();
	return 0;
}

static int cf_vec_metatable_insert(lua_State *L){
	//const int selfArg = lua_isuserdata(L, 1) ? 1 : 0;
	const int selfArg = 0;
	if (lua_isinteger(L, selfArg + 1)){
		int i = luaL_checkinteger(L, selfArg + 1);
		hWnd_vec.insert(hWnd_vec.begin()+i, (HWND)luaL_checkinteger(L, selfArg + 2));
	} else {
		raise_error(L, "String argument required for property access");
	}
	return 0;
}

static int cf_vec_metatable_index(lua_State *L){
	// const int selfArg = lua_isuserdata(L, 1) ? 1 : 0;
	const int selfArg = 1;
	if (lua_isinteger(L, selfArg + 1)){
		int i = luaL_checkinteger(L, selfArg + 1);
		if (i < hWnd_vec.size()){
			lua_pushinteger(L, (lua_Integer)hWnd_vec[i]);
			return 1;
		}
		else{
			raise_error(L, "array index is out of range");
		}
	} else {
		raise_error(L, "String argument required for property access");
	}
	return 0;
}

static int cf_vec_metatable_newindex(lua_State *L){
	const int selfArg = lua_isuserdata(L, 1)? 1 : 0;
	int i = lua_isinteger(L, selfArg + 1)? luaL_checkinteger(L, selfArg + 1): 0;
	HWND v = (HWND)luaL_checkinteger(L, selfArg + 2);
	
	if (lua_isnil(L, selfArg + 2)){
		hWnd_vec[i] = NULL;
	}else{
		hWnd_vec[i] = v;
	}
	return 0;
}

static bool call_function(lua_State *L, int nargs, bool ignoreFunctionReturnValue = false){
	bool handled = false;
	if (L){
		int traceback = 0;
		if (tracebackEnabled){
			lua_getglobal(L, "debug");
			lua_getfield(L, -1, "traceback");
			lua_remove(L, -2);
			if (lua_isfunction(L, -1)){
				traceback = lua_gettop(L)- nargs - 1;
				lua_insert(L, traceback);
			} else {
				lua_pop(L, 1);
			}
		}
		
		const int result = lua_pcall(L, nargs, ignoreFunctionReturnValue ? 0 : 1, traceback);
		
		if (traceback){
			lua_remove(L, traceback);
		}
		
		if (0 == result){
			if (ignoreFunctionReturnValue){
				handled = true;
			} else {
				handled = (0 != lua_toboolean(L, -1));
				lua_pop(L, 1);
			}
		} else if (result == LUA_ERRRUN){
			lua_getglobal(L, "print");
			lua_insert(L, -2); // use pushed error message
			lua_pcall(L, 1, 0, 0);
		} else {
			lua_pop(L, 1);
			lua_getglobal(L, "print");
			if (result == LUA_ERRMEM){
				// host->Trace("> Lua: memory allocation error\n");
				lua_pushstring(L, "> Lua: memory allocation error\n");
			} else if (result == LUA_ERRERR){
				// host->Trace("> Lua: an error occurred, but cannot be reported due to failure in _TRACEBACK\n");
				lua_pushstring(L, "> Lua: an error occurred, but cannot be reported due to failure in _TRACEBACK\n");
			} else {
				// host->Trace("> Lua: unexpected error\n");
				lua_pushstring(L, "> Lua: unexpected error\n");
			}
			lua_pcall(L, 1, 0, 0);
			
		}
	}
	return handled;
}
static bool CallNamedFunction(const char *name, lua_Integer numberArg, const char *stringArg2){
	bool handled = false;
	if (luaState){
		lua_getglobal(luaState, name);
		if (lua_isfunction(luaState, -1)){
			lua_pushinteger(luaState, numberArg);
			lua_pushstring(luaState, stringArg2);
			handled = call_function(luaState, 2);
		} else {
			lua_pop(luaState, 1);
		}
	}
	return handled;
}
typedef struct {
	HANDLE hEvent;
	HANDLE hEvent2;
	HANDLE hThread;
	HINSTANCE hInstance;
	HWND hGwnd;
	HWND hwndDlg;
	HWND hCombo;
	HWND hwndButton;
	lua_State *luaState;
	
} SJumpDialogParam;

static unsigned __stdcall JumpDialogProc( LPVOID lpParameter )
{
	SJumpDialogParam* pParam = (SJumpDialogParam*) lpParameter;
	pParam->hGwnd = hGwnd;
	
	MSG msg;
	CLuaDll cDlg;
	HWND hwndDlg = cDlg.DoModeless(pParam->hInstance, NULL, IDD_LINE_JUMP); // エディタビジーでも表示できるよう、親を指定しない   pParam->hGwnd
	pParam->hwndDlg = hwndDlg;
	pParam->hCombo = GetDlgItem(hwndDlg, IDC_COMBO1);
	pParam->hwndButton = GetDlgItem(hwndDlg, ID_WORK);
	SetEvent(pParam->hEvent);
	pParam->luaState=NULL;
	for(;;){
		DWORD dwResult = MsgWaitForMultipleObjects( 1, &pParam->hEvent2, FALSE, INFINITE, QS_ALLINPUT );
		if(dwResult == WAIT_OBJECT_0){
			ResetEvent(pParam->hEvent2);
			//「WAIT_OBJECT_0」はMsgWaitForMultipleObjects()関数の戻り値を判定するための定数です。
			// 戻り値が「WAIT_OBJECT_0+ハンドル数」より小さいとき、
			// イベントオブジェクトがシグナルになったことを示します。
			::SendMessage( hwndDlg, WM_COMMAND, ID_CLOSE, 0 );
		}else if(dwResult == WAIT_OBJECT_0+1){
			// また戻り値が「WAIT_OBJECT_0+ハンドル数」に等しいときは、
			// MsgWaitForMultipleObjects()関数がスレッドメッセージを受け取ったことを示します。
			while(::PeekMessage(&msg , NULL , 0 , 0, PM_REMOVE )){
				if(cDlg.GetHwnd() != NULL && ::IsDialogMessage(cDlg.GetHwnd(), &msg)){
				}else{
					::TranslateMessage(&msg);
					::DispatchMessage(&msg);
				}
			}
		}else{
			//MsgWaitForMultipleObjectsに与えたハンドルのエラー
			if (  pParam->luaState ){
				lua_settop(pParam->luaState, 0);
				lua_getglobal(pParam->luaState, "print");
				lua_pushstring(pParam->luaState, "> MsgWaitForMultipleObjectsに与えたハンドルのエラー\n");
				lua_pcall(pParam->luaState, 1, 0, 0);
			}
			break;
		}
		if( cDlg.GetHwnd()  == NULL){
			// OutputDebugString(_T("Close\n"));
			/*
			if (  pParam->luaState ){
				lua_settop(pParam->luaState, 0);
				lua_getglobal(pParam->luaState, "print");
				lua_pushstring(pParam->luaState, "Close\n");
				lua_pcall(pParam->luaState, 1, 0, 0);
			}
			*/
			break;
		}
	}
	SetEvent(pParam->hEvent);
	::CloseHandle(pParam->hThread);
	::CloseHandle(pParam->hEvent);
	::CloseHandle(pParam->hEvent2);
	delete pParam;
	return 0;
}
#ifdef _M_AMD64
#define GWL_HINSTANCE	GWLP_HINSTANCE
#endif

#ifdef __cplusplus
extern "C" {
	static int luaB_t1b1_close(lua_State *L)
	{
		int type = lua_type(L, 1);
		if (type == LUA_TNUMBER){
			SJumpDialogParam *gpsThreadParam= (SJumpDialogParam*)luaL_checkinteger(L, 1);
			gpsThreadParam->luaState=L;
			SetEvent(gpsThreadParam->hEvent2);
			WaitForSingleObject(gpsThreadParam->hEvent, INFINITE);
		}
		else{
			raise_error(L, "parameter not for gpsThreadParam");
		}
		return 0;
	}
	static int luaB_t1b1(lua_State *L)
	{
		
		int i, j, n, m;
		
		DWORD dwIndex;
		char achTemp[256];
		n = lua_gettop(L);
		// dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM)achTemp);  hInst
		
		CLuaDll cDlg;
		
		// ダイアログタイトルとファイル名を設定
		luaL_checktype(L, 1, LUA_TTABLE);
		/*
		lua_getfield(L, 1, "hWndDlg");
		lua_getfield(L, 1, "hCombo");
		lua_getfield(L, 1, "hwndButton");
		hwndDlg =luaL_checkinteger(L, -3) 
		hCombo =luaL_checkinteger(L, -2) 
		hwndButton =luaL_checkinteger(L, -1) 
		if ( luaL_checkinteger(L, -1) == 0){
		}
		*/
		HINSTANCE hInst = GetModuleHandle(NULL);
		// HWND hGwnd = GetForegroundWindow();
		// hGwnd = NULL;
		// HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hGwnd, GWL_HINSTANCE);
		GetWindowText(hGwnd, achTemp, 256);
		unsigned int nThreadId = 0;
		// MessageBox(NULL, achTemp, "DoGetForegroundWindow1", MB_OK);

		SJumpDialogParam   *gpsThreadParam= new  SJumpDialogParam();
		
		
		
		gpsThreadParam->hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
		gpsThreadParam->hEvent2 = ::CreateEvent(NULL, TRUE, FALSE, NULL);
		// ResetEvent(gsThreadParam.hEvent);
		gpsThreadParam->hInstance  = hInstanceDll;
		gpsThreadParam->hThread = (HANDLE)_beginthreadex(NULL, 0, JumpDialogProc, (LPVOID)gpsThreadParam, 0, &nThreadId);
		WaitForSingleObject(gpsThreadParam->hEvent, INFINITE);
		ResetEvent(gpsThreadParam->hEvent);
		
		lua_getfield(L, 1, "dlg");
		lua_getfield(L, 1, "button");
		lua_getfield(L, 1, "show_idx");
		
		
		for (i = 2; i <= n; i++){
			int type = lua_type(L, i);
			if (type == LUA_TTABLE){
				m = luaL_len(L, i);
				for (j = 1; j <= m; j++){
					lua_geti(L, i, j); /* push t[j] */
					int type2 = lua_type(L, -1);
					if (type2 == LUA_TSTRING){
						
						SendMessage(gpsThreadParam->hCombo, CB_ADDSTRING, 0, (LPARAM)lua_tostring(L, -1));
					}
					else if (type2 == LUA_TNUMBER){
						sprintf(achTemp, "%d", luaL_checkinteger(L, -1));
						SendMessage(gpsThreadParam->hCombo, CB_ADDSTRING, 0, (LPARAM)achTemp);
					}
					lua_remove(L, -1);
				}
			}
			else if (type == LUA_TSTRING){
				SendMessage(gpsThreadParam->hCombo, CB_ADDSTRING, 0, (LPARAM)lua_tostring(L, i));
				
			}
			else if (type == LUA_TNUMBER){
				sprintf(achTemp, "%d", luaL_checkinteger(L, i));
				SendMessage(gpsThreadParam->hCombo, CB_ADDSTRING, 0, (LPARAM)lua_tostring(L, i));
			}
		}
		::SendMessage(gpsThreadParam->hwndDlg, WM_SETTEXT, 0, (LPARAM)lua_tostring(L, -3));
		::SendMessage(gpsThreadParam->hwndButton, WM_SETTEXT, 0, (LPARAM)lua_tostring(L, -2));
		::SendDlgItemMessage(gpsThreadParam->hwndDlg, IDC_COMBO1, CB_SETCURSEL, luaL_checkinteger(L, -1), 0);
		::SendMessage(gpsThreadParam->hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(gpsThreadParam->hwndDlg, IDC_COMBO1), TRUE);
		
		lua_settop(L, 0);
		lua_createtable(L, 0, 4);
		lua_pushinteger(L, (lua_Integer)hGwnd);
		lua_setfield(L, -2, "hGwnd");
		lua_pushinteger(L, (lua_Integer)gpsThreadParam->hInstance);
		lua_setfield(L, -2, "hInstance");
		lua_pushinteger(L, (lua_Integer)gpsThreadParam->hwndDlg);
		lua_setfield(L, -2, "hWndDlg");
		lua_pushinteger(L, (lua_Integer)gpsThreadParam->hCombo);
		lua_setfield(L, -2, "hCombo");
		lua_pushinteger(L, (lua_Integer)gpsThreadParam->hwndButton);
		lua_setfield(L, -2, "hwndButton");
		lua_pushinteger(L, (lua_Integer)gpsThreadParam);
		lua_setfield(L, -2, "gpsThreadParam");
		luaDll_get_State(L);
		return 1;
	}
	
	extern int cf_hWnds_vec_init(lua_State *L){
		lua_getglobal(L, "spawner");
		if (lua_isnil(L, -1)){
			lua_pop(L, 1);
			lua_newtable(L);
		}
		lua_pushcfunction(L, luaB_t1b1);
		lua_setfield(L, -2, "dlgTextButton");
		lua_pushcfunction(L, luaB_t1b1_close);
		lua_setfield(L, -2, "dlgTextButtonClose");
		lua_pushcfunction(L, cf_setCheckIsDialogMessage);
		lua_setfield(L, -2, "setChkIsDlgMsg");
		lua_newuserdata(L, 1); // the value doesn't matter.             //   {}  ⇒ { u(1) } ;     
		// lua_createtable(L, 0, 0);
		if (luaL_newmetatable(L, "hWnd_meta1")){                        //   { u(1) }  ⇒ { meta , u(1) } ;                            
			
			lua_pushcfunction(L, cf_vec_metatable_size); //   { meta , u(1) }  ⇒ { in, meta , u(1) } ;            
			lua_setfield(L, -2, "size"); //  { size, meta , u(1) }  ⇒ {  meta , u(1) } ;meta{size}     
			
			lua_pushcfunction(L, cf_vec_metatable_clear); //   {  meta , u(1) } ;meta{size}   ⇒ { clear, meta , u(1) } ;meta{size};       
			lua_setfield(L, -2, "clear"); //  { clear, meta , u(1) } ;meta{size}   ⇒ {  meta , u(1) } ;meta{size,clear}   
			
			lua_pushcfunction(L, cf_vec_metatable_insert); //   {  meta , u(1) } ;meta{size,clear}  ⇒ { insert,  meta , u(1) } ;meta{size,clear};   
			lua_setfield(L, -2, "insert"); //  { insert,  meta , u(1) } ;meta{size,clear} ⇒ { meta , u(1) } ;meta{insert,size,clear}   
			
			lua_pushcfunction(L, cf_vec_metatable_erase); //   { meta , u(1) }  ⇒ { in, meta , u(1) } ;            
			lua_setfield(L, -2, "erase"); //  { size, meta , u(1) }  ⇒ {  meta , u(1) } ;meta{size}     
			
			lua_pushvalue(L, -1); //  { meta , u(1) } ;meta{insert,size,clear} ⇒  { meta, meta , u(1) } ;meta{insert,size,clear} 
			lua_setfield(L, -2, "__index"); //  { meta1, meta1 , u(1) } ;meta{insert,size,clear} ⇒ { meta1 , u(1) } ;meta1{__index=self,insert,size,clear}
			if (luaL_newmetatable(L, "hWnd_meta2")){                     //  { meta1 , u(1) } ;meta1{__index=self,insert,size,clear}  ⇒  { meta2, meta1 , u(1) } ;meta1{__index=self,insert,size,clear}
				lua_pushcfunction(L, cf_vec_metatable_index); //  { meta2, meta1 , u(1) } ;meta1{__index=self,insert,size,clear}   ⇒  { in. meta2, meta1 , u(1) } ;meta1{__index=self,insert,size,clear} 
				lua_setfield(L, -2, "__index"); //  { in. meta2, meta1 , u(1) } ;meta1{__index=self,insert,size,clear}  ⇒ { meta2, meta1 , u(1) } ;meta1{__index=self,insert,size,clear};meta2{__index=in}
			}
			lua_setmetatable(L, -2); //   { meta2, meta1 , u(1) } ;meta1{__index=self,insert,size,clear};meta2{__index=in} ⇒ { meta1 , u(1) } ;meta1{ meta=meta2{__index=in},__index=self,insert,size,clear};
			lua_pushcfunction(L, cf_vec_metatable_newindex); //  { meta1 , u(1) } ;meta1{ meta=meta2{__index=in},__index=self,insert,size,clear}; ⇒ { nin,meta1 , u(1) } ;meta1{ meta=meta2{__index=in},__index=self,insert,size,clear};
			lua_setfield(L, -2, "__newindex"); //  { nin,meta1 , u(1) } ;meta1{ meta=meta2{__index=in},__index=self,insert,size,clear}; ⇒ { meta1 , u(1) } ;meta1{ meta=meta2{__index=in},__index=self,__newindex=nin,insert,size,clear};   
			
		}
		lua_setmetatable(L, -2); //  { meta1 , u(1) } ;meta1{ meta=meta2{__index=in},__index=self,__newindex=nin,insert,size,clear} ⇒ {u(1)};u(1){meta=meta1{ meta=meta2{__index=in},__index=self,__newindex=nin,insert,size,clear}}
		lua_setfield(L, -2, "hWnds"); //  {u(1), tbl };u(1){meta=meta1{ meta=meta2{__index=in},__index=self,__newindex=nin,insert,size,clear}} ⇒ {};tbl["hWnds"]=u(1){meta=meta1{ meta=meta2{__index=in},__index=self,__newindex=nin,insert,size,clear}}  
		lua_setglobal(L, "spawner"); // { tbl };  ⇒  g["spawner"]=tbl
		return 0;
	}
	
	extern void lua_setEquipment(lua_State *L)
	{
	   lua_getglobal(L, "spawner");
		if (lua_isnil(L, -1)) {
		  lua_pop(L, 1);
		  lua_newtable(L);
		}
		lua_pushliteral( L, "wsh" ); // ==> stack: ..., spawner{}, "wsh"
		lua_newtable( L ); // ==> stack: ..., spawner{}, "wsh", {}
		lua_settable( L, -3 );// ==> stack: ..., spawner{},

		lua_pushcfunction(L, lua_setFuncOfJscript); //   { meta , u(1) }  ⇒ { in, meta , u(1) } ;            
		lua_setfield(L, -2, "setFuncOfJscript"); //  { size, meta , u(1) }  ⇒ {  meta , u(1) } ;meta{size}   

		lua_pushcfunction(L, lua_runJscript); //   { meta , u(1) }  ⇒ { in, meta , u(1) } ;            
		lua_setfield(L, -2, "runJscript"); //  { size, meta , u(1) }  ⇒ {  meta , u(1) } ;meta{size}   

		lua_setglobal(L, "spawner"); // { tbl };  ⇒  g["spawner"]=tbl

		return;
	}
}
#endif


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
HHOOK hHook;
LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	LPMSG lpMsg = (LPMSG)lParam;
	
	if (nCode >= 0 && PM_REMOVE == wParam)
	{
		// Don't translate non-input events.
		if ((lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST))
		{
			if (IsDialogMessage(hwndDllDlg, lpMsg))
			{
				// The value returned from this hookproc is ignored, 
				// and it cannot be used to tell Windows the message
				// has been handled. To avoid further processing,
				// convert the message to WM_NULL before returning.
				lpMsg->message = WM_NULL;
				lpMsg->lParam = 0;
				lpMsg->wParam = 0;
			}
		}
	}
	return CallNextHookEx(hHook, nCode, wParam, lParam);
}
INT_PTR CALLBACK LuaDllDialogProc(
	HWND hwndDlg, // handle to dialog box
	UINT uMsg, // message
	WPARAM wParam, // first message parameter
	LPARAM lParam 	// second message parameter
)
{
	char buf[256];
	CLuaDll* pCDialog;
	switch(uMsg){
		case WM_INITDIALOG:
			pCDialog = (CLuaDll*)lParam;
			if (NULL != pCDialog){ 
				::SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
				// g_oldDlgdProc = (WNDPROC)GetWindowLongPtr(hwndDlg, GWLP_WNDPROC); 
				// ::SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (INT_PTR)&DlgWindowsProc);
				return pCDialog->DispatchEvent(hwndDlg, uMsg, wParam, lParam);
			}
			return FALSE;
		case WM_KEYDOWN:
			sprintf(buf, "WM_KEYDOWN:wMsg=0x%08X, wParam=0x%08X,lParam=0x%08X,", uMsg,wParam, lParam);
			CallNamedFunction("OnLuaMsgTest", (lua_Integer)uMsg, buf);
			return TRUE;
		case WM_CHAR:
			sprintf(buf, "WM_CHAR:wMsg=0x%08X, wParam=0x%08X,lParam=0x%08X,", uMsg,wParam, lParam);
			CallNamedFunction("OnLuaMsgTest", (lua_Integer)uMsg, buf);
			return TRUE;
		case WM_KEYUP:
			sprintf(buf, "WM_KEYUP:wMsg=0x%08X, wParam=0x%08X,lParam=0x%08X,", uMsg,wParam, lParam);
			CallNamedFunction("OnLuaMsgTest", (lua_Integer)uMsg, buf);
			return TRUE;
		case WM_DESTROY:
			// UnhookWindowsHookEx(hHook);
			return FALSE;
		default:
			// Modified by KEITA for WIN64 2003.9.6
			pCDialog = (CLuaDll*)::GetWindowLongPtr(hwndDlg, DWLP_USER);
			if (NULL != pCDialog){
				INT_PTR result = pCDialog->DispatchEvent(hwndDlg, uMsg, wParam, lParam);
				/*
				if ( FALSE == result )
				return CallWindowProc(g_oldDlgdProc,hwndDlg, uMsg, wParam, lParam);
				else
				*/
				return result;
			}
			else {
				return FALSE;
			}
	}
	
	
}


CLuaDll::CLuaDll()
{
	;; //m_bCANCEL = FALSE;	/* IDCANCELボタンが押された */
}

/** 標準以外のメッセージを捕捉する
@date 2008.05.28 ryoji 新規作成
*/
INT_PTR CLuaDll::DispatchEvent(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	INT_PTR result = FALSE;
	char buf[256];
	switch(wMsg){
		case WM_INITDIALOG:	
			return OnInitDialog(hWnd, wParam, lParam);
		case WM_CLOSE:
			CallNamedFunction("OnLuaJumpClose", (lua_Integer)hWnd, "");
			::DestroyWindow(hWnd);
			return TRUE;
			break;
		case WM_KEYDOWN:
			sprintf(buf, "WM_KEYDOWN:wMsg=0x%08X, wParam=0x%08X,lParam=0x%08X,", wMsg,wParam, lParam);
			CallNamedFunction("OnLuaMsgTest", (lua_Integer)wMsg, buf);
			break;
		case WM_CHAR:
			sprintf(buf, "WM_CHAR:wMsg=0x%08X, wParam=0x%08X,lParam=0x%08X,", wMsg,wParam, lParam);
			CallNamedFunction("OnLuaMsgTest", (lua_Integer)wMsg, buf);
			break;
		case WM_KEYUP:
			sprintf(buf, "WM_KEYUP:wMsg=0x%08X, wParam=0x%08X,lParam=0x%08X,", wMsg,wParam, lParam);
			CallNamedFunction("OnLuaMsgTest", (lua_Integer)wMsg, buf);
			break;
		case WM_COMMAND:
			return OnCommand(hWnd, wParam, lParam);
		default:
			
			break;
	}
	// return DefWindowProc(hWnd, wMsg, wParam, lParam);;
	return result;
}
BOOL CLuaDll::OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	WORD	wID;
	BOOL	ret = FALSE;
	char achTemp[256];
	
	wID = LOWORD(wParam); /* 項目ID、 コントロールID、 またはアクセラレータID */
	// IDOK と IDCANCEL はボタンからでなくても同じ扱い
	// MSDN [Windows Management] "Dialog Box Programming Considerations"
	switch(wID){
		case ID_WORK:
			{
				// HWND hwndGroupsBox = GetDlgItem(hwndDlg, IDC_COMBO1);
				// コンボボックスID_COMBO1のテキスト部分の内容を取得し, tszBufに格納.
				HWND hCombo = GetDlgItem(hWnd, IDC_COMBO1); // GetDlgItemでID_COMBO1のウィンドウハンドルhComboを取得.
				GetWindowText(hCombo, achTemp, sizeof(achTemp)); // GetWindowTextでhComboのエディットボックス部分のテキスト内容を取得してtszBufに格納.
				if (CallNamedFunction("OnLuaJump", (lua_Integer)hWnd, achTemp))
					ret = TRUE;
			}
			break;
		case ID_CLOSE:
			::DestroyWindow(hWnd);
			m_hWnd = NULL;
			ret = TRUE;
			break;
		default:
			
			break;
	}
	return ret;
}

/* モードレスダイアログの表示 */
HWND CLuaDll::DoModeless(HINSTANCE hInstance, HWND hwndParent, int nDlgTemplete)
{
	// m_bCANCEL = FALSE;	/* IDCANCELボタンが押された */
	// return CDialog::doDoModeless( hInstance, hwndParent, nDlgTemplete, (LPARAM)NULL, SW_SHOW );
	HWND m_hWnd = ::CreateDialogParam(
		hInstance,
		MAKEINTRESOURCE(nDlgTemplete),
		hwndParent,
		LuaDllDialogProc,
		reinterpret_cast<LPARAM>(this)
		//(LPARAM)this
	);
	if (NULL != m_hWnd){
		::ShowWindow(m_hWnd, SW_SHOW);
	}
	else {
		
		char buf[100];
		sprintf(buf, "Error x%x", GetLastError());
		// 0x716 means "The specified resource name cannot be found in the image file"
		// 0x716 means "The specified resource name cannot be found in the image file"
		MessageBox(0, buf, "CreateDialog", MB_ICONEXCLAMATION | MB_OK);
		
	}
	return m_hWnd;
	
}

BOOL CLuaDll::OnInitDialog(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
	m_hWnd = hwndDlg;
	HICON	hIcon;
	hIcon = ::LoadIcon(NULL, IDI_ASTERISK);
	//	hIcon = ::LoadIcon( m_hInstance, MAKEINTRESOURCE( IDI_ICON_GREP ) );
	//	::SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)NULL );
	//	::SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon );
	//	::SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)NULL );
	//	::SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon );
	
	//SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_COMBO1), TRUE);
	// ::SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_SETCURSEL, 0, 0);
	// ::SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_COMBO1), TRUE);
	
	return FALSE;
}

void CLuaDll::CloseDialog(void)
{
	
	::DestroyWindow(m_hWnd);
	m_hWnd = NULL;
	return;
}
void InitGroupListTest(HINSTANCE hInst, HWND hDlg)
{
	TCHAR achTemp[256];
	DWORD dwIndex;
	
	// Get the handle of the food groups combo box.
	HWND hwndGroupsBox = GetDlgItem(hDlg, IDC_COMBO1);
	
	LoadString(hInst, IDS_TEST1, achTemp, sizeof(achTemp)/sizeof(TCHAR));
	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM)achTemp);
	// SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmBread);
	
	LoadString(hInst, IDS_TEST2, achTemp, sizeof(achTemp)/sizeof(TCHAR));
	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM)achTemp);
	// SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmDairy);
	
	LoadString(hInst, IDS_TEST3, achTemp, sizeof(achTemp)/sizeof(TCHAR));
	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM)achTemp);
	// SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmFruit); 
	
	LoadString(hInst, IDS_TEST4, achTemp, sizeof(achTemp)/sizeof(TCHAR));
	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM)achTemp);
	// SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmMeat);
	
	return;
}





