/*

  toolfunc.h
  Copyright(C) 2002-2014 INASOFT 矢吹拓也/Ayacy

  toolfunc.lib (汎用ツールライブラリ) を利用するためのヘッダファイル

*/

#ifndef MYLIB__ISTTOOLFUNC__
#define MYLIB__ISTTOOLFUNC__

#ifndef OWN__TOOLFUNC__
#pragma comment(lib, "toolfunc.lib")
#endif  /* OWN__TOOLFUNC__ */

#ifndef LibExport

#ifdef __cplusplus

#define LibExport extern "C"

#else /* __cplusplus */

#define LibExport extern

#endif /* __cplusplus */

#endif  /* LibExport */

#define TOOLFUNC_H_VERSIONNUMBER 40036

// toolfunc.libのバージョン番号を返す
// 整数部×10000＋小数部×100＋内部リリースNo.
LibExport DWORD toolfunclib_GetVersion( VOID );


#ifdef _UNICODE
#define addResizableBorder	addResizableBorderW
#else  /* _UNICODE */
#define addResizableBorder	addResizableBorderA
#endif /* _UNICODE */

// ダイアログ枠のウィンドウに対しサイズ変更枠を「追加」し、
// リサイズできるようにメニューの追加も行う。
LibExport BOOL addResizableBorderA(HWND hWnd, const char    *name_resizeitem);
LibExport BOOL addResizableBorderW(HWND hWnd, const wchar_t *name_resizeitem);

// リージョンハンドルのコピーを作成し、ウィンドウに適用する
LibExport int SetWindowRgn2(HWND hWnd, HRGN hRgn, BOOL bRedraw);

// fnameの中にスペースがあったら、ダブルコーテーションを付けて返す
LibExport char    *insert_dcA(char    *fname);
LibExport wchar_t *insert_dcW(wchar_t *fname);

#ifdef __cplusplus

#include <string>
using namespace std;
extern bool insert_dcA(string  &fname);
extern bool insert_dcW(wstring &fname);
extern bool delete_dcA(string  &fname);
extern bool delete_dcW(wstring &fname);

#endif /* __cplusplus */

// fnameの中がダブルコーテーションで始まっていたら、両端がダブルコーテーションで囲まれていると
// みなして取り除く（引数がconstではありません。引数で与えられたメモリを直接いじります）
LibExport char    *delete_dcA(char    *fname);
LibExport wchar_t *delete_dcW(wchar_t *fname);

#ifdef _UNICODE
#define insert_dc	insert_dcW
#define delete_dc	delete_dcW
#else  /* _UNICODE */
#define insert_dc	insert_dcA
#define delete_dc	delete_dcA
#endif /* _UNICODE */

// 260〜519バイトになるようなファイル名を扱う場合のANSI版FindFirstFile用構造体
typedef struct _WIN32_FIND_DATA520A {
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD nFileSizeHigh;
    DWORD nFileSizeLow;
    DWORD dwReserved0;
    DWORD dwReserved1;
    CHAR   cFileName[ MAX_PATH*2 ];
    CHAR   cAlternateFileName[ 14 ];
#ifdef _MAC
    DWORD dwFileType;
    DWORD dwCreatorType;
    WORD  wFinderFlags;
#endif
} WIN32_FIND_DATA520A, *PWIN32_FIND_DATA520A, *LPWIN32_FIND_DATA520A;

#ifdef _UNICODE
#define WIN32_FIND_DATA520		WIN32_FIND_DATAW
#define PWIN32_FIND_DATA520		PWIN32_FIND_DATAW
#define LPWIN32_FIND_DATA520	LPWIN32_FIND_DATAW
#else  /* _UNICODE */
#define WIN32_FIND_DATA520		WIN32_FIND_DATA520A
#define PWIN32_FIND_DATA520		PWIN32_FIND_DATA520A
#define LPWIN32_FIND_DATA520	LPWIN32_FIND_DATA520A
#endif /* _UNICODE */

// 260〜519バイトになるようなファイル名を扱う場合のANSI版FindFirstFile/FindNextFile
LibExport HANDLE FindFirstFile520A(LPCSTR lpFileName, LPWIN32_FIND_DATA520 lpFindFileData);
LibExport BOOL   FindNextFile520A(HANDLE hFindFile, LPWIN32_FIND_DATA520 lpFindFileData);

#ifdef _UNICODE
#define FindFirstFile520	FindFirstFileW
#define FindNextFile520		FindNextFileW
#else  /* _UNICODE */
#define FindFirstFile520	FindFirstFile520A
#define FindNextFile520		FindNextFile520A
#endif /* _UNICODE */

// ファイルが存在するかどうか
LibExport BOOL tFileExistA(const char    *fname);
LibExport BOOL tFileExistW(const wchar_t *fname);

#ifdef _UNICODE
#define tFileExist	tFileExistW
#else  /* _UNICODE */
#define tFileExist	tFileExistA
#endif /* _UNICODE */

// デバッグ用のメッセージ出力
LibExport void DebugMesA(const char    *mes);
LibExport void DebugMesW(const wchar_t *mes);

#ifdef _UNICODE
#define DebugMes	DebugMesW
#else  /* _UNICODE */
#define DebugMes	DebugMesA
#endif /* _UNICODE */

// Windows NT 終了権限の取得
LibExport void GetQuitRight(void);

// 数値を10進数の文字列に直す (返すのは関数内部のstaticなバッファへのポインタであることに注意)
LibExport char    *itoa10A(unsigned int n);
LibExport wchar_t *itoa10W(unsigned int n);
LibExport char    *s_itoa10A(int n);
LibExport wchar_t *s_itoa10W(int n);

// 数値を16進数の文字列に直す (返すのは関数内部のstaticなバッファへのポインタであることに注意)
LibExport char    *itoa16A(int n);
LibExport wchar_t *itoa16W(int n);

#ifdef _UNICODE
#define itoa10		itoa10W
#define s_itoa10	s_itoa10W
#define itoa16		itoa16W
#else  /* _UNICODE */
#define itoa10		itoa10A
#define s_itoa10	s_itoa10A
#define itoa16		itoa16A
#endif /* _UNICODE */

// ●上記３関数の再入可能版。11/12/9バイトの文字列が格納できるバッファを渡すこと)
#define itoa10exA(n,buf)    _ultoa((unsigned long)(n),(buf),10)
#define s_itoa10exA(n,buf)  _itoa((int)(n),(buf),10)
#define itoa16exA(n,buf)    _ultoa((unsigned long)(n),(buf),16)

#define itoa10exW(n,buf)    _ultow((unsigned long)(n),(buf),10)
#define s_itoa10exW(n,buf)  _itow((int)(n),(buf),10)
#define itoa16exW(n,buf)    _ultow((unsigned long)(n),(buf),16)

#define itoa10ex(n,buf)    _ultot((unsigned long)(n),(buf),10)
#define s_itoa10ex(n,buf)  _itot((int)(n),(buf),10)
#define itoa16ex(n,buf)    _ultot((unsigned long)(n),(buf),16)

// 「ファイル名,番号」からアイコンハンドルを得る
LibExport HICON LoadIconFromFileA(HINSTANCE hInst, const char    *fname_num);
LibExport HICON LoadIconFromFileW(HINSTANCE hInst, const wchar_t *fname_num);

#ifdef _UNICODE
#define LoadIconFromFile	LoadIconFromFileW
#else  /* _UNICODE */
#define LoadIconFromFile	LoadIconFromFileA
#endif /* _UNICODE */

// 「ファイル名,番号」から、アイコンハンドルを得る。大きいサイズと小さいサイズの両方。
LibExport UINT LoadIconFromFileExA(const char    *fname_num, HICON *phIcon, HICON *phSmallIcon);
LibExport UINT LoadIconFromFileExW(const wchar_t *fname_num, HICON *phIcon, HICON *phSmallIcon);

#ifdef _UNICODE
#define LoadIconFromFileEx	LoadIconFromFileExW
#else  /* _UNICODE */
#define LoadIconFromFileEx	LoadIconFromFileExA
#endif /* _UNICODE */

// リストビューのカーソル位置取得
// LibExport int  GetLVCursor(HWND hListView);
#define GetLVCursor(h) ListView_GetNextItem(h,-1,LVNI_SELECTED)

// リストビューのリサイズ
LibExport void ResizeListView(HWND hParent, HWND hStatusBar, HWND hListView);

// リストビューのスタイル変更
LibExport void ChangeLVStyle(HWND hWnd, HWND hwndListView, int style, BOOL Repaint);

// Unlha32.dllを呼び出して、バージョン情報を取得する
LibExport DWORD call_unlha32_GetVersion(VOID);

// Unlha32.dllを呼び出して、使用言語を設定する
// englishflag = TRUE:英語モード / FALSE:日本語モード
LibExport BOOL call_unlha32_UseEnglishMode(BOOL englishflag);

// Unlha32.dllを呼び出して、カレントディレクトリにlzhnameを解凍する(_logは出力ログ取得版)
LibExport int call_unlha32A(HWND hWnd, LPCSTR lzhname);
LibExport int call_unlha32W(HWND hWnd, LPCWSTR lzhname);
LibExport int call_unlha32_logA(HWND hWnd, LPCSTR  lzhname, LPSTR  szOutput, DWORD dwOutputSize); 
LibExport int call_unlha32_logW(HWND hWnd, LPCWSTR lzhname, LPWSTR szOutput, DWORD dwOutputSize); 

// Unlha32.dllを呼び出して、指定ディレクトリにlzhnameを解凍する(_logは出力ログ取得版)
LibExport int call_unlha32dA(HWND hWnd, LPCSTR  lzhname, LPCSTR  dir);
LibExport int call_unlha32dW(HWND hWnd, LPCWSTR lzhname, LPCWSTR dir);
LibExport int call_unlha32d_logA(HWND hWnd, LPCSTR  lzhname, LPCSTR  dir, LPSTR  szOutput, DWORD dwOutputSize);
LibExport int call_unlha32d_logW(HWND hWnd, LPCWSTR lzhname, LPCWSTR dir, LPWSTR szOutput, DWORD dwOutputSize);

// Unlha32.dllを呼び出して、レスポンスファイルで指定されたファイル群をlzhnameに圧縮する(_logは出力ログ取得版)
LibExport int call_unlha32rA(HWND hWnd, LPCSTR  lzhname, LPCSTR  response_file, LPCSTR  option);
LibExport int call_unlha32rW(HWND hWnd, LPCWSTR lzhname, LPCWSTR response_file, LPCWSTR option);
LibExport int call_unlha32r_logA(HWND hWnd, LPCSTR  lzhname, LPCSTR  response_file, LPCSTR  option, LPSTR  szOutput, DWORD dwOutputSize);
LibExport int call_unlha32r_logW(HWND hWnd, LPCWSTR lzhname, LPCWSTR response_file, LPCWSTR option, LPWSTR szOutput, DWORD dwOutputSize);

// Unlha32.dllを呼び出して、lzhをexe(WinSFX32)に変換する(s -gw1)(_logは出力ログ取得版)
LibExport int call_unlha32_toexeA(HWND hWnd, LPCSTR  lzhname);
LibExport int call_unlha32_toexeW(HWND hWnd, LPCWSTR lzhname);
LibExport int call_unlha32_toexe_logA(HWND hWnd, LPCSTR  lzhname, LPSTR  szOutput, DWORD dwOutputSize);
LibExport int call_unlha32_toexe_logW(HWND hWnd, LPCWSTR lzhname, LPWSTR szOutput, DWORD dwOutputSize);

