Frost Moon Project

Src/Ashley.cpp-Ashley Ver.1.30- - Frost Moon Project アクセスランキング

Home > ソフトウェア > Ashley > Ashley130.zip/Ashley130.exe > Src > Ashley.cpp

//Ashley.cpp
//メイン

/*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
    Ashley Ver.1.30
    Coded by x@rgs

    This code is released under NYSL Version 0.9982
    See NYSL_withfaq.TXT for further details.

    Ashleyは、アップローダからダウンロードしたZIPやRAR等のファイル名を元に戻すソフトです。
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*/


#include"Common.h"
#include"CommonSettings.h"
#include"CtrlAHook.h"
#include"DebugConsole.h"
#include"GDIPlusInit.h"
#include"GetDirName.h"
#include"GetFileList.h"
#include"Function.h"
#include"ListView.h"
#include"Path.h"
#include"PrivateProfile.h"
#include"Settings.h"
#include"Thumbnail.h"
#include<shlwapi.h>
#include<process.h>

HWND g_hMainWnd=NULL;//メインウインドウのハンドル
HWND g_hListView=NULL;//リストビューのハンドル
HWND g_hListViewHeader=NULL;//リストビューのヘッダーのハンドル
HWND g_hStatusBar=NULL;//ステータスバーのハンドル
HWND g_hStatusProgressBar=NULL;//ステータスバー上のプログレスバーのハンドル
HWND g_hProgressDlg=NULL;//プログレスバーダイアログのハンドル
HINSTANCE g_hInstance=NULL;//インスタンスハンドル

WNDPROC DefToolBarProc;//ツールバーのプロシージャ保存用
WNDPROC DefListViewProc;//リストビューのプロシージャ保存用
WNDPROC DefListViewHeaderProc;//リストビューヘッダのプロシージャ保存用

HIMAGELIST g_hImgFileIcon=NULL;//イメージリストハンドル[ファイルのアイコン]
HIMAGELIST g_hImgThumbnail=NULL;//イメージリストハンドル

//リストビュー用フォント
HFONT g_hDefaultItemFont=NULL;
HFONT g_hReadyItemFont=NULL;
HFONT g_hRenamedItemFont=NULL;
HFONT g_hFailedItemFont=NULL;

//WM_SETFONT用
HFONT g_hBoldFont=NULL;
HFONT g_hNormalFont=NULL;

//リストビューのファイルアイコンテーブル
struct FileIconTable{
    tstring strType;
    int iIconIndex;
};
std::vector<FileIconTable> g_vFileIconTable;

//リストビューカラムのテーブル
struct LISTVIEWCOLUMN_TABLE g_ListViewColumn_Table[LISTITEM_NUM];

//設定構造体
struct CONFIG g_Config;
//ウインドウを表示しない[実行ファイルにDnD/「送る」メニュー]
bool g_bNoWindow=false;
//設定ダイアログが表示されている
bool g_bSettingsDialog=false;
//ファイル処理中
bool g_bWorking=false;
//スレッド動作中
bool g_bThread=false;

//常に手前に表示
bool g_bAlwaysOnTop=false;
//ファイルサイズをKB単位
bool g_bFormatKBSize=true;
//ソートは昇順か降順か
int g_iSortUp=0;

//ログファイルのパス
TCHAR g_szLogFile[MAX_PATH]={0};

//コマンドラインオプション
struct CommandLineOptions{
    bool bShowWindow;//ウインドウを表示する
    bool bSilent;//進捗ダイアログを表示しない
    bool bVerySilent;//進捗/報告ダイアログを表示しない。
};

//サムネイルサイズ
enum ENUMTHUMBSIZE{
    NO_THUMBNAIL,//表示しない
    SMALL_THUMBNAIL,//小さいサイズ
    NORMAL_THUMBNAIL,//標準サイズ
    LARGE_THUMBNAIL//大きいサイズ
};

ENUMTHUMBSIZE g_eThumbSize=NO_THUMBNAIL;

//書庫情報の構造体
typedef struct{
    TCHAR szCurrentFileName[MAX_PATH];//現在のファイル名
    TCHAR szNewFileName[MAX_PATH];//新しいファイル名
    int iStatus;//ステータス(文字列はArchiveStatus参照)
    TCHAR szDirectory[MAX_PATH];//ディレクトリ
    LARGE_INTEGER liSize;//サイズ
    DWORD dwAttribute;//属性
    TCHAR szType[64];//種類
    int iIcon;//アイコン
    FILETIME ftLastModified;//更新日時

    TCHAR szCurrentFullFileName[MAX_PATH];//現在のファイル名[フルパス]
    TCHAR szNewFullFileName[MAX_PATH];//新しいファイル名[フルパス]
    TCHAR szOldFullFileName[MAX_PATH];//現在のファイル名のバックアップ[フルパス]
    TCHAR szOldFileName[MAX_PATH];//現在のファイル名のバックアップ
    UNIT uiItemState;//アイテムの状態(ListView_G/SetItemState)
}ARCHIVEFILEINFO,*LPARCHIVEFILEINFO;
//グローバルなファイルの構造体
LPARCHIVEFILEINFO g_lpArcFileInfo;

#ifdef DEBUG
    #define ARCHIVE_INFO(g_lpArcFileInfo,iIndex)                        \
            dprintf(_T("\n***Archive_Information***\n"                    \
                        "   szCurrentFileName=%s\n"                        \
                        "   szNewFileName=%s\n"                            \
                        "   iStatus=%d\n"                                \
                        "   szDirectory=%s\n"                            \
                        "   szType=%s\n"                                \
                        "   szCurrentFullFileName=%s\n"                    \
                        "   szNewFullFileName=%s\n"                        \
                        "   szOldFullFileName=%s\n"                        \
                        "   szOldFileName=%s\n"                            \
                        "   uiItemState=%d\n"),                            \
                        g_lpArcFileInfo[iIndex].szCurrentFileName,        \
                        g_lpArcFileInfo[iIndex].szNewFileName,            \
                        g_lpArcFileInfo[iIndex].iStatus,                \
                        g_lpArcFileInfo[iIndex].szDirectory,            \
                        g_lpArcFileInfo[iIndex].szType,                    \
                        g_lpArcFileInfo[iIndex].szCurrentFullFileName,    \
                        g_lpArcFileInfo[iIndex].szNewFullFileName,        \
                        g_lpArcFileInfo[iIndex].szOldFullFileName,        \
                        g_lpArcFileInfo[iIndex].szOldFileName,            \
                        g_lpArcFileInfo[iIndex].uiItemState                \
                )
#else

#endif //DEBUG


int g_iFileCount=0;//重複したファイルを含まないファイル数


#define SUPPORTEDFILE_COUNT 5
//対応ファイル
struct SupportedFile{
    LPCTSTR lpszExtension;//拡張子
    bool* pbEnable;//EnableFileType
}

SupportedFile[]={
    {_T(".zip"),&g_Config.EnableFileType.bZip},
    {_T(".7z"),&g_Config.EnableFileType.b7z},
    {_T(".cab"),&g_Config.EnableFileType.bCab},
    {_T(".lzh"),&g_Config.EnableFileType.bLzh},
    {_T(".rar"),&g_Config.EnableFileType.bRar},
};

//ステータス
struct ArchiveStatus{
    LPCTSTR lpszStatus;
}

ArchiveStatus[]={
    {_T("")},//ARC_DEFAULT
    {_T("リネームすることが出来ます")},//ARC_READY_FOR_RENAME
    {_T("正常にリネームされました")},//ARC_RENAMED

    {_T("リネームに失敗しました")},//ARC_RENAME_FAILURE
    {_T("ファイル名に使えない文字が含まれています")},//ARC_ERROR_BADNAME
    {_T("ファイル名とフォルダ名が一致します")},//ARC_ERROR_NEEDNT_TO_RENAME


    {_T("ファイルが見つかりません")},//ARC_ERROR_FILE_NOT_FOUND
    {_T("対応していないファイルです")},//ARC_ERROR_FILE_NOT_SUPPORTED
    {_T("アーカイバDLLが実行中です")},//ARC_ERROR_DLL_IS_RUNNING
    {_T("ファイルを開くことが出来ません")},//ARC_ERROR_FILE_CANT_OPEN
    {_T("ファイル内の情報を取得することが出来ません")},//ARC_ERROR_FILE_CANT_GET_INFORMATION
    {_T("ファイル名を取得することが出来ません")},//ARC_ERROR_FILE_CANT_GETFILENAME
    {_T("ファイル内にフォルダが見つかりません")},//ARC_ERROR_DIRECTORY_NOT_FOUND_IN_ARCHIVE
};


//処理終了メッセージ(Thread->Main)
//AddSelectDirectoryThread()
#define WM_EXIT_ADDSELECTDIRECTORY_THREAD (WM_APP+1)
//AddDroppedFilesThread()
#define WM_EXIT_ADDDROPPEDFILES_THREAD (WM_APP+2)
//FileNameThread()
#define WM_EXIT_FILENAME_THREAD (WM_APP+3)
//UpdateLatestVersionThread()
#define WM_EXIT_UPDATELATESTVERSION_THREAD (WM_APP+4)
//CreateThumbnailThread()
#define WM_EXIT_CREATETHUMBNAIL_THREAD (WM_APP+5)
//サムネイル作成メッセージ
#define WM_CREATETHUMBNAIL (WM_APP+6)

#define WM_SHOWPROGRESSBAR (WM_APP+7)
//プログレスバーダイアログプロシージャに渡すデータ
typedef struct{
    int iArgc;//argc
    LPTSTR* lplpszArgv;//argv
    struct CommandLineOptions clOptions;//コマンドラインオプション
}Param_ProgressBarDialogProc,*lpParam_ProgressBarDialogProc;
Param_ProgressBarDialogProc param_ProgressBarDialogProc;

//NoWindowRenameThread()の引数
typedef struct{
    HWND hDlg;//ダイアログのハンドル
    HWND hProgressBar;//プログレスバーのハンドル
    LPARCHIVEFILEINFO lpArcFileInfo;//ファイルの情報
    struct CommandLineOptions clOptions;//コマンドラインオプション
    int iItemCount;//ファイル数
}Param_NoWindowRenameThread,*lpParam_NoWindowRenameThread;
Param_NoWindowRenameThread param_NoWindowRenameThread;
//NoWindowでリネームするスレッドのハンドル
HANDLE g_hNoWindowRenameThread=NULL;

//AddSelectDirectoryThread()の引数
typedef struct{
    HWND hWnd;//処理終了の報告先ウインドウハンドル
    TCHAR szDirectory[MAX_PATH];//追加するディレクトリ名
    int iBeforeFileCount;//ファイル追加前のファイル数
}Param_AddSelectDirectoryThread,*lpParam_AddSelectDirectoryThread;
Param_AddSelectDirectoryThread param_AddSelectDirectoryThread;
//選択ディレクトリ追加スレッドハンドル
HANDLE g_hAddSelectDirectoryThread=NULL;

//AddDroppedFilesThread()の引数
typedef struct{
    HWND hWnd;//処理終了の報告先ウインドウハンドル
    HWND hStatusProgressBar;//ステータスバー上のプログレスバーのハンドル
    HDROP hDrop;//ドロップされたファイルのハンドル
    int iBeforeFileCount;//ファイル追加前のファイル数
}Param_AddDroppedFilesThread,*lpParam_AddDroppedFilesThread;
Param_AddDroppedFilesThread param_AddDroppedFilesThread;
//ドロップされたファイルを追加するスレッドのハンドル
HANDLE g_hAddDroppedFilesThread=NULL;

//FileNameThread()の引数
typedef struct{
    bool (*pRunFunc)(LPARCHIVEFILEINFO ArcFileInfo,int iIndex);//実行したい関数名
    HWND hWnd;//処理終了の報告先ウインドウハンドル
    HWND hStatusProgressBar;//ステータスバー上のプログレスバーのハンドル
    LPARCHIVEFILEINFO lpArcFileInfo;//ファイルの情報
    int iItemCount;//ファイル数
    int iSelected;//選択されているアイテム数
    bool bSelectedOnly;//選択したファイルのみが対象
}Param_FileNameThread,*lpParam_FileNameThread;
Param_FileNameThread param_FileNameThread;
//ファイル名を操作するスレッドのハンドル
HANDLE g_hFileNameThread=NULL;

//UpdateLatestVersionThread()の引数
typedef struct{
    HWND hWnd;//処理終了の報告先ウインドウハンドル
    HINSTANCE hInstance;//インスタンス
    HWND hStatusBar;//ステータスバーのハンドル
    HWND hStatusProgressBar;//ステータスバー上のプログレスバーのハンドル
    bool bNotFoundMessage;//最新版が見つからなかった旨のメッセージダイアログを表示する
}Param_UpdateLatestVersionThread,*lpParam_UpdateLatestVersionThread;
Param_UpdateLatestVersionThread param_UpdateLatestVersionThread;
//最新版にバージョンアップするスレッドのハンドル
HANDLE g_hUpdateLatestVersionThread=NULL;

//CreateThumbnailThread()の引数
typedef struct{
    HWND hWnd;//処理終了の報告先ウインドウハンドル
    HWND hListView;//リストビューハンドル
    HIMAGELIST hImg;//サムネイルを格納するイメージリストハンドル
    HWND hStatusProgressBar;//ステータスバー上のプログレスバーのハンドル
    int iItemCount;//ファイル数
    LPARCHIVEFILEINFO lpArcFileInfo;//サムネイルを作成したいファイルの情報
    int iBeginIndex;//サムネイルの作成を開始するIndex
    bool bRegenerate;//サムネイルを再作成する
    int iSelected;//選択されているアイテム数
    int iWidth;//サムネイルの横幅
    int iHeight;//サムネイルの縦幅
}Param_CreateThumbnail,*lpParam_CreateThumbnail;
Param_CreateThumbnail param_CreateThumbnail;
//サムネイル作成スレッドのハンドル
HANDLE g_hCreateThumbnailThread=NULL;

//クリティカルセクション
CRITICAL_SECTION csCriticalSection;


#define IDC_TREEVIEW 100
#define IDC_LISTVIEW 101
#define IDC_TOOLBAR 102

//ツールバーのボタンID
enum{
    ID_FILE=1001,//ファイルを開く
    ID_FOLDER,//フォルダを開く
    ID_ALLRENAME,//すべてリネーム
    ID_RENAME,//リネーム
    ID_ANALYZE,//ファイル名を取得
    ID_UNDO,//取り消す
    ID_THUMBNAIL,//サムネイル
    ID_CLEAR,//クリア
    ID_OPTIONS,//オプション
    ID_EXIT,//終了
    ID_COUNT//ダミー
};

//ツールバーのボタン数
const unsigned int BUTTONCOUNT=ID_COUNT-1001;

//キャスト済み_beginthreadex()
typedef unsigned (__stdcall *PTHREAD_START) (void *);

#define BEGINTHREADEX(psa,cbStack,pfnStartAddr, \
    pvParam, fdwCreate, pdwThreadID)            \
    ((HANDLE) _beginthreadex(                    \
    (void *) (psa),                                \
    (unsigned) (cbStack),                        \
    (PTHREAD_START) (pfnStartAddr),                \
    (void *) (pvParam),                            \
    (unsigned) (fdwCreate),                        \
    (unsigned *) (pdwThreadID)))


//ダブルバッファ[XP以降]
#ifndef LVS_EX_DOUBLEBUFFER
    #define LVS_EX_DOUBLEBUFFER 0x00010000
#endif

//ソートアイコン(三角形)[XP以降]
#ifndef HDF_SORTDOWN
    #define HDF_SORTDOWN 0x0200
    #define HDF_SORTUP   0x0400
#endif

//LVM_SETVIEW/LVM_GETVIEW[XP以降]
#ifndef LV_VIEW_ICON
    #define LV_VIEW_ICON        0x0000
    #define LV_VIEW_DETAILS     0x0001
    #define LV_VIEW_SMALLICON   0x0002
    #define LV_VIEW_LIST        0x0003
    #define LV_VIEW_TILE        0x0004
    #define LV_VIEW_MAX         0x0004
#endif

typedef struct tagLVTILEVIEWINFO{
    UINT cbSize;
    DWORD dwMask;
    DWORD dwFlags;
    SIZE sizeTile;
    int cLines;
    RECT rcLabelMargin;
}LVTILEVIEWINFO,*PLVTILEVIEWINFO;

#ifndef LVTVIF_AUTOSIZE
    #define LVTVIF_AUTOSIZE    0x00000000
    #define LVTVIF_FIXEDWIDTH  0x00000001
    #define LVTVIF_FIXEDHEIGHT 0x00000002
    #define LVTVIF_FIXEDSIZE   0x00000003

    #define LVTVIM_TILESIZE    0x00000001
    #define LVTVIM_COLUMNS     0x00000002
    #define LVTVIM_LABELMARGIN 0x00000004
#endif

typedef struct LVTILEINFO{
    UINT cbSize;
    int  iItem;
    UINT cColumns;
    PUINT puColumns;
#if (_WIN32_WINNT>=0x0600)
    int *piColFmt;
#endif 
}LVTILEINFO,*PLVTILEINFO;

//サムネイル再作成メニュー
#define IDM_REGENERATE_THUMBNAIL                40087
#define IDM_ALLREGENERATE_THUMBNAIL             40088



//関数のプロトタイプ宣言

//ファイルの種類からイメージリストのインデックスを取得
int GetIndexFromType(LPCTSTR lpszType);
//ファイルの種類でイメージリストにアイコンを追加
bool AddIconFromType(LPCTSTR lpszType,LPCTSTR lpszFileName);
//ファイルアイコンを取得しなおす
void RefreshFileIcon(void);

//リストのフォントを設定しなおす
void RefreshGUIFont(void);

//現在のサムネイルサイズを取得
inline int GetThumbnailSize();
//対応している書庫ファイルであるか否か
bool IsSupportedArchive(const TCHAR* pszPath);
//対応している書庫ファイルであるか否か
bool IsSupportedArchive(const TCHAR* pszPath);

//複数のファイルを選択
bool SelectArchiveFile(HWND hWnd);

//選択されているファイルをリストビューから削除し、ファイル本体はゴミ箱に送る
void RemoveListViewFile(void);

//szCurrentFullFileNameの重複があるかどうか検索
bool SearchCurrentFullPathName(TCHAR* pszCurrentFullFileName);

void Swap(LPARCHIVEFILEINFO ArcInfo1,LPARCHIVEFILEINFO ArcInfo2);
void QuickSort(LPARCHIVEFILEINFO ArcFileInfo,int iLeft, int iRight,int iSubItem,int iSortUp);
//リストビューをソートする
void SortListViewItem(int iSubItem,int iSortUp);

//ファイルの再帰的検索
void AddDirectory(LPCTSTR lpszDirectory, LPCTSTR lpszExtension);
//ファイルの情報を構造体に追加
void CreateArchiveFileData(LPARCHIVEFILEINFO ArcFileInfo);
//ファイルの情報をリストビューに追加
bool AddArchiveFiles(TCHAR* pszPath);
//アイテムを追加
void AddListViewItem(LPARCHIVEFILEINFO ArcFileInfo);
//iItem番のアイテムを削除
bool RemoveListViewItem(int iItem);
//リストビューの諸々の調整
void AdjustListView(bool bEnsureVisible=false);

//書庫のエラーメッセージを取得
bool GetArcErrorMessage(TCHAR* szResult,int iErrorMessage);

//サムネイル作成
HANDLE CreateThumbnail(int iItemCount,int iWidth,int iHeight,HWND hStatusProgressBar=NULL,int iBeginIndex=0,bool bRegenerate=false,int iSelected=-1);
//サムネイル作成スレッド
unsigned __stdcall CreateThumbnailThread(LPVOID lvParam);
//新しいファイル名の取得、追加
bool GetNewFileName(LPARCHIVEFILEINFO ArcFileInfo,int iIndex);
//新しいファイル名にリネーム
bool RenameFileName(LPARCHIVEFILEINFO ArcFileInfo,int iIndex);
//リネームを取り消す
bool UndoFileName(LPARCHIVEFILEINFO ArcFileInfo,int iIndex);
//新しいファイル名の取得、追加を行うスレッド
unsigned __stdcall FileNameThread(LPVOID lvParam);
//ファイル名を操作するスレッド
HANDLE CallFileNameThread(bool (*pRunFunc)(LPARCHIVEFILEINFO,int),LPARCHIVEFILEINFO lpArcFileInfo,HWND hStatusProgressBar=NULL,int iItemCount=1,int iSelected=-1,bool bSelectedOnly=false);
//選択されたフォルダを追加するスレッド
unsigned __stdcall AddSelectDirectoryThread(LPVOID lvParam);
//ドロップされたファイルを追加する
HANDLE AddDroppedFiles(HDROP hDrop,int iBeforeFileCount,HWND hStatusProgressBar=NULL);
//ドロップされたファイルを追加するスレッド
unsigned __stdcall AddDroppedFilesThread(LPVOID lvParam);
//最新版にバージョンアップするスレッドを呼び出す
HANDLE CallUpdateLatestVersion(HWND hWnd,HINSTANCE hInstance,HWND hStatusBar=NULL,HWND hStatusProgressBar=NULL,bool bNotFoundMessage=true);
//最新版にバージョンアップするスレッド
unsigned __stdcall UpdateLatestVersionThread(LPVOID lvParam);

//NoWindowでリネームするスレッド
unsigned __stdcall NoWindowRenameThread(LPVOID lvParam);

//ファイル名の変更ダイアログプロシージャ
LRESULT CALLBACK RenameDialogProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
//ツールバーのプロシージャ
LRESULT CALLBACK ToolBarProc(HWND hToolBar,UINT uMsg,WPARAM wParam,LPARAM lParam);
//リストビューのプロシージャ
LRESULT CALLBACK ListViewProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//リストビューヘッダーのプロシージャ
LRESULT CALLBACK ListViewHeaderProc(HWND hHeader,UINT uMsg,WPARAM wParam,LPARAM lParam);
//ウインドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//ウインドウクラスを登録
bool InitApplication(HINSTANCE hInstance,LPCTSTR lpszClassName);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow);


//ファイルの種類からイメージリストのインデックスを取得
int GetIndexFromType(LPCTSTR lpszType){
    if(lpszType==NULL)return -1;
    for(int i=0;i<(int)g_vFileIconTable.size();i++){
        if(_tcscmp(g_vFileIconTable[i].strType.c_str(),lpszType)==0){
            return g_vFileIconTable[i].iIconIndex;
        }
    }
    return -1;
}

