mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
9393fc320e
Excluded: 3rd-party code (incl. wine) and most of the win32ss.
895 lines
33 KiB
C++
895 lines
33 KiB
C++
/*
|
||
* PROJECT: ReactOS Applications
|
||
* LICENSE: LGPL - See COPYING in the top level directory
|
||
* FILE: base/applications/msconfig_new/systempage.c
|
||
* PURPOSE: System page message handler
|
||
* COPYRIGHT: Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
|
||
* 2011 Gregor Schneider <Gregor.Schneider@reactos.org>
|
||
* Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr>
|
||
*/
|
||
|
||
#include "precomp.h"
|
||
#include <share.h>
|
||
|
||
#include "treeview.h"
|
||
#include "uxthemesupp.h"
|
||
|
||
#include "regutils.h"
|
||
#include "utils.h"
|
||
|
||
|
||
extern "C" {
|
||
|
||
LPCWSTR lpszSystemIni = L"%SystemRoot%\\system.ini"; // or: %windir%\\... ?
|
||
LPCWSTR lpszWinIni = L"%SystemRoot%\\win.ini"; // or: %windir%\\... ?
|
||
|
||
}
|
||
|
||
static LPCWSTR szMSConfigTok = L";msconfig "; // Note the trailing whitespace
|
||
static const size_t MSConfigTokLen = 10;
|
||
|
||
|
||
extern "C" {
|
||
|
||
DWORD GetSystemIniActivation(VOID)
|
||
{
|
||
DWORD dwSystemIni = 0;
|
||
RegGetDWORDValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\state", L"system.ini", &dwSystemIni);
|
||
return dwSystemIni;
|
||
}
|
||
|
||
DWORD GetWinIniActivation(VOID)
|
||
{
|
||
DWORD dwWinIni = 0;
|
||
RegGetDWORDValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\state", L"win.ini", &dwWinIni);
|
||
return dwWinIni;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
static HWND hTree = NULL;
|
||
static WCHAR szSearchString[MAX_VALUE_NAME] = L"";
|
||
static BOOL bMatchExactText = FALSE;
|
||
static BOOL bSearchSense = TRUE; // TRUE == down, FALSE == up.
|
||
static BOOL bCaseSensitive = FALSE;
|
||
|
||
static void
|
||
ToLower(LPWSTR lpszString)
|
||
{
|
||
if (!lpszString)
|
||
return;
|
||
|
||
while (*lpszString)
|
||
{
|
||
*lpszString = towlower(*lpszString);
|
||
++lpszString;
|
||
}
|
||
}
|
||
|
||
INT_PTR CALLBACK
|
||
FindDialogWndProc(HWND hDlg,
|
||
UINT message,
|
||
WPARAM wParam,
|
||
LPARAM lParam)
|
||
{
|
||
UNREFERENCED_PARAMETER(lParam);
|
||
|
||
switch (message)
|
||
{
|
||
case WM_INITDIALOG:
|
||
{
|
||
hTree = (HWND)lParam;
|
||
|
||
Button_SetCheck(GetDlgItem(hDlg, IDC_CBX_FIND_WHOLE_WORD_ONLY), (bMatchExactText ? BST_CHECKED : BST_UNCHECKED));
|
||
Button_SetCheck(GetDlgItem(hDlg, IDC_RB_FIND_DOWN), (bSearchSense ? BST_CHECKED : BST_UNCHECKED)); // TRUE == down, FALSE == up.
|
||
Button_SetCheck(GetDlgItem(hDlg, IDC_RB_FIND_UP ), (bSearchSense ? BST_UNCHECKED : BST_CHECKED )); // TRUE == down, FALSE == up.
|
||
Button_SetCheck(GetDlgItem(hDlg, IDC_CBX_FIND_MATCH_CASE), (bCaseSensitive ? BST_CHECKED : BST_UNCHECKED));
|
||
|
||
Edit_SetText(GetDlgItem(hDlg, IDC_TXT_FIND_TEXT), szSearchString);
|
||
SetFocus(GetDlgItem(hDlg, IDC_TXT_FIND_TEXT));
|
||
Edit_SetSel(GetDlgItem(hDlg, IDC_TXT_FIND_TEXT), 0, -1);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case WM_COMMAND:
|
||
{
|
||
switch (LOWORD(wParam))
|
||
{
|
||
case IDOK:
|
||
{
|
||
TVITEMEXW tvItemEx;
|
||
HTREEITEM htiIterator;
|
||
WCHAR label[MAX_VALUE_NAME] = L"";
|
||
WCHAR szTemp[MAX_VALUE_NAME];
|
||
|
||
bMatchExactText = (Button_GetCheck(GetDlgItem(hDlg, IDC_CBX_FIND_WHOLE_WORD_ONLY)) == BST_CHECKED);
|
||
bSearchSense = ((Button_GetCheck(GetDlgItem(hDlg, IDC_RB_FIND_DOWN)) == BST_CHECKED) &&
|
||
(Button_GetCheck(GetDlgItem(hDlg, IDC_RB_FIND_UP )) == BST_UNCHECKED)); // TRUE == down, FALSE == up.
|
||
bCaseSensitive = (Button_GetCheck(GetDlgItem(hDlg, IDC_CBX_FIND_MATCH_CASE)) == BST_CHECKED);
|
||
|
||
Edit_GetText(GetDlgItem(hDlg, IDC_TXT_FIND_TEXT), szSearchString, _ARRAYSIZE(szSearchString));
|
||
wcscpy(szTemp, szSearchString);
|
||
if (!bCaseSensitive)
|
||
ToLower(szTemp);
|
||
|
||
for (htiIterator = ((Button_GetCheck(GetDlgItem(hDlg, IDC_CBX_FIND_FROM_BEGINNING)) == BST_CHECKED) ? (bSearchSense ? TreeView_GetFirst(hTree)
|
||
: TreeView_GetLast(hTree))
|
||
: (bSearchSense ? TreeView_GetNext(hTree, TreeView_GetSelection(hTree))
|
||
: TreeView_GetPrev(hTree, TreeView_GetSelection(hTree))));
|
||
htiIterator ;
|
||
htiIterator = (bSearchSense ? TreeView_GetNext(hTree, htiIterator)
|
||
: TreeView_GetPrev(hTree, htiIterator)))
|
||
{
|
||
SecureZeroMemory(&tvItemEx, sizeof(tvItemEx));
|
||
|
||
tvItemEx.hItem = htiIterator; // Handle of the item to be retrieved
|
||
tvItemEx.mask = TVIF_HANDLE | TVIF_TEXT;
|
||
tvItemEx.pszText = label;
|
||
tvItemEx.cchTextMax = MAX_VALUE_NAME;
|
||
TreeView_GetItem(hTree, &tvItemEx);
|
||
if (!bCaseSensitive)
|
||
ToLower(label);
|
||
|
||
if (bMatchExactText ? (_tcscmp(label, szTemp) == 0) : !!_tcsstr(label, szTemp)) // <-- hackish. A arranger.
|
||
{
|
||
TreeView_SelectItem(hTree, htiIterator);
|
||
EndDialog(hDlg, LOWORD(wParam));
|
||
return TRUE;
|
||
}
|
||
//MessageBox(NULL, label, _T("Info"), MB_ICONINFORMATION | MB_OK);
|
||
}
|
||
|
||
// FIXME: Localize!
|
||
MessageBoxW(hDlg, L"No correspondence found.", szAppName, MB_ICONINFORMATION | MB_OK);
|
||
SetFocus(GetDlgItem(hDlg, IDC_TXT_FIND_TEXT));
|
||
Edit_SetSel(GetDlgItem(hDlg, IDC_TXT_FIND_TEXT), 0, -1);
|
||
//EndDialog(hDlg, LOWORD(wParam));
|
||
return TRUE;
|
||
}
|
||
|
||
case IDCANCEL:
|
||
EndDialog(hDlg, LOWORD(wParam));
|
||
return TRUE;
|
||
|
||
default:
|
||
//break;
|
||
return FALSE;
|
||
}
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
|
||
static void
|
||
TreeView_SetBOOLCheck(HWND hTree, HTREEITEM htiItem, BOOL bState, BOOL bPropagateStateToParent)
|
||
{
|
||
if (!hTree || !htiItem)
|
||
return;
|
||
|
||
TreeView_SetCheckState(hTree, htiItem, bState);
|
||
|
||
/*
|
||
* Add or remove the token for tree leaves only.
|
||
*/
|
||
if (!TreeView_GetChild(hTree, htiItem))
|
||
{
|
||
/* 1- Retrieve properties */
|
||
TVITEMEXW tvItemEx;
|
||
SecureZeroMemory(&tvItemEx, sizeof(tvItemEx));
|
||
|
||
tvItemEx.hItem = htiItem; // Handle of the item to be retrieved.
|
||
tvItemEx.mask = TVIF_HANDLE | TVIF_TEXT;
|
||
WCHAR label[MAX_VALUE_NAME] = L"";
|
||
tvItemEx.pszText = label;
|
||
tvItemEx.cchTextMax = MAX_VALUE_NAME;
|
||
TreeView_GetItem(hTree, &tvItemEx);
|
||
|
||
if (!bState)
|
||
{
|
||
/* 2- Add the token IF NEEDED */
|
||
if ((wcslen(tvItemEx.pszText) < MSConfigTokLen) || (_wcsnicmp(tvItemEx.pszText, szMSConfigTok, MSConfigTokLen) != 0))
|
||
{
|
||
LPWSTR newLabel = (LPWSTR)MemAlloc(0, (_tcslen(tvItemEx.pszText) + MSConfigTokLen + 1) * sizeof(WCHAR));
|
||
wcscpy(newLabel, szMSConfigTok);
|
||
wcscat(newLabel, tvItemEx.pszText);
|
||
tvItemEx.pszText = newLabel;
|
||
|
||
TreeView_SetItem(hTree, &tvItemEx);
|
||
|
||
MemFree(newLabel);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* 2- Remove the token IF NEEDED */
|
||
if ((wcslen(tvItemEx.pszText) >= MSConfigTokLen) && (_wcsnicmp(tvItemEx.pszText, szMSConfigTok, MSConfigTokLen) == 0))
|
||
{
|
||
LPWSTR newLabel = (LPWSTR)MemAlloc(0, (_tcslen(tvItemEx.pszText) - MSConfigTokLen + 1) * sizeof(WCHAR));
|
||
wcscpy(newLabel, tvItemEx.pszText + MSConfigTokLen);
|
||
tvItemEx.pszText = newLabel;
|
||
|
||
TreeView_SetItem(hTree, &tvItemEx);
|
||
|
||
// TODO: if one finds tvItemEx.pszText == L"", one can
|
||
// directly remove the item (cf. message TVN_ENDLABELEDIT).
|
||
|
||
MemFree(newLabel);
|
||
}
|
||
}
|
||
}
|
||
////////////////////////
|
||
|
||
for (HTREEITEM htiIterator = TreeView_GetChild(hTree, htiItem) ; htiIterator ; htiIterator = TreeView_GetNextSibling(hTree, htiIterator))
|
||
TreeView_SetBOOLCheck(hTree, htiIterator, bState, FALSE);
|
||
|
||
if (bPropagateStateToParent)
|
||
TreeView_PropagateStateOfItemToParent(hTree, htiItem);
|
||
|
||
return;
|
||
}
|
||
|
||
static void
|
||
LoadIniFile(HWND hTree, LPCWSTR lpszIniFile)
|
||
{
|
||
// Ouverture en lecture (sans cr<63>ation de fichier si celui-ci n'esistait pas d<>j<EFBFBD>)
|
||
// d'un flux en mode texte, avec permission de lecture seule.
|
||
DWORD dwNumOfChars = ExpandEnvironmentStringsW(lpszIniFile, NULL, 0);
|
||
LPWSTR lpszFileName = (LPWSTR)MemAlloc(0, dwNumOfChars * sizeof(WCHAR));
|
||
ExpandEnvironmentStringsW(lpszIniFile, lpszFileName, dwNumOfChars);
|
||
|
||
FILE* ini_file = _wfsopen(lpszFileName, L"rt", _SH_DENYWR); // r+t <-- read write text ; rt <-- read text
|
||
MemFree(lpszFileName);
|
||
|
||
if (!ini_file)
|
||
return; // error
|
||
|
||
WCHAR szLine[MAX_VALUE_NAME] = L"";
|
||
TVINSERTSTRUCT tvis;
|
||
HTREEITEM hParent = TVI_ROOT;
|
||
BOOL bIsSection = FALSE;
|
||
LPWSTR lpsz1 = NULL;
|
||
LPWSTR lpsz2 = NULL;
|
||
|
||
while (!feof(ini_file) && fgetws(szLine, _ARRAYSIZE(szLine), ini_file))
|
||
{
|
||
/* Skip hypothetical starting spaces or newline characters */
|
||
lpsz1 = szLine;
|
||
while (*lpsz1 == L' ' || *lpsz1 == L'\r' || *lpsz1 == L'\n')
|
||
++lpsz1;
|
||
|
||
/* Skip empty lines */
|
||
if (!*lpsz1)
|
||
continue;
|
||
|
||
/* Find the last newline character (if exists) and replace it by the NULL terminator */
|
||
lpsz2 = lpsz1;
|
||
while (*lpsz2)
|
||
{
|
||
if (*lpsz2 == L'\r' || *lpsz2 == L'\n')
|
||
{
|
||
*lpsz2 = L'\0';
|
||
break;
|
||
}
|
||
|
||
++lpsz2;
|
||
}
|
||
|
||
/* Check for new sections. They should be parent of ROOT. */
|
||
if (*lpsz1 == L'[')
|
||
{
|
||
bIsSection = TRUE;
|
||
hParent = TVI_ROOT;
|
||
}
|
||
|
||
SecureZeroMemory(&tvis, sizeof(tvis));
|
||
tvis.hParent = hParent;
|
||
tvis.hInsertAfter = TVI_LAST;
|
||
tvis.itemex.mask = TVIF_TEXT; // TVIF_HANDLE | TVIF_TEXT;
|
||
tvis.itemex.pszText = lpsz1;
|
||
tvis.itemex.hItem = TreeView_InsertItem(hTree, &tvis);
|
||
|
||
/* The special ";msconfig " token disables the line */
|
||
if (!bIsSection && _wcsnicmp(lpsz1, szMSConfigTok, MSConfigTokLen) == 0)
|
||
TreeView_SetBOOLCheck(hTree, tvis.itemex.hItem, FALSE, TRUE);
|
||
else
|
||
TreeView_SetBOOLCheck(hTree, tvis.itemex.hItem, TRUE, TRUE);
|
||
|
||
/*
|
||
* Now, all the elements will be children of this section,
|
||
* until we create a new one.
|
||
*/
|
||
if (bIsSection)
|
||
{
|
||
bIsSection = FALSE;
|
||
hParent = tvis.itemex.hItem;
|
||
}
|
||
}
|
||
|
||
fclose(ini_file);
|
||
return;
|
||
|
||
//// Test code for the TreeView ////
|
||
/*
|
||
HTREEITEM hItem[16];
|
||
|
||
hItem[0] = InsertItem(hTree, _T("B"),TVI_ROOT,TVI_LAST);
|
||
hItem[1] = InsertItem(hTree, _T("C"),TVI_ROOT,TVI_LAST);
|
||
hItem[2] = InsertItem(hTree, _T("A"),TVI_ROOT,TVI_LAST);
|
||
hItem[3] = InsertItem(hTree, _T("D"),TVI_ROOT,TVI_LAST);
|
||
hItem[4] = InsertItem(hTree, _T("D-1"),hItem[3] ,TVI_LAST);
|
||
hItem[5] = InsertItem(hTree, _T("D-2"),hItem[3] ,TVI_LAST);
|
||
hItem[9] = InsertItem(hTree, _T("D-2-1"),hItem[5],TVI_LAST);
|
||
hItem[6] = InsertItem(hTree, _T("D-3"),hItem[3] ,TVI_LAST);
|
||
hItem[7] = InsertItem(hTree, _T("D-3-1"),hItem[6],TVI_LAST);
|
||
hItem[10] = InsertItem(hTree, _T("D-3-1-1"),hItem[7],TVI_LAST);
|
||
hItem[11] = InsertItem(hTree, _T("D-3-1-2"),hItem[7],TVI_LAST);
|
||
hItem[12] = InsertItem(hTree, _T("D-3-1-3"),hItem[7],TVI_LAST);
|
||
hItem[13] = InsertItem(hTree, _T("D-3-1-4"),hItem[7],TVI_LAST);
|
||
hItem[14] = InsertItem(hTree, _T("D-3-1-5"),hItem[7],TVI_LAST);
|
||
hItem[15] = InsertItem(hTree, _T("D-3-1-6"),hItem[7],TVI_LAST);
|
||
hItem[13] = InsertItem(hTree, _T("E"),TVI_ROOT,TVI_LAST);
|
||
*/
|
||
////////////////////////////////////
|
||
|
||
}
|
||
|
||
static void
|
||
WriteIniFile(HWND hTree, LPCWSTR lpszIniFile)
|
||
{
|
||
// Ouverture en <20>criture (avec cr<63>ation de fichier si celui-ci n'esistait pas d<>j<EFBFBD>)
|
||
// d'un flux en mode texte, avec permission de lecture seule.
|
||
#if 0
|
||
DWORD dwNumOfChars = ExpandEnvironmentStringsW(lpszIniFile, NULL, 0);
|
||
LPWSTR lpszFileName = MemAlloc(0, dwNumOfChars * sizeof(WCHAR));
|
||
ExpandEnvironmentStringsW(lpszIniFile, lpszFileName, dwNumOfChars);
|
||
#else
|
||
// HACK: delete these following lines when the program will be ready.
|
||
DWORD dwNumOfChars = ExpandEnvironmentStringsW(lpszIniFile, NULL, 0) + 11;
|
||
LPWSTR lpszFileName = (LPWSTR)MemAlloc(0, dwNumOfChars * sizeof(WCHAR));
|
||
ExpandEnvironmentStringsW(lpszIniFile, lpszFileName, dwNumOfChars);
|
||
wcscat(lpszFileName, L"__tests.ini");
|
||
// END HACK.
|
||
#endif
|
||
|
||
FILE* ini_file = _wfsopen(lpszFileName, L"wt", _SH_DENYRW); // w+t <-- write read text ; wt <-- write text
|
||
MemFree(lpszFileName);
|
||
|
||
if (!ini_file)
|
||
return; // error
|
||
|
||
|
||
TVITEMEXW tvItemEx;
|
||
WCHAR label[MAX_VALUE_NAME] = L"";
|
||
// WCHAR szLine[MAX_VALUE_NAME] = L"";
|
||
|
||
// for (HTREEITEM htiIterator = TreeView_GetRoot(hTree) ; htiIterator ; htiIterator = TreeView_GetNextSibling(hTree, htiIterator))
|
||
for (HTREEITEM htiIterator = TreeView_GetFirst(hTree) ; htiIterator ; htiIterator = TreeView_GetNext(hTree, htiIterator))
|
||
{
|
||
SecureZeroMemory(&tvItemEx, sizeof(tvItemEx));
|
||
|
||
tvItemEx.hItem = htiIterator; // Handle of the item to be retrieved.
|
||
tvItemEx.mask = TVIF_HANDLE | TVIF_TEXT;
|
||
tvItemEx.pszText = label;
|
||
tvItemEx.cchTextMax = MAX_VALUE_NAME;
|
||
TreeView_GetItem(hTree, &tvItemEx);
|
||
|
||
// Write into the file.
|
||
wcscat(label, L"\n");
|
||
fputws(label, ini_file);
|
||
}
|
||
|
||
fclose(ini_file);
|
||
return;
|
||
}
|
||
|
||
static void
|
||
Update_Btn_States(HWND hDlg)
|
||
{
|
||
HWND hTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
HTREEITEM hti = TreeView_GetSelection(hTree);
|
||
HTREEITEM htiPrev = TreeView_GetPrevSibling(hTree, hti);
|
||
HTREEITEM htiNext = TreeView_GetNextSibling(hTree, hti);
|
||
|
||
//
|
||
// "Up" / "Down" buttons.
|
||
//
|
||
if (htiPrev)
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_UP), TRUE);
|
||
else
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_UP), FALSE);
|
||
|
||
if (htiNext)
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DOWN), TRUE);
|
||
else
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DOWN), FALSE);
|
||
|
||
//
|
||
// "Enable" / "Disable" buttons.
|
||
//
|
||
UINT uCheckState = TreeView_GetCheckState(hTree, hti);
|
||
if (uCheckState == 0)
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE) , TRUE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE), FALSE);
|
||
}
|
||
else if (uCheckState == 1)
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE) , FALSE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE), TRUE);
|
||
}
|
||
else if (uCheckState == 2)
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE) , TRUE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE), TRUE);
|
||
}
|
||
else
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE) , FALSE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE), FALSE);
|
||
}
|
||
|
||
//
|
||
// "Enable all" / "Disable all" buttons.
|
||
//
|
||
UINT uRootCheckState = TreeView_GetRealSubtreeState(hTree, TVI_ROOT);
|
||
if (uRootCheckState == 0)
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE_ALL) , TRUE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE_ALL), FALSE);
|
||
}
|
||
else if (uRootCheckState == 1)
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE_ALL) , FALSE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE_ALL), TRUE);
|
||
}
|
||
else if (uRootCheckState == 2)
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE_ALL) , TRUE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE_ALL), TRUE);
|
||
}
|
||
else
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_ENABLE_ALL) , FALSE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DISABLE_ALL), FALSE);
|
||
}
|
||
|
||
//
|
||
// "Search" / "Edit" / "Delete" buttons.
|
||
//
|
||
if (TreeView_GetRoot(hTree))
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_FIND) , TRUE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_EDIT) , TRUE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DELETE), TRUE);
|
||
}
|
||
else
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_FIND) , FALSE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_EDIT) , FALSE);
|
||
EnableWindow(GetDlgItem(hDlg, IDC_BTN_SYSTEM_DELETE), FALSE);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
INT_PTR
|
||
CommonWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
UNREFERENCED_PARAMETER(lParam);
|
||
UNREFERENCED_PARAMETER(wParam);
|
||
|
||
switch (message)
|
||
{
|
||
case WM_INITDIALOG:
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
//
|
||
// Initialize the styles.
|
||
//
|
||
TreeView_Set3StateCheck(hSystemTree);
|
||
SetWindowTheme(hSystemTree, L"Explorer", NULL);
|
||
|
||
TreeView_SetIndent(hSystemTree, TreeView_GetIndent(hSystemTree) + 2);
|
||
|
||
/* Load data */
|
||
LoadIniFile(hSystemTree, (LPCWSTR)((LPPROPSHEETPAGE)lParam)->lParam);
|
||
|
||
/* Select the first item */
|
||
TreeView_SelectItem(hSystemTree, TreeView_GetRoot(hSystemTree)); // Is it really necessary?
|
||
SetFocus(hSystemTree);
|
||
|
||
Update_Btn_States(hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case WM_DESTROY:
|
||
{
|
||
TreeView_Cleanup(GetDlgItem(hDlg, IDC_SYSTEM_TREE));
|
||
return FALSE;
|
||
}
|
||
|
||
case WM_COMMAND:
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
switch (LOWORD(wParam))
|
||
{
|
||
case IDC_BTN_SYSTEM_UP:
|
||
{
|
||
TreeView_UpItem(hSystemTree, TreeView_GetSelection(hSystemTree));
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_DOWN:
|
||
{
|
||
TreeView_DownItem(hSystemTree, TreeView_GetSelection(hSystemTree));
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_ENABLE:
|
||
{
|
||
HTREEITEM hItem = TreeView_GetSelection(hSystemTree);
|
||
TreeView_SetBOOLCheck(hSystemTree, hItem, TRUE, TRUE);
|
||
TreeView_SelectItem(hSystemTree, hItem);
|
||
Update_Btn_States(hDlg);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_ENABLE_ALL:
|
||
{
|
||
for (HTREEITEM htiIterator = TreeView_GetRoot(hSystemTree) ; htiIterator ; htiIterator = TreeView_GetNextSibling(hSystemTree, htiIterator))
|
||
TreeView_SetBOOLCheck(hSystemTree, htiIterator, TRUE, TRUE);
|
||
|
||
Update_Btn_States(hDlg);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_DISABLE:
|
||
{
|
||
HTREEITEM hItem = TreeView_GetSelection(hSystemTree);
|
||
TreeView_SetBOOLCheck(hSystemTree, hItem, FALSE, TRUE);
|
||
TreeView_SelectItem(hSystemTree, hItem);
|
||
|
||
Update_Btn_States(hDlg);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_DISABLE_ALL:
|
||
{
|
||
for (HTREEITEM htiIterator = TreeView_GetRoot(hSystemTree) ; htiIterator ; htiIterator = TreeView_GetNextSibling(hSystemTree, htiIterator))
|
||
TreeView_SetBOOLCheck(hSystemTree, htiIterator, FALSE, TRUE);
|
||
|
||
Update_Btn_States(hDlg);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_FIND:
|
||
{
|
||
DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_FIND_DIALOG), hDlg /* hMainWnd */, FindDialogWndProc, (LPARAM)hSystemTree);
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_NEW:
|
||
{
|
||
HTREEITEM hInsertAfter = TreeView_GetSelection(hSystemTree);
|
||
HTREEITEM hNewItem = InsertItem(hSystemTree, L"", TreeView_GetParent(hSystemTree, hInsertAfter), hInsertAfter);
|
||
TreeView_EditLabel(hSystemTree, hNewItem);
|
||
TreeView_SelectItem(hSystemTree, hNewItem);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_EDIT:
|
||
{
|
||
TreeView_EditLabel(hSystemTree, TreeView_GetSelection(hSystemTree));
|
||
return TRUE;
|
||
}
|
||
|
||
case IDC_BTN_SYSTEM_DELETE:
|
||
{
|
||
TreeView_DeleteItem(hSystemTree, TreeView_GetSelection(hSystemTree));
|
||
Update_Btn_States(hDlg);
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
return TRUE;
|
||
}
|
||
|
||
default:
|
||
return FALSE;
|
||
}
|
||
// return FALSE;
|
||
}
|
||
|
||
case UM_CHECKSTATECHANGE:
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
/* Retrieve the new checked state of the item and handle the notification */
|
||
HTREEITEM hItemChanged = (HTREEITEM)lParam;
|
||
|
||
//
|
||
// State before | State after
|
||
// -------------------------------
|
||
// 0 (unchecked) | 1 (checked)
|
||
// 1 (checked) | 0 (unchecked)
|
||
// 2 (grayed) | 1 (checked) --> this case corresponds to the former
|
||
// | with 0 == 2 mod 2.
|
||
//
|
||
UINT uiCheckState = TreeView_GetCheckState(hSystemTree, hItemChanged) % 2;
|
||
TreeView_SetBOOLCheck(hSystemTree, hItemChanged, uiCheckState ? FALSE : TRUE, TRUE);
|
||
TreeView_SelectItem(hSystemTree, hItemChanged);
|
||
Update_Btn_States(hDlg);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case WM_NOTIFY:
|
||
{
|
||
if (((LPNMHDR)lParam)->idFrom == IDC_SYSTEM_TREE)
|
||
{
|
||
switch (((LPNMHDR)lParam)->code)
|
||
{
|
||
case NM_CLICK:
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
DWORD dwpos = GetMessagePos();
|
||
TVHITTESTINFO ht = {};
|
||
ht.pt.x = GET_X_LPARAM(dwpos);
|
||
ht.pt.y = GET_Y_LPARAM(dwpos);
|
||
MapWindowPoints(HWND_DESKTOP /*NULL*/, hSystemTree, &ht.pt, 1);
|
||
|
||
TreeView_HitTest(hSystemTree, &ht);
|
||
|
||
if (TVHT_ONITEMSTATEICON & ht.flags)
|
||
{
|
||
PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)ht.hItem);
|
||
|
||
// Disable default behaviour. Needed for the UM_CHECKSTATECHANGE
|
||
// custom notification to work as expected.
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE);
|
||
}
|
||
/*
|
||
else
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
|
||
*/
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case TVN_KEYDOWN:
|
||
{
|
||
if (((LPNMTVKEYDOWN)lParam)->wVKey == VK_SPACE)
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
HTREEITEM hti = TreeView_GetSelection(hSystemTree);
|
||
|
||
// Hack the tree item state. This is needed because whether or not
|
||
// TRUE is being returned, the default implementation of SysTreeView32
|
||
// is always being processed for a key down !
|
||
if (GetWindowLongPtr(hSystemTree, GWL_STYLE) & TVS_CHECKBOXES)
|
||
{
|
||
TreeView_SetItemState(hSystemTree, hti, INDEXTOSTATEIMAGEMASK(TreeView_GetCheckState(hSystemTree, hti)), TVIS_STATEIMAGEMASK);
|
||
}
|
||
|
||
PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)hti);
|
||
|
||
// Disable default behaviour. Needed for the UM_CHECKSTATECHANGE
|
||
// custom notification to work as expected.
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
case TVN_ENDLABELEDIT:
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
/*
|
||
* Ehh yes, we have to deal with a "dialog proc", which is quite different from a "window proc":
|
||
*
|
||
* (excerpt from: MSDN library http://msdn.microsoft.com/en-us/library/ms645469(VS.85).aspx)
|
||
*
|
||
* Return Value
|
||
* ============
|
||
* INT_PTR
|
||
*
|
||
* Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not.
|
||
* If the dialog box procedure returns FALSE, the dialog manager performs the default dialog operation in response
|
||
* to the message.
|
||
*
|
||
* If the dialog box procedure processes a message that requires a specific return value, the dialog box procedure
|
||
* should set the desired return value by calling SetWindowLong(hwndDlg, DWLP_MSGRESULT, lResult) immediately before
|
||
* returning TRUE. Note that you must call SetWindowLong immediately before returning TRUE; doing so earlier may result
|
||
* in the DWLP_MSGRESULT value being overwritten by a nested dialog box message.
|
||
*
|
||
* [...]
|
||
*
|
||
* Remarks
|
||
* =======
|
||
* You should use the dialog box procedure only if you use the dialog box class for the dialog box. This is the default
|
||
* class and is used when no explicit class is specified in the dialog box template. Although the dialog box procedure
|
||
* is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted
|
||
* messages are processed internally by the dialog box window procedure.
|
||
*
|
||
*/
|
||
|
||
// A arranger un peu ???? Certainement.
|
||
TVITEMW truc = ((LPNMTVDISPINFO)lParam)->item;
|
||
if (truc.pszText)
|
||
{
|
||
if (!*truc.pszText)
|
||
TreeView_DeleteItem(hSystemTree, truc.hItem);
|
||
|
||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE);
|
||
}
|
||
else
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
|
||
|
||
Update_Btn_States(hDlg);
|
||
return TRUE;
|
||
}
|
||
|
||
case TVN_SELCHANGED:
|
||
Update_Btn_States(hDlg);
|
||
return TRUE;
|
||
|
||
default:
|
||
return FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
switch (((LPNMHDR)lParam)->code)
|
||
{
|
||
case PSN_APPLY:
|
||
{
|
||
// TODO: Enum the items.
|
||
// HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
//
|
||
PropSheet_CancelToClose(GetParent(hDlg));
|
||
|
||
/* TODO: see :
|
||
*
|
||
* dll/win32/devmgr/advprop.c: PropSheet_RebootSystem(hwndDlg);
|
||
* include/psdk/prsht.h:#define PropSheet_RebootSystem(d) SendMessage(d,PSM_REBOOTSYSTEM,0,0)
|
||
*
|
||
* dll/shellext/deskadp/deskadp.c: PropSheet_RestartWindows(GetParent(This->hwndDlg));
|
||
* dll/shellext/deskmon/deskmon.c: PropSheet_RestartWindows(GetParent(This->hwndDlg));
|
||
* include/psdk/prsht.h:#define PropSheet_RestartWindows(d) SendMessage(d,PSM_RESTARTWINDOWS,0,0)
|
||
*
|
||
* for their usage.
|
||
*/
|
||
PropSheet_RebootSystem(GetParent(hDlg));
|
||
//PropSheet_RestartWindows(GetParent(hDlg));
|
||
|
||
WriteIniFile(GetDlgItem(hDlg, IDC_SYSTEM_TREE), (LPCWSTR)wParam);
|
||
|
||
// Since there are nothing to modify, applying modifications
|
||
// cannot return any error.
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
|
||
//PropSheet_UnChanged(GetParent(hDlg) /*hMainWnd*/, hDlg);
|
||
return TRUE;
|
||
}
|
||
|
||
case PSN_HELP:
|
||
{
|
||
MessageBox(hDlg, _T("Help not implemented yet!"), _T("Help"), MB_ICONINFORMATION | MB_OK);
|
||
return TRUE;
|
||
}
|
||
|
||
case PSN_KILLACTIVE: // Is going to lose activation.
|
||
{
|
||
// Changes are always valid of course.
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
|
||
return TRUE;
|
||
}
|
||
|
||
case PSN_QUERYCANCEL:
|
||
{
|
||
// Allows cancellation since there are nothing to cancel...
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
|
||
return TRUE;
|
||
}
|
||
|
||
case PSN_QUERYINITIALFOCUS:
|
||
{
|
||
HWND hSystemTree = GetDlgItem(hDlg, IDC_SYSTEM_TREE);
|
||
|
||
// Give the focus on and select the first item.
|
||
ListView_SetItemState(hSystemTree, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
|
||
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LONG_PTR)hSystemTree);
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// DO NOT TOUCH THESE NEXT MESSAGES, THEY ARE OK LIKE THIS...
|
||
//
|
||
case PSN_RESET: // Perform final cleaning, called before WM_DESTROY.
|
||
return TRUE;
|
||
|
||
case PSN_SETACTIVE: // Is going to gain activation.
|
||
{
|
||
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
|
||
return TRUE;
|
||
}
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
default:
|
||
return FALSE;
|
||
}
|
||
|
||
// return FALSE;
|
||
}
|
||
|
||
|
||
extern "C" {
|
||
|
||
INT_PTR CALLBACK
|
||
SystemPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
static LPCWSTR lpszIniFile = NULL;
|
||
|
||
if (message == WM_INITDIALOG)
|
||
lpszIniFile = (LPCWSTR)((LPPROPSHEETPAGE)lParam)->lParam;
|
||
|
||
if ( (message == WM_NOTIFY) && (((LPNMHDR)lParam)->code == PSN_APPLY) )
|
||
wParam = (WPARAM)lpszIniFile;
|
||
|
||
return CommonWndProc(hDlg, message, wParam, lParam);
|
||
}
|
||
|
||
INT_PTR CALLBACK
|
||
WinPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
static LPCWSTR lpszIniFile = NULL;
|
||
|
||
if (message == WM_INITDIALOG)
|
||
lpszIniFile = (LPCWSTR)((LPPROPSHEETPAGE)lParam)->lParam;
|
||
|
||
if ( (message == WM_NOTIFY) && (((LPNMHDR)lParam)->code == PSN_APPLY) )
|
||
wParam = (WPARAM)lpszIniFile;
|
||
|
||
return CommonWndProc(hDlg, message, wParam, lParam);
|
||
}
|
||
|
||
}
|