#ifdef _UNICODE
#define call_unlha32			call_unlha32W
#define call_unlha32_log		call_unlha32_logW
#define call_unlha32d			call_unlha32dW
#define call_unlha32d_log		call_unlha32d_logW
#define call_unlha32r			call_unlha32rW
#define call_unlha32r_log		call_unlha32r_logW
#define call_unlha32_toexe		call_unlha32_toexeW
#define call_unlha32_toexe_log	call_unlha32_toexe_logW
#else  /* _UNICODE */
#define call_unlha32			call_unlha32A
#define call_unlha32_log		call_unlha32_logA
#define call_unlha32d			call_unlha32dA
#define call_unlha32d_log		call_unlha32d_logA
#define call_unlha32r			call_unlha32rA
#define call_unlha32r_log		call_unlha32r_logA
#define call_unlha32_toexe		call_unlha32_toexeA
#define call_unlha32_toexe_log	call_unlha32_toexe_logA
#endif /* _UNICODE */

// Unlha32.dllを呼び出して、Unlha()が使用中かどうかを確かめる
LibExport BOOL call_unlha32_getrunning( void );

// Unzip32.dllを呼び出して、カレントディレクトリにzipnameを解凍する(_logは出力ログ取得版)
LibExport int call_unzip32(HWND hWnd, LPCSTR zipname);
LibExport int call_unzip32_log(HWND hWnd, LPCSTR zipname, LPSTR szOutput, DWORD dwOutputSize);

// Unzip32.dllを呼び出して、指定ディレクトリにzipnameを解凍する(_logは出力ログ取得版)
LibExport int call_unzip32d(HWND hWnd, LPCSTR zipname, LPCSTR dir);
LibExport int call_unzip32d_log(HWND hWnd, LPCSTR zipname, LPCSTR dir, LPSTR szOutput, DWORD dwOutputSize);

// Unzip32.dllを呼び出して、Unzip()が使用中かどうかを確かめる
LibExport BOOL call_unzip32_getrunning( void );

// Zip32.dllを呼び出して、レスポンスファイルで指定されたファイル群をzipnameに圧縮する(_logは出力ログ取得版)
LibExport int call_zip32j(HWND hWnd, LPCSTR zipname, LPCSTR response_file, LPCSTR option);
LibExport int call_zip32j_log(HWND hWnd, LPCSTR zipname, LPCSTR response_file, LPCSTR option, LPSTR szOutput, DWORD dwOutputSize);

// zip32j.dllを呼び出して、zipをexe(SFX)に変換する(--sfx)(_logは出力ログ取得版)
LibExport int call_zip32_toexe(HWND hWnd, LPCSTR zipname);
LibExport int call_zip32_toexe_log(HWND hWnd, LPCSTR zipname, LPSTR szOutput, DWORD dwOutputSize);

// Zip32.dllを呼び出して、Zip()が使用中かどうかを確かめる
LibExport BOOL call_zip32j_getrunning( void );

// 7-Zip32.dllを呼び出して、カレントディレクトリにsznameを解凍する(x)(_logは出力ログ取得版)
LibExport int call_7zip32(HWND hWnd, LPCSTR szname);
LibExport int call_7zip32_log(HWND hWnd, LPCSTR szname, LPSTR szOutput, DWORD dwOutputSize);

// 7-Zip32.dllを呼び出して、指定ディレクトリにsznameを解凍する(x -o<dir>)(_logは出力ログ取得版)
LibExport int call_7zip32d(HWND hWnd, LPCSTR szname, LPCSTR dir);
LibExport int call_7zip32d_log(HWND hWnd, LPCSTR szname, LPCSTR dir, LPSTR szOutput, DWORD dwOutputSize);

// 7-Zip32.dllを呼び出して、リストファイルで指定されたファイル群をsznameに圧縮する(a -t??? ***)(_logは出力ログ取得版)
LibExport int call_7zip32r(HWND hWnd, LPCSTR szname, LPCSTR list_file, LPCSTR option);
LibExport int call_7zip32r_log(HWND hWnd, LPCSTR szname, LPCSTR list_file, LPCSTR option, LPSTR szOutput, DWORD dwOutputSize);

// 7-Zip32.dllを呼び出して、SevenZip()が使用中かどうかを確かめる
LibExport BOOL call_7zip32_getrunning( void );

// OSのZipFolder機能を利用し、指定したフォルダ（フルパス）へ、zipファイルを展開する
// Windows XP以降で、zip展開機能が有効であること。Unicode版関数のみ提供
// あらかじめ CoInitialize() しておくこと!!
LibExport int Shell_UnZipW(LPWSTR zipfile, LPWSTR outfolder);

// TFI_TaskBarAddIcon - タスクバーの通知エリアにアイコンを追加
LibExport BOOL TFI_TaskBarAddIconA(HWND hwnd, UINT uID, HICON hicon, LPCSTR  lpszTip, int messageID);
LibExport BOOL TFI_TaskBarAddIconW(HWND hwnd, UINT uID, HICON hicon, LPCWSTR lpszTip, int messageID);

#ifdef _UNICODE
#define TFI_TaskBarAddIcon	TFI_TaskBarAddIconW
#else  /* _UNICODE */
#define TFI_TaskBarAddIcon	TFI_TaskBarAddIconA
#endif /* _UNICODE */

// TFI_TaskBarModifyIcon - タスクバーの通知エリアに追加したアイコンを変更
LibExport BOOL TFI_TaskBarModifyIconA(HWND hwnd, UINT uID, HICON hicon, LPCSTR  lpszTip, int messageID);
LibExport BOOL TFI_TaskBarModifyIconW(HWND hwnd, UINT uID, HICON hicon, LPCWSTR lpszTip, int messageID);

#ifdef _UNICODE
#define TFI_TaskBarModifyIcon	TFI_TaskBarModifyIconW
#else  /* _UNICODE */
#define TFI_TaskBarModifyIcon	TFI_TaskBarModifyIconA
#endif /* _UNICODE */

