/**
@filename ProgressDialog.h
@brief Windows95でも使えるIProgressDialogの代わり
@since 2006/02/08
@author d金魚
@note
<PRE>
IProgressDialogはWindows2000,XPでしか使えない。
よってWindows95でも使えるProgress Dialogが必要と思った次第だ。

仕様：
プログレスバーが100%になっても終了しない。
キャンセルを押されるとダイアログが消える。
</PRE>
 */
#ifndef DKUTIL_GUI_WIN32_PROGRESS_DIALOG_H
#define DKUTIL_GUI_WIN32_PROGRESS_DIALOG_H


#include <windows.h>

#ifndef DKINGYOPROGRESSDIALOG_NOT_IMPORT





#include <dkutil_c/dkc_misc.h>



#ifdef DKINGYOPROGRESSDIALOG_EXPORTS
# define DKINGYOPROGRESSDIALOG_EXTERN extern "C" DKC_EXTERN_EXPORT
#else
#	define DKINGYOPROGRESSDIALOG_EXTERN extern "C" DKC_EXTERN_IMPORT
#endif


/**
@param percentage[in] パーセンテージを保存している変数へのポインタ
@param movetext[in] Text box内で動かす文字列（NULLでも良い）
@return 生成されたダイアログのWINDOW HANDLE。 NULLだとエラー
*/
DKINGYOPROGRESSDIALOG_EXTERN HWND WINAPI dkcProgressDialogDoModeless(unsigned int *percentage,const char *movetext,BOOL *isCancel);
DKINGYOPROGRESSDIALOG_EXTERN HWND WINAPI dkcProgressDialogDoModeless2(HWND hwnd,unsigned int *percentage,const char *movetext,BOOL *isCancel);

///Progress dialog領域を開放（DestroyWindow付き）必ず終了する時呼び出してください。
DKINGYOPROGRESSDIALOG_EXTERN BOOL WINAPI dkcProgressDialogFree(HWND wnd);

///流れる文字列を変更する時に呼び出してください。
DKINGYOPROGRESSDIALOG_EXTERN BOOL WINAPI dkcProgressDialogSetMoveText(HWND wnd,const char *movetext,unsigned int textboxsize);


#else
#	define DKC_INLINE __inline
#endif


///いわいるお決まりのShowWindowとUpdateWindowをやってくれます。
#ifdef __cplusplus
DKC_INLINE void WINAPI dkcProgressDialogShowAndUpdate(HWND hwnd,int nCmdSnow = SW_SHOW)
#else
DKC_INLINE void WINAPI dkcProgressDialogShowAndUpdate(HWND hwnd,int nCmdSnow)
#endif
{
	ShowWindow(hwnd,nCmdSnow);
	UpdateWindow(hwnd);
}
#ifdef __cplusplus
DKC_INLINE int WINAPI dkcProgressDialogMessageProcess(HWND hwnd = NULL,MSG *pmsg=NULL,BOOL bPeek=TRUE){
#else
DKC_INLINE int WINAPI dkcProgressDialogMessageProcess(HWND hwnd,MSG *pmsg,BOOL bPeek){
#endif
	/*MSG msg;
	int t;
	if(!pmsg){
		pmsg = &msg;
	}
	if(!hwnd) return -1;
	t = GetMessage(pmsg, hwnd, 0, 0);
	if(t) {
    TranslateMessage(pmsg);
    DispatchMessage(pmsg);
	}
	return t;
	*/
	//yaneSDK3rdより
	MSG msg;
	HWND hWnd = hwnd;
	HACCEL	m_hAccel = NULL;			//	アクセラレータ
	if (bPeek) {
		while (PeekMessage(&msg, NULL /* hWnd */,0,0,PM_REMOVE)) {
			//	⇒ここ、hWndにしないとマルチウィンドゥにしたとき、マズイのだが、
			//　どうも、NULLウィンドゥにしか飛んでこないメッセージがあるようで...
			//	メッセージが存在する限り処理しつづける
			if(TranslateAccelerator(hWnd,m_hAccel,&msg)==0) {
				TranslateMessage(&msg); 
				DispatchMessage(&msg);
			}
		}
		//	安全にするなら、PeekMessageがエラー終了していないか調べるべきなのかも知れない
		//	GetMessageに対して戻り値が-1かどうかをチェックしているわけで、PeekMessageについても
		//	それに対応する処理が必要だと考えられる
		return 0;
	} else {
		LRESULT lr = GetMessage(&msg,NULL,0,0);
		//	⇒ここ、GetHWndにしないとマルチウィンドゥにしたとき、マズイのだが、
		//　どうも、NULLウィンドゥにしか飛んでこないメッセージがあるようで...
		if (lr!=-1) {
			//	エラーコードが返ってきている場合、それを
			//	dispatchしてはいけない。
			//	しかし、この場合、アプリを終了させるべきだろうか？
			if(TranslateAccelerator(hWnd,m_hAccel,&msg)==0) {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		} else {
			// -1が返ってきたなら、このスレッド破棄したほうがいいんじゃね？
			//InvalidateThread();
		}
		return lr;
	}
}


typedef HWND (WINAPI *DKC_PROGRESS_DIALOG_DO_MODELESS_F_TYPE)(unsigned int *percentage,const char *movetext,BOOL *isCancel);
typedef HWND (WINAPI *DKC_PROGRESS_DIALOG_DO_MODELESS2_F_TYPE)(HWND hwnd,unsigned int *percentage,const char *movetext,BOOL *isCancel);
typedef BOOL (WINAPI *DKC_PROGRESS_DIALOG_FREE_F_TYPE)(HWND wnd);
typedef BOOL (WINAPI *DKC_PROGRESS_DIALOG_SET_MOVE_TEXT_F_TYPE)(HWND wnd,const char *movetext,unsigned int textboxsize);


#endif