[ros-diffs] [cfinck] 33507: Completely revamped "control.exe": - Now uses shell32 functions for loading the control panel applets, so that the mutex is used as well (see bug #781) - Supports all built-in command-line parameters, which are supported by the WinXP version. This also added support for opening shell folders. - Loads other possible parameters from the registry. - Only passes the command for RunControlPanel to each ListView item, not a whole struct whose members aren't needed later. - Fixed memory leaks - Added a header file - Fixed indentation This is the last version of the standalone Control Panel. I will change it to call the Explorer shell folder in my next commit. See issue #781 for more details.

cfinck at svn.reactos.org cfinck at svn.reactos.org
Tue May 13 23:30:56 CEST 2008


Author: cfinck
Date: Tue May 13 16:30:55 2008
New Revision: 33507

URL: http://svn.reactos.org/svn/reactos?rev=33507&view=rev
Log:
Completely revamped "control.exe":
- Now uses shell32 functions for loading the control panel applets, so that the mutex is used as well (see bug #781)
- Supports all built-in command-line parameters, which are supported by the WinXP version.
  This also added support for opening shell folders.
- Loads other possible parameters from the registry.
- Only passes the command for RunControlPanel to each ListView item, not a whole struct whose members aren't needed later.
- Fixed memory leaks
- Added a header file
- Fixed indentation

This is the last version of the standalone Control Panel.
I will change it to call the Explorer shell folder in my next commit.
See issue #781 for more details.

Added:
    trunk/reactos/base/applications/control/control.h   (with props)
Modified:
    trunk/reactos/base/applications/control/control.c   (contents, props changed)
    trunk/reactos/base/applications/control/control.rbuild

Modified: trunk/reactos/base/applications/control/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/control/control.c?rev=33507&r1=33506&r2=33507&view=diff
==============================================================================
--- trunk/reactos/base/applications/control/control.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/control/control.c [iso-8859-1] Tue May 13 16:30:55 2008
@@ -1,458 +1,418 @@
 /*
- *  ReactOS
- *  Copyright (C) 2004 ReactOS Team
- *  Copyright (C) 2004 GkWare e.K.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * PROJECT:         ReactOS System Control Panel
+ * FILE:            base/applications/control/control.c
+ * PURPOSE:         ReactOS System Control Panel
+ * PROGRAMMERS:     Gero Kuehn (reactos.filter at gkware.com)
+ *                  Colin Finck (mail at colinfinck.de)
  */
-/* $Id$
- *
- * PROJECT:         ReactOS System Control Panel
- * FILE:            lib/cpl/system/control.c
- * PURPOSE:         ReactOS System Control Panel
- * PROGRAMMER:      Gero Kuehn (reactos.filter at gkware.com)
- * UPDATE HISTORY:
- *      06-13-2004  Created
- */
-#include <windows.h>
-#include <commctrl.h>
-#include <cpl.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <tchar.h>
-
-#include "resource.h"
-
-//#define CONTROL_DEBUG_ENABLE
-
-#ifdef CONTROL_DEBUG_ENABLE
-#define CTL_DEBUG(x) dbgprint x
-#else
-#define CTL_DEBUG(x)
-#endif
-
-#define MYWNDCLASS _T("CTLPANELCLASS")
-
-typedef LONG (CALLBACK *CPLAPPLETFUNC)(HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
-
-typedef struct CPLLISTENTRY
-{
-	TCHAR pszPath[MAX_PATH];
-	HMODULE hDll;
-	CPLAPPLETFUNC pFunc;
-	CPLINFO CplInfo;
-	int nIndex;
-} CPLLISTENTRY, *PCPLLISTENTRY;
-
-
-HWND hListView;
+
+#include "control.h"
+
+static const TCHAR szWindowClass[] = _T("DummyControlClass");
+
+HANDLE hProcessHeap;
 HINSTANCE hInst;
-HWND hMainWnd;
-DEVMODE pDevMode;
-
-VOID dbgprint(TCHAR *format,...)
-{
-	TCHAR buf[1000];
-	va_list va;
-
-	va_start(va,format);
-	_vstprintf(buf,format,va);
-	OutputDebugString(buf);
-	va_end(va);
-}
-
-VOID PopulateCPLList(HWND hLisCtrl)
-{
-	WIN32_FIND_DATA fd;
-	HANDLE hFind;
-	TCHAR pszSearchPath[MAX_PATH];
-	HIMAGELIST hImgListSmall;
-	HIMAGELIST hImgListLarge;
-	int ColorDepth;
-	HMODULE hDll;
-	CPLAPPLETFUNC pFunc;
-	TCHAR pszPath[MAX_PATH];
-
-	/* Icon drawing mode */
-	pDevMode.dmSize = sizeof(DEVMODE);
-	pDevMode.dmDriverExtra = 0;
-
-	EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&pDevMode);
-	switch (pDevMode.dmBitsPerPel)
-	{
-		case 32: ColorDepth = ILC_COLOR32; break;
-		case 24: ColorDepth = ILC_COLOR24; break;
-		case 16: ColorDepth = ILC_COLOR16; break;
-		case  8: ColorDepth = ILC_COLOR8;  break;
-		case  4: ColorDepth = ILC_COLOR4;  break;
-		default: ColorDepth = ILC_COLOR;  break;
-	}
-
-	hImgListSmall = ImageList_Create(16,16,ColorDepth | ILC_MASK,5,5);
-	hImgListLarge = ImageList_Create(32,32,ColorDepth | ILC_MASK,5,5);
-
-	GetSystemDirectory(pszSearchPath,MAX_PATH);
-	_tcscat(pszSearchPath,_T("\\*.cpl"));
-
-	hFind = FindFirstFile(pszSearchPath,&fd);
-	while (hFind != INVALID_HANDLE_VALUE)
-	{
-		PCPLLISTENTRY pEntry;
-		CTL_DEBUG((_T("Found %s\r\n"), fd.cFileName));
-
-		_tcscpy(pszPath, pszSearchPath);
-		*_tcsrchr(pszPath, '\\')=0;
-		_tcscat(pszPath, _T("\\"));
-		_tcscat(pszPath, fd.cFileName);
-
-		hDll = LoadLibrary(pszPath);
-		CTL_DEBUG((_T("Handle %08X\r\n"), hDll));
-
-		pFunc = (CPLAPPLETFUNC)GetProcAddress(hDll, "CPlApplet");
-		CTL_DEBUG((_T("CPLFunc %08X\r\n"), pFunc));
-
-		if (pFunc && pFunc(hLisCtrl, CPL_INIT, 0, 0))
-		{
-			UINT i, uPanelCount;
-
-			uPanelCount = (UINT)pFunc(hLisCtrl, CPL_GETCOUNT, 0, 0);
-			for (i = 0; i < uPanelCount; i++)
-			{
-				HICON hIcon;
-				TCHAR Name[MAX_PATH];
-				int index;
-
-				pEntry = (PCPLLISTENTRY)malloc(sizeof(CPLLISTENTRY));
-				if (pEntry == NULL)
-					return;
-
-				memset(pEntry, 0, sizeof(CPLLISTENTRY));
-				pEntry->hDll = hDll;
-				pEntry->pFunc = pFunc;
-				_tcscpy(pEntry->pszPath, pszPath);
-
-				pEntry->pFunc(hLisCtrl, CPL_INQUIRE, (LPARAM)i, (LPARAM)&pEntry->CplInfo);
-				hIcon = LoadImage(pEntry->hDll,MAKEINTRESOURCE(pEntry->CplInfo.idIcon),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
-				index = ImageList_AddIcon(hImgListSmall,hIcon);
-				DestroyIcon(hIcon);
-				hIcon = LoadImage(pEntry->hDll,MAKEINTRESOURCE(pEntry->CplInfo.idIcon),IMAGE_ICON,32,32,LR_DEFAULTCOLOR);
-				ImageList_AddIcon(hImgListLarge,hIcon);
-				DestroyIcon(hIcon);
-
-				if (LoadString(pEntry->hDll, pEntry->CplInfo.idName, Name, MAX_PATH))
-				{
-					LV_ITEM lvi;
-
-					memset(&lvi,0x00,sizeof(lvi));
-					lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-					lvi.pszText = Name;
-					lvi.state = 0;
-					lvi.iImage = index;
-					lvi.lParam = (LPARAM)pEntry;
-					pEntry->nIndex = ListView_InsertItem(hLisCtrl,&lvi);
-
-					if (LoadString(pEntry->hDll, pEntry->CplInfo.idInfo, Name, MAX_PATH))
-						ListView_SetItemText(hLisCtrl, pEntry->nIndex, 1, Name);
-				}
-			}
-		}
-
-		if (!FindNextFile(hFind,&fd))
-			hFind = INVALID_HANDLE_VALUE;
-	}
-
-	(void)ListView_SetImageList(hLisCtrl,hImgListSmall,LVSIL_SMALL);
-	(void)ListView_SetImageList(hLisCtrl,hImgListLarge,LVSIL_NORMAL);
-}
-
-LRESULT CALLBACK MyWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
-{
-	TCHAR szBuf[1024];
-
-	switch (uMsg)
-	{
-	case WM_CREATE:
-		{
-			RECT rect;
-			LV_COLUMN column;
-
-			GetClientRect(hWnd,&rect);
-			hListView = CreateWindow(WC_LISTVIEW,_T(""),LVS_REPORT | LVS_ALIGNLEFT | LVS_SORTASCENDING | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD | WS_TABSTOP,0,0,rect.right ,rect.bottom,hWnd,NULL,hInst,0);
-			CTL_DEBUG((_T("Listview Window %08X\r\n"),hListView));
-
-			memset(&column,0x00,sizeof(column));
-			column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
-			column.fmt = LVCFMT_LEFT;
-			column.cx = (rect.right - rect.left) / 3;
-			column.iSubItem = 0;
-			LoadString(hInst, IDS_NAME, szBuf, sizeof(szBuf) / sizeof(TCHAR));
-			column.pszText = szBuf;
-			(void)ListView_InsertColumn(hListView,0,&column);
-			column.cx = (rect.right - rect.left) - ((rect.right - rect.left) / 3) - 1;
-			column.iSubItem = 1;
-			LoadString(hInst, IDS_COMMENT, szBuf, sizeof(szBuf) / sizeof(TCHAR));
-			column.pszText = szBuf;
-			(void)ListView_InsertColumn(hListView,1,&column);
-			PopulateCPLList(hListView);
-			(void)ListView_SetColumnWidth(hListView,2,LVSCW_AUTOSIZE_USEHEADER);
-			(void)ListView_Update(hListView,0);
-
-			SetFocus(hListView);
-		}
-		break;
-
-	case WM_DESTROY:
-		PostQuitMessage(0);
-		break;
-
-	case WM_SIZE:
-		{
-			RECT rect;
-
-			GetClientRect(hWnd,&rect);
-			MoveWindow(hListView,0,0,rect.right,rect.bottom,TRUE);
-		}
-		break;
-
-	case WM_NOTIFY:
-		{
-			NMHDR *phdr;
-			phdr = (NMHDR*)lParam;
-			switch(phdr->code)
-			{
-			case NM_RETURN:
-			case NM_DBLCLK:
-				{
-					int nSelect;
-					LV_ITEM lvi;
-					PCPLLISTENTRY pEntry;
-
-					nSelect=SendMessage(hListView,LVM_GETNEXTITEM,(WPARAM)-1,LVNI_FOCUSED);
-
-					if (nSelect==-1)
-					{
-						/* no items */
-						LoadString(hInst, IDS_NO_ITEMS, szBuf, sizeof(szBuf) / sizeof(TCHAR));
-						MessageBox(hWnd,(LPCTSTR)szBuf,NULL,MB_OK|MB_ICONINFORMATION);
-						break;
-					}
-
-					CTL_DEBUG((_T("Select %d\r\n"),nSelect));
-					memset(&lvi,0x00,sizeof(lvi));
-					lvi.iItem = nSelect;
-					lvi.mask = LVIF_PARAM;
-					(void)ListView_GetItem(hListView,&lvi);
-					pEntry = (PCPLLISTENTRY)lvi.lParam;
-					CTL_DEBUG((_T("Listview DblClk Entry %08X\r\n"),pEntry));
-					if (pEntry)
-					{
-						CTL_DEBUG((_T("Listview DblClk Entry Func %08X\r\n"),pEntry->pFunc));
-					}
-
-					if (pEntry && pEntry->pFunc)
-						pEntry->pFunc(hListView,CPL_DBLCLK,pEntry->CplInfo.lData,0);
-				}
-			}
-		}
-		break;
-
-	case WM_COMMAND:
-		switch (LOWORD(wParam))
-		{
-		case IDM_LARGEICONS:
-			SetWindowLong(hListView,GWL_STYLE,LVS_ICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
-			break;
-		case IDM_SMALLICONS:
-			SetWindowLong(hListView,GWL_STYLE,LVS_SMALLICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
-			break;
-		case IDM_LIST:
-			SetWindowLong(hListView,GWL_STYLE,LVS_LIST | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
-			break;
-		case IDM_DETAILS:
-			SetWindowLong(hListView,GWL_STYLE,LVS_REPORT | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
-			break;
-		case IDM_CLOSE:
-			DestroyWindow(hWnd);
-			break;
-		case IDM_ABOUT:
-			{
-				TCHAR Title[256];
-				
-				LoadString(hInst, IDS_ABOUT, szBuf, sizeof(szBuf) / sizeof(TCHAR));
-				LoadString(hInst, IDS_ABOUT_TITLE, Title, sizeof(Title) / sizeof(TCHAR));
-				
-				MessageBox(hWnd,(LPCTSTR)szBuf,(LPCTSTR)Title,MB_OK | MB_ICONINFORMATION);
-			}
-			break;
-		}
-		break;
-
-	default:
-		return DefWindowProc(hWnd,uMsg,wParam,lParam);
-	}
-
-	return 0;
+
+static INT
+OpenShellFolder(LPTSTR lpFolderCLSID)
+{
+    TCHAR szParameters[MAX_PATH];
+
+    /* Open a shell folder using "explorer.exe".
+       The passed CLSID's are all subfolders of the "Control Panel" shell folder. */
+    _tcscpy(szParameters, _T("/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"));
+    _tcscat(szParameters, lpFolderCLSID);
+
+    return (int)ShellExecute(NULL, _T("open"), _T("explorer.exe"), szParameters, NULL, SW_SHOWDEFAULT) > 32;
+}
+
+static INT
+RunControlPanel(LPTSTR lpCmd)
+{
+    TCHAR szParameters[MAX_PATH];
+
+    _tcscpy(szParameters, _T("shell32.dll,Control_RunDLL "));
+    _tcscat(szParameters, lpCmd);
+
+    return RUNDLL(szParameters);
+}
+
+static VOID
+PopulateCPLList(HWND hLisCtrl)
+{
+    WIN32_FIND_DATA fd;
+    HANDLE hFind;
+    TCHAR pszSearchPath[MAX_PATH];
+    HIMAGELIST hImgListSmall;
+    HIMAGELIST hImgListLarge;
+    HMODULE hDll;
+    CPLAPPLETFUNC pFunc;
+    TCHAR pszPath[MAX_PATH];
+    TCHAR szPanelNum[CCH_UINT_MAX + 1];
+    DEVMODE pDevMode;
+
+    /* Icon drawing mode */
+    pDevMode.dmSize = sizeof(DEVMODE);
+    pDevMode.dmDriverExtra = 0;
+
+    EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &pDevMode);
+    hImgListSmall = ImageList_Create(16, 16, pDevMode.dmBitsPerPel | ILC_MASK, 5, 5);
+    hImgListLarge = ImageList_Create(32, 32, pDevMode.dmBitsPerPel | ILC_MASK, 5, 5);
+
+    GetSystemDirectory(pszSearchPath, MAX_PATH);
+    _tcscat(pszSearchPath, _T("\\*.cpl"));
+
+    hFind = FindFirstFile(pszSearchPath, &fd);
+
+    while (hFind != INVALID_HANDLE_VALUE)
+    {
+        _tcscpy(pszPath, pszSearchPath);
+        *_tcsrchr(pszPath, '\\') = 0;
+        _tcscat(pszPath, _T("\\"));
+        _tcscat(pszPath, fd.cFileName);
+
+        hDll = LoadLibrary(pszPath);
+        pFunc = (CPLAPPLETFUNC)GetProcAddress(hDll, "CPlApplet");
+
+        if (pFunc && pFunc(hLisCtrl, CPL_INIT, 0, 0))
+        {
+            UINT i, uPanelCount;
+
+            uPanelCount = (UINT)pFunc(hLisCtrl, CPL_GETCOUNT, 0, 0);
+
+            for (i = 0; i < uPanelCount; i++)
+            {
+                CPLINFO CplInfo;
+                HICON hIcon;
+                TCHAR Name[MAX_PATH];
+                int index;
+                LPTSTR pszCmd;
+
+                pszCmd = (LPTSTR) HeapAlloc(hProcessHeap, 0, MAX_PATH * sizeof(TCHAR));
+                if(!pszCmd)
+                    return;
+
+                /* Build the command, which is later passed to RunControlPanel */
+                _tcscpy(pszCmd, fd.cFileName);
+                _tcscat(pszCmd, _T(" @"));
+                _itot(i, szPanelNum, 10);
+                _tcscat(pszCmd, szPanelNum);
+
+                pFunc(hLisCtrl, CPL_INQUIRE, (LPARAM)i, (LPARAM)&CplInfo);
+
+                hIcon = LoadImage(hDll, MAKEINTRESOURCE(CplInfo.idIcon), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+                index = ImageList_AddIcon(hImgListSmall, hIcon);
+                DestroyIcon(hIcon);
+
+                hIcon = LoadImage(hDll, MAKEINTRESOURCE(CplInfo.idIcon), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
+                ImageList_AddIcon(hImgListLarge, hIcon);
+                DestroyIcon(hIcon);
+
+                if (LoadString(hDll, CplInfo.idName, Name, MAX_PATH))
+                {
+                    INT nIndex;
+                    LV_ITEM lvi = {0};
+
+                    lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
+                    lvi.pszText = Name;
+                    lvi.state = 0;
+                    lvi.iImage = index;
+                    lvi.lParam = (LPARAM)pszCmd;
+                    nIndex = ListView_InsertItem(hLisCtrl, &lvi);
+
+                    if (LoadString(hDll, CplInfo.idInfo, Name, MAX_PATH))
+                        ListView_SetItemText(hLisCtrl, nIndex, 1, Name);
+                }
+            }
+        }
+
+        if (!FindNextFile(hFind, &fd))
+            hFind = INVALID_HANDLE_VALUE;
+    }
+
+    (void)ListView_SetImageList(hLisCtrl, hImgListSmall, LVSIL_SMALL);
+    (void)ListView_SetImageList(hLisCtrl, hImgListLarge, LVSIL_NORMAL);
+}
+
+LRESULT CALLBACK
+MyWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    static HWND hListView;
+    TCHAR szBuf[1024];
+
+    switch (uMsg)
+    {
+        case WM_CREATE:
+        {
+            RECT rect;
+            LV_COLUMN column = {0};
+
+            GetClientRect(hWnd, &rect);
+            hListView = CreateWindow(WC_LISTVIEW, NULL, LVS_REPORT | LVS_ALIGNLEFT | LVS_SORTASCENDING | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, rect.right, rect.bottom, hWnd, NULL, hInst, 0);
+
+            column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
+            column.fmt = LVCFMT_LEFT;
+            column.cx = (rect.right - rect.left) / 3;
+            column.iSubItem = 0;
+            LoadString(hInst, IDS_NAME, szBuf, sizeof(szBuf) / sizeof(TCHAR));
+            column.pszText = szBuf;
+            (void)ListView_InsertColumn(hListView, 0, &column);
+
+            column.cx = (rect.right - rect.left) - ((rect.right - rect.left) / 3) - 1;
+            column.iSubItem = 1;
+            LoadString(hInst, IDS_COMMENT, szBuf, sizeof(szBuf) / sizeof(TCHAR));
+            column.pszText = szBuf;
+            (void)ListView_InsertColumn(hListView, 1, &column);
+
+            PopulateCPLList(hListView);
+
+            (void)ListView_SetColumnWidth(hListView, 2, LVSCW_AUTOSIZE_USEHEADER);
+            (void)ListView_Update(hListView, 0);
+
+            SetFocus(hListView);
+
+            return 0;
+        }
+
+        case WM_DESTROY:
+        {
+            LV_ITEM lvi;
+            INT nItems;
+
+            lvi.mask = LVIF_PARAM;
+
+            /* Free the memory used for the command strings */
+            for(nItems = ListView_GetItemCount(hListView); --nItems >= 0;)
+            {
+                lvi.iItem = nItems;
+                (void)ListView_GetItem(hListView, &lvi);
+                HeapFree(hProcessHeap, 0, (LPVOID)lvi.lParam);
+            }
+
+            PostQuitMessage(0);
+            return 0;
+        }
+
+        case WM_SIZE:
+        {
+            RECT rect;
+
+            GetClientRect(hWnd, &rect);
+            MoveWindow(hListView, 0, 0, rect.right, rect.bottom, TRUE);
+
+            return 0;
+        }
+
+        case WM_NOTIFY:
+        {
+            NMHDR *phdr;
+            phdr = (NMHDR*)lParam;
+
+            switch(phdr->code)
+            {
+                case NM_RETURN:
+                case NM_DBLCLK:
+                {
+                    int nSelect;
+                    LV_ITEM lvi = {0};
+                    LPTSTR pszCmd;
+
+                    nSelect = SendMessage(hListView, LVM_GETNEXTITEM, (WPARAM)-1, LVNI_FOCUSED);
+
+                    if (nSelect == -1)
+                    {
+                        /* no items */
+                        LoadString(hInst, IDS_NO_ITEMS, szBuf, sizeof(szBuf) / sizeof(TCHAR));
+                        MessageBox(hWnd, (LPCTSTR)szBuf, NULL, MB_OK | MB_ICONINFORMATION);
+                        break;
+                    }
+
+                    lvi.iItem = nSelect;
+                    lvi.mask = LVIF_PARAM;
+                    (void)ListView_GetItem(hListView, &lvi);
+
+                    pszCmd = (LPTSTR)lvi.lParam;
+
+                    if (pszCmd)
+                        RunControlPanel(pszCmd);
+
+                    return 0;
+                }
+            }
+        }
+
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case IDM_LARGEICONS:
+                    SetWindowLong(hListView,GWL_STYLE,LVS_ICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
+                    return 0;
+
+                case IDM_SMALLICONS:
+                    SetWindowLong(hListView,GWL_STYLE,LVS_SMALLICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
+                    return 0;
+
+                case IDM_LIST:
+                    SetWindowLong(hListView,GWL_STYLE,LVS_LIST | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
+                    return 0;
+
+                case IDM_DETAILS:
+                    SetWindowLong(hListView,GWL_STYLE,LVS_REPORT | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL   | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
+                    return 0;
+
+                case IDM_CLOSE:
+                    DestroyWindow(hWnd);
+                    return 0;
+
+                case IDM_ABOUT:
+                {
+                    TCHAR Title[256];
+
+                    LoadString(hInst, IDS_ABOUT, szBuf, sizeof(szBuf) / sizeof(TCHAR));
+                    LoadString(hInst, IDS_ABOUT_TITLE, Title, sizeof(Title) / sizeof(TCHAR));
+
+                    MessageBox(hWnd, (LPCTSTR)szBuf, (LPCTSTR)Title, MB_OK | MB_ICONINFORMATION);
+
+                    return 0;
+                }
+            }
+    }
+
+    return DefWindowProc(hWnd, uMsg, wParam, lParam);
 }
 
 
 static INT
 RunControlPanelWindow(int nCmdShow)
 {
-  MSG msg;
-  WNDCLASS wc;
-  TCHAR szBuf[256];
-
-  memset(&wc,0x00,sizeof(wc));
-  wc.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAINICON));
-  wc.lpszClassName = MYWNDCLASS;
-  wc.lpszMenuName = _T("MAINMENU");
-  wc.lpfnWndProc = MyWindowProc;
-  RegisterClass(&wc);
-
-  InitCommonControls();
-  
-  LoadString(hInst, IDS_WINDOW_TITLE, szBuf, sizeof(szBuf) / sizeof(TCHAR));
-  hMainWnd = CreateWindowEx(WS_EX_CLIENTEDGE,
-			    MYWNDCLASS,
-			    (LPCTSTR)szBuf,
-			    WS_OVERLAPPEDWINDOW,
-			    CW_USEDEFAULT,
-			    CW_USEDEFAULT,
-			    CW_USEDEFAULT,
-			    CW_USEDEFAULT,
-			    NULL,
-			    LoadMenu(hInst, MAKEINTRESOURCE(IDM_MAINMENU)),
-			    hInst,
-			    0);
-  if (!hMainWnd)
+    MSG msg;
+    HWND hMainWnd;
+    INITCOMMONCONTROLSEX icex;
+    WNDCLASSEX wcex = {0};
+    TCHAR szBuf[256];
+
+    wcex.cbSize = sizeof(wcex);
+    wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAINICON));
+    wcex.lpszClassName = MYWNDCLASS;
+    wcex.lpfnWndProc = MyWindowProc;
+    RegisterClassEx(&wcex);
+
+    icex.dwSize = sizeof(icex);
+    icex.dwICC = ICC_LISTVIEW_CLASSES;
+    InitCommonControlsEx(&icex);
+
+    LoadString(hInst, IDS_WINDOW_TITLE, szBuf, sizeof(szBuf) / sizeof(TCHAR));
+
+    hMainWnd = CreateWindowEx(WS_EX_CLIENTEDGE,
+                              MYWNDCLASS,
+                              (LPCTSTR)szBuf,
+                              WS_OVERLAPPEDWINDOW,
+                              CW_USEDEFAULT,
+                              CW_USEDEFAULT,
+                              CW_USEDEFAULT,
+                              CW_USEDEFAULT,
+                              NULL,
+                              LoadMenu(hInst, MAKEINTRESOURCE(IDM_MAINMENU)),
+                              hInst,
+                              0);
+    if (!hMainWnd)
+        return 1;
+
+    ShowWindow(hMainWnd, nCmdShow);
+
+    while (GetMessage(&msg, 0, 0, 0))
     {
-      CTL_DEBUG((_T("Unable to create window\r\n")));
-      return -1;
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
     }
 
-  ShowWindow(hMainWnd, nCmdShow);
-  while (GetMessage(&msg, 0, 0, 0))
+    return 0;
+}
+
+int WINAPI
+_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
+{
+    HKEY hKey;
+
+    hInst = hInstance;
+    hProcessHeap = GetProcessHeap();
+
+    /* Show the control panel window if no argument or "panel" was passed */
+    if(lpCmdLine[0] == 0 || !_tcsicmp(lpCmdLine, _T("panel")))
+        return RunControlPanelWindow(nCmdShow);
+
+    /* Check one of the built-in control panel handlers */
+    if (!_tcsicmp(lpCmdLine, _T("admintools")))           return OpenShellFolder(_T("\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}"));
+    else if (!_tcsicmp(lpCmdLine, _T("color")))           return RunControlPanel(_T("desk.cpl"));       /* TODO: Switch to the "Apperance" tab */
+    else if (!_tcsicmp(lpCmdLine, _T("date/time")))       return RunControlPanel(_T("timedate.cpl"));
+    else if (!_tcsicmp(lpCmdLine, _T("desktop")))         return RunControlPanel(_T("desk.cpl"));
+    else if (!_tcsicmp(lpCmdLine, _T("folders")))         return RUNDLL(_T("shell32.dll,Options_RunDLL"));
+    else if (!_tcsicmp(lpCmdLine, _T("fonts")))           return OpenShellFolder(_T("\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}"));
+    else if (!_tcsicmp(lpCmdLine, _T("infrared")))        return RunControlPanel(_T("irprops.cpl"));
+    else if (!_tcsicmp(lpCmdLine, _T("international")))   return RunControlPanel(_T("intl.cpl"));
+    else if (!_tcsicmp(lpCmdLine, _T("keyboard")))        return RunControlPanel(_T("main.cpl @1"));
+    else if (!_tcsicmp(lpCmdLine, _T("mouse")))           return RunControlPanel(_T("main.cpl @0"));
+    else if (!_tcsicmp(lpCmdLine, _T("netconnections")))  return OpenShellFolder(_T("\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}"));
+    else if (!_tcsicmp(lpCmdLine, _T("netware")))         return RunControlPanel(_T("nwc.cpl"));
+    else if (!_tcsicmp(lpCmdLine, _T("ports")))           return RunControlPanel(_T("sysdm.cpl"));      /* TODO: Switch to the "Computer Name" tab */
+    else if (!_tcsicmp(lpCmdLine, _T("printers")))        return OpenShellFolder(_T("\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"));
+    else if (!_tcsicmp(lpCmdLine, _T("scannercamera")))   return OpenShellFolder(_T("\\::{E211B736-43FD-11D1-9EFB-0000F8757FCD}"));
+    else if (!_tcsicmp(lpCmdLine, _T("schedtasks")))      return OpenShellFolder(_T("\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}"));
+    else if (!_tcsicmp(lpCmdLine, _T("telephony")))       return RunControlPanel(_T("telephon.cpl"));
+    else if (!_tcsicmp(lpCmdLine, _T("userpasswords")))   return RunControlPanel(_T("nusrmgr.cpl"));       /* Graphical User Account Manager */
+    else if (!_tcsicmp(lpCmdLine, _T("userpasswords2")))  return RUNDLL(_T("netplwiz.dll,UsersRunDll"));   /* Dialog based advanced User Account Manager */
+
+    /* It is none of them, so look for a handler in the registry */
+    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
     {
-      TranslateMessage(&msg);
-      DispatchMessage(&msg);
+        DWORD dwIndex;
+
+        for(dwIndex = 0; ; ++dwIndex)
+        {
+            DWORD dwDataSize;
+            DWORD dwValueSize = MAX_VALUE_NAME;
+            TCHAR szValueName[MAX_VALUE_NAME];
+
+            /* Get the value name and data size */
+            if(RegEnumValue(hKey, dwIndex, szValueName, &dwValueSize, 0, NULL, NULL, &dwDataSize) != ERROR_SUCCESS)
+                break;
+
+            /* Check if the parameter is the value name */
+            if(!_tcsicmp(lpCmdLine, szValueName))
+            {
+                LPTSTR pszData;
+
+                /* Allocate memory for the data plus two more characters, so we can quote the file name if required */
+                pszData = (LPTSTR) HeapAlloc(hProcessHeap, 0, dwDataSize + 2 * sizeof(TCHAR));
+                ++pszData;
+
+                /* This value is the one we are looking for, so get the data. It is the path to a .cpl file */
+                if(RegQueryValueEx(hKey, szValueName, 0, NULL, (LPBYTE)pszData, &dwDataSize) == ERROR_SUCCESS)
+                {
+                    INT nReturnValue;
+
+                    /* Quote the file name if required */
+                    if(*pszData != '\"')
+                    {
+                        *(--pszData) = '\"';
+                        pszData[dwDataSize / sizeof(TCHAR)] = '\"';
+                        pszData[(dwDataSize / sizeof(TCHAR)) + 1] = 0;
+                    }
+
+                    nReturnValue = RunControlPanel(pszData);
+                    HeapFree(hProcessHeap, 0, pszData);
+                    RegCloseKey(hKey);
+
+                    return nReturnValue;
+                }
+
+                HeapFree(hProcessHeap, 0, pszData);
+            }
+        }
+
+        RegCloseKey(hKey);
     }
 
-  return 0;
-}
-
-
-static INT
-RunControlPanel(LPCTSTR lpName, UINT uIndex)
-{
-  CPLINFO CplInfo;
-  HMODULE hDll;
-  CPLAPPLETFUNC pFunc;
-  UINT uPanelCount;
-
-  hDll = LoadLibrary(lpName);
-  if (hDll == 0)
-    {
-      return -1;
-    }
-  CTL_DEBUG((_T("Handle %08X\r\n"), hDll));
-
-  pFunc = (CPLAPPLETFUNC)GetProcAddress(hDll, "CPlApplet");
-  if (pFunc == NULL)
-    {
-      FreeLibrary(hDll);
-      return -1;
-    }
-  CTL_DEBUG((_T("CPLFunc %08X\r\n"), pFunc));
-
-  if (!pFunc(NULL, CPL_INIT, 0, 0))
-    {
-      FreeLibrary(hDll);
-      return -1;
-    }
-
-  uPanelCount = (UINT)pFunc(NULL, CPL_GETCOUNT, 0, 0);
-  if (uIndex >= uPanelCount)
-    {
-      FreeLibrary(hDll);
-      return -1;
-    }
-
-  pFunc(NULL, CPL_INQUIRE, (LPARAM)uIndex, (LPARAM)&CplInfo);
-
-  pFunc(NULL, CPL_DBLCLK, CplInfo.lData, 0);
-
-  FreeLibrary(hDll);
-
-  return 0;
-}
-
-int
-_tmain(int argc, const TCHAR *argv[])
-{
-  STARTUPINFO si;
-  TCHAR * szExt;
-
-  si.cb = sizeof(si);
-  GetStartupInfo(&si);
-
-  hInst = GetModuleHandle(NULL);
-
-  if (argc <= 1)
-    {
-      /* No argument on the command line */
-      return RunControlPanelWindow(si.wShowWindow);
-    }
-
-  if (_tcsicmp(argv[1], _T("desktop")) == 0)
-    {
-      return RunControlPanel(_T("desk.cpl"), 0);
-    }
-  else if (_tcsicmp(argv[1], _T("date/time")) == 0)
-    {
-      return RunControlPanel(_T("timedate.cpl"), 0);
-    }
-  else if (_tcsicmp(argv[1], _T("international")) == 0)
-    {
-      return RunControlPanel(_T("intl.cpl"), 0);
-    }
-  else if (_tcsicmp(argv[1], _T("mouse")) == 0)
-    {
-      return RunControlPanel(_T("main.cpl"), 0);
-    }
-  else if (_tcsicmp(argv[1], _T("keyboard")) == 0)
-    {
-      return RunControlPanel(_T("main.cpl"), 1);
-    }
-  else if ((szExt = _tcsstr(argv[1], _T(".cpl"))))
-    {
-      TCHAR * szSep;
-      TCHAR szCPL[MAX_PATH];
-      UINT selPage = 0;    
-
-      _tcscpy(szCPL, argv[1]);
-      szSep = _tcsstr(szCPL, _T(".cpl,"));
-
-      if (szSep)
-        {
-          /* FIXME for now ignore page index */
-          szSep[4] = _T('\0');
-        }
-      return RunControlPanel(szCPL, selPage);
-    }
-
-  return 0;
-}
+    /* It's none of the known parameters, so interpret the parameter as the file name of a control panel applet */
+    return RunControlPanel(lpCmdLine);
+}

Propchange: trunk/reactos/base/applications/control/control.c
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords (removed)
@@ -1,1 +1,0 @@
-author date id revision

Added: trunk/reactos/base/applications/control/control.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/control/control.h?rev=33507&view=auto
==============================================================================
--- trunk/reactos/base/applications/control/control.h (added)
+++ trunk/reactos/base/applications/control/control.h [iso-8859-1] Tue May 13 16:30:55 2008
@@ -1,0 +1,24 @@
+/*
+ * PROJECT:         ReactOS System Control Panel
+ * FILE:            base/applications/control/control.h
+ * PURPOSE:         ReactOS System Control Panel
+ * PROGRAMMERS:     Gero Kuehn (reactos.filter at gkware.com)
+ *                  Colin Finck (mail at colinfinck.de)
+ */
+
+#include <windows.h>
+#include <commctrl.h>
+#include <cpl.h>
+#include <tchar.h>
+
+#include "resource.h"
+
+#define MYWNDCLASS _T("CTLPANELCLASS")
+typedef LONG (CALLBACK *CPLAPPLETFUNC)(HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
+
+#define CCH_UINT_MAX   11
+#define MAX_VALUE_NAME 16383
+
+/* Macro for calling "rundll32.exe"
+   According to MSDN, ShellExecute returns a value greater than 32 if the operation was successful. */
+#define RUNDLL(param)   ((int)ShellExecute(NULL, _T("open"), _T("rundll32.exe"), (param), NULL, SW_SHOWDEFAULT) > 32)

Propchange: trunk/reactos/base/applications/control/control.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/base/applications/control/control.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/control/control.rbuild?rev=33507&r1=33506&r2=33507&view=diff
==============================================================================
--- trunk/reactos/base/applications/control/control.rbuild [iso-8859-1] (original)
+++ trunk/reactos/base/applications/control/control.rbuild [iso-8859-1] Tue May 13 16:30:55 2008
@@ -4,9 +4,11 @@
 	<include base="control">.</include>
 	<define name="_WIN32_IE">0x600</define>
 	<define name="_WIN32_WINNT">0x501</define>
+	<library>advapi32</library>
+	<library>comctl32</library>
 	<library>kernel32</library>
+	<library>shell32</library>
 	<library>user32</library>
-	<library>comctl32</library>
 	<file>control.c</file>
 	<file>control.rc</file>
 </module>



More information about the Ros-diffs mailing list