// Created 04-Jan-1993 1:10pm by Jeff Parsons #include "shellprv.h" #pragma hdrstop BINF abinfMem[] = { {IDC_HMA, BITNUM(MEMINIT_NOHMA) | 0x80}, {IDC_GLOBALPROTECT, BITNUM(MEMINIT_GLOBALPROTECT) }, }; VINF avinfMem[] = { {FIELD_OFFSET(PROPMEM,wMinLow), VINF_AUTOMINMAX, IDC_LOWMEM, MEMLOW_MIN, MEMLOW_MAX, IDS_BAD_MEMLOW}, {FIELD_OFFSET(PROPMEM,wMinEMS), VINF_AUTOMINMAX, IDC_EMSMEM, MEMEMS_MIN, MEMEMS_MAX, IDS_BAD_MEMEMS}, {FIELD_OFFSET(PROPMEM,wMinXMS), VINF_AUTOMINMAX, IDC_XMSMEM, MEMXMS_MIN, MEMXMS_MAX, IDS_BAD_MEMXMS}, }; VINF avinfEnvMem[] = { {FIELD_OFFSET(PROPENV,cbEnvironment), VINF_AUTO, IDC_ENVMEM, ENVSIZE_MIN, ENVSIZE_MAX, IDS_BAD_ENVIRONMENT}, {FIELD_OFFSET(PROPENV,wMaxDPMI), VINF_AUTO, IDC_DPMIMEM, ENVDPMI_MIN, ENVDPMI_MAX, IDS_BAD_MEMDPMI}, }; // Per-dialog data #define MEMINFO_RELAUNCH 0x0001 // relaunch required to take effect #define EMS_NOEMS 0x0001 // EMS no supported in protmode #define EMS_EMM386 0x0002 // EM386 is installed #define EMS_QEMM 0x0004 // Third-party mmgr installed #define EMS_RMPAGEFRAME 0x0008 // Page frame present in real mode #define EMS_SYSINIDISABLE 0x0010 // EMS forced off by system.ini typedef struct MEMINFO { /* mi */ PPROPLINK ppl; // pointer to property info DWORD flMemInfo; // initially zero thx to LocalAlloc(LPTR) DWORD flEms; // EMS support flags } MEMINFO; typedef MEMINFO *PMEMINFO; /* pmi */ // Private function prototypes BOOL GetSetMemProps(HWND hDlg, GETSETFN lpfn, PPROPLINK ppl, LPPROPMEM lpmem, LPPROPENV lpenv, int idError); void InitMemDlg(HWND hDlg, PMEMINFO pmi); void ApplyMemDlg(HWND hDlg, PMEMINFO pmi); void AdjustEmsControls(HWND hDlg, PMEMINFO pmi); void ExplainNoEms(HWND hDlg, PMEMINFO pmi); // Context-sensitive help ids const static DWORD rgdwHelp[] = { IDC_CONVMEMLBL, IDH_DOS_MEMORY_CONV, IDC_LOWMEM, IDH_DOS_MEMORY_CONV, IDC_GLOBALPROTECT, IDH_DOS_MEMORY_CONV_GLOBAL, IDC_EXPMEMGRP, IDH_COMM_GROUPBOX, IDC_EXPMEMLBL, IDH_DOS_MEMORY_EXP, IDC_EMSMEM, IDH_DOS_MEMORY_EXP, IDC_EXTMEMGRP, IDH_COMM_GROUPBOX, IDC_XMSMEM, IDH_DOS_MEMORY_EXT, IDC_EXTMEMLBL, IDH_DOS_MEMORY_EXT, IDC_DPMIMEMGRP, IDH_COMM_GROUPBOX, IDC_DPMIMEM, IDH_DOS_MEMORY_DPMI, IDC_DPMIMEMLBL, IDH_DOS_MEMORY_DPMI, IDC_HMA, IDH_DOS_MEMORY_EXT_HMA, IDC_CONVMEMGRP, IDH_COMM_GROUPBOX, IDC_LOCALENVLBL, IDH_DOS_PROGRAM_ENVIRSZ, IDC_ENVMEM, IDH_DOS_PROGRAM_ENVIRSZ, IDC_REALMODEDISABLE, IDH_DOS_REALMODEPROPS, IDC_NOEMSDETAILS, IDH_DOS_MEMORY_NOEMS_DETAILS, 0, 0 }; BOOL_PTR CALLBACK DlgMemProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fError; PMEMINFO pmi; FunctionName(DlgMemProc); pmi = (PMEMINFO)GetWindowLongPtr(hDlg, DWLP_USER); switch (uMsg) { case WM_INITDIALOG: // allocate dialog instance data if (NULL != (pmi = (PMEMINFO)LocalAlloc(LPTR, SIZEOF(MEMINFO)))) { pmi->ppl = (PPROPLINK)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pmi); InitMemDlg(hDlg, pmi); } else { EndDialog(hDlg, FALSE); // fail the dialog create } break; case WM_DESTROY: // free the pmi if (pmi) { EVAL(LocalFree(pmi) == NULL); SetWindowLongPtr(hDlg, DWLP_USER, 0); } break; HELP_CASES(rgdwHelp) // Handle help messages case WM_COMMAND: if (LOWORD(lParam) == 0) break; // message not from a control switch (LOWORD(wParam)) { case IDC_ENVMEM: case IDC_LOWMEM: case IDC_EMSMEM: case IDC_XMSMEM: case IDC_DPMIMEM: if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE) { SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L); pmi->flMemInfo |= MEMINFO_RELAUNCH; } break; case IDC_HMA: case IDC_GLOBALPROTECT: if (HIWORD(wParam) == BN_CLICKED) { SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L); if (LOWORD(wParam) != IDC_GLOBALPROTECT) pmi->flMemInfo |= MEMINFO_RELAUNCH; } break; case IDC_NOEMSDETAILS: if (HIWORD(wParam) == BN_CLICKED) { ExplainNoEms(hDlg, pmi); } return FALSE; // return 0 if we process WM_COMMAND } break; case WM_NOTIFY: switch (((NMHDR *)lParam)->code) { case PSN_SETACTIVE: AdjustRealModeControls(pmi->ppl, hDlg); AdjustEmsControls(hDlg, pmi); // make sure DWL_MSGRESULT is zero, // otherwise the prsht code thinks we // "failed" this notify and switches // to another (sometimes random) page -JTP SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); break; case PSN_KILLACTIVE: // This gives the current page a chance to validate itself fError = ValidateDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem)); fError |= ValidateDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem)); SetWindowLongPtr(hDlg, DWLP_MSGRESULT, fError); break; case PSN_APPLY: // This happens on OK.... ApplyMemDlg(hDlg, pmi); break; case PSN_RESET: // This happens on Cancel.... break; } break; default: return FALSE; // return 0 when not processing } return TRUE; } BOOL GetSetMemProps(HWND hDlg, GETSETFN lpfn, PPROPLINK ppl, LPPROPMEM lpmem, LPPROPENV lpenv, int idError) { if (!(*lpfn)(ppl, MAKELP(0,GROUP_MEM), lpmem, SIZEOF(*lpmem), GETPROPS_NONE) || !(*lpfn)(ppl, MAKELP(0,GROUP_ENV), lpenv, SIZEOF(*lpenv), GETPROPS_NONE)) { Warning(hDlg, (WORD)idError, (WORD)MB_ICONEXCLAMATION | MB_OK); return FALSE; } return TRUE; } void InitMemDlg(HWND hDlg, PMEMINFO pmi) { PROPMEM mem; PROPENV env; PPROPLINK ppl = pmi->ppl; FunctionName(InitMemDlg); if (!GetSetMemProps(hDlg, PifMgr_GetProperties, ppl, &mem, &env, IDS_QUERY_ERROR)) return; SetDlgBits(hDlg, abinfMem, ARRAYSIZE(abinfMem), mem.flMemInit); SetDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem), (LPVOID)&mem); SetDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem), (LPVOID)&env); /* Disallow "None" as a valid setting for "Conventional memory" */ SendDlgItemMessage(hDlg, IDC_LOWMEM, CB_DELETESTRING, (WPARAM)SendDlgItemMessage(hDlg, IDC_LOWMEM, CB_FINDSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)g_szNone), 0L); pmi->flEms = (EMS_EMM386 | EMS_RMPAGEFRAME); AdjustEmsControls(hDlg, pmi); } void ApplyMemDlg(HWND hDlg, PMEMINFO pmi) { PROPMEM mem; PROPENV env; PPROPLINK ppl = pmi->ppl; FunctionName(ApplyMemDlg); if (!GetSetMemProps(hDlg, PifMgr_GetProperties, ppl, &mem, &env, IDS_UPDATE_ERROR)) return; GetDlgBits(hDlg, abinfMem, ARRAYSIZE(abinfMem), &mem.flMemInit); GetDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem), (LPVOID)&mem); GetDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem), (LPVOID)&env); if (GetSetMemProps(hDlg, PifMgr_SetProperties, ppl, &mem, &env, IDS_UPDATE_ERROR)) { if (ppl->hwndNotify) { ppl->flProp |= PROP_NOTIFY; PostMessage(ppl->hwndNotify, ppl->uMsgNotify, SIZEOF(mem), (LPARAM)MAKELP(0,GROUP_MEM)); PostMessage(ppl->hwndNotify, ppl->uMsgNotify, SIZEOF(env), (LPARAM)MAKELP(0,GROUP_ENV)); } if (ppl->hVM && (pmi->flMemInfo & MEMINFO_RELAUNCH)) { pmi->flMemInfo &= ~MEMINFO_RELAUNCH; Warning(hDlg, IDS_MEMORY_RELAUNCH, MB_ICONWARNING | MB_OK); } } } void HideAndDisable(HWND hwnd) { ShowWindow(hwnd, SW_HIDE); EnableWindow(hwnd, FALSE); } void AdjustEmsControls(HWND hDlg, PMEMINFO pmi) { if (!(pmi->ppl->flProp & PROP_REALMODE)) { /* * When not marked as PROP_REALMODE, all the EMS-related controls * are visible. We need to choose which set to disable. * * We cheat, because we know that there are only two controls * in both cases, and they come right after each other. */ UINT uiHide; if (pmi->flEms & EMS_NOEMS) { uiHide = IDC_EXPMEMLBL; CTASSERTF(IDC_EXPMEMLBL + 1 == IDC_EMSMEM); } else { uiHide = IDC_NOEMS; CTASSERTF(IDC_NOEMS + 1 == IDC_NOEMSDETAILS); } HideAndDisable(GetDlgItem(hDlg, uiHide)); HideAndDisable(GetDlgItem(hDlg, uiHide+1)); } } void ExplainNoEms(HWND hDlg, PMEMINFO pmi) { WORD idsHelp; TCHAR szMsg[MAX_STRING_SIZE]; /* * Here is where we stare at all the bits to try to figure * out what recommendation to make. */ ASSERTTRUE(pmi->flEms & EMS_NOEMS); if (pmi->flEms & EMS_SYSINIDISABLE) { /* * System.ini contains the line NOEMMDRIVER=1. */ idsHelp = IDS_SYSINI_NOEMS; } else if (pmi->flEms & EMS_RMPAGEFRAME) { /* * Had page-frame in real mode, which means that some protmode * guy must've messed it up. */ idsHelp = IDS_RING0_NOEMS; } else if (pmi->flEms & EMS_EMM386) { /* * No page-frame in real mode, and EMM386 was in charge, * so it's EMM386's fault. */ idsHelp = IDS_EMM386_NOEMS; } else { /* * No page-frame in real mode, and QEMM was in charge, * so it's QEMM's fault. */ idsHelp = IDS_QEMM_NOEMS; } if (LoadStringSafe(hDlg, idsHelp+1, szMsg, ARRAYSIZE(szMsg))) { Warning(hDlg, idsHelp, MB_OK, (LPCTSTR)szMsg); } }