├── .gitattributes
├── Doc
├── 如何编译并在新项目中使用curl.txt
└── 自动在线升级源码.txt
├── README.md
└── Src
├── .vs
└── AutoUpdate
│ └── v14
│ └── .suo
├── AutoUpdate.cpp
├── AutoUpdate.h
├── AutoUpdate.rc
├── AutoUpdate.sln
├── AutoUpdate.vcxproj
├── AutoUpdate.vcxproj.filters
├── AutoUpdateDlg.cpp
├── AutoUpdateDlg.h
├── FileMD5.cpp
├── HttpClient.cpp
├── HttpClient.h
├── Include
├── curl
│ ├── curl.h
│ ├── curlver.h
│ ├── easy.h
│ ├── mprintf.h
│ ├── multi.h
│ ├── stdcheaders.h
│ ├── system.h
│ └── typecheck-gcc.h
└── jsoncpp
│ ├── allocator.h
│ ├── assertions.h
│ ├── autolink.h
│ ├── config.h
│ ├── features.h
│ ├── forwards.h
│ ├── json.h
│ ├── reader.h
│ ├── value.h
│ ├── version.h
│ └── writer.h
├── InternetGetFile.cpp
├── InternetGetFile.h
├── JsonParser.cpp
├── JsonParser.h
├── Lib
├── curl
│ └── libcurl.lib
└── jsoncpp
│ └── lib_json.lib
├── Md5.cpp
├── Md5.h
├── MultiLanguage.h
├── RButton.cpp
├── RButton.h
├── RDialog.cpp
├── RDialog.h
├── RMessageBox.cpp
├── RMessageBox.h
├── Release
├── AutoUpdate.exe
├── AutoUpdate.res
├── DelRegistry.exe
├── ImageTuner.exe
├── InitRegistry.exe
├── MyBrowser.exe
├── UpdateConfig-Full.ini
├── UpdateConfig.ini
├── UsbDll.dll
├── UsbPhone.ini
├── getcpu.exe
├── machineinf.bat
├── myie.ini
└── shdoclc.dll
├── StdAfx.cpp
├── StdAfx.h
├── UISkinManager.cpp
├── UISkinManager.h
├── UpdateThread.cpp
├── UpdateThread.h
├── res
├── AutoUpdate.ico
├── AutoUpdate.rc2
├── button01.bmp
├── button_system_control.bmp
└── title01.bmp
└── resource.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/Doc/如何编译并在新项目中使用curl.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Doc/如何编译并在新项目中使用curl.txt
--------------------------------------------------------------------------------
/Doc/自动在线升级源码.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Doc/自动在线升级源码.txt
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AutoUpdate
2 |
3 | 一个在线升级程序,Visual C++编写
4 |
5 | (1) 请使用vs2015编译
6 |
7 | (2) 升级配置文件编写请使用viewfileinfo程序提取文件信息
8 |
9 |
--------------------------------------------------------------------------------
/Src/.vs/AutoUpdate/v14/.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/.vs/AutoUpdate/v14/.suo
--------------------------------------------------------------------------------
/Src/AutoUpdate.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // AutoUpdate.cpp : Defines the class behaviors for the application.
3 | //
4 |
5 | #include "stdafx.h"
6 | #include "AutoUpdate.h"
7 | #include "InternetGetFile.h"
8 | #include "UISkinManager.h"
9 | #include "RMessageBox.h"
10 | #include "AutoUpdateDlg.h"
11 | #include "UpdateThread.h"
12 | #include "tlhelp32.h"
13 |
14 | #include "HttpClient.h"
15 | #include "JsonParser.h"
16 |
17 | using namespace std;
18 |
19 | #ifdef _DEBUG
20 | #define new DEBUG_NEW
21 | #undef THIS_FILE
22 | static char THIS_FILE[] = __FILE__;
23 | #endif
24 |
25 | // 全局字符串常量表数组(数组初始化在InitStringTable()函数中进行)
26 | struct StringStru g_String[STRING_BOTTOM];
27 |
28 | // 全局语言代码(不可随意修改其值,否则会导致程序异常!)
29 | enum enLANGUAGE g_LanguageID;
30 |
31 | /////////////////////////////////////////////////////////////////////////////
32 | // CAutoUpdateApp
33 |
34 | BEGIN_MESSAGE_MAP(CAutoUpdateApp, CWinApp)
35 | //{{AFX_MSG_MAP(CAutoUpdateApp)
36 | // NOTE - the ClassWizard will add and remove mapping macros here.
37 | // DO NOT EDIT what you see in these blocks of generated code!
38 | //}}AFX_MSG
39 | ON_COMMAND(ID_HELP, CWinApp::OnHelp)
40 | END_MESSAGE_MAP()
41 |
42 | /////////////////////////////////////////////////////////////////////////////
43 | // CAutoUpdateApp construction
44 |
45 | CAutoUpdateApp::CAutoUpdateApp()
46 | {
47 | // TODO: add construction code here,
48 | // Place all significant initialization in InitInstance
49 | m_bSilenceMode = FALSE;
50 | }
51 |
52 | /////////////////////////////////////////////////////////////////////////////
53 | // The one and only CAutoUpdateApp object
54 |
55 | CAutoUpdateApp theApp;
56 |
57 | /////////////////////////////////////////////////////////////////////////////
58 | // CAutoUpdateApp initialization
59 |
60 | BOOL CAutoUpdateApp::InitInstance()
61 | {
62 | LOG(0, 0, "============ 自动更新程序启动 ============");
63 |
64 | // ================ 测试开始 ================
65 |
66 | // CHttpClient httpclient;
67 | // string strResponse;
68 | // httpclient.Post("http://httpbin.org/post", "name=akagi201&project=curl", strResponse);
69 | // CParseJson jsonParser;
70 | // bool result = jsonParser.ParseJson(strResponse);
71 |
72 | // string value;
73 | // result = jsonParser.GetString("data", value);
74 | // ::MessageBox(NULL, value.c_str(), "提示", 0);
75 |
76 | // 嵌套解析
77 | // Value jsonValue;
78 | // result = jsonParser.GetObjectValue("form", jsonValue);
79 | // ::MessageBox(NULL,
80 | // ("root.form.name值为:" + jsonValue["name"].asString()).c_str(),
81 | // "信息",
82 | // 0);
83 |
84 | // ================ 测试结束 ================
85 |
86 |
87 | // 初始化自绘界面
88 | CUISkinManager::Init();
89 |
90 | // 初始化全局字符串常量表数组
91 | InitStringTable();
92 |
93 | // 处理命令行
94 | if (!ParseCommandLine()) {
95 | // 清理自绘界面
96 | CUISkinManager::Uninit();
97 | return FALSE;
98 | }
99 |
100 | // 检查程序是否已经在运行,如是则直接退出
101 | if (IsAppRunning()) { return FALSE; }
102 |
103 | AfxEnableControlContainer();
104 |
105 | // Standard initialization
106 | // If you are not using these features and wish to reduce the size
107 | // of your final executable, you should remove from the following
108 | // the specific initialization routines you do not need.
109 |
110 | #ifdef _AFXDLL
111 | // Call this when using MFC in a shared DLL
112 | Enable3dControls();
113 | #else
114 | // Call this when linking to MFC statically
115 | Enable3dControlsStatic();
116 | #endif
117 |
118 | // 显示主窗口
119 | CAutoUpdateDlg dlg;
120 | m_pMainWnd = &dlg;
121 | dlg.m_strAppName = m_strAppName;
122 | dlg.m_bSilenceMode = m_bSilenceMode;
123 | if (m_bSilenceMode) {
124 | // 静默方式执行升级
125 | m_pMainWnd = NULL;
126 | dlg.SetConfigFile(GetAppDirectory() + UPDATE_CONFIG_FILENAME);
127 | dlg.DoUpdate();
128 |
129 | // 等待升级线程完成
130 | HANDLE hThread = (dlg.m_pUpdateThread)->m_hThread;
131 | WaitForSingleObject(hThread, INFINITE);
132 | DWORD dwExit;
133 | BOOL bRet = GetExitCodeThread(hThread, &dwExit);
134 |
135 | if (dwExit != 1) {
136 | LOG(0, 0, "升级线程出现错误,开始还原UpdateConfig.ini文件.");
137 | RestoreUpdateCfgIniFile();
138 | }
139 | } else {
140 | int nResponse = dlg.DoModal();
141 | if (nResponse == IDOK) {
142 | // TODO: Place code here to handle when the dialog is
143 | // dismissed with OK
144 | } else if (nResponse == IDCANCEL) {
145 | // && dlg.m_btnCancel.GetWindowTextA() == STRING(STR_BUTTON_SUCCESS_UPGRADE, "完成升级")
146 | if (dlg.m_strPrompt == STRING(STR_PROMPT_UPGRADE_FINISHED, "升级完毕!")) {
147 | LOG(0, 0, "升级完成.");
148 | } else {
149 | LOG(0, 0, "用户取消升级,开始还原UpdateConfig.ini文件.");
150 | RestoreUpdateCfgIniFile();
151 | }
152 | }
153 | }
154 |
155 | // 清理自绘界面
156 | CUISkinManager::Uninit();
157 |
158 | LOG(0, 0, "AutoUpdate程序即将退出!");
159 | LOG(0, 0, "------------ 自动更新程序结束 ------------");
160 |
161 | // Since the dialog has been closed, return FALSE so that we exit the
162 | // application, rather than start the application's message pump.
163 | return FALSE;
164 | }
165 |
166 | //
167 | // 处理命令行
168 | // 返回值
169 | // TRUE 表示要继续运行后面的程序,
170 | // FALSE 表示终止程序运行
171 | //
172 | BOOL CAutoUpdateApp::ParseCommandLine()
173 | {
174 | m_strAppName = "MyBrowser.exe";
175 |
176 | CString sConfigFilename = GetAppDirectory() + UPDATE_CONFIG_FILENAME;
177 |
178 | // 从升级配置文件取得最新软件版本号
179 | try {
180 | CString sKey = "Version";
181 | const int BUFFER_SIZE = 512;
182 | char acBuffer[BUFFER_SIZE] = { 0 };
183 | GetPrivateProfileString(SECTION_UPDATE,
184 | sKey.GetBuffer(0),
185 | "",
186 | acBuffer,
187 | BUFFER_SIZE,
188 | sConfigFilename.GetBuffer(0));
189 | m_strVersion = (char*)acBuffer;
190 | } catch (...) {
191 | m_strVersion = "3.3.0";
192 | }
193 |
194 | try {
195 | CString sKey = "BaseUrl";
196 | const int BUFFER_SIZE = 512;
197 | char acBuffer[BUFFER_SIZE] = { 0 };
198 | GetPrivateProfileString(SECTION_UPDATE,
199 | sKey.GetBuffer(0),
200 | "",
201 | acBuffer,
202 | BUFFER_SIZE,
203 | sConfigFilename.GetBuffer(0));
204 | m_strBaseURL = (char*)acBuffer;
205 | } catch (...) {
206 | m_strBaseURL = "http://127.0.0.1:8080/Autoupdate";
207 | }
208 |
209 | m_strURL = m_strBaseURL + "/" + UPDATE_CONFIG_FILENAME;
210 |
211 | // m_strNotifyWindowTitle = "小房子浏览器自动升级程序";
212 | m_bSilenceMode = FALSE;
213 |
214 | m_strAppName.TrimLeft();
215 | m_strAppName.TrimRight();
216 | if (m_strAppName.IsEmpty()) {
217 | LOG(0, 0, "无效的应用名称.");
218 | return FALSE;
219 | }
220 |
221 | m_strVersion.TrimLeft();
222 | m_strVersion.TrimRight();
223 | if (m_strVersion.IsEmpty()) {
224 | LOG(0, 0, "无效的本地当前版本号,请检查当前目录下UpdateConfig.ini文件配置.");
225 | return FALSE;
226 | }
227 |
228 | // 检查升级配置文件,判断是否有新版本的软件可用
229 | if (CheckUpdate()) {
230 | if (!m_bSilenceMode) {
231 | CRMessageBox MsgBox;
232 | // MsgBox.m_sTitle = m_strAppName + " " + STRING(STR_AUTO_UPDATE, "Auto Update");
233 | MsgBox.m_strTitle = "小房子浏览器在线升级";
234 | MsgBox.m_strPromptMessage = STRING(STR_PROMPT_NEWER_VERSION_AVAILABLE, "当前有更新版本的软件可用,是否立即升级?");
235 | // 默认使用静默方式升级
236 | MsgBox.m_bOption1 = TRUE;
237 | MsgBox.m_strOptionPromptMessage1 = STRING(STR_OPTION_UPGRADE_IN_BACKGROUND , "继续运行程序,从后台执行升级。");
238 | MsgBox.m_iType = MB_YESNO + MB_ICONQUESTION;
239 | if (IDOK == MsgBox.DoModal()) {
240 | // 先将本次选择的"是否静默升级"模式值传递出去
241 | m_bSilenceMode = MsgBox.m_bOption1;
242 |
243 | if (MsgBox.m_iID == IDYES) {
244 | // 进入升级,退出主程序,保证安全顺利升级
245 | CloseProgram(m_strAppName);
246 | return TRUE;
247 | } else {
248 | LOG(0, 0, "用户点击了取消按钮,无需升级,开始还原UpdateConfig.ini文件");
249 | RestoreUpdateCfgIniFile();
250 | return FALSE;
251 | }
252 | } else {
253 | LOG(0, 0, "用户关闭了升级提示窗口,无需升级,开始还原UpdateConfig.ini文件!");
254 | RestoreUpdateCfgIniFile();
255 | return FALSE;
256 | }
257 | }
258 | } else {
259 | LOG(0, 0, "检测到运行程序已是最新版本,无需升级!");
260 | RestoreUpdateCfgIniFile();
261 | if (!m_bSilenceMode) {
262 | // AfxMessageBox("当前已是最新版本,无需升级!");
263 |
264 | // 暂用“关于”窗口代替提示信息展现窗口
265 | CAboutDlg dlg;
266 | dlg.DoModal();
267 | }
268 |
269 | return FALSE;
270 | }
271 |
272 | return TRUE;
273 | }
274 |
275 | //
276 | // 还原UpdateConfig.ini文件
277 | //
278 | BOOL CAutoUpdateApp::RestoreUpdateCfgIniFile()
279 | {
280 | CString sConfigFilename = GetAppDirectory() + UPDATE_CONFIG_FILENAME;
281 | CString sBakConfigFilename = GetAppDirectory() + "Backup\\" + UPDATE_CONFIG_FILENAME;
282 |
283 | // 创建备份文件目录
284 | CreateDirectory((GetAppDirectory() + "Backup").GetBuffer(0), NULL);
285 | if (FALSE == CopyFile(sBakConfigFilename.GetBuffer(0),
286 | sConfigFilename.GetBuffer(0),
287 | FALSE)) {
288 | LOG(0, 0, "还原UpdateConfig.ini文件失败");
289 | return FALSE;
290 | }
291 | else {
292 | LOG(0, 0, "还原UpdateConfig.ini文件成功");
293 | return TRUE;
294 | }
295 | }
296 |
297 | //
298 | // 从服务器下载升级配置文件,
299 | // 检查是否有新版本可用
300 | // 返回值为TRUE表示有新版本可用
301 | //
302 | BOOL CAutoUpdateApp::CheckUpdate()
303 | {
304 | CString sConfigFilename = GetAppDirectory() + UPDATE_CONFIG_FILENAME;
305 | CString sBakConfigFilename = GetAppDirectory() + "Backup\\" + UPDATE_CONFIG_FILENAME;
306 |
307 | // 从指定的URL下载升级配置文件
308 | if (!m_strURL.IsEmpty()) {
309 | // 创建备份文件目录
310 | CreateDirectory((GetAppDirectory() + "Backup").GetBuffer(0), NULL);
311 |
312 | // 下载前,先备份UpdateConfig.ini文件
313 | if (FALSE == CopyFile(sConfigFilename.GetBuffer(0),
314 | sBakConfigFilename.GetBuffer(0),
315 | FALSE)) {
316 | LOG(0, 0, "备份UpdateConfig.ini文件失败");
317 | return FALSE;
318 | }
319 |
320 | if (Internet::InternetGetURL(m_strURL.GetBuffer(0),
321 | sConfigFilename.GetBuffer(0))
322 | != Internet::INTERNET_SUCCESS) {
323 | LOG(0, 0, "下载文件失败:%s", m_strURL.GetBuffer(0));
324 | return FALSE;
325 | }
326 | }
327 |
328 | // 从升级配置文件取得最新软件版本号
329 | CString sKey = "Version";
330 | const int BUFFER_SIZE = 512;
331 | char acBuffer[BUFFER_SIZE] = {0};
332 | GetPrivateProfileString(SECTION_UPDATE,
333 | sKey.GetBuffer(0),
334 | "",
335 | acBuffer,
336 | BUFFER_SIZE,
337 | sConfigFilename.GetBuffer(0));
338 | CString strRemoteVersion = (char*)acBuffer;
339 |
340 | // 与当前软件版本号比较以确定是否需要升级
341 | if (strRemoteVersion > m_strVersion) {
342 | return TRUE;
343 | } else {
344 | return FALSE;
345 | }
346 | }
347 |
348 | //
349 | // 初始化全局字符串常量表
350 | //
351 | void CAutoUpdateApp::InitStringTable(enum enLANGUAGE Language)
352 | {
353 | if (Language < LANGUAGE_BOTTOM) {
354 | g_LanguageID = Language;
355 | } else {
356 | // 根据操作系统语言代码确定程序界面的语言代码
357 | switch (GetSystemDefaultLangID()) {
358 | case 0x0804: // Chinese (PRC)
359 | case 0x1004: // Chinese (Singapore)
360 | g_LanguageID = LANGUAGE_GB;
361 | break;
362 | case 0x0404: // Chinese (Taiwan)
363 | case 0x0c04: // Chinese (Hong Kong SAR, PRC)
364 | case 0x1404: // Chinese (Macao)
365 | g_LanguageID = LANGUAGE_BIG5;
366 | break;
367 | default:
368 | g_LanguageID = LANGUAGE_ENGLISH;
369 | break;
370 | }
371 | }
372 |
373 | //
374 | // 初始化全局字符串常量表
375 | //
376 | g_String[STR_NULL].Set("", "", "");
377 | g_String[STR_AUTO_UPDATE].Set("自动升级", "自動升級", "Auto Update");
378 | g_String[STR_APP_ALREADY_RUNNING].Set("升级程序已经在运行中!", "升級程序已經在運行中", "Auto update program is already running."); // 退出应用程序;提示保存文档\n退出
379 |
380 | g_String[STR_PROMPT_NEWER_VERSION_AVAILABLE].Set("当前有更新版本的软件可用,是否立即升级?", "當前有更新版本的軟件可用,是否立即升級?", "There is a newer version available. Do you want to update right now?");
381 | g_String[STR_OPTION_UPGRADE_IN_BACKGROUND].Set("后台执行升级", "後臺執行升級", "Run updating in background mode");
382 | g_String[STR_PROMPT_UPGRADE_READY].Set("升级准备就绪。", "升級準備就緒", "Update is ready. Please press [Start update] button to update.");
383 | g_String[STR_PROMPT_FAIL_TO_OPEN_UPDATE_CONFIG_FILE].Set("打开升级配置文件失败,无法执行升级!", "打開升級配置文件失敗,無法執行升級!", "Fail to open update config file. Update is canceled.");
384 | g_String[STR_PROMPT_DOWNLOADING_FILE].Set("正在下载文件 %s", "正在下載文件 %s", "Downloading file %s");
385 | g_String[STR_TOTAL_UPGRADE_PROGRESS].Set("升级总进度 %d / %d", "升級總進度 %d / %d", "Total progress %d / %d");
386 | g_String[STR_PROMPT_FAIL_IN_DOWNLOADING_FILES].Set("下载文件 %s 失败!", "下載文件 %s 失敗!", "Fail in downloading file %s!");
387 | g_String[STR_PROMPT_FAIL_IN_VERIFYING_FILES].Set("校验文件 %s 失败!", "校驗文件 %s 失敗!", "Fail in verifying file %s!");
388 | g_String[STR_PROMPT_FAIL_IN_UPDATING_FILES].Set("更新文件 %s 失败!", "更新文件 %s 失敗!", "Fail in updating file %s!");
389 | g_String[STR_PROMPT_FAIL_IN_UPDATING].Set("升级失败!", "升級失敗!", "Fail in updating!");
390 | g_String[STR_PROMPT_UPGRADE_FINISHED].Set("升级完毕!", "升級完畢!", "Update finished!");
391 |
392 | g_String[STR_BUTTON_START_UPGRADE].Set("开始升级", "開始升級", "Start update");
393 | g_String[STR_BUTTON_CANCEL_UPGRADE].Set("取消升级", "取消升級", "Cancel");
394 | g_String[STR_BUTTON_SUCCESS_UPGRADE].Set("完成升级", "完成升級", "Success update");
395 |
396 | g_String[STR_BUTTON_OK].Set("确定(&O)", "確定(&O)", "&OK");
397 | g_String[STR_BUTTON_CANCEL].Set("取消(&C)", "取消(&C)", "&Cancel");
398 | g_String[STR_BUTTON_ABORT].Set("跳出(&A)", "跳出(&A)", "&Abort");
399 | g_String[STR_BUTTON_IGANORE].Set("忽略(&I)", "忽略(&I)", "&Ignore");
400 | g_String[STR_BUTTON_RETRY].Set("重试(&R)", "重試(&R)", "&Retry");
401 | g_String[STR_BUTTON_CONTINUE].Set("继续(&C)", "繼續(&C)", "&Continue");
402 | g_String[STR_BUTTON_YES].Set("是(&Y)", "是(&Y)", "&Yes");
403 | g_String[STR_BUTTON_NO].Set("否(&N)", "否(&N)", "&No");
404 | g_String[STR_BUTTON_CLOSE].Set("关闭", "關閉", "Close");
405 | g_String[STR_BUTTON_APPLY].Set("应用(&A)", "應用(&A)", "&Apply");
406 |
407 | g_String[STR_OTHER].Set("其他", "其他", "Other");
408 |
409 | g_String[STR_ERROR].Set("错误", "錯誤", "Error");
410 | g_String[STR_ERROR_MESSAGE].Set("错误:%s", "錯誤:%s", "Error: %s");
411 | }
412 |
413 | BOOL CAutoUpdateApp::IsAppRunning()
414 | {
415 | // 创建互斥量,防止同时启动多个程序实例
416 | CString sMutex = m_strAppName + "AutoUpdateMutex";
417 | if (::OpenMutex(MUTEX_ALL_ACCESS, FALSE, sMutex.GetBuffer(0))) {
418 | return TRUE;
419 | } else {
420 | ::CreateMutex(0, FALSE, sMutex.GetBuffer(0));
421 | return FALSE;
422 | }
423 | }
424 |
425 | //
426 | // 终止MyBrowser.exe程序
427 | //
428 | void CAutoUpdateApp::CloseProgram(CString strProgram)
429 | {
430 | // 定义CreateToolhelp32Snapshot系统快照句柄
431 | HANDLE handle;
432 | // 定义要结束进程句柄
433 | HANDLE handle1;
434 | // 获得系统快照句柄
435 | handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
436 | // 定义PROCESSENTRY32结构字指针
437 | PROCESSENTRY32 *info;
438 | // PROCESSENTRY32 结构的 dwSize 成员设置成 sizeof(PROCESSENTRY32)
439 |
440 | info = new PROCESSENTRY32;
441 | info->dwSize = sizeof(PROCESSENTRY32);
442 | // 调用一次 Process32First 函数,从快照中获取进程列表
443 | Process32First(handle, info);
444 | // 重复调用 Process32Next,直到函数返回 FALSE 为止
445 | while(Process32Next(handle, info) != FALSE) {
446 | // 指向进程名字
447 | CString strTmp = info->szExeFile;
448 |
449 | if (strProgram.CompareNoCase(info->szExeFile) == 0 ) {
450 | // PROCESS_TERMINATE表示为结束操作打开,
451 | // FALSE=可继承,info->th32ProcessID=进程ID
452 | handle1 = OpenProcess(PROCESS_TERMINATE, FALSE, info->th32ProcessID);
453 | // 结束进程
454 | TerminateProcess(handle1, 0);
455 | }
456 | }
457 | delete info;
458 |
459 | CloseHandle(handle);
460 | }
--------------------------------------------------------------------------------
/Src/AutoUpdate.h:
--------------------------------------------------------------------------------
1 | // AutoUpdate.h : main header file for the AUTOUPDATE application
2 | //
3 |
4 | #if !defined(AFX_AUTOUPDATE_H__187D3C3A_DD05_4283_9FCA_1FAF58B23B29__INCLUDED_)
5 | #define AFX_AUTOUPDATE_H__187D3C3A_DD05_4283_9FCA_1FAF58B23B29__INCLUDED_
6 |
7 | #if _MSC_VER > 1000
8 | #pragma once
9 | #endif // _MSC_VER > 1000
10 |
11 | #ifndef __AFXWIN_H__
12 | #error include 'stdafx.h' before including this file for PCH
13 | #endif
14 |
15 | // main symbols
16 | #include "resource.h"
17 |
18 | #include "MultiLanguage.h"
19 |
20 | // 本地保存的升级配置文件名
21 | #define UPDATE_CONFIG_FILENAME "UpdateConfig.ini"
22 |
23 | // 升级配置文件中的区段名
24 | #define SECTION_UPDATE "UPDATE"
25 | #define SECTION_COMMON "COMMON"
26 |
27 | // 上报到界面的升级进度消息
28 | enum
29 | {
30 | // 通知要下载的文件状况
31 | NOTIFY_DOWNLOAD_INFO = 1001,
32 | // 通知已下载的文件状况
33 | NOTIFY_DOWNLOADED_INFO,
34 | // 通知下载单个文件进度
35 | NOTIFY_DOWNLOAD_PROGRESS,
36 | // 通知正在下载的文件名
37 | NOTIFY_DOWNLOADING_FILENAME,
38 | // 通知下载文件失败
39 | NOTIFY_DOWNLOAD_FILE_FAIL,
40 | // 通知校验文件失败
41 | NOTIFY_VERIFY_FILE_FAIL,
42 | // 通知更新文件失败
43 | NOTIFY_UPDATE_FILE_FAIL,
44 | // 通知升级完毕消息
45 | NOTIFY_FINISH_UPDATE,
46 | };
47 |
48 | // 升级下载文件状态消息结构
49 | struct DOWNLOAD_INFO_STRU
50 | {
51 | // 合计文件数
52 | UINT iFileCount;
53 | // 合计字节数
54 | UINT iFileSize;
55 | };
56 |
57 | // 下载单个文件进度消息结构
58 | struct DOWNLOAD_PROGRESS_STRU
59 | {
60 | // 当前正在下载的文件的字节数
61 | UINT iCurrentFileSize;
62 |
63 | // 当前文件已下载字节数
64 | UINT iCurrentFileFinishedSize;
65 | };
66 |
67 | /////////////////////////////////////////////////////////////////////////////
68 | // CAutoUpdateApp:
69 | // See AutoUpdate.cpp for the implementation of this class
70 | //
71 |
72 | class CAutoUpdateApp : public CWinApp
73 | {
74 | public:
75 | CAutoUpdateApp();
76 | void InitStringTable(enum enLANGUAGE Language = LANGUAGE_BOTTOM);
77 |
78 | // Overrides
79 | // ClassWizard generated virtual function overrides
80 | //{{AFX_VIRTUAL(CAutoUpdateApp)
81 | public:
82 | virtual BOOL InitInstance();
83 | //}}AFX_VIRTUAL
84 |
85 | // Implementation
86 |
87 | //{{AFX_MSG(CAutoUpdateApp)
88 | // NOTE - the ClassWizard will add and remove member functions here.
89 | // DO NOT EDIT what you see in these blocks of generated code !
90 | //}}AFX_MSG
91 | DECLARE_MESSAGE_MAP()
92 |
93 | public :
94 | // 下载升级基础URL
95 | CString m_strBaseURL;
96 |
97 | private:
98 | // 处理命令行
99 | BOOL ParseCommandLine();
100 |
101 | // 判断本程序是否正在运行
102 | BOOL IsAppRunning();
103 |
104 | // 从软件网站下载升级配置文件,
105 | // 检查是否有新版本的软件可用
106 | BOOL CheckUpdate();
107 |
108 | // 终止主程序(例如:小房子浏览器程序MyBrowser.exe)
109 | void CloseProgram(CString strProgram);
110 |
111 | // 还原UpdateConfig.ini文件
112 | BOOL RestoreUpdateCfgIniFile();
113 |
114 | private:
115 | // 应用程序名,用以创建互斥量
116 | CString m_strAppName;
117 |
118 | // 应用程序的当前版本
119 | CString m_strVersion;
120 |
121 | // 下载升级配置文件的URL
122 | CString m_strURL;
123 |
124 | // 升级过程中发送消息的目标窗口句柄
125 | // DWORD m_iNotifyWindow;
126 |
127 | // 升级过程中发送消息的目标窗口标题
128 | // CString m_strNotifyWindowTitle;
129 |
130 | // 升级完毕发送的消息代码
131 | // DWORD m_iNotifyFinish;
132 |
133 | // 静默方式执行升级,不显示升级程序界面,
134 | // 只在升级完毕后提醒用户
135 | BOOL m_bSilenceMode;
136 | };
137 |
138 | /////////////////////////////////////////////////////////////////////////////
139 |
140 | //{{AFX_INSERT_LOCATION}}
141 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
142 |
143 | #endif // !defined(AFX_AUTOUPDATE_H__187D3C3A_DD05_4283_9FCA_1FAF58B23B29__INCLUDED_)
144 |
--------------------------------------------------------------------------------
/Src/AutoUpdate.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/AutoUpdate.rc
--------------------------------------------------------------------------------
/Src/AutoUpdate.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AutoUpdate", "AutoUpdate.vcxproj", "{CBF915DD-73F9-D5B9-A845-0D34125937AC}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {CBF915DD-73F9-D5B9-A845-0D34125937AC}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {CBF915DD-73F9-D5B9-A845-0D34125937AC}.Debug|Win32.Build.0 = Debug|Win32
14 | {CBF915DD-73F9-D5B9-A845-0D34125937AC}.Release|Win32.ActiveCfg = Release|Win32
15 | {CBF915DD-73F9-D5B9-A845-0D34125937AC}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/Src/AutoUpdate.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | MFCProj
19 | {CBF915DD-73F9-D5B9-A845-0D34125937AC}
20 |
21 |
22 |
23 | Application
24 | Static
25 | MultiByte
26 | v140
27 |
28 |
29 | Application
30 | Static
31 | MultiByte
32 | v140
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .\Debug\
48 | .\Debug\
49 | true
50 |
51 |
52 | .\Release\
53 | .\Release\
54 | false
55 |
56 |
57 |
58 | MultiThreadedDebug
59 | Default
60 | false
61 | Disabled
62 | true
63 | Level3
64 | true
65 | ProgramDatabase
66 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
67 | .\Debug\
68 | .\Debug\AutoUpdate.pch
69 | Use
70 | stdafx.h
71 | .\Debug\
72 | .\Debug\
73 | EnableFastChecks
74 |
75 |
76 | true
77 | _DEBUG;%(PreprocessorDefinitions)
78 | .\Debug\AutoUpdate.tlb
79 | true
80 | Win32
81 |
82 |
83 | 0x0804
84 | _DEBUG;%(PreprocessorDefinitions)
85 |
86 |
87 | true
88 | .\Debug\AutoUpdate.bsc
89 |
90 |
91 | true
92 | true
93 | Windows
94 | .\Debug\AutoUpdate.exe
95 | wininet.lib;Winmm.lib;Version.lib;%(AdditionalDependencies)
96 |
97 |
98 |
99 |
100 | MultiThreaded
101 | Default
102 | true
103 | true
104 | Disabled
105 | true
106 | Level3
107 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);BUILDING_LIBCURL;HTTP_ONLY
108 | .\Release\
109 | .\Release\AutoUpdate.pch
110 | Use
111 | stdafx.h
112 | .\Release\
113 | .\Release\
114 |
115 |
116 | true
117 | NDEBUG;%(PreprocessorDefinitions)
118 | .\Release\AutoUpdate.tlb
119 | true
120 | Win32
121 |
122 |
123 | 0x0804
124 | NDEBUG;%(PreprocessorDefinitions)
125 |
126 |
127 | true
128 | .\Release\AutoUpdate.bsc
129 |
130 |
131 | true
132 | Windows
133 | .\Release\AutoUpdate.exe
134 | wininet.lib;Winmm.lib;Version.lib;%(AdditionalDependencies)
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | NotUsing
143 |
144 |
145 |
146 | NotUsing
147 |
148 |
149 |
150 |
151 |
152 |
153 | Create
154 | stdafx.h
155 | Create
156 | stdafx.h
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 | RC
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
--------------------------------------------------------------------------------
/Src/AutoUpdate.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4fc46688-ecc2-4a63-8136-fa58094b2cc6}
6 | cpp;c;cxx;rc;def;r;odl;idl;hpj;bat
7 |
8 |
9 | {3c467eac-09b3-4603-b64f-61f2d8c0dc51}
10 | h;hpp;hxx;hm;inl
11 |
12 |
13 | {ca8e1d72-78af-43e9-a607-1eef2f31b147}
14 | ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Source Files
35 |
36 |
37 | Source Files
38 |
39 |
40 | Source Files
41 |
42 |
43 | Source Files
44 |
45 |
46 | Source Files
47 |
48 |
49 | Source Files
50 |
51 |
52 | Source Files
53 |
54 |
55 | Source Files
56 |
57 |
58 |
59 |
60 | Source Files
61 |
62 |
63 |
64 |
65 | Header Files
66 |
67 |
68 | Header Files
69 |
70 |
71 | Header Files
72 |
73 |
74 | Header Files
75 |
76 |
77 | Header Files
78 |
79 |
80 | Header Files
81 |
82 |
83 | Header Files
84 |
85 |
86 | Header Files
87 |
88 |
89 | Header Files
90 |
91 |
92 | Header Files
93 |
94 |
95 | Header Files
96 |
97 |
98 | Header Files
99 |
100 |
101 | Header Files
102 |
103 |
104 | Header Files
105 |
106 |
107 |
108 |
109 | Resource Files
110 |
111 |
112 | Resource Files
113 |
114 |
115 | Resource Files
116 |
117 |
118 | Resource Files
119 |
120 |
121 | Resource Files
122 |
123 |
124 | Resource Files
125 |
126 |
127 | Resource Files
128 |
129 |
130 | Resource Files
131 |
132 |
133 | Resource Files
134 |
135 |
136 | Resource Files
137 |
138 |
139 | Resource Files
140 |
141 |
142 | Resource Files
143 |
144 |
145 | Resource Files
146 |
147 |
148 | Resource Files
149 |
150 |
151 | Resource Files
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/Src/AutoUpdateDlg.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // AutoUpdateDlg.cpp : implementation file
3 | //
4 |
5 | #include "stdafx.h"
6 | #include
7 | #include "AutoUpdate.h"
8 | #include "InternetGetFile.h"
9 | #include "UpdateThread.h"
10 | #include "UISkinManager.h"
11 | #include "AutoUpdateDlg.h"
12 |
13 | #ifdef _DEBUG
14 | #define new DEBUG_NEW
15 | #undef THIS_FILE
16 | static char THIS_FILE[] = __FILE__;
17 | #endif
18 |
19 | CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
20 | {
21 | //{{AFX_DATA_INIT(CAboutDlg)
22 | //}}AFX_DATA_INIT
23 | }
24 |
25 | void CAboutDlg::DoDataExchange(CDataExchange* pDX)
26 | {
27 | CDialog::DoDataExchange(pDX);
28 | //{{AFX_DATA_MAP(CAboutDlg)
29 | //}}AFX_DATA_MAP
30 | }
31 |
32 | BOOL CAboutDlg::OnInitDialog()
33 | {
34 | CDialog::OnInitDialog();
35 |
36 | // 已在资源管理器的窗体属性中设置Topmost属性为true
37 | // int ret = SetWindowPos(&CWnd::wndTopMost, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
38 | // if (ret == 0) {
39 | // return false;
40 | // } else {
41 | // return true;
42 | // }
43 |
44 | return TRUE;
45 | }
46 |
47 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
48 | //{{AFX_MSG_MAP(CAboutDlg)
49 | // No message handlers
50 | //}}AFX_MSG_MAP
51 | END_MESSAGE_MAP()
52 |
53 | /////////////////////////////////////////////////////////////////////////////
54 | // CAutoUpdateDlg dialog
55 |
56 | CAutoUpdateDlg::CAutoUpdateDlg(CWnd* pParent /*=NULL*/)
57 | : CRDialog(CAutoUpdateDlg::IDD, pParent)
58 | {
59 | //{{AFX_DATA_INIT(CAutoUpdateDlg)
60 | m_strPrompt = _T("");
61 | m_strPromptTotalProgress = _T("");
62 | m_strProgressBar = _T("");
63 | m_strTotalProgressBar = _T("");
64 | m_TotalFileInfo.iFileCount = 0;
65 | m_TotalFileInfo.iFileSize = 0;
66 | m_FinishedFileInfo.iFileCount = 0;
67 | m_FinishedFileInfo.iFileSize = 0;
68 | m_fDownloadPercent = 0.0;
69 | m_bSilenceMode = FALSE;
70 | m_bUserBreak = FALSE;
71 | //}}AFX_DATA_INIT
72 | // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
73 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
74 |
75 | m_pUpdateThread = NULL;
76 | }
77 |
78 | void CAutoUpdateDlg::DoDataExchange(CDataExchange* pDX)
79 | {
80 | CDialog::DoDataExchange(pDX);
81 | //{{AFX_DATA_MAP(CAutoUpdateDlg)
82 | DDX_Control(pDX, IDOK, m_btnUpgrade);
83 | DDX_Control(pDX, IDCANCEL, m_btnCancel);
84 | DDX_Text(pDX, IDC_STATIC_PROMPT, m_strPrompt);
85 | DDX_Text(pDX, IDC_STATIC_PROMPT_TOTAL_PROGRESS, m_strPromptTotalProgress);
86 | DDX_Text(pDX, IDC_STATIC_PROGRESS, m_strProgressBar);
87 | DDX_Text(pDX, IDC_STATIC_TOTAL_PROGRESS, m_strTotalProgressBar);
88 | //}}AFX_DATA_MAP
89 | }
90 |
91 | BEGIN_MESSAGE_MAP(CAutoUpdateDlg, CDialog)
92 | //{{AFX_MSG_MAP(CAutoUpdateDlg)
93 | RDIALOG_UI_MESSAGE_MAP
94 | ON_WM_SYSCOMMAND()
95 | ON_WM_QUERYDRAGICON()
96 | ON_MESSAGE(WM_USER, OnUserMessage)
97 | //}}AFX_MSG_MAP
98 | END_MESSAGE_MAP()
99 |
100 | /////////////////////////////////////////////////////////////////////////////
101 | // CAutoUpdateDlg message handlers
102 |
103 | BOOL CAutoUpdateDlg::OnInitDialog()
104 | {
105 | CRDialog::OnInitDialog();
106 |
107 | // Add "About..." menu item to system menu.
108 |
109 | // IDM_ABOUTBOX must be in the system command range.
110 | ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
111 | ASSERT(IDM_ABOUTBOX < 0xF000);
112 |
113 | CMenu* pSysMenu = GetSystemMenu(FALSE);
114 | if (pSysMenu != NULL) {
115 | CString strAboutMenu;
116 | strAboutMenu.LoadString(IDS_ABOUTBOX);
117 | if (!strAboutMenu.IsEmpty()) {
118 | pSysMenu->AppendMenu(MF_SEPARATOR);
119 | pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
120 | }
121 | }
122 |
123 | // Set the icon for this dialog. The framework does this automatically
124 | // when the application's main window is not a dialog
125 | SetIcon(m_hIcon, TRUE); // Set big icon
126 | SetIcon(m_hIcon, FALSE); // Set small icon
127 |
128 | // TODO: Add extra initialization here
129 | // SetWindowText(m_strAppName + " " + STRING(STR_AUTO_UPDATE, "Auto Update"));
130 | SetWindowText("小房子浏览器在线升级");
131 | m_btnUpgrade.SetWindowText(STRING(STR_BUTTON_START_UPGRADE, "开始升级"));
132 | m_btnCancel.SetWindowText(STRING(STR_BUTTON_CANCEL_UPGRADE, "取消升级"));
133 | m_strPrompt = STRING(STR_PROMPT_UPGRADE_READY, "Upgrade is ready. Please press [Start upgrade] button to upgrade.");
134 | UpdateData(FALSE);
135 | if (m_bSilenceMode) {
136 | ShowWindow(SW_HIDE);
137 | OnOK();
138 | }
139 |
140 | if (CUISkinManager::m_iCurrentStyle == CUISkinManager::StyleNormal) {
141 | // 以字符方式显示进度
142 | GetDlgItem(IDC_STATIC_PROGRESS)->ShowWindow(SW_SHOW);
143 | GetDlgItem(IDC_STATIC_TOTAL_PROGRESS)->ShowWindow(SW_SHOW);
144 | } else {
145 | // 以图形图显示进度
146 | GetDlgItem(IDC_STATIC_PROGRESS)->ShowWindow(SW_HIDE);
147 | GetDlgItem(IDC_STATIC_TOTAL_PROGRESS)->ShowWindow(SW_HIDE);
148 | }
149 |
150 | // return TRUE unless you set the focus to a control
151 | return TRUE;
152 | }
153 |
154 | void CAutoUpdateDlg::OnSysCommand(UINT nID, LPARAM lParam)
155 | {
156 | if ((nID & 0xFFF0) == IDM_ABOUTBOX) {
157 | CAboutDlg dlgAbout;
158 | dlgAbout.DoModal();
159 | } else {
160 | CDialog::OnSysCommand(nID, lParam);
161 | }
162 | }
163 |
164 | //
165 | // If you add a minimize button to your dialog, you will need the code below
166 | // to draw the icon. For MFC applications using the document/view model,
167 | // this is automatically done for you by the framework.
168 | //
169 | void CAutoUpdateDlg::OnPaint()
170 | {
171 | CRDialog::OnPaint();
172 |
173 | if (IsIconic()) {
174 | // device context for painting
175 | CPaintDC dc(this);
176 |
177 | SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
178 |
179 | // Center icon in client rectangle
180 | int cxIcon = GetSystemMetrics(SM_CXICON);
181 | int cyIcon = GetSystemMetrics(SM_CYICON);
182 | CRect rect;
183 | GetClientRect(&rect);
184 | int x = (rect.Width() - cxIcon + 1) / 2;
185 | int y = (rect.Height() - cyIcon + 1) / 2;
186 |
187 | // Draw the icon
188 | dc.DrawIcon(x, y, m_hIcon);
189 | } else {
190 | CDialog::OnPaint();
191 | }
192 |
193 | // 重绘进度条
194 | if (m_fTotalDownloadPercent != 0.0) {
195 | UpdateProgress(m_TotalFileInfo.iFileCount,
196 | m_FinishedFileInfo.iFileCount,
197 | m_fTotalDownloadPercent,
198 | m_fDownloadPercent);
199 | }
200 | }
201 |
202 | //
203 | // The system calls this to obtain the cursor
204 | // to display while the user drags the minimized window.
205 | //
206 | HCURSOR CAutoUpdateDlg::OnQueryDragIcon()
207 | {
208 | return (HCURSOR) m_hIcon;
209 | }
210 |
211 | void CAutoUpdateDlg::OnCancel()
212 | {
213 | m_bUserBreak = TRUE;
214 | if (m_pUpdateThread != NULL) {
215 | LOG(0, 0, "用户取消升级.");
216 | HANDLE hThread = m_pUpdateThread->m_hThread;
217 | m_pUpdateThread->m_bUserBreak = TRUE;
218 | Internet::bInternetGetURLUserBreak = TRUE;
219 | WaitForSingleObject(hThread, 1000);
220 | }
221 |
222 | CDialog::OnCancel();
223 | }
224 |
225 | void CAutoUpdateDlg::OnOK()
226 | {
227 | // 点击开始升级按钮,执行升级
228 | if (!SetConfigFile(GetAppDirectory() + UPDATE_CONFIG_FILENAME)) {
229 | RMessageBox(STRING(STR_PROMPT_FAIL_TO_OPEN_UPDATE_CONFIG_FILE, "Fail to open update config file."));
230 | } else {
231 | // 开始升级,禁用按钮,避免重复点击
232 | GetDlgItem(IDOK)->EnableWindow(FALSE);
233 | DoUpdate();
234 | }
235 |
236 | // CDialog::OnOK();
237 | }
238 |
239 | // 设置升级配置文件名
240 | BOOL CAutoUpdateDlg::SetConfigFile(CString &strFilename)
241 | {
242 | CFileFind FileFinder;
243 |
244 | if (FileFinder.FindFile(strFilename)) {
245 | FileFinder.FindNextFile();
246 | if (!FileFinder.IsDirectory()) {
247 | m_strConfigFileName = strFilename;
248 | FileFinder.Close();
249 | return TRUE;
250 | }
251 | FileFinder.Close();
252 | }
253 |
254 | return FALSE;
255 | }
256 |
257 | BOOL CAutoUpdateDlg::DoUpdate(void)
258 | {
259 | LOG(0, 0, "启动升级线程...");
260 |
261 | // 启动升级线程
262 | m_pUpdateThread = new CUpdateThread;
263 | m_pUpdateThread->m_bAutoDelete = TRUE;
264 | m_pUpdateThread->m_strConfigFileName = m_strConfigFileName;
265 | m_pUpdateThread->m_hProgressWindow = m_hWnd;
266 | m_pUpdateThread->CreateThread();
267 |
268 | LOG(0, 0, "启动升级线程完成.");
269 |
270 | return TRUE;
271 | }
272 |
273 | // 处理用户消息
274 | LRESULT CAutoUpdateDlg::OnUserMessage(WPARAM wParam, LPARAM lParam)
275 | {
276 | switch (wParam) {
277 | case NOTIFY_DOWNLOAD_INFO:
278 | // 通知要下载的文件状况
279 | {
280 | m_TotalFileInfo = *(DOWNLOAD_INFO_STRU*)lParam;
281 | m_fDownloadPercent = 0;
282 | m_fTotalDownloadPercent = 0;
283 | UpdateProgress(m_TotalFileInfo.iFileCount,
284 | m_FinishedFileInfo.iFileCount,
285 | m_fTotalDownloadPercent,
286 | m_fDownloadPercent);
287 | }
288 | break;
289 |
290 | case NOTIFY_DOWNLOADED_INFO:
291 | // 通知已下载的文件状况
292 | {
293 | m_FinishedFileInfo = *(DOWNLOAD_INFO_STRU*)lParam;
294 | m_fDownloadPercent = 0;
295 | m_fTotalDownloadPercent = float(m_FinishedFileInfo.iFileSize) / m_TotalFileInfo.iFileSize;
296 | UpdateProgress(m_TotalFileInfo.iFileCount,
297 | m_FinishedFileInfo.iFileCount,
298 | m_fTotalDownloadPercent,
299 | m_fDownloadPercent);
300 | }
301 | break;
302 |
303 | case NOTIFY_DOWNLOAD_PROGRESS:
304 | // 通知下载单个文件进度
305 | {
306 | DOWNLOAD_PROGRESS_STRU* pDownloadProgress = (DOWNLOAD_PROGRESS_STRU*)lParam;
307 | m_fDownloadPercent = float(pDownloadProgress->iCurrentFileFinishedSize) / pDownloadProgress->iCurrentFileSize;
308 | m_fTotalDownloadPercent = float(m_FinishedFileInfo.iFileSize + pDownloadProgress->iCurrentFileFinishedSize) / m_TotalFileInfo.iFileSize;
309 | UpdateProgress(m_TotalFileInfo.iFileCount,
310 | m_FinishedFileInfo.iFileCount,
311 | m_fTotalDownloadPercent,
312 | m_fDownloadPercent);
313 | }
314 | break;
315 |
316 | case NOTIFY_DOWNLOADING_FILENAME:
317 | // 通知正在下载的文件名
318 | {
319 | if (lParam != 0) {
320 | m_strPrompt.Format(STRING(STR_PROMPT_DOWNLOADING_FILE, "Downloading file %s."), (char*)lParam);
321 | } else {
322 | m_strPrompt = "正在下载文件:";
323 | }
324 | m_strProgressBar = "";
325 | UpdateData(FALSE);
326 | }
327 | break;
328 |
329 | case NOTIFY_DOWNLOAD_FILE_FAIL:
330 | // 通知下载文件失败
331 | {
332 | m_strPrompt.Format(STRING(STR_PROMPT_FAIL_IN_DOWNLOADING_FILES, "下载文件 %s 失败!"), (char*)lParam);
333 | m_strProgressBar = "";
334 | UpdateData(FALSE);
335 | }
336 | break;
337 |
338 | case NOTIFY_VERIFY_FILE_FAIL:
339 | // 通知校验文件失败
340 | {
341 | m_strPrompt.Format(STRING(STR_PROMPT_FAIL_IN_VERIFYING_FILES, "校验文件 %s 失败!"), (char*)lParam);
342 | m_strProgressBar = "";
343 | UpdateData(FALSE);
344 | }
345 | break;
346 |
347 | case NOTIFY_UPDATE_FILE_FAIL:
348 | // 通知更新文件失败
349 | {
350 | m_strPrompt.Format(STRING(STR_PROMPT_FAIL_IN_UPDATING_FILES, "更新文件 %s 失败!"), (char*)lParam);
351 | m_strProgressBar = "";
352 | UpdateData(FALSE);
353 | }
354 | break;
355 |
356 | case NOTIFY_FINISH_UPDATE:
357 | // 通知升级完毕消息
358 | {
359 | OnNotifyUpdateFinish((BOOL)lParam);
360 | }
361 | break;
362 |
363 | default:
364 | break;
365 | }
366 |
367 | return TRUE;
368 | }
369 |
370 | // 更新显示下载文件进度
371 | void CAutoUpdateDlg::UpdateProgress(UINT iTotalFileCount,
372 | UINT iFinishedFileCount,
373 | float fTotalPercent,
374 | float fPercent)
375 | {
376 | if (m_hWnd == NULL ||
377 | m_bSilenceMode ||
378 | iTotalFileCount == 0) {
379 | return;
380 | }
381 |
382 | //
383 | // 绘制进度条
384 | //
385 | if (CUISkinManager::m_iCurrentStyle == CUISkinManager::StyleNormal) {
386 | const int BUFFER_SIZE = 500;
387 | char acBuffer[BUFFER_SIZE] = {0};
388 |
389 | fPercent *= 100;
390 | if (fPercent < 0) {
391 | fPercent = 0;
392 | }
393 | if (fPercent > 100) {
394 | fPercent = 100;
395 | }
396 | if (fPercent < 44) {
397 | strncpy(acBuffer, ">>>>>>>>>>>>>>>>>>>>>> 100% >>>>>>>>>>>>>>>>>>>>", int(fPercent / 2));
398 | strncat(acBuffer, " ", 22 - int(fPercent / 2));
399 | sprintf(acBuffer, "%s %2.1f%% ", acBuffer, fPercent);
400 | } else {
401 | strncpy(acBuffer, ">>>>>>>>>>>>>>>>>>>>>> 100% >>>>>>>>>>>>>>>>>>>>", 22);
402 | sprintf(acBuffer, "%s %2.1f%% ", acBuffer, fPercent);
403 | if (fPercent > 56) {
404 | strncat(acBuffer, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", int(fPercent / 2) - 28);
405 | }
406 | }
407 | m_strProgressBar = acBuffer;
408 |
409 | memset(acBuffer, 0, BUFFER_SIZE);
410 | fTotalPercent *= 100;
411 | if (fTotalPercent < 0) {
412 | fTotalPercent = 0;
413 | }
414 | if (fTotalPercent > 100) {
415 | fTotalPercent = 100;
416 | }
417 | if (fTotalPercent < 44) {
418 | strncpy(acBuffer, ">>>>>>>>>>>>>>>>>>>>>> 100% >>>>>>>>>>>>>>>>>>>>", int(fTotalPercent / 2));
419 | strncat(acBuffer, " ", 22 - int(fTotalPercent / 2));
420 | sprintf(acBuffer, "%s %2.1f%% ", acBuffer, fTotalPercent);
421 | } else {
422 | strncpy(acBuffer, ">>>>>>>>>>>>>>>>>>>>>> 100% >>>>>>>>>>>>>>>>>>>>", 22);
423 | sprintf(acBuffer, "%s %2.1f%% ", acBuffer, fTotalPercent);
424 | if (fTotalPercent > 56) {
425 | strncat(acBuffer, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", int(fTotalPercent / 2) - 28);
426 | }
427 | }
428 | m_strTotalProgressBar = acBuffer;
429 |
430 | m_strPromptTotalProgress.Format(STRING(STR_TOTAL_UPGRADE_PROGRESS,
431 | "升级总进度 %d / %d"),
432 | iFinishedFileCount >= iTotalFileCount ? iTotalFileCount : iFinishedFileCount + 1,
433 | iTotalFileCount);
434 |
435 | UpdateData(FALSE);
436 |
437 | return;
438 | } else {
439 | CDC *pDC = GetDC();
440 | CRect rcWnd;
441 | CRect rc, rc2;
442 |
443 | GetClientRect(&rcWnd);
444 |
445 | // 画进度条外框
446 | rc = rcWnd;
447 | rc.DeflateRect(30, 75, 30, 75);
448 | rc.bottom = rc.top + 18;
449 | pDC->Draw3dRect(&rc, RGB(200, 210, 220), RGB(30, 70, 100));
450 | rc.DeflateRect(1, 1, 1, 1);
451 | pDC->Draw3dRect(&rc, RGB(140, 160, 180), RGB(90, 120, 180));
452 |
453 | // 填充进度条背景色
454 | rc.DeflateRect(2, 2, 2, 2);
455 | pDC->FillSolidRect(&rc, RGB(239, 247, 255));
456 |
457 | // 画进度条
458 | int iTotalWidth = rc.Width();
459 | int iFinishedWidth = int(iTotalWidth * fPercent);
460 | rc.right = rc.left + iFinishedWidth;
461 | rc2 = rc;
462 | rc.DeflateRect(0, 0, 0, rc.Height() / 2 - 1);
463 | rc2.DeflateRect(0, rc2.Height() / 2 - 1, 0, 0);
464 | CUISkinManager::GradientFillRect(this, pDC, rc, GRADIENT_FILL_RECT_V, RGB(193, 231, 255), RGB(140, 186, 247));
465 | CUISkinManager::GradientFillRect(this, pDC, rc2, GRADIENT_FILL_RECT_V, RGB(140, 186, 247), RGB(173, 211, 247));
466 |
467 | m_strPromptTotalProgress.Format(STRING(STR_TOTAL_UPGRADE_PROGRESS,
468 | "升级总进度 %d / %d"),
469 | iFinishedFileCount >= iTotalFileCount ? iTotalFileCount : iFinishedFileCount + 1,
470 | iTotalFileCount);
471 | UpdateData(FALSE);
472 |
473 | // 画总进度条外框
474 | rc = rcWnd;
475 | rc.DeflateRect(30, 130, 30, 0);
476 | rc.bottom = rc.top + 18;
477 | pDC->Draw3dRect(&rc, RGB(200, 210, 220), RGB(30, 70, 100));
478 | rc.DeflateRect(1, 1, 1, 1);
479 | pDC->Draw3dRect(&rc, RGB(140, 160, 180), RGB(90, 120, 180));
480 |
481 | // 填充总进度条背景色
482 | rc.DeflateRect(2, 2, 2, 2);
483 | pDC->FillSolidRect(&rc, RGB(239, 247, 255));
484 |
485 | // 画总进度条
486 | iFinishedWidth = int(iTotalWidth * fTotalPercent);
487 | rc.right = rc.left + iFinishedWidth;
488 | rc2 = rc;
489 | rc.DeflateRect(0, 0, 0, rc.Height() / 2 - 1);
490 | rc2.DeflateRect(0, rc2.Height() / 2 - 1, 0, 0);
491 | CUISkinManager::GradientFillRect(this, pDC, rc, GRADIENT_FILL_RECT_V, RGB(193, 231, 255), RGB(140, 186, 247));
492 | CUISkinManager::GradientFillRect(this, pDC, rc2, GRADIENT_FILL_RECT_V, RGB(140, 186, 247), RGB(173, 211, 247));
493 |
494 | ReleaseDC(pDC);
495 | }
496 | }
497 |
498 | // 升级程序执行完毕
499 | void CAutoUpdateDlg::OnNotifyUpdateFinish(BOOL bSuccess)
500 | {
501 | m_pUpdateThread = NULL;
502 |
503 | if (m_bSilenceMode) {
504 | CDialog::OnOK();
505 | } else if (bSuccess) {
506 | m_strPrompt = STRING(STR_PROMPT_UPGRADE_FINISHED, "升级完毕!");
507 | m_btnCancel.SetWindowText(STRING(STR_BUTTON_SUCCESS_UPGRADE, "完成升级"));
508 | } else {
509 | m_strPromptTotalProgress = "";
510 | m_strTotalProgressBar = "";
511 | }
512 |
513 | m_strProgressBar = "";
514 | UpdateData(FALSE);
515 | if (!m_bSilenceMode && bSuccess) {
516 | // 升级完成,不必再次点击升级
517 | GetDlgItem(IDOK)->EnableWindow(FALSE);
518 | } else {
519 | GetDlgItem(IDOK)->EnableWindow();
520 | }
521 | }
--------------------------------------------------------------------------------
/Src/AutoUpdateDlg.h:
--------------------------------------------------------------------------------
1 | // AutoUpdateDlg.h : header file
2 | //
3 |
4 | #if !defined(AFX_AUTOUPDATEDLG_H__4CA1BB40_75FF_4A00_AF96_F141507CE885__INCLUDED_)
5 | #define AFX_AUTOUPDATEDLG_H__4CA1BB40_75FF_4A00_AF96_F141507CE885__INCLUDED_
6 |
7 | #if _MSC_VER > 1000
8 | #pragma once
9 | #endif // _MSC_VER > 1000
10 |
11 | /////////////////////////////////////////////////////////////////////////////
12 | // CAutoUpdateDlg dialog
13 |
14 | #include "RDialog.h"
15 |
16 | class CUpdateThread;
17 |
18 | /////////////////////////////////////////////////////////////////////////////
19 | // CAboutDlg dialog used for App About
20 |
21 | class CAboutDlg : public CDialog
22 | {
23 | public:
24 | CAboutDlg();
25 |
26 | // Dialog Data
27 | //{{AFX_DATA(CAboutDlg)
28 | enum { IDD = IDD_ABOUTBOX };
29 | //}}AFX_DATA
30 |
31 | // ClassWizard generated virtual function overrides
32 | //{{AFX_VIRTUAL(CAboutDlg)
33 | protected:
34 | // DDX/DDV support
35 | virtual void DoDataExchange(CDataExchange* pDX);
36 | virtual BOOL OnInitDialog();
37 |
38 | //}}AFX_VIRTUAL
39 |
40 | // Implementation
41 | protected:
42 | //{{AFX_MSG(CAboutDlg)
43 | //}}AFX_MSG
44 | DECLARE_MESSAGE_MAP()
45 | };
46 |
47 | class CAutoUpdateDlg : public CRDialog
48 | {
49 | // Construction
50 | public:
51 | // standard constructor
52 | CAutoUpdateDlg(CWnd* pParent = NULL);
53 | // 设置配置文件名
54 | BOOL SetConfigFile(CString& strFilename);
55 | BOOL DoUpdate(void);
56 | LRESULT OnUserMessage(WPARAM wParam, LPARAM lParam);
57 | void UpdateProgress(UINT iTotalFileCount, UINT iFinishedFileCount, float fTotalPercent, float fPercent);
58 | void OnNotifyUpdateFinish(BOOL bSuccess = TRUE);
59 |
60 | // Dialog Data
61 | //{{AFX_DATA(CAutoUpdateDlg)
62 | enum { IDD = IDD_AUTOUPDATE };
63 | CRButton m_btnUpgrade;
64 | CRButton m_btnCancel;
65 | // 应用程序名
66 | CString m_strAppName;
67 | // 下载文件进度提示信息
68 | CString m_strPrompt;
69 | // 升级总进度提示信息
70 | CString m_strPromptTotalProgress;
71 | // CString m_strStatus;
72 | // 下载文件进度条
73 | CString m_strProgressBar;
74 | // 升级总进度条
75 | CString m_strTotalProgressBar;
76 | // 静默方式执行升级,不显示升级程序界面,
77 | // 只在升级完毕后提醒用户
78 | BOOL m_bSilenceMode;
79 | // 用户终止升级
80 | BOOL m_bUserBreak;
81 | // 执行升级的线程
82 | CUpdateThread *m_pUpdateThread;
83 | //}}AFX_DATA
84 |
85 | // ClassWizard generated virtual function overrides
86 | //{{AFX_VIRTUAL(CAutoUpdateDlg)
87 | protected:
88 | // DDX/DDV support
89 | virtual void DoDataExchange(CDataExchange* pDX);
90 | //}}AFX_VIRTUAL
91 |
92 | // Implementation
93 | protected:
94 | // 升级配置文件名
95 | CString m_strConfigFileName;
96 | HICON m_hIcon;
97 |
98 | // Generated message map functions
99 | //{{AFX_MSG(CAutoUpdateDlg)
100 | virtual BOOL OnInitDialog();
101 | afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
102 | afx_msg void OnPaint();
103 | afx_msg HCURSOR OnQueryDragIcon();
104 | virtual void OnCancel();
105 | virtual void OnOK();
106 | //}}AFX_MSG
107 | DECLARE_MESSAGE_MAP()
108 |
109 | private:
110 | // 要下载的文件总数和大小总和
111 | DOWNLOAD_INFO_STRU m_TotalFileInfo;
112 | // 已下载的文件总数和大小总和
113 | DOWNLOAD_INFO_STRU m_FinishedFileInfo;
114 | // 当前正在下载的文件进度
115 | float m_fDownloadPercent;
116 | // 所有要下载的文件总进度
117 | float m_fTotalDownloadPercent;
118 | };
119 |
120 | //{{AFX_INSERT_LOCATION}}
121 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
122 |
123 | #endif // !defined(AFX_AUTOUPDATEDLG_H__4CA1BB40_75FF_4A00_AF96_F141507CE885__INCLUDED_)
124 |
--------------------------------------------------------------------------------
/Src/FileMD5.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/FileMD5.cpp
--------------------------------------------------------------------------------
/Src/HttpClient.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/HttpClient.cpp
--------------------------------------------------------------------------------
/Src/HttpClient.h:
--------------------------------------------------------------------------------
1 | #ifndef __HTTP_CLIENT_CURL_H__
2 | #define __HTTP_CLIENT_CURL_H__
3 |
4 | #include
5 |
6 | class CHttpClient
7 | {
8 | public:
9 | CHttpClient(void);
10 | ~CHttpClient(void);
11 |
12 | public:
13 | /**
14 | * @brief HTTP POST请求
15 | * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com
16 | * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&…
17 | * @param strResponse 输出参数,返回的内容
18 | * @return 返回是否Post成功
19 | */
20 | int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse);
21 |
22 | /**
23 | * @brief HTTP GET请求
24 | * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com
25 | * @param strResponse 输出参数,返回的内容
26 | * @return 返回是否Post成功
27 | */
28 | int Get(const std::string & strUrl, std::string & strResponse);
29 |
30 | /**
31 | * @brief HTTPS POST请求,无证书版本
32 | * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com
33 | * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&…
34 | * @param strResponse 输出参数,返回的内容
35 | * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性.
36 | * @return 返回是否Post成功
37 | */
38 | int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL);
39 |
40 | /**
41 | * @brief HTTPS GET请求,无证书版本
42 | * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com
43 | * @param strResponse 输出参数,返回的内容
44 | * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性.
45 | * @return 返回是否Post成功
46 | */
47 | int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL);
48 |
49 | public:
50 | void SetDebug(bool bDebug);
51 |
52 | private:
53 | bool m_bDebug;
54 | };
55 |
56 | #endif
--------------------------------------------------------------------------------
/Src/Include/curl/curlver.h:
--------------------------------------------------------------------------------
1 | #ifndef __CURL_CURLVER_H
2 | #define __CURL_CURLVER_H
3 | /***************************************************************************
4 | * _ _ ____ _
5 | * Project ___| | | | _ \| |
6 | * / __| | | | |_) | |
7 | * | (__| |_| | _ <| |___
8 | * \___|\___/|_| \_\_____|
9 | *
10 | * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al.
11 | *
12 | * This software is licensed as described in the file COPYING, which
13 | * you should have received as part of this distribution. The terms
14 | * are also available at https://curl.haxx.se/docs/copyright.html.
15 | *
16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17 | * copies of the Software, and permit persons to whom the Software is
18 | * furnished to do so, under the terms of the COPYING file.
19 | *
20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 | * KIND, either express or implied.
22 | *
23 | ***************************************************************************/
24 |
25 | /* This header file contains nothing but libcurl version info, generated by
26 | a script at release-time. This was made its own header file in 7.11.2 */
27 |
28 | /* This is the global package copyright */
29 | #define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, ."
30 |
31 | /* This is the version number of the libcurl package from which this header
32 | file origins: */
33 | #define LIBCURL_VERSION "7.56.1"
34 |
35 | /* The numeric version number is also available "in parts" by using these
36 | defines: */
37 | #define LIBCURL_VERSION_MAJOR 7
38 | #define LIBCURL_VERSION_MINOR 56
39 | #define LIBCURL_VERSION_PATCH 1
40 |
41 | /* This is the numeric version of the libcurl version number, meant for easier
42 | parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
43 | always follow this syntax:
44 |
45 | 0xXXYYZZ
46 |
47 | Where XX, YY and ZZ are the main version, release and patch numbers in
48 | hexadecimal (using 8 bits each). All three numbers are always represented
49 | using two digits. 1.2 would appear as "0x010200" while version 9.11.7
50 | appears as "0x090b07".
51 |
52 | This 6-digit (24 bits) hexadecimal number does not show pre-release number,
53 | and it is always a greater number in a more recent release. It makes
54 | comparisons with greater than and less than work.
55 |
56 | Note: This define is the full hex number and _does not_ use the
57 | CURL_VERSION_BITS() macro since curl's own configure script greps for it
58 | and needs it to contain the full number.
59 | */
60 | #define LIBCURL_VERSION_NUM 0x073801
61 |
62 | /*
63 | * This is the date and time when the full source package was created. The
64 | * timestamp is not stored in git, as the timestamp is properly set in the
65 | * tarballs by the maketgz script.
66 | *
67 | * The format of the date follows this template:
68 | *
69 | * "2007-11-23"
70 | */
71 | #define LIBCURL_TIMESTAMP "2017-10-23"
72 |
73 | #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
74 | #define CURL_AT_LEAST_VERSION(x,y,z) \
75 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
76 |
77 | #endif /* __CURL_CURLVER_H */
78 |
--------------------------------------------------------------------------------
/Src/Include/curl/easy.h:
--------------------------------------------------------------------------------
1 | #ifndef __CURL_EASY_H
2 | #define __CURL_EASY_H
3 | /***************************************************************************
4 | * _ _ ____ _
5 | * Project ___| | | | _ \| |
6 | * / __| | | | |_) | |
7 | * | (__| |_| | _ <| |___
8 | * \___|\___/|_| \_\_____|
9 | *
10 | * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al.
11 | *
12 | * This software is licensed as described in the file COPYING, which
13 | * you should have received as part of this distribution. The terms
14 | * are also available at https://curl.haxx.se/docs/copyright.html.
15 | *
16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17 | * copies of the Software, and permit persons to whom the Software is
18 | * furnished to do so, under the terms of the COPYING file.
19 | *
20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 | * KIND, either express or implied.
22 | *
23 | ***************************************************************************/
24 | #ifdef __cplusplus
25 | extern "C" {
26 | #endif
27 |
28 | CURL_EXTERN CURL *curl_easy_init(void);
29 | CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
30 | CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
31 | CURL_EXTERN void curl_easy_cleanup(CURL *curl);
32 |
33 | /*
34 | * NAME curl_easy_getinfo()
35 | *
36 | * DESCRIPTION
37 | *
38 | * Request internal information from the curl session with this function. The
39 | * third argument MUST be a pointer to a long, a pointer to a char * or a
40 | * pointer to a double (as the documentation describes elsewhere). The data
41 | * pointed to will be filled in accordingly and can be relied upon only if the
42 | * function returns CURLE_OK. This function is intended to get used *AFTER* a
43 | * performed transfer, all results from this function are undefined until the
44 | * transfer is completed.
45 | */
46 | CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
47 |
48 |
49 | /*
50 | * NAME curl_easy_duphandle()
51 | *
52 | * DESCRIPTION
53 | *
54 | * Creates a new curl session handle with the same options set for the handle
55 | * passed in. Duplicating a handle could only be a matter of cloning data and
56 | * options, internal state info and things like persistent connections cannot
57 | * be transferred. It is useful in multithreaded applications when you can run
58 | * curl_easy_duphandle() for each new thread to avoid a series of identical
59 | * curl_easy_setopt() invokes in every thread.
60 | */
61 | CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
62 |
63 | /*
64 | * NAME curl_easy_reset()
65 | *
66 | * DESCRIPTION
67 | *
68 | * Re-initializes a CURL handle to the default values. This puts back the
69 | * handle to the same state as it was in when it was just created.
70 | *
71 | * It does keep: live connections, the Session ID cache, the DNS cache and the
72 | * cookies.
73 | */
74 | CURL_EXTERN void curl_easy_reset(CURL *curl);
75 |
76 | /*
77 | * NAME curl_easy_recv()
78 | *
79 | * DESCRIPTION
80 | *
81 | * Receives data from the connected socket. Use after successful
82 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
83 | */
84 | CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
85 | size_t *n);
86 |
87 | /*
88 | * NAME curl_easy_send()
89 | *
90 | * DESCRIPTION
91 | *
92 | * Sends data over the connected socket. Use after successful
93 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
94 | */
95 | CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
96 | size_t buflen, size_t *n);
97 |
98 | #ifdef __cplusplus
99 | }
100 | #endif
101 |
102 | #endif
103 |
--------------------------------------------------------------------------------
/Src/Include/curl/mprintf.h:
--------------------------------------------------------------------------------
1 | #ifndef __CURL_MPRINTF_H
2 | #define __CURL_MPRINTF_H
3 | /***************************************************************************
4 | * _ _ ____ _
5 | * Project ___| | | | _ \| |
6 | * / __| | | | |_) | |
7 | * | (__| |_| | _ <| |___
8 | * \___|\___/|_| \_\_____|
9 | *
10 | * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al.
11 | *
12 | * This software is licensed as described in the file COPYING, which
13 | * you should have received as part of this distribution. The terms
14 | * are also available at https://curl.haxx.se/docs/copyright.html.
15 | *
16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17 | * copies of the Software, and permit persons to whom the Software is
18 | * furnished to do so, under the terms of the COPYING file.
19 | *
20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 | * KIND, either express or implied.
22 | *
23 | ***************************************************************************/
24 |
25 | #include
26 | #include /* needed for FILE */
27 | #include "curl.h" /* for CURL_EXTERN */
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | CURL_EXTERN int curl_mprintf(const char *format, ...);
34 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
35 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
36 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
37 | const char *format, ...);
38 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
39 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
40 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
41 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
42 | const char *format, va_list args);
43 | CURL_EXTERN char *curl_maprintf(const char *format, ...);
44 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
45 |
46 | #ifdef __cplusplus
47 | }
48 | #endif
49 |
50 | #endif /* __CURL_MPRINTF_H */
51 |
--------------------------------------------------------------------------------
/Src/Include/curl/stdcheaders.h:
--------------------------------------------------------------------------------
1 | #ifndef __STDC_HEADERS_H
2 | #define __STDC_HEADERS_H
3 | /***************************************************************************
4 | * _ _ ____ _
5 | * Project ___| | | | _ \| |
6 | * / __| | | | |_) | |
7 | * | (__| |_| | _ <| |___
8 | * \___|\___/|_| \_\_____|
9 | *
10 | * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al.
11 | *
12 | * This software is licensed as described in the file COPYING, which
13 | * you should have received as part of this distribution. The terms
14 | * are also available at https://curl.haxx.se/docs/copyright.html.
15 | *
16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17 | * copies of the Software, and permit persons to whom the Software is
18 | * furnished to do so, under the terms of the COPYING file.
19 | *
20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 | * KIND, either express or implied.
22 | *
23 | ***************************************************************************/
24 |
25 | #include
26 |
27 | size_t fread(void *, size_t, size_t, FILE *);
28 | size_t fwrite(const void *, size_t, size_t, FILE *);
29 |
30 | int strcasecmp(const char *, const char *);
31 | int strncasecmp(const char *, const char *, size_t);
32 |
33 | #endif /* __STDC_HEADERS_H */
34 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/allocator.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef CPPTL_JSON_ALLOCATOR_H_INCLUDED
7 | #define CPPTL_JSON_ALLOCATOR_H_INCLUDED
8 |
9 | #include
10 | #include
11 |
12 | #pragma pack(push, 8)
13 |
14 | namespace Json {
15 | template
16 | class SecureAllocator {
17 | public:
18 | // Type definitions
19 | using value_type = T;
20 | using pointer = T*;
21 | using const_pointer = const T*;
22 | using reference = T&;
23 | using const_reference = const T&;
24 | using size_type = std::size_t;
25 | using difference_type = std::ptrdiff_t;
26 |
27 | /**
28 | * Allocate memory for N items using the standard allocator.
29 | */
30 | pointer allocate(size_type n) {
31 | // allocate using "global operator new"
32 | return static_cast(::operator new(n * sizeof(T)));
33 | }
34 |
35 | /**
36 | * Release memory which was allocated for N items at pointer P.
37 | *
38 | * The memory block is filled with zeroes before being released.
39 | * The pointer argument is tagged as "volatile" to prevent the
40 | * compiler optimizing out this critical step.
41 | */
42 | void deallocate(volatile pointer p, size_type n) {
43 | std::memset(p, 0, n * sizeof(T));
44 | // free using "global operator delete"
45 | ::operator delete(p);
46 | }
47 |
48 | /**
49 | * Construct an item in-place at pointer P.
50 | */
51 | template
52 | void construct(pointer p, Args&&... args) {
53 | // construct using "placement new" and "perfect forwarding"
54 | ::new (static_cast(p)) T(std::forward(args)...);
55 | }
56 |
57 | size_type max_size() const {
58 | return size_t(-1) / sizeof(T);
59 | }
60 |
61 | pointer address( reference x ) const {
62 | return std::addressof(x);
63 | }
64 |
65 | const_pointer address( const_reference x ) const {
66 | return std::addressof(x);
67 | }
68 |
69 | /**
70 | * Destroy an item in-place at pointer P.
71 | */
72 | void destroy(pointer p) {
73 | // destroy using "explicit destructor"
74 | p->~T();
75 | }
76 |
77 | // Boilerplate
78 | SecureAllocator() {}
79 | template SecureAllocator(const SecureAllocator&) {}
80 | template struct rebind { using other = SecureAllocator; };
81 | };
82 |
83 |
84 | template
85 | bool operator==(const SecureAllocator&, const SecureAllocator&) {
86 | return true;
87 | }
88 |
89 | template
90 | bool operator!=(const SecureAllocator&, const SecureAllocator&) {
91 | return false;
92 | }
93 |
94 | } //namespace Json
95 |
96 | #pragma pack(pop)
97 |
98 | #endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED
99 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/assertions.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
7 | #define CPPTL_JSON_ASSERTIONS_H_INCLUDED
8 |
9 | #include
10 | #include
11 |
12 | #if !defined(JSON_IS_AMALGAMATION)
13 | #include "config.h"
14 | #endif // if !defined(JSON_IS_AMALGAMATION)
15 |
16 | /** It should not be possible for a maliciously designed file to
17 | * cause an abort() or seg-fault, so these macros are used only
18 | * for pre-condition violations and internal logic errors.
19 | */
20 | #if JSON_USE_EXCEPTION
21 |
22 | // @todo <= add detail about condition in exception
23 | # define JSON_ASSERT(condition) \
24 | {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
25 |
26 | # define JSON_FAIL_MESSAGE(message) \
27 | { \
28 | JSONCPP_OSTRINGSTREAM oss; oss << message; \
29 | Json::throwLogicError(oss.str()); \
30 | abort(); \
31 | }
32 |
33 | #else // JSON_USE_EXCEPTION
34 |
35 | # define JSON_ASSERT(condition) assert(condition)
36 |
37 | // The call to assert() will show the failure message in debug builds. In
38 | // release builds we abort, for a core-dump or debugger.
39 | # define JSON_FAIL_MESSAGE(message) \
40 | { \
41 | JSONCPP_OSTRINGSTREAM oss; oss << message; \
42 | assert(false && oss.str().c_str()); \
43 | abort(); \
44 | }
45 |
46 |
47 | #endif
48 |
49 | #define JSON_ASSERT_MESSAGE(condition, message) \
50 | if (!(condition)) { \
51 | JSON_FAIL_MESSAGE(message); \
52 | }
53 |
54 | #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED
55 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/autolink.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef JSON_AUTOLINK_H_INCLUDED
7 | #define JSON_AUTOLINK_H_INCLUDED
8 |
9 | #include "config.h"
10 |
11 | #ifdef JSON_IN_CPPTL
12 | #include
13 | #endif
14 |
15 | #if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && \
16 | !defined(JSON_IN_CPPTL)
17 | #define CPPTL_AUTOLINK_NAME "json"
18 | #undef CPPTL_AUTOLINK_DLL
19 | #ifdef JSON_DLL
20 | #define CPPTL_AUTOLINK_DLL
21 | #endif
22 | #include "autolink.h"
23 | #endif
24 |
25 | #endif // JSON_AUTOLINK_H_INCLUDED
26 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/config.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef JSON_CONFIG_H_INCLUDED
7 | #define JSON_CONFIG_H_INCLUDED
8 | #include
9 | #include //typedef String
10 | #include //typedef int64_t, uint64_t
11 |
12 | /// If defined, indicates that json library is embedded in CppTL library.
13 | //# define JSON_IN_CPPTL 1
14 |
15 | /// If defined, indicates that json may leverage CppTL library
16 | //# define JSON_USE_CPPTL 1
17 | /// If defined, indicates that cpptl vector based map should be used instead of
18 | /// std::map
19 | /// as Value container.
20 | //# define JSON_USE_CPPTL_SMALLMAP 1
21 |
22 | // If non-zero, the library uses exceptions to report bad input instead of C
23 | // assertion macros. The default is to use exceptions.
24 | #ifndef JSON_USE_EXCEPTION
25 | #define JSON_USE_EXCEPTION 1
26 | #endif
27 |
28 | /// If defined, indicates that the source file is amalgated
29 | /// to prevent private header inclusion.
30 | /// Remarks: it is automatically defined in the generated amalgated header.
31 | // #define JSON_IS_AMALGAMATION
32 |
33 | #ifdef JSON_IN_CPPTL
34 | #include
35 | #ifndef JSON_USE_CPPTL
36 | #define JSON_USE_CPPTL 1
37 | #endif
38 | #endif
39 |
40 | #ifdef JSON_IN_CPPTL
41 | #define JSON_API CPPTL_API
42 | #elif defined(JSON_DLL_BUILD)
43 | #if defined(_MSC_VER) || defined(__MINGW32__)
44 | #define JSON_API __declspec(dllexport)
45 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
46 | #endif // if defined(_MSC_VER)
47 | #elif defined(JSON_DLL)
48 | #if defined(_MSC_VER) || defined(__MINGW32__)
49 | #define JSON_API __declspec(dllimport)
50 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
51 | #endif // if defined(_MSC_VER)
52 | #endif // ifdef JSON_IN_CPPTL
53 | #if !defined(JSON_API)
54 | #define JSON_API
55 | #endif
56 |
57 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
58 | // integer
59 | // Storages, and 64 bits integer support is disabled.
60 | // #define JSON_NO_INT64 1
61 |
62 | #if defined(_MSC_VER) // MSVC
63 | # if _MSC_VER <= 1200 // MSVC 6
64 | // Microsoft Visual Studio 6 only support conversion from __int64 to double
65 | // (no conversion from unsigned __int64).
66 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1
67 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
68 | // characters in the debug information)
69 | // All projects I've ever seen with VS6 were using this globally (not bothering
70 | // with pragma push/pop).
71 | # pragma warning(disable : 4786)
72 | # endif // MSVC 6
73 |
74 | # if _MSC_VER >= 1500 // MSVC 2008
75 | /// Indicates that the following function is deprecated.
76 | # define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
77 | # endif
78 |
79 | #endif // defined(_MSC_VER)
80 |
81 | // In c++11 the override keyword allows you to explicity define that a function
82 | // is intended to override the base-class version. This makes the code more
83 | // managable and fixes a set of common hard-to-find bugs.
84 | #if __cplusplus >= 201103L
85 | # define JSONCPP_OVERRIDE override
86 | # define JSONCPP_NOEXCEPT noexcept
87 | #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
88 | # define JSONCPP_OVERRIDE override
89 | # define JSONCPP_NOEXCEPT throw()
90 | #elif defined(_MSC_VER) && _MSC_VER >= 1900
91 | # define JSONCPP_OVERRIDE override
92 | # define JSONCPP_NOEXCEPT noexcept
93 | #else
94 | # define JSONCPP_OVERRIDE
95 | # define JSONCPP_NOEXCEPT throw()
96 | #endif
97 |
98 | #ifndef JSON_HAS_RVALUE_REFERENCES
99 |
100 | #if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
101 | #define JSON_HAS_RVALUE_REFERENCES 1
102 | #endif // MSVC >= 2010
103 |
104 | #ifdef __clang__
105 | #if __has_feature(cxx_rvalue_references)
106 | #define JSON_HAS_RVALUE_REFERENCES 1
107 | #endif // has_feature
108 |
109 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
110 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
111 | #define JSON_HAS_RVALUE_REFERENCES 1
112 | #endif // GXX_EXPERIMENTAL
113 |
114 | #endif // __clang__ || __GNUC__
115 |
116 | #endif // not defined JSON_HAS_RVALUE_REFERENCES
117 |
118 | #ifndef JSON_HAS_RVALUE_REFERENCES
119 | #define JSON_HAS_RVALUE_REFERENCES 0
120 | #endif
121 |
122 | #ifdef __clang__
123 | # if __has_extension(attribute_deprecated_with_message)
124 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
125 | # endif
126 | #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
127 | # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
128 | # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
129 | # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
130 | # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
131 | # endif // GNUC version
132 | #endif // __clang__ || __GNUC__
133 |
134 | #if !defined(JSONCPP_DEPRECATED)
135 | #define JSONCPP_DEPRECATED(message)
136 | #endif // if !defined(JSONCPP_DEPRECATED)
137 |
138 | #if __GNUC__ >= 6
139 | # define JSON_USE_INT64_DOUBLE_CONVERSION 1
140 | #endif
141 |
142 | #if !defined(JSON_IS_AMALGAMATION)
143 |
144 | # include "version.h"
145 |
146 | # if JSONCPP_USING_SECURE_MEMORY
147 | # include "allocator.h" //typedef Allocator
148 | # endif
149 |
150 | #endif // if !defined(JSON_IS_AMALGAMATION)
151 |
152 | namespace Json {
153 | typedef int Int;
154 | typedef unsigned int UInt;
155 | #if defined(JSON_NO_INT64)
156 | typedef int LargestInt;
157 | typedef unsigned int LargestUInt;
158 | #undef JSON_HAS_INT64
159 | #else // if defined(JSON_NO_INT64)
160 | // For Microsoft Visual use specific types as long long is not supported
161 | #if defined(_MSC_VER) // Microsoft Visual Studio
162 | typedef __int64 Int64;
163 | typedef unsigned __int64 UInt64;
164 | #else // if defined(_MSC_VER) // Other platforms, use long long
165 | typedef int64_t Int64;
166 | typedef uint64_t UInt64;
167 | #endif // if defined(_MSC_VER)
168 | typedef Int64 LargestInt;
169 | typedef UInt64 LargestUInt;
170 | #define JSON_HAS_INT64
171 | #endif // if defined(JSON_NO_INT64)
172 | #if JSONCPP_USING_SECURE_MEMORY
173 | #define JSONCPP_STRING std::basic_string, Json::SecureAllocator >
174 | #define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator >
175 | #define JSONCPP_OSTREAM std::basic_ostream>
176 | #define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator >
177 | #define JSONCPP_ISTREAM std::istream
178 | #else
179 | #define JSONCPP_STRING std::string
180 | #define JSONCPP_OSTRINGSTREAM std::ostringstream
181 | #define JSONCPP_OSTREAM std::ostream
182 | #define JSONCPP_ISTRINGSTREAM std::istringstream
183 | #define JSONCPP_ISTREAM std::istream
184 | #endif // if JSONCPP_USING_SECURE_MEMORY
185 | } // end namespace Json
186 |
187 | #endif // JSON_CONFIG_H_INCLUDED
188 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/features.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef CPPTL_JSON_FEATURES_H_INCLUDED
7 | #define CPPTL_JSON_FEATURES_H_INCLUDED
8 |
9 | #if !defined(JSON_IS_AMALGAMATION)
10 | #include "forwards.h"
11 | #endif // if !defined(JSON_IS_AMALGAMATION)
12 |
13 | #pragma pack(push, 8)
14 |
15 | namespace Json {
16 |
17 | /** \brief Configuration passed to reader and writer.
18 | * This configuration object can be used to force the Reader or Writer
19 | * to behave in a standard conforming way.
20 | */
21 | class JSON_API Features {
22 | public:
23 | /** \brief A configuration that allows all features and assumes all strings
24 | * are UTF-8.
25 | * - C & C++ comments are allowed
26 | * - Root object can be any JSON value
27 | * - Assumes Value strings are encoded in UTF-8
28 | */
29 | static Features all();
30 |
31 | /** \brief A configuration that is strictly compatible with the JSON
32 | * specification.
33 | * - Comments are forbidden.
34 | * - Root object must be either an array or an object value.
35 | * - Assumes Value strings are encoded in UTF-8
36 | */
37 | static Features strictMode();
38 |
39 | /** \brief Initialize the configuration like JsonConfig::allFeatures;
40 | */
41 | Features();
42 |
43 | /// \c true if comments are allowed. Default: \c true.
44 | bool allowComments_;
45 |
46 | /// \c true if root must be either an array or an object value. Default: \c
47 | /// false.
48 | bool strictRoot_;
49 |
50 | /// \c true if dropped null placeholders are allowed. Default: \c false.
51 | bool allowDroppedNullPlaceholders_;
52 |
53 | /// \c true if numeric object key are allowed. Default: \c false.
54 | bool allowNumericKeys_;
55 | };
56 |
57 | } // namespace Json
58 |
59 | #pragma pack(pop)
60 |
61 | #endif // CPPTL_JSON_FEATURES_H_INCLUDED
62 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/forwards.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef JSON_FORWARDS_H_INCLUDED
7 | #define JSON_FORWARDS_H_INCLUDED
8 |
9 | #if !defined(JSON_IS_AMALGAMATION)
10 | #include "config.h"
11 | #endif // if !defined(JSON_IS_AMALGAMATION)
12 |
13 | namespace Json {
14 |
15 | // writer.h
16 | class FastWriter;
17 | class StyledWriter;
18 |
19 | // reader.h
20 | class Reader;
21 |
22 | // features.h
23 | class Features;
24 |
25 | // value.h
26 | typedef unsigned int ArrayIndex;
27 | class StaticString;
28 | class Path;
29 | class PathArgument;
30 | class Value;
31 | class ValueIteratorBase;
32 | class ValueIterator;
33 | class ValueConstIterator;
34 |
35 | } // namespace Json
36 |
37 | #endif // JSON_FORWARDS_H_INCLUDED
38 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/json.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef JSON_JSON_H_INCLUDED
7 | #define JSON_JSON_H_INCLUDED
8 |
9 | #include "autolink.h"
10 | #include "value.h"
11 | #include "reader.h"
12 | #include "writer.h"
13 | #include "features.h"
14 |
15 | #endif // JSON_JSON_H_INCLUDED
16 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/reader.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef CPPTL_JSON_READER_H_INCLUDED
7 | #define CPPTL_JSON_READER_H_INCLUDED
8 |
9 | #if !defined(JSON_IS_AMALGAMATION)
10 | #include "features.h"
11 | #include "value.h"
12 | #endif // if !defined(JSON_IS_AMALGAMATION)
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | // Disable warning C4251: : needs to have dll-interface to
20 | // be used by...
21 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
22 | #pragma warning(push)
23 | #pragma warning(disable : 4251)
24 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
25 |
26 | #pragma pack(push, 8)
27 |
28 | namespace Json {
29 |
30 | /** \brief Unserialize a JSON document into a
31 | *Value.
32 | *
33 | * \deprecated Use CharReader and CharReaderBuilder.
34 | */
35 | class JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") JSON_API Reader {
36 | public:
37 | typedef char Char;
38 | typedef const Char* Location;
39 |
40 | /** \brief An error tagged with where in the JSON text it was encountered.
41 | *
42 | * The offsets give the [start, limit) range of bytes within the text. Note
43 | * that this is bytes, not codepoints.
44 | *
45 | */
46 | struct StructuredError {
47 | ptrdiff_t offset_start;
48 | ptrdiff_t offset_limit;
49 | JSONCPP_STRING message;
50 | };
51 |
52 | /** \brief Constructs a Reader allowing all features
53 | * for parsing.
54 | */
55 | Reader();
56 |
57 | /** \brief Constructs a Reader allowing the specified feature set
58 | * for parsing.
59 | */
60 | Reader(const Features& features);
61 |
62 | /** \brief Read a Value from a JSON
63 | * document.
64 | * \param document UTF-8 encoded string containing the document to read.
65 | * \param root [out] Contains the root value of the document if it was
66 | * successfully parsed.
67 | * \param collectComments \c true to collect comment and allow writing them
68 | * back during
69 | * serialization, \c false to discard comments.
70 | * This parameter is ignored if
71 | * Features::allowComments_
72 | * is \c false.
73 | * \return \c true if the document was successfully parsed, \c false if an
74 | * error occurred.
75 | */
76 | bool
77 | parse(const std::string& document, Value& root, bool collectComments = true);
78 |
79 | /** \brief Read a Value from a JSON
80 | document.
81 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
82 | document to read.
83 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the
84 | document to read.
85 | * Must be >= beginDoc.
86 | * \param root [out] Contains the root value of the document if it was
87 | * successfully parsed.
88 | * \param collectComments \c true to collect comment and allow writing them
89 | back during
90 | * serialization, \c false to discard comments.
91 | * This parameter is ignored if
92 | Features::allowComments_
93 | * is \c false.
94 | * \return \c true if the document was successfully parsed, \c false if an
95 | error occurred.
96 | */
97 | bool parse(const char* beginDoc,
98 | const char* endDoc,
99 | Value& root,
100 | bool collectComments = true);
101 |
102 | /// \brief Parse from input stream.
103 | /// \see Json::operator>>(std::istream&, Json::Value&).
104 | bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
105 |
106 | /** \brief Returns a user friendly string that list errors in the parsed
107 | * document.
108 | * \return Formatted error message with the list of errors with their location
109 | * in
110 | * the parsed document. An empty string is returned if no error
111 | * occurred
112 | * during parsing.
113 | * \deprecated Use getFormattedErrorMessages() instead (typo fix).
114 | */
115 | JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
116 | JSONCPP_STRING getFormatedErrorMessages() const;
117 |
118 | /** \brief Returns a user friendly string that list errors in the parsed
119 | * document.
120 | * \return Formatted error message with the list of errors with their location
121 | * in
122 | * the parsed document. An empty string is returned if no error
123 | * occurred
124 | * during parsing.
125 | */
126 | JSONCPP_STRING getFormattedErrorMessages() const;
127 |
128 | /** \brief Returns a vector of structured erros encounted while parsing.
129 | * \return A (possibly empty) vector of StructuredError objects. Currently
130 | * only one error can be returned, but the caller should tolerate
131 | * multiple
132 | * errors. This can occur if the parser recovers from a non-fatal
133 | * parse error and then encounters additional errors.
134 | */
135 | std::vector getStructuredErrors() const;
136 |
137 | /** \brief Add a semantic error message.
138 | * \param value JSON Value location associated with the error
139 | * \param message The error message.
140 | * \return \c true if the error was successfully added, \c false if the
141 | * Value offset exceeds the document size.
142 | */
143 | bool pushError(const Value& value, const JSONCPP_STRING& message);
144 |
145 | /** \brief Add a semantic error message with extra context.
146 | * \param value JSON Value location associated with the error
147 | * \param message The error message.
148 | * \param extra Additional JSON Value location to contextualize the error
149 | * \return \c true if the error was successfully added, \c false if either
150 | * Value offset exceeds the document size.
151 | */
152 | bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
153 |
154 | /** \brief Return whether there are any errors.
155 | * \return \c true if there are no errors to report \c false if
156 | * errors have occurred.
157 | */
158 | bool good() const;
159 |
160 | private:
161 | enum TokenType {
162 | tokenEndOfStream = 0,
163 | tokenObjectBegin,
164 | tokenObjectEnd,
165 | tokenArrayBegin,
166 | tokenArrayEnd,
167 | tokenString,
168 | tokenNumber,
169 | tokenTrue,
170 | tokenFalse,
171 | tokenNull,
172 | tokenArraySeparator,
173 | tokenMemberSeparator,
174 | tokenComment,
175 | tokenError
176 | };
177 |
178 | class Token {
179 | public:
180 | TokenType type_;
181 | Location start_;
182 | Location end_;
183 | };
184 |
185 | class ErrorInfo {
186 | public:
187 | Token token_;
188 | JSONCPP_STRING message_;
189 | Location extra_;
190 | };
191 |
192 | typedef std::deque Errors;
193 |
194 | bool readToken(Token& token);
195 | void skipSpaces();
196 | bool match(Location pattern, int patternLength);
197 | bool readComment();
198 | bool readCStyleComment();
199 | bool readCppStyleComment();
200 | bool readString();
201 | void readNumber();
202 | bool readValue();
203 | bool readObject(Token& token);
204 | bool readArray(Token& token);
205 | bool decodeNumber(Token& token);
206 | bool decodeNumber(Token& token, Value& decoded);
207 | bool decodeString(Token& token);
208 | bool decodeString(Token& token, JSONCPP_STRING& decoded);
209 | bool decodeDouble(Token& token);
210 | bool decodeDouble(Token& token, Value& decoded);
211 | bool decodeUnicodeCodePoint(Token& token,
212 | Location& current,
213 | Location end,
214 | unsigned int& unicode);
215 | bool decodeUnicodeEscapeSequence(Token& token,
216 | Location& current,
217 | Location end,
218 | unsigned int& unicode);
219 | bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
220 | bool recoverFromError(TokenType skipUntilToken);
221 | bool addErrorAndRecover(const JSONCPP_STRING& message,
222 | Token& token,
223 | TokenType skipUntilToken);
224 | void skipUntilSpace();
225 | Value& currentValue();
226 | Char getNextChar();
227 | void
228 | getLocationLineAndColumn(Location location, int& line, int& column) const;
229 | JSONCPP_STRING getLocationLineAndColumn(Location location) const;
230 | void addComment(Location begin, Location end, CommentPlacement placement);
231 | void skipCommentTokens(Token& token);
232 |
233 | static bool containsNewLine(Location begin, Location end);
234 | static JSONCPP_STRING normalizeEOL(Location begin, Location end);
235 |
236 | typedef std::stack Nodes;
237 | Nodes nodes_;
238 | Errors errors_;
239 | JSONCPP_STRING document_;
240 | Location begin_;
241 | Location end_;
242 | Location current_;
243 | Location lastValueEnd_;
244 | Value* lastValue_;
245 | JSONCPP_STRING commentsBefore_;
246 | Features features_;
247 | bool collectComments_;
248 | }; // Reader
249 |
250 | /** Interface for reading JSON from a char array.
251 | */
252 | class JSON_API CharReader {
253 | public:
254 | virtual ~CharReader() {}
255 | /** \brief Read a Value from a JSON
256 | document.
257 | * The document must be a UTF-8 encoded string containing the document to read.
258 | *
259 | * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
260 | document to read.
261 | * \param endDoc Pointer on the end of the UTF-8 encoded string of the
262 | document to read.
263 | * Must be >= beginDoc.
264 | * \param root [out] Contains the root value of the document if it was
265 | * successfully parsed.
266 | * \param errs [out] Formatted error messages (if not NULL)
267 | * a user friendly string that lists errors in the parsed
268 | * document.
269 | * \return \c true if the document was successfully parsed, \c false if an
270 | error occurred.
271 | */
272 | virtual bool parse(
273 | char const* beginDoc, char const* endDoc,
274 | Value* root, JSONCPP_STRING* errs) = 0;
275 |
276 | class JSON_API Factory {
277 | public:
278 | virtual ~Factory() {}
279 | /** \brief Allocate a CharReader via operator new().
280 | * \throw std::exception if something goes wrong (e.g. invalid settings)
281 | */
282 | virtual CharReader* newCharReader() const = 0;
283 | }; // Factory
284 | }; // CharReader
285 |
286 | /** \brief Build a CharReader implementation.
287 |
288 | Usage:
289 | \code
290 | using namespace Json;
291 | CharReaderBuilder builder;
292 | builder["collectComments"] = false;
293 | Value value;
294 | JSONCPP_STRING errs;
295 | bool ok = parseFromStream(builder, std::cin, &value, &errs);
296 | \endcode
297 | */
298 | class JSON_API CharReaderBuilder : public CharReader::Factory {
299 | public:
300 | // Note: We use a Json::Value so that we can add data-members to this class
301 | // without a major version bump.
302 | /** Configuration of this builder.
303 | These are case-sensitive.
304 | Available settings (case-sensitive):
305 | - `"collectComments": false or true`
306 | - true to collect comment and allow writing them
307 | back during serialization, false to discard comments.
308 | This parameter is ignored if allowComments is false.
309 | - `"allowComments": false or true`
310 | - true if comments are allowed.
311 | - `"strictRoot": false or true`
312 | - true if root must be either an array or an object value
313 | - `"allowDroppedNullPlaceholders": false or true`
314 | - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
315 | - `"allowNumericKeys": false or true`
316 | - true if numeric object keys are allowed.
317 | - `"allowSingleQuotes": false or true`
318 | - true if '' are allowed for strings (both keys and values)
319 | - `"stackLimit": integer`
320 | - Exceeding stackLimit (recursive depth of `readValue()`) will
321 | cause an exception.
322 | - This is a security issue (seg-faults caused by deeply nested JSON),
323 | so the default is low.
324 | - `"failIfExtra": false or true`
325 | - If true, `parse()` returns false when extra non-whitespace trails
326 | the JSON value in the input string.
327 | - `"rejectDupKeys": false or true`
328 | - If true, `parse()` returns false when a key is duplicated within an object.
329 | - `"allowSpecialFloats": false or true`
330 | - If true, special float values (NaNs and infinities) are allowed
331 | and their values are lossfree restorable.
332 |
333 | You can examine 'settings_` yourself
334 | to see the defaults. You can also write and read them just like any
335 | JSON Value.
336 | \sa setDefaults()
337 | */
338 | Json::Value settings_;
339 |
340 | CharReaderBuilder();
341 | ~CharReaderBuilder() JSONCPP_OVERRIDE;
342 |
343 | CharReader* newCharReader() const JSONCPP_OVERRIDE;
344 |
345 | /** \return true if 'settings' are legal and consistent;
346 | * otherwise, indicate bad settings via 'invalid'.
347 | */
348 | bool validate(Json::Value* invalid) const;
349 |
350 | /** A simple way to update a specific setting.
351 | */
352 | Value& operator[](JSONCPP_STRING key);
353 |
354 | /** Called by ctor, but you can use this to reset settings_.
355 | * \pre 'settings' != NULL (but Json::null is fine)
356 | * \remark Defaults:
357 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
358 | */
359 | static void setDefaults(Json::Value* settings);
360 | /** Same as old Features::strictMode().
361 | * \pre 'settings' != NULL (but Json::null is fine)
362 | * \remark Defaults:
363 | * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
364 | */
365 | static void strictMode(Json::Value* settings);
366 | };
367 |
368 | /** Consume entire stream and use its begin/end.
369 | * Someday we might have a real StreamReader, but for now this
370 | * is convenient.
371 | */
372 | bool JSON_API parseFromStream(
373 | CharReader::Factory const&,
374 | JSONCPP_ISTREAM&,
375 | Value* root, std::string* errs);
376 |
377 | /** \brief Read from 'sin' into 'root'.
378 |
379 | Always keep comments from the input JSON.
380 |
381 | This can be used to read a file into a particular sub-object.
382 | For example:
383 | \code
384 | Json::Value root;
385 | cin >> root["dir"]["file"];
386 | cout << root;
387 | \endcode
388 | Result:
389 | \verbatim
390 | {
391 | "dir": {
392 | "file": {
393 | // The input stream JSON would be nested here.
394 | }
395 | }
396 | }
397 | \endverbatim
398 | \throw std::exception on parse error.
399 | \see Json::operator<<()
400 | */
401 | JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
402 |
403 | } // namespace Json
404 |
405 | #pragma pack(pop)
406 |
407 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
408 | #pragma warning(pop)
409 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
410 |
411 | #endif // CPPTL_JSON_READER_H_INCLUDED
412 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/version.h:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This file (and "version") is generated by CMake.
2 | // Run CMake configure step to update it.
3 | #ifndef JSON_VERSION_H_INCLUDED
4 | # define JSON_VERSION_H_INCLUDED
5 |
6 | # define JSONCPP_VERSION_STRING "1.8.3"
7 | # define JSONCPP_VERSION_MAJOR 1
8 | # define JSONCPP_VERSION_MINOR 8
9 | # define JSONCPP_VERSION_PATCH 3
10 | # define JSONCPP_VERSION_QUALIFIER
11 | # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
12 |
13 | #ifdef JSONCPP_USING_SECURE_MEMORY
14 | #undef JSONCPP_USING_SECURE_MEMORY
15 | #endif
16 | #define JSONCPP_USING_SECURE_MEMORY 0
17 | // If non-zero, the library zeroes any memory that it has allocated before
18 | // it frees its memory.
19 |
20 | #endif // JSON_VERSION_H_INCLUDED
21 |
--------------------------------------------------------------------------------
/Src/Include/jsoncpp/writer.h:
--------------------------------------------------------------------------------
1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 | // Distributed under MIT license, or public domain if desired and
3 | // recognized in your jurisdiction.
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 |
6 | #ifndef JSON_WRITER_H_INCLUDED
7 | #define JSON_WRITER_H_INCLUDED
8 |
9 | #if !defined(JSON_IS_AMALGAMATION)
10 | #include "value.h"
11 | #endif // if !defined(JSON_IS_AMALGAMATION)
12 | #include
13 | #include
14 | #include
15 |
16 | // Disable warning C4251: : needs to have dll-interface to
17 | // be used by...
18 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)
19 | #pragma warning(push)
20 | #pragma warning(disable : 4251)
21 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
22 |
23 | #pragma pack(push, 8)
24 |
25 | namespace Json {
26 |
27 | class Value;
28 |
29 | /**
30 |
31 | Usage:
32 | \code
33 | using namespace Json;
34 | void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
35 | std::unique_ptr const writer(
36 | factory.newStreamWriter());
37 | writer->write(value, &std::cout);
38 | std::cout << std::endl; // add lf and flush
39 | }
40 | \endcode
41 | */
42 | class JSON_API StreamWriter {
43 | protected:
44 | JSONCPP_OSTREAM* sout_; // not owned; will not delete
45 | public:
46 | StreamWriter();
47 | virtual ~StreamWriter();
48 | /** Write Value into document as configured in sub-class.
49 | Do not take ownership of sout, but maintain a reference during function.
50 | \pre sout != NULL
51 | \return zero on success (For now, we always return zero, so check the stream instead.)
52 | \throw std::exception possibly, depending on configuration
53 | */
54 | virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
55 |
56 | /** \brief A simple abstract factory.
57 | */
58 | class JSON_API Factory {
59 | public:
60 | virtual ~Factory();
61 | /** \brief Allocate a CharReader via operator new().
62 | * \throw std::exception if something goes wrong (e.g. invalid settings)
63 | */
64 | virtual StreamWriter* newStreamWriter() const = 0;
65 | }; // Factory
66 | }; // StreamWriter
67 |
68 | /** \brief Write into stringstream, then return string, for convenience.
69 | * A StreamWriter will be created from the factory, used, and then deleted.
70 | */
71 | JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
72 |
73 |
74 | /** \brief Build a StreamWriter implementation.
75 |
76 | Usage:
77 | \code
78 | using namespace Json;
79 | Value value = ...;
80 | StreamWriterBuilder builder;
81 | builder["commentStyle"] = "None";
82 | builder["indentation"] = " "; // or whatever you like
83 | std::unique_ptr writer(
84 | builder.newStreamWriter());
85 | writer->write(value, &std::cout);
86 | std::cout << std::endl; // add lf and flush
87 | \endcode
88 | */
89 | class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
90 | public:
91 | // Note: We use a Json::Value so that we can add data-members to this class
92 | // without a major version bump.
93 | /** Configuration of this builder.
94 | Available settings (case-sensitive):
95 | - "commentStyle": "None" or "All"
96 | - "indentation": ""
97 | - "enableYAMLCompatibility": false or true
98 | - slightly change the whitespace around colons
99 | - "dropNullPlaceholders": false or true
100 | - Drop the "null" string from the writer's output for nullValues.
101 | Strictly speaking, this is not valid JSON. But when the output is being
102 | fed to a browser's Javascript, it makes for smaller output and the
103 | browser can handle the output just fine.
104 | - "useSpecialFloats": false or true
105 | - If true, outputs non-finite floating point values in the following way:
106 | NaN values as "NaN", positive infinity as "Infinity", and negative infinity
107 | as "-Infinity".
108 |
109 | You can examine 'settings_` yourself
110 | to see the defaults. You can also write and read them just like any
111 | JSON Value.
112 | \sa setDefaults()
113 | */
114 | Json::Value settings_;
115 |
116 | StreamWriterBuilder();
117 | ~StreamWriterBuilder() JSONCPP_OVERRIDE;
118 |
119 | /**
120 | * \throw std::exception if something goes wrong (e.g. invalid settings)
121 | */
122 | StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE;
123 |
124 | /** \return true if 'settings' are legal and consistent;
125 | * otherwise, indicate bad settings via 'invalid'.
126 | */
127 | bool validate(Json::Value* invalid) const;
128 | /** A simple way to update a specific setting.
129 | */
130 | Value& operator[](JSONCPP_STRING key);
131 |
132 | /** Called by ctor, but you can use this to reset settings_.
133 | * \pre 'settings' != NULL (but Json::null is fine)
134 | * \remark Defaults:
135 | * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
136 | */
137 | static void setDefaults(Json::Value* settings);
138 | };
139 |
140 | /** \brief Abstract class for writers.
141 | * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
142 | */
143 | class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer {
144 | public:
145 | virtual ~Writer();
146 |
147 | virtual JSONCPP_STRING write(const Value& root) = 0;
148 | };
149 |
150 | /** \brief Outputs a Value in JSON format
151 | *without formatting (not human friendly).
152 | *
153 | * The JSON document is written in a single line. It is not intended for 'human'
154 | *consumption,
155 | * but may be usefull to support feature such as RPC where bandwith is limited.
156 | * \sa Reader, Value
157 | * \deprecated Use StreamWriterBuilder.
158 | */
159 | #if defined(_MSC_VER)
160 | #pragma warning(push)
161 | #pragma warning(disable:4996) // Deriving from deprecated class
162 | #endif
163 | class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer {
164 | public:
165 | FastWriter();
166 | ~FastWriter() JSONCPP_OVERRIDE {}
167 |
168 | void enableYAMLCompatibility();
169 |
170 | /** \brief Drop the "null" string from the writer's output for nullValues.
171 | * Strictly speaking, this is not valid JSON. But when the output is being
172 | * fed to a browser's Javascript, it makes for smaller output and the
173 | * browser can handle the output just fine.
174 | */
175 | void dropNullPlaceholders();
176 |
177 | void omitEndingLineFeed();
178 |
179 | public: // overridden from Writer
180 | JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
181 |
182 | private:
183 | void writeValue(const Value& value);
184 |
185 | JSONCPP_STRING document_;
186 | bool yamlCompatiblityEnabled_;
187 | bool dropNullPlaceholders_;
188 | bool omitEndingLineFeed_;
189 | };
190 | #if defined(_MSC_VER)
191 | #pragma warning(pop)
192 | #endif
193 |
194 | /** \brief Writes a Value in JSON format in a
195 | *human friendly way.
196 | *
197 | * The rules for line break and indent are as follow:
198 | * - Object value:
199 | * - if empty then print {} without indent and line break
200 | * - if not empty the print '{', line break & indent, print one value per
201 | *line
202 | * and then unindent and line break and print '}'.
203 | * - Array value:
204 | * - if empty then print [] without indent and line break
205 | * - if the array contains no object value, empty array or some other value
206 | *types,
207 | * and all the values fit on one lines, then print the array on a single
208 | *line.
209 | * - otherwise, it the values do not fit on one line, or the array contains
210 | * object or non empty array, then print one value per line.
211 | *
212 | * If the Value have comments then they are outputed according to their
213 | *#CommentPlacement.
214 | *
215 | * \sa Reader, Value, Value::setComment()
216 | * \deprecated Use StreamWriterBuilder.
217 | */
218 | #if defined(_MSC_VER)
219 | #pragma warning(push)
220 | #pragma warning(disable:4996) // Deriving from deprecated class
221 | #endif
222 | class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer {
223 | public:
224 | StyledWriter();
225 | ~StyledWriter() JSONCPP_OVERRIDE {}
226 |
227 | public: // overridden from Writer
228 | /** \brief Serialize a Value in JSON format.
229 | * \param root Value to serialize.
230 | * \return String containing the JSON document that represents the root value.
231 | */
232 | JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
233 |
234 | private:
235 | void writeValue(const Value& value);
236 | void writeArrayValue(const Value& value);
237 | bool isMultineArray(const Value& value);
238 | void pushValue(const JSONCPP_STRING& value);
239 | void writeIndent();
240 | void writeWithIndent(const JSONCPP_STRING& value);
241 | void indent();
242 | void unindent();
243 | void writeCommentBeforeValue(const Value& root);
244 | void writeCommentAfterValueOnSameLine(const Value& root);
245 | bool hasCommentForValue(const Value& value);
246 | static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
247 |
248 | typedef std::vector ChildValues;
249 |
250 | ChildValues childValues_;
251 | JSONCPP_STRING document_;
252 | JSONCPP_STRING indentString_;
253 | unsigned int rightMargin_;
254 | unsigned int indentSize_;
255 | bool addChildValues_;
256 | };
257 | #if defined(_MSC_VER)
258 | #pragma warning(pop)
259 | #endif
260 |
261 | /** \brief Writes a Value in JSON format in a
262 | human friendly way,
263 | to a stream rather than to a string.
264 | *
265 | * The rules for line break and indent are as follow:
266 | * - Object value:
267 | * - if empty then print {} without indent and line break
268 | * - if not empty the print '{', line break & indent, print one value per
269 | line
270 | * and then unindent and line break and print '}'.
271 | * - Array value:
272 | * - if empty then print [] without indent and line break
273 | * - if the array contains no object value, empty array or some other value
274 | types,
275 | * and all the values fit on one lines, then print the array on a single
276 | line.
277 | * - otherwise, it the values do not fit on one line, or the array contains
278 | * object or non empty array, then print one value per line.
279 | *
280 | * If the Value have comments then they are outputed according to their
281 | #CommentPlacement.
282 | *
283 | * \sa Reader, Value, Value::setComment()
284 | * \deprecated Use StreamWriterBuilder.
285 | */
286 | #if defined(_MSC_VER)
287 | #pragma warning(push)
288 | #pragma warning(disable:4996) // Deriving from deprecated class
289 | #endif
290 | class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter {
291 | public:
292 | /**
293 | * \param indentation Each level will be indented by this amount extra.
294 | */
295 | StyledStreamWriter(JSONCPP_STRING indentation = "\t");
296 | ~StyledStreamWriter() {}
297 |
298 | public:
299 | /** \brief Serialize a Value in JSON format.
300 | * \param out Stream to write to. (Can be ostringstream, e.g.)
301 | * \param root Value to serialize.
302 | * \note There is no point in deriving from Writer, since write() should not
303 | * return a value.
304 | */
305 | void write(JSONCPP_OSTREAM& out, const Value& root);
306 |
307 | private:
308 | void writeValue(const Value& value);
309 | void writeArrayValue(const Value& value);
310 | bool isMultineArray(const Value& value);
311 | void pushValue(const JSONCPP_STRING& value);
312 | void writeIndent();
313 | void writeWithIndent(const JSONCPP_STRING& value);
314 | void indent();
315 | void unindent();
316 | void writeCommentBeforeValue(const Value& root);
317 | void writeCommentAfterValueOnSameLine(const Value& root);
318 | bool hasCommentForValue(const Value& value);
319 | static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
320 |
321 | typedef std::vector ChildValues;
322 |
323 | ChildValues childValues_;
324 | JSONCPP_OSTREAM* document_;
325 | JSONCPP_STRING indentString_;
326 | unsigned int rightMargin_;
327 | JSONCPP_STRING indentation_;
328 | bool addChildValues_ : 1;
329 | bool indented_ : 1;
330 | };
331 | #if defined(_MSC_VER)
332 | #pragma warning(pop)
333 | #endif
334 |
335 | #if defined(JSON_HAS_INT64)
336 | JSONCPP_STRING JSON_API valueToString(Int value);
337 | JSONCPP_STRING JSON_API valueToString(UInt value);
338 | #endif // if defined(JSON_HAS_INT64)
339 | JSONCPP_STRING JSON_API valueToString(LargestInt value);
340 | JSONCPP_STRING JSON_API valueToString(LargestUInt value);
341 | JSONCPP_STRING JSON_API valueToString(double value);
342 | JSONCPP_STRING JSON_API valueToString(bool value);
343 | JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
344 |
345 | /// \brief Output using the StyledStreamWriter.
346 | /// \see Json::operator>>()
347 | JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
348 |
349 | } // namespace Json
350 |
351 | #pragma pack(pop)
352 |
353 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
354 | #pragma warning(pop)
355 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
356 |
357 | #endif // JSON_WRITER_H_INCLUDED
358 |
--------------------------------------------------------------------------------
/Src/InternetGetFile.cpp:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | // InternetGetFile.cpp: implementation of the InternetGetFile namespace.
3 | //
4 | //////////////////////////////////////////////////////////////////////
5 |
6 | #include "stdafx.h"
7 | #include "AutoUpdate.h"
8 | #include
9 | #include
10 | #include
11 | #include "InternetGetFile.h"
12 |
13 | #ifdef _DEBUG
14 | #undef THIS_FILE
15 | static char THIS_FILE[]=__FILE__;
16 | #define new DEBUG_NEW
17 | #endif
18 |
19 | #define INTERNET_CONNECTION_OFFLINE 0x20
20 |
21 | // #define NOTIFY_DOWNLOAD_PROGRESS 1003
22 |
23 | BOOL Internet::bInternetGetURLUserBreak = FALSE;
24 |
25 | //
26 | // 通过HTTP协议从制定网址下载文件并保存到磁盘
27 | // sURL:网址
28 | // sSaveFilename:要保存的本地文件全路径
29 | // sHeader:HTTP请求头信息
30 | // hProgressWindow:接收下载文件进度消息并显示的窗口句柄
31 | //
32 | int Internet::InternetGetURL(const char* sURL,
33 | const char* sSaveFilename,
34 | const char* sHeader,
35 | HWND hProgressWindow)
36 | {
37 | const int BUFFER_SIZE = 32768;
38 | const int iInterval = 250;
39 | DWORD iFlags;
40 | char sAgent[64];
41 | HINTERNET hInternet;
42 | HINTERNET hConnect;
43 | char acBuffer[BUFFER_SIZE];
44 | DWORD iReadBytes;
45 | DWORD iTotalReadBytes = 0;
46 | FILE *pFile = NULL;
47 | DWORD iStartTime;
48 | DWORD iCurrentTime;
49 | DWORD iDuration = 10;
50 | DWORD iLastRefreshTime = 0;
51 | DOWNLOAD_PROGRESS_STRU DownloadProgress = {0};
52 | DWORD iBytesToRead = 0;
53 | DWORD iReadBytesOfRq = 4;
54 | DWORD iCPUTickStart;
55 | DWORD iCPUTickEnd;
56 |
57 | // Get connection state
58 | InternetGetConnectedState(&iFlags, 0);
59 | // take appropriate steps
60 | if (iFlags & INTERNET_CONNECTION_OFFLINE) {
61 | return INTERNET_ERROR_OPEN;
62 | }
63 |
64 | // Set agent string
65 | _snprintf(sAgent, 64, "Agent%ld", GetTickCount() / 1000);
66 | // Open internet session
67 | if (!(iFlags & INTERNET_CONNECTION_PROXY)) {
68 | hInternet = InternetOpenA(sAgent,
69 | INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
70 | NULL,
71 | NULL,
72 | 0);
73 | } else {
74 | hInternet = InternetOpenA(sAgent,
75 | INTERNET_OPEN_TYPE_PRECONFIG,
76 | NULL,
77 | NULL,
78 | 0);
79 | }
80 | if (hInternet) {
81 | if (sHeader == NULL) {
82 | sHeader = "Accept: */*\r\n\r\n";
83 | }
84 |
85 | // Get URL
86 | if (!(hConnect = InternetOpenUrlA (hInternet,
87 | sURL,
88 | sHeader,
89 | lstrlenA(sHeader),
90 | INTERNET_FLAG_DONT_CACHE |
91 | INTERNET_FLAG_PRAGMA_NOCACHE |
92 | INTERNET_FLAG_RELOAD,
93 | 0))) {
94 | InternetCloseHandle(hInternet);
95 | return INTERNET_ERROR_OPENURL;
96 | }
97 |
98 | // Open file to write
99 | if (!(pFile = fopen(sSaveFilename, "wb"))) {
100 | InternetCloseHandle(hInternet);
101 | return INTERNET_ERROR_FILEOPEN;
102 | }
103 |
104 | // Get content size
105 | if (!HttpQueryInfo(hConnect,
106 | HTTP_QUERY_CONTENT_LENGTH |
107 | HTTP_QUERY_FLAG_NUMBER,
108 | (LPVOID)&iBytesToRead,
109 | &iReadBytesOfRq,
110 | NULL)) {
111 | iBytesToRead = 0;
112 | }
113 |
114 | DownloadProgress.iCurrentFileSize = iBytesToRead;
115 |
116 | iStartTime = GetTickCount();
117 | iCPUTickStart = GetTickCount();
118 |
119 | do {
120 | if (bInternetGetURLUserBreak) { break; }
121 |
122 | // Keep copying in 16 KB chunks, while file has any data left.
123 | // Note: bigger buffer will greatly improve performance.
124 | if (!InternetReadFile(hConnect, acBuffer, BUFFER_SIZE, &iReadBytes)) {
125 | fclose(pFile);
126 | InternetCloseHandle(hInternet);
127 | return INTERNET_ERROR_READFILE;
128 | }
129 | if (iReadBytes > 0) {
130 | // Write to file
131 | fwrite(acBuffer, sizeof(char), iReadBytes, pFile);
132 | }
133 |
134 | iTotalReadBytes += iReadBytes;
135 |
136 | iCurrentTime = GetTickCount();
137 | iDuration = iCurrentTime - iStartTime;
138 | if (iDuration < 10) {
139 | iDuration = 10;
140 | }
141 |
142 | if (iBytesToRead > 0
143 | && hProgressWindow != NULL
144 | && iCurrentTime - iLastRefreshTime > iInterval
145 | || iTotalReadBytes == iBytesToRead) {
146 | // Show progress
147 | iLastRefreshTime = iCurrentTime;
148 | memset(acBuffer, 0, BUFFER_SIZE);
149 | DownloadProgress.iCurrentFileFinishedSize = iTotalReadBytes;
150 | SendMessage(hProgressWindow, WM_USER, (WPARAM)NOTIFY_DOWNLOAD_PROGRESS, (LPARAM)&DownloadProgress);
151 | #ifdef _DEBUG
152 | Sleep(100); // Delay some time to see progress clearly
153 | #endif
154 | }
155 |
156 | if (iReadBytes <= 0) {
157 | // Condition of iReadBytes=0 indicate EOF. Stop.
158 | break;
159 | }
160 |
161 | // 降低资源CPU占用率
162 | iCPUTickEnd = GetTickCount();
163 | if (iCPUTickEnd - iCPUTickStart > 50) {
164 | Sleep(iCPUTickEnd - iCPUTickStart);
165 | iCPUTickStart = GetTickCount();
166 | }
167 | } while (TRUE);
168 |
169 | fflush (pFile);
170 | fclose (pFile);
171 |
172 | InternetCloseHandle(hInternet);
173 | } else {
174 | return INTERNET_ERROR_OPEN;
175 | }
176 |
177 | return INTERNET_SUCCESS;
178 | }
--------------------------------------------------------------------------------
/Src/InternetGetFile.h:
--------------------------------------------------------------------------------
1 | // InternetGetFile.h: interface for the InternetGetFile namespace.
2 | //
3 | //////////////////////////////////////////////////////////////////////
4 |
5 | #pragma once
6 |
7 | #if !defined(INTERNETGETFILE_H)
8 | #define INTERNETGETFILE_H
9 |
10 | namespace Internet
11 | {
12 | enum
13 | {
14 | INTERNET_SUCCESS = 0,
15 | INTERNET_ERROR_OPENURL,
16 | INTERNET_ERROR_FILEOPEN,
17 | INTERNET_ERROR_READFILE,
18 | INTERNET_ERROR_OPEN
19 | };
20 |
21 | // 中断下载标记,置为真则中断下载文件
22 | extern BOOL bInternetGetURLUserBreak;
23 |
24 | // Get URL form internet with inet API
25 | int InternetGetURL(const char* sURL,
26 | const char* sSaveFilename,
27 | const char* sHeader = NULL,
28 | HWND hProgressWindow = NULL);
29 | };
30 |
31 | #endif // !defined(INTERNETGETFILE_H)
32 |
--------------------------------------------------------------------------------
/Src/JsonParser.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/JsonParser.cpp
--------------------------------------------------------------------------------
/Src/JsonParser.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "./Include/jsoncpp/json.h"
4 |
5 | using namespace Json;
6 | using namespace std;
7 |
8 | class CParseJson
9 | {
10 | public:
11 | CParseJson();
12 | bool ParseJson(const string& _strJson);
13 | bool GetString(const string& _strKey, string& _strValue);
14 | bool GetInt(const string& _strKey, int& _iValue);
15 | bool GetBool(const string& _strKey, bool& _bValue);
16 | bool GetDouble(const string& _strKey, double& _dValue);
17 | bool GetArray(const string& _strKey, Value& _aryValue);
18 | bool GetObjectValue(const string& _strKey, Value& _objValue);
19 | const char* GetLastError();
20 | private:
21 | bool _GetValue(const string& _strKey, int _iType, Value& _Value);
22 | private:
23 | /**
24 | * @brief The Type enum
25 | * 字段类型枚举
26 | */
27 | enum Type {
28 | Int = 0x0, // 整型
29 | Bool = 0x1, // bool值
30 | Double = 0x2, // 浮点型
31 | String = 0x3, // 字符串
32 | Array = 0x4, // json数组
33 | Object = 0x5, // json对象
34 | Undefined = 0x80 // 无定义
35 | };
36 | Value m_jsonObj; // 解析后的json对象
37 | string m_strError; // 解析过程出现的错误信息
38 | bool m_bSucceess; // 解析是否成功标志位
39 | };
40 |
--------------------------------------------------------------------------------
/Src/Lib/curl/libcurl.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Lib/curl/libcurl.lib
--------------------------------------------------------------------------------
/Src/Lib/jsoncpp/lib_json.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Lib/jsoncpp/lib_json.lib
--------------------------------------------------------------------------------
/Src/Md5.cpp:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | * Copyright (C) 2000 by Robert Hubley. *
3 | * All rights reserved. *
4 | * *
5 | * This software is provided ``AS IS'' and any express or implied *
6 | * warranties, including, but not limited to, the implied warranties of *
7 | * merchantability and fitness for a particular purpose, are disclaimed. *
8 | * In no event shall the authors be liable for any direct, indirect, *
9 | * incidental, special, exemplary, or consequential damages (including, but *
10 | * not limited to, procurement of substitute goods or services; loss of use, *
11 | * data, or profits; or business interruption) however caused and on any *
12 | * theory of liability, whether in contract, strict liability, or tort *
13 | * (including negligence or otherwise) arising in any way out of the use of *
14 | * this software, even if advised of the possibility of such damage. *
15 | * *
16 | ******************************************************************************
17 |
18 | MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
19 |
20 | Port to Win32 DLL by Robert Hubley 1/5/2000
21 |
22 | Original Copyright:
23 |
24 | Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
25 | rights reserved.
26 |
27 | License to copy and use this software is granted provided that it
28 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest
29 | Algorithm" in all material mentioning or referencing this software
30 | or this function.
31 |
32 | License is also granted to make and use derivative works provided
33 | that such works are identified as "derived from the RSA Data
34 | Security, Inc. MD5 Message-Digest Algorithm" in all material
35 | mentioning or referencing the derived work.
36 |
37 | RSA Data Security, Inc. makes no representations concerning either
38 | the merchantability of this software or the suitability of this
39 | software for any particular purpose. It is provided "as is"
40 | without express or implied warranty of any kind.
41 |
42 | These notices must be retained in any copies of any part of this
43 | documentation and/or software.
44 | */
45 |
46 | #include "stdafx.h"
47 | #ifdef _WIN32
48 | # include
49 | #endif
50 | #include "Md5.h"
51 |
52 | //
53 | // Constants for MD5Transform routine.
54 | //
55 | #define S11 7
56 | #define S12 12
57 | #define S13 17
58 | #define S14 22
59 | #define S21 5
60 | #define S22 9
61 | #define S23 14
62 | #define S24 20
63 | #define S31 4
64 | #define S32 11
65 | #define S33 16
66 | #define S34 23
67 | #define S41 6
68 | #define S42 10
69 | #define S43 15
70 | #define S44 21
71 |
72 | //
73 | // F, G, H and I are basic MD5 functions.
74 | //
75 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
76 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
77 | #define H(x, y, z) ((x) ^ (y) ^ (z))
78 | #define I(x, y, z) ((y) ^ ((x) | (~z)))
79 |
80 | //
81 | // ROTATE_LEFT rotates x left n bits.
82 | //
83 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
84 |
85 | //
86 | // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
87 | // Rotation is separate from addition to prevent recomputation.
88 | //
89 | #define FF(a, b, c, d, x, s, ac) { \
90 | (a) += F ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
91 | (a) = ROTATE_LEFT ((a), (s)); \
92 | (a) += (b); \
93 | }
94 | #define GG(a, b, c, d, x, s, ac) { \
95 | (a) += G ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
96 | (a) = ROTATE_LEFT ((a), (s)); \
97 | (a) += (b); \
98 | }
99 | #define HH(a, b, c, d, x, s, ac) { \
100 | (a) += H ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
101 | (a) = ROTATE_LEFT ((a), (s)); \
102 | (a) += (b); \
103 | }
104 | #define II(a, b, c, d, x, s, ac) { \
105 | (a) += I ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
106 | (a) = ROTATE_LEFT ((a), (s)); \
107 | (a) += (b); \
108 | }
109 |
110 | MD5_CTX::MD5_CTX()
111 | {
112 | MD5Init();
113 | }
114 |
115 | MD5_CTX::~MD5_CTX()
116 | {
117 | }
118 |
119 | //
120 | // MD5 initialization. Begins an MD5 operation, writing a new context.
121 | //
122 | void MD5_CTX::MD5Init()
123 | {
124 | this->count[0] = this->count[1] = 0;
125 | /* Load magic initialization constants.*/
126 | this->state[0] = 0x67452301;
127 | this->state[1] = 0xefcdab89;
128 | this->state[2] = 0x98badcfe;
129 | this->state[3] = 0x10325476;
130 | MD5_memset (PADDING, 0, sizeof(PADDING));
131 | *PADDING = 0x80;
132 | }
133 |
134 | //
135 | // MD5 block update operation. Continues an MD5 message-digest
136 | // operation, processing another message block, and updating the
137 | // context.
138 | //
139 | void MD5_CTX::MD5Update (unsigned char *input,
140 | unsigned int inputLen)
141 | {
142 | unsigned int i, index, partLen;
143 |
144 | // Compute number of bytes mod 64
145 | index = (unsigned int)((this->count[0] >> 3) & 0x3F);
146 |
147 | // Update number of bits
148 | if ((this->count[0] += ((unsigned long int)inputLen << 3))
149 | < ((unsigned long int)inputLen << 3)) {
150 | this->count[1]++;
151 | }
152 | this->count[1] += ((unsigned long int)inputLen >> 29);
153 |
154 | partLen = 64 - index;
155 |
156 | /// Transform as many times as possible.
157 | if (inputLen >= partLen) {
158 | MD5_memcpy ((unsigned char*)&this->buffer[index],
159 | (unsigned char*)input, partLen);
160 | MD5Transform (this->state, this->buffer);
161 | for (i = partLen; i + 63 < inputLen; i += 64) {
162 | MD5Transform (this->state, &input[i]);
163 | }
164 | index = 0;
165 | } else {
166 | i = 0;
167 | }
168 |
169 | // Buffer remaining input
170 | MD5_memcpy ((unsigned char*)&this->buffer[index], (unsigned char*)&input[i], inputLen-i);
171 | }
172 |
173 | //
174 | // MD5 finalization. Ends an MD5 message-digest operation, writing the
175 | // the message digest and zeroizing the context.
176 | //
177 | void MD5_CTX::MD5Final (unsigned char digest[16])
178 | {
179 | unsigned char bits[8];
180 | unsigned int index, padLen;
181 |
182 | // Save number of bits
183 | Encode (bits, this->count, 8);
184 |
185 | // Pad out to 56 mod 64.
186 | index = (unsigned int)((this->count[0] >> 3) & 0x3f);
187 | padLen = (index < 56) ? (56 - index) : (120 - index);
188 | MD5Update ( PADDING, padLen);
189 |
190 | // Append length (before padding)
191 | MD5Update (bits, 8);
192 | // Store state in digest
193 | Encode (digest, this->state, 16);
194 |
195 | // Zeroize sensitive information.
196 | MD5_memset ((unsigned char*)this, 0, sizeof (*this));
197 | this->MD5Init();
198 | }
199 |
200 | //
201 | // MD5 basic transformation. Transforms state based on block.
202 | //
203 | void MD5_CTX::MD5Transform (unsigned long int state[4],
204 | unsigned char block[64])
205 | {
206 | unsigned long int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
207 |
208 | Decode (x, block, 64);
209 |
210 | // Round 1
211 | FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
212 | FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
213 | FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
214 | FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
215 | FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
216 | FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
217 | FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
218 | FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
219 | FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
220 | FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
221 | FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
222 | FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
223 | FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
224 | FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
225 | FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
226 | FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
227 |
228 | // Round 2
229 | GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
230 | GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
231 | GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
232 | GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
233 | GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
234 | GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
235 | GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
236 | GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
237 | GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
238 | GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
239 | GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
240 | GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
241 | GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
242 | GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
243 | GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
244 | GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
245 |
246 | // Round 3
247 | HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
248 | HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
249 | HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
250 | HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
251 | HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
252 | HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
253 | HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
254 | HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
255 | HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
256 | HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
257 | HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
258 | HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
259 | HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
260 | HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
261 | HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
262 | HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
263 |
264 | // Round 4
265 | II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
266 | II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
267 | II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
268 | II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
269 | II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
270 | II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
271 | II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
272 | II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
273 | II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
274 | II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
275 | II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
276 | II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
277 | II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
278 | II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
279 | II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
280 | II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
281 |
282 | state[0] += a;
283 | state[1] += b;
284 | state[2] += c;
285 | state[3] += d;
286 |
287 | // Zeroize sensitive information.
288 | MD5_memset ((unsigned char*)x, 0, sizeof (x));
289 | }
290 |
291 | //
292 | // Encodes input (unsigned long int) into output (unsigned char). Assumes len is
293 | // a multiple of 4.
294 | //
295 | void MD5_CTX::Encode (unsigned char *output,
296 | unsigned long int *input,
297 | unsigned int len)
298 | {
299 | unsigned int i, j;
300 |
301 | for (i = 0, j = 0; j < len; i++, j += 4) {
302 | output[j] = (unsigned char)(input[i] & 0xff);
303 | output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
304 | output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
305 | output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
306 | }
307 | }
308 |
309 | //
310 | // Decodes input (unsigned char) into output (unsigned long int). Assumes len is
311 | // a multiple of 4.
312 | //
313 | void MD5_CTX::Decode (unsigned long int *output,
314 | unsigned char *input,
315 | unsigned int len)
316 | {
317 | unsigned int i, j;
318 |
319 | for (i = 0, j = 0; j < len; i++, j += 4) {
320 | output[i] = ((unsigned long int)input[j])
321 | | (((unsigned long int)input[j+1]) << 8)
322 | | (((unsigned long int)input[j+2]) << 16)
323 | | (((unsigned long int)input[j+3]) << 24);
324 | }
325 | }
326 |
327 | #ifndef _WIN32
328 |
329 | //
330 | // Note: Replace "for loop" with standard memcpy if possible.
331 | //
332 | void MD5_CTX::MD5_memcpy (unsigned char* output,
333 | unsigned char* input,
334 | unsigned int len)
335 | {
336 | unsigned int i;
337 |
338 | for (i = 0; i < len; i++) {
339 | output[i] = input[i];
340 | }
341 | }
342 |
343 | //
344 | // Note: Replace "for loop" with standard memset if possible.
345 | //
346 | void MD5_CTX::MD5_memset (unsigned char* output,
347 | int value,
348 | unsigned int len)
349 | {
350 | unsigned int i;
351 |
352 | for (i = 0; i < len; i++) {
353 | ((char *)output)[i] = (char)value;
354 | }
355 | }
356 |
357 | #endif // #ifndef _WIN32
--------------------------------------------------------------------------------
/Src/Md5.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | * Copyright (C) 2000 by Robert Hubley. *
3 | * All rights reserved. *
4 | * *
5 | * This software is provided ``AS IS'' and any express or implied *
6 | * warranties, including, but not limited to, the implied warranties of *
7 | * merchantability and fitness for a particular purpose, are disclaimed. *
8 | * In no event shall the authors be liable for any direct, indirect, *
9 | * incidental, special, exemplary, or consequential damages (including, but *
10 | * not limited to, procurement of substitute goods or services; loss of use, *
11 | * data, or profits; or business interruption) however caused and on any *
12 | * theory of liability, whether in contract, strict liability, or tort *
13 | * (including negligence or otherwise) arising in any way out of the use of *
14 | * this software, even if advised of the possibility of such damage. *
15 | * *
16 | ******************************************************************************
17 |
18 | MD5.H - header file for MD5C.C
19 |
20 | Port to Win32 DLL by Robert Hubley 1/5/2000
21 |
22 | Original Copyright:
23 |
24 | Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
25 | rights reserved.
26 |
27 | License to copy and use this software is granted provided that it
28 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest
29 | Algorithm" in all material mentioning or referencing this software
30 | or this function.
31 |
32 | License is also granted to make and use derivative works provided
33 | that such works are identified as "derived from the RSA Data
34 | Security, Inc. MD5 Message-Digest Algorithm" in all material
35 | mentioning or referencing the derived work.
36 |
37 | RSA Data Security, Inc. makes no representations concerning either
38 | the merchantability of this software or the suitability of this
39 | software for any particular purpose. It is provided "as is"
40 | without express or implied warranty of any kind.
41 |
42 | These notices must be retained in any copies of any part of this
43 | documentation and/or software.
44 | */
45 | /******************************************************************************
46 | * Copyright (C) 2000 by Robert Hubley. *
47 | * All rights reserved. *
48 | * *
49 | * This software is provided ``AS IS'' and any express or implied *
50 | * warranties, including, but not limited to, the implied warranties of *
51 | * merchantability and fitness for a particular purpose, are disclaimed. *
52 | * In no event shall the authors be liable for any direct, indirect, *
53 | * incidental, special, exemplary, or consequential damages (including, but *
54 | * not limited to, procurement of substitute goods or services; loss of use, *
55 | * data, or profits; or business interruption) however caused and on any *
56 | * theory of liability, whether in contract, strict liability, or tort *
57 | * (including negligence or otherwise) arising in any way out of the use of *
58 | * this software, even if advised of the possibility of such damage. *
59 | * *
60 | ******************************************************************************
61 | */
62 |
63 |
64 | #ifndef _LGY_MD5_H
65 | #define _LGY_MD5_H
66 |
67 | // MD5 Class.
68 | class MD5_CTX
69 | {
70 | public:
71 | MD5_CTX();
72 | virtual ~MD5_CTX();
73 | void MD5Update (unsigned char *input, unsigned int inputLen);
74 | void MD5Final (unsigned char digest[16]);
75 |
76 | private:
77 | // state (ABCD)
78 | unsigned long int state[4];
79 | // number of bits, modulo 2^64 (lsb first)
80 | unsigned long int count[2];
81 | // input buffer
82 | unsigned char buffer[64];
83 | // What?
84 | unsigned char PADDING[64];
85 |
86 | private:
87 | void MD5Init ();
88 | void MD5Transform (unsigned long int state[4], unsigned char block[64]);
89 | void Encode (unsigned char* output, unsigned long int* input, unsigned int len);
90 | void Decode (unsigned long int* output, unsigned char* input, unsigned int len);
91 | #ifndef _WIN32
92 | void MD5_memcpy (unsigned char* output, unsigned char* input, unsigned int len);
93 | void MD5_memset (unsigned char* output, int value, unsigned int len);
94 | #else
95 | # define MD5_memcpy memcpy
96 | # define MD5_memset memset
97 | #endif // #ifndef _WIN32
98 | };
99 |
100 | #endif
101 |
--------------------------------------------------------------------------------
/Src/MultiLanguage.h:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:MultiLanguage.h
3 | // 文件版本:v1.0
4 | // 文件描述:实现多语言切换的头文件
5 | //------------------------------------------------------------------------------
6 |
7 | // 语言ID常量枚举,增加、减少语言时直接修改此枚举定义
8 | enum enLANGUAGE
9 | {
10 | LANGUAGE_GB = 0,
11 | LANGUAGE_BIG5,
12 | LANGUAGE_ENGLISH,
13 | LANGUAGE_BOTTOM
14 | };
15 |
16 | // 字符串常量ID枚举,增加、减少表达某个语意的字符串时直接修改此枚举定义
17 | enum enSTRING
18 | {
19 | STR_NULL = 0,
20 | STR_AUTO_UPDATE,
21 | STR_APP_ALREADY_RUNNING,
22 |
23 | STR_PROMPT_NEWER_VERSION_AVAILABLE,
24 | STR_OPTION_UPGRADE_IN_BACKGROUND,
25 | STR_PROMPT_UPGRADE_READY,
26 | STR_PROMPT_FAIL_TO_OPEN_UPDATE_CONFIG_FILE,
27 | STR_PROMPT_DOWNLOADING_FILE,
28 | STR_TOTAL_UPGRADE_PROGRESS,
29 | STR_PROMPT_FAIL_IN_DOWNLOADING_FILES,
30 | STR_PROMPT_FAIL_IN_VERIFYING_FILES,
31 | STR_PROMPT_FAIL_IN_UPDATING_FILES,
32 | STR_PROMPT_FAIL_IN_UPDATING,
33 | STR_PROMPT_UPGRADE_FINISHED,
34 |
35 | STR_OTHER,
36 |
37 | STR_BUTTON_START_UPGRADE,
38 | STR_BUTTON_CANCEL_UPGRADE,
39 | STR_BUTTON_SUCCESS_UPGRADE,
40 |
41 | STR_BUTTON_OK,
42 | STR_BUTTON_CANCEL,
43 | STR_BUTTON_ABORT,
44 | STR_BUTTON_IGANORE,
45 | STR_BUTTON_RETRY,
46 | STR_BUTTON_CONTINUE,
47 | STR_BUTTON_YES,
48 | STR_BUTTON_NO,
49 | STR_BUTTON_CLOSE,
50 | STR_BUTTON_APPLY,
51 |
52 | STR_ERROR,
53 | STR_ERROR_MESSAGE,
54 |
55 | STRING_BOTTOM
56 | };
57 |
58 | // 保存不同语言版本的常量字符串的结构,
59 | // 增加、减少语言时要改写构造函数和Set函数
60 | struct StringStru
61 | {
62 | // 保存不同语言版本的常量字符串的指针
63 | const char *Language[LANGUAGE_BOTTOM];
64 | StringStru()
65 | {
66 | Language[0] = "";
67 | Language[1] = "";
68 | Language[2] = "";
69 | };
70 |
71 | void Set(const char *s1, const char *s2, const char *s3)
72 | {
73 | if (NULL != s1) {
74 | Language[0] = s1;
75 | }
76 |
77 | if (NULL != s2) {
78 | Language[1] = s2;
79 | }
80 |
81 | if (NULL != s3) {
82 | Language[2] = s3;
83 | }
84 | };
85 | };
86 |
87 | // 全局字符串常量表数组(数组初始化在InitStringTable()函数中进行)
88 | extern struct StringStru g_String[STRING_BOTTOM];
89 |
90 | // 全局语言代码(注意:随意修改其值可能会导致程序异常!)
91 | extern enum enLANGUAGE g_LanguageID;
92 |
93 | // 取得常量字符串的宏定义,STRING_ID为常量字符串ID,PROMPT为任意助记提示字符串,编译时被忽略
94 | #define STRING(STRING_ID, PROMPT) (const char *)(g_String[STRING_ID].Language[g_LanguageID])
95 |
--------------------------------------------------------------------------------
/Src/RButton.cpp:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:RButton.h
3 | // 文件版本:v1.0
4 | // 文件描述:自绘按钮类实现文件
5 | //------------------------------------------------------------------------------
6 |
7 | #include "stdafx.h"
8 | #include "AutoUpdate.h"
9 | #include "UISkinManager.h"
10 | #include "RButton.h"
11 |
12 | #ifdef _DEBUG
13 | #define new DEBUG_NEW
14 | #undef THIS_FILE
15 | static char THIS_FILE[] = __FILE__;
16 | #endif
17 |
18 | // CRButton
19 |
20 | IMPLEMENT_DYNAMIC(CRButton, CButton)
21 |
22 | CRButton::CRButton(enButtonType iButtonType)
23 | {
24 | m_iButtonType = iButtonType;
25 | m_bTracking = FALSE;
26 | m_bOver = FALSE;
27 | m_bDown = FALSE;
28 | m_bFocus = FALSE;
29 | m_bDefault = FALSE;
30 | }
31 |
32 | CRButton::~CRButton()
33 | {
34 | }
35 |
36 | void CRButton::PreSubclassWindow()
37 | {
38 | CButton::PreSubclassWindow();
39 |
40 | UINT uStyle = GetButtonStyle();
41 | if (uStyle == BS_DEFPUSHBUTTON) {
42 | m_bDefault = TRUE;
43 | }
44 |
45 | ModifyStyle(0, BS_OWNERDRAW);
46 | }
47 |
48 | // 自绘控件
49 | void CRButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
50 | {
51 | CRect rcButton = lpDrawItemStruct->rcItem;
52 | CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
53 | UINT iState = lpDrawItemStruct->itemState;
54 |
55 | // 获取按钮的状态
56 | m_bFocus = iState & ODS_FOCUS;
57 | m_bDown = iState & ODS_SELECTED;
58 |
59 | // 绘制按钮背景
60 | if (CUISkinManager::m_iCurrentStyle == CUISkinManager::StyleSummer) {
61 | if (m_iButtonType == ButtonTypeMinimize) {
62 | // 绘制最小化窗口按钮
63 | DrawSystemControlButtonWithBitmap(pDC->GetSafeHdc(),
64 | rcButton,
65 | (HBITMAP)CUISkinManager::m_bmSystemControlButtonImage,
66 | m_bDown ? 16 : 0);
67 | return;
68 | } else if (m_iButtonType == ButtonTypeMaximize) {
69 | if (GetWindowLong(GetParent()->m_hWnd, GWL_STYLE) & WS_MAXIMIZE)
70 | {
71 | // 绘制最大化窗口按钮
72 | DrawSystemControlButtonWithBitmap(pDC->GetSafeHdc(),
73 | rcButton,
74 | (HBITMAP)CUISkinManager::m_bmSystemControlButtonImage,
75 | m_bDown ? 48 : 32);
76 | } else {
77 | // 绘制还原窗口大小按钮
78 | DrawSystemControlButtonWithBitmap(pDC->GetSafeHdc(),
79 | rcButton,
80 | (HBITMAP)CUISkinManager::m_bmSystemControlButtonImage,
81 | m_bDown ? 80 : 64);
82 | }
83 | return;
84 | } else if (m_iButtonType == ButtonTypeClose) {
85 | // 绘制关闭窗口按钮
86 | DrawSystemControlButtonWithBitmap(pDC->GetSafeHdc(),
87 | rcButton,
88 | (HBITMAP)CUISkinManager::m_bmSystemControlButtonImage,
89 | m_bDown ? 112 : 96);
90 | return;
91 | } else if (m_bDefault) {
92 | DrawItemWithBitmap(pDC->GetSafeHdc(),
93 | rcButton,
94 | (HBITMAP)CUISkinManager::m_bmButtonImage,
95 | 20,
96 | 32);
97 | } else if (m_bOver) {
98 | DrawItemWithBitmap(pDC->GetSafeHdc(),
99 | rcButton,
100 | (HBITMAP)CUISkinManager::m_bmButtonImage,
101 | 20,
102 | 32 * 2);
103 | } else if (m_bDown) {
104 | DrawItemWithBitmap(pDC->GetSafeHdc(),
105 | rcButton,
106 | (HBITMAP)CUISkinManager::m_bmButtonImage,
107 | 20,
108 | 32 * 3);
109 | } else {
110 | DrawItemWithBitmap(pDC->GetSafeHdc(),
111 | rcButton,
112 | (HBITMAP)CUISkinManager::m_bmButtonImage,
113 | 20,
114 | 0);
115 | }
116 | } else {
117 | //
118 | // 缺省风格
119 | //
120 |
121 | // 内边框
122 | COLORREF crTop, crBottom;
123 | CRect rcOver = rcButton;
124 | rcOver.DeflateRect(1,1);
125 |
126 | if (m_bDefault) {
127 | crTop = RGB(203, 231, 255);
128 | crBottom = RGB(105, 130, 238);
129 | } else if (m_bOver) {
130 | crTop = RGB(255, 240, 207);
131 | crBottom = RGB(229, 151, 0);
132 | } else if (m_bDown) {
133 | crTop = RGB(209, 204, 193);
134 | crBottom = RGB(218, 216, 207);
135 | } else {
136 | crTop = RGB(254, 254, 254);
137 | crBottom = RGB(234, 245, 255);
138 | }
139 | CUISkinManager::GradientFillRect(this,
140 | pDC,
141 | rcOver,
142 | GRADIENT_FILL_RECT_V,
143 | crTop,
144 | crBottom);
145 |
146 | // 外边框
147 | // 边框颜色
148 | CPen pen(PS_SOLID, 1, RGB(200, 210, 240));
149 | DrawRoundBorder(pDC, rcButton);
150 |
151 | // 内部填充
152 | if (!m_bDown) {
153 | CRect rcIn = rcButton;
154 | if (m_bOver || m_bFocus) {
155 | rcIn.DeflateRect(3,3);
156 | } else {
157 | rcIn.DeflateRect(2,2);
158 | }
159 | crTop = RGB(252, 252, 251);
160 | crBottom = RGB(236, 235, 230);
161 | CUISkinManager::GradientFillRect(this,
162 | pDC,
163 | rcIn,
164 | GRADIENT_FILL_RECT_V,
165 | crTop,
166 | crBottom);
167 | }
168 | }
169 |
170 | rcButton.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
171 |
172 | // 绘制焦点框
173 | if (m_bFocus) {
174 | CRect rcFoucs = rcButton;
175 | pDC->DrawFocusRect(rcFoucs);
176 | }
177 |
178 | //
179 | // 绘制按钮标题文本
180 | //
181 | CString strTitle;
182 |
183 | GetWindowText(strTitle);
184 |
185 | if (strlen(strTitle) > 0) {
186 | CFont* hFont = GetFont();
187 | CFont* hOldFont = pDC->SelectObject(hFont);
188 | // 计算文本显示的宽度
189 | CSize szExtent = pDC->GetTextExtent(strTitle, lstrlen(strTitle));
190 | if (strstr(strTitle, "&") != 0) {
191 | // 减去因 '&' 字符被隐藏时的宽度
192 | szExtent.cx -= pDC->GetTextExtent("&").cx;
193 | }
194 |
195 | CPoint pt(rcButton.CenterPoint().x - szExtent.cx / 2, rcButton.CenterPoint().y - szExtent.cy / 2);
196 | if (iState & ODS_SELECTED) {
197 | pt.Offset(1, 1);
198 | }
199 | int nMode = pDC->SetBkMode(TRANSPARENT);
200 | if (iState & ODS_DISABLED) {
201 | pDC->DrawState(pt, szExtent, strTitle, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
202 | } else {
203 | pDC->DrawState(pt, szExtent, strTitle, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
204 | }
205 |
206 | pDC->SelectObject(hOldFont);
207 | pDC->SetBkMode(nMode);
208 | }
209 | }
210 |
211 |
212 | BEGIN_MESSAGE_MAP(CRButton, CButton)
213 | ON_WM_SIZE()
214 | ON_WM_MOUSEMOVE()
215 | ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
216 | ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
217 | END_MESSAGE_MAP()
218 |
219 |
220 | //
221 | // CRButton 消息处理程序
222 | //
223 | void CRButton::OnMouseMove(UINT nFlags, CPoint point)
224 | {
225 | if (!m_bTracking) {
226 | TRACKMOUSEEVENT tms;
227 | tms.cbSize = sizeof(TRACKMOUSEEVENT);
228 | tms.dwFlags = TME_LEAVE|TME_HOVER;
229 | tms.dwHoverTime = 1;
230 | tms.hwndTrack = m_hWnd;
231 | m_bTracking = ::_TrackMouseEvent(&tms);
232 | }
233 | CButton::OnMouseMove(nFlags, point);
234 | }
235 |
236 | LRESULT CRButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
237 | {
238 | m_bOver = TRUE;
239 | InvalidateRect(NULL);
240 | return m_bTracking;
241 | }
242 |
243 | LRESULT CRButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
244 | {
245 | m_bTracking = FALSE;
246 | m_bOver = FALSE;
247 | InvalidateRect(NULL);
248 | return m_bTracking;
249 | }
250 |
251 | //
252 | // 以位图方式描绘按钮控件,要求位图宽度为32象素
253 | // (左15 + 中2 + 右15,中间随着控件宽度拉伸)
254 | // HDC hdcDest:目标设备环境句柄
255 | // CRect& rc:按钮所占的区域(描绘区域)
256 | // HBITMAP hBitMap:位图句柄
257 | // UINT iBitMapHeight:位图高度
258 | // UINT cx:从位图复制的起点位置,
259 | // 按钮处于不同状态(正常、有焦点、
260 | // 鼠标悬停、按下)时对应不同的起点位置
261 | void CRButton::DrawItemWithBitmap(HDC hdcDest,
262 | CRect& rc,
263 | HBITMAP hBitMap,
264 | UINT iBitMapHeight,
265 | UINT cx)
266 | {
267 | if (hdcDest == NULL ||
268 | hBitMap == NULL) {
269 | return;
270 | }
271 |
272 | HDC hdcSrc = CreateCompatibleDC(hdcDest);
273 | HGDIOBJ hOldGdiObj = SelectObject(hdcSrc, hBitMap);
274 |
275 | TransparentBlt(hdcDest,
276 | 0,
277 | 0,
278 | CUISkinManager::m_iButtonImageLeftPartWidth,
279 | rc.Height(),
280 | hdcSrc,
281 | cx,
282 | 0,
283 | CUISkinManager::m_iButtonImageLeftPartWidth,
284 | iBitMapHeight,
285 | CUISkinManager::TRANSPARENT_COLOR);
286 |
287 | TransparentBlt(hdcDest,
288 | CUISkinManager::m_iButtonImageLeftPartWidth,
289 | 0
290 | ,
291 | rc.Width() - CUISkinManager::m_iButtonImageLeftPartWidth + CUISkinManager::m_iButtonImageRightPartWidth,
292 | rc.Height(),
293 | hdcSrc,
294 | cx + CUISkinManager::m_iButtonImageLeftPartWidth,
295 | 0,
296 | CUISkinManager::m_iButtonImageMiddlePartWidth,
297 | iBitMapHeight,
298 | CUISkinManager::TRANSPARENT_COLOR);
299 |
300 | TransparentBlt(hdcDest,
301 | rc.Width() - CUISkinManager::m_iButtonImageRightPartWidth,
302 | 0,
303 | CUISkinManager::m_iButtonImageRightPartWidth, rc.Height(),
304 | hdcSrc,
305 | cx + CUISkinManager::m_iButtonImageLeftPartWidth + CUISkinManager::m_iButtonImageMiddlePartWidth,
306 | 0,
307 | CUISkinManager::m_iButtonImageRightPartWidth,
308 | iBitMapHeight,
309 | CUISkinManager::TRANSPARENT_COLOR);
310 |
311 | SelectObject(hdcSrc, hOldGdiObj);
312 | DeleteDC(hdcSrc);
313 | }
314 |
315 | // 以位图方式描绘系统控制按钮控件,
316 | // 要求位图宽度为128象素以上
317 | // HDC hdcDest:目标设备环境句柄
318 | // CRect& rc:按钮所占的区域(描绘区域)
319 | // HBITMAP hBitMap:位图句柄
320 | // UINT cx:从位图复制的起点位置
321 | void CRButton::DrawSystemControlButtonWithBitmap(HDC hdcDest,
322 | CRect& rc,
323 | HBITMAP hBitMap,
324 | UINT cx)
325 | {
326 | if (hdcDest == NULL ||
327 | hBitMap == NULL) {
328 | return;
329 | }
330 |
331 | HDC hdcSrc = CreateCompatibleDC(hdcDest);
332 | HGDIOBJ hOldGdiObj = SelectObject(hdcSrc, hBitMap);
333 |
334 | TransparentBlt(hdcDest,
335 | 0,
336 | 0,
337 | rc.Width(),
338 | rc.Height(),
339 | hdcSrc,
340 | cx,
341 | 0,
342 | CUISkinManager::m_iSystemControlButtonWidth,
343 | CUISkinManager::m_iSystemControlButtonHeight,
344 | CUISkinManager::TRANSPARENT_COLOR);
345 |
346 | SelectObject(hdcSrc, hOldGdiObj);
347 | DeleteDC(hdcSrc);
348 | }
349 |
350 | // 描绘边框
351 | void CRButton::DrawRoundBorder(CDC *pDC,
352 | CRect rcBorder)
353 | {
354 | rcBorder.DeflateRect(0, 0, 1, 1);
355 | CPoint pt[] = {
356 | CPoint(rcBorder.left, rcBorder.top + 2),
357 | CPoint(rcBorder.left, rcBorder.bottom - 2),
358 | CPoint(rcBorder.left + 1, rcBorder.bottom - 1),
359 | CPoint(rcBorder.left + 2, rcBorder.bottom),
360 | CPoint(rcBorder.right - 2, rcBorder.bottom),
361 | CPoint(rcBorder.right - 1, rcBorder.bottom - 1),
362 | CPoint(rcBorder.right, rcBorder.bottom - 2),
363 | CPoint(rcBorder.right, rcBorder.top + 2),
364 | CPoint(rcBorder.right - 1, rcBorder.top + 1),
365 | CPoint(rcBorder.right - 2, rcBorder.top),
366 | CPoint(rcBorder.left + 2, rcBorder.top),
367 | CPoint(rcBorder.left + 1, rcBorder.top + 1),
368 | CPoint(rcBorder.left, rcBorder.top + 2)
369 | };
370 |
371 | BYTE bt[] = {
372 | PT_MOVETO,
373 | PT_LINETO,
374 | PT_LINETO,
375 | PT_LINETO,
376 | PT_LINETO,
377 | PT_LINETO,
378 | PT_LINETO,
379 | PT_LINETO,
380 | PT_LINETO,
381 | PT_LINETO,
382 | PT_LINETO,
383 | PT_LINETO,
384 | PT_LINETO
385 | };
386 |
387 | pDC->PolyDraw(pt, bt, 13);
388 | }
389 |
--------------------------------------------------------------------------------
/Src/RButton.h:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:RButton.h
3 | // 文件版本:v1.0
4 | // 文件描述:自绘按钮类
5 | //------------------------------------------------------------------------------
6 |
7 | #pragma once
8 |
9 | #ifndef RBUTTON_H
10 | #define RBUTTON_H
11 |
12 | // CRButton
13 |
14 | class CRButton : public CButton
15 | {
16 | public:
17 | enum enButtonType
18 | {
19 | ButtonTypeNormal = 0,
20 | ButtonTypeClose,
21 | ButtonTypeMaximize,
22 | ButtonTypeMinimize,
23 | ButtonTypeBottom
24 | };
25 |
26 | DECLARE_DYNAMIC(CRButton)
27 |
28 | public:
29 | CRButton(enButtonType m_iButtonType = ButtonTypeNormal);
30 | virtual ~CRButton();
31 |
32 | public:
33 | virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
34 |
35 | protected:
36 | virtual void PreSubclassWindow();
37 |
38 | DECLARE_MESSAGE_MAP()
39 |
40 | afx_msg void OnMouseMove(UINT nFlags, CPoint point);
41 | afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
42 | afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
43 |
44 | protected:
45 | void DrawRoundBorder(CDC *pDC, CRect rcBorder);
46 | // 以位图方式描绘按钮控件,要求位图宽度为32象素(左15 + 中2 + 右15,中间随着控件宽度拉伸)
47 | void DrawItemWithBitmap(HDC hdcDest, CRect& rc, HBITMAP hBitMap, UINT iBitMapHeight, UINT cx);
48 | // 以位图方式描绘系统控制按钮控件,要求位图宽度为128象素以上
49 | void DrawSystemControlButtonWithBitmap(HDC hdcDest, CRect& rc, HBITMAP hBitMap, UINT cx);
50 |
51 | protected:
52 | enum enButtonType m_iButtonType;
53 | BOOL m_bTracking;
54 | BOOL m_bDefault;
55 | BOOL m_bFocus;
56 | BOOL m_bOver;
57 | BOOL m_bDown;
58 | };
59 |
60 | #endif // #ifndef RBUTTON_H
61 |
--------------------------------------------------------------------------------
/Src/RDialog.cpp:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:RDialog.cpp
3 | // 文件版本:v1.0
4 | // 文件描述:自绘对话框类实现文件
5 | //------------------------------------------------------------------------------
6 |
7 | #include "stdafx.h"
8 | #include "AutoUpdate.h"
9 | #include "UISkinManager.h"
10 | #include "RDialog.h"
11 |
12 | #ifdef _DEBUG
13 | #define new DEBUG_NEW
14 | #undef THIS_FILE
15 | static char THIS_FILE[] = __FILE__;
16 | #endif
17 |
18 | //
19 | // CRDialog 对话框
20 | //
21 |
22 | IMPLEMENT_DYNAMIC(CRDialog, CDialog)
23 |
24 | CRDialog::CRDialog(LPCTSTR lpszTemplateName,
25 | CWnd* pParentWnd /*=NULL*/)
26 | : CDialog(lpszTemplateName, pParentWnd)
27 | {
28 | }
29 |
30 | CRDialog::CRDialog(UINT nIDTemplate,
31 | CWnd* pParentWnd /*=NULL*/)
32 | : CDialog(nIDTemplate, pParentWnd),
33 | m_btnMinimize(CRButton::ButtonTypeMinimize),
34 | m_btnMaximize(CRButton::ButtonTypeMaximize),
35 | m_btnClose(CRButton::ButtonTypeClose)
36 | {
37 | }
38 |
39 | CRDialog::~CRDialog()
40 | {
41 | }
42 |
43 | BOOL CRDialog::OnInitDialog()
44 | {
45 | CDialog::OnInitDialog();
46 |
47 | // 已在资源管理器的窗体属性中设置Topmost属性为true
48 | // SetWindowPos(&CWnd::wndTopMost, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
49 |
50 | // 创建最小化、自动化、关闭按钮
51 | CRect rcWnd;
52 | CRect rcButton;
53 |
54 | GetClientRect(&rcWnd);
55 | rcButton.SetRect(0,
56 | 0,
57 | CUISkinManager::m_iSystemControlButtonWidth,
58 | CUISkinManager::m_iSystemControlButtonHeight);
59 | rcButton.OffsetRect(rcWnd.Width() - CUISkinManager::m_iLeftMargin - rcButton.Width(), 6);
60 |
61 | m_btnMinimize.Create("", WS_CHILD, rcButton, this, IDC_BUTTON_MINIMIZE);
62 | m_btnMaximize.Create("", WS_CHILD, rcButton, this, IDC_BUTTON_MAXIMIZE);
63 | m_btnClose.Create("", WS_CHILD, rcButton, this, IDC_BUTTON_CLOSE);
64 |
65 | m_btnClose.MoveWindow(rcButton);
66 | rcButton.OffsetRect(-rcButton.Width() - 2, 0);
67 | m_btnMaximize.MoveWindow(rcButton);
68 | rcButton.OffsetRect(-rcButton.Width() - 2, 0);
69 | m_btnMinimize.MoveWindow(rcButton);
70 |
71 | // 显示/隐藏按钮
72 | DWORD iWindowStyle;
73 |
74 | iWindowStyle = GetStyle();
75 | if (iWindowStyle & WS_MINIMIZEBOX) {
76 | m_btnMinimize.ShowWindow(SW_SHOW);
77 | }
78 | if (iWindowStyle & WS_MAXIMIZEBOX) {
79 | m_btnMaximize.ShowWindow(SW_SHOW);
80 | }
81 |
82 | // if (iWindowStyle & WS_CLOSE)
83 | // {
84 | m_btnClose.ShowWindow(SW_SHOW);
85 | // }
86 |
87 | // return TRUE unless you set the focus to a control
88 | // 异常: OCX 属性页应返回 FALSE
89 | return TRUE;
90 | }
91 |
92 | // 处理命令消息
93 | BOOL CRDialog::OnCmdMsg(UINT nID,
94 | int nCode,
95 | void* pExtra,
96 | AFX_CMDHANDLERINFO* pHandlerInfo)
97 | {
98 | if (nID == IDC_BUTTON_MINIMIZE) {
99 | OnBtnClickedMinimize();
100 | } else if (nID == IDC_BUTTON_MAXIMIZE) {
101 | OnBtnClickedMaximize();
102 | } else if (nID == IDC_BUTTON_CLOSE) {
103 | OnBtnClickedClose();
104 | }
105 |
106 | return CDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
107 | }
108 |
109 | BEGIN_MESSAGE_MAP(CRDialog, CDialog)
110 | // RDIALOG_UI_MESSAGE_MAP
111 | ON_BN_CLICKED(IDC_BUTTON_MINIMIZE, OnBtnClickedMinimize)
112 | ON_BN_CLICKED(IDC_BUTTON_MAXIMIZE, OnBtnClickedMaximize)
113 | ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnBtnClickedClose)
114 | END_MESSAGE_MAP()
115 |
116 | //
117 | // CRDialog 消息处理程序
118 | //
119 | void CRDialog::OnPaint()
120 | {
121 | if (!IsWindowVisible() ||
122 | IsIconic()) {
123 | CDialog::OnPaint();
124 | return;
125 | }
126 |
127 | // device context for painting
128 | CPaintDC dc(this);
129 |
130 | // TODO: 在此处添加消息处理程序代码
131 | // 不为绘图消息调用 CDialog::OnPaint()
132 |
133 | CUISkinManager::Paint(this, &dc);
134 |
135 | // 自绘窗口
136 | CUISkinManager::PaintDialogBorder(this, &dc);
137 |
138 | //
139 | // 重绘按钮
140 | //
141 |
142 | // m_btnMinimize.Invalidate();
143 | // m_btnMaximize.Invalidate();
144 | // m_btnClose.Invalidate();
145 |
146 | return;
147 | }
148 |
149 | void CRDialog::OnSize(UINT nType,
150 | int cx,
151 | int cy)
152 | {
153 | CDialog::OnSize(nType, cx, cy);
154 |
155 | // 移动按钮
156 | if (m_btnClose.m_hWnd != NULL) {
157 | CRect rcButton;
158 | m_btnClose.GetWindowRect(&rcButton);
159 | rcButton.OffsetRect(cx - CUISkinManager::m_iLeftMargin - rcButton.Width() - rcButton.left, 6 - rcButton.top);
160 | m_btnClose.MoveWindow(rcButton);
161 | rcButton.OffsetRect(-rcButton.Width() - 2, 0);
162 | m_btnMaximize.MoveWindow(rcButton);
163 | rcButton.OffsetRect(-rcButton.Width() - 2, 0);
164 | m_btnMinimize.MoveWindow(rcButton);
165 | }
166 |
167 | CUISkinManager::SetRgn(this);
168 | }
169 |
170 | HBRUSH CRDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
171 | {
172 | // HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
173 |
174 | // TODO: 在此更改 DC 的任何属性
175 |
176 | // TODO: 如果默认的不是所需画笔,则返回另一个画笔
177 | // return hbr;
178 | return CUISkinManager::OnCtlColor(pDC, pWnd, nCtlColor);
179 | }
180 |
181 | void CRDialog::OnLButtonDown(UINT nFlags,
182 | CPoint point)
183 | {
184 | // 鼠标点击窗口标题栏,发送消息模拟实现拖动窗口的功能
185 | if (point.y <= (LONG)CUISkinManager::m_iTitleBarHeight) {
186 | SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);
187 | }
188 |
189 | CDialog::OnLButtonDown(nFlags, point);
190 | }
191 |
192 | // 点击最小化按钮
193 | void CRDialog::OnBtnClickedMinimize()
194 | {
195 | // 发送最小化窗口消息
196 | SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
197 | }
198 |
199 | // 点击最大化按钮
200 | void CRDialog::OnBtnClickedMaximize()
201 | {
202 | if (GetWindowLong(m_hWnd, GWL_STYLE) & WS_MAXIMIZE) {
203 | // 如果当前窗口处于最大化状态,发送恢复窗口大小消息
204 | SendMessage(WM_SYSCOMMAND, SC_RESTORE);
205 | } else {
206 | // 发送最大化窗口消息
207 | SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE);
208 | }
209 | }
210 |
211 | // 点击关闭按钮
212 | void CRDialog::OnBtnClickedClose()
213 | {
214 | // 发送关闭窗口消息
215 | SendMessage(WM_SYSCOMMAND, SC_CLOSE);
216 | }
217 |
--------------------------------------------------------------------------------
/Src/RDialog.h:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:RDialog.h
3 | // 文件版本:v1.0
4 | // 文件描述:自绘对话框类
5 | // 使用自绘对话框类派生自定义对话框的步骤是:
6 | // 1、将自定义对话框类的基类由CDialog改为CRDialog
7 | // 2、在派生类的构造函数、对话框初始化函数OnInitDialog等各处,将CDialog改为CRDialog
8 | // 3、在派生类的消息定义BEGIN_MESSAGE_MAP后添加宏RDIALOG_UI_MESSAGE_MAP
9 | //------------------------------------------------------------------------------
10 |
11 | #pragma once
12 |
13 | #ifndef RDIALOG_H
14 | #define RDIALOG_H
15 |
16 | #include "RButton.h"
17 |
18 | // 实现自绘界面的消息映射宏,将此宏插入到派生类的BEGIN_MESSAGE_MAP后
19 | #define RDIALOG_UI_MESSAGE_MAP\
20 | ON_WM_PAINT()\
21 | ON_WM_SIZE()\
22 | ON_WM_CTLCOLOR()\
23 | ON_WM_LBUTTONDOWN()
24 |
25 | // CRDialog 对话框
26 |
27 | class CRDialog : public CDialog
28 | {
29 | DECLARE_DYNAMIC(CRDialog)
30 |
31 | public:
32 | // 构造/析构函数
33 | CRDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
34 | CRDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
35 | virtual ~CRDialog();
36 |
37 | protected:
38 | virtual BOOL OnInitDialog();
39 | virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
40 |
41 | DECLARE_MESSAGE_MAP()
42 |
43 | public:
44 | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
45 | afx_msg void OnPaint();
46 | afx_msg void OnSize(UINT nType, int cx, int cy);
47 | afx_msg void OnBtnClickedMinimize();
48 | afx_msg void OnBtnClickedMaximize();
49 | afx_msg void OnBtnClickedClose();
50 | afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
51 |
52 | protected:
53 | // 最小化按钮
54 | CRButton m_btnMinimize;
55 | // 最大化按钮
56 | CRButton m_btnMaximize;
57 | // 关闭按钮
58 | CRButton m_btnClose;
59 | };
60 |
61 | #endif // #ifndef RDIALOG_H
62 |
--------------------------------------------------------------------------------
/Src/RMessageBox.cpp:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:RMessageBox.cpp
3 | // 文件版本:v1.0
4 | // 文件描述:自定义消息框类实现文件
5 | //------------------------------------------------------------------------------
6 |
7 | #include "stdafx.h"
8 | #include "AutoUpdate.h"
9 | #include "RMessageBox.h"
10 |
11 | #ifdef _DEBUG
12 | #define new DEBUG_NEW
13 | #undef THIS_FILE
14 | static char THIS_FILE[] = __FILE__;
15 | #endif
16 |
17 | //
18 | // CRMessageBox 对话框
19 | //
20 |
21 | IMPLEMENT_DYNAMIC(CRMessageBox, CDialog)
22 |
23 | CRMessageBox::CRMessageBox(CWnd* pParent /*=NULL*/)
24 | : CRDialog(CRMessageBox::IDD, pParent)
25 | {
26 | m_iID = MB_OK;
27 | m_bOption1 = FALSE;
28 | m_bOption2 = FALSE;
29 | }
30 |
31 | CRMessageBox::~CRMessageBox()
32 | {
33 | }
34 |
35 | void CRMessageBox::DoDataExchange(CDataExchange* pDX)
36 | {
37 | CDialog::DoDataExchange(pDX);
38 | DDX_Control(pDX, IDC_STATIC_ICON, m_stcIcon);
39 | DDX_Control(pDX, IDC_STATIC_PROMPT, m_stcPromptMessage);
40 | DDX_Control(pDX, IDC_CHECK_OPTION1, m_chkOption1);
41 | DDX_Check(pDX, IDC_CHECK_OPTION1, m_bOption1);
42 | DDX_Control(pDX, IDC_CHECK_OPTION2, m_chkOption2);
43 | DDX_Check(pDX, IDC_CHECK_OPTION2, m_bOption2);
44 | DDX_Control(pDX, IDC_BUTTON_OK, m_btnOK);
45 | DDX_Control(pDX, IDC_BUTTON_CANCEL, m_btnCancel);
46 | DDX_Control(pDX, IDC_BUTTON_ABORT, m_btnAbort);
47 | DDX_Control(pDX, IDC_BUTTON_IGANORE, m_btnIganore);
48 | DDX_Control(pDX, IDC_BUTTON_RETRY, m_btnRetry);
49 | DDX_Control(pDX, IDC_BUTTON_CONTINUE, m_btnContinue);
50 | DDX_Control(pDX, IDC_BUTTON_YES, m_btnYes);
51 | DDX_Control(pDX, IDC_BUTTON_NO, m_btnNo);
52 | }
53 |
54 | BOOL CRMessageBox::OnInitDialog()
55 | {
56 | CRDialog::OnInitDialog();
57 |
58 | // 设置对话框标题
59 | SetWindowText(m_strTitle);
60 |
61 | m_btnOK.SetWindowText(STRING(STR_BUTTON_OK, "确定(&O)"));
62 | m_btnCancel.SetWindowText(STRING(STR_BUTTON_CANCEL, "取消(&C)"));
63 | m_btnAbort.SetWindowText(STRING(STR_BUTTON_ABORT, "跳出(&A)"));
64 | m_btnIganore.SetWindowText(STRING(STR_BUTTON_IGANORE, "忽略(&I)"));
65 | m_btnRetry.SetWindowText(STRING(STR_BUTTON_RETRY, "重试(&R)"));
66 | m_btnContinue.SetWindowText(STRING(STR_BUTTON_CONTINUE, "继续(&C)"));
67 | m_btnYes.SetWindowText(STRING(STR_BUTTON_YES, "是(&Y)"));
68 | m_btnNo.SetWindowText(STRING(STR_BUTTON_NO, "否(&N)"));
69 |
70 | // 判断是否需要显示复选框
71 | if (!m_strOptionPromptMessage1.IsEmpty()) {
72 | m_chkOption1.SetWindowText(m_strOptionPromptMessage1);
73 | m_chkOption1.ShowWindow(SW_SHOW);
74 | } else {
75 | m_chkOption1.ShowWindow(SW_HIDE);
76 | }
77 | if (!m_strOptionPromptMessage2.IsEmpty()) {
78 | m_chkOption2.SetWindowText(m_strOptionPromptMessage2);
79 | m_chkOption2.ShowWindow(SW_SHOW);
80 | } else {
81 | m_chkOption2.ShowWindow(SW_HIDE);
82 | }
83 |
84 | // 图标控件仅作为占位符来用,不显示
85 | m_stcIcon.ShowWindow(SW_HIDE);
86 |
87 | UpdateData(FALSE);
88 |
89 | // 重置对话框大小、按钮位置
90 | ResetMessageBox();
91 |
92 | // return TRUE unless you set the focus to a control
93 | // 异常: OCX 属性页应返回 FALSE
94 | return TRUE;
95 | }
96 |
97 | void CRMessageBox::OnOK()
98 | {
99 | CWnd *pActiveControl = GetFocus();
100 | if (*pActiveControl == m_btnOK) {
101 | OnBtnClickedOk();
102 | } else if (*pActiveControl == m_btnCancel) {
103 | OnBtnClickedCancel();
104 | } else if (*pActiveControl == m_btnAbort) {
105 | OnBtnClickedAbort();
106 | } else if (*pActiveControl == m_btnIganore) {
107 | OnBtnClickedIganore();
108 | } else if (*pActiveControl == m_btnRetry) {
109 | OnBtnClickedRetry();
110 | } else if (*pActiveControl == m_btnContinue) {
111 | OnBtnClickedContinue();
112 | } else if (*pActiveControl == m_btnYes) {
113 | OnBtnClickedYes();
114 | } else if (*pActiveControl == m_btnNo) {
115 | OnBtnClickedNo();
116 | }
117 |
118 | // CDialog::OnOK();
119 | }
120 |
121 | void CRMessageBox::OnCancel()
122 | {
123 | // 根据消息框样式对按下ESC键
124 | // 及关闭对话框按钮操作的结果进行修正
125 | switch (m_iType & 0xF) {
126 | case MB_OK:
127 | m_iID = IDOK;
128 | break;
129 | case MB_OKCANCEL:
130 | m_iID = IDCANCEL;
131 | break;
132 | case MB_YESNO:
133 | m_iID = IDNO;
134 | break;
135 | case MB_YESNOCANCEL:
136 | m_iID = IDCANCEL;
137 | break;
138 | case MB_RETRYCANCEL:
139 | m_iID = IDCANCEL;
140 | break;
141 |
142 | // case MB_CANCELTRYCONTINUE:
143 | // m_iID = IDCANCEL;
144 | // break;
145 |
146 | case MB_ABORTRETRYIGNORE:
147 | m_iID = IDABORT;
148 | break;
149 | default:
150 | m_iID = IDCANCEL;
151 | break;
152 | }
153 | CDialog::OnCancel();
154 | }
155 |
156 |
157 | BEGIN_MESSAGE_MAP(CRMessageBox, CDialog)
158 | RDIALOG_UI_MESSAGE_MAP
159 | ON_BN_CLICKED(IDOK, OnOK)
160 | ON_BN_CLICKED(IDCANCEL, OnCancel)
161 | ON_BN_CLICKED(IDC_BUTTON_OK, OnBtnClickedOk)
162 | ON_BN_CLICKED(IDC_BUTTON_CANCEL, OnBtnClickedCancel)
163 | ON_BN_CLICKED(IDC_BUTTON_ABORT, OnBtnClickedAbort)
164 | ON_BN_CLICKED(IDC_BUTTON_IGANORE, OnBtnClickedIganore)
165 | ON_BN_CLICKED(IDC_BUTTON_RETRY, OnBtnClickedRetry)
166 | ON_BN_CLICKED(IDC_BUTTON_CONTINUE, OnBtnClickedContinue)
167 | ON_BN_CLICKED(IDC_BUTTON_YES, OnBtnClickedYes)
168 | ON_BN_CLICKED(IDC_BUTTON_NO, OnBtnClickedNo)
169 | END_MESSAGE_MAP()
170 |
171 | //
172 | // CRMessageBox 消息处理程序
173 | //
174 |
175 | void CRMessageBox::OnPaint()
176 | {
177 | if (!IsWindowVisible() ||
178 | IsIconic()) {
179 | CDialog::OnPaint();
180 | return;
181 | }
182 |
183 | // 绘制窗口
184 | CRDialog::OnPaint();
185 |
186 | // 显示图标
187 | HICON hIcon;
188 | CRect rcIcon;
189 | POINT point;
190 |
191 | m_stcIcon.GetWindowRect(&rcIcon);
192 | ScreenToClient(&rcIcon);
193 | point.x = rcIcon.left;
194 | point.y = rcIcon.top;
195 |
196 | // 根据消息框类型加载不同的图标
197 | switch (m_iType & 0xF0) {
198 | case MB_ICONHAND: // MB_ICONERROR/MB_ICONSTOP
199 | hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_HAND));
200 | break;
201 | case MB_ICONQUESTION:
202 | hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION));
203 | break;
204 | case MB_ICONEXCLAMATION: // MB_ICONWARNING
205 | hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_WARNING));
206 | break;
207 | case MB_ICONINFORMATION: // MB_ICONASTERISK
208 | hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_INFORMATION));
209 | break;
210 | case MB_USERICON:
211 | default:
212 | hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_INFORMATION));
213 | break;
214 | }
215 |
216 | // 画图标
217 | CDC *pDC = GetDC();
218 | pDC->DrawIcon(point, hIcon);
219 | ReleaseDC(pDC);
220 | }
221 |
222 | void CRMessageBox::OnBtnClickedOk()
223 | {
224 | m_iID = IDOK;
225 |
226 | // 隐藏窗口
227 | CDialog::OnOK();
228 | }
229 |
230 | void CRMessageBox::OnBtnClickedCancel()
231 | {
232 | m_iID = IDCANCEL;
233 |
234 | // 隐藏窗口
235 | CDialog::OnOK();
236 | }
237 |
238 | void CRMessageBox::OnBtnClickedAbort()
239 | {
240 | m_iID = IDABORT;
241 |
242 | // 隐藏窗口
243 | CDialog::OnOK();
244 | }
245 |
246 | void CRMessageBox::OnBtnClickedIganore()
247 | {
248 | m_iID = IDIGNORE;
249 |
250 | // 隐藏窗口
251 | CDialog::OnOK();
252 | }
253 |
254 | void CRMessageBox::OnBtnClickedRetry()
255 | {
256 | m_iID = IDRETRY;
257 |
258 | // 隐藏窗口
259 | CDialog::OnOK();
260 | }
261 |
262 | void CRMessageBox::OnBtnClickedContinue()
263 | {
264 | // m_iID = IDCONTINUE;
265 |
266 | // 隐藏窗口
267 | CDialog::OnOK();
268 | }
269 |
270 | void CRMessageBox::OnBtnClickedYes()
271 | {
272 | m_iID = IDYES;
273 |
274 | // 隐藏窗口
275 | CDialog::OnOK();
276 | }
277 |
278 | void CRMessageBox::OnBtnClickedNo()
279 | {
280 | m_iID = IDNO;
281 |
282 | // 隐藏窗口
283 | CDialog::OnOK();
284 | }
285 |
286 | // 重置消息框样式和外观
287 | void CRMessageBox::ResetMessageBox()
288 | {
289 | // 根据信息的多少重置对话框窗口大小
290 | CRect rcWnd;
291 | CRect rcPromptMessage;
292 | CRect rcButton;
293 | CSize size;
294 | CDC* pDC;
295 | // 按钮控件需要在垂直方向上的移位距离
296 | int iOffsetY;
297 |
298 | GetWindowRect(&rcWnd);
299 |
300 | // 根据提示文字的多少计算窗口大小
301 | pDC = m_stcPromptMessage.GetDC();
302 | size = pDC->GetTextExtent(m_strPromptMessage);
303 | m_stcPromptMessage.ReleaseDC(pDC);
304 | if (size.cx < 200) {
305 | size.cx = 200;
306 | } else if (size.cx > 500) {
307 | size.cy = size.cx / 500 * size.cy;
308 | size.cx = 500;
309 | }
310 | if (size.cy < 32) {
311 | size.cy = 32;
312 | }
313 | rcWnd.right = rcWnd.left + size.cx + 100;
314 | rcWnd.bottom = rcWnd.top + size.cy + 155;
315 | // 如果要显示复选框,要加上复选框的高度
316 | if (!m_strOptionPromptMessage1.IsEmpty()) {
317 | rcWnd.bottom += 18;
318 | }
319 | if (!m_strOptionPromptMessage2.IsEmpty()) {
320 | rcWnd.bottom += 18;
321 | }
322 |
323 | // 将窗口移动到屏幕中间
324 | CRect rcScreen;
325 | // 取得屏幕大小
326 | ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0);
327 | rcWnd.OffsetRect(rcScreen.CenterPoint() - rcWnd.CenterPoint());
328 |
329 | MoveWindow(&rcWnd);
330 |
331 | // 重置提示信息标签的大小
332 | m_stcPromptMessage.GetWindowRect(&rcPromptMessage);
333 | ScreenToClient(&rcPromptMessage);
334 | rcPromptMessage.right = rcPromptMessage.left + size.cx;
335 | rcPromptMessage.bottom = rcPromptMessage.top + size.cy + 5;
336 | m_stcPromptMessage.MoveWindow(&rcPromptMessage);
337 |
338 | // 重置复选框控件的大小
339 | m_chkOption1.GetWindowRect(&rcPromptMessage);
340 | ScreenToClient(&rcPromptMessage);
341 | rcPromptMessage.right = rcPromptMessage.left + size.cx;
342 | m_chkOption1.MoveWindow(&rcPromptMessage);
343 | m_chkOption2.GetWindowRect(&rcPromptMessage);
344 | ScreenToClient(&rcPromptMessage);
345 | rcPromptMessage.right = rcPromptMessage.left + size.cx;
346 | m_chkOption2.MoveWindow(&rcPromptMessage);
347 |
348 | // 显示提示信息
349 | m_stcPromptMessage.SetWindowText(m_strPromptMessage);
350 |
351 | // 根据类型显示不同的按钮,并将它们移动到对话框中间
352 | m_btnOK.GetWindowRect(&rcButton);
353 | ScreenToClient(&rcButton);
354 | iOffsetY = rcWnd.Height() - rcButton.top - 48;
355 | switch (m_iType & 0xF) {
356 | case MB_OK:
357 | m_btnOK.ShowWindow(SW_SHOW);
358 | rcButton.OffsetRect((rcWnd.Width() - rcButton.Width()) / 2 - rcButton.left, iOffsetY);
359 | m_btnOK.MoveWindow(&rcButton);
360 | break;
361 | case MB_OKCANCEL:
362 | m_btnOK.ShowWindow(SW_SHOW);
363 | m_btnCancel.ShowWindow(SW_SHOW);
364 | rcButton.OffsetRect(rcWnd.Width() / 2 - rcButton.Width() - 2 - rcButton.left, iOffsetY);
365 | m_btnOK.MoveWindow(&rcButton);
366 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
367 | m_btnCancel.MoveWindow(&rcButton);
368 | break;
369 | case MB_YESNO:
370 | m_btnYes.ShowWindow(SW_SHOW);
371 | m_btnNo.ShowWindow(SW_SHOW);
372 | rcButton.OffsetRect(rcWnd.Width() / 2 - rcButton.Width() - 2 - rcButton.left, iOffsetY);
373 | m_btnYes.MoveWindow(&rcButton);
374 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
375 | m_btnNo.MoveWindow(&rcButton);
376 | break;
377 | case MB_YESNOCANCEL:
378 | m_btnYes.ShowWindow(SW_SHOW);
379 | m_btnNo.ShowWindow(SW_SHOW);
380 | m_btnCancel.ShowWindow(SW_SHOW);
381 | rcButton.OffsetRect((rcWnd.Width() - rcButton.Width()) / 2 - 2 - rcButton.Width() - rcButton.left, iOffsetY);
382 | m_btnYes.MoveWindow(&rcButton);
383 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
384 | m_btnNo.MoveWindow(&rcButton);
385 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
386 | m_btnCancel.MoveWindow(&rcButton);
387 | break;
388 | case MB_RETRYCANCEL:
389 | m_btnRetry.ShowWindow(SW_SHOW);
390 | m_btnCancel.ShowWindow(SW_SHOW);
391 | rcButton.OffsetRect(rcWnd.Width() / 2 - rcButton.Width() - 2 - rcButton.left, iOffsetY);
392 | m_btnRetry.MoveWindow(&rcButton);
393 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
394 | m_btnCancel.MoveWindow(&rcButton);
395 | break;
396 |
397 | // case MB_CANCELTRYCONTINUE:
398 | // m_btnCancel.ShowWindow(SW_SHOW);
399 | // m_btnContinue.ShowWindow(SW_SHOW);
400 | // rcButton.OffsetRect(rcWnd.Width() / 2 - rcButton.Width() - 2 - rcButton.left, iOffsetY);
401 | // m_btnCancel.MoveWindow(&rcButton);
402 | // rcButton.OffsetRect(rcButton.Width() + 4, 0);
403 | // m_btnContinue.MoveWindow(&rcButton);
404 | // break;
405 |
406 | case MB_ABORTRETRYIGNORE:
407 | m_btnAbort.ShowWindow(SW_SHOW);
408 | m_btnRetry.ShowWindow(SW_SHOW);
409 | m_btnIganore.ShowWindow(SW_SHOW);
410 | rcButton.OffsetRect((rcWnd.Width() - rcButton.Width()) / 2 - 2 - rcButton.Width() - rcButton.left, iOffsetY);
411 | m_btnAbort.MoveWindow(&rcButton);
412 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
413 | m_btnRetry.MoveWindow(&rcButton);
414 | rcButton.OffsetRect(rcButton.Width() + 4, 0);
415 | m_btnIganore.MoveWindow(&rcButton);
416 | break;
417 | default:
418 | break;
419 | }
420 |
421 | // 图标的显示在OnPaint函数中实现
422 | }
--------------------------------------------------------------------------------
/Src/RMessageBox.h:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:RMessageBox.h
3 | // 文件版本:v1.0
4 | // 文件描述:自定义消息框类
5 | //------------------------------------------------------------------------------
6 |
7 | #pragma once
8 |
9 | #ifndef RMESSAGEBOX_H
10 | #define RMESSAGEBOX_H
11 |
12 | #include "RDialog.h"
13 | #include "RButton.h"
14 |
15 | // CRMessageBox 对话框
16 |
17 | class CRMessageBox : public CRDialog
18 | {
19 | DECLARE_DYNAMIC(CRMessageBox)
20 |
21 | public:
22 | // 标准构造函数
23 | CRMessageBox(CWnd* pParent = NULL);
24 | virtual ~CRMessageBox();
25 |
26 | // 对话框数据
27 | enum { IDD = IDD_MESSAGEBOX };
28 |
29 | protected:
30 | // DDX/DDV 支持
31 | virtual void DoDataExchange(CDataExchange* pDX);
32 | virtual BOOL OnInitDialog();
33 | virtual void OnOK();
34 | virtual void OnCancel();
35 |
36 | DECLARE_MESSAGE_MAP()
37 |
38 | protected:
39 | afx_msg void OnPaint();
40 | afx_msg void OnBtnClickedOk();
41 | afx_msg void OnBtnClickedCancel();
42 | afx_msg void OnBtnClickedAbort();
43 | afx_msg void OnBtnClickedIganore();
44 | afx_msg void OnBtnClickedRetry();
45 | afx_msg void OnBtnClickedContinue();
46 | afx_msg void OnBtnClickedYes();
47 | afx_msg void OnBtnClickedNo();
48 | void ResetMessageBox();
49 |
50 | public:
51 | // 消息框标题
52 | CString m_strTitle;
53 | // 消息框样式
54 | int m_iType;
55 | // 用户点中的按钮
56 | int m_iID;
57 | // 提示信息
58 | CString m_strPromptMessage;
59 | // 复选框1提示信息,当此字符串不为空时,显示复选框,否则隐藏复选框
60 | CString m_strOptionPromptMessage1;
61 | // 复选框1选则状态的值
62 | BOOL m_bOption1;
63 | // 复选框2提示信息,当此字符串不为空时,显示复选框,否则隐藏复选框
64 | CString m_strOptionPromptMessage2;
65 | // 复选框2选则状态的值
66 | BOOL m_bOption2;
67 |
68 | protected:
69 | CStatic m_stcIcon;
70 | CStatic m_stcPromptMessage;
71 | CButton m_chkOption1;
72 | CButton m_chkOption2;
73 | CRButton m_btnOK;
74 | CRButton m_btnCancel;
75 | CRButton m_btnAbort;
76 | CRButton m_btnIganore;
77 | CRButton m_btnRetry;
78 | CRButton m_btnContinue;
79 | CRButton m_btnYes;
80 | CRButton m_btnNo;
81 | };
82 |
83 | #endif // #ifndef RMESSAGEBOX_H
84 |
--------------------------------------------------------------------------------
/Src/Release/AutoUpdate.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/AutoUpdate.exe
--------------------------------------------------------------------------------
/Src/Release/AutoUpdate.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/AutoUpdate.res
--------------------------------------------------------------------------------
/Src/Release/DelRegistry.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/DelRegistry.exe
--------------------------------------------------------------------------------
/Src/Release/ImageTuner.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/ImageTuner.exe
--------------------------------------------------------------------------------
/Src/Release/InitRegistry.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/InitRegistry.exe
--------------------------------------------------------------------------------
/Src/Release/MyBrowser.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/MyBrowser.exe
--------------------------------------------------------------------------------
/Src/Release/UpdateConfig-Full.ini:
--------------------------------------------------------------------------------
1 | # 更新配置文件UpdateCofig.ini
2 |
3 | [UPDATE]
4 | AppName=MyBrowser
5 | Version=3.2.1
6 | BaseUrl=http://beijing.cbs.bacic5i5j.com/static/AutoUpdate
7 | RunAfterDownload=MyBrowser.exe
8 |
9 | [COMMON]
10 | FileCount=2
11 |
12 | [CommonFile1]
13 | Name=MyBrowser.exe
14 | Size=3930808
15 | Hash=FC18F71B1C80D83CEE344F87B8AC3374
16 | CompressMethod=None
17 | DestPath=
18 |
19 | [CommonFile2]
20 | Name=myie.ini
21 | Size=3126
22 | Hash=85F88866A2F97D8FAD4613033BDE5D25
23 | CompressMethod=None
24 | DestPath=
25 |
26 | ########################################################################################################
27 | 附录:路径字符串变量中一些固定变量的替换
28 | # 自动更新软件运行目录,即软件安装目录
29 | # Windows程序文件目录,例如C:\Program Files
30 | # Windows公共程序文件目录,例如C:\Program Files\Common Files
31 | # 用户桌面目录
32 | # Windows目录,例如C:\Windows
33 | # Windows系统文件目录,例如C:\Windows\System32
34 | # 临时文件目录,例如C:\Windows\Temp
35 | # 开始菜单目录
36 | # 开始菜单下的程序目录
37 | # 开始菜单下的启动目录
38 | # Windows任务条快速启动目录
39 | # 我的文档目录
40 | # 应用程序数据目录
41 | # 用户目录,例如C:\Documents and Settings\Administrator
42 | ########################################################################################################
43 |
--------------------------------------------------------------------------------
/Src/Release/UpdateConfig.ini:
--------------------------------------------------------------------------------
1 | ######## 小房子自动升级配置文件 ########
2 |
3 | [UPDATE]
4 | AppName=MyBrowser
5 | Version=3.3.0
6 | BaseUrl=http://beijing.cbs.bacic5i5j.com/static/AutoUpdate
7 | RunAfterDownload=MyBrowser.exe
8 |
9 | [COMMON]
10 | FileCount=2
11 |
12 | [CommonFile1]
13 | Name=MyBrowser.exe
14 | Size=3978248
15 | Hash=98A2BDBA2CC5AED904FABDE61EADC0C9
16 | CompressMethod=None
17 | DestPath=
18 |
19 | [CommonFile2]
20 | Name=myie.ini
21 | Size=3274
22 | Hash=16D2329FCD34EB0715714307A5818E76
23 | CompressMethod=None
24 | DestPath=
25 |
26 | #########################################
--------------------------------------------------------------------------------
/Src/Release/UsbDll.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/UsbDll.dll
--------------------------------------------------------------------------------
/Src/Release/UsbPhone.ini:
--------------------------------------------------------------------------------
1 | [UsbPhone]
2 | Record=1
3 | Upload=1
4 | UploadPath=UploadFile/
5 | FtpServer=192.168.0.101
6 | FtpUser=
7 | FtpPassword=
8 | WriteLog=1
9 | LogDir=c:\Work\UsbPhone\Debug\log\
10 |
--------------------------------------------------------------------------------
/Src/Release/getcpu.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/getcpu.exe
--------------------------------------------------------------------------------
/Src/Release/machineinf.bat:
--------------------------------------------------------------------------------
1 | cmd /k getcpu.exe
--------------------------------------------------------------------------------
/Src/Release/myie.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/myie.ini
--------------------------------------------------------------------------------
/Src/Release/shdoclc.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/Release/shdoclc.dll
--------------------------------------------------------------------------------
/Src/StdAfx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // AutoUpdate.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 | #include "AutoUpdate.h"
7 | #include "RMessageBox.h"
8 |
9 | // // 记录日志级别
10 | int g_iLogLevel = 0;
11 |
12 | // 显示日志的文本框
13 | // extern CRichEditCtrl *g_pLogViewer;
14 |
15 | // 日志格式[时间][模块ID][日志级别][日志内容]
16 | #define LOG_FORMAT "[%s][%d][%d] %s \r\n"
17 | // 日志缓冲区大小
18 | #define LOG_BUFFER_SIZE 1024
19 |
20 | // 写日志
21 | // iModuleID:模块ID
22 | // iLevel:日志级别
23 | // szFormat:日志格式
24 | // ...:日志内容
25 | void LOG(int iModuleID,
26 | int iLevel,
27 | const char* sFormat, ...)
28 | {
29 | // 只记录级别在指定日志级别以上的日志
30 | if (iLevel < g_iLogLevel) { return; }
31 |
32 | char *pBuffer1 = new char[LOG_BUFFER_SIZE];
33 | char *pBuffer2 = new char[LOG_BUFFER_SIZE];
34 | memset(pBuffer1, 0, LOG_BUFFER_SIZE);
35 | memset(pBuffer2, 0, LOG_BUFFER_SIZE);
36 |
37 | va_list args;
38 | va_start(args, sFormat);
39 | _vsnprintf(pBuffer1, LOG_BUFFER_SIZE, sFormat, args);
40 | va_end(args);
41 |
42 | try {
43 | CString sNow = CTime::GetCurrentTime().Format("%Y-%m-%d %H:%M:%S");
44 | _snprintf(pBuffer2,
45 | LOG_BUFFER_SIZE,
46 | LOG_FORMAT,
47 | sNow.GetBuffer(0),
48 | iModuleID,
49 | iLevel,
50 | pBuffer1);
51 |
52 | // // 输出到文本框
53 | // g_pLogViewer->SetSel(-1, 0);
54 | // g_pLogViewer->ReplaceSel(pBuffer2 + CString("\n"));
55 |
56 | // 写入文件
57 | CFile file;
58 |
59 | // 创建Log目录
60 | CreateDirectory(GetAppDirectory() + "Log", NULL);
61 |
62 | file.Open(GetAppDirectory() + "Log\\AutoUpdate.log",
63 | CFile::modeCreate |
64 | CFile::modeNoTruncate |
65 | CFile::modeWrite);
66 | file.SeekToEnd();
67 | file.Write(pBuffer2, (UINT)strlen(pBuffer2));
68 | } catch (...) {
69 | }
70 |
71 | // 释放临时申请的内存
72 | delete []pBuffer1;
73 | delete []pBuffer2;
74 | pBuffer1 = NULL;
75 | pBuffer2 = NULL;
76 | }
77 |
78 | //
79 | // 取得程序运行的目录
80 | // bEndWithBackSlash:是否以反斜线结尾
81 | //
82 | CString GetAppDirectory(BOOL bEndWithBackSlash)
83 | {
84 | char acBuffer[MAX_PATH];
85 |
86 | memset((void *)acBuffer, 0, MAX_PATH);
87 | GetModuleFileName(AfxGetInstanceHandle(), acBuffer, sizeof(acBuffer));
88 |
89 | char *p = strrchr(acBuffer, '\\');
90 | if (p != NULL) {
91 | if (bEndWithBackSlash) {
92 | *(p + 1) = '\0';
93 | } else {
94 | *p = '\0';
95 | }
96 | } else {
97 | p = strrchr(acBuffer, ':');
98 | if (p != NULL) {
99 | if (bEndWithBackSlash) {
100 | *(p + 1) = '\\';
101 | *(p + 2) = '\0';
102 | } else {
103 | *p = '\\';
104 | *(p + 1) = '\0';
105 | }
106 | }
107 | }
108 |
109 | return CString(acBuffer);
110 | }
111 |
112 | // 从文件全路径取得文件名
113 | CString GetFilename(const char* sFilePath)
114 | {
115 | if (sFilePath == NULL) {
116 | return CString("");
117 | }
118 |
119 | char *pBackSlash = strrchr(const_cast(sFilePath), '\\');
120 | if (pBackSlash == NULL) {
121 | return CString(sFilePath);
122 | } else {
123 | return CString(++pBackSlash);
124 | }
125 | }
126 |
127 | CString GetFilename(const CString &sFilePath)
128 | {
129 | int iPos = sFilePath.ReverseFind('\\');
130 | if (iPos == -1) {
131 | return sFilePath;
132 | } else {
133 | return sFilePath.Mid(iPos + 1);
134 | }
135 | }
136 |
137 | // 取得文件扩展名(不含'.'字符)
138 | CString GetFileExtendName(const char* sFilename)
139 | {
140 | if (sFilename == NULL) {
141 | return CString("");
142 | }
143 |
144 | char *pExtendName = strrchr(const_cast(sFilename), '.');
145 | if (pExtendName == NULL) {
146 | return CString("");
147 | } else {
148 | return CString(++pExtendName);
149 | }
150 | }
151 |
152 | // 取得文件扩展名(不含'.'字符)
153 | CString GetFileExtendName(const CString& sFilename)
154 | {
155 | int iPos = sFilename.ReverseFind('.');
156 | if (iPos == -1) {
157 | return CString("");
158 | } else {
159 | return sFilename.Mid(iPos + 1);
160 | }
161 | }
162 |
163 | // 取得文件大小
164 | size_t GetFileSize(const char* sFilename)
165 | {
166 | CFileFind FileFinder;
167 |
168 | if (sFilename == NULL) { return 0; }
169 |
170 | if (FileFinder.FindFile(sFilename)) {
171 | FileFinder.FindNextFile();
172 | return (size_t)FileFinder.GetLength();
173 | } else {
174 | return 0;
175 | }
176 | }
177 |
178 | // 取得文件大小
179 | size_t GetFileSize(const CString& sFilename)
180 | {
181 | CFileFind FileFinder;
182 |
183 | if (FileFinder.FindFile(sFilename)) {
184 | FileFinder.FindNextFile();
185 | return (size_t)FileFinder.GetLength();
186 | } else {
187 | return 0;
188 | }
189 | }
190 |
191 | // 显示消息框
192 | int RMessageBox(CString& sText,
193 | UINT nType,
194 | UINT nIDHelp)
195 | {
196 | return RMessageBox(sText.GetBuffer(0), nType, nIDHelp);
197 | }
198 |
199 | // 显示消息框
200 | int RMessageBox(LPCTSTR lpszText,
201 | UINT nType,
202 | UINT nIDHelp)
203 | {
204 | ASSERT(lpszText);
205 |
206 | CRMessageBox mb;
207 |
208 | mb.m_strTitle = AfxGetApp()->m_pszAppName;
209 | mb.m_iType = nType;
210 | mb.m_strPromptMessage = lpszText;
211 | mb.DoModal();
212 | return mb.m_iID;
213 | }
214 |
215 | // 替换路径中的特殊字符串为实际路径
216 | CString ResolvePath(const char* sPath)
217 | {
218 | if (sPath == NULL) {
219 | ASSERT(FALSE);
220 | return CString("");
221 | }
222 |
223 | char acBuffer[MAX_PATH];
224 | CString sDestFilename = sPath;
225 |
226 | sDestFilename.Replace("", GetAppDirectory().GetBuffer(0));
227 |
228 | memset(acBuffer, 0, MAX_PATH);
229 | GetWindowsDirectory(acBuffer, MAX_PATH);
230 | sDestFilename.Replace("", acBuffer);
231 |
232 | memset(acBuffer, 0, MAX_PATH);
233 | GetSystemDirectory(acBuffer, MAX_PATH);
234 | sDestFilename.Replace("", acBuffer);
235 |
236 | memset(acBuffer, 0, MAX_PATH);
237 | // CSIDL_FONTS (0x0014)
238 | SHGetSpecialFolderPath(NULL, acBuffer, 0x0014, FALSE);
239 | sDestFilename.Replace("", acBuffer);
240 |
241 | memset(acBuffer, 0, MAX_PATH);
242 | // CSIDL_PROGRAM_FILES (0x0026)
243 | SHGetSpecialFolderPath(NULL, acBuffer, 0x0026, FALSE);
244 | sDestFilename.Replace("", acBuffer);
245 |
246 | memset(acBuffer, 0, MAX_PATH);
247 | // CSIDL_PROGRAM_FILES_COMMON (0x002b)
248 | SHGetSpecialFolderPath(NULL, acBuffer, 0x002b, FALSE);
249 | sDestFilename.Replace("", acBuffer);
250 |
251 | memset(acBuffer, 0, MAX_PATH);
252 | // CSIDL_PROFILE (0x0028)
253 | SHGetSpecialFolderPath(NULL, acBuffer, 0x0028, FALSE);
254 | sDestFilename.Replace("", acBuffer);
255 |
256 | memset(acBuffer, 0, MAX_PATH);
257 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_PERSONAL, FALSE);
258 | sDestFilename.Replace("", acBuffer);
259 |
260 | memset(acBuffer, 0, MAX_PATH);
261 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_DESKTOPDIRECTORY, FALSE);
262 | sDestFilename.Replace("", acBuffer);
263 |
264 | memset(acBuffer, 0, MAX_PATH);
265 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_STARTMENU, FALSE);
266 | sDestFilename.Replace("", acBuffer);
267 |
268 | memset(acBuffer, 0, MAX_PATH);
269 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_PROGRAMS, FALSE);
270 | sDestFilename.Replace("", acBuffer);
271 |
272 | memset(acBuffer, 0, MAX_PATH);
273 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_STARTUP, FALSE);
274 | sDestFilename.Replace("", acBuffer);
275 |
276 | // sDestFilename.Replace("", acBuffer);
277 |
278 | memset(acBuffer, 0, MAX_PATH);
279 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_SENDTO, FALSE);
280 | sDestFilename.Replace("", acBuffer);
281 |
282 | memset(acBuffer, 0, MAX_PATH);
283 | // CSIDL_FAVORITES (0x0006)
284 | SHGetSpecialFolderPath(NULL, acBuffer, 0x0006, FALSE);
285 | sDestFilename.Replace("", acBuffer);
286 |
287 | memset(acBuffer, 0, MAX_PATH);
288 | SHGetSpecialFolderPath(NULL, acBuffer, CSIDL_APPDATA, FALSE);
289 | sDestFilename.Replace("", acBuffer);
290 |
291 | memset(acBuffer, 0, MAX_PATH);
292 | // CSIDL_LOCAL_APPDATA (0x001c)
293 | SHGetSpecialFolderPath(NULL, acBuffer, 0x001c, FALSE);
294 | sDestFilename.Replace("", acBuffer);
295 |
296 | // sDestFilename.Replace("", acBuffer);
297 |
298 | return sDestFilename;
299 | }
--------------------------------------------------------------------------------
/Src/StdAfx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #if !defined(AFX_STDAFX_H__6E171DE5_929C_4558_880B_14D7DDC8781D__INCLUDED_)
7 | #define AFX_STDAFX_H__6E171DE5_929C_4558_880B_14D7DDC8781D__INCLUDED_
8 |
9 | #if _MSC_VER > 1000
10 | #pragma once
11 | #endif // _MSC_VER > 1000
12 |
13 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
14 |
15 | #include // MFC core and standard components
16 | #include // MFC extensions
17 | #include // MFC Automation classes
18 | #include // MFC support for Internet Explorer 4 Common Controls
19 | #ifndef _AFX_NO_AFXCMN_SUPPORT
20 | #include // MFC support for Windows Common Controls
21 | #endif // _AFX_NO_AFXCMN_SUPPORT
22 |
23 | // 取得程序运行的目录
24 | CString GetAppDirectory(BOOL bEndWithBackSlash = TRUE);
25 |
26 | // 从文件全路径取得文件名
27 | CString GetFilename(const char* sFilePath);
28 | CString GetFilename(const CString& sFilePath);
29 |
30 | // 取得文件扩展名
31 | CString GetFileExtendName(const char* sFilename);
32 | CString GetFileExtendName(const CString& sFilename);
33 |
34 | // 取得文件大小
35 | size_t GetFileSize(const char* sFilename);
36 | size_t GetFileSize(const CString& sFilename);
37 |
38 | // 写日志
39 | void LOG(int iModuleID, int iLevel, const char* sFormat, ...);
40 |
41 | // 计算文件的MD5摘要码
42 | extern BOOL CalculateMD5(const char* sFilename, unsigned char acMD5Digest[]);
43 | extern CString MD5toString(unsigned char acMD5Digest[]);
44 |
45 | // 显示消息框函数,用于替代AfxMessageBox函数
46 | int RMessageBox(CString& sText, UINT nType = MB_OK, UINT nIDHelp = 0);
47 | int RMessageBox(LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0);
48 |
49 | // 替换路径中的特殊字符串为实际路径
50 | CString ResolvePath(const char* sPath);
51 |
52 | //{{AFX_INSERT_LOCATION}}
53 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
54 |
55 | #endif // !defined(AFX_STDAFX_H__6E171DE5_929C_4558_880B_14D7DDC8781D__INCLUDED_)
56 |
--------------------------------------------------------------------------------
/Src/UISkinManager.h:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:UISkinManager.h
3 | // 文件描述:界面管理类,提供实现自绘界面的公用函数以及风格设置和切换
4 | //------------------------------------------------------------------------------
5 |
6 | #pragma once
7 |
8 | #ifndef UISKINMANAGER_H
9 | #define UISKINMANAGER_H
10 |
11 | class CUISkinManager
12 | {
13 | public:
14 | CUISkinManager();
15 | ~CUISkinManager();
16 |
17 | static BOOL Init();
18 | static void Uninit();
19 | static BOOL LoadImages();
20 | static HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
21 | static COLORREF GetColor();
22 | static HBRUSH GetBrush();
23 |
24 | // 以渐变方式填充矩形
25 | static void GradientFillRect(CWnd* pWnd,
26 | CDC* pDC,
27 | CRect& rcFill,
28 | ULONG nMode,
29 | COLORREF crLeftTop,
30 | COLORREF crRightBottom);
31 |
32 | // 透明拉伸复制
33 | static void TransparentBlt(HDC hdcDest,
34 | int nXDest,
35 | int nYDest,
36 | int nWidthDest,
37 | int nHeightDest,
38 | HDC hdcSrc,
39 | int nXSrc,
40 | int nYSrc,
41 | int nWidthSrc,
42 | int nHeightSrc,
43 | COLORREF crTransparent);
44 |
45 | // 绘制对话框
46 | static void Paint(CWnd* pWnd,
47 | CDC* pDC = NULL,
48 | BOOL bFillClient = TRUE,
49 | COLORREF crFillColor = RGB(255, 255, 255));
50 |
51 | static void Paint_Normal(CWnd* pWnd,
52 | CDC* pDC = NULL,
53 | BOOL bFillClient = TRUE,
54 | COLORREF crFillColor = RGB(255, 255, 255));
55 |
56 | static void Paint_XP(CWnd* pWnd,
57 | CDC* pDC = NULL,
58 | BOOL bFillClient = TRUE,
59 | COLORREF crFillColor = RGB(255, 255, 255));
60 |
61 | static void PaintDialogBorder(CWnd* pWnd,
62 | CDC* pDC = NULL);
63 |
64 | // 设置对话框边框
65 | static void SetRgn(CWnd* pWnd);
66 | static void SetRgn_Normal(CWnd* pWnd);
67 | static void SetRgn_XP(CWnd* pWnd);
68 |
69 | public:
70 | // 界面风格枚举
71 | enum SkinStyle {
72 | StyleNormal = 0,
73 | StyleSpring,
74 | StyleSummer,
75 | StyleAutumn,
76 | StyleWinter,
77 | StyleXP,
78 | StyleCustomize,
79 | SkinStyleBottom
80 | };
81 | // 切换界面风格
82 | static void ChangeStyle(enum SkinStyle iNewStyle);
83 |
84 | public:
85 | // 透明色
86 | static const COLORREF TRANSPARENT_COLOR;
87 |
88 | // 当前界面风格
89 | static enum SkinStyle m_iCurrentStyle;
90 |
91 | // 窗口标题栏风格
92 |
93 | // 标题栏高度
94 | static UINT m_iTitleBarHeight;
95 | // 绘制标题栏所需的图像宽度(象素)
96 | static UINT m_iTitleBarImageWidth;
97 | // 标题栏图象左边部分的宽度
98 | static UINT m_iTitleBarImageLeftPartWidth;
99 | // 标题栏图象中间部分的宽度(此部分是可拉伸的)
100 | static UINT m_iTitleBarImageMiddlePartWidth;
101 | // 标题栏图象右边部分的宽度
102 | static UINT m_iTitleBarImageRightPartWidth;
103 | // 绘制标题栏所需的图像集(每个图像宽度为 m_iTitleBarImageWidth 象素,
104 | // 按正常、失去焦点的顺序排列,总宽度不小于 2 * m_iTitleBarImageWidth 象素)
105 | static CBitmap m_bmTitleBarImage;
106 |
107 | // 对话框窗口左右边距
108 | static UINT m_iLeftMargin;
109 | // 对话框窗口上下边距
110 | static UINT m_iTopMargin;
111 |
112 | // 按钮风格
113 |
114 | // 按钮高度(绘制按钮所需的图像高度)
115 | static UINT m_iButtonHeight;
116 | // 绘制按钮所需的图像宽度(象素)
117 | static UINT m_iButtonImageWidth;
118 | // 按钮图象左边部分的宽度
119 | static UINT m_iButtonImageLeftPartWidth;
120 | // 按钮图象中间部分的宽度(此部分是可拉伸的)
121 | static UINT m_iButtonImageMiddlePartWidth;
122 | // 按钮图象右边部分的宽度
123 | static UINT m_iButtonImageRightPartWidth;
124 | // 绘制按钮所需的图像集(每个图像宽度为 m_iButtonImageWidth 象素,
125 | // 按正常、缺省、鼠标悬停、鼠标按下的顺序排列,
126 | // 总宽度不小于 4 * m_iButtonImageWidth 象素)
127 | static CBitmap m_bmButtonImage;
128 | // 系统控制按钮的宽度和高度(象素)
129 | static UINT m_iSystemControlButtonWidth;
130 | static UINT m_iSystemControlButtonHeight;
131 | // 绘制系统控制按钮(最小化、最大化、关闭等按钮)所需的图像集
132 | // (每个图像宽度为 m_iSystemControlButtonImageWidth 象素,
133 | // 按最小化、最大化、恢复、关闭、按钮按下状态的顺序排列,
134 | // 总宽度不小于 8 * m_iSystemControlButtonImageWidth 象素)
135 | static CBitmap m_bmSystemControlButtonImage;
136 |
137 | // 绘制控件的画笔
138 | static HBRUSH m_hbr;
139 | };
140 |
141 | #endif // #ifndef UISKINMANAGER_H
142 |
--------------------------------------------------------------------------------
/Src/UpdateThread.cpp:
--------------------------------------------------------------------------------
1 | // UpdateThread.cpp : implementation file
2 | //
3 |
4 | #include "stdafx.h"
5 | #include "AutoUpdate.h"
6 | #include "InternetGetFile.h"
7 | #include "UpdateThread.h"
8 |
9 | #ifdef _DEBUG
10 | #define new DEBUG_NEW
11 | #undef THIS_FILE
12 | static char THIS_FILE[] = __FILE__;
13 | #endif
14 |
15 | /////////////////////////////////////////////////////////////////////////////
16 | // CUpdateThread
17 |
18 | IMPLEMENT_DYNCREATE(CUpdateThread, CWinThread)
19 |
20 | CUpdateThread::CUpdateThread()
21 | {
22 | m_bSilenceMode = FALSE;
23 | m_bUserBreak = FALSE;
24 | m_fPercent = 0;
25 | m_hProgressWindow = NULL;
26 | }
27 |
28 | CUpdateThread::~CUpdateThread()
29 | {
30 | }
31 |
32 | BOOL CUpdateThread::InitInstance()
33 | {
34 | // TODO: perform and per-thread initialization here
35 | return TRUE;
36 | }
37 |
38 | int CUpdateThread::ExitInstance()
39 | {
40 | // TODO: perform any per-thread cleanup here
41 | m_bUserBreak = TRUE;
42 |
43 | return CWinThread::ExitInstance();
44 | }
45 |
46 | BEGIN_MESSAGE_MAP(CUpdateThread, CWinThread)
47 | //{{AFX_MSG_MAP(CUpdateThread)
48 | // NOTE - the ClassWizard will add and remove mapping macros here.
49 | //}}AFX_MSG_MAP
50 | END_MESSAGE_MAP()
51 |
52 | /////////////////////////////////////////////////////////////////////////////
53 | // CUpdateThread message handlers
54 |
55 | int CUpdateThread::Run()
56 | {
57 | LOG(0, 0, "更新线程开始工作...");
58 |
59 | try {
60 | if (DoUpdate()) {
61 | if (m_hProgressWindow) {
62 | SendMessage(m_hProgressWindow, WM_USER, (WPARAM)NOTIFY_FINISH_UPDATE, (LPARAM)1);
63 | }
64 |
65 | LOG(0, 0, "更新线程成功完成!");
66 | ExitThread(1);
67 | return 1;
68 | } else {
69 | if (m_hProgressWindow) {
70 | SendMessage(m_hProgressWindow, WM_USER, (WPARAM)NOTIFY_FINISH_UPDATE, (LPARAM)0);
71 | }
72 |
73 | LOG(0, 0, "更新线程失败结束!");
74 |
75 | ExitThread(0);
76 | return 0;
77 | }
78 | } catch (...) {
79 | LOG(0, 0, "更新线程出现异常!");
80 | ExitThread(0);
81 | }
82 | // return CWinThread::Run();
83 | }
84 |
85 | //
86 | // 执行升级
87 | //
88 | BOOL CUpdateThread::DoUpdate()
89 | {
90 | if (m_strConfigFileName.IsEmpty()) { return FALSE; }
91 |
92 | UINT iCommonFileCount = 0;
93 | DOWNLOAD_INFO_STRU DownloadInfo = {0};
94 | UINT i;
95 | const int BUFFER_SIZE = 512;
96 | char acBuffer[BUFFER_SIZE];
97 | CString sSection;
98 | CString sKey;
99 | CString strFileName;
100 | CString sHash;
101 | CString sURL;
102 | CString sTemp;
103 |
104 | // 创建保存升级文件的目录
105 | CreateDirectory(GetAppDirectory() + "Update", NULL);
106 |
107 | //
108 | // 取得公共文件数及文件大小总和
109 | //
110 | LOG(0, 0, "开始获取本次升级涉及的文件总个数和总大小...");
111 | iCommonFileCount = GetPrivateProfileInt(SECTION_COMMON,
112 | "FileCount",
113 | 0,
114 | m_strConfigFileName.GetBuffer(0));
115 | for (i = 1; i <= iCommonFileCount; i++) {
116 | sSection.Format("CommonFile%d", i);
117 | DownloadInfo.iFileSize += GetPrivateProfileInt(sSection.GetBuffer(0),
118 | "Size",
119 | 0,
120 | m_strConfigFileName.GetBuffer(0));
121 | }
122 | DownloadInfo.iFileCount += iCommonFileCount;
123 |
124 | // 将文件总数和文件大小总和上报到界面
125 | if (!m_bSilenceMode &&
126 | m_hProgressWindow != NULL) {
127 | SendMessage(m_hProgressWindow,
128 | WM_USER,
129 | (WPARAM)NOTIFY_DOWNLOAD_INFO,
130 | (LPARAM)&DownloadInfo);
131 | }
132 |
133 | LOG(0, 0, "文件总个数为:%u (%u BYTES).", DownloadInfo.iFileCount, DownloadInfo.iFileSize);
134 |
135 | LOG(0, 0, "获取升级文件总个数和总大小完成!");
136 |
137 | //
138 | // 下载所有文件
139 | //
140 |
141 | LOG(0, 0, "开始下载文件...");
142 |
143 | memset(&DownloadInfo, 0, sizeof(DOWNLOAD_INFO_STRU));
144 |
145 | // 循环下载所有公共文件
146 | for (i = 1; i <= iCommonFileCount; i++) {
147 | if (m_bUserBreak) {
148 | return FALSE;
149 | }
150 |
151 | sSection.Format("CommonFile%d", i);
152 | if (!DownloadFile(sSection)) {
153 | // 文件下载失败,升级失败
154 | if (!m_bSilenceMode &&
155 | m_hProgressWindow != NULL) {
156 | sKey = "Name";
157 | memset(acBuffer, 0, BUFFER_SIZE);
158 | GetPrivateProfileString(sSection.GetBuffer(0),
159 | sKey.GetBuffer(0),
160 | "",
161 | (char*)acBuffer,
162 | BUFFER_SIZE,
163 | m_strConfigFileName.GetBuffer(0));
164 | SendMessage(m_hProgressWindow,
165 | WM_USER,
166 | (WPARAM)NOTIFY_DOWNLOAD_FILE_FAIL,
167 | (LPARAM)acBuffer);
168 | }
169 | return FALSE;
170 | }
171 |
172 | // 将升级进度上报到界面
173 | DownloadInfo.iFileCount++;
174 | DownloadInfo.iFileSize += GetPrivateProfileInt(sSection.GetBuffer(0),
175 | "Size",
176 | 0,
177 | m_strConfigFileName.GetBuffer(0));
178 | if (!m_bSilenceMode &&
179 | m_hProgressWindow != NULL) {
180 | SendMessage(m_hProgressWindow,
181 | WM_USER,
182 | (WPARAM)NOTIFY_DOWNLOADED_INFO,
183 | (LPARAM)&DownloadInfo);
184 | }
185 |
186 | LOG(0, 0, "当前共下载成功文件数为:%u (%u BYTES).", DownloadInfo.iFileCount, DownloadInfo.iFileSize);
187 | }
188 |
189 | LOG(0, 0, "文件下载完成!");
190 |
191 | //
192 | // 下载完毕后校验文件
193 | //
194 |
195 | LOG(0, 0, "开始校验文件大小和MD5签名...");
196 |
197 | // 循环校验所有公共文件
198 | for (i = 1; i <= iCommonFileCount; i++) {
199 | if (m_bUserBreak) {
200 | return FALSE;
201 | }
202 |
203 | sSection.Format("CommonFile%d", i);
204 |
205 | if (!VerifyFile(sSection)) {
206 | // 文件校验不通过,升级失败
207 | if (!m_bSilenceMode &&
208 | m_hProgressWindow != NULL) {
209 | sKey = "Name";
210 | memset(acBuffer, 0, BUFFER_SIZE);
211 | GetPrivateProfileString(sSection.GetBuffer(0),
212 | sKey.GetBuffer(0),
213 | "",
214 | (char*)acBuffer,
215 | BUFFER_SIZE,
216 | m_strConfigFileName.GetBuffer(0));
217 | SendMessage(m_hProgressWindow,
218 | WM_USER,
219 | (WPARAM)NOTIFY_VERIFY_FILE_FAIL,
220 | (LPARAM)acBuffer);
221 | }
222 | return FALSE;
223 | }
224 | }
225 |
226 | LOG(0, 0, "文件校验完成!");
227 |
228 | //
229 | // 复制、更新文件
230 | //
231 |
232 | LOG(0, 0, "开始覆盖更新文件...");
233 |
234 | // 创建备份文件目录
235 | CreateDirectory((GetAppDirectory() + "Backup").GetBuffer(0), NULL);
236 | // 循环更新所有文件
237 | for (i = 1; i <= iCommonFileCount; i++) {
238 | if (m_bUserBreak) {
239 | return FALSE;
240 | }
241 |
242 | sSection.Format("CommonFile%d", i);
243 | if (!UpdateFile(sSection)) {
244 | // 文件更新不成功,升级失败
245 | if (!m_bSilenceMode &&
246 | m_hProgressWindow != NULL) {
247 | sKey = "Name";
248 | memset(acBuffer, 0, BUFFER_SIZE);
249 | GetPrivateProfileString(sSection.GetBuffer(0),
250 | sKey.GetBuffer(0),
251 | "",
252 | (char*)acBuffer,
253 | BUFFER_SIZE,
254 | m_strConfigFileName.GetBuffer(0));
255 | SendMessage(m_hProgressWindow,
256 | WM_USER,
257 | (WPARAM)NOTIFY_UPDATE_FILE_FAIL,
258 | (LPARAM)acBuffer);
259 | }
260 | return FALSE;
261 | }
262 | }
263 |
264 | LOG(0, 0, "覆盖更新文件完成!");
265 |
266 | //
267 | // 执行升级程序
268 | //
269 | LOG(0, 0, "开始执行更新后程序...");
270 |
271 | sKey = "RunAfterDownload";
272 | memset(acBuffer, 0, BUFFER_SIZE);
273 | GetPrivateProfileString(SECTION_UPDATE,
274 | sKey.GetBuffer(0),
275 | "",
276 | (char*)acBuffer,
277 | BUFFER_SIZE,
278 | m_strConfigFileName.GetBuffer(0));
279 | strFileName = (char*)acBuffer;
280 |
281 | if (!strFileName.IsEmpty()) {
282 | LOG(0, 0, "开始启动:%s", strFileName.GetBuffer(0));
283 |
284 | ShellExecute(NULL,
285 | "open",
286 | (GetAppDirectory() + strFileName).GetBuffer(0),
287 | "",
288 | "",
289 | SW_NORMAL);
290 | }
291 | LOG(0, 0, "执行更新后程序完成!");
292 |
293 | LOG(0, 0, "升级工作整体完成!");
294 |
295 | // 通知界面升级完毕
296 | if (!m_bSilenceMode &&
297 | m_hProgressWindow != NULL) {
298 | SendMessage(m_hProgressWindow,
299 | WM_USER,
300 | (WPARAM)NOTIFY_FINISH_UPDATE,
301 | 0);
302 | }
303 |
304 | return TRUE;
305 | }
306 |
307 | // 检查并下载一个文件
308 | BOOL CUpdateThread::DownloadFile(CString &strFileSection)
309 | {
310 | const int BUFFER_SIZE = 512;
311 | char acBuffer[BUFFER_SIZE];
312 | CString strFileName;
313 | CString strHash;
314 | CString strURL;
315 | CString strKey;
316 |
317 | LOG(0, 0, "开始处理下载文件配置节:%s", strFileSection.GetBuffer(0));
318 |
319 | // 比较文件是否已经下载了,如是则跳过
320 | if (VerifyFile(strFileSection)) {
321 | LOG(0, 0, "本地文件%s已是最新,无需下载.", strFileName.GetBuffer(0));
322 | return TRUE;
323 | }
324 |
325 | // 取得文件名
326 | strKey = "Name";
327 | memset(acBuffer, 0, BUFFER_SIZE);
328 | GetPrivateProfileString(strFileSection.GetBuffer(0),
329 | strKey.GetBuffer(0),
330 | "",
331 | (char*)acBuffer,
332 | BUFFER_SIZE,
333 | m_strConfigFileName.GetBuffer(0));
334 | strFileName = (char*)acBuffer;
335 |
336 | LOG(0, 0, "开始通过网络下载文件:%s.", strFileName.GetBuffer(0));
337 |
338 | // // 取得文件URL
339 | // strKey = "URL";
340 | // memset(acBuffer, 0, BUFFER_SIZE);
341 | // GetPrivateProfileString(strFileSection.GetBuffer(0),
342 | // strKey.GetBuffer(0),
343 | // "",
344 | // (char*)acBuffer,
345 | // BUFFER_SIZE,
346 | // m_strConfigFileName.GetBuffer(0));
347 | // strURL = (char*)acBuffer;
348 |
349 | CAutoUpdateApp* pMainApp = (CAutoUpdateApp*)::AfxGetApp();
350 | strURL = pMainApp->m_strBaseURL + "/" + strFileName;
351 |
352 | // 更新显示正在下载的文件
353 | // 下载文件
354 | if (!m_bSilenceMode &&
355 | m_hProgressWindow != NULL) {
356 | SendMessage(m_hProgressWindow,
357 | WM_USER,
358 | (WPARAM)NOTIFY_DOWNLOADING_FILENAME,
359 | (LPARAM)strFileName.GetBuffer(0));
360 | }
361 | if (Internet::InternetGetURL(strURL.GetBuffer(0),
362 | (GetAppDirectory() + "Update\\" + strFileName).GetBuffer(0),
363 | NULL,
364 | m_hProgressWindow)
365 | != Internet::INTERNET_SUCCESS) {
366 | // 记录下载文件失败日志
367 | LOG(0, 0, "下载文件失败:%s", strFileName.GetBuffer(0));
368 |
369 | LOG(0, 0, "文件下载URL为:%s", strURL.GetBuffer(0));
370 |
371 | return FALSE;
372 | } else {
373 | // 记录下载文件成功日志
374 | LOG(0, 0, "下载文件成功:%s", strFileName.GetBuffer(0));
375 | }
376 |
377 | return TRUE;
378 | }
379 |
380 | // 校验文件(update目录下文件与服务器相应文件做校验)
381 | BOOL CUpdateThread::VerifyFile(CString &strFileSection)
382 | {
383 | const int BUFFER_SIZE = 512;
384 | char acBuffer[BUFFER_SIZE];
385 | CString strFileName;
386 | UINT iFileSize;
387 | CString sHash;
388 | CString sKey;
389 |
390 | LOG(0, 0, "开始校验文件配置节 = %s.", strFileSection.GetBuffer(0));
391 |
392 | // 取得文件名
393 | sKey = "Name";
394 | memset(acBuffer, 0, BUFFER_SIZE);
395 | GetPrivateProfileString(strFileSection.GetBuffer(0),
396 | sKey.GetBuffer(0),
397 | "",
398 | (char*)acBuffer,
399 | BUFFER_SIZE,
400 | m_strConfigFileName.GetBuffer(0));
401 | strFileName = (char*)acBuffer;
402 |
403 | // 取得文件大小
404 | sKey = "Size";
405 | iFileSize = GetPrivateProfileInt(strFileSection.GetBuffer(0),
406 | sKey.GetBuffer(0),
407 | 0,
408 | m_strConfigFileName.GetBuffer(0));
409 | UINT iLocalFileSize = GetFileSize(GetAppDirectory() + "Update\\" + strFileName);
410 | if (iLocalFileSize == iFileSize) {
411 | sKey = "Hash";
412 | memset(acBuffer, 0, BUFFER_SIZE);
413 | GetPrivateProfileString(strFileSection.GetBuffer(0),
414 | sKey.GetBuffer(0),
415 | "",
416 | (char*)acBuffer,
417 | BUFFER_SIZE,
418 | m_strConfigFileName.GetBuffer(0));
419 | sHash = (char*)acBuffer;
420 |
421 | // 计算文件的Hash码以进行比较
422 | unsigned char acMD5Digest[16];
423 | CalculateMD5((GetAppDirectory() + "Update\\" + strFileName).GetBuffer(0), acMD5Digest);
424 |
425 | if (sHash.CompareNoCase(MD5toString(acMD5Digest)) == 0) {
426 | return TRUE;
427 | } else {
428 | LOG(0, 0, "校验文件MD5失败:%s,本地文件MD5:%s,预期文件MD5为:%s",
429 | strFileName.GetBuffer(0),
430 | sHash.GetBuffer(0),
431 | MD5toString(acMD5Digest).GetBuffer(0));
432 | }
433 | } else {
434 | LOG(0, 0, "校验文件大小失败:%s,本地文件大小:%u,预期大小为:%u",
435 | strFileName.GetBuffer(0),
436 | iLocalFileSize,
437 | iFileSize);
438 | }
439 |
440 | return FALSE;
441 | }
442 |
443 | // 更新文件
444 | BOOL CUpdateThread::UpdateFile(CString &strFileSection)
445 | {
446 | const int BUFFER_SIZE = 512;
447 | char acBuffer[BUFFER_SIZE];
448 | CString strFileName;
449 | CString sFileSubcatalog;
450 | CString sDestFilename;
451 | CString sBackupFilename;
452 | CString sKey;
453 |
454 | // 取得文件名
455 | sKey = "Name";
456 | memset(acBuffer, 0, BUFFER_SIZE);
457 | GetPrivateProfileString(strFileSection.GetBuffer(0),
458 | sKey.GetBuffer(0),
459 | "",
460 | (char*)acBuffer,
461 | BUFFER_SIZE,
462 | m_strConfigFileName.GetBuffer(0));
463 | strFileName = (char*)acBuffer;
464 |
465 | // 取得子目录结构
466 | sKey = "Subcatalog";
467 | memset(acBuffer, 0, BUFFER_SIZE);
468 | GetPrivateProfileString(strFileSection.GetBuffer(0),
469 | sKey.GetBuffer(0),
470 | "",
471 | (char*)acBuffer,
472 | BUFFER_SIZE,
473 | m_strConfigFileName.GetBuffer(0));
474 | sFileSubcatalog = (char*)acBuffer;
475 |
476 | // 取得目标文件名
477 | sKey = "DestPath";
478 | memset(acBuffer, 0, BUFFER_SIZE);
479 | GetPrivateProfileString(strFileSection.GetBuffer(0),
480 | sKey.GetBuffer(0),
481 | "",
482 | (char*)acBuffer,
483 | BUFFER_SIZE,
484 | m_strConfigFileName.GetBuffer(0));
485 | sDestFilename = (char*)acBuffer;
486 | sDestFilename.TrimLeft();
487 | sDestFilename.TrimRight();
488 | if (sDestFilename.IsEmpty()) {
489 | // 无目标目录,文件无需复制
490 | return TRUE;
491 | }
492 | sDestFilename += sFileSubcatalog + strFileName;
493 |
494 | // 替换变量字符串为系统变量
495 | sDestFilename = ResolvePath(sDestFilename.GetBuffer(0));
496 |
497 | // 备份原文件
498 | sBackupFilename = GetAppDirectory() + "Backup\\" + strFileName;
499 | if (GetFileSize(sDestFilename) > 0) {
500 | char acBuffer[MAX_PATH] = {0};
501 |
502 | // 取得本自动升级程序的文件全路径
503 | GetModuleFileName(AfxGetInstanceHandle(), acBuffer, sizeof(acBuffer));
504 |
505 | if (strFileName.CompareNoCase(GetFilename(acBuffer)) == 0) {
506 | // 要更新的文件是本自动升级程序,须换名更新
507 | CopyFile(sDestFilename.GetBuffer(0), sBackupFilename.GetBuffer(0), FALSE);
508 | // 复制新文件,新文件名加上 .new 后缀,由主程序来将其更名
509 | sDestFilename += ".new";
510 | return CopyFile((GetAppDirectory() + "Update\\" + strFileName).GetBuffer(0),
511 | sDestFilename.GetBuffer(0),
512 | FALSE);
513 | } else {
514 | MoveFile(sDestFilename.GetBuffer(0), sBackupFilename.GetBuffer(0));
515 | }
516 | }
517 |
518 | // 如果输出目录在子目录中,则创建对应的目录结构
519 | if (sFileSubcatalog!="") {
520 | CString csTemp = sFileSubcatalog.Left(strlen(sFileSubcatalog) - 1);
521 | CreateDirectory(GetAppDirectory() + csTemp, NULL);
522 | }
523 |
524 | // 复制新文件
525 | return CopyFile((GetAppDirectory() + "Update\\" + strFileName).GetBuffer(0),
526 | sDestFilename.GetBuffer(0),
527 | FALSE);
528 | }
529 |
--------------------------------------------------------------------------------
/Src/UpdateThread.h:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // 文件名称:UpdateThread.h
3 | // 文件版本:v1.0
4 | // 文件描述:自动升级线程类
5 | //------------------------------------------------------------------------------
6 |
7 | #if !defined(AFX_UPDATETHREAD_H__194A514F_A0D7_4ADD_8D2A_9E7081810D82__INCLUDED_)
8 | #define AFX_UPDATETHREAD_H__194A514F_A0D7_4ADD_8D2A_9E7081810D82__INCLUDED_
9 |
10 | #if _MSC_VER > 1000
11 | #pragma once
12 | #endif // _MSC_VER > 1000
13 |
14 | // UpdateThread.h : header file
15 | //
16 |
17 | /////////////////////////////////////////////////////////////////////////////
18 | // CUpdateThread thread
19 |
20 | class CUpdateThread : public CWinThread
21 | {
22 | DECLARE_DYNCREATE(CUpdateThread)
23 | protected:
24 |
25 | // Attributes
26 | public:
27 | CString m_strConfigFileName; // 升级配置文件名
28 | BOOL m_bSilenceMode; // 静默方式执行升级,不显示升级程序界面,只在升级完毕后提醒用户
29 | BOOL m_bUserBreak; // 用户终止升级
30 | double m_fPercent; // 下载文件进度百分比
31 | HWND m_hProgressWindow; // 显示升级进度的窗口句柄
32 |
33 | // Operations
34 | public:
35 | CUpdateThread(); // protected constructor used by dynamic creation
36 | BOOL DoUpdate(); // 执行升级
37 |
38 | // Overrides
39 | // ClassWizard generated virtual function overrides
40 | //{{AFX_VIRTUAL(CUpdateThread)
41 | public:
42 | virtual BOOL InitInstance();
43 | virtual int ExitInstance();
44 | virtual int Run();
45 | //}}AFX_VIRTUAL
46 |
47 | // Implementation
48 | protected:
49 | virtual ~CUpdateThread();
50 |
51 | // Generated message map functions
52 | //{{AFX_MSG(CUpdateThread)
53 | // NOTE - the ClassWizard will add and remove member functions here.
54 | //}}AFX_MSG
55 |
56 | DECLARE_MESSAGE_MAP()
57 |
58 | private:
59 | // 下载文件
60 | BOOL DownloadFile(CString& strFileSection);
61 | // 校验文件
62 | BOOL VerifyFile(CString &strFileSection);
63 | // 更新文件
64 | BOOL UpdateFile(CString &strFileSection);
65 | };
66 |
67 | /////////////////////////////////////////////////////////////////////////////
68 |
69 | //{{AFX_INSERT_LOCATION}}
70 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
71 |
72 | #endif // !defined(AFX_UPDATETHREAD_H__194A514F_A0D7_4ADD_8D2A_9E7081810D82__INCLUDED_)
73 |
--------------------------------------------------------------------------------
/Src/res/AutoUpdate.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/res/AutoUpdate.ico
--------------------------------------------------------------------------------
/Src/res/AutoUpdate.rc2:
--------------------------------------------------------------------------------
1 | //
2 | // AUTOUPDATE.RC2 - resources Microsoft Visual C++ does not edit directly
3 | //
4 |
5 | #ifdef APSTUDIO_INVOKED
6 | #error this file is not editable by Microsoft Visual C++
7 | #endif //APSTUDIO_INVOKED
8 |
9 |
10 | /////////////////////////////////////////////////////////////////////////////
11 | // Add manually edited resources here...
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 |
--------------------------------------------------------------------------------
/Src/res/button01.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/res/button01.bmp
--------------------------------------------------------------------------------
/Src/res/button_system_control.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/res/button_system_control.bmp
--------------------------------------------------------------------------------
/Src/res/title01.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jackyzhangguwen/AutoUpdate/e037abaa56fa4f4d20a341d3a8cfb0d3bf23a006/Src/res/title01.bmp
--------------------------------------------------------------------------------
/Src/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Developer Studio generated include file.
3 | // Used by AutoUpdate.rc
4 | //
5 | #define IDM_ABOUTBOX 0x0010
6 | #define IDD_ABOUTBOX 100
7 | #define IDS_ABOUTBOX 101
8 | #define IDD_AUTOUPDATE 102
9 | #define IDD_MESSAGEBOX 103
10 | #define IDC_BUTTON_OK 118
11 | #define IDC_BUTTON_CANCEL 119
12 | #define IDC_BUTTON_YES 120
13 | #define IDC_BUTTON_NO 121
14 | #define IDC_BUTTON_ABORT 122
15 | #define IDC_BUTTON_RETRY 123
16 | #define IDC_BUTTON_IGANORE 124
17 | #define IDC_BUTTON_CONTINUE 125
18 | #define IDC_CHECK_OPTION2 126
19 | #define IDC_CHECK_OPTION1 127
20 | #define IDR_MAINFRAME 128
21 | #define IDB_TITLEBAR 129
22 | #define IDB_BUTTON 130
23 | #define IDC_BUTTON_MINIMIZE 131
24 | #define IDC_BUTTON_MAXIMIZE 132
25 | #define IDC_BUTTON_CLOSE 133
26 | #define IDC_STATIC_PROMPT 134
27 | #define IDC_STATIC_PROGRESS 135
28 | #define IDC_STATIC_ICON 136
29 | #define IDC_STATIC_PROMPT_TOTAL_PROGRESS 137
30 | #define IDC_STATIC_TOTAL_PROGRESS 138
31 | #define IDB_SYSTEM_CONTROL_BUTTON 139
32 |
33 | // Next default values for new objects
34 | //
35 | #ifdef APSTUDIO_INVOKED
36 | #ifndef APSTUDIO_READONLY_SYMBOLS
37 | #define _APS_NEXT_RESOURCE_VALUE 140
38 | #define _APS_NEXT_COMMAND_VALUE 32771
39 | #define _APS_NEXT_CONTROL_VALUE 1002
40 | #define _APS_NEXT_SYMED_VALUE 101
41 | #endif
42 | #endif
43 |
--------------------------------------------------------------------------------