// TFI_TaskBarDeleteIcon - タスクバーの通知エリアに追加したアイコンを削除
LibExport BOOL TFI_TaskBarDeleteIconA(HWND hwnd, UINT uID);
LibExport BOOL TFI_TaskBarDeleteIconW(HWND hwnd, UINT uID);

#ifdef _UNICODE
#define TFI_TaskBarDeleteIcon	TFI_TaskBarDeleteIconW
#else  /* _UNICODE */
#define TFI_TaskBarDeleteIcon	TFI_TaskBarDeleteIconA
#endif /* _UNICODE */

// SHEmptyRecycleBin のコール (ごみ箱を空にする) testflag = 1 このAPIが利用できるかどうかを確認
//LibExport BOOL EmptyRecycleBinA(BOOL testflag);
//LibExport BOOL EmptyRecycleBinW(BOOL testflag);
//#ifdef _UNICODE
//#define EmptyRecycleBin		EmptyRecycleBinW
//#else  /* _UNICODE */
//#define EmptyRecycleBin		EmptyRecycleBinA
//#endif /* _UNICODE */
#define EmptyRecycleBin(testflag)		(testflag ? 1 : (S_OK == SHEmptyRecycleBin(NULL, NULL, SHERB_NOCONFIRMATION | SHERB_NOSOUND)))

// カレントディレクトリを自分のところにセット
LibExport BOOL SetCurrentDirectoryOwnDirA( void );
LibExport BOOL SetCurrentDirectoryOwnDirW( void );

#ifdef _UNICODE
#define SetCurrentDirectoryOwnDir		SetCurrentDirectoryOwnDirW
#else  /* _UNICODE */
#define SetCurrentDirectoryOwnDir		SetCurrentDirectoryOwnDirA
#endif /* _UNICODE */

// ショートカットの作成
LibExport BOOL MakeLinkA(LPCSTR  exe, LPCSTR  args, LPCSTR  lnk);
LibExport BOOL MakeLinkW(LPCWSTR exe, LPCWSTR args, LPCWSTR lnk);

#ifdef _UNICODE
#define MakeLink	MakeLinkW
#else  /* _UNICODE */
#define MakeLink	MakeLinkA
#endif /* _UNICODE */

// ショートカットの読み出し
LibExport int QueryLinkA(const char    *pszLinkFile, char    *pszTarget, char    *pszOption,
						       char    *pszIcon,     int     *piIconIndex);
LibExport int QueryLinkW(const wchar_t *pszLinkFile, wchar_t *pszTarget, wchar_t *pszOption,
						       wchar_t *pszIcon,     int     *piIconIndex);

#ifdef _UNICODE
#define QueryLink	QueryLinkW
#else  /* _UNICODE */
#define QueryLink	QueryLinkA
#endif /* _UNICODE */

// ショートカットの作成（アイコンもつける）
LibExport BOOL MakeLinkIconA(LPCSTR  exe, LPCSTR  args, LPCSTR  lnk, LPCSTR  icon, int no);
LibExport BOOL MakeLinkIconW(LPCWSTR exe, LPCWSTR args, LPCWSTR lnk, LPCWSTR icon, int no);

#ifdef _UNICODE
#define MakeLinkIcon	MakeLinkIconW
#else  /* _UNICODE */
#define MakeLinkIcon	MakeLinkIconA
#endif /* _UNICODE */

// strdupのnew版
LibExport char    *new_strcpyA(const char    *src);
LibExport wchar_t *new_strcpyW(const wchar_t *src);

#ifdef _UNICODE
#define new_strcpy	new_strcpyW
#else  /* _UNICODE */
#define new_strcpy	new_strcpyA
#endif /* _UNICODE */

// new_strcpyのstrcat版
LibExport char    *new_strcatA(char    *ptr, const char    *str);
LibExport wchar_t *new_strcatW(wchar_t *ptr, const wchar_t *str);

#ifdef _UNICODE
#define new_strcat	new_strcatW
#else  /* _UNICODE */
#define new_strcat	new_strcatA
#endif /* _UNICODE */

// realloc を使って strcat
LibExport char    *realloc_strcatA( char    *str1, const char    *str2 );
LibExport wchar_t *realloc_strcatW( wchar_t *str1, const wchar_t *str2 );

#ifdef _UNICODE
#define realloc_strcat	realloc_strcatW
#else  /* _UNICODE */
#define realloc_strcat	realloc_strcatA
#endif /* _UNICODE */

// 文字列strのn文字目は、Shift JIS漢字の第1バイト目か?
LibExport BOOL isKanji1A( const char *str, int n );
LibExport BOOL isKanji1W( const wchar_t *, int );

#ifdef _UNICODE
#define isKanji1	isKanji1W
#else  /* _UNICODE */
#define isKanji1	isKanji1A
#endif /* _UNICODE */

// スタートメニュー:プログラムのフォルダ（個人ユーザー用）を得る
LibExport char    *GetProgramFolderA(void);
LibExport wchar_t *GetProgramFolderW(void);

#ifdef _UNICODE
#define GetProgramFolder	GetProgramFolderW
#else  /* _UNICODE */
#define GetProgramFolder	GetProgramFolderA
#endif /* _UNICODE */

// スタートメニュー:プログラムのフォルダ（全ユーザー用）を得る
LibExport char    *GetCommonProgramFolderA(void);
LibExport wchar_t *GetCommonProgramFolderW(void);

#ifdef _UNICODE
#define GetCommonProgramFolder	GetCommonProgramFolderW
#else  /* _UNICODE */
#define GetCommonProgramFolder	GetCommonProgramFolderA
#endif /* _UNICODE */

// デスクトップフォルダ（個人ユーザー用）を得る
LibExport char    *GetDesktopFolderA(void);
LibExport wchar_t *GetDesktopFolderW(void);

