1428 lines
33 KiB
C++
1428 lines
33 KiB
C++
|
/*
|
||
|
* propsht.cpp - IPropSheetExt implementation for URL class.
|
||
|
*/
|
||
|
|
||
|
|
||
|
/* Headers
|
||
|
**********/
|
||
|
|
||
|
#include "project.hpp"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#undef NO_HELP // for help.h
|
||
|
|
||
|
#include <help.h>
|
||
|
|
||
|
#undef IDH_COMM_GROUPBOX // for addon.h
|
||
|
#include <addon.h>
|
||
|
|
||
|
#include "resource.h"
|
||
|
|
||
|
#include <mluisupp.h>
|
||
|
|
||
|
|
||
|
/* Types
|
||
|
********/
|
||
|
|
||
|
/* Internet Shortcut property sheet data */
|
||
|
|
||
|
typedef struct _isps
|
||
|
{
|
||
|
PROPSHEETPAGE psp;
|
||
|
|
||
|
PInternetShortcut pintshcut;
|
||
|
|
||
|
char rgchIconFile[MAX_PATH_LEN];
|
||
|
|
||
|
int niIcon;
|
||
|
}
|
||
|
ISPS;
|
||
|
DECLARE_STANDARD_TYPES(ISPS);
|
||
|
|
||
|
|
||
|
/* Module Constants
|
||
|
*******************/
|
||
|
|
||
|
#pragma data_seg(DATA_SEG_READ_ONLY)
|
||
|
|
||
|
// Tray notification window class
|
||
|
|
||
|
PRIVATE_DATA const char s_cszTrayNotificationClass[] = WNDCLASS_TRAYNOTIFY;
|
||
|
|
||
|
// HACKHACK: WMTRAY_SCREGISTERHOTKEY and WMTRAY_SCUNREGISTERHOTKEY are stolen
|
||
|
// from shelldll\link.c.
|
||
|
|
||
|
PRIVATE_DATA CUINT WMTRAY_SCREGISTERHOTKEY = (WM_USER + 233);
|
||
|
PRIVATE_DATA CUINT WMTRAY_SCUNREGISTERHOTKEY = (WM_USER + 234);
|
||
|
|
||
|
// show commands - N.b., the order of these constants must match the order of
|
||
|
// the corresponding IDS_ string table constants.
|
||
|
|
||
|
PRIVATE_DATA const UINT s_ucMaxShowCmdLen = MAX_PATH_LEN;
|
||
|
|
||
|
PRIVATE_DATA const int s_rgnShowCmds[] =
|
||
|
{
|
||
|
SW_SHOWNORMAL,
|
||
|
SW_SHOWMINNOACTIVE,
|
||
|
SW_SHOWMAXIMIZED
|
||
|
};
|
||
|
|
||
|
// help files
|
||
|
|
||
|
PRIVATE_DATA const char s_cszPlusHelpFile[] = "Plus!.hlp";
|
||
|
|
||
|
// help topics
|
||
|
|
||
|
PRIVATE_DATA const DWORD s_rgdwHelpIDs[] =
|
||
|
{
|
||
|
IDD_LINE_1, NO_HELP,
|
||
|
IDD_LINE_2, NO_HELP,
|
||
|
IDD_ICON, IDH_FCAB_LINK_ICON,
|
||
|
IDD_NAME, IDH_FCAB_LINK_NAME,
|
||
|
IDD_URL_TEXT, IDH_INTERNET_SHORTCUT_TARGET,
|
||
|
IDD_URL, IDH_INTERNET_SHORTCUT_TARGET,
|
||
|
IDD_HOTKEY_TEXT, IDH_FCAB_LINK_HOTKEY,
|
||
|
IDD_HOTKEY, IDH_FCAB_LINK_HOTKEY,
|
||
|
IDD_START_IN_TEXT, IDH_FCAB_LINK_WORKING,
|
||
|
IDD_START_IN, IDH_FCAB_LINK_WORKING,
|
||
|
IDD_SHOW_CMD, IDH_FCAB_LINK_RUN,
|
||
|
IDD_CHANGE_ICON, IDH_FCAB_LINK_CHANGEICON,
|
||
|
0, 0
|
||
|
};
|
||
|
|
||
|
#pragma data_seg()
|
||
|
|
||
|
|
||
|
/***************************** Private Functions *****************************/
|
||
|
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
|
||
|
PRIVATE_CODE BOOL IsValidPCISPS(PCISPS pcisps)
|
||
|
{
|
||
|
return(IS_VALID_READ_PTR(pcisps, CISPS) &&
|
||
|
IS_VALID_STRUCT_PTR(&(pcisps->psp), CPROPSHEETPAGE) &&
|
||
|
IS_VALID_STRUCT_PTR(pcisps->pintshcut, CInternetShortcut) &&
|
||
|
EVAL(IsValidIconIndex(*(pcisps->rgchIconFile) ? S_OK : S_FALSE, pcisps->rgchIconFile, sizeof(pcisps->rgchIconFile), pcisps->niIcon)));
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
PRIVATE_CODE UINT CALLBACK ISPSCallback(HWND hwnd, UINT uMsg,
|
||
|
LPPROPSHEETPAGE ppsp)
|
||
|
{
|
||
|
UINT uResult = TRUE;
|
||
|
PISPS pisps = (PISPS)ppsp;
|
||
|
|
||
|
// uMsg may be any value.
|
||
|
|
||
|
ASSERT(! hwnd ||
|
||
|
IS_VALID_HANDLE(hwnd, WND));
|
||
|
ASSERT(IS_VALID_STRUCT_PTR((PCISPS)ppsp, CISPS));
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case PSPCB_CREATE:
|
||
|
TRACE_OUT(("ISPSCallback(): Received PSPCB_CREATE."));
|
||
|
break;
|
||
|
|
||
|
case PSPCB_RELEASE:
|
||
|
TRACE_OUT(("ISPSCallback(): Received PSPCB_RELEASE."));
|
||
|
pisps->pintshcut->Release();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
TRACE_OUT(("ISPSCallback(): Unhandled message %u.",
|
||
|
uMsg));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return(uResult);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void SetISPSIcon(HWND hdlg, HICON hicon)
|
||
|
{
|
||
|
HICON hiconOld;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
ASSERT(IS_VALID_HANDLE(hicon, ICON));
|
||
|
|
||
|
hiconOld = (HICON)SendDlgItemMessage(hdlg, IDD_ICON, STM_SETICON,
|
||
|
(WPARAM)hicon, 0);
|
||
|
|
||
|
if (hiconOld)
|
||
|
DestroyIcon(hiconOld);
|
||
|
|
||
|
TRACE_OUT(("SetISPSIcon(): Set property sheet icon to %#lx.",
|
||
|
hicon));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void SetISPSFileNameAndIcon(HWND hdlg)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
PInternetShortcut pintshcut;
|
||
|
char rgchFile[MAX_PATH_LEN];
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
hr = pintshcut->GetCurFile(rgchFile, sizeof(rgchFile));
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
SHFILEINFO shfi;
|
||
|
DWORD_PTR dwResult;
|
||
|
|
||
|
dwResult = SHGetFileInfo(rgchFile, 0, &shfi, sizeof(shfi),
|
||
|
(SHGFI_DISPLAYNAME | SHGFI_ICON));
|
||
|
|
||
|
if (dwResult)
|
||
|
{
|
||
|
PSTR pszFileName;
|
||
|
|
||
|
pszFileName = (PSTR)ExtractFileName(shfi.szDisplayName);
|
||
|
|
||
|
EVAL(SetDlgItemText(hdlg, IDD_NAME, pszFileName));
|
||
|
|
||
|
TRACE_OUT(("SetISPSFileNameAndIcon(): Set property sheet file name to \"%s\".",
|
||
|
pszFileName));
|
||
|
|
||
|
SetISPSIcon(hdlg, shfi.hIcon);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
TRACE_OUT(("SetISPSFileNameAndIcon(): SHGetFileInfo() failed, returning %lu.",
|
||
|
dwResult));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
TRACE_OUT(("SetISPSFileNameAndIcon(): GetCurFile() failed, returning %s.",
|
||
|
GetHRESULTString(hr)));
|
||
|
|
||
|
if (hr != S_OK)
|
||
|
EVAL(SetDlgItemText(hdlg, IDD_NAME, EMPTY_STRING));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void SetISPSURL(HWND hdlg)
|
||
|
{
|
||
|
PInternetShortcut pintshcut;
|
||
|
HRESULT hr;
|
||
|
PSTR pszURL;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
hr = pintshcut->GetURL(&pszURL);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
EVAL(SetDlgItemText(hdlg, IDD_URL, pszURL));
|
||
|
|
||
|
TRACE_OUT(("SetISPSURL(): Set property sheet URL to \"%s\".",
|
||
|
pszURL));
|
||
|
|
||
|
SHFree(pszURL);
|
||
|
pszURL = NULL;
|
||
|
}
|
||
|
else
|
||
|
EVAL(SetDlgItemText(hdlg, IDD_URL, EMPTY_STRING));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void SetISPSWorkingDirectory(HWND hdlg)
|
||
|
{
|
||
|
PInternetShortcut pintshcut;
|
||
|
HRESULT hr;
|
||
|
char rgchWorkingDirectory[MAX_PATH_LEN];
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
hr = pintshcut->GetWorkingDirectory(rgchWorkingDirectory,
|
||
|
sizeof(rgchWorkingDirectory));
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
EVAL(SetDlgItemText(hdlg, IDD_START_IN, rgchWorkingDirectory));
|
||
|
|
||
|
TRACE_OUT(("SetISPSWorkingDirectory(): Set property sheet working directory to \"%s\".",
|
||
|
rgchWorkingDirectory));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRACE_OUT(("SetISPSWorkingDirectory(): GetWorkingDirectory() failed, returning %s.",
|
||
|
GetHRESULTString(hr)));
|
||
|
|
||
|
EVAL(SetDlgItemText(hdlg, IDD_START_IN, EMPTY_STRING));
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void InitISPSHotkey(HWND hdlg)
|
||
|
{
|
||
|
PInternetShortcut pintshcut;
|
||
|
WORD wHotkey;
|
||
|
HRESULT hr;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
// Set hotkey combinations.
|
||
|
|
||
|
SendDlgItemMessage(hdlg, IDD_HOTKEY, HKM_SETRULES,
|
||
|
(HKCOMB_NONE | HKCOMB_A | HKCOMB_C | HKCOMB_S),
|
||
|
(HOTKEYF_CONTROL | HOTKEYF_ALT));
|
||
|
|
||
|
// Set current hotkey.
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
hr = pintshcut->GetHotkey(&wHotkey);
|
||
|
SendDlgItemMessage(hdlg, IDD_HOTKEY, HKM_SETHOTKEY, wHotkey, 0);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void InitISPSShowCmds(HWND hdlg)
|
||
|
{
|
||
|
int niShowCmd;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
for (niShowCmd = IDS_SHOW_NORMAL;
|
||
|
niShowCmd <= IDS_SHOW_MAXIMIZED;
|
||
|
niShowCmd++)
|
||
|
{
|
||
|
char rgchShowCmd[s_ucMaxShowCmdLen];
|
||
|
|
||
|
if (MLLoadStringA(niShowCmd, rgchShowCmd,
|
||
|
sizeof(rgchShowCmd)))
|
||
|
{
|
||
|
SendDlgItemMessage(hdlg, IDD_SHOW_CMD, CB_ADDSTRING, 0,
|
||
|
(LPARAM)rgchShowCmd);
|
||
|
|
||
|
TRACE_OUT(("InitISPSShowCmds(): Added show command \"%s\".",
|
||
|
rgchShowCmd));
|
||
|
}
|
||
|
else
|
||
|
ERROR_OUT(("InitISPSShowCmds(): Unable to load string %d.",
|
||
|
niShowCmd));
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void SetISPSShowCmd(HWND hdlg)
|
||
|
{
|
||
|
PInternetShortcut pintshcut;
|
||
|
int nShowCmd;
|
||
|
int i;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
pintshcut->GetShowCmd(&nShowCmd);
|
||
|
|
||
|
for (i = 0; i < ARRAY_ELEMENTS(s_rgnShowCmds); i++)
|
||
|
{
|
||
|
if (s_rgnShowCmds[i] == nShowCmd)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (i >= ARRAY_ELEMENTS(s_rgnShowCmds))
|
||
|
{
|
||
|
ASSERT(i == ARRAY_ELEMENTS(s_rgnShowCmds));
|
||
|
|
||
|
WARNING_OUT(("SetISPSShowCmd(): Unrecognized show command %d. Defaulting to normal.",
|
||
|
nShowCmd));
|
||
|
|
||
|
i = 0;
|
||
|
}
|
||
|
|
||
|
SendDlgItemMessage(hdlg, IDD_SHOW_CMD, CB_SETCURSEL, i, 0);
|
||
|
|
||
|
TRACE_OUT(("SetISPSShowCmd(): Set property sheet show command to index %d.",
|
||
|
i));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
PRIVATE_CODE BOOL ISPS_InitDialog(HWND hdlg, WPARAM wparam, LPARAM lparam)
|
||
|
{
|
||
|
PInternetShortcut pintshcut;
|
||
|
|
||
|
// wparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
ASSERT(IS_VALID_STRUCT_PTR((PCISPS)lparam, CISPS));
|
||
|
|
||
|
SetWindowLongPtr(hdlg, DWLP_USER, lparam);
|
||
|
|
||
|
pintshcut = ((PISPS)lparam)->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
// Initialize control contents.
|
||
|
|
||
|
SetISPSFileNameAndIcon(hdlg);
|
||
|
|
||
|
SendDlgItemMessage(hdlg, IDD_URL, EM_LIMITTEXT, g_ucMaxURLLen - 1, 0);
|
||
|
SetISPSURL(hdlg);
|
||
|
|
||
|
SendDlgItemMessage(hdlg, IDD_START_IN, EM_LIMITTEXT, MAX_PATH_LEN - 1, 0);
|
||
|
SetISPSWorkingDirectory(hdlg);
|
||
|
|
||
|
InitISPSHotkey(hdlg);
|
||
|
|
||
|
InitISPSShowCmds(hdlg);
|
||
|
SetISPSShowCmd(hdlg);
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE BOOL ISPS_Destroy(HWND hdlg, WPARAM wparam, LPARAM lparam)
|
||
|
{
|
||
|
PInternetShortcut pintshcut;
|
||
|
|
||
|
// wparam may be any value.
|
||
|
// lparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
SetWindowLongPtr(hdlg, DWLP_USER, NULL);
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void ISPSChanged(HWND hdlg)
|
||
|
{
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
PropSheet_Changed(GetParent(hdlg), hdlg);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE HRESULT ChooseIcon(HWND hdlg)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
PISPS pisps;
|
||
|
PInternetShortcut pintshcut;
|
||
|
char rgchTempIconFile[MAX_PATH_LEN];
|
||
|
int niIcon;
|
||
|
UINT uFlags;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pisps = (PISPS)GetWindowLongPtr(hdlg, DWLP_USER);
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pisps, CISPS));
|
||
|
pintshcut = pisps->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
if (pintshcut->GetIconLocation(0, rgchTempIconFile,
|
||
|
sizeof(rgchTempIconFile), &niIcon, &uFlags)
|
||
|
!= S_OK)
|
||
|
{
|
||
|
rgchTempIconFile[0] = '\0';
|
||
|
niIcon = 0;
|
||
|
}
|
||
|
|
||
|
ASSERT(lstrlen(rgchTempIconFile) < sizeof(rgchTempIconFile));
|
||
|
if (RUNNING_NT)
|
||
|
{
|
||
|
WCHAR uTempIconFile[MAX_PATH_LEN];
|
||
|
|
||
|
MultiByteToWideChar(CP_ACP, 0, rgchTempIconFile, -1,
|
||
|
uTempIconFile, MAX_PATH_LEN);
|
||
|
|
||
|
if (PickIconDlg(hdlg, uTempIconFile, MAX_PATH_LEN, &niIcon))
|
||
|
{
|
||
|
WideCharToMultiByte(CP_ACP, 0, uTempIconFile, -1, pisps->rgchIconFile,
|
||
|
MAX_PATH_LEN, NULL, NULL);
|
||
|
|
||
|
pisps->niIcon = niIcon;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
TRACE_OUT(("ChooseIcon(NT): PickIconDlg() failed."));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (PickIconDlg(hdlg, (LPWSTR)rgchTempIconFile, sizeof(rgchTempIconFile), &niIcon)) // (LPWSTR) so it builds, but works downlevel
|
||
|
{
|
||
|
ASSERT(lstrlen(rgchTempIconFile) < sizeof(pisps->rgchIconFile));
|
||
|
lstrcpy(pisps->rgchIconFile, rgchTempIconFile);
|
||
|
pisps->niIcon = niIcon;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
TRACE_OUT(("ChooseIcon(): PickIconDlg() failed."));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE void UpdateISPSIcon(HWND hdlg)
|
||
|
{
|
||
|
PISPS pisps;
|
||
|
HICON hicon;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pisps = (PISPS)GetWindowLongPtr(hdlg, DWLP_USER);
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pisps, CISPS));
|
||
|
ASSERT(pisps->rgchIconFile[0]);
|
||
|
|
||
|
// This icon does not have the link arrow overlayed. shell32.dll's
|
||
|
// Shortcut property sheet has the same bug.
|
||
|
|
||
|
hicon = ExtractIcon(GetThisModulesHandle(), pisps->rgchIconFile,
|
||
|
pisps->niIcon);
|
||
|
|
||
|
if (hicon)
|
||
|
SetISPSIcon(hdlg, hicon);
|
||
|
else
|
||
|
WARNING_OUT(("UpdateISPSIcon(): ExtractIcon() failed for icon %d in file %s.",
|
||
|
pisps->niIcon,
|
||
|
pisps->rgchIconFile));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
PRIVATE_CODE BOOL ISPS_Command(HWND hdlg, WPARAM wparam, LPARAM lparam)
|
||
|
{
|
||
|
BOOL bMsgHandled = FALSE;
|
||
|
WORD wCmd;
|
||
|
|
||
|
// wparam may be any value.
|
||
|
// lparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
wCmd = HIWORD(wparam);
|
||
|
|
||
|
switch (LOWORD(wparam))
|
||
|
{
|
||
|
case IDD_URL:
|
||
|
case IDD_HOTKEY:
|
||
|
case IDD_START_IN:
|
||
|
if (wCmd == EN_CHANGE)
|
||
|
{
|
||
|
ISPSChanged(hdlg);
|
||
|
|
||
|
bMsgHandled = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDD_SHOW_CMD:
|
||
|
if (wCmd == LBN_SELCHANGE)
|
||
|
{
|
||
|
ISPSChanged(hdlg);
|
||
|
|
||
|
bMsgHandled = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDD_CHANGE_ICON:
|
||
|
// Ignore return value.
|
||
|
if (ChooseIcon(hdlg) == S_OK)
|
||
|
{
|
||
|
UpdateISPSIcon(hdlg);
|
||
|
ISPSChanged(hdlg);
|
||
|
}
|
||
|
bMsgHandled = TRUE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return(bMsgHandled);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
|
||
|
PRIVATE_CODE HRESULT ComplainAboutURL(HWND hwndParent, PCSTR pcszURL,
|
||
|
HRESULT hrError)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
int nResult;
|
||
|
|
||
|
// Validate hrError below.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hwndParent, WND));
|
||
|
ASSERT(IS_VALID_STRING_PTR(pcszURL, CSTR));
|
||
|
|
||
|
switch (hrError)
|
||
|
{
|
||
|
case URL_E_UNREGISTERED_PROTOCOL:
|
||
|
{
|
||
|
PSTR pszProtocol;
|
||
|
|
||
|
hr = CopyURLProtocol(pcszURL, &pszProtocol);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
|
||
|
MAKEINTRESOURCE(IDS_UNREGISTERED_PROTOCOL),
|
||
|
(MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION),
|
||
|
&nResult, pszProtocol))
|
||
|
{
|
||
|
switch (nResult)
|
||
|
{
|
||
|
case IDYES:
|
||
|
hr = S_OK;
|
||
|
TRACE_OUT(("ComplainAboutURL(): Allowing URL %s despite unregistered protocol %s, by request.",
|
||
|
pcszURL,
|
||
|
pszProtocol));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
ASSERT(nResult == IDNO);
|
||
|
hr = E_FAIL;
|
||
|
TRACE_OUT(("ComplainAboutURL(): Not allowing URL %s because of unregistered protocol %s, as directed.",
|
||
|
pcszURL,
|
||
|
pszProtocol));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete pszProtocol;
|
||
|
pszProtocol = NULL;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
ASSERT(hrError == URL_E_INVALID_SYNTAX);
|
||
|
|
||
|
if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
|
||
|
MAKEINTRESOURCE(IDS_INVALID_URL_SYNTAX),
|
||
|
(MB_OK | MB_ICONEXCLAMATION), &nResult, pcszURL)) {
|
||
|
ASSERT(nResult == IDOK);
|
||
|
}
|
||
|
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
TRACE_OUT(("ComplainAboutURL(): Not allowing URL %s because of invalid syntax.",
|
||
|
pcszURL));
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
PRIVATE_CODE HRESULT ComplainAboutWorkingDirectory(HWND hwndParent,
|
||
|
PCSTR pcszWorkingDirectory,
|
||
|
HRESULT hrError)
|
||
|
{
|
||
|
int nResult;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hwndParent, WND));
|
||
|
ASSERT(IS_VALID_STRING_PTR(pcszWorkingDirectory, CSTR));
|
||
|
ASSERT(hrError == E_PATH_NOT_FOUND);
|
||
|
|
||
|
if (MyMsgBox(hwndParent, MAKEINTRESOURCE(IDS_SHORTCUT_ERROR_TITLE),
|
||
|
MAKEINTRESOURCE(IDS_WORKING_DIR_NOT_FOUND),
|
||
|
(MB_OK | MB_ICONEXCLAMATION), &nResult, pcszWorkingDirectory)) {
|
||
|
ASSERT(nResult == IDOK);
|
||
|
}
|
||
|
|
||
|
TRACE_OUT(("ComplainAboutWorkingDirectory(): Not allowing non-existent working directory %s.",
|
||
|
pcszWorkingDirectory));
|
||
|
|
||
|
return(E_FAIL);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
|
||
|
PRIVATE_CODE HRESULT InjectISPSData(HWND hdlg)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
PISPS pisps;
|
||
|
PInternetShortcut pintshcut;
|
||
|
PSTR pszURL;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pisps = (PISPS)GetWindowLongPtr(hdlg, DWLP_USER);
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pisps, CISPS));
|
||
|
pintshcut = pisps->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
hr = CopyDlgItemText(hdlg, IDD_URL, &pszURL);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
PCSTR pcszURLToUse;
|
||
|
PSTR pszTranslatedURL;
|
||
|
|
||
|
pcszURLToUse = pszURL;
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
hr = TranslateURL(pszURL, (TRANSLATEURL_FL_GUESS_PROTOCOL |
|
||
|
TRANSLATEURL_FL_USE_DEFAULT_PROTOCOL),
|
||
|
&pszTranslatedURL);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (hr == S_OK)
|
||
|
pcszURLToUse = pszTranslatedURL;
|
||
|
else
|
||
|
ASSERT(hr == S_FALSE);
|
||
|
|
||
|
hr = ValidateURL(pcszURLToUse);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
hr = ComplainAboutURL(hdlg, pcszURLToUse, hr);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
SetEditFocus(GetDlgItem(hdlg, IDD_URL));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// A blank URL is OK.
|
||
|
|
||
|
ASSERT(hr == S_FALSE);
|
||
|
|
||
|
pszTranslatedURL = NULL;
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = pintshcut->SetURL(pcszURLToUse, 0);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
WORD wHotkey;
|
||
|
WORD wOldHotkey;
|
||
|
|
||
|
// Refresh URL in case it was changed by TranslateURL().
|
||
|
|
||
|
SetISPSURL(hdlg);
|
||
|
|
||
|
wHotkey = (WORD)SendDlgItemMessage(hdlg, IDD_HOTKEY, HKM_GETHOTKEY,
|
||
|
0, 0);
|
||
|
|
||
|
hr = pintshcut->GetHotkey(&wOldHotkey);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
hr = pintshcut->SetHotkey(wHotkey);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
char szFile[MAX_PATH_LEN];
|
||
|
|
||
|
hr = pintshcut->GetCurFile(szFile, sizeof(szFile));
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
if (RegisterGlobalHotkey(wOldHotkey, wHotkey, szFile))
|
||
|
{
|
||
|
PSTR pszWorkingDirectory;
|
||
|
|
||
|
hr = CopyDlgItemText(hdlg, IDD_START_IN,
|
||
|
&pszWorkingDirectory);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
hr = ValidateWorkingDirectory(pszWorkingDirectory);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
hr = ComplainAboutWorkingDirectory(hdlg,
|
||
|
pszWorkingDirectory,
|
||
|
hr);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
SetEditFocus(GetDlgItem(hdlg, IDD_START_IN));
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = pintshcut->SetWorkingDirectory(pszWorkingDirectory);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
// Refresh working directory in case it was changed by
|
||
|
// SetWorkingDirectory().
|
||
|
|
||
|
SetISPSWorkingDirectory(hdlg);
|
||
|
|
||
|
if (pisps->rgchIconFile[0])
|
||
|
hr = pintshcut->SetIconLocation(pisps->rgchIconFile,
|
||
|
pisps->niIcon);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
INT_PTR iShowCmd;
|
||
|
|
||
|
iShowCmd = SendDlgItemMessage(hdlg,
|
||
|
IDD_SHOW_CMD,
|
||
|
CB_GETCURSEL,
|
||
|
0, 0);
|
||
|
|
||
|
if (iShowCmd >= 0 &&
|
||
|
iShowCmd < ARRAY_ELEMENTS(s_rgnShowCmds))
|
||
|
pintshcut->SetShowCmd(s_rgnShowCmds[iShowCmd]);
|
||
|
else
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pszWorkingDirectory)
|
||
|
{
|
||
|
delete pszWorkingDirectory;
|
||
|
pszWorkingDirectory = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pszURL)
|
||
|
{
|
||
|
delete pszURL;
|
||
|
pszURL = NULL;
|
||
|
}
|
||
|
|
||
|
if (pszTranslatedURL)
|
||
|
{
|
||
|
LocalFree(pszTranslatedURL);
|
||
|
pszTranslatedURL = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
TRACE_OUT(("InjectISPSData(): Injected property sheet data into Internet Shortcut successfully."));
|
||
|
else
|
||
|
WARNING_OUT(("InjectISPSData(): Failed to inject property sheet data into Internet Shortcut, returning %s.",
|
||
|
GetHRESULTString(hr)));
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE HRESULT ISPSSave(HWND hdlg)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
PInternetShortcut pintshcut;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
pintshcut = ((PISPS)GetWindowLongPtr(hdlg, DWLP_USER))->pintshcut;
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
|
||
|
if (pintshcut->IsDirty() == S_OK)
|
||
|
{
|
||
|
hr = pintshcut->Save((LPCOLESTR)NULL, FALSE);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
TRACE_OUT(("ISPSSave(): Saved Internet Shortcut successfully."));
|
||
|
else
|
||
|
WARNING_OUT(("ISPSSave(): Save() failed, returning %s.",
|
||
|
GetHRESULTString(hr)));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRACE_OUT(("ISPSSave(): Internet Shortcut unchanged. No save required."));
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
PRIVATE_CODE BOOL ISPS_Notify(HWND hdlg, WPARAM wparam, LPARAM lparam)
|
||
|
{
|
||
|
BOOL bMsgHandled = FALSE;
|
||
|
|
||
|
// wparam may be any value.
|
||
|
// lparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
switch (((PNMHDR)lparam)->code)
|
||
|
{
|
||
|
case PSN_APPLY:
|
||
|
SetWindowLongPtr(hdlg, DWLP_MSGRESULT, ISPSSave(hdlg) == S_OK ?
|
||
|
PSNRET_NOERROR :
|
||
|
PSNRET_INVALID_NOCHANGEPAGE);
|
||
|
bMsgHandled = TRUE;
|
||
|
break;
|
||
|
|
||
|
case PSN_KILLACTIVE:
|
||
|
SetWindowLongPtr(hdlg, DWLP_MSGRESULT, FAILED(InjectISPSData(hdlg)));
|
||
|
bMsgHandled = TRUE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return(bMsgHandled);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
|
||
|
PRIVATE_CODE PCSTR ISPS_GetHelpFileFromControl(HWND hwndControl)
|
||
|
{
|
||
|
PCSTR pcszHelpFile = NULL;
|
||
|
int nControlID = 0;
|
||
|
|
||
|
ASSERT(! hwndControl ||
|
||
|
IS_VALID_HANDLE(hwndControl, WND));
|
||
|
|
||
|
if (hwndControl)
|
||
|
{
|
||
|
nControlID = GetDlgCtrlID(hwndControl);
|
||
|
|
||
|
switch (nControlID)
|
||
|
{
|
||
|
case IDD_URL_TEXT:
|
||
|
case IDD_URL:
|
||
|
// URL help comes from the Plus! Pack help file.
|
||
|
pcszHelpFile = s_cszPlusHelpFile;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
// Other help is borrowed from the default Win95 help file.
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TRACE_OUT(("ISPS_GetHelpFileFromControl(): Using %s for control %d (HWND %#lx).",
|
||
|
pcszHelpFile ? pcszHelpFile : "default Win95 help file",
|
||
|
nControlID,
|
||
|
hwndControl));
|
||
|
|
||
|
ASSERT(! pcszHelpFile ||
|
||
|
IS_VALID_STRING_PTR(pcszHelpFile, CSTR));
|
||
|
|
||
|
return(pcszHelpFile);
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE INT_PTR CALLBACK ISPS_DlgProc(HWND hdlg, UINT uMsg, WPARAM wparam,
|
||
|
LPARAM lparam)
|
||
|
{
|
||
|
INT_PTR bMsgHandled = FALSE;
|
||
|
|
||
|
// uMsg may be any value.
|
||
|
// wparam may be any value.
|
||
|
// lparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
bMsgHandled = ISPS_InitDialog(hdlg, wparam, lparam);
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
bMsgHandled = ISPS_Destroy(hdlg, wparam, lparam);
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
bMsgHandled = ISPS_Command(hdlg, wparam, lparam);
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
bMsgHandled = ISPS_Notify(hdlg, wparam, lparam);
|
||
|
break;
|
||
|
|
||
|
case WM_HELP:
|
||
|
SHWinHelpOnDemandWrap((HWND)(((LPHELPINFO)lparam)->hItemHandle),
|
||
|
ISPS_GetHelpFileFromControl((HWND)(((LPHELPINFO)lparam)->hItemHandle)),
|
||
|
HELP_WM_HELP, (DWORD_PTR)(PVOID)s_rgdwHelpIDs);
|
||
|
bMsgHandled = TRUE;
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU:
|
||
|
{
|
||
|
POINT pt;
|
||
|
|
||
|
LPARAM_TO_POINT(lparam, pt);
|
||
|
EVAL(ScreenToClient(hdlg, &pt));
|
||
|
|
||
|
SHWinHelpOnDemandWrap((HWND)wparam,
|
||
|
ISPS_GetHelpFileFromControl(ChildWindowFromPoint(hdlg, pt)),
|
||
|
HELP_CONTEXTMENU, (DWORD_PTR)(PVOID)s_rgdwHelpIDs);
|
||
|
bMsgHandled = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return(bMsgHandled);
|
||
|
}
|
||
|
|
||
|
|
||
|
PRIVATE_CODE HRESULT AddISPS(PInternetShortcut pintshcut,
|
||
|
LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lparam)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
ISPS isps;
|
||
|
HPROPSHEETPAGE hpsp;
|
||
|
|
||
|
// lparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(pintshcut, CInternetShortcut));
|
||
|
ASSERT(IS_VALID_CODE_PTR(pfnAddPage, LPFNADDPROPSHEETPAGE));
|
||
|
|
||
|
ZeroMemory(&isps, sizeof(isps));
|
||
|
|
||
|
isps.psp.dwSize = sizeof(isps);
|
||
|
isps.psp.dwFlags = (PSP_DEFAULT | PSP_USECALLBACK);
|
||
|
isps.psp.hInstance = MLGetHinst();
|
||
|
isps.psp.pszTemplate = MAKEINTRESOURCE(DLG_INTERNET_SHORTCUT_PROP_SHEET);
|
||
|
isps.psp.pfnDlgProc = &ISPS_DlgProc;
|
||
|
isps.psp.pfnCallback = &ISPSCallback;
|
||
|
|
||
|
isps.pintshcut = pintshcut;
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(&isps, CISPS));
|
||
|
|
||
|
hpsp = CreatePropertySheetPage(&(isps.psp));
|
||
|
|
||
|
if (hpsp)
|
||
|
{
|
||
|
if ((*pfnAddPage)(hpsp, lparam))
|
||
|
{
|
||
|
pintshcut->AddRef();
|
||
|
hr = S_OK;
|
||
|
TRACE_OUT(("AddISPS(): Added Internet Shortcut property sheet."));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DestroyPropertySheetPage(hpsp);
|
||
|
|
||
|
hr = E_FAIL;
|
||
|
WARNING_OUT(("AddISPS(): Callback to add property sheet failed."));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************** Public Functions *****************************/
|
||
|
|
||
|
|
||
|
PUBLIC_CODE void SetEditFocus(HWND hwnd)
|
||
|
{
|
||
|
ASSERT(IS_VALID_HANDLE(hwnd, WND));
|
||
|
|
||
|
SetFocus(hwnd);
|
||
|
SendMessage(hwnd, EM_SETSEL, 0, -1);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PUBLIC_CODE BOOL ConstructMessageString(PCSTR pcszFormat, PSTR *ppszMsg,
|
||
|
va_list *ArgList)
|
||
|
{
|
||
|
BOOL bResult;
|
||
|
char rgchFormat[MAX_MSG_LEN];
|
||
|
|
||
|
// ArgList may be any value.
|
||
|
|
||
|
ASSERT(! HIWORD(pcszFormat) ||
|
||
|
IS_VALID_STRING_PTR(pcszFormat, CSTR));
|
||
|
ASSERT(IS_VALID_WRITE_PTR(ppszMsg, PSTR));
|
||
|
|
||
|
if (IS_INTRESOURCE(pcszFormat))
|
||
|
{
|
||
|
MLLoadStringA(LOWORD(PtrToUlong(pcszFormat)), rgchFormat,
|
||
|
sizeof(rgchFormat));
|
||
|
|
||
|
pcszFormat = rgchFormat;
|
||
|
}
|
||
|
|
||
|
bResult = FormatMessage((FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
|
FORMAT_MESSAGE_FROM_STRING), pcszFormat, 0, 0,
|
||
|
(PSTR)ppszMsg, 0, ArgList);
|
||
|
|
||
|
ASSERT(! bResult ||
|
||
|
IS_VALID_STRING_PTR(*ppszMsg, STR));
|
||
|
|
||
|
return(bResult);
|
||
|
}
|
||
|
|
||
|
|
||
|
PUBLIC_CODE BOOL __cdecl MyMsgBox(HWND hwndParent, PCSTR pcszTitle,
|
||
|
PCSTR pcszMsgFormat, DWORD dwMsgBoxFlags,
|
||
|
PINT pnResult, ...)
|
||
|
{
|
||
|
BOOL bResult;
|
||
|
va_list ArgList;
|
||
|
PSTR pszMsg;
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hwndParent, WND));
|
||
|
ASSERT(IS_INTRESOURCE(pcszTitle) ||
|
||
|
IS_VALID_STRING_PTR(pcszTitle, CSTR));
|
||
|
ASSERT(IS_INTRESOURCE(pcszMsgFormat) ||
|
||
|
IS_VALID_STRING_PTR(pcszMsgFormat, CSTR));
|
||
|
ASSERT(FLAGS_ARE_VALID(dwMsgBoxFlags, ALL_MSG_BOX_FLAGS));
|
||
|
ASSERT(IS_VALID_WRITE_PTR(pnResult, INT));
|
||
|
|
||
|
*pnResult = 0;
|
||
|
|
||
|
va_start(ArgList, pnResult);
|
||
|
|
||
|
bResult = ConstructMessageString(pcszMsgFormat, &pszMsg, &ArgList);
|
||
|
|
||
|
va_end(ArgList);
|
||
|
|
||
|
if (bResult)
|
||
|
{
|
||
|
char rgchTitle[MAX_MSG_LEN];
|
||
|
|
||
|
if (! HIWORD(pcszTitle))
|
||
|
{
|
||
|
MLLoadStringA(LOWORD(PtrToUlong(pcszTitle)), rgchTitle,
|
||
|
sizeof(rgchTitle));
|
||
|
|
||
|
pcszTitle = rgchTitle;
|
||
|
}
|
||
|
|
||
|
*pnResult = MessageBox(hwndParent, pszMsg, pcszTitle, dwMsgBoxFlags);
|
||
|
|
||
|
bResult = (*pnResult != 0);
|
||
|
|
||
|
LocalFree(pszMsg);
|
||
|
pszMsg = NULL;
|
||
|
}
|
||
|
|
||
|
return(bResult);
|
||
|
}
|
||
|
|
||
|
|
||
|
PUBLIC_CODE HRESULT CopyDlgItemText(HWND hdlg, int nControlID, PSTR *ppszText)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
HWND hwndControl;
|
||
|
|
||
|
// nContolID may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
||
|
ASSERT(IS_VALID_WRITE_PTR(ppszText, PSTR));
|
||
|
|
||
|
*ppszText = NULL;
|
||
|
|
||
|
hwndControl = GetDlgItem(hdlg, nControlID);
|
||
|
|
||
|
if (hwndControl)
|
||
|
{
|
||
|
int ncchTextLen;
|
||
|
|
||
|
ncchTextLen = GetWindowTextLength(hwndControl);
|
||
|
|
||
|
if (ncchTextLen > 0)
|
||
|
{
|
||
|
PSTR pszText;
|
||
|
|
||
|
ASSERT(ncchTextLen < INT_MAX);
|
||
|
ncchTextLen++;
|
||
|
ASSERT(ncchTextLen > 0);
|
||
|
|
||
|
pszText = new(char[ncchTextLen]);
|
||
|
|
||
|
if (pszText)
|
||
|
{
|
||
|
int ncchCopiedLen;
|
||
|
|
||
|
ncchCopiedLen = GetWindowText(hwndControl, pszText, ncchTextLen);
|
||
|
ASSERT(ncchCopiedLen == ncchTextLen - 1);
|
||
|
|
||
|
if (EVAL(ncchCopiedLen > 0))
|
||
|
{
|
||
|
if (AnyMeat(pszText))
|
||
|
{
|
||
|
*ppszText = pszText;
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
else
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
if (hr != S_OK)
|
||
|
{
|
||
|
delete pszText;
|
||
|
pszText = NULL;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
else
|
||
|
// No text.
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
else
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
PUBLIC_CODE BOOL RegisterGlobalHotkey(WORD wOldHotkey, WORD wNewHotkey,
|
||
|
PCSTR pcszPath)
|
||
|
{
|
||
|
BOOL bResult;
|
||
|
HWND hwndTray;
|
||
|
|
||
|
ASSERT(! wOldHotkey ||
|
||
|
IsValidHotkey(wOldHotkey));
|
||
|
ASSERT(! wNewHotkey ||
|
||
|
IsValidHotkey(wNewHotkey));
|
||
|
ASSERT(IsValidPath(pcszPath));
|
||
|
|
||
|
hwndTray = FindWindow(s_cszTrayNotificationClass, 0);
|
||
|
|
||
|
if (hwndTray)
|
||
|
{
|
||
|
if (wOldHotkey)
|
||
|
{
|
||
|
SendMessage(hwndTray, WMTRAY_SCUNREGISTERHOTKEY, wOldHotkey, 0);
|
||
|
|
||
|
TRACE_OUT(("RegisterGlobalHotkey(): Unregistered old hotkey %#04x for %s.",
|
||
|
wOldHotkey,
|
||
|
pcszPath));
|
||
|
}
|
||
|
|
||
|
if (wNewHotkey)
|
||
|
{
|
||
|
if (RUNNING_NT)
|
||
|
{
|
||
|
ATOM atom = GlobalAddAtom(pcszPath);
|
||
|
ASSERT(atom);
|
||
|
if (atom)
|
||
|
{
|
||
|
SendMessage(hwndTray, WMTRAY_SCREGISTERHOTKEY, wNewHotkey, (LPARAM)atom);
|
||
|
GlobalDeleteAtom(atom);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SendMessage(hwndTray, WMTRAY_SCREGISTERHOTKEY, wNewHotkey,
|
||
|
(LPARAM)pcszPath);
|
||
|
}
|
||
|
|
||
|
TRACE_OUT(("RegisterGlobalHotkey(): Registered new hotkey %#04x for %s.",
|
||
|
wNewHotkey,
|
||
|
pcszPath));
|
||
|
}
|
||
|
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bResult = FALSE;
|
||
|
|
||
|
WARNING_OUT(("RegisterGlobalHotkey(): Unable to find Tray window of class %s to notify.",
|
||
|
s_cszTrayNotificationClass));
|
||
|
}
|
||
|
|
||
|
return(bResult);
|
||
|
}
|
||
|
|
||
|
/********************************** Methods **********************************/
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
HRESULT STDMETHODCALLTYPE InternetShortcut::Initialize(
|
||
|
PCITEMIDLIST pcidlFolder,
|
||
|
PIDataObject pido,
|
||
|
HKEY hkeyProgID)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
FORMATETC fmtetc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||
|
STGMEDIUM stgmed;
|
||
|
|
||
|
DebugEntry(InternetShortcut::Initialize);
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
|
||
|
ASSERT(! pcidlFolder ||
|
||
|
IS_VALID_STRUCT_PTR(pcidlFolder, CITEMIDLIST));
|
||
|
ASSERT(IS_VALID_INTERFACE_PTR(pido, IDataObject));
|
||
|
ASSERT(IS_VALID_HANDLE(hkeyProgID, KEY));
|
||
|
|
||
|
hr = pido->GetData(&fmtetc, &stgmed);
|
||
|
|
||
|
if (hr == S_OK)
|
||
|
{
|
||
|
UINT ucbPathLen;
|
||
|
PSTR pszFile;
|
||
|
|
||
|
// (+ 1) for null terminator.
|
||
|
|
||
|
ucbPathLen = DragQueryFile((HDROP)(stgmed.hGlobal), 0, NULL, 0) + 1;
|
||
|
ASSERT(ucbPathLen > 0);
|
||
|
|
||
|
pszFile = new(char[ucbPathLen]);
|
||
|
|
||
|
if (pszFile)
|
||
|
{
|
||
|
EVAL(DragQueryFile((HDROP)(stgmed.hGlobal), 0, pszFile, ucbPathLen) == ucbPathLen - 1);
|
||
|
ASSERT(IS_VALID_STRING_PTR(pszFile, STR));
|
||
|
ASSERT((UINT)lstrlen(pszFile) == ucbPathLen - 1);
|
||
|
|
||
|
hr = LoadFromFile(pszFile, TRUE);
|
||
|
|
||
|
delete pszFile;
|
||
|
pszFile = NULL;
|
||
|
}
|
||
|
else
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
|
||
|
if (stgmed.tymed != TYMED_NULL)
|
||
|
MyReleaseStgMedium(&stgmed);
|
||
|
}
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
|
||
|
|
||
|
DebugExitHRESULT(InternetShortcut::Initialize, hr);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
|
||
|
HRESULT STDMETHODCALLTYPE InternetShortcut::AddPages(
|
||
|
LPFNADDPROPSHEETPAGE pfnAddPage,
|
||
|
LPARAM lparam)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
DebugEntry(InternetShortcut::AddPages);
|
||
|
|
||
|
// lparam may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
|
||
|
ASSERT(IS_VALID_CODE_PTR(pfnAddPage, LPFNADDPROPSHEETPAGE));
|
||
|
|
||
|
hr = AddISPS(this, pfnAddPage, lparam);
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
|
||
|
|
||
|
DebugExitHRESULT(InternetShortcut::AddPages, hr);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
|
||
|
|
||
|
HRESULT STDMETHODCALLTYPE InternetShortcut::ReplacePage(
|
||
|
UINT uPageID,
|
||
|
LPFNADDPROPSHEETPAGE pfnReplaceWith,
|
||
|
LPARAM lparam)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
DebugEntry(InternetShortcut::ReplacePage);
|
||
|
|
||
|
// lparam may be any value.
|
||
|
// uPageID may be any value.
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
|
||
|
ASSERT(IS_VALID_CODE_PTR(pfnReplaceWith, LPFNADDPROPSHEETPAGE));
|
||
|
|
||
|
hr = E_NOTIMPL;
|
||
|
|
||
|
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
|
||
|
|
||
|
DebugExitHRESULT(InternetShortcut::ReplacePage, hr);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|