1 /* $Id: appwiz.c 29364 2007-10-02 23:34:00Z janderwald $
3 * PROJECT: ReactOS Software Control Panel
4 * FILE: dll/cpl/appwiz/createlink.c
5 * PURPOSE: ReactOS Software Control Panel
6 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
7 * Dmitry Chapyshev (lentind@yandex.ru)
23 if (RegQueryValueExW(hKey
, L
"IsShortcut", NULL
, &Type
, (LPBYTE
)Value
, &Size
) != ERROR_SUCCESS
)
29 return (wcsicmp(Value
, L
"yes") == 0);
33 IsExtensionAShortcut(LPWSTR lpExtension
)
40 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, lpExtension
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
49 Size
= sizeof(Buffer
);
50 if (RegQueryValueEx(hKey
, NULL
, NULL
, &Type
, (LPBYTE
)Buffer
, &Size
) != ERROR_SUCCESS
|| Type
!= REG_SZ
)
58 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, Buffer
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
72 CreateShortcut(PCREATE_LINK_CONTEXT pContext
)
74 IShellLinkW
*pShellLink
, *pSourceShellLink
;
75 IPersistFile
*pPersistFile
;
80 /* get the extension */
81 lpExtension
= wcsrchr(pContext
->szTarget
, '.');
83 if (IsExtensionAShortcut(lpExtension
))
85 hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_ALL
, &IID_IShellLink
, (void**)&pSourceShellLink
);
90 hr
= pSourceShellLink
->lpVtbl
->QueryInterface(pSourceShellLink
, &IID_IPersistFile
, (void**)&pPersistFile
);
93 pSourceShellLink
->lpVtbl
->Release(pSourceShellLink
);
97 hr
= pPersistFile
->lpVtbl
->Load(pPersistFile
, (LPCOLESTR
)pContext
->szTarget
, STGM_READ
);
98 pPersistFile
->lpVtbl
->Release(pPersistFile
);
102 pSourceShellLink
->lpVtbl
->Release(pSourceShellLink
);
106 hr
= pSourceShellLink
->lpVtbl
->GetPath(pSourceShellLink
, Path
, sizeof(Path
) / sizeof(WCHAR
), NULL
, 0);
107 pSourceShellLink
->lpVtbl
->Release(pSourceShellLink
);
116 wcscpy(Path
, pContext
->szTarget
);
119 hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_ALL
,
120 &IID_IShellLink
, (void**)&pShellLink
);
126 pShellLink
->lpVtbl
->SetPath(pShellLink
, Path
);
127 pShellLink
->lpVtbl
->SetDescription(pShellLink
, pContext
->szDescription
);
128 pShellLink
->lpVtbl
->SetWorkingDirectory(pShellLink
, pContext
->szWorkingDirectory
);
130 hr
= pShellLink
->lpVtbl
->QueryInterface(pShellLink
, &IID_IPersistFile
, (void**)&pPersistFile
);
133 pShellLink
->lpVtbl
->Release(pShellLink
);
137 hr
= pPersistFile
->lpVtbl
->Save(pPersistFile
, pContext
->szLinkName
, TRUE
);
138 pPersistFile
->lpVtbl
->Release(pPersistFile
);
139 pShellLink
->lpVtbl
->Release(pShellLink
);
148 WelcomeDlgProc(HWND hwndDlg
,
153 LPPROPSHEETPAGEW ppsp
;
154 PCREATE_LINK_CONTEXT pContext
;
156 WCHAR szPath
[MAX_PATH
];
159 LPITEMIDLIST pidllist
;
165 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
166 pContext
= (PCREATE_LINK_CONTEXT
) ppsp
->lParam
;
167 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pContext
);
168 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
171 switch(HIWORD(wParam
))
174 if (SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_LOCATION
, WM_GETTEXTLENGTH
, 0, 0))
176 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
180 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
184 switch(LOWORD(wParam
))
186 case IDC_SHORTCUT_BROWSE
:
187 ZeroMemory(&brws
, sizeof(brws
));
188 brws
.hwndOwner
= hwndDlg
;
189 brws
.pidlRoot
= NULL
;
190 brws
.pszDisplayName
= szPath
;
191 brws
.ulFlags
= BIF_BROWSEINCLUDEFILES
;
193 pidllist
= SHBrowseForFolder(&brws
);
197 if (SHGetPathFromIDList(pidllist
, szPath
))
198 SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_LOCATION
, WM_SETTEXT
, 0, (LPARAM
)szPath
);
200 /* Free memory, if possible */
201 if (SUCCEEDED(SHGetMalloc(&malloc
)))
203 IMalloc_Free(malloc
, pidllist
);
204 IMalloc_Release(malloc
);
211 lppsn
= (LPPSHNOTIFY
) lParam
;
212 if (lppsn
->hdr
.code
== PSN_WIZNEXT
)
214 pContext
= (PCREATE_LINK_CONTEXT
) GetWindowLongPtr(hwndDlg
, DWLP_USER
);
215 SendDlgItemMessageW(hwndDlg
, IDC_SHORTCUT_LOCATION
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pContext
->szTarget
);
218 /// it should also be possible to create a link to folders, shellobjects etc....
220 if (GetFileAttributesW(pContext
->szTarget
) == INVALID_FILE_ATTRIBUTES
)
224 if (LoadStringW(hApplet
, IDS_CREATE_SHORTCUT
, szDesc
, 100) < 100 &&
225 LoadStringW(hApplet
, IDS_ERROR_NOT_FOUND
, szPath
, MAX_PATH
) < MAX_PATH
)
227 WCHAR szError
[MAX_PATH
+ 100];
229 _swprintf(szError
, szPath
, pContext
->szTarget
);
231 swprintf(szError
, szPath
, pContext
->szTarget
);
233 MessageBoxW(hwndDlg
, szError
, szDesc
, MB_ICONERROR
);
235 SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_LOCATION
, EM_SETSEL
, 0, -1);
236 SetFocus(GetDlgItem(hwndDlg
, IDC_SHORTCUT_LOCATION
));
237 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, PSNRET_INVALID_NOCHANGEPAGE
);
242 WCHAR
* first
, *last
;
243 wcscpy(pContext
->szWorkingDirectory
, pContext
->szTarget
);
244 first
= wcschr(pContext
->szWorkingDirectory
, L
'\\');
245 last
= wcsrchr(pContext
->szWorkingDirectory
, L
'\\');
246 wcscpy(pContext
->szDescription
, &last
[1]);
253 first
= wcsrchr(pContext
->szDescription
, L
'.');
267 FinishDlgProc(HWND hwndDlg
,
272 LPPROPSHEETPAGEW ppsp
;
273 PCREATE_LINK_CONTEXT pContext
;
279 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
280 pContext
= (PCREATE_LINK_CONTEXT
) ppsp
->lParam
;
281 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pContext
);
282 SendDlgItemMessageW(hwndDlg
, IDC_SHORTCUT_NAME
, WM_SETTEXT
, 0, (LPARAM
)pContext
->szDescription
);
283 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
286 switch(HIWORD(wParam
))
289 if (SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_NAME
, WM_GETTEXTLENGTH
, 0, 0))
291 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
295 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
301 lppsn
= (LPPSHNOTIFY
) lParam
;
302 pContext
= (PCREATE_LINK_CONTEXT
) GetWindowLongPtr(hwndDlg
, DWLP_USER
);
303 if (lppsn
->hdr
.code
== PSN_WIZFINISH
)
305 SendDlgItemMessageW(hwndDlg
, IDC_SHORTCUT_NAME
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pContext
->szDescription
);
306 wcscat(pContext
->szLinkName
, pContext
->szDescription
);
307 wcscat(pContext
->szLinkName
, L
".lnk");
308 if (!CreateShortcut(pContext
))
310 MessageBox(hwndDlg
, _T("Failed to create shortcut"), _T("Error"), MB_ICONERROR
);
320 ShowCreateShortcutWizard(HWND hwndCPl
, LPWSTR szPath
)
322 PROPSHEETHEADERW psh
;
323 HPROPSHEETPAGE ahpsp
[2];
329 PCREATE_LINK_CONTEXT pContext
= (PCREATE_LINK_CONTEXT
) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CREATE_LINK_CONTEXT
));
335 nLength
= wcslen(szPath
);
338 /* no directory given */
342 attrs
= GetFileAttributesW(szPath
);
343 if (attrs
== INVALID_FILE_ATTRIBUTES
|| (attrs
& FILE_ATTRIBUTE_DIRECTORY
))
349 wcscpy(pContext
->szLinkName
, szPath
);
350 if (pContext
->szLinkName
[nLength
-1] != L
'\\')
352 pContext
->szLinkName
[nLength
] = L
'\\';
353 pContext
->szLinkName
[nLength
+1] = L
'\0';
357 /* Create the Welcome page */
358 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
359 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
360 psp
.hInstance
= hApplet
;
361 psp
.pfnDlgProc
= WelcomeDlgProc
;
362 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SHORTCUT_LOCATION
);
363 psp
.lParam
= (LPARAM
)pContext
;
364 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
366 /* Create the Finish page */
367 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
368 psp
.pfnDlgProc
= FinishDlgProc
;
369 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SHORTCUT_FINISH
);
370 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
373 /* Create the property sheet */
374 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
375 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
;
376 psh
.hInstance
= hApplet
;
377 psh
.hwndParent
= NULL
;
381 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
383 /* Display the wizard */
385 HeapFree(GetProcessHeap(), 0, pContext
);
392 NewLinkHere(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
394 WCHAR szFile
[MAX_PATH
];
396 if (MultiByteToWideChar(CP_ACP
, 0, (LPSTR
) lParam1
, -1, szFile
, MAX_PATH
))
398 return ShowCreateShortcutWizard(hwndCPl
, szFile
);
406 NewLinkHereW(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
408 return ShowCreateShortcutWizard(hwndCPl
, (LPWSTR
) lParam1
);
413 NewLinkHereA(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
415 WCHAR szFile
[MAX_PATH
];
417 if (MultiByteToWideChar(CP_ACP
, 0, (LPSTR
) lParam1
, -1, szFile
, MAX_PATH
))
419 return ShowCreateShortcutWizard(hwndCPl
, szFile
);