#ifdef _UNICODE
#define GetDesktopFolder	GetDesktopFolderW
#else  /* _UNICODE */
#define GetDesktopFolder	GetDesktopFolderA
#endif /* _UNICODE */

// デスクトップフォルダを得る（全ユーザー用）
LibExport char    *GetCommonDesktopFolderA(void);
LibExport wchar_t *GetCommonDesktopFolderW(void);

#ifdef _UNICODE
#define GetCommonDesktopFolder	GetCommonDesktopFolderW
#else  /* _UNICODE */
#define GetCommonDesktopFolder	GetCommonDesktopFolderA
#endif /* _UNICODE */

// スタートアップフォルダ（個人ユーザー用）を得る
LibExport char    *GetStartUpFolderA(void);
LibExport wchar_t *GetStartUpFolderW(void);

#ifdef _UNICODE
#define GetStartUpFolder	GetStartUpFolderW
#else  /* _UNICODE */
#define GetStartUpFolder	GetStartUpFolderA
#endif /* _UNICODE */

// スタートアップフォルダを得る（全ユーザー用）
LibExport char    *GetCommonStartUpFolderA(void);
LibExport wchar_t *GetCommonStartUpFolderW(void);

#ifdef _UNICODE
#define GetCommonStartUpFolder	GetCommonStartUpFolderW
#else  /* _UNICODE */
#define GetCommonStartUpFolder	GetCommonStartUpFolderA
#endif /* _UNICODE */

// 起動ディレクトリ(Windowsフォルダではない)を得る
LibExport char    *GetBootDirectoryA(void);
LibExport wchar_t *GetBootDirectoryW(void);

#ifdef _UNICODE
#define GetBootDirectory	GetBootDirectoryW
#else  /* _UNICODE */
#define GetBootDirectory	GetBootDirectoryA
#endif /* _UNICODE */

// ダイアログから文字列を読みとり、そのまま領域ごと返す。あとで delete[] すること！
LibExport char    *new_GetDlgItemTextA(HWND hDlg, int nIDDlgItem);
LibExport wchar_t *new_GetDlgItemTextW(HWND hDlg, int nIDDlgItem);

#ifdef _UNICODE
#define new_GetDlgItemText	new_GetDlgItemTextW
#else  /* _UNICODE */
#define new_GetDlgItemText	new_GetDlgItemTextA
#endif /* _UNICODE */

// structure for CreateToolTip()
//
struct DEFTOOLTIPA {
	int cid;
	char *tip;
};
struct DEFTOOLTIPW {
	int cid;
	wchar_t *tip;
};

#ifdef _UNICODE
#define DEFTOOLTIP	DEFTOOLTIPW
#else  /* _UNICODE */
#define DEFTOOLTIP	DEFTOOLTIPA
#endif /* _UNICODE */

// ツールチップの作成
LibExport HWND CreateToolTipA(HINSTANCE hInst, HWND hWnd, const struct DEFTOOLTIPA *dtt);
LibExport HWND CreateToolTipW(HINSTANCE hInst, HWND hWnd, const struct DEFTOOLTIPW *dtt);

#ifdef _UNICODE
#define CreateToolTip	CreateToolTipW
#else  /* _UNICODE */
#define CreateToolTip	CreateToolTipA
#endif /* _UNICODE */

// 指定したダイアログの子ウィンドウ(コントロール)のフォントを MS UI Gothic にしてしまう
LibExport void SetChildWindowFont(HWND hWnd);

// 文字列を表示させる。
LibExport BOOL TextOutLengthA(HDC hdc, const char    *str, int x0, int y0);
LibExport BOOL TextOutLengthW(HDC hdc, const wchar_t *str, int x0, int y0);
#define tTextOutA(h,x,y,s) TextOutLengthA(h,s,x,y)
#define tTextOutW(h,x,y,s) TextOutLengthW(h,s,x,y)

#ifdef _UNICODE
#define TextOutLength	TextOutLengthW
#define tTextOut		tTextOutW
#else  /* _UNICODE */
#define TextOutLength	TextOutLengthA
#define tTextOut		tTextOutA
#endif /* _UNICODE */

// 指定された四角の中に、文字列を表示させる(自動改行、強制改行付き)。
LibExport int DrawTextRectA(HDC hdc, const char    *str, int x0, int y0, int x1, int y1);
LibExport int DrawTextRectW(HDC hdc, const wchar_t *str, int x0, int y0, int x1, int y1);

#ifdef _UNICODE
#define DrawTextRect	DrawTextRectW
#else  /* _UNICODE */
#define DrawTextRect	DrawTextRectA
#endif /* _UNICODE */

// 指定されたウインドウを半透明にする n:α値
LibExport int SetExl(HWND hWnd, BYTE n);

// 指定されたウインドウのα値を得る
LibExport int GetExl(HWND hWnd);

// エディットボックスの中身が数値かどうかを見て、違ったら 0 を入れる
LibExport BOOL CheckNumericDlgEdit(HWND hWnd, WORD id);

// 16進数を10進数へ
LibExport int atoi16A(const char    *str);
LibExport int atoi16W(const wchar_t *str);

#ifdef _UNICODE
#define atoi16	atoi16W
#else  /* _UNICODE */
#define atoi16	atoi16A
#endif /* _UNICODE */

// 3桁ごとのカンマを付ける (staticな領域を返す)
LibExport char    *commaA(unsigned int value);
LibExport wchar_t *commaW(unsigned int value);

#ifdef _UNICODE
#define comma	commaW
#else  /* _UNICODE */
#define comma	commaA
#endif /* _UNICODE */

// ●3桁ごとのカンマを付ける (再入可能版。14バイトの文字列が格納できるバッファを渡すこと)
LibExport char    *commaexA(unsigned int value, char    *buf);
LibExport wchar_t *commaexW(unsigned int value, wchar_t *buf);

