├── .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 | --------------------------------------------------------------------------------