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.

812 lines
19 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: buttons.c
  3. *
  4. * Bitmap button support. On Daytona bitmap buttons are provided by
  5. * mmcntrls. On Chicago there is no mmcntrls, so we use the functions
  6. * in this file.
  7. *
  8. *
  9. * Created: 19-04-94
  10. * Author: Stephen Estrop [StephenE]
  11. *
  12. * Copyright (c) 1993 Microsoft Corporation
  13. \**************************************************************************/
  14. #pragma warning( once : 4201 4214 )
  15. #define NOOLE
  16. #include <windows.h>
  17. #include <windowsx.h>
  18. #include <commctrl.h>
  19. #include "buttons.h"
  20. #include "literals.h"
  21. /* -------------------------------------------------------------------------
  22. ** Color globals
  23. ** -------------------------------------------------------------------------
  24. */
  25. int nSysColorChanges = 0;
  26. DWORD rgbFace;
  27. DWORD rgbShadow;
  28. DWORD rgbHilight;
  29. DWORD rgbFrame;
  30. /*****************************Private*Routine******************************\
  31. * PatB
  32. *
  33. * Fast way to fill an rectangle with a solid colour.
  34. *
  35. * History:
  36. * 18-11-93 - StephenE - Created
  37. *
  38. \**************************************************************************/
  39. void
  40. PatB(
  41. HDC hdc,
  42. int x,
  43. int y,
  44. int dx,
  45. int dy,
  46. DWORD rgb
  47. )
  48. {
  49. RECT rc;
  50. SetBkColor(hdc,rgb);
  51. rc.left = x;
  52. rc.top = y;
  53. rc.right = x + dx;
  54. rc.bottom = y + dy;
  55. ExtTextOut(hdc,0,0,ETO_OPAQUE,&rc,NULL,0,NULL);
  56. }
  57. /*****************************Private*Routine******************************\
  58. * CheckSysColors
  59. *
  60. * Checks the system colors and updates the cached global variables if
  61. * they have changed.
  62. *
  63. * History:
  64. * 18-11-93 - StephenE - Created
  65. *
  66. \**************************************************************************/
  67. void
  68. CheckSysColors(
  69. void
  70. )
  71. {
  72. static COLORREF rgbSaveFace = 0xffffffffL,
  73. rgbSaveShadow = 0xffffffffL,
  74. rgbSaveHilight = 0xffffffffL,
  75. rgbSaveFrame = 0xffffffffL;
  76. rgbFace = GetSysColor(COLOR_BTNFACE);
  77. rgbShadow = GetSysColor(COLOR_BTNSHADOW);
  78. rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
  79. rgbFrame = GetSysColor(COLOR_WINDOWFRAME);
  80. if (rgbSaveFace!=rgbFace || rgbSaveShadow!=rgbShadow
  81. || rgbSaveHilight!=rgbHilight || rgbSaveFrame!=rgbFrame)
  82. {
  83. ++nSysColorChanges;
  84. rgbSaveFace = rgbFace;
  85. rgbSaveShadow = rgbShadow;
  86. rgbSaveHilight = rgbHilight;
  87. rgbSaveFrame = rgbFrame;
  88. }
  89. }
  90. /* -------------------------------------------------------------------------
  91. ** Button globals -- some of these should be constants
  92. ** -------------------------------------------------------------------------
  93. */
  94. const TCHAR szBbmProp[] = TEXT("ButtonBitmapProp");
  95. const TCHAR szButtonProp[] = TEXT("ButtonProp");
  96. typedef struct tagBTNSTATE { /* instance data for toolbar window */
  97. WNDPROC lpfnDefProc;
  98. HWND hwndToolTips;
  99. HINSTANCE hInst;
  100. UINT wID;
  101. UINT uStyle;
  102. HBITMAP hbm;
  103. HDC hdcGlyphs;
  104. HDC hdcMono;
  105. HBITMAP hbmMono;
  106. HBITMAP hbmDefault;
  107. int dxBitmap;
  108. int dyBitmap;
  109. int nButtons;
  110. int nSysColorChanges;
  111. BITMAPBTN Buttons[1];
  112. } BTNSTATE, NEAR *PBTNSTATE, FAR *LPBTNSTATE;
  113. typedef struct {
  114. WNDPROC lpfnDefProc;
  115. HWND hwndParent;
  116. HWND hwndToolTips;
  117. } BTN_INFO, *LPBTN_INFO;
  118. LRESULT CALLBACK
  119. ButtonSubclassProc(
  120. HWND hwnd,
  121. UINT uMsg,
  122. WPARAM wParam,
  123. LPARAM lParam
  124. );
  125. LRESULT CALLBACK
  126. ParentSubclassProc(
  127. HWND hwnd,
  128. UINT uMsg,
  129. WPARAM wParam,
  130. LPARAM lParam
  131. );
  132. void FAR PASCAL
  133. RelayToToolTips(
  134. HWND hwndToolTips,
  135. HWND hWnd,
  136. UINT wMsg,
  137. WPARAM wParam,
  138. LPARAM lParam
  139. );
  140. BOOL
  141. InitObjects(
  142. LPBTNSTATE pTBState
  143. );
  144. BOOL
  145. FreeObjects(
  146. LPBTNSTATE pTBState
  147. );
  148. void
  149. CreateButtonMask(
  150. LPBTNSTATE pTBState,
  151. PBITMAPBTN pTBButton
  152. );
  153. /*****************************Private*Routine******************************\
  154. * InitObjects
  155. *
  156. *
  157. *
  158. * History:
  159. * 18-11-93 - StephenE - Created
  160. *
  161. \**************************************************************************/
  162. BOOL
  163. InitObjects(
  164. LPBTNSTATE pTBState
  165. )
  166. {
  167. pTBState->hdcGlyphs = CreateCompatibleDC(NULL);
  168. if (pTBState->hdcGlyphs == NULL ) {
  169. return FALSE;
  170. }
  171. pTBState->hdcMono = CreateCompatibleDC(NULL);
  172. if (pTBState->hdcMono == NULL ) {
  173. DeleteObject( pTBState->hdcGlyphs );
  174. return FALSE;
  175. }
  176. pTBState->hbmMono = CreateBitmap( pTBState->dxBitmap,
  177. pTBState->dyBitmap, 1, 1, NULL);
  178. if ( pTBState->hbmMono == NULL ) {
  179. DeleteObject( pTBState->hdcGlyphs );
  180. DeleteObject( pTBState->hdcMono );
  181. return FALSE;
  182. }
  183. pTBState->hbmDefault = SelectObject(pTBState->hdcMono, pTBState->hbmMono);
  184. return TRUE;
  185. }
  186. /*****************************Private*Routine******************************\
  187. * FreeObjects
  188. *
  189. *
  190. *
  191. * History:
  192. * 18-11-93 - StephenE - Created
  193. *
  194. \**************************************************************************/
  195. BOOL
  196. FreeObjects(
  197. LPBTNSTATE pTBState
  198. )
  199. {
  200. if (pTBState->hdcMono) {
  201. SelectObject(pTBState->hdcMono, pTBState->hbmDefault);
  202. DeleteDC(pTBState->hdcMono); /* toast the DCs */
  203. }
  204. if (pTBState->hdcGlyphs) {
  205. DeleteDC(pTBState->hdcGlyphs);
  206. }
  207. if (pTBState->hbmMono) {
  208. DeleteObject(pTBState->hbmMono);
  209. }
  210. return TRUE;
  211. }
  212. /*****************************Private*Routine******************************\
  213. * CreateButtonMask
  214. *
  215. * create a mono bitmap mask:
  216. * 1's where color == COLOR_BTNFACE || COLOR_HILIGHT
  217. * 0's everywhere else
  218. *
  219. *
  220. * History:
  221. * 18-11-93 - StephenE - Created
  222. *
  223. \**************************************************************************/
  224. void
  225. CreateButtonMask(
  226. LPBTNSTATE pTBState,
  227. PBITMAPBTN pTBButton
  228. )
  229. {
  230. /* initalize whole area with 0's */
  231. PatBlt( pTBState->hdcMono, 0, 0, pTBState->dxBitmap,
  232. pTBState->dyBitmap, WHITENESS);
  233. /* create mask based on color bitmap
  234. ** convert this to 1's
  235. */
  236. SetBkColor(pTBState->hdcGlyphs, rgbFace);
  237. BitBlt( pTBState->hdcMono, 0, 0, pTBState->dxBitmap, pTBState->dyBitmap,
  238. pTBState->hdcGlyphs, pTBButton->iBitmap * pTBState->dxBitmap, 0,
  239. SRCCOPY );
  240. /* convert this to 1's */
  241. SetBkColor(pTBState->hdcGlyphs, rgbHilight);
  242. /* OR in the new 1's */
  243. BitBlt( pTBState->hdcMono, 0, 0, pTBState->dxBitmap, pTBState->dyBitmap,
  244. pTBState->hdcGlyphs, pTBButton->iBitmap * pTBState->dxBitmap, 0,
  245. SRCPAINT );
  246. }
  247. #define PSDPxax 0x00B8074A
  248. /*****************************Private*Routine******************************\
  249. * BtnDrawButton
  250. *
  251. *
  252. *
  253. * History:
  254. * 18-11-93 - StephenE - Created
  255. *
  256. \**************************************************************************/
  257. void WINAPI
  258. BtnDrawButton(
  259. HWND hwnd,
  260. HDC hdc,
  261. int dx,
  262. int dy,
  263. LPBITMAPBTN ptButton
  264. )
  265. {
  266. int glyph_offset;
  267. HBRUSH hbrOld, hbr;
  268. BOOL bMaskCreated = FALSE;
  269. RECT rcFocus;
  270. PBTNSTATE pTBState;
  271. int x = 0, y = 0;
  272. pTBState = (PBTNSTATE)GetProp(hwnd, szBbmProp);
  273. CheckSysColors();
  274. if (pTBState->nSysColorChanges != nSysColorChanges) {
  275. DeleteObject( pTBState->hbm );
  276. pTBState->hbm = CreateMappedBitmap( pTBState->hInst,
  277. pTBState->wID, TRUE, NULL, 0);
  278. pTBState->nSysColorChanges = nSysColorChanges;
  279. }
  280. /*
  281. ** erase with face color
  282. */
  283. PatB(hdc, x, y, dx, dy, rgbFace);
  284. SetRect( &rcFocus, x, y, x + dx, y + dy );
  285. if (ptButton->fsState & BTNSTATE_PRESSED) {
  286. DrawEdge( hdc, &rcFocus, EDGE_SUNKEN, BF_RECT );
  287. glyph_offset = 1;
  288. }
  289. else {
  290. DrawEdge( hdc, &rcFocus, EDGE_RAISED, BF_RECT );
  291. glyph_offset = 0;
  292. }
  293. /*
  294. ** make the coordinates the interior of the button
  295. */
  296. x += 2;
  297. y += 2;
  298. dx -= 4;
  299. dy -= 4;
  300. SelectObject( pTBState->hdcGlyphs, pTBState->hbm );
  301. /* now put on the face */
  302. /*
  303. ** We need to centre the Bitmap here within the button
  304. */
  305. x += (dx - pTBState->dxBitmap ) / 2;
  306. y += (dy - pTBState->dyBitmap ) / 2;
  307. if (!(ptButton->fsState & BTNSTATE_DISABLED)) {
  308. /* regular version */
  309. BitBlt( hdc, x + glyph_offset, y + glyph_offset,
  310. pTBState->dxBitmap, pTBState->dyBitmap,
  311. pTBState->hdcGlyphs,
  312. ptButton->iBitmap * pTBState->dxBitmap, 0, SRCCOPY);
  313. }
  314. else {
  315. /* disabled version */
  316. bMaskCreated = TRUE;
  317. CreateButtonMask(pTBState, ptButton );
  318. SetTextColor(hdc, 0L); /* 0's in mono -> 0 (for ROP) */
  319. SetBkColor(hdc, 0x00FFFFFF); /* 1's in mono -> 1 */
  320. hbr = CreateSolidBrush(rgbHilight);
  321. if (hbr) {
  322. hbrOld = SelectObject(hdc, hbr);
  323. if (hbrOld) {
  324. /* draw hilight color where we have 0's in the mask */
  325. BitBlt( hdc, x + 1, y + 1,
  326. pTBState->dxBitmap, pTBState->dyBitmap,
  327. pTBState->hdcMono, 0, 0, PSDPxax);
  328. SelectObject(hdc, hbrOld);
  329. }
  330. DeleteObject(hbr);
  331. }
  332. hbr = CreateSolidBrush(rgbShadow);
  333. if (hbr) {
  334. hbrOld = SelectObject(hdc, hbr);
  335. if (hbrOld) {
  336. /* draw the shadow color where we have 0's in the mask */
  337. BitBlt(hdc, x, y, pTBState->dxBitmap, pTBState->dyBitmap,
  338. pTBState->hdcMono, 0, 0, PSDPxax);
  339. SelectObject(hdc, hbrOld);
  340. }
  341. DeleteObject(hbr);
  342. }
  343. }
  344. if (ptButton->fsState & ODS_FOCUS) {
  345. BtnDrawFocusRect(hdc, &rcFocus, ptButton->fsState);
  346. }
  347. }
  348. /*****************************Private*Routine******************************\
  349. * BtnCreateBitmapButtons
  350. *
  351. * Returns TRUE if successful, otherwise FALSE;
  352. *
  353. * History:
  354. * 18-11-93 - StephenE - Created
  355. *
  356. \**************************************************************************/
  357. BOOL WINAPI
  358. BtnCreateBitmapButtons(
  359. HWND hWnd,
  360. HINSTANCE hInst,
  361. UINT wID,
  362. UINT uStyle,
  363. LPBITMAPBTN lpButtons,
  364. int nButtons,
  365. int dxBitmap,
  366. int dyBitmap
  367. )
  368. {
  369. PBTNSTATE pTBState;
  370. /*
  371. ** If we have already created Bitmap Buttons for this
  372. ** window just return.
  373. */
  374. if (GetProp(hWnd, szBbmProp)) {
  375. return TRUE;
  376. }
  377. CheckSysColors();
  378. /*
  379. ** Allocate the required storage and save the pointer in the window
  380. ** property list.
  381. */
  382. pTBState = (PBTNSTATE)LocalAlloc( LMEM_FIXED,
  383. (sizeof(BTNSTATE) - sizeof(BITMAPBTN)) +
  384. (nButtons * sizeof(BITMAPBTN)) );
  385. if (pTBState == NULL ) {
  386. return FALSE;
  387. }
  388. SetProp(hWnd, szBbmProp, (HANDLE)pTBState);
  389. pTBState->hInst = hInst;
  390. pTBState->wID = wID;
  391. pTBState->uStyle = uStyle;
  392. pTBState->nButtons = nButtons;
  393. pTBState->hbm = CreateMappedBitmap( hInst, wID, TRUE, NULL, 0);
  394. pTBState->dxBitmap = dxBitmap;
  395. pTBState->dyBitmap = dyBitmap;
  396. InitObjects( pTBState );
  397. CopyMemory( pTBState->Buttons, lpButtons, nButtons * sizeof(BITMAPBTN) );
  398. /*
  399. ** Does the caller want tool tips ?
  400. */
  401. if (pTBState->uStyle & BBS_TOOLTIPS) {
  402. pTBState->hwndToolTips = CreateWindow(TOOLTIPS_CLASS, g_szEmpty,
  403. WS_POPUP,
  404. CW_USEDEFAULT, CW_USEDEFAULT,
  405. CW_USEDEFAULT, CW_USEDEFAULT,
  406. hWnd, NULL, hInst, NULL);
  407. if (pTBState->hwndToolTips != (HWND)NULL ) {
  408. int i;
  409. TOOLINFO ti;
  410. pTBState->lpfnDefProc = SubclassWindow( hWnd, ParentSubclassProc );
  411. ti.uFlags = 0;
  412. ti.cbSize = sizeof(ti);
  413. ti.lpszText = LPSTR_TEXTCALLBACK;
  414. for ( i = 0; i < nButtons; i++ ) {
  415. LPBTN_INFO lpBtnInfo;
  416. HWND hwndBtn;
  417. hwndBtn = GetDlgItem(hWnd, pTBState->Buttons[i].uId);
  418. if ( hwndBtn == (HWND)NULL ) {
  419. break;
  420. }
  421. lpBtnInfo = (LPBTN_INFO)LocalAlloc(LPTR, sizeof(BTN_INFO));
  422. if (lpBtnInfo == NULL ) {
  423. break;
  424. }
  425. SetProp(hwndBtn, szButtonProp, (HANDLE)lpBtnInfo);
  426. lpBtnInfo->hwndToolTips = pTBState->hwndToolTips;
  427. lpBtnInfo->hwndParent = hWnd;
  428. lpBtnInfo->lpfnDefProc = SubclassWindow( hwndBtn,
  429. ButtonSubclassProc );
  430. ti.hwnd = hwndBtn;
  431. ti.uId = pTBState->Buttons[i].uId;
  432. GetClientRect( hwndBtn, &ti.rect );
  433. SendMessage( lpBtnInfo->hwndToolTips, TTM_ADDTOOL,
  434. (WPARAM)0, (LPARAM)&ti );
  435. /*
  436. ** Add the same rectangle in parent co-ordinates so that
  437. ** the tooltip still gets displayed even though the button
  438. ** is disabled.
  439. */
  440. MapWindowRect( hwndBtn, hWnd, &ti.rect );
  441. ti.hwnd = hWnd;
  442. SendMessage( lpBtnInfo->hwndToolTips, TTM_ADDTOOL,
  443. (WPARAM)0, (LPARAM)&ti );
  444. }
  445. }
  446. else {
  447. /*
  448. ** No tips available, just remove the BBS_TOOLTIPS style
  449. */
  450. pTBState->uStyle &= ~BBS_TOOLTIPS;
  451. }
  452. }
  453. return TRUE;
  454. }
  455. /******************************Public*Routine******************************\
  456. * BtnDestroyBitmapButtons
  457. *
  458. *
  459. *
  460. * History:
  461. * dd-mm-94 - StephenE - Created
  462. *
  463. \**************************************************************************/
  464. void WINAPI
  465. BtnDestroyBitmapButtons(
  466. HWND hwnd
  467. )
  468. {
  469. PBTNSTATE pTBState;
  470. pTBState = (PBTNSTATE)GetProp(hwnd, szBbmProp);
  471. if ( pTBState != NULL ) {
  472. DeleteObject( pTBState->hbm );
  473. FreeObjects( pTBState );
  474. }
  475. RemoveProp(hwnd, szBbmProp);
  476. }
  477. /******************************Public*Routine******************************\
  478. * BtnDrawFocusRect
  479. *
  480. * Use this function to draw focus rectangle around a bitmap button.
  481. *
  482. * History:
  483. * 18-11-93 - StephenE - Created
  484. *
  485. \**************************************************************************/
  486. void WINAPI
  487. BtnDrawFocusRect(
  488. HDC hdc,
  489. const RECT *lpRect,
  490. UINT fsState
  491. )
  492. {
  493. int iFaceOffset;
  494. RECT rc;
  495. CopyRect( &rc, lpRect );
  496. rc.top = rc.left = 3;
  497. if (fsState & ODS_SELECTED) {
  498. iFaceOffset = 2;
  499. }
  500. else {
  501. iFaceOffset = 4;
  502. }
  503. rc.right -= iFaceOffset;
  504. rc.bottom -= iFaceOffset;
  505. SetBkColor( hdc, rgbFace );
  506. DrawFocusRect( hdc, &rc );
  507. }
  508. /******************************Public*Routine******************************\
  509. * BtnUpdateColors
  510. *
  511. * After a WM_SYSCOLORCHANGE message is received this function should be
  512. * called to update the colors of the button bitmaps.
  513. *
  514. * History:
  515. * 18-11-93 - StephenE - Created
  516. *
  517. \**************************************************************************/
  518. void WINAPI
  519. BtnUpdateColors(
  520. HWND hwnd
  521. )
  522. {
  523. PBTNSTATE pTBState;
  524. pTBState = (PBTNSTATE)GetProp(hwnd, szBbmProp);
  525. if (pTBState->nSysColorChanges != nSysColorChanges)
  526. {
  527. DeleteObject( pTBState->hbm );
  528. pTBState->hbm = CreateMappedBitmap( pTBState->hInst,
  529. pTBState->wID, TRUE, NULL, 0);
  530. pTBState->nSysColorChanges = nSysColorChanges;
  531. }
  532. }
  533. /******************************Public*Routine******************************\
  534. * ButtonSubclassProc
  535. *
  536. *
  537. *
  538. * History:
  539. * dd-mm-94 - StephenE - Created
  540. *
  541. \**************************************************************************/
  542. LRESULT CALLBACK
  543. ButtonSubclassProc(
  544. HWND hwnd,
  545. UINT uMsg,
  546. WPARAM wParam,
  547. LPARAM lParam
  548. )
  549. {
  550. LPBTN_INFO lpBtnInfo;
  551. WNDPROC lpfnDefProc;
  552. lpBtnInfo = (LPBTN_INFO)GetProp( hwnd, szButtonProp );
  553. /*
  554. ** Save this in case anything happens to lpBtnInfo before we return.
  555. */
  556. lpfnDefProc = lpBtnInfo->lpfnDefProc;
  557. switch ( uMsg ) {
  558. case WM_DESTROY:
  559. SubclassWindow( hwnd, lpfnDefProc );
  560. if (lpBtnInfo) {
  561. LocalFree((HLOCAL)lpBtnInfo);
  562. RemoveProp(hwnd, szButtonProp);
  563. }
  564. break;
  565. case WM_LBUTTONDOWN:
  566. case WM_LBUTTONUP:
  567. case WM_RBUTTONDOWN:
  568. case WM_RBUTTONUP:
  569. case WM_MBUTTONDOWN:
  570. case WM_MBUTTONUP:
  571. case WM_MOUSEMOVE:
  572. RelayToToolTips( lpBtnInfo->hwndToolTips, hwnd, uMsg, wParam, lParam );
  573. break;
  574. case WM_MOVE:
  575. {
  576. TOOLINFO ti;
  577. ti.cbSize = sizeof(ti);
  578. ti.uFlags = 0;
  579. ti.hwnd = hwnd;
  580. ti.lpszText = LPSTR_TEXTCALLBACK;
  581. ti.uId = GetDlgCtrlID( hwnd );
  582. GetClientRect( hwnd, &ti.rect );
  583. SendMessage( lpBtnInfo->hwndToolTips, TTM_NEWTOOLRECT, 0,
  584. (LPARAM)&ti );
  585. /*
  586. ** Add the same rectangle in parent co-ordinates so that
  587. ** the tooltip still gets displayed even though the button
  588. ** is disabled.
  589. */
  590. MapWindowRect( hwnd, lpBtnInfo->hwndParent, &ti.rect );
  591. ti.hwnd = lpBtnInfo->hwndParent;
  592. SendMessage( lpBtnInfo->hwndToolTips, TTM_NEWTOOLRECT,
  593. (WPARAM)0, (LPARAM)&ti );
  594. }
  595. break;
  596. case WM_NOTIFY:
  597. SendMessage(lpBtnInfo->hwndParent, WM_NOTIFY, wParam, lParam);
  598. break;
  599. }
  600. return CallWindowProc(lpfnDefProc, hwnd, uMsg, wParam, lParam);
  601. }
  602. /******************************Public*Routine******************************\
  603. * ParentSubclassProc
  604. *
  605. * Why do I need to subclass the buttons parent window ? Well,
  606. * if a button is disable it will not receive mouse messages, the
  607. * messages go to the window underneath the button (ie. the parent).
  608. * Therefore we detect this and relay the mouse message to the tool tips
  609. * window as above.
  610. *
  611. * History:
  612. * dd-mm-94 - StephenE - Created
  613. *
  614. \**************************************************************************/
  615. LRESULT CALLBACK
  616. ParentSubclassProc(
  617. HWND hwnd,
  618. UINT uMsg,
  619. WPARAM wParam,
  620. LPARAM lParam
  621. )
  622. {
  623. WNDPROC lpfnDefProc;
  624. PBTNSTATE pTBState;
  625. pTBState = (PBTNSTATE)GetProp(hwnd, szBbmProp);
  626. /*
  627. ** Save this in case anything happens to lpBtnInfo before we return.
  628. */
  629. lpfnDefProc = pTBState->lpfnDefProc;
  630. switch ( uMsg ) {
  631. case TB_GETTOOLTIPS:
  632. return (LRESULT)(UINT)pTBState->hwndToolTips;
  633. case WM_LBUTTONDOWN:
  634. case WM_LBUTTONUP:
  635. case WM_RBUTTONDOWN:
  636. case WM_RBUTTONUP:
  637. case WM_MBUTTONDOWN:
  638. case WM_MBUTTONUP:
  639. case WM_MOUSEMOVE:
  640. case WM_NCMOUSEMOVE:
  641. RelayToToolTips( pTBState->hwndToolTips, hwnd, uMsg, wParam, lParam );
  642. break;
  643. }
  644. return CallWindowProc(lpfnDefProc, hwnd, uMsg, wParam, lParam);
  645. }
  646. /******************************Public*Routine******************************\
  647. * RelayToToolTips
  648. *
  649. *
  650. *
  651. * History:
  652. * dd-mm-94 - StephenE - Created
  653. *
  654. \**************************************************************************/
  655. void FAR PASCAL
  656. RelayToToolTips(
  657. HWND hwndToolTips,
  658. HWND hWnd,
  659. UINT wMsg,
  660. WPARAM wParam,
  661. LPARAM lParam
  662. )
  663. {
  664. if(hwndToolTips) {
  665. MSG msg;
  666. msg.lParam = lParam;
  667. msg.wParam = wParam;
  668. msg.message = wMsg;
  669. msg.hwnd = hWnd;
  670. SendMessage(hwndToolTips, TTM_RELAYEVENT, 0, (LPARAM)(LPMSG)&msg);
  671. }
  672. }
  673.