#ifdef _UNICODE
#define commaex	commaexW
#else  /* _UNICODE */
#define commaex	commaexA
#endif /* _UNICODE */

// フルパスからファイル名の部分だけを取り出す (ダブルコーテーションがあるとうまくいきません)
LibExport const char    *GetOnlyFileNameA(const char    *path);
LibExport const wchar_t *GetOnlyFileNameW(const wchar_t *path);

#ifdef _UNICODE
#define GetOnlyFileName	GetOnlyFileNameW
#else  /* _UNICODE */
#define GetOnlyFileName	GetOnlyFileNameA
#endif /* _UNICODE */

#define basenameA(fn) GetOnlyFileNameA(fn)
#define basenameW(fn) GetOnlyFileNameW(fn)

#ifdef _UNICODE
#define basename	basenameW
#else  /* _UNICODE */
#define basename	basenameA
#endif /* _UNICODE */

// フォルダの作成(親フォルダがいなくても強制的に作成)
LibExport int  CreateDirA(const char    *dirname);
LibExport int  CreateDirW(const wchar_t *dirname);

#ifdef _UNICODE
#define CreateDir	CreateDirW
#else  /* _UNICODE */
#define CreateDir	CreateDirA
#endif /* _UNICODE */

// 文字列→UINT
LibExport unsigned atouA(const char    *str);
LibExport unsigned atouW(const wchar_t *str);

#ifdef _UNICODE
#define atou	atouW
#else  /* _UNICODE */
#define atou	atouA
#endif /* _UNICODE */

// ディレクトリ名のみを抜き出す
// fullpathのディレクトリ名の部分をdirbufに書き出す。
// fullpathのポインタとdirbufのポインタが指している先が同じでもよい
// 成功すると dirbuf を返し、失敗するとNULLを返す
LibExport char    *getDirectoryNameA(const char    *fullpath, char    *dirbuf, int dirbufsize);
LibExport wchar_t *getDirectoryNameW(const wchar_t *fullpath, wchar_t *dirbuf, int dirbufsize);

#ifdef _UNICODE
#define getDirectoryName	getDirectoryNameW
#else  /* _UNICODE */
#define getDirectoryName	getDirectoryNameA
#endif /* _UNICODE */

// 拡張子を取り除いた部分を抜き出す
// fullpathのディレクトリ名＋ファイル名の部分をdirbufに書き出す。
// fullpathのポインタとdirbufのポインタが指している先が同じでもよい
// 成功すると dirbuf を返し、失敗するとNULLを返す
LibExport char    *getFileNameOnlyA(const char    *fullpath, char    *fnamebuf, int fnamebufsize);
LibExport wchar_t *getFileNameOnlyW(const wchar_t *fullpath, wchar_t *fnamebuf, int fnamebufsize);

#ifdef _UNICODE
#define getFileNameOnly	getFileNameOnlyW
#else  /* _UNICODE */
#define getFileNameOnly	getFileNameOnlyA
#endif /* _UNICODE */

// リストビュー hListview の n 行目の c 桁目の文字列を得て、calloc で確保した配列を返す
LibExport char    *lvGetItemStringA( HWND hListview, unsigned n, unsigned c );
LibExport wchar_t *lvGetItemStringW( HWND hListview, unsigned n, unsigned c );

#ifdef _UNICODE
#define lvGetItemString	lvGetItemStringW
#else  /* _UNICODE */
#define lvGetItemString	lvGetItemStringA
#endif /* _UNICODE */

// SJIS文字列であることを考慮しつつ、strlwrする
LibExport char *sjislwr(char *str);

// SJIS文字列であることを考慮しつつ、struprする
LibExport char *sjisupr(char *str);

// SJIS文字列であることを考慮しつつ、strstr, strstriする。
LibExport char *sjisstr( const char *str1, const char *str2 );
LibExport char *sjisstri( const char *str1, const char *str2 );

// 大小文字無視版のstrstr
LibExport char    *strstriA( const char    *str1, const char    *str2 );
LibExport wchar_t *strstriW( const wchar_t *str1, const wchar_t *str2 );

#ifdef _UNICODE
#define strstri	strstriW
#else  /* _UNICODE */
#define strstri	strstriA
#endif /* _UNICODE */

// 文字列str中のrep1をrep2に置き換える
// 戻り値：変換後の文字列へのポインタ。使い終わったら解放すること
LibExport char    *replacestrA( const char    *str, const char    *rep1, const char    *rep2 );
LibExport wchar_t *replacestrW( const wchar_t *str, const wchar_t *rep1, const wchar_t *rep2 );

#ifdef _UNICODE
#define replacestr	replacestrW
#else  /* _UNICODE */
#define replacestr	replacestrA
#endif /* _UNICODE */

// GetLastError()の戻り値を渡すと、エラーメッセージを文字列にして返却する(戻り値は解放しないこと)
LibExport char    *getLastErrorStringMJPA(BOOL modeJP, DWORD errorcode);
LibExport wchar_t *getLastErrorStringMJPW(BOOL modeJP, DWORD errorcode);

#ifdef _UNICODE
#define getLastErrorString(X)	getLastErrorStringMJPW(1,X)
#define getLastErrorStringMJP   getLastErrorStringMJPW
#else  /* _UNICODE */
#define getLastErrorString(X)	getLastErrorStringMJPA(1,X)
#define getLastErrorStringMJP	getLastErrorStringMJPA
#endif /* _UNICODE */

// 復元ポイントを作成する
// 引数　：name = 作成する復元ポイントに付ける名前(MAX_DESCバイトまで)
// 戻り値：成功 ERROR_SUCCESS(0), 失敗 0以外
LibExport UINT createRestorePointA( const char    *name );
LibExport UINT createRestorePointW( const wchar_t *name );

#ifdef _UNICODE
#define createRestorePoint	createRestorePointW
#else  /* _UNICODE */
#define createRestorePoint	createRestorePointA
#endif /* _UNICODE */

