mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:43:01 +00:00
- implement create shortcut wizard (works currently only for files)
svn path=/trunk/; revision=29393
This commit is contained in:
parent
327e65fe96
commit
fe4f628972
7 changed files with 242 additions and 26 deletions
|
@ -141,6 +141,7 @@ DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
|
CoInitialize(NULL);
|
||||||
hApplet = hinstDLL;
|
hApplet = hinstDLL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,5 +3,7 @@ LIBRARY appwiz.cpl
|
||||||
EXPORTS
|
EXPORTS
|
||||||
CPlApplet
|
CPlApplet
|
||||||
NewLinkHere
|
NewLinkHere
|
||||||
|
NewLinkHereA
|
||||||
|
NewLinkHereW
|
||||||
|
|
||||||
; EOF
|
; EOF
|
||||||
|
|
|
@ -11,6 +11,15 @@ typedef struct
|
||||||
CPLAPPLET_PROC AppletProc;
|
CPLAPPLET_PROC AppletProc;
|
||||||
} APPLET, *PAPPLET;
|
} APPLET, *PAPPLET;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
WCHAR szTarget[MAX_PATH];
|
||||||
|
WCHAR szWorkingDirectory[MAX_PATH];
|
||||||
|
WCHAR szDescription[MAX_PATH];
|
||||||
|
WCHAR szLinkName[MAX_PATH];
|
||||||
|
}CREATE_LINK_CONTEXT, *PCREATE_LINK_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
extern HINSTANCE hApplet;
|
extern HINSTANCE hApplet;
|
||||||
|
|
||||||
/* remove.c */
|
/* remove.c */
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
<library>user32</library>
|
<library>user32</library>
|
||||||
<library>comctl32</library>
|
<library>comctl32</library>
|
||||||
<library>msvcrt</library>
|
<library>msvcrt</library>
|
||||||
|
<library>ole32</library>
|
||||||
|
<library>uuid</library>
|
||||||
|
<library>shell32</library>
|
||||||
<file>appwiz.c</file>
|
<file>appwiz.c</file>
|
||||||
<file>remove.c</file>
|
<file>remove.c</file>
|
||||||
<file>add.c</file>
|
<file>add.c</file>
|
||||||
|
|
|
@ -1,29 +1,10 @@
|
||||||
/*
|
|
||||||
* ReactOS
|
|
||||||
* Copyright (C) 2004 ReactOS Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
/* $Id: appwiz.c 29364 2007-10-02 23:34:00Z janderwald $
|
/* $Id: appwiz.c 29364 2007-10-02 23:34:00Z janderwald $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS Software Control Panel
|
* PROJECT: ReactOS Software Control Panel
|
||||||
* FILE: dll/cpl/appwiz/appwiz.c
|
* FILE: dll/cpl/appwiz/createlink.c
|
||||||
* PURPOSE: ReactOS Software Control Panel
|
* PURPOSE: ReactOS Software Control Panel
|
||||||
* PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
|
* PROGRAMMER: Johannes Anderwald
|
||||||
* UPDATE HISTORY:
|
|
||||||
* 06-17-2004 Created
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -35,10 +16,49 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <objbase.h>
|
||||||
|
#include <shobjidl.h>
|
||||||
|
#include <shlguid.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "appwiz.h"
|
#include "appwiz.h"
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
CreateShortcut(PCREATE_LINK_CONTEXT pContext)
|
||||||
|
{
|
||||||
|
IShellLinkW *pShellLink;
|
||||||
|
IPersistFile *pPersistFile;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_ALL,
|
||||||
|
&IID_IShellLink, (void**)&pShellLink);
|
||||||
|
|
||||||
|
if (hr != S_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
pShellLink->lpVtbl->SetPath(pShellLink, pContext->szTarget);
|
||||||
|
pShellLink->lpVtbl->SetDescription(pShellLink, pContext->szDescription);
|
||||||
|
pShellLink->lpVtbl->SetWorkingDirectory(pShellLink, pContext->szWorkingDirectory);
|
||||||
|
|
||||||
|
hr = pShellLink->lpVtbl->QueryInterface(pShellLink, &IID_IPersistFile, (void**)&pPersistFile);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
pShellLink->lpVtbl->Release(pShellLink);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pPersistFile->lpVtbl->Save(pPersistFile, pContext->szLinkName, TRUE);
|
||||||
|
pPersistFile->lpVtbl->Release(pPersistFile);
|
||||||
|
pShellLink->lpVtbl->Release(pShellLink);
|
||||||
|
return (hr == S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INT_PTR
|
INT_PTR
|
||||||
CALLBACK
|
CALLBACK
|
||||||
WelcomeDlgProc(HWND hwndDlg,
|
WelcomeDlgProc(HWND hwndDlg,
|
||||||
|
@ -46,9 +66,20 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
LPPROPSHEETPAGEW ppsp;
|
||||||
|
PCREATE_LINK_CONTEXT pContext;
|
||||||
|
LPPSHNOTIFY lppsn;
|
||||||
|
WCHAR szPath[MAX_PATH];
|
||||||
|
WCHAR szDesc[100];
|
||||||
|
BROWSEINFOW brws;
|
||||||
|
LPITEMIDLIST pidllist;
|
||||||
|
|
||||||
switch(uMsg)
|
switch(uMsg)
|
||||||
{
|
{
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
|
ppsp = (LPPROPSHEETPAGEW)lParam;
|
||||||
|
pContext = (PCREATE_LINK_CONTEXT) ppsp->lParam;
|
||||||
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
|
||||||
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
|
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
|
||||||
break;
|
break;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
|
@ -63,9 +94,76 @@ WelcomeDlgProc(HWND hwndDlg,
|
||||||
{
|
{
|
||||||
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
|
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDC_SHORTCUT_BROWSE:
|
||||||
|
brws.hwndOwner = hwndDlg;
|
||||||
|
brws.pidlRoot = NULL;
|
||||||
|
brws.pszDisplayName = szPath;
|
||||||
|
brws.ulFlags = BIF_BROWSEINCLUDEFILES;
|
||||||
|
brws.lpfn = NULL;
|
||||||
|
pidllist = SHBrowseForFolder(&brws);
|
||||||
|
if (!pidllist)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (SHGetPathFromIDList(pidllist, szPath))
|
||||||
|
SendDlgItemMessage(hwndDlg, IDC_SHORTCUT_LOCATION, WM_SETTEXT, 0, (LPARAM)szPath);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
lppsn = (LPPSHNOTIFY) lParam;
|
||||||
|
if (lppsn->hdr.code == PSN_WIZNEXT)
|
||||||
|
{
|
||||||
|
pContext = (PCREATE_LINK_CONTEXT) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||||||
|
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_LOCATION, WM_GETTEXT, MAX_PATH, (LPARAM)pContext->szTarget);
|
||||||
|
///
|
||||||
|
/// FIXME
|
||||||
|
/// it should also be possible to create a link to folders, shellobjects etc....
|
||||||
|
///
|
||||||
|
if (GetFileAttributesW(pContext->szTarget) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
szDesc[0] = L'\0';
|
||||||
|
szPath[0] = L'\0';
|
||||||
|
if (LoadStringW(hApplet, IDS_CREATE_SHORTCUT, szDesc, 100) < 100 &&
|
||||||
|
LoadStringW(hApplet, IDS_ERROR_NOT_FOUND, szPath, MAX_PATH) < MAX_PATH)
|
||||||
|
{
|
||||||
|
WCHAR szError[MAX_PATH + 100];
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
_swprintf(szError, szPath, pContext->szTarget);
|
||||||
|
#else
|
||||||
|
swprintf(szError, szPath, pContext->szTarget);
|
||||||
|
#endif
|
||||||
|
MessageBoxW(hwndDlg, szError, szDesc, MB_ICONERROR);
|
||||||
|
}
|
||||||
|
SendDlgItemMessage(hwndDlg, IDC_SHORTCUT_LOCATION, EM_SETSEL, 0, -1);
|
||||||
|
SetFocus(GetDlgItem(hwndDlg, IDC_SHORTCUT_LOCATION));
|
||||||
|
SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WCHAR * first, *last;
|
||||||
|
wcscpy(pContext->szWorkingDirectory, pContext->szTarget);
|
||||||
|
first = wcschr(pContext->szWorkingDirectory, L'\\');
|
||||||
|
last = wcsrchr(pContext->szWorkingDirectory, L'\\');
|
||||||
|
wcscpy(pContext->szDescription, &last[1]);
|
||||||
|
|
||||||
|
if (first != last)
|
||||||
|
last[0] = L'\0';
|
||||||
|
else
|
||||||
|
first[1] = L'\0';
|
||||||
|
|
||||||
|
first = wcsrchr(pContext->szDescription, L'.');
|
||||||
|
first[0] = L'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,23 +174,86 @@ FinishDlgProc(HWND hwndDlg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
LPPROPSHEETPAGEW ppsp;
|
||||||
|
PCREATE_LINK_CONTEXT pContext;
|
||||||
|
LPPSHNOTIFY lppsn;
|
||||||
|
|
||||||
switch(uMsg)
|
switch(uMsg)
|
||||||
{
|
{
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
|
ppsp = (LPPROPSHEETPAGEW)lParam;
|
||||||
|
pContext = (PCREATE_LINK_CONTEXT) ppsp->lParam;
|
||||||
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
|
||||||
|
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_NAME, WM_SETTEXT, 0, (LPARAM)pContext->szDescription);
|
||||||
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
|
||||||
break;
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
switch(HIWORD(wParam))
|
||||||
|
{
|
||||||
|
case EN_CHANGE:
|
||||||
|
if (SendDlgItemMessage(hwndDlg, IDC_SHORTCUT_LOCATION, WM_GETTEXTLENGTH, 0, 0))
|
||||||
|
{
|
||||||
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
lppsn = (LPPSHNOTIFY) lParam;
|
||||||
|
pContext = (PCREATE_LINK_CONTEXT) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||||||
|
if (lppsn->hdr.code == PSN_WIZFINISH)
|
||||||
|
{
|
||||||
|
SendDlgItemMessageW(hwndDlg, IDC_SHORTCUT_NAME, WM_GETTEXT, MAX_PATH, (LPARAM)pContext->szDescription);
|
||||||
|
wcscat(pContext->szLinkName, pContext->szDescription);
|
||||||
|
wcscat(pContext->szLinkName, L".lnk");
|
||||||
|
if (!CreateShortcut(pContext))
|
||||||
|
{
|
||||||
|
MessageBox(hwndDlg, _T("Failed to create shortcut"), _T("Error"), MB_ICONERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LONG CALLBACK
|
LONG CALLBACK
|
||||||
NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
ShowCreateShortcutWizard(HWND hwndCPl, LPWSTR szPath)
|
||||||
{
|
{
|
||||||
PROPSHEETHEADERW psh;
|
PROPSHEETHEADERW psh;
|
||||||
HPROPSHEETPAGE ahpsp[2];
|
HPROPSHEETPAGE ahpsp[2];
|
||||||
PROPSHEETPAGE psp;
|
PROPSHEETPAGE psp;
|
||||||
UINT nPages = 0;
|
UINT nPages = 0;
|
||||||
|
UINT nLength;
|
||||||
|
|
||||||
|
PCREATE_LINK_CONTEXT pContext = (PCREATE_LINK_CONTEXT) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CREATE_LINK_CONTEXT));
|
||||||
|
if (!pContext)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
nLength = wcslen(szPath);
|
||||||
|
if (!nLength)
|
||||||
|
{
|
||||||
|
/* no directory given */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
///
|
||||||
|
/// FIXME
|
||||||
|
/// check if path is valid
|
||||||
|
///
|
||||||
|
|
||||||
|
wcscpy(pContext->szLinkName, szPath);
|
||||||
|
if (pContext->szLinkName[nLength-1] != L'\\')
|
||||||
|
{
|
||||||
|
pContext->szLinkName[nLength] = L'\\';
|
||||||
|
pContext->szLinkName[nLength+1] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create the Welcome page */
|
/* Create the Welcome page */
|
||||||
psp.dwSize = sizeof(PROPSHEETPAGE);
|
psp.dwSize = sizeof(PROPSHEETPAGE);
|
||||||
|
@ -100,6 +261,7 @@ NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||||
psp.hInstance = hApplet;
|
psp.hInstance = hApplet;
|
||||||
psp.pfnDlgProc = WelcomeDlgProc;
|
psp.pfnDlgProc = WelcomeDlgProc;
|
||||||
psp.pszTemplate = MAKEINTRESOURCE(IDD_SHORTCUT_LOCATION);
|
psp.pszTemplate = MAKEINTRESOURCE(IDD_SHORTCUT_LOCATION);
|
||||||
|
psp.lParam = (LPARAM)pContext;
|
||||||
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
|
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
|
||||||
|
|
||||||
/* Create the Finish page */
|
/* Create the Finish page */
|
||||||
|
@ -121,6 +283,41 @@ NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||||
|
|
||||||
/* Display the wizard */
|
/* Display the wizard */
|
||||||
PropertySheet(&psh);
|
PropertySheet(&psh);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pContext);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
CALLBACK
|
||||||
|
NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||||
|
{
|
||||||
|
WCHAR szFile[MAX_PATH];
|
||||||
|
|
||||||
|
if (MultiByteToWideChar(CP_ACP, 0, (char*)lParam1, strlen((char*)lParam1)+1, szFile, MAX_PATH))
|
||||||
|
{
|
||||||
|
return ShowCreateShortcutWizard(hwndCPl, szFile);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
CALLBACK
|
||||||
|
NewLinkHereW(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||||
|
{
|
||||||
|
return ShowCreateShortcutWizard(hwndCPl, (LPWSTR)lParam1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
CALLBACK
|
||||||
|
NewLinkHereA(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||||
|
{
|
||||||
|
WCHAR szFile[MAX_PATH];
|
||||||
|
|
||||||
|
if (MultiByteToWideChar(CP_ACP, 0, (char*)lParam1, strlen((char*)lParam1)+1, szFile, MAX_PATH))
|
||||||
|
{
|
||||||
|
return ShowCreateShortcutWizard(hwndCPl, szFile);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -97,4 +97,6 @@ BEGIN
|
||||||
IDS_LARGEICONS "Large Icons"
|
IDS_LARGEICONS "Large Icons"
|
||||||
IDS_LIST "List"
|
IDS_LIST "List"
|
||||||
IDS_DETAILS "Details"
|
IDS_DETAILS "Details"
|
||||||
|
IDS_CREATE_SHORTCUT "Create Shortcut"
|
||||||
|
IDS_ERROR_NOT_FOUND "The file %s was not found."
|
||||||
END
|
END
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#define IDS_LARGEICONS 2007
|
#define IDS_LARGEICONS 2007
|
||||||
#define IDS_LIST 2008
|
#define IDS_LIST 2008
|
||||||
#define IDS_DETAILS 2009
|
#define IDS_DETAILS 2009
|
||||||
|
#define IDS_CREATE_SHORTCUT 2010
|
||||||
|
#define IDS_ERROR_NOT_FOUND 2011
|
||||||
|
|
||||||
/* controls */
|
/* controls */
|
||||||
#define IDC_INSTALL 101
|
#define IDC_INSTALL 101
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue