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>
13 #include "toolspage.h"
15 #include "startuppage.h"
16 #include "freeldrpage.h"
17 #include "systempage.h"
18 #include "generalpage.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 bIsOSVersionLessThanVista
= TRUE
;
34 HINSTANCE hInst
= NULL
;
35 LPWSTR szAppName
= NULL
;
36 HWND hMainWnd
; /* Main Window */
38 HWND hTabWnd
; /* Tab Control Window */
39 // HICON hDialogIcon = NULL;
41 WNDPROC wpOrigEditProc
= NULL
;
44 ////////////////////////////////////////////////////////////////////////////////
45 // Taken from WinSpy++ 1.7
46 // http://www.catch22.net/software/winspy
47 // Copyright (c) 2002 by J Brown
51 // Copied from uxtheme.h
52 // If you have this new header, then delete these and
53 // #include <uxtheme.h> instead!
55 #define ETDT_DISABLE 0x00000001
56 #define ETDT_ENABLE 0x00000002
57 #define ETDT_USETABTEXTURE 0x00000004
58 #define ETDT_ENABLETAB (ETDT_ENABLE | ETDT_USETABTEXTURE)
61 typedef HRESULT (WINAPI
* ETDTProc
) (HWND
, DWORD
);
64 // Try to call EnableThemeDialogTexture, if uxtheme.dll is present
66 BOOL
EnableDialogTheme(HWND hwnd
)
69 ETDTProc fnEnableThemeDialogTexture
;
71 hUXTheme
= LoadLibrary(_T("uxtheme.dll"));
75 fnEnableThemeDialogTexture
=
76 (ETDTProc
)GetProcAddress(hUXTheme
, "EnableThemeDialogTexture");
78 if(fnEnableThemeDialogTexture
)
80 fnEnableThemeDialogTexture(hwnd
, ETDT_ENABLETAB
);
82 FreeLibrary(hUXTheme
);
87 // Failed to locate API!
88 FreeLibrary(hUXTheme
);
94 // Not running under XP? Just fail gracefully
99 /* About Box dialog */
100 INT_PTR CALLBACK
About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
102 UNREFERENCED_PARAMETER(lParam
);
106 return (INT_PTR
)TRUE
;
109 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
111 EndDialog(hDlg
, LOWORD(wParam
));
112 return (INT_PTR
)TRUE
;
116 return (INT_PTR
)FALSE
;
120 /* Message handler for dialog box. */
121 LRESULT CALLBACK
MainWndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
127 switch (LOWORD(wParam
) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
130 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
141 switch (LOWORD(wParam
) /*GET_WM_COMMAND_ID(wParam, lParam)*/)
144 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
154 case WM_SYSCOLORCHANGE
:
155 /* Forward WM_SYSCOLORCHANGE to common controls */
156 SendMessage(hServicesListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
157 SendMessage(hStartupListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
158 SendMessage(hToolsListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
168 SetWindowLongPtr(hWnd
, DWLP_DLGPROC
, (LONG_PTR
)wpOrigEditProc
);
177 return CallWindowProc(wpOrigEditProc
, hWnd
, uMessage
, wParam
, lParam
);
183 #include <pshpack1.h>
184 typedef struct DLGTEMPLATEEX
196 } DLGTEMPLATEEX
, *LPDLGTEMPLATEEX
;
200 VOID
ModifySystemMenu(HWND hWnd
)
202 WCHAR szMenuString
[255];
204 /* Customize the window's system menu, add items before the "Close" item */
205 HMENU hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
209 if (LoadStringW(hInst
,
212 ARRAYSIZE(szMenuString
)) > 0)
215 InsertMenuW(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_ENABLED
| MF_STRING
, IDM_ABOUT
, szMenuString
);
217 InsertMenuW(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_SEPARATOR
, 0 , NULL
);
224 int CALLBACK
PropSheetCallback(HWND hDlg
, UINT message
, LPARAM lParam
)
230 LPDLGTEMPLATE dlgTemplate
= (LPDLGTEMPLATE
)lParam
;
231 LPDLGTEMPLATEEX dlgTemplateEx
= (LPDLGTEMPLATEEX
)lParam
;
233 /* Set the styles of the property sheet dialog */
234 if (dlgTemplateEx
->signature
== 0xFFFF)
236 //// MFC : DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION;
238 dlgTemplateEx
->style
= DS_SHELLFONT
| DS_MODALFRAME
| DS_CENTER
| WS_MINIMIZEBOX
| WS_POPUP
| WS_VISIBLE
| WS_CAPTION
| WS_SYSMENU
;
239 // dlgTemplateEx->style = DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
240 dlgTemplateEx
->exStyle
= WS_EX_CONTROLPARENT
| WS_EX_APPWINDOW
;
244 dlgTemplate
->style
= DS_SHELLFONT
| DS_MODALFRAME
| DS_CENTER
| WS_MINIMIZEBOX
| WS_POPUP
| WS_VISIBLE
| WS_CAPTION
| WS_SYSMENU
;
245 // dlgTemplate->style = DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
246 dlgTemplate
->dwExtendedStyle
= WS_EX_CONTROLPARENT
| WS_EX_APPWINDOW
;
252 case PSCB_INITIALIZED
:
254 /* Modify the system menu of the property sheet dialog */
255 ModifySystemMenu(hDlg
);
257 /* Set the dialog icons */
258 hIcon
= (HICON
)LoadImage(hInst
, MAKEINTRESOURCE(IDI_APPICON
), IMAGE_ICON
, 0, 0, LR_DEFAULTSIZE
);
259 SendMessage(hDlg
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
260 SendMessage(hDlg
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIcon
);
262 /* Sub-class the property sheet window procedure */
263 wpOrigEditProc
= (WNDPROC
)SetWindowLongPtr(hDlg
, DWLP_DLGPROC
, (LONG_PTR
)MainWndProc
);
275 HWND
CreatePropSheet(HINSTANCE hInstance
, HWND hwndOwner
, LPCTSTR lpszTitle
)
279 PROPSHEETPAGE psp
[7];
280 unsigned int nPages
= 0;
283 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
284 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
| /*PSH_USEICONID |*/ PSH_HASHELP
| /*PSH_NOCONTEXTHELP |*/ PSH_USECALLBACK
;
285 psh
.hInstance
= hInstance
;
286 psh
.hwndParent
= hwndOwner
;
287 //psh.pszIcon = MAKEINTRESOURCE(IDI_APPICON); // It's crap... Only works for the small icon and not the big...
288 psh
.pszCaption
= lpszTitle
;
291 psh
.pfnCallback
= (PFNPROPSHEETCALLBACK
)PropSheetCallback
;
294 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
295 psp
[nPages
].dwFlags
= PSP_HASHELP
;
296 psp
[nPages
].hInstance
= hInstance
;
297 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_GENERAL_PAGE
);
298 psp
[nPages
].pfnDlgProc
= (DLGPROC
)GeneralPageWndProc
;
302 if (bIsWindows
&& bIsOSVersionLessThanVista
)
304 /* SYSTEM.INI page */
305 if (MyFileExists(lpszSystemIni
, NULL
))
307 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
308 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
309 psp
[nPages
].hInstance
= hInstance
;
310 psp
[nPages
].pszTitle
= MAKEINTRESOURCE(IDS_TAB_SYSTEM
);
311 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_SYSTEM_PAGE
);
312 psp
[nPages
].pfnDlgProc
= (DLGPROC
)SystemPageWndProc
;
313 psp
[nPages
].lParam
= (LPARAM
)lpszSystemIni
;
316 BackupIniFile(lpszSystemIni
);
320 if (MyFileExists(lpszWinIni
, NULL
))
322 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
323 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
324 psp
[nPages
].hInstance
= hInstance
;
325 psp
[nPages
].pszTitle
= MAKEINTRESOURCE(IDS_TAB_WIN
);
326 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_SYSTEM_PAGE
);
327 psp
[nPages
].pfnDlgProc
= (DLGPROC
)WinPageWndProc
;
328 psp
[nPages
].lParam
= (LPARAM
)lpszWinIni
;
331 BackupIniFile(lpszWinIni
);
336 // TODO: Program the interface for Vista : "light" BCD editor...
337 if (!bIsWindows
|| (bIsWindows
&& bIsOSVersionLessThanVista
))
339 LPCTSTR lpszLoaderIniFile
= NULL
;
340 DWORD dwTabNameId
= 0;
343 lpszLoaderIniFile
= lpszBootIni
;
344 dwTabNameId
= IDS_TAB_BOOT
;
348 lpszLoaderIniFile
= lpszFreeLdrIni
;
349 dwTabNameId
= IDS_TAB_FREELDR
;
352 if (MyFileExists(lpszLoaderIniFile
, NULL
))
354 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
355 psp
[nPages
].dwFlags
= PSP_HASHELP
| PSP_USETITLE
;
356 psp
[nPages
].hInstance
= hInstance
;
357 psp
[nPages
].pszTitle
= MAKEINTRESOURCE(dwTabNameId
);
358 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_FREELDR_PAGE
);
359 psp
[nPages
].pfnDlgProc
= (DLGPROC
)FreeLdrPageWndProc
;
360 psp
[nPages
].lParam
= (LPARAM
)lpszLoaderIniFile
;
363 BackupIniFile(lpszLoaderIniFile
);
368 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
369 psp
[nPages
].dwFlags
= PSP_HASHELP
;
370 psp
[nPages
].hInstance
= hInstance
;
371 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_SERVICES_PAGE
);
372 psp
[nPages
].pfnDlgProc
= (DLGPROC
)ServicesPageWndProc
;
376 psp
[nPages
].dwSize
= sizeof(PROPSHEETPAGE
);
377 psp
[nPages
].dwFlags
= PSP_HASHELP
;
378 psp
[nPages
].hInstance
= hInstance
;
379 psp
[nPages
].pszTemplate
= MAKEINTRESOURCE(IDD_STARTUP_PAGE
);
380 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
;
392 /* Set the total number of created pages */
395 /* Create the property sheet */
396 hPropSheet
= (HWND
)PropertySheet(&psh
);
399 /* Center the property sheet on the desktop */
400 //ShowWindow(hPropSheet, SW_HIDE);
401 ClipOrCenterWindowToMonitor(hPropSheet
, MONITOR_WORKAREA
| MONITOR_CENTER
);
402 //ShowWindow(hPropSheet, SW_SHOWNORMAL);
408 BOOL
Initialize(HINSTANCE hInstance
)
411 LPWSTR lpszVistaAppName
= NULL
;
413 INITCOMMONCONTROLSEX InitControls
;
415 /* Initialize our global version flags */
416 bIsWindows
= TRUE
; /* IsWindowsOS(); */ // TODO: Commented for testing purposes...
417 bIsOSVersionLessThanVista
= TRUE
; /* IsOSVersionLessThanVista(); */ // TODO: Commented for testing purposes...
419 /* Initialize global strings */
420 szAppName
= LoadResourceString(hInstance
, IDS_MSCONFIG
);
421 if (!bIsOSVersionLessThanVista
)
422 lpszVistaAppName
= LoadResourceString(hInstance
, IDS_MSCONFIG_2
);
424 /* We use a semaphore in order to have a single-instance application */
425 hSemaphore
= CreateSemaphoreW(NULL
, 0, 1, L
"MSConfigRunning");
426 if (!hSemaphore
|| GetLastError() == ERROR_ALREADY_EXISTS
)
428 CloseHandle(hSemaphore
);
431 * A semaphore with the same name already exist. It should have been
432 * created by another instance of MSConfig. Try to find its window
433 * and bring it to front.
435 if ( (hSingleWnd
&& IsWindow(hSingleWnd
)) ||
436 ( (hSingleWnd
= FindWindowW(L
"#32770", szAppName
)) != NULL
) ||
437 (!bIsOSVersionLessThanVista
? ( (hSingleWnd
= FindWindowW(L
"#32770", lpszVistaAppName
)) != NULL
) : FALSE
) )
439 /* Found it. Show the window. */
440 ShowWindow(hSingleWnd
, SW_SHOWNORMAL
);
441 SetForegroundWindow(hSingleWnd
);
444 /* Quit this instance of MSConfig */
447 if (!bIsOSVersionLessThanVista
) MemFree(lpszVistaAppName
);
449 /* Quit now if we failed */
456 /* Initialize the common controls */
457 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
458 InitControls
.dwICC
= ICC_LISTVIEW_CLASSES
| ICC_TREEVIEW_CLASSES
| ICC_UPDOWN_CLASS
/* | ICC_PROGRESS_CLASS | ICC_HOTKEY_CLASS*/;
459 InitCommonControlsEx(&InitControls
);
470 // // Close the sentry semaphore.
471 // CloseHandle(hSemaphore);
474 int APIENTRY
_tWinMain(HINSTANCE hInstance
,
475 HINSTANCE hPrevInstance
,
482 UNREFERENCED_PARAMETER(hPrevInstance
);
483 UNREFERENCED_PARAMETER(lpCmdLine
);
484 UNREFERENCED_PARAMETER(nCmdShow
);
487 * Initialize this instance of MSConfig. Quit if we have
488 * another instance already running.
490 if (!Initialize(hInstance
))
493 // hInst = hInstance;
495 hMainWnd
= CreatePropSheet(hInstance
, NULL
, szAppName
);
498 /* We failed, cleanup and bail out */
503 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDR_MSCONFIG
));
506 while (IsWindow(hMainWnd
) && GetMessage(&msg
, NULL
, 0, 0))
509 * PropSheet_GetCurrentPageHwnd returns NULL when the user clicks the OK or Cancel button
510 * and after all of the pages have been notified. Apply button doesn't cause this to happen.
511 * We can then use the DestroyWindow function to destroy the property sheet.
513 if (PropSheet_GetCurrentPageHwnd(hMainWnd
) == NULL
)
516 /* Process the accelerator table */
517 if (!TranslateAccelerator(hMainWnd
, hAccelTable
, &msg
))
520 * If e.g. an item on the tree view is being edited,
521 * we cannot pass the event to PropSheet_IsDialogMessage.
522 * Doing so causes the property sheet to be closed at Enter press
523 * (instead of completing edit operation).
525 if (/*g_bDisableDialogDispatch ||*/ !PropSheet_IsDialogMessage(hMainWnd
, &msg
))
527 TranslateMessage(&msg
);
528 DispatchMessage(&msg
);
533 // FIXME: Process the results of MSConfig !!
535 /* Destroy the accelerator table and the window */
536 if (hAccelTable
!= NULL
)
537 DestroyAcceleratorTable(hAccelTable
);
539 DestroyWindow(hMainWnd
);
541 /* Finish cleanup and return */
543 return (int)msg
.wParam
;