//ファイルの種類でイメージリストにアイコンを追加
bool AddIconFromType(LPCTSTR lpszType,LPCTSTR lpszFileName){
    bool bResult=false;
    int iFileIconIndex=g_vFileIconTable.size();

    FileIconTable* pFileIconTable=new FileIconTable;
    //構造体に追加
    pFileIconTable->strType=tstring(lpszType);
    pFileIconTable->iIconIndex=iFileIconIndex;
    //構造体を保存
    g_vFileIconTable.insert(g_vFileIconTable.begin()+iFileIconIndex,*pFileIconTable);
    delete pFileIconTable;
    pFileIconTable=NULL;

    //アイコンを追加
    SHFILEINFO shFileInfo;

    SHGetFileInfo(lpszFileName,0,&shFileInfo,sizeof(shFileInfo),SHGFI_ICON|SHGFI_SMALLICON);
    if(shFileInfo.hIcon!=NULL){
        bResult=(ImageList_AddIcon(g_hImgFileIcon,shFileInfo.hIcon)!=-1)?true:false;
        DestroyIcon(shFileInfo.hIcon);
    }
    return bResult;
}

//ファイルアイコンを取得しなおす
void RefreshFileIcon(void){
    //アイコンテーブルを初期化
    g_vFileIconTable.clear();
    ImageList_RemoveAll(g_hImgFileIcon);
    ImageList_SetImageCount(g_hImgFileIcon,0);
    ImageList_SetBkColor(g_hImgFileIcon,CLR_NONE);//TODO:
    for(int i=0;i<g_iFileCount;i++){
        if(GetIndexFromType(g_lpArcFileInfo[i].szType)==-1){
            AddIconFromType(g_lpArcFileInfo[i].szType,g_lpArcFileInfo[i].szCurrentFullFileName);
        }
    }
    if(!ListView_SetImageList(g_hListView,g_hImgFileIcon,LVSIL_NORMAL)){};//適用/warning: value computed is not used対策
    return;
}

//リストのフォントを設定しなおす
void RefreshGUIFont(void){
    //1.フォントが太字だと、ファイル名が隠れてしまう場合があるので、
    //2.ファイルリネーム時、新しいファイル名が複数行にわたる場合、一部が表示されないので、
    //  リストビュー全体に太字フォント適用後、ヘッダ、ツールチップに通常のフォントを設定して対策
    if(g_hBoldFont)DeleteObject(g_hBoldFont);
    g_hBoldFont=CreateGUIFont(NULL,g_Config.DefaultItemDesign.iFontSize,SFONT_BOLD);
    SendMessage(g_hListView,WM_SETFONT,(WPARAM)g_hBoldFont,MAKELPARAM(true,0));

    if(g_hNormalFont)DeleteObject(g_hNormalFont);
    g_hNormalFont=CreateGUIFont(NULL,0,0);
    //ヘッダ
    SendMessage(g_hListViewHeader,WM_SETFONT,(WPARAM)g_hNormalFont,MAKELPARAM(true,0));
    //ツールチップ
    SendMessage(ListView_GetToolTips(g_hListView),WM_SETFONT,(WPARAM)g_hNormalFont,MAKELPARAM(true,0));
    return;
}

//現在のサムネイルサイズを取得
inline int GetThumbnailSize(){
    int iResult=0;
    switch(g_eThumbSize){
        case SMALL_THUMBNAIL:
            iResult=g_Config.Thumbnail.iSmall;
            break;
        case NORMAL_THUMBNAIL:
            iResult=g_Config.Thumbnail.iNormal;
            break;
        case LARGE_THUMBNAIL:
            iResult=g_Config.Thumbnail.iLarge;
            break;
        case NO_THUMBNAIL:
        default:
            iResult=0;
            break;
    }
    return iResult;
}

//対応している書庫ファイルであるか否か
bool IsSupportedArchive(TCHAR* pszPath){
    TCHAR szExtension[_MAX_EXT]={0};

    _tcscpy(szExtension,PathFindExtension(pszPath));
    for(int i=0;i<SUPPORTEDFILE_COUNT;i++){
        if((_tcsicmp(szExtension,SupportedFile[i].lpszExtension))==0&&(*(SupportedFile[i].pbEnable)))return true;
    }
    return false;
}

//複数のファイルを選択
bool SelectArchiveFile(HWND hWnd){
    bool bResult=false;
    int iLen=0;
    TCHAR szFullFile[MAX_PATH]={0};//リスト追加用
    TCHAR szDlgErr[30]={0};//CommDlgExtendedError()用
    TCHAR szDirectory[MAX_PATH]={0};
    TCHAR szFile[2526]={0};
    TCHAR* pszFile=NULL;
    TCHAR szDeskTopPath[MAX_PATH]={0};
    TCHAR szEnableFileType[64]={0};
    TCHAR szFilter[128]={0};
    LPITEMIDLIST lpItemIDList=NULL;

    szFile[0]=_T('\0');
    SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP,&lpItemIDList);
    SHGetPathFromIDList(lpItemIDList,szDeskTopPath);
    CoTaskMemFree(lpItemIDList);

    //対象書庫ファイルのFilter作成
    for(int i=0;i<SUPPORTEDFILE_COUNT;i++){
        if(*(SupportedFile[i].pbEnable)){
            _tcscat(szEnableFileType,_T("*"));
            _tcscat(szEnableFileType,SupportedFile[i].lpszExtension);
            _tcscat(szEnableFileType,_T(";"));
        }
    }
    if(!lstrlen(szEnableFileType))return false;
    //末尾の「;」を削除
    szEnableFileType[lstrlen(szEnableFileType)-1]=_T('\0');
    wsprintf(szFilter,_T("書庫ファイル (%s)|%s||"),szEnableFileType,szEnableFileType);
    int iPosition=0;
    while(iPosition!=-1){
        iPosition=path::LocateLastCharacter(szFilter,_T('|'));
        if(iPosition!=-1)szFilter[iPosition]=_T('\0');
    }

    OPENFILENAME ofnOpen;
    ZeroMemory(&ofnOpen,sizeof(ofnOpen));
    ofnOpen.lStructSize=sizeof(OPENFILENAME);
    ofnOpen.hwndOwner=hWnd;
    ofnOpen.lpstrInitialDir=szDeskTopPath;
    ofnOpen.lpstrFilter=szFilter;
    ofnOpen.lpstrFile=szFile;
    ofnOpen.nMaxFile=ARRAY_SIZEOF(szFile);
    ofnOpen.lpstrTitle=_T("ファイルを選択してください");
    ofnOpen.Flags=OFN_ALLOWMULTISELECT|OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;
    //ファイルを複数選択した場合、フォルダ\0ファイル\0ファイルで格納する。ファイルはフルパスでない。
    if(GetOpenFileName(&ofnOpen)){
        if(!path::IsDirectory(szFile)){
            bResult=AddArchiveFiles(szFile);
        }
        _tcscpy(szDirectory,szFile);
        pszFile=szFile;
        while(1){
            iLen=lstrlen(pszFile);
            pszFile+=(iLen+1);
            if(pszFile[0]==_T('\0'))break;
            _tcscpy(szFullFile,szFile);
            path::AddBackSlash(szFullFile,szFullFile);
            _tcscat(szFullFile,pszFile);
            bResult=(AddArchiveFiles(szFullFile))?true:(bResult)?true:false;
        }
    }else{
        DWORD dwDlgErr=CommDlgExtendedError();
        if(dwDlgErr!=0){
            if(dwDlgErr==FNERR_BUFFERTOOSMALL){//FNERR_BUFFERTOOSMALL[バッファが小さい]
                _tcscpy(szDlgErr,_T("選択したファイルの数が多過ぎます。"));
            }else{
                wsprintf(szDlgErr,_T("ファイルの選択に失敗しました。\nErrCode:0x%08X"),dwDlgErr);
            }
            MessageBox(g_hMainWnd,szDlgErr,NULL,MB_ICONWARNING);
        }
        return false;
    }
    return bResult;
}

//選択されているファイルをリストビューから削除し、ファイル本体はゴミ箱に送る
void RemoveListViewFile(void){
    int i=0,j=0;
    int iIndex=0;//単体ファイル選択時用
    int iCount=0;
    int iSize=0;
    int iResult=0;
    TCHAR szMsg[MAX_PATH+30]={0};//MessageBox()用
    LPTSTR lpszFilePath=NULL,psz=NULL;

    iSize=2*sizeof(TCHAR);
    lpszFilePath=(LPTSTR)malloc(iSize+3);
    if(lpszFilePath==NULL){
        MessageBox(g_hMainWnd,_T("メモリの確保に失敗しました。"),NULL,MB_ICONSTOP);
        return;
    }
    i=ListView_GetNextItem(g_hListView,-1,LVNI_SELECTED);
    while(i!=-1){
        int iLen=lstrlen(g_lpArcFileInfo[i].szCurrentFullFileName);
        iCount++;
        iSize+=(iLen+1)*sizeof(TCHAR);
        psz=(LPTSTR)realloc(lpszFilePath,iSize);
        if(psz==NULL){
            MessageBox(g_hMainWnd,_T("メモリの確保に失敗しました。"),NULL,MB_ICONSTOP);
            free(lpszFilePath);
            return;
        }
        lpszFilePath=psz;
        _tcscpy(lpszFilePath+j,g_lpArcFileInfo[i].szCurrentFullFileName);
        j+=iLen+1;
        *(lpszFilePath+j)=_T('\0');
        iIndex=i;
        i=ListView_GetNextItem(g_hListView,i,LVNI_SELECTED);
    }
    if(iCount==1){
        //ファイルの削除の確認
        wsprintf(szMsg,_T("'%s' をごみ箱に移しますか?"),g_lpArcFileInfo[iIndex].szCurrentFullFileName);
    }else if(iCount>0){
        //複数ファイルの削除の確認
        wsprintf(szMsg,_T("これら %d 個のファイルをごみ箱に移しますか?"),iCount);
    }else if(iCount==0){
        return;
    }
    if(g_bAlwaysOnTop)SetWindowPos(g_hMainWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//解除
    if(MessageBox(g_hMainWnd,szMsg,(iCount==1)?_T("ファイルの削除の確認"):_T("複数ファイルの削除の確認"),MB_YESNO|MB_ICONQUESTION)==IDYES){
        iResult=MoveToRecycleBin(g_hMainWnd,lpszFilePath);
    }else{
        iResult=1;
    }
    SetForegroundWindow(g_hMainWnd);
    if(g_bAlwaysOnTop)SetWindowPos(g_hMainWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//手前に表示
    if(lpszFilePath){
        free(lpszFilePath);
        lpszFilePath=NULL;
    }
    if(iResult!=0)return;
    //リストから削除
    for(i=0;i<ListView_GetItemCount(g_hListView);i++){
        if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED){RemoveListViewItem(i);i--;}
    }
    return;
}

//szCurrentFullFileNameの重複があるかどうか検索
bool SearchCurrentFullPathName(TCHAR* pszCurrentFullFileName){
    for(int i=0;i<g_iFileCount;i++){
        if(_tcscmp(g_lpArcFileInfo[i].szCurrentFullFileName,pszCurrentFullFileName)==0)return true;
    }
    return false;
}

void Swap(LPARCHIVEFILEINFO ArcInfo1,LPARCHIVEFILEINFO ArcInfo2){
    ARCHIVEFILEINFO ArcFileInfoTmp=*(ArcInfo1);
    *(ArcInfo1)=*(ArcInfo2);
    *(ArcInfo2)=ArcFileInfoTmp;
}

void QuickSort(LPARCHIVEFILEINFO ArcFileInfo,int iLeft, int iRight,int iSubItem,int iSortUp){
    if(iLeft>=iRight)return;
    int i=0,iResult=0;
    int p=iLeft;

    for(i=iLeft+1;i<=iRight;i++){
        switch(iSubItem){
            case LISTITEM_CURRENTFILENAME:
                iResult=lstrcmp(ArcFileInfo[i].szCurrentFileName,ArcFileInfo[iLeft].szCurrentFileName);
                break;
            case LISTITEM_NEWFILENAME:
                iResult=lstrcmp(ArcFileInfo[i].szCurrentFileName,ArcFileInfo[iLeft].szCurrentFileName);
                break;
            case LISTITEM_STATUS:
                iResult=ArcFileInfo[i].iStatus-ArcFileInfo[iLeft].iStatus;
                break;
            case LISTITEM_DIRECTORY:
                iResult=lstrcmp(ArcFileInfo[i].szDirectory,ArcFileInfo[iLeft].szDirectory);
                break;
            case LISTITEM_SIZE:
                iResult=ArcFileInfo[i].liSize.QuadPart-ArcFileInfo[iLeft].liSize.QuadPart;
                break;
            case LISTITEM_TYPE:
                iResult=lstrcmp(ArcFileInfo[i].szType,ArcFileInfo[iLeft].szType);
                break;
            case LISTITEM_LASTMODIFIED:
                iResult=ArcFileInfo[i].ftLastModified.dwHighDateTime-ArcFileInfo[iLeft].ftLastModified.dwHighDateTime;
                break;
        }

        if(iResult>0)iResult=1;
        else if(iResult==0)continue;
        else iResult=0;

        if(!iSortUp)iResult=!iResult;
        if(iResult){
            Swap(&ArcFileInfo[++p],&ArcFileInfo[i]);
            ImageList_Copy(g_hImgThumbnail,p,g_hImgThumbnail,i,ILCF_SWAP);
        }
    }
    Swap(&ArcFileInfo[iLeft],&ArcFileInfo[p]);
    QuickSort(ArcFileInfo,iLeft,p-1,iSubItem,iSortUp);
    QuickSort(ArcFileInfo,p+1,iRight,iSubItem,iSortUp);
}

//リストビューをソートする
void SortListViewItem(int iSubItem,int iSortUp){
    int i=0;
    LVITEM lvItem;
    HDITEM hdItem;

    //アイテム取得
    int iLVCount=ListView_GetItemCount(g_hListView);
    if(iLVCount<=0)return;
    //アイテムの状態を保存
    for(i=0;i<iLVCount;i++){
        g_lpArcFileInfo[i].uiItemState=ListView_GetItemState(g_hListView,i,LVIS_SELECTED|LVIS_FOCUSED);
    }
    //アイテムの選択を全て解除
    ListView_SetItemState(g_hListView,-1,0,LVIS_SELECTED);
    //ソートを行う
    QuickSort(g_lpArcFileInfo,0,iLVCount-1,iSubItem,iSortUp);
    //アイテムを設定
    for(i=0;i<iLVCount;i++){
        lvItem.mask=LVIF_TEXT|LVIF_IMAGE;
        lvItem.iItem=i;
        lvItem.iSubItem=0;
        lvItem.pszText=LPSTR_TEXTCALLBACK;
        lvItem.cchTextMax=MAX_PATH;
        lvItem.iImage=I_IMAGECALLBACK;
        ListView_SetItem(g_hListView,&lvItem);
        //保存したアイテムの状態を適用
        ListView_SetItemState(g_hListView,i,g_lpArcFileInfo[i].uiItemState,g_lpArcFileInfo[i].uiItemState);
        //フォーカスがあるアイテムが見える位置までスクロールする
        if(g_lpArcFileInfo[i].uiItemState&LVIS_FOCUSED)ListView_EnsureVisible(g_hListView,i,false);
    }
    hdItem.mask=HDI_FORMAT;
    //ヘッダのアイコンを削除
    for(i=0;i<LISTITEM_NUM;i++){
        Header_GetItem(g_hListViewHeader,i,&hdItem);
        hdItem.fmt&=~(HDF_SORTDOWN|HDF_SORTUP);
        Header_SetItem(g_hListViewHeader,i,&hdItem);
    }
    //ヘッダにソート用のアイコンを表示する
    Header_GetItem(g_hListViewHeader,iSubItem,&hdItem);
    hdItem.fmt|=(iSortUp)?HDF_SORTDOWN:HDF_SORTUP;
    Header_SetItem(g_hListViewHeader,iSubItem,&hdItem);
}

//ファイルの再帰的検索
void AddDirectory(LPCTSTR lpszDirectory,LPCTSTR lpszExtension){
    HANDLE hFind;
    WIN32_FIND_DATA FindFileData;
    TCHAR szSearchPath[MAX_PATH+12];
    TCHAR szFilePath[MAX_PATH]={0};
    TCHAR szDirectory[MAX_PATH]={0};

    if(lpszDirectory==NULL)return;
    if(!path::IsDirectory(lpszDirectory))return;
    //バックスラッシュを追加
    path::AddBackSlash(szSearchPath,lpszDirectory);
    _tcscat(szDirectory,szSearchPath);//ディレクトリ名を保存
    _tcscat(szSearchPath,_T("*"));

    //ファイルの検索
//    if((hFind=FindFirstFile(szSearchPath,&FindFileData))!=INVALID_HANDLE_VALUE){
    if((hFind=FindFirstFileEx(szSearchPath,FindExInfoStandard,&FindFileData,FindExSearchNameMatch,NULL,0))!=INVALID_HANDLE_VALUE){
        do{
            if(_tcscmp(FindFileData.cFileName,_T("."))!=0&&_tcscmp(FindFileData.cFileName,_T(".."))!=0){
                if((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)==0){//ファイルである
                    if((_tcsicmp(PathFindExtension(FindFileData.cFileName),lpszExtension))==0){
                        _tcscat(_tcscpy(szFilePath,szDirectory),FindFileData.cFileName);
                        AddArchiveFiles(szFilePath);
                    }
                }else{
                    //サブディレクトリを検索
                    _tcscat(_tcscpy(szFilePath,szDirectory),FindFileData.cFileName);
                    AddDirectory(szFilePath,lpszExtension);
                }
            }
            if(!g_bWorking)break;
        }while(FindNextFile(hFind,&FindFileData));
        FindClose(hFind);
    }
return;
}

//ファイルの情報を構造体に追加
void CreateArchiveFileData(LPARCHIVEFILEINFO lpArcFileInfo){
    HANDLE hFind=NULL;
    WIN32_FIND_DATA wfd;
    SHFILEINFO shFileInfo;

    //ディレクトリを取得
    path::GetParentDirectory(lpArcFileInfo->szDirectory,lpArcFileInfo->szCurrentFullFileName);
    //SHGetFileInfoでファイル名,種類を取得
    CoInitialize(NULL);
    SHGetFileInfo(lpArcFileInfo->szCurrentFullFileName,0,&shFileInfo,sizeof(shFileInfo),SHGFI_DISPLAYNAME|SHGFI_TYPENAME);
    _tcscpy(lpArcFileInfo->szCurrentFileName,shFileInfo.szDisplayName);
    _tcscpy(lpArcFileInfo->szType,shFileInfo.szTypeName);//種類
    CoUninitialize();

    //FindFirstFileでサイズ,属性,更新日時を取得
    hFind=FindFirstFile(lpArcFileInfo->szCurrentFullFileName,&wfd);
    lpArcFileInfo->liSize.HighPart=wfd.nFileSizeHigh;//サイズ[上位32bit]
    lpArcFileInfo->liSize.LowPart=wfd.nFileSizeLow;//サイズ[下位32bit]
    lpArcFileInfo->dwAttribute=wfd.dwFileAttributes;//属性
    lpArcFileInfo->ftLastModified=wfd.ftLastWriteTime;//更新日時
    FindClose(hFind);

    if(GetIndexFromType(lpArcFileInfo->szType)==-1){
        //アイコンを追加
        AddIconFromType(lpArcFileInfo->szType,lpArcFileInfo->szCurrentFullFileName);
    }
    return;
}

//ファイルの情報をリストビューに追加
bool AddArchiveFiles(TCHAR* pszPath){
    ARCHIVEFILEINFO ArcFileInfo={0};

    if(!path::FileExists(pszPath))return false;
    if(g_iFileCount!=0&&!g_bNoWindow){
        if(!g_Config.bAllowDuplicate){//重複を認めない場合
            if(SearchCurrentFullPathName(pszPath))return false;//重複チェック
        }
    }
    _tcscpy(ArcFileInfo.szCurrentFullFileName,pszPath);
    if(!g_bNoWindow){
        CreateArchiveFileData(&ArcFileInfo);//サイズ,更新日時などを取得
    }
    AddListViewItem(&ArcFileInfo);
    return true;
}

//アイテムを追加
void AddListViewItem(LPARCHIVEFILEINFO lpArcFileInfo){
    g_iFileCount++;
    LPARCHIVEFILEINFO lpArcFileInfoTmp=(LPARCHIVEFILEINFO)realloc(g_lpArcFileInfo,sizeof(ARCHIVEFILEINFO)*g_iFileCount);
    dprintf(_T("g_iFileCount=%d\n"),g_iFileCount);
    if(lpArcFileInfo==NULL||lpArcFileInfoTmp==NULL){
        MessageBox((!g_bNoWindow)?g_hMainWnd:NULL,_T("メモリの確保に失敗しました。"),NULL,MB_ICONSTOP);
        SendMessage(g_hMainWnd,WM_CLOSE,0,0);
        return;
    }
    g_lpArcFileInfo=lpArcFileInfoTmp;
    memcpy(&g_lpArcFileInfo[g_iFileCount-1],lpArcFileInfo,sizeof(ARCHIVEFILEINFO));

    //アイテム数を設定
    ListView_SetItemCountEx(g_hListView,g_iFileCount,LVSICF_NOINVALIDATEALL|LVSICF_NOSCROLL);
    return;
}

//iItem番目のアイテムを削除
bool RemoveListViewItem(int iItem){
    if(!INRANGE(0,iItem,g_iFileCount-1))return false;
    if(g_iFileCount==1){
        memset(&g_lpArcFileInfo[0],_T('\0'),sizeof(ARCHIVEFILEINFO));
        if(g_eThumbSize!=NO_THUMBNAIL)ImageList_RemoveAll(g_hImgThumbnail);
    }else{
        if(g_eThumbSize!=NO_THUMBNAIL)ImageList_Remove(g_hImgThumbnail,iItem);
        memmove(&g_lpArcFileInfo[iItem],&g_lpArcFileInfo[iItem+1],sizeof(ARCHIVEFILEINFO)*(g_iFileCount-iItem-1));//構造体から削除
    }

    //リストから削除
    if(ListView_DeleteItem(g_hListView,iItem)){
        g_iFileCount--;
        //アイテム数を設定
        ListView_SetItemCountEx(g_hListView,g_iFileCount,LVSICF_NOINVALIDATEALL|LVSICF_NOSCROLL);
        return true;
    }
    return false;
}

//全てのアイテムを削除
void RemoveAllListViewItem(){
    if(!g_iFileCount)return;

    for(int i=0;i<ListView_GetItemCount(g_hListView);i++){
        if(RemoveListViewItem(i)){
            i--;
        }
    }
    AdjustListView();
    return;
}

//リストビューの諸々の調整
void AdjustListView(bool bEnsureVisible){
    dprintf(_T("AdjustListView(%d)\n"),bEnsureVisible);
    TCHAR szCount[256]={0};

    //フォーカスを設定
    SetFocus(g_hListView);
    //最後のアイテムが完全に見えるようスクロール
    if(bEnsureVisible)ListView_EnsureVisible(g_hListView,ListView_GetItemCount(g_hListView)-1,false);
    //ステータスバーのメッセージ更新
    SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)_T("ファイルやフォルダをドロップしてください"));
    if(ListView_GetItemCount(g_hListView)>0){
        wsprintf(szCount,_T("合計 %d 個のファイル"),ListView_GetItemCount(g_hListView));
        SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)szCount);
    }else{
        SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T(""));
    }
    //再描画
    ListView_RedrawItems(g_hListView,0,ListView_GetItemCount(g_hListView)-1);
    return;
}

