2025-11-27 16:46:48 +09:00

573 lines
16 KiB
C++

// ShortcutDlg.cpp : implementation file
//
#include "stdafx.h"
#include "utsampleabout.h"
#include "Shortcut.h"
#include "ShortcutDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CShortcutDlg dialog
CShortcutDlg::CShortcutDlg(CWnd* pParent /*=NULL*/)
: CDialog(CShortcutDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CShortcutDlg)
m_bThrowException = FALSE;
m_sPathCreate = _T("");
m_sPathOpen = _T("");
m_sFN = _T("");
m_bParam = FALSE;
m_nParam = 0;
m_sParam = _T("");
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_bCreate = FALSE;
::GetCurrentDirectory(MAX_PATH, m_sCurDir.GetBuffer(MAX_PATH));
m_sCurDir.ReleaseBuffer();
}
void CShortcutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CShortcutDlg)
DDX_Control(pDX, IDC_PARAM_BOOL, m_ctlBool);
DDX_Control(pDX, IDC_PARAM_SPIN, m_ctlSpin);
DDX_Control(pDX, IDC_PARAM_KEY, m_ctlHotkey);
DDX_Control(pDX, IDC_COMBO_FN, m_ctlFn);
DDX_Check(pDX, IDC_CHECK_THROW_EXCEPTION, m_bThrowException);
DDX_Text(pDX, IDC_EDIT_CREATE, m_sPathCreate);
DDX_Text(pDX, IDC_EDIT_OPEN, m_sPathOpen);
DDX_CBString(pDX, IDC_COMBO_FN, m_sFN);
DDX_Check(pDX, IDC_PARAM_BOOL, m_bParam);
DDX_Text(pDX, IDC_PARAM_NUMBER, m_nParam);
DDV_MinMaxInt(pDX, m_nParam, 0, 99);
DDX_Text(pDX, IDC_PARAM_STRING, m_sParam);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CShortcutDlg, CDialog)
//{{AFX_MSG_MAP(CShortcutDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_CREATE, OnButtonCreate)
ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
ON_BN_CLICKED(IDC_BUTTON_FILE_OK, OnButtonFileOk)
ON_BN_CLICKED(IDC_BUTTON_FN_OK, OnButtonFnOk)
ON_BN_CLICKED(IDC_RADIO_CREATE, OnRadioCreate)
ON_BN_CLICKED(IDC_RADIO_OPEN, OnRadioOpen)
ON_CBN_SELCHANGE(IDC_COMBO_FN, OnSelchangeComboFn)
ON_BN_CLICKED(IDC_PARAM_BOOL, OnParamBool)
ON_BN_CLICKED(IDC_SAVE, OnSave)
ON_BN_CLICKED(IDC_BUTTON_PARAM_STRING, OnButtonParamString)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CShortcutDlg message handlers
#define FN_CLOSE _T("Close(BOOL bSave)")
#define FN_GETARGUMENTS _T("GetArguments(...)")
#define FN_GETCURFILE _T("GetCurFile()")
#define FN_GETDESCRIPTION _T("GetDescription(...)")
#define FN_GETHOTKEY _T("GetHotkey(...)")
#define FN_GETICONINDEX _T("GetIconIndex(...)")
#define FN_GETICONPATH _T("GetIconPath(...)")
#define FN_GETIDLIST _T("GetIDList(...)")
#define FN_GETLASTERROR _T("GetLastError()")
#define FN_GETPATH _T("GetPath(..., BOOL bUNC)")
#define FN_GETSHOWCMD _T("GetShowCmd(...)")
#define FN_GETWORKINGDIRECTORY _T("GetWorkingDirectory(...)")
#define FN_ISDIRTY _T("IsDirty()")
#define FN_OPEN _T("Open()")
#define FN_RESOLVE _T("Resolve(this, SLR_ANY_MATCH)")
#define FN_SAVE _T("Save(LPCTSTR pszFileName, BOOL fRemember)")
#define FN_SETARGUMENTS _T("SetArguments(LPCTSTR pszArguments)")
#define FN_SETDESCRIPTION _T("SetDescription(LPCTSTR pszDescription)")
#define FN_SETHOTKEY _T("SetHotkey(WORD wHotkey)")
#define FN_SETICONINDEX _T("SetIconIndex(int nIconIndex)")
#define FN_SETICONPATH _T("SetIconPath(LPCTSTR pszPath)")
#define FN_SETIDLIST _T("SetIDList(pidlPrograms)")
#define FN_SETPATH _T("SetPath(LPCTSTR pszPath)")
#define FN_SETRELATIVEPATH _T("SetRelativePath(LPCTSTR pszPath)")
#define FN_SETSHOWCMD _T("SetShowCmd(int nShowCmd)")
#define FN_SETWORKINGDIRECTORY _T("SetWorkingDirectory(LPCTSTR pszWorkingDirectory)")
BOOL CShortcutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_ctlFn.AddString(FN_CLOSE);
m_ctlFn.AddString(FN_GETARGUMENTS);
m_ctlFn.AddString(FN_GETCURFILE);
m_ctlFn.AddString(FN_GETDESCRIPTION);
m_ctlFn.AddString(FN_GETHOTKEY);
m_ctlFn.AddString(FN_GETICONINDEX);
m_ctlFn.AddString(FN_GETICONPATH);
m_ctlFn.AddString(FN_GETIDLIST);
m_ctlFn.AddString(FN_GETLASTERROR);
m_ctlFn.AddString(FN_GETPATH);
m_ctlFn.AddString(FN_GETSHOWCMD);
m_ctlFn.AddString(FN_GETWORKINGDIRECTORY);
m_ctlFn.AddString(FN_ISDIRTY);
// m_ctlFn.AddString(FN_OPEN);
m_ctlFn.AddString(FN_RESOLVE);
m_ctlFn.AddString(FN_SAVE);
m_ctlFn.AddString(FN_SETARGUMENTS);
m_ctlFn.AddString(FN_SETDESCRIPTION);
m_ctlFn.AddString(FN_SETHOTKEY);
m_ctlFn.AddString(FN_SETICONINDEX);
m_ctlFn.AddString(FN_SETICONPATH);
m_ctlFn.AddString(FN_SETIDLIST);
m_ctlFn.AddString(FN_SETPATH);
m_ctlFn.AddString(FN_SETRELATIVEPATH);
m_ctlFn.AddString(FN_SETSHOWCMD);
m_ctlFn.AddString(FN_SETWORKINGDIRECTORY);
m_ctlSpin.SetRange(0, 99);
UpdateControls();
((CButton*)GetDlgItem(IDC_RADIO_OPEN))->SetCheck(1);
return TRUE; // return TRUE unless you set the focus to a control
}
void CShortcutDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CUTSampleAboutDlg dlgAbout(IDR_MAINFRAME,ID_DESCRIPTION_FILE);
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CShortcutDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CShortcutDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CShortcutDlg::UpdateControls()
{
UpdateData();
BOOL bOpened = !m_scDemo.GetCurFile().IsEmpty();
SetDlgItemText(IDC_EDIT_OUTPUT, m_sOutput);
GetDlgItem(IDC_EDIT_OPEN)->EnableWindow(!m_bCreate);
GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(!m_bCreate);
GetDlgItem(IDC_EDIT_CREATE)->EnableWindow(m_bCreate);
GetDlgItem(IDC_BUTTON_CREATE)->EnableWindow(m_bCreate);
GetDlgItem(IDC_COMBO_FN)->EnableWindow(bOpened);
GetDlgItem(IDC_SAVE)->EnableWindow(bOpened);
GetDlgItem(IDC_BUTTON_FN_OK)->EnableWindow(bOpened && !m_sFN.IsEmpty());
GetDlgItem(IDC_PARAM_BOOL) ->EnableWindow(bOpened && m_sFN.Find(_T("BOOL")) != -1);
GetDlgItem(IDC_PARAM_KEY) ->EnableWindow(bOpened && m_sFN.Find(_T("WORD")) != -1);
GetDlgItem(IDC_PARAM_NUMBER)->EnableWindow(bOpened && m_sFN.Find(_T("int")) != -1);
GetDlgItem(IDC_PARAM_SPIN) ->EnableWindow(bOpened && m_sFN.Find(_T("int")) != -1);
GetDlgItem(IDC_PARAM_STRING)->EnableWindow(bOpened && m_sFN.Find(_T("LPCTSTR")) != -1);
GetDlgItem(IDC_BUTTON_PARAM_STRING)->EnableWindow(bOpened && m_sFN.Find(_T("LPCTSTR")) != -1);
}
void CShortcutDlg::OnButtonCreate()
{
CFileDialog dlg(FALSE, _T("LNK"), _T("New Shortcut"),
OFN_HIDEREADONLY | OFN_NODEREFERENCELINKS);
dlg.m_ofn.lpstrTitle = _T("Create...");
dlg.m_ofn.lpstrInitialDir = m_sCurDir;
if (dlg.DoModal() == IDOK)
{
SetDlgItemText(IDC_EDIT_CREATE, dlg.GetPathName());
m_sCurDir = dlg.GetPathName().Left(dlg.GetPathName().GetLength()
- dlg.GetFileTitle().GetLength());
}
}
void CShortcutDlg::OnButtonOpen()
{
CFileDialog dlg(TRUE, _T(".LNK"), NULL,
OFN_HIDEREADONLY | OFN_NODEREFERENCELINKS,
_T("Shortcut Files (*.LNK) | *.LNK;*.lnk | All Files (*.*) | *.*;* ||"), this);
dlg.m_ofn.lpstrInitialDir = m_sCurDir;
if (dlg.DoModal() == IDOK)
{
SetDlgItemText(IDC_EDIT_OPEN, m_sCurDir = dlg.GetPathName());
m_sCurDir = dlg.GetPathName().Left(dlg.GetPathName().GetLength()
- dlg.GetFileTitle().GetLength());
}
}
void CShortcutDlg::OnButtonParamString()
{
CFileDialog dlg(TRUE, NULL, NULL,
OFN_HIDEREADONLY | OFN_NODEREFERENCELINKS);
dlg.m_ofn.lpstrTitle = _T("Get pathname...");
dlg.m_ofn.lpstrInitialDir = m_sCurDir;
if (dlg.DoModal() == IDOK)
{
SetDlgItemText(IDC_PARAM_STRING, m_sCurDir = dlg.GetPathName());
m_sCurDir = dlg.GetPathName().Left(dlg.GetPathName().GetLength()
- dlg.GetFileTitle().GetLength());
}
}
void CShortcutDlg::OnSave()
{
CString sTemp = m_sParam;
SetDlgItemText(IDC_PARAM_STRING, _T(""));
if (UpdateData()) DemoOutput(FN_SAVE);
SetDlgItemText(IDC_PARAM_STRING, sTemp);
}
void CShortcutDlg::OnButtonFileOk()
{
if (UpdateData()) DemoOutput(FN_OPEN);
}
void CShortcutDlg::OnButtonFnOk()
{
if (UpdateData()) DemoOutput(m_sFN);
}
void CShortcutDlg::OnRadioCreate()
{
m_bCreate = TRUE;
UpdateControls();
}
void CShortcutDlg::OnRadioOpen()
{
m_bCreate = FALSE;
UpdateControls();
}
void CShortcutDlg::OnSelchangeComboFn()
{
UpdateControls();
SetDlgItemText(IDC_EDIT_OUTPUT, _T(""));
}
void CShortcutDlg::OnParamBool()
{
UpdateData();
m_ctlBool.SetWindowText(m_bParam ? _T("TRUE") : _T("FALSE"));
}
// for CShortcutDlg::DemoOutput() only
#define SWITCH \
if(FALSE) \
{ \
#define CASE(fn) \
} \
else if(sFN.Compare(fn) == 0) \
{ \
#define END_SWITCH \
} \
//////////////////////////////////////////////////////////////////////////////////////////////
// This is the only function that you may need to look into in order to understand COXShortcut
void CShortcutDlg::DemoOutput(LPCTSTR lpszFN)
{
LPCTSTR fmtX = _T("%02X");
LPCTSTR fmtN = _T("%d");
LPCTSTR fmtS = _T("\"%s\"");
CString sFN = lpszFN;
CString sBuffer;
// ... assume successful
BOOL bSuccess = TRUE;
m_sOutput = CString(sFN) + _T("\r\nOK\r\n");
try
{
SWITCH
CASE(FN_CLOSE)
m_scDemo.Close(m_bParam);
CASE(FN_GETARGUMENTS)
if (bSuccess == m_scDemo.GetArguments(sBuffer))
m_sOutput.Format(fmtS, sBuffer);
CASE(FN_GETCURFILE)
sBuffer = m_scDemo.GetCurFile();
m_sOutput.Format(fmtS, sBuffer);
CASE(FN_GETDESCRIPTION)
if (bSuccess == m_scDemo.GetDescription(sBuffer))
m_sOutput.Format(fmtS, sBuffer);
CASE(FN_GETHOTKEY)
WORD wVirtualKeyCode, wModifiers, wHotkey;
if (bSuccess == m_scDemo.GetHotkey(wHotkey))
{
wVirtualKeyCode = (WORD)(wHotkey & 0x00FF);
wModifiers = (WORD)(wHotkey >> 8);
m_ctlHotkey.EnableWindow(TRUE);
m_ctlHotkey.SetHotKey(wVirtualKeyCode, wModifiers);
m_sOutput += _T("Please see 'Key' for the current value");
}
CASE(FN_GETICONINDEX)
int iIcon;
if (bSuccess == m_scDemo.GetIconIndex(iIcon))
m_sOutput.Format(fmtN, iIcon);
CASE(FN_GETICONPATH)
if (bSuccess == m_scDemo.GetIconPath(sBuffer))
m_sOutput.Format(fmtS, sBuffer);
CASE(FN_GETIDLIST)
LPMALLOC g_pMalloc;
LPITEMIDLIST pidl;
// we need to call SHGetMalloc() to get an allocator
// pointer to free the memory allocation afterwards
if (SUCCEEDED(SHGetMalloc(&g_pMalloc)) && (bSuccess == m_scDemo.GetIDList(pidl)))
{
m_sOutput.Empty();
// output pidl
LPITEMIDLIST pidlWalkthrough = pidl;
int cb = pidl->mkid.cb;
while (cb)
{
int nLen = cb - sizeof(USHORT);
m_sOutput += _T('{');
for (int i = 0; i < nLen; i++)
{
sBuffer.Format(fmtX, pidlWalkthrough->mkid.abID[i]);
m_sOutput += sBuffer + ((i == nLen - 1) ? _T("}\r\n") : _T(", "));
}
pidlWalkthrough = (LPITEMIDLIST) (((LPBYTE) pidlWalkthrough) + cb);
cb = pidlWalkthrough->mkid.cb;
}
// ... now we're freeing it
g_pMalloc->Free(pidl);
}
CASE(FN_GETLASTERROR)
m_sOutput.Format(fmtN, m_scDemo.GetLastError());
CASE(FN_GETPATH)
if (bSuccess == m_scDemo.GetPath(sBuffer, m_bParam))
m_sOutput.Format(fmtS, sBuffer);
CASE(FN_GETSHOWCMD)
int iShowCmd;
if (bSuccess == m_scDemo.GetShowCmd(iShowCmd))
{
m_sOutput.Format(fmtN, iShowCmd);
m_sOutput += _T(": ");
// NOTE: not all showcmd would be accepted as is
switch(iShowCmd)
{
case SW_HIDE: m_sOutput += _T("SW_HIDE"); break;
case SW_MAXIMIZE: m_sOutput += _T("SW_MAXIMIZE"); break;
case SW_MINIMIZE: m_sOutput += _T("SW_MINIMIZE"); break;
case SW_RESTORE: m_sOutput += _T("SW_RESTORE"); break;
case SW_SHOW: m_sOutput += _T("SW_SHOW"); break;
case SW_SHOWDEFAULT: m_sOutput += _T("SW_SHOWDEFAULT"); break;
// case SW_SHOWMAXIMIZED: m_sOutput += _T("SW_SHOWMAXIMIZED"); break;
case SW_SHOWMINIMIZED: m_sOutput += _T("SW_SHOWMINIMIZED"); break;
case SW_SHOWMINNOACTIVE:m_sOutput += _T("SW_SHOWMINNOACTIVE"); break;
case SW_SHOWNA: m_sOutput += _T("SW_SHOWNA"); break;
case SW_SHOWNOACTIVATE: m_sOutput += _T("SW_SHOWNOACTIVATE"); break;
case SW_SHOWNORMAL: m_sOutput += _T("SW_SHOWNORMAL"); break;
default: m_sOutput += _T("(undefined)"); break;
}
}
CASE(FN_GETWORKINGDIRECTORY)
if (bSuccess == m_scDemo.GetWorkingDirectory(sBuffer))
m_sOutput.Format(fmtS, sBuffer);
CASE(FN_ISDIRTY)
m_sOutput.Format(fmtN, m_scDemo.IsDirty());
CASE(FN_OPEN)
if (m_bCreate)
{
// in real situation, you rarely use _T("") to start a new shortcut file
// because it appears as "My Computer" (the topest level, as you may find from
// the GetIDList()).
m_sOutput = _T("Here we use empty path as the object this shortcut points to.");
bSuccess = m_scDemo.Open(m_sPathCreate, _T(""), m_bThrowException);
}
else
{
bSuccess = m_scDemo.Open(m_sPathOpen, NULL, m_bThrowException);
}
CASE(FN_RESOLVE)
bSuccess = m_scDemo.Resolve(this, SLR_ANY_MATCH);
CASE(FN_SAVE)
if (m_sParam.IsEmpty())
{
m_sOutput = _T("Here we use NULL as the first parameter.");
bSuccess = m_scDemo.Save();
}
else
{
if (AfxMessageBox(CString(_T("Save as ")) + m_sParam, MB_OKCANCEL) == IDOK)
bSuccess = m_scDemo.Save(m_sParam, m_bParam);
}
CASE(FN_SETARGUMENTS)
bSuccess = m_scDemo.SetArguments(m_sParam);
CASE(FN_SETDESCRIPTION)
bSuccess = m_scDemo.SetDescription(m_sParam);
CASE(FN_SETHOTKEY)
WORD wVirtualKeyCode, wModifiers, wHotkey;
m_ctlHotkey.GetHotKey(wVirtualKeyCode, wModifiers);
wHotkey = (WORD)((wModifiers << 8) + wVirtualKeyCode);
bSuccess = m_scDemo.SetHotkey(wHotkey);
CASE(FN_SETICONINDEX)
bSuccess = m_scDemo.SetIconIndex(m_nParam);
CASE(FN_SETICONPATH)
bSuccess = m_scDemo.SetIconPath(m_sParam);
CASE(FN_SETIDLIST)
m_sOutput = _T("Here we use \"Programs\" folder as an example.");
int nFolder = CSIDL_PROGRAMS;
LPMALLOC g_pMalloc;
LPITEMIDLIST pidl;
if (SUCCEEDED(SHGetMalloc(&g_pMalloc)) &&
SUCCEEDED(SHGetSpecialFolderLocation(NULL, nFolder, &pidl)))
{
bSuccess = m_scDemo.SetIDList(pidl);
g_pMalloc->Free(pidl);
}
CASE(FN_SETPATH)
bSuccess = m_scDemo.SetPath(m_sParam);
CASE(FN_SETRELATIVEPATH)
bSuccess = m_scDemo.SetRelativePath(m_sParam);
CASE(FN_SETSHOWCMD)
bSuccess = m_scDemo.SetShowCmd(m_nParam);
CASE(FN_SETWORKINGDIRECTORY)
bSuccess = m_scDemo.SetWorkingDirectory(m_sParam);
END_SWITCH
}
catch (COleException* e)
{
bSuccess = FALSE;
e->ReportError();
e->Delete();
}
if (!bSuccess)
{
CString sFormat = CString(sFN) + _T("\r\n");
HRESULT hres = m_scDemo.GetLastError();
if (m_bThrowException)
sFormat += _T("Error: exception was thrown.");
else
{
// even when not successful, SUCCEEDED(hres) may be TRUE, e.g. S_FALSE;
// These kinds of HRESULT will cause a FALSE return on member functions
// (without throwing exceptions even when m_bThrowException == TRUE)
if (SUCCEEDED(hres))
{
if (hres == S_FALSE)
sFormat += _T("Failed (or succeeded with S_FALSE).");
else
// in case there are more codes (S_XXX) defined
// currently only S_OK (same as NOERROR) and S_FALSE are defined
// (check WinError.h)
sFormat += _T("Failed (or succeeded with unexpected result).");
}
else
// These are OLE-defined errors (should we have set m_bThrowException == TRUE,
// an exception will be thrown)
sFormat += _T("Error: no exception was thrown.");
}
sFormat += _T(" HRESULT: $%08X");
m_sOutput.Format(sFormat, hres);
}
SetWindowText(CString(_T("Demo of COXShortcut - ")) + m_scDemo.GetCurFile());
UpdateControls();
}