/* * PROJECT: ReactOS Applications * LICENSE: LGPL - See COPYING in the top level directory * FILE: base/applications/msconfig_new/msconfig.c * PURPOSE: MSConfig main dialog * COPYRIGHT: Copyright 2005-2006 Christoph von Wittich */ #include "precomp.h" #include "fileutils.h" #include "utils.h" #include "generalpage.h" #include "systempage.h" #include "freeldrpage.h" #include "srvpage.h" // #include "startuppage.h" #include "toolspage.h" /* Allow only for a single instance of MSConfig */ #ifdef _MSC_VER #pragma data_seg("MSConfigInstance") HWND hSingleWnd = NULL; #pragma data_seg() #pragma comment(linker, "/SECTION:MSConfigInstance,RWS") #else HWND hSingleWnd __attribute__((section ("MSConfigInstance"), shared)) = NULL; #endif /* Defaults for ReactOS */ BOOL bIsWindows = FALSE; BOOL bIsPreVistaOSVersion = TRUE; /* Language-independent Vendor strings */ const LPCWSTR IDS_REACTOS = L"ReactOS"; const LPCWSTR IDS_MICROSOFT = L"Microsoft"; const LPCWSTR IDS_WINDOWS = L"Windows"; HINSTANCE hInst = NULL; LPWSTR szAppName = NULL; HWND hMainWnd; /* Main Window */ HWND hTabWnd; /* Tab Control Window */ HICON hIcon = NULL, hIconSm = NULL; WNDPROC wpOrigEditProc = NULL; /* About Box dialog */ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } /* Message handler for dialog box */ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) { switch (uMessage) { case WM_SYSCOMMAND: { switch (LOWORD(wParam) /*GET_WM_COMMAND_ID(wParam, lParam)*/) { case IDM_ABOUT: DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_ABOUTBOX), hWnd, About); // break; return TRUE; } // break; return FALSE; } case WM_COMMAND: { switch (LOWORD(wParam) /*GET_WM_COMMAND_ID(wParam, lParam)*/) { case IDM_ABOUT: DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_ABOUTBOX), hWnd, About); // break; return TRUE; } break; // return FALSE; } case WM_DESTROY: { if (wpOrigEditProc) SetWindowLongPtr(hWnd, DWLP_DLGPROC, (LONG_PTR)wpOrigEditProc); if (hIcon) DestroyIcon(hIcon); if (hIconSm) DestroyIcon(hIconSm); } default: break; } /* Return */ if (wpOrigEditProc) return CallWindowProc(wpOrigEditProc, hWnd, uMessage, wParam, lParam); else return FALSE; } #include typedef struct DLGTEMPLATEEX { WORD dlgVer; WORD signature; DWORD helpID; DWORD exStyle; DWORD style; WORD cDlgItems; short x; short y; short cx; short cy; } DLGTEMPLATEEX, *LPDLGTEMPLATEEX; #include int CALLBACK PropSheetCallback(HWND hDlg, UINT message, LPARAM lParam) { switch (message) { case PSCB_PRECREATE: { LPDLGTEMPLATE dlgTemplate = (LPDLGTEMPLATE)lParam; LPDLGTEMPLATEEX dlgTemplateEx = (LPDLGTEMPLATEEX)lParam; // MFC : DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION; DWORD style = DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU; // DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; DWORD exStyle = WS_EX_CONTROLPARENT | WS_EX_APPWINDOW; /* Hide the dialog by default; we will center it on screen later, and then show it */ style &= ~WS_VISIBLE; /* Set the styles of the property sheet dialog */ if (dlgTemplateEx->signature == 0xFFFF) { dlgTemplateEx->style = style; dlgTemplateEx->exStyle = exStyle; } else { dlgTemplate->style = style; dlgTemplate->dwExtendedStyle = exStyle; } break; } case PSCB_INITIALIZED: { /* Customize the window's system menu, add items before the "Close" item */ LPWSTR szMenuString; HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); assert(hSysMenu); szMenuString = LoadResourceString(hInst, IDS_ABOUT); if (szMenuString) { /* "About" menu */ InsertMenuW(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED | MF_STRING, IDM_ABOUT, szMenuString); /* Separator */ InsertMenuW(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_SEPARATOR , 0 , NULL); MemFree(szMenuString); } DrawMenuBar(hDlg); /* Set the dialog icons */ hIcon = (HICON)LoadImageW(hInst, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE); hIconSm = (HICON)CopyImage(hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE); SendMessageW(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); SendMessageW(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); /* Sub-class the property sheet window procedure */ wpOrigEditProc = (WNDPROC)SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LONG_PTR)MainWndProc); break; } default: break; } return FALSE; } HWND CreatePropSheet(HINSTANCE hInstance, HWND hwndOwner, LPCTSTR lpszTitle) { HWND hPropSheet; PROPSHEETHEADERW psh; PROPSHEETPAGEW psp[7]; unsigned int nPages = 0; /* Header */ psh.dwSize = sizeof(psh); psh.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS | /*PSH_USEICONID |*/ PSH_HASHELP | /*PSH_NOCONTEXTHELP |*/ PSH_USECALLBACK; psh.hInstance = hInstance; psh.hwndParent = hwndOwner; // psh.pszIcon = MAKEINTRESOURCEW(IDI_APPICON); // Disabled because it only sets the small icon; the big icon is a stretched version of the small one. psh.pszCaption = lpszTitle; psh.nStartPage = 0; psh.ppsp = psp; psh.pfnCallback = PropSheetCallback; /* General page */ psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP; psp[nPages].hInstance = hInstance; psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_GENERAL_PAGE); psp[nPages].pfnDlgProc = GeneralPageWndProc; ++nPages; // if (bIsPreVistaOSVersion) { /* SYSTEM.INI page */ if (MyFileExists(lpszSystemIni, NULL)) { psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP | PSP_USETITLE; psp[nPages].hInstance = hInstance; psp[nPages].pszTitle = MAKEINTRESOURCEW(IDS_TAB_SYSTEM); psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_SYSTEM_PAGE); psp[nPages].pfnDlgProc = SystemPageWndProc; psp[nPages].lParam = (LPARAM)lpszSystemIni; ++nPages; BackupIniFile(lpszSystemIni); } /* WIN.INI page */ if (MyFileExists(lpszWinIni, NULL)) { psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP | PSP_USETITLE; psp[nPages].hInstance = hInstance; psp[nPages].pszTitle = MAKEINTRESOURCEW(IDS_TAB_WIN); psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_SYSTEM_PAGE); psp[nPages].pfnDlgProc = WinPageWndProc; psp[nPages].lParam = (LPARAM)lpszWinIni; ++nPages; BackupIniFile(lpszWinIni); } } /* FreeLdr page */ // TODO: Program the interface for Vista: "light" BCD editor... if (!bIsWindows || (bIsWindows && bIsPreVistaOSVersion)) { LPCWSTR lpszLoaderIniFile = NULL; DWORD dwTabNameId = 0; if (bIsWindows) { lpszLoaderIniFile = lpszBootIni; dwTabNameId = IDS_TAB_BOOT; } else { lpszLoaderIniFile = lpszFreeLdrIni; dwTabNameId = IDS_TAB_FREELDR; } if (MyFileExists(lpszLoaderIniFile, NULL)) { psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP | PSP_USETITLE; psp[nPages].hInstance = hInstance; psp[nPages].pszTitle = MAKEINTRESOURCEW(dwTabNameId); psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_FREELDR_PAGE); psp[nPages].pfnDlgProc = FreeLdrPageWndProc; psp[nPages].lParam = (LPARAM)lpszLoaderIniFile; ++nPages; BackupIniFile(lpszLoaderIniFile); } } /* Services page */ psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP; psp[nPages].hInstance = hInstance; psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_SERVICES_PAGE); psp[nPages].pfnDlgProc = ServicesPageWndProc; ++nPages; #if 0 /* Startup page */ psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP; psp[nPages].hInstance = hInstance; psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_STARTUP_PAGE); psp[nPages].pfnDlgProc = StartupPageWndProc; ++nPages; #endif /* Tools page */ psp[nPages].dwSize = sizeof(PROPSHEETPAGEW); psp[nPages].dwFlags = PSP_HASHELP; psp[nPages].hInstance = hInstance; psp[nPages].pszTemplate = MAKEINTRESOURCEW(IDD_TOOLS_PAGE); psp[nPages].pfnDlgProc = ToolsPageWndProc; ++nPages; /* Set the total number of created pages */ psh.nPages = nPages; /* Create the property sheet */ hPropSheet = (HWND)PropertySheetW(&psh); if (hPropSheet) { /* Center the property sheet on the desktop and show it */ ClipOrCenterWindowToMonitor(hPropSheet, MONITOR_WORKAREA | MONITOR_CENTER); ShowWindow(hPropSheet, SW_SHOWNORMAL); } return hPropSheet; } BOOL Initialize(HINSTANCE hInstance) { BOOL Success = TRUE; LPWSTR lpszVistaAppName = NULL; HANDLE hSemaphore; INITCOMMONCONTROLSEX InitControls; /* Initialize our global version flags */ bIsWindows = IsWindowsOS(); bIsPreVistaOSVersion = IsPreVistaOSVersion(); /* Initialize global strings */ szAppName = LoadResourceString(hInstance, IDS_MSCONFIG); if (!bIsPreVistaOSVersion) lpszVistaAppName = LoadResourceString(hInstance, IDS_MSCONFIG_2); /* We use a semaphore in order to have a single-instance application */ hSemaphore = CreateSemaphoreW(NULL, 0, 1, L"MSConfigRunning"); if (!hSemaphore || GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hSemaphore); /* * A semaphore with the same name already exist. It should have been * created by another instance of MSConfig. Try to find its window * and bring it to front. */ if ( (hSingleWnd && IsWindow(hSingleWnd)) || ( (hSingleWnd = FindWindowW(L"#32770", szAppName)) != NULL ) || (!bIsPreVistaOSVersion ? ( (hSingleWnd = FindWindowW(L"#32770", lpszVistaAppName)) != NULL ) : FALSE) ) { /* Found it. Show the window. */ ShowWindow(hSingleWnd, SW_SHOWNORMAL); SetForegroundWindow(hSingleWnd); } /* Quit this instance of MSConfig */ Success = FALSE; } if (!bIsPreVistaOSVersion) MemFree(lpszVistaAppName); /* Quit now if we failed */ if (!Success) { MemFree(szAppName); return FALSE; } /* Initialize the common controls */ InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX); InitControls.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS /* | ICC_PROGRESS_CLASS | ICC_HOTKEY_CLASS*/; InitCommonControlsEx(&InitControls); hInst = hInstance; return Success; } VOID Cleanup(VOID) { MemFree(szAppName); // // Close the sentry semaphore. // CloseHandle(hSemaphore); } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MSG msg; HACCEL hAccelTable; UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); /* * Initialize this instance of MSConfig. Quit if we have * another instance already running. */ if (!Initialize(hInstance)) return -1; // hInst = hInstance; hMainWnd = CreatePropSheet(hInstance, NULL, szAppName); if (!hMainWnd) { /* We failed, cleanup and bail out */ Cleanup(); return -1; } hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_MSCONFIG)); /* Message loop */ while (IsWindow(hMainWnd) && GetMessageW(&msg, NULL, 0, 0)) { /* * PropSheet_GetCurrentPageHwnd returns NULL when the user clicks the OK or Cancel button * and after all of the pages have been notified. Apply button doesn't cause this to happen. * We can then use the DestroyWindow function to destroy the property sheet. */ if (PropSheet_GetCurrentPageHwnd(hMainWnd) == NULL) break; /* Process the accelerator table */ if (!TranslateAcceleratorW(hMainWnd, hAccelTable, &msg)) { /* * If e.g. an item on the tree view is being edited, * we cannot pass the event to PropSheet_IsDialogMessage. * Doing so causes the property sheet to be closed at Enter press * (instead of completing edit operation). */ if (/*g_bDisableDialogDispatch ||*/ !PropSheet_IsDialogMessage(hMainWnd, &msg)) { TranslateMessage(&msg); DispatchMessageW(&msg); } } } // FIXME: Process the results of MSConfig !! /* Destroy the accelerator table and the window */ if (hAccelTable != NULL) DestroyAcceleratorTable(hAccelTable); DestroyWindow(hMainWnd); /* Finish cleanup and return */ Cleanup(); return (int)msg.wParam; } /* EOF */