Home > ソフトウェア > Ashley > Ashley130.zip/Ashley130.exe > Src > Function.cpp
//Function.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"Pch.h" #include"Function.h" #include"Path.h" #include"resources/resource.h" #include<objidl.h> #include<shlobj.h> #include<shlwapi.h> #include<wininet.h> //SHBrowseForFolder() #ifndef BIF_NONEWFOLDERBUTTON #define BIF_NONEWFOLDERBUTTON 0x00000200 #endif //SHAutoComplete() #ifndef SHACF_DEFAULT #define SHACF_DEFAULT 0x00000000 #define SHACF_FILESYSTEM 0x00000001 #define SHACF_URLALL (SHACF_URLHISTORY|SHACF_URLMRU) #define SHACF_URLHISTORY 0x00000002 #define SHACF_URLMRU 0x00000004 #define SHACF_USETAB 0x00000008 #define SHACF_FILESYS_ONLY 0x00000010 #define SHACF_AUTOSUGGEST_FORCE_ON 0x10000000 #define SHACF_AUTOSUGGEST_FORCE_OFF 0x20000000 #define SHACF_AUTOAPPEND_FORCE_ON 0x40000000 #define SHACF_AUTOAPPEND_FORCE_OFF 0x80000000 #endif //Function.hで宣言された以外の関数 //SHBrowseForFolder()のコールバック int CALLBACK BrowseForFolderCallbackProc(HWND hWnd,UINT uMsg,LPARAM lParam,LPARAM lpData); //ファイル保存ダイアログ bool SaveFileDialog(HWND hWnd,TCHAR* pszResult,int iLength,const TCHAR* pszFilter,const TCHAR* pszTitle); //ファイルに一行書き込む bool WriteFileLine(HANDLE hFile,LPSTR lpszLine,bool bUTF8); //バージョンファイルを元に最新版かどうか比較 int CheckLatestVersion(TCHAR* pszApplicationName,TCHAR* pszVersionFilePath,TCHAR* pszResultFileName,TCHAR* pszResultUrl); //ファイルをダウンロード bool DownloadFile(TCHAR* pszServer,TCHAR* pszFileName,TCHAR* pszUrl,HWND hStatusBar=NULL,HWND hStatusProgressBar=NULL); //一つのファイルを選択 bool OpenSingleFileDialog(HWND hWnd,TCHAR* pszResult,int iLength,const TCHAR* pszFilter,const TCHAR* pszTitle){ TCHAR szDlgErr[30]={0};//CommDlgExtendedError()用 pszResult[0]=_T('\0'); OPENFILENAME ofnOpen; ZeroMemory(&ofnOpen,sizeof(OPENFILENAME)); ofnOpen.lStructSize=sizeof(OPENFILENAME); ofnOpen.hwndOwner=hWnd; ofnOpen.lpstrFilter=pszFilter; ofnOpen.lpstrFile=pszResult; ofnOpen.nMaxFile=iLength; ofnOpen.lpstrTitle=pszTitle; ofnOpen.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST; if(GetOpenFileName(&ofnOpen)){ if(path::IsDirectory(pszResult)){ pszResult[0]=_T('\0'); return false; } }else{ DWORD dwDlgErr=CommDlgExtendedError(); if(dwDlgErr!=0){ wsprintf(szDlgErr,_T("ファイルの選択に失敗しました。\nErrCode:0x%08X"),dwDlgErr); MessageBox(hWnd,szDlgErr,NULL,MB_ICONWARNING); pszResult[0]=_T('\0'); } return false; } return true; } //ファイル保存ダイアログ bool SaveFileDialog(HWND hWnd,TCHAR* pszResult,int iLength,const TCHAR* pszFilter,const TCHAR* pszTitle){ TCHAR szDlgErr[30]={0};//CommDlgExtendedError()用 // pszResult[0]=_T('\0');<-デフォルトファイル名を有効にするためコメントアウト OPENFILENAME ofnSave; ZeroMemory(&ofnSave,sizeof(OPENFILENAME)); ofnSave.lStructSize=sizeof(OPENFILENAME); ofnSave.hwndOwner=hWnd; ofnSave.lpstrFilter=pszFilter; ofnSave.lpstrFile=pszResult; ofnSave.nMaxFile=iLength; ofnSave.lpstrTitle=pszTitle; ofnSave.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_OVERWRITEPROMPT; if(GetSaveFileName(&ofnSave)==0){ DWORD dwDlgErr=CommDlgExtendedError(); if(dwDlgErr!=0){ wsprintf(szDlgErr,_T("ファイルの選択に失敗しました。\nErrCode:0x%08X"),dwDlgErr); MessageBox(hWnd,szDlgErr,NULL,MB_ICONWARNING); pszResult[0]=_T('\0'); } return false; } return true; } int CALLBACK BrowseForFolderCallbackProc(HWND hWnd,UINT uMsg,LPARAM lParam,LPARAM lpData){ static HWND hEdit; switch(uMsg){ case BFFM_INITIALIZED:{ if(lpData){ //初期ディレクトリ設定 SendMessage(hWnd,BFFM_SETSELECTION,(WPARAM)true,(LPARAM)lpData); hEdit=FindWindowEx(hWnd,NULL,_T("Edit"),NULL); // SetWindowLongPtr(hWnd,GWL_STYLE,GetWindowLongPtr(hWnd,GWL_STYLE)^WS_THICKFRAME); if(hEdit){ //エディットコントロールにオートコンプリート機能を実装 SHAutoComplete(hEdit,SHACF_FILESYSTEM|SHACF_URLALL|SHACF_FILESYS_ONLY|SHACF_USETAB); } } break; } case BFFM_SELCHANGED:{ LPITEMIDLIST lpItemIDList=(LPITEMIDLIST)lParam; TCHAR szDirectory[MAX_PATH]={0}; //TODO:マイコンピュータを素通りしてしまう if(SHGetPathFromIDList(lpItemIDList,szDirectory)){ if(hEdit){ path::AddBackSlash(szDirectory,szDirectory); SendMessage(hEdit,WM_SETTEXT,(WPARAM)0,(LPARAM)szDirectory); } } break; } //無効なディレクトリ名であった場合 case BFFM_VALIDATEFAILED:return 1; default: break; } return 0; } //ディレクトリを選択 bool SelectDirectory(HWND hWnd,TCHAR* pResult,const TCHAR* pszTitle,const TCHAR* pszDefaultDirectory){ bool bResult=false; CoInitialize(NULL); LPTSTR lpBuffer; LPITEMIDLIST pidlRoot;//ルートディレクトリ LPITEMIDLIST lpItemIDList=NULL; LPMALLOC lpMalloc=NULL; if(FAILED(SHGetMalloc(&lpMalloc)))return false; if((lpBuffer=(LPTSTR)lpMalloc->Alloc(MAX_PATH))==NULL)return false; if(!SUCCEEDED(SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP/*CSIDL_DRIVES*/,&pidlRoot))){ lpMalloc->Free(lpBuffer); CoUninitialize(); return false; } //デスクトップのパスを取得 // TCHAR szDesktopPath[MAX_PATH]={0}; SHFILEINFO shFileInfo; ZeroMemory(&shFileInfo,sizeof(SHFILEINFO)); SHGetFileInfo((LPCTSTR)pidlRoot,0,&shFileInfo,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME|SHGFI_PIDL); // SHGetSpecialFolderPath(NULL,szDesktopPath,CSIDL_DESKTOP,false); BROWSEINFO BrowseInfo; ZeroMemory(&BrowseInfo,sizeof(BrowseInfo)); BrowseInfo.hwndOwner=hWnd; BrowseInfo.pidlRoot=pidlRoot; BrowseInfo.pszDisplayName=lpBuffer; BrowseInfo.lpszTitle=(pszTitle)?pszTitle:_T("フォルダを選択してください"); //BIF_DONTGOBELOWDOMAINを有効にすると、デスクトップ上のファイルが列挙されてしまう BrowseInfo.ulFlags=BIF_USENEWUI|BIF_NONEWFOLDERBUTTON|BIF_RETURNONLYFSDIRS/*|BIF_DONTGOBELOWDOMAIN*/|BIF_VALIDATE; BrowseInfo.lpfn=BrowseForFolderCallbackProc; BrowseInfo.lParam=reinterpret_cast<LPARAM>((pszDefaultDirectory)?pszDefaultDirectory:shFileInfo.szDisplayName);//szDesktopPath; BrowseInfo.iImage=0; lpItemIDList=SHBrowseForFolder(&BrowseInfo); if(lpItemIDList){ if(SHGetPathFromIDList(lpItemIDList,pResult)){ bResult=true; } lpMalloc->Free(lpItemIDList); } lpMalloc->Free(pidlRoot); lpMalloc->Free(lpBuffer); lpMalloc->Release(); CoUninitialize(); return bResult; } //ファイルの削除 //\0は既に追加済みとする int MoveToRecycleBin(HWND hWnd,const TCHAR* lpszPath){ int iResult=0; SHFILEOPSTRUCT ShFileOp; ZeroMemory(&ShFileOp,sizeof(SHFILEOPSTRUCT)); ShFileOp.pFrom=lpszPath; ShFileOp.hwnd=hWnd; ShFileOp.wFunc=FO_DELETE; ShFileOp.pTo=NULL; ShFileOp.fFlags=FOF_FILESONLY|FOF_ALLOWUNDO|FOF_NOCONFIRMATION|FOF_MULTIDESTFILES; ShFileOp.fAnyOperationsAborted=false; ShFileOp.hNameMappings=NULL; ShFileOp.lpszProgressTitle=NULL; iResult=SHFileOperation(&ShFileOp); iResult=ShFileOp.fAnyOperationsAborted;//削除をキャンセルした場合true return iResult; } //ショートカットを作成 //C++ではなく、Cの場合メンバlpVtblを介さなければならない //又、型REFCLSIDの宣言が異なる為、CoCreateInstance()の引数にも注意 //例えば、C++の場合はCLSID_ShellLink //Cの場合は&CLSID_ShellLink bool CreateShortcut(LPCTSTR lpszShortcutFile,LPCTSTR lpszTargetFile,LPCTSTR lpszArgs,LPCTSTR lpszDescription,LPCTSTR lpszWorkingDirectory){ bool bResult=false; //COMの初期化を行う CoInitialize(NULL); //シェルリンク用インターフェイス IShellLink *pShellLink=NULL; //ファイル保存用インターフェイス IPersistFile *pPersistFile=NULL; //IShellLinkのポインタを取得する if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&pShellLink))){ //IPersistFileのポインタを取得する if(SUCCEEDED(pShellLink->QueryInterface(IID_IPersistFile,(LPVOID*)&pPersistFile))){ //リンクパス if(SUCCEEDED(pShellLink->SetPath(lpszTargetFile))){ //実行時の引数 if(lpszArgs){ pShellLink->SetArguments(lpszArgs); } //説明文 if(lpszDescription){ pShellLink->SetDescription(lpszDescription); } //作業ディレクトリ if(lpszWorkingDirectory){ pShellLink->SetWorkingDirectory(lpszWorkingDirectory); } #ifdef _UNICODE //ショートカットファイルの保存 if(SUCCEEDED(pPersistFile->Save(lpszShortcutFile,true)))bResult=true; #else WCHAR szShortcutFileW[MAX_PATH]; if(MultiByteToWideChar(CP_ACP,0,lpszShortcutFile,-1,szShortcutFileW,MAX_PATH)>0){ //ショートカットファイルの保存 if(SUCCEEDED(pPersistFile->Save(szShortcutFileW,true)))bResult=true; } #endif //_UNICODE } pPersistFile->Release(); } pShellLink->Release(); } //COMを解放 CoUninitialize(); return bResult; } //ファイルの行数を取得 int GetFileLineCount(const TCHAR* pszFilePath){ FILE *fp; TCHAR szLine[MAX_PATH*2]={0}; int iCount=0; fp=_tfopen(pszFilePath,_T("r")); if(fp==NULL){ return 0; } while(_fgetts(szLine,ARRAY_SIZEOF(szLine),fp)!=NULL){ iCount++; } fclose(fp); return iCount; } //ファイルの先頭から指定された行まで削除 bool ShiftFile(const TCHAR* pszFilePath,int iLine){ FILE *fp,*fpTemp; TCHAR szLine[MAX_PATH*2]={0}; TCHAR szTempFilePath[MAX_PATH]={0}; int iCount=1; bool bResult=false; //ログファイルを開く fp=_tfopen(pszFilePath,_T("r")); if(fp==NULL){ return false; } //一時ファイル名作成 wsprintf(szTempFilePath,_T("%s.tmp"),pszFilePath); //一時ファイルを開く fpTemp=_tfopen(szTempFilePath,_T("w")); while(_fgetts(szLine,ARRAY_SIZEOF(szLine),fp)!=NULL){ if(iCount>iLine){ //一時ファイルに書き込む _fputts(szLine,fpTemp); } iCount++; } //ファイルを閉じる fclose(fp); fclose(fpTemp); //元のファイルを削除し、一時ファイルをリネーム if(_tremove(pszFilePath)==0){ if(_trename(szTempFilePath,pszFilePath)==0){ bResult=true; } } return bResult; } //ファイルに一行書き込む bool WriteFileLine(HANDLE hFile,LPSTR lpszLine,bool bUTF8){ if(hFile==NULL)return false; bool bResult=false; const BYTE byUTF8BOM[3]={0xef,0xbb,0xbf}; const char szCRLF[]="\r\n"; DWORD dwNumberOfBytesWrite; LARGE_INTEGER liFileSize; //UTF-8の場合先にBOMを書き込み GetFileSizeEx(hFile,&liFileSize); if(liFileSize.QuadPart==0&&bUTF8){ WriteFile(hFile,byUTF8BOM,(DWORD)sizeof(byUTF8BOM),&dwNumberOfBytesWrite,NULL); printf("WriteBOM"); } LARGE_INTEGER liDistanceToMove; liDistanceToMove.QuadPart=0; //ファイルポインタを末尾に移動 SetFilePointer(hFile,0,NULL,FILE_END); if((WriteFile(hFile,lpszLine,lstrlenA(lpszLine),&dwNumberOfBytesWrite,NULL))!=0)bResult=true; if((WriteFile(hFile,szCRLF,lstrlenA(szCRLF),&dwNumberOfBytesWrite,NULL))!=0)bResult=true; return bResult; } //ログファイル出力 bool WriteLog(const TCHAR* pszLogFile,const TCHAR* pszState,const TCHAR* pszOriginal,const TCHAR* pszRenamed,bool bUTF8){ HANDLE hFile=CreateFile(pszLogFile,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE)return false; SYSTEMTIME SystemTime; GetLocalTime(&SystemTime); bool bResult=false; char szLogA[MAX_PATH]={0}; TCHAR szLog[MAX_PATH*2]={0}; wsprintf(szLog,_T("%04d/%02d/%02d %02d:%02d:%02d,%s,%s,%s"),SystemTime.wYear,SystemTime.wMonth,SystemTime.wDay, SystemTime.wHour,SystemTime.wMinute,SystemTime.wSecond, pszState,pszOriginal,pszRenamed ); WideCharToMultiByte((bUTF8)?CP_UTF8:CP_ACP,0,szLog,-1,szLogA,MAX_PATH,NULL,NULL); bResult=WriteFileLine(hFile,szLogA,bUTF8); CloseHandle(hFile); return bResult; } //ステータスバー上にプログレスバーを作成 HWND CreateProgressBarOnStatusBar(HINSTANCE hInstance,HWND hStatusBar,int iIndex){ if(hInstance==NULL||hStatusBar==NULL)return NULL; RECT rcStatus;//ステータスバーの位置 SendMessage(hStatusBar,SB_GETRECT,(WPARAM)iIndex,(LPARAM)&rcStatus);//ステータスバーの位置を取得 //プログレスバー作成 return CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD|WS_VISIBLE, rcStatus.left, rcStatus.top, rcStatus.right, rcStatus.bottom, hStatusBar, 0, hInstance, NULL ); } //スピン+エディットコントロールの初期設定 bool InitializeSpinEditControl(HWND hSpin,HWND hEdit,int iMinimum,int iMaximum,int iCurrent){ if(hSpin==NULL||hEdit==NULL)return false; //エディットコントロールを関連付ける SendMessage(hSpin,UDM_SETBUDDY,(WPARAM)hEdit,(LPARAM)0); //最大値と最小値を設定 SendMessage(hSpin,UDM_SETRANGE32,(WPARAM)iMinimum,(LPARAM)iMaximum); //現在サイズの位置に移動 SendMessage(hSpin,UDM_SETPOS,(WPARAM)0,(LPARAM)MAKELONG((short)iCurrent,0)); return true; } //エディットボックスから数値を取得 int GetIntFromEdit(HWND hWnd,const int iMinimum,const int iMaximum){ TCHAR szNumber[10]={0}; int iResult=0; GetWindowText(hWnd,szNumber,sizeof(szNumber)-1); iResult=_ttoi(szNumber); //最小値 if(iResult<iMinimum)iResult=iMinimum; //最大値 if(iResult>iMaximum)iResult=iMaximum; return iResult; } //数値を文字列に変換してエディットボックスに入力 bool SetIntToEdit(HWND hEdit,const int iNumber){ TCHAR* pszNumber=NULL; pszNumber=(TCHAR*)malloc(GetIntLength(iNumber)*sizeof(TCHAR)+1); if(pszNumber==NULL)return false; wsprintf(pszNumber,_T("%d"),iNumber); SetWindowText(hEdit,pszNumber); free(pszNumber); pszNumber=NULL; return true; } //画面中央にダイアログを表示 void SetCenterWindow(HWND hDlg){ RECT rc; GetWindowRect(hDlg,&rc); SetWindowPos(hDlg, NULL, (GetSystemMetrics(SM_CXSCREEN)-(rc.right-rc.left))>>1, (GetSystemMetrics(SM_CYSCREEN)-(rc.bottom-rc.top))>>1, -1, -1, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE ); return; } //ツールバー内のボタンの状態を調べる bool GetStateButtonToolBar(HWND hToolBar,int iButtonId,LONG lState){ LRESULT lResult=SendMessage(hToolBar,TB_GETSTATE,(WPARAM)iButtonId,(LPARAM)0); if(lResult&lState)return true; else return false; } //エディットボックスの拡張子を除くファイル名を選択 void SelectEditExcludeExtension(HWND hEdit){ int iDotPos=0; TCHAR szFileName[MAX_PATH]={0}; GetWindowText(hEdit,szFileName,ARRAY_SIZEOF(szFileName));//エディットボックスから取得 iDotPos=path::LocateLastCharacter(szFileName,_T('.'));//'.'の位置を検索 SetFocus(hEdit);//これがないとEM_SETSELが動作しない SendMessage(hEdit,EM_SETSEL,(WPARAM)0,(LPARAM)iDotPos);//拡張子の部分を除いて選択 return; } //ファイルのバージョンを取得 void GetFileVersion(TCHAR* pszResult,const TCHAR* pszFilePath){ DWORD dwHandle; LPVOID lpBuffer=NULL; DWORD dwSize=GetFileVersionInfoSize(pszFilePath,&dwHandle); if(dwSize<=0||!(lpBuffer=GlobalAlloc(GPTR,dwSize))){ if(path::FileExists(pszFilePath)){ _tcscpy(pszResult,_T("OK ")); }else{ _tcscpy(pszResult,_T("------------")); } return; } LPVOID lpResult=NULL; UINT uiLength=0; if(GetFileVersionInfo(pszFilePath,0,dwSize,lpBuffer)){ VerQueryValue((const LPVOID)lpBuffer,_T("\\"),&lpResult,&uiLength); VS_FIXEDFILEINFO* pVSFileInfo=(VS_FIXEDFILEINFO*)lpResult; DWORD dwFileVerMS=pVSFileInfo->dwFileVersionMS; DWORD dwFileVerLS=pVSFileInfo->dwFileVersionLS; wsprintf(pszResult,_T("%ld.%02lu.%ld.%02lu"),dwFileVerMS>>16,dwFileVerMS&0xffff,dwFileVerLS>>16,dwFileVerLS&0xffff); }else{ _tcscpy(pszResult,_T("---------")); } GlobalFree(lpBuffer); return; } //XPスタイルのソートを行う int _StrCmpLogicalW(PCWSTR psz1,PCWSTR psz2){ int iResult=0; TCHAR szDllPath[MAX_PATH]={0}; typedef DWORD(WINAPI *PSTRCMPLOGICALW)(PCWSTR,PCWSTR); PSTRCMPLOGICALW pStrCmpLogicalW; GetSystemDirectory(szDllPath,MAX_PATH); _tcscat(szDllPath,_T("\\shlwapi.dll")); HMODULE hDll=LoadLibrary(szDllPath); if(hDll){ pStrCmpLogicalW=(PSTRCMPLOGICALW)GetProcAddress(hDll,"StrCmpLogicalW"); if(pStrCmpLogicalW){ iResult=pStrCmpLogicalW(psz1,psz2); } FreeLibrary(hDll); } return iResult; } //IDからめニュー内のアイテムの場所を取得 int _GetMenuPosFromID(HMENU hmenu,UINT id){ int iResult=0; TCHAR szDllPath[MAX_PATH]={0}; typedef DWORD(WINAPI *PGETMENUPOSFROMID)(HMENU,UNIT); PGETMENUPOSFROMID pGetMenuPosFromID; GetSystemDirectory(szDllPath,MAX_PATH); _tcscat(szDllPath,_T("\\shlwapi.dll")); HMODULE hDll=LoadLibrary(szDllPath); if(hDll){ pGetMenuPosFromID=(PGETMENUPOSFROMID)GetProcAddress(hDll,"GetMenuPosFromID"); if(pGetMenuPosFromID){ iResult=pGetMenuPosFromID(hmenu,id); } FreeLibrary(hDll); } return iResult; } //文字列をクリップボードにコピー bool SetClipboardText(HWND hWnd,const TCHAR* pszText,int iLength){ bool bResult=false; int iBufferSize=0; if(!OpenClipboard(hWnd))return false; iBufferSize=iLength*sizeof(TCHAR)+sizeof(TCHAR); HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,iBufferSize); if(hGlobal!=NULL){ LPVOID lpMemory=static_cast<LPVOID>(GlobalLock(hGlobal)); memcpy(lpMemory,pszText,iBufferSize); GlobalUnlock(hGlobal); EmptyClipboard(); #ifdef UNICODE if(SetClipboardData(CF_UNICODETEXT,hGlobal))bResult=true; #else if(SetClipboardData(CF_TEXT,hGlobal))bResult=true; #endif } CloseClipboard(); return bResult; } //ビジュアルスタイルが有効かどうか確認 bool IsVisualStyle(){ bool bResult=false; TCHAR szDllPath[MAX_PATH]={0}; GetSystemDirectory(szDllPath,MAX_PATH); _tcscat(szDllPath,_T("\\UxTheme.dll")); HMODULE hUxThemeDll=LoadLibrary(szDllPath); if(hUxThemeDll){ typedef bool(*ISAPPTHEMEDPROC)(); ISAPPTHEMEDPROC pIsAppThemed; pIsAppThemed=(ISAPPTHEMEDPROC)GetProcAddress(hUxThemeDll,"IsAppThemed"); if(pIsAppThemed){ bResult=pIsAppThemed(); } FreeLibrary(hUxThemeDll); } return bResult; } //背景ブラシを更新(ビジュアルスタイルが有効な際コントロールの描画がおかしくなる問題を防止) void UpdateBackgroundBrush(HWND hWnd,HBRUSH hBrush,bool bVisualStyle){ //前回のブラシを破棄 if(hBrush){ DeleteObject(hBrush); } hBrush=NULL; if(bVisualStyle){//ビジュアルスタイルが有効であれば RECT rc; GetWindowRect(hWnd,&rc); HDC hDC=GetDC(hWnd); //互換性のあるDCを作成 HDC hDCMem=CreateCompatibleDC(hDC); HBITMAP hBitmap=CreateCompatibleBitmap(hDC,rc.right-rc.left,rc.bottom-rc.top); HBITMAP hBitmapOld=(HBITMAP)(SelectObject(hDCMem,hBitmap)); //hWndにhDCMemによる描画を通知 SendMessage(hWnd,WM_PRINTCLIENT,(WPARAM)(hDCMem),(LPARAM)(PRF_ERASEBKGND|PRF_CLIENT|PRF_NONCLIENT)); //hBitmapからビットマップパターンを持つ論理ブラシを作成 hBrush=CreatePatternBrush(hBitmap); SelectObject(hDCMem,hBitmapOld); DeleteObject(hBitmap); DeleteDC(hDCMem); ReleaseDC(hWnd,hDC); } return; } //数字の桁数を取得 int GetIntLength(int iNumber){ int iResult=0; for(;iNumber!=0;iResult++)iNumber/=10; return iResult; } //16進数またはRGB表記の文字列をCOLORREF型に変換 COLORREF StringToCOLORREF(TCHAR* pszString){ if(((pszString[0]==_T('#')&&lstrlen(pszString)==7)|| (lstrlen(pszString)==6&&path::LocateFirstCharacter(pszString,_T(','))==-1))){ //16進数値 unsigned long ulResult=static_cast<unsigned long>(_tcstoul((pszString[0]==_T('#'))?pszString+1:pszString,NULL,16)); return RGB(GetBValue(ulResult),GetGValue(ulResult),GetRValue(ulResult)); }else if((pszString[0]!=_T('#')&&path::CountCharacter(pszString,_T(','))==2)){ //RGB値 int iR,iG,iB; iR=_ttoi(pszString);//r,g,bからrを取り出す pszString+=path::LocateFirstCharacter(pszString,_T(','))+1;//rとgの間の','+1に移動 iG=_ttoi(pszString);//g,bからgを取り出す pszString+=path::LocateFirstCharacter(pszString,_T(','))+1;//gとbの間の','+1に移動 iB=_ttoi(pszString);//bからbを取り出す return RGB(iR,iG,iB); } return static_cast<COLORREF>(_ttol(pszString)); } //COLORREF型を16進数表記の文字列に変換 bool COLORREFToHex(TCHAR* pszResult,COLORREF color){ wsprintf(pszResult,_T("#%02X%02X%02X"),GetRValue(color),GetGValue(color),GetBValue(color)); return true; } //COLORREF型をRGB表記の文字列に変換 bool COLORREFToRGB(TCHAR* pszResult,COLORREF color){ wsprintf(pszResult,_T("%d,%d,%d"),GetRValue(color),GetGValue(color),GetBValue(color)); return true; } //標準のGUIフォントを作成 HFONT CreateGUIFont(LPCTSTR lpszFontName,int iSize,int iStyle){ NONCLIENTMETRICS ncMetrics; LOGFONT lgFont; memset(&ncMetrics,0,sizeof(NONCLIENTMETRICS)); ncMetrics.cbSize=sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncMetrics,0); memcpy(&lgFont,&ncMetrics.lfMessageFont,sizeof(LOGFONT)); if(lstrlen(lpszFontName))_tcscpy(lgFont.lfFaceName,lpszFontName); if(iSize>0)lgFont.lfHeight=iSize; if(iStyle&SFONT_BOLD)lgFont.lfWeight=FW_BOLD; if(iStyle&SFONT_ITALIC)lgFont.lfItalic=true; if(iStyle&SFONT_UNDERLINE)lgFont.lfUnderline=true; if(iStyle&SFONT_STRIKEOUT)lgFont.lfStrikeOut=true; return CreateFontIndirect(&lgFont); } //論理フォントをコントロールに適用 void SetFont(HWND hWnd,LPCTSTR lpszFontName,int iSize,int iStyle){ HFONT hFont; HDC hDC=GetDC(hWnd); hFont=CreateGUIFont(lpszFontName,iSize,iStyle); SetBkMode(hDC,OPAQUE); SendMessage(hWnd,WM_SETFONT,(WPARAM)hFont,true); ReleaseDC(hWnd,hDC); return; } //現在のフォントサイズを取得 int GetCurrentFontSize(HWND hWnd){ TEXTMETRIC TextMetric; HDC hDC=GetDC(hWnd); SelectObject(hDC,reinterpret_cast<void*>(SendMessage(hWnd,WM_GETFONT,(WPARAM)0,(LPARAM)0))); GetTextMetrics(hDC,&TextMetric); ReleaseDC(hWnd,hDC); return TextMetric.tmHeight; } //バージョンファイルを元に最新版かどうか比較 int CheckLatestVersion(TCHAR* pszApplicationName,TCHAR* pszVersionFilePath,TCHAR* pszResultFileName,TCHAR* pszResultUrl){ TCHAR szOldVersion[256]; //現在のバージョンを取得 DWORD dwHandle; LPVOID lpBuffer=NULL; DWORD dwSize=GetFileVersionInfoSize(pszApplicationName,&dwHandle); if(dwSize<=0||!(lpBuffer=GlobalAlloc(GPTR,dwSize))){ return -1; } LPVOID lpResult=NULL; UINT uiLength=0; if(GetFileVersionInfo(pszApplicationName,0,dwSize,lpBuffer)){ VerQueryValue((const LPVOID)lpBuffer,_T("\\"),&lpResult,&uiLength); VS_FIXEDFILEINFO* pVSFileInfo=(VS_FIXEDFILEINFO*)lpResult; DWORD dwFileVerMS=pVSFileInfo->dwFileVersionMS; DWORD dwFileVerLS=pVSFileInfo->dwFileVersionLS; wsprintf(szOldVersion,_T("%ld.%lu.%ld.%lu"),dwFileVerMS>>16,dwFileVerMS&0xffff,dwFileVerLS>>16,dwFileVerLS&0xffff); } GlobalFree(lpBuffer); HINTERNET hInternet=InternetOpen(_T("Check Latest Version"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); if(hInternet==NULL)return -1; HINTERNET hUrl=InternetOpenUrl(hInternet,pszVersionFilePath,NULL,0,INTERNET_FLAG_RELOAD,0); if(hUrl==NULL){ InternetCloseHandle(hInternet); return -1; } //バージョンファイルを読み込む char szBufferA[256]; DWORD dwReadSize; InternetReadFile(hUrl,szBufferA,sizeof(szBufferA),&dwReadSize); szBufferA[dwReadSize]='\0'; InternetCloseHandle(hUrl); InternetCloseHandle(hInternet); TCHAR szNewVersion[128]={0}; TCHAR szFileName[128]={0}; TCHAR szDownUrl[128]={0}; #ifdef UNICODE wchar_t szBufferW[128]={0}; MultiByteToWideChar(CP_ACP,0,szBufferA,-1,szBufferW,(int)(sizeof(szBufferW)/sizeof(wchar_t))-1); _stscanf((const wchar_t*)&szBufferW,_T("%[^,],%[^,],%[^,]"),szNewVersion,szFileName,szDownUrl); #else _stscanf((const char*)&szBufferA,_T("%[^,],%[^,],%[^,]"),szNewVersion,szFileName,szDownUrl); #endif dprintf(_T("szNewVersion=%s\n"),szNewVersion); dprintf(_T("szFileName=%s\n"),szFileName); dprintf(_T("szDownUrl=%s\n"),szDownUrl); _tcscpy(pszResultFileName,szFileName); _tcscpy(pszResultUrl,szDownUrl); TCHAR* pszOldVersion=szOldVersion; TCHAR* pszNewVersion=szNewVersion; int iOldVersion=_ttoi(pszOldVersion); int iNewVersion=_ttoi(pszNewVersion); dprintf(_T("old=%s,ver=%s,old=%d,ver=%d\n"),pszOldVersion,pszNewVersion,iOldVersion,iNewVersion); //<0>,0,0,0をチェック if(iOldVersion<iNewVersion)return 1; for(int i=0;i<3;i++){ //0,<0>,0,0から0,0,0,<0>をチェック pszOldVersion+=path::LocateFirstCharacter(pszOldVersion,L'.')+1; pszNewVersion+=path::LocateFirstCharacter(pszNewVersion,L'.')+1; iOldVersion=_ttoi(pszOldVersion); iNewVersion=_ttoi(pszNewVersion); dprintf(_T("old=%s,ver=%s,old=%d,ver=%d\n"),pszOldVersion,pszNewVersion,iOldVersion,iNewVersion); if(iOldVersion<iNewVersion)return 1; else if(iOldVersion>iNewVersion)return 0; } return 0; } //ファイルをダウンロード bool DownloadFile(TCHAR* pszServer,TCHAR* pszFileName,TCHAR* pszUrl,HWND hStatusBar,HWND hStatusProgressBar){ HINTERNET hInternet; dprintf(_T("pszFileName=%s,pszServer=%s,pszUrl=%s\n"),pszFileName,pszServer,pszUrl); if(InternetAttemptConnect(0)!=ERROR_SUCCESS)return false; hInternet=InternetOpen(_T("Update"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); if(hInternet==NULL)return false; //サーバに接続 HINTERNET hConnect; hConnect=InternetConnect(hInternet,pszServer,INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,NULL); if(hConnect==NULL){ InternetCloseHandle(hInternet); return false; } //HTTPリクエストを作成 HINTERNET hRequest; hRequest=HttpOpenRequest(hConnect,_T("GET"),pszUrl,NULL,NULL,NULL,INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION,NULL); if(hRequest==NULL){ InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return false; } bool bResult=false; //HTTPリクエストを送信 if((bResult=HttpSendRequest(hRequest,NULL,0,NULL,0))){ long lFileSize; DWORD dwSize=sizeof(long);//4096; HANDLE hFile; char szBuffer[4096+16]; bool bProgress=false; //ファイルサイズを取得 if(HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER,&lFileSize,&dwSize,NULL)){ bProgress=true; } dprintf(_T("FileSize:%d\n"),lFileSize); //プログレスバーの設定 if(hStatusProgressBar!=NULL&&lFileSize>0){ //範囲指定 PostMessage(hStatusProgressBar,PBM_SETRANGE,(WPARAM)0,MAKELPARAM(0,100)); //1Stepは1 PostMessage(hStatusProgressBar,PBM_SETSTEP,(WPARAM)1,(LPARAM)0); } //ファイルを作成 DWORD dwDownloaded=0; hFile=CreateFile(pszFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile!=INVALID_HANDLE_VALUE){ TCHAR szMsg[128]={0}; DWORD dwByte=0; DWORD dwWritten; while(1){ InternetReadFile(hRequest,szBuffer,4096,&dwByte); if(dwByte==0)break; //ファイルの書き込み WriteFile(hFile,szBuffer,dwByte,&dwWritten,NULL); dwDownloaded+=dwByte; if(hStatusBar!=NULL){ wsprintf(szMsg,_T("%d byte"),dwDownloaded); PostMessage(hStatusBar,SB_SETTEXT,0|2,(LPARAM)szMsg); } if(hStatusProgressBar!=NULL)PostMessage(hStatusProgressBar,PBM_SETPOS,(WPARAM)int(dwDownloaded*100/lFileSize),(LPARAM)0); dprintf(_T("%d Byte Downloaded.\n"),dwDownloaded); if(!g_bWorking)break; } } FlushFileBuffers(hFile); CloseHandle(hFile); } InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return bResult; } //最新版にアップデート bool UpdateLatestVersion(HWND hWnd,HINSTANCE hInstance,HWND hStatusBar,HWND hStatusProgressBar,bool bNotFoundMessage){ TCHAR szApplicationName[MAX_PATH]={0}; if(GetModuleFileName(NULL,szApplicationName,sizeof(szApplicationName))){ PathFindFileName(szApplicationName); dprintf(_T("***Update***\n")); TCHAR szVersionFilePath[MAX_PATH]={0};//URL TCHAR szServer[128]={0}; TCHAR szFileName[128]={0}; TCHAR szUrl[256]={0}; if(hStatusBar!=NULL)PostMessage(hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("最新版を確認しています...")); //現在はwww16.atpages.jp LoadString(hInstance,IDS_SERVER,(LPTSTR)&szServer,sizeof(szServer)-1); //現在はhttp://www16.atpages.jp/rayna/Ashley/version.dat LoadString(hInstance,IDS_VERSION_FILE,(LPTSTR)&szVersionFilePath,sizeof(szVersionFilePath)-1); int iResult=CheckLatestVersion(szApplicationName,szVersionFilePath,szFileName,szUrl); if(iResult==1){ dprintf(_T("New Version found.\n")); if(hStatusBar!=NULL)PostMessage(hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("最新版が見つかりました")); int iResult=IDNO; iResult=MessageBox(hWnd,_T("最新版が公開されているようです。\n\nダウンロードしますか?"),_T("アップデート"),MB_YESNO|MB_ICONQUESTION); if(iResult==IDNO){ iResult=MessageBox(hWnd,_T("このバージョンにはとんでもないバグが含まれていて、\nえっちぃファイルを根こそぎ削除するかもしれません。\n\nダウンロードしますか?"),_T("アップデート"),MB_YESNO|MB_ICONQUESTION); } if(iResult==IDYES){ if(!SaveFileDialog(hWnd, szFileName, ARRAY_SIZEOF(szFileName)+1, _T("書庫ファイル (*.zip)\0*.zip\0\0"), _T("保存先を選択してください"))){ return false; } if(hStatusBar!=NULL)PostMessage(hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("ダウンロードしています...")); if(!DownloadFile(szServer,szFileName,szUrl,hStatusBar,hStatusProgressBar)){ MessageBox(hWnd,_T("ファイルのダウンロードに失敗しました。"),_T("アップデート"),MB_ICONSTOP); return false; } if(hStatusBar!=NULL)PostMessage(hStatusBar,SB_SETTEXT,0|1,(LPARAM)_T("ダウンロードが完了しました")); } }else if(iResult==0){ if(bNotFoundMessage){ if(IDYES==MessageBox(hWnd,_T("最新版を使用しています。\n\nどうやら作者はバグにまだ気付いていないようです。\n作者に報告しますか?"),_T("アップデート"),MB_YESNO|MB_ICONQUESTION)){ //ホームページにアクセス TCHAR szBuffer[64]={0}; LoadString(hInstance,IDS_URL,(LPTSTR)&szBuffer,sizeof(szBuffer)-1); ShellExecute(NULL,_T("open"),szBuffer,NULL,NULL,SW_SHOWNORMAL); } } }else{ MessageBox(hWnd,_T("エラーが発生したため、バージョンチェックを行うことが出来ません。\nインターネットに接続されているか確認して下さい。"),_T("アップデート"),MB_ICONSTOP); } } return true; } //文字列をすべて置換する void AllReplace(TCHAR* pszDest,const TCHAR* pszSrc,const TCHAR* pszPattern,const TCHAR* pszReplace){ const tstring strSrc(pszSrc); const tstring strPattern(pszPattern); const tstring strReplace(pszReplace); tstring strResult; tstring::size_type iBeforePosition=0; tstring::size_type iPosition=0; tstring::size_type iLength=strPattern.size(); while((iPosition=strSrc.find(strPattern,iPosition))!=tstring::npos){ strResult.append(strSrc,iBeforePosition,iPosition-iBeforePosition); strResult.append(strReplace); iPosition+=iLength; iBeforePosition=iPosition; } strResult.append(strSrc,iBeforePosition,strSrc.size()-iBeforePosition); _tcscpy(pszDest,strResult.c_str()); return; } //四角形を指定した純色で塗りつぶす void FillSolidRect(HDC hDC,RECT *prcRect,COLORREF clColorRef){ SetBkColor(hDC,clColorRef); ExtTextOut(hDC,0,0,ETO_OPAQUE,prcRect,NULL,0,NULL); return; }
Home > ソフトウェア > Ashley > Ashley130.zip/Ashley130.exe > Src > Function.cpp