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.

296 lines
8.1 KiB

  1. // File: floatbar.cpp
  2. #include "precomp.h"
  3. #include "global.h"
  4. #include "ConfRoom.h"
  5. #include "cmd.h"
  6. #include "FloatBar.h"
  7. #include "resource.h"
  8. #include "ConfPolicies.h"
  9. CFloatToolbar::CFloatToolbar(CConfRoom* pcr):
  10. m_pConfRoom (pcr),
  11. m_hwnd (NULL),
  12. m_hwndT (NULL),
  13. m_hBmp (NULL),
  14. m_fInPopup (FALSE)
  15. {
  16. TRACE_OUT(("Constructing CFloatToolbar"));
  17. }
  18. CFloatToolbar::~CFloatToolbar()
  19. {
  20. TRACE_OUT(("Destructing CFloatToolbar"));
  21. ASSERT(!m_fInPopup);
  22. if (NULL != m_hBmp)
  23. {
  24. ::DeleteObject(m_hBmp);
  25. }
  26. if (NULL != m_hwnd)
  27. {
  28. // bug 1450: don't destroy the window inside the notification,
  29. // instead, use PostMessage() to insure that we return from the
  30. // WM_NOTIFY message before the window is destroyed:
  31. ::PostMessage(m_hwnd, WM_CLOSE, 0L, 0L);
  32. // DestroyWindow(m_hwnd);
  33. }
  34. }
  35. /****************************************************************************
  36. *
  37. * CLASS: CFloatToolbar
  38. *
  39. * MEMBER: FloatWndProc(HWND, unsigned, WORD, LONG)
  40. *
  41. * PURPOSE:
  42. *
  43. ****************************************************************************/
  44. LRESULT CALLBACK CFloatToolbar::FloatWndProc(
  45. HWND hWnd, /* window handle */
  46. UINT message, /* type of message */
  47. WPARAM wParam, /* additional information */
  48. LPARAM lParam) /* additional information */
  49. {
  50. CFloatToolbar* pft;
  51. LPCREATESTRUCT lpcs;
  52. switch (message)
  53. {
  54. case WM_CREATE:
  55. {
  56. TRACE_OUT(("Float Window created"));
  57. lpcs = (LPCREATESTRUCT) lParam;
  58. pft = (CFloatToolbar*) lpcs->lpCreateParams;
  59. ASSERT(pft);
  60. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) pft);
  61. const COLORMAP MyColorMap[] =
  62. {
  63. {TOOLBAR_MASK_COLOR, ::GetSysColor(COLOR_BTNFACE)}, // bright grey
  64. {TOOLBAR_HIGHLIGHT_COLOR, ::GetSysColor(COLOR_BTNHIGHLIGHT)},// white
  65. };
  66. pft->m_hBmp = ::CreateMappedBitmap( GetInstanceHandle(),
  67. IDB_POPUPBAR,
  68. 0,
  69. (LPCOLORMAP) MyColorMap,
  70. 2);
  71. CConfRoom * pcr = GetConfRoom();
  72. BYTE bASState = (pcr && pcr->IsSharingAllowed()) ? TBSTATE_ENABLED : 0;
  73. BYTE bChatState = (pcr && pcr->IsChatAllowed()) ? TBSTATE_ENABLED : 0;
  74. BYTE bWBState = (pcr && pcr->IsNewWhiteboardAllowed()) ? TBSTATE_ENABLED : 0;
  75. BYTE bFTState = (pcr && pcr->IsFileTransferAllowed()) ? TBSTATE_ENABLED : 0;
  76. TBBUTTON tbFloatButtonAry[] =
  77. {
  78. { ShareBitmapIndex , ID_TB_SHARING , bASState, TBSTYLE_BUTTON, 0, -1 },
  79. { ChatBitmapIndex , ID_TB_CHAT , bChatState, TBSTYLE_BUTTON, 0, -1 },
  80. { WhiteboardBitmapIndex, ID_TB_NEWWHITEBOARD, bWBState, TBSTYLE_BUTTON, 0, -1 },
  81. { FTBitmapIndex , ID_TB_FILETRANSFER , bFTState, TBSTYLE_BUTTON, 0, -1 },
  82. } ;
  83. ASSERT(pft->m_pConfRoom);
  84. pft->m_hwndT = CreateToolbarEx(hWnd,
  85. WS_CHILD | WS_VISIBLE | CCS_NODIVIDER |
  86. TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_ADJUSTABLE,
  87. ID_FLOAT_TOOLBAR,
  88. NUM_FLOATBAR_TOOLBAR_BITMAPS,
  89. NULL, // no instance
  90. (UINT_PTR) pft->m_hBmp, // bitmap handle
  91. tbFloatButtonAry, // buttons
  92. ARRAY_ELEMENTS(tbFloatButtonAry),
  93. 16, 16, // button sizes
  94. 16, 16, // bitmap sizes
  95. sizeof(TBBUTTON));
  96. ASSERT(pft->m_hwndT);
  97. // Put buttons in the correct state:
  98. pft->UpdateButtons();
  99. // Make the toolbar control window active so we can insure we will get a
  100. // WM_ACTIVATE when the user clicks somewhere off the toolbar
  101. ::SetForegroundWindow(pft->m_hwndT);
  102. break;
  103. }
  104. case WM_ACTIVATE:
  105. {
  106. // Click outside the toolbar:
  107. pft = (CFloatToolbar*) ::GetWindowLongPtr(hWnd, GWLP_USERDATA);
  108. //
  109. // Kill the toolbar if we're not in the middle of handling the
  110. // popup menu with the list of apps to share. In that case,
  111. // activation will cancel menu mode and we'll get a chance to
  112. // kill ourselves after we come back.
  113. //
  114. // We don't want to because COMCTL32 will trash our heap. It
  115. // can't handle the toolbar window and structure going away
  116. // while processing a TBN_DROPDOWN notification. When we return
  117. // back it will try to use the now-freed window data.
  118. //
  119. // Yes, we post ourselves a WM_CLOSE on destroy, but with a
  120. // message box up or other things, this could easily be
  121. // processed long before menu processing returns.
  122. //
  123. if ((NULL != pft) &&
  124. (!pft->m_fInPopup) &&
  125. (NULL != pft->m_hwnd) &&
  126. (NULL != pft->m_hwndT))
  127. {
  128. // NULL out the object pointer:
  129. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, 0L);
  130. delete pft;
  131. }
  132. break;
  133. }
  134. case WM_NOTIFY:
  135. {
  136. // BUGBUG: Copied from CConfRoom : put this is a central location:
  137. LPNMHDR pnmh = (LPNMHDR) lParam;
  138. if (TTN_NEEDTEXT == pnmh->code)
  139. {
  140. LPTOOLTIPTEXT lpToolTipText = (LPTOOLTIPTEXT)lParam;
  141. if (0 == (TTF_IDISHWND & lpToolTipText->uFlags))
  142. {
  143. lpToolTipText->hinst = ::GetInstanceHandle();
  144. lpToolTipText->lpszText = (LPTSTR) lpToolTipText->hdr.idFrom;
  145. }
  146. }
  147. break;
  148. }
  149. case WM_COMMAND:
  150. {
  151. TRACE_OUT(("Float Window command wp=0x%x", wParam));
  152. pft = (CFloatToolbar*) ::GetWindowLongPtr(hWnd, GWLP_USERDATA);
  153. if (NULL != pft)
  154. {
  155. if (NULL != pft->m_pConfRoom)
  156. {
  157. ::PostMessage(pft->m_pConfRoom->GetTopHwnd(), WM_COMMAND,
  158. wParam, lParam);
  159. }
  160. //
  161. // If we're in the middle of the popup, don't kill ourself.
  162. // We wait until the stack unwinds back above.
  163. //
  164. if (!pft->m_fInPopup)
  165. {
  166. // Dismiss the floating toolbar window:
  167. // NULL out the object pointer:
  168. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, 0L);
  169. delete pft;
  170. }
  171. }
  172. break;
  173. }
  174. default:
  175. {
  176. return ::DefWindowProc(hWnd, message, wParam, lParam);
  177. }
  178. }
  179. return FALSE;
  180. }
  181. /****************************************************************************
  182. *
  183. * CLASS: CFloatToolbar
  184. *
  185. * MEMBER: Create(POINT ptClickPos)
  186. *
  187. * PURPOSE: Creates a floating toolbar window
  188. *
  189. ****************************************************************************/
  190. HWND CFloatToolbar::Create(POINT ptClickPos)
  191. {
  192. // BUGBUG: move these defines once the size is finalized
  193. static const int TOOLBAR_WIDTH = 6 + 23 * NUM_FLOATBAR_STANDARD_TOOLBAR_BUTTONS;
  194. static const int TOOLBAR_HEIGHT = 6 + 22 * 1;
  195. HWND hwndDesktop = GetDesktopWindow();
  196. RECT rctDesktop;
  197. if (NULL != hwndDesktop)
  198. {
  199. if (GetWindowRect(hwndDesktop, &rctDesktop))
  200. {
  201. // First attempt will be to center the toolbar horizontally
  202. // with respect to the mouse position and place it directly
  203. // above vertically.
  204. int xPos = ptClickPos.x - (TOOLBAR_WIDTH / 2);
  205. int yPos = ptClickPos.y - (TOOLBAR_HEIGHT);
  206. // If we are too high on the screen (the taskbar is probably
  207. // docked on top), then use the click position as the top of
  208. // where the toolbar will appear.
  209. if (yPos < 0)
  210. {
  211. yPos = ptClickPos.y;
  212. }
  213. // Repeat the same logic for the horizontal position
  214. if (xPos < 0)
  215. {
  216. xPos = ptClickPos.x;
  217. }
  218. // If the toolbar if off the screen to the right, then right-justify it
  219. if (xPos > (rctDesktop.right - TOOLBAR_WIDTH))
  220. {
  221. xPos = ptClickPos.x - TOOLBAR_WIDTH;
  222. }
  223. m_hwnd = CreateWindowEx(WS_EX_PALETTEWINDOW,
  224. g_szFloatWndClass,
  225. g_szEmpty,
  226. WS_POPUP | WS_VISIBLE | WS_DLGFRAME,
  227. xPos, yPos,
  228. TOOLBAR_WIDTH, TOOLBAR_HEIGHT,
  229. NULL,
  230. NULL,
  231. _Module.GetModuleInstance(),
  232. (LPVOID) this);
  233. return m_hwnd;
  234. }
  235. }
  236. // Something went wrong
  237. return NULL;
  238. }
  239. /****************************************************************************
  240. *
  241. * CLASS: CFloatToolbar
  242. *
  243. * MEMBER: UpdateButtons()
  244. *
  245. * PURPOSE: Puts the toolbar buttons in their correct state
  246. *
  247. ****************************************************************************/
  248. BOOL CFloatToolbar::UpdateButtons()
  249. {
  250. return TRUE;
  251. }