// リストビューの指定された項目のアイコン番号を取得する
LibExport int lvGetIconNumber( HWND hListView, int cur );

// リストビューの指定された項目のLPARAMを取得する
LibExport LPARAM lvGetLParam( HWND hListView, int cur );

// ファイル名を指定して、ファイルサイズを取得する。ただし、ファイルサイズは2GBまで。ファイルが存在しない場合は -1 が返る
LibExport DWORD getFileSizeA( const char    *fname );
LibExport DWORD getFileSizeW( const wchar_t *fname );

#ifdef _UNICODE
#define getFileSize	getFileSizeW
#else  /* _UNICODE */
#define getFileSize	getFileSizeA
#endif /* _UNICODE */

// ファイル名を指定して、ファイルサイズを取得する。ただし、ファイルサイズの上限はQWORD. ファイルが存在しない場合は -1 が返る
LibExport UINT64 getFileSizeQA( const char    *fname );
LibExport UINT64 getFileSizeQW( const wchar_t *fname );

#ifdef _UNICODE
#define getFileSizeQ	getFileSizeQW
#else  /* _UNICODE */
#define getFileSizeQ	getFileSizeQA
#endif /* _UNICODE */

// Windowsのバージョンを、整数部×100+小数部で返す
LibExport WORD tf_getWinVer( void );

// WindowsのプラットフォームIDを返す
LibExport DWORD tf_GetPlatform( void );

// 常にWindows NT系
#define tf_isNT()	1

// dir + file を実行し、dir に格納する(ファイル名をダブルコーテーションで囲まないこと)
LibExport char    *dir_add_fileA( char    *dir, const char    *fname );
LibExport wchar_t *dir_add_fileW( wchar_t *dir, const wchar_t *fname );

#ifdef _UNICODE
#define dir_add_file	dir_add_fileW
#else  /* _UNICODE */
#define dir_add_file	dir_add_fileA
#endif /* _UNICODE */

// dir の後ろに \ が付いていない場合に \ を付加する(ファイル名をダブルコーテーションで囲まないこと)
LibExport char    *dir_add_bsA( char    *dir );
LibExport wchar_t *dir_add_bsW( wchar_t *dir );

#ifdef _UNICODE
#define dir_add_bs	dir_add_bsW
#else  /* _UNICODE */
#define dir_add_bs	dir_add_bsA
#endif /* _UNICODE */

// マルチバイトからワイドキャラクタへの変換。およびその逆。(使用後はfreeで開放すること)
LibExport wchar_t *mb2wc( const char *mbstr );
LibExport char    *wc2mb( const wchar_t *wcstr );

// ファイルからMD5を算出する
// fname : ファイル名
// md5   : char [33] 文字型配列。MD5の算出結果を文字列にして格納する
// cbfunc: 進捗状況を伝えるためのコールバック関数。不要な場合はNULL。戻り値がFALSEの場合は処理中断
// 戻り値: 成功=1、失敗=0（失敗時はmd5の指すアドレスの中のデータは変えない）
typedef BOOL(*md5file_callback)(long lNow, long lMax);
LibExport BOOL md5fileA( const char    *fname, char    *md5, md5file_callback cbfunc );
LibExport BOOL md5fileW( const wchar_t *fname, wchar_t *md5, md5file_callback cbfunc );

#ifdef _UNICODE
#define md5file	md5fileW
#else  /* _UNICODE */
#define md5file	md5fileA
#endif /* _UNICODE */

// メモリ上のデータからMD5を算出する
// data  : データの格納されたメモリの先頭アドレス
// datalength : dataの長さ（バイト単位）
// md5   : char [33] 文字型配列。MD5の算出結果を文字列にして格納する
// 戻り値: 成功=1、失敗=0（失敗時はmd5の指すアドレスの中のデータは変えない）
LibExport BOOL md5dataA( const void *data, int datalength, char    *md5 );
LibExport BOOL md5dataW( const void *data, int datalength, wchar_t *md5 );

#ifdef _UNICODE
#define md5data	md5dataW
#else  /* _UNICODE */
#define md5data	md5dataA
#endif /* _UNICODE */

// 自らのMD5値を取得・比較（ただし、比較元MD5が'x'32個なら比較しない
// fname    : チェック対象のファイル名(NULLのときは、自プログラム名を使用)
// root     : 最終正常起動日時を記録するためのレジストリのハイブ
// regkey   : 最終正常起動日時を記録するためのレジストリのキー
// lasttime : 前回正常起動日時を返す32バイト以上のエリア(NULLのときは無視)
//   なお、root == NULL の場合は、regkey をファイル名と見なして、そこへ記録する。
//   regkey == NULL の時は、記録を行わない。
// 戻り値 = 0 : MD5不一致、 1 : MD5一致、 2 : 未判明、 3 : 自プログラム名取得不可
LibExport int md5FileCheckA( const char    *fname, HKEY root, const char    *regkey, char    *lasttime );
LibExport int md5FileCheckW( const wchar_t *fname, HKEY root, const wchar_t *regkey, wchar_t *lasttime );

#ifdef _UNICODE
#define md5FileCheck	md5FileCheckW
#else  /* _UNICODE */
#define md5FileCheck	md5FileCheckA
#endif /* _UNICODE */

// WOW64下の32bitプロセスとして実行している場合、TRUEを返す。そうでない場合はFALSEを返す。
LibExport BOOL tf_IsWow64Process();

// 指定されたプロセスが、WOW64下の32bitプロセスとして実行している場合、TRUEを返す。そうでない場合はFALSEを返す。
LibExport BOOL tf_IsWow64ProcessHandle(HANDLE hProcess);


// 現在のスレッドにおける、WOW64によるファイルリダイレクション(System32→SysWOW64)を無効化する。成功すると0以外の値が返る。
// 引数には、現在のリダイレクトするかどうかの状態を入れるための変数へのポインタを指定する。
LibExport BOOL tf_Wow64DisableWow64FsRedirection(PVOID *pOldValue);