//書庫のエラーメッセージを取得
bool GetArcErrorMessage(TCHAR* szResult,int iErrorMessage){
    switch(iErrorMessage){
        case ARC_DEFAULT:
            _tcscpy(szResult,_T(""));
            break;

        case ARC_ERROR_FILE_NOT_FOUND:
            _tcscpy(szResult,_T("ファイルが見つかりません"));
            break;

        case ARC_ERROR_FILE_NOT_SUPPORTED:
            _tcscpy(szResult,_T("対応していないファイルです"));
        break;

        case ARC_ERROR_DLL_IS_RUNNING:
            _tcscpy(szResult,_T("アーカイバDLLが実行中です"));
            break;

        case ARC_ERROR_FILE_CANT_OPEN:
            _tcscpy(szResult,_T("ファイルを開くことが出来ません"));
            break;

        case ARC_ERROR_FILE_CANT_GET_INFORMATION:
            _tcscpy(szResult,_T("ファイルの情報を取得することが出来ません"));
            break;

        case ARC_ERROR_FILE_CANT_GETFILENAME:
            _tcscpy(szResult,_T("ファイル名を取得することが出来ません"));
            break;

        case ARC_ERROR_DIRECTORY_NOT_FOUND_IN_ARCHIVE:
            _tcscpy(szResult,_T("ファイル内にフォルダが見つかりません"));
            break;

        default:
            _tcscpy(szResult,_T(""));
            return false;
            break;
    }
    return true;
}

//サムネイル作成
HANDLE CreateThumbnail(int iItemCount,int iWidth,int iHeight,HWND hStatusProgressBar,int iBeginIndex,bool bRegenerate,int iSelected){
    assert(iItemCount>0);
    assert(iBeginIndex<=iItemCount);
    HANDLE hThread;
    unsigned uThreadID;

    ZeroMemory(&param_CreateThumbnail,sizeof(param_CreateThumbnail));
    param_CreateThumbnail.hWnd=g_hMainWnd;//処理終了の報告先ウインドウハンドル
    param_CreateThumbnail.hListView=g_hListView;//リストビューハンドル
    param_CreateThumbnail.hImg=g_hImgThumbnail;//サムネイルを格納するイメージリスト
    param_CreateThumbnail.hStatusProgressBar=hStatusProgressBar;//ステータスバー上のプログレスバーハンドル
    param_CreateThumbnail.iItemCount=iItemCount;//ファイル数
    param_CreateThumbnail.lpArcFileInfo=g_lpArcFileInfo;//サムネイルを作成したいファイルの情報
    param_CreateThumbnail.iBeginIndex=iBeginIndex;//サムネイルの作成を開始するIndex
    param_CreateThumbnail.bRegenerate=bRegenerate;//サムネイルを再作成する
    param_CreateThumbnail.iSelected=iSelected;//選択されているアイテム数
    param_CreateThumbnail.iWidth=iWidth;//サムネイルの横幅
    param_CreateThumbnail.iHeight=iHeight;//サムネイルの縦幅
    InitializeCriticalSection(&csCriticalSection);
    dprintf(_T("iItemCount=%d\n"),iItemCount);
    dprintf(_T("iBeginIndex=%d\n"),iBeginIndex);
    dprintf(_T("iSelected=%d\n"),iSelected);
    hThread=BEGINTHREADEX(NULL,0,CreateThumbnailThread,&param_CreateThumbnail,0,&uThreadID);
    return hThread;
}

//サムネイル作成スレッド
unsigned __stdcall CreateThumbnailThread(LPVOID lvParam){
    lpParam_CreateThumbnail lpParam=(lpParam_CreateThumbnail)lvParam;
    HBITMAP hBitmap=NULL;
    int iStep=0;
    int iImageListCount=ImageList_GetImageCount(lpParam->hImg);
    LARGE_INTEGER liFreq,liStart,liEnd;

    ZeroMemory(&liFreq,sizeof(LARGE_INTEGER));
    ZeroMemory(&liStart,sizeof(LARGE_INTEGER));
    ZeroMemory(&liEnd,sizeof(LARGE_INTEGER));

#ifdef DEBUG
    //サムネイル作成時間計測
    QueryPerformanceFrequency(&liFreq);
    QueryPerformanceCounter(&liStart);
#endif

    EnterCriticalSection(&csCriticalSection);

    HBITMAP hbmpDummy=NULL;

    if(lpParam->bRegenerate){
        //前回作成されていない&再作成の対象でないアイテムのためのダミーのHBITMAPを作成
        hbmpDummy=CreateDummyBitmap(lpParam->iWidth,lpParam->iHeight);
    }


    dprintf(_T("ImageList_GetImageCount()  %d\n"),ImageList_GetImageCount(lpParam->hImg));

    //書庫ファイル内の画像のサムネイルをHBITMAPで取得
    for(int i=lpParam->iBeginIndex;i<lpParam->iItemCount;i++){
        dprintf(_T("i=%d\n"),i);
        if(lpParam->bRegenerate&&lpParam->iSelected&&((ListView_GetItemState(lpParam->hListView,i,LVIS_SELECTED))&LVIS_SELECTED)==0){
            if(i>=iImageListCount){
                ImageList_Add(lpParam->hImg,hbmpDummy,NULL);
                dprintf(_T("Skip(Not Selected)  ImageList_Add(hbmpDummy)\n"));
            }else{
                dprintf(_T("Skip(Not Selected)\n"));
            }
            continue;
        }
        hBitmap=GetThumbnailBitmapFromArchiveFile(lpParam->lpArcFileInfo[i].szCurrentFullFileName,lpParam->iWidth,lpParam->iHeight);

        if(hBitmap){
            if(lpParam->bRegenerate){
                if(i>=iImageListCount){
                    ImageList_Add(lpParam->hImg,hBitmap,NULL);
                    dprintf(_T("ImageList_Add()  (Regenerate)\n"));
                }else{
                    ImageList_Replace(lpParam->hImg,i,hBitmap,NULL);
                    dprintf(_T("ImageList_Replace()\n"));
                }
            }else{
                ImageList_Add(lpParam->hImg,hBitmap,NULL);
                dprintf(_T("ImageList_Add()\n"));
            }
        }else{
            hBitmap=CreateBitmapFromPath(lpParam->lpArcFileInfo[i].szCurrentFullFileName,lpParam->iWidth,lpParam->iHeight);
            if(lpParam->bRegenerate){
                if(i>=iImageListCount){
                    ImageList_Add(lpParam->hImg,hBitmap,NULL);
                    dprintf(_T("ImageList_Add()  (Regenerate)\n"));
                }else{
                    ImageList_Replace(lpParam->hImg,i,hBitmap,NULL);
                    dprintf(_T("ImageList_Replace()\n"));
                }
            }else{
                ImageList_Add(lpParam->hImg,hBitmap,NULL);
                dprintf(_T("ImageList_Add()\n"));
            }
        }
        DeleteObject(hBitmap);
        hBitmap=NULL;

        //アイテムを再描画
        ListView_RedrawItems(lpParam->hListView,i,i);
        //1Step増加
        if(lpParam->hStatusProgressBar!=NULL)PostMessage(lpParam->hStatusProgressBar,PBM_SETPOS,(WPARAM)iStep+1,(LPARAM)0);
        iStep++;
        if(!g_bWorking)break;
    }

    if(lpParam->bRegenerate){
        DeleteObject(hbmpDummy);
        hbmpDummy=NULL;
    }

    dprintf(_T("ImageList_GetImageCount()  %d\n"),ImageList_GetImageCount(lpParam->hImg));

    if(lpParam->hStatusProgressBar!=NULL){
        ShowWindow(lpParam->hStatusProgressBar,SW_HIDE);
        DestroyWindow(lpParam->hStatusProgressBar);
    }
    LeaveCriticalSection(&csCriticalSection);

#ifdef DEBUG
    QueryPerformanceCounter(&liEnd);
    dprintf(_T("CreateThumbnailThread() : %d ms\n"),(liEnd.QuadPart-liStart.QuadPart)*1000/liFreq.QuadPart);
#endif

    //メインウインドウに処理終了を報告
    PostMessage(lpParam->hWnd,WM_EXIT_CREATETHUMBNAIL_THREAD,(WPARAM)0,(LPARAM)0);
    _endthreadex(0);
    return 0;
}

//新しいファイル名の取得、追加
bool GetNewFileName(LPARCHIVEFILEINFO lpArcFileInfo,int iIndex){
    int iResult=0;
    TCHAR szDrive[_MAX_DRIVE]={0};
    TCHAR szFilePath[MAX_PATH]={0};//リネーム前のファイルのパス
    TCHAR szExtension[_MAX_EXT]={0};

    TCHAR szDirectoryTmp[MAX_PATH]={0};//%dirで置換するため取得(ドライブ直下であれば置換しないように)
    TCHAR szOldFileName[MAX_PATH]={0};//%origで置換するため取得
    TCHAR szNewFileNameTmp[MAX_PATH]={0};//置換後の結果

    TCHAR szNewFileName[MAX_PATH]={0};
    TCHAR szNewFullFileName[MAX_PATH]={0};

    if(lpArcFileInfo[iIndex].iStatus==ARC_RENAMED)return false;//リネーム済み

    switch((iResult=GetDirectoryNameInArchive(szNewFileName,lpArcFileInfo[iIndex].szCurrentFullFileName))){
        case ARC_DEFAULT:
            if(path::IsBadName(szNewFileName)){
                lpArcFileInfo[iIndex].iStatus=ARC_ERROR_BADNAME;//ファイル名に使えない文字が含まれています
                break;
            }
            _tsplitpath(lpArcFileInfo[iIndex].szCurrentFullFileName,szDrive,szFilePath,szOldFileName,szExtension);

            //新しいファイル名のフォーマットに合わせる
            AllReplace(szNewFileNameTmp,g_Config.szFormat,_T("%orig"),szOldFileName);
            AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%new"),szNewFileName);
            _tcscpy(szDirectoryTmp,PathFindFileName(g_lpArcFileInfo[iIndex].szDirectory));
            if(path::CountCharacter(szDirectoryTmp,':')==0){
                AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%dir"),szDirectoryTmp);
            }else{
                AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%dir"),_T(""));
            }

            SYSTEMTIME stLastModified;//システムファイル
            FILETIME ftLastModified;//ファイルタイム
            TCHAR szTmp[64];//更新日時用

            FileTimeToLocalFileTime(&lpArcFileInfo[iIndex].ftLastModified,&ftLastModified);
            FileTimeToSystemTime(&ftLastModified,&stLastModified);

            wsprintf(szTmp,_T("%04d%02d%02d"),stLastModified.wYear,stLastModified.wMonth,stLastModified.wDay,stLastModified.wHour,stLastModified.wMinute);
            AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%date"),szTmp);

            wsprintf(szTmp,_T("%02d%02d"),stLastModified.wHour,stLastModified.wMinute);
            AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%time"),szTmp);

            _tcscpy(szNewFileName,szNewFileNameTmp);


            wsprintf(szNewFullFileName,_T("%s%s%s%s"),szDrive,szFilePath,szNewFileName,szExtension);
            if(_tcsicmp(lpArcFileInfo[iIndex].szCurrentFullFileName,szNewFullFileName)==0){//リネームの必要が無い
                lpArcFileInfo[iIndex].iStatus=ARC_ERROR_NEEDNT_TO_RENAME;//ファイル名とフォルダ名が一致します
                break;
            }
            _tcscpy(lpArcFileInfo[iIndex].szNewFullFileName,szNewFullFileName);
            wsprintf(lpArcFileInfo[iIndex].szNewFileName,_T("%s%s"),szNewFileName,szExtension);
            lpArcFileInfo[iIndex].iStatus=ARC_READY_FOR_RENAME;//リネームすることが出来ます
            return true;
            break;

        default:
            //書庫のエラー情報
            lpArcFileInfo[iIndex].iStatus=iResult;
            break;
    }
    _tcscpy(lpArcFileInfo[iIndex].szNewFileName,_T(""));
    _tcscpy(lpArcFileInfo[iIndex].szNewFullFileName,_T(""));
    return false;
}

//新しいファイル名にリネーム
bool RenameFileName(LPARCHIVEFILEINFO lpArcFileInfo,int iIndex){
    if(lpArcFileInfo[iIndex].iStatus==ARC_RENAMED)return false;//リネーム済み
    dprintf(_T("iIndex=%d\n"),iIndex);
    if(lpArcFileInfo[iIndex].iStatus==ARC_DEFAULT)GetNewFileName(lpArcFileInfo,iIndex);//新しいファイル名を取得していない場合は取得する
    if(lpArcFileInfo[iIndex].iStatus!=ARC_READY_FOR_RENAME){
    if(g_Config.Log.iMaxLine!=-1){
            WriteLog(g_szLogFile,_T("Error"),lpArcFileInfo[iIndex].szCurrentFullFileName,_T(""));
        }
        return false;
    }

    dprintf(_T("%s\n     V\n%s\n"),lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szNewFullFileName);

    if(MoveFile(lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szNewFullFileName)){
        _tcscpy(lpArcFileInfo[iIndex].szOldFileName,lpArcFileInfo[iIndex].szCurrentFileName);//現在のファイル名をバックアップ
        _tcscpy(lpArcFileInfo[iIndex].szOldFullFileName,lpArcFileInfo[iIndex].szCurrentFullFileName);//現在のファイル名をバックアップ[フルパス]
        _tcscpy(lpArcFileInfo[iIndex].szCurrentFileName,lpArcFileInfo[iIndex].szNewFileName);//現在のファイル名を新しいファイル名に
        _tcscpy(lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szNewFullFileName);//現在のファイル名を新しいファイル名に[フルパス]
        _tcscpy(lpArcFileInfo[iIndex].szNewFileName,_T(""));//新しいファイル名を空に
        _tcscpy(lpArcFileInfo[iIndex].szNewFullFileName,_T(""));//新しいファイル名を空に[フルパス]
        lpArcFileInfo[iIndex].iStatus=ARC_RENAMED;//正常にリネームされました
        if(g_Config.Log.iMaxLine!=-1){
            WriteLog(g_szLogFile,_T("Success"),lpArcFileInfo[iIndex].szOldFullFileName,lpArcFileInfo[iIndex].szCurrentFileName);
        }
        return true;
    }else{
        lpArcFileInfo[iIndex].iStatus=ARC_RENAME_FAILURE;//リネームに失敗しました
        //TODO:FormatMessage()で原因表示
        if(g_Config.Log.iMaxLine!=-1){
            WriteLog(g_szLogFile,_T("Failure"),lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szNewFileName);
        }
    }
    return false;
}

//リネームを取り消す
bool UndoFileName(LPARCHIVEFILEINFO lpArcFileInfo,int iIndex){
    if(!(lpArcFileInfo[iIndex].iStatus==ARC_RENAMED)||lpArcFileInfo[iIndex].iStatus>=ARC_RENAME_FAILURE)return false;

    dprintf(_T("%s\n     V\n%s\n"),lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szOldFullFileName);

    if(MoveFile(lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szOldFullFileName)){//バックアップを利用
        _tcscpy(lpArcFileInfo[iIndex].szCurrentFileName,lpArcFileInfo[iIndex].szOldFileName);
        _tcscpy(lpArcFileInfo[iIndex].szCurrentFullFileName,lpArcFileInfo[iIndex].szOldFullFileName);
        _tcscpy(lpArcFileInfo[iIndex].szNewFileName,_T(""));//新しいファイル名を空に
        _tcscpy(lpArcFileInfo[iIndex].szNewFullFileName,_T(""));//新しいファイル名を空に[フルパス]
        _tcscpy(lpArcFileInfo[iIndex].szOldFileName,_T(""));//バックアップ用ファイル名を空に
        _tcscpy(lpArcFileInfo[iIndex].szOldFullFileName,_T(""));//バックアップ用ファイル名を空に[フルパス]
        lpArcFileInfo[iIndex].iStatus=ARC_DEFAULT;//未処理扱い
//        GetNewFileName(lpArcFileInfo,iIndex);
        return true;
    }else{
        lpArcFileInfo[iIndex].iStatus=ARC_RENAME_FAILURE;//リネームに失敗しました
    }
    return false;
}

