// test.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "VTM_IL.h" #include #include #include #include #include using namespace std; #define MAX_LOADSTRING 100 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); // TODO: 在此放置代码。 MSG msg; HACCEL hAccelTable; // 初始化全局字符串 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_TEST, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 执行应用程序初始化: 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); } 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()); char cVer[MAX_PATH] = {0}; ifstream infile(szFilePath); if(infile) // 有该文件 { if(infile.getline(cVer, MAX_PATH)) { memcpy_s(*pVersion, MAX_PATH, cVer, MAX_PATH); infile.close(); return 1; } else { MessageBoxA(NULL,"获取版本信息失败:文件内容为空",NULL,0); return 0; } } else { MessageBoxA(NULL,"获取版本信息失败:文件打开失败",NULL,0); 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)) { sprintf_s(szFilePath, MAX_PATH, "%s\\%s\\bin\\SpShell.exe", strDir.c_str(), pVer); } else { return FALSE; } memcpy_s(*pPath, MAX_PATH, szFilePath, MAX_PATH); if (NULL != pVer) { free(pVer); pVer = NULL; } ifstream shellFile(*pPath); if(shellFile) { return TRUE; } else { MessageBoxA(NULL,"获取执行文件失败:文件无效或文件不存在",NULL,0); return FALSE; } } BOOL Execute(const char* cExeName) { SHELLEXECUTEINFOA sei = {sizeof(SHELLEXECUTEINFOA)}; sei.lpVerb = "runas"; sei.lpFile = cExeName; sei.nShow = SW_SHOWNORMAL; if (!ShellExecuteExA(&sei)) { DWORD dwError = GetLastError(); char szError[128]; memset(szError, '\0', 128); sprintf_s(szError, 128, "执行应用程序失败:%u", dwError); MessageBoxA(NULL, szError,NULL,0); return FALSE; } return TRUE; } BOOL RunSpshell() { char* pSpPath = new char[MAX_PATH]; memset(pSpPath, 0, MAX_PATH); if (!GetSpShellPath(&pSpPath)) { return FALSE; } if (!Execute(pSpPath)) { return FALSE; } if (NULL != pSpPath) { free(pSpPath); pSpPath = NULL; } return TRUE; } //校正 void checkActiveTxtAttr() { char vtmexePath[MAX_PATH] = {0}; GetModuleFileNameA(NULL, vtmexePath, sizeof(vtmexePath)); string strRunVtmPath = vtmexePath; int nPosVtm = strRunVtmPath.find_first_of("\\version\\VTM.exe"); if(nPosVtm<0) { MessageBoxA(NULL,"VTM.exe 不在X:\\version\\VTM.exe下",NULL,0); return ; } int nPos = strRunVtmPath.find_last_of("\\"); string strVersionDir = strRunVtmPath.substr(0, nPos); CString strActiveTxtPath=strVersionDir.c_str();//+"active.txt"; strActiveTxtPath +="\\"; strActiveTxtPath +="active.txt"; CFileStatus rStatus; CFile::GetStatus(strActiveTxtPath,rStatus);//获得文件的属性设置 //如果文件为只读的,将只读属性去掉 if(rStatus.m_attribute&CFile::readOnly){ rStatus.m_attribute=rStatus.m_attribute & 0x3E ; CFile::SetStatus(strActiveTxtPath, rStatus );//更改文件的属性设置 } } 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的属性 checkActiveTxtAttr(); //启动框架 if (RunSpshell()) { HideTaskBar(TRUE); } hInst = hInstance; // 将实例句柄存储在全局变量中 /*hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);*/ //MessageBoxA(NULL,"Hello",NULL,0); 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; }