/******************************Module*Header*******************************\ * Module Name: ledwnd.c * * Implementation of the LED window. * * * Created: 18-11-93 * Author: Stephen Estrop [StephenE] * * Copyright (c) 1993 Microsoft Corporation \**************************************************************************/ #pragma warning( once : 4201 4214 ) #define NOOLE #include /* required for all Windows applications */ #include #include #include /* contains portable ascii/unicode macros */ #include #include "playres.h" #include "cdplayer.h" #include "cdapi.h" #include "literals.h" #include "trklst.h" #define DECLARE_DATA #include "ledwnd.h" #include "dib.h" #include "..\cdopt\cdopt.h" #define WM_LED_INFO_PAINT (WM_USER+2000) //wparam = draw, lparam = volchanged state #define WM_LED_MUTE (WM_USER+2001) //wparam = unused, lparam = mute flag #define WM_LED_DOWNLOAD (WM_USER+2002) //wparam = unused, lparam = download flag #define WM_NET_CHANGEPROVIDER (WM_USER+1002) //wparam = unused, lparam = LPCDPROVIDER #define VOLUME_STEPS 40 #define VOLUME_SPACING 3 #define VOLUME_DELTA 0x2FF #define VOLUME_LINE_HEIGHT 28 #define VOLUME_WIDTH 290 #define TOOLID_STATUS 0 #define TOOLID_MODE 1 #define TOOLID_LOGO 2 #define TOOLID_TIME 3 #define TOOLID_TRACKORMUTE 4 #define TOOLID_TITLE 5 #define TOOLID_TRACK 6 #define TOOLID_ARTIST 7 #define LARGE_MODE_INDICATOR 400 #define LOGO_X_OFFSET 4 #define LOGO_Y_OFFSET 4 #define INFO_AREA_OFFSET 55 #define ANI_NOCD_FRAME 0 #define ANI_STOP_FRAME 1 #define ANI_LAST_PLAY_FRAME 4 #define ANI_PAUSE_FRAME 5 #define MODE_NORMAL_FRAME 0 #define MODE_REPEAT1_FRAME 1 #define MODE_REPEATALL_FRAME 2 #define MODE_INTRO_FRAME 3 #define MODE_RANDOM_FRAME 4 int g_nLastXOrigin = 0; BITMAP g_bmLogo; BOOL g_fAllowDraw = TRUE; DWORD g_dwLevel = 0; TCHAR* g_szMixerName = NULL; HWND g_hwndPlay = NULL; HWND g_hwndMode = NULL; HWND g_hwndDownload = NULL; DWORD g_dwLastState = CD_NO_CD; DWORD g_dwLastModeFrame = MODE_NORMAL_FRAME; COLORREF CurrentColorRef = RGB(0x00,0xFF,0xFF); BOOL g_fMute = TRUE; BOOL g_fDownloading = FALSE; LPCDPROVIDER g_pCurrentProvider = NULL; RECT g_timerect; HWND g_hwndToolTips = NULL; extern HINSTANCE g_hInst; /* ------------------------------------------------------------------------- ** Private functions for the LED class ** ------------------------------------------------------------------------- */ BOOL LED_OnCreate( HWND hwnd, LPCREATESTRUCT lpCreateStruct ); BOOL LED_LargeMode(HWND hwnd); void LED_OnPaint( HWND hwnd ); void LED_OnLButtonUp( HWND hwnd, int x, int y, UINT keyFlags ); void LED_OnSetText( HWND hwnd, LPCTSTR lpszText ); void LED_DrawText( HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen ); void LED_Animation(HDC hdc); void LED_DrawLogo( HWND hwnd, HDC hdcLed, RECT* pPaintRect); void LED_DrawInfo( HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen, RECT* pPaintRect ); void LED_DrawTrackMute( HWND hwnd, HDC hdcLed, RECT* pPaintRect); void LED_CreateLEDFonts( HDC hdc ); void LED_DrawVolume( HWND ledWnd, HDC hdc ); HANDLE hbmpLogo = NULL; HANDLE hbmpVendorLogo = NULL; /******************************Public*Routine******************************\ * InitLEDClass * * Called to register the LED window class and create a font for the LED * window to use. This function must be called before the CD Player dialog * box is created. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ BOOL InitLEDClass( HINSTANCE hInst ) { WNDCLASS LEDwndclass; HDC hdc; ZeroMemory( &LEDwndclass, sizeof(LEDwndclass) ); /* ** Register the LED window. */ LEDwndclass.lpfnWndProc = LEDWndProc; LEDwndclass.hInstance = hInst; LEDwndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); LEDwndclass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); LEDwndclass.lpszClassName = g_szLEDClassName; LEDwndclass.style = CS_OWNDC; hdc = GetDC( GetDesktopWindow() ); LED_CreateLEDFonts( hdc ); ReleaseDC( GetDesktopWindow(), hdc ); return RegisterClass( &LEDwndclass ); } void LED_OnDestroy(HWND hwnd) { if (hbmpLogo) { GlobalFree(hbmpLogo); hbmpLogo = NULL; } if ( hLEDFontL != NULL ) { DeleteObject( hLEDFontL ); } if ( hLEDFontS != NULL ) { DeleteObject( hLEDFontS ); } if ( hLEDFontB != NULL ) { DeleteObject( hLEDFontB ); } } //////////////////////////////////////////////////////////////////////////////////////////// // * LED_OnToolTipNotify // Called from tool tips to get the text they need to display //////////////////////////////////////////////////////////////////////////////////////////// VOID LED_OnToolTipNotify(HWND hwnd, LPARAM lParam) { LPTOOLTIPTEXT lpttt; UINT nID; if ((((LPNMHDR) lParam)->code) == TTN_NEEDTEXT) { nID = (UINT)((LPNMHDR)lParam)->idFrom; lpttt = (LPTOOLTIPTEXT)lParam; switch (nID) { case TOOLID_STATUS : { TCHAR szFormat[30]; TCHAR szStatus[30]; LoadString(g_hInst,STR_FORMAT_STATUS,szFormat,sizeof(szFormat)/sizeof(TCHAR)); if (g_fDownloading) { LoadString(g_hInst,STR_STATUS_DOWNLOADING,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } else { if (g_State & CD_PLAYING) { LoadString(g_hInst,STR_STATUS_PLAY,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } if (g_State & CD_STOPPED) { LoadString(g_hInst,STR_STATUS_STOP,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } if (g_State & CD_PAUSED) { LoadString(g_hInst,STR_STATUS_PAUSED,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } if ((g_State & CD_NO_CD) || (g_State & CD_DATA_CD_LOADED)) { LoadString(g_hInst,STR_STATUS_NODISC,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } } //end else wsprintf(lpttt->szText,szFormat,szStatus); } break; case TOOLID_MODE : { TCHAR szFormat[30]; TCHAR szStatus[30]; LoadString(g_hInst,STR_FORMAT_MODE,szFormat,sizeof(szFormat)/sizeof(TCHAR)); LoadString(g_hInst,STR_MODE_NORMAL,szStatus,sizeof(szStatus)/sizeof(TCHAR)); if (g_fContinuous) { LoadString(g_hInst,STR_MODE_REPEATALL,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } if (g_fIntroPlay) { LoadString(g_hInst,STR_MODE_INTROPLAY,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } if (!g_fSelectedOrder) { LoadString(g_hInst,STR_MODE_RANDOM,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } if (g_fRepeatSingle) { LoadString(g_hInst,STR_MODE_REPEATONE,szStatus,sizeof(szStatus)/sizeof(TCHAR)); } wsprintf(lpttt->szText,szFormat,szStatus); } break; case TOOLID_LOGO : { if (g_fDownloading) { _tcscpy(lpttt->szText,g_pCurrentProvider->szProviderName); } else { LoadString(g_hInst,STR_LOGO,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } } break; case TOOLID_TIME : { if (g_fDisplayT) { LoadString(g_hInst,STR_TRACK_TIME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } if (g_fDisplayTr) { LoadString(g_hInst,STR_TRACK_REMAINING,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } if (g_fDisplayD) { LoadString(g_hInst,STR_DISC_TIME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } if (g_fDisplayDr) { LoadString(g_hInst,STR_DISC_REMAINING,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } } break; case TOOLID_TRACKORMUTE : { BOOL fLargeMode = FALSE; if (LED_LargeMode(hwnd)) { fLargeMode = TRUE; } if ((g_fMute) && (fLargeMode)) { LoadString(g_hInst,STR_STATUS_MUTE,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } else { LoadString(g_hInst,STR_TRACK_NUMBER,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } } break; case TOOLID_TITLE : { if (g_fAllowDraw) { LoadString(g_hInst,STR_TITLE,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } else { LoadString(g_hInst,STR_VOLUME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } } break; case TOOLID_TRACK : { if (g_fAllowDraw) { LoadString(g_hInst,STR_TRACK,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } else { LoadString(g_hInst,STR_VOLUME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } } break; case TOOLID_ARTIST : { if (g_fAllowDraw) { LoadString(g_hInst,STR_ARTIST,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } else { LoadString(g_hInst,STR_VOLUME,lpttt->szText,sizeof(lpttt->szText)/sizeof(TCHAR)); } } break; } //end switch } return; } void DoDrawing(HWND hwnd, HDC hdc, RECT* pPaintRect) { int sLen; TCHAR s[MAX_PATH]; sLen = GetWindowText( hwnd, s, sizeof(s)/sizeof(TCHAR)); RECT wndRect; GetClientRect(hwnd,&wndRect); HPALETTE hPalOld = SelectPalette(hdc,g_pSink->GetPalette(),FALSE); RealizePalette(hdc); HDC memDC = CreateCompatibleDC(hdc); HPALETTE hPalOldMem = SelectPalette(hdc,g_pSink->GetPalette(),FALSE); RealizePalette(hdc); SetBkColor( memDC, RGB(0x00,0x00,0x00) ); SetTextColor( memDC, CurrentColorRef ); HBITMAP hbmp = CreateCompatibleBitmap(hdc,wndRect.right-wndRect.left,wndRect.bottom-wndRect.top); HBITMAP holdBmp = (HBITMAP)SelectObject(memDC,hbmp); if (LED_LargeMode(hwnd)) { LED_Animation(hdc); //use hdc to ensure the clip rect is not affecting these windows LED_DrawLogo(hwnd,memDC,pPaintRect); LED_DrawTrackMute(hwnd,memDC,pPaintRect); if (g_fAllowDraw) { LED_DrawInfo(hwnd,memDC, s, sLen,pPaintRect); } else { LED_DrawVolume(hwnd,memDC); } } else { //hide all animations ShowWindow(g_hwndPlay,SW_HIDE); ShowWindow(g_hwndMode,SW_HIDE); if (g_hwndDownload) { ShowWindow(g_hwndDownload,SW_HIDE); } } /* ** Draw the LED display text */ LED_DrawText( hwnd, memDC, s, sLen ); //blit from memory onto display and clean up BitBlt(hdc,wndRect.left,wndRect.top,wndRect.right-wndRect.left,wndRect.bottom-wndRect.top, memDC,0,0,SRCCOPY); SelectObject(memDC,holdBmp); DeleteObject(hbmp); SelectPalette(hdc,hPalOld,FALSE); RealizePalette(hdc); SelectPalette(memDC,hPalOldMem,FALSE); RealizePalette(memDC); DeleteDC(memDC); GetClientRect( hwnd, &wndRect ); HRGN region = CreateRectRgn(wndRect.left,wndRect.top,wndRect.right,wndRect.bottom); SelectClipRgn(hdc, region); DeleteObject(region); } BOOL LED_OnEraseBackground(HWND hwnd, HDC hdc) { //DoDrawing(hwnd,hdc); return TRUE; } /******************************Public*Routine******************************\ * LEDWndProc * * This routine handles the WM_PAINT and WM_SETTEXT messages * for the "LED" display window. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ LRESULT CALLBACK LEDWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { HANDLE_MSG( hwnd, WM_CREATE, LED_OnCreate ); HANDLE_MSG( hwnd, WM_DESTROY, LED_OnDestroy); HANDLE_MSG( hwnd, WM_PAINT, LED_OnPaint ); HANDLE_MSG( hwnd, WM_LBUTTONUP, LED_OnLButtonUp ); HANDLE_MSG( hwnd, WM_SETTEXT, LED_OnSetText ); HANDLE_MSG( hwnd, WM_ERASEBKGND, LED_OnEraseBackground); case WM_NOTIFY : { if ((((LPNMHDR)lParam)->code) == TTN_NEEDTEXT) { LED_OnToolTipNotify(hwnd,lParam); } } break; case WM_LBUTTONDOWN : case WM_MBUTTONDOWN : case WM_RBUTTONDOWN : case WM_MOUSEMOVE : { MSG msg; msg.lParam = lParam; msg.wParam = wParam; msg.message = message; msg.hwnd = hwnd; SendMessage(g_hwndToolTips, TTM_RELAYEVENT, 0, (LPARAM)&msg); } break; case WM_LED_INFO_PAINT : { g_fAllowDraw = (BOOL)wParam; if (!g_fAllowDraw) { MMONVOLCHANGED* pVolChange = (MMONVOLCHANGED*)lParam; g_szMixerName = pVolChange->szLineName; g_dwLevel = pVolChange->dwNewVolume; InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); } } break; case WM_LED_MUTE : { g_fMute = (BOOL)lParam; InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); } break; case WM_NET_CHANGEPROVIDER : { if (g_fDownloading) { if (hbmpVendorLogo) { GlobalFree(hbmpVendorLogo); hbmpVendorLogo = NULL; } LPCDPROVIDER pProv = (LPCDPROVIDER)lParam; if (pProv) { hbmpVendorLogo = OpenDIB(pProv->szProviderLogo,-1); g_pCurrentProvider = pProv; //if tool tip is showing, kill it TOOLINFO ti; ti.cbSize = sizeof(ti); if (SendMessage(g_hwndToolTips, TTM_GETCURRENTTOOL, 0, (LPARAM) (LPTOOLINFO) &ti)) { if (ti.uId == TOOLID_LOGO) { //fake a button down MSG msg; msg.lParam = 0; msg.wParam = 0; msg.message = WM_LBUTTONDOWN; msg.hwnd = hwnd; SendMessage(g_hwndToolTips, TTM_RELAYEVENT, 0, (LPARAM)&msg); } } } InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); } //end if downloading } break; case WM_LED_DOWNLOAD : { BOOL fDownloading = (BOOL)lParam; if (fDownloading == g_fDownloading) { //can get called multiple times for same mode break; } g_fDownloading = fDownloading; if (g_fDownloading) { //get the path to the vendor logo file LPCDOPT pOpts = (LPCDOPT)g_pSink->GetOptions(); if (pOpts) { LPCDOPTIONS pOptions = NULL; pOptions = pOpts->GetCDOpts(); if (pOptions) { if (pOptions->pCurrentProvider!=NULL) { hbmpVendorLogo = OpenDIB(pOptions->pCurrentProvider->szProviderLogo,-1); g_pCurrentProvider = pOptions->pCurrentProvider; } //end if current provider ok } //end if poptions ok } //end if popts created //create the downloading animation g_hwndDownload = Animate_Create(hwnd, IDI_ICON_ANI_DOWN, WS_CHILD, g_hInst); //headers don't have Animate_OpenEx yet, //so just do the straight call SendMessage(g_hwndDownload,ACM_OPEN,(WPARAM)g_hInst, (LPARAM)MAKEINTRESOURCE(IDI_ICON_ANI_DOWN)); //move to the top/left of the window RECT anirect; GetClientRect(g_hwndDownload,&anirect); MoveWindow(g_hwndDownload, LOGO_X_OFFSET, LOGO_Y_OFFSET, anirect.right - anirect.left, anirect.bottom - anirect.top, FALSE); Animate_Play(g_hwndDownload,0,-1,-1); ShowWindow(g_hwndPlay,SW_HIDE); ShowWindow(g_hwndDownload,SW_SHOW); if (hbmpVendorLogo) { InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); } } else { ShowWindow(g_hwndDownload,SW_HIDE); ShowWindow(g_hwndPlay,SW_SHOW); DestroyWindow(g_hwndDownload); g_hwndDownload = NULL; if (hbmpVendorLogo) { GlobalFree(hbmpVendorLogo); InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); } } } break; } return DefWindowProc( hwnd, message, wParam, lParam ); } void LED_SetTool(HWND hwnd, UINT toolID, int left, int top, int right, int bottom) { TOOLINFO ti; RECT toolRect; BOOL fAddTool = TRUE; SetRect(&toolRect,left,top,right,bottom); ti.cbSize = sizeof(TOOLINFO); ti.uFlags = 0; ti.hwnd = hwnd; ti.hinst = g_hInst; ti.uId = toolID; ti.lpszText = LPSTR_TEXTCALLBACK; //check to see if tool already exists if (SendMessage(g_hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) (LPTOOLINFO) &ti)) { //if tool exists, we don't want to add it ... fAddTool = FALSE; //... unless the rects have changed if (memcmp(&ti.rect,&toolRect,sizeof(RECT)) != 0) { SendMessage(g_hwndToolTips, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); fAddTool = TRUE; } } if (fAddTool) { SetRect(&ti.rect,left,top,right,bottom); SendMessage(g_hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); } } /*****************************Private*Routine******************************\ * LED_OnCreate * * * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ BOOL LED_OnCreate( HWND hwnd, LPCREATESTRUCT lpCreateStruct ) { HDC hdcLed; hdcLed = GetDC( hwnd ); SetTextColor( hdcLed, CurrentColorRef ); ReleaseDC( hwnd, hdcLed ); //create the tooltips g_hwndToolTips = CreateWindow(TOOLTIPS_CLASS, (LPTSTR) NULL, TTS_ALWAYSTIP | WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, (HMENU) NULL, g_hInst, NULL); //determine color depth HDC hdcScreen = GetDC(NULL); UINT uBPP = GetDeviceCaps(hdcScreen, PLANES) * GetDeviceCaps(hdcScreen, BITSPIXEL); ReleaseDC(NULL, hdcScreen); //load the logo HBITMAP hbmpTemp = NULL; if (uBPP == 4) //16-color { hbmpTemp = (HBITMAP)LoadImage(g_hInst,MAKEINTRESOURCE(IDB_CDLOGO_16),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION); } else { hbmpTemp = (HBITMAP)LoadImage(g_hInst,MAKEINTRESOURCE(IDB_CDLOGO),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION); } hbmpLogo = DibFromBitmap((HBITMAP)hbmpTemp,0,0,NULL,0); GetObject(hbmpTemp,sizeof(g_bmLogo),&g_bmLogo); DeleteObject(hbmpTemp); g_hwndPlay = Animate_Create(hwnd, IDI_ICON_ANI_PLAY, WS_CHILD, g_hInst); //headers don't have Animate_OpenEx yet, //so just do the straight call SendMessage(g_hwndPlay,ACM_OPEN,(WPARAM)g_hInst, (LPARAM)MAKEINTRESOURCE(IDI_ICON_ANI_PLAY)); //move to the top/left of the window RECT anirect; GetClientRect(g_hwndPlay,&anirect); MoveWindow(g_hwndPlay, LOGO_X_OFFSET, LOGO_Y_OFFSET, anirect.right - anirect.left, anirect.bottom - anirect.top, FALSE); LED_SetTool(hwnd,TOOLID_STATUS,anirect.left,anirect.top,anirect.right,anirect.bottom); ShowWindow(g_hwndPlay,SW_SHOW); g_hwndMode = Animate_Create(hwnd, IDI_ICON_ANI_MODE, WS_CHILD, g_hInst); //headers don't have Animate_OpenEx yet, //so just do the straight call SendMessage(g_hwndMode,ACM_OPEN,(WPARAM)g_hInst, (LPARAM)MAKEINTRESOURCE(IDI_ICON_ANI_MODE)); //move to the top/left of the window GetClientRect(g_hwndMode,&anirect); MoveWindow(g_hwndMode, (g_bmLogo.bmWidth - (anirect.right - anirect.left)) + LOGO_X_OFFSET, LOGO_Y_OFFSET, anirect.right - anirect.left, anirect.bottom - anirect.top, FALSE); LED_SetTool(hwnd,TOOLID_MODE, (g_bmLogo.bmWidth - (anirect.right - anirect.left)) + LOGO_X_OFFSET, LOGO_Y_OFFSET, g_bmLogo.bmWidth + LOGO_X_OFFSET, LOGO_Y_OFFSET + (anirect.bottom - anirect.top)); ShowWindow(g_hwndMode,SW_SHOW); //set the bounding rect for clicking on the time ... intialize to whole rect RECT rcParent; GetClientRect(hwnd,&rcParent); SetRect(&g_timerect,rcParent.left,rcParent.top,rcParent.right,rcParent.bottom); return TRUE; } void LED_Animation(HDC hdc) { ShowWindow(g_hwndMode,SW_SHOW); if (!g_fDownloading) { ShowWindow(g_hwndPlay,SW_SHOW); if (g_State != g_dwLastState) { g_dwLastState = g_State; Animate_Stop(g_hwndPlay); if (g_State & CD_PLAYING) { Animate_Play(g_hwndPlay,ANI_STOP_FRAME,ANI_LAST_PLAY_FRAME,-1); } if (g_State & CD_STOPPED) { Animate_Seek(g_hwndPlay,ANI_STOP_FRAME); } if (g_State & CD_PAUSED) { Animate_Play(g_hwndPlay,ANI_LAST_PLAY_FRAME,ANI_PAUSE_FRAME,-1); } if ((g_State & CD_NO_CD) || (g_State & CD_DATA_CD_LOADED)) { Animate_Seek(g_hwndPlay,ANI_NOCD_FRAME); } } } else { if (g_hwndDownload) { ShowWindow(g_hwndDownload,SW_SHOW); } } RECT rect; GetClientRect(g_hwndPlay,&rect); ExcludeClipRect(hdc, LOGO_X_OFFSET, LOGO_Y_OFFSET, (rect.right - rect.left) + LOGO_X_OFFSET, (rect.bottom - rect.top) + LOGO_Y_OFFSET); DWORD dwCurFrame = MODE_NORMAL_FRAME; if (g_fContinuous) { dwCurFrame = MODE_REPEATALL_FRAME; } if (g_fIntroPlay) { dwCurFrame = MODE_INTRO_FRAME; } if (!g_fSelectedOrder) { dwCurFrame = MODE_RANDOM_FRAME; } if (g_fRepeatSingle) { dwCurFrame = MODE_REPEAT1_FRAME; } if (dwCurFrame != g_dwLastModeFrame) { g_dwLastModeFrame = dwCurFrame; Animate_Seek(g_hwndMode,dwCurFrame); } GetClientRect(g_hwndMode,&rect); ExcludeClipRect(hdc, (g_bmLogo.bmWidth - (rect.right - rect.left)) + LOGO_X_OFFSET, LOGO_Y_OFFSET, g_bmLogo.bmWidth + LOGO_X_OFFSET, (rect.bottom - rect.top) + LOGO_Y_OFFSET); } BOOL LED_LargeMode(HWND hwnd) { RECT rcParent; GetClientRect(GetParent(hwnd),&rcParent); if (rcParent.right - rcParent.left < LARGE_MODE_INDICATOR) { return FALSE; } return TRUE; } /*****************************Private*Routine******************************\ * LED_OnPaint * * * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void LED_OnPaint( HWND hwnd ) { PAINTSTRUCT ps; HDC hdcLed; hdcLed = BeginPaint( hwnd, &ps ); DoDrawing(hwnd, hdcLed, &(ps.rcPaint)); EndPaint( hwnd, &ps ); } /*****************************Private*Routine******************************\ * LED_OnLButtonUp * * Rotate the time remaing buttons and then set the display accordingly. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void LED_OnLButtonUp( HWND hwnd, int x, int y, UINT keyFlags ) { BOOL b, b2; /* ** If this window is not the master display LED just return */ if ( GetWindowLongPtr(hwnd, GWLP_ID) != IDC_LED ) { return; } RECT rcParent; GetClientRect(GetParent(hwnd),&rcParent); POINT pt; pt.x = x; pt.y = y; //if we're downloading AND within the logo rect, launch the provider's url if ((g_fDownloading) && (g_pCurrentProvider)) { RECT logoRect; SetRect(&logoRect, LOGO_X_OFFSET, (rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET, LOGO_X_OFFSET + g_bmLogo.bmWidth, rcParent.bottom - LOGO_Y_OFFSET); if (PtInRect(&logoRect,pt)) { ShellExecute(NULL,_TEXT("open"),g_pCurrentProvider->szProviderHome,NULL,_TEXT(""),SW_NORMAL); return; } } //if button in time rect AND volume isn't showing, allow click if ((PtInRect(&g_timerect,pt)) && (g_fAllowDraw)) { b = g_fDisplayT; b2 = g_fDisplayD; g_fDisplayD = g_fDisplayTr; g_fDisplayT = g_fDisplayDr; g_fDisplayDr = b2; g_fDisplayTr = b; //reset options LPCDOPT pOpts = (LPCDOPT)g_pSink->GetOptions(); if (pOpts) { LPCDOPTDATA pOptions = pOpts->GetCDOpts()->pCDData; if (pOptions) { if (g_fDisplayT) { pOptions->fDispMode = CDDISP_TRACKTIME; } if (g_fDisplayTr) { pOptions->fDispMode = CDDISP_TRACKREMAIN; } if (g_fDisplayD) { pOptions->fDispMode = CDDISP_CDTIME; } if (g_fDisplayDr) { pOptions->fDispMode = CDDISP_CDREMAIN; } } //end if poptions pOpts->UpdateRegistry(); } //end if popts UpdateDisplay( DISPLAY_UPD_LED ); } //end if point in rect of time } void LED_DrawVolume(HWND ledWnd, HDC hdc) { if (g_szMixerName == NULL) { return; } //only do it in "large mode" if (!LED_LargeMode(ledWnd)) { g_fAllowDraw = TRUE; //allow drawing of title and artist return; } RECT volrect, wholerect; HWND hwndparent = GetParent(ledWnd); GetClientRect(hwndparent,&wholerect); //normalize the rect and set new left-hand side wholerect.bottom = (wholerect.bottom - wholerect.top); wholerect.top = 0; wholerect.right = (wholerect.right - wholerect.left); wholerect.left = INFO_AREA_OFFSET; volrect.bottom = wholerect.bottom - LOGO_Y_OFFSET; volrect.top = volrect.bottom - VOLUME_LINE_HEIGHT; volrect.left = wholerect.left; volrect.right = volrect.left + VOLUME_WIDTH; if (volrect.right > g_nLastXOrigin) { volrect.right = g_nLastXOrigin; } int nWidth = volrect.right-volrect.left; //setup HDC memDC = CreateCompatibleDC(hdc); HBITMAP hbmp = CreateCompatibleBitmap(hdc,wholerect.right-wholerect.left,wholerect.bottom-wholerect.top); HBITMAP holdBmp = (HBITMAP)SelectObject(memDC,hbmp); HBRUSH hbrBlack = CreateSolidBrush(RGB(0x00,0x00,0x00)); HBRUSH hbrBlue = CreateSolidBrush(CurrentColorRef); HFONT horgFont = (HFONT)SelectObject(memDC,hLEDFontB); int nStepWidth = (nWidth / VOLUME_STEPS); int nRectWidth = nStepWidth - VOLUME_SPACING; //blank out the background FillRect(memDC,&wholerect,hbrBlack); DeleteObject(hbrBlack); SetTextColor(memDC,CurrentColorRef); SetBkColor(memDC, RGB(0x00,0x00,0x00)); SIZE sz; RECT textrect; memcpy(&textrect,&wholerect,sizeof(textrect)); GetTextExtentPoint32(memDC, g_szMixerName,_tcslen(g_szMixerName), &sz ); textrect.right = textrect.left + sz.cx; textrect.bottom = volrect.top - 3; textrect.top = textrect.bottom - sz.cy; ExtTextOut(memDC,textrect.left,textrect.top,ETO_OPAQUE,&textrect,g_szMixerName,_tcslen(g_szMixerName),NULL); //draw lines float nVolLines = ((float)g_dwLevel / 65535) * VOLUME_STEPS; for (int i = 0; i < VOLUME_STEPS; i++) { RECT rect; int nLineTop = volrect.top+5; if ((i >= nVolLines) && (i != 0) && (i != VOLUME_STEPS -1)) { nLineTop = volrect.bottom - ((volrect.bottom - nLineTop) / 4); } SetRect(&rect, volrect.left + (i * nStepWidth), nLineTop, volrect.left + (i * nStepWidth) + nRectWidth, volrect.bottom); FillRect(memDC,&rect,hbrBlue); } //blit from memory onto display and clean up BitBlt(hdc,wholerect.left,wholerect.top,nWidth,wholerect.bottom-wholerect.top, memDC,wholerect.left,wholerect.top,SRCCOPY); SelectObject(memDC,holdBmp); SelectObject(memDC,horgFont); DeleteDC(memDC); DeleteObject(hbmp); DeleteObject(hbrBlue); } //draws text and excludes its clipping rect //returns the bottom of the rectangle, so it can be used to do lines of text int DrawAndExclude(HDC hdc, TCHAR* szText, int xPos, int yPos, int nRight, HWND hwnd, int ToolID) { SIZE sizeText; GetTextExtentPoint32( hdc, szText, _tcslen(szText), &sizeText ); RECT rc; rc.top = yPos; rc.left = xPos; rc.right = nRight; rc.bottom = rc.top + sizeText.cy; DrawText(hdc,szText,-1,&rc,DT_CALCRECT|DT_END_ELLIPSIS|DT_EXPANDTABS|DT_NOPREFIX|DT_SINGLELINE); //don't do drawing and clipping, or tooltip, for null strings if (_tcslen(szText)>0) { DrawText(hdc,szText,-1,&rc,DT_END_ELLIPSIS|DT_EXPANDTABS|DT_NOPREFIX|DT_SINGLELINE); ExcludeClipRect(hdc,rc.left,rc.top,rc.right,rc.bottom); LED_SetTool(hwnd,ToolID, rc.left, rc.top, rc.right, rc.bottom); } return (rc.bottom); } void LED_DrawLogo(HWND hwnd, HDC hdcLed, RECT* pPaintRect) { //check to see if we should even bother RECT rcParent; GetClientRect(GetParent(hwnd),&rcParent); RECT destrect, logorect; SetRect(&logorect,LOGO_X_OFFSET,(rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET,4+g_bmLogo.bmWidth,rcParent.bottom-LOGO_Y_OFFSET); if (!IntersectRect(&destrect,&logorect,pPaintRect)) { return; //painting wasn't needed } HANDLE hLogoOrVendor = hbmpLogo; if ((g_fDownloading) && (hbmpVendorLogo)) { hLogoOrVendor = hbmpVendorLogo; } //draw the bitmap of the cd logo DibBlt(hdcLed, // destination DC LOGO_X_OFFSET, // x upper left (rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET, // y upper left // The next two lines specify the width and height. -1, -1, hLogoOrVendor, // source image 0, 0, // x and y upper left SRCCOPY,0); // raster operation ExcludeClipRect(hdcLed,LOGO_X_OFFSET,(rcParent.bottom - g_bmLogo.bmHeight) - LOGO_Y_OFFSET,4+g_bmLogo.bmWidth,rcParent.bottom-LOGO_Y_OFFSET); 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); } void LED_GetTimeRect(HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen, RECT& rect) { RECT rcParent; GetClientRect(GetParent(hwnd),&rcParent); HFONT hOrgFont = (HFONT)SelectObject(hdcLed,hLEDFontL); SIZE sz; GetTextExtentPoint32( hdcLed, s, sLen, &sz ); rect.left = (rcParent.right - sz.cx) - LOGO_X_OFFSET; rect.top = (rcParent.bottom - sz.cy) - LOGO_Y_OFFSET; rect.bottom = rect.top + sz.cy + 3; rect.right = rcParent.right - 3; SelectObject( hdcLed, hOrgFont ); } void LED_DrawInfo(HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen, RECT* pPaintRect) { //figure out where time text will be, so we don't run into it RECT timerect; LED_GetTimeRect(hwnd,hdcLed,s,sLen,timerect); int xOrigin = timerect.left; RECT rcParent; GetClientRect(GetParent(hwnd),&rcParent); RECT rc; rc.bottom = rcParent.bottom; rc.top = rcParent.top; rc.left = rcParent.left + INFO_AREA_OFFSET; rc.right = xOrigin; RECT destrect; if (!IntersectRect(&destrect,&rc,pPaintRect)) { return; //painting wasn't needed } HFONT hOrgFont = (HFONT)SelectObject( hdcLed, hLEDFontB ); TCHAR szDisp[MAX_PATH]; TCHAR sztrack[MAX_PATH]; _tcscpy(sztrack,TEXT("")); PTRACK_INF t; if (CURRTRACK(g_CurrCdrom)!=NULL) { t = FindTrackNodeFromTocIndex( CURRTRACK(g_CurrCdrom)->TocIndex, ALLTRACKS( g_CurrCdrom ) ); if (t) { _tcscpy(sztrack,t->name); } } LoadString(g_hInst, STR_DISPLAY_LABELS, szDisp, sizeof(szDisp)/sizeof(TCHAR)); DrawText( hdcLed, // handle to device context szDisp, // pointer to string to draw -1, // string length, in characters &rc, // pointer to struct with formatting dimensions DT_CALCRECT|DT_EXPANDTABS|DT_NOPREFIX); rc.top = rcParent.top + ((rcParent.bottom - rc.bottom)/2); rc.bottom = rcParent.bottom + ((rcParent.bottom - rc.bottom)/2); rc.right = rc.left; TCHAR szTitle[MAX_PATH]; _tcscpy(szTitle,TITLE(g_CurrCdrom)); if (_tcslen(szTitle)==0) { _tcscpy(szTitle,IdStr( STR_NEW_TITLE )); } int nNextLineTop = 0; nNextLineTop = DrawAndExclude(hdcLed,szTitle,rc.right,rc.top,xOrigin,hwnd,TOOLID_TITLE); nNextLineTop = DrawAndExclude(hdcLed,sztrack,rc.right,nNextLineTop,xOrigin,hwnd,TOOLID_TRACK); DrawAndExclude(hdcLed,ARTIST(g_CurrCdrom),rc.right,nNextLineTop,xOrigin,hwnd,TOOLID_ARTIST); SelectObject( hdcLed, hOrgFont ); } void LED_DrawTrackMute(HWND hwnd, HDC hdcLed, RECT* pPaintRect) { RECT rcParent; GetClientRect(GetParent(hwnd),&rcParent); //draw the mute status, if present (or track number) BOOL fDrawInfo = TRUE; RECT muteRect; muteRect.top = LOGO_Y_OFFSET; muteRect.right = rcParent.right; muteRect.left = rcParent.left; muteRect.bottom = rcParent.bottom; TCHAR mutestr[MAX_PATH]; if (g_fMute) { LoadString(g_hInst,STR_MUTE,mutestr,sizeof(mutestr)/sizeof(TCHAR)); } else { TCHAR tempstr[MAX_PATH]; LoadString(g_hInst,STR_INIT_TRACK,tempstr,sizeof(tempstr)/sizeof(TCHAR)); if (CURRTRACK(g_CurrCdrom)) { wsprintf(mutestr,tempstr,(CURRTRACK(g_CurrCdrom)->TocIndex)+1); } else { fDrawInfo = FALSE; //remove the tooltip TOOLINFO ti; ti.cbSize = sizeof(TOOLINFO); ti.uFlags = 0; ti.hwnd = hwnd; ti.hinst = g_hInst; ti.uId = TOOLID_TRACKORMUTE; ti.lpszText = LPSTR_TEXTCALLBACK; SendMessage(g_hwndToolTips, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); } } if (fDrawInfo) { HFONT hOldFont; hOldFont = (HFONT) SelectObject(hdcLed, hLEDFontB); DrawText(hdcLed,mutestr,-1,&muteRect,DT_CALCRECT|DT_SINGLELINE); muteRect.left = (rcParent.right - LOGO_X_OFFSET) - (muteRect.right - muteRect.left); muteRect.right = rcParent.right - LOGO_X_OFFSET; RECT destrect; if (IntersectRect(&destrect,&muteRect,pPaintRect)) { if (g_fMute) { SetTextColor(hdcLed,RGB(0xFF,0x00,0x00)); } DrawText(hdcLed,mutestr,-1,&muteRect,DT_SINGLELINE); ExcludeClipRect(hdcLed,muteRect.left,muteRect.top,muteRect.right,muteRect.bottom); LED_SetTool(hwnd,TOOLID_TRACKORMUTE,muteRect.left,muteRect.top,muteRect.right,muteRect.bottom); SetTextColor( hdcLed, CurrentColorRef ); } // restore font SelectObject(hdcLed, hOldFont); } //end if draw info } /*****************************Private*Routine******************************\ * LED_DrawText * * Draws the LED display screen text (quickly). The text is centered * vertically and horizontally. Only the backround is drawn if the g_fFlashed * flag is set. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void LED_DrawText( HWND hwnd, HDC hdcLed, LPCTSTR s, int sLen ) { RECT rc; SIZE sz; int xOrigin; int yOrigin; BOOL fLargeMode = FALSE; HWND hwndparent = GetParent(hwnd); HFONT hOrgFont = NULL; RECT rcParent; GetClientRect(hwndparent,&rcParent); if (LED_LargeMode(hwnd)) { fLargeMode = TRUE; } else { //change the string to display the track info if (CURRTRACK(g_CurrCdrom)) { TCHAR tempstr[MAX_PATH]; wsprintf(tempstr,TEXT("[%i] %s"),CURRTRACK(g_CurrCdrom)->TocIndex+1,s); _tcscpy((TCHAR*)s,tempstr); sLen = _tcslen(s); } } if (fLargeMode) { hOrgFont = (HFONT)SelectObject(hdcLed,hLEDFontL); } else { hOrgFont = (HFONT)SelectObject(hdcLed,hLEDFontS); } GetTextExtentPoint32( hdcLed, s, sLen, &sz ); if (fLargeMode) { xOrigin = (rcParent.right - sz.cx) - LOGO_X_OFFSET; yOrigin = (rcParent.bottom - sz.cy) - LOGO_Y_OFFSET; } else { xOrigin = ((rcParent.right - rcParent.left) - sz.cx) / 2; yOrigin = ((rcParent.bottom - rcParent.top) - sz.cy) / 2; } if (sLen==1) { xOrigin = g_nLastXOrigin; } else { g_nLastXOrigin = xOrigin; } if (fLargeMode) { if (!g_fAllowDraw) { int nRightClip = INFO_AREA_OFFSET + VOLUME_WIDTH; if (nRightClip > xOrigin) { nRightClip = xOrigin; } ExcludeClipRect(hdcLed,INFO_AREA_OFFSET,rcParent.top,nRightClip,rcParent.bottom); } } rc.top = yOrigin; rc.bottom = rc.top + sz.cy + 3; rc.left = xOrigin; rc.right = rcParent.right - 3; ExtTextOut( hdcLed, xOrigin, rc.top, ETO_OPAQUE, &rc, s, sLen, NULL); ExcludeClipRect(hdcLed,rc.left,rc.top,rc.right,rc.bottom); if (fLargeMode) { //set time rect to cover just the time values for clicking SetRect(&g_timerect,rc.left,rc.top,rc.right,rc.bottom); } else { SIZE tracksz; tracksz.cx = 0; if (CURRTRACK(g_CurrCdrom)) { TCHAR tempstr[MAX_PATH]; wsprintf(tempstr,TEXT("[%i]"),CURRTRACK(g_CurrCdrom)->TocIndex+1); GetTextExtentPoint32( hdcLed, tempstr, _tcslen(tempstr), &tracksz ); LED_SetTool(hwnd,TOOLID_TRACKORMUTE,rcParent.left,rcParent.top,rc.left+tracksz.cx,rcParent.bottom); } else { rc.left = rcParent.left; } //set time rect to cover the part of the client area that isn't the track SetRect(&g_timerect,rc.left+tracksz.cx,rcParent.top,rcParent.right,rcParent.bottom); } LED_SetTool(hwnd,TOOLID_TIME,g_timerect.left,g_timerect.top,g_timerect.right,g_timerect.bottom); HBRUSH hbrBlack = CreateSolidBrush(RGB(0x00,0x00,0x00)); RECT rectLED; GetClientRect(hwnd,&rectLED); FillRect(hdcLed,&rectLED,hbrBlack); DeleteObject(hbrBlack); SelectObject(hdcLed, hOrgFont); } /*****************************Private*Routine******************************\ * LED_OnSetText * * Change the LED display text. Calling DefWindowProc ensures that the * window text is saved correctly. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void LED_OnSetText( HWND hwnd, LPCTSTR lpszText ) { DefWindowProc( hwnd, WM_SETTEXT, 0, (LPARAM)lpszText); if (LED_LargeMode(hwnd)) { RECT rect; HDC hdc = GetDC(hwnd); LED_GetTimeRect(hwnd, hdc, lpszText, _tcslen(lpszText), rect); ReleaseDC(hwnd,hdc); rect.left = g_nLastXOrigin; InvalidateRect(hwnd,&rect,FALSE); } else { InvalidateRect(hwnd,NULL,FALSE); } UpdateWindow(hwnd); } /*****************************Private*Routine******************************\ * LED_CreateLEDFonts * * Small font is 12pt MS Sans Serif * Large font is 18pt MS Sans Serif * * History: * dd-mm-94 - StephenE - Created * \**************************************************************************/ void LED_CreateLEDFonts( HDC hdc ) { LOGFONT lf; int iLogPelsY; iLogPelsY = GetDeviceCaps( hdc, LOGPIXELSY ); ZeroMemory( &lf, sizeof(lf) ); HFONT hTempFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); GetObject(hTempFont,sizeof(lf),&lf); lf.lfHeight = (-9 * iLogPelsY) / 72; /* 9pt */ if (lf.lfCharSet == ANSI_CHARSET) { lf.lfWeight = FW_BOLD; } lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS; hLEDFontS = CreateFontIndirect(&lf); lf.lfHeight = (-10 * iLogPelsY) / 72; /* 10 pt */ if (lf.lfCharSet == ANSI_CHARSET) { lf.lfWeight = FW_BOLD; } hLEDFontB = CreateFontIndirect(&lf); lf.lfHeight = (-20 * iLogPelsY) / 72; /* 20 pt */ if (lf.lfCharSet == ANSI_CHARSET) { lf.lfWeight = FW_EXTRABOLD; /* extra bold */ } hLEDFontL = CreateFontIndirect(&lf); /* ** If can't create either font set up some sensible defaults. */ if ( hLEDFontL == NULL || hLEDFontS == NULL || hLEDFontB == NULL) { if ( hLEDFontL != NULL ) { DeleteObject( hLEDFontL ); } if ( hLEDFontS != NULL ) { DeleteObject( hLEDFontS ); } if ( hLEDFontB != NULL ) { DeleteObject( hLEDFontB ); } hLEDFontS = hLEDFontL = hLEDFontB = (HFONT)GetStockObject( ANSI_VAR_FONT ); } } /* ------------------------------------------------------------------------- ** Private functions for the Text class ** ------------------------------------------------------------------------- */ void Text_OnPaint( HWND hwnd ); LRESULT CALLBACK TextWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ); void Text_OnSetText( HWND hwnd, LPCTSTR lpszText ); void Text_OnSetFont( HWND hwndCtl, HFONT hfont, BOOL fRedraw ); /******************************Public*Routine******************************\ * Init_SJE_TextClass * * Called to register the text window class . * This function must be called before the CD Player dialog box is created. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ BOOL Init_SJE_TextClass( HINSTANCE hInst ) { WNDCLASS wndclass; ZeroMemory( &wndclass, sizeof(wndclass) ); /* ** Register the Text window. */ wndclass.lpfnWndProc = TextWndProc; wndclass.hInstance = hInst; wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wndclass.lpszClassName = g_szTextClassName; return RegisterClass( &wndclass ); } /******************************Public*Routine******************************\ * TextWndProc * * This routine handles the WM_PAINT and WM_SETTEXT messages * for the "Text" display window. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ LRESULT CALLBACK TextWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { HANDLE_MSG( hwnd, WM_PAINT, Text_OnPaint ); HANDLE_MSG( hwnd, WM_SETTEXT, Text_OnSetText ); HANDLE_MSG( hwnd, WM_SETFONT, Text_OnSetFont ); } return DefWindowProc( hwnd, message, wParam, lParam ); } /*****************************Private*Routine******************************\ * Text_OnPaint * * * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void Text_OnPaint( HWND hwnd ) { PAINTSTRUCT ps; TCHAR s[128]; int sLen; HDC hdc; RECT rc; HFONT hfont; HFONT hfontOrg; LONG_PTR lStyle; hdc = BeginPaint( hwnd, &ps ); GetWindowRect( hwnd, &rc ); MapWindowRect( GetDesktopWindow(), hwnd, &rc ); lStyle = GetWindowLongPtr( hwnd, GWL_STYLE ); sLen = GetWindowText( hwnd, s, 128 ); hfont = (HFONT)GetWindowLongPtr( hwnd, GWLP_USERDATA ); if ( hfont ) { hfontOrg = (HFONT)SelectObject( hdc, hfont ); } /* ** Draw a frame around the window */ DrawEdge( hdc, &rc, EDGE_SUNKEN, BF_RECT ); /* ** Draw the text */ SetBkColor( hdc, GetSysColor( COLOR_BTNFACE ) ); SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) ); rc.left = 1 + (2 * GetSystemMetrics(SM_CXBORDER)); DrawText( hdc, s, sLen, &rc, DT_NOPREFIX | DT_LEFT | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE ); if ( hfontOrg ) { SelectObject( hdc, hfontOrg ); } EndPaint( hwnd, &ps ); } /*****************************Private*Routine******************************\ * Text_OnSetText * * Change the text. Calling DefWindowProc ensures that the * window text is saved correctly. * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void Text_OnSetText( HWND hwnd, LPCTSTR lpszText ) { DefWindowProc( hwnd, WM_SETTEXT, 0, (LPARAM)lpszText); InvalidateRect( hwnd, NULL, TRUE ); UpdateWindow( hwnd ); } /*****************************Private*Routine******************************\ * Text_OnSetFont * * Sets the windows font * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ void Text_OnSetFont( HWND hwnd, HFONT hfont, BOOL fRedraw ) { SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)hfont ); if ( fRedraw ) { InvalidateRect( hwnd, NULL, TRUE ); UpdateWindow( hwnd ); } }