//ファイル名を操作するスレッド
unsigned __stdcall FileNameThread(LPVOID lvParam){
    lpParam_FileNameThread lpParam=(lpParam_FileNameThread)lvParam;
    int iSuccess=0;

    EnterCriticalSection(&csCriticalSection);

    for(int i=0;i<lpParam->iItemCount;i++){
        dprintf(_T("i=%d\n"),i);
        if(lpParam->iSelected&&lpParam->bSelectedOnly&&((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED)==0)continue;

        //ファイル名操作を実行
        if(lpParam->pRunFunc(lpParam->lpArcFileInfo,i)){
            iSuccess++;
        }

        //1Step増加
        if(lpParam->hStatusProgressBar!=NULL)PostMessage(lpParam->hStatusProgressBar,PBM_SETPOS,(WPARAM)i+1,(LPARAM)0);
        if(!g_bWorking)break;
    }

    //ログが有効であり、最大行数が0より上の場合
    if(g_Config.Log.iMaxLine>0){
        int iFileLineCount=GetFileLineCount(g_szLogFile);

        //最大行数を超えている場合、先頭から削除
        if(iFileLineCount>g_Config.Log.iMaxLine){
            ShiftFile(g_szLogFile,iFileLineCount-g_Config.Log.iMaxLine);
        }
    }

    if(lpParam->hStatusProgressBar!=NULL){
        ShowWindow(lpParam->hStatusProgressBar,SW_HIDE);
        DestroyWindow(lpParam->hStatusProgressBar);
    }
    LeaveCriticalSection(&csCriticalSection);
    //メインウインドウに処理終了を報告
    //選択したアイテムのみが対象の場合、総アイテム数は選択ファイル数にする
    PostMessage(lpParam->hWnd,WM_EXIT_FILENAME_THREAD,(WPARAM)iSuccess,(LPARAM)(!lpParam->bSelectedOnly)?lpParam->iItemCount:lpParam->iSelected);
    _endthreadex(0);
    return 0;
}

//ファイル名を操作するスレッドを呼び出す
HANDLE CallFileNameThread(bool (*pRunFunc)(LPARCHIVEFILEINFO,int),LPARCHIVEFILEINFO lpArcFileInfo,HWND hStatusProgressBar,int iItemCount,int iSelected,bool bSelectedOnly){
    HANDLE hThread=NULL;
    unsigned uThreadID;

    ZeroMemory(&param_FileNameThread,sizeof(param_FileNameThread));
    param_FileNameThread.pRunFunc=pRunFunc;//実行したい関数名
    param_FileNameThread.hWnd=g_hMainWnd;//処理終了の報告先ウインドウハンドル
    param_FileNameThread.hStatusProgressBar=hStatusProgressBar;//ステータスバー上のプログレスバーハンドル
    param_FileNameThread.lpArcFileInfo=lpArcFileInfo;//ファイルの情報
    param_FileNameThread.iItemCount=iItemCount;//ファイル数
    param_FileNameThread.iSelected=iSelected;//選択されているアイテム数
    param_FileNameThread.bSelectedOnly=bSelectedOnly;//選択したファイルのみが対象

    InitializeCriticalSection(&csCriticalSection);
    hThread=BEGINTHREADEX(NULL,0,FileNameThread,&param_FileNameThread,0,&uThreadID);
    return hThread;
}

//選択されたフォルダを追加するスレッド
unsigned __stdcall AddSelectDirectoryThread(LPVOID lvParam){
    lpParam_AddSelectDirectoryThread lpParam=(lpParam_AddSelectDirectoryThread)lvParam;

    EnterCriticalSection(&csCriticalSection);

    for(int i=0;i<SUPPORTEDFILE_COUNT;i++){
        if(*(SupportedFile[i].pbEnable)){
            AddDirectory(lpParam->szDirectory,SupportedFile[i].lpszExtension);
        }
        if(!g_bWorking)break;
    }
    LeaveCriticalSection(&csCriticalSection);
    //メインウインドウに処理終了を報告
    //wParamにはDnDでファイル追加前のファイル数
    PostMessage(lpParam->hWnd,WM_EXIT_ADDSELECTDIRECTORY_THREAD,(WPARAM)lpParam->iBeforeFileCount,(LPARAM)0);
    _endthreadex(0);
    return 0;
}

//ドロップされたファイルを追加する
HANDLE AddDroppedFiles(HDROP hDrop,int iBeforeFileCount,HWND hStatusProgressBar){
    HANDLE hThread=NULL;
    unsigned uThreadID;
    assert(hDrop!=NULL);

    param_AddDroppedFilesThread.hWnd=g_hMainWnd;//処理終了の報告先ウインドウハンドル
    param_AddDroppedFilesThread.hDrop=hDrop;//ドロップされたファイルのハンドル
    param_AddDroppedFilesThread.iBeforeFileCount=iBeforeFileCount;//ファイル追加前のファイル数
    param_AddDroppedFilesThread.hStatusProgressBar=hStatusProgressBar;//ステータスバー上のプログレスバーハンドル
    InitializeCriticalSection(&csCriticalSection);
    hThread=BEGINTHREADEX(NULL,0,AddDroppedFilesThread,&param_AddDroppedFilesThread,0,&uThreadID);
    return hThread;
}

//ドロップされたファイルを追加するスレッド
unsigned __stdcall AddDroppedFilesThread(LPVOID lvParam){
    lpParam_AddDroppedFilesThread lpParam=(lpParam_AddDroppedFilesThread)lvParam;
    UNIT uiFileCount=DragQueryFile(lpParam->hDrop,0xffffffff,NULL,0);//ファイル数
    TCHAR szCurrentFullFileNameTmp[MAX_PATH]={0};
    assert(lpParam->hDrop!=NULL);

    EnterCriticalSection(&csCriticalSection);

    for(int i=0;i<static_cast<int>(uiFileCount);i++){
        //DragQueryFileでファイル名[フルパス]を取得
        DragQueryFile(lpParam->hDrop,i,szCurrentFullFileNameTmp,ARRAY_SIZEOF(szCurrentFullFileNameTmp));
        if(path::IsDirectory(szCurrentFullFileNameTmp)){
            for(int j=0;j<SUPPORTEDFILE_COUNT;j++){
                if(*(SupportedFile[j].pbEnable)){
                    AddDirectory(szCurrentFullFileNameTmp,SupportedFile[j].lpszExtension);
                }
            }
        }else{
            if(IsSupportedArchive(szCurrentFullFileNameTmp))AddArchiveFiles(szCurrentFullFileNameTmp);
        }
        //1Step増加
        if(lpParam->hStatusProgressBar!=NULL)PostMessage(lpParam->hStatusProgressBar,PBM_SETPOS,(WPARAM)i+1,(LPARAM)0);
        if(!g_bWorking)break;
    }

    DragFinish(lpParam->hDrop);
    if(lpParam->hStatusProgressBar!=NULL){
        ShowWindow(lpParam->hStatusProgressBar,SW_HIDE);
        DestroyWindow(lpParam->hStatusProgressBar);
    }
    LeaveCriticalSection(&csCriticalSection);
    //メインウインドウに処理終了を報告
    //wParamにはDnDでファイル追加前のファイル数
    PostMessage(lpParam->hWnd,WM_EXIT_ADDDROPPEDFILES_THREAD,(WPARAM)lpParam->iBeforeFileCount,(LPARAM)0);
    _endthreadex(0);
    return 0;
}

//最新版にバージョンアップするスレッドを呼び出す
HANDLE CallUpdateLatestVersion(HWND hWnd,HINSTANCE hInstance,HWND hStatusBar,HWND hStatusProgressBar,bool bNotFoundMessage){
    HANDLE hThread;
    unsigned uThreadID;

    ZeroMemory(&param_UpdateLatestVersionThread,sizeof(param_UpdateLatestVersionThread));
    param_UpdateLatestVersionThread.hWnd=g_hMainWnd;//処理終了の報告先ウインドウハンドル
    param_UpdateLatestVersionThread.hInstance=g_hInstance;//インスタンスハンドル
    param_UpdateLatestVersionThread.hStatusBar=hStatusBar;//ステータスバーのハンドル
    param_UpdateLatestVersionThread.hStatusProgressBar=hStatusProgressBar;//ステータスバー上のプログレスバーハンドル
    param_UpdateLatestVersionThread.bNotFoundMessage=bNotFoundMessage;//最新版が見つからなかった旨のメッセージダイアログを表示する
    InitializeCriticalSection(&csCriticalSection);
    hThread=BEGINTHREADEX(NULL,0,UpdateLatestVersionThread,&param_UpdateLatestVersionThread,0,&uThreadID);
    return hThread;
}

//最新版にバージョンアップするスレッド
unsigned __stdcall UpdateLatestVersionThread(LPVOID lvParam){
    lpParam_UpdateLatestVersionThread lpParam=(lpParam_UpdateLatestVersionThread)lvParam;

    EnterCriticalSection(&csCriticalSection);

    UpdateLatestVersion(lpParam->hWnd,lpParam->hInstance,lpParam->hStatusBar,lpParam->hStatusProgressBar,lpParam->bNotFoundMessage);

    if(lpParam->hStatusProgressBar!=NULL){
        ShowWindow(lpParam->hStatusProgressBar,SW_HIDE);
        DestroyWindow(lpParam->hStatusProgressBar);
    }
    LeaveCriticalSection(&csCriticalSection);

    //メインウインドウに処理終了を報告
    PostMessage(lpParam->hWnd,WM_EXIT_UPDATELATESTVERSION_THREAD,(WPARAM)0,(LPARAM)0);
    _endthreadex(0);
    return 0;
}

//NoWindowでリネームするスレッド
unsigned __stdcall NoWindowRenameThread(LPVOID lvParam){
    lpParam_NoWindowRenameThread lpParam=(lpParam_NoWindowRenameThread)lvParam;
    int iStep=0;
    int iSuccess=0;

    EnterCriticalSection(&csCriticalSection);

    dprintf(_T("iTemCount=%d\n"),lpParam->iItemCount);

    for(int iIndex=0;iIndex<lpParam->iItemCount;iIndex++){
        if(!lpParam->clOptions.bSilent&&!lpParam->clOptions.bVerySilent){
            //ファイルパスを必要あれば縮小して表示
            PathSetDlgItemPath(lpParam->hDlg,IDC_STATIC_FILENAME,lpParam->lpArcFileInfo[iIndex].szCurrentFullFileName);
            //1Step増加
            if(lpParam->hProgressBar!=NULL)PostMessage(lpParam->hProgressBar,PBM_SETPOS,(WPARAM)iStep+1,(LPARAM)0);
            iStep++;

            if(!g_bWorking)break;
        }

        if(lpParam->lpArcFileInfo[iIndex].iStatus!=ARC_READY_FOR_RENAME){
            if(g_Config.Log.iMaxLine!=-1){
                WriteLog(g_szLogFile,_T("Error"),lpParam->lpArcFileInfo[iIndex].szCurrentFullFileName,_T(""));
            }
            continue;
        }

        dprintf(_T("%s\n     V\n%s\n"),lpParam->lpArcFileInfo[iIndex].szCurrentFullFileName,lpParam->lpArcFileInfo[iIndex].szNewFileName);

        if(MoveFile(lpParam->lpArcFileInfo[iIndex].szCurrentFullFileName,lpParam->lpArcFileInfo[iIndex].szNewFullFileName)){
            if(g_Config.Log.iMaxLine!=-1){
                WriteLog(g_szLogFile,_T("Success"),lpParam->lpArcFileInfo[iIndex].szCurrentFullFileName,lpParam->lpArcFileInfo[iIndex].szNewFileName);
            }
            iSuccess++;
        }else{
            //TODO:FormatMessage()で原因表示
            if(g_Config.Log.iMaxLine!=-1){
                WriteLog(g_szLogFile,_T("Failure"),lpParam->lpArcFileInfo[iIndex].szCurrentFullFileName,lpParam->lpArcFileInfo[iIndex].szNewFileName);
            }
        }
    }

    LeaveCriticalSection(&csCriticalSection);

    //ダイアログに処理終了を報告
    PostMessage(lpParam->hDlg,WM_CLOSE,(WPARAM)iSuccess,(LPARAM)0);

    _endthreadex(0);
    return 0;
}

//プログレスバーダイアログプロシージャ
LRESULT CALLBACK ProgressBarDialogProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
    int iArgc=0;//argc
    LPTSTR* lplpszArgv=NULL;//argv
    static struct CommandLineOptions clOptions;//コマンドラインオプション

    switch (uMsg){
        case WM_SHOWPROGRESSBAR:{
            int iIndex=0;
            int iResult=0;

            iArgc=param_ProgressBarDialogProc.iArgc;//argc
            lplpszArgv=param_ProgressBarDialogProc.lplpszArgv;//argv
            clOptions=param_ProgressBarDialogProc.clOptions;//コマンドラインオプション

            TCHAR szDrive[_MAX_DRIVE]={0};
            TCHAR szFilePath[MAX_PATH]={0};//リネーム前のファイルのパス
            TCHAR szExt[_MAX_EXT]={0};
            TCHAR szNewFileName[MAX_PATH]={0};//書庫内ディレクトリ名

            TCHAR szDirectoryTmp[MAX_PATH]={0};//%dirで置換するため取得(ドライブ直下であれば置換しないように)
            TCHAR szOldFileName[MAX_PATH]={0};//%origで置換するため取得
            TCHAR szNewFileNameTmp[MAX_PATH]={0};//置換後の結果

            HWND hProgressBar=NULL;

            dprintf(_T("***No_Window***\n"));

            g_bWorking=true;//AddDirectory()対策

            //現在のファイル名を追加
            for(iIndex=1;iIndex<iArgc;iIndex++){//lplpszArgv[0]は実行ファイル名
                if(path::IsDirectory(lplpszArgv[iIndex])){
                    for(int i=0;i<SUPPORTEDFILE_COUNT;i++){
                        if(*(SupportedFile[i].pbEnable)){
                            AddDirectory(lplpszArgv[iIndex],SupportedFile[i].lpszExtension);
                        }
                    }
                }else{
                    if(IsSupportedArchive(lplpszArgv[iIndex]))AddArchiveFiles(lplpszArgv[iIndex]);
                }
            }

            //新しいファイル名を追加
            for(iIndex=0;iIndex<g_iFileCount;iIndex++){
                if((iResult=GetDirectoryNameInArchive(szNewFileName,g_lpArcFileInfo[iIndex].szCurrentFullFileName))==ARC_DEFAULT){
                    if(path::IsBadName(szNewFileName)){
                        g_lpArcFileInfo[iIndex].iStatus=ARC_ERROR_BADNAME;//ファイル名に使えない文字が含まれています
                        continue;
                    }
                    _tsplitpath(g_lpArcFileInfo[iIndex].szCurrentFullFileName,szDrive,szFilePath,szOldFileName,szExt);


                    //新しいファイル名のフォーマットに合わせる
                    AllReplace(szNewFileNameTmp,g_Config.szFormat,_T("%orig"),szOldFileName);
                    AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%new"),szNewFileName);
                    _tcscpy(szDirectoryTmp,PathFindFileName(g_lpArcFileInfo[iIndex].szDirectory));
                    if(path::CountCharacter(szDirectoryTmp,':')==0){
                        AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%dir"),szDirectoryTmp);
                    }else{
                        AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%dir"),_T(""));
                    }

                    FILETIME ftLastModifiedTmp;//取得用(NoWin時は更新日時を前もって取得していないため)
                    SYSTEMTIME stLastModified;//システムファイル
                    FILETIME ftLastModified;//ファイルタイム
                    TCHAR szTmp[64];//更新日時用

                    path::GetFileLastModified(g_lpArcFileInfo[iIndex].szCurrentFullFileName,&ftLastModifiedTmp);
                    FileTimeToLocalFileTime(&ftLastModifiedTmp,&ftLastModified);
                    FileTimeToSystemTime(&ftLastModified,&stLastModified);

                    wsprintf(szTmp,_T("%04d%02d%02d"),stLastModified.wYear,stLastModified.wMonth,stLastModified.wDay,stLastModified.wHour,stLastModified.wMinute);
                    AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%date"),szTmp);

                    wsprintf(szTmp,_T("%02d%02d"),stLastModified.wHour,stLastModified.wMinute);
                    AllReplace(szNewFileNameTmp,szNewFileNameTmp,_T("%time"),szTmp);

                    _tcscpy(szNewFileName,szNewFileNameTmp);


                    wsprintf(g_lpArcFileInfo[iIndex].szNewFullFileName,_T("%s%s%s%s"),szDrive,szFilePath,szNewFileName,szExt);//新しいファイル名[フルパス]作成
                    if(_tcsicmp(g_lpArcFileInfo[iIndex].szCurrentFullFileName,g_lpArcFileInfo[iIndex].szNewFullFileName)==0){//リネームの必要が無い
                        g_lpArcFileInfo[iIndex].iStatus=ARC_ERROR_NEEDNT_TO_RENAME;//ファイル名とフォルダ名が一致します
                        continue;
                    }
                    if(g_Config.Log.iMaxLine!=-1){
                        wsprintf(g_lpArcFileInfo[iIndex].szNewFileName,_T("%s%s"),szNewFileName,szExt);//新しいファイル名作成
                    }
                    g_lpArcFileInfo[iIndex].iStatus=ARC_READY_FOR_RENAME;//リネームすることが出来ます
                }else{
                    //書庫のエラー情報
                    g_lpArcFileInfo[iIndex].iStatus=iResult;
                }
            }

            if(!clOptions.bSilent&&!clOptions.bVerySilent){
                hProgressBar=GetDlgItem(g_hProgressDlg,IDC_PROGRESS);
                SendMessage(hProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));//範囲指定
                SendMessage(hProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);//1Stepは1

                ShowWindow(hDlg,SW_SHOW);
                dprintf(_T("Window Title is リネーム中\n"));
                SetWindowText(hDlg,_T("リネーム中"));
            }

            //リネーム実行

            dprintf(_T("\n***Rename***\n"));

            HANDLE hThread;
            unsigned uThreadID;

            ZeroMemory(&param_NoWindowRenameThread,sizeof(param_NoWindowRenameThread));
            param_NoWindowRenameThread.hDlg=g_hProgressDlg;//ダイアログのハンドル
            param_NoWindowRenameThread.hProgressBar=hProgressBar;//プログレスバーハンドル
            param_NoWindowRenameThread.lpArcFileInfo=g_lpArcFileInfo;//新しいファイル名を取得したいファイルの情報
            param_NoWindowRenameThread.clOptions=clOptions;//コマンドラインオプション
            param_NoWindowRenameThread.iItemCount=g_iFileCount;//ファイル数


            InitializeCriticalSection(&csCriticalSection);
            hThread=BEGINTHREADEX(NULL,0,NoWindowRenameThread,&param_NoWindowRenameThread,0,&uThreadID);
            break;
        }

        case WM_COMMAND:
            switch(LOWORD(wParam)){
                case IDC_BUTTON_CANCEL:
                    g_bWorking=false;
                    break;

                default:
                    break;
            }
            break;

        case WM_CLOSE:{
            if(g_hNoWindowRenameThread!=NULL){
                DeleteCriticalSection(&csCriticalSection);
                CloseHandle(g_hNoWindowRenameThread);
                g_hNoWindowRenameThread=NULL;
            }

            g_bWorking=false;

            if(!clOptions.bSilent&&!clOptions.bVerySilent){
                //ダイアログを非表示
                ShowWindow(g_hProgressDlg,SW_HIDE);
                //ダイアログ破棄
                DestroyWindow(g_hProgressDlg);
            }

            //ログが有効であり、最大行数が0より上の場合
            if(g_Config.Log.iMaxLine>0){
                int iFileLineCount=GetFileLineCount(g_szLogFile);

                //最大行数を超えている場合、先頭から削除
                if(iFileLineCount>g_Config.Log.iMaxLine){
                    ShiftFile(g_szLogFile,iFileLineCount-g_Config.Log.iMaxLine);
                }
            }

            TCHAR szMsg[256]={0};
            //WM_CLOSEのWPARAMが空いているので使う
            int iSuccess=static_cast<int>(wParam);

            if(!clOptions.bVerySilent){
                if(iSuccess>0)wsprintf(szMsg,_T("%d 個中 %d 個のファイルのリネームが完了しました。"),g_iFileCount,iSuccess);
                else _tcscpy(szMsg,_T("全てのファイルのリネームに失敗しました。"));
                MessageBox(NULL,szMsg,_T("リネーム処理の終了"),MB_OK);
            }

            //構造体のメモリ解放
            if(g_lpArcFileInfo!=NULL){
                free(g_lpArcFileInfo);
                g_lpArcFileInfo=NULL;
            }

            EndDialog(hDlg,IDOK);
            DestroyWindow(hDlg);
            PostQuitMessage(0);
            break;
        }

        default:
            break;
    }
    return false;
}

//新しいファイル名の変更ダイアログプロシージャ
LRESULT CALLBACK RenameDialogProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
    static int iIndex=0,iSize=0;
    static TCHAR szFileName[MAX_PATH]={0};
    static TCHAR szExtension[_MAX_EXT]={0};

    switch (uMsg){
        case WM_INITDIALOG:{
            for(iIndex=0;iIndex<ListView_GetItemCount(g_hListView);iIndex++)if((ListView_GetItemState(g_hListView,iIndex,LVIS_FOCUSED))&LVIS_FOCUSED)break;

            ListView_GetItemText(g_hListView,iIndex,LISTITEM_NEWFILENAME,szFileName,MAX_PATH);
            //何らかのエラーで新しいファイル名が取得されていない場合(ファイル名とディレクトリ名一致も含む)、現在のファイル名を使用
            if(!lstrlen(szFileName))ListView_GetItemText(g_hListView,iIndex,LISTITEM_CURRENTFILENAME,szFileName,MAX_PATH);

            //エディットボックスに入力
            SetWindowText(GetDlgItem(hDlg,IDC_EDIT_FILENAME),szFileName);
            //拡張子取得
            _tcscpy(szExtension,PathFindExtension(szFileName));
            //拡張子を除くファイル名を選択
            SelectEditExcludeExtension(GetDlgItem(hDlg,IDC_EDIT_FILENAME));
            //ダイアログのタイトル
            SetWindowText(hDlg,_T("新しいファイル名の変更"));

            HWND hList=GetDlgItem(hDlg,IDC_LIST_FILE);
            LVCOLUMN LVColumn;
            LVITEM LVItem;
            RECT rc;

            GetWindowRect(hList,&rc);
            //リストビューにカラムを追加
            LVColumn.mask=LVCF_FMT|LVCF_WIDTH|LVCF_TEXT;
            LVColumn.fmt=LVCFMT_LEFT;
            LVColumn.cx=rc.right-rc.left;
            LVColumn.pszText=NULL;
            ListView_InsertColumn(hList,0,&LVColumn);

            std::vector<tstring> vFileList;
            vFileList.clear();

            //書庫内ファイルのリストを取得
            GetFileList(vFileList,g_lpArcFileInfo[iIndex].szCurrentFullFileName);

            //重複削除
            std::sort(vFileList.begin(),vFileList.end());
            vFileList.erase(std::unique(vFileList.begin(),vFileList.end()),vFileList.end());

            //アイテムを追加
            int i=0;
            for(std::vector<tstring>::iterator itr=vFileList.begin();itr!=vFileList.end();++itr){
                LVItem.mask=LVIF_TEXT;
                LVItem.pszText=(LPTSTR)itr->c_str();
                LVItem.iItem=i;
                LVItem.iSubItem=0;
                ListView_InsertItem(hList,&LVItem);
                i++;
            }
            iSize=vFileList.size();

            LONG_PTR lpListViewStyle=ListView_GetExtendedListViewStyle(hList);//スタイル取得
            //LVS_EX_FULLROWSELECT(行全体選択)
            //LVS_EX_GRIDLINES(罫線表示)
            lpListViewStyle|=LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES;
            ListView_SetExtendedListViewStyle(hList,lpListViewStyle);//スタイル適用

            //先頭行を選択
//            if(i>1)ListView_SetItemState(hList,0,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED);
            break;
        }

        case WM_COMMAND:
            switch(LOWORD(wParam)){
                case IDOK:{//Enter
                    TCHAR szNewFileName[MAX_PATH]={0};
                    //エディットボックスから取得
                    GetWindowText(GetDlgItem(hDlg,IDC_EDIT_FILENAME),szNewFileName,ARRAY_SIZEOF(szNewFileName));
                    if(!lstrlen(szNewFileName)){
                        EndDialog(hDlg,IDCANCEL);
                        break;
                    }
                    if(path::IsBadName(szNewFileName)){
                        MessageBox(hDlg,_T("ファイル名には次の文字は使えません。\n\t\\ / : , ; * ? \" < > |"),_T("新しいファイル名の変更"),MB_ICONSTOP);
                        //拡張子を除くファイル名を選択
                        SelectEditExcludeExtension(GetDlgItem(hDlg,IDC_EDIT_FILENAME));
                        break;
                    }

                    //ファイル名が変更されていない場合
                    if(lstrcmpi(szFileName,szNewFileName)==0){
                        EndDialog(hDlg,IDCANCEL);
                        break;
                    }

                    //新しいファイル名の変更
                    _tcscpy(g_lpArcFileInfo[iIndex].szNewFileName,szNewFileName);
                    //新しいファイルのフルパス変更
                    _tcscpy(g_lpArcFileInfo[iIndex].szNewFullFileName,g_lpArcFileInfo[iIndex].szDirectory);
                    _tcscat(g_lpArcFileInfo[iIndex].szNewFullFileName,_T("\\"));
                    _tcscat(g_lpArcFileInfo[iIndex].szNewFullFileName,szNewFileName);

                    //未処理、リネーム済やリネーム失敗ファイル
                    if(g_lpArcFileInfo[iIndex].iStatus!=ARC_READY_FOR_RENAME){
                        g_lpArcFileInfo[iIndex].iStatus=ARC_READY_FOR_RENAME;//リネームすることが出来ます
                    }
                    EndDialog(hDlg,IDOK);
                    break;
                }

                case IDCANCEL://Esc
                    EndDialog(hDlg,IDCANCEL);
                    break;

                default:
                    break;
            }
            break;

        case WM_NOTIFY:{
            if(((LPNMHDR)lParam)->idFrom==IDC_LIST_FILE){
                switch(((LPNMLISTVIEW)lParam)->hdr.code){
                    case LVN_ITEMCHANGED:{//アイテムを選択
                        TCHAR szSelectedFileName[MAX_PATH]={0};
                        int iIndex=ListView_GetNextItem(((LPNMLISTVIEW)lParam)->hdr.hwndFrom,-1,LVIS_SELECTED);
                        if(iIndex!=-1){
                            LVITEM LVItem;

                            LVItem.mask=LVIF_TEXT;
                            LVItem.iItem=((LPNMLISTVIEW)lParam)->iItem;
                            LVItem.iSubItem=0;
                            LVItem.pszText=szSelectedFileName;
                            LVItem.cchTextMax=ARRAY_SIZEOF(szSelectedFileName);
                            ListView_GetItem(((LPNMLISTVIEW)lParam)->hdr.hwndFrom,&LVItem);

                            _tcscat(szSelectedFileName,szExtension);
                            SetWindowText(GetDlgItem(hDlg,IDC_EDIT_FILENAME),szSelectedFileName);

                            //現在選択しているファイル番号(1から)と総ファイル数を表示
                            TCHAR szNumber[64]={0};
                            wsprintf(szNumber,_T("%d/%d"),iIndex+1,iSize);
                            SetWindowText(GetDlgItem(hDlg,IDC_STATIC_NUMBER),szNumber);
                        }
                        break;
                    }

                    case NM_DBLCLK://ダブルクリックした場合
                        SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDOK,0),(LPARAM)0);
                        break;

                    default:
                        break;
                }
            }
            break;

        default:
            break;
        }
    }
    return false;
}

