254 lines
6.6 KiB
C
254 lines
6.6 KiB
C
/*
|
|
* 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, <mgrca8@gmail.com>
|
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
|
*
|
|
* Copyright 2016-2019 Miran Grca.
|
|
* Copyright 2017-2019 Fred N. van Kempen.
|
|
*/
|
|
#define UNICODE
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <shlobj.h>
|
|
#include <commdlg.h>
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <wchar.h>
|
|
#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));
|
|
}
|