// 現在のスレッドにおける、WOW64によるファイルリダイレクション(System32→SysWOW64)を前の状態に戻す。成功すると0以外の値が返る。
// 引数には、現在のリダイレクトするかどうかの状態を入れるための変数を指定する。これは、Wow64DisableWow64FsRedirectionの
// 引数へ入れたときに得られた値となる。つまり、Wow64DisableWow64FsRedirection前の状態に復帰するということになる。
LibExport BOOL tf_Wow64RevertWow64FsRedirection(PVOID OldValue);

// カレントディレクトリをWindowsのSystem32フォルダに移してからDLLをLoadする
LibExport HMODULE LoadLibrary_System32W(const wchar_t* pwzFileName);
LibExport HMODULE LoadLibrary_System32A(const char *pszFileName);

#ifdef _UNICODE
#define LoadLibrary_System32	LoadLibrary_System32W
#else  /* _UNICODE */
#define LoadLibrary_System32	LoadLibrary_System32A
#endif /* _UNICODE */

// 再帰的にフォルダ内のファイルを削除
LibExport int emptyDirectoryW(LPCWSTR folder, FILETIME *bf_ft);	// [Unicode版]
LibExport int emptyDirectoryA(LPCSTR folder, FILETIME *bf_ft);	// [ANSI版]

// UAC有効時に、管理者権限プログラムへの、一般プログラムからのドラッグ＆ドロップを許可
LibExport int enableDropFiles(void);

#ifdef _UNICODE
#define emptyDirectory			emptyDirectoryW
#else  /* _UNICODE */
#define emptyDirectory			emptyDirectoryA
#endif /* _UNICODE */

// flags for call_unlha32x(), call_unzip32x() and call_zip32j()
//
#ifndef T_TF_SUCCESS
#define T_TF_SUCCESS		0
#define T_TF_DLLNOTFOUND	1
#define T_TF_ILLEGALDLL		2
#define T_TF_ERROR			3
#define T_TF_ILLEGALCALL	4
#endif /* T_TF_SUCCESS */

// flags for SHEmptyRecycleBin()
//
#ifndef SHERB_NOCONFIRMATION
#define SHERB_NOCONFIRMATION    0x00000001
#define SHERB_NOPROGRESSUI      0x00000002
#define SHERB_NOSOUND           0x00000004
#endif /* SHERB_NOCONFIRMATION */

// a flag for GetExl()/SetExl()
//
#ifndef WS_EX_LAYERED
  #define WS_EX_LAYERED		0x80000
  #define WS_EX_NOACTIVATE	0x8000000
#endif /* WS_EX_LAYERED */

// a flag for isKanji1()
//
#ifndef ISKANJI1M
#define ISKANJI1MA(x) ((0x81 <= ((unsigned char)(x)) && ((unsigned char)(x)) <= 0x9F) || (0xE0 <= ((unsigned char)(x)) && ((unsigned char)(x)) <= 0xEF) || (0xF0 <= ((unsigned char)(x)) && ((unsigned char)(x)) <= 0xFC))
#define ISKANJI1MW(x) (0)

#ifdef _UNICODE
#define ISKANJI1M	ISKANJI1MW
#else  /* _UNICODE */
#define ISKANJI1M	ISKANJI1MA
#endif /* _UNICODE */

#endif /* ISKANJI1M */

#ifndef UBOUND
// 配列のサイズ計算(_countofと同じかな)
#define UBOUND(array) (sizeof(array)/sizeof(array[0]))
#endif /* UBOUND */

#ifndef mstrncmp
#define mstrncmp(str1,str2) strncmp((str1),(str2),strlen(str2))
#endif /* mstrncmp */

#ifndef mwcsncmp
#define mwcsncmp(str1,str2) wcsncmp((str1),(str2),wcslen(str2))
#endif /* mwcsncmp */

#ifndef debwrite
#define debwrite(str1) {FILE *fp;if(NULL!=(fp=fopen("temp.txt","at"))){fputs(str1,fp);fclose(fp);}}
#endif /* debwrite */

// 取扱DLL名
#define UNLHA32DLL	    "unlha32.dll"
#define L_UNLHA32DLL    L"unlha32.dll"
#define UNZIP32DLL	    "unzip32.dll"
#define ZIP32JDLL       "zip32j.dll"
#define SEVENZIP32DLL	"7-zip32.dll"

#ifdef _WIN64
#define UNLHA64DLL	    "unlha64.dll"
#define L_UNLHA64DLL    L"unlha64.dll"
#define UNZIP64DLL	    "unzip64.dll"
#define ZIP64JDLL       "zip64j.dll"
#define SEVENZIP64DLL	"7-zip64.dll"
#endif

// safefree() and safedelete() macro
//
#ifndef safefree
#define safefree(p)   {if(p){free((void *)(p));p=0;}}
#define safedelete(p) {if(p){delete[] p;p=0;}}
#define safedelete1(p) {if(p){delete p;p=0;}}
#define safegfree(h)  {if(h){GlobalFree(h);h=0;}}
#define zalloc(n)     ((char *)calloc((n),sizeof(char)))
#define walloc(n)     ((wchar_t *)calloc((n),sizeof(wchar_t)))
#define talloc(n)     ((TCHAR *)calloc((n),sizeof(TCHAR)))
#endif /* safefree */

// ATMLチェック
// 現在は問題は解消されたと見なすので、必ず0を返すようにする。
#define ATML_ENABLED 0
// 1:チェックNG, 0:チェックOK
LibExport int checkAtmlA();
LibExport int checkAtmlW();

#ifdef _UNICODE
#define checkAtml	checkAtmlW
#else  /* _UNICODE */
#define checkAtml	checkAtmlA
#endif /* _UNICODE */

#endif /* MYLIB__ISTTOOLFUNC__ */
