Leaked source code of windows server 2003
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.

462 lines
10 KiB

  1. #include "shellprv.h"
  2. #include "apithk.h"
  3. #include "basebar.h"
  4. #define DBM_ONPOSRECTCHANGE (WM_USER)
  5. //*** CBaseBar::IDeskBar::* {
  6. //
  7. /*----------------------------------------------------------
  8. Purpose: IDeskBar::SetClient
  9. Usually the function that composes a bar/bandsite/band
  10. union is responsible for calling this method to inform
  11. the bar what the client (bandsite) is.
  12. */
  13. HRESULT CBaseBar::SetClient(IUnknown *punkChild)
  14. {
  15. if (_punkChild != NULL)
  16. {
  17. // 4, 3, 2, 1 Release
  18. _hwndChild = NULL;
  19. if (_pDBC)
  20. {
  21. // This must happen first, before _pWEH becomes NULL so cleanup
  22. // notifications can still go thru
  23. _pDBC->SetDeskBarSite(NULL);
  24. }
  25. ATOMICRELEASE(_pDBC);
  26. ATOMICRELEASE(_pWEH);
  27. ATOMICRELEASE(_punkChild);
  28. }
  29. _punkChild = punkChild;
  30. HRESULT hr = S_OK;
  31. if (_punkChild != NULL)
  32. {
  33. // 1, 2, 3, 4 QI/AddRef/etc.
  34. _punkChild->AddRef();
  35. if (!_hwnd)
  36. {
  37. _RegisterDeskBarClass();
  38. _CreateDeskBarWindow();
  39. if (!_hwnd)
  40. {
  41. return E_OUTOFMEMORY;
  42. }
  43. // can't do CBaseBar::_Initialize yet (haven't done SetSite yet)
  44. }
  45. hr = _punkChild->QueryInterface(IID_PPV_ARG(IWinEventHandler, &_pWEH));
  46. if (SUCCEEDED(hr))
  47. {
  48. hr = _punkChild->QueryInterface(IID_PPV_ARG(IDeskBarClient, &_pDBC));
  49. if (SUCCEEDED(hr))
  50. {
  51. // nothing to cache yet due to lazy CreateWindow
  52. hr = _pDBC->SetDeskBarSite(SAFECAST(this, IDeskBar*));
  53. IUnknown_GetWindow(_punkChild, &_hwndChild);
  54. }
  55. }
  56. }
  57. return hr;
  58. }
  59. HRESULT CBaseBar::GetClient(IUnknown **ppunk)
  60. {
  61. *ppunk = _punkChild;
  62. if (_punkChild)
  63. _punkChild->AddRef();
  64. return _punkChild ? S_OK : E_FAIL;
  65. }
  66. HRESULT CBaseBar::OnPosRectChangeDB(LPRECT prc)
  67. {
  68. _szChild.cx = RECTWIDTH(*prc);
  69. _szChild.cy = RECTHEIGHT(*prc);
  70. // We can't change our size right away because we haven't returned from processing
  71. // this WM_SIZE message. If we resize right now, USER gets confused...
  72. //
  73. // We cannot use PeekMessage to determine if there is already a pending
  74. // DBM_ONPOSRECTCHANGE because that allows incoming SendMessage's to
  75. // arrive, and then we can get into a bad recursive situation when there
  76. // are a lot of SHChangeNotify's arriving in rapid succession.
  77. //
  78. if (!_fPosRectChangePending)
  79. {
  80. _fPosRectChangePending = TRUE;
  81. PostMessage(_hwnd, DBM_ONPOSRECTCHANGE, 0, 0);
  82. }
  83. return S_OK;
  84. }
  85. // Derived classes are expected to implement this method and do something
  86. // interesting...
  87. void CBaseBar::_OnPostedPosRectChange()
  88. {
  89. }
  90. // }
  91. HRESULT CBaseBar::ShowDW(BOOL fShow)
  92. {
  93. fShow = BOOLIFY(fShow);
  94. if (BOOLIFY(_fShow) == fShow)
  95. return S_OK;
  96. _fShow = fShow;
  97. if (_pDBC)
  98. return _pDBC->UIActivateDBC(fShow ? DBC_SHOW : DBC_HIDE);
  99. else
  100. return E_UNEXPECTED;
  101. }
  102. void CBaseBar::_OnCreate()
  103. {
  104. SendMessage(_hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, 0), 0);
  105. }
  106. LRESULT CBaseBar::_OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam)
  107. {
  108. LRESULT lres = 0;
  109. _CheckForwardWinEvent(uMsg, wParam, lParam, &lres);
  110. return lres;
  111. }
  112. /***
  113. */
  114. LRESULT CBaseBar::v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  115. {
  116. LRESULT lres = 0;
  117. switch (uMsg) {
  118. case WM_CREATE:
  119. _OnCreate();
  120. break;
  121. case WM_COMMAND:
  122. return _OnCommand(uMsg, wParam, lParam);
  123. case WM_SIZE:
  124. _OnSize();
  125. break;
  126. case WM_NOTIFY:
  127. return _OnNotify(uMsg, wParam, lParam);
  128. case WM_SYSCOLORCHANGE:
  129. case WM_WININICHANGE:
  130. case WM_CONTEXTMENU:
  131. case WM_INITMENUPOPUP:
  132. case WM_MEASUREITEM:
  133. case WM_DRAWITEM:
  134. case WM_MENUCHAR:
  135. case WM_PALETTECHANGED:
  136. _CheckForwardWinEvent(uMsg, wParam, lParam, &lres);
  137. break;
  138. case DBM_ONPOSRECTCHANGE:
  139. _fPosRectChangePending = FALSE;
  140. _OnPostedPosRectChange();
  141. break;
  142. default:
  143. return DefWindowProcWrap(hwnd, uMsg, wParam, lParam);
  144. }
  145. return lres;
  146. }
  147. /***
  148. */
  149. CBaseBar::CBaseBar() : _cRef(1)
  150. {
  151. DllAddRef();
  152. }
  153. /***
  154. */
  155. CBaseBar::~CBaseBar()
  156. {
  157. // see Release, where we call virtuals (which can't be called from dtor)
  158. DllRelease();
  159. }
  160. /***
  161. */
  162. void CBaseBar::_RegisterDeskBarClass()
  163. {
  164. WNDCLASS wc = {0};
  165. wc.style = _GetClassStyle();
  166. wc.lpfnWndProc = s_WndProc;
  167. //wc.cbClsExtra = 0;
  168. wc.cbWndExtra = SIZEOF(CBaseBar*);
  169. wc.hInstance = HINST_THISDLL;
  170. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  171. wc.hbrBackground = (HBRUSH) (COLOR_3DFACE+1);
  172. //wc.lpszMenuName = NULL;
  173. wc.lpszClassName = TEXT("BaseBar");
  174. //wc.hIcon = NULL;
  175. SHRegisterClass(&wc);
  176. }
  177. DWORD CBaseBar::_GetExStyle()
  178. {
  179. return WS_EX_TOOLWINDOW;
  180. }
  181. DWORD CBaseBar::_GetClassStyle()
  182. {
  183. return 0;
  184. }
  185. void CBaseBar::_CreateDeskBarWindow()
  186. {
  187. // _hwnd is set in s_WndProc
  188. DWORD dwExStyle = _GetExStyle();
  189. dwExStyle |= IS_BIDI_LOCALIZED_SYSTEM() ? dwExStyleRTLMirrorWnd : 0L;
  190. HWND hwndDummy = CreateWindowEx(
  191. dwExStyle,
  192. TEXT("BaseBar"), NULL,
  193. _hwndSite ? WS_CHILD | WS_CLIPCHILDREN : WS_POPUP | WS_CLIPCHILDREN,
  194. 0,0,100,100,
  195. _hwndSite, NULL, HINST_THISDLL,
  196. (LPVOID)SAFECAST(this, CImpWndProc*));
  197. }
  198. void CBaseBar::_OnSize(void)
  199. {
  200. RECT rc;
  201. if (!_hwndChild)
  202. return;
  203. GetClientRect(_hwnd, &rc);
  204. SetWindowPos(_hwndChild, 0,
  205. rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc),
  206. SWP_NOACTIVATE|SWP_NOZORDER);
  207. }
  208. void CBaseBar::_NotifyModeChange(DWORD dwMode)
  209. {
  210. if (_pDBC) {
  211. _dwMode = dwMode;
  212. // FEATURE: should we add an STBBIF_VIEWMODE_FLOAT?
  213. _pDBC->SetModeDBC(_dwMode);
  214. }
  215. }
  216. BOOL CBaseBar::_CheckForwardWinEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres)
  217. {
  218. HWND hwnd = NULL;
  219. *plres = 0;
  220. switch (uMsg)
  221. {
  222. case WM_CONTEXTMENU:
  223. case WM_INITMENUPOPUP:
  224. case WM_MEASUREITEM:
  225. case WM_DRAWITEM:
  226. case WM_MENUCHAR:
  227. hwnd = _hwndChild;
  228. break;
  229. case WM_NOTIFY:
  230. hwnd = ((LPNMHDR)lParam)->hwndFrom;
  231. break;
  232. case WM_COMMAND:
  233. hwnd = GET_WM_COMMAND_HWND(wParam, lParam);
  234. break;
  235. case WM_SYSCOLORCHANGE:
  236. case WM_WININICHANGE:
  237. case WM_PALETTECHANGED:
  238. hwnd = _hwndChild;
  239. break;
  240. }
  241. if (hwnd && _pWEH && _pWEH->IsWindowOwner(hwnd) == S_OK)
  242. {
  243. _pWEH->OnWinEvent(_hwnd, uMsg, wParam, lParam, plres);
  244. return TRUE;
  245. }
  246. return FALSE;
  247. }
  248. /***
  249. */
  250. LRESULT CBaseBar::_OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
  251. {
  252. LRESULT lres = 0;
  253. _CheckForwardWinEvent(uMsg, wParam, lParam, &lres);
  254. return lres;
  255. }
  256. HRESULT CBaseBar::CloseDW(DWORD dwReserved)
  257. {
  258. SetClient(NULL);
  259. if (_hwnd) {
  260. DestroyWindow(_hwnd);
  261. _hwnd = NULL;
  262. }
  263. return S_OK;
  264. }
  265. HRESULT CBaseBar::QueryInterface(REFIID riid, LPVOID * ppvObj)
  266. {
  267. static const QITAB qit[] = {
  268. QITABENT(CBaseBar, IOleWindow),
  269. QITABENT(CBaseBar, IDeskBar),
  270. QITABENT(CBaseBar, IInputObject),
  271. QITABENT(CBaseBar, IInputObjectSite),
  272. QITABENT(CBaseBar, IServiceProvider),
  273. QITABENT(CBaseBar, IOleCommandTarget),
  274. { 0 },
  275. };
  276. return QISearch(this, (LPCQITAB)qit, riid, ppvObj);
  277. }
  278. ULONG CBaseBar::AddRef()
  279. {
  280. _cRef++;
  281. return _cRef;
  282. }
  283. ULONG CBaseBar::Release()
  284. {
  285. ASSERT(_cRef > 0);
  286. _cRef--;
  287. if (_cRef > 0)
  288. return _cRef;
  289. // 'virtual dtor'
  290. // gotta do virtual stuff here (not in dtor) because can't call
  291. // any virtuals in the dtor
  292. // CBaseBar::Destroy() {
  293. CloseDW(0);
  294. // }
  295. delete this;
  296. return 0;
  297. }
  298. //*** CBaseBar::IOleWindow::* {
  299. //
  300. HRESULT CBaseBar::GetWindow(HWND * lphwnd)
  301. {
  302. *lphwnd = _hwnd;
  303. return (_hwnd) ? S_OK : E_FAIL;
  304. }
  305. HRESULT CBaseBar::ContextSensitiveHelp(BOOL fEnterMode)
  306. {
  307. // FEATURE: Visit here later.
  308. return E_NOTIMPL;
  309. }
  310. // }
  311. // }
  312. // some helpers... {
  313. // What's the point of having
  314. // these empty implementations in the base class?
  315. //
  316. //*** CBaseBar::IServiceProvider::*
  317. //
  318. HRESULT CBaseBar::QueryService(REFGUID guidService,
  319. REFIID riid, void **ppvObj)
  320. {
  321. HRESULT hres = E_FAIL;
  322. *ppvObj = NULL;
  323. return hres;
  324. }
  325. //*** CBaseBar::IOleCommandTarget::*
  326. //
  327. HRESULT CBaseBar::QueryStatus(const GUID *pguidCmdGroup,
  328. ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pcmdtext)
  329. {
  330. return MayQSForward(_pDBC, OCTD_DOWN, pguidCmdGroup, cCmds, rgCmds, pcmdtext);
  331. }
  332. HRESULT CBaseBar::Exec(const GUID *pguidCmdGroup,
  333. DWORD nCmdID, DWORD nCmdexecopt,
  334. VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
  335. {
  336. return MayExecForward(_pDBC, OCTD_DOWN, pguidCmdGroup, nCmdID, nCmdexecopt,
  337. pvarargIn, pvarargOut);
  338. }
  339. // }
  340. //*** CDeskBar::IInputObject::* {
  341. HRESULT CBaseBar::HasFocusIO()
  342. {
  343. HRESULT hres;
  344. hres = IUnknown_HasFocusIO(_pDBC);
  345. return hres;
  346. }
  347. HRESULT CBaseBar::TranslateAcceleratorIO(LPMSG lpMsg)
  348. {
  349. HRESULT hres;
  350. hres = IUnknown_TranslateAcceleratorIO(_pDBC, lpMsg);
  351. return hres;
  352. }
  353. HRESULT CBaseBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
  354. {
  355. HRESULT hres;
  356. hres = IUnknown_UIActivateIO(_pDBC, fActivate, lpMsg);
  357. return hres;
  358. }
  359. // }
  360. //*** CDeskBar::IInputObjectSite::* {
  361. HRESULT CBaseBar::OnFocusChangeIS(IUnknown *punk, BOOL fSetFocus)
  362. {
  363. return NOERROR;
  364. }
  365. // }