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.

175 lines
4.5 KiB

  1. // TaskSheet.cpp : Implementation of CTaskSheet
  2. #include "stdafx.h"
  3. #include "TaskUI.h"
  4. #include "TaskSheet.h"
  5. #include "propbag.h"
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CTaskSheet
  8. CTaskSheet::CTaskSheet(void)
  9. : m_pTaskFrame(NULL),
  10. m_pPropertyBag(NULL)
  11. {
  12. }
  13. CTaskSheet::~CTaskSheet(void)
  14. {
  15. ATOMICRELEASE(m_pTaskFrame);
  16. ATOMICRELEASE(m_pPropertyBag);
  17. }
  18. //
  19. // Retrieve an interface to the sheet's property bag.
  20. // If the bag doesn't yet exist, one is created.
  21. // NOTE, this is not currently thread-safe.
  22. //
  23. STDMETHODIMP CTaskSheet::GetPropertyBag(REFIID riid, void **ppv)
  24. {
  25. if (ppv == NULL)
  26. return E_POINTER;
  27. if (NULL == m_pPropertyBag)
  28. {
  29. HRESULT hr = TaskUiPropertyBag_CreateInstance(IID_IPropertyBag, (void **)&m_pPropertyBag);
  30. if (FAILED(hr))
  31. return hr;
  32. }
  33. return m_pPropertyBag->QueryInterface(riid, ppv);
  34. }
  35. STDMETHODIMP CTaskSheet::Run(ITaskPageFactory *pPageFactory, REFCLSID rclsidStartPage, HWND hwndOwner)
  36. {
  37. HRESULT hr;
  38. BOOL bModeless;
  39. HWND hwndTopOwner;
  40. HWND hwndOriginalFocus;
  41. HWND hwndFrame;
  42. if (NULL == pPageFactory)
  43. return E_POINTER;
  44. if (CLSID_NULL == rclsidStartPage)
  45. return E_INVALIDARG;
  46. if (NULL != m_pTaskFrame)
  47. return E_UNEXPECTED;
  48. bModeless = FALSE; // default is modal
  49. hwndTopOwner = NULL;
  50. hwndOriginalFocus = NULL;
  51. CComPtr<IPropertyBag> pPropertyBag;
  52. hr = GetPropertyBag(IID_IPropertyBag, (void **)&pPropertyBag);
  53. if (FAILED(hr))
  54. return hr;
  55. hr = CTaskFrame::CreateInstance(pPropertyBag, pPageFactory, &m_pTaskFrame);
  56. if (FAILED(hr))
  57. return hr;
  58. // Figure out whether we're modal or modeless
  59. CComVariant var;
  60. if (SUCCEEDED(pPropertyBag->Read(TS_PROP_MODELESS, &var, NULL)) &&
  61. SUCCEEDED(var.ChangeType(VT_BOOL)))
  62. {
  63. bModeless = (VARIANT_TRUE == var.boolVal);
  64. }
  65. if (!bModeless)
  66. {
  67. // Modal case: disable the toplevel parent of the owner window
  68. hwndTopOwner = hwndOwner;
  69. hwndOriginalFocus = GetFocus();
  70. if (hwndTopOwner)
  71. {
  72. while (GetWindowLongW(hwndTopOwner, GWL_STYLE) & WS_CHILD)
  73. hwndTopOwner = GetParent(hwndTopOwner);
  74. if (hwndOriginalFocus != hwndTopOwner && !IsChild(hwndTopOwner, hwndOriginalFocus))
  75. hwndOriginalFocus = NULL;
  76. //
  77. // If the window was the desktop window, then don't disable
  78. // it now and don't reenable it later.
  79. // Also, if the window was already disabled, then don't
  80. // enable it later.
  81. //
  82. if (hwndTopOwner == GetDesktopWindow() ||
  83. EnableWindow(hwndTopOwner, FALSE))
  84. {
  85. hwndTopOwner = NULL;
  86. }
  87. }
  88. }
  89. // Create the frame window
  90. hwndFrame = m_pTaskFrame->CreateFrameWindow(hwndOwner);
  91. if (hwndFrame)
  92. {
  93. hr = m_pTaskFrame->ShowPage(rclsidStartPage, FALSE);
  94. if (SUCCEEDED(hr))
  95. {
  96. ShowWindow(hwndFrame, SW_SHOW);
  97. UpdateWindow(hwndFrame);
  98. if (!bModeless)
  99. {
  100. // Modal case: pump messages
  101. MSG msg;
  102. while (IsWindow(hwndFrame) && GetMessageW(&msg, NULL, 0, 0) > 0)
  103. {
  104. //if (!IsDialogMessageW(hwndFrame, &msg))
  105. {
  106. TranslateMessage(&msg);
  107. DispatchMessageW(&msg);
  108. }
  109. }
  110. // Enable the owner prior to setting focus back to wherever
  111. // it was, since it may have been the owner that had focus.
  112. if (hwndTopOwner)
  113. {
  114. EnableWindow(hwndTopOwner, TRUE);
  115. hwndTopOwner = NULL;
  116. }
  117. if (hwndOriginalFocus && IsWindow(hwndOriginalFocus))
  118. SetFocus(hwndOriginalFocus);
  119. ATOMICRELEASE(m_pTaskFrame);
  120. }
  121. }
  122. }
  123. else
  124. {
  125. DWORD dwErr = GetLastError();
  126. hr = HRESULT_FROM_WIN32(dwErr);
  127. }
  128. // In case an error prevented us from re-enabling the owner above
  129. if (hwndTopOwner)
  130. EnableWindow(hwndTopOwner, TRUE);
  131. return hr;
  132. }
  133. STDMETHODIMP CTaskSheet::Close()
  134. {
  135. HRESULT hr;
  136. if (NULL == m_pTaskFrame)
  137. return E_UNEXPECTED;
  138. hr = m_pTaskFrame->Close();
  139. ATOMICRELEASE(m_pTaskFrame);
  140. return hr;
  141. }