2 * PROJECT: ReactOS Software Control Panel
3 * FILE: dll/cpl/appwiz/createlink.c
4 * PURPOSE: ReactOS Software Control Panel
5 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
6 * Dmitry Chapyshev (lentind@yandex.ru)
22 if (RegQueryValueExW(hKey
, L
"IsShortcut", NULL
, &Type
, (LPBYTE
)Value
, &Size
) != ERROR_SUCCESS
)
28 return (wcsicmp(Value
, L
"yes") == 0);
32 IsExtensionAShortcut(LPWSTR lpExtension
)
39 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, lpExtension
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
48 Size
= sizeof(Buffer
);
49 if (RegQueryValueEx(hKey
, NULL
, NULL
, &Type
, (LPBYTE
)Buffer
, &Size
) != ERROR_SUCCESS
|| Type
!= REG_SZ
)
57 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, Buffer
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
71 CreateShortcut(PCREATE_LINK_CONTEXT pContext
)
73 IShellLinkW
*pShellLink
, *pSourceShellLink
;
74 IPersistFile
*pPersistFile
;
79 /* get the extension */
80 lpExtension
= wcsrchr(pContext
->szTarget
, '.');
82 if (IsExtensionAShortcut(lpExtension
))
84 hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_ALL
, &IID_IShellLinkW
, (void**)&pSourceShellLink
);
89 hr
= pSourceShellLink
->lpVtbl
->QueryInterface(pSourceShellLink
, &IID_IPersistFile
, (void**)&pPersistFile
);
92 pSourceShellLink
->lpVtbl
->Release(pSourceShellLink
);
96 hr
= pPersistFile
->lpVtbl
->Load(pPersistFile
, (LPCOLESTR
)pContext
->szTarget
, STGM_READ
);
97 pPersistFile
->lpVtbl
->Release(pPersistFile
);
101 pSourceShellLink
->lpVtbl
->Release(pSourceShellLink
);
105 hr
= pSourceShellLink
->lpVtbl
->GetPath(pSourceShellLink
, Path
, sizeof(Path
) / sizeof(WCHAR
), NULL
, 0);
106 pSourceShellLink
->lpVtbl
->Release(pSourceShellLink
);
115 wcscpy(Path
, pContext
->szTarget
);
118 hr
= CoCreateInstance(&CLSID_ShellLink
, NULL
, CLSCTX_ALL
,
119 &IID_IShellLinkW
, (void**)&pShellLink
);
125 pShellLink
->lpVtbl
->SetPath(pShellLink
, Path
);
126 pShellLink
->lpVtbl
->SetDescription(pShellLink
, pContext
->szDescription
);
127 pShellLink
->lpVtbl
->SetWorkingDirectory(pShellLink
, pContext
->szWorkingDirectory
);
129 hr
= pShellLink
->lpVtbl
->QueryInterface(pShellLink
, &IID_IPersistFile
, (void**)&pPersistFile
);
132 pShellLink
->lpVtbl
->Release(pShellLink
);
136 hr
= pPersistFile
->lpVtbl
->Save(pPersistFile
, pContext
->szLinkName
, TRUE
);
137 pPersistFile
->lpVtbl
->Release(pPersistFile
);
138 pShellLink
->lpVtbl
->Release(pShellLink
);
147 WelcomeDlgProc(HWND hwndDlg
,
152 LPPROPSHEETPAGEW ppsp
;
153 PCREATE_LINK_CONTEXT pContext
;
155 WCHAR szPath
[MAX_PATH
];
158 LPITEMIDLIST pidllist
;
164 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
165 pContext
= (PCREATE_LINK_CONTEXT
) ppsp
->lParam
;
166 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pContext
);
167 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
170 switch(HIWORD(wParam
))
173 if (SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_LOCATION
, WM_GETTEXTLENGTH
, 0, 0))
175 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
179 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
183 switch(LOWORD(wParam
))
185 case IDC_SHORTCUT_BROWSE
:
186 ZeroMemory(&brws
, sizeof(brws
));
187 brws
.hwndOwner
= hwndDlg
;
188 brws
.pidlRoot
= NULL
;
189 brws
.pszDisplayName
= szPath
;
190 brws
.ulFlags
= BIF_BROWSEINCLUDEFILES
;
192 pidllist
= SHBrowseForFolderW(&brws
);
196 if (SHGetPathFromIDListW(pidllist
, szPath
))
197 SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_LOCATION
, WM_SETTEXT
, 0, (LPARAM
)szPath
);
199 /* Free memory, if possible */
200 if (SUCCEEDED(SHGetMalloc(&malloc
)))
202 IMalloc_Free(malloc
, pidllist
);
203 IMalloc_Release(malloc
);
210 lppsn
= (LPPSHNOTIFY
) lParam
;
211 if (lppsn
->hdr
.code
== PSN_WIZNEXT
)
213 pContext
= (PCREATE_LINK_CONTEXT
) GetWindowLongPtr(hwndDlg
, DWLP_USER
);
214 SendDlgItemMessageW(hwndDlg
, IDC_SHORTCUT_LOCATION
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pContext
->szTarget
);
217 /// it should also be possible to create a link to folders, shellobjects etc....
219 if (GetFileAttributesW(pContext
->szTarget
) == INVALID_FILE_ATTRIBUTES
)
223 if (LoadStringW(hApplet
, IDS_CREATE_SHORTCUT
, szDesc
, 100) < 100 &&
224 LoadStringW(hApplet
, IDS_ERROR_NOT_FOUND
, szPath
, MAX_PATH
) < MAX_PATH
)
226 WCHAR szError
[MAX_PATH
+ 100];
228 _swprintf(szError
, szPath
, pContext
->szTarget
);
230 swprintf(szError
, szPath
, pContext
->szTarget
);
232 MessageBoxW(hwndDlg
, szError
, szDesc
, MB_ICONERROR
);
234 SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_LOCATION
, EM_SETSEL
, 0, -1);
235 SetFocus(GetDlgItem(hwndDlg
, IDC_SHORTCUT_LOCATION
));
236 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, PSNRET_INVALID_NOCHANGEPAGE
);
241 WCHAR
* first
, *last
;
242 wcscpy(pContext
->szWorkingDirectory
, pContext
->szTarget
);
243 first
= wcschr(pContext
->szWorkingDirectory
, L
'\\');
244 last
= wcsrchr(pContext
->szWorkingDirectory
, L
'\\');
245 wcscpy(pContext
->szDescription
, &last
[1]);
252 first
= wcsrchr(pContext
->szDescription
, L
'.');
266 FinishDlgProc(HWND hwndDlg
,
271 LPPROPSHEETPAGEW ppsp
;
272 PCREATE_LINK_CONTEXT pContext
;
278 ppsp
= (LPPROPSHEETPAGEW
)lParam
;
279 pContext
= (PCREATE_LINK_CONTEXT
) ppsp
->lParam
;
280 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pContext
);
281 SendDlgItemMessageW(hwndDlg
, IDC_SHORTCUT_NAME
, WM_SETTEXT
, 0, (LPARAM
)pContext
->szDescription
);
282 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
285 switch(HIWORD(wParam
))
288 if (SendDlgItemMessage(hwndDlg
, IDC_SHORTCUT_NAME
, WM_GETTEXTLENGTH
, 0, 0))
290 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
294 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
300 lppsn
= (LPPSHNOTIFY
) lParam
;
301 pContext
= (PCREATE_LINK_CONTEXT
) GetWindowLongPtr(hwndDlg
, DWLP_USER
);
302 if (lppsn
->hdr
.code
== PSN_WIZFINISH
)
304 SendDlgItemMessageW(hwndDlg
, IDC_SHORTCUT_NAME
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pContext
->szDescription
);
305 wcscat(pContext
->szLinkName
, pContext
->szDescription
);
306 wcscat(pContext
->szLinkName
, L
".lnk");
307 if (!CreateShortcut(pContext
))
309 MessageBox(hwndDlg
, _T("Failed to create shortcut"), _T("Error"), MB_ICONERROR
);
319 ShowCreateShortcutWizard(HWND hwndCPl
, LPWSTR szPath
)
321 PROPSHEETHEADERW psh
;
322 HPROPSHEETPAGE ahpsp
[2];
328 PCREATE_LINK_CONTEXT pContext
= (PCREATE_LINK_CONTEXT
) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CREATE_LINK_CONTEXT
));
334 nLength
= wcslen(szPath
);
337 HeapFree(GetProcessHeap(), 0, pContext
);
339 /* no directory given */
343 attrs
= GetFileAttributesW(szPath
);
344 if (attrs
== INVALID_FILE_ATTRIBUTES
)
346 HeapFree(GetProcessHeap(), 0, pContext
);
352 wcscpy(pContext
->szLinkName
, szPath
);
353 if (pContext
->szLinkName
[nLength
-1] != L
'\\')
355 pContext
->szLinkName
[nLength
] = L
'\\';
356 pContext
->szLinkName
[nLength
+1] = L
'\0';
360 /* Create the Welcome page */
361 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
362 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
363 psp
.hInstance
= hApplet
;
364 psp
.pfnDlgProc
= WelcomeDlgProc
;
365 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SHORTCUT_LOCATION
);
366 psp
.lParam
= (LPARAM
)pContext
;
367 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
369 /* Create the Finish page */
370 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
371 psp
.pfnDlgProc
= FinishDlgProc
;
372 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SHORTCUT_FINISH
);
373 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
376 /* Create the property sheet */
377 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
378 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
;
379 psh
.hInstance
= hApplet
;
380 psh
.hwndParent
= NULL
;
384 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
386 /* Display the wizard */
388 HeapFree(GetProcessHeap(), 0, pContext
);
395 NewLinkHere(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
397 WCHAR szFile
[MAX_PATH
];
399 if (MultiByteToWideChar(CP_ACP
, 0, (LPSTR
) lParam1
, -1, szFile
, MAX_PATH
))
401 return ShowCreateShortcutWizard(hwndCPl
, szFile
);
409 NewLinkHereW(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
411 return ShowCreateShortcutWizard(hwndCPl
, (LPWSTR
) lParam1
);
416 NewLinkHereA(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
418 WCHAR szFile
[MAX_PATH
];
420 if (MultiByteToWideChar(CP_ACP
, 0, (LPSTR
) lParam1
, -1, szFile
, MAX_PATH
))
422 return ShowCreateShortcutWizard(hwndCPl
, szFile
);