//ツールバーのプロシージャ
LRESULT CALLBACK ToolBarProc(HWND hToolBar,UINT uMsg,WPARAM wParam,LPARAM lParam){
    switch(uMsg){
        case WM_RBUTTONDOWN:
        case WM_RBUTTONUP:
            //左クリック+右クリックで以後入力を受け付けなくなる
            //XPのバグ対策
            if(SendMessage(hToolBar,TB_GETHOTITEM,(WPARAM)0,(LPARAM)0)>=0){
                ReleaseCapture();
            }
            return 0;

        default:
            break;
    }
    return CallWindowProc(DefToolBarProc,hToolBar,uMsg,wParam,lParam);
}

//リストビューのプロシージャ
LRESULT CALLBACK ListViewProc(HWND hList,UINT uMsg,WPARAM wParam,LPARAM lParam){
    switch(uMsg){
        case WM_ERASEBKGND:return 1;

        case WM_DROPFILES:{
            int iBeforeFileCount=g_iFileCount;//ファイル追加前のファイル数
            HDROP hDrop=(HDROP)wParam;
            UNIT uiFileCount=DragQueryFile(hDrop,0xffffffff,NULL,0);//ファイル数
            dprintf(_T("uiFileCount=%d\n"),uiFileCount);
            assert(hDrop!=NULL);
            HWND hStatusProgressBar=NULL;

            g_bWorking=true;
            //ステータスバーに文字追加
            SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("ファイル追加中..."));
            SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
            //ステータスバー上にプログレスバー作成
            hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);
            if(hStatusProgressBar!=NULL){
                //範囲指定
                SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,uiFileCount));
                //1Stepは1
                SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);
            }
            g_hAddDroppedFilesThread=AddDroppedFiles(hDrop,iBeforeFileCount,hStatusProgressBar);
            break;
        }

        default:
            break;
    }
    return CallWindowProc(DefListViewProc,hList,uMsg,wParam,lParam);
}

//リストビューヘッダーのプロシージャ
LRESULT CALLBACK ListViewHeaderProc(HWND hHeader,UINT uMsg,WPARAM wParam,LPARAM lParam){
    static HCURSOR hCursorDrag;
    static HCURSOR hCursorArrow;

    switch(uMsg){
        //非表示カラム上のマウスカーソルが<-||->にならないための対策
        //が、たまに一瞬だけ<-||->になってしまう
        case WM_MOUSEMOVE:{
            CURSORINFO CursorInfo;

            CursorInfo.cbSize=sizeof(CURSORINFO);
            GetCursorInfo(&CursorInfo);

            if(hCursorDrag==NULL)hCursorDrag=LoadCursor(GetModuleHandle(_T("comctl32")),MAKEINTRESOURCE(107));
            if(hCursorDrag==CursorInfo.hCursor){
                if(hCursorArrow==NULL)hCursorArrow=LoadCursor(NULL,IDC_ARROW);
                SetCursor(hCursorArrow);
                return true;
            }
            break;
        }

        default:
            break;
    }
    return CallWindowProc(DefListViewHeaderProc,hHeader,uMsg,wParam,lParam);
}

//ウインドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
    static HFONT hToolBarFont=NULL;

    static HWND hReBar=NULL;//レバーハンドル
    static HWND hToolBar=NULL;//ツールバーハンドル

    static HMENU hMainMenu;//メインメニュー
    static HMENU hViewMenu;//メインメニューの「表示」メニュ-
    static HMENU hAnalyzeMenu,hAnalyzeSubMenu;//「ファイル名を取得する」メニュー
    static HMENU hUndoMenu,hUndoSubMenu;//「取り消す」メニュー
    static HMENU hThumbnailMenu,hThumbnailSubMenu;//「サムネイルを表示する」メニュー
    static HMENU hContextMenu,hContextSubMenu;//右クリックメニュー[リストビューのアイテム以外を右クリックした場合]
    static HMENU hListItemContextMenu,hListItemContextSubMenu;//右クリックメニュー[リストビューのアイテムを右クリックした場合]
    static HMENU hHeaderMenu,hHeaderSubMenu;//ヘッダーメニュー

    HIMAGELIST hImgToolIcon=NULL;//イメージリストハンドル[ツールボタン]
    static HWND hStatusProgressBar=NULL;//ステータスバー上のプログレスバーハンドル

    //ウインドウのサイズが変更されたかどうか
    static bool bSizeChanged=false;

    switch(uMsg){
    case WM_CREATE:{

        int i=0;
        LONG_PTR lpListViewStyle={0};

        INITCOMMONCONTROLSEX ic;//コモンコントロール利用に必須
        ic.dwSize=sizeof(INITCOMMONCONTROLSEX);
        ic.dwICC=ICC_LISTVIEW_CLASSES|ICC_COOL_CLASSES|ICC_BAR_CLASSES|ICC_PROGRESS_CLASS;//ListView,ReBar,StatusBar,ProgressBar
        InitCommonControlsEx(&ic);


        hReBar=CreateWindowEx(WS_EX_TOOLWINDOW,
                                REBARCLASSNAME,
                                NULL,
                                WS_CHILD|WS_VISIBLE|WS_BORDER|WS_CLIPSIBLINGS|/*WS_CLIPCHILDREN|*/RBS_VARHEIGHT|RBS_AUTOSIZE|RBS_BANDBORDERS|CCS_NODIVIDER,
                                0,0,
                                0,0,
                                hWnd,
                                NULL,
                                g_hInstance,
                                NULL);
        REBARINFO ReBarInfo;
        ZeroMemory(&ReBarInfo,sizeof(REBARINFO));
        ReBarInfo.cbSize=sizeof(REBARINFO);
        ReBarInfo.fMask=0;
        ReBarInfo.himl=0;
        SendMessage(hReBar,RB_SETBARINFO,(WPARAM)0,(LPARAM)&ReBarInfo);

        //ツールバーボタン
        TBBUTTON tbButton[]={
            //warning: missing braces around initializer for 'BYTE [2]'
            //を防ぐ為、BYTE  bReservedは{0}の様にする事
            {0,ID_FILE,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//ファイルを開く
            {1,ID_FOLDER,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//フォルダを開く
            {2,ID_ALLRENAME,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//すべてリネーム
            {3,ID_RENAME,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//リネーム
            {4,ID_ANALYZE,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//ファイル名を取得
            {5,ID_UNDO,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//取り消す
            {6,ID_THUMBNAIL,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//サムネイル
            {7,ID_CLEAR,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//クリア
            {8,ID_OPTIONS,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0},//オプション
            {9,ID_EXIT,TBSTATE_ENABLED,TBSTYLE_BUTTON|BTNS_AUTOSIZE,{0},0,0}//終了
        };
        //区切り線
        TBBUTTON tbSeparate[]={
            {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,{0},0,0},
            {1,0,TBSTATE_ENABLED,TBSTYLE_SEP,{0},0,0},
            {2,0,TBSTATE_ENABLED,TBSTYLE_SEP,{0},0,0},
            {3,0,TBSTATE_ENABLED,TBSTYLE_SEP,{0},0,0},
            {4,0,TBSTATE_ENABLED,TBSTYLE_SEP,{0},0,0},
            {5,0,TBSTATE_ENABLED,TBSTYLE_SEP,{0},0,0},
        };

        //ツールバー作成
        hToolBar=CreateWindowEx(0,
                                TOOLBARCLASSNAME,
                                NULL,
                                WS_CHILD|WS_VISIBLE|/*TBSTYLE_LIST|*/TBSTYLE_FLAT|TBSTYLE_TOOLTIPS|CCS_NOPARENTALIGN|CCS_NORESIZE|CCS_NODIVIDER|CCS_NOMOVEY,
                                0,0,
                                g_Config.WindowState.rcWindow.right,40,
                                hReBar,
                                (HMENU)IDC_TOOLBAR,
                                g_hInstance,
                                NULL);
        SendMessage(hToolBar,TB_BUTTONSTRUCTSIZE,(WPARAM)sizeof(TBBUTTON),(LPARAM)0);

        //サブクラス化
        DefToolBarProc=(WNDPROC)GetWindowLongPtr(hToolBar,GWL_WNDPROC);
        SetWindowLongPtr(hToolBar,GWL_WNDPROC,(LONG_PTR)ToolBarProc);

        //イメージリスト作成
        hImgToolIcon=ImageList_Create(32,32,ILC_COLOR32,0,0);
        //背景色指定
        ImageList_SetBkColor(hImgToolIcon,GetSysColor(COLOR_3DFACE));
        //アイコンをイメージリストに追加
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_FILE)));//ファイルを追加
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_FOLDER)));//フォルダを追加
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_ALLRENAME)));//すべてリネーム
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_RENAME)));//リネーム
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_ANALYZE)));//ファイル名を取得
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_UNDO)));//取り消す
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_THUMBNAIL)));//サムネイル
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_CLEAR)));//クリア
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_OPTIONS)));//オプション
        ImageList_AddIcon(hImgToolIcon,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON_EXIT)));//終了
        SendMessage(hToolBar,TB_SETIMAGELIST,0,(LPARAM)hImgToolIcon);

        //文字列を追加
        TCHAR szBuffer[256]={0};
        LoadString(g_hInstance,IDT_FILE,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[0].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_FOLDER,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[1].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_ALLRENAME,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[2].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_RENAME,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[3].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_ALLANALYZE,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[4].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_UNDO,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[5].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_THUMBNAIL,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[6].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_CLEAR,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[7].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_OPTIONS,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[8].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);
        LoadString(g_hInstance,IDT_EXIT,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
        tbButton[9].iString=SendMessage(hToolBar,TB_ADDSTRING,0,(LPARAM)szBuffer);

        //ボタンを追加
        SendMessage(hToolBar,TB_ADDBUTTONS,(WPARAM)BUTTONCOUNT,(LPARAM)(LPTBBUTTON)&tbButton);

        //区切り線を追加
        SendMessage(hToolBar,TB_INSERTBUTTON,0,(LPARAM)&tbSeparate);
        //1[ファイルを追加]
        //2[フォルダを追加]
        SendMessage(hToolBar,TB_INSERTBUTTON,3,(LPARAM)&tbSeparate);
        //4すべてリネーム]
        //5[リネーム]
        //6[ファイル名を取得]
        //7[取り消す]
        SendMessage(hToolBar,TB_INSERTBUTTON,8,(LPARAM)&tbSeparate);
        //9[サムネイル]
        SendMessage(hToolBar,TB_INSERTBUTTON,10,(LPARAM)&tbSeparate);
        //11[クリア]
        SendMessage(hToolBar,TB_INSERTBUTTON,12,(LPARAM)&tbSeparate);
        //13[オプション]
        SendMessage(hToolBar,TB_INSERTBUTTON,14,(LPARAM)&tbSeparate);
        //15[終了]
        SendMessage(hToolBar,TB_AUTOSIZE,0,0);

        DWORD dwToolBarSize=SendMessage(hToolBar,TB_GETBUTTONSIZE,(WPARAM)0,(LPARAM)0);

        REBARBANDINFO ReBarBandInfo;
        ZeroMemory(&ReBarBandInfo,sizeof(REBARBANDINFO));
        ReBarBandInfo.cbSize=sizeof(REBARBANDINFO);
        ReBarBandInfo.fMask=RBBIM_STYLE|RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_SIZE|RBBIM_ID;
        ReBarBandInfo.fStyle=RBBS_CHILDEDGE|RBBS_NOGRIPPER;
        ReBarBandInfo.wID=IDC_TOOLBAR;
        ReBarBandInfo.hwndChild=hToolBar;
        ReBarBandInfo.cyChild=LOWORD(dwToolBarSize);
        ReBarBandInfo.cxMinChild=BUTTONCOUNT*HIWORD(dwToolBarSize);
        ReBarBandInfo.cyMinChild=HIWORD(dwToolBarSize);
        ReBarBandInfo.cx=0;
        SendMessage(hReBar,RB_INSERTBAND,(WPARAM)-1,(LPARAM)&ReBarBandInfo);

        //フォントを設定
        hToolBarFont=CreateGUIFont();
        SendMessage(hToolBar,WM_SETFONT,(WPARAM)hToolBarFont,(LPARAM)true);

        //ツールチップ作成
        HWND hToolTip=NULL;
        TOOLINFO ToolInfo={0};
        UNIT uiToolTipTextId[BUTTONCOUNT]={IDS_FILE,IDS_FOLDER,IDS_ALLRENAME,IDS_RENAME,IDS_ANALYZE,IDS_UNDO,IDS_THUMBNAIL,IDS_CLEAR,IDS_OPTIONS,IDS_EXIT};
        for(i=0;i<(int)ARRAY_SIZEOF(tbButton);i++){
            hToolTip=CreateWindowEx(0,
                                    TOOLTIPS_CLASS,
                                    NULL,
                                    TTS_ALWAYSTIP,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    hWnd,
                                    NULL,
                                    g_hInstance,
                                    NULL);
            SendMessage(hToolBar,TB_GETRECT,ID_FILE+i,(LPARAM)&ToolInfo.rect);
            ToolInfo.cbSize=sizeof(TOOLINFO);
            ToolInfo.uFlags=TTF_SUBCLASS;
            ToolInfo.hwnd=hToolBar;
            ToolInfo.uId=ID_FILE+i;
            ToolInfo.hinst=g_hInstance;
            ToolInfo.lpszText=(LPTSTR)uiToolTipTextId[i];
            SendMessage(hToolTip,TTM_ADDTOOL,(WPARAM)0,(LPARAM)&ToolInfo);
            SendMessage(hToolTip,TTM_SETMAXTIPWIDTH,(WPARAM)0,(LPARAM)0);//これがないと\nで改行されない
        }
        SendMessage(hToolBar,TB_SETTOOLTIPS,(WPARAM)hToolTip,(LPARAM)0);

        //リストビュー作成
        g_hListView=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW|WS_EX_ACCEPTFILES,
                                WC_LISTVIEW,
                                _T(""),
                                WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_ICON|LVS_AUTOARRANGE|LVS_SHOWSELALWAYS|LVS_OWNERDATA,
                                0,0,0,0,
                                hWnd,
                                (HMENU)IDC_LISTVIEW,
                                g_hInstance,
                                NULL);

        lpListViewStyle=ListView_GetExtendedListViewStyle(g_hListView);//スタイル取得
        //LVS_EX_FULLROWSELECT(行全体選択),
        //LVS_EX_HEADERDRAGDROP(ヘッダ並び替え),
        //LVS_EX_INFOTIP(ツールチップ表示),
        //LVS_EX_BORDERSELECT(枠選択にする)
        //LVS_EX_DOUBLEBUFFER(ダブルバッファ)[XP以降]
        lpListViewStyle|=LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_INFOTIP|LVS_EX_BORDERSELECT|LVS_EX_DOUBLEBUFFER;
        ListView_SetExtendedListViewStyle(g_hListView,lpListViewStyle);//スタイル適用

        //サブクラス化
        DefListViewProc=(WNDPROC)GetWindowLongPtr(g_hListView,GWL_WNDPROC);
        SetWindowLongPtr(g_hListView,GWL_WNDPROC,(LONG_PTR)ListViewProc);

        //リストビューのヘッダー
        g_hListViewHeader=ListView_GetHeader(g_hListView);
        //サブクラス化
        DefListViewHeaderProc=(WNDPROC)GetWindowLongPtr(g_hListViewHeader,GWL_WNDPROC);
        SetWindowLongPtr(g_hListViewHeader,GWL_WNDPROC,(LONG_PTR)ListViewHeaderProc);

        //カラムを設定
        LisView_InitColumn(g_ListViewColumn_Table,&g_Config,g_hListView);

        LVCOLUMN lvColumn;

        lvColumn.mask=LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM;
        //現在のファイル名
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_CURRENTFILENAME].iDefaultWidth;
        lvColumn.fmt=LVCFMT_LEFT;
        lvColumn.pszText=(LPTSTR)_T("現在のファイル名");
        lvColumn.iSubItem=LISTITEM_CURRENTFILENAME;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_CURRENTFILENAME,&lvColumn);
        //新しいファイル名
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_NEWFILENAME].iDefaultWidth;
        lvColumn.fmt=LVCFMT_LEFT;
        lvColumn.pszText=(LPTSTR)_T("新しいファイル名");
        lvColumn.iSubItem=LISTITEM_NEWFILENAME;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_NEWFILENAME,&lvColumn);
        //ステータス
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_STATUS].iDefaultWidth;
        lvColumn.fmt=LVCFMT_LEFT;
        lvColumn.pszText=(LPTSTR)_T("ステータス");
        lvColumn.iSubItem=LISTITEM_STATUS;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_STATUS,&lvColumn);
        //ディレクトリ
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_DIRECTORY].iDefaultWidth;
        lvColumn.fmt=LVCFMT_LEFT;
        lvColumn.pszText=(LPTSTR)_T("ディレクトリ");
        lvColumn.iSubItem=LISTITEM_DIRECTORY;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_DIRECTORY,&lvColumn);
        //サイズ
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_SIZE].iDefaultWidth;
        lvColumn.fmt=LVCFMT_RIGHT;
        lvColumn.pszText=(LPTSTR)_T("サイズ");
        lvColumn.iSubItem=LISTITEM_SIZE;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_SIZE,&lvColumn);
        //種類
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_TYPE].iDefaultWidth;
        lvColumn.fmt=LVCFMT_LEFT;
        lvColumn.pszText=(LPTSTR)_T("種類");
        lvColumn.iSubItem=LISTITEM_TYPE;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_TYPE,&lvColumn);
        //更新日時
        lvColumn.cx=g_ListViewColumn_Table[LISTITEM_LASTMODIFIED].iDefaultWidth;
        lvColumn.fmt=LVCFMT_LEFT;
        lvColumn.pszText=(LPTSTR)_T("更新日時");
        lvColumn.iSubItem=LISTITEM_LASTMODIFIED;
        ListView_AddColumn(g_ListViewColumn_Table,g_hListView,LISTITEM_LASTMODIFIED,&lvColumn);

        //リストビューカラムの幅を設定
        for(int i=0;i<static_cast<int>(ARRAY_SIZEOF(g_ListViewColumn_Table));i++){
            ListView_SetColumnWidth(g_hListView,g_ListViewColumn_Table[i].iListItem,*(g_ListViewColumn_Table[i].piWidth));
        }

        //リストビューカラムの並び順を設定
        ListView_SetColumnOrderArray(g_hListView,LISTITEM_NUM,g_Config.ListViewColumn.iOrder);

        //フォントを読み込む
        //リストビューの仕様上、iFontSizeはDefaultItemDesignでのみ有効にすること
        g_hDefaultItemFont=CreateGUIFont(g_Config.DefaultItemDesign.szFont,g_Config.DefaultItemDesign.iFontSize,g_Config.DefaultItemDesign.iFontStyle);
        g_hReadyItemFont=CreateGUIFont(g_Config.ReadyItemDesign.szFont,g_Config.DefaultItemDesign.iFontSize,g_Config.ReadyItemDesign.iFontStyle);
        g_hRenamedItemFont=CreateGUIFont(g_Config.RenamedItemDesign.szFont,g_Config.DefaultItemDesign.iFontSize,g_Config.RenamedItemDesign.iFontStyle);
        g_hFailedItemFont=CreateGUIFont(g_Config.FailedItemDesign.szFont,g_Config.DefaultItemDesign.iFontSize,g_Config.FailedItemDesign.iFontStyle);

        RefreshGUIFont();

        ListView_SetBkColor(g_hListView,g_Config.DefaultItemDesign.clrTextBk);

        ListView_SetOutlineColor(g_hListView,g_Config.DefaultItemDesign.clrOutline);

        //ファイルアイコン用イメージリスト登録
        g_hImgFileIcon=ImageList_Create(16,16,ILC_COLOR32,0,0);
        ImageList_SetBkColor(g_hImgFileIcon,CLR_NONE);
        if(!ListView_SetImageList(g_hListView,g_hImgFileIcon,LVSIL_SMALL)){}//warning: value computed is not used対策
        //サムネイル用イメージリスト登録
        g_hImgThumbnail=ImageList_Create(g_Config.Thumbnail.iNormal,g_Config.Thumbnail.iNormal,ILC_COLOR32,0,0);
        ImageList_SetBkColor(g_hImgThumbnail,CLR_NONE);
        if(!ListView_SetImageList(g_hListView,g_hImgThumbnail,LVSIL_NORMAL)){};//warning: value computed is not used対策

        //メインメニューを読み込む
        hMainMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_MAIN));
        SetMenu(hWnd,hMainMenu);

        //「取り消す」メニューを読み込む
        hUndoMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_UNDO));
        hUndoSubMenu=GetSubMenu(hUndoMenu,0);

        //「サムネイルを表示する」メニューを読み込む
        hThumbnailMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_THUMBNAIL));
        hThumbnailSubMenu=GetSubMenu(hThumbnailMenu,0);

        hViewMenu=GetSubMenu(hMainMenu,2);//「表示」メニュー取得(セパレータもアイテムの一つであることに注意する)

        //「表示」メニューに「サムネイル」メニューを追加
        MENUITEMINFO MenuItemInfo;
        ZeroMemory(&MenuItemInfo,sizeof(MENUITEMINFO));
        MenuItemInfo.cbSize=sizeof(MENUITEMINFO);
        MenuItemInfo.fMask=MIIM_TYPE|MIIM_SUBMENU;
        MenuItemInfo.fType=MFT_STRING;
        MenuItemInfo.dwTypeData=(LPTSTR)_T("サムネイル(&T)");
        MenuItemInfo.hSubMenu=hThumbnailSubMenu;
        InsertMenuItem(hViewMenu,4,true,&MenuItemInfo);

        //「ファイル名を取得する」メニューを読み込む
        hAnalyzeMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_ANALYZE));
        hAnalyzeSubMenu=GetSubMenu(hAnalyzeMenu,0);


        //右クリックメニューを読み込む
        hContextMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_CONTEXT1));
        hContextSubMenu=GetSubMenu(hContextMenu,0);
        hListItemContextMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_CONTEXT2));
        hListItemContextSubMenu=GetSubMenu(hListItemContextMenu,0);

        //ヘッダーメニューを読み込む
        hHeaderMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU_HEADER));
        hHeaderSubMenu=GetSubMenu(hHeaderMenu,0);

        //ステータスバーを読み込む
        g_hStatusBar=CreateWindow(STATUSCLASSNAME,
                                    NULL,
                                    WS_CHILD|SBT_TOOLTIPS|CCS_BOTTOM|WS_VISIBLE|SBARS_SIZEGRIP,
                                    0,0,0,0,
                                    hWnd,
                                    (HMENU)0,
                                    g_hInstance,
                                    NULL);
        SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)_T("ファイルやフォルダをドロップしてください"));

        //ステータスバー上にプログレスバー作成
        g_hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);
        //非表示
        ShowWindow(g_hStatusProgressBar,SW_HIDE);

        //起動時のサムネイルの設定を適用
        if(g_Config.Thumbnail.iStartup>=STARTUP_LASTTIME)g_Config.Thumbnail.iStartup-=STARTUP_LASTTIME;
        if(g_Config.Thumbnail.iStartup!=STARTUP_NO_THUMBNAIL){
            switch(g_Config.Thumbnail.iStartup){
                case STARTUP_SMALL_THUMBNAIL:
                    g_eThumbSize=SMALL_THUMBNAIL;
                    break;

                case STARTUP_NORMAL_THUMBNAIL:
                default:
                    g_eThumbSize=NORMAL_THUMBNAIL;
                    break;

                case STARTUP_LARGE_THUMBNAIL:
                    g_eThumbSize=LARGE_THUMBNAIL;
                    break;
            }

            int iSize=GetThumbnailSize();
            ListView_SetView(g_hListView,LV_VIEW_ICON);
            ImageList_SetIconSize(g_hImgThumbnail,iSize,iSize);

            if(!ListView_SetImageList(g_hListView,g_hImgThumbnail,LVSIL_NORMAL)){};//適用/warning: value computed is not used対策
        }

        DragAcceptFiles(g_hListView,true);
        SetFocus(g_hListView);

        return 0;
    }

    case WM_SETFOCUS:
        //ウインドウが入力フォーカスを得た場合、リストにフォーカスを移す。
        //ビューアを終了した際に、アイテムを選択しておくため。
        SetFocus(g_hListView);
        break;

    case WM_INITMENU:{
        MENUITEMINFO MenuItemInfo;
        ZeroMemory(&MenuItemInfo,sizeof(MENUITEMINFO));
        MenuItemInfo.cbSize=sizeof(MENUITEMINFO);
        MenuItemInfo.fMask=MIIM_STATE;

        UNIT uiThumbnailMenu[]={IDM_NO_THUMBNAIL,IDM_SMALL_THUMBNAIL,IDM_NORMAL_THUMBNAIL,IDM_LARGE_THUMBNAIL};

        if(wParam==(WPARAM)hMainMenu||wParam==(WPARAM)hThumbnailSubMenu){
            HMENU hmenuThumbnail=NULL;

            //「表示」->「サムネイル」メニュー
            for(int i=0;i<static_cast<int>(ARRAY_SIZEOF(uiThumbnailMenu));i++){
                MenuItemInfo.fState=((g_eThumbSize==i)?MFS_CHECKED:MFS_UNCHECKED);
                SetMenuItemInfo((HMENU)wParam,uiThumbnailMenu[i],false,&MenuItemInfo);
            }

            if(wParam==(WPARAM)hMainMenu){
                //メニューにチェックを付ける
                MenuItemInfo.fState=(g_bAlwaysOnTop?MFS_CHECKED:MFS_UNCHECKED);
                SetMenuItemInfo(hMainMenu,IDM_ALWAYSONTOP,false,&MenuItemInfo);//メニューのチェックを設定
                MenuItemInfo.fState=(g_bFormatKBSize?MFS_CHECKED:MFS_UNCHECKED);
                SetMenuItemInfo(hMainMenu,IDM_FILESIZEKB,false,&MenuItemInfo);//メニューのチェックを設定

                hmenuThumbnail=GetSubMenu(hViewMenu,4);
            }else if(wParam==(WPARAM)hThumbnailSubMenu){
                hmenuThumbnail=(HMENU)wParam;
            }
            if(g_eThumbSize!=NO_THUMBNAIL){
                if(_GetMenuPosFromID(hmenuThumbnail,IDM_REGENERATE_THUMBNAIL)==-1){
                    MenuItemInfo.fMask=MIIM_ID|MIIM_TYPE;

                    //すべて再作成
                    MenuItemInfo.wID=IDM_ALLREGENERATE_THUMBNAIL;
                    MenuItemInfo.fType=MFT_STRING;
                    MenuItemInfo.dwTypeData=(LPTSTR)_T("すべて再作成(&A)");
                    InsertMenuItem(hmenuThumbnail,IDM_NO_THUMBNAIL,false,&MenuItemInfo);

                    //再作成
                    MenuItemInfo.wID=IDM_REGENERATE_THUMBNAIL;
                    MenuItemInfo.fType=MFT_STRING;
                    MenuItemInfo.dwTypeData=(LPTSTR)_T("再作成(&R)");
                    InsertMenuItem(hmenuThumbnail,IDM_NO_THUMBNAIL,false,&MenuItemInfo);

                    //境界線
                    MenuItemInfo.fType=MFT_SEPARATOR;
                    InsertMenuItem(hmenuThumbnail,IDM_NO_THUMBNAIL,false,&MenuItemInfo);
                }
            }else{
                if(_GetMenuPosFromID(hmenuThumbnail,IDM_REGENERATE_THUMBNAIL)!=-1){
                    //「表示しない」の場合、再作成関連のアイテムを削除
                    RemoveMenu(hmenuThumbnail,IDM_ALLREGENERATE_THUMBNAIL,MF_BYCOMMAND);
                    RemoveMenu(hmenuThumbnail,IDM_REGENERATE_THUMBNAIL,MF_BYCOMMAND);
                    RemoveMenu(hmenuThumbnail,static_cast<int>(ARRAY_SIZEOF(uiThumbnailMenu)),MF_BYPOSITION);
                }
            }
            break;
        }else if(wParam==(WPARAM)hHeaderSubMenu){
            for(int i=0;i<LISTITEM_NUM;i++){
                if(i==LISTITEM_CURRENTFILENAME)MenuItemInfo.fState=MFS_GRAYED|MFS_CHECKED;//LISTITEM_CURRENTFILENAMEは常に有効
                else MenuItemInfo.fState=((g_ListViewColumn_Table[i].bVisible)?MFS_CHECKED:MFS_UNCHECKED);
                SetMenuItemInfo(hHeaderSubMenu,g_ListViewColumn_Table[i].iMenuId,false,&MenuItemInfo);
            }
            break;
        }
        break;
    }

    case WM_NOTIFY:{
        LPNMHDR lpNMHdr=(LPNMHDR)lParam;

        switch(lpNMHdr->idFrom){
            case 0:{
                if(lpNMHdr->hwndFrom==g_hListViewHeader){
                    LPNMHEADER lpNMHeader=(LPNMHEADER)lParam;

                    switch(lpNMHdr->code){
                        case NM_RCLICK:{//リストビューのヘッダを右クリックした
                            POINT pt;

                            GetCursorPos(&pt);
                            TrackPopupMenu(hHeaderSubMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON,pt.x,pt.y,0,hWnd,NULL);
                            break;
                        }

                        case HDN_BEGINTRACK:{
                            //非表示のカラムの幅変更禁止
                            if(lpNMHeader->pitem->cxy==0)return true;
                            break;
                        }

                        case HDN_ENDTRACK://カラム幅を変更した
                            //リストビューカラムの幅を保存
                            *(g_ListViewColumn_Table[lpNMHeader->iItem].piWidth)=lpNMHeader->pitem->cxy;
                            dprintf(_T("*(g_ListViewColumn_Table[%d].piWidth)=%d\n"),lpNMHeader->iItem,*(g_ListViewColumn_Table[lpNMHeader->iItem].piWidth));
                            break;

                        default:
                            break;
                    }
                }
                break;
            }

            case IDC_LISTVIEW:{//リストビュー
                TCHAR szTmp[64];//サイズ,更新日時表示用
                SYSTEMTIME stLastModified;//システムファイル
                FILETIME ftLastModified;//ファイルタイム
                LPNMLISTVIEW lpNMLV;
                lpNMLV=(LPNMLISTVIEW)lParam;
                switch(lpNMHdr->code){
                    case LVN_COLUMNCLICK:{//ヘッダをクリックした
                        SortListViewItem(lpNMLV->iSubItem,g_iSortUp);
                        InvalidateRect(lpNMHdr->hwndFrom,NULL,false);
                        g_iSortUp=!g_iSortUp;//逆にする
                        break;
                    }

                    case NM_DBLCLK:{//ダブルクリック
                        if(lstrlen(g_Config.szViewerPath)<=0){
                            if(!OpenSingleFileDialog(hWnd,
                                                     g_Config.szViewerPath,
                                                     ARRAY_SIZEOF(g_Config.szViewerPath)+1,
                                                       _T("ビューア (*.exe)\0*.exe\0すべてのファイル (*.*)\0*.*\0\0"),
                                                     _T("ビューアを選択してください"))){
                                break;
                            }
                        }

                        LPNMITEMACTIVATE lpNMItemActivate=(LPNMITEMACTIVATE)lParam;
                        if(lpNMItemActivate->iItem!=-1){//アイテム上でダブルクリック
                            int iSize=lstrlen(g_lpArcFileInfo[lpNMLV->iItem].szCurrentFullFileName)+5;
                            LPTSTR lpszBuffer=(LPTSTR)malloc(sizeof(TCHAR)*iSize);

                            wsprintf(lpszBuffer,_T("\"%s\""),g_lpArcFileInfo[lpNMLV->iItem].szCurrentFullFileName);
                            ShellExecute(hWnd,NULL,g_Config.szViewerPath,lpszBuffer,NULL,SW_SHOW);
                            free(lpszBuffer);
                            lpszBuffer=NULL;
                            ListView_EnsureVisible(lpNMHdr->hwndFrom,lpNMLV->iItem,false);
                        }
                        break;
                    }

                    case NM_RCLICK:{//右クリック
                        LPNMITEMACTIVATE lpNMItemActivate=(LPNMITEMACTIVATE)lParam;
                        POINT pt;

                        GetCursorPos(&pt);
                        if(lpNMItemActivate->iItem==-1){
                            TrackPopupMenu(hContextSubMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON,pt.x,pt.y,0,hWnd,NULL);//リストビューのアイテム上の右クリックではない
                        }else{
                            TrackPopupMenu(hListItemContextSubMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON,pt.x,pt.y,0,hWnd,NULL);
                        }
                        return 0;
                    }

                    case LVN_GETINFOTIP:{//ツールチップ
                        LPNMLVGETINFOTIP lpNMLVGetInfoTip=(LPNMLVGETINFOTIP)lParam;
                        lpNMLVGetInfoTip->dwFlags=LVGIT_UNFOLDED;
                        _tcscpy(lpNMLVGetInfoTip->pszText,_T("現在のファイル名: "));
                        _tcscat(lpNMLVGetInfoTip->pszText,g_lpArcFileInfo[lpNMLVGetInfoTip->iItem].szCurrentFileName);
                        if(g_lpArcFileInfo[lpNMLVGetInfoTip->iItem].iStatus==ARC_READY_FOR_RENAME){//リネーム出来る
                            _tcscat(lpNMLVGetInfoTip->pszText,_T("\n新しいファイル名: "));
                            _tcscat(lpNMLVGetInfoTip->pszText,g_lpArcFileInfo[lpNMLVGetInfoTip->iItem].szNewFileName);
                        }
                        return 0;
                    }

                    case LVN_ITEMCHANGED:{
                        int i=0,iSelectedCount=0;
                        TCHAR szSelectedCount[256]={0};
                        for(i=0;i<ListView_GetItemCount(lpNMHdr->hwndFrom);i++)if((ListView_GetItemState(lpNMHdr->hwndFrom,i,LVIS_SELECTED))&LVIS_SELECTED)iSelectedCount++;
                        if(iSelectedCount>0)wsprintf(szSelectedCount,_T("選択 %d 個のファイル"),iSelectedCount);
                        else if(g_bThread)_tcscpy(szSelectedCount,_T("Escで中止します"));
                        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)szSelectedCount);
                        break;
                    }

                    case NM_CUSTOMDRAW:{
                        LPNMLVCUSTOMDRAW lpNMLVCD=(LPNMLVCUSTOMDRAW)lParam;

                        if(lpNMLVCD->nmcd.dwDrawStage==CDDS_PREPAINT){
                            return CDRF_NOTIFYITEMDRAW;
                        }

                        if(lpNMLVCD->nmcd.dwDrawStage==CDDS_ITEMPREPAINT){
                            //LVS_ICONのみ(?)、nmcd.dwItemSpecに異常な値が代入されている場合があるので、リストのアイテム数より多かったり、値が負の数の場合処理しない
                            if(static_cast<int>(lpNMLVCD->nmcd.dwItemSpec)>=ListView_GetItemCount(lpNMHdr->hwndFrom)||lpNMLVCD->nmcd.dwItemSpec<0)break;

                            //文字色、背景色、フォントを設定
                            if(g_lpArcFileInfo[lpNMLVCD->nmcd.dwItemSpec].iStatus==ARC_DEFAULT){//デフォルト
                                lpNMLVCD->clrText=g_Config.DefaultItemDesign.clrText;
                                lpNMLVCD->clrTextBk=g_Config.DefaultItemDesign.clrTextBk;
                                SelectObject(lpNMLVCD->nmcd.hdc,g_hDefaultItemFont);
                            }else if(g_lpArcFileInfo[lpNMLVCD->nmcd.dwItemSpec].iStatus==ARC_READY_FOR_RENAME){//リネーム可能
                                lpNMLVCD->clrText=g_Config.ReadyItemDesign.clrText;
                                lpNMLVCD->clrTextBk=g_Config.ReadyItemDesign.clrTextBk;
                                SelectObject(lpNMLVCD->nmcd.hdc,g_hReadyItemFont);
                            }else if(g_lpArcFileInfo[lpNMLVCD->nmcd.dwItemSpec].iStatus==ARC_RENAMED){//リネーム済
                                lpNMLVCD->clrText=g_Config.RenamedItemDesign.clrText;
                                lpNMLVCD->clrTextBk=g_Config.RenamedItemDesign.clrTextBk;
                                SelectObject(lpNMLVCD->nmcd.hdc,g_hRenamedItemFont);
                            }else if(g_lpArcFileInfo[lpNMLVCD->nmcd.dwItemSpec].iStatus>=ARC_RENAME_FAILURE){//エラー
                                lpNMLVCD->clrText=g_Config.FailedItemDesign.clrText;
                                lpNMLVCD->clrTextBk=g_Config.FailedItemDesign.clrTextBk;
                                SelectObject(lpNMLVCD->nmcd.hdc,g_hFailedItemFont);
                            }
                            return CDRF_NEWFONT;
                        }else{
                            return CDRF_DODEFAULT;
                        }
                        break;
                    }

                    // リストビューからの要求
                    case LVN_GETDISPINFO:{
                        LVITEM* pLVItem;

                        pLVItem=&((NMLVDISPINFO*)lParam)->item;
                        //イメージリストを設定
                        if(pLVItem->mask&LVIF_IMAGE){
                            if(g_eThumbSize==NO_THUMBNAIL){
                                //ファイルアイコン表示
                                int iFileIconIndex=GetIndexFromType(g_lpArcFileInfo[pLVItem->iItem].szType);
                                pLVItem->iImage=iFileIconIndex;
                            }else{
                                //サムネイル表示
                                pLVItem->iImage=pLVItem->iItem;
                            }

                            pLVItem->stateMask=0;
                            pLVItem->state=0;
                        }

                        //テキストを設定
                        if(pLVItem->mask&LVIF_TEXT){
                            //iITemに異常な値が代入されている場合があるので、リストのアイテム数より多かったり、値が負の数の場合処理しない
                            if(pLVItem->iItem>=ListView_GetItemCount(lpNMHdr->hwndFrom)||pLVItem->iItem<0)break;

                            switch(pLVItem->iSubItem){
                                case LISTITEM_CURRENTFILENAME://現在のファイル名
                                    _tcscpy(pLVItem->pszText,g_lpArcFileInfo[pLVItem->iItem].szCurrentFileName);
                                    break;

                                case LISTITEM_NEWFILENAME://新しいファイル名
                                    _tcscpy(pLVItem->pszText,g_lpArcFileInfo[pLVItem->iItem].szNewFileName);
                                    break;

                                case LISTITEM_STATUS://ステータス
                                    _tcscpy(pLVItem->pszText,ArchiveStatus[g_lpArcFileInfo[pLVItem->iItem].iStatus].lpszStatus);
                                    break;

                                case LISTITEM_DIRECTORY://ディレクトリ
                                    _tcscpy(pLVItem->pszText,g_lpArcFileInfo[pLVItem->iItem].szDirectory);
                                    break;

                                case LISTITEM_SIZE://サイズ
                                    if(g_bFormatKBSize)StrFormatKBSize(g_lpArcFileInfo[pLVItem->iItem].liSize.QuadPart,szTmp,ARRAY_SIZEOF(szTmp));
                                    else StrFormatByteSize(g_lpArcFileInfo[pLVItem->iItem].liSize.QuadPart,szTmp,ARRAY_SIZEOF(szTmp));
                                    _tcscpy(pLVItem->pszText,szTmp);
                                    break;

                                case LISTITEM_TYPE://種類
                                    _tcscpy(pLVItem->pszText,g_lpArcFileInfo[pLVItem->iItem].szType);
                                    break;

                                case LISTITEM_LASTMODIFIED://更新日時
                                    FileTimeToLocalFileTime(&g_lpArcFileInfo[pLVItem->iItem].ftLastModified,&ftLastModified);
                                    FileTimeToSystemTime(&ftLastModified,&stLastModified);
                                    wsprintf(szTmp,_T("%04d/%02d/%02d %02d:%02d"),stLastModified.wYear,stLastModified.wMonth,stLastModified.wDay,stLastModified.wHour,stLastModified.wMinute);
                                    _tcscpy(pLVItem->pszText,szTmp);
                                    break;
                            }
                        }
                        break;

                        case LVN_ODFINDITEM:{//クイックキーアクセス
                            LRESULT lpResult;
                            int iStartPos=0;
                            int iCurrentPos=0;
                            LPNMLVFINDITEM lplvFindInfo=(NMLVFINDITEM*)lParam;
                            lpResult=-1;
                            if((lplvFindInfo->lvfi.flags&LVFI_STRING)==0)return lpResult;
                            LPCTSTR lpSearch=lplvFindInfo->lvfi.psz;
                            iStartPos=lplvFindInfo->iStart;
                            if(iStartPos>=ListView_GetItemCount(lpNMHdr->hwndFrom))iStartPos=0;
                            iCurrentPos=iStartPos;
                            lpResult=iStartPos;
                            do{
                                //ソート中のカラムを取得
                                int iOrders[LISTITEM_NUM]={0};
                                int iOrder=0;
                                bool bSorted=false;

                                HDITEM hdItem;
                                hdItem.mask=HDI_FORMAT;
                                for(iOrder=0;iOrder<LISTITEM_NUM;iOrder++){
                                    Header_GetItem(ListView_GetHeader(lpNMHdr->hwndFrom),iOrder,&hdItem);
                                    if((hdItem.fmt&HDF_SORTDOWN||hdItem.fmt&HDF_SORTUP)&&ListView_GetColumnWidth(lpNMHdr->hwndFrom,iOrder)!=0){
                                        bSorted=true;
                                        break;
                                    }
                                }

                                //ソートされていないorソートされているアイテムが非表示
                                if(!bSorted){
                                    ListView_GetColumnOrderArray(lpNMHdr->hwndFrom,LISTITEM_NUM,&iOrders);
                                    for(int i=0;i<LISTITEM_NUM;i++){
                                        if(ListView_GetColumnWidth(lpNMHdr->hwndFrom,iOrders[i])!=0){
                                            iOrder=iOrders[i];
                                            break;
                                        }
                                    }
                                }


                                dprintf(_T("iOrder=%d\n"),iOrder);


                                TCHAR szTmp[64];//サイズ,更新日時表示用

                                if(iOrder==LISTITEM_CURRENTFILENAME){//現在のファイル名
                                    if(_tcsnicmp(g_lpArcFileInfo[iCurrentPos].szCurrentFileName,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }else if(iOrder==LISTITEM_NEWFILENAME){//新しいファイル名
                                    if(_tcsnicmp(g_lpArcFileInfo[iCurrentPos].szNewFileName,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }else if(iOrder==LISTITEM_STATUS){//ステータス
                                    if(_tcsnicmp(ArchiveStatus[g_lpArcFileInfo[iCurrentPos].iStatus].lpszStatus,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }else if(iOrder==LISTITEM_DIRECTORY){//ディレクトリ
                                    if(_tcsnicmp(g_lpArcFileInfo[iCurrentPos].szDirectory,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }else if(iOrder==LISTITEM_SIZE){//サイズ
                                    if(g_bFormatKBSize)StrFormatKBSize(g_lpArcFileInfo[iCurrentPos].liSize.QuadPart,szTmp,ARRAY_SIZEOF(szTmp));
                                    else StrFormatByteSize(g_lpArcFileInfo[iCurrentPos].liSize.QuadPart,szTmp,ARRAY_SIZEOF(szTmp));
                                    if(_tcsnicmp(szTmp,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }else if(iOrder==LISTITEM_TYPE){//種類
                                    if(_tcsnicmp(g_lpArcFileInfo[iCurrentPos].szType,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }else if(iOrder==LISTITEM_LASTMODIFIED){//更新日時
                                    FileTimeToLocalFileTime(&g_lpArcFileInfo[iCurrentPos].ftLastModified,&ftLastModified);
                                    FileTimeToSystemTime(&ftLastModified,&stLastModified);
                                    wsprintf(szTmp,_T("%04d/%02d/%02d %02d:%02d"),stLastModified.wYear,stLastModified.wMonth,stLastModified.wDay,stLastModified.wHour,stLastModified.wMinute);
                                    if(_tcsnicmp(szTmp,lpSearch,_tcslen(lpSearch))==0){
                                        lpResult=iCurrentPos;
                                        break;
                                    }
                                }

                                iCurrentPos++;
                                if(iCurrentPos>=ListView_GetItemCount(lpNMHdr->hwndFrom))iCurrentPos=0;
                            }while(iCurrentPos!=iStartPos);
                            return lpResult;
                        }//LVN_ODFINDITEM
                        break;

                        default:
                            break;
                    }//LVN_GETDISPINFO
                }//switch(lpNMHdr->code)
                break;
            }//case IDC_LISTVIEW

            default:
                break;
        }//switch(lpNMHdr->idFrom)
        break;
    }//case WM_NOTIFY

    case WM_SIZE:{
        if(!IsWindowVisible(hWnd))return 0;
        int iStatusBarSize[3]={0,0,0};
        iStatusBarSize[2]=LOWORD(lParam);
        iStatusBarSize[1]=LOWORD(lParam)-LOWORD(lParam)/6;
        iStatusBarSize[0]=LOWORD(lParam)-LOWORD(lParam)/3;
        SendMessage(g_hStatusBar,SB_SETPARTS,3,(LPARAM)iStatusBarSize);
        SendMessage(g_hStatusBar,WM_SIZE,wParam,lParam);//ステータスバーの長さを調整
        SendMessage(hReBar,WM_SIZE,wParam,lParam+10);//レバーの長さを調整

        //リストビューの大きさを調整
        RECT rcStatusBar;
        int iRebarHeight;
        HDWP hDwp=NULL;

        iRebarHeight=(int)SendMessage(hReBar,RB_GETBARHEIGHT,(WPARAM)0,(LPARAM)0);
        GetClientRect(g_hStatusBar,&rcStatusBar);
        hDwp=BeginDeferWindowPos(3);
        hDwp=DeferWindowPos(hDwp,
                            g_hListView,HWND_TOP,
                            0,
                            iRebarHeight,
                            LOWORD(lParam),
                            HIWORD(lParam)-iRebarHeight-rcStatusBar.bottom,
                            SWP_NOZORDER);
        EndDeferWindowPos(hDwp);

        bSizeChanged=true;
        break;
    }

    case WM_ENTERSIZEMOVE:
        dprintf(_T("WM_ENTERSIZEMOVE\n"));
        bSizeChanged=false;
        break;

    case WM_EXITSIZEMOVE:
        dprintf(_T("WM_EXITSIZEMOVE\n"));
        if(bSizeChanged){
            //再描画
            InvalidateRect(g_hListView,NULL,true);
            UpdateWindow(g_hListView);
        }
        break;

    case WM_MENUSELECT:{
        //メニューヘルプ表示
        TCHAR szMenuHelp[1024]={0};
        LoadString(g_hInstance,LOWORD(wParam),szMenuHelp,ARRAY_SIZEOF(szMenuHelp));
        SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)szMenuHelp);
        break;
    }

    case WM_COMMAND:{
        int i=0;

        if(g_bWorking&&LOWORD(wParam)!=IDM_STOPTHREAD)return 0;//処理中[中止メッセージ以外は受け付けない]
        switch(LOWORD(wParam)){
            case ID_FILE://ファイルを開く[ツールバー]
            case IDM_OPENFILE:{//ファイルを開く[メニュー]
                dprintf(_T("OpenFile\n"));

                if(!g_Config.EnableFileType.bZip&&
                   !g_Config.EnableFileType.b7z&&
                   !g_Config.EnableFileType.bCab&&
                   !g_Config.EnableFileType.bLzh&&
                   !g_Config.EnableFileType.bRar){
                    dprintf(_T("Invalid All EnableFileType\n"));
                    break;
                }

                int iBeforeFileCount=g_iFileCount;//ファイル追加前のファイル数を保存
                g_bWorking=true;

                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("ファイル追加中..."));
                if(!SelectArchiveFile(hWnd)){
                    g_bWorking=false;
                    SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T(""));
                    break;
                }

                //サムネイルを作成
                PostMessage(hWnd,WM_CREATETHUMBNAIL,(WPARAM)iBeforeFileCount,(LPARAM)0);
                AdjustListView(true);
                break;
            }

            case ID_FOLDER://フォルダを開く[ツールバー]
            case IDM_OPENFOLDER:{//フォルダを開く[メニュー]
                dprintf(_T("OpenDirectory\n"));

                if(!g_Config.EnableFileType.bZip&&
                   !g_Config.EnableFileType.b7z&&
                   !g_Config.EnableFileType.bCab&&
                   !g_Config.EnableFileType.bLzh&&
                   !g_Config.EnableFileType.bRar){
                    dprintf(_T("Invalid All EnableFileType\n"));
                    break;
                }

                TCHAR szDirectory[MAX_PATH]={0};

                g_bWorking=true;
                if(!SelectDirectory(hWnd,szDirectory)){
                    g_bWorking=false;
                    break;
                }

                dprintf(_T("szDirectory=%s\n"),szDirectory);

                if(!path::IsDirectory(szDirectory)){
                    g_bWorking=false;
                    break;
                }

                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("ファイル追加中..."));
                SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));

                unsigned uThreadID;
                ZeroMemory(&param_AddSelectDirectoryThread,sizeof(param_AddSelectDirectoryThread));
                param_AddSelectDirectoryThread.hWnd=hWnd;//処理終了の報告先ウインドウハンドル
                _tcscpy(param_AddSelectDirectoryThread.szDirectory,szDirectory);//追加するディレクトリ名
                param_AddSelectDirectoryThread.iBeforeFileCount=g_iFileCount;//ファイル追加前のファイル数
                InitializeCriticalSection(&csCriticalSection);
                g_hAddSelectDirectoryThread=BEGINTHREADEX(NULL,0,AddSelectDirectoryThread,&param_AddSelectDirectoryThread,0,&uThreadID);
                break;
            }

            case IDM_ALL://すべて選択
                if(!g_iFileCount)break;
                ListView_SelectAll(g_hListView);
                break;

            case IDM_HIDESELECTION://選択を解除
                if(!g_iFileCount)break;
                ListView_SelectNone(g_hListView);
                break;

            case IDM_INVERSE://選択範囲を反転
                if(!g_iFileCount)break;
                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED){
                        ListView_SetItemState(g_hListView,i,0,LVIS_SELECTED);
                    }else{
                        ListView_SetItemState(g_hListView,i,LVIS_SELECTED,LVIS_SELECTED);
                    }
                }
                break;

            case IDM_REMOVEFILE://ごみ箱に移動
                if(!g_iFileCount)break;
                g_bWorking=true;
                RemoveListViewFile();
                AdjustListView();
                g_bWorking=false;
                break;

            case IDM_REMOVELIST://削除
                if(!g_iFileCount)break;
                g_bWorking=true;
                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED){
                        RemoveListViewItem(i);
                        i--;
                    }
                }
                AdjustListView();
                g_bWorking=false;
                break;

            case ID_CLEAR://クリア[メニューバー]
            case IDM_ALLREMOVEFILE://すべて削除
                if(!g_iFileCount)break;
                if(MessageBox(hWnd,_T("リストをすべてクリアしますか?"),_T("リストクリアの確認"),MB_YESNO|MB_ICONQUESTION)==IDYES){
                    RemoveAllListViewItem();
                }
                break;
            case IDM_REMOVEERROR://エラーのファイルをすべて削除
                if(!g_iFileCount)break;
                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if(g_lpArcFileInfo[i].iStatus>=ARC_RENAME_FAILURE){RemoveListViewItem(i);i--;}
                }
                AdjustListView();
                break;

            case IDM_EDITNAME://新しいファイル名の変更
                if(!g_iFileCount)break;
                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if((ListView_GetItemState(g_hListView,i,LVIS_FOCUSED))&LVIS_FOCUSED){
                        if(IDOK==(DialogBox(g_hInstance,
                                            MAKEINTRESOURCE(IDD_DIALOG_RENAME),
                                            hWnd,
                                            (DLGPROC)RenameDialogProc))){

                        }
                        break;
                    }
                }
                AdjustListView();
                SetFocus(g_hListView);
                break;

            case IDM_ALWAYSONTOP://常に手前に表示
                g_bAlwaysOnTop=!g_bAlwaysOnTop;//反転
                if(g_bAlwaysOnTop)SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//手前に表示
                else SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//解除
                break;

            case IDM_FILESIZEKB:
                g_bFormatKBSize=!g_bFormatKBSize;//反転
                ListView_RedrawItems(g_hListView,0,ListView_GetItemCount(g_hListView)-1);//再描画
                break;

            case ID_ALLRENAME://すべてリネーム[ツールバー]
            case ID_RENAME://リネーム[ツールバー]
            case IDM_RENAME://選択したファイルをリネーム
            case IDM_ALLRENAME:{//すべてリネーム[メニュー]
                dprintf(_T("\n***Rename***\n"));
                if(!g_iFileCount)break;

                if(path::IsBadName(g_Config.szFormat)){
                    MessageBox(hWnd,_T("新しいファイル名には次の文字は使えません。\n\t\\ / : , ; * ? \" < > |"),_T("新しいファイル名のフォーマット"),MB_ICONSTOP);
                    break;;
                }

                int iSelected=0;

                g_bWorking=true;
                g_bThread=true;
                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("リネーム中..."));
                SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
                //ステータスバー上にプログレスバー作成
                hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);

                if((LOWORD(wParam))!=ID_ALLRENAME&&(LOWORD(wParam))!=IDM_ALLRENAME){
                    //「すべて~」でない場合
                    for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                        if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED)iSelected++;
                    }
                    if(hStatusProgressBar!=NULL){
                        if(iSelected<1){//選択されていない
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                        }else{//選択されている
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,iSelected));
                        }
                    }
                }else{
                    //プログレスバーの範囲指定
                    SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                }
                dprintf(_T("iSelected/g_iFileCount=%d/%d\n"),iSelected,g_iFileCount);

                if(hStatusProgressBar!=NULL)SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);//1Stepは1

                InitializeCriticalSection(&csCriticalSection);
                g_hFileNameThread=CallFileNameThread(RenameFileName,
                                                     g_lpArcFileInfo,
                                                     hStatusProgressBar,
                                                     ListView_GetItemCount(g_hListView),
                                                     iSelected,
                                                     (LOWORD(wParam)!=ID_ALLRENAME&&iSelected)?true:false
                                                    );
                //スレッドの優先度を「高」に設定
                SetThreadPriority(g_hFileNameThread,THREAD_PRIORITY_HIGHEST);
                break;
            }

            case IDM_UNDO://リネームを取り消す[メニュー]
            case IDM_ALLUNDO:{//すべてのファイルのリネームを取り消します
                dprintf(_T("\n***Undo***\n"));
                if(!g_iFileCount)break;
                int iSelected=0;

                g_bWorking=true;
                g_bThread=true;
                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("取り消しています..."));
                SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
                //ステータスバー上にプログレスバー作成
                hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);

                if((LOWORD(wParam))!=IDM_ALLUNDO){
                    //「すべて~」でない場合
                    for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                        if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED)iSelected++;
                    }
                    if(hStatusProgressBar!=NULL){
                        if(iSelected<1){//選択されていない
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                        }else{//選択されている
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,iSelected));
                        }
                    }
                }else{
                    //プログレスバーの範囲指定
                    SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                }

                dprintf(_T("iSelected/g_iFileCount=%d/%d\n"),iSelected,g_iFileCount);

                SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);//1Stepは1

                InitializeCriticalSection(&csCriticalSection);
                g_hFileNameThread=CallFileNameThread(UndoFileName,
                                                     g_lpArcFileInfo,
                                                     hStatusProgressBar,
                                                     ListView_GetItemCount(g_hListView),
                                                     iSelected,
                                                     (LOWORD(wParam)!=IDM_ALLUNDO&&iSelected)?true:false
                                                    );
                //スレッドの優先度を「高」に設定
                SetThreadPriority(g_hFileNameThread,THREAD_PRIORITY_HIGHEST);
                break;
            }

            case IDM_ANALYZE://選択したファイルのみ新しいファイル名を取得
            case IDM_ALLANALYZE:{//すべての新しいファイル名を取得
                dprintf(_T("\n***Analyze***\n"));
                if(!g_iFileCount)break;

                if(path::IsBadName(g_Config.szFormat)){
                    MessageBox(hWnd,_T("新しいファイル名には次の文字は使えません。\n\t\\ / : , ; * ? \" < > |"),_T("新しいファイル名のフォーマット"),MB_ICONSTOP);
                    break;
                }

                int iSelected=0;

                g_bWorking=true;
                g_bThread=true;
                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("ファイル名取得中..."));
                SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
                //ステータスバー上にプログレスバー作成
                hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);

                if((LOWORD(wParam))!=IDM_ALLANALYZE){
                    //「すべて~」でない場合
                    for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                        if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED)iSelected++;
                    }
                    if(hStatusProgressBar!=NULL){
                        if(iSelected<1){//選択されていない
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                        }else{//選択されている
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,iSelected));
                        }
                    }
                }else{
                    //プログレスバーの範囲指定
                    if(hStatusProgressBar!=NULL)SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                }

                dprintf(_T("iSelected=%d\n"),iSelected);

                if(hStatusProgressBar!=NULL)SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);//1Stepは1

                InitializeCriticalSection(&csCriticalSection);
                g_hFileNameThread=CallFileNameThread(GetNewFileName,
                                                     g_lpArcFileInfo,
                                                     hStatusProgressBar,
                                                     ListView_GetItemCount(g_hListView),
                                                     iSelected,
                                                     (LOWORD(wParam)!=IDM_ALLANALYZE&&iSelected)?true:false
                                                    );
                //スレッドの優先度を「高」に設定
                SetThreadPriority(g_hFileNameThread,THREAD_PRIORITY_HIGHEST);
                break;
            }

            case ID_OPTIONS://オプション[ツールバー]
            case IDM_OPTIONS://オプション
            case IDM_ABOUT://バージョン情報
                if(!g_bSettingsDialog){
                    int iBeforeSize=0;

                    if(g_eThumbSize!=NO_THUMBNAIL){
                        iBeforeSize=GetThumbnailSize();
                        dprintf(_T("ThumbnailSize(Before)=%d\n"),iBeforeSize);
                    }
                    dprintf(_T("SettingsDialog()..."));
                    if(IDOK==ShowSettingsDialog(hWnd,((LOWORD(wParam)==ID_OPTIONS||(LOWORD(wParam)==IDM_OPTIONS)?TAB_GENERAL:TAB_VERSION)))){
                        dprintf(_T("IDOK\n"));

                        RefreshGUIFont();
                        ListView_SetBkColor(g_hListView,g_Config.DefaultItemDesign.clrTextBk);

                        //ListView_SetIconSpacing()でも利用するため、この位置で取得
                        int iAfterSize=GetThumbnailSize();

                        //背景色変更に対応するため、サムネイル非表示時のみアイコンを更新
                        if(g_eThumbSize==NO_THUMBNAIL){
                            SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("アイコン更新中..."));
                            RefreshFileIcon();
                        }else{
                            dprintf(_T("ThumbnailSize(After)=%d\n"),iBeforeSize);

                            if(iBeforeSize!=iAfterSize){
                                //サムネイルサイズ変更
                                ImageList_SetIconSize(g_hImgThumbnail,iAfterSize,iAfterSize);
                                if(!ListView_SetImageList(g_hListView,g_hImgThumbnail,LVSIL_NORMAL)){};//適用/warning: value computed is not used対策
                                //サムネイルを再作成
                                PostMessage(hWnd,WM_COMMAND,(WPARAM)MAKEWPARAM(IDM_ALLREGENERATE_THUMBNAIL,0),(LPARAM)0);
                            }
                        }
                        //サムネイルの間隔を変更
                        ListView_SetItemSpacing(g_hListView,
                                    (g_Config.Thumbnail.iSpacingX==-1)?g_Config.Thumbnail.iSpacingX:iAfterSize+g_Config.Thumbnail.iSpacingX,
                                    (g_Config.Thumbnail.iSpacingY==-1)?g_Config.Thumbnail.iSpacingY:iAfterSize+g_Config.Thumbnail.iSpacingY);
                    }else{
                        dprintf(_T("IDCANCEL\n"));
                    }
                    AdjustListView();
                }
                break;

            case IDM_HOMEPAGE:{//ホームページを開く
                TCHAR szBuffer[64]={0};

                LoadString(g_hInstance,IDS_URL,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
                ShellExecute(NULL,_T("open"),szBuffer,NULL,NULL,SW_SHOWNORMAL);
                break;
            }

            case IDM_UPDATE://最新版を確認
                g_bWorking=true;
                g_bThread=true;
                //ステータスバー上にプログレスバー作成
                hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);
                CallUpdateLatestVersion(g_hMainWnd,g_hInstance,g_hStatusBar,hStatusProgressBar);
                break;

            case IDM_PROPERTY:{//プロパティ
                if(!g_iFileCount)break;
                SHELLEXECUTEINFO ShellExecuteInfo;//IDM_PROPERTY
                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if(ListView_GetItemState(g_hListView,i,LVIS_FOCUSED)&LVIS_FOCUSED){
                        ZeroMemory(&ShellExecuteInfo,sizeof(SHELLEXECUTEINFO));
                        ShellExecuteInfo.cbSize=sizeof(SHELLEXECUTEINFO);
                        ShellExecuteInfo.fMask=SEE_MASK_NOCLOSEPROCESS|SEE_MASK_INVOKEIDLIST|SEE_MASK_FLAG_NO_UI;
                        ShellExecuteInfo.lpVerb=_T("Properties");
                        ShellExecuteInfo.hwnd=hWnd;
                        ShellExecuteInfo.lpFile=g_lpArcFileInfo[i].szCurrentFullFileName;
                        ShellExecuteEx(&ShellExecuteInfo);
                    }
                }
                break;
            }

            case IDM_VIEWER://ビューアで開く
