From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- miranda-wine/src/modules/srfile/fileexistsdlg.c | 331 ++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 miranda-wine/src/modules/srfile/fileexistsdlg.c (limited to 'miranda-wine/src/modules/srfile/fileexistsdlg.c') diff --git a/miranda-wine/src/modules/srfile/fileexistsdlg.c b/miranda-wine/src/modules/srfile/fileexistsdlg.c new file mode 100644 index 0000000..73d2bf3 --- /dev/null +++ b/miranda-wine/src/modules/srfile/fileexistsdlg.c @@ -0,0 +1,331 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "commonheaders.h" +#include +#include +#include +#include "file.h" + +static void SetControlToUnixTime(HWND hwndDlg, UINT idCtrl, time_t unixTime) +{ + LARGE_INTEGER liFiletime; + FILETIME filetime; + SYSTEMTIME st; + char szTime[64],szDate[64],szOutput[128]; + + liFiletime.QuadPart=(BIGI(11644473600)+(__int64)unixTime)*10000000; + filetime.dwHighDateTime=liFiletime.HighPart; + filetime.dwLowDateTime=liFiletime.LowPart; + FileTimeToSystemTime(&filetime,&st); + GetTimeFormatA(LOCALE_USER_DEFAULT,0,&st,NULL,szTime,SIZEOF(szTime)); + GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,szDate,SIZEOF(szDate)); + wsprintfA(szOutput,"%s %s",szDate,szTime); + SetDlgItemTextA(hwndDlg,idCtrl,szOutput); +} + +#define C_CONTEXTMENU 0 +#define C_PROPERTIES 1 +// not defined in VC++ 6.0 SE +#ifndef CMF_EXTENDEDVERBS +#define CMF_EXTENDEDVERBS 0x00000100 +#endif +static void DoAnnoyingShellCommand(HWND hwnd,const char *szFilename,int cmd,POINT *ptCursor) +{ + IMalloc *pShellMalloc; + + OleInitialize(NULL); + if(SHGetMalloc(&pShellMalloc)==NOERROR) { + IShellFolder *pDesktopFolder; + if(SHGetDesktopFolder(&pDesktopFolder)==NOERROR) { + WCHAR wszFilename[MAX_PATH]; + ITEMIDLIST *pCurrentIdl; + MultiByteToWideChar(CP_ACP,0,szFilename,-1,wszFilename,SIZEOF(wszFilename)); + if(pDesktopFolder->lpVtbl->ParseDisplayName(pDesktopFolder,NULL,NULL,wszFilename,NULL,&pCurrentIdl,NULL)==NOERROR) { + if(pCurrentIdl->mkid.cb) { + ITEMIDLIST *pidl,*pidlNext,*pidlFilename; + IShellFolder *pFileFolder; + + for(pidl=pCurrentIdl;;) { + pidlNext=(ITEMIDLIST*)((PBYTE)pidl+pidl->mkid.cb); + if(pidlNext->mkid.cb==0) { + pidlFilename=pShellMalloc->lpVtbl->Alloc(pShellMalloc,pidl->mkid.cb+sizeof(pidl->mkid.cb)); + CopyMemory(pidlFilename,pidl,pidl->mkid.cb+sizeof(pidl->mkid.cb)); + pidl->mkid.cb=0; + break; + } + pidl=pidlNext; + } + if(pDesktopFolder->lpVtbl->BindToObject(pDesktopFolder,pCurrentIdl,NULL,&IID_IShellFolder,&pFileFolder)==NOERROR) { + IContextMenu *pContextMenu; + if(pFileFolder->lpVtbl->GetUIObjectOf(pFileFolder,NULL,1,&pidlFilename,&IID_IContextMenu,NULL,&pContextMenu)==NOERROR) { + switch(cmd) { + case C_PROPERTIES: + { CMINVOKECOMMANDINFO ici={0}; + ici.cbSize=sizeof(ici); + ici.hwnd=hwnd; + ici.lpVerb="properties"; + ici.nShow=SW_SHOW; + pContextMenu->lpVtbl->InvokeCommand(pContextMenu,&ici); + break; + } + case C_CONTEXTMENU: + { HMENU hMenu; + hMenu=CreatePopupMenu(); + if(SUCCEEDED(pContextMenu->lpVtbl->QueryContextMenu(pContextMenu,hMenu,0,1000,65535,(GetKeyState(VK_SHIFT)&0x8000?CMF_EXTENDEDVERBS:0)|CMF_NORMAL))) { + int cmd; + cmd=TrackPopupMenu(hMenu,TPM_RETURNCMD,ptCursor->x,ptCursor->y,0,hwnd,NULL); + if(cmd) { + CMINVOKECOMMANDINFO ici={0}; + ici.cbSize=sizeof(ici); + ici.hwnd=hwnd; + ici.lpVerb=MAKEINTRESOURCEA(cmd-1000); + ici.nShow=SW_SHOW; + pContextMenu->lpVtbl->InvokeCommand(pContextMenu,&ici); + } + } + DestroyMenu(hMenu); + break; + } + } + pContextMenu->lpVtbl->Release(pContextMenu); + } + pFileFolder->lpVtbl->Release(pFileFolder); + } + pShellMalloc->lpVtbl->Free(pShellMalloc,pidlFilename); + } + pShellMalloc->lpVtbl->Free(pShellMalloc,pCurrentIdl); + } + pDesktopFolder->lpVtbl->Release(pDesktopFolder); + } + pShellMalloc->lpVtbl->Release(pShellMalloc); + } + OleUninitialize(); +} + +static WNDPROC pfnIconWindowProc; +static LRESULT CALLBACK IconCtrlSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_LBUTTONDBLCLK: + ShellExecuteA(hwnd,NULL,((PROTOFILETRANSFERSTATUS*)GetWindowLong(GetParent(hwnd),GWL_USERDATA))->currentFile,NULL,NULL,SW_SHOW); + break; + case WM_RBUTTONUP: + { POINT pt; + pt.x=(short)LOWORD(lParam); pt.y=(short)HIWORD(lParam); + ClientToScreen(hwnd,&pt); + DoAnnoyingShellCommand(hwnd,((PROTOFILETRANSFERSTATUS*)GetWindowLong(GetParent(hwnd),GWL_USERDATA))->currentFile,C_CONTEXTMENU,&pt); + return 0; + } + } + return CallWindowProc(pfnIconWindowProc,hwnd,msg,wParam,lParam); +} + +struct loadiconsstartinfo { + HWND hwndDlg; + char *szFilename; +}; +void __cdecl LoadIconsAndTypesThread(struct loadiconsstartinfo *info) +{ + SHFILEINFOA fileInfo; + + OleInitialize(NULL); + if(SHGetFileInfoA(info->szFilename,0,&fileInfo,sizeof(fileInfo),SHGFI_TYPENAME|SHGFI_ICON|SHGFI_LARGEICON)) { + char *pszExtension,*pszFilename; + char szExtension[64]; + char szIconFile[MAX_PATH]; + + pszFilename=strrchr(info->szFilename,'\\'); + if(pszFilename==NULL) pszFilename=info->szFilename; + pszExtension=strrchr(pszFilename,'.'); + if(pszExtension) lstrcpynA(szExtension,pszExtension+1,SIZEOF(szExtension)); + else {pszExtension="."; szExtension[0]='\0';} + CharUpperA(szExtension); + if(fileInfo.szTypeName[0]=='\0') + wsprintfA(fileInfo.szTypeName,Translate("%s File"),szExtension); + SetDlgItemTextA(info->hwndDlg,IDC_EXISTINGTYPE,fileInfo.szTypeName); + SetDlgItemTextA(info->hwndDlg,IDC_NEWTYPE,fileInfo.szTypeName); + SendDlgItemMessage(info->hwndDlg,IDC_EXISTINGICON,STM_SETICON,(WPARAM)fileInfo.hIcon,0); + szIconFile[0]='\0'; + if(!lstrcmpA(szExtension,"EXE")) { + SRFile_GetRegValue(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons","2",szIconFile,SIZEOF(szIconFile)); + } + else { + char szTypeName[MAX_PATH]; + if(SRFile_GetRegValue(HKEY_CLASSES_ROOT,pszExtension,NULL,szTypeName,SIZEOF(szTypeName))) { + lstrcatA(szTypeName,"\\DefaultIcon"); + if(SRFile_GetRegValue(HKEY_CLASSES_ROOT,szTypeName,NULL,szIconFile,SIZEOF(szIconFile))) { + if(strstr(szIconFile,"%1")) + SRFile_GetRegValue(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons","0",szIconFile,SIZEOF(szIconFile)); + else szIconFile[0]='\0'; + } + } + } + if(szIconFile[0]) { + int iconIndex; + HICON hIcon; + char *pszComma=strrchr(szIconFile,','); + if(pszComma==NULL) iconIndex=0; + else {iconIndex=atoi(pszComma+1); *pszComma='\0';} + hIcon=ExtractIconA(GetModuleHandle(NULL),szIconFile,iconIndex); + if(hIcon) fileInfo.hIcon=hIcon; + } + SendDlgItemMessage(info->hwndDlg,IDC_NEWICON,STM_SETICON,(WPARAM)fileInfo.hIcon,0); + } + OleUninitialize(); + mir_free(info->szFilename); + mir_free(info); +} + +BOOL CALLBACK DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PROTOFILETRANSFERSTATUS *fts; + + fts=(PROTOFILETRANSFERSTATUS*)GetWindowLong(hwndDlg,GWL_USERDATA); + switch(msg) { + case WM_INITDIALOG: + { TCHAR szSize[64]; + struct _stat statbuf; + struct loadiconsstartinfo *lisi; + HWND hwndFocus; + + SetPropA(hwndDlg,"Miranda.Preshutdown",HookEventMessage(ME_SYSTEM_PRESHUTDOWN,hwndDlg,M_PRESHUTDOWN)); + + TranslateDialogDefault(hwndDlg); + fts=(PROTOFILETRANSFERSTATUS*)mir_alloc(sizeof(PROTOFILETRANSFERSTATUS)); + CopyProtoFileTransferStatus(fts,(PROTOFILETRANSFERSTATUS*)lParam); + SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)fts); + SetDlgItemTextA(hwndDlg,IDC_FILENAME,fts->currentFile); + SetControlToUnixTime(hwndDlg,IDC_NEWDATE,fts->currentFileTime); + GetSensiblyFormattedSize(fts->currentFileSize,szSize,SIZEOF(szSize),0,1,NULL); + SetDlgItemText(hwndDlg,IDC_NEWSIZE,szSize); + + pfnIconWindowProc=(WNDPROC)SetWindowLong(GetDlgItem(hwndDlg,IDC_EXISTINGICON),GWL_WNDPROC,(LONG)IconCtrlSubclassProc); + + hwndFocus=GetDlgItem(hwndDlg,IDC_RESUME); + if(_stat(fts->currentFile,&statbuf)==0) { + SetControlToUnixTime(hwndDlg,IDC_EXISTINGDATE,statbuf.st_mtime); + GetSensiblyFormattedSize(statbuf.st_size,szSize,SIZEOF(szSize),0,1,NULL); + SetDlgItemText(hwndDlg,IDC_EXISTINGSIZE,szSize); + if(statbuf.st_size>(int)fts->currentFileSize) { + EnableWindow(GetDlgItem(hwndDlg,IDC_RESUME),FALSE); + hwndFocus=GetDlgItem(hwndDlg,IDC_OVERWRITE); + } + } + lisi=(struct loadiconsstartinfo*)mir_alloc(sizeof(struct loadiconsstartinfo)); + lisi->hwndDlg=hwndDlg; + lisi->szFilename=mir_strdup(fts->currentFile); + //can be a little slow, so why not? + forkthread(LoadIconsAndTypesThread,0,lisi); + SetFocus(hwndFocus); + SetWindowLong(hwndFocus,GWL_STYLE,GetWindowLong(hwndFocus,GWL_STYLE)|BS_DEFPUSHBUTTON); + return FALSE; + } + case WM_COMMAND: + { PROTOFILERESUME pfr={0}; + switch(LOWORD(wParam)) { + case IDC_OPENFILE: + ShellExecuteA(hwndDlg,NULL,fts->currentFile,NULL,NULL,SW_SHOW); + return FALSE; + case IDC_OPENFOLDER: + { char szFile[MAX_PATH]; + char *pszLastBackslash; + lstrcpynA(szFile,fts->currentFile,SIZEOF(szFile)); + pszLastBackslash=strrchr(szFile,'\\'); + if(pszLastBackslash) *pszLastBackslash='\0'; + ShellExecuteA(hwndDlg,NULL,szFile,NULL,NULL,SW_SHOW); + return FALSE; + } + case IDC_PROPERTIES: + DoAnnoyingShellCommand(hwndDlg,fts->currentFile,C_PROPERTIES,NULL); + return FALSE; + case IDC_RESUME: + pfr.action=FILERESUME_RESUME; + break; + case IDC_RESUMEALL: + pfr.action=FILERESUME_RESUMEALL; + break; + case IDC_OVERWRITE: + pfr.action=FILERESUME_OVERWRITE; + break; + case IDC_OVERWRITEALL: + pfr.action=FILERESUME_OVERWRITEALL; + break; + case IDC_SAVEAS: + { OPENFILENAMEA ofn={0}; + char filter[512],*pfilter; + char str[MAX_PATH]; + + lstrcpynA(str,fts->currentFile,SIZEOF(str)); + ofn.lStructSize=OPENFILENAME_SIZE_VERSION_400; + ofn.hwndOwner=hwndDlg; + ofn.Flags=OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY; + strcpy(filter,Translate("All Files")); + strcat(filter," (*)"); + pfilter=filter+strlen(filter)+1; + strcpy(pfilter,"*"); + pfilter=pfilter+strlen(pfilter)+1; + *pfilter='\0'; + ofn.lpstrFilter=filter; + ofn.lpstrFile=str; + ofn.nMaxFile=SIZEOF(str); + ofn.nMaxFileTitle=MAX_PATH; + if(!GetSaveFileNameA(&ofn)) break; + pfr.szFilename=mir_strdup(str); + pfr.action=FILERESUME_RENAME; + break; + } + case IDC_SKIP: + pfr.action=FILERESUME_SKIP; + break; + case IDCANCEL: + pfr.action=FILERESUME_CANCEL; + break; + default: + return FALSE; + } + { PROTOFILERESUME *pfrCopy; + pfrCopy=(PROTOFILERESUME*)mir_alloc(sizeof(pfr)); + CopyMemory(pfrCopy,&pfr,sizeof(pfr)); + PostMessage(GetParent(hwndDlg),M_FILEEXISTSDLGREPLY,(WPARAM)mir_strdup(fts->currentFile),(LPARAM)pfrCopy); + DestroyWindow(hwndDlg); + } + break; + } + case WM_CLOSE: + PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDCANCEL,BN_CLICKED),(LPARAM)GetDlgItem(hwndDlg,IDCANCEL)); + break; + case M_PRESHUTDOWN: + { + PostMessage(hwndDlg,WM_CLOSE,0,0); + break; + } + case WM_DESTROY: + UnhookEvent(GetPropA(hwndDlg,"Miranda.Preshutdown")); // GetProp() will return NULL if it couldnt find anything + DestroyIcon((HICON)SendDlgItemMessage(hwndDlg,IDC_EXISTINGICON,STM_GETICON,0,0)); + DestroyIcon((HICON)SendDlgItemMessage(hwndDlg,IDC_NEWICON,STM_GETICON,0,0)); + FreeProtoFileTransferStatus(fts); + mir_free(fts); + break; + } + return FALSE; +} -- cgit v1.2.3