/*************************************************************************
 * <_xZkqqHx_iDhEiDeAiDeDiDiL_xHqqkZx_> UtilErr.cpp
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_> _xZkqqHx_iDeHiDiJiBfLiKnGjIeBiCmMiDgDiBfLiDiLiPfHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_> 99.02.22 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/

#include "stdafx.h"
#include "UtilErr.h"		// This header.

struct S_UTILERR
{
	S_UTILERR () : s_hWnd(NULL), s_callback(NULL) {}
	HWND					s_hWnd;
	DsErrorThrowCallback	s_callback;
}; // struct S_UTILERR.

typedef FCCsAreaRead<S_UTILERR>		s0_read;
typedef FCCsAreaWrite<S_UTILERR>		s0_write;
typedef FCCsAreaReadWrite<S_UTILERR>	s0_readwrite;

static FCCsAreaDef<S_UTILERR> s_0;

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FFMessageBox
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_jDmGiOkJiCmMiDiBiDgCiDfKiBfLiDfHiDhLiDgCiDeOiDfIiCpAjFfMiOkGiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	wcpText		:_xZkqqHx_iDgFiDeMiDfIiDgHjFlGiOjKjHpBiCpAiOhHjCoIiBeC_xHqqkZx_
 *			wcpCaption	:_xZkqqHx_iDeMiDiDiDhGiDfGiDiHiDjDjFlGiOjKjHpBiCpAiOhHjCoIiBeC_xHqqkZx_NULL _xZkqqHx_iCmMiPoKiNiHiCmN_xHqqkZx_
 *						 _xZkqqHx_iDeBiDhGiDiKjGlMiCpAjFfMiOkGiBeC_xHqqkZx_
 *			dwType		:_xZkqqHx_iDiBiDgCiDfKiBfLiDfHiMgAiOkOiBeC_xHqqkZx_
 *			szTextBox	:_xZkqqHx_iDiBiDgCiDfKiBfLiDfHiCkKjFfMiOkGiClDiCoKiCoJiDhLiDgCiDeOiDfIiCmMiDfEiDeDiDfJiCpAiOhHjCoIiBeC_xHqqkZx_
 *						 _xZkqqHx_iClBiCmMjCgMiCkK_xHqqkZx_SIZE(0,0)_xZkqqHx_iCmMiPoKiNiHiCmNiBeBiDfPiDeDiDeBiDiNiDePiDfEiDeDiDfJiCkK_xHqqkZx_
 *						 _xZkqqHx_iDiBiDgCiDfKiBfLiDfHiDhLiDgCiDeOiDfIiCmJiNiHiClJiCmEiDiKiDfEiDeDiDfJiClDiCoKiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iJjPiClDiCoKiClNiDhLiDfOiDjDiCmM_xHqqkZx_ID_xZkqqHx_iCpAjFnEiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	00.07.03 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
int FFMessageBox (	const wchar_t* wcpText,
					const wchar_t* wcpCaption, DWORD dwType)
{
	s0_read s0r(s_0);
	return ::MessageBox(s0r->s_hWnd, 
						WStrToTStr(wcpText),
						WStrToTStr(wcpCaption),
						dwType);
} // FFMessageBox.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FFThrowMiscLastError
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	GetLastError_xZkqqHx_iKnGjAjEiCkKjFnEiClHiDeHiDiJiBfLiCpAiBeB_xHqqkZx_CFCMiscException_xZkqqHx_jHoBiKePiCmGiClFiCmE_xHqqkZx_
 *			_xZkqqHx_iDfIiDiNiBfLiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.11.15 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
void FFThrowMiscLastError ()
{
	// GetLastError _xZkqqHx_iCkKjFnEiClHiDfCiBfLiDgIiCpAjFlGiOjKjHpBiJlLiClHiCoJiBeC_xHqqkZx_
	LPTSTR lpMsgBuf;
	::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
					FORMAT_MESSAGE_FROM_SYSTEM | 
					FORMAT_MESSAGE_IGNORE_INSERTS,
					NULL,
					GetLastError(),
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
					(LPTSTR)&lpMsgBuf,
					0,
					NULL);

	WString wstrMessage = TStrToWStr(lpMsgBuf);
	// Free the buffer.
	LocalFree(lpMsgBuf);
	FFThrowMiscError(DWORD(-1), wstrMessage);
} // FFThrowMiscLastError.

void FFThrowMiscException (DWORD dwMessageId, ...)
{
	//----- _xZkqqHx_iDeHiDiJiBfLiDiBiDgCiDfKiBfLiDfHiCmMjFlGiOjKjHpBiCpAjBgHiCnNjHkHiCmEiCoJ_xHqqkZx_ -----
	WString wstrMsg;
	WString wstrFormat;
	(void)wstrFormat.LoadString(dwMessageId);
	va_list argList;
	va_start(argList, dwMessageId);
	wstrMsg.FormatV(wstrFormat.c_str(), argList);
	va_end(argList);
	FFThrowMiscError(dwMessageId, wstrMsg);
} // FFThrowMiscException.

void FFThrowMiscError (DWORD dwErrorCode, const wchar_t* wcpMessage)
{
	s0_read s0r(s_0);
	if (s0r->s_callback != NULL)
		(*s0r->s_callback)(dwErrorCode, wcpMessage);
	else
		throw dwErrorCode;
} // FFThrowMiscError.

void FFSetErrorThrowFunc (DsErrorThrowCallback callback)
{
	s0_readwrite s0rw(s_0);
	s0rw->s_callback = callback;
} // FFSetErrorThrowFunc.

void FFSetErrorHwnd (HWND hWnd)
{
	s0_readwrite s0rw(s_0);
	s0rw->s_hWnd = hWnd;
} // FFSetErrorHwnd.

void FFDebugTrace (const wchar_t* wcpFormat, ...)
{
	WString wstrMsg;
	va_list argList;
	va_start(argList, wcpFormat);
	wstrMsg.FormatV(wcpFormat, argList);
	va_end(argList);
	OutputDebugString(WStrToTStr(wstrMsg));
} // FFDebugTrace.
