C++ ATL + WTL 选择文件
1 #include "stdafx.h" 2 #include "CStringHelper.h" 3 #include "AFileEngine.h" 4 #include "CFilePacket.h" 5 #include <comdef.h> 6 #pragma comment(lib,"Ws2_32.lib") 7 #include <vector> 8 9 void ExecuteCallBack(Json::Value iResponse,Json::FastWriter iWriter,VARIANT lpCallBack); 10 11 const float KBCount = 1024; 12 const float MBCount = KBCount * 1024; 13 const float GBCount = MBCount * 1024; 14 const DWORD dwBlockBufferSize = 128 * 1024; 15 16 void DoEvent(void); 17 18 void DoEvent(void) 19 { 20 MSG msg; 21 while(PeekMessage(&msg, 22 (HWND)NULL,0,0,PM_REMOVE)) { 23 TranslateMessage(&msg); 24 DispatchMessage(&msg); 25 } 26 } 27 28 typedef struct 29 { 30 SOCKET socket; 31 VARIANT callback; 32 const char *buffer; 33 int len; 34 } uParam,*sParam; 35 36 DWORD WINAPI AsyncThreadingWork(PVOID pParam); 37 38 DWORD WINAPI AsyncThreadingWork(PVOID pParam) 39 { 40 sParam pa; 41 pa = (sParam)pParam; 42 43 std::vector<char> vec; 44 vec.insert(vec.end(),pa->buffer,pa->buffer+pa-len); 45 46 DWORD dwBytesOfSend = 0; 47 48 while(vec.size() > 0) { 49 if(vec.size() > 1024) 50 dwBytesOfSend = send(pa->socket,vec.data(),1024,0); 51 else 52 dwBytesOfSend = send(pa->socket,vec.data(),vec.size(),0); 53 54 vec.erase(vec.begin(),vec.begin() + dwBytesOfSend); 55 56 if(dwBytesOfSend == SOCKET_ERROR) { 57 return dwBytesOfSend; 58 } 59 } 60 61 return dwBytesOfSend; 62 } 63 64 // 选择文件对话框 65 STDMETHODDIMP CAFileEngine::OpenFileDialog(VARIANT lpOptions,VARIANT lpCallback) 66 { 67 // 初始化JSONCPP组件 68 Json::Reader iReader; 69 Json::Value iOptions,iResponse; 70 Json::FastWriter iWriter; 71 72 CString cso(lpOptions); 73 74 try 75 { 76 if(!iReader.parse(WC2UT(cso),iOptions,false)) { 77 iResponse["event"] = "error"; 78 iResponse["code"] = -1; 79 iResponse["message"] = iReader.getFormatedErrorMessage().c_str(); 80 ExecuteCallBack(iResponse,iWriter,lpCallback); 81 return S_OK; 82 } else { 83 // 替换文件列表 84 CString strFilter(iOptions["FileType"].asCString()); 85 86 DWORD dwFlags = 0L; 87 88 if(iOptions["Maximum"].asUInt() == 1) 89 { 90 dwFlags = OFN_FILEMUSTEXIST | OFN_READONLY | OFN_HIDERREADONLY; 91 92 CFileDialog mDialog(TRUE,NULL,NULL,dwFlags,strFilter); 93 94 if(mDialog.DoModal() == IDOK) { 95 Json::Value item; 96 97 CString str(mDialog.m_szFileName); 98 99 // 文件扩展名获取 100 CString extension(PathFindExtension(mDialog.m_szFileName)); 101 extension.Replace(L".",NULL); 102 103 // 计算文件自定义的MD5 104 // 先要读取出文件的最后写入时间 105 WIN32_FIND_DATA fData; 106 CString mAttribute; 107 SYSTEMTIME mTime,mUtc; 108 HANDLE hr = FindFirstFile(mDialog.m_szFileName,&fData); 109 if(!FIleTimeToSystemTime(&fData,ftLastWriterTime,&mUtc)) { 110 iResponse["event"] = "error"; 111 iResponse["code"] = static_cast<UINT>(GetLastError()); 112 iResponse["message"] = "系统权限不足!"; 113 ExecuteCallBack(iResponse,iWriter,lpCallback); 114 return S_OK; 115 } 116 117 if(!SystemTimeToTzSpecificLocalTime(NULL,&mUtc,&mTime)) { 118 iResponse["event"] = "error"; 119 iResponse["code"] = static_cast<UINT>(GetLastError()); 120 iResponse["message"] = "系统权限不足!"; 121 ExecuteCallBack(iResponse,iWriter,lpCallback); 122 return S_OK; 123 } 124 125 __int64 ulFileSize = static_cast<__int64>(static_cast<__int64>(fData.nFileSizeHigh) << 32) + static_cast<__int64>(fData.nFileSizeLow); 126 127 mAttribute.Format(L"%s%d%d%d%d%d%d%lld", 128 str,mTime.wYear,mTime.wMonth,mTime.wDay, 129 mTime.wHour,mTime.wMinute,mTime.wSecond, 130 static_cast<UINT64>(ulFileSize)); 131 132 item["ID"] = 0; 133 item["Ptah"] = WC2UT(str); 134 item["Title"] = WC2UT(str); 135 item["MD5"] = WC2UT(MD5((BYTE*)mAttribute.GetBuffer(mAttribute.GetLength()),mAttribute.GetLength())); 136 item["Block"] = static_cast<__int64>(ulFileSize % (128*1024) > 0 ? ulFileSize / (128*1024) + 1 : ulFileSize / (128*1024)); 137 item["Extension"] = WC2UT(extension); 138 item["Length"] = static_cast<__int64>(ulFileSize); 139 140 FindClose(hr); 141 mAttribute.ReleaseBuffer(); 142 iResponse["data"].append(item); 143 CloseHandle(mDialog); 144 145 // 清理缓冲 146 strFilter.ReleaseBuffer(); 147 str.ReleaseBuffer(); 148 iResponse["event"] = "succss"; 149 iResponse["code"] = 0; 150 iResponse["message"] = "文件选择成功!"; 151 ExecuteCallBack(iResponse,iWriter,lpCallback); 152 return S_OK; 153 } 154 } 155 156 if(iOptions["Maximum"].asUInt() > 1) 157 dwFlags = OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_READONLY | OFN_HIDERREADONLY; 158 else { 159 iResponse["event"] = "error"; 160 iResponse["code"] = -1; 161 iResponse["message"] = "错误的参数配置!"; 162 ExecuteCallBack(iResponse,iWriter,lpCallback); 163 return S_OK; 164 } 165 166 CMultiFileDialog dialog(NULL,NULL,dwFlags,strFilter,NULL); 167 dialog.m_ofn.nMaxFile = (DWORD)iOptions["Maximum"].asUInt() * MAX_PATH; 168 dialog.m_ofn.lpstrFile= new TCHAR[dialog.m_ofn.nMaxFile]; 169 170 ZeroMemory( 171 dialog.m_ofn.lpstrFile, 172 sizeof(TCHAR) * dialog.m_ofn.nMaxFile); 173 174 iResponse["event"] = "succss"; 175 iResponse["code"] = 0; 176 iResponse["message"] = "文件选择成功!"; 177 178 if(dialog.DoModal() == IDOK) { 179 Json::Value item; 180 UINT nMaximum = 0; 181 CString strPath; 182 TCHAR szChar[MAX_PATH]; 183 dialog.GetDirectory(szChar,MAX_PATH); 184 strPath = CString(szChar); 185 186 CString str = dialog.GetFirstFileName(); 187 188 while(!str.IsEmpty()) { 189 if(nMaximum >= static_cast<UINT>(iOptions["Maximum"].asUInt())) { 190 iResponse["event"] = "error"; 191 iResponse["code"] = -1; 192 iResponse["message"] = "文件超过最大数量限制!"; 193 ExecuteCallBack(iResponse,iWriter,lpCallback); 194 return S_OK; 195 } 196 197 // 拼接文件名称 198 CString mFileName; 199 mFileName.Format(L"%s\\%s",strPath,str); 200 // 扩展名获取 201 CString extension(PathFindExtension(mFileName)); 202 extension.Replace(L".",NULL); 203 204 // 计算文件自定义的MD5 205 // 先要读取出文件的最后写入时间 206 WIN32_FIND_DATA fData; 207 CString mAttribute; 208 SYSTEMTIME mTime,mUtc; 209 HANDLE hr = FindFirstFile(mDialog.m_szFileName,&fData); 210 if(!FIleTimeToSystemTime(&fData,ftLastWriterTime,&mUtc)) { 211 iResponse["event"] = "error"; 212 iResponse["code"] = static_cast<UINT>(GetLastError()); 213 iResponse["message"] = "系统权限不足!"; 214 ExecuteCallBack(iResponse,iWriter,lpCallback); 215 return S_OK; 216 } 217 218 if(!SystemTimeToTzSpecificLocalTime(NULL,&mUtc,&mTime)) { 219 iResponse["event"] = "error"; 220 iResponse["code"] = static_cast<UINT>(GetLastError()); 221 iResponse["message"] = "系统权限不足!"; 222 ExecuteCallBack(iResponse,iWriter,lpCallback); 223 return S_OK; 224 } 225 226 __int64 ulFileSize = static_cast<__int64>(static_cast<__int64>(fData.nFileSizeHigh) << 32) + static_cast<__int64>(fData.nFileSizeLow); 227 228 mAttribute.Format(L"%s%d%d%d%d%d%d%lld", 229 str,mTime.wYear,mTime.wMonth,mTime.wDay, 230 mTime.wHour,mTime.wMinute,mTime.wSecond, 231 static_cast<UINT64>(ulFileSize)); 232 233 item["ID"] = 0; 234 item["Ptah"] = WC2UT(str); 235 item["Title"] = WC2UT(str); 236 item["MD5"] = WC2UT(MD5((BYTE*)mAttribute.GetBuffer(mAttribute.GetLength()),mAttribute.GetLength())); 237 item["Block"] = static_cast<__int64>(ulFileSize % (128*1024) > 0 ? ulFileSize / (128*1024) + 1 : ulFileSize / (128*1024)); 238 item["Extension"] = WC2UT(extension); 239 item["Length"] = static_cast<__int64>(ulFileSize); 240 241 FindClose(hr); 242 mAttribute.ReleaseBuffer(); 243 iResponse["data"].append(item); 244 nMaximum++; 245 } 246 247 CloseHandle(dialog); 248 // 清理缓冲 249 strFilter.ReleaseBuffer(); 250 str.ReleaseBuffer(); 251 ExecuteCallBack(iResponse,iWriter,lpCallback); 252 return S_OK; 253 } 254 } 255 } 256 catch(_com_error e) 257 { 258 iResponse["event"] = "error"; 259 iResponse["code"] = -1; 260 iResponse["message"] = WC2UT(CString(e.ErrorMessage())).c_str(); 261 ExecuteCallBack(iResponse,iWriter,lpCallback); 262 return S_OK; 263 } 264 } 265 266 // Socket参数配置 267 SOCKET m_socket; 268 WORD m_version; 269 WSADATA m_wsaData; 270 int nZero = 0; 271 DWORD dwSpeed = 0; 272 int dwCurrentIndex = 0; 273 274 void ExecuteCallBack(Json::Value iResponse,Json::FastWriter iWriter,VARINAT lpCallback) { 275 CComPtr<IDispatch> cbResponse; 276 277 if(lpCallBack.vt == VT_DISPATCH) { 278 cbResponse = lpCallBck.pdispVal; 279 } else { 280 return; 281 } 282 283 CComVariant comParams[1]; 284 comParams[0] = iWriter.write(iReponse).c_str(); 285 DISPPARAMS params = { comParams,NULL,1,0 }; 286 287 if(cbResponse) { 288 cbResponse->Invoke( 289 NULL, 290 IID_NULL, 291 LOCALE_USER_DEFAULT, 292 DISPATCH_METHOD, 293 ¶ms, 294 NULL,NULL,NULL); 295 } 296 }