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.

1805 lines
48 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: ledwnd.c
  3. *
  4. * Implementation of the LED window.
  5. *
  6. *
  7. * Created: 18-11-93
  8. * Author: Stephen Estrop [StephenE]
  9. *
  10. * Copyright (c) 1993 Microsoft Corporation
  11. \**************************************************************************/
  12. #pragma warning( once : 4201 4214 )
  13. #define NOOLE
  14. #include <windows.h> /* required for all Windows applications */
  15. #include <windowsx.h>
  16. #include <string.h>
  17. #include <tchar.h> /* contains portable ascii/unicode macros */
  18. #include <commctrl.h>
  19. #include "playres.h"
  20. #include "cdplayer.h"
  21. #include "cdapi.h"
  22. #include "literals.h"
  23. #include "trklst.h"
  24. #define DECLARE_DATA
  25. #include "ledwnd.h"
  26. #include "dib.h"
  27. #include "..\cdopt\cdopt.h"
  28. #define WM_LED_INFO_PAINT (WM_USER+2000) //wparam = draw, lparam = volchanged state
  29. #define WM_LED_MUTE (WM_USER+2001) //wparam = unused, lparam = mute flag
  30. #define WM_LED_DOWNLOAD (WM_USER+2002) //wparam = unused, lparam = download flag
  31. #define WM_NET_CHANGEPROVIDER (WM_USER+1002) //wparam = unused, lparam = LPCDPROVIDER
  32. #define VOLUME_STEPS 40
  33. #define VOLUME_SPACING 3
  34. #define VOLUME_DELTA 0x2FF
  35. #define VOLUME_LINE_HEIGHT 28
  36. #define VOLUME_WIDTH 290
  37. #define TOOLID_STATUS 0
  38. #define TOOLID_MODE 1
  39. #define TOOLID_LOGO 2
  40. #define TOOLID_TIME 3
  41. #define TOOLID_TRACKORMUTE 4
  42. #define TOOLID_TITLE 5
  43. #define TOOLID_TRACK 6
  44. #define TOOLID_ARTIST 7
  45. #define LARGE_MODE_INDICATOR 400
  46. #define LOGO_X_OFFSET 4
  47. #define LOGO_Y_OFFSET 4
  48. #define INFO_AREA_OFFSET 55
  49. #define ANI_NOCD_FRAME 0
  50. #define ANI_STOP_FRAME 1
  51. #define ANI_LAST_PLAY_FRAME 4
  52. #define ANI_PAUSE_FRAME 5
  53. #define MODE_NORMAL_FRAME 0
  54. #define MODE_REPEAT1_FRAME 1
  55. #define MODE_REPEATALL_FRAME 2
  56. #define MODE_INTRO_FRAME 3
  57. #define MODE_RANDOM_FRAME 4
  58. int g_nLastXOrigin = 0;
  59. BITMAP g_bmLogo;
  60. BOOL g_fAllowDraw = TRUE;
  61. DWORD g_dwLevel = 0;
  62. TCHAR* g_szMixerName = NULL;
  63. HWND g_hwndPlay = NULL;
  64. HWND g_hwndMode = NULL;
  65. HWND g_hwndDownload = NULL;
  66. DWORD g_dwLastState = CD_NO_CD;
  67. DWORD g_dwLastModeFrame = MODE_NORMAL_FRAME;
  68. COLORREF CurrentColorRef = RGB(0x00,0xFF,0xFF);
  69. BOOL g_fMute = TRUE;
  70. BOOL g_fDownloading = FALSE;
  71. LPCDPROVIDER g_pCurrentProvider = NULL;
  72. RECT g_timerect;
  73. HWND g_hwndToolTips = NULL;
  74. extern HINSTANCE g_hInst;
  75. /* -------------------------------------------------------------------------
  76. ** Private functions for the LED class
  77. ** -------------------------------------------------------------------------
  78. */
  79. BOOL
  80. LED_OnCreate(
  81. HWND hwnd,
  82. LPCREATESTRUCT lpCreateStruct
  83. );
  84. BOOL
  85. LED_LargeMode(HWND hwnd);
  86. void
  87. LED_OnPaint(
  88. HWND hwnd
  89. );
  90. void
  91. LED_OnLButtonUp(
  92. HWND hwnd,
  93. int x,
  94. int y,
  95. UINT keyFlags
  96. );
  97. void
  98. LED_OnSetText(
  99. HWND hwnd,
  100. LPCTSTR lpszText
  101. );
  102. void
  103. LED_DrawText(
  104. HWND hwnd,
  105. HDC hdcLed,
  106. LPCTSTR s,
  107. int sLen
  108. );
  109. void
  110. LED_Animation(HDC hdc);
  111. void
  112. LED_DrawLogo(
  113. HWND hwnd,
  114. HDC hdcLed, RECT* pPaintRect);
  115. void
  116. LED_DrawInfo(
  117. HWND hwnd,
  118. HDC hdcLed,
  119. LPCTSTR s,
  120. int sLen, RECT* pPaintRect
  121. );
  122. void
  123. LED_DrawTrackMute(
  124. HWND hwnd,
  125. HDC hdcLed, RECT* pPaintRect);
  126. void
  127. LED_CreateLEDFonts(
  128. HDC hdc
  129. );
  130. void LED_DrawVolume(
  131. HWND ledWnd, HDC hdc
  132. );
  133. HANDLE hbmpLogo = NULL;
  134. HANDLE hbmpVendorLogo = NULL;
  135. /******************************Public*Routine******************************\
  136. * InitLEDClass
  137. *
  138. * Called to register the LED window class and create a font for the LED
  139. * window to use. This function must be called before the CD Player dialog
  140. * box is created.
  141. *
  142. * History:
  143. * 18-11-93 - StephenE - Created
  144. *
  145. \**************************************************************************/
  146. BOOL
  147. InitLEDClass(
  148. HINSTANCE hInst
  149. )
  150. {
  151. WNDCLASS LEDwndclass;
  152. HDC hdc;
  153. ZeroMemory( &LEDwndclass, sizeof(LEDwndclass) );
  154. /*
  155. ** Register the LED window.
  156. */
  157. LEDwndclass.lpfnWndProc = LEDWndProc;
  158. LEDwndclass.hInstance = hInst;
  159. LEDwndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  160. LEDwndclass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  161. LEDwndclass.lpszClassName = g_szLEDClassName;
  162. LEDwndclass.style = CS_OWNDC;
  163. hdc = GetDC( GetDesktopWindow() );
  164. LED_CreateLEDFonts( hdc );
  165. ReleaseDC( GetDesktopWindow(), hdc );
  166. return RegisterClass( &LEDwndclass );
  167. }
  168. void LED_OnDestroy(HWND hwnd)
  169. {
  170. if (hbmpLogo)
  171. {
  172. GlobalFree(hbmpLogo);
  173. hbmpLogo = NULL;
  174. }
  175. if ( hLEDFontL != NULL )
  176. {
  177. DeleteObject( hLEDFontL );
  178. }
  179. if ( hLEDFontS != NULL )
  180. {
  181. DeleteObject( hLEDFontS );
  182. }
  183. if ( hLEDFontB != NULL )
  184. {
  185. DeleteObject( hLEDFontB );
  186. }
  187. }
  188. ////////////////////////////////////////////////////////////////////////////////////////////
  189. // * LED_OnToolTipNotify
  190. // Called from tool tips to get the text they need to display
  191. ////////////////////////////////////////////////////////////////////////////////////////////
  192. VOID LED_OnToolTipNotify(HWND hwnd, LPARAM lParam)
  193. {
  194. LPTOOLTIPTEXT lpttt;
  195. UINT nID;
  196. if ((((LPNMHDR) lParam)->code) == TTN_NEEDTEXT)
  197. {
  198. nID = (UINT)((LPNMHDR)lParam)->idFrom;
  199. lpttt = (LPTOOLTIPTEXT)lParam;
  200. switch (nID)
  201. {
  202. case TOOLID_STATUS :
  203. {
  204. TCHAR szFormat[30];
  205. TCHAR szStatus[30];
  206. LoadString(g_hInst,STR_FORMAT_STATUS,szFormat,sizeof(szFormat)/sizeof(TCHAR));
  207. if (g_fDownloading)
  208. {
  209. LoadString(g_hInst,STR_STATUS_DOWNLOADING,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  210. }
  211. else
  212. {
  213. if (g_State & CD_PLAYING)
  214. {
  215. LoadString(g_hInst,STR_STATUS_PLAY,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  216. }
  217. if (g_State & CD_STOPPED)
  218. {
  219. LoadString(g_hInst,STR_STATUS_STOP,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  220. }
  221. if (g_State & CD_PAUSED)
  222. {
  223. LoadString(g_hInst,STR_STATUS_PAUSED,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  224. }
  225. if ((g_State & CD_NO_CD) || (g_State & CD_DATA_CD_LOADED))
  226. {
  227. LoadString(g_hInst,STR_STATUS_NODISC,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  228. }
  229. } //end else
  230. wsprintf(lpttt->szText,szFormat,szStatus);
  231. }
  232. break;
  233. case TOOLID_MODE :
  234. {
  235. TCHAR szFormat[30];
  236. TCHAR szStatus[30];
  237. LoadString(g_hInst,STR_FORMAT_MODE,szFormat,sizeof(szFormat)/sizeof(TCHAR));
  238. LoadString(g_hInst,STR_MODE_NORMAL,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  239. if (g_fContinuous)
  240. {
  241. LoadString(g_hInst,STR_MODE_REPEATALL,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  242. }
  243. if (g_fIntroPlay)
  244. {
  245. LoadString(g_hInst,STR_MODE_INTROPLAY,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  246. }
  247. if (!g_fSelectedOrder)
  248. {
  249. LoadString(g_hInst,STR_MODE_RANDOM,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  250. }
  251. if (g_fRepeatSingle)
  252. {
  253. LoadString(g_hInst,STR_MODE_REPEATONE,szStatus,sizeof(szStatus)/sizeof(TCHAR));
  254. }
  255. wsprintf(lpttt->szText,szFormat,szStatus);
  256. }
  257. break;
  258. case TOOLID_LOGO :
  259. {
  260. if (g_fDownloading)
  261. {
  262. _tcscpy(lpttt->szText,g_pCurrentProvider->szProviderName);
  263. }
  264. else
  265. {
  266. LoadString(g_hInst,STR_LOGO,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  267. }
  268. }
  269. break;
  270. case TOOLID_TIME :
  271. {
  272. if (g_fDisplayT)
  273. {
  274. LoadString(g_hInst,STR_TRACK_TIME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  275. }
  276. if (g_fDisplayTr)
  277. {
  278. LoadString(g_hInst,STR_TRACK_REMAINING,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  279. }
  280. if (g_fDisplayD)
  281. {
  282. LoadString(g_hInst,STR_DISC_TIME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  283. }
  284. if (g_fDisplayDr)
  285. {
  286. LoadString(g_hInst,STR_DISC_REMAINING,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  287. }
  288. }
  289. break;
  290. case TOOLID_TRACKORMUTE :
  291. {
  292. BOOL fLargeMode = FALSE;
  293. if (LED_LargeMode(hwnd))
  294. {
  295. fLargeMode = TRUE;
  296. }
  297. if ((g_fMute) && (fLargeMode))
  298. {
  299. LoadString(g_hInst,STR_STATUS_MUTE,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  300. }
  301. else
  302. {
  303. LoadString(g_hInst,STR_TRACK_NUMBER,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  304. }
  305. }
  306. break;
  307. case TOOLID_TITLE :
  308. {
  309. if (g_fAllowDraw)
  310. {
  311. LoadString(g_hInst,STR_TITLE,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  312. }
  313. else
  314. {
  315. LoadString(g_hInst,STR_VOLUME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  316. }
  317. }
  318. break;
  319. case TOOLID_TRACK :
  320. {
  321. if (g_fAllowDraw)
  322. {
  323. LoadString(g_hInst,STR_TRACK,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  324. }
  325. else
  326. {
  327. LoadString(g_hInst,STR_VOLUME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  328. }
  329. }
  330. break;
  331. case TOOLID_ARTIST :
  332. {
  333. if (g_fAllowDraw)
  334. {
  335. LoadString(g_hInst,STR_ARTIST,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  336. }
  337. else
  338. {
  339. LoadString(g_hInst,STR_VOLUME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR));
  340. }
  341. }
  342. break;
  343. } //end switch
  344. }
  345. return;
  346. }
  347. void DoDrawing(HWND hwnd, HDC hdc, RECT* pPaintRect)
  348. {
  349. int sLen;
  350. TCHAR s[MAX_PATH];
  351. sLen = GetWindowText( hwnd, s, sizeof(s)/sizeof(TCHAR));
  352. RECT wndRect;
  353. GetClientRect(hwnd,&wndRect);
  354. HPALETTE hPalOld = SelectPalette(hdc,g_pSink->GetPalette(),FALSE);
  355. RealizePalette(hdc);
  356. HDC memDC = CreateCompatibleDC(hdc);
  357. HPALETTE hPalOldMem = SelectPalette(hdc,g_pSink->GetPalette(),FALSE);
  358. RealizePalette(hdc);
  359. SetBkColor( memDC, RGB(0x00,0x00,0x00) );
  360. SetTextColor( memDC, CurrentColorRef );
  361. HBITMAP hbmp = CreateCompatibleBitmap(hdc,wndRect.right-wndRect.left,wndRect.bottom-wndRect.top);
  362. HBITMAP holdBmp = (HBITMAP)SelectObject(memDC,hbmp);
  363. if (LED_LargeMode(hwnd))
  364. {
  365. LED_Animation(hdc); //use hdc to ensure the clip rect is not affecting these windows
  366. LED_DrawLogo(hwnd,memDC,pPaintRect);
  367. LED_DrawTrackMute(hwnd,memDC,pPaintRect);
  368. if (g_fAllowDraw)
  369. {
  370. LED_DrawInfo(hwnd,memDC, s, sLen,pPaintRect);
  371. }
  372. else
  373. {
  374. LED_DrawVolume(hwnd,memDC);
  375. }
  376. }
  377. else
  378. {
  379. //hide all animations
  380. ShowWindow(g_hwndPlay,SW_HIDE);
  381. ShowWindow(g_hwndMode,SW_HIDE);
  382. if (g_hwndDownload)
  383. {
  384. ShowWindow(g_hwndDownload,SW_HIDE);
  385. }
  386. }
  387. /*
  388. ** Draw the LED display text
  389. */
  390. LED_DrawText( hwnd, memDC, s, sLen );
  391. //blit from memory onto display and clean up
  392. BitBlt(hdc,wndRect.left,wndRect.top,wndRect.right-wndRect.left,wndRect.bottom-wndRect.top,
  393. memDC,0,0,SRCCOPY);
  394. SelectObject(memDC,holdBmp);
  395. DeleteObject(hbmp);
  396. SelectPalette(hdc,hPalOld,FALSE);
  397. RealizePalette(hdc);
  398. SelectPalette(memDC,hPalOldMem,FALSE);
  399. RealizePalette(memDC);
  400. DeleteDC(memDC);
  401. GetClientRect( hwnd, &wndRect );
  402. HRGN region = CreateRectRgn(wndRect.left,wndRect.top,wndRect.right,wndRect.bottom);
  403. SelectClipRgn(hdc, region);
  404. DeleteObject(region);
  405. }
  406. BOOL LED_OnEraseBackground(HWND hwnd, HDC hdc)
  407. {
  408. //DoDrawing(hwnd,hdc);
  409. return TRUE;
  410. }
  411. /******************************Public*Routine******************************\
  412. * LEDWndProc
  413. *
  414. * This routine handles the WM_PAINT and WM_SETTEXT messages
  415. * for the "LED" display window.
  416. *
  417. * History:
  418. * 18-11-93 - StephenE - Created
  419. *
  420. \**************************************************************************/
  421. LRESULT CALLBACK
  422. LEDWndProc(
  423. HWND hwnd,
  424. UINT message,
  425. WPARAM wParam,
  426. LPARAM lParam
  427. )
  428. {
  429. switch( message )
  430. {
  431. HANDLE_MSG( hwnd, WM_CREATE, LED_OnCreate );
  432. HANDLE_MSG( hwnd, WM_DESTROY, LED_OnDestroy);
  433. HANDLE_MSG( hwnd, WM_PAINT, LED_OnPaint );
  434. HANDLE_MSG( hwnd, WM_LBUTTONUP, LED_OnLButtonUp );
  435. HANDLE_MSG( hwnd, WM_SETTEXT, LED_OnSetText );
  436. HANDLE_MSG( hwnd, WM_ERASEBKGND, LED_OnEraseBackground);
  437. case WM_NOTIFY :
  438. {
  439. if ((((LPNMHDR)lParam)->code) == TTN_NEEDTEXT)
  440. {
  441. LED_OnToolTipNotify(hwnd,lParam);
  442. }
  443. }
  444. break;
  445. case WM_LBUTTONDOWN :
  446. case WM_MBUTTONDOWN :
  447. case WM_RBUTTONDOWN :
  448. case WM_MOUSEMOVE :
  449. {
  450. MSG msg;
  451. msg.lParam = lParam;
  452. msg.wParam = wParam;
  453. msg.message = message;
  454. msg.hwnd = hwnd;
  455. SendMessage(g_hwndToolTips, TTM_RELAYEVENT, 0, (LPARAM)&msg);
  456. }
  457. break;
  458. case WM_LED_INFO_PAINT :
  459. {
  460. g_fAllowDraw = (BOOL)wParam;
  461. if (!g_fAllowDraw)
  462. {
  463. MMONVOLCHANGED* pVolChange = (MMONVOLCHANGED*)lParam;
  464. g_szMixerName = pVolChange->szLineName;
  465. g_dwLevel = pVolChange->dwNewVolume;
  466. InvalidateRect(hwnd,NULL,FALSE);
  467. UpdateWindow(hwnd);
  468. }
  469. }
  470. break;
  471. case WM_LED_MUTE :
  472. {
  473. g_fMute = (BOOL)lParam;
  474. InvalidateRect(hwnd,NULL,FALSE);
  475. UpdateWindow(hwnd);
  476. }
  477. break;
  478. case WM_NET_CHANGEPROVIDER :
  479. {
  480. if (g_fDownloading)
  481. {
  482. if (hbmpVendorLogo)
  483. {
  484. GlobalFree(hbmpVendorLogo);
  485. hbmpVendorLogo = NULL;
  486. }
  487. LPCDPROVIDER pProv = (LPCDPROVIDER)lParam;
  488. if (pProv)
  489. {
  490. hbmpVendorLogo = OpenDIB(pProv->szProviderLogo,-1);
  491. g_pCurrentProvider = pProv;
  492. //if tool tip is showing, kill it
  493. TOOLINFO ti;
  494. ti.cbSize = sizeof(ti);
  495. if (SendMessage(g_hwndToolTips, TTM_GETCURRENTTOOL, 0, (LPARAM) (LPTOOLINFO) &ti))
  496. {
  497. if (ti.uId == TOOLID_LOGO)
  498. {
  499. //fake a button down
  500. MSG msg;
  501. msg.lParam = 0;
  502. msg.wParam = 0;
  503. msg.message = WM_LBUTTONDOWN;
  504. msg.hwnd = hwnd;
  505. SendMessage(g_hwndToolTips, TTM_RELAYEVENT, 0, (LPARAM)&msg);
  506. }
  507. }
  508. }
  509. InvalidateRect(hwnd,NULL,FALSE);
  510. UpdateWindow(hwnd);
  511. } //end if downloading
  512. }
  513. break;
  514. case WM_LED_DOWNLOAD :
  515. {
  516. BOOL fDownloading = (BOOL)lParam;
  517. if (fDownloading == g_fDownloading)
  518. {
  519. //can get called multiple times for same mode
  520. break;
  521. }
  522. g_fDownloading = fDownloading;
  523. if (g_fDownloading)
  524. {
  525. //get the path to the vendor logo file
  526. LPCDOPT pOpts = (LPCDOPT)g_pSink->GetOptions();
  527. if (pOpts)
  528. {
  529. LPCDOPTIONS pOptions = NULL;
  530. pOptions = pOpts->GetCDOpts();
  531. if (pOptions)
  532. {
  533. if (pOptions->pCurrentProvider!=NULL)
  534. {
  535. hbmpVendorLogo = OpenDIB(pOptions->pCurrentProvider->szProviderLogo,-1);
  536. g_pCurrentProvider = pOptions->pCurrentProvider;
  537. } //end if current provider ok
  538. } //end if poptions ok
  539. } //end if popts created
  540. //create the downloading animation
  541. g_hwndDownload = Animate_Create(hwnd,
  542. IDI_ICON_ANI_DOWN,
  543. WS_CHILD,
  544. g_hInst);
  545. //headers don't have Animate_OpenEx yet,
  546. //so just do the straight call
  547. SendMessage(g_hwndDownload,ACM_OPEN,(WPARAM)g_hInst,
  548. (LPARAM)MAKEINTRESOURCE(IDI_ICON_ANI_DOWN));
  549. //move to the top/left of the window
  550. RECT anirect;
  551. GetClientRect(g_hwndDownload,&anirect);
  552. MoveWindow(g_hwndDownload,
  553. LOGO_X_OFFSET,
  554. LOGO_Y_OFFSET,
  555. anirect.right - anirect.left,
  556. anirect.bottom - anirect.top,
  557. FALSE);
  558. Animate_Play(g_hwndDownload,0,-1,-1);
  559. ShowWindow(g_hwndPlay,SW_HIDE);
  560. ShowWindow(g_hwndDownload,SW_SHOW);
  561. if (hbmpVendorLogo)
  562. {
  563. InvalidateRect(hwnd,NULL,FALSE);
  564. UpdateWindow(hwnd);
  565. }
  566. }
  567. else
  568. {
  569. ShowWindow(g_hwndDownload,SW_HIDE);
  570. ShowWindow(g_hwndPlay,SW_SHOW);
  571. DestroyWindow(g_hwndDownload);
  572. g_hwndDownload = NULL;
  573. if (hbmpVendorLogo)
  574. {
  575. GlobalFree(hbmpVendorLogo);
  576. InvalidateRect(hwnd,NULL,FALSE);
  577. UpdateWindow(hwnd);
  578. }
  579. }
  580. }
  581. break;
  582. }
  583. return DefWindowProc( hwnd, message, wParam, lParam );
  584. }
  585. void LED_SetTool(HWND hwnd, UINT toolID, int left, int top, int right, int bottom)
  586. {
  587. TOOLINFO ti;
  588. RECT toolRect;
  589. BOOL fAddTool = TRUE;
  590. SetRect(&toolRect,left,top,right,bottom);
  591. ti.cbSize = sizeof(TOOLINFO);
  592. ti.uFlags = 0;
  593. ti.hwnd = hwnd;
  594. ti.hinst = g_hInst;
  595. ti.uId = toolID;
  596. ti.lpszText = LPSTR_TEXTCALLBACK;
  597. //check to see if tool already exists
  598. if (SendMessage(g_hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) (LPTOOLINFO) &ti))
  599. {
  600. //if tool exists, we don't want to add it ...
  601. fAddTool = FALSE;
  602. //... unless the rects have changed
  603. if (memcmp(&ti.rect,&toolRect,sizeof(RECT)) != 0)
  604. {
  605. SendMessage(g_hwndToolTips, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
  606. fAddTool = TRUE;
  607. }
  608. }
  609. if (fAddTool)
  610. {
  611. SetRect(&ti.rect,left,top,right,bottom);
  612. SendMessage(g_hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
  613. }
  614. }
  615. /*****************************Private*Routine******************************\
  616. * LED_OnCreate
  617. *
  618. *
  619. *
  620. * History:
  621. * 18-11-93 - StephenE - Created
  622. *
  623. \**************************************************************************/
  624. BOOL
  625. LED_OnCreate(
  626. HWND hwnd,
  627. LPCREATESTRUCT lpCreateStruct
  628. )
  629. {
  630. HDC hdcLed;
  631. hdcLed = GetDC( hwnd );
  632. SetTextColor( hdcLed, CurrentColorRef );
  633. ReleaseDC( hwnd, hdcLed );
  634. //create the tooltips
  635. g_hwndToolTips = CreateWindow(TOOLTIPS_CLASS, (LPTSTR) NULL, TTS_ALWAYSTIP | WS_POPUP,
  636. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  637. hwnd, (HMENU) NULL, g_hInst, NULL);
  638. //determine color depth
  639. HDC hdcScreen = GetDC(NULL);
  640. UINT uBPP = GetDeviceCaps(hdcScreen, PLANES) * GetDeviceCaps(hdcScreen, BITSPIXEL);
  641. ReleaseDC(NULL, hdcScreen);
  642. //load the logo
  643. HBITMAP hbmpTemp = NULL;
  644. if (uBPP == 4) //16-color
  645. {
  646. hbmpTemp = (HBITMAP)LoadImage(g_hInst,MAKEINTRESOURCE(IDB_CDLOGO_16),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
  647. }
  648. else
  649. {
  650. hbmpTemp = (HBITMAP)LoadImage(g_hInst,MAKEINTRESOURCE(IDB_CDLOGO),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
  651. }
  652. hbmpLogo = DibFromBitmap((HBITMAP)hbmpTemp,0,0,NULL,0);
  653. GetObject(hbmpTemp,sizeof(g_bmLogo),&g_bmLogo);
  654. DeleteObject(hbmpTemp);
  655. g_hwndPlay = Animate_Create(hwnd,
  656. IDI_ICON_ANI_PLAY,
  657. WS_CHILD,
  658. g_hInst);
  659. //headers don't have Animate_OpenEx yet,
  660. //so just do the straight call
  661. SendMessage(g_hwndPlay,ACM_OPEN,(WPARAM)g_hInst,
  662. (LPARAM)MAKEINTRESOURCE(IDI_ICON_ANI_PLAY));
  663. //move to the top/left of the window
  664. RECT anirect;
  665. GetClientRect(g_hwndPlay,&anirect);
  666. MoveWindow(g_hwndPlay,
  667. LOGO_X_OFFSET,
  668. LOGO_Y_OFFSET,
  669. anirect.right - anirect.left,
  670. anirect.bottom - anirect.top,
  671. FALSE);
  672. LED_SetTool(hwnd,TOOLID_STATUS,anirect.left,anirect.top,anirect.right,anirect.bottom);
  673. ShowWindow(g_hwndPlay,SW_SHOW);
  674. g_hwndMode = Animate_Create(hwnd,
  675. IDI_ICON_ANI_MODE,
  676. WS_CHILD,
  677. g_hInst);
  678. //headers don't have Animate_OpenEx yet,
  679. //so just do the straight call
  680. SendMessage(g_hwndMode,ACM_OPEN,(WPARAM)g_hInst,
  681. (LPARAM)MAKEINTRESOURCE(IDI_ICON_ANI_MODE));
  682. //move to the top/left of the window
  683. GetClientRect(g_hwndMode,&anirect);
  684. MoveWindow(g_hwndMode,
  685. (g_bmLogo.bmWidth - (anirect.right - anirect.left)) + LOGO_X_OFFSET,
  686. LOGO_Y_OFFSET,
  687. anirect.right - anirect.left,
  688. anirect.bottom - anirect.top,
  689. FALSE);
  690. LED_SetTool(hwnd,TOOLID_MODE,
  691. (g_bmLogo.bmWidth - (anirect.right - anirect.left)) + LOGO_X_OFFSET,
  692. LOGO_Y_OFFSET,
  693. g_bmLogo.bmWidth + LOGO_X_OFFSET,
  694. LOGO_Y_OFFSET + (anirect.bottom - anirect.top));
  695. ShowWindow(g_hwndMode,SW_SHOW);
  696. //set the bounding rect for clicking on the time ... intialize to whole rect
  697. RECT rcParent;
  698. GetClientRect(hwnd,&rcParent);
  699. SetRect(&g_timerect,rcParent.left,rcParent.top,rcParent.right,rcParent.bottom);
  700. return TRUE;
  701. }
  702. void LED_Animation(HDC hdc)
  703. {
  704. ShowWindow(g_hwndMode,SW_SHOW);
  705. if (!g_fDownloading)
  706. {
  707. ShowWindow(g_hwndPlay,SW_SHOW);
  708. if (g_State != g_dwLastState)
  709. {
  710. g_dwLastState = g_State;
  711. Animate_Stop(g_hwndPlay);
  712. if (g_State & CD_PLAYING)
  713. {
  714. Animate_Play(g_hwndPlay,ANI_STOP_FRAME,ANI_LAST_PLAY_FRAME,-1);
  715. }
  716. if (g_State & CD_STOPPED)
  717. {
  718. Animate_Seek(g_hwndPlay,ANI_STOP_FRAME);
  719. }
  720. if (g_State & CD_PAUSED)
  721. {
  722. Animate_Play(g_hwndPlay,ANI_LAST_PLAY_FRAME,ANI_PAUSE_FRAME,-1);
  723. }
  724. if ((g_State & CD_NO_CD) || (g_State & CD_DATA_CD_LOADED))
  725. {
  726. Animate_Seek(g_hwndPlay,ANI_NOCD_FRAME);
  727. }
  728. }
  729. }
  730. else
  731. {
  732. if (g_hwndDownload)
  733. {
  734. ShowWindow(g_hwndDownload,SW_SHOW);
  735. }
  736. }
  737. RECT rect;
  738. GetClientRect(g_hwndPlay,&rect);
  739. ExcludeClipRect(hdc,
  740. LOGO_X_OFFSET,
  741. LOGO_Y_OFFSET,
  742. (rect.right - rect.left) + LOGO_X_OFFSET,
  743. (rect.bottom - rect.top) + LOGO_Y_OFFSET);
  744. DWORD dwCurFrame = MODE_NORMAL_FRAME;
  745. if (g_fContinuous)
  746. {
  747. dwCurFrame = MODE_REPEATALL_FRAME;
  748. }
  749. if (g_fIntroPlay)
  750. {
  751. dwCurFrame = MODE_INTRO_FRAME;
  752. }
  753. if (!g_fSelectedOrder)
  754. {
  755. dwCurFrame = MODE_RANDOM_FRAME;
  756. }
  757. if (g_fRepeatSingle)
  758. {
  759. dwCurFrame = MODE_REPEAT1_FRAME;
  760. }
  761. if (dwCurFrame != g_dwLastModeFrame)
  762. {
  763. g_dwLastModeFrame = dwCurFrame;
  764. Animate_Seek(g_hwndMode,dwCurFrame);
  765. }
  766. GetClientRect(g_hwndMode,&rect);
  767. ExcludeClipRect(hdc,
  768. (g_bmLogo.bmWidth - (rect.right - rect.left)) + LOGO_X_OFFSET,
  769. LOGO_Y_OFFSET,
  770. g_bmLogo.bmWidth + LOGO_X_OFFSET,
  771. (rect.bottom - rect.top) + LOGO_Y_OFFSET);
  772. }
  773. BOOL LED_LargeMode(HWND hwnd)
  774. {
  775. RECT rcParent;
  776. GetClientRect(GetParent(hwnd),&rcParent);
  777. if (rcParent.right - rcParent.left < LARGE_MODE_INDICATOR)
  778. {
  779. return FALSE;
  780. }
  781. return TRUE;
  782. }
  783. /*****************************Private*Routine******************************\
  784. * LED_OnPaint
  785. *
  786. *
  787. *
  788. * History:
  789. * 18-11-93 - StephenE - Created
  790. *
  791. \**************************************************************************/
  792. void
  793. LED_OnPaint(
  794. HWND hwnd
  795. )
  796. {
  797. PAINTSTRUCT ps;
  798. HDC hdcLed;
  799. hdcLed = BeginPaint( hwnd, &ps );
  800. DoDrawing(hwnd, hdcLed, &(ps.rcPaint));
  801. EndPaint( hwnd, &ps );
  802. }
  803. /*****************************Private*Routine******************************\
  804. * LED_OnLButtonUp
  805. *
  806. * Rotate the time remaing buttons and then set the display accordingly.
  807. *
  808. * History:
  809. * 18-11-93 - StephenE - Created
  810. *
  811. \**************************************************************************/
  812. void
  813. LED_OnLButtonUp(
  814. HWND hwnd,
  815. int x,
  816. int y,
  817. UINT keyFlags
  818. )
  819. {
  820. BOOL b, b2;
  821. /*
  822. ** If this window is not the master display LED just return
  823. */
  824. if ( GetWindowLongPtr(hwnd, GWLP_ID) != IDC_LED )
  825. {
  826. return;
  827. }
  828. RECT rcParent;
  829. GetClientRect(GetParent(hwnd),&rcParent);
  830. POINT pt;
  831. pt.x = x;
  832. pt.y = y;
  833. //if we're downloading AND within the logo rect, launch the provider's url
  834. if ((g_fDownloading) && (g_pCurrentProvider))
  835. {
  836. RECT logoRect;
  837. SetRect(&logoRect,
  838. LOGO_X_OFFSET,
  839. (rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET,
  840. LOGO_X_OFFSET + g_bmLogo.bmWidth,
  841. rcParent.bottom - LOGO_Y_OFFSET);
  842. if (PtInRect(&logoRect,pt))
  843. {
  844. ShellExecute(NULL,_TEXT("open"),g_pCurrentProvider->szProviderHome,NULL,_TEXT(""),SW_NORMAL);
  845. return;
  846. }
  847. }
  848. //if button in time rect AND volume isn't showing, allow click
  849. if ((PtInRect(&g_timerect,pt)) && (g_fAllowDraw))
  850. {
  851. b = g_fDisplayT;
  852. b2 = g_fDisplayD;
  853. g_fDisplayD = g_fDisplayTr;
  854. g_fDisplayT = g_fDisplayDr;
  855. g_fDisplayDr = b2;
  856. g_fDisplayTr = b;
  857. //reset options
  858. LPCDOPT pOpts = (LPCDOPT)g_pSink->GetOptions();
  859. if (pOpts)
  860. {
  861. LPCDOPTDATA pOptions = pOpts->GetCDOpts()->pCDData;
  862. if (pOptions)
  863. {
  864. if (g_fDisplayT)
  865. {
  866. pOptions->fDispMode = CDDISP_TRACKTIME;
  867. }
  868. if (g_fDisplayTr)
  869. {
  870. pOptions->fDispMode = CDDISP_TRACKREMAIN;
  871. }
  872. if (g_fDisplayD)
  873. {
  874. pOptions->fDispMode = CDDISP_CDTIME;
  875. }
  876. if (g_fDisplayDr)
  877. {
  878. pOptions->fDispMode = CDDISP_CDREMAIN;
  879. }
  880. } //end if poptions
  881. pOpts->UpdateRegistry();
  882. } //end if popts
  883. UpdateDisplay( DISPLAY_UPD_LED );
  884. } //end if point in rect of time
  885. }
  886. void LED_DrawVolume(HWND ledWnd, HDC hdc)
  887. {
  888. if (g_szMixerName == NULL)
  889. {
  890. return;
  891. }
  892. //only do it in "large mode"
  893. if (!LED_LargeMode(ledWnd))
  894. {
  895. g_fAllowDraw = TRUE; //allow drawing of title and artist
  896. return;
  897. }
  898. RECT volrect, wholerect;
  899. HWND hwndparent = GetParent(ledWnd);
  900. GetClientRect(hwndparent,&wholerect);
  901. //normalize the rect and set new left-hand side
  902. wholerect.bottom = (wholerect.bottom - wholerect.top);
  903. wholerect.top = 0;
  904. wholerect.right = (wholerect.right - wholerect.left);
  905. wholerect.left = INFO_AREA_OFFSET;
  906. volrect.bottom = wholerect.bottom - LOGO_Y_OFFSET;
  907. volrect.top = volrect.bottom - VOLUME_LINE_HEIGHT;
  908. volrect.left = wholerect.left;
  909. volrect.right = volrect.left + VOLUME_WIDTH;
  910. if (volrect.right > g_nLastXOrigin)
  911. {
  912. volrect.right = g_nLastXOrigin;
  913. }
  914. int nWidth = volrect.right-volrect.left;
  915. //setup
  916. HDC memDC = CreateCompatibleDC(hdc);
  917. HBITMAP hbmp = CreateCompatibleBitmap(hdc,wholerect.right-wholerect.left,wholerect.bottom-wholerect.top);
  918. HBITMAP holdBmp = (HBITMAP)SelectObject(memDC,hbmp);
  919. HBRUSH hbrBlack = CreateSolidBrush(RGB(0x00,0x00,0x00));
  920. HBRUSH hbrBlue = CreateSolidBrush(CurrentColorRef);
  921. HFONT horgFont = (HFONT)SelectObject(memDC,hLEDFontB);
  922. int nStepWidth = (nWidth / VOLUME_STEPS);
  923. int nRectWidth = nStepWidth - VOLUME_SPACING;
  924. //blank out the background
  925. FillRect(memDC,&wholerect,hbrBlack);
  926. DeleteObject(hbrBlack);
  927. SetTextColor(memDC,CurrentColorRef);
  928. SetBkColor(memDC, RGB(0x00,0x00,0x00));
  929. SIZE sz;
  930. RECT textrect;
  931. memcpy(&textrect,&wholerect,sizeof(textrect));
  932. GetTextExtentPoint32(memDC, g_szMixerName,_tcslen(g_szMixerName), &sz );
  933. textrect.right = textrect.left + sz.cx;
  934. textrect.bottom = volrect.top - 3;
  935. textrect.top = textrect.bottom - sz.cy;
  936. ExtTextOut(memDC,textrect.left,textrect.top,ETO_OPAQUE,&textrect,g_szMixerName,_tcslen(g_szMixerName),NULL);
  937. //draw lines
  938. float nVolLines = ((float)g_dwLevel / 65535) * VOLUME_STEPS;
  939. for (int i = 0; i < VOLUME_STEPS; i++)
  940. {
  941. RECT rect;
  942. int nLineTop = volrect.top+5;
  943. if ((i >= nVolLines) && (i != 0) && (i != VOLUME_STEPS -1))
  944. {
  945. nLineTop = volrect.bottom - ((volrect.bottom - nLineTop) / 4);
  946. }
  947. SetRect(&rect,
  948. volrect.left + (i * nStepWidth),
  949. nLineTop,
  950. volrect.left + (i * nStepWidth) + nRectWidth,
  951. volrect.bottom);
  952. FillRect(memDC,&rect,hbrBlue);
  953. }
  954. //blit from memory onto display and clean up
  955. BitBlt(hdc,wholerect.left,wholerect.top,nWidth,wholerect.bottom-wholerect.top,
  956. memDC,wholerect.left,wholerect.top,SRCCOPY);
  957. SelectObject(memDC,holdBmp);
  958. SelectObject(memDC,horgFont);
  959. DeleteDC(memDC);
  960. DeleteObject(hbmp);
  961. DeleteObject(hbrBlue);
  962. }
  963. //draws text and excludes its clipping rect
  964. //returns the bottom of the rectangle, so it can be used to do lines of text
  965. int DrawAndExclude(HDC hdc, TCHAR* szText, int xPos, int yPos, int nRight, HWND hwnd, int ToolID)
  966. {
  967. SIZE sizeText;
  968. GetTextExtentPoint32( hdc, szText, _tcslen(szText), &sizeText );
  969. RECT rc;
  970. rc.top = yPos;
  971. rc.left = xPos;
  972. rc.right = nRight;
  973. rc.bottom = rc.top + sizeText.cy;
  974. DrawText(hdc,szText,-1,&rc,DT_CALCRECT|DT_END_ELLIPSIS|DT_EXPANDTABS|DT_NOPREFIX|DT_SINGLELINE);
  975. //don't do drawing and clipping, or tooltip, for null strings
  976. if (_tcslen(szText)>0)
  977. {
  978. DrawText(hdc,szText,-1,&rc,DT_END_ELLIPSIS|DT_EXPANDTABS|DT_NOPREFIX|DT_SINGLELINE);
  979. ExcludeClipRect(hdc,rc.left,rc.top,rc.right,rc.bottom);
  980. LED_SetTool(hwnd,ToolID, rc.left, rc.top, rc.right, rc.bottom);
  981. }
  982. return (rc.bottom);
  983. }
  984. void LED_DrawLogo(HWND hwnd, HDC hdcLed, RECT* pPaintRect)
  985. {
  986. //check to see if we should even bother
  987. RECT rcParent;
  988. GetClientRect(GetParent(hwnd),&rcParent);
  989. RECT destrect, logorect;
  990. SetRect(&logorect,LOGO_X_OFFSET,(rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET,4+g_bmLogo.bmWidth,rcParent.bottom-LOGO_Y_OFFSET);
  991. if (!IntersectRect(&destrect,&logorect,pPaintRect))
  992. {
  993. return; //painting wasn't needed
  994. }
  995. HANDLE hLogoOrVendor = hbmpLogo;
  996. if ((g_fDownloading) && (hbmpVendorLogo))
  997. {
  998. hLogoOrVendor = hbmpVendorLogo;
  999. }
  1000. //draw the bitmap of the cd logo
  1001. DibBlt(hdcLed, // destination DC
  1002. LOGO_X_OFFSET, // x upper left
  1003. (rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET, // y upper left
  1004. // The next two lines specify the width and height.
  1005. -1,
  1006. -1,
  1007. hLogoOrVendor, // source image
  1008. 0, 0, // x and y upper left
  1009. SRCCOPY,0); // raster operation
  1010. ExcludeClipRect(hdcLed,LOGO_X_OFFSET,(rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET,4+g_bmLogo.bmWidth,rcParent.bottom-LOGO_Y_OFFSET);
  1011. LED_SetTool(hwnd,TOOLID_LOGO,LOGO_X_OFFSET,(rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET,4+g_bmLogo.bmWidth,rcParent.bottom-LOGO_Y_OFFSET);
  1012. }
  1013. void LED_GetTimeRect(HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen, RECT& rect)
  1014. {
  1015. RECT rcParent;
  1016. GetClientRect(GetParent(hwnd),&rcParent);
  1017. HFONT hOrgFont = (HFONT)SelectObject(hdcLed,hLEDFontL);
  1018. SIZE sz;
  1019. GetTextExtentPoint32( hdcLed, s, sLen, &sz );
  1020. rect.left = (rcParent.right - sz.cx) - LOGO_X_OFFSET;
  1021. rect.top = (rcParent.bottom - sz.cy) - LOGO_Y_OFFSET;
  1022. rect.bottom = rect.top + sz.cy + 3;
  1023. rect.right = rcParent.right - 3;
  1024. SelectObject( hdcLed, hOrgFont );
  1025. }
  1026. void LED_DrawInfo(HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen, RECT* pPaintRect)
  1027. {
  1028. //figure out where time text will be, so we don't run into it
  1029. RECT timerect;
  1030. LED_GetTimeRect(hwnd,hdcLed,s,sLen,timerect);
  1031. int xOrigin = timerect.left;
  1032. RECT rcParent;
  1033. GetClientRect(GetParent(hwnd),&rcParent);
  1034. RECT rc;
  1035. rc.bottom = rcParent.bottom;
  1036. rc.top = rcParent.top;
  1037. rc.left = rcParent.left + INFO_AREA_OFFSET;
  1038. rc.right = xOrigin;
  1039. RECT destrect;
  1040. if (!IntersectRect(&destrect,&rc,pPaintRect))
  1041. {
  1042. return; //painting wasn't needed
  1043. }
  1044. HFONT hOrgFont = (HFONT)SelectObject( hdcLed, hLEDFontB );
  1045. TCHAR szDisp[MAX_PATH];
  1046. TCHAR sztrack[MAX_PATH];
  1047. _tcscpy(sztrack,TEXT(""));
  1048. PTRACK_INF t;
  1049. if (CURRTRACK(g_CurrCdrom)!=NULL)
  1050. {
  1051. t = FindTrackNodeFromTocIndex( CURRTRACK(g_CurrCdrom)->TocIndex, ALLTRACKS( g_CurrCdrom ) );
  1052. if (t)
  1053. {
  1054. _tcscpy(sztrack,t->name);
  1055. }
  1056. }
  1057. LoadString(g_hInst, STR_DISPLAY_LABELS, szDisp, sizeof(szDisp)/sizeof(TCHAR));
  1058. DrawText( hdcLed, // handle to device context
  1059. szDisp, // pointer to string to draw
  1060. -1, // string length, in characters
  1061. &rc, // pointer to struct with formatting dimensions
  1062. DT_CALCRECT|DT_EXPANDTABS|DT_NOPREFIX);
  1063. rc.top = rcParent.top + ((rcParent.bottom - rc.bottom)/2);
  1064. rc.bottom = rcParent.bottom + ((rcParent.bottom - rc.bottom)/2);
  1065. rc.right = rc.left;
  1066. TCHAR szTitle[MAX_PATH];
  1067. _tcscpy(szTitle,TITLE(g_CurrCdrom));
  1068. if (_tcslen(szTitle)==0)
  1069. {
  1070. _tcscpy(szTitle,IdStr( STR_NEW_TITLE ));
  1071. }
  1072. int nNextLineTop = 0;
  1073. nNextLineTop = DrawAndExclude(hdcLed,szTitle,rc.right,rc.top,xOrigin,hwnd,TOOLID_TITLE);
  1074. nNextLineTop = DrawAndExclude(hdcLed,sztrack,rc.right,nNextLineTop,xOrigin,hwnd,TOOLID_TRACK);
  1075. DrawAndExclude(hdcLed,ARTIST(g_CurrCdrom),rc.right,nNextLineTop,xOrigin,hwnd,TOOLID_ARTIST);
  1076. SelectObject( hdcLed, hOrgFont );
  1077. }
  1078. void LED_DrawTrackMute(HWND hwnd, HDC hdcLed, RECT* pPaintRect)
  1079. {
  1080. RECT rcParent;
  1081. GetClientRect(GetParent(hwnd),&rcParent);
  1082. //draw the mute status, if present (or track number)
  1083. BOOL fDrawInfo = TRUE;
  1084. RECT muteRect;
  1085. muteRect.top = LOGO_Y_OFFSET;
  1086. muteRect.right = rcParent.right;
  1087. muteRect.left = rcParent.left;
  1088. muteRect.bottom = rcParent.bottom;
  1089. TCHAR mutestr[MAX_PATH];
  1090. if (g_fMute)
  1091. {
  1092. LoadString(g_hInst,STR_MUTE,mutestr,sizeof(mutestr)/sizeof(TCHAR));
  1093. }
  1094. else
  1095. {
  1096. TCHAR tempstr[MAX_PATH];
  1097. LoadString(g_hInst,STR_INIT_TRACK,tempstr,sizeof(tempstr)/sizeof(TCHAR));
  1098. if (CURRTRACK(g_CurrCdrom))
  1099. {
  1100. wsprintf(mutestr,tempstr,(CURRTRACK(g_CurrCdrom)->TocIndex)+1);
  1101. }
  1102. else
  1103. {
  1104. fDrawInfo = FALSE;
  1105. //remove the tooltip
  1106. TOOLINFO ti;
  1107. ti.cbSize = sizeof(TOOLINFO);
  1108. ti.uFlags = 0;
  1109. ti.hwnd = hwnd;
  1110. ti.hinst = g_hInst;
  1111. ti.uId = TOOLID_TRACKORMUTE;
  1112. ti.lpszText = LPSTR_TEXTCALLBACK;
  1113. SendMessage(g_hwndToolTips, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
  1114. }
  1115. }
  1116. if (fDrawInfo)
  1117. {
  1118. HFONT hOldFont;
  1119. hOldFont = (HFONT) SelectObject(hdcLed, hLEDFontB);
  1120. DrawText(hdcLed,mutestr,-1,&muteRect,DT_CALCRECT|DT_SINGLELINE);
  1121. muteRect.left = (rcParent.right - LOGO_X_OFFSET) - (muteRect.right - muteRect.left);
  1122. muteRect.right = rcParent.right - LOGO_X_OFFSET;
  1123. RECT destrect;
  1124. if (IntersectRect(&destrect,&muteRect,pPaintRect))
  1125. {
  1126. if (g_fMute)
  1127. {
  1128. SetTextColor(hdcLed,RGB(0xFF,0x00,0x00));
  1129. }
  1130. DrawText(hdcLed,mutestr,-1,&muteRect,DT_SINGLELINE);
  1131. ExcludeClipRect(hdcLed,muteRect.left,muteRect.top,muteRect.right,muteRect.bottom);
  1132. LED_SetTool(hwnd,TOOLID_TRACKORMUTE,muteRect.left,muteRect.top,muteRect.right,muteRect.bottom);
  1133. SetTextColor( hdcLed, CurrentColorRef );
  1134. }
  1135. // restore font
  1136. SelectObject(hdcLed, hOldFont);
  1137. } //end if draw info
  1138. }
  1139. /*****************************Private*Routine******************************\
  1140. * LED_DrawText
  1141. *
  1142. * Draws the LED display screen text (quickly). The text is centered
  1143. * vertically and horizontally. Only the backround is drawn if the g_fFlashed
  1144. * flag is set.
  1145. *
  1146. * History:
  1147. * 18-11-93 - StephenE - Created
  1148. *
  1149. \**************************************************************************/
  1150. void
  1151. LED_DrawText(
  1152. HWND hwnd,
  1153. HDC hdcLed,
  1154. LPCTSTR s,
  1155. int sLen
  1156. )
  1157. {
  1158. RECT rc;
  1159. SIZE sz;
  1160. int xOrigin;
  1161. int yOrigin;
  1162. BOOL fLargeMode = FALSE;
  1163. HWND hwndparent = GetParent(hwnd);
  1164. HFONT hOrgFont = NULL;
  1165. RECT rcParent;
  1166. GetClientRect(hwndparent,&rcParent);
  1167. if (LED_LargeMode(hwnd))
  1168. {
  1169. fLargeMode = TRUE;
  1170. }
  1171. else
  1172. {
  1173. //change the string to display the track info
  1174. if (CURRTRACK(g_CurrCdrom))
  1175. {
  1176. TCHAR tempstr[MAX_PATH];
  1177. wsprintf(tempstr,TEXT("[%i] %s"),CURRTRACK(g_CurrCdrom)->TocIndex+1,s);
  1178. _tcscpy((TCHAR*)s,tempstr);
  1179. sLen = _tcslen(s);
  1180. }
  1181. }
  1182. if (fLargeMode)
  1183. {
  1184. hOrgFont = (HFONT)SelectObject(hdcLed,hLEDFontL);
  1185. }
  1186. else
  1187. {
  1188. hOrgFont = (HFONT)SelectObject(hdcLed,hLEDFontS);
  1189. }
  1190. GetTextExtentPoint32( hdcLed, s, sLen, &sz );
  1191. if (fLargeMode)
  1192. {
  1193. xOrigin = (rcParent.right - sz.cx) - LOGO_X_OFFSET;
  1194. yOrigin = (rcParent.bottom - sz.cy) - LOGO_Y_OFFSET;
  1195. }
  1196. else
  1197. {
  1198. xOrigin = ((rcParent.right - rcParent.left) - sz.cx) / 2;
  1199. yOrigin = ((rcParent.bottom - rcParent.top) - sz.cy) / 2;
  1200. }
  1201. if (sLen==1)
  1202. {
  1203. xOrigin = g_nLastXOrigin;
  1204. }
  1205. else
  1206. {
  1207. g_nLastXOrigin = xOrigin;
  1208. }
  1209. if (fLargeMode)
  1210. {
  1211. if (!g_fAllowDraw)
  1212. {
  1213. int nRightClip = INFO_AREA_OFFSET + VOLUME_WIDTH;
  1214. if (nRightClip > xOrigin)
  1215. {
  1216. nRightClip = xOrigin;
  1217. }
  1218. ExcludeClipRect(hdcLed,INFO_AREA_OFFSET,rcParent.top,nRightClip,rcParent.bottom);
  1219. }
  1220. }
  1221. rc.top = yOrigin;
  1222. rc.bottom = rc.top + sz.cy + 3;
  1223. rc.left = xOrigin;
  1224. rc.right = rcParent.right - 3;
  1225. ExtTextOut( hdcLed, xOrigin, rc.top, ETO_OPAQUE, &rc, s, sLen, NULL);
  1226. ExcludeClipRect(hdcLed,rc.left,rc.top,rc.right,rc.bottom);
  1227. if (fLargeMode)
  1228. {
  1229. //set time rect to cover just the time values for clicking
  1230. SetRect(&g_timerect,rc.left,rc.top,rc.right,rc.bottom);
  1231. }
  1232. else
  1233. {
  1234. SIZE tracksz;
  1235. tracksz.cx = 0;
  1236. if (CURRTRACK(g_CurrCdrom))
  1237. {
  1238. TCHAR tempstr[MAX_PATH];
  1239. wsprintf(tempstr,TEXT("[%i]"),CURRTRACK(g_CurrCdrom)->TocIndex+1);
  1240. GetTextExtentPoint32( hdcLed, tempstr, _tcslen(tempstr), &tracksz );
  1241. LED_SetTool(hwnd,TOOLID_TRACKORMUTE,rcParent.left,rcParent.top,rc.left+tracksz.cx,rcParent.bottom);
  1242. }
  1243. else
  1244. {
  1245. rc.left = rcParent.left;
  1246. }
  1247. //set time rect to cover the part of the client area that isn't the track
  1248. SetRect(&g_timerect,rc.left+tracksz.cx,rcParent.top,rcParent.right,rcParent.bottom);
  1249. }
  1250. LED_SetTool(hwnd,TOOLID_TIME,g_timerect.left,g_timerect.top,g_timerect.right,g_timerect.bottom);
  1251. HBRUSH hbrBlack = CreateSolidBrush(RGB(0x00,0x00,0x00));
  1252. RECT rectLED;
  1253. GetClientRect(hwnd,&rectLED);
  1254. FillRect(hdcLed,&rectLED,hbrBlack);
  1255. DeleteObject(hbrBlack);
  1256. SelectObject(hdcLed, hOrgFont);
  1257. }
  1258. /*****************************Private*Routine******************************\
  1259. * LED_OnSetText
  1260. *
  1261. * Change the LED display text. Calling DefWindowProc ensures that the
  1262. * window text is saved correctly.
  1263. *
  1264. * History:
  1265. * 18-11-93 - StephenE - Created
  1266. *
  1267. \**************************************************************************/
  1268. void
  1269. LED_OnSetText(
  1270. HWND hwnd,
  1271. LPCTSTR lpszText
  1272. )
  1273. {
  1274. DefWindowProc( hwnd, WM_SETTEXT, 0, (LPARAM)lpszText);
  1275. if (LED_LargeMode(hwnd))
  1276. {
  1277. RECT rect;
  1278. HDC hdc = GetDC(hwnd);
  1279. LED_GetTimeRect(hwnd, hdc, lpszText, _tcslen(lpszText), rect);
  1280. ReleaseDC(hwnd,hdc);
  1281. rect.left = g_nLastXOrigin;
  1282. InvalidateRect(hwnd,&rect,FALSE);
  1283. }
  1284. else
  1285. {
  1286. InvalidateRect(hwnd,NULL,FALSE);
  1287. }
  1288. UpdateWindow(hwnd);
  1289. }
  1290. /*****************************Private*Routine******************************\
  1291. * LED_CreateLEDFonts
  1292. *
  1293. * Small font is 12pt MS Sans Serif
  1294. * Large font is 18pt MS Sans Serif
  1295. *
  1296. * History:
  1297. * dd-mm-94 - StephenE - Created
  1298. *
  1299. \**************************************************************************/
  1300. void
  1301. LED_CreateLEDFonts(
  1302. HDC hdc
  1303. )
  1304. {
  1305. LOGFONT lf;
  1306. int iLogPelsY;
  1307. iLogPelsY = GetDeviceCaps( hdc, LOGPIXELSY );
  1308. ZeroMemory( &lf, sizeof(lf) );
  1309. HFONT hTempFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  1310. GetObject(hTempFont,sizeof(lf),&lf);
  1311. lf.lfHeight = (-9 * iLogPelsY) / 72; /* 9pt */
  1312. if (lf.lfCharSet == ANSI_CHARSET)
  1313. {
  1314. lf.lfWeight = FW_BOLD;
  1315. }
  1316. lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  1317. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  1318. lf.lfQuality = PROOF_QUALITY;
  1319. lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
  1320. hLEDFontS = CreateFontIndirect(&lf);
  1321. lf.lfHeight = (-10 * iLogPelsY) / 72; /* 10 pt */
  1322. if (lf.lfCharSet == ANSI_CHARSET)
  1323. {
  1324. lf.lfWeight = FW_BOLD;
  1325. }
  1326. hLEDFontB = CreateFontIndirect(&lf);
  1327. lf.lfHeight = (-20 * iLogPelsY) / 72; /* 20 pt */
  1328. if (lf.lfCharSet == ANSI_CHARSET)
  1329. {
  1330. lf.lfWeight = FW_EXTRABOLD; /* extra bold */
  1331. }
  1332. hLEDFontL = CreateFontIndirect(&lf);
  1333. /*
  1334. ** If can't create either font set up some sensible defaults.
  1335. */
  1336. if ( hLEDFontL == NULL || hLEDFontS == NULL || hLEDFontB == NULL)
  1337. {
  1338. if ( hLEDFontL != NULL )
  1339. {
  1340. DeleteObject( hLEDFontL );
  1341. }
  1342. if ( hLEDFontS != NULL )
  1343. {
  1344. DeleteObject( hLEDFontS );
  1345. }
  1346. if ( hLEDFontB != NULL )
  1347. {
  1348. DeleteObject( hLEDFontB );
  1349. }
  1350. hLEDFontS = hLEDFontL = hLEDFontB = (HFONT)GetStockObject( ANSI_VAR_FONT );
  1351. }
  1352. }
  1353. /* -------------------------------------------------------------------------
  1354. ** Private functions for the Text class
  1355. ** -------------------------------------------------------------------------
  1356. */
  1357. void
  1358. Text_OnPaint(
  1359. HWND hwnd
  1360. );
  1361. LRESULT CALLBACK
  1362. TextWndProc(
  1363. HWND hwnd,
  1364. UINT message,
  1365. WPARAM wParam,
  1366. LPARAM lParam
  1367. );
  1368. void
  1369. Text_OnSetText(
  1370. HWND hwnd,
  1371. LPCTSTR lpszText
  1372. );
  1373. void
  1374. Text_OnSetFont(
  1375. HWND hwndCtl,
  1376. HFONT hfont,
  1377. BOOL fRedraw
  1378. );
  1379. /******************************Public*Routine******************************\
  1380. * Init_SJE_TextClass
  1381. *
  1382. * Called to register the text window class .
  1383. * This function must be called before the CD Player dialog box is created.
  1384. *
  1385. * History:
  1386. * 18-11-93 - StephenE - Created
  1387. *
  1388. \**************************************************************************/
  1389. BOOL
  1390. Init_SJE_TextClass(
  1391. HINSTANCE hInst
  1392. )
  1393. {
  1394. WNDCLASS wndclass;
  1395. ZeroMemory( &wndclass, sizeof(wndclass) );
  1396. /*
  1397. ** Register the Text window.
  1398. */
  1399. wndclass.lpfnWndProc = TextWndProc;
  1400. wndclass.hInstance = hInst;
  1401. wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  1402. wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  1403. wndclass.lpszClassName = g_szTextClassName;
  1404. return RegisterClass( &wndclass );
  1405. }
  1406. /******************************Public*Routine******************************\
  1407. * TextWndProc
  1408. *
  1409. * This routine handles the WM_PAINT and WM_SETTEXT messages
  1410. * for the "Text" display window.
  1411. *
  1412. * History:
  1413. * 18-11-93 - StephenE - Created
  1414. *
  1415. \**************************************************************************/
  1416. LRESULT CALLBACK
  1417. TextWndProc(
  1418. HWND hwnd,
  1419. UINT message,
  1420. WPARAM wParam,
  1421. LPARAM lParam
  1422. )
  1423. {
  1424. switch( message ) {
  1425. HANDLE_MSG( hwnd, WM_PAINT, Text_OnPaint );
  1426. HANDLE_MSG( hwnd, WM_SETTEXT, Text_OnSetText );
  1427. HANDLE_MSG( hwnd, WM_SETFONT, Text_OnSetFont );
  1428. }
  1429. return DefWindowProc( hwnd, message, wParam, lParam );
  1430. }
  1431. /*****************************Private*Routine******************************\
  1432. * Text_OnPaint
  1433. *
  1434. *
  1435. *
  1436. * History:
  1437. * 18-11-93 - StephenE - Created
  1438. *
  1439. \**************************************************************************/
  1440. void
  1441. Text_OnPaint(
  1442. HWND hwnd
  1443. )
  1444. {
  1445. PAINTSTRUCT ps;
  1446. TCHAR s[128];
  1447. int sLen;
  1448. HDC hdc;
  1449. RECT rc;
  1450. HFONT hfont;
  1451. HFONT hfontOrg;
  1452. LONG_PTR lStyle;
  1453. hdc = BeginPaint( hwnd, &ps );
  1454. GetWindowRect( hwnd, &rc );
  1455. MapWindowRect( GetDesktopWindow(), hwnd, &rc );
  1456. lStyle = GetWindowLongPtr( hwnd, GWL_STYLE );
  1457. sLen = GetWindowText( hwnd, s, 128 );
  1458. hfont = (HFONT)GetWindowLongPtr( hwnd, GWLP_USERDATA );
  1459. if ( hfont )
  1460. {
  1461. hfontOrg = (HFONT)SelectObject( hdc, hfont );
  1462. }
  1463. /*
  1464. ** Draw a frame around the window
  1465. */
  1466. DrawEdge( hdc, &rc, EDGE_SUNKEN, BF_RECT );
  1467. /*
  1468. ** Draw the text
  1469. */
  1470. SetBkColor( hdc, GetSysColor( COLOR_BTNFACE ) );
  1471. SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) );
  1472. rc.left = 1 + (2 * GetSystemMetrics(SM_CXBORDER));
  1473. DrawText( hdc, s, sLen, &rc,
  1474. DT_NOPREFIX | DT_LEFT | DT_VCENTER |
  1475. DT_NOCLIP | DT_SINGLELINE );
  1476. if ( hfontOrg ) {
  1477. SelectObject( hdc, hfontOrg );
  1478. }
  1479. EndPaint( hwnd, &ps );
  1480. }
  1481. /*****************************Private*Routine******************************\
  1482. * Text_OnSetText
  1483. *
  1484. * Change the text. Calling DefWindowProc ensures that the
  1485. * window text is saved correctly.
  1486. *
  1487. * History:
  1488. * 18-11-93 - StephenE - Created
  1489. *
  1490. \**************************************************************************/
  1491. void
  1492. Text_OnSetText(
  1493. HWND hwnd,
  1494. LPCTSTR lpszText
  1495. )
  1496. {
  1497. DefWindowProc( hwnd, WM_SETTEXT, 0, (LPARAM)lpszText);
  1498. InvalidateRect( hwnd, NULL, TRUE );
  1499. UpdateWindow( hwnd );
  1500. }
  1501. /*****************************Private*Routine******************************\
  1502. * Text_OnSetFont
  1503. *
  1504. * Sets the windows font
  1505. *
  1506. * History:
  1507. * 18-11-93 - StephenE - Created
  1508. *
  1509. \**************************************************************************/
  1510. void
  1511. Text_OnSetFont(
  1512. HWND hwnd,
  1513. HFONT hfont,
  1514. BOOL fRedraw
  1515. )
  1516. {
  1517. SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)hfont );
  1518. if ( fRedraw ) {
  1519. InvalidateRect( hwnd, NULL, TRUE );
  1520. UpdateWindow( hwnd );
  1521. }
  1522. }