1533 lines
30 KiB
C++
1533 lines
30 KiB
C++
/*
|
|
* propsht.cpp - IPropSheetExt implementation for App Shortcut class.
|
|
*/
|
|
|
|
|
|
|
|
// * NOTE!!: this code is incomplete. Also error checking (any leak?),
|
|
// * restructuring (for better coding/efficiency) to be done.
|
|
|
|
|
|
|
|
|
|
// * this file uses CharNext etc as it needs User32 anyway *
|
|
|
|
/* Headers
|
|
**********/
|
|
|
|
#include "project.hpp"
|
|
|
|
#include <prsht.h>
|
|
|
|
#include "resource.h"
|
|
|
|
extern "C" WINSHELLAPI int WINAPI PickIconDlg(HWND hwnd, LPWSTR pwzIconPath, UINT cbIconPath, int *piIconIndex);
|
|
|
|
extern HINSTANCE g_DllInstance;
|
|
|
|
/* Types
|
|
********/
|
|
|
|
// Application Shortcut property sheet data
|
|
|
|
typedef enum _appshcutpropsheetpgs
|
|
{
|
|
APPSHCUT_PS_APPSHCUT_PAGE = 0x0000,
|
|
APPSHCUT_PS_APPREF_PAGE = 0x0001,
|
|
|
|
ALL_APPSHCUT_PS_PAGES
|
|
}
|
|
APPSHCUTPSPAGES;
|
|
|
|
typedef struct _asps
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
|
|
WCHAR rgchIconFile[MAX_PATH];
|
|
|
|
int niIcon;
|
|
|
|
APPSHCUTPSPAGES eCurPage;
|
|
}
|
|
ASPS;
|
|
DECLARE_STANDARD_TYPES(ASPS);
|
|
|
|
typedef ASPS* PASPS;
|
|
|
|
/* Module Constants
|
|
*******************/
|
|
|
|
// Tray notification window class
|
|
|
|
//copied from shell32!
|
|
#define WNDCLASS_TRAYNOTIFY L"Shell_TrayWnd" //internal_win40
|
|
const WCHAR s_cwzTrayNotificationClass[] = WNDCLASS_TRAYNOTIFY;
|
|
|
|
// HACKHACK: WMTRAY_SCREGISTERHOTKEY and WMTRAY_SCUNREGISTERHOTKEY are stolen
|
|
// from shelldll\link.c.
|
|
typedef const UINT CUINT;
|
|
CUINT WMTRAY_SCREGISTERHOTKEY = (WM_USER + 233);
|
|
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.
|
|
|
|
const UINT s_ucMaxShowCmdLen = MAX_PATH;
|
|
const UINT s_ucMaxTypeLen = TYPESTRINGLENGTH;
|
|
|
|
const int s_rgnShowCmds[] =
|
|
{
|
|
SW_SHOWNORMAL,
|
|
SW_SHOWMINNOACTIVE,
|
|
SW_SHOWMAXIMIZED
|
|
};
|
|
|
|
// this ordering has to match the strings in the resource file,
|
|
// the strings has to be in sync with the parsing code in persist.cpp
|
|
const int s_rgnType[] =
|
|
{
|
|
APPTYPE_NETASSEMBLY,
|
|
APPTYPE_WIN32EXE
|
|
};
|
|
|
|
/*
|
|
** ExtractFileName()
|
|
**
|
|
** Extracts the file name from a path name.
|
|
**
|
|
** Arguments: pcwzPathName - path string from which to extract file name
|
|
**
|
|
** Returns: Pointer to file name in path string.
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
#define BACKSLASH L'/'
|
|
#define SLASH L'\\'
|
|
#define COLON L':'
|
|
#define IS_SLASH(ch) ((ch) == SLASH || (ch) == BACKSLASH)
|
|
PCWSTR ExtractFileName(PCWSTR pcwzPathName)
|
|
{
|
|
PCWSTR pcwzLastComponent;
|
|
PCWSTR pcwz;
|
|
|
|
for (pcwzLastComponent = pcwz = pcwzPathName; *pcwz; pcwz = CharNext(pcwz))
|
|
{
|
|
if (IS_SLASH(*pcwz) || *pcwz == COLON)
|
|
pcwzLastComponent = CharNext(pcwz);
|
|
}
|
|
|
|
ASSERT(IsValidPath(pcwzLastComponent));
|
|
|
|
return(pcwzLastComponent);
|
|
}
|
|
|
|
/***************************** Private Functions *****************************/
|
|
|
|
|
|
UINT CALLBACK ASPSCallback(HWND hwnd, UINT uMsg,
|
|
LPPROPSHEETPAGE ppsp)
|
|
{
|
|
// this is called after ASPS_DlgProc WM_DESTROY (ie. ASPS_Destroy)
|
|
// this func should do the frees/releases
|
|
|
|
UINT uResult = TRUE;
|
|
PASPS pasps = (PASPS)(ppsp->lParam);
|
|
|
|
// uMsg may be any value.
|
|
|
|
ASSERT(! hwnd ||
|
|
IS_VALID_HANDLE(hwnd, WND));
|
|
|
|
switch (uMsg)
|
|
{
|
|
case PSPCB_CREATE:
|
|
// from MSDN: A dialog box for a page is being created.
|
|
// Return nonzero to allow it to be created, or zero to prevent it.
|
|
break;
|
|
|
|
case PSPCB_RELEASE:
|
|
// ???? need checking if NULL
|
|
|
|
pasps->pappshcut->Release();
|
|
|
|
// free the ASPS structure, this is created in AddASPS
|
|
// delete only after the ref is removed
|
|
delete pasps;
|
|
ppsp->lParam = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
// ignore other msg - unhandled
|
|
break;
|
|
}
|
|
|
|
return(uResult);
|
|
}
|
|
|
|
|
|
void SetASPSIcon(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);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSFileNameAndIcon(HWND hdlg)
|
|
{
|
|
HRESULT hr;
|
|
CAppShortcut* pappshcut;
|
|
WCHAR rgchFile[MAX_PATH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetCurFile(rgchFile, sizeof(rgchFile) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
SHFILEINFO shfi;
|
|
DWORD_PTR dwResult;
|
|
|
|
dwResult = SHGetFileInfo(rgchFile, 0, &shfi, sizeof(shfi),
|
|
(SHGFI_DISPLAYNAME | SHGFI_ICON));
|
|
|
|
if (dwResult)
|
|
{
|
|
LPWSTR pwzFileName;
|
|
|
|
pwzFileName = (LPWSTR)ExtractFileName(shfi.szDisplayName);
|
|
|
|
EVAL(SetDlgItemText(hdlg, IDD_NAME, pwzFileName));
|
|
|
|
SetASPSIcon(hdlg, shfi.hIcon);
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if (hr != S_OK)
|
|
EVAL(SetDlgItemText(hdlg, IDD_NAME, g_cwzEmptyString));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSWorkingDirectory(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchWorkingDirectory[MAX_PATH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetWorkingDirectory(rgchWorkingDirectory,
|
|
sizeof(rgchWorkingDirectory) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_START_IN, rgchWorkingDirectory));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_START_IN, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void InitASPSHotkey(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
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.
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetHotkey(&wHotkey);
|
|
SendDlgItemMessage(hdlg, IDD_HOTKEY, HKM_SETHOTKEY, wHotkey, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void InitASPSShowCmds(HWND hdlg)
|
|
{
|
|
int niShowCmd;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
for (niShowCmd = IDS_SHOW_NORMAL;
|
|
niShowCmd <= IDS_SHOW_MAXIMIZED;
|
|
niShowCmd++)
|
|
{
|
|
WCHAR rgchShowCmd[s_ucMaxShowCmdLen];
|
|
|
|
if (LoadString(g_DllInstance, niShowCmd, rgchShowCmd, //MLLoadStringA
|
|
s_ucMaxShowCmdLen))//sizeof(rgchShowCmd)))
|
|
{
|
|
SendDlgItemMessage(hdlg, IDD_SHOW_CMD, CB_ADDSTRING, 0,
|
|
(LPARAM)rgchShowCmd);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSShowCmd(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
int nShowCmd;
|
|
int i;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
pappshcut->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));
|
|
|
|
i = 0; // default is 0 == 'normal'
|
|
}
|
|
|
|
SendDlgItemMessage(hdlg, IDD_SHOW_CMD, CB_SETCURSEL, i, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSDisplayName(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[DISPLAYNAMESTRINGLENGTH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetDisplayName(rgchString, sizeof(rgchString) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_DISPLAY_NAME, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_DISPLAY_NAME, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSName(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[NAMESTRINGLENGTH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetName(rgchString, sizeof(rgchString) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_NAME, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_NAME, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSVersion(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[VERSIONSTRINGLENGTH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetVersion(rgchString, sizeof(rgchString) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_VERSION, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_VERSION, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSCulture(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[CULTURESTRINGLENGTH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetCulture(rgchString, sizeof(rgchString) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_CULTURE, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_CULTURE, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSPKT(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[PKTSTRINGLENGTH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetPKT(rgchString, sizeof(rgchString) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_PKT, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_PKT, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSCodebase(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[MAX_URL_LENGTH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetCodebase(rgchString, sizeof(rgchString) / sizeof(WCHAR));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_CODEBASE, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_CODEBASE, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSEntrypoint(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
HRESULT hr;
|
|
WCHAR rgchString[MAX_PATH];
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
hr = pappshcut->GetPath(rgchString, sizeof(rgchString) / sizeof(WCHAR), NULL, 0);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_ENTRYPOINT, rgchString));
|
|
}
|
|
else
|
|
{
|
|
EVAL(SetDlgItemText(hdlg, IDD_ENTRYPOINT, g_cwzEmptyString));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void InitASPSType(HWND hdlg)
|
|
{
|
|
int i;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
for (i = IDS_APPTYPE_NETASSEMBLY; i <= IDS_APPTYPE_WIN32EXE; i++)
|
|
{
|
|
WCHAR rgchString[s_ucMaxTypeLen];
|
|
|
|
if (LoadString(g_DllInstance, i, rgchString, s_ucMaxTypeLen))//sizeof(rgchShowCmd))) //MLLoadStringA
|
|
{
|
|
SendDlgItemMessage(hdlg, IDD_TYPE, CB_ADDSTRING, 0, (LPARAM)rgchString);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SetASPSType(HWND hdlg)
|
|
{
|
|
CAppShortcut* pappshcut;
|
|
int nType;
|
|
int i;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
pappshcut->GetAppType(&nType);
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(s_rgnType); i++)
|
|
{
|
|
if (s_rgnType[i] == nType)
|
|
break;
|
|
}
|
|
|
|
if (i >= ARRAY_ELEMENTS(s_rgnType))
|
|
{
|
|
ASSERT(i == ARRAY_ELEMENTS(s_rgnType));
|
|
|
|
// not found! this clears the edit control - there's no default for this
|
|
// note: InjectASPSData has to handle this special case... as CB_ERR...
|
|
i = -1;
|
|
}
|
|
|
|
SendDlgItemMessage(hdlg, IDD_TYPE, CB_SETCURSEL, i, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL ASPS_InitDialog(HWND hdlg, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// wparam may be any value.
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
// this set PROPSHEETPAGE struct to DWLP_USER
|
|
SetWindowLongPtr(hdlg, DWLP_USER, lparam);
|
|
|
|
// Initialize control contents.
|
|
|
|
if (((PASPS)(((PROPSHEETPAGE*)lparam)->lParam))->eCurPage == APPSHCUT_PS_APPSHCUT_PAGE)
|
|
{
|
|
SetASPSFileNameAndIcon(hdlg);
|
|
|
|
// note: need limits on all editbox!
|
|
SetASPSDisplayName(hdlg);
|
|
|
|
SendDlgItemMessage(hdlg, IDD_CODEBASE, EM_LIMITTEXT, MAX_URL_LENGTH - 1, 0);
|
|
SetASPSCodebase(hdlg);
|
|
|
|
InitASPSType(hdlg);
|
|
SetASPSType(hdlg);
|
|
|
|
SendDlgItemMessage(hdlg, IDD_ENTRYPOINT, EM_LIMITTEXT, MAX_PATH - 1, 0);
|
|
SetASPSEntrypoint(hdlg);
|
|
|
|
SendDlgItemMessage(hdlg, IDD_START_IN, EM_LIMITTEXT, MAX_PATH - 1, 0);
|
|
SetASPSWorkingDirectory(hdlg);
|
|
|
|
InitASPSHotkey(hdlg);
|
|
|
|
InitASPSShowCmds(hdlg);
|
|
SetASPSShowCmd(hdlg);
|
|
}
|
|
else if (((PASPS)(((PROPSHEETPAGE*)lparam)->lParam))->eCurPage == APPSHCUT_PS_APPREF_PAGE)
|
|
{
|
|
// note: need limits on all editbox!
|
|
SetASPSDisplayName(hdlg);
|
|
SetASPSName(hdlg);
|
|
SetASPSVersion(hdlg);
|
|
SetASPSCulture(hdlg);
|
|
SetASPSPKT(hdlg);
|
|
}
|
|
// else do nothing?
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL ASPS_Destroy(HWND hdlg, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
// ASPSCallback is called after this func. The remaining frees/releases are there
|
|
|
|
// wparam may be any value.
|
|
// lparam may be any value.
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
SetWindowLongPtr(hdlg, DWLP_USER, NULL);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
void ASPSChanged(HWND hdlg)
|
|
{
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
PropSheet_Changed(GetParent(hdlg), hdlg);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
HRESULT ChooseIcon(HWND hdlg)
|
|
{
|
|
HRESULT hr;
|
|
PASPS pasps;
|
|
CAppShortcut* pappshcut;
|
|
WCHAR rgchTempIconFile[MAX_PATH];
|
|
int niIcon;
|
|
UINT uFlags;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pasps = (PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam);
|
|
pappshcut = pasps->pappshcut;
|
|
|
|
if (pappshcut->GetIconLocation(0, rgchTempIconFile,
|
|
sizeof(rgchTempIconFile)/sizeof(WCHAR), &niIcon, &uFlags) != S_OK)
|
|
{
|
|
rgchTempIconFile[0] = '\0';
|
|
niIcon = 0;
|
|
}
|
|
|
|
ASSERT(wcslen(rgchTempIconFile) < (sizeof(rgchTempIconFile)/sizeof(WCHAR)));
|
|
|
|
// a private shell32.dll export (by ordinal)...
|
|
if (PickIconDlg(hdlg, rgchTempIconFile, sizeof(rgchTempIconFile), &niIcon)) //??? sizeof
|
|
{
|
|
ASSERT(wcslen(rgchTempIconFile) < (sizeof(pasps->rgchIconFile)/sizeof(WCHAR)));
|
|
wcscpy(pasps->rgchIconFile, rgchTempIconFile);
|
|
pasps->niIcon = niIcon;
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
void UpdateASPSIcon(HWND hdlg)
|
|
{
|
|
PASPS pasps;
|
|
HICON hicon;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pasps = (PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam);
|
|
ASSERT(pasps->rgchIconFile[0]);
|
|
|
|
hicon = ExtractIcon(g_DllInstance, pasps->rgchIconFile, pasps->niIcon);
|
|
|
|
if (hicon)
|
|
SetASPSIcon(hdlg, hicon);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL ASPS_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_CODEBASE:
|
|
case IDD_HOTKEY:
|
|
case IDD_ENTRYPOINT:
|
|
case IDD_START_IN:
|
|
case IDD_DISPLAY_NAME:
|
|
case IDD_NAME:
|
|
case IDD_VERSION:
|
|
case IDD_CULTURE:
|
|
case IDD_PKT:
|
|
if (wCmd == EN_CHANGE)
|
|
{
|
|
ASPSChanged(hdlg);
|
|
|
|
bMsgHandled = TRUE;
|
|
}
|
|
break;
|
|
|
|
case IDD_SHOW_CMD:
|
|
case IDD_TYPE:
|
|
if (wCmd == LBN_SELCHANGE)
|
|
{
|
|
ASPSChanged(hdlg);
|
|
|
|
bMsgHandled = TRUE;
|
|
}
|
|
break;
|
|
|
|
case IDD_CHANGE_ICON:
|
|
// Ignore return value.
|
|
if (ChooseIcon(hdlg) == S_OK)
|
|
{
|
|
UpdateASPSIcon(hdlg);
|
|
ASPSChanged(hdlg);
|
|
}
|
|
bMsgHandled = TRUE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(bMsgHandled);
|
|
}
|
|
|
|
|
|
HRESULT InjectASPSData(HWND hdlg)
|
|
{
|
|
// BUGBUG: TODO: this function should validate the user's changes...
|
|
|
|
HRESULT hr = S_OK;
|
|
PASPS pasps;
|
|
CAppShortcut* pappshcut;
|
|
LPWSTR pwzURL;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pasps = (PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam);
|
|
pappshcut = pasps->pappshcut;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT ASPSSave(HWND hdlg)
|
|
{
|
|
HRESULT hr;
|
|
CAppShortcut* pappshcut;
|
|
|
|
ASSERT(IS_VALID_HANDLE(hdlg, WND));
|
|
|
|
pappshcut = ((PASPS)(((PROPSHEETPAGE*)GetWindowLongPtr(hdlg, DWLP_USER))->lParam))->pappshcut;
|
|
|
|
if (pappshcut->IsDirty() == S_OK)
|
|
{
|
|
// BUGBUG: TODO: IPersistFile::Save is not implemented
|
|
hr = pappshcut->Save((LPCOLESTR)NULL, FALSE);
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
BOOL ASPS_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 (((NMHDR*)lparam)->code)
|
|
{
|
|
case PSN_APPLY:
|
|
SetWindowLongPtr(hdlg, DWLP_MSGRESULT, ASPSSave(hdlg) == S_OK ?
|
|
PSNRET_NOERROR :
|
|
PSNRET_INVALID_NOCHANGEPAGE);
|
|
bMsgHandled = TRUE;
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hdlg, DWLP_MSGRESULT, FAILED(InjectASPSData(hdlg)));
|
|
bMsgHandled = TRUE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(bMsgHandled);
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK ASPS_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 = ASPS_InitDialog(hdlg, wparam, lparam);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
bMsgHandled = ASPS_Destroy(hdlg, wparam, lparam);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
bMsgHandled = ASPS_Command(hdlg, wparam, lparam);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
bMsgHandled = ASPS_Notify(hdlg, wparam, lparam);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(bMsgHandled);
|
|
}
|
|
|
|
|
|
HRESULT AddASPS(CAppShortcut* pappshcut,
|
|
LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lparam)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
PASPS pasps;
|
|
PROPSHEETPAGE psp;
|
|
HPROPSHEETPAGE hpsp;
|
|
|
|
PASPS pasps2;
|
|
PROPSHEETPAGE psp2;
|
|
HPROPSHEETPAGE hpsp2;
|
|
|
|
// lparam may be any value.
|
|
|
|
// this is deleted in ASPSCallback
|
|
pasps = new ASPS;
|
|
ZeroMemory(pasps, sizeof(*pasps));
|
|
|
|
psp.dwSize = sizeof(psp);
|
|
psp.dwFlags = (PSP_DEFAULT | PSP_USECALLBACK);
|
|
psp.hInstance = g_DllInstance; //MLGetHinst();
|
|
psp.pszTemplate = MAKEINTRESOURCE(DLG_APP_SHORTCUT_PROP_SHEET);
|
|
psp.pfnDlgProc = &ASPS_DlgProc;
|
|
psp.pfnCallback = &ASPSCallback;
|
|
psp.lParam = (LPARAM)pasps;
|
|
psp.hIcon = 0; // not used
|
|
psp.pszTitle = NULL; // not used
|
|
psp.pcRefParent = 0; // not used
|
|
|
|
pasps->pappshcut = pappshcut;
|
|
pasps->eCurPage = APPSHCUT_PS_APPSHCUT_PAGE; // page 1
|
|
|
|
// will psp be copied in this func? else this won't work...!!????????
|
|
hpsp = CreatePropertySheetPage(&psp);
|
|
|
|
if (hpsp)
|
|
{
|
|
if ((*pfnAddPage)(hpsp, lparam))
|
|
{
|
|
pappshcut->AddRef();
|
|
}
|
|
else
|
|
{
|
|
DestroyPropertySheetPage(hpsp);
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
// this is deleted in ASPSCallback
|
|
pasps2 = new ASPS;
|
|
ZeroMemory(pasps2, sizeof(*pasps2));
|
|
|
|
psp2.dwSize = sizeof(psp2);
|
|
psp2.dwFlags = (PSP_DEFAULT | PSP_USECALLBACK);
|
|
psp2.hInstance = g_DllInstance; //MLGetHinst();
|
|
psp2.pszTemplate = MAKEINTRESOURCE(DLG_APP_SHORTCUT_PROP_SHEET_APPNAME);
|
|
psp2.pfnDlgProc = &ASPS_DlgProc;
|
|
psp2.pfnCallback = &ASPSCallback;
|
|
psp2.lParam = (LPARAM)pasps2;
|
|
psp2.hIcon = 0; // not used
|
|
psp2.pszTitle = NULL; // not used
|
|
psp2.pcRefParent = 0; // not used
|
|
|
|
pasps2->pappshcut = pappshcut;
|
|
pasps2->eCurPage = APPSHCUT_PS_APPREF_PAGE; // page 2
|
|
|
|
// will psp be copied in this func? else this won't work...!!????????
|
|
hpsp2 = CreatePropertySheetPage(&psp2);
|
|
|
|
if (hpsp2)
|
|
{
|
|
if ((*pfnAddPage)(hpsp2, lparam))
|
|
{
|
|
pappshcut->AddRef();
|
|
}
|
|
else
|
|
{
|
|
DestroyPropertySheetPage(hpsp2);
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
/****************************** Public Functions *****************************/
|
|
|
|
|
|
BOOL RegisterGlobalHotkey(WORD wOldHotkey, WORD wNewHotkey,
|
|
LPCWSTR pcwzPath)
|
|
{
|
|
// BUGBUG?: does this work??
|
|
|
|
BOOL bResult = FALSE;
|
|
HWND hwndTray;
|
|
|
|
ASSERT(! wOldHotkey || IsValidHotkey(wOldHotkey));
|
|
ASSERT(! wNewHotkey || IsValidHotkey(wNewHotkey));
|
|
ASSERT(IsValidPath(pcwzPath));
|
|
|
|
hwndTray = FindWindow(s_cwzTrayNotificationClass, 0);
|
|
|
|
if (hwndTray)
|
|
{
|
|
if (wOldHotkey)
|
|
{
|
|
SendMessage(hwndTray, WMTRAY_SCUNREGISTERHOTKEY, wOldHotkey, 0);
|
|
}
|
|
|
|
if (wNewHotkey)
|
|
{
|
|
ATOM atom = GlobalAddAtom(pcwzPath);
|
|
ASSERT(atom);
|
|
if (atom)
|
|
{
|
|
SendMessage(hwndTray, WMTRAY_SCREGISTERHOTKEY, wNewHotkey, (LPARAM)atom);
|
|
GlobalDeleteAtom(atom);
|
|
}
|
|
}
|
|
|
|
bResult = TRUE;
|
|
}
|
|
/*else
|
|
{
|
|
bResult = FALSE;
|
|
}*/
|
|
|
|
return(bResult);
|
|
}
|
|
|
|
/********************************** Methods **********************************/
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::Initialize(LPCITEMIDLIST pcidlFolder,
|
|
IDataObject* pido,
|
|
HKEY hkeyProgID)
|
|
{
|
|
HRESULT hr;
|
|
STGMEDIUM stgmed;
|
|
FORMATETC fmtetc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
|
ASSERT(NULL != pido);
|
|
ASSERT(IS_VALID_HANDLE(hkeyProgID, KEY));
|
|
|
|
hr = pido->GetData(&fmtetc, &stgmed);
|
|
if (hr == S_OK)
|
|
{
|
|
WCHAR wzPath[MAX_PATH];
|
|
if (DragQueryFile((HDROP)stgmed.hGlobal, 0, wzPath, sizeof(wzPath)/sizeof(*wzPath)))
|
|
{
|
|
//mode is ignored for now
|
|
hr = Load(wzPath, 0);
|
|
}
|
|
// else path len > MAX_PATH or other error
|
|
|
|
ReleaseStgMedium(&stgmed);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage,
|
|
LPARAM lparam)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// lparam may be any value.
|
|
|
|
hr = AddASPS(this, pfnAddPage, lparam);
|
|
|
|
// BUGBUG: why this does not work?
|
|
// From MSDN:
|
|
//With version 4.71 and later, you can request that a particular property
|
|
//sheet page be displayed first, instead of the default page. To do so,
|
|
//return the one-based index of the desired page. For example, if you
|
|
//want the second of three pages displayed, the return value should be 2.
|
|
//Note that this return value is a request. The property sheet may still
|
|
//display the default page. --> see doc for AddPages()
|
|
if (SUCCEEDED(hr))
|
|
hr = HRESULT(4); // or 3??
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::ReplacePage(UINT uPageID,
|
|
LPFNADDPROPSHEETPAGE pfnReplaceWith,
|
|
LPARAM lparam)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// lparam may be any value.
|
|
// uPageID may be any value.
|
|
|
|
hr = E_NOTIMPL;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetDisplayName(LPCWSTR pcwzDisplayName)
|
|
{
|
|
// BUGBUG: not much checking is done!
|
|
|
|
BOOL bChanged = FALSE;
|
|
LPWSTR pwzOriString = NULL;
|
|
LPWSTR pwzNewString = (LPWSTR) pcwzDisplayName;
|
|
|
|
ASSERT(! pwzNewString);
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
pwzOriString = m_pappRefInfo->_wzDisplayName;
|
|
|
|
// ... this checks if all space in string...
|
|
if (! AnyNonWhiteSpace(pwzNewString))
|
|
pwzNewString = NULL;
|
|
|
|
bChanged = ! ((! pwzNewString && ! pwzOriString) ||
|
|
(pwzNewString && pwzOriString &&
|
|
! wcscmp(pwzNewString, pwzOriString)));
|
|
|
|
if (bChanged)
|
|
{
|
|
if (pwzNewString)
|
|
{
|
|
wcsncpy(pwzOriString, pwzNewString, DISPLAYNAMESTRINGLENGTH-1);
|
|
pwzOriString[DISPLAYNAMESTRINGLENGTH-1] = L'\0';
|
|
}
|
|
else
|
|
pwzOriString[0] = L'\0';
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetDisplayName(LPWSTR pwzDisplayName, int ncbLen)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (m_pappRefInfo->_wzDisplayName)
|
|
{
|
|
if ((int) wcslen(m_pappRefInfo->_wzDisplayName) < ncbLen)
|
|
{
|
|
wcsncpy(pwzDisplayName, m_pappRefInfo->_wzDisplayName, ncbLen-1);
|
|
pwzDisplayName[ncbLen-1] = L'\0';
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if (ncbLen > 0)
|
|
pwzDisplayName = L'\0';
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetName(LPCWSTR pcwzName)
|
|
{
|
|
// BUGBUG: not much checking is done!
|
|
|
|
BOOL bChanged = FALSE;
|
|
LPWSTR pwzOriString = NULL;
|
|
LPWSTR pwzNewString = (LPWSTR) pcwzName;
|
|
|
|
ASSERT(! pwzNewString);
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
pwzOriString = m_pappRefInfo->_wzName;
|
|
|
|
// ... this checks if all space in string...
|
|
if (! AnyNonWhiteSpace(pwzNewString))
|
|
pwzNewString = NULL;
|
|
|
|
bChanged = ! ((! pwzNewString && ! pwzOriString) ||
|
|
(pwzNewString && pwzOriString &&
|
|
! wcscmp(pwzNewString, pwzOriString)));
|
|
|
|
if (bChanged)
|
|
{
|
|
if (pwzNewString)
|
|
{
|
|
wcsncpy(pwzOriString, pwzNewString, NAMESTRINGLENGTH-1);
|
|
pwzOriString[NAMESTRINGLENGTH-1] = L'\0';
|
|
}
|
|
else
|
|
pwzOriString[0] = L'\0';
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetName(LPWSTR pwzName, int ncbLen)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (m_pappRefInfo->_wzName)
|
|
{
|
|
if ((int) wcslen(m_pappRefInfo->_wzName) < ncbLen)
|
|
{
|
|
wcsncpy(pwzName, m_pappRefInfo->_wzName, ncbLen-1);
|
|
pwzName[ncbLen-1] = L'\0';
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if (ncbLen > 0)
|
|
pwzName = L'\0';
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetVersion(LPCWSTR pcwzVersion)
|
|
{
|
|
// BUGBUG: not much checking is done!
|
|
|
|
BOOL bChanged = FALSE;
|
|
LPWSTR pwzOriString = NULL;
|
|
LPWSTR pwzNewString = (LPWSTR) pcwzVersion;
|
|
|
|
ASSERT(! pwzNewString);
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
pwzOriString = m_pappRefInfo->_wzVersion;
|
|
|
|
// ... this checks if all space in string...
|
|
if (! AnyNonWhiteSpace(pwzNewString))
|
|
pwzNewString = NULL;
|
|
|
|
bChanged = ! ((! pwzNewString && ! pwzOriString) ||
|
|
(pwzNewString && pwzOriString &&
|
|
! wcscmp(pwzNewString, pwzOriString)));
|
|
|
|
if (bChanged)
|
|
{
|
|
if (pwzNewString)
|
|
{
|
|
wcsncpy(pwzOriString, pwzNewString, VERSIONSTRINGLENGTH-1);
|
|
pwzOriString[VERSIONSTRINGLENGTH-1] = L'\0';
|
|
}
|
|
else
|
|
pwzOriString[0] = L'\0';
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetVersion(LPWSTR pwzVersion, int ncbLen)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (m_pappRefInfo->_wzVersion)
|
|
{
|
|
if ((int) wcslen(m_pappRefInfo->_wzVersion) < ncbLen)
|
|
{
|
|
wcsncpy(pwzVersion, m_pappRefInfo->_wzVersion, ncbLen-1);
|
|
pwzVersion[ncbLen-1] = L'\0';
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if (ncbLen > 0)
|
|
pwzVersion = L'\0';
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetCulture(LPCWSTR pcwzCulture)
|
|
{
|
|
// BUGBUG: not much checking is done!
|
|
|
|
BOOL bChanged = FALSE;
|
|
LPWSTR pwzOriString = NULL;
|
|
LPWSTR pwzNewString = (LPWSTR) pcwzCulture;
|
|
|
|
ASSERT(! pwzNewString);
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
pwzOriString = m_pappRefInfo->_wzCulture;
|
|
|
|
// ... this checks if all space in string...
|
|
if (! AnyNonWhiteSpace(pwzNewString))
|
|
pwzNewString = NULL;
|
|
|
|
bChanged = ! ((! pwzNewString && ! pwzOriString) ||
|
|
(pwzNewString && pwzOriString &&
|
|
! wcscmp(pwzNewString, pwzOriString)));
|
|
|
|
if (bChanged)
|
|
{
|
|
if (pwzNewString)
|
|
{
|
|
wcsncpy(pwzOriString, pwzNewString, CULTURESTRINGLENGTH-1);
|
|
pwzOriString[CULTURESTRINGLENGTH-1] = L'\0';
|
|
}
|
|
else
|
|
pwzOriString[0] = L'\0';
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetCulture(LPWSTR pwzCulture, int ncbLen)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (m_pappRefInfo->_wzCulture)
|
|
{
|
|
if ((int) wcslen(m_pappRefInfo->_wzCulture) < ncbLen)
|
|
{
|
|
wcsncpy(pwzCulture, m_pappRefInfo->_wzCulture, ncbLen-1);
|
|
pwzCulture[ncbLen-1] = L'\0';
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if (ncbLen > 0)
|
|
pwzCulture = L'\0';
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetPKT(LPCWSTR pcwzPKT)
|
|
{
|
|
// BUGBUG: not much checking is done!
|
|
|
|
BOOL bChanged = FALSE;
|
|
LPWSTR pwzOriString = NULL;
|
|
LPWSTR pwzNewString = (LPWSTR) pcwzPKT;
|
|
|
|
ASSERT(! pwzNewString);
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
pwzOriString = m_pappRefInfo->_wzPKT;
|
|
|
|
// ... this checks if all space in string...
|
|
if (! AnyNonWhiteSpace(pwzNewString))
|
|
pwzNewString = NULL;
|
|
|
|
bChanged = ! ((! pwzNewString && ! pwzOriString) ||
|
|
(pwzNewString && pwzOriString &&
|
|
! wcscmp(pwzNewString, pwzOriString)));
|
|
|
|
if (bChanged)
|
|
{
|
|
if (pwzNewString)
|
|
{
|
|
wcsncpy(pwzOriString, pwzNewString, PKTSTRINGLENGTH-1);
|
|
pwzOriString[PKTSTRINGLENGTH-1] = L'\0';
|
|
}
|
|
else
|
|
pwzOriString[0] = L'\0';
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetPKT(LPWSTR pwzPKT, int ncbLen)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (m_pappRefInfo->_wzPKT)
|
|
{
|
|
if ((int) wcslen(m_pappRefInfo->_wzPKT) < ncbLen)
|
|
{
|
|
wcsncpy(pwzPKT, m_pappRefInfo->_wzPKT, ncbLen-1);
|
|
pwzPKT[ncbLen-1] = L'\0';
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if (ncbLen > 0)
|
|
pwzPKT = L'\0';
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetCodebase(LPCWSTR pcwzCodebase)
|
|
{
|
|
// BUGBUG: not much checking is done!
|
|
|
|
BOOL bChanged = FALSE;
|
|
LPWSTR pwzOriString = NULL;
|
|
LPWSTR pwzNewString = (LPWSTR) pcwzCodebase;
|
|
|
|
ASSERT(! pwzNewString);
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
pwzOriString = m_pappRefInfo->_wzCodebase;
|
|
|
|
// ... this checks if all space in string...
|
|
if (! AnyNonWhiteSpace(pwzNewString))
|
|
pwzNewString = NULL;
|
|
|
|
bChanged = ! ((! pwzNewString && ! pwzOriString) ||
|
|
(pwzNewString && pwzOriString &&
|
|
! wcscmp(pwzNewString, pwzOriString)));
|
|
|
|
if (bChanged)
|
|
{
|
|
if (pwzNewString)
|
|
{
|
|
wcsncpy(pwzOriString, pwzNewString, MAX_URL_LENGTH-1);
|
|
pwzOriString[MAX_URL_LENGTH-1] = L'\0';
|
|
}
|
|
else
|
|
pwzOriString[0] = L'\0';
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetCodebase(LPWSTR pwzCodebase, int ncbLen)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (m_pappRefInfo->_wzCodebase)
|
|
{
|
|
if ((int) wcslen(m_pappRefInfo->_wzCodebase) < ncbLen)
|
|
{
|
|
wcsncpy(pwzCodebase, m_pappRefInfo->_wzCodebase, ncbLen-1);
|
|
pwzCodebase[ncbLen-1] = L'\0';
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
if (ncbLen > 0)
|
|
pwzCodebase = L'\0';
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::SetAppType(int nAppType)
|
|
{
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
if (nAppType != m_pappRefInfo->_fAppType)
|
|
{
|
|
m_pappRefInfo->_fAppType = nAppType;
|
|
|
|
Dirty(TRUE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CAppShortcut::GetAppType(PINT pnAppType)
|
|
{
|
|
if (!m_pappRefInfo)
|
|
return (E_FAIL);
|
|
|
|
*pnAppType = m_pappRefInfo->_fAppType;
|
|
|
|
return(S_OK);
|
|
}
|
|
|