Author: janderwald Date: Fri Oct 5 03:51:10 2007 New Revision: 29393
URL: http://svn.reactos.org/svn/reactos?rev=29393&view=rev Log: - implement create shortcut wizard (works currently only for files)
Modified: trunk/reactos/dll/cpl/appwiz/appwiz.c trunk/reactos/dll/cpl/appwiz/appwiz.def trunk/reactos/dll/cpl/appwiz/appwiz.h trunk/reactos/dll/cpl/appwiz/appwiz.rbuild trunk/reactos/dll/cpl/appwiz/createlink.c trunk/reactos/dll/cpl/appwiz/lang/en-US.rc trunk/reactos/dll/cpl/appwiz/resource.h
Modified: trunk/reactos/dll/cpl/appwiz/appwiz.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/appwiz.c?rev... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/appwiz.c (original) +++ trunk/reactos/dll/cpl/appwiz/appwiz.c Fri Oct 5 03:51:10 2007 @@ -141,6 +141,7 @@ { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: + CoInitialize(NULL); hApplet = hinstDLL; break; }
Modified: trunk/reactos/dll/cpl/appwiz/appwiz.def URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/appwiz.def?r... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/appwiz.def (original) +++ trunk/reactos/dll/cpl/appwiz/appwiz.def Fri Oct 5 03:51:10 2007 @@ -3,5 +3,7 @@ EXPORTS CPlApplet NewLinkHere +NewLinkHereA +NewLinkHereW
; EOF
Modified: trunk/reactos/dll/cpl/appwiz/appwiz.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/appwiz.h?rev... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/appwiz.h (original) +++ trunk/reactos/dll/cpl/appwiz/appwiz.h Fri Oct 5 03:51:10 2007 @@ -10,6 +10,15 @@ int idDescription; CPLAPPLET_PROC AppletProc; } 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;
Modified: trunk/reactos/dll/cpl/appwiz/appwiz.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/appwiz.rbuil... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/appwiz.rbuild (original) +++ trunk/reactos/dll/cpl/appwiz/appwiz.rbuild Fri Oct 5 03:51:10 2007 @@ -12,6 +12,9 @@ <library>user32</library> <library>comctl32</library> <library>msvcrt</library> + <library>ole32</library> + <library>uuid</library> + <library>shell32</library> <file>appwiz.c</file> <file>remove.c</file> <file>add.c</file>
Modified: trunk/reactos/dll/cpl/appwiz/createlink.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/createlink.c... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/createlink.c (original) +++ trunk/reactos/dll/cpl/appwiz/createlink.c Fri Oct 5 03:51:10 2007 @@ -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 $ * * PROJECT: ReactOS Software Control Panel - * FILE: dll/cpl/appwiz/appwiz.c + * FILE: dll/cpl/appwiz/createlink.c * PURPOSE: ReactOS Software Control Panel - * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com) - * UPDATE HISTORY: - * 06-17-2004 Created + * PROGRAMMER: Johannes Anderwald */
#include <windows.h> @@ -35,9 +16,48 @@ #include <stdarg.h> #include <tchar.h> #include <process.h> - +#include <shlobj.h> +#include <objbase.h> +#include <shobjidl.h> +#include <shlguid.h> +#include <stdio.h> #include "resource.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 CALLBACK @@ -46,9 +66,20 @@ WPARAM wParam, LPARAM lParam) { + LPPROPSHEETPAGEW ppsp; + PCREATE_LINK_CONTEXT pContext; + LPPSHNOTIFY lppsn; + WCHAR szPath[MAX_PATH]; + WCHAR szDesc[100]; + BROWSEINFOW brws; + LPITEMIDLIST pidllist; + switch(uMsg) { case WM_INITDIALOG: + ppsp = (LPPROPSHEETPAGEW)lParam; + pContext = (PCREATE_LINK_CONTEXT) ppsp->lParam; + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext); PropSheet_SetWizButtons(GetParent(hwndDlg), 0); break; case WM_COMMAND: @@ -63,8 +94,75 @@ { 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; } @@ -76,23 +174,86 @@ WPARAM wParam, LPARAM lParam) { + LPPROPSHEETPAGEW ppsp; + PCREATE_LINK_CONTEXT pContext; + LPPSHNOTIFY lppsn; + switch(uMsg) { 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); 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; }
- LONG CALLBACK -NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) +ShowCreateShortcutWizard(HWND hwndCPl, LPWSTR szPath) { PROPSHEETHEADERW psh; HPROPSHEETPAGE ahpsp[2]; PROPSHEETPAGE psp; 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 */ psp.dwSize = sizeof(PROPSHEETPAGE); @@ -100,6 +261,7 @@ psp.hInstance = hApplet; psp.pfnDlgProc = WelcomeDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_SHORTCUT_LOCATION); + psp.lParam = (LPARAM)pContext; ahpsp[nPages++] = CreatePropertySheetPage(&psp);
/* Create the Finish page */ @@ -121,6 +283,41 @@
/* Display the wizard */ PropertySheet(&psh); - + HeapFree(GetProcessHeap(), 0, pContext); 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; +}
Modified: trunk/reactos/dll/cpl/appwiz/lang/en-US.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/lang/en-US.r... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/lang/en-US.rc (original) +++ trunk/reactos/dll/cpl/appwiz/lang/en-US.rc Fri Oct 5 03:51:10 2007 @@ -97,4 +97,6 @@ IDS_LARGEICONS "Large Icons" IDS_LIST "List" IDS_DETAILS "Details" + IDS_CREATE_SHORTCUT "Create Shortcut" + IDS_ERROR_NOT_FOUND "The file %s was not found." END
Modified: trunk/reactos/dll/cpl/appwiz/resource.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/resource.h?r... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/resource.h (original) +++ trunk/reactos/dll/cpl/appwiz/resource.h Fri Oct 5 03:51:10 2007 @@ -40,6 +40,8 @@ #define IDS_LARGEICONS 2007 #define IDS_LIST 2008 #define IDS_DETAILS 2009 +#define IDS_CREATE_SHORTCUT 2010 +#define IDS_ERROR_NOT_FOUND 2011
/* controls */ #define IDC_INSTALL 101