PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/xaos-3.5/src/ui/ui-drv/win32/windialo.c

#
C | 471 lines | 435 code | 21 blank | 15 comment | 75 complexity | e49ee7229c32978893de1b44809aca05 MD5 | raw file
Possible License(s): GPL-2.0
  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <config.h>
  7. /*#include <filter.h>
  8. #include <ui_helper.h> */
  9. #include <xerror.h>
  10. #include <xldio.h>
  11. #include <ui.h>
  12. #include <xmenu.h>
  13. #include "ui_win32.h"
  14. #ifdef HAVE_GETTEXT
  15. #include <libintl.h>
  16. #else
  17. #define gettext(STRING) STRING
  18. #endif
  19. TCHAR text[100];
  20. #define QUESTIONSTART 100
  21. #define ITEMSTART 10
  22. #define PERITEM 5
  23. #define OK 1
  24. #define CANCEL 2
  25. #define HELP 3
  26. static struct dialogrecord {
  27. CONST menuitem *item;
  28. CONST menudialog *dialog;
  29. int nitems;
  30. HWND windialog;
  31. struct uih_context *c;
  32. struct dialogrecord *next, *prev;
  33. } *firstdialog = NULL;
  34. static CONST char *win32_getextension(CONST char *ch)
  35. {
  36. int i = 0;
  37. while (ch[i]) {
  38. if (ch[i] == '*')
  39. return (ch + i + 1);
  40. i++;
  41. }
  42. return ch + i;
  43. }
  44. static char *win32_dofiledialog(struct uih_context *uih,
  45. CONST menuitem * item,
  46. CONST menudialog * dialog)
  47. {
  48. OPENFILENAME ofn;
  49. char szDirName[256];
  50. char szFile[256], szFileTitle[256];
  51. UINT i, p;
  52. char szFilter[256];
  53. helptopic = item->shortname;
  54. szDirName[0] = 0;
  55. /*GetSystemDirectory(szDirName, sizeof(szDirName)); */
  56. szFile[0] = 0;
  57. if (dialog[0].type == DIALOG_OFILE) {
  58. strcpy(szFile, dialog[0].defstr);
  59. for (i = 0; dialog[0].defstr[i] && dialog[0].defstr[i] != '*';
  60. i++);
  61. szFile[i] = 0;
  62. strcpy(szFile,
  63. ui_getfile(szFile, win32_getextension(dialog[0].defstr)));
  64. }
  65. for (i = 0; dialog[0].defstr[i] && dialog[0].defstr[i] != '*'; i++)
  66. if (!dialog[0].defstr[i])
  67. i = 0;
  68. strcpy(szFilter, dialog[0].defstr + i);
  69. p = strlen(szFilter);
  70. strcpy(szFilter + p + 1, dialog[0].defstr + i);
  71. p += strlen(szFilter + p + 1) + 1;
  72. strcpy(szFilter + p + 1, "All files");
  73. p += strlen(szFilter + p + 1) + 1;
  74. strcpy(szFilter + p + 1, "*.*");
  75. p += strlen(szFilter + p + 1) + 1;
  76. szFilter[p + 1] = 0;
  77. memset(&ofn, 0, sizeof(OPENFILENAME));
  78. ofn.lStructSize = sizeof(OPENFILENAME);
  79. ofn.hwndOwner = hWnd;
  80. ofn.lpstrFilter = szFilter;
  81. ofn.nFilterIndex = 1;
  82. ofn.lpstrFile = szFile;
  83. ofn.nMaxFile = sizeof(szFile);
  84. ofn.lpstrFileTitle = szFileTitle;
  85. ofn.nMaxFileTitle = sizeof(szFileTitle);
  86. ofn.lpstrInitialDir = szDirName;
  87. ofn.Flags =
  88. OFN_SHOWHELP | OFN_PATHMUSTEXIST | (dialog[0].type ==
  89. DIALOG_IFILE ?
  90. OFN_FILEMUSTEXIST :
  91. OFN_OVERWRITEPROMPT);
  92. if (dialog[0].type == DIALOG_IFILE)
  93. i = GetOpenFileName(&ofn);
  94. else
  95. i = GetSaveFileName(&ofn);
  96. helptopic = "main";
  97. if (i) {
  98. return (strdup(ofn.lpstrFile));
  99. }
  100. return NULL;
  101. }
  102. static void
  103. win32_filedialog(struct uih_context *uih, CONST menuitem * item,
  104. CONST menudialog * dialog)
  105. {
  106. char *name = win32_dofiledialog(uih, item, dialog);
  107. if (name) {
  108. dialogparam *param = malloc(sizeof(dialogparam));
  109. param->dstring = name;
  110. ui_menuactivate(item, param);
  111. }
  112. }
  113. static void win32_freedialog(struct dialogrecord *r)
  114. {
  115. if (r->next)
  116. r->next->prev = r->prev;
  117. if (r->prev)
  118. r->prev->next = r->next;
  119. else
  120. firstdialog = r->next;
  121. free(r);
  122. }
  123. static int win32_dodialog(struct dialogrecord *r, HWND hDLG)
  124. {
  125. dialogparam *p = calloc(sizeof(*p), r->nitems);
  126. int i;
  127. char s[256];
  128. for (i = 0; i < r->nitems; i++) {
  129. switch (r->dialog[i].type) {
  130. case DIALOG_IFILE:
  131. case DIALOG_OFILE:
  132. case DIALOG_STRING:
  133. case DIALOG_KEYSTRING:
  134. GetDlgItemText(hDLG, i * PERITEM + ITEMSTART, s, sizeof(s));
  135. p[i].dstring = strdup(s);
  136. break;
  137. case DIALOG_INT:
  138. GetDlgItemText(hDLG, i * PERITEM + ITEMSTART, s, sizeof(s));
  139. p[i].dint = r->dialog[i].defint;
  140. sscanf(s, "%i", &p[i].dint);
  141. break;
  142. case DIALOG_FLOAT:
  143. GetDlgItemText(hDLG, i * PERITEM + ITEMSTART, s, sizeof(s));
  144. p[i].number = r->dialog[i].deffloat;
  145. p[i].number = x_strtold(s, NULL);
  146. break;
  147. case DIALOG_COORD:
  148. GetDlgItemText(hDLG, i * PERITEM + ITEMSTART, s, sizeof(s));
  149. p[i].dcoord[0] = r->dialog[i].deffloat;
  150. p[i].dcoord[0] = x_strtold(s, NULL);
  151. GetDlgItemText(hDLG, i * PERITEM + ITEMSTART + 1, s,
  152. sizeof(s));
  153. p[i].dcoord[1] = r->dialog[i].deffloat2;
  154. p[i].dcoord[1] = x_strtold(s, NULL);
  155. break;
  156. case DIALOG_CHOICE:
  157. /*x_message("Choice is not implemented yet"); */
  158. {
  159. int y;
  160. y = LOWORD(SendDlgItemMessage
  161. (hDLG, i * PERITEM + ITEMSTART, CB_GETCURSEL, 0,
  162. 0L));
  163. p[i].dint =
  164. LOWORD(SendDlgItemMessage
  165. (hDLG, i * PERITEM + ITEMSTART, CB_GETITEMDATA,
  166. (WPARAM) y, 0L));
  167. }
  168. }
  169. }
  170. ui_menuactivate(r->item, p);
  171. return 1;
  172. }
  173. static BOOL APIENTRY
  174. DialogHandler(HWND hDLG, UINT message, UINT wParam, LONG lParam)
  175. {
  176. struct dialogrecord *rec = firstdialog;
  177. int i;
  178. /* while(rec->windialog!=hDLG) rec=rec->next; */
  179. if (!rec->windialog)
  180. rec->windialog = hDLG;
  181. switch (message) {
  182. case WM_INITDIALOG:
  183. /*x_message("Creating dialog"); */
  184. ShowWindow(hDLG, SW_HIDE);
  185. /*CenterWindow (hDLG, GetWindow (hDLG, GW_OWNER)); */
  186. if (GetWindowText(hDLG, text, GetWindowTextLength(hDLG) + 1) > 0);
  187. SetWindowText(hDLG, gettext(text));
  188. SetDlgItemText(hDLG, OK, gettext("OK"));
  189. SetDlgItemText(hDLG, CANCEL, gettext("Cancel"));
  190. SetDlgItemText(hDLG, HELP, gettext("Help"));
  191. for (i = 0; rec->dialog[i].question; i++) {
  192. if (GetDlgItemText
  193. (hDLG, i * PERITEM + QUESTIONSTART, text, 100) > 0)
  194. SetDlgItemText(hDLG, i * PERITEM + QUESTIONSTART,
  195. gettext(text));
  196. switch (rec->dialog[i].type) {
  197. char s[256];
  198. case DIALOG_STRING:
  199. case DIALOG_IFILE:
  200. case DIALOG_OFILE:
  201. SetDlgItemText(hDLG, i * PERITEM + ITEMSTART,
  202. rec->dialog[i].defstr);
  203. break;
  204. case DIALOG_INT:
  205. sprintf(s, "%i", rec->dialog[i].defint);
  206. SetDlgItemText(hDLG, i * PERITEM + ITEMSTART, s);
  207. break;
  208. case DIALOG_COORD:
  209. sprintf(s, "%g", (double) rec->dialog[i].deffloat2);
  210. SetDlgItemText(hDLG, i * PERITEM + ITEMSTART + 1, s);
  211. /*Fall trought */
  212. case DIALOG_FLOAT:
  213. sprintf(s, "%g", (double) rec->dialog[i].deffloat);
  214. SetDlgItemText(hDLG, i * PERITEM + ITEMSTART, s);
  215. break;
  216. case DIALOG_CHOICE:
  217. {
  218. CONST char **strings =
  219. (CONST char **) rec->dialog[i].defstr;
  220. int y;
  221. int pos;
  222. for (y = 0; strings[y]; y++) {
  223. pos =
  224. LOWORD(SendDlgItemMessage
  225. (hDLG, i * PERITEM + ITEMSTART,
  226. CB_ADDSTRING, (WPARAM) 0,
  227. (LPARAM) (LPSTR) strings[y]));
  228. /*x_message("%s %i",strings[y],pos); */
  229. SendMessage(GetDlgItem
  230. (hDLG, i * PERITEM + ITEMSTART),
  231. CB_SETITEMDATA, (WPARAM) pos, y);
  232. if (y == rec->dialog[i].defint) {
  233. pos =
  234. SendMessage(GetDlgItem
  235. (hDLG,
  236. i * PERITEM + ITEMSTART),
  237. CB_SETCURSEL, (WPARAM) pos,
  238. 0L);
  239. /*x_message("Default %i",pos); */
  240. }
  241. }
  242. pos =
  243. LOWORD(SendDlgItemMessage
  244. (hDLG, i * PERITEM + ITEMSTART, CB_GETCOUNT,
  245. (WPARAM) 0, 0));
  246. /*x_message("Count %i",pos); */
  247. }
  248. break;
  249. }
  250. }
  251. CenterWindow(hDLG, GetWindow(hDLG, GW_OWNER));
  252. ShowWindow(hDLG, SW_SHOW);
  253. return (TRUE);
  254. case WM_SYSCOMMAND:
  255. if (wParam == SC_CLOSE) {
  256. EndDialog(hDLG, 0);
  257. return (TRUE);
  258. }
  259. break;
  260. case WM_COMMAND:
  261. if (wParam == OK) {
  262. if (win32_dodialog(rec, hDLG)) {
  263. EndDialog(hDLG, 0);
  264. return (TRUE);
  265. }
  266. }
  267. if (wParam == CANCEL) {
  268. EndDialog(hDLG, 0);
  269. return (TRUE);
  270. }
  271. if (wParam == HELP) {
  272. win32_help(rec->c, rec->item->shortname);
  273. return (TRUE);
  274. }
  275. {
  276. int i = (wParam - ITEMSTART) / PERITEM;
  277. int pos = (wParam - ITEMSTART) % PERITEM;
  278. if (i >= 0 && i < rec->nitems) {
  279. if (pos == 1
  280. && (rec->dialog[i].type == DIALOG_IFILE
  281. || rec->dialog[i].type == DIALOG_OFILE)) {
  282. /*x_message("File dialog\n"); */
  283. char *file =
  284. win32_dofiledialog(rec->c, rec->item,
  285. rec->dialog + i);
  286. if (file) {
  287. SetDlgItemText(hDLG, wParam - 1, file);
  288. free(file);
  289. }
  290. }
  291. }
  292. }
  293. break;
  294. }
  295. return FALSE;
  296. }
  297. #define INPUTSIZE 20
  298. #define XBORDER 0
  299. #define YBORDER 5
  300. #define XSEP 4
  301. #define CHARWIDTH 4
  302. #define MINWIDTH ((7*3)*CHARWIDTH)
  303. #define LINEHEIGHT 14
  304. #define TEXTHEIGHT 11
  305. static FILE *file;
  306. static void
  307. win32_outputdialog(struct uih_context *uih, CONST struct menuitem *item)
  308. {
  309. CONST menudialog *dialog;
  310. int leftsize = 0;
  311. int rightsize = 0;
  312. int width, height;
  313. int i;
  314. rightsize = INPUTSIZE;
  315. if (item->type != MENU_DIALOG && item->type != MENU_CUSTOMDIALOG)
  316. return;
  317. if (item->flags & MENUFLAG_NOMENU)
  318. return;
  319. dialog = menu_getdialog(uih, item);
  320. for (i = 0; dialog[i].question; i++) {
  321. if (leftsize < (int) strlen(dialog[i].question))
  322. leftsize = strlen(dialog[i].question);
  323. }
  324. if (i == 1
  325. && (dialog[0].type == DIALOG_IFILE
  326. || dialog[0].type == DIALOG_OFILE))
  327. return;
  328. leftsize = XBORDER + leftsize * CHARWIDTH + XSEP;
  329. rightsize = XBORDER + rightsize * CHARWIDTH;
  330. width = leftsize + rightsize;
  331. if (width < MINWIDTH)
  332. width = MINWIDTH;
  333. height = 2 * YBORDER + (i + 1) * LINEHEIGHT;
  334. fprintf(file, "%sBox DIALOG %i, %i, %i, %i\n", item->shortname, 52,
  335. 57, width, height);
  336. fprintf(file, "STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU\n");
  337. fprintf(file, "CAPTION \"%s\"\n", item->name);
  338. fprintf(file, "FONT 8, \"MS Shell Dlg\"\n");
  339. fprintf(file, "BEGIN\n");
  340. for (i = 0; dialog[i].question; i++) {
  341. fprintf(file, " RTEXT \"%s\", %i, %i, %i, %i, %i, WS_GROUP\n",
  342. dialog[i].question,
  343. i * PERITEM + QUESTIONSTART,
  344. 0, YBORDER + i * LINEHEIGHT, leftsize - XSEP, TEXTHEIGHT);
  345. switch (dialog[i].type) {
  346. case DIALOG_INT:
  347. case DIALOG_FLOAT:
  348. case DIALOG_STRING:
  349. case DIALOG_KEYSTRING:
  350. fprintf(file,
  351. " EDITTEXT %i, %i, %i, %i, %i, ES_AUTOHSCROLL | WS_TABSTOP\n",
  352. i * PERITEM + ITEMSTART, leftsize,
  353. i * LINEHEIGHT + YBORDER, rightsize - XSEP,
  354. TEXTHEIGHT);
  355. break;
  356. case DIALOG_COORD:
  357. fprintf(file,
  358. " EDITTEXT %i, %i, %i, %i, %i, ES_AUTOHSCROLL | WS_TABSTOP\n",
  359. i * PERITEM + ITEMSTART, leftsize,
  360. i * LINEHEIGHT + YBORDER,
  361. (rightsize - XSEP - 4 * CHARWIDTH) / 2, TEXTHEIGHT);
  362. fprintf(file,
  363. " EDITTEXT %i, %i, %i, %i, %i, ES_AUTOHSCROLL | WS_TABSTOP\n",
  364. i * PERITEM + ITEMSTART + 1,
  365. leftsize + (rightsize - XSEP + CHARWIDTH) / 2,
  366. i * LINEHEIGHT + YBORDER,
  367. (rightsize - XSEP - 4 * CHARWIDTH) / 2, TEXTHEIGHT);
  368. fprintf(file, " RTEXT \"+\", -1, %i, %i, %i, %i\n",
  369. leftsize + (rightsize - XSEP - 2 * CHARWIDTH) / 2,
  370. YBORDER + i * LINEHEIGHT, CHARWIDTH, TEXTHEIGHT);
  371. fprintf(file, " RTEXT \"i\", -1, %i, %i, %i, %i\n",
  372. leftsize + rightsize - XSEP - CHARWIDTH,
  373. YBORDER + i * LINEHEIGHT, CHARWIDTH, TEXTHEIGHT);
  374. break;
  375. case DIALOG_CHOICE:
  376. fprintf(file,
  377. " COMBOBOX %i, %i, %i, %i, %i, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\n",
  378. i * PERITEM + ITEMSTART, leftsize,
  379. i * LINEHEIGHT + YBORDER, rightsize - XSEP,
  380. TEXTHEIGHT * 10);
  381. break;
  382. case DIALOG_IFILE:
  383. case DIALOG_OFILE:
  384. #define BROWSEWIDTH ((strlen("Browse")+1)*CHARWIDTH)
  385. fprintf(file,
  386. " EDITTEXT %i, %i, %i, %i, %i, ES_AUTOHSCROLL | WS_TABSTOP\n",
  387. i * PERITEM + ITEMSTART, leftsize,
  388. i * LINEHEIGHT + YBORDER,
  389. rightsize - 2 * XSEP - BROWSEWIDTH, TEXTHEIGHT);
  390. fprintf(file,
  391. " PUSHBUTTON \"Browse\", %i, %i, %i, %i, %i, WS_GROUP\n",
  392. i * PERITEM + ITEMSTART + 1,
  393. leftsize + rightsize - XSEP - BROWSEWIDTH,
  394. i * LINEHEIGHT + YBORDER, BROWSEWIDTH, TEXTHEIGHT);
  395. break;
  396. }
  397. }
  398. fprintf(file,
  399. " DEFPUSHBUTTON \"&OK\", %i, %i, %i, %i, %i, WS_GROUP\n", OK,
  400. XSEP / 2, i * LINEHEIGHT + YBORDER, width / 3 - XSEP, 14);
  401. fprintf(file, " PUSHBUTTON \"&Cancel\", %i, %i, %i, %i, %i\n", CANCEL,
  402. width / 3 + XSEP / 2, i * LINEHEIGHT + YBORDER,
  403. width / 3 - XSEP, 14);
  404. fprintf(file, " PUSHBUTTON \"&Help\", %i, %i, %i, %i, %i\n", HELP,
  405. 2 * width / 3 + XSEP / 2, i * LINEHEIGHT + YBORDER,
  406. width / 3 - XSEP, 14);
  407. fprintf(file, "END\n");
  408. }
  409. void win32_genresources(struct uih_context *uih)
  410. {
  411. file = fopen("xaos.dlg", "w");
  412. menu_forall(uih, win32_outputdialog);
  413. fclose(file);
  414. }
  415. void win32_dialog(struct uih_context *uih, CONST char *name)
  416. {
  417. CONST menuitem *item = menu_findcommand(name);
  418. CONST menudialog *dialog;
  419. int nitems;
  420. char s[256];
  421. if (!item)
  422. return;
  423. dialog = menu_getdialog(uih, item);
  424. if (!dialog)
  425. return;
  426. for (nitems = 0; dialog[nitems].question; nitems++);
  427. if (nitems == 1
  428. && (dialog[0].type == DIALOG_IFILE
  429. || dialog[0].type == DIALOG_OFILE))
  430. win32_filedialog(uih, item, dialog);
  431. else {
  432. struct dialogrecord *r = calloc(sizeof(*r), 1);
  433. r->next = firstdialog;
  434. firstdialog = r;
  435. r->prev = NULL;
  436. r->item = item;
  437. r->nitems = nitems;
  438. r->dialog = dialog;
  439. r->c = uih;
  440. sprintf(s, "%sBox", item->shortname);
  441. if (DialogBox(hInstance, s, hWnd, DialogHandler) == -1) {
  442. /*r->windialog=CreateDialog (hInstance, s, hWnd, DialogHandler);
  443. if(r->windialog==NULL) { */
  444. x_message("Failed to create dialog %s", item->shortname);
  445. win32_freedialog(r);
  446. }
  447. win32_freedialog(r);
  448. /*x_message("Dialog (%s %i %s) not implemented", name, nitems, dialog[0].question); */
  449. }
  450. }