VTM_IL.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. // test.cpp : 定义应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "VTM_IL.h"
  5. #include<string>
  6. #include <windows.h>
  7. #include <shellapi.h>
  8. #include <fstream>
  9. #include <ShlObj.h>
  10. using namespace std;
  11. #define MAX_LOADSTRING 100
  12. const int HOTKEY_ID = 1;
  13. double horizontalScale;
  14. double verticalScale;
  15. HWND taskbar;
  16. RECT position;
  17. // 全局变量:
  18. HINSTANCE hInst; // 当前实例
  19. TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
  20. TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
  21. // 此代码模块中包含的函数的前向声明:
  22. ATOM MyRegisterClass(HINSTANCE hInstance);
  23. BOOL InitInstance(HINSTANCE, int);
  24. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  25. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  26. int APIENTRY _tWinMain(HINSTANCE hInstance,
  27. HINSTANCE hPrevInstance,
  28. LPTSTR lpCmdLine,
  29. int nCmdShow)
  30. {
  31. UNREFERENCED_PARAMETER(hPrevInstance);
  32. UNREFERENCED_PARAMETER(lpCmdLine);
  33. // TODO: 在此放置代码。
  34. MSG msg;
  35. HACCEL hAccelTable;
  36. // 初始化全局字符串
  37. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  38. LoadString(hInstance, IDC_TEST, szWindowClass, MAX_LOADSTRING);
  39. MyRegisterClass(hInstance);
  40. // 执行应用程序初始化:
  41. if (!InitInstance (hInstance, nCmdShow))
  42. {
  43. return FALSE;
  44. }
  45. hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST));
  46. // 主消息循环:
  47. while (GetMessage(&msg, NULL, 0, 0))
  48. {
  49. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  50. {
  51. TranslateMessage(&msg);
  52. DispatchMessage(&msg);
  53. }
  54. }
  55. return (int) msg.wParam;
  56. }
  57. //
  58. // 函数: MyRegisterClass()
  59. //
  60. // 目的: 注册窗口类。
  61. //
  62. // 注释:
  63. //
  64. // 仅当希望
  65. // 此代码与添加到 Windows 95 中的“RegisterClassEx”
  66. // 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
  67. // 这样应用程序就可以获得关联的
  68. // “格式正确的”小图标。
  69. //
  70. ATOM MyRegisterClass(HINSTANCE hInstance)
  71. {
  72. WNDCLASSEX wcex;
  73. wcex.cbSize = sizeof(WNDCLASSEX);
  74. wcex.style = CS_HREDRAW | CS_VREDRAW;
  75. wcex.lpfnWndProc = WndProc;
  76. wcex.cbClsExtra = 0;
  77. wcex.cbWndExtra = 0;
  78. wcex.hInstance = hInstance;
  79. wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST));
  80. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  81. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  82. wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TEST);
  83. wcex.lpszClassName = szWindowClass;
  84. wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  85. return RegisterClassEx(&wcex);
  86. }
  87. int GetVersion(char** pVersion)
  88. {
  89. char szFileName[MAX_PATH] = {0};
  90. char szFilePath[MAX_PATH] = {0};
  91. GetModuleFileNameA(NULL, szFileName, sizeof(szFileName));
  92. string strFileName = szFileName;
  93. int nPos = strFileName.find_last_of("\\");
  94. string strDir = strFileName.substr(0, nPos);
  95. sprintf_s(szFilePath, MAX_PATH,"%s\\active.txt", strDir.c_str());
  96. char cVer[MAX_PATH] = {0};
  97. ifstream infile(szFilePath);
  98. if(infile) // 有该文件
  99. {
  100. if(infile.getline(cVer, MAX_PATH))
  101. {
  102. memcpy_s(*pVersion, MAX_PATH, cVer, MAX_PATH);
  103. infile.close();
  104. return 1;
  105. }
  106. else
  107. {
  108. MessageBoxA(NULL,"获取版本信息失败:文件内容为空",NULL,0);
  109. return 0;
  110. }
  111. }
  112. else
  113. {
  114. MessageBoxA(NULL,"获取版本信息失败:文件打开失败",NULL,0);
  115. return 0;
  116. }
  117. infile.close();
  118. return 0;
  119. }
  120. BOOL GetSpShellPath(char** pPath)
  121. {
  122. char* pVer = new char[MAX_PATH];
  123. memset(pVer, 0, MAX_PATH);
  124. char szFileName[MAX_PATH] = {0};
  125. char szFilePath[MAX_PATH] = {0};
  126. GetModuleFileNameA(NULL, szFileName, sizeof(szFileName));
  127. string strFileName = szFileName;
  128. int nPos = strFileName.find_last_of("\\");
  129. string strDir = strFileName.substr(0, nPos);
  130. if(GetVersion(&pVer))
  131. {
  132. sprintf_s(szFilePath, MAX_PATH, "%s\\%s\\bin\\SpShell.exe", strDir.c_str(), pVer);
  133. }
  134. else
  135. {
  136. return FALSE;
  137. }
  138. memcpy_s(*pPath, MAX_PATH, szFilePath, MAX_PATH);
  139. if (NULL != pVer)
  140. {
  141. free(pVer);
  142. pVer = NULL;
  143. }
  144. ifstream shellFile(*pPath);
  145. if(shellFile)
  146. {
  147. return TRUE;
  148. }
  149. else
  150. {
  151. MessageBoxA(NULL,"获取执行文件失败:文件无效或文件不存在",NULL,0);
  152. return FALSE;
  153. }
  154. }
  155. BOOL Execute(const char* cExeName)
  156. {
  157. SHELLEXECUTEINFOA sei = {sizeof(SHELLEXECUTEINFOA)};
  158. sei.lpVerb = "runas";
  159. sei.lpFile = cExeName;
  160. sei.nShow = SW_SHOWNORMAL;
  161. if (!ShellExecuteExA(&sei))
  162. {
  163. DWORD dwError = GetLastError();
  164. char szError[128];
  165. memset(szError, '\0', 128);
  166. sprintf_s(szError, 128, "执行应用程序失败:%u", dwError);
  167. MessageBoxA(NULL, szError,NULL,0);
  168. return FALSE;
  169. }
  170. return TRUE;
  171. }
  172. BOOL RunSpshell()
  173. {
  174. char* pSpPath = new char[MAX_PATH];
  175. memset(pSpPath, 0, MAX_PATH);
  176. if (!GetSpShellPath(&pSpPath))
  177. {
  178. return FALSE;
  179. }
  180. if (!Execute(pSpPath))
  181. {
  182. return FALSE;
  183. }
  184. if (NULL != pSpPath)
  185. {
  186. free(pSpPath);
  187. pSpPath = NULL;
  188. }
  189. return TRUE;
  190. }
  191. //校正
  192. void checkActiveTxtAttr()
  193. {
  194. char vtmexePath[MAX_PATH] = {0};
  195. GetModuleFileNameA(NULL, vtmexePath, sizeof(vtmexePath));
  196. string strRunVtmPath = vtmexePath;
  197. int nPosVtm = strRunVtmPath.find_first_of("\\version\\VTM.exe");
  198. if(nPosVtm<0)
  199. {
  200. MessageBoxA(NULL,"VTM.exe 不在X:\\version\\VTM.exe下",NULL,0);
  201. return ;
  202. }
  203. int nPos = strRunVtmPath.find_last_of("\\");
  204. string strVersionDir = strRunVtmPath.substr(0, nPos);
  205. CString strActiveTxtPath=strVersionDir.c_str();//+"active.txt";
  206. strActiveTxtPath +="\\";
  207. strActiveTxtPath +="active.txt";
  208. CFileStatus rStatus;
  209. CFile::GetStatus(strActiveTxtPath,rStatus);//获得文件的属性设置
  210. //如果文件为只读的,将只读属性去掉
  211. if(rStatus.m_attribute&CFile::readOnly){
  212. rStatus.m_attribute=rStatus.m_attribute & 0x3E ;
  213. CFile::SetStatus(strActiveTxtPath, rStatus );//更改文件的属性设置
  214. }
  215. }
  216. void RegistHotkey()
  217. {
  218. RegisterHotKey(
  219. NULL, // this thread will process the hotkey
  220. HOTKEY_ID,
  221. MOD_WIN, // win
  222. VK_OEM_3 // ~
  223. );
  224. }
  225. void UnRegistHotkey()
  226. {
  227. UnregisterHotKey(NULL, HOTKEY_ID);
  228. }
  229. void FormatPosition()
  230. {
  231. if (position.left < 0) {
  232. // taskbar is on the left, move right
  233. position.right -= position.left;
  234. position.left = 0;
  235. }
  236. if (position.bottom < 0) {
  237. // taskbar is on the bottom, move up
  238. position.top -= position.bottom;
  239. position.bottom = 0;
  240. }
  241. }
  242. void HideTaskbarEx()
  243. {
  244. auto empty = CreateRectRgn(0, 0, 0, 0);
  245. SetWindowRgn(taskbar, empty, true);
  246. DeleteObject(empty);
  247. }
  248. void ShowTaskbarEx()
  249. {
  250. auto region = CreateRectRgn(position.left, position.top, position.right * horizontalScale, position.bottom * verticalScale);
  251. SetWindowRgn(taskbar, region, true);
  252. DeleteObject(region);
  253. }
  254. VOID HideTaskBar(BOOL bHide)
  255. {
  256. int nCmdShow;
  257. HWND hWnd;
  258. LPARAM lParam;
  259. hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);
  260. if (bHide == TRUE) {
  261. nCmdShow = SW_HIDE;
  262. lParam = ABS_AUTOHIDE | ABS_ALWAYSONTOP;
  263. }
  264. else {
  265. nCmdShow = SW_SHOW;
  266. lParam = ABS_ALWAYSONTOP;
  267. }
  268. if (hWnd != NULL) {
  269. taskbar = hWnd;
  270. //ShowWindow(hWnd, nCmdShow);
  271. //GetWindowRect(hWnd, &position);
  272. //FormatPosition();
  273. //HideTaskbarEx();
  274. #if defined(DEVOPS_ON_PRD) || defined(DEVOPS_ON_UAT)
  275. APPBARDATA apBar;
  276. memset(&apBar, 0, sizeof(apBar));
  277. apBar.cbSize = sizeof(apBar);
  278. apBar.hWnd = hWnd;
  279. if (apBar.hWnd != NULL)
  280. {
  281. apBar.lParam = lParam;
  282. SHAppBarMessage(ABM_SETSTATE, &apBar);
  283. }
  284. #endif // DEVOPS_ON_PRD
  285. }
  286. }
  287. // Ref: https://stackoverflow.com/questions/54912038/querying-windows-display-scaling
  288. void GetDisplayScale()
  289. {
  290. auto activeWindow = GetActiveWindow();
  291. HMONITOR monitor = MonitorFromWindow(activeWindow, MONITOR_DEFAULTTONEAREST);
  292. // Get the logical width and height of the monitor
  293. MONITORINFOEX monitorInfoEx;
  294. monitorInfoEx.cbSize = sizeof(monitorInfoEx);
  295. GetMonitorInfo(monitor, &monitorInfoEx);
  296. auto cxLogical = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left;
  297. auto cyLogical = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top;
  298. // Get the physical width and height of the monitor
  299. DEVMODE devMode;
  300. devMode.dmSize = sizeof(devMode);
  301. devMode.dmDriverExtra = 0;
  302. EnumDisplaySettings(monitorInfoEx.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
  303. auto cxPhysical = devMode.dmPelsWidth;
  304. auto cyPhysical = devMode.dmPelsHeight;
  305. // Calculate the scaling factor
  306. horizontalScale = ((double)cxPhysical / (double)cxLogical);
  307. verticalScale = ((double)cyPhysical / (double)cyLogical);
  308. #ifdef _DEBUG
  309. printf("horizontalScale: %f\n", horizontalScale);
  310. printf("verticalScale: %f\n", verticalScale);
  311. #endif
  312. }
  313. //
  314. // 函数: InitInstance(HINSTANCE, int)
  315. //
  316. // 目的: 保存实例句柄并创建主窗口
  317. //
  318. // 注释:
  319. //
  320. // 在此函数中,我们在全局变量中保存实例句柄并
  321. // 创建和显示主程序窗口。
  322. //
  323. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  324. {
  325. // 校正active.txt的属性
  326. checkActiveTxtAttr();
  327. //启动框架
  328. if (RunSpshell()) {
  329. HideTaskBar(TRUE);
  330. }
  331. hInst = hInstance; // 将实例句柄存储在全局变量中
  332. /*hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  333. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  334. if (!hWnd)
  335. {
  336. return FALSE;
  337. }
  338. ShowWindow(hWnd, nCmdShow);
  339. UpdateWindow(hWnd);*/
  340. //MessageBoxA(NULL,"Hello",NULL,0);
  341. return FALSE;
  342. }
  343. //
  344. // 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
  345. //
  346. // 目的: 处理主窗口的消息。
  347. //
  348. // WM_COMMAND - 处理应用程序菜单
  349. // WM_PAINT - 绘制主窗口
  350. // WM_DESTROY - 发送退出消息并返回
  351. //
  352. //
  353. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  354. {
  355. int wmId, wmEvent;
  356. PAINTSTRUCT ps;
  357. HDC hdc;
  358. switch (message)
  359. {
  360. case WM_COMMAND:
  361. wmId = LOWORD(wParam);
  362. wmEvent = HIWORD(wParam);
  363. // 分析菜单选择:
  364. switch (wmId)
  365. {
  366. case IDM_ABOUT:
  367. DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
  368. break;
  369. case IDM_EXIT:
  370. DestroyWindow(hWnd);
  371. break;
  372. default:
  373. return DefWindowProc(hWnd, message, wParam, lParam);
  374. }
  375. break;
  376. case WM_PAINT:
  377. hdc = BeginPaint(hWnd, &ps);
  378. // TODO: 在此添加任意绘图代码...
  379. EndPaint(hWnd, &ps);
  380. break;
  381. case WM_DESTROY:
  382. PostQuitMessage(0);
  383. break;
  384. default:
  385. return DefWindowProc(hWnd, message, wParam, lParam);
  386. }
  387. return 0;
  388. }
  389. // “关于”框的消息处理程序。
  390. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  391. {
  392. UNREFERENCED_PARAMETER(lParam);
  393. switch (message)
  394. {
  395. case WM_INITDIALOG:
  396. return (INT_PTR)TRUE;
  397. case WM_COMMAND:
  398. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  399. {
  400. EndDialog(hDlg, LOWORD(wParam));
  401. return (INT_PTR)TRUE;
  402. }
  403. break;
  404. }
  405. return (INT_PTR)FALSE;
  406. }