/* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM * PC systems and compatibles from 1981 through fairly recent * system designs based on the PCI bus. * * This file is part of the 86Box distribution. * * Several dialogs for the application. * * * * Author: Miran Grca, * Fred N. van Kempen, * * Copyright 2016-2019 Miran Grca. * Copyright 2017-2019 Fred N. van Kempen. */ #define UNICODE #include #include #include #include #include #include #include #include #include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/win.h> #define STRING_OR_RESOURCE(s) ((!(s)) ? (NULL) : ((((uintptr_t)s) < ((uintptr_t)65636)) ? (MAKEINTRESOURCE((uintptr_t)s)) : (s))) WCHAR wopenfilestring[512]; char openfilestring[512]; uint8_t filterindex = 0; int ui_msgbox(int flags, void *message) { return ui_msgbox_ex(flags, NULL, message, NULL, NULL, NULL); } int ui_msgbox_header(int flags, void *header, void *message) { return ui_msgbox_ex(flags, header, message, NULL, NULL, NULL); } int ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) { WCHAR temp[512]; TASKDIALOGCONFIG tdconfig = {0}; TASKDIALOG_BUTTON tdbuttons[3], tdb_yes = {IDYES, STRING_OR_RESOURCE(btn1)}, tdb_no = {IDNO, STRING_OR_RESOURCE(btn2)}, tdb_cancel = {IDCANCEL, STRING_OR_RESOURCE(btn3)}, tdb_exit = {IDCLOSE, MAKEINTRESOURCE(IDS_2119)}; int ret = 0, checked = 0; /* Configure the default OK button. */ tdconfig.cButtons = 0; if (btn1) tdbuttons[tdconfig.cButtons++] = tdb_yes; else tdconfig.dwCommonButtons = TDCBF_OK_BUTTON; /* Configure the message type. */ switch(flags & 0x1f) { case MBX_INFO: /* just an informational message */ tdconfig.pszMainIcon = TD_INFORMATION_ICON; break; case MBX_ERROR: /* error message */ if (flags & MBX_FATAL) { tdconfig.pszMainIcon = TD_ERROR_ICON; tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); /* "Fatal error" */ /* replace default "OK" button with "Exit" button */ if (btn1) tdconfig.cButtons = 0; else tdconfig.dwCommonButtons = 0; tdbuttons[tdconfig.cButtons++] = tdb_exit; } else { tdconfig.pszMainIcon = TD_WARNING_ICON; tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2049); /* "Error" */ } break; case MBX_QUESTION: /* question */ case MBX_QUESTION_YN: case MBX_QUESTION_OK: if (!btn1) /* replace default "OK" button with "Yes" button */ tdconfig.dwCommonButtons = (flags & MBX_QUESTION_OK) ? TDCBF_OK_BUTTON : TDCBF_YES_BUTTON; if (btn2) /* "No" button */ tdbuttons[tdconfig.cButtons++] = tdb_no; else tdconfig.dwCommonButtons |= (flags & MBX_QUESTION_OK) ? TDCBF_CANCEL_BUTTON : TDCBF_NO_BUTTON; if (flags & MBX_QUESTION) { if (btn3) /* "Cancel" button */ tdbuttons[tdconfig.cButtons++] = tdb_cancel; else tdconfig.dwCommonButtons |= TDCBF_CANCEL_BUTTON; } if (flags & MBX_WARNING) tdconfig.pszMainIcon = TD_WARNING_ICON; break; } /* If the message is an ANSI string, convert it. */ tdconfig.pszContent = (WCHAR *) STRING_OR_RESOURCE(message); if (flags & MBX_ANSI) { mbstoc16s(temp, (char *)message, strlen((char *)message)+1); tdconfig.pszContent = temp; } /* Configure the rest of the TaskDialog. */ tdconfig.cbSize = sizeof(tdconfig); tdconfig.hwndParent = hwndMain; if (flags & MBX_LINKS) tdconfig.dwFlags = TDF_USE_COMMAND_LINKS; tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); if (header) tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header); tdconfig.pButtons = tdbuttons; if (flags & MBX_DONTASK) tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2135); /* Run the TaskDialog. */ TaskDialogIndirect(&tdconfig, &ret, NULL, &checked); /* Convert return values to generic ones. */ if (ret == IDNO) ret = 1; else if (ret == IDCANCEL) ret = -1; else ret = 0; /* 10 is added to the return value if "don't show again" is checked. */ if (checked) ret += 10; return(ret); } int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save) { OPENFILENAME ofn; BOOL r; /* DWORD err; */ int old_dopause; /* Initialize OPENFILENAME */ ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFile = wopenfilestring; /* * Set lpstrFile[0] to '\0' so that GetOpenFileName does * not use the contents of szFile to initialize itself. */ memset(ofn.lpstrFile, 0x00, 512 * sizeof(WCHAR)); memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); ofn.nMaxFile = sizeof_w(wopenfilestring); ofn.lpstrFilter = f; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST; if (! save) ofn.Flags |= OFN_FILEMUSTEXIST; if (title) ofn.lpstrTitle = title; /* Display the Open dialog box. */ old_dopause = dopause; plat_pause(1); if (save) r = GetSaveFileName(&ofn); else r = GetOpenFileName(&ofn); plat_pause(old_dopause); plat_chdir(usr_path); if (r) { c16stombs(openfilestring, wopenfilestring, sizeof(openfilestring)); filterindex = ofn.nFilterIndex; return(0); } return(1); } int file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save) { WCHAR ufn[512], title_buf[512]; mbstoc16s(ufn, fn, strlen(fn) + 1); if (title) mbstoc16s(title_buf, title, sizeof title_buf); return(file_dlg_w(hwnd, f, ufn, title ? title_buf : NULL, save)); } int file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save) { WCHAR uf[512], ufn[512], title_buf[512]; mbstoc16s(uf, f, strlen(f) + 1); mbstoc16s(ufn, fn, strlen(fn) + 1); if (title) mbstoc16s(title_buf, title, sizeof title_buf); return(file_dlg_w(hwnd, uf, ufn, title ? title_buf : NULL, save)); } int file_dlg_w_st(HWND hwnd, int id, WCHAR *fn, char *title, int save) { WCHAR title_buf[512]; if (title) mbstoc16s(title_buf, title, sizeof title_buf); return(file_dlg_w(hwnd, plat_get_string(id), fn, title ? title_buf : NULL, save)); } int file_dlg_st(HWND hwnd, int id, char *fn, char *title, int save) { return(file_dlg(hwnd, plat_get_string(id), fn, title, save)); }