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.

542 lines
16 KiB

  1. // AppsCtl.cpp : Implementation of the CAppsCtrl OLE control class.
  2. #include "stdafx.h"
  3. #include <iadmw.h>
  4. #include "cnfgprts.h"
  5. #include "AppsCtl.h"
  6. #include "AppsPpg.h"
  7. #include "AspDbgPg.h"
  8. #include "AspMnPg.h"
  9. #include "approcpg.h"
  10. #include "RecycleOptPage.h"
  11. #include "ListRow.h"
  12. #include "AppMapPg.h"
  13. #include "wrapmb.h"
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. IMPLEMENT_DYNCREATE(CAppsCtrl, COleControl)
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Message map
  22. BEGIN_MESSAGE_MAP(CAppsCtrl, COleControl)
  23. //{{AFX_MSG_MAP(CAppsCtrl)
  24. //}}AFX_MSG_MAP
  25. ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
  26. ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // Dispatch map
  30. BEGIN_DISPATCH_MAP(CAppsCtrl, COleControl)
  31. //{{AFX_DISPATCH_MAP(CAppsCtrl)
  32. DISP_FUNCTION(CAppsCtrl, "DeleteParameters", DeleteParameters, VT_EMPTY, VTS_NONE)
  33. DISP_FUNCTION(CAppsCtrl, "SetAdminTarget", SetAdminTarget, VT_EMPTY, VTS_BSTR VTS_BSTR VTS_BOOL)
  34. DISP_FUNCTION(CAppsCtrl, "SetShowProcOptions", SetShowProcOptions, VT_EMPTY, VTS_BOOL)
  35. DISP_FUNCTION(CAppsCtrl, "DeleteProcParameters", DeleteProcParameters, VT_EMPTY, VTS_NONE)
  36. DISP_STOCKFUNC_DOCLICK()
  37. DISP_STOCKPROP_BORDERSTYLE()
  38. DISP_STOCKPROP_CAPTION()
  39. DISP_STOCKPROP_ENABLED()
  40. DISP_STOCKPROP_FONT()
  41. //}}AFX_DISPATCH_MAP
  42. END_DISPATCH_MAP()
  43. /////////////////////////////////////////////////////////////////////////////
  44. // Event map
  45. BEGIN_EVENT_MAP(CAppsCtrl, COleControl)
  46. //{{AFX_EVENT_MAP(CAppsCtrl)
  47. EVENT_STOCK_CLICK()
  48. EVENT_STOCK_KEYUP()
  49. //}}AFX_EVENT_MAP
  50. END_EVENT_MAP()
  51. /////////////////////////////////////////////////////////////////////////////
  52. // Property pages
  53. BEGIN_PROPPAGEIDS(CAppsCtrl, 2)
  54. PROPPAGEID(CAppsPropPage::guid)
  55. PROPPAGEID(CLSID_CFontPropPage)
  56. END_PROPPAGEIDS(CAppsCtrl)
  57. /////////////////////////////////////////////////////////////////////////////
  58. // Initialize class factory and guid
  59. IMPLEMENT_OLECREATE_EX(CAppsCtrl, "CNFGPRTS.AppsCtrl.1",
  60. 0xba63460b, 0xb771, 0x11d0, 0x92, 0x96, 0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b)
  61. /////////////////////////////////////////////////////////////////////////////
  62. // Type library ID and version
  63. IMPLEMENT_OLETYPELIB(CAppsCtrl, _tlid, _wVerMajor, _wVerMinor)
  64. /////////////////////////////////////////////////////////////////////////////
  65. // Interface IDs
  66. const IID BASED_CODE IID_DApps =
  67. { 0xba634609, 0xb771, 0x11d0, { 0x92, 0x96, 0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b } };
  68. const IID BASED_CODE IID_DAppsEvents =
  69. { 0xba63460a, 0xb771, 0x11d0, { 0x92, 0x96, 0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b } };
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Control type information
  72. static const DWORD BASED_CODE _dwAppsOleMisc =
  73. OLEMISC_ACTIVATEWHENVISIBLE |
  74. OLEMISC_SETCLIENTSITEFIRST |
  75. OLEMISC_INSIDEOUT |
  76. OLEMISC_CANTLINKINSIDE |
  77. OLEMISC_ACTSLIKEBUTTON |
  78. OLEMISC_RECOMPOSEONRESIZE;
  79. IMPLEMENT_OLECTLTYPE(CAppsCtrl, IDS_APPS, _dwAppsOleMisc)
  80. /////////////////////////////////////////////////////////////////////////////
  81. // CAppsCtrl::CAppsCtrlFactory::UpdateRegistry -
  82. // Adds or removes system registry entries for CAppsCtrl
  83. BOOL CAppsCtrl::CAppsCtrlFactory::UpdateRegistry(BOOL bRegister)
  84. {
  85. // TODO: Verify that your control follows apartment-model threading rules.
  86. // Refer to MFC TechNote 64 for more information.
  87. // If your control does not conform to the apartment-model rules, then
  88. // you must modify the code below, changing the 6th parameter from
  89. // afxRegApartmentThreading to 0.
  90. if (bRegister)
  91. return AfxOleRegisterControlClass(
  92. AfxGetInstanceHandle(),
  93. m_clsid,
  94. m_lpszProgID,
  95. IDS_APPS,
  96. IDB_APPS,
  97. afxRegApartmentThreading,
  98. _dwAppsOleMisc,
  99. _tlid,
  100. _wVerMajor,
  101. _wVerMinor);
  102. else
  103. return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  104. }
  105. /////////////////////////////////////////////////////////////////////////////
  106. // CAppsCtrl::CAppsCtrl - Constructor
  107. CAppsCtrl::CAppsCtrl():
  108. m_fUpdateFont( FALSE ),
  109. m_fLocalMachine( FALSE ),
  110. m_fShowProcOptions( FALSE ),
  111. m_hAccel( NULL ),
  112. m_cAccel( 0 )
  113. {
  114. InitializeIIDs(&IID_DApps, &IID_DAppsEvents);
  115. }
  116. /////////////////////////////////////////////////////////////////////////////
  117. // CAppsCtrl::~CAppsCtrl - Destructor
  118. CAppsCtrl::~CAppsCtrl()
  119. {
  120. if ( m_hAccel )
  121. DestroyAcceleratorTable( m_hAccel );
  122. m_hAccel = NULL;
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. // CAppsCtrl::OnDraw - Drawing function
  126. void CAppsCtrl::OnDraw(
  127. CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  128. {
  129. DoSuperclassPaint(pdc, rcBounds);
  130. }
  131. /////////////////////////////////////////////////////////////////////////////
  132. // CAppsCtrl::DoPropExchange - Persistence support
  133. void CAppsCtrl::DoPropExchange(CPropExchange* pPX)
  134. {
  135. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  136. COleControl::DoPropExchange(pPX);
  137. }
  138. /////////////////////////////////////////////////////////////////////////////
  139. // CAppsCtrl::OnResetState - Reset control to default state
  140. void CAppsCtrl::OnResetState()
  141. {
  142. COleControl::OnResetState(); // Resets defaults found in DoPropExchange
  143. }
  144. /////////////////////////////////////////////////////////////////////////////
  145. // CAppsCtrl::PreCreateWindow - Modify parameters for CreateWindowEx
  146. BOOL CAppsCtrl::PreCreateWindow(CREATESTRUCT& cs)
  147. {
  148. if ( cs.style & WS_CLIPSIBLINGS )
  149. cs.style ^= WS_CLIPSIBLINGS;
  150. cs.lpszClass = _T("BUTTON");
  151. return COleControl::PreCreateWindow(cs);
  152. }
  153. /////////////////////////////////////////////////////////////////////////////
  154. // CAppsCtrl::IsSubclassedControl - This is a subclassed control
  155. BOOL CAppsCtrl::IsSubclassedControl()
  156. {
  157. return TRUE;
  158. }
  159. /////////////////////////////////////////////////////////////////////////////
  160. // CAppsCtrl::OnOcmCommand - Handle command messages
  161. LRESULT CAppsCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
  162. {
  163. #ifdef _WIN32
  164. WORD wNotifyCode = HIWORD(wParam);
  165. #else
  166. WORD wNotifyCode = HIWORD(lParam);
  167. #endif
  168. return 0;
  169. }
  170. /////////////////////////////////////////////////////////////////////////////
  171. // CAppsCtrl message handlers
  172. //---------------------------------------------------------------------------
  173. void CAppsCtrl::OnClick(USHORT iButton)
  174. {
  175. CWaitCursor wait;
  176. // in case there are any errors, prepare the error string
  177. CString sz;
  178. // set the name of the application correctly
  179. sz.LoadString( IDS_APP_ERR_TITLE );
  180. // free the existing name, and copy in the new one
  181. free((void*)AfxGetApp()->m_pszAppName);
  182. AfxGetApp()->m_pszAppName = _tcsdup(sz);
  183. // initialize the metabase wrappings - pass in the name of the target machine
  184. // if one has been specified
  185. IMSAdminBase* pMB = FInitMetabaseWrapper( (LPTSTR)(LPCTSTR)m_szMachine );
  186. if ( !pMB )
  187. {
  188. MessageBeep(0);
  189. return;
  190. }
  191. // if there is no set metabase path - give it a test path
  192. if ( m_szMetaObject.IsEmpty() )
  193. m_szMetaObject = _T("/lm/w3svc/1/Root/iisadmin");
  194. // pointers to the pages
  195. CAppMapPage pageMap;
  196. CRecycleOptPage pageRecycle;
  197. CAppAspMainPage pageASPMain;
  198. CAppAspDebugPage pageASPDebug;
  199. CAppProcPage pageProc;
  200. // declare the property sheet
  201. CPropertySheet propsheet( IDS_APP_SHEETTITLE );
  202. // set up the metabase com pointer
  203. pageMap.m_pMB = pMB;
  204. pageASPMain.m_pMB = pMB;
  205. pageASPDebug.m_pMB = pMB;
  206. pageProc.m_pMB = pMB;
  207. // prepare the pages
  208. pageMap.m_szMeta = m_szMetaObject;
  209. pageASPMain.m_szMeta = m_szMetaObject;
  210. pageASPDebug.m_szMeta = m_szMetaObject;
  211. pageProc.m_szMeta = m_szMetaObject;
  212. // prepare the server name
  213. pageMap.m_szServer = m_szMachine;
  214. pageASPMain.m_szServer = m_szMachine;
  215. pageASPDebug.m_szServer = m_szMachine;
  216. pageProc.m_szServer = m_szMachine;
  217. // set the local machine for the script mappings
  218. pageMap.m_fLocalMachine = m_fLocalMachine;
  219. // add the pages to the sheet
  220. propsheet.AddPage( &pageMap );
  221. propsheet.AddPage( &pageRecycle );
  222. propsheet.AddPage( &pageASPMain );
  223. // only show the proc page if it is appropriate
  224. if ( m_fShowProcOptions )
  225. propsheet.AddPage( &pageProc );
  226. // finish added the pages to the sheet
  227. propsheet.AddPage( &pageASPDebug );
  228. // turn on help
  229. propsheet.m_psh.dwFlags |= PSH_HASHELP;
  230. pageMap.m_psp.dwFlags |= PSP_HASHELP;
  231. pageASPMain.m_psp.dwFlags |= PSP_HASHELP;
  232. pageASPDebug.m_psp.dwFlags |= PSP_HASHELP;
  233. pageProc.m_psp.dwFlags |= PSP_HASHELP;
  234. // Things could (potentially maybe) throw here, so better protect it.
  235. try
  236. {
  237. // run the propdsheet dialog
  238. // let the host container know that we are putting up a modal dialog
  239. PreModalDialog();
  240. // run the dialog
  241. propsheet.DoModal();
  242. // let the host container know we are done with the modality
  243. PostModalDialog();
  244. }
  245. catch ( CException e )
  246. {
  247. }
  248. // close the metabase wrappings
  249. FCloseMetabaseWrapper(pMB);
  250. // don't fire anything off
  251. COleControl::OnClick(iButton);
  252. }
  253. //---------------------------------------------------------------------------
  254. void CAppsCtrl::OnFontChanged()
  255. {
  256. m_fUpdateFont = TRUE;
  257. COleControl::OnFontChanged();
  258. }
  259. //---------------------------------------------------------------------------
  260. // The thing about applications is that if one gets stopped, we should blow away
  261. // all of that applications parameters
  262. void CAppsCtrl::DeleteParameters()
  263. {
  264. CWaitCursor wait;
  265. // initialize the metabase wrappings - pass in the name of the target machine
  266. // if one has been specified
  267. IMSAdminBase* pMB = FInitMetabaseWrapper( (LPTSTR)(LPCTSTR)m_szMachine );
  268. if ( !pMB )
  269. {
  270. MessageBeep(0);
  271. return;
  272. }
  273. // pointers to the pages (construction may throw, so we need to be careful)
  274. CAppMapPage pageMap;
  275. CAppAspMainPage pageASPMain;
  276. CAppAspDebugPage pageASPDebug;
  277. CAppProcPage pageProc;
  278. // set up the metabase com pointer
  279. pageMap.m_pMB = pMB;
  280. pageASPMain.m_pMB = pMB;
  281. pageASPDebug.m_pMB = pMB;
  282. pageProc.m_pMB = pMB;
  283. // prepare the pages
  284. pageMap.m_szMeta = m_szMetaObject;
  285. pageASPMain.m_szMeta = m_szMetaObject;
  286. pageASPDebug.m_szMeta = m_szMetaObject;
  287. pageProc.m_szMeta = m_szMetaObject;
  288. // tell each page to blow away its parameters
  289. pageMap.BlowAwayParameters();
  290. pageASPMain.BlowAwayParameters();
  291. pageASPDebug.BlowAwayParameters();
  292. pageProc.BlowAwayParameters();
  293. // close the metabase wrappings
  294. FCloseMetabaseWrapper(pMB);
  295. }
  296. //---------------------------------------------------------------------------
  297. void CAppsCtrl::SetAdminTarget(LPCTSTR szMachineName, LPCTSTR szMetaTarget, BOOL fLocalMachine)
  298. {
  299. m_szMachine = szMachineName;
  300. m_szMetaObject = szMetaTarget;
  301. m_fLocalMachine = fLocalMachine;
  302. }
  303. //---------------------------------------------------------------------------
  304. void CAppsCtrl::SetShowProcOptions(BOOL fShowProcOptions)
  305. {
  306. m_fShowProcOptions = fShowProcOptions;
  307. }
  308. //---------------------------------------------------------------------------
  309. // delete just the process level parameters in the metabase. This is used when
  310. // the use has done editing as if it is an out-of-proc application, then changed
  311. // their mind and made it in proc. If this wasn't called then there would be extra
  312. // things in the metabase messing up inheritance, yet they would not be reflected
  313. // anywhere in the UI. This should never be called on the master properites.
  314. void CAppsCtrl::DeleteProcParameters()
  315. {
  316. CWaitCursor wait;
  317. // initialize the metabase wrappings - pass in the name of the target machine
  318. // if one has been specified
  319. IMSAdminBase* pMB = FInitMetabaseWrapper( (LPTSTR)(LPCTSTR)m_szMachine );
  320. if ( !pMB )
  321. {
  322. MessageBeep(0);
  323. return;
  324. }
  325. // pointers to the pages (construction may throw, so we need to be careful)
  326. CAppProcPage pageProc;
  327. // set up the metabase com pointer
  328. pageProc.m_pMB = pMB;
  329. // prepare the pages
  330. pageProc.m_szMeta = m_szMetaObject;
  331. // tell each page to blow away its parameters
  332. pageProc.BlowAwayParameters();
  333. // close the metabase wrappings
  334. FCloseMetabaseWrapper(pMB);
  335. }
  336. //---------------------------------------------------------------------------
  337. void CAppsCtrl::OnAmbientPropertyChange(DISPID dispid)
  338. {
  339. BOOL flag;
  340. UINT style;
  341. // do the right thing depending on the dispid
  342. switch ( dispid )
  343. {
  344. case DISPID_AMBIENT_DISPLAYASDEFAULT:
  345. if ( GetAmbientProperty( DISPID_AMBIENT_DISPLAYASDEFAULT, VT_BOOL, &flag ) )
  346. {
  347. style = GetWindowLong(
  348. GetSafeHwnd(), // handle of window
  349. GWL_STYLE // offset of value to retrieve
  350. );
  351. if ( flag )
  352. style |= BS_DEFPUSHBUTTON;
  353. else
  354. style ^= BS_DEFPUSHBUTTON;
  355. SetWindowLong(
  356. GetSafeHwnd(), // handle of window
  357. GWL_STYLE, // offset of value to retrieve
  358. style
  359. );
  360. Invalidate(TRUE);
  361. }
  362. break;
  363. };
  364. COleControl::OnAmbientPropertyChange(dispid);
  365. }
  366. //---------------------------------------------------------------------------
  367. // an important method where we tell the container how to deal with us.
  368. // pControlInfo is passed in by the container, although we are responsible
  369. // for maintining the hAccel structure
  370. void CAppsCtrl::OnGetControlInfo(LPCONTROLINFO pControlInfo)
  371. {
  372. // do a rudimentary check to see if we understand pControlInfo
  373. if ( !pControlInfo || pControlInfo->cb < sizeof(CONTROLINFO) )
  374. return;
  375. // set the accelerator handle into place
  376. pControlInfo->hAccel = m_hAccel;
  377. pControlInfo->cAccel = m_cAccel;
  378. // when we have focus, we do want the enter key
  379. pControlInfo->dwFlags = CTRLINFO_EATS_RETURN;
  380. }
  381. //---------------------------------------------------------------------------
  382. // the ole control container object specifically filters out the space
  383. // key so we do not get it as a OnMnemonic call. Thus we need to look
  384. // for it ourselves
  385. void CAppsCtrl::OnKeyUpEvent(USHORT nChar, USHORT nShiftState)
  386. {
  387. if ( nChar == _T(' ') )
  388. {
  389. OnClick((USHORT)GetDlgCtrlID());
  390. }
  391. COleControl::OnKeyUpEvent(nChar, nShiftState);
  392. }
  393. //---------------------------------------------------------------------------
  394. void CAppsCtrl::OnMnemonic(LPMSG pMsg)
  395. {
  396. OnClick((USHORT)GetDlgCtrlID());
  397. COleControl::OnMnemonic(pMsg);
  398. }
  399. //---------------------------------------------------------------------------
  400. void CAppsCtrl::OnTextChanged()
  401. {
  402. ACCEL accel;
  403. int iAccel;
  404. // get the new text
  405. CString sz = InternalGetText();
  406. sz.MakeLower();
  407. // if the handle has already been allocated, free it
  408. if ( m_hAccel )
  409. {
  410. DestroyAcceleratorTable( m_hAccel );
  411. m_hAccel = NULL;
  412. m_cAccel = 0;
  413. }
  414. // if there is a & character, then declare the accelerator
  415. iAccel = sz.Find(_T('&'));
  416. if ( iAccel >= 0 )
  417. {
  418. // fill in the accererator record
  419. accel.fVirt = FALT;
  420. accel.key = sz.GetAt(iAccel + 1);
  421. accel.cmd = (USHORT)GetDlgCtrlID();
  422. m_hAccel = CreateAcceleratorTable( &accel, 1 );
  423. if ( m_hAccel )
  424. m_cAccel = 1;
  425. // make sure the new accelerator table gets loaded
  426. ControlInfoChanged();
  427. }
  428. // finish with the default handling.
  429. COleControl::OnTextChanged();
  430. }