C++ ATL + WTL 选择文件

2023-07-29,,

  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 &params,
294 NULL,NULL,NULL);
295 }
296 }

C++ ATL + WTL 选择文件的相关教程结束。

《C++ ATL + WTL 选择文件.doc》

下载本文的Word格式文档,以方便收藏与打印。