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(¶m_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,¶m_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(¶m_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,¶m_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,¶m_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(¶m_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,¶m_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(¶m_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,¶m_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(¶m_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,¶m_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)¶m_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