main.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. #define UNICODE
  2. #if defined(UNICODE) && !defined(_UNICODE)
  3. #define _UNICODE
  4. #elif defined(_UNICODE) && !defined(UNICODE)
  5. #define UNICODE
  6. #endif
  7. #include <stdio.h>
  8. #include <wchar.h>
  9. #include <tchar.h>
  10. #include <windows.h>
  11. #include <time.h>
  12. #include "base64/libbase64.h"
  13. #include "md5/md5.h"
  14. #include "sha1/sha1.h"
  15. #include "url/url.h"
  16. #include "parson/parson.h"
  17. #include "resources.h"
  18. #include "timelib/timelib.h"
  19. #define MIN_WIDTH 600
  20. #define MIN_HEIGHT 500
  21. #define FRAME_PADDING 3
  22. #define ROW_PADDING 10
  23. #define TOP_ROW_HEIGHT 26
  24. #define TOP_ITEM_WIDTH 60
  25. #define TOP_ITEM_SPACE 6
  26. #define BOTTOM_ROW_HEIGHT 26
  27. #define BOTTOM_ITEM_WIDTH 80
  28. #define BOTTOM_ITEM_SPACE 10
  29. /* Declare Windows procedure */
  30. LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
  31. /* Make the class name into a global variable */
  32. TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");
  33. HINSTANCE gInst;
  34. HMENU gMenu;
  35. HWND gWindows[256] = {};
  36. WORD gLastMenu = IDM_BASE64;
  37. WORD gLastFocus = IDC_EDIT;
  38. int gUTF8 = 1;
  39. timelib_tzinfo *gTimeZoneInfo;
  40. static BOOL RegWC(HINSTANCE inst);
  41. static void OnCreate(HWND hwnd);
  42. static void OnSizing(HWND hwnd, WPARAM fwSide, LPRECT lpRect);
  43. static void OnSize(HWND hwnd);
  44. static void OnMenuClicked(HWND hwnd, WORD id);
  45. static void OnAccelerator(HWND hwnd, WORD id);
  46. static void OnClicked(HWND hwnd, WORD id);
  47. static void ButtonOnClicked(HWND hwnd, WORD id);
  48. static char *wchar_to_utf8(const TCHAR *in, int in_len, int *out_len);
  49. static TCHAR *utf8_to_wchar(const char *in, int in_len, int *out_len);
  50. static char *wchar_to_acp(const TCHAR *in, int in_len, int *out_len);
  51. static TCHAR *acp_to_wchar(const char *in, int in_len, int *out_len);
  52. static char *nl_unix2win(const char *in, char *out);
  53. static TCHAR *base64_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8);
  54. static TCHAR *base64_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8);
  55. static TCHAR *url_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8);
  56. static TCHAR *url_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8);
  57. static TCHAR *md5_string(const TCHAR *in, int in_len, int *out_len, int utf8);
  58. static TCHAR *sha1_string(const TCHAR *in, int in_len, int *out_len, int utf8);
  59. static TCHAR *json_format(const TCHAR *in, int in_len, int *out_len, int utf8);
  60. static TCHAR *json_minify(const TCHAR *in, int in_len, int *out_len, int utf8);
  61. static TCHAR *time_convert_to_string(const TCHAR *in, int in_len, int *out_len);
  62. static TCHAR *string_convert_to_time(const TCHAR *in, int in_len, int *out_len);
  63. static timelib_tzinfo *my_date_parse_tzfile_wrapper(char *formal_tzname, const timelib_tzdb *tzdb);
  64. int WINAPI WinMain (HINSTANCE hThisInstance,
  65. HINSTANCE hPrevInstance,
  66. LPSTR lpszArgument,
  67. int nCmdShow)
  68. {
  69. HWND hwnd; /* This is the handle for our window */
  70. MSG messages; /* Here messages to the application are saved */
  71. HACCEL hAccel;
  72. int tziCode;
  73. gInst = hThisInstance;
  74. /* Register the window class, and if it fails quit the program */
  75. if (!RegWC (hThisInstance))
  76. return 0;
  77. gMenu = LoadMenu(hThisInstance, MAKEINTRESOURCE(IDM_MAIN));
  78. hAccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(IDD_ACCEL));
  79. /* The class is registered, let's create the program*/
  80. hwnd = CreateWindowEx (
  81. 0, /* Extended possibilites for variation */
  82. szClassName, /* Classname */
  83. _T("常用编解码工具"), /* Title Text */
  84. WS_OVERLAPPEDWINDOW, /* default window */
  85. CW_USEDEFAULT, /* Windows decides the position */
  86. CW_USEDEFAULT, /* where the window ends up on the screen */
  87. MIN_WIDTH, /* The programs width */
  88. MIN_HEIGHT, /* and height in pixels */
  89. HWND_DESKTOP, /* The window is a child-window to desktop */
  90. gMenu, /* No menu */
  91. hThisInstance, /* Program Instance handler */
  92. NULL /* No Window Creation data */
  93. );
  94. gWindows[0] = hwnd;
  95. /* Make the window visible on the screen */
  96. ShowWindow (hwnd, nCmdShow);
  97. gTimeZoneInfo = timelib_parse_tzfile("Etc/GMT-8", timelib_builtin_db(), &tziCode);
  98. /* Run the message loop. It will run until GetMessage() returns 0 */
  99. while (GetMessage (&messages, NULL, 0, 0))
  100. {
  101. if (TranslateAccelerator(hwnd, hAccel, &messages) == 0)
  102. {
  103. /* Translate virtual-key messages into character messages */
  104. TranslateMessage(&messages);
  105. }
  106. /* Send message to WindowProcedure */
  107. DispatchMessage(&messages);
  108. }
  109. /* The program return-value is 0 - The value that PostQuitMessage() gave */
  110. return messages.wParam;
  111. }
  112. static BOOL RegWC(HINSTANCE inst)
  113. {
  114. WNDCLASSEX wincl; /* Data structure for the windowclass */
  115. /* The Window structure */
  116. wincl.hInstance = inst;
  117. wincl.lpszClassName = szClassName;
  118. wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
  119. wincl.style = CS_DBLCLKS; /* Catch double-clicks */
  120. wincl.cbSize = sizeof (WNDCLASSEX);
  121. /* Use default icon and mouse-pointer */
  122. wincl.hIcon = LoadIcon (inst, MAKEINTRESOURCE(IDI_APP));
  123. wincl.hIconSm = LoadIcon (inst, MAKEINTRESOURCE(IDI_APP));
  124. wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  125. wincl.lpszMenuName = NULL; /* No menu */
  126. wincl.cbClsExtra = 0; /* No extra bytes after the window class */
  127. wincl.cbWndExtra = 0; /* structure or the window instance */
  128. /* Use Windows's default colour as the background of the window */
  129. wincl.hbrBackground = (HBRUSH) COLOR_WINDOW;
  130. /* Register the window class, and if it fails quit the program */
  131. return RegisterClassEx (&wincl);
  132. }
  133. /* This function is called by the Windows function DispatchMessage() */
  134. LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  135. {
  136. WORD wh, wl;
  137. switch (message) /* handle the messages */
  138. {
  139. case WM_CREATE:
  140. OnCreate(hwnd);
  141. break;
  142. case WM_SIZING:
  143. OnSizing(hwnd, wParam, (LPRECT)lParam);
  144. return TRUE;
  145. case WM_SIZE:
  146. OnSize(hwnd);
  147. break;
  148. case WM_COMMAND:
  149. wh = HIWORD(wParam); //message
  150. wl = LOWORD(wParam); //control id
  151. if (lParam == (LPARAM)NULL)
  152. {
  153. if (wh == 0)
  154. {
  155. OnMenuClicked(hwnd, wl);
  156. }
  157. else if (wh == 1)
  158. {
  159. OnAccelerator(hwnd, wl);
  160. }
  161. }
  162. else if (wh == BN_CLICKED)
  163. {
  164. OnClicked(hwnd, wl);
  165. }
  166. break;
  167. case WM_NOTIFY:
  168. break;
  169. case WM_DESTROY:
  170. PostQuitMessage (0); /* send a WM_QUIT to the message queue */
  171. break;
  172. default: /* for messages that we don't deal with */
  173. return DefWindowProc (hwnd, message, wParam, lParam);
  174. }
  175. return 0;
  176. }
  177. static void OnCreate(HWND hwnd)
  178. {
  179. RECT rect;
  180. long topRowL, topRowT, bottomRowL, bottomRowT, bodyL, bodyT, bodyW, bodyH;
  181. HFONT font;
  182. GetClientRect(hwnd, &rect);
  183. topRowL = bottomRowL = bodyL = rect.left + FRAME_PADDING;
  184. topRowT = rect.top + FRAME_PADDING;
  185. bottomRowT = rect.bottom - FRAME_PADDING - BOTTOM_ROW_HEIGHT;
  186. bodyT = topRowT + TOP_ROW_HEIGHT + ROW_PADDING;
  187. bodyW = rect.right - rect.left - FRAME_PADDING - FRAME_PADDING;
  188. bodyH = bottomRowT - ROW_PADDING - bodyT;
  189. gWindows[IDC_LABEL] = CreateWindowEx(0, _T("STATIC"), _T("编码:"), WS_CHILD | WS_VISIBLE, topRowL, topRowT+4, TOP_ITEM_WIDTH, TOP_ROW_HEIGHT-4, hwnd, (HMENU)IDC_LABEL, gInst, NULL);
  190. gWindows[IDC_UTF8] = CreateWindowEx(0, _T("BUTTON"), _T("UTF8"), WS_CHILD | BS_RADIOBUTTON | WS_VISIBLE, topRowL + (TOP_ITEM_WIDTH + TOP_ITEM_SPACE), topRowT, TOP_ITEM_WIDTH, TOP_ROW_HEIGHT, hwnd, (HMENU)IDC_UTF8, gInst, NULL);
  191. gWindows[IDC_GBK] = CreateWindowEx(0, _T("BUTTON"), _T("GBK"), WS_CHILD | BS_RADIOBUTTON | WS_VISIBLE, topRowL + (TOP_ITEM_WIDTH + TOP_ITEM_SPACE)*2, topRowT, TOP_ITEM_WIDTH, TOP_ROW_HEIGHT, hwnd, (HMENU)IDC_GBK, gInst, NULL);
  192. gWindows[IDC_EDIT] = CreateWindowEx(0, _T("EDIT"), NULL, WS_CHILD | WS_VSCROLL | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL, bodyL, bodyT, bodyW, bodyH, hwnd, (HMENU)IDC_EDIT, gInst, NULL);
  193. gWindows[IDC_ENC] = CreateWindowEx(0, _T("BUTTON"), _T("编码"), WS_CHILD | WS_VISIBLE, bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_ENC, gInst, NULL);
  194. gWindows[IDC_DEC] = CreateWindowEx(0, _T("BUTTON"), _T("解码"), WS_CHILD | WS_VISIBLE, bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_DEC, gInst, NULL);
  195. gWindows[IDC_FORMAT] = CreateWindowEx(0, _T("BUTTON"), _T("格式化"), WS_CHILD, bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_FORMAT, gInst, NULL);
  196. gWindows[IDC_MINIFY] = CreateWindowEx(0, _T("BUTTON"), _T("压缩"), WS_CHILD, bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_MINIFY, gInst, NULL);
  197. gWindows[IDC_TIME2STR] = CreateWindowEx(0, _T("BUTTON"), _T("转字符串"), WS_CHILD, bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_TIME2STR, gInst, NULL);
  198. gWindows[IDC_STR2TIME] = CreateWindowEx(0, _T("BUTTON"), _T("转时间戳"), WS_CHILD, bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_STR2TIME, gInst, NULL);
  199. font = CreateFont(0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("宋体"));
  200. if (font == NULL)
  201. {
  202. MessageBox(hwnd, _T("系统未安装宋体!"), _T("提示"), MB_OK);
  203. }
  204. else
  205. {
  206. SendMessage(gWindows[IDC_LABEL], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  207. SendMessage(gWindows[IDC_UTF8], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  208. SendMessage(gWindows[IDC_GBK], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  209. SendMessage(gWindows[IDC_EDIT], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  210. SendMessage(gWindows[IDC_ENC], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  211. SendMessage(gWindows[IDC_DEC], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  212. SendMessage(gWindows[IDC_FORMAT], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  213. SendMessage(gWindows[IDC_MINIFY], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  214. SendMessage(gWindows[IDC_TIME2STR], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  215. SendMessage(gWindows[IDC_STR2TIME], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0));
  216. }
  217. CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8);
  218. SendMessage(gWindows[IDC_EDIT], EM_SETLIMITTEXT, (WPARAM)0x7FFFFFFE, 0);
  219. SetFocus(gWindows[IDC_EDIT]);
  220. }
  221. static void OnSizing(HWND hwnd, WPARAM fsSide, LPRECT lpRect)
  222. {
  223. long width, height;
  224. width = lpRect->right - lpRect->left;
  225. height = lpRect->bottom - lpRect->top;
  226. if (width < MIN_WIDTH)
  227. {
  228. if (fsSide & WMSZ_LEFT || fsSide & WMSZ_TOPLEFT || fsSide & WMSZ_BOTTOMLEFT)
  229. {
  230. lpRect->left = lpRect->right - MIN_WIDTH;
  231. }
  232. else if (fsSide & WMSZ_RIGHT || fsSide & WMSZ_TOPRIGHT || fsSide & WMSZ_BOTTOMRIGHT)
  233. {
  234. lpRect->right = lpRect->left + MIN_WIDTH;
  235. }
  236. }
  237. if (height < MIN_HEIGHT)
  238. {
  239. if (fsSide & WMSZ_TOP || fsSide & WMSZ_TOPLEFT || fsSide & WMSZ_TOPRIGHT)
  240. {
  241. lpRect->top = lpRect->bottom - MIN_HEIGHT;
  242. }
  243. else if (fsSide & WMSZ_BOTTOM || fsSide & WMSZ_BOTTOMLEFT || fsSide & WMSZ_BOTTOMRIGHT)
  244. {
  245. lpRect->bottom = lpRect->top + MIN_HEIGHT;
  246. }
  247. }
  248. }
  249. static void OnSize(HWND hwnd)
  250. {
  251. RECT rect = {};
  252. long topRowT, bottomRowL, bottomRowT, bodyL, bodyT, bodyW, bodyH;
  253. GetClientRect(hwnd, &rect);
  254. bottomRowL = bodyL = rect.left + FRAME_PADDING;
  255. topRowT = rect.top + FRAME_PADDING;
  256. bottomRowT = rect.bottom - FRAME_PADDING - BOTTOM_ROW_HEIGHT;
  257. bodyT = topRowT + TOP_ROW_HEIGHT + ROW_PADDING;
  258. bodyW = rect.right - rect.left - FRAME_PADDING - FRAME_PADDING;
  259. bodyH = bottomRowT - ROW_PADDING - bodyT;
  260. MoveWindow(gWindows[IDC_ENC], bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE);
  261. MoveWindow(gWindows[IDC_DEC], bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE);
  262. MoveWindow(gWindows[IDC_FORMAT], bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE);
  263. MoveWindow(gWindows[IDC_MINIFY], bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE);
  264. MoveWindow(gWindows[IDC_TIME2STR], bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE);
  265. MoveWindow(gWindows[IDC_STR2TIME], bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE);
  266. MoveWindow(gWindows[IDC_EDIT], bodyL, bodyT, bodyW, bodyH, TRUE);
  267. }
  268. static void OnMenuClicked(HWND hwnd, WORD id)
  269. {
  270. if (id == IDM_ABOUT)
  271. {
  272. MessageBox(hwnd, _T("快捷键\r\nCtrl + A: 全选\r\nCtrl + Q: 退出\r\nCtrl + F: 切换焦点\r\nCtrl + T: 切换UTF-8\r\nCtrl + G: 切换GBK\r\n[Weicky 2019]"), _T("提示"), MB_OK);
  273. return;
  274. }
  275. SetMenuDefaultItem(gMenu, id, FALSE);
  276. EnableWindow(gWindows[IDC_UTF8], id == IDM_TIME ? FALSE : TRUE);
  277. EnableWindow(gWindows[IDC_GBK], id == IDM_JSON || id == IDM_TIME ? FALSE : TRUE);
  278. ShowWindow(gWindows[IDC_ENC], id == IDM_BASE64 || id == IDM_URL || id == IDM_MD5 || id == IDM_SHA1 ? SW_SHOW : SW_HIDE);
  279. ShowWindow(gWindows[IDC_DEC], id == IDM_BASE64 || id == IDM_URL ? SW_SHOW : SW_HIDE);
  280. ShowWindow(gWindows[IDC_FORMAT], id == IDM_JSON ? SW_SHOW : SW_HIDE);
  281. ShowWindow(gWindows[IDC_MINIFY], id == IDM_JSON ? SW_SHOW : SW_HIDE);
  282. ShowWindow(gWindows[IDC_TIME2STR], id == IDM_TIME ? SW_SHOW : SW_HIDE);
  283. ShowWindow(gWindows[IDC_STR2TIME], id == IDM_TIME ? SW_SHOW : SW_HIDE);
  284. if (id == IDM_JSON)
  285. {
  286. CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8);
  287. }
  288. if (id == IDM_TIME)
  289. {
  290. char ts[32] = "";
  291. TCHAR *wts;
  292. int wts_len;
  293. sprintf(ts, "%ld", time(NULL));
  294. wts = acp_to_wchar(ts, strlen(ts), &wts_len);
  295. SetWindowText(gWindows[IDC_EDIT], wts);
  296. free(wts);
  297. }
  298. DrawMenuBar(gWindows[0]);
  299. gLastMenu = id;
  300. }
  301. static void OnAccelerator(HWND hwnd, WORD id)
  302. {
  303. switch (id)
  304. {
  305. case IDD_SELECT: //ctrl + A
  306. SendMessage(gWindows[IDC_EDIT], EM_SETSEL, (WPARAM)0, (LPARAM)-1);
  307. break;
  308. case IDD_QUIT: //ctrl + Q
  309. if (MessageBox(hwnd, _T("确定要退出吗?"), _T("提示"), MB_YESNO) == IDYES)
  310. {
  311. DestroyWindow(hwnd);
  312. }
  313. break;
  314. case IDD_FOCUS: //ctrl + T
  315. while (1)
  316. {
  317. gLastFocus = gLastFocus == IDC_STR2TIME ? IDC_EDIT : gLastFocus + 1;
  318. if (gLastFocus == IDC_LABEL || gLastFocus == IDC_UTF8 || gLastFocus == IDC_GBK || IsWindowEnabled(gWindows[gLastFocus]) == FALSE || IsWindowVisible(gWindows[gLastFocus]) == FALSE)
  319. {
  320. continue;
  321. }
  322. SetFocus(gWindows[gLastFocus]);
  323. break;
  324. }
  325. break;
  326. case IDD_UTF8:
  327. if (IsWindowEnabled(gWindows[IDC_UTF8]) == TRUE)
  328. {
  329. CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8);
  330. }
  331. break;
  332. case IDD_GBK:
  333. if (IsWindowEnabled(gWindows[IDC_GBK]) == TRUE)
  334. {
  335. CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_GBK);
  336. }
  337. break;
  338. }
  339. }
  340. static void OnClicked(HWND hwnd, WORD id)
  341. {
  342. switch (id)
  343. {
  344. case IDC_UTF8:
  345. CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8);
  346. gUTF8 = 1;
  347. break;
  348. case IDC_GBK:
  349. CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_GBK);
  350. gUTF8 = 0;
  351. break;
  352. case IDC_ENC:
  353. ButtonOnClicked(hwnd, id);
  354. break;
  355. case IDC_DEC:
  356. ButtonOnClicked(hwnd, id);
  357. break;
  358. case IDC_FORMAT:
  359. ButtonOnClicked(hwnd, id);
  360. break;
  361. case IDC_MINIFY:
  362. ButtonOnClicked(hwnd, id);
  363. break;
  364. case IDC_TIME2STR:
  365. ButtonOnClicked(hwnd, id);
  366. break;
  367. case IDC_STR2TIME:
  368. ButtonOnClicked(hwnd, id);
  369. break;
  370. }
  371. }
  372. static void ButtonOnClicked(HWND hwnd, WORD id)
  373. {
  374. TCHAR *input, *output;
  375. int inputLen, outputLen;
  376. inputLen = GetWindowTextLength(gWindows[IDC_EDIT]);
  377. if (inputLen)
  378. {
  379. input = (TCHAR *)calloc(inputLen + 1, sizeof(TCHAR));
  380. GetWindowText(gWindows[IDC_EDIT], input, inputLen + 1);
  381. switch (gLastMenu)
  382. {
  383. case IDM_BASE64:
  384. if (id == IDC_ENC)
  385. {
  386. output = base64_encode_string(input, inputLen, &outputLen, gUTF8);
  387. }
  388. else if (id == IDC_DEC)
  389. {
  390. output = base64_decode_string(input, inputLen, &outputLen, gUTF8);
  391. }
  392. else
  393. {
  394. return;
  395. }
  396. break;
  397. case IDM_URL:
  398. if (id == IDC_ENC)
  399. {
  400. output = url_encode_string(input, inputLen, &outputLen, gUTF8);
  401. }
  402. else if (id == IDC_DEC)
  403. {
  404. output = url_decode_string(input, inputLen, &outputLen, gUTF8);
  405. }
  406. else
  407. {
  408. return;
  409. }
  410. break;
  411. case IDM_MD5:
  412. output = md5_string(input, inputLen, &outputLen, gUTF8);
  413. break;
  414. case IDM_SHA1:
  415. output = sha1_string(input, inputLen, &outputLen, gUTF8);
  416. break;
  417. case IDM_JSON:
  418. if (id == IDC_FORMAT)
  419. {
  420. output = json_format(input, inputLen, &outputLen, gUTF8);
  421. }
  422. else if (id == IDC_MINIFY)
  423. {
  424. output = json_minify(input, inputLen, &outputLen, gUTF8);
  425. }
  426. else
  427. {
  428. return;
  429. }
  430. break;
  431. case IDM_TIME:
  432. if (id == IDC_TIME2STR)
  433. {
  434. output = time_convert_to_string(input, inputLen, &outputLen);
  435. }
  436. else if (id == IDC_STR2TIME)
  437. {
  438. output = string_convert_to_time(input, inputLen, &outputLen);
  439. }
  440. else
  441. {
  442. return;
  443. }
  444. break;
  445. }
  446. //输出&清理
  447. SetWindowText(gWindows[IDC_EDIT], output);
  448. free(output);
  449. free(input);
  450. }
  451. }
  452. static char *nl_unix2win(const char *in, char *out)
  453. {
  454. char *cpy, c;
  455. cpy = out;
  456. while ((c = *in++))
  457. {
  458. if (c == '\r' && *in == '\n')
  459. {
  460. *cpy++ = c;
  461. *cpy++ = *in++;
  462. }
  463. else if (c == '\n')
  464. {
  465. *cpy++ = '\r';
  466. }
  467. *cpy++ = c;
  468. }
  469. return out;
  470. }
  471. static char *wchar_to_utf8(const TCHAR *in, int in_len, int *out_len)
  472. {
  473. char *out;
  474. *out_len = WideCharToMultiByte(CP_UTF8, 0, in, in_len, NULL, 0, NULL, NULL);
  475. if (*out_len == 0)
  476. {
  477. return NULL;
  478. }
  479. out = (char *)calloc(*out_len + 1, 1);
  480. WideCharToMultiByte(CP_UTF8, 0, in, in_len, out, *out_len, NULL, NULL);
  481. return out;
  482. }
  483. static TCHAR *utf8_to_wchar(const char *in, int in_len, int *out_len)
  484. {
  485. TCHAR *out;
  486. *out_len = MultiByteToWideChar(CP_UTF8, 0, in, in_len, NULL, 0);
  487. if (*out_len == 0)
  488. {
  489. return NULL;
  490. }
  491. out = (TCHAR *)calloc((*out_len + 1) * sizeof(TCHAR), 1);
  492. MultiByteToWideChar(CP_UTF8, 0, in, in_len, out, *out_len);
  493. return out;
  494. }
  495. static char *wchar_to_acp(const TCHAR *in, int in_len, int *out_len)
  496. {
  497. char *out;
  498. *out_len = WideCharToMultiByte(CP_ACP, 0, in, in_len, NULL, 0, NULL, NULL);
  499. if (*out_len == 0)
  500. {
  501. return NULL;
  502. }
  503. out = (char *)calloc(*out_len + 1, 1);
  504. WideCharToMultiByte(CP_ACP, 0, in, in_len, out, *out_len, NULL, NULL);
  505. return out;
  506. }
  507. static TCHAR *acp_to_wchar(const char *in, int in_len, int *out_len)
  508. {
  509. TCHAR *out;
  510. *out_len = MultiByteToWideChar(CP_ACP, 0, in, in_len, NULL, 0);
  511. if (*out_len == 0)
  512. {
  513. return NULL;
  514. }
  515. out = (TCHAR *)calloc((*out_len + 1) * sizeof(TCHAR), 1);
  516. MultiByteToWideChar(CP_ACP, 0, in, in_len, out, *out_len);
  517. return out;
  518. }
  519. static TCHAR *base64_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8)
  520. {
  521. char *cpy, *res;
  522. int cpy_len, res_len;
  523. TCHAR *out;
  524. if (utf8)
  525. {
  526. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  527. }
  528. else
  529. {
  530. cpy = wchar_to_acp(in, in_len, &cpy_len);
  531. }
  532. res_len = cpy_len * 3;
  533. res = (char *)calloc(res_len + 1, 1);
  534. base64_encode(cpy, cpy_len, res, (size_t *)&res_len, 0);
  535. free(cpy);
  536. if (utf8)
  537. {
  538. out = utf8_to_wchar(res, res_len, out_len);
  539. }
  540. else
  541. {
  542. out = acp_to_wchar(res, res_len, out_len);
  543. }
  544. free(res);
  545. return out;
  546. }
  547. static TCHAR *base64_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8)
  548. {
  549. char *cpy, *res;
  550. int cpy_len, res_len;
  551. TCHAR *out;
  552. if (utf8)
  553. {
  554. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  555. }
  556. else
  557. {
  558. cpy = wchar_to_acp(in, in_len, &cpy_len);
  559. }
  560. res_len = cpy_len * 3;
  561. res = (char *)calloc(res_len + 1, 1);
  562. base64_decode(cpy, cpy_len, res, (size_t *)&res_len, 0);
  563. free(cpy);
  564. if (utf8)
  565. {
  566. out = utf8_to_wchar(res, res_len, out_len);
  567. }
  568. else
  569. {
  570. out = acp_to_wchar(res, res_len, out_len);
  571. }
  572. free(res);
  573. return out;
  574. }
  575. static TCHAR *url_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8)
  576. {
  577. char *cpy, *res;
  578. int cpy_len, res_len;
  579. TCHAR *out;
  580. if (utf8)
  581. {
  582. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  583. }
  584. else
  585. {
  586. cpy = wchar_to_acp(in, in_len, &cpy_len);
  587. }
  588. res_len = cpy_len * 3;
  589. res = (char *)calloc(res_len + 1, 1);
  590. url_encode(cpy, cpy_len, res, (size_t *)&res_len);
  591. free(cpy);
  592. if (utf8)
  593. {
  594. out = utf8_to_wchar(res, res_len, out_len);
  595. }
  596. else
  597. {
  598. out = acp_to_wchar(res, res_len, out_len);
  599. }
  600. free(res);
  601. return out;
  602. }
  603. static TCHAR *url_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8)
  604. {
  605. char *cpy, *res;
  606. int cpy_len, res_len;
  607. TCHAR *out;
  608. if (utf8)
  609. {
  610. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  611. }
  612. else
  613. {
  614. cpy = wchar_to_acp(in, in_len, &cpy_len);
  615. }
  616. res_len = cpy_len * 3;
  617. res = (char *)calloc(res_len + 1, 1);
  618. url_decode(cpy, cpy_len, res, (size_t *)&res_len);
  619. free(cpy);
  620. if (utf8)
  621. {
  622. out = utf8_to_wchar(res, res_len, out_len);
  623. }
  624. else
  625. {
  626. out = acp_to_wchar(res, res_len, out_len);
  627. }
  628. free(res);
  629. return out;
  630. }
  631. static TCHAR *md5_string(const TCHAR *in, int in_len, int *out_len, int utf8)
  632. {
  633. char *cpy, *res;
  634. int cpy_len, res_len;
  635. TCHAR *out;
  636. if (utf8)
  637. {
  638. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  639. }
  640. else
  641. {
  642. cpy = wchar_to_acp(in, in_len, &cpy_len);
  643. }
  644. res_len = 32;
  645. res = (char *)calloc(res_len + 1, 1);
  646. md5(cpy, cpy_len, res);
  647. free(cpy);
  648. if (utf8)
  649. {
  650. out = utf8_to_wchar(res, res_len, out_len);
  651. }
  652. else
  653. {
  654. out = acp_to_wchar(res, res_len, out_len);
  655. }
  656. free(res);
  657. return out;
  658. }
  659. static TCHAR *sha1_string(const TCHAR *in, int in_len, int *out_len, int utf8)
  660. {
  661. char *cpy, *res;
  662. int cpy_len, res_len;
  663. TCHAR *out;
  664. if (utf8)
  665. {
  666. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  667. }
  668. else
  669. {
  670. cpy = wchar_to_acp(in, in_len, &cpy_len);
  671. }
  672. res_len = 40;
  673. res = (char *)calloc(res_len + 1, 1);
  674. sha1(cpy, cpy_len, res);
  675. free(cpy);
  676. if (utf8)
  677. {
  678. out = utf8_to_wchar(res, res_len, out_len);
  679. }
  680. else
  681. {
  682. out = acp_to_wchar(res, res_len, out_len);
  683. }
  684. free(res);
  685. return out;
  686. }
  687. static TCHAR *json_format(const TCHAR *in, int in_len, int *out_len, int utf8)
  688. {
  689. char *cpy, *json, *json_cpy;
  690. int cpy_len;
  691. JSON_Value *obj;
  692. TCHAR *out;
  693. if (utf8)
  694. {
  695. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  696. }
  697. else
  698. {
  699. cpy = wchar_to_acp(in, in_len, &cpy_len);
  700. }
  701. obj = json_parse_string_with_comments(cpy);
  702. free(cpy);
  703. if (obj == NULL)
  704. {
  705. *out_len = 5;
  706. out = (TCHAR *)calloc(*out_len, sizeof(TCHAR));
  707. wcscpy(out, _T("null"));
  708. }
  709. else
  710. {
  711. json = json_serialize_to_string_pretty(obj);
  712. json_value_free(obj);
  713. json_cpy = (char *)calloc(strlen(json) * 2 + 1, 1);
  714. nl_unix2win(json, json_cpy);
  715. json_free_serialized_string(json);
  716. out = utf8_to_wchar(json_cpy, strlen(json_cpy), out_len);
  717. free(json_cpy);
  718. }
  719. return out;
  720. }
  721. static TCHAR *json_minify(const TCHAR *in, int in_len, int *out_len, int utf8)
  722. {
  723. char *cpy, *json, *json_cpy;
  724. int cpy_len;
  725. JSON_Value *obj;
  726. TCHAR *out;
  727. if (utf8)
  728. {
  729. cpy = wchar_to_utf8(in, in_len, &cpy_len);
  730. }
  731. else
  732. {
  733. cpy = wchar_to_acp(in, in_len, &cpy_len);
  734. }
  735. obj = json_parse_string_with_comments(cpy);
  736. free(cpy);
  737. if (obj == NULL)
  738. {
  739. *out_len = 5;
  740. out = (TCHAR *)calloc(*out_len, sizeof(TCHAR));
  741. wcscpy(out, _T("null"));
  742. }
  743. else
  744. {
  745. json = json_serialize_to_string(obj);
  746. json_value_free(obj);
  747. json_cpy = (char *)calloc(strlen(json) * 2 + 1, 1);
  748. nl_unix2win(json, json_cpy);
  749. json_free_serialized_string(json);
  750. out = utf8_to_wchar(json_cpy, strlen(json_cpy), out_len);
  751. free(json_cpy);
  752. }
  753. return out;
  754. }
  755. static TCHAR *time_convert_to_string(const TCHAR *in, int in_len, int *out_len)
  756. {
  757. char *cpy, res[32] = "";
  758. int cpy_len;
  759. time_t ts;
  760. TCHAR *out;
  761. timelib_time *t;
  762. //wchar*转int
  763. cpy = wchar_to_acp(in, in_len, &cpy_len);
  764. ts = (time_t)atoi(cpy);
  765. free(cpy);
  766. //int转timelib_time(struct)
  767. t = timelib_time_ctor();
  768. t->tz_info = gTimeZoneInfo;
  769. t->zone_type = TIMELIB_ZONETYPE_ID;
  770. timelib_unixtime2local(t, ts);
  771. //timelib_time转char*
  772. sprintf(res, "%ld-%02ld-%02ld %02ld:%02ld:%02ld", (long)t->y, (long)t->m, (long)t->d, (long)t->h, (long)t->i, (long)t->s);
  773. timelib_time_dtor(t);
  774. //char*转wchar*
  775. out = acp_to_wchar(res, strlen(res), out_len);
  776. return out;
  777. }
  778. static TCHAR *string_convert_to_time(const TCHAR *in, int in_len, int *out_len)
  779. {
  780. char *cpy, res[32] = "";
  781. int cpy_len, error1, error2;
  782. int64_t ts;
  783. TCHAR *out;
  784. timelib_time *t, *now;
  785. timelib_error_container *error;
  786. //wchar*转char*
  787. cpy = wchar_to_acp(in, in_len, &cpy_len);
  788. ts = (time_t)atoi(cpy);
  789. //char*转timelib_time(struct)再转int64_t
  790. now = timelib_time_ctor();
  791. now->tz_info = gTimeZoneInfo;
  792. now->zone_type = TIMELIB_ZONETYPE_ID;
  793. timelib_unixtime2local(now, time(NULL));
  794. t = timelib_strtotime(cpy, strlen(cpy), &error, timelib_builtin_db(), (timelib_tz_get_wrapper)my_date_parse_tzfile_wrapper);
  795. error1 = error->error_count;
  796. timelib_error_container_dtor(error);
  797. timelib_fill_holes(t, now, TIMELIB_NO_CLONE);
  798. timelib_update_ts(t, gTimeZoneInfo);
  799. ts = (int64_t)timelib_date_to_int(t, &error2);
  800. timelib_time_dtor(now);
  801. timelib_time_dtor(t);
  802. free(cpy);
  803. //将int64_t转为char*
  804. if (error1 || error2)
  805. {
  806. *out_len = in_len;
  807. return in;
  808. }
  809. else
  810. {
  811. sprintf(res, "%ld", (long)ts);
  812. }
  813. //将char*转为TCHAR*
  814. out = acp_to_wchar(res, strlen(res), out_len);
  815. return out;
  816. }
  817. static timelib_tzinfo *my_date_parse_tzfile_wrapper(char *formal_tzname, const timelib_tzdb *tzdb)
  818. {
  819. return gTimeZoneInfo;
  820. }