#ifndef DEBUG
                if(lstrlen(g_Config.szViewerPath)<=0){
                    if(!OpenSingleFileDialog(hWnd,
                                             g_Config.szViewerPath,
                                             ARRAY_SIZEOF(g_Config.szViewerPath)+1,
                                               _T("ビューア (*.exe)\0*.exe\0すべてのファイル (*.*)\0*.*\0\0"),
                                               _T("ビューアを選択してください"))){
                        break;
                    }
                }
#endif

                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if((ListView_GetItemState(g_hListView,i,LVIS_FOCUSED))&LVIS_FOCUSED){
#ifdef DEBUG
                        ARCHIVE_INFO(g_lpArcFileInfo,i);
#else
                        int iSize=lstrlen(g_lpArcFileInfo[i].szCurrentFullFileName)+5;
                        LPTSTR lpszBuffer=(LPTSTR)malloc(sizeof(TCHAR)*iSize);

                        wsprintf(lpszBuffer,_T("\"%s\""),g_lpArcFileInfo[i].szCurrentFullFileName);
                        ShellExecute(hWnd,NULL,g_Config.szViewerPath,lpszBuffer,NULL,SW_SHOW);
                        free(lpszBuffer);
                        lpszBuffer=NULL;
                        ListView_EnsureVisible(g_hListView,i,false);
#endif
                        break;
                    }
                }
                break;

            case IDM_CLIPBOARDFULLPATH://クリップボードにコピー->フルパス
            case IDM_CLIPBOARDFILEPATHONLY://クリップボードにコピー->ファイル名のみ
                if(!g_iFileCount)break;
                for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                    if((ListView_GetItemState(g_hListView,i,LVIS_FOCUSED))&LVIS_FOCUSED){
                        SetClipboardText(hWnd,
                                        (LOWORD(wParam)==IDM_CLIPBOARDFULLPATH)?g_lpArcFileInfo[i].szCurrentFullFileName:g_lpArcFileInfo[i].szCurrentFileName,
                                        lstrlen((LOWORD(wParam)==IDM_CLIPBOARDFULLPATH)?g_lpArcFileInfo[i].szCurrentFullFileName:g_lpArcFileInfo[i].szCurrentFileName)
                        );
                        break;
                    }
                }
                break;

            case ID_ANALYZE:{//ファイル名を取得[ツールバー]
                RECT rc;
                SendMessage(hToolBar,TB_GETRECT,(WPARAM)ID_ANALYZE,(LPARAM)&rc);
                MapWindowPoints(hToolBar,HWND_DESKTOP,(LPPOINT)&rc,2);
                TrackPopupMenu(hAnalyzeSubMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rc.left,rc.bottom,0,hWnd,NULL);
                AdjustListView();
                break;
            }

            case ID_UNDO:{//取り消す[ツールバー]
                RECT rc;
                SendMessage(hToolBar,TB_GETRECT,(WPARAM)ID_UNDO,(LPARAM)&rc);
                MapWindowPoints(hToolBar,HWND_DESKTOP,(LPPOINT)&rc,2);
                TrackPopupMenu(hUndoSubMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rc.left,rc.bottom,0,hWnd,NULL);
                AdjustListView();
                break;
            }

            case ID_THUMBNAIL:{//サムネイルを表示[ツールバー]
                RECT rc;
                SendMessage(hToolBar,TB_GETRECT,(WPARAM)ID_THUMBNAIL,(LPARAM)&rc);
                MapWindowPoints(hToolBar,HWND_DESKTOP,(LPPOINT)&rc,2);
                TrackPopupMenu(hThumbnailSubMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rc.left,rc.bottom,0,hWnd,NULL);
                AdjustListView();
                break;
            }

            //サムネイル作成/破棄処理はswitch()後
            case IDM_SMALL_THUMBNAIL://小さいサイズ
                if(g_eThumbSize!=SMALL_THUMBNAIL)g_eThumbSize=SMALL_THUMBNAIL;
                else return DefWindowProc(hWnd,uMsg,wParam,lParam);
                break;

            case IDM_NORMAL_THUMBNAIL://標準サイズ
                if(g_eThumbSize!=NORMAL_THUMBNAIL)g_eThumbSize=NORMAL_THUMBNAIL;
                else return DefWindowProc(hWnd,uMsg,wParam,lParam);
                break;

            case IDM_LARGE_THUMBNAIL://大きいサイズ
                if(g_eThumbSize!=LARGE_THUMBNAIL)g_eThumbSize=LARGE_THUMBNAIL;
                else return DefWindowProc(hWnd,uMsg,wParam,lParam);
                break;

            case IDM_NO_THUMBNAIL://表示しない
                if(g_eThumbSize!=NO_THUMBNAIL)g_eThumbSize=NO_THUMBNAIL;
                else return DefWindowProc(hWnd,uMsg,wParam,lParam);
                break;

            case IDM_REGENERATE_THUMBNAIL://再作成
            case IDM_ALLREGENERATE_THUMBNAIL:{//すべて再作成

                int iSize=GetThumbnailSize();

                //リストビューにファイルが無い場合
                if(!g_iFileCount)break;

                int iSelected=0;

                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("サムネイル再作成中..."));
                SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
                //ステータスバー上にプログレスバー作成
                hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);
                if((LOWORD(wParam))!=IDM_ALLREGENERATE_THUMBNAIL){
                    //「すべて~」でない場合
                    for(i=0;i<ListView_GetItemCount(g_hListView);i++){
                        if((ListView_GetItemState(g_hListView,i,LVIS_SELECTED))&LVIS_SELECTED)iSelected++;
                    }
                    if(hStatusProgressBar!=NULL){
                        if(iSelected<1){//選択されていない
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                        }else{//選択されている
                            //プログレスバーの範囲指定
                            SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,iSelected));
                        }
                    }
                }else{
                    //プログレスバーの範囲指定
                    if(hStatusProgressBar!=NULL)SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                }

                //1Stepは1
                SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);

                g_bWorking=true;
                g_bThread=true;
                g_hCreateThumbnailThread=CreateThumbnail(g_iFileCount,iSize,iSize,hStatusProgressBar,0,true,iSelected);
                //スレッドの優先度を「高」に設定
                SetThreadPriority(g_hCreateThumbnailThread,THREAD_PRIORITY_HIGHEST);
                break;
            }

            case ID_EXIT://終了[ツールバー]
            case IDM_EXIT://終了
                PostMessage(hWnd,WM_SYSCOMMAND,SC_CLOSE,0);
                break;

            case IDM_STOPTHREAD://サムネイル作成中止
                if(g_bThread)g_bWorking=false;
                dprintf(_T("Esc\n"));
                break;

            default:
                break;
        }

        if(LOWORD(wParam)==IDM_CURRENTFILENAME_HEADER||
           LOWORD(wParam)==IDM_NEWFILENAME_HEADER||
           LOWORD(wParam)==IDM_STATUS_HEADER||
           LOWORD(wParam)==IDM_DIRECTORY_HEADER||
           LOWORD(wParam)==IDM_SIZE_HEADER||
           LOWORD(wParam)==IDM_TYPE_HEADER||
           LOWORD(wParam)==IDM_LASTMODIFIED_HEADER){
            for(int i=1;i<LISTITEM_NUM;i++){//LISTITEM_CURRENTFILENAMEをskipするためi=1
                if(LOWORD(wParam)==g_ListViewColumn_Table[i].iMenuId){
                    if(g_ListViewColumn_Table[i].bVisible){
                        //カラムを削除(カラム幅を0にする)
                        ListView_RemoveColumn(g_ListViewColumn_Table,g_hListView,i);
                    }else{
                        //カラムを再表示
                        ListView_RedisplayColumn(g_ListViewColumn_Table,g_hListView,i);
                    }
                }
            }
        }

        if(LOWORD(wParam)==IDM_SMALL_THUMBNAIL||
            LOWORD(wParam)==IDM_NORMAL_THUMBNAIL||
            LOWORD(wParam==IDM_LARGE_THUMBNAIL)){
            ImageList_RemoveAll(g_hImgThumbnail);
            ImageList_SetImageCount(g_hImgThumbnail,0);
            int iSize=GetThumbnailSize();

            //スタイルを変更
            if(LV_VIEW_ICON!=(ListView_GetView(g_hListView))){
                ListView_SetView(g_hListView,LV_VIEW_ICON);
            }

            //サムネイルサイズ変更
            ImageList_SetIconSize(g_hImgThumbnail,iSize,iSize);
            if(!ListView_SetImageList(g_hListView,g_hImgThumbnail,LVSIL_NORMAL)){};//適用/warning: value computed is not used対策

            //サムネイルの間隔を変更
            ListView_SetItemSpacing(g_hListView,
                                    (g_Config.Thumbnail.iSpacingX==-1)?g_Config.Thumbnail.iSpacingX:iSize+g_Config.Thumbnail.iSpacingX,
                                    (g_Config.Thumbnail.iSpacingY==-1)?g_Config.Thumbnail.iSpacingY:iSize+g_Config.Thumbnail.iSpacingY);
            dprintf(_T("g_Config.Thumbnail.iSpacingX=%d\ng_Config.Thumbnail.iSpacingY\ng_Config.Thumbnail.iSpacingX+iSize=%d\ng_Config.Thumbnail.iSpacingY+iSize\n"),g_Config.Thumbnail.iSpacingX,g_Config.Thumbnail.iSpacingY,g_Config.Thumbnail.iSpacingX+iSize,g_Config.Thumbnail.iSpacingY+iSize);

            //リストビューにファイルが無い場合
            if(!g_iFileCount)break;

            //ステータスバーに文字追加
            SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("サムネイル作成中..."));
            SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
            //ステータスバー上にプログレスバー作成
            hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);
            if(hStatusProgressBar!=NULL){
                //範囲指定
                SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,g_iFileCount));
                //1Stepは1
                SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);
            }

            g_bWorking=true;
            g_bThread=true;

            g_hCreateThumbnailThread=CreateThumbnail(g_iFileCount,iSize,iSize,hStatusProgressBar);
            //スレッドの優先度を「高」に設定
            SetThreadPriority(g_hCreateThumbnailThread,THREAD_PRIORITY_HIGHEST);
        }else if(LOWORD(wParam)==IDM_NO_THUMBNAIL){
            //サムネイル表示時の背景色変更に対応
            SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("アイコン更新中..."));
            RefreshFileIcon();
            SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T(""));

            ImageList_RemoveAll(g_hImgThumbnail);
            //スタイルを変更
            ListView_SetView(g_hListView,LV_VIEW_DETAILS);
            g_bWorking=false;
        }
    }
    break;

    //サムネイル作成はswitch()後
    //AddSelectDirectoryThread()から
    case WM_EXIT_ADDSELECTDIRECTORY_THREAD:
        if(g_hAddSelectDirectoryThread!=NULL){
            DeleteCriticalSection(&csCriticalSection);
            CloseHandle(g_hAddSelectDirectoryThread);
            g_hAddSelectDirectoryThread=NULL;
        }
        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T(""));
        AdjustListView(true);
        g_bThread=false;
        break;

    //サムネイル作成はswitch()後
    //AddDroppedFilesThread()から
    case WM_EXIT_ADDDROPPEDFILES_THREAD:
        if(g_hAddDroppedFilesThread!=NULL){
            DeleteCriticalSection(&csCriticalSection);
            CloseHandle(g_hAddDroppedFilesThread);
            g_hAddDroppedFilesThread=NULL;
        }
        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T(""));
        AdjustListView(true);
        g_bThread=false;
        break;

    //FilenameThread()から
    case WM_EXIT_FILENAME_THREAD:
        if(g_hFileNameThread!=NULL){
            DeleteCriticalSection(&csCriticalSection);
            CloseHandle(g_hFileNameThread);
            g_hFileNameThread=NULL;
        }

        //スレッドの優先度を「通常」に設定
        SetThreadPriority(g_hFileNameThread,THREAD_PRIORITY_NORMAL);

        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T(""));
        RefreshGUIFont();
        AdjustListView();

        {
            TCHAR szMsg[256]={0};

            wsprintf(szMsg,_T("%d 個中 %d 個のファイル処理は正常に完了しました"),static_cast<int>(lParam),static_cast<int>(wParam));
            SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)szMsg);
        }

        g_bThread=false;
        g_bWorking=false;
        break;

    //UpdateLatestVersionThread()から
    case WM_EXIT_UPDATELATESTVERSION_THREAD:
        if(g_hUpdateLatestVersionThread!=NULL){
            DeleteCriticalSection(&csCriticalSection);
            CloseHandle(g_hUpdateLatestVersionThread);
            g_hUpdateLatestVersionThread=NULL;
        }

        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T(""));
        AdjustListView();
        g_bThread=false;
        g_bWorking=false;
        break;

    //CreateThumbnailThread()から
    case WM_EXIT_CREATETHUMBNAIL_THREAD:
        if(g_hCreateThumbnailThread!=NULL){
            DeleteCriticalSection(&csCriticalSection);
            CloseHandle(g_hCreateThumbnailThread);
            g_hCreateThumbnailThread=NULL;
        }
        //スレッドの優先度を「通常」に設定
        SetThreadPriority(g_hCreateThumbnailThread,THREAD_PRIORITY_NORMAL);

        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T(""));
        AdjustListView();
        g_bThread=false;
        g_bWorking=false;
        break;

    //ウインドウの最小サイズ制限
    case WM_GETMINMAXINFO:{
        LPMINMAXINFO lpMMInfo=(LPMINMAXINFO)lParam;
        lpMMInfo->ptMinTrackSize.x=400;
        lpMMInfo->ptMinTrackSize.y=250;
        break;
    }

    case WM_CLOSE:{
        //本当に終了するか確認する
        if(g_Config.bConfirmExit&&g_iFileCount>0){
            if(MessageBox(hWnd,_T("Ashleyを終了しますか?"),_T("終了の確認"),MB_YESNO|MB_ICONQUESTION)==IDNO)return 0;
        }

        ShowWindow(hWnd,SW_HIDE);

        //リストビューカラムの並び順を保存
        ListView_GetColumnOrderArray(g_hListView,LISTITEM_NUM,g_Config.ListViewColumn.iOrder);

        //起動時のサムネイルの設定を保存
        //「前回終了時の設定」の場合
        if(g_Config.Thumbnail.iStartup==4){
            switch(g_eThumbSize){
                case SMALL_THUMBNAIL:
                    g_Config.Thumbnail.iStartup+=STARTUP_SMALL_THUMBNAIL;
                    break;

                case NORMAL_THUMBNAIL:
                    g_Config.Thumbnail.iStartup+=STARTUP_NORMAL_THUMBNAIL;
                    break;

                case LARGE_THUMBNAIL:
                    g_Config.Thumbnail.iStartup+=STARTUP_LARGE_THUMBNAIL;
                    break;

                case NO_THUMBNAIL:
                default:
                    break;
            }
        }

        //cfgファイルに書き込む
        WritePrivateProfile(hWnd);

        //イメージリストを破棄
        ImageList_Destroy(g_hImgFileIcon);
        ImageList_Destroy(g_hImgThumbnail);
        ImageList_Destroy(hImgToolIcon);

        //フォントを破棄
        DeleteObject(hToolBarFont);
        DeleteObject(g_hDefaultItemFont);
        DeleteObject(g_hReadyItemFont);
        DeleteObject(g_hRenamedItemFont);
        DeleteObject(g_hFailedItemFont);
        DeleteObject(g_hBoldFont);
        DeleteObject(g_hNormalFont);

        //レバーを破棄
        DestroyWindow(hReBar);

        //ツールバーを破棄
        DestroyWindow(hToolBar);

        //メニューを破棄
        DestroyMenu(hMainMenu);
        hMainMenu=NULL;
        DestroyMenu(hAnalyzeMenu);
        hAnalyzeMenu=NULL;
        DestroyMenu(hUndoMenu);
        hUndoMenu=NULL;
        DestroyMenu(hThumbnailMenu);
        hThumbnailMenu=NULL;
        DestroyMenu(hContextMenu);
        hContextMenu=NULL;
        DestroyMenu(hListItemContextMenu);
        hListItemContextMenu=NULL;
        DestroyMenu(hHeaderMenu);
        hHeaderMenu=NULL;

        //構造体のメモリ解放
        if(g_lpArcFileInfo!=NULL){
            free(g_lpArcFileInfo);
            g_lpArcFileInfo=NULL;
        }

        if(DefListViewHeaderProc!=NULL){
            SetWindowLongPtr(g_hListViewHeader,GWL_WNDPROC,(LONG_PTR)DefListViewHeaderProc);
            DefListViewHeaderProc=NULL;
        }

        if(DefListViewProc!=NULL){
            SetWindowLongPtr(hToolBar,GWL_WNDPROC,(LONG_PTR)DefToolBarProc);
            DefToolBarProc=NULL;
            SetWindowLongPtr(g_hListView,GWL_WNDPROC,(LONG_PTR)DefListViewProc);
            DefListViewProc=NULL;
        }
        DestroyWindow(hWnd);
        break;
    }

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    default:
        break;
    }

    if(uMsg==WM_EXIT_ADDDROPPEDFILES_THREAD||uMsg==WM_EXIT_ADDSELECTDIRECTORY_THREAD||uMsg==WM_CREATETHUMBNAIL){
        SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T(""));

        int iItemCount=0;
        int iBeforeFileCount=static_cast<int>(wParam);
        if(g_iFileCount&&iBeforeFileCount<g_iFileCount){
            iItemCount=g_iFileCount-iBeforeFileCount;
            dprintf(_T("iItemCount=%d\n"),iItemCount);
            if(g_eThumbSize!=NO_THUMBNAIL){
                int iSize=GetThumbnailSize();

                //サムネイルの間隔を変更
                ListView_SetItemSpacing(g_hListView,
                                        (g_Config.Thumbnail.iSpacingX==-1)?g_Config.Thumbnail.iSpacingX:iSize+g_Config.Thumbnail.iSpacingX,
                                        (g_Config.Thumbnail.iSpacingY==-1)?g_Config.Thumbnail.iSpacingY:iSize+g_Config.Thumbnail.iSpacingY);
                dprintf(_T("g_Config.Thumbnail.iSpacingX=%d\ng_Config.Thumbnail.iSpacingY\ng_Config.Thumbnail.iSpacingX+iSize=%d\ng_Config.Thumbnail.iSpacingY+iSize\n"),g_Config.Thumbnail.iSpacingX,g_Config.Thumbnail.iSpacingY,g_Config.Thumbnail.iSpacingX+iSize,g_Config.Thumbnail.iSpacingY+iSize);

                g_bWorking=true;
                g_bThread=true;

                //ステータスバー上にプログレスバー作成
                HWND hStatusProgressBar=CreateProgressBarOnStatusBar(g_hInstance,g_hStatusBar,0);
                //範囲指定
                SendMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,iItemCount));
                //1Stepは1
                SendMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0);
                //ステータスバーに文字追加
                SendMessage(g_hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("サムネイル作成中..."));
                SendMessage(g_hStatusBar,SB_SETTEXT,0|2,(LPARAM)_T("Escで中止します"));
                g_hCreateThumbnailThread=CreateThumbnail(g_iFileCount,iSize,iSize,hStatusProgressBar,iBeforeFileCount);
                //スレッドの優先度を「高」に設定
                SetThreadPriority(g_hCreateThumbnailThread,THREAD_PRIORITY_HIGHEST);
            }else{
                g_bWorking=false;
            }
        }else{
            g_bWorking=false;
        }
    }

