mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 17:30:32 +00:00
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. svn path=/trunk/; revision=33507
This commit is contained in:
parent
ce69bc85e4
commit
6efebc63d2
3 changed files with 390 additions and 404 deletions
|
@ -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.
|
|
||||||
*/
|
|
||||||
/* $Id$
|
|
||||||
*
|
|
||||||
* PROJECT: ReactOS System Control Panel
|
* PROJECT: ReactOS System Control Panel
|
||||||
* FILE: lib/cpl/system/control.c
|
* FILE: base/applications/control/control.c
|
||||||
* PURPOSE: ReactOS System Control Panel
|
* PURPOSE: ReactOS System Control Panel
|
||||||
* PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
|
* PROGRAMMERS: Gero Kuehn (reactos.filter@gkware.com)
|
||||||
* UPDATE HISTORY:
|
* Colin Finck (mail@colinfinck.de)
|
||||||
* 06-13-2004 Created
|
|
||||||
*/
|
*/
|
||||||
#include <windows.h>
|
|
||||||
#include <commctrl.h>
|
|
||||||
#include <cpl.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "control.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
|
|
||||||
#include "resource.h"
|
static const TCHAR szWindowClass[] = _T("DummyControlClass");
|
||||||
|
|
||||||
//#define CONTROL_DEBUG_ENABLE
|
HANDLE hProcessHeap;
|
||||||
|
|
||||||
#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;
|
|
||||||
HINSTANCE hInst;
|
HINSTANCE hInst;
|
||||||
HWND hMainWnd;
|
|
||||||
DEVMODE pDevMode;
|
|
||||||
|
|
||||||
VOID dbgprint(TCHAR *format,...)
|
static INT
|
||||||
|
OpenShellFolder(LPTSTR lpFolderCLSID)
|
||||||
{
|
{
|
||||||
TCHAR buf[1000];
|
TCHAR szParameters[MAX_PATH];
|
||||||
va_list va;
|
|
||||||
|
|
||||||
va_start(va,format);
|
/* Open a shell folder using "explorer.exe".
|
||||||
_vstprintf(buf,format,va);
|
The passed CLSID's are all subfolders of the "Control Panel" shell folder. */
|
||||||
OutputDebugString(buf);
|
_tcscpy(szParameters, _T("/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"));
|
||||||
va_end(va);
|
_tcscat(szParameters, lpFolderCLSID);
|
||||||
|
|
||||||
|
return (int)ShellExecute(NULL, _T("open"), _T("explorer.exe"), szParameters, NULL, SW_SHOWDEFAULT) > 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PopulateCPLList(HWND hLisCtrl)
|
static INT
|
||||||
|
RunControlPanel(LPTSTR lpCmd)
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATA fd;
|
TCHAR szParameters[MAX_PATH];
|
||||||
HANDLE hFind;
|
|
||||||
TCHAR pszSearchPath[MAX_PATH];
|
|
||||||
HIMAGELIST hImgListSmall;
|
|
||||||
HIMAGELIST hImgListLarge;
|
|
||||||
int ColorDepth;
|
|
||||||
HMODULE hDll;
|
|
||||||
CPLAPPLETFUNC pFunc;
|
|
||||||
TCHAR pszPath[MAX_PATH];
|
|
||||||
|
|
||||||
/* Icon drawing mode */
|
_tcscpy(szParameters, _T("shell32.dll,Control_RunDLL "));
|
||||||
pDevMode.dmSize = sizeof(DEVMODE);
|
_tcscat(szParameters, lpCmd);
|
||||||
pDevMode.dmDriverExtra = 0;
|
|
||||||
|
|
||||||
EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&pDevMode);
|
return RUNDLL(szParameters);
|
||||||
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)
|
static VOID
|
||||||
|
PopulateCPLList(HWND hLisCtrl)
|
||||||
{
|
{
|
||||||
TCHAR szBuf[1024];
|
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;
|
||||||
|
|
||||||
switch (uMsg)
|
/* Icon drawing mode */
|
||||||
{
|
pDevMode.dmSize = sizeof(DEVMODE);
|
||||||
case WM_CREATE:
|
pDevMode.dmDriverExtra = 0;
|
||||||
{
|
|
||||||
RECT rect;
|
|
||||||
LV_COLUMN column;
|
|
||||||
|
|
||||||
GetClientRect(hWnd,&rect);
|
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &pDevMode);
|
||||||
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);
|
hImgListSmall = ImageList_Create(16, 16, pDevMode.dmBitsPerPel | ILC_MASK, 5, 5);
|
||||||
CTL_DEBUG((_T("Listview Window %08X\r\n"),hListView));
|
hImgListLarge = ImageList_Create(32, 32, pDevMode.dmBitsPerPel | ILC_MASK, 5, 5);
|
||||||
|
|
||||||
memset(&column,0x00,sizeof(column));
|
GetSystemDirectory(pszSearchPath, MAX_PATH);
|
||||||
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
|
_tcscat(pszSearchPath, _T("\\*.cpl"));
|
||||||
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);
|
hFind = FindFirstFile(pszSearchPath, &fd);
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_DESTROY:
|
while (hFind != INVALID_HANDLE_VALUE)
|
||||||
PostQuitMessage(0);
|
{
|
||||||
break;
|
_tcscpy(pszPath, pszSearchPath);
|
||||||
|
*_tcsrchr(pszPath, '\\') = 0;
|
||||||
|
_tcscat(pszPath, _T("\\"));
|
||||||
|
_tcscat(pszPath, fd.cFileName);
|
||||||
|
|
||||||
case WM_SIZE:
|
hDll = LoadLibrary(pszPath);
|
||||||
{
|
pFunc = (CPLAPPLETFUNC)GetProcAddress(hDll, "CPlApplet");
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
GetClientRect(hWnd,&rect);
|
if (pFunc && pFunc(hLisCtrl, CPL_INIT, 0, 0))
|
||||||
MoveWindow(hListView,0,0,rect.right,rect.bottom,TRUE);
|
{
|
||||||
}
|
UINT i, uPanelCount;
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_NOTIFY:
|
uPanelCount = (UINT)pFunc(hLisCtrl, CPL_GETCOUNT, 0, 0);
|
||||||
{
|
|
||||||
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);
|
for (i = 0; i < uPanelCount; i++)
|
||||||
|
{
|
||||||
|
CPLINFO CplInfo;
|
||||||
|
HICON hIcon;
|
||||||
|
TCHAR Name[MAX_PATH];
|
||||||
|
int index;
|
||||||
|
LPTSTR pszCmd;
|
||||||
|
|
||||||
if (nSelect==-1)
|
pszCmd = (LPTSTR) HeapAlloc(hProcessHeap, 0, MAX_PATH * sizeof(TCHAR));
|
||||||
{
|
if(!pszCmd)
|
||||||
/* no items */
|
return;
|
||||||
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));
|
/* Build the command, which is later passed to RunControlPanel */
|
||||||
memset(&lvi,0x00,sizeof(lvi));
|
_tcscpy(pszCmd, fd.cFileName);
|
||||||
lvi.iItem = nSelect;
|
_tcscat(pszCmd, _T(" @"));
|
||||||
lvi.mask = LVIF_PARAM;
|
_itot(i, szPanelNum, 10);
|
||||||
(void)ListView_GetItem(hListView,&lvi);
|
_tcscat(pszCmd, szPanelNum);
|
||||||
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)
|
pFunc(hLisCtrl, CPL_INQUIRE, (LPARAM)i, (LPARAM)&CplInfo);
|
||||||
pEntry->pFunc(hListView,CPL_DBLCLK,pEntry->CplInfo.lData,0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_COMMAND:
|
hIcon = LoadImage(hDll, MAKEINTRESOURCE(CplInfo.idIcon), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
||||||
switch (LOWORD(wParam))
|
index = ImageList_AddIcon(hImgListSmall, hIcon);
|
||||||
{
|
DestroyIcon(hIcon);
|
||||||
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:
|
hIcon = LoadImage(hDll, MAKEINTRESOURCE(CplInfo.idIcon), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
|
||||||
return DefWindowProc(hWnd,uMsg,wParam,lParam);
|
ImageList_AddIcon(hImgListLarge, hIcon);
|
||||||
}
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
return 0;
|
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
|
static INT
|
||||||
RunControlPanelWindow(int nCmdShow)
|
RunControlPanelWindow(int nCmdShow)
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
WNDCLASS wc;
|
HWND hMainWnd;
|
||||||
TCHAR szBuf[256];
|
INITCOMMONCONTROLSEX icex;
|
||||||
|
WNDCLASSEX wcex = {0};
|
||||||
|
TCHAR szBuf[256];
|
||||||
|
|
||||||
memset(&wc,0x00,sizeof(wc));
|
wcex.cbSize = sizeof(wcex);
|
||||||
wc.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAINICON));
|
wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAINICON));
|
||||||
wc.lpszClassName = MYWNDCLASS;
|
wcex.lpszClassName = MYWNDCLASS;
|
||||||
wc.lpszMenuName = _T("MAINMENU");
|
wcex.lpfnWndProc = MyWindowProc;
|
||||||
wc.lpfnWndProc = MyWindowProc;
|
RegisterClassEx(&wcex);
|
||||||
RegisterClass(&wc);
|
|
||||||
|
|
||||||
InitCommonControls();
|
icex.dwSize = sizeof(icex);
|
||||||
|
icex.dwICC = ICC_LISTVIEW_CLASSES;
|
||||||
LoadString(hInst, IDS_WINDOW_TITLE, szBuf, sizeof(szBuf) / sizeof(TCHAR));
|
InitCommonControlsEx(&icex);
|
||||||
hMainWnd = CreateWindowEx(WS_EX_CLIENTEDGE,
|
|
||||||
MYWNDCLASS,
|
LoadString(hInst, IDS_WINDOW_TITLE, szBuf, sizeof(szBuf) / sizeof(TCHAR));
|
||||||
(LPCTSTR)szBuf,
|
|
||||||
WS_OVERLAPPEDWINDOW,
|
hMainWnd = CreateWindowEx(WS_EX_CLIENTEDGE,
|
||||||
CW_USEDEFAULT,
|
MYWNDCLASS,
|
||||||
CW_USEDEFAULT,
|
(LPCTSTR)szBuf,
|
||||||
CW_USEDEFAULT,
|
WS_OVERLAPPEDWINDOW,
|
||||||
CW_USEDEFAULT,
|
CW_USEDEFAULT,
|
||||||
NULL,
|
CW_USEDEFAULT,
|
||||||
LoadMenu(hInst, MAKEINTRESOURCE(IDM_MAINMENU)),
|
CW_USEDEFAULT,
|
||||||
hInst,
|
CW_USEDEFAULT,
|
||||||
0);
|
NULL,
|
||||||
if (!hMainWnd)
|
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")));
|
TranslateMessage(&msg);
|
||||||
return -1;
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow(hMainWnd, nCmdShow);
|
return 0;
|
||||||
while (GetMessage(&msg, 0, 0, 0))
|
|
||||||
{
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WINAPI
|
||||||
static INT
|
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
|
||||||
RunControlPanel(LPCTSTR lpName, UINT uIndex)
|
|
||||||
{
|
{
|
||||||
CPLINFO CplInfo;
|
HKEY hKey;
|
||||||
HMODULE hDll;
|
|
||||||
CPLAPPLETFUNC pFunc;
|
|
||||||
UINT uPanelCount;
|
|
||||||
|
|
||||||
hDll = LoadLibrary(lpName);
|
hInst = hInstance;
|
||||||
if (hDll == 0)
|
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)
|
||||||
{
|
{
|
||||||
return -1;
|
DWORD dwIndex;
|
||||||
}
|
|
||||||
CTL_DEBUG((_T("Handle %08X\r\n"), hDll));
|
|
||||||
|
|
||||||
pFunc = (CPLAPPLETFUNC)GetProcAddress(hDll, "CPlApplet");
|
for(dwIndex = 0; ; ++dwIndex)
|
||||||
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 */
|
DWORD dwDataSize;
|
||||||
szSep[4] = _T('\0');
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return RunControlPanel(szCPL, selPage);
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
24
reactos/base/applications/control/control.h
Normal file
24
reactos/base/applications/control/control.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS System Control Panel
|
||||||
|
* FILE: base/applications/control/control.h
|
||||||
|
* PURPOSE: ReactOS System Control Panel
|
||||||
|
* PROGRAMMERS: Gero Kuehn (reactos.filter@gkware.com)
|
||||||
|
* Colin Finck (mail@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)
|
|
@ -4,9 +4,11 @@
|
||||||
<include base="control">.</include>
|
<include base="control">.</include>
|
||||||
<define name="_WIN32_IE">0x600</define>
|
<define name="_WIN32_IE">0x600</define>
|
||||||
<define name="_WIN32_WINNT">0x501</define>
|
<define name="_WIN32_WINNT">0x501</define>
|
||||||
<library>kernel32</library>
|
<library>advapi32</library>
|
||||||
<library>user32</library>
|
|
||||||
<library>comctl32</library>
|
<library>comctl32</library>
|
||||||
|
<library>kernel32</library>
|
||||||
|
<library>shell32</library>
|
||||||
|
<library>user32</library>
|
||||||
<file>control.c</file>
|
<file>control.c</file>
|
||||||
<file>control.rc</file>
|
<file>control.rc</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
Loading…
Reference in a new issue