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.

294 lines
7.3 KiB

  1. #include "bands.h"
  2. #define DM_PERSIST 0 // trace IPS::Load, ::Save, etc.
  3. #define DM_MENU 0 // menu code
  4. #define DM_FOCUS 0 // focus
  5. #define DM_FOCUS2 0 // like DM_FOCUS, but verbose
  6. //=================================================================
  7. // Implementation of CToolBand
  8. //=================================================================
  9. ULONG CToolBand::AddRef()
  10. {
  11. _cRef++;
  12. return _cRef;
  13. }
  14. ULONG CToolBand::Release()
  15. {
  16. ASSERT(_cRef > 0);
  17. _cRef--;
  18. if (_cRef > 0)
  19. return _cRef;
  20. delete this;
  21. return 0;
  22. }
  23. HRESULT CToolBand::QueryInterface(REFIID riid, void **ppvObj)
  24. {
  25. static const QITAB qit[] =
  26. {
  27. QITABENT(CToolBand, IDeskBand), // IID_IDeskBand
  28. QITABENTMULTI(CToolBand, IOleWindow, IDeskBand), // IID_IOleWindod
  29. QITABENTMULTI(CToolBand, IDockingWindow, IDeskBand), // IID_IDockingWindow
  30. QITABENT(CToolBand, IInputObject), // IID_IInputObject
  31. QITABENT(CToolBand, IOleCommandTarget), // IID_IOleCommandTarget
  32. QITABENT(CToolBand, IServiceProvider), // IID_IServiceProvider
  33. QITABENT(CToolBand, IPersistStream), // IID_IPersistStream
  34. QITABENTMULTI(CToolBand, IPersist, IPersistStream), // IID_IPersist
  35. QITABENT(CToolBand, IObjectWithSite), // IID_IObjectWithSite
  36. { 0 },
  37. };
  38. return QISearch(this, qit, riid, ppvObj);
  39. }
  40. // *** IOleCommandTarget methods ***
  41. HRESULT CToolBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pcmdtext)
  42. {
  43. return E_NOTIMPL;
  44. }
  45. HRESULT CToolBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
  46. {
  47. return E_NOTIMPL;
  48. }
  49. // *** IServiceProvider methods ***
  50. HRESULT CToolBand::QueryService(REFGUID guidService,
  51. REFIID riid, void **ppvObj)
  52. {
  53. return IUnknown_QueryService(_punkSite, guidService, riid, ppvObj);
  54. }
  55. // *** IOleWindow methods ***
  56. HRESULT CToolBand::GetWindow(HWND * lphwnd)
  57. {
  58. *lphwnd = _hwnd;
  59. if (*lphwnd)
  60. return S_OK;
  61. return E_FAIL;
  62. }
  63. // *** IInputObject methods ***
  64. HRESULT CToolBand::TranslateAcceleratorIO(LPMSG lpMsg)
  65. {
  66. return E_NOTIMPL;
  67. }
  68. HRESULT CToolBand::HasFocusIO()
  69. {
  70. HRESULT hres;
  71. HWND hwndFocus = GetFocus();
  72. hres = SHIsChildOrSelf(_hwnd, hwndFocus);
  73. ASSERT(hwndFocus != NULL || hres == S_FALSE);
  74. ASSERT(_hwnd != NULL || hres == S_FALSE);
  75. return hres;
  76. }
  77. HRESULT CToolBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
  78. {
  79. ASSERT(NULL == lpMsg || IS_VALID_WRITE_PTR(lpMsg, MSG));
  80. TraceMsg(DM_FOCUS, "ctb.uiaio(fActivate=%d) _fCanFocus=%d _hwnd=%x GF()=%x", fActivate, _fCanFocus, _hwnd, GetFocus());
  81. if (!_fCanFocus) {
  82. TraceMsg(DM_FOCUS, "ctb.uiaio: !_fCanFocus ret S_FALSE");
  83. return S_FALSE;
  84. }
  85. if (fActivate)
  86. {
  87. IUnknown_OnFocusChangeIS(_punkSite, SAFECAST(this, IInputObject*), TRUE);
  88. SetFocus(_hwnd);
  89. }
  90. return S_OK;
  91. }
  92. HRESULT CToolBand::ResizeBorderDW(LPCRECT prcBorder,
  93. IUnknown* punkToolbarSite,
  94. BOOL fReserved)
  95. {
  96. return S_OK;
  97. }
  98. HRESULT CToolBand::ShowDW(BOOL fShow)
  99. {
  100. return S_OK;
  101. }
  102. HRESULT CToolBand::SetSite(IUnknown *punkSite)
  103. {
  104. if (punkSite != _punkSite)
  105. {
  106. IUnknown_Set(&_punkSite, punkSite);
  107. IUnknown_GetWindow(_punkSite, &_hwndParent);
  108. }
  109. return S_OK;
  110. }
  111. HRESULT CToolBand::_BandInfoChanged()
  112. {
  113. VARIANTARG v = {0};
  114. VARIANTARG* pv = NULL;
  115. if (_dwBandID != (DWORD)-1)
  116. {
  117. v.vt = VT_I4;
  118. v.lVal = _dwBandID;
  119. pv = &v;
  120. }
  121. return IUnknown_Exec(_punkSite, &CGID_DeskBand, DBID_BANDINFOCHANGED, 0, pv, NULL);
  122. }
  123. // *** IPersistStream methods ***
  124. HRESULT CToolBand::IsDirty(void)
  125. {
  126. return S_FALSE; // never be dirty
  127. }
  128. HRESULT CToolBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
  129. {
  130. return E_NOTIMPL;
  131. }
  132. CToolBand::CToolBand() : _cRef(1)
  133. {
  134. _dwBandID = (DWORD)-1;
  135. DllAddRef();
  136. }
  137. CToolBand::~CToolBand()
  138. {
  139. ASSERT(_hwnd == NULL); // CloseDW was called
  140. ASSERT(_punkSite == NULL); // SetSite(NULL) was called
  141. DllRelease();
  142. }
  143. HRESULT CToolBand::CloseDW(DWORD dw)
  144. {
  145. if (_hwnd)
  146. {
  147. DestroyWindow(_hwnd);
  148. _hwnd = NULL;
  149. }
  150. return S_OK;
  151. }
  152. //=================================================================
  153. // Implementation of CToolbarBand
  154. //=================================================================
  155. // Class for bands whose _hwnd is a toolbar control. Implements
  156. // functionality generic to all such bands (e.g. hottracking
  157. // behavior).
  158. //=================================================================
  159. HRESULT CToolbarBand::_PushChevron(BOOL bLast)
  160. {
  161. if (_dwBandID == (DWORD)-1)
  162. return E_UNEXPECTED;
  163. VARIANTARG v;
  164. v.vt = VT_I4;
  165. v.lVal = bLast ? DBPC_SELECTLAST : DBPC_SELECTFIRST;
  166. return IUnknown_Exec(_punkSite, &CGID_DeskBand, DBID_PUSHCHEVRON, _dwBandID, &v, NULL);
  167. }
  168. LRESULT CToolbarBand::_OnHotItemChange(LPNMTBHOTITEM pnmtb)
  169. {
  170. LRESULT lres = 0;
  171. if (!(pnmtb->dwFlags & (HICF_LEAVING | HICF_MOUSE)))
  172. {
  173. // check to see if new hot button is clipped. if it is,
  174. // then we pop down the chevron menu.
  175. RECT rc;
  176. GetClientRect(_hwnd, &rc);
  177. int iButton = (int)SendMessage(_hwnd, TB_COMMANDTOINDEX, pnmtb->idNew, 0);
  178. DWORD dwEdge = SHIsButtonObscured(_hwnd, &rc, iButton);
  179. if (dwEdge)
  180. {
  181. //
  182. // Only pop down the menu if the button is obscured
  183. // along the axis of the toolbar
  184. //
  185. BOOL fVertical = (ToolBar_GetStyle(_hwnd) & CCS_VERT);
  186. if ((fVertical && (dwEdge & (EDGE_TOP | EDGE_BOTTOM)))
  187. || (!fVertical && (dwEdge & (EDGE_LEFT | EDGE_RIGHT))))
  188. {
  189. // clear hot item
  190. SendMessage(_hwnd, TB_SETHOTITEM, -1, 0);
  191. // figure out whether to highlight first or last button in dd menu
  192. int cButtons = (int)SendMessage(_hwnd, TB_BUTTONCOUNT, 0, 0);
  193. BOOL bLast = (iButton == cButtons - 1);
  194. _PushChevron(bLast);
  195. lres = 1;
  196. }
  197. }
  198. }
  199. return lres;
  200. }
  201. LRESULT CToolbarBand::_OnNotify(LPNMHDR pnmh)
  202. {
  203. LRESULT lres = 0;
  204. switch (pnmh->code)
  205. {
  206. case TBN_HOTITEMCHANGE:
  207. lres = _OnHotItemChange((LPNMTBHOTITEM)pnmh);
  208. break;
  209. }
  210. return lres;
  211. }
  212. // *** IWinEventHandler methods ***
  213. HRESULT CToolbarBand::OnWinEvent(HWND hwnd, UINT dwMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres)
  214. {
  215. HRESULT hres = S_OK;
  216. switch (dwMsg)
  217. {
  218. case WM_NOTIFY:
  219. *plres = _OnNotify((LPNMHDR)lParam);
  220. break;
  221. case WM_WININICHANGE:
  222. InvalidateRect(_hwnd, NULL, TRUE);
  223. _BandInfoChanged();
  224. break;
  225. }
  226. return hres;
  227. }
  228. HRESULT CToolbarBand::IsWindowOwner(HWND hwnd)
  229. {
  230. if (hwnd == _hwnd)
  231. return S_OK;
  232. else
  233. return S_FALSE;
  234. }