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>
12 #include "toolspage.h"
14 #include "startuppage.h"
15 #include "freeldrpage.h"
16 #include "systempage.h"
17 #include "generalpage.h"
19 /* Allow only for a single instance of MSConfig */
21 #pragma data_seg("MSConfigInstance")
22 HWND hSingleWnd
= NULL
;
24 #pragma comment(linker, "/SECTION:MSConfigInstance,RWS")
26 HWND hSingleWnd
__attribute__((section ("MSConfigInstance"), shared
)) = NULL
;
29 /* Defaults for ReactOS */
30 BOOL bIsWindows
= FALSE
;
31 BOOL bIsOSVersionLessThanVista
= TRUE
;
33 HINSTANCE hInst
= NULL
;
34 LPWSTR szAppName
= NULL
;
35 HWND hMainWnd
; /* Main Window */
37 HWND hTabWnd
; /* Tab Control Window */
38 // HICON hDialogIcon = NULL;
40 WNDPROC wpOrigEditProc
= NULL
;
43 ////////////////////////////////////////////////////////////////////////////////
44 // Taken from WinSpy++ 1.7
45 // http://www.catch22.net/software/winspy
46 // Copyright (c) 2002 by J Brown
50 // Copied from uxtheme.h
51 // If you have this new header, then delete these and
52 // #include <uxtheme.h> instead!
54 #define ETDT_DISABLE 0x00000001
55 #define ETDT_ENABLE 0x00000002
56 #define ETDT_USETABTEXTURE 0x00000004
57 #define ETDT_ENABLETAB (ETDT_ENABLE | ETDT_USETABTEXTURE)
60 typedef HRESULT (WINAPI
* ETDTProc
) (HWND
, DWORD
);
63 // Try to call EnableThemeDialogTexture, if uxtheme.dll is present
65 BOOL
EnableDialogTheme(HWND hwnd
)
68 ETDTProc fnEnableThemeDialogTexture
;
70 hUXTheme
= LoadLibrary(_T("uxtheme.dll"));
74 fnEnableThemeDialogTexture
=
75 (ETDTProc
)GetProcAddress(hUXTheme
, "EnableThemeDialogTexture");
77 if(fnEnableThemeDialogTexture
)
79 fnEnableThemeDialogTexture(hwnd
, ETDT_ENABLETAB
);
81 FreeLibrary(hUXTheme
);
86 // Failed to locate API!
87 FreeLibrary(hUXTheme
);
93 // Not running under XP? Just fail gracefully
98 /* About Box dialog */
99 INT_PTR CALLBACK
About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
101 UNREFERENCED_PARAMETER(lParam
);
105 return (INT_PTR
)TRUE
;
108 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
110 EndDialog(hDlg
, LOWORD(wParam
));
111 return (INT_PTR
)TRUE
;
115 return (INT_PTR
)FALSE
;
119 /* Message handler for dialog box. */
120 LRESULT CALLBACK
MainWndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
126 switch (LOWORD(wParam
) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
129 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
140 switch (LOWORD(wParam
) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
143 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
153 case WM_SYSCOLORCHANGE
:
154 /* Forward WM_SYSCOLORCHANGE to common controls */
155 SendMessage(hServicesListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
156 SendMessage(hStartupListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
157 SendMessage(hToolsListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
167 SetWindowLongPtr(hWnd
, DWLP_DLGPROC
, (LONG_PTR
)wpOrigEditProc
);
176 return CallWindowProc(wpOrigEditProc
, hWnd
, uMessage
, wParam
, lParam
);
182 #include <pshpack1.h>
183 typedef struct DLGTEMPLATEEX
195 } DLGTEMPLATEEX
, *LPDLGTEMPLATEEX
;
199 VOID
ModifySystemMenu(HWND hWnd
)
201 WCHAR szMenuString
[255];
203 /* Customize the window's system menu, add items before the "Close" item */
204 HMENU hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
208 if (LoadStringW(hInst
,
211 ARRAYSIZE(szMenuString
)) > 0)
214 InsertMenuW(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_ENABLED
| MF_STRING
, IDM_ABOUT
, szMenuString
);
216 InsertMenuW(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_SEPARATOR
, 0 , NULL
);
223 int CALLBACK
PropSheetCallback(HWND hDlg
, UINT message
, LPARAM lParam
)
229 LPDLGTEMPLATE dlgTemplate
= (LPDLGTEMPLATE
)lParam
;
230 LPDLGTEMPLATEEX dlgTemplateEx
= (LPDLGTEMPLATEEX
)lParam
;
232 /* Set the styles of the property sheet dialog */
233 if (dlgTemplateEx
->signature
== 0xFFFF)
235 //// MFC : DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION;
237 dlgTemplateEx
->style
= DS_SHELLFONT
| DS_MODALFRAME
| DS_CENTER
| WS_MINIMIZEBOX
| WS_POPUP
| WS_VISIBLE
| WS_CAPTION
| WS_SYSMENU
;
238 // dlgTemplateEx->style = DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
239 dlgTemplateEx
->exStyle
= WS_EX_CONTROLPARENT
| WS_EX_APPWINDOW
;
243 dlgTemplate
->style
= DS_SHELLFONT
| DS_MODALFRAME
| DS_CENTER
| WS_MINIMIZEBOX
| WS_POPUP
| WS_VISIBLE
| WS_CAPTION
| WS_SYSMENU
;
244 // dlgTemplate->style = DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
245 dlgTemplate
->dwExtendedStyle
= WS_EX_CONTROLPARENT
| WS_EX_APPWINDOW
;
251 case PSCB_INITIALIZED
:
253 /* Modify the system menu of the property sheet dialog */
254 ModifySystemMenu(hDlg
);
256 /* Set the dialog icons */
257 hIcon
= (HICON
)LoadImage(hInst
, MAKEINTRESOURCE(IDI_APPICON
), IMAGE_ICON
, 0, 0, LR_DEFAULTSIZE
);
258 SendMessage(hDlg
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
259 SendMessage(hDlg
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIcon
);
261 /* Sub-class the property sheet window procedure */
262 wpOrigEditProc
= (WNDPROC
)SetWindowLongPtr(hDlg
, DWLP_DLGPROC
, (LONG_PTR
)MainWndProc
);
274 HWND
CreatePropSheet(HINSTANCE hInstance
, HWND hwndOwner
, LPCTSTR lpszTitle
)
278 PROPSHEETPAGE psp
[7];
279 unsigned int nPages
= 0;
282 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
283 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
| /*PSH_USEICONID |*/ PSH_HASHELP
| /*PSH_NOCONTEXTHELP |*/ PSH_USECALLBACK
;
284 psh
.hInstance
= hInstance
;
285 psh
.hwndParent
= hwndOwner
;
286 //psh.pszIcon = MAKEINTRESOURCE(IDI_APPICON); // It's crap... Only works for the small icon and not the big...
287 psh
.pszCaption
= lpszTitle
;
290 psh
.pfnCallback
= (PFNPROPSHEETCALLBACK
)PropSheetCallback
;
293 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
294 psp
[nPages
].dwFlags
= PSP_HASHELP
;
295 psp
[nPages
].hInstance
= hInstance
;
296 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_GENERAL_PAGE
);
297 psp
[nPages
].pfnDlgProc
= (DLGPROC
)GeneralPageWndProc
;
301 if (bIsWindows
&& bIsOSVersionLessThanVista
)
303 /* SYSTEM.INI page */
304 if (MyFileExists(lpszSystemIni
, NULL
))
306 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
307 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
308 psp
[nPages
].hInstance
= hInstance
;
309 psp
[nPages
].pszTitle
= MAKEINTRESOURCE(IDS_TAB_SYSTEM
);
310 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_SYSTEM_PAGE
);
311 psp
[nPages
].pfnDlgProc
= (DLGPROC
)SystemPageWndProc
;
312 psp
[nPages
].lParam
= (LPARAM
)lpszSystemIni
;
315 BackupIniFile(lpszSystemIni
);
319 if (MyFileExists(lpszWinIni
, NULL
))
321 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
322 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
323 psp
[nPages
].hInstance
= hInstance
;
324 psp
[nPages
].pszTitle
= MAKEINTRESOURCE(IDS_TAB_WIN
);
325 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_SYSTEM_PAGE
);
326 psp
[nPages
].pfnDlgProc
= (DLGPROC
)WinPageWndProc
;
327 psp
[nPages
].lParam
= (LPARAM
)lpszWinIni
;
330 BackupIniFile(lpszWinIni
);
335 // TODO: Program the interface for Vista : "light" BCD editor...
336 if (!bIsWindows
|| (bIsWindows
&& bIsOSVersionLessThanVista
))
338 LPCTSTR lpszLoaderIniFile
= NULL
;
339 DWORD dwTabNameId
= 0;
342 lpszLoaderIniFile
= lpszBootIni
;
343 dwTabNameId
= IDS_TAB_BOOT
;
347 lpszLoaderIniFile
= lpszFreeLdrIni
;
348 dwTabNameId
= IDS_TAB_FREELDR
;
351 if (MyFileExists(lpszLoaderIniFile
, NULL
))
353 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
354 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
355 psp
[nPages
].hInstance
= hInstance
;
356 psp
[nPages
].pszTitle
= MAKEINTRESOURCE(dwTabNameId
);
357 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_FREELDR_PAGE
);
358 psp
[nPages
].pfnDlgProc
= (DLGPROC
)FreeLdrPageWndProc
;
359 psp
[nPages
].lParam
= (LPARAM
)lpszLoaderIniFile
;
362 BackupIniFile(lpszLoaderIniFile
);
367 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
368 psp
[nPages
].dwFlags
= PSP_HASHELP
;
369 psp
[nPages
].hInstance
= hInstance
;
370 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_SERVICES_PAGE
);
371 psp
[nPages
].pfnDlgProc
= (DLGPROC
)ServicesPageWndProc
;
375 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
376 psp
[nPages
].dwFlags
= PSP_HASHELP
;
377 psp
[nPages
].hInstance
= hInstance
;
378 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_STARTUP_PAGE
);
379 psp
[nPages
].pfnDlgProc
= (DLGPROC
)StartupPageWndProc
;
384 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
385 psp
[nPages
].dwFlags
= PSP_HASHELP
;
386 psp
[nPages
].hInstance
= hInstance
;
387 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_TOOLS_PAGE
);
388 psp
[nPages
].pfnDlgProc
= (DLGPROC
)ToolsPageWndProc
;
391 /* Set the total number of created pages */
394 /* Create the property sheet */
395 hPropSheet
= (HWND
)PropertySheet(&psh
);
398 /* Center the property sheet on the desktop */
399 //ShowWindow(hPropSheet, SW_HIDE);
400 ClipOrCenterWindowToMonitor(hPropSheet
, MONITOR_WORKAREA
| MONITOR_CENTER
);
401 //ShowWindow(hPropSheet, SW_SHOWNORMAL);
407 BOOL
Initialize(HINSTANCE hInstance
)
410 LPWSTR lpszVistaAppName
= NULL
;
412 INITCOMMONCONTROLSEX InitControls
;
414 /* Initialize our global version flags */
415 bIsWindows
= TRUE
; /* IsWindowsOS(); */ // TODO: Commented for testing purposes...
416 bIsOSVersionLessThanVista
= TRUE
; /* IsOSVersionLessThanVista(); */ // TODO: Commented for testing purposes...
418 /* Initialize global strings */
419 szAppName
= LoadResourceString(hInstance
, IDS_MSCONFIG
);
420 if (!bIsOSVersionLessThanVista
)
421 lpszVistaAppName
= LoadResourceString(hInstance
, IDS_MSCONFIG_2
);
423 /* We use a semaphore in order to have a single-instance application */
424 hSemaphore
= CreateSemaphoreW(NULL
, 0, 1, L
"MSConfigRunning");
425 if (!hSemaphore
|| GetLastError() == ERROR_ALREADY_EXISTS
)
427 CloseHandle(hSemaphore
);
430 * A semaphore with the same name already exist. It should have been
431 * created by another instance of MSConfig. Try to find its window
432 * and bring it to front.
434 if ( (hSingleWnd
&& IsWindow(hSingleWnd
)) ||
435 ( (hSingleWnd
= FindWindowW(L
"#32770", szAppName
)) != NULL
) ||
436 (!bIsOSVersionLessThanVista
? ( (hSingleWnd
= FindWindowW(L
"#32770", lpszVistaAppName
)) != NULL
) : FALSE
) )
438 /* Found it. Show the window. */
439 ShowWindow(hSingleWnd
, SW_SHOWNORMAL
);
440 SetForegroundWindow(hSingleWnd
);
443 /* Quit this instance of MSConfig */
446 if (!bIsOSVersionLessThanVista
) MemFree(lpszVistaAppName
);
448 /* Quit now if we failed */
455 /* Initialize the common controls */
456 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
457 InitControls
.dwICC
= ICC_LISTVIEW_CLASSES
| ICC_TREEVIEW_CLASSES
| ICC_UPDOWN_CLASS
/* | ICC_PROGRESS_CLASS | ICC_HOTKEY_CLASS*/;
458 InitCommonControlsEx(&InitControls
);
469 // // Close the sentry semaphore.
470 // CloseHandle(hSemaphore);
473 int APIENTRY
_tWinMain(HINSTANCE hInstance
,
474 HINSTANCE hPrevInstance
,
481 UNREFERENCED_PARAMETER(hPrevInstance
);
482 UNREFERENCED_PARAMETER(lpCmdLine
);
483 UNREFERENCED_PARAMETER(nCmdShow
);
486 * Initialize this instance of MSConfig. Quit if we have
487 * another instance already running.
489 if (!Initialize(hInstance
))
492 // hInst = hInstance;
494 hMainWnd
= CreatePropSheet(hInstance
, NULL
, szAppName
);
497 /* We failed, cleanup and bail out */
502 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDR_MSCONFIG
));
505 while (IsWindow(hMainWnd
) && GetMessage(&msg
, NULL
, 0, 0))
508 * PropSheet_GetCurrentPageHwnd returns NULL when the user clicks the OK or Cancel button
509 * and after all of the pages have been notified. Apply button doesn't cause this to happen.
510 * We can then use the DestroyWindow function to destroy the property sheet.
512 if (PropSheet_GetCurrentPageHwnd(hMainWnd
) == NULL
)
515 /* Process the accelerator table */
516 if (!TranslateAccelerator(hMainWnd
, hAccelTable
, &msg
))
519 * If e.g. an item on the tree view is being edited,
520 * we cannot pass the event to PropSheet_IsDialogMessage.
521 * Doing so causes the property sheet to be closed at Enter press
522 * (instead of completing edit operation).
524 if (/*g_bDisableDialogDispatch ||*/ !PropSheet_IsDialogMessage(hMainWnd
, &msg
))
526 TranslateMessage(&msg
);
527 DispatchMessage(&msg
);
532 // FIXME: Process the results of MSConfig !!
534 /* Destroy the accelerator table and the window */
535 if (hAccelTable
!= NULL
)
536 DestroyAcceleratorTable(hAccelTable
);
538 DestroyWindow(hMainWnd
);
540 /* Finish cleanup and return */
542 return (int)msg
.wParam
;