return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

//ウインドウクラスを登録
bool InitApplication(HINSTANCE hInstance,LPCTSTR lpszClassName){
    WNDCLASS wc;

    wc.style        =0;//CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc    =static_cast<WNDPROC>(WindowProc);
    wc.cbClsExtra    =0;
    wc.cbWndExtra    =0;
    wc.hInstance    =hInstance;
    wc.hIcon        =LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
    wc.hCursor        =NULL;//static_cast<HCURSOR>(LoadImage(NULL,IDC_ARROW,IMAGE_CURSOR,0,0,LR_SHARED));
    wc.hbrBackground=static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
    wc.lpszMenuName    =NULL;
    wc.lpszClassName=lpszClassName;
    return RegisterClass(&wc);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow){
    TCHAR szAppName[]=ASHLEY_VERSION;
    TCHAR szClassName[]=_T("AshleyWindowClass");
    HWND hWnd;
    MSG msg;
    HACCEL hAccel;
    //インスタンスハンドル保存
    g_hInstance=hInstance;
    InitApplication(g_hInstance,szClassName);

    //Ctrl+Aをローカルフックして、エディットコントロールの文字列を全選択できるようにする
    CCtrlAHook CtrlAHook;

    //デバッグウインドウ表示
#ifdef DEBUG
    CDebugConsole DebugConsole;
    dprintf(_T("%s\n"),ASHLEY_VERSION);
#endif

    //cfgファイルを読み込む
    ReadPrivateProfile();

    //logファイルのパスを取得
    TCHAR szBuffer[32]={0};

    path::GetExeDirectory(g_szLogFile,MAX_PATH);
    LoadString(g_hInstance,IDS_FILENAME,(LPTSTR)&szBuffer,sizeof(szBuffer)-1);
    _tcscat(g_szLogFile,_T("\\"));
    _tcscat(g_szLogFile,szBuffer);
    _tcscat(g_szLogFile,_T(".log"));

    //コマンドライン引数を取得
    int iArgc=0;//argc
    LPTSTR* lplpszArgv=NULL;//argv
    struct CommandLineOptions clOptions={0};
    lplpszArgv=CommandLineToArgvW(GetCommandLine(),&iArgc);

    if(iArgc>1){//引数がある場合
        if(lplpszArgv[1][0]==_T('/')){
            if(_tcsicmp(lplpszArgv[1],_T("/showwindow"))==0){
                //ウインドウを表示する
                clOptions.bShowWindow=true;
                dprintf(_T("/showwindow is enabled.\n"));
            }else if(_tcsicmp(lplpszArgv[1],_T("/silent"))==0){
                //進捗ダイアログを表示しない
                clOptions.bSilent=true;
                dprintf(_T("/silent is enabled.\n"));
            }else if(_tcsicmp(lplpszArgv[1],_T("/verysilent"))==0){
                //進捗/報告ダイアログを表示しない
                clOptions.bVerySilent=true;
                dprintf(_T("/verysilent is enabled.\n"));
            }
        }

        if(!clOptions.bShowWindow){
            if(clOptions.bSilent||clOptions.bVerySilent){
                if(iArgc>2)g_bNoWindow=true;
            }else{
                g_bNoWindow=true;
            }
        }else{
            clOptions.bSilent=false;
            clOptions.bVerySilent=false;
        }
    }

    if(!g_bNoWindow){
        dprintf(_T("CreateWindowEx()\n"));
        hWnd=CreateWindowEx(0,
                            szClassName,
                            szAppName,
                            WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
                            CW_USEDEFAULT,CW_USEDEFAULT,//座標
                            CW_USEDEFAULT,CW_USEDEFAULT,//サイズ
                            NULL,
                            NULL,
                            g_hInstance,
                            NULL
        );
        if(hWnd==NULL)ExitProcess(0);
        //メインウインドウハンドルを保存
        g_hMainWnd=hWnd;

        nCmdShow=(g_Config.WindowState.bMaximized)?SW_SHOWMAXIMIZED:nCmdShow;
        UpdateWindow(hWnd);
        WINDOWPLACEMENT wpl;

        //ウインドウの状態を復元
        wpl.length=sizeof(WINDOWPLACEMENT);
        wpl.rcNormalPosition.left=g_Config.WindowState.rcWindow.left;
        wpl.rcNormalPosition.top=g_Config.WindowState.rcWindow.top;
        wpl.rcNormalPosition.right=g_Config.WindowState.rcWindow.left+g_Config.WindowState.sizeWindow.cx;
        wpl.rcNormalPosition.bottom=g_Config.WindowState.rcWindow.top+g_Config.WindowState.sizeWindow.cy;
        SetWindowPlacement(hWnd,&wpl);

        //ウインドウの表示
        ShowWindow(hWnd,nCmdShow);

        //GDI+の初期化
        CGDIPlusInit GDIPlusInit;

        //アクセラレータテーブルの読み込み
        hAccel=LoadAccelerators(g_hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR));

        if(clOptions.bShowWindow){
            g_bWorking=true;//AddDirectory()対策
            for(int iIndex=2;iIndex<iArgc;iIndex++){//lplpszArgv[0]は実行ファイル名
                if(path::IsDirectory(lplpszArgv[iIndex])){
                    for(int i=0;i<SUPPORTEDFILE_COUNT;i++){
                        if(*(SupportedFile[i].pbEnable)){
                            AddDirectory(lplpszArgv[iIndex],SupportedFile[i].lpszExtension);
                        }
                    }
                }else{
                    if(IsSupportedArchive(lplpszArgv[iIndex]))AddArchiveFiles(lplpszArgv[iIndex]);
                }
            }
            g_bWorking=false;
            PostMessage(hWnd,WM_CREATETHUMBNAIL,(WPARAM)0,(LPARAM)0);
            AdjustListView(true);
        }

        while(GetMessage(&msg,NULL,0,0)){
            if(!TranslateAccelerator(hWnd,hAccel,&msg)){
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }else{
        if(path::IsBadName(g_Config.szFormat)){
            MessageBox(NULL,_T("新しいファイル名には次の文字は使えません。\n\t\\ / : , ; * ? \" < > |"),_T("新しいファイル名のフォーマット"),MB_ICONSTOP);
            return msg.wParam;
        }

        param_ProgressBarDialogProc.iArgc=iArgc;//argc
        param_ProgressBarDialogProc.lplpszArgv=lplpszArgv;//argv
        param_ProgressBarDialogProc.clOptions=clOptions;//コマンドラインオプション

        //プログレスバーダイアログ作成
        g_hProgressDlg=CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG_PROGRESS),NULL,(DLGPROC)ProgressBarDialogProc);
//        ShowWindow(g_hProgressDlg,SW_HIDE);

        SetWindowLongPtr(g_hProgressDlg,GWL_USERDATA,(LONG_PTR)&param_ProgressBarDialogProc);

        SendMessage(g_hProgressDlg,WM_SHOWPROGRESSBAR,(WPARAM)0,(LPARAM)0);
        while(GetMessage(&msg,NULL,0,0)){
            if(g_hProgressDlg&&IsDialogMessage(g_hProgressDlg,&msg))continue;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return msg.wParam;
}

Home > ソフトウェア > Ashley > Ashley130.zip/Ashley130.exe > Src > Ashley.cpp