2 * PROJECT: ReactOS Applications
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/msconfig_new/msconfig.c
5 * PURPOSE: MSConfig main dialog
6 * COPYRIGHT: Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
10 #include "fileutils.h"
13 #include "generalpage.h"
14 #include "systempage.h"
15 #include "freeldrpage.h"
17 // #include "startuppage.h"
18 #include "toolspage.h"
20 /* Allow only for a single instance of MSConfig */
22 #pragma data_seg("MSConfigInstance")
23 HWND hSingleWnd
= NULL
;
25 #pragma comment(linker, "/SECTION:MSConfigInstance,RWS")
27 HWND hSingleWnd
__attribute__((section ("MSConfigInstance"), shared
)) = NULL
;
30 /* Defaults for ReactOS */
31 BOOL bIsWindows
= FALSE
;
32 BOOL bIsPreVistaOSVersion
= TRUE
;
34 /* Language-independent Vendor strings */
35 const LPCWSTR IDS_REACTOS
= L
"ReactOS";
36 const LPCWSTR IDS_MICROSOFT
= L
"Microsoft";
37 const LPCWSTR IDS_WINDOWS
= L
"Windows";
39 HINSTANCE hInst
= NULL
;
40 LPWSTR szAppName
= NULL
;
41 HWND hMainWnd
; /* Main Window */
43 HWND hTabWnd
; /* Tab Control Window */
44 HICON hIcon
= NULL
, hIconSm
= NULL
;
45 WNDPROC wpOrigEditProc
= NULL
;
48 /* About Box dialog */
49 INT_PTR CALLBACK
About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
51 UNREFERENCED_PARAMETER(lParam
);
58 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
60 EndDialog(hDlg
, LOWORD(wParam
));
65 return (INT_PTR
)FALSE
;
69 /* Message handler for dialog box */
70 LRESULT CALLBACK
MainWndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
76 switch (LOWORD(wParam
) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
79 DialogBoxW(hInst
, MAKEINTRESOURCEW(IDD_ABOUTBOX
), hWnd
, About
);
90 switch (LOWORD(wParam
) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
93 DialogBoxW(hInst
, MAKEINTRESOURCEW(IDD_ABOUTBOX
), hWnd
, About
);
105 SetWindowLongPtr(hWnd
, DWLP_DLGPROC
, (LONG_PTR
)wpOrigEditProc
);
107 if (hIcon
) DestroyIcon(hIcon
);
108 if (hIconSm
) DestroyIcon(hIconSm
);
117 return CallWindowProc(wpOrigEditProc
, hWnd
, uMessage
, wParam
, lParam
);
123 #include <pshpack1.h>
124 typedef struct DLGTEMPLATEEX
136 } DLGTEMPLATEEX
, *LPDLGTEMPLATEEX
;
139 int CALLBACK
PropSheetCallback(HWND hDlg
, UINT message
, LPARAM lParam
)
145 LPDLGTEMPLATE dlgTemplate
= (LPDLGTEMPLATE
)lParam
;
146 LPDLGTEMPLATEEX dlgTemplateEx
= (LPDLGTEMPLATEEX
)lParam
;
148 // MFC : DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION;
149 DWORD style
= DS_SHELLFONT
| DS_MODALFRAME
| DS_CENTER
| WS_MINIMIZEBOX
| WS_POPUP
| WS_VISIBLE
| WS_CAPTION
| WS_SYSMENU
;
150 // DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
151 DWORD exStyle
= WS_EX_CONTROLPARENT
| WS_EX_APPWINDOW
;
153 /* Hide the dialog by default; we will center it on screen later, and then show it */
154 style
&= ~WS_VISIBLE
;
156 /* Set the styles of the property sheet dialog */
157 if (dlgTemplateEx
->signature
== 0xFFFF)
159 dlgTemplateEx
->style
= style
;
160 dlgTemplateEx
->exStyle
= exStyle
;
164 dlgTemplate
->style
= style
;
165 dlgTemplate
->dwExtendedStyle
= exStyle
;
171 case PSCB_INITIALIZED
:
173 /* Customize the window's system menu, add items before the "Close" item */
175 HMENU hSysMenu
= GetSystemMenu(hDlg
, FALSE
);
178 szMenuString
= LoadResourceString(hInst
, IDS_ABOUT
);
182 InsertMenuW(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_ENABLED
| MF_STRING
, IDM_ABOUT
, szMenuString
);
184 InsertMenuW(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_SEPARATOR
, 0 , NULL
);
186 MemFree(szMenuString
);
190 /* Set the dialog icons */
191 hIcon
= (HICON
)LoadImageW(hInst
, MAKEINTRESOURCEW(IDI_APPICON
), IMAGE_ICON
, 0, 0, LR_SHARED
| LR_DEFAULTSIZE
);
192 hIconSm
= (HICON
)CopyImage(hIcon
, IMAGE_ICON
, GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), LR_COPYFROMRESOURCE
);
193 SendMessageW(hDlg
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
194 SendMessageW(hDlg
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIconSm
);
196 /* Sub-class the property sheet window procedure */
197 wpOrigEditProc
= (WNDPROC
)SetWindowLongPtr(hDlg
, DWLP_DLGPROC
, (LONG_PTR
)MainWndProc
);
209 HWND
CreatePropSheet(HINSTANCE hInstance
, HWND hwndOwner
, LPCTSTR lpszTitle
)
212 PROPSHEETHEADERW psh
;
213 PROPSHEETPAGEW psp
[7];
214 unsigned int nPages
= 0;
217 psh
.dwSize
= sizeof(psh
);
218 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
| /*PSH_USEICONID |*/ PSH_HASHELP
| /*PSH_NOCONTEXTHELP |*/ PSH_USECALLBACK
;
219 psh
.hInstance
= hInstance
;
220 psh
.hwndParent
= hwndOwner
;
221 // psh.pszIcon = MAKEINTRESOURCEW(IDI_APPICON); // Disabled because it only sets the small icon; the big icon is a stretched version of the small one.
222 psh
.pszCaption
= lpszTitle
;
225 psh
.pfnCallback
= PropSheetCallback
;
228 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
229 psp
[nPages
].dwFlags
= PSP_HASHELP
;
230 psp
[nPages
].hInstance
= hInstance
;
231 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_GENERAL_PAGE
);
232 psp
[nPages
].pfnDlgProc
= GeneralPageWndProc
;
235 // if (bIsPreVistaOSVersion)
237 /* SYSTEM.INI page */
238 if (MyFileExists(lpszSystemIni
, NULL
))
240 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
241 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
242 psp
[nPages
].hInstance
= hInstance
;
243 psp
[nPages
].pszTitle
= MAKEINTRESOURCEW(IDS_TAB_SYSTEM
);
244 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_SYSTEM_PAGE
);
245 psp
[nPages
].pfnDlgProc
= SystemPageWndProc
;
246 psp
[nPages
].lParam
= (LPARAM
)lpszSystemIni
;
249 BackupIniFile(lpszSystemIni
);
253 if (MyFileExists(lpszWinIni
, NULL
))
255 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
256 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
257 psp
[nPages
].hInstance
= hInstance
;
258 psp
[nPages
].pszTitle
= MAKEINTRESOURCEW(IDS_TAB_WIN
);
259 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_SYSTEM_PAGE
);
260 psp
[nPages
].pfnDlgProc
= WinPageWndProc
;
261 psp
[nPages
].lParam
= (LPARAM
)lpszWinIni
;
264 BackupIniFile(lpszWinIni
);
269 // TODO: Program the interface for Vista: "light" BCD editor...
270 if (!bIsWindows
|| (bIsWindows
&& bIsPreVistaOSVersion
))
272 LPCWSTR lpszLoaderIniFile
= NULL
;
273 DWORD dwTabNameId
= 0;
276 lpszLoaderIniFile
= lpszBootIni
;
277 dwTabNameId
= IDS_TAB_BOOT
;
281 lpszLoaderIniFile
= lpszFreeLdrIni
;
282 dwTabNameId
= IDS_TAB_FREELDR
;
285 if (MyFileExists(lpszLoaderIniFile
, NULL
))
287 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
288 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
289 psp
[nPages
].hInstance
= hInstance
;
290 psp
[nPages
].pszTitle
= MAKEINTRESOURCEW(dwTabNameId
);
291 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_FREELDR_PAGE
);
292 psp
[nPages
].pfnDlgProc
= FreeLdrPageWndProc
;
293 psp
[nPages
].lParam
= (LPARAM
)lpszLoaderIniFile
;
296 BackupIniFile(lpszLoaderIniFile
);
301 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
302 psp
[nPages
].dwFlags
= PSP_HASHELP
;
303 psp
[nPages
].hInstance
= hInstance
;
304 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_SERVICES_PAGE
);
305 psp
[nPages
].pfnDlgProc
= ServicesPageWndProc
;
310 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
311 psp
[nPages
].dwFlags
= PSP_HASHELP
;
312 psp
[nPages
].hInstance
= hInstance
;
313 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_STARTUP_PAGE
);
314 psp
[nPages
].pfnDlgProc
= StartupPageWndProc
;
319 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGEW
);
320 psp
[nPages
].dwFlags
= PSP_HASHELP
;
321 psp
[nPages
].hInstance
= hInstance
;
322 psp
[nPages
].pszTemplate
= MAKEINTRESOURCEW(IDD_TOOLS_PAGE
);
323 psp
[nPages
].pfnDlgProc
= ToolsPageWndProc
;
326 /* Set the total number of created pages */
329 /* Create the property sheet */
330 hPropSheet
= (HWND
)PropertySheetW(&psh
);
333 /* Center the property sheet on the desktop and show it */
334 ClipOrCenterWindowToMonitor(hPropSheet
, MONITOR_WORKAREA
| MONITOR_CENTER
);
335 ShowWindow(hPropSheet
, SW_SHOWNORMAL
);
341 BOOL
Initialize(HINSTANCE hInstance
)
344 LPWSTR lpszVistaAppName
= NULL
;
346 INITCOMMONCONTROLSEX InitControls
;
348 /* Initialize our global version flags */
349 bIsWindows
= IsWindowsOS();
350 bIsPreVistaOSVersion
= IsPreVistaOSVersion();
352 /* Initialize global strings */
353 szAppName
= LoadResourceString(hInstance
, IDS_MSCONFIG
);
354 if (!bIsPreVistaOSVersion
)
355 lpszVistaAppName
= LoadResourceString(hInstance
, IDS_MSCONFIG_2
);
357 /* We use a semaphore in order to have a single-instance application */
358 hSemaphore
= CreateSemaphoreW(NULL
, 0, 1, L
"MSConfigRunning");
359 if (!hSemaphore
|| GetLastError() == ERROR_ALREADY_EXISTS
)
361 CloseHandle(hSemaphore
);
364 * A semaphore with the same name already exist. It should have been
365 * created by another instance of MSConfig. Try to find its window
366 * and bring it to front.
368 if ( (hSingleWnd
&& IsWindow(hSingleWnd
)) ||
369 ( (hSingleWnd
= FindWindowW(L
"#32770", szAppName
)) != NULL
) ||
370 (!bIsPreVistaOSVersion
? ( (hSingleWnd
= FindWindowW(L
"#32770", lpszVistaAppName
)) != NULL
) : FALSE
) )
372 /* Found it. Show the window. */
373 ShowWindow(hSingleWnd
, SW_SHOWNORMAL
);
374 SetForegroundWindow(hSingleWnd
);
377 /* Quit this instance of MSConfig */
380 if (!bIsPreVistaOSVersion
) MemFree(lpszVistaAppName
);
382 /* Quit now if we failed */
389 /* Initialize the common controls */
390 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
391 InitControls
.dwICC
= ICC_LISTVIEW_CLASSES
| ICC_TREEVIEW_CLASSES
| ICC_UPDOWN_CLASS
/* | ICC_PROGRESS_CLASS | ICC_HOTKEY_CLASS*/;
392 InitCommonControlsEx(&InitControls
);
403 // // Close the sentry semaphore.
404 // CloseHandle(hSemaphore);
407 int APIENTRY
_tWinMain(HINSTANCE hInstance
,
408 HINSTANCE hPrevInstance
,
415 UNREFERENCED_PARAMETER(hPrevInstance
);
416 UNREFERENCED_PARAMETER(lpCmdLine
);
417 UNREFERENCED_PARAMETER(nCmdShow
);
420 * Initialize this instance of MSConfig. Quit if we have
421 * another instance already running.
423 if (!Initialize(hInstance
))
426 // hInst = hInstance;
428 hMainWnd
= CreatePropSheet(hInstance
, NULL
, szAppName
);
431 /* We failed, cleanup and bail out */
436 hAccelTable
= LoadAcceleratorsW(hInstance
, MAKEINTRESOURCEW(IDR_MSCONFIG
));
439 while (IsWindow(hMainWnd
) && GetMessageW(&msg
, NULL
, 0, 0))
442 * PropSheet_GetCurrentPageHwnd returns NULL when the user clicks the OK or Cancel button
443 * and after all of the pages have been notified. Apply button doesn't cause this to happen.
444 * We can then use the DestroyWindow function to destroy the property sheet.
446 if (PropSheet_GetCurrentPageHwnd(hMainWnd
) == NULL
)
449 /* Process the accelerator table */
450 if (!TranslateAcceleratorW(hMainWnd
, hAccelTable
, &msg
))
453 * If e.g. an item on the tree view is being edited,
454 * we cannot pass the event to PropSheet_IsDialogMessage.
455 * Doing so causes the property sheet to be closed at Enter press
456 * (instead of completing edit operation).
458 if (/*g_bDisableDialogDispatch ||*/ !PropSheet_IsDialogMessage(hMainWnd
, &msg
))
460 TranslateMessage(&msg
);
461 DispatchMessageW(&msg
);
466 // FIXME: Process the results of MSConfig !!
468 /* Destroy the accelerator table and the window */
469 if (hAccelTable
!= NULL
)
470 DestroyAcceleratorTable(hAccelTable
);
472 DestroyWindow(hMainWnd
);
474 /* Finish cleanup and return */
476 return (int)msg
.wParam
;