Something went wrong. Try again.
Reactos
Something went wrong. Try again.
17 kB · 526 lines
C++
at listview
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527/* * PROJECT: ReactOS Applications * LICENSE: LGPL - See COPYING in the top level directory * FILE: base/applications/msconfig_new/toolspage.cpp * PURPOSE: Tools page message handler * COPYRIGHT: Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de> * Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr> */
#include "precomp.h"#include "xmldomparser.hpp"#include "utils.h"#include "listview.h"#include "uxthemesupp.h"
static HWND hToolsPage = NULL;static HWND hToolsListCtrl = NULL;static int iToolsPageSortedColumn = 0;
struct TOOL{ TOOL(const _bstr_t& Command, const _bstr_t& DefParam, const _bstr_t& AdvParam) : m_Command(Command), m_DefParam(DefParam), m_AdvParam(AdvParam) { }
~TOOL(void) { }
DWORD Run(BOOL bUseAdvParams) { return RunCommand(m_Command, bUseAdvParams ? m_AdvParam : m_DefParam, SW_SHOW); }
_bstr_t m_Command; _bstr_t m_DefParam; _bstr_t m_AdvParam;};
static void AddTool(IXMLDOMElement*, BOOL);
static HRESULTParseToolsList(IXMLDOMDocument* pXMLDom, BOOL bIsStandard){ static const _bstr_t XMLFileTag(L"MSCONFIGTOOLFILE"); static const _bstr_t XMLToolsTag(L"MSCONFIGTOOLS");
HRESULT hr = S_OK;
IXMLDOMNode *pIterator = NULL, *pTmp = NULL; IXMLDOMElement* pEl = NULL; DOMNodeType type; _bstr_t tagName;
if (!pXMLDom) return E_POINTER; // E_INVALIDARG
pXMLDom->get_documentElement(&pEl);
pEl->get_tagName(&tagName.GetBSTR()); _wcsupr(tagName); if (tagName == XMLFileTag) { pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl); while (pIterator) { pIterator->get_nodeType(&type); if (type == NODE_ELEMENT) { pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);
pEl->get_tagName(&tagName.GetBSTR()); _wcsupr(tagName); if (tagName == XMLToolsTag) { pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl); while (pIterator) { pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */); AddTool(pEl, bIsStandard); SAFE_RELEASE(pEl);
pIterator->get_nextSibling(&pTmp); SAFE_RELEASE(pIterator); pIterator = pTmp; } // SAFE_RELEASE(pIterator);
break; }
SAFE_RELEASE(pEl); }
pIterator->get_nextSibling(&pTmp); SAFE_RELEASE(pIterator); pIterator = pTmp; } // SAFE_RELEASE(pIterator); } else if (tagName == XMLToolsTag) { pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl); while (pIterator) { pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */); AddTool(pEl, bIsStandard); SAFE_RELEASE(pEl);
pIterator->get_nextSibling(&pTmp); SAFE_RELEASE(pIterator); pIterator = pTmp; } // SAFE_RELEASE(pIterator); }
SAFE_RELEASE(pEl);
return hr;}
static voidAddItem(BOOL bIsStandard, const _bstr_t& name, const _bstr_t& descr, TOOL* tool){ LPWSTR lpszStandard; LVITEM item = {};
assert(tool);
item.mask = LVIF_TEXT | LVIF_PARAM; item.lParam = (LPARAM)tool;
item.pszText = (LPWSTR)name; item.iSubItem = 0; // item.iItem = ListView_GetItemCount(hToolsListCtrl);
ListView_InsertItem(hToolsListCtrl, &item);
if (bIsStandard) { lpszStandard = LoadResourceString(hInst, IDS_YES); ListView_SetItemText(hToolsListCtrl, item.iItem, 1, lpszStandard); MemFree(lpszStandard); } else { lpszStandard = LoadResourceString(hInst, IDS_NO); ListView_SetItemText(hToolsListCtrl, item.iItem, 1, lpszStandard); MemFree(lpszStandard); }
ListView_SetItemText(hToolsListCtrl, item.iItem, 2, (LPWSTR)descr);}
static voidAddTool(IXMLDOMElement* pXMLTool, BOOL bIsStandard){ TOOL* tool; _variant_t varLocID, varName, varPath, varDefOpt, varAdvOpt, varHelp;
assert(pXMLTool);
pXMLTool->getAttribute(_bstr_t(L"_locID") , &varLocID ); pXMLTool->getAttribute(_bstr_t(L"NAME") , &varName ); pXMLTool->getAttribute(_bstr_t(L"PATH") , &varPath ); pXMLTool->getAttribute(_bstr_t(L"DEFAULT_OPT"), &varDefOpt); pXMLTool->getAttribute(_bstr_t(L"ADV_OPT") , &varAdvOpt); pXMLTool->getAttribute(_bstr_t(L"HELP") , &varHelp );
// TODO: check if the tool really exists... ??
tool = new TOOL(_bstr_t(varPath), _bstr_t(varDefOpt), _bstr_t(varAdvOpt)); AddItem(bIsStandard, _bstr_t(varName), _bstr_t(varHelp), tool);}
static voidFillListView(void){ IXMLDOMDocument* pXMLDom = NULL;
if (!SUCCEEDED(InitXMLDOMParser())) return;
if (SUCCEEDED(CreateAndInitXMLDOMDocument(&pXMLDom))) { // Load the internal tools list. if (LoadXMLDocumentFromResource(pXMLDom, L"MSCFGTL.XML")) ParseToolsList(pXMLDom, TRUE);
// Try to load the user-provided tools list. If it doesn't exist, // then the second list-view's column "Standard" tool is removed. if (LoadXMLDocumentFromFile(pXMLDom, L"MSCFGTLC.XML", TRUE)) ParseToolsList(pXMLDom, FALSE); else ListView_DeleteColumn(hToolsListCtrl, 1); }
SAFE_RELEASE(pXMLDom); UninitXMLDOMParser();}
static size_tBuildCommandLine(LPWSTR lpszDest, LPCWSTR lpszCmdLine, LPCWSTR lpszParam, size_t bufSize){ size_t numOfChars = 0; // The null character is counted in ExpandEnvironmentStrings(...). // TODO: Take into account the "plus one" for numOfChars for ANSI version (see MSDN for more details).
if (lpszCmdLine && *lpszCmdLine) { numOfChars += ExpandEnvironmentStringsW(lpszCmdLine, NULL, 0); if (lpszDest) ExpandEnvironmentStringsW(lpszCmdLine, lpszDest, (DWORD)bufSize); // TODO: size_t to DWORD conversion !
if (lpszParam && *lpszParam) { ++numOfChars; if (lpszDest) wcscat(lpszDest, L" "); } }
if (lpszParam && *lpszParam) { numOfChars += wcslen(lpszParam); if (lpszDest) wcscat(lpszDest, lpszParam); }
return numOfChars;}
static void Update_States(int iSelectedItem){ TOOL* tool; LVITEM item = {};
assert(hToolsPage);
item.mask = LVIF_PARAM; item.iItem = iSelectedItem;
if (ListView_GetItem(hToolsListCtrl, &item)) // (item.iItem > -1) // TODO: corriger ailleurs ce genre de code... { LPWSTR lpszCmdLine = NULL; size_t numOfChars = 0; tool = reinterpret_cast<TOOL*>(item.lParam);
ListView_EnsureVisible(hToolsListCtrl, item.iItem, FALSE);
Button_Enable(GetDlgItem(hToolsPage, IDC_BTN_RUN), TRUE);
if (!*(wchar_t*)tool->m_AdvParam) { ShowWindow(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), SW_HIDE); Button_Enable(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), FALSE); } else { Button_Enable(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), TRUE); ShowWindow(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), SW_NORMAL); }
if ( (Button_IsEnabled(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT))) && (Button_GetCheck(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT)) == BST_CHECKED) ) { numOfChars = BuildCommandLine(NULL, tool->m_Command, tool->m_AdvParam, 0); lpszCmdLine = (LPWSTR)MemAlloc(0, numOfChars * sizeof(WCHAR)); BuildCommandLine(lpszCmdLine, tool->m_Command, tool->m_AdvParam, numOfChars); } else { numOfChars = BuildCommandLine(NULL, tool->m_Command, tool->m_DefParam, 0); lpszCmdLine = (LPWSTR)MemAlloc(0, numOfChars * sizeof(WCHAR)); BuildCommandLine(lpszCmdLine, tool->m_Command, tool->m_DefParam, numOfChars); }
SendDlgItemMessage(hToolsPage, IDC_TOOLS_CMDLINE, WM_SETTEXT, 0, (LPARAM)lpszCmdLine);
MemFree(lpszCmdLine); } else { ShowWindow(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), SW_HIDE); Button_Enable(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), FALSE); Button_Enable(GetDlgItem(hToolsPage, IDC_BTN_RUN), FALSE); }}
static BOOL RunSelectedTool(VOID){ BOOL Success = FALSE; BOOL bUseAdvParams;
LVITEM item = {}; item.mask = LVIF_PARAM; item.iItem = ListView_GetSelectionMark(hToolsListCtrl); ListView_GetItem(hToolsListCtrl, &item);
if (ListView_GetItem(hToolsListCtrl, &item)) // (item.iItem > -1) // TODO: corriger ailleurs ce genre de code... { if ( (Button_IsEnabled(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT))) && (Button_GetCheck(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT)) == BST_CHECKED) ) bUseAdvParams = TRUE; else bUseAdvParams = FALSE;
// Values greater (strictly) than 32 indicate success (see MSDN documentation for ShellExecute(...) API). Success = (reinterpret_cast<TOOL*>(item.lParam)->Run(bUseAdvParams) > 32); }
return Success;}
extern "C" {
INT_PTR CALLBACKToolsPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_INITDIALOG: { hToolsPage = hDlg; hToolsListCtrl = GetDlgItem(hToolsPage, IDC_TOOLS_LIST);
// // Initialize the styles. // DWORD dwStyle = ListView_GetExtendedListViewStyle(hToolsListCtrl); ListView_SetExtendedListViewStyle(hToolsListCtrl, dwStyle | LVS_EX_FULLROWSELECT); SetWindowTheme(hToolsListCtrl, L"Explorer", NULL);
// // Initialize the application page's controls. // LVCOLUMN column = {};
// First column : Tool's name. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_NAME); column.cx = 150; ListView_InsertColumn(hToolsListCtrl, 0, &column); MemFree(column.pszText);
// Second column : Whether the tool is a standard one or not. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_STANDARD); column.cx = 60; ListView_InsertColumn(hToolsListCtrl, 1, &column); MemFree(column.pszText);
// Third column : Description. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_DESCR); column.cx = 500; ListView_InsertColumn(hToolsListCtrl, 2, &column); MemFree(column.pszText);
// // Populate and sort the list. // FillListView(); ListView_Sort(hToolsListCtrl, 0);
// Force an update in case of an empty list (giving focus on it when empty won't emit a LVN_ITEMCHANGED message). Update_States(-1 /* Wrong index to initialize all the controls with their default state (i.e. disabled) */);
PropSheet_UnChanged(GetParent(hToolsPage), hToolsPage);
return TRUE; }
case WM_DESTROY: { LVITEM lvitem = {}; lvitem.mask = LVIF_PARAM; lvitem.iItem = -1; // From the beginning.
while ((lvitem.iItem = ListView_GetNextItem(hToolsListCtrl, lvitem.iItem, LVNI_ALL)) != -1) { // ListView_Update(); // Updates a list-view item. // ListView_FindItem(); // peut �tre int�ressant pour faire de la recherche it�rative � partir du nom (ou partie du...) de l'item.
ListView_GetItem(hToolsListCtrl, &lvitem);
delete reinterpret_cast<TOOL*>(lvitem.lParam); lvitem.lParam = NULL; } ListView_DeleteAllItems(hToolsListCtrl);
return 0; }
case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BTN_RUN: { RunSelectedTool(); return TRUE; }
case IDC_CBX_TOOLS_ADVOPT: { Update_States(ListView_GetSelectionMark(hToolsListCtrl)); return TRUE; }
default: return FALSE; } return FALSE; }
case WM_NOTIFY: { if (((LPNMHDR)lParam)->hwndFrom == hToolsListCtrl) { switch (((LPNMHDR)lParam)->code) { case LVN_ITEMCHANGED: { if ( (((LPNMLISTVIEW)lParam)->uChanged & LVIF_STATE) && /* The state has changed */ (((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ ) { Update_States(((LPNMLISTVIEW)lParam)->iItem); }
return TRUE; }
case NM_DBLCLK: case NM_RDBLCLK: { RunSelectedTool(); return TRUE; }
case LVN_COLUMNCLICK: { int iSortingColumn = ((LPNMLISTVIEW)lParam)->iSubItem;
ListView_SortEx(hToolsListCtrl, iSortingColumn, iToolsPageSortedColumn); iToolsPageSortedColumn = iSortingColumn;
return TRUE; }
default: break; } } else { switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { // Since there are nothing to modify, applying modifications // cannot return any error. SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, PSNRET_NOERROR); PropSheet_UnChanged(GetParent(hToolsPage), hToolsPage); return TRUE; }
case PSN_HELP: { MessageBoxW(hToolsPage, L"Help not implemented yet!", L"Help", MB_ICONINFORMATION | MB_OK); return TRUE; }
case PSN_KILLACTIVE: // Is going to lose activation. { // Changes are always valid of course. SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, FALSE); return TRUE; }
case PSN_QUERYCANCEL: { // Allows cancellation since there are nothing to cancel... SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, FALSE); return TRUE; }
case PSN_QUERYINITIALFOCUS: { // Give the focus on and select the first item. ListView_SetItemState(hToolsListCtrl, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, (LONG_PTR)hToolsListCtrl); 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(hToolsPage, DWLP_MSGRESULT, 0); return TRUE; }
default: break; } }
return FALSE; }
default: return FALSE; }
// return FALSE;}
}
/* EOF */