main.c 27 KB

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