1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:     ReactOS Applications
3c2c66affSColin Finck  * LICENSE:     LGPL - See COPYING in the top level directory
4c2c66affSColin Finck  * FILE:        base/applications/msconfig_new/toolspage.cpp
5c2c66affSColin Finck  * PURPOSE:     Tools page message handler
6c2c66affSColin Finck  * COPYRIGHT:   Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
7c2c66affSColin Finck  *              Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr>
8c2c66affSColin Finck  */
9c2c66affSColin Finck 
10c2c66affSColin Finck #include "precomp.h"
11c2c66affSColin Finck #include "xmldomparser.hpp"
12c2c66affSColin Finck #include "utils.h"
13c2c66affSColin Finck #include "listview.h"
14c2c66affSColin Finck #include "uxthemesupp.h"
15c2c66affSColin Finck 
16c2c66affSColin Finck static HWND hToolsPage     = NULL;
17c2c66affSColin Finck static HWND hToolsListCtrl = NULL;
18*9ce192a8SAmine Khaldi static int  iToolsPageSortedColumn  = 0;
19c2c66affSColin Finck 
20c2c66affSColin Finck struct TOOL
21c2c66affSColin Finck {
TOOLTOOL22c2c66affSColin Finck     TOOL(const _bstr_t& Command,
23c2c66affSColin Finck          const _bstr_t& DefParam,
24c2c66affSColin Finck          const _bstr_t& AdvParam) :
25c2c66affSColin Finck         m_Command(Command),
26c2c66affSColin Finck         m_DefParam(DefParam),
27c2c66affSColin Finck         m_AdvParam(AdvParam)
28c2c66affSColin Finck     { }
29c2c66affSColin Finck 
~TOOLTOOL30c2c66affSColin Finck     ~TOOL(void)
31c2c66affSColin Finck     { }
32c2c66affSColin Finck 
RunTOOL33c2c66affSColin Finck     DWORD Run(BOOL bUseAdvParams)
34c2c66affSColin Finck     {
35c2c66affSColin Finck         return RunCommand(m_Command, bUseAdvParams ? m_AdvParam : m_DefParam, SW_SHOW);
36c2c66affSColin Finck     }
37c2c66affSColin Finck 
38c2c66affSColin Finck     _bstr_t m_Command;
39c2c66affSColin Finck     _bstr_t m_DefParam;
40c2c66affSColin Finck     _bstr_t m_AdvParam;
41c2c66affSColin Finck };
42c2c66affSColin Finck 
43c2c66affSColin Finck static void AddTool(IXMLDOMElement*, BOOL);
44c2c66affSColin Finck 
45c2c66affSColin Finck static HRESULT
ParseToolsList(IXMLDOMDocument * pXMLDom,BOOL bIsStandard)46c2c66affSColin Finck ParseToolsList(IXMLDOMDocument* pXMLDom, BOOL bIsStandard)
47c2c66affSColin Finck {
48c2c66affSColin Finck     static const _bstr_t XMLFileTag(L"MSCONFIGTOOLFILE");
49c2c66affSColin Finck     static const _bstr_t XMLToolsTag(L"MSCONFIGTOOLS");
50c2c66affSColin Finck 
51c2c66affSColin Finck     HRESULT hr = S_OK;
52c2c66affSColin Finck 
53c2c66affSColin Finck     IXMLDOMNode    *pIterator = NULL, *pTmp = NULL;
54c2c66affSColin Finck     IXMLDOMElement* pEl       = NULL;
55c2c66affSColin Finck     DOMNodeType     type;
56c2c66affSColin Finck     _bstr_t         tagName;
57c2c66affSColin Finck 
58c2c66affSColin Finck     if (!pXMLDom)
59c2c66affSColin Finck         return E_POINTER; // E_INVALIDARG
60c2c66affSColin Finck 
61c2c66affSColin Finck     pXMLDom->get_documentElement(&pEl);
62c2c66affSColin Finck 
63c2c66affSColin Finck     pEl->get_tagName(&tagName.GetBSTR());
64c2c66affSColin Finck     _wcsupr(tagName);
65c2c66affSColin Finck     if (tagName == XMLFileTag)
66c2c66affSColin Finck     {
67c2c66affSColin Finck         pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl);
68c2c66affSColin Finck         while (pIterator)
69c2c66affSColin Finck         {
70c2c66affSColin Finck             pIterator->get_nodeType(&type);
71c2c66affSColin Finck             if (type == NODE_ELEMENT)
72c2c66affSColin Finck             {
73c2c66affSColin Finck                 pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);
74c2c66affSColin Finck 
75c2c66affSColin Finck                 pEl->get_tagName(&tagName.GetBSTR());
76c2c66affSColin Finck                 _wcsupr(tagName);
77c2c66affSColin Finck                 if (tagName == XMLToolsTag)
78c2c66affSColin Finck                 {
79c2c66affSColin Finck                     pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl);
80c2c66affSColin Finck                     while (pIterator)
81c2c66affSColin Finck                     {
82c2c66affSColin Finck                         pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);
83c2c66affSColin Finck                         AddTool(pEl, bIsStandard);
84c2c66affSColin Finck                         SAFE_RELEASE(pEl);
85c2c66affSColin Finck 
86c2c66affSColin Finck                         pIterator->get_nextSibling(&pTmp);
87c2c66affSColin Finck                         SAFE_RELEASE(pIterator); pIterator = pTmp;
88c2c66affSColin Finck                     }
89c2c66affSColin Finck                     // SAFE_RELEASE(pIterator);
90c2c66affSColin Finck 
91c2c66affSColin Finck                     break;
92c2c66affSColin Finck                 }
93c2c66affSColin Finck 
94c2c66affSColin Finck                 SAFE_RELEASE(pEl);
95c2c66affSColin Finck             }
96c2c66affSColin Finck 
97c2c66affSColin Finck             pIterator->get_nextSibling(&pTmp);
98c2c66affSColin Finck             SAFE_RELEASE(pIterator); pIterator = pTmp;
99c2c66affSColin Finck         }
100c2c66affSColin Finck         // SAFE_RELEASE(pIterator);
101c2c66affSColin Finck     }
102c2c66affSColin Finck     else if (tagName == XMLToolsTag)
103c2c66affSColin Finck     {
104c2c66affSColin Finck         pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl);
105c2c66affSColin Finck         while (pIterator)
106c2c66affSColin Finck         {
107c2c66affSColin Finck             pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);
108c2c66affSColin Finck             AddTool(pEl, bIsStandard);
109c2c66affSColin Finck             SAFE_RELEASE(pEl);
110c2c66affSColin Finck 
111c2c66affSColin Finck             pIterator->get_nextSibling(&pTmp);
112c2c66affSColin Finck             SAFE_RELEASE(pIterator); pIterator = pTmp;
113c2c66affSColin Finck         }
114c2c66affSColin Finck         // SAFE_RELEASE(pIterator);
115c2c66affSColin Finck     }
116c2c66affSColin Finck 
117c2c66affSColin Finck     SAFE_RELEASE(pEl);
118c2c66affSColin Finck 
119c2c66affSColin Finck     return hr;
120c2c66affSColin Finck }
121c2c66affSColin Finck 
122c2c66affSColin Finck static void
AddItem(BOOL bIsStandard,const _bstr_t & name,const _bstr_t & descr,TOOL * tool)123c2c66affSColin Finck AddItem(BOOL bIsStandard, const _bstr_t& name, const _bstr_t& descr, TOOL* tool)
124c2c66affSColin Finck {
125c2c66affSColin Finck     LPWSTR lpszStandard;
126c2c66affSColin Finck     LVITEM item = {};
127c2c66affSColin Finck 
128c2c66affSColin Finck     assert(tool);
129c2c66affSColin Finck 
130c2c66affSColin Finck     item.mask   = LVIF_TEXT | LVIF_PARAM;
131c2c66affSColin Finck     item.lParam = (LPARAM)tool;
132c2c66affSColin Finck 
133c2c66affSColin Finck     item.pszText  = (LPWSTR)name;
134c2c66affSColin Finck     item.iSubItem = 0;
135c2c66affSColin Finck     // item.iItem    = ListView_GetItemCount(hToolsListCtrl);
136c2c66affSColin Finck 
137c2c66affSColin Finck     ListView_InsertItem(hToolsListCtrl, &item);
138c2c66affSColin Finck 
139c2c66affSColin Finck     if (bIsStandard)
140c2c66affSColin Finck     {
141c2c66affSColin Finck         lpszStandard = LoadResourceString(hInst, IDS_YES);
142c2c66affSColin Finck         ListView_SetItemText(hToolsListCtrl, item.iItem, 1, lpszStandard);
143c2c66affSColin Finck         MemFree(lpszStandard);
144c2c66affSColin Finck     }
145c2c66affSColin Finck     else
146c2c66affSColin Finck     {
147c2c66affSColin Finck         lpszStandard = LoadResourceString(hInst, IDS_NO);
148c2c66affSColin Finck         ListView_SetItemText(hToolsListCtrl, item.iItem, 1, lpszStandard);
149c2c66affSColin Finck         MemFree(lpszStandard);
150c2c66affSColin Finck     }
151c2c66affSColin Finck 
152c2c66affSColin Finck     ListView_SetItemText(hToolsListCtrl, item.iItem, 2, (LPWSTR)descr);
153c2c66affSColin Finck }
154c2c66affSColin Finck 
155c2c66affSColin Finck static void
AddTool(IXMLDOMElement * pXMLTool,BOOL bIsStandard)156c2c66affSColin Finck AddTool(IXMLDOMElement* pXMLTool, BOOL bIsStandard)
157c2c66affSColin Finck {
158c2c66affSColin Finck     TOOL* tool;
159c2c66affSColin Finck     _variant_t varLocID, varName, varPath,
160c2c66affSColin Finck                varDefOpt, varAdvOpt, varHelp;
161c2c66affSColin Finck 
162c2c66affSColin Finck     assert(pXMLTool);
163c2c66affSColin Finck 
164c2c66affSColin Finck     pXMLTool->getAttribute(_bstr_t(L"_locID")     , &varLocID );
165c2c66affSColin Finck     pXMLTool->getAttribute(_bstr_t(L"NAME")       , &varName  );
166c2c66affSColin Finck     pXMLTool->getAttribute(_bstr_t(L"PATH")       , &varPath  );
167c2c66affSColin Finck     pXMLTool->getAttribute(_bstr_t(L"DEFAULT_OPT"), &varDefOpt);
168c2c66affSColin Finck     pXMLTool->getAttribute(_bstr_t(L"ADV_OPT")    , &varAdvOpt);
169c2c66affSColin Finck     pXMLTool->getAttribute(_bstr_t(L"HELP")       , &varHelp  );
170c2c66affSColin Finck 
171c2c66affSColin Finck     // TODO: check if the tool really exists... ??
172c2c66affSColin Finck 
173c2c66affSColin Finck     tool = new TOOL(_bstr_t(varPath), _bstr_t(varDefOpt), _bstr_t(varAdvOpt));
174c2c66affSColin Finck     AddItem(bIsStandard, _bstr_t(varName), _bstr_t(varHelp), tool);
175c2c66affSColin Finck }
176c2c66affSColin Finck 
177c2c66affSColin Finck static void
FillListView(void)178c2c66affSColin Finck FillListView(void)
179c2c66affSColin Finck {
180c2c66affSColin Finck     IXMLDOMDocument* pXMLDom = NULL;
181c2c66affSColin Finck 
182c2c66affSColin Finck     if (!SUCCEEDED(InitXMLDOMParser()))
183c2c66affSColin Finck         return;
184c2c66affSColin Finck 
185c2c66affSColin Finck     if (SUCCEEDED(CreateAndInitXMLDOMDocument(&pXMLDom)))
186c2c66affSColin Finck     {
187c2c66affSColin Finck         // Load the internal tools list.
188c2c66affSColin Finck         if (LoadXMLDocumentFromResource(pXMLDom, L"MSCFGTL.XML"))
189c2c66affSColin Finck             ParseToolsList(pXMLDom, TRUE);
190c2c66affSColin Finck 
191c2c66affSColin Finck         // Try to load the user-provided tools list. If it doesn't exist,
192c2c66affSColin Finck         // then the second list-view's column "Standard" tool is removed.
193c2c66affSColin Finck         if (LoadXMLDocumentFromFile(pXMLDom, L"MSCFGTLC.XML", TRUE))
194c2c66affSColin Finck             ParseToolsList(pXMLDom, FALSE);
195c2c66affSColin Finck         else
196c2c66affSColin Finck             ListView_DeleteColumn(hToolsListCtrl, 1);
197c2c66affSColin Finck     }
198c2c66affSColin Finck 
199c2c66affSColin Finck     SAFE_RELEASE(pXMLDom);
200c2c66affSColin Finck     UninitXMLDOMParser();
201c2c66affSColin Finck }
202c2c66affSColin Finck 
203c2c66affSColin Finck static size_t
BuildCommandLine(LPWSTR lpszDest,LPCWSTR lpszCmdLine,LPCWSTR lpszParam,size_t bufSize)204c2c66affSColin Finck BuildCommandLine(LPWSTR lpszDest, LPCWSTR lpszCmdLine, LPCWSTR lpszParam, size_t bufSize)
205c2c66affSColin Finck {
206c2c66affSColin Finck     size_t numOfChars = 0; // The null character is counted in ExpandEnvironmentStrings(...).
207c2c66affSColin Finck     // TODO: Take into account the "plus one" for numOfChars for ANSI version (see MSDN for more details).
208c2c66affSColin Finck 
209c2c66affSColin Finck     if (lpszCmdLine && *lpszCmdLine)
210c2c66affSColin Finck     {
211c2c66affSColin Finck         numOfChars += ExpandEnvironmentStringsW(lpszCmdLine, NULL, 0);
212c2c66affSColin Finck         if (lpszDest)
213c2c66affSColin Finck             ExpandEnvironmentStringsW(lpszCmdLine, lpszDest, (DWORD)bufSize); // TODO: size_t to DWORD conversion !
214c2c66affSColin Finck 
215c2c66affSColin Finck         if (lpszParam && *lpszParam)
216c2c66affSColin Finck         {
217c2c66affSColin Finck             ++numOfChars;
218c2c66affSColin Finck             if (lpszDest)
219c2c66affSColin Finck                 wcscat(lpszDest, L" ");
220c2c66affSColin Finck         }
221c2c66affSColin Finck     }
222c2c66affSColin Finck 
223c2c66affSColin Finck     if (lpszParam && *lpszParam)
224c2c66affSColin Finck     {
225c2c66affSColin Finck         numOfChars += wcslen(lpszParam);
226c2c66affSColin Finck         if (lpszDest)
227c2c66affSColin Finck             wcscat(lpszDest, lpszParam);
228c2c66affSColin Finck     }
229c2c66affSColin Finck 
230c2c66affSColin Finck     return numOfChars;
231c2c66affSColin Finck }
232c2c66affSColin Finck 
Update_States(int iSelectedItem)233c2c66affSColin Finck static void Update_States(int iSelectedItem)
234c2c66affSColin Finck {
235c2c66affSColin Finck     TOOL* tool;
236c2c66affSColin Finck     LVITEM item = {};
237c2c66affSColin Finck 
238c2c66affSColin Finck     assert(hToolsPage);
239c2c66affSColin Finck 
240c2c66affSColin Finck     item.mask  = LVIF_PARAM;
241c2c66affSColin Finck     item.iItem = iSelectedItem;
242c2c66affSColin Finck 
243c2c66affSColin Finck     if (ListView_GetItem(hToolsListCtrl, &item)) // (item.iItem > -1) // TODO: corriger ailleurs ce genre de code...
244c2c66affSColin Finck     {
245c2c66affSColin Finck         LPWSTR lpszCmdLine = NULL;
246c2c66affSColin Finck         size_t numOfChars  = 0;
247c2c66affSColin Finck         tool = reinterpret_cast<TOOL*>(item.lParam);
248c2c66affSColin Finck 
249c2c66affSColin Finck         ListView_EnsureVisible(hToolsListCtrl, item.iItem, FALSE);
250c2c66affSColin Finck 
251c2c66affSColin Finck         Button_Enable(GetDlgItem(hToolsPage, IDC_BTN_RUN), TRUE);
252c2c66affSColin Finck 
253c2c66affSColin Finck         if (!*(wchar_t*)tool->m_AdvParam)
254c2c66affSColin Finck         {
255c2c66affSColin Finck             ShowWindow(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), SW_HIDE);
256c2c66affSColin Finck             Button_Enable(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), FALSE);
257c2c66affSColin Finck         }
258c2c66affSColin Finck         else
259c2c66affSColin Finck         {
260c2c66affSColin Finck             Button_Enable(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), TRUE);
261c2c66affSColin Finck             ShowWindow(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), SW_NORMAL);
262c2c66affSColin Finck         }
263c2c66affSColin Finck 
264c2c66affSColin Finck         if ( (Button_IsEnabled(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT))) &&
265c2c66affSColin Finck              (Button_GetCheck(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT)) == BST_CHECKED) )
266c2c66affSColin Finck         {
267c2c66affSColin Finck             numOfChars = BuildCommandLine(NULL, tool->m_Command, tool->m_AdvParam, 0);
268c2c66affSColin Finck             lpszCmdLine = (LPWSTR)MemAlloc(0, numOfChars * sizeof(WCHAR));
269c2c66affSColin Finck             BuildCommandLine(lpszCmdLine, tool->m_Command, tool->m_AdvParam, numOfChars);
270c2c66affSColin Finck         }
271c2c66affSColin Finck         else
272c2c66affSColin Finck         {
273c2c66affSColin Finck             numOfChars = BuildCommandLine(NULL, tool->m_Command, tool->m_DefParam, 0);
274c2c66affSColin Finck             lpszCmdLine = (LPWSTR)MemAlloc(0, numOfChars * sizeof(WCHAR));
275c2c66affSColin Finck             BuildCommandLine(lpszCmdLine, tool->m_Command, tool->m_DefParam, numOfChars);
276c2c66affSColin Finck         }
277c2c66affSColin Finck 
278c2c66affSColin Finck         SendDlgItemMessage(hToolsPage, IDC_TOOLS_CMDLINE, WM_SETTEXT, 0, (LPARAM)lpszCmdLine);
279c2c66affSColin Finck 
280c2c66affSColin Finck         MemFree(lpszCmdLine);
281c2c66affSColin Finck     }
282c2c66affSColin Finck     else
283c2c66affSColin Finck     {
284c2c66affSColin Finck         ShowWindow(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), SW_HIDE);
285c2c66affSColin Finck         Button_Enable(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT), FALSE);
286c2c66affSColin Finck         Button_Enable(GetDlgItem(hToolsPage, IDC_BTN_RUN), FALSE);
287c2c66affSColin Finck     }
288c2c66affSColin Finck }
289c2c66affSColin Finck 
RunSelectedTool(VOID)290c2c66affSColin Finck static BOOL RunSelectedTool(VOID)
291c2c66affSColin Finck {
292c2c66affSColin Finck     BOOL Success = FALSE;
293c2c66affSColin Finck     BOOL bUseAdvParams;
294c2c66affSColin Finck 
295c2c66affSColin Finck     LVITEM item = {};
296c2c66affSColin Finck     item.mask = LVIF_PARAM;
297c2c66affSColin Finck     item.iItem = ListView_GetSelectionMark(hToolsListCtrl);
298c2c66affSColin Finck     ListView_GetItem(hToolsListCtrl, &item);
299c2c66affSColin Finck 
300c2c66affSColin Finck     if (ListView_GetItem(hToolsListCtrl, &item)) // (item.iItem > -1) // TODO: corriger ailleurs ce genre de code...
301c2c66affSColin Finck     {
302c2c66affSColin Finck         if ( (Button_IsEnabled(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT))) &&
303c2c66affSColin Finck              (Button_GetCheck(GetDlgItem(hToolsPage, IDC_CBX_TOOLS_ADVOPT)) == BST_CHECKED) )
304c2c66affSColin Finck             bUseAdvParams = TRUE;
305c2c66affSColin Finck         else
306c2c66affSColin Finck             bUseAdvParams = FALSE;
307c2c66affSColin Finck 
308c2c66affSColin Finck         // Values greater (strictly) than 32 indicate success (see MSDN documentation for ShellExecute(...) API).
309c2c66affSColin Finck         Success = (reinterpret_cast<TOOL*>(item.lParam)->Run(bUseAdvParams) > 32);
310c2c66affSColin Finck     }
311c2c66affSColin Finck 
312c2c66affSColin Finck     return Success;
313c2c66affSColin Finck }
314c2c66affSColin Finck 
315c2c66affSColin Finck extern "C" {
316c2c66affSColin Finck 
317c2c66affSColin Finck INT_PTR CALLBACK
ToolsPageWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)318c2c66affSColin Finck ToolsPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
319c2c66affSColin Finck {
320c2c66affSColin Finck     switch (message)
321c2c66affSColin Finck     {
322c2c66affSColin Finck         case WM_INITDIALOG:
323c2c66affSColin Finck         {
324c2c66affSColin Finck             hToolsPage     = hDlg;
325c2c66affSColin Finck             hToolsListCtrl = GetDlgItem(hToolsPage, IDC_TOOLS_LIST);
326c2c66affSColin Finck 
327c2c66affSColin Finck             //
328c2c66affSColin Finck             // Initialize the styles.
329c2c66affSColin Finck             //
330c2c66affSColin Finck             DWORD dwStyle = ListView_GetExtendedListViewStyle(hToolsListCtrl);
331c2c66affSColin Finck             ListView_SetExtendedListViewStyle(hToolsListCtrl, dwStyle | LVS_EX_FULLROWSELECT);
332c2c66affSColin Finck             SetWindowTheme(hToolsListCtrl, L"Explorer", NULL);
333c2c66affSColin Finck 
334c2c66affSColin Finck             //
335c2c66affSColin Finck             // Initialize the application page's controls.
336c2c66affSColin Finck             //
337c2c66affSColin Finck             LVCOLUMN column = {};
338c2c66affSColin Finck 
339c2c66affSColin Finck             // First column : Tool's name.
340c2c66affSColin Finck             column.mask = LVCF_TEXT | LVCF_WIDTH;
341c2c66affSColin Finck             column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_NAME);
342c2c66affSColin Finck             column.cx = 150;
343c2c66affSColin Finck             ListView_InsertColumn(hToolsListCtrl, 0, &column);
344c2c66affSColin Finck             MemFree(column.pszText);
345c2c66affSColin Finck 
346c2c66affSColin Finck             // Second column : Whether the tool is a standard one or not.
347c2c66affSColin Finck             column.mask = LVCF_TEXT | LVCF_WIDTH;
348c2c66affSColin Finck             column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_STANDARD);
349c2c66affSColin Finck             column.cx = 60;
350c2c66affSColin Finck             ListView_InsertColumn(hToolsListCtrl, 1, &column);
351c2c66affSColin Finck             MemFree(column.pszText);
352c2c66affSColin Finck 
353c2c66affSColin Finck             // Third column : Description.
354c2c66affSColin Finck             column.mask = LVCF_TEXT | LVCF_WIDTH;
355c2c66affSColin Finck             column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_DESCR);
356c2c66affSColin Finck             column.cx = 500;
357c2c66affSColin Finck             ListView_InsertColumn(hToolsListCtrl, 2, &column);
358c2c66affSColin Finck             MemFree(column.pszText);
359c2c66affSColin Finck 
360c2c66affSColin Finck             //
361c2c66affSColin Finck             // Populate and sort the list.
362c2c66affSColin Finck             //
363c2c66affSColin Finck             FillListView();
364c2c66affSColin Finck             ListView_Sort(hToolsListCtrl, 0);
365c2c66affSColin Finck 
366c2c66affSColin Finck             // Force an update in case of an empty list (giving focus on it when empty won't emit a LVN_ITEMCHANGED message).
367c2c66affSColin Finck             Update_States(-1 /* Wrong index to initialize all the controls with their default state (i.e. disabled) */);
368c2c66affSColin Finck 
369c2c66affSColin Finck             PropSheet_UnChanged(GetParent(hToolsPage), hToolsPage);
370c2c66affSColin Finck 
371c2c66affSColin Finck             return TRUE;
372c2c66affSColin Finck         }
373c2c66affSColin Finck 
374c2c66affSColin Finck         case WM_DESTROY:
375c2c66affSColin Finck         {
376c2c66affSColin Finck             LVITEM lvitem = {};
377c2c66affSColin Finck             lvitem.mask  = LVIF_PARAM;
378c2c66affSColin Finck             lvitem.iItem = -1; // From the beginning.
379c2c66affSColin Finck 
380c2c66affSColin Finck             while ((lvitem.iItem = ListView_GetNextItem(hToolsListCtrl, lvitem.iItem, LVNI_ALL)) != -1)
381c2c66affSColin Finck             {
382c2c66affSColin Finck                 // ListView_Update();   // Updates a list-view item.
383c2c66affSColin Finck                 // ListView_FindItem(); // peut �tre int�ressant pour faire de la recherche it�rative � partir du nom (ou partie du...) de l'item.
384c2c66affSColin Finck 
385c2c66affSColin Finck                 ListView_GetItem(hToolsListCtrl, &lvitem);
386c2c66affSColin Finck 
387c2c66affSColin Finck                 delete reinterpret_cast<TOOL*>(lvitem.lParam);
388c2c66affSColin Finck                 lvitem.lParam = NULL;
389c2c66affSColin Finck             }
390c2c66affSColin Finck             ListView_DeleteAllItems(hToolsListCtrl);
391c2c66affSColin Finck 
392c2c66affSColin Finck             return 0;
393c2c66affSColin Finck         }
394c2c66affSColin Finck 
395c2c66affSColin Finck         case WM_COMMAND:
396c2c66affSColin Finck         {
397c2c66affSColin Finck             switch (LOWORD(wParam))
398c2c66affSColin Finck             {
399c2c66affSColin Finck                 case IDC_BTN_RUN:
400c2c66affSColin Finck                 {
401c2c66affSColin Finck                     RunSelectedTool();
402c2c66affSColin Finck                     return TRUE;
403c2c66affSColin Finck                 }
404c2c66affSColin Finck 
405c2c66affSColin Finck                 case IDC_CBX_TOOLS_ADVOPT:
406c2c66affSColin Finck                 {
407c2c66affSColin Finck                     Update_States(ListView_GetSelectionMark(hToolsListCtrl));
408c2c66affSColin Finck                     return TRUE;
409c2c66affSColin Finck                 }
410c2c66affSColin Finck 
411c2c66affSColin Finck                 default:
412c2c66affSColin Finck                     return FALSE;
413c2c66affSColin Finck             }
414c2c66affSColin Finck             return FALSE;
415c2c66affSColin Finck         }
416c2c66affSColin Finck 
417c2c66affSColin Finck         case WM_NOTIFY:
418c2c66affSColin Finck         {
419c2c66affSColin Finck             if (((LPNMHDR)lParam)->hwndFrom == hToolsListCtrl)
420c2c66affSColin Finck             {
421c2c66affSColin Finck                 switch (((LPNMHDR)lParam)->code)
422c2c66affSColin Finck                 {
423c2c66affSColin Finck                     case LVN_ITEMCHANGED:
424c2c66affSColin Finck                     {
425c2c66affSColin Finck                         if ( (((LPNMLISTVIEW)lParam)->uChanged  & LVIF_STATE) && /* The state has changed */
426c2c66affSColin Finck                              (((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ )
427c2c66affSColin Finck                         {
428c2c66affSColin Finck                             Update_States(((LPNMLISTVIEW)lParam)->iItem);
429c2c66affSColin Finck                         }
430c2c66affSColin Finck 
431c2c66affSColin Finck                         return TRUE;
432c2c66affSColin Finck                     }
433c2c66affSColin Finck 
434c2c66affSColin Finck                     case NM_DBLCLK:
435c2c66affSColin Finck                     case NM_RDBLCLK:
436c2c66affSColin Finck                     {
437c2c66affSColin Finck                         RunSelectedTool();
438c2c66affSColin Finck                         return TRUE;
439c2c66affSColin Finck                     }
440c2c66affSColin Finck 
441c2c66affSColin Finck                     case LVN_COLUMNCLICK:
442c2c66affSColin Finck                     {
443c2c66affSColin Finck                         int iSortingColumn = ((LPNMLISTVIEW)lParam)->iSubItem;
444c2c66affSColin Finck 
445*9ce192a8SAmine Khaldi                         ListView_SortEx(hToolsListCtrl, iSortingColumn, iToolsPageSortedColumn);
446*9ce192a8SAmine Khaldi                         iToolsPageSortedColumn = iSortingColumn;
447c2c66affSColin Finck 
448c2c66affSColin Finck                         return TRUE;
449c2c66affSColin Finck                     }
450c2c66affSColin Finck 
451c2c66affSColin Finck                     default:
452c2c66affSColin Finck                         break;
453c2c66affSColin Finck                 }
454c2c66affSColin Finck             }
455c2c66affSColin Finck             else
456c2c66affSColin Finck             {
457c2c66affSColin Finck                 switch (((LPNMHDR)lParam)->code)
458c2c66affSColin Finck                 {
459c2c66affSColin Finck                     case PSN_APPLY:
460c2c66affSColin Finck                     {
461c2c66affSColin Finck                         // Since there are nothing to modify, applying modifications
462c2c66affSColin Finck                         // cannot return any error.
463c2c66affSColin Finck                         SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, PSNRET_NOERROR);
464c2c66affSColin Finck                         PropSheet_UnChanged(GetParent(hToolsPage), hToolsPage);
465c2c66affSColin Finck                         return TRUE;
466c2c66affSColin Finck                     }
467c2c66affSColin Finck 
468c2c66affSColin Finck                     case PSN_HELP:
469c2c66affSColin Finck                     {
470c2c66affSColin Finck                         MessageBoxW(hToolsPage, L"Help not implemented yet!", L"Help", MB_ICONINFORMATION | MB_OK);
471c2c66affSColin Finck                         return TRUE;
472c2c66affSColin Finck                     }
473c2c66affSColin Finck 
474c2c66affSColin Finck                     case PSN_KILLACTIVE: // Is going to lose activation.
475c2c66affSColin Finck                     {
476c2c66affSColin Finck                         // Changes are always valid of course.
477c2c66affSColin Finck                         SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, FALSE);
478c2c66affSColin Finck                         return TRUE;
479c2c66affSColin Finck                     }
480c2c66affSColin Finck 
481c2c66affSColin Finck                     case PSN_QUERYCANCEL:
482c2c66affSColin Finck                     {
483c2c66affSColin Finck                         // Allows cancellation since there are nothing to cancel...
484c2c66affSColin Finck                         SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, FALSE);
485c2c66affSColin Finck                         return TRUE;
486c2c66affSColin Finck                     }
487c2c66affSColin Finck 
488c2c66affSColin Finck                     case PSN_QUERYINITIALFOCUS:
489c2c66affSColin Finck                     {
490c2c66affSColin Finck                         // Give the focus on and select the first item.
491c2c66affSColin Finck                         ListView_SetItemState(hToolsListCtrl, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
492c2c66affSColin Finck 
493c2c66affSColin Finck                         SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, (LONG_PTR)hToolsListCtrl);
494c2c66affSColin Finck                         return TRUE;
495c2c66affSColin Finck                     }
496c2c66affSColin Finck 
497c2c66affSColin Finck                     //
498c2c66affSColin Finck                     // DO NOT TOUCH THESE NEXT MESSAGES, THEY ARE OK LIKE THIS...
499c2c66affSColin Finck                     //
500c2c66affSColin Finck                     case PSN_RESET: // Perform final cleaning, called before WM_DESTROY.
501c2c66affSColin Finck                         return TRUE;
502c2c66affSColin Finck 
503c2c66affSColin Finck                     case PSN_SETACTIVE: // Is going to gain activation.
504c2c66affSColin Finck                     {
505c2c66affSColin Finck                         SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, 0);
506c2c66affSColin Finck                         return TRUE;
507c2c66affSColin Finck                     }
508c2c66affSColin Finck 
509c2c66affSColin Finck                     default:
510c2c66affSColin Finck                         break;
511c2c66affSColin Finck                 }
512c2c66affSColin Finck             }
513c2c66affSColin Finck 
514c2c66affSColin Finck             return FALSE;
515c2c66affSColin Finck         }
516c2c66affSColin Finck 
517c2c66affSColin Finck         default:
518c2c66affSColin Finck             return FALSE;
519c2c66affSColin Finck     }
520c2c66affSColin Finck 
521c2c66affSColin Finck     // return FALSE;
522c2c66affSColin Finck }
523c2c66affSColin Finck 
524c2c66affSColin Finck }
525c2c66affSColin Finck 
526c2c66affSColin Finck /* EOF */
527