123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- // test.cpp : 定义应用程序的入口点。
- //
- #include "stdafx.h"
- #include "VTM_IL.h"
- #include<string>
- #include<regex>
- #include <windows.h>
- #include <shellapi.h>
- #include <fstream>
- #include <algorithm>
- #include <cctype> // for std::tolower
- #include <ShlObj.h>
- using namespace std;
- #define MAX_LOADSTRING 100
- #define ERROR_TITILE "可视柜台终端应用程序"
- const int HOTKEY_ID = 1;
- double horizontalScale;
- double verticalScale;
- HWND taskbar;
- RECT position;
- // 全局变量:
- HINSTANCE hInst; // 当前实例
- TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
- TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
- // 此代码模块中包含的函数的前向声明:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
- int APIENTRY _tWinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
- {
- UNREFERENCED_PARAMETER(hPrevInstance);
- UNREFERENCED_PARAMETER(lpCmdLine);
- MSG msg;
- HACCEL hAccelTable;
- // 初始化全局字符串
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_TEST, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- Sleep(200);
- // 执行应用程序初始化:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST));
- // 主消息循环:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return (int) msg.wParam;
- }
- //
- // 函数: MyRegisterClass()
- //
- // 目的: 注册窗口类。
- //
- // 注释:
- //
- // 仅当希望
- // 此代码与添加到 Windows 95 中的“RegisterClassEx”
- // 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
- // 这样应用程序就可以获得关联的
- // “格式正确的”小图标。
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST));
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TEST);
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
- return RegisterClassEx(&wcex);
- }
- BOOL ExistsFileA(LPCSTR lpFilePath)
- {
- DWORD dwRet = GetFileAttributesA(lpFilePath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && !(dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- BOOL ExistsDirA(LPCSTR lpDirPath)
- {
- DWORD dwRet = GetFileAttributesA(lpDirPath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && (dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- UINT GetErrorMessage(CString& retMessage, LPCTSTR lpDefault, DWORD error = GetLastError())
- {
- if (error == 0) {
- retMessage = lpDefault;
- return strlen(lpDefault);
- }
- LPVOID lpMsgBuf;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
- | FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)&lpMsgBuf,
- 0,
- NULL);
- if (lpMsgBuf == NULL) {
- retMessage = lpDefault;
- return strlen(lpDefault);
- }
- CString strTemp;
- strTemp.Format("错误描述:%s", (LPCTSTR)lpMsgBuf);
- retMessage = strTemp;
- LocalFree((LPVOID)lpMsgBuf);
- return retMessage.GetLength();
- }
- int GetVersion(char** pVersion)
- {
- char szFileName[MAX_PATH] = {0};
- char szFilePath[MAX_PATH] = {0};
- GetModuleFileNameA(NULL, szFileName, sizeof(szFileName));
- string strFileName = szFileName;
- int nPos = strFileName.find_last_of("\\");
- string strDir = strFileName.substr(0, nPos);
- sprintf_s(szFilePath, MAX_PATH,"%s\\active.txt", strDir.c_str());
- if (!ExistsFileA(szFilePath)) {
- CString strText;
- strText.Format("[RTA0031] 版本文件不存在,请重新安装程序版本!");
- MessageBoxA(NULL, strText, ERROR_TITILE, MB_OK | MB_ICONERROR);
- return 0;
- }
- ifstream infile(szFilePath);
- if(infile.is_open())
- {
- std::string line;
- if(std::getline(infile, line)){
- CString strVersionTxt(line.c_str());
- memcpy_s(*pVersion, MAX_PATH, strVersionTxt.GetString(), MAX_PATH);
- infile.close();
- return 1;
- }
- else
- {
- CString strText;
- strText.Format("[RTA0032] 版本文件内容为空,请重新安装程序版本!");
- MessageBoxA(NULL, strText, ERROR_TITILE, MB_OK | MB_ICONERROR);
- infile.close();
- return 0;
- }
- }
- else {
- const DWORD dwError = GetLastError();
- CString strText;
- CString strError;
- char szDefault[128];
- sprintf_s(szDefault, "错误描述:%u", dwError);
- GetErrorMessage(strError, szDefault, dwError);
- strText.Format("[RTA0033] 版本文件打开失败,请联系分行IT或厂商排查!\r\n\r\n%s", strError.GetBuffer());
- MessageBoxA(NULL, strText, ERROR_TITILE, MB_OK | MB_ICONERROR);
- return 0;
- }
- infile.close();
- return 0;
- }
- BOOL GetSpShellPath(char** pPath)
- {
- char* pVer = new char[MAX_PATH];
- memset(pVer, 0, MAX_PATH);
- char szFileName[MAX_PATH] = {0};
- char szFilePath[MAX_PATH] = {0};
- GetModuleFileNameA(NULL, szFileName, sizeof(szFileName));
- string strFileName = szFileName;
- int nPos = strFileName.find_last_of("\\");
- string strDir = strFileName.substr(0, nPos);
- if(!GetVersion(&pVer))
- {
- if (NULL != pVer)
- {
- delete [] pVer;
- pVer = NULL;
- }
- return FALSE;
- }
- memset(szFileName, 0, sizeof(szFileName));
- sprintf_s(szFileName, MAX_PATH, "%s\\%s", strDir.c_str(), pVer);
- if (!ExistsDirA(szFileName)) {
- CString strText;
- strText.Format("[RTA0034] 版本文件夹 [%s] 不存在,请重新安装程序版本!",pVer);
- MessageBoxA(NULL, strText, ERROR_TITILE, MB_OK | MB_ICONERROR);
- if (NULL != pVer)
- {
- delete[] pVer;
- pVer = NULL;
- }
- return FALSE;
- }
- sprintf_s(szFilePath, MAX_PATH, "%s\\%s\\bin\\SpShell.exe", strDir.c_str(), pVer);
- memcpy_s(*pPath, MAX_PATH, szFilePath, MAX_PATH);
- if (NULL != pVer)
- {
- delete[] pVer;
- pVer = NULL;
- }
- if (!ExistsFileA(*pPath)) {
- CString strText;
- strText.Format("[RTA0035] 程序执行文件不存在,请重新安装程序版本!(文件路径:%s)", *pPath);
- MessageBoxA(NULL, strText, ERROR_TITILE, MB_OK | MB_ICONERROR);
- return FALSE;
- }
- return TRUE;
- }
- BOOL Execute(const char* cExeName)
- {
- SHELLEXECUTEINFOA sei = {sizeof(SHELLEXECUTEINFOA)};
- sei.lpVerb = "runas";
- sei.lpFile = cExeName;
- sei.nShow = SW_SHOWNORMAL;
- if (!ShellExecuteExA(&sei))
- {
- const DWORD dwError = GetLastError();
- CString strText;
- CString strError;
- char szDefault[128];
- sprintf_s(szDefault, "错误描述:%u", dwError);
- GetErrorMessage(strError, szDefault, dwError);
- strText.Format("[RTA0036] 执行应用程序文件失败,请联系分行IT或厂商排查!\r\n\r\n%s", strError.GetBuffer());
- MessageBoxA(NULL, strText, ERROR_TITILE, MB_OK | MB_ICONERROR);
- return FALSE;
- }
- return TRUE;
- }
- BOOL RunSpshell()
- {
- BOOL ret = FALSE;
- char* pSpPath = new char[MAX_PATH];
- memset(pSpPath, 0, MAX_PATH);
- do
- {
- if (!GetSpShellPath(&pSpPath))
- {
- break;
- }
- if (!Execute(pSpPath))
- {
- break;
- }
- ret = TRUE;
- } while (false);
- if (NULL != pSpPath)
- {
- delete[] pSpPath;
- pSpPath = NULL;
- }
- return ret;
- }
- //校正
- int checkActiveTxtAttr()
- {
- char vtmexePath[MAX_PATH] = {0};
- GetModuleFileNameA(NULL, vtmexePath, sizeof(vtmexePath));
- string strRunVtmPath = vtmexePath;
- string strCheck = vtmexePath;
- std::transform(strCheck.begin(), strCheck.end(), strCheck.begin(), ::tolower);
- const auto nPosVtm = strCheck.find("\\version\\vtm.exe");
- if(nPosVtm == -1)
- {
- MessageBoxA(NULL,"[RTA0030] 可视柜台应用程序不在规定路径下执行,请重新安装程序版本!", ERROR_TITILE, MB_OK | MB_ICONERROR);
- return -1;
- }
- const int nPos = strRunVtmPath.find_last_of("\\");
- string strVersionDir = strRunVtmPath.substr(0, nPos);
- CString strActiveTxtPath=strVersionDir.c_str();//+"active.txt";
- strActiveTxtPath +="\\";
- strActiveTxtPath +="active.txt";
- if (ExistsFileA(strActiveTxtPath)) {
- CFileStatus rStatus;
- CFile::GetStatus(strActiveTxtPath, rStatus);//获得文件的属性设置
- //如果文件为只读的,将只读属性去掉
- if (rStatus.m_attribute & CFile::readOnly) {
- rStatus.m_attribute = rStatus.m_attribute & 0x3E;
- CFile::SetStatus(strActiveTxtPath, rStatus);//更改文件的属性设置
- }
- }
- return 0;
- }
- void RegistHotkey()
- {
- RegisterHotKey(
- NULL, // this thread will process the hotkey
- HOTKEY_ID,
- MOD_WIN, // win
- VK_OEM_3 // ~
- );
- }
- void UnRegistHotkey()
- {
- UnregisterHotKey(NULL, HOTKEY_ID);
- }
- void FormatPosition()
- {
- if (position.left < 0) {
- // taskbar is on the left, move right
- position.right -= position.left;
- position.left = 0;
- }
- if (position.bottom < 0) {
- // taskbar is on the bottom, move up
- position.top -= position.bottom;
- position.bottom = 0;
- }
- }
- void HideTaskbarEx()
- {
- auto empty = CreateRectRgn(0, 0, 0, 0);
- SetWindowRgn(taskbar, empty, true);
- DeleteObject(empty);
- }
- void ShowTaskbarEx()
- {
- auto region = CreateRectRgn(position.left, position.top, position.right * horizontalScale, position.bottom * verticalScale);
- SetWindowRgn(taskbar, region, true);
- DeleteObject(region);
- }
- VOID HideTaskBar(BOOL bHide)
- {
- int nCmdShow;
- HWND hWnd;
- LPARAM lParam;
-
- hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);
- if (bHide == TRUE) {
- nCmdShow = SW_HIDE;
- lParam = ABS_AUTOHIDE | ABS_ALWAYSONTOP;
- }
- else {
- nCmdShow = SW_SHOW;
- lParam = ABS_ALWAYSONTOP;
- }
- if (hWnd != NULL) {
- taskbar = hWnd;
- //ShowWindow(hWnd, nCmdShow);
- //GetWindowRect(hWnd, &position);
- //FormatPosition();
- //HideTaskbarEx();
- #if defined(DEVOPS_ON_PRD) || defined(DEVOPS_ON_UAT)
- APPBARDATA apBar;
- memset(&apBar, 0, sizeof(apBar));
- apBar.cbSize = sizeof(apBar);
- apBar.hWnd = hWnd;
- if (apBar.hWnd != NULL)
- {
- apBar.lParam = lParam;
- SHAppBarMessage(ABM_SETSTATE, &apBar);
- }
- #endif // DEVOPS_ON_PRD
- }
- }
- // Ref: https://stackoverflow.com/questions/54912038/querying-windows-display-scaling
- void GetDisplayScale()
- {
- auto activeWindow = GetActiveWindow();
- HMONITOR monitor = MonitorFromWindow(activeWindow, MONITOR_DEFAULTTONEAREST);
- // Get the logical width and height of the monitor
- MONITORINFOEX monitorInfoEx;
- monitorInfoEx.cbSize = sizeof(monitorInfoEx);
- GetMonitorInfo(monitor, &monitorInfoEx);
- auto cxLogical = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left;
- auto cyLogical = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top;
- // Get the physical width and height of the monitor
- DEVMODE devMode;
- devMode.dmSize = sizeof(devMode);
- devMode.dmDriverExtra = 0;
- EnumDisplaySettings(monitorInfoEx.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
- auto cxPhysical = devMode.dmPelsWidth;
- auto cyPhysical = devMode.dmPelsHeight;
- // Calculate the scaling factor
- horizontalScale = ((double)cxPhysical / (double)cxLogical);
- verticalScale = ((double)cyPhysical / (double)cyLogical);
- #ifdef _DEBUG
- printf("horizontalScale: %f\n", horizontalScale);
- printf("verticalScale: %f\n", verticalScale);
- #endif
- }
- //
- // 函数: InitInstance(HINSTANCE, int)
- //
- // 目的: 保存实例句柄并创建主窗口
- //
- // 注释:
- //
- // 在此函数中,我们在全局变量中保存实例句柄并
- // 创建和显示主程序窗口。
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- // 校正active.txt的属性
- if (0 == checkActiveTxtAttr() && RunSpshell()) {
- HideTaskBar(TRUE);
- }
- hInst = hInstance; // 将实例句柄存储在全局变量中
- //HWND hWnd = CreateWindowA(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- //CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
- //if (!hWnd)
- //{
- //return FALSE;
- //}
- //ShowWindow(hWnd, nCmdShow);
- //UpdateWindow(hWnd);
- return FALSE;
- }
- //
- // 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
- //
- // 目的: 处理主窗口的消息。
- //
- // WM_COMMAND - 处理应用程序菜单
- // WM_PAINT - 绘制主窗口
- // WM_DESTROY - 发送退出消息并返回
- //
- //
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- switch (message)
- {
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // 分析菜单选择:
- switch (wmId)
- {
- case IDM_ABOUT:
- DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
- break;
- case IDM_EXIT:
- DestroyWindow(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- // TODO: 在此添加任意绘图代码...
- EndPaint(hWnd, &ps);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
- // “关于”框的消息处理程序。
- INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- UNREFERENCED_PARAMETER(lParam);
- switch (message)
- {
- case WM_INITDIALOG:
- return (INT_PTR)TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
- }
- break;
- }
- return (INT_PTR)FALSE;
- }
|