Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

384 lines
12 KiB

  1. #include "stdafx.h"
  2. #include "netplace.h"
  3. #include "pubwiz.h"
  4. #pragma hdrstop
  5. // add net place wizard (v2)
  6. class CAddNetPlace : IWizardSite, IServiceProvider
  7. {
  8. public:
  9. CAddNetPlace();
  10. ~CAddNetPlace();
  11. void _ShowAddNetPlace();
  12. // IUnknown
  13. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
  14. STDMETHOD_(ULONG,AddRef)(void);
  15. STDMETHOD_(ULONG,Release)(void);
  16. // IWizardSite
  17. STDMETHODIMP GetPreviousPage(HPROPSHEETPAGE *phPage);
  18. STDMETHODIMP GetNextPage(HPROPSHEETPAGE *phPage);
  19. STDMETHODIMP GetCancelledPage(HPROPSHEETPAGE *phPage)
  20. { return E_NOTIMPL; }
  21. // IServiceProvider
  22. STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv);
  23. private:
  24. // dialog handlers
  25. static CAddNetPlace* s_GetANP(HWND hwnd, UINT uMsg, LPARAM lParam);
  26. static INT_PTR s_WelcomeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  27. { CAddNetPlace *panp = s_GetANP(hwnd, uMsg, lParam); return panp->_WelcomeDlgProc(hwnd, uMsg, wParam, lParam); }
  28. static INT_PTR s_DoneDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  29. { CAddNetPlace *panp = s_GetANP(hwnd, uMsg, lParam); return panp->_DoneDlgProc(hwnd, uMsg, wParam, lParam); }
  30. INT_PTR _WelcomeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  31. INT_PTR _DoneDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  32. HWND _hwndFrame;
  33. LONG _cRef;
  34. IPublishingWizard *_ppw; // publishing wizard object
  35. IResourceMap *_prm; // our resource map object
  36. CNetworkPlace _np;
  37. };
  38. // Construction/destruction
  39. CAddNetPlace::CAddNetPlace() :
  40. _cRef(1)
  41. {
  42. DllAddRef();
  43. }
  44. CAddNetPlace::~CAddNetPlace()
  45. {
  46. DllRelease();
  47. }
  48. // Reference counting of the object
  49. ULONG CAddNetPlace::AddRef()
  50. {
  51. return InterlockedIncrement(&_cRef);
  52. }
  53. ULONG CAddNetPlace::Release()
  54. {
  55. if (InterlockedDecrement(&_cRef))
  56. return _cRef;
  57. delete this;
  58. return 0;
  59. }
  60. HRESULT CAddNetPlace::QueryInterface(REFIID riid, void **ppv)
  61. {
  62. static const QITAB qit[] =
  63. {
  64. QITABENT(CAddNetPlace, IWizardSite), // IID_IWizardSite
  65. QITABENT(CAddNetPlace, IServiceProvider), // IID_IServiceProvider
  66. {0, 0 },
  67. };
  68. return QISearch(this, qit, riid, ppv);
  69. }
  70. // Helper functions
  71. CAddNetPlace* CAddNetPlace::s_GetANP(HWND hwnd, UINT uMsg, LPARAM lParam)
  72. {
  73. if (uMsg == WM_INITDIALOG)
  74. {
  75. PROPSHEETPAGE *ppsp = (PROPSHEETPAGE*)lParam;
  76. SetWindowLongPtr(hwnd, GWLP_USERDATA, ppsp->lParam);
  77. return (CAddNetPlace*)ppsp->lParam;
  78. }
  79. return (CAddNetPlace*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  80. }
  81. // Welcome/Intro dialog
  82. INT_PTR CAddNetPlace::_WelcomeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  83. {
  84. switch (uMsg)
  85. {
  86. case WM_INITDIALOG:
  87. {
  88. _hwndFrame = GetParent(hwnd);
  89. SendDlgItemMessage(hwnd, IDC_PUB_WELCOME, WM_SETFONT, (WPARAM)GetIntroFont(hwnd), 0);
  90. IXMLDOMNode *pdn;
  91. HRESULT hr = _prm->SelectResourceScope(TEXT("dialog"), TEXT("welcome"), &pdn);
  92. if (SUCCEEDED(hr))
  93. {
  94. TCHAR szBuffer[1024];
  95. _prm->LoadString(pdn, TEXT("caption"), szBuffer, ARRAYSIZE(szBuffer));
  96. SetDlgItemText(hwnd, IDC_PUB_WELCOME, szBuffer);
  97. _prm->LoadString(pdn, TEXT("description"), szBuffer, ARRAYSIZE(szBuffer));
  98. SetDlgItemText(hwnd, IDC_PUB_WELCOMEPROMPT, szBuffer);
  99. pdn->Release();
  100. }
  101. return TRUE;
  102. }
  103. case WM_NOTIFY:
  104. {
  105. LPNMHDR pnmh = (LPNMHDR)lParam;
  106. switch (pnmh->code)
  107. {
  108. case PSN_SETACTIVE:
  109. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_NEXT);
  110. return TRUE;
  111. case PSN_WIZNEXT:
  112. {
  113. HPROPSHEETPAGE hpage;
  114. if (SUCCEEDED(_ppw->GetFirstPage(&hpage)))
  115. {
  116. PropSheet_SetCurSel(GetParent(hwnd), hpage, -1);
  117. }
  118. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LPARAM)-1);
  119. return TRUE;
  120. }
  121. }
  122. break;
  123. }
  124. }
  125. return FALSE;
  126. }
  127. // Were done, so lets create the link etc.
  128. INT_PTR CAddNetPlace::_DoneDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  129. {
  130. switch ( uMsg )
  131. {
  132. case WM_INITDIALOG:
  133. SendDlgItemMessage(hwnd, IDC_PUB_DONE, WM_SETFONT, (WPARAM)GetIntroFont(hwnd), 0);
  134. return TRUE;
  135. case WM_NOTIFY:
  136. {
  137. LPNMHDR pnmh = (LPNMHDR)lParam;
  138. switch (pnmh->code)
  139. {
  140. case NM_CLICK:
  141. case NM_RETURN:
  142. if (pnmh->idFrom == IDC_PUB_COMPLETEMSG)
  143. {
  144. _np.CreatePlace(hwnd, TRUE);
  145. return TRUE;
  146. }
  147. break;
  148. case PSN_SETACTIVE:
  149. {
  150. TCHAR szTemp[INTERNET_MAX_URL_LENGTH] = {0};
  151. TCHAR szBuffer[MAX_PATH+INTERNET_MAX_URL_LENGTH];
  152. // using the manifest lets work out where the net place was created to.
  153. IXMLDOMDocument *pdocManifest;
  154. HRESULT hr = _ppw->GetTransferManifest(NULL, &pdocManifest);
  155. if (SUCCEEDED(hr))
  156. {
  157. IXMLDOMNode *pdnUploadInfo;
  158. if (S_OK == pdocManifest->selectSingleNode(XPATH_UPLOADINFO, &pdnUploadInfo))
  159. {
  160. hr = GetURLFromElement(pdnUploadInfo, ELEMENT_TARGET, szTemp, ARRAYSIZE(szTemp));
  161. if (SUCCEEDED(hr))
  162. {
  163. // set the target so that we create the place
  164. _np.SetTarget(NULL, szTemp, NPTF_VALIDATE | NPTF_ALLOWWEBFOLDERS);
  165. IXMLDOMNode *pdnTarget;
  166. hr = pdocManifest->selectSingleNode(XPATH_UPLOADTARGET, &pdnTarget);
  167. if (hr == S_OK)
  168. {
  169. // get the user name (for the FTP case)
  170. if (SUCCEEDED(GetStrFromAttribute(pdnTarget, ATTRIBUTE_USERNAME, szBuffer, ARRAYSIZE(szBuffer))))
  171. _np.SetLoginInfo(szBuffer, NULL);
  172. // lets get the prefered display name, if this is not found then we will default to
  173. // using the name generated by the net places code.
  174. if (SUCCEEDED(GetStrFromAttribute(pdnUploadInfo, ATTRIBUTE_FRIENDLYNAME, szTemp, ARRAYSIZE(szTemp))))
  175. _np.SetName(NULL, szTemp);
  176. pdnTarget->Release();
  177. }
  178. }
  179. pdnUploadInfo->Release();
  180. }
  181. pdocManifest->Release();
  182. }
  183. // lets format up the text for the control.
  184. FormatMessageString(IDS_ANP_SUCCESS, szBuffer, ARRAYSIZE(szBuffer), szTemp);
  185. SetDlgItemText(hwnd, IDC_PUB_COMPLETEMSG, szBuffer);
  186. // lets move the controls accordingly
  187. UINT ctls[] = { IDC_PUB_OPENFILES };
  188. int dy = SizeControlFromText(hwnd, IDC_PUB_COMPLETEMSG, szBuffer);
  189. MoveControls(hwnd, ctls, ARRAYSIZE(ctls), 0, dy);
  190. // default to opening the place when the user closes this wizard.
  191. CheckDlgButton(hwnd, IDC_PUB_OPENFILES, TRUE);
  192. // were done.
  193. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_FINISH);
  194. return TRUE;
  195. }
  196. case PSN_WIZFINISH:
  197. {
  198. _np.CreatePlace(hwnd, (IsDlgButtonChecked(hwnd, IDC_PUB_OPENFILES) == BST_CHECKED));
  199. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LPARAM)FALSE);
  200. return TRUE;
  201. }
  202. }
  203. break;
  204. }
  205. }
  206. return FALSE;
  207. }
  208. // IServiceProvider
  209. STDMETHODIMP CAddNetPlace::QueryService(REFGUID guidService, REFIID riid, void **ppv)
  210. {
  211. if (guidService == SID_ResourceMap)
  212. return _prm->QueryInterface(riid, ppv);
  213. *ppv = NULL;
  214. return E_FAIL;
  215. }
  216. // Site object helpers, these allow nagivation back and forward in the wizard
  217. HRESULT CAddNetPlace::GetPreviousPage(HPROPSHEETPAGE *phPage)
  218. {
  219. int i = PropSheet_IdToIndex(_hwndFrame, IDD_PUB_WELCOME);
  220. *phPage = PropSheet_IndexToPage(_hwndFrame, i);
  221. return S_OK;
  222. }
  223. HRESULT CAddNetPlace::GetNextPage(HPROPSHEETPAGE *phPage)
  224. {
  225. int i = PropSheet_IdToIndex(_hwndFrame, IDD_ANP_DONE);
  226. *phPage = PropSheet_IndexToPage(_hwndFrame, i);
  227. return S_OK;
  228. }
  229. // main entry point which shows the wizard
  230. void CAddNetPlace::_ShowAddNetPlace()
  231. {
  232. struct
  233. {
  234. INT idPage;
  235. INT idHeading;
  236. INT idSubHeading;
  237. DWORD dwFlags;
  238. DLGPROC dlgproc;
  239. }
  240. c_wpPages[] =
  241. {
  242. {IDD_PUB_WELCOME, 0, 0, PSP_HIDEHEADER, CAddNetPlace::s_WelcomeDlgProc},
  243. {IDD_ANP_DONE, 0, 0, PSP_HIDEHEADER, CAddNetPlace::s_DoneDlgProc},
  244. };
  245. // create the page array, we add the welcome page and the finished page
  246. // the rest is loaded as an extension to the wizard.
  247. HPROPSHEETPAGE hpages[10] = { 0 };
  248. for (int i = 0; i < ARRAYSIZE(c_wpPages) ; i++ )
  249. {
  250. PROPSHEETPAGE psp = { 0 };
  251. psp.dwSize = SIZEOF(PROPSHEETPAGE);
  252. psp.hInstance = g_hinst;
  253. psp.lParam = (LPARAM)this;
  254. psp.dwFlags = PSP_USETITLE | PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE | c_wpPages[i].dwFlags;
  255. psp.pszTemplate = MAKEINTRESOURCE(c_wpPages[i].idPage);
  256. psp.pfnDlgProc = c_wpPages[i].dlgproc;
  257. psp.pszTitle = MAKEINTRESOURCE(IDS_ANP_CAPTION);
  258. psp.pszHeaderTitle = MAKEINTRESOURCE(c_wpPages[i].idHeading);
  259. psp.pszHeaderSubTitle = MAKEINTRESOURCE(c_wpPages[i].idSubHeading);
  260. hpages[i] = CreatePropertySheetPage(&psp);
  261. }
  262. // create the wizard extension (for publishing) and have it append its
  263. // pages, if that succeeds then lets show the wizard.
  264. HRESULT hr = CResourceMap_Initialize(L"res://netplwiz.dll/xml/resourcemap.xml", &_prm);
  265. if (SUCCEEDED(hr))
  266. {
  267. hr = _prm->LoadResourceMap(TEXT("wizard"), TEXT("AddNetPlace"));
  268. if (SUCCEEDED(hr))
  269. {
  270. hr = CoCreateInstance(CLSID_PublishingWizard, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IPublishingWizard, &_ppw));
  271. if (SUCCEEDED(hr))
  272. {
  273. hr = _ppw->Initialize(NULL, SHPWHF_NOFILESELECTOR|SHPWHF_VALIDATEVIAWEBFOLDERS, TEXT("AddNetPlace"));
  274. if (SUCCEEDED(hr))
  275. {
  276. IUnknown_SetSite(_ppw, SAFECAST(this, IWizardSite*)); // we are the site
  277. UINT nPages;
  278. hr = _ppw->AddPages(&hpages[i], ARRAYSIZE(hpages)-i, &nPages);
  279. if (SUCCEEDED(hr))
  280. {
  281. PROPSHEETHEADER psh = { 0 };
  282. psh.dwSize = SIZEOF(PROPSHEETHEADER);
  283. psh.hInstance = g_hinst;
  284. psh.dwFlags = PSH_WIZARD | PSH_WIZARD97 | PSH_WATERMARK | PSH_STRETCHWATERMARK | PSH_HEADER;
  285. psh.pszbmHeader = MAKEINTRESOURCE(IDB_ANP_BANNER);
  286. psh.pszbmWatermark = MAKEINTRESOURCE(IDB_ANP_WATERMARK);
  287. psh.phpage = hpages;
  288. psh.nPages = i+nPages;
  289. PropertySheetIcon(&psh, MAKEINTRESOURCE(IDI_ADDNETPLACE));
  290. }
  291. IUnknown_SetSite(_ppw, NULL);
  292. }
  293. _ppw->Release();
  294. }
  295. }
  296. _prm->Release();
  297. }
  298. }
  299. // RunDll entry point used by the world to access the Add Net Place wizard.
  300. void APIENTRY AddNetPlaceRunDll(HWND hwndStub, HINSTANCE hAppInstance, LPSTR pszCmdLine, int nCmdShow)
  301. {
  302. if (SUCCEEDED(CoInitialize(NULL)))
  303. {
  304. CAddNetPlace *panp = new CAddNetPlace;
  305. if (panp)
  306. {
  307. panp->_ShowAddNetPlace();
  308. panp->Release();
  309. }
  310. CoUninitialize();
  311. }
  312. }