Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

796 lines
26 KiB

#include "shellprv.h"
#pragma hdrstop
// BUGBUG: duplicate strings as in cstrings.c
TCHAR const c_szSSlashS[] = TEXT("%s\\%s");
extern TCHAR g_szFileTemplate[]; // used to build type name...
extern BOOL App_IsLFNAware(LPCTSTR pszFile);
void _GenerateAssociateNotify(LPTSTR pszExt)
{
TCHAR szFakePath[MAX_PATH];
LPITEMIDLIST pidl;
//
// This is a real hack, but for now we generate an idlist that looks
// something like: C:\*.ext which is the extension for the IDList.
// We use the simple IDList as to not hit the disk...
//
PathBuildRoot(szFakePath, 2); // (c:\)
lstrcat(szFakePath, c_szStar);
lstrcat(szFakePath, pszExt);
pidl = SHSimpleIDListFromPath(szFakePath);
// Now call off to the notify function.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, pidl, NULL);
ILFree(pidl);
}
// Given a class key returns the shell\open\command string in szValue
// and the number of chars copied in cbMaxValue. cbMaxValue should
// be initialised to the max siz eof szValue.
// We now expect and return the count in characters (DavePl)
void GetCmdLine(LPCTSTR szKey, LPTSTR szValue, LONG cchValue)
{
TCHAR szTemp[MAX_PATH+40]; // Leave room for both extension plus junk on at end...
VDATEINPUTBUF(szValue, TCHAR, cchValue);
wsprintf(szTemp, c_szSSlashS, szKey, c_szShellOpenCmd);
szValue[0] = 0;
cchValue *= SIZEOF(TCHAR);
RegQueryValue(HKEY_CLASSES_ROOT, szTemp, szValue, &cchValue);
}
// uFlags GCD_ flags from GetClassDescription uFlags
void FillListWithClasses(HWND hwnd, BOOL fComboBox, UINT uFlags)
{
int i;
TCHAR szClass[CCH_KEYMAX];
TCHAR szDisplayName[CCH_KEYMAX];
LONG lcb;
SendMessage(hwnd, fComboBox ? CB_RESETCONTENT : LB_RESETCONTENT, 0, 0L);
if (uFlags & GCD_MUSTHAVEEXTASSOC)
{
TCHAR szExt[CCH_KEYMAX];
// The caller stated that they only want those classes that
// have have at least one extension associated with it.
//
for (i = 0; RegEnumKey(HKEY_CLASSES_ROOT, i, szClass, ARRAYSIZE(szClass)) == ERROR_SUCCESS; i++)
{
// Is this an extension
if (szClass[0] != TEXT('.'))
continue; // go process the next one...
// Get the class name
lstrcpy(szExt, szClass);
lcb = SIZEOF(szClass);
if ((RegQueryValue(HKEY_CLASSES_ROOT, szExt, szClass, &lcb) != ERROR_SUCCESS) || (lcb == 0))
continue; // Again we are not interested.
// use uFlags passed in to filter
if (GetClassDescription(HKEY_CLASSES_ROOT, szClass, szDisplayName, ARRAYSIZE(szDisplayName), uFlags))
{
int iItem;
/* If the display name is zero length then don't bother to show in the control. */
if ( !lstrlen( szDisplayName ) )
continue;
// Now make sure it is not already in the list...
if ((int)SendMessage(hwnd, fComboBox ? CB_FINDSTRINGEXACT : LB_FINDSTRINGEXACT,
(WPARAM)-1, (LPARAM)(LPTSTR)szDisplayName) >= 0)
continue; // allready in the list.
// sorted
iItem = (int)SendMessage(hwnd, fComboBox ? CB_ADDSTRING : LB_ADDSTRING,
0, (LONG)(LPTSTR)szDisplayName);
if (iItem >= 0)
SendMessage(hwnd, fComboBox ? CB_SETITEMDATA : LB_SETITEMDATA, iItem, (DWORD)AddHashItem(NULL, szClass));
}
}
}
else
{
for (i = 0; RegEnumKey(HKEY_CLASSES_ROOT, i, szClass, ARRAYSIZE(szClass)) == ERROR_SUCCESS; i++)
{
// use uFlags passed in to filter
if (GetClassDescription(HKEY_CLASSES_ROOT, szClass, szDisplayName, ARRAYSIZE(szDisplayName), uFlags))
{
// sorted
int iItem = (int)SendMessage(hwnd, fComboBox ? CB_ADDSTRING : LB_ADDSTRING,
0, (LONG)(LPTSTR)szDisplayName);
if (iItem >= 0)
SendMessage(hwnd, fComboBox ? CB_SETITEMDATA : LB_SETITEMDATA, iItem, (DWORD)AddHashItem(NULL, szClass));
}
}
}
}
// get the displayable name for file types "classes"
//
//
// uFlags:
// GCD_MUSTHAVEOPENCMD only returns things with open verbs
// GCD_ADDEXETODISPNAME append the name of the ext that is in the open cmd
// (GCD_MUSTHAVEOPENCMD)
// GCD_ALLOWPSUDEOCLASSES return psudeo classes, those with stuff haning
// off the .ext key
BOOL GetClassDescription(HKEY hkClasses, LPCTSTR pszClass, LPTSTR szDisplayName, int cchDisplayName, UINT uFlags)
{
TCHAR szExe[MAX_PATH];
TCHAR szClass[CCH_KEYMAX];
LPTSTR pszExeFile;
LONG lcb;
// Skip things that aren't classes (extensions).
if (pszClass[0] == TEXT('.'))
{
if (uFlags & GCD_ALLOWPSUDEOCLASSES)
{
lcb = SIZEOF(szClass);
if ((RegQueryValue(hkClasses, pszClass, szClass, &lcb) != ERROR_SUCCESS) || (lcb == 0))
{
// look for .ext\shel\open\command directly (hard wired association)
// if this extenstion does not name a real class
GetCmdLine(pszClass, szExe, ARRAYSIZE(szExe));
if (szExe[0]) {
lstrcpyn(szDisplayName, PathFindFileName(szExe), cchDisplayName);
return TRUE;
}
return FALSE;
}
pszClass = szClass;
}
else
{
return FALSE; // don't return psudeo class
}
}
// REVIEW: we should really special case the OLE junk here. if pszClass is
// CLSID, Interface, TypeLib, etc we should skip it
// REVIEW: we really need to verify that some extension points at this type to verfy
// that it is valid. perhaps the existance of a "shell" key is enough.
// get the classes displayable name
lcb = cchDisplayName * SIZEOF(TCHAR);
if (RegQueryValue(hkClasses, pszClass, szDisplayName, &lcb) != ERROR_SUCCESS || (lcb < 2))
return FALSE;
if (uFlags & GCD_MUSTHAVEOPENCMD)
{
// verify that it has an open command
GetCmdLine(pszClass, szExe, ARRAYSIZE(szExe));
if (!szExe[0])
return FALSE;
// BUGBUG: currently this is dead functionallity
if (uFlags & GCD_ADDEXETODISPNAME)
{
PathRemoveArgs(szExe);
// eliminate per instance type things (programs, pif, etc)
// Skip things that aren't relevant ot the shell.
if (szExe[0] == TEXT('%'))
return FALSE;
// skip things with per-instance type associations
pszExeFile = PathFindFileName(szExe);
if ((int)((lstrlen(szDisplayName) + lstrlen(pszExeFile) + 2)) < cchDisplayName)
{
wsprintf(szDisplayName + lstrlen(szDisplayName), TEXT(" (%s)"), pszExeFile);
}
}
}
return TRUE;
}
void DeleteListAttoms(HWND hwnd, BOOL fComboBox)
{
int cItems;
PHASHITEM phiClass;
int iGetDataMsg;
iGetDataMsg = fComboBox ? CB_GETITEMDATA : LB_GETITEMDATA;
cItems = (int)SendMessage(hwnd, fComboBox ? CB_GETCOUNT : LB_GETCOUNT, 0, 0) - 1;
/* clean out them atoms except for "(none)".
*/
for (; cItems >= 0; cItems--)
{
phiClass = (PHASHITEM)SendMessage(hwnd, iGetDataMsg, cItems, 0L);
if (phiClass != (PHASHITEM)LB_ERR && phiClass)
DeleteHashItem(NULL, phiClass);
}
}
// BEGIN new stuff
typedef struct { // oad
// params
HWND hwnd;
LPCTSTR lpszFile;
// local data
int idDlg;
HWND hDlg;
HWND hwndList;
LPTSTR lpszExt;
TCHAR szTypeName[CCH_KEYMAX]; // type name
TCHAR szDescription[CCH_KEYMAX]; // type description
} OPENAS_DATA, *POPENAS_DATA;
typedef struct {
UINT bHasQuote; // Did we find a quote around param? "%1"
TCHAR szApp[MAX_PATH+2]; // May need room for quotes
} APPINFO;
#define HASQUOTE_NO 0
#define HASQUOTE_MAYBE 1
#define HASQUOTE_YES 3
void FillListWithApps(HWND hwndList)
{
int i, iMax;
TCHAR szClass[CCH_KEYMAX];
TCHAR szKey[CCH_KEYMAX];
TCHAR szValue[MAX_PATH];
APPINFO *paiLast;
LV_ITEM item;
int iLast;
BOOL fLastExists = FALSE;
for (i = 0; RegEnumKey(HKEY_CLASSES_ROOT, i, szClass, ARRAYSIZE(szClass)) == ERROR_SUCCESS; i++)
{
LONG lTmp;
wsprintf(szKey, c_szSSlashS, szClass, c_szShellOpenCmd);
lTmp = SIZEOF(szValue);
if (RegQueryValue(HKEY_CLASSES_ROOT, szKey, szValue, &lTmp) == ERROR_SUCCESS)
{
// filter out stuff we know is bogus
// strings that start with: %1, "%1"
// strings that contain: rundll
//
if ((szValue[0] != TEXT('%')) &&
((szValue[0] != TEXT('"')) || (szValue[1] != TEXT('%'))) &&
(StrStr(szValue, c_szRunDll) == NULL))
{
APPINFO *pai = (APPINFO *)LocalAlloc(LPTR, SIZEOF(APPINFO));
if (pai)
{
// See if we we can find %1 in the string.
LPTSTR pszT = StrStr(szValue, c_szPercentOne);
if (pszT)
{
if (*--pszT == TEXT('"'))
pai->bHasQuote = HASQUOTE_YES;
}
PathRemoveArgs(szValue);
lstrcpy(pai->szApp, szValue);
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
item.iItem = 0x7FFF;
item.iSubItem = 0;
item.state = 0;
item.iImage = I_IMAGECALLBACK;
PathRemoveExtension(szValue);
item.pszText = PathFindFileName(szValue);
item.lParam = (LPARAM)pai;
ListView_InsertItem(hwndList, &item);
}
}
}
}
// punt dups
ListView_SortItems(hwndList, NULL, 0);
paiLast = NULL;
// szKey will hold the lpszLast's display name
for (i = 0, iMax = ListView_GetItemCount(hwndList); i < iMax; i++)
{
APPINFO *pai;
item.mask = LVIF_TEXT | LVIF_PARAM;
item.iItem = i;
item.iSubItem = 0;
item.pszText = szValue;
item.cchTextMax = ARRAYSIZE(szValue);
// get the text string
ListView_GetItem(hwndList, &item);
pai = (APPINFO *)item.lParam;
if (paiLast && (!lstrcmpi(szKey, szValue))) {
int iDelete = i;
// if they are different in path, delete the one that doesn't exit (or the new one if they both do)
if (lstrcmpi(paiLast->szApp, pai->szApp)) {
if (!fLastExists && !(fLastExists = PathFileExists(pai->szApp))) {
if (paiLast->bHasQuote > pai->bHasQuote)
pai->bHasQuote = paiLast->bHasQuote;
iDelete = iLast;
}
}
// Will assume that if either item has quote set that it will work...
if (pai->bHasQuote > paiLast->bHasQuote)
paiLast->bHasQuote =pai->bHasQuote;
ListView_DeleteItem(hwndList, iDelete);
i--; iMax--;
// we deleted the iLast, we need to set a new iLast
if (iDelete == iLast)
goto NewLastExe;
} else {
NewLastExe:
iLast = i;
paiLast = pai;
lstrcpy(szKey, szValue);
fLastExists = TRUE;
}
}
// Lets set the focus to first item, but not the focus as some users
// have made the mistake and type in the name and hit return and it
// runs the first guy in the list which in the current cases tries to
// run the backup app...
ListView_SetItemState(hwndList, 0, LVNI_FOCUSED, LVNI_FOCUSED | LVNI_SELECTED);
SetFocus(hwndList);
}
void _InitOpenAsDlg(POPENAS_DATA poad)
{
TCHAR szFormat[200];
TCHAR szFileName[MAX_PATH];
TCHAR szTemp[MAX_PATH + ARRAYSIZE(szFormat)];
BOOL fDisableAssociate;
HIMAGELIST himlLarge, himlSmall;
LV_COLUMN col = {LVCF_FMT | LVCF_WIDTH, LVCFMT_LEFT};
RECT rc;
// Don't let the file name go beyond the width of one line...
GetDlgItemText(poad->hDlg, IDD_TEXT, szFormat, ARRAYSIZE(szFormat));
lstrcpy(szFileName, PathFindFileName(poad->lpszFile));
GetClientRect(GetDlgItem(poad->hDlg, IDD_TEXT), &rc);
PathCompactPath(NULL, szFileName, rc.right - 4 * GetSystemMetrics(SM_CXBORDER));
wsprintf(szTemp, szFormat, szFileName);
SetDlgItemText(poad->hDlg, IDD_TEXT, szTemp);
// Don't allow associations to be made for things we consider exes...
fDisableAssociate = PathIsExe(poad->lpszFile);
if (poad->idDlg == DLG_OPENAS_NOTYPE) {
GetDlgItemText(poad->hDlg, IDD_DESCRIPTIONTEXT, szFormat, ARRAYSIZE(szFormat));
wsprintf(szTemp, szFormat, poad->lpszExt);
SetDlgItemText(poad->hDlg, IDD_DESCRIPTIONTEXT, szTemp);
// Default to Set the association here if we do not know what
// the file is...
if (!fDisableAssociate)
CheckDlgButton(poad->hDlg, IDD_MAKEASSOC, TRUE);
}
if (fDisableAssociate)
EnableWindow(GetDlgItem(poad->hDlg, IDD_MAKEASSOC), FALSE);
poad->hwndList = GetDlgItem(poad->hDlg, IDD_APPLIST);
Shell_GetImageLists(&himlLarge, &himlSmall);
ListView_SetImageList(poad->hwndList, himlLarge, LVSIL_NORMAL);
ListView_SetImageList(poad->hwndList, himlSmall, LVSIL_SMALL);
SetWindowLong(poad->hwndList, GWL_EXSTYLE,
GetWindowLong(poad->hwndList, GWL_EXSTYLE) | WS_EX_CLIENTEDGE);
GetClientRect(poad->hwndList, &rc);
col.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL)
- 4 * GetSystemMetrics(SM_CXEDGE);
ListView_InsertColumn(poad->hwndList, 0, &col);
FillListWithApps(poad->hwndList);
// and initialize the OK button
EnableWindow(GetDlgItem(poad->hDlg, IDOK),
(ListView_GetNextItem(poad->hwndList, -1, LVNI_SELECTED) != -1));
}
void RunAs(POPENAS_DATA poad)
{
SHELLEXECUTEINFO ExecInfo;
// If this run created a new type we should use it, otherwise we should
// construct a command using the exe that we selected...
if (*poad->lpszExt && IsDlgButtonChecked(poad->hDlg, IDD_MAKEASSOC))
{
FillExecInfo(ExecInfo, poad->hwnd, NULL, poad->lpszFile, NULL, NULL, SW_NORMAL);
}
else
{
TCHAR szApp[MAX_PATH];
TCHAR szQuotedFile[MAX_PATH+2];
APPINFO *pai;
int iItemFocus = ListView_GetNextItem(poad->hwndList, -1, LVNI_SELECTED);
pai = (APPINFO *)LVUtil_GetLParam(poad->hwndList, iItemFocus);
lstrcpy(szQuotedFile, poad->lpszFile);
lstrcpy(szApp, pai->szApp);
PathUnquoteSpaces(szApp);
// Try to intellegently quote blanks or not...
if (!App_IsLFNAware(szApp))
{
// We better also make sure that this a short path name
// pass off to the application...
PathGetShortPath(szQuotedFile);
}
else
{
// Either maybe or yes is we should quote
if (pai->bHasQuote)
PathQuoteSpaces(szQuotedFile);
}
FillExecInfo(ExecInfo, poad->hwnd, NULL, szApp, szQuotedFile, NULL, SW_NORMAL);
}
ShellExecuteEx(&ExecInfo);
}
void OpenAsOther(POPENAS_DATA poad)
{
TCHAR szText[MAX_PATH];
GetDlgItemText(poad->hDlg, IDD_COMMAND, szText, ARRAYSIZE(szText));
// do a file open browse
if (GetFileNameFromBrowse(poad->hDlg, szText, ARRAYSIZE(szText), NULL,
MAKEINTRESOURCE(IDS_EXE), MAKEINTRESOURCE(IDS_PROGRAMSFILTER), MAKEINTRESOURCE(IDS_OPENAS)))
{
// then add it to the list view and select it.
APPINFO *pai = (APPINFO *)LocalAlloc(LPTR, SIZEOF(APPINFO));
if (pai)
{
LV_ITEM item;
int i;
int iItem;
APPINFO *paiT;
pai->bHasQuote = HASQUOTE_MAYBE;
lstrcpy(pai->szApp, szText);
PathQuoteSpaces(pai->szApp);
item.mask = LVIF_TEXT|LVIF_STATE|LVIF_IMAGE|LVIF_PARAM;
item.iItem = 0x7FFF;
item.iSubItem = 0;
item.state = 0;
item.iImage = I_IMAGECALLBACK;
PathRemoveExtension(szText);
item.pszText = PathFindFileName(szText);
item.lParam = (LPARAM)pai;
i = ListView_InsertItem(poad->hwndList, &item);
ListView_SetItemState(poad->hwndList, i, LVNI_SELECTED | LVNI_FOCUSED, LVNI_SELECTED | LVNI_FOCUSED);
ListView_EnsureVisible(poad->hwndList, i, FALSE);
SetFocus(poad->hwndList);
// We also want to see if we find another entry in the listview for the
// application. We do this such that we can see if the app supports
// quotes or not.
for (iItem = ListView_GetItemCount(poad->hwndList) - 1; iItem >= 0; iItem--)
{
if (iItem == i)
continue;
item.mask = LVIF_PARAM;
item.iItem = iItem;
item.iSubItem = 0;
ListView_GetItem(poad->hwndList, &item);
paiT = (APPINFO *)item.lParam;
if (lstrcmpi(pai->szApp, paiT->szApp) == 0)
{
pai->bHasQuote = paiT->bHasQuote;
break;
}
}
}
}
}
// return true if ok to continue
BOOL OpenAsMakeAssociation(POPENAS_DATA poad)
{
UINT err;
// See if we should make an association or not...
if (!IsDlgButtonChecked(poad->hDlg, IDD_MAKEASSOC))
return(TRUE);
if (poad->idDlg == DLG_OPENAS_NOTYPE)
{
if (!GetDlgItemText(poad->hDlg, IDD_DESCRIPTION, poad->szDescription, ARRAYSIZE(poad->szDescription)))
{
TCHAR szExt[_MAX_EXT];
int cchMaxExtCopy = min((ARRAYSIZE(poad->szDescription)-lstrlen(g_szFileTemplate)), ARRAYSIZE(szExt));
lstrcpyn(szExt, CharNext(poad->lpszExt), cchMaxExtCopy);
#if (defined(DBCS) || (defined(FE_SB) && !defined(UNICODE)))
AnsiUpperNoDBCS(szExt);
#else
CharUpper(szExt);
#endif
wsprintf(poad->szDescription, g_szFileTemplate, szExt);
}
lstrcpyn(poad->szTypeName, poad->lpszExt+1, ARRAYSIZE(poad->szTypeName)
- SIZEOF(TEXT("_auto_file")));
lstrcat(poad->szTypeName, TEXT("_auto_file"));
err = RegSetValue(HKEY_CLASSES_ROOT, poad->lpszExt, REG_SZ, poad->szTypeName, 0L);
err |= RegSetValue(HKEY_CLASSES_ROOT, poad->szTypeName, REG_SZ, poad->szDescription, 0L);
Assert(err == ERROR_SUCCESS);
if (err != ERROR_SUCCESS)
{
MessageBeep(MB_ICONEXCLAMATION);
return(FALSE);
}
}
if (*poad->lpszExt) {
TCHAR szTemp[MAX_PATH];
TCHAR szCommand[MAX_PATH + 10];
int iItemFocus = ListView_GetNextItem(poad->hwndList, -1, LVNI_FOCUSED);
APPINFO *pai = (APPINFO *)LVUtil_GetLParam(poad->hwndList, iItemFocus);
// We need to set the open commands value to empty to take care of cases
// that have something like: open=&Merge
wsprintf(szTemp, TEXT("%s\\shell\\open"), poad->szTypeName);
err = RegSetValue(HKEY_CLASSES_ROOT, szTemp, REG_SZ, c_szNULL, 0L);
lstrcat(szTemp, c_szSlashCommand);
if ((pai->bHasQuote == HASQUOTE_YES) ||
((pai->bHasQuote == HASQUOTE_MAYBE) && App_IsLFNAware(pai->szApp)))
wsprintf(szCommand, TEXT("%s \"%%1\""), pai->szApp);
else
wsprintf(szCommand, TEXT("%s %%1"), pai->szApp);
err = RegSetValue(HKEY_CLASSES_ROOT, szTemp, REG_SZ, szCommand, 0L);
Assert(err == ERROR_SUCCESS);
if (err != ERROR_SUCCESS)
{
MessageBeep(MB_ICONEXCLAMATION);
return(FALSE);
}
// Need to delete any ddeexec information that might also exist...
PathRemoveFileSpec(szTemp); // Remove the command (last component)
lstrcat(szTemp, c_szSlashDDEExec);
RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
// notify views
_GenerateAssociateNotify(poad->lpszExt);
}
return TRUE;
}
#pragma data_seg(DATASEG_READONLY)
const static DWORD aOpenAsHelpIDs[] = { // Context Help IDs
IDD_TEXT, IDH_FCAB_OPENAS_DESCRIPTION,
IDD_DESCRIPTIONTEXT, IDH_FCAB_OPENAS_DESCRIPTION,
IDD_DESCRIPTION, IDH_FCAB_OPENAS_DESCRIPTION,
IDD_APPLIST, IDH_FCAB_OPENAS_APPLIST,
IDD_MAKEASSOC, IDH_FCAB_OPENAS_MAKEASSOC,
IDD_OTHER, IDH_FCAB_OPENAS_OTHER,
0, 0
};
#pragma data_seg()
BOOL CALLBACK OpenAsDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
POPENAS_DATA poad = (POPENAS_DATA)GetWindowLong(hDlg, DWL_USER);
switch (wMsg) {
case WM_INITDIALOG:
SetWindowLong(hDlg, DWL_USER, lParam);
poad = (POPENAS_DATA)lParam;
poad->hDlg = hDlg;
_InitOpenAsDlg(poad);
break;
case WM_HELP:
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, NULL,
HELP_WM_HELP, (DWORD)(LPTSTR) aOpenAsHelpIDs);
break;
case WM_CONTEXTMENU:
if ((int)SendMessage(hDlg, WM_NCHITTEST, 0, lParam) != HTCLIENT)
return FALSE; // don't process it
WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU,
(DWORD)(LPVOID)aOpenAsHelpIDs);
break;
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case LVN_GETDISPINFO:
{
#define pdi ((LV_DISPINFO *)lParam)
TCHAR szApp[MAX_PATH];
APPINFO *pai = (APPINFO *)pdi->item.lParam;
lstrcpy(szApp, pai->szApp);
PathUnquoteSpaces(szApp);
pdi->item.iImage = Shell_GetCachedImageIndex(szApp, 0, 0);
if (pdi->item.iImage == -1)
{
pdi->item.iImage = Shell_GetCachedImageIndex(c_szShell32Dll,
II_APPLICATION, 0);
}
break;
#undef pdi
}
case LVN_DELETEITEM:
LocalFree((HLOCAL)((NM_LISTVIEW *)lParam)->lParam);
break;
case LVN_ITEMCHANGED:
EnableWindow(GetDlgItem(hDlg, IDOK),
(ListView_GetNextItem(poad->hwndList, -1, LVNI_SELECTED) != -1));
break;
case NM_DBLCLK:
if (IsWindowEnabled(GetDlgItem(hDlg, IDOK)))
PostMessage(hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(IDOK, hDlg, 0));
break;
}
break;
case WM_COMMAND:
Assert(poad);
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDD_OTHER:
OpenAsOther(poad);
break;
case IDOK:
// BUGBUG: Implement me.. make association first
if (!OpenAsMakeAssociation(poad))
break;
RunAs(poad);
SHAddToRecentDocs(SHARD_PATH, poad->lpszFile);
/*** FALL THRU ***/
case IDCANCEL:
EndDialog(hDlg, wParam == IDOK);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
// external API version
int OpenAsDialog(HWND hwnd, LPCTSTR lpszFile)
{
OPENAS_DATA oad;
int idDlg;
oad.hwnd = hwnd;
oad.lpszFile = lpszFile;
oad.szDescription[0] = 0;
oad.szTypeName[0] = 0;
DebugMsg(DM_TRACE, TEXT("Enter OpenAs for %s"), lpszFile);
oad.lpszExt = PathFindExtension(lpszFile);
if (*oad.lpszExt) {
LONG lTmp = SIZEOF(oad.szTypeName);
if ((RegQueryValue(HKEY_CLASSES_ROOT, oad.lpszExt, oad.szTypeName, &lTmp) == ERROR_SUCCESS)
&& (lTmp != 0) && (*oad.szTypeName)) {
idDlg = DLG_OPENAS;
} else
idDlg = DLG_OPENAS_NOTYPE;
} else {
idDlg = DLG_OPENAS;
}
oad.idDlg = idDlg;
return DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(idDlg), hwnd, OpenAsDlgProc, (LPARAM)(POPENAS_DATA)&oad);
}
void WINAPI OpenAs_RunDLL(HWND hwnd, HINSTANCE hAppInstance, LPSTR lpszCmdLine, int nCmdShow)
{
#ifdef UNICODE
UINT iLen = lstrlenA(lpszCmdLine)+1;
LPWSTR lpwszCmdLine;
lpwszCmdLine = (LPWSTR)LocalAlloc(LPTR,iLen*SIZEOF(WCHAR));
if (lpwszCmdLine)
{
MultiByteToWideChar(CP_ACP, 0,
lpszCmdLine, -1,
lpwszCmdLine, iLen);
DebugMsg(DM_TRACE, TEXT("OpenAs_RunDLL is called with (%s)"), lpwszCmdLine);
OpenAsDialog(hwnd, lpwszCmdLine);
LocalFree(lpwszCmdLine);
}
#else
DebugMsg(DM_TRACE, TEXT("OpenAs_RunDLL is called with (%s)"), lpszCmdLine);
OpenAsDialog(hwnd, lpszCmdLine);
#endif
}
void WINAPI OpenAs_RunDLLW(HWND hwnd, HINSTANCE hAppInstance, LPWSTR lpwszCmdLine, int nCmdShow)
{
#ifdef UNICODE
DebugMsg(DM_TRACE, TEXT("OpenAs_RunDLL is called with (%s)"), lpwszCmdLine);
OpenAsDialog(hwnd, lpwszCmdLine);
#else
UINT iLen = WideCharToMultiByte(CP_ACP, 0,
lpwszCmdLine, -1,
NULL, 0, NULL, NULL)+1;
LPSTR lpszCmdLine;
lpszCmdLine = (LPSTR)LocalAlloc(LPTR,iLen);
if (lpszCmdLine)
{
WideCharToMultiByte(CP_ACP, 0,
lpwszCmdLine, -1,
lpszCmdLine, iLen,
NULL, NULL);
DebugMsg(DM_TRACE, TEXT("OpenAs_RunDLL is called with (%s)"), lpszCmdLine);
OpenAsDialog( hwnd, lpszCmdLine);
LocalFree(lpszCmdLine);
}
#endif
}
#ifdef DEBUG
//
// Type checking
//
static RUNDLLPROCA lpfnRunDLL = OpenAs_RunDLL;
static RUNDLLPROCW lpfnRunDLLW = OpenAs_RunDLLW;
#endif