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.

467 lines
14 KiB

  1. /*
  2. * GIZMOBAR.C
  3. * GizmoBar Version 1.00, Win32 version August 1993
  4. *
  5. * Contains the main window procedure of the GizmoBar control
  6. * that handles mouse logic and Windows messages.
  7. *
  8. * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9. *
  10. * Kraig Brockschmidt, Software Design Engineer
  11. * Microsoft Systems Developer Relations
  12. *
  13. * Internet : kraigb@microsoft.com
  14. * Compuserve: >INTERNET:kraigb@microsoft.com
  15. */
  16. #include <windows.h>
  17. #include "gizmoint.h"
  18. /*
  19. * GizmoBarWndProc
  20. *
  21. * Purpose:
  22. * Window Procedure for the GizmoBar custom control. Handles all
  23. * messages like WM_PAINT just as a normal application window would.
  24. * Any message not processed here should go to DefWindowProc.
  25. *
  26. * Parameters:
  27. * Standard
  28. *
  29. * Return Value:
  30. * Standard
  31. */
  32. LRESULT FAR PASCAL GizmoBarWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  33. {
  34. BOOL fSuccess;
  35. BOOL fTemp;
  36. LPCREATESTRUCT pCreate;
  37. LPGIZMOBAR pGB;
  38. LPGIZMO pGizmo;
  39. RECT rc;
  40. POINT pt;
  41. short x, y;
  42. COLORREF cr;
  43. COMMANDPARAMS(wID, wCode, hWndMsg);
  44. pGB=(LPGIZMOBAR)GetWindowLong(hWnd, GBWL_STRUCTURE);
  45. //Pass control messages onto another function for processing.
  46. if (iMsg >= WM_USER)
  47. return GBMessageHandler(hWnd, iMsg, wParam, lParam, pGB);
  48. switch (iMsg)
  49. {
  50. case WM_NCCREATE:
  51. pCreate=(LPCREATESTRUCT)lParam;
  52. pGB=GizmoBarPAllocate((LPINT)&fSuccess, hWnd, pCreate->hInstance
  53. , pCreate->hwndParent, pCreate->style, 0
  54. , (UINT)pCreate->hMenu);
  55. if (!fSuccess)
  56. {
  57. GizmoBarPFree(pGB);
  58. return -1L;
  59. }
  60. else
  61. SetWindowLong(hWnd, GBWL_STRUCTURE, (LONG)pGB);
  62. return DefWindowProc(hWnd, iMsg, wParam, lParam);
  63. case WM_DESTROY:
  64. /*
  65. * We want to clean up before DestroyWindow nukes all the
  66. * children, so WM_DESTROY is a better to do it than
  67. * WM_NCDESTROY.
  68. */
  69. GizmoBarPFree(pGB);
  70. break;
  71. case WM_ERASEBKGND:
  72. /*
  73. * Eat this message to avoid erasing portions that
  74. * we are going to repaint in WM_PAINT. Part of a
  75. * change-state-and-repaint strategy is to rely on
  76. * WM_PAINT to do anything visual, which includes
  77. * erasing invalid portions. Letting WM_ERASEBKGND
  78. * erase the background is redundant.
  79. */
  80. return TRUE;
  81. #ifdef WIN32
  82. case WM_CTLCOLORBTN:
  83. case WM_CTLCOLORSTATIC:
  84. fTemp=TRUE;
  85. #else
  86. case WM_CTLCOLOR:
  87. //Change the color of static text on the GizmoBar.
  88. fTemp=(HIWORD(lParam)==CTLCOLOR_STATIC
  89. || HIWORD(lParam)==CTLCOLOR_BTN);
  90. #endif
  91. if (fTemp)
  92. {
  93. cr=GetSysColor(COLOR_BTNFACE);
  94. SetTextColor((HDC)wParam, GetSysColor(COLOR_BTNTEXT));
  95. SetBkColor((HDC)wParam, cr);
  96. /*
  97. * If the system colors have changed, then crFace will
  98. * not be equal to COLOR_BTNFACE, so we reinitialize the
  99. * background brush. This scheme handles system color
  100. * changes appropriately without processing WM_WININICHANGE
  101. * and without blindly creating a new brush on every
  102. * WM_CTLCOLOR message.
  103. */
  104. if (cr!=pGB->crFace)
  105. {
  106. pGB->crFace=cr;
  107. if (NULL!=pGB->hBrFace)
  108. DeleteObject(pGB->hBrFace);
  109. pGB->hBrFace=CreateSolidBrush(pGB->crFace);
  110. }
  111. return (LONG)(UINT)pGB->hBrFace;
  112. }
  113. return DefWindowProc(hWnd, iMsg, wParam, lParam);
  114. case WM_PAINT:
  115. GizmoBarPaint(hWnd, pGB);
  116. break;
  117. case WM_SETFONT:
  118. /*
  119. * wParam has the new font that we now send to all other
  120. * windows controls in us. We control repaints here to
  121. * prevent a lot of repainting for each control.
  122. */
  123. DefWindowProc(hWnd, WM_SETREDRAW, FALSE, 0L);
  124. if ((WPARAM)NULL!=wParam)
  125. {
  126. pGB->hFont=(HFONT)wParam;
  127. GizmoPEnum(&pGB->pGizmos, FEnumChangeFont, (DWORD)(LPSTR)pGB);
  128. DefWindowProc(hWnd, WM_SETREDRAW, TRUE, 0L);
  129. InvalidateRect(hWnd, NULL, FALSE);
  130. UpdateWindow(hWnd);
  131. }
  132. break;
  133. case WM_GETFONT:
  134. return (LRESULT)(UINT)pGB->hFont;
  135. case WM_ENABLE:
  136. /*
  137. * wParam has the new enable flag that we use to enable
  138. * or disable ALL controls in us at one time. We also turn
  139. * the redraw off to prevent a lot of flicker.
  140. */
  141. DefWindowProc(hWnd, WM_SETREDRAW, FALSE, 0L);
  142. pGB->fEnabled=(BOOL)wParam;
  143. GizmoPEnum(&pGB->pGizmos, FEnumEnable, (DWORD)(LPSTR)pGB);
  144. DefWindowProc(hWnd, WM_SETREDRAW, TRUE, 0L);
  145. InvalidateRect(hWnd, NULL, FALSE);
  146. UpdateWindow(hWnd);
  147. break;
  148. case WM_CANCELMODE:
  149. pGizmo=pGB->pGizmoTrack;
  150. pGB->fTracking=FALSE;
  151. pGB->fMouseOut=FALSE;
  152. if (NULL!=pGizmo)
  153. GizmoPStateSet(hWnd, pGizmo, COMMANDBUTTON_UP);
  154. ReleaseCapture();
  155. break;
  156. case WM_LBUTTONDBLCLK:
  157. case WM_LBUTTONDOWN:
  158. //Get the mouse coordinates.
  159. x=LOWORD(lParam);
  160. y=HIWORD(lParam);
  161. /*
  162. * See if we hit a command or attribute gizmo or not. Anything
  163. * else that is a control will get the message instead of
  164. * us anyway, so we don't have to check. FEnumHitTest also
  165. * validates drawn gizmos, enabled, and visible, so we don't.
  166. */
  167. pGizmo=GizmoPEnum(&pGB->pGizmos, FEnumHitTest, lParam);
  168. if (NULL==pGizmo)
  169. break; //Didn't hit one matching our needs.
  170. /*
  171. * Inform the associate that a command was hit like a menu item.
  172. */
  173. if (NULL!=pGB->hWndAssociate)
  174. {
  175. if (pGizmo->fNotify)
  176. SendMenuSelect(pGB->hWndAssociate, pGizmo->uID, 0, 0);
  177. }
  178. /*
  179. * We hit a button. If it's a command or attribute, then change
  180. * the state and start tracking.
  181. */
  182. pGB->fTracking=TRUE;
  183. pGB->pGizmoTrack=pGizmo;
  184. pGB->fMouseOut=FALSE;
  185. SetCapture(hWnd);
  186. pGizmo->uStateOrg=pGizmo->uState;
  187. GizmoPStateSet(hWnd, pGizmo, ATTRIBUTEBUTTON_MOUSEDOWN);
  188. break;
  189. case WM_MOUSEMOVE:
  190. POINTFROMLPARAM(pt, lParam);
  191. if (!pGB->fTracking)
  192. break;
  193. pGizmo=pGB->pGizmoTrack;
  194. SetRect(&rc, pGizmo->x, pGizmo->y, pGizmo->x+pGizmo->dx, pGizmo->y+pGizmo->dy);
  195. fTemp=pGB->fMouseOut;
  196. pGB->fMouseOut=!PtInRect(&rc, pt);
  197. //If the mouse went out, change state to the original.
  198. if (!fTemp && pGB->fMouseOut)
  199. {
  200. GizmoPStateSet(hWnd, pGizmo, pGizmo->uStateOrg);
  201. if (NULL!=pGB->hWndAssociate)
  202. {
  203. //Notify that we left the button
  204. if (pGizmo->fNotify)
  205. SendMenuSelect(pGB->hWndAssociate, 0x0000, 0xFFFF, 0);
  206. }
  207. }
  208. if (fTemp && !pGB->fMouseOut)
  209. {
  210. GizmoPStateSet(hWnd, pGizmo, ATTRIBUTEBUTTON_MOUSEDOWN);
  211. if (NULL!=pGB->hWndAssociate)
  212. {
  213. //Notify that we pressed down again
  214. if (pGizmo->fNotify)
  215. SendMenuSelect(pGB->hWndAssociate, pGizmo->uID, 0x0000, 0);
  216. }
  217. }
  218. break;
  219. case WM_LBUTTONUP:
  220. if (!pGB->fTracking)
  221. break;
  222. pGB->fTracking=FALSE;
  223. pGizmo=pGB->pGizmoTrack;
  224. ReleaseCapture();
  225. /*
  226. * Repaint if we were actually below the mouse when this
  227. * occurred. For command buttons, pop the button up. For
  228. * attributes, either toggle the state (inclusive buttons)
  229. * or check the selected one (exclusive buttons).
  230. */
  231. if (!pGB->fMouseOut)
  232. {
  233. //Command buttons always come up.
  234. if (GIZMOTYPE_BUTTONCOMMAND==pGizmo->iType)
  235. GizmoPStateSet(hWnd, pGizmo, COMMANDBUTTON_UP);
  236. //Attribute inclusive buttons toggle
  237. if (GIZMOTYPE_BUTTONATTRIBUTEIN==pGizmo->iType)
  238. GizmoPCheck(hWnd, pGizmo, !(BUTTONGROUP_DOWN & pGizmo->uStateOrg));
  239. //Attribure exclusive buttons are always checked.
  240. if (GIZMOTYPE_BUTTONATTRIBUTEEX==pGizmo->iType)
  241. GizmoPCheck(hWnd, pGizmo, TRUE);
  242. //Only send messages if notify is ON.
  243. if (NULL!=pGB->hWndAssociate && pGizmo->fNotify)
  244. {
  245. SendMenuSelect(pGB->hWndAssociate, 0, 0xFFFF, 0);
  246. SendCommand(pGB->hWndAssociate, pGizmo->uID, BN_CLICKED, hWnd);
  247. }
  248. }
  249. break;
  250. case WM_COMMAND:
  251. //Pass control messages on if the gizmo's notify is ON.
  252. if (NULL!=pGB->hWndAssociate)
  253. {
  254. pGizmo=PGizmoFromHwndID(hWnd, wID);
  255. if (NULL!=pGizmo)
  256. {
  257. if (pGizmo->fNotify)
  258. SendMessage(pGB->hWndAssociate, iMsg, wParam, lParam);
  259. }
  260. }
  261. break;
  262. default:
  263. return DefWindowProc(hWnd, iMsg, wParam, lParam);
  264. }
  265. return 0L;
  266. }
  267. /*
  268. * FEnumChangeFont
  269. *
  270. * Purpose:
  271. * Enumeration callback for all the gizmos we know about in order to
  272. * send a new font to them that's stored in LPGIZMOBAR in dw.
  273. *
  274. * Parameters:
  275. * pGizmo LPGIZMO to draw.
  276. * iGizmo UINT index on the GizmoBar of this gizmo.
  277. * dw DWORD extra data passed to GizmoPEnum, in our case
  278. * the GizmoBar's pGB.
  279. *
  280. * Return Value:
  281. * BOOL TRUE to continue the enumeration, FALSE otherwise.
  282. */
  283. BOOL FAR PASCAL FEnumChangeFont(LPGIZMO pGizmo, UINT iGizmo, DWORD dw)
  284. {
  285. LPGIZMOBAR pGB=(LPGIZMOBAR)dw;
  286. //We only need to change fonts in windowed controls using WM_SETFONT
  287. if (NULL!=pGizmo->hWnd)
  288. SendMessage(pGizmo->hWnd, WM_SETFONT, (WPARAM)pGB->hFont, 1L);
  289. return TRUE;
  290. }
  291. /*
  292. * FEnumEnable
  293. *
  294. * Purpose:
  295. * Enumeration callback for all the gizmos we know about in order to
  296. * enable or disable them from the WM_ENABLE message.
  297. *
  298. * Parameters:
  299. * pGizmo LPGIZMO to draw.
  300. * iGizmo UINT index on the GizmoBar of this gizmo.
  301. * dw DWORD extra data passed to GizmoPEnum, in our case
  302. * the GizmoBar's pGB.
  303. *
  304. * Return Value:
  305. * BOOL TRUE to continue the enumeration, FALSE otherwise.
  306. */
  307. BOOL FAR PASCAL FEnumEnable(LPGIZMO pGizmo, UINT iGizmo, DWORD dw)
  308. {
  309. LPGIZMOBAR pGB=(LPGIZMOBAR)dw;
  310. BOOL fEnable=pGB->fEnabled;
  311. //NOTE: This code is duplicated in GBGizmoEnable in API.C
  312. if (NULL!=pGizmo->hWnd)
  313. EnableWindow(pGizmo->hWnd, fEnable);
  314. else
  315. {
  316. //If we're not down, command and attribute buttons act the same.
  317. if (!(BUTTONGROUP_DOWN & pGizmo->uState))
  318. {
  319. GizmoPStateSet(pGB->hWnd, pGizmo
  320. , fEnable ? COMMANDBUTTON_UP : COMMANDBUTTON_DISABLED);
  321. }
  322. else
  323. {
  324. //Attribute buttons are a little more sensitive with DOWNDISABLED
  325. GizmoPStateSet(pGB->hWnd, pGizmo
  326. , fEnable ? ATTRIBUTEBUTTON_DOWN : ATTRIBUTEBUTTON_DOWNDISABLED);
  327. }
  328. }
  329. return TRUE;
  330. }
  331. /*
  332. * FEnumHitTest
  333. *
  334. * Purpose:
  335. * Enumeration callback for all the gizmos we know about in order to
  336. * hit-test them.
  337. *
  338. * Parameters:
  339. * pGizmo LPGIZMO to draw.
  340. * iGizmo UINT index on the GizmoBar of this gizmo.
  341. * dw DWORD extra data passed to GizmoPEnum, in our case
  342. * the hDC on which to draw.
  343. *
  344. * Return Value:
  345. * BOOL TRUE to continue the enumeration, FALSE otherwise.
  346. */
  347. BOOL FAR PASCAL FEnumHitTest(LPGIZMO pGizmo, UINT iGizmo, DWORD dw)
  348. {
  349. RECT rc;
  350. POINT pt;
  351. POINTFROMLPARAM(pt, dw);
  352. //Hit tests have to happen on visible, enabled, and drawn controls only.
  353. if (GIZMOTYPE_DRAWN & pGizmo->iType
  354. && !pGizmo->fHidden && !(BUTTONGROUP_DISABLED & pGizmo->uState))
  355. {
  356. SetRect(&rc, pGizmo->x, pGizmo->y
  357. , pGizmo->x+pGizmo->dx, pGizmo->y+pGizmo->dy);
  358. //Stop enumeration if we have a hit.
  359. return !PtInRect(&rc, pt);
  360. }
  361. return TRUE;
  362. }