#define _CRT_SECURE_NO_WARNINGS #include #include #include #pragma comment(lib, "winmm.lib") #define IDI_MAIN 1 #define ID_GEN 101 #define ID_PREV 102 #define ID_NEW 103 #define ID_ENV 104 static HFONT hfTitle, hfBody, hfMono; static HBRUSH hbrDark, hbrDarker, hbrAccent; static HWND hEnvCheck; static void ReadProtk(char* buf, int sz) { buf[0] = 0; FILE* f = fopen("protk.dat", "r"); if (!f) { snprintf(buf, sz, "protk.dat not found in current directory"); return; } int total = 0; char ln[512]; while (fgets(ln, sizeof(ln), f) && total < sz - 4) { int len = (int)strlen(ln); memcpy(buf + total, ln, len); total += len; } fclose(f); buf[total] = 0; } static void GetExeDir(char* buf, int sz) { GetModuleFileNameA(NULL, buf, sz); char* slash = strrchr(buf, '\\'); if (slash) *slash = '\0'; } static void GenerateProtk(char* buf, int sz) { char dir[MAX_PATH]; GetExeDir(dir, sizeof(dir)); snprintf(buf, sz, "NAME Resource_Library\r\n" "EXEC_FILE %s\\Res_center.dll\r\n" "TEXT_DIR %s\\text\r\n" "STARTUP dll\r\n" "REVISION 18\r\n" "END\r\n", dir, dir); } static void SetEnvVar(const char* name, const char* value) { HKEY hKey; if (RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL) == ERROR_SUCCESS) { RegSetValueExA(hKey, name, 0, REG_SZ, (const BYTE*)value, (DWORD)(strlen(value) + 1)); RegCloseKey(hKey); SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, NULL); } } static void DeleteEnvVar(const char* name) { HKEY hKey; if (RegOpenKeyExA(HKEY_CURRENT_USER, "Environment", 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { RegDeleteValueA(hKey, name); RegCloseKey(hKey); SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, NULL); } } static void InitTheme(void) { hbrDark = CreateSolidBrush(RGB(32, 32, 32)); hbrDarker = CreateSolidBrush(RGB(22, 22, 22)); hbrAccent = CreateSolidBrush(RGB(0, 120, 212)); NONCLIENTMETRICSW nm = {sizeof(nm)}; SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(nm), &nm, 0); nm.lfMenuFont.lfHeight = -22; nm.lfMenuFont.lfWeight = FW_SEMIBOLD; hfTitle = CreateFontIndirectW(&nm.lfMenuFont); nm.lfMenuFont.lfHeight = -14; nm.lfMenuFont.lfWeight = FW_NORMAL; hfBody = CreateFontIndirectW(&nm.lfMenuFont); nm.lfMenuFont.lfHeight = -13; nm.lfMenuFont.lfPitchAndFamily = FIXED_PITCH; hfMono = CreateFontIndirectW(&nm.lfMenuFont); } static void DrawMetroButton(HWND hBtn, LPDRAWITEMSTRUCT dis) { wchar_t txt[64]; GetWindowTextW(hBtn, txt, 64); int pressed = (dis->itemState & ODS_SELECTED); int hot = (dis->itemState & ODS_HOTLIGHT); HBRUSH br = pressed ? CreateSolidBrush(RGB(0, 90, 170)) : hot ? CreateSolidBrush(RGB(0, 105, 190)) : hbrAccent; FillRect(dis->hDC, &dis->rcItem, br); if (!pressed && !hot) DeleteObject(br); SetBkMode(dis->hDC, TRANSPARENT); SetTextColor(dis->hDC, RGB(255,255,255)); SelectObject(dis->hDC, hfTitle); DrawTextW(dis->hDC, txt, -1, &dis->rcItem, DT_CENTER|DT_VCENTER|DT_SINGLELINE); } static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM w, LPARAM l) { static HWND hPrev, hNew, hGen; switch (msg) { case WM_CREATE: { InitTheme(); SetClassLongPtrW(hWnd, GCLP_HBRBACKGROUND, (LONG_PTR)hbrDark); HWND h = CreateWindowW(L"STATIC", L"Protk.dat Configurator", WS_CHILD|WS_VISIBLE|SS_CENTER, 10, 8, 580, 28, hWnd, NULL, NULL, NULL); SendMessageW(h, WM_SETFONT, (WPARAM)hfTitle, 1); CreateWindowW(L"STATIC", L"Current protk.dat:", WS_CHILD|WS_VISIBLE, 15, 48, 150, 20, hWnd, NULL, NULL, NULL); hPrev = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|ES_READONLY| ES_AUTOVSCROLL|WS_VSCROLL, 15, 68, 570, 100, hWnd, (HMENU)ID_PREV, NULL, NULL); SendMessageW(hPrev, WM_SETFONT, (WPARAM)hfMono, 1); CreateWindowW(L"STATIC", L"New protk.dat (auto-detected):", WS_CHILD|WS_VISIBLE, 15, 178, 250, 20, hWnd, NULL, NULL, NULL); hNew = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|ES_READONLY| ES_AUTOVSCROLL|WS_VSCROLL, 15, 198, 570, 120, hWnd, (HMENU)ID_NEW, NULL, NULL); SendMessageW(hNew, WM_SETFONT, (WPARAM)hfMono, 1); /* Checkbox for env var */ hEnvCheck = CreateWindowW(L"BUTTON", L"Set RES_CENTER_DIR to current path", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 15, 328, 300, 22, hWnd, (HMENU)ID_ENV, NULL, NULL); SendMessageW(hEnvCheck, WM_SETFONT, (WPARAM)hfBody, 1); SendMessageW(hEnvCheck, BM_SETCHECK, BST_CHECKED, 0); hGen = CreateWindowW(L"BUTTON", L"GENERATE protk.dat", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_FLAT|BS_OWNERDRAW, 150, 360, 300, 36, hWnd, (HMENU)ID_GEN, NULL, NULL); char old[4096] = {0}; ReadProtk(old, sizeof(old)); SetWindowTextA(hPrev, old); char newp[4096] = {0}; GenerateProtk(newp, sizeof(newp)); SetWindowTextA(hNew, newp); return 0; } case WM_DRAWITEM: if (w == ID_GEN) DrawMetroButton(hGen, (LPDRAWITEMSTRUCT)l); return 0; case WM_COMMAND: if (LOWORD(w) == ID_GEN) { char newp[4096] = {0}; GenerateProtk(newp, sizeof(newp)); FILE* f = fopen("protk.dat", "wb"); if (f) { fputs(newp, f); fclose(f); SetWindowTextA(hPrev, newp); /* handle env var */ if (SendMessageW(hEnvCheck, BM_GETCHECK, 0, 0) == BST_CHECKED) { char dir[MAX_PATH]; GetExeDir(dir, sizeof(dir)); SetEnvVar("RES_CENTER_DIR", dir); SetWindowTextW(hNew, L"protk.dat written.\r\nRES_CENTER_DIR set.\r\nRestart Creo."); } else { DeleteEnvVar("RES_CENTER_DIR"); SetWindowTextW(hNew, L"protk.dat written.\r\nRES_CENTER_DIR removed.\r\nRestart Creo."); } FlashWindow(hWnd, TRUE); } else { SetWindowTextW(hNew, L"ERROR: Cannot write.\r\nClose Creo if running."); } } return 0; case WM_CTLCOLORSTATIC: case WM_CTLCOLOREDIT: SetBkColor((HDC)w, RGB(45, 45, 45)); SetTextColor((HDC)w, RGB(255, 255, 255)); return (LRESULT)hbrDarker; case WM_DESTROY: if (hfTitle) DeleteObject(hfTitle); if (hfBody) DeleteObject(hfBody); if (hfMono) DeleteObject(hfMono); if (hbrDark) DeleteObject(hbrDark); if (hbrDarker) DeleteObject(hbrDarker); if (hbrAccent) DeleteObject(hbrAccent); PostQuitMessage(0); return 0; } return DefWindowProcW(hWnd, msg, w, l); } int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cmd, int show) { (void)hp; (void)cmd; (void)show; WNDCLASSW wc = {0}; wc.lpfnWndProc = WndProc; wc.hInstance = hi; wc.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW); wc.hbrBackground = CreateSolidBrush(RGB(32, 32, 32)); wc.lpszClassName = L"RCConfigen"; wc.hIcon = LoadIconW(hi, MAKEINTRESOURCEW(IDI_MAIN)); wc.style = CS_HREDRAW|CS_VREDRAW; RegisterClassW(&wc); int sw = GetSystemMetrics(SM_CXSCREEN), sh = GetSystemMetrics(SM_CYSCREEN); int ww = 620, wh = 440; HWND hWnd = CreateWindowExW(0, L"RCConfigen", L"Protk.dat Configurator", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_VISIBLE, (sw-ww)/2, (sh-wh)/2, ww, wh, NULL, NULL, hi, NULL); BOOL dark = TRUE; DwmSetWindowAttribute(hWnd, 19, &dark, sizeof(dark)); DwmSetWindowAttribute(hWnd, 20, &dark, sizeof(dark)); MSG msg; while (GetMessageW(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessageW(&msg); } return 0; }