1 /* 2 * PROJECT: ReactOS Cicero 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Cicero UIF Library 5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #include "precomp.h" 9 #include "cicuif.h" 10 11 ///////////////////////////////////////////////////////////////////////////// 12 // static members 13 14 HINSTANCE CUIFTheme::s_hUXTHEME = NULL; 15 FN_OpenThemeData CUIFTheme::s_fnOpenThemeData = NULL; 16 FN_CloseThemeData CUIFTheme::s_fnCloseThemeData = NULL; 17 FN_DrawThemeBackground CUIFTheme::s_fnDrawThemeBackground = NULL; 18 FN_DrawThemeParentBackground CUIFTheme::s_fnDrawThemeParentBackground = NULL; 19 FN_DrawThemeText CUIFTheme::s_fnDrawThemeText = NULL; 20 FN_DrawThemeIcon CUIFTheme::s_fnDrawThemeIcon = NULL; 21 FN_GetThemeBackgroundExtent CUIFTheme::s_fnGetThemeBackgroundExtent = NULL; 22 FN_GetThemeBackgroundContentRect CUIFTheme::s_fnGetThemeBackgroundContentRect = NULL; 23 FN_GetThemeTextExtent CUIFTheme::s_fnGetThemeTextExtent = NULL; 24 FN_GetThemePartSize CUIFTheme::s_fnGetThemePartSize = NULL; 25 FN_DrawThemeEdge CUIFTheme::s_fnDrawThemeEdge = NULL; 26 FN_GetThemeColor CUIFTheme::s_fnGetThemeColor = NULL; 27 FN_GetThemeMargins CUIFTheme::s_fnGetThemeMargins = NULL; 28 FN_GetThemeFont CUIFTheme::s_fnGetThemeFont = NULL; 29 FN_GetThemeSysColor CUIFTheme::s_fnGetThemeSysColor = NULL; 30 FN_GetThemeSysSize CUIFTheme::s_fnGetThemeSysSize = NULL; 31 32 CUIFSystemInfo *CUIFSystemInfo::s_pSystemInfo = NULL; 33 34 CUIFColorTableSys *CUIFScheme::s_pColorTableSys = NULL; 35 CUIFColorTableOff10 *CUIFScheme::s_pColorTableOff10 = NULL; 36 37 ///////////////////////////////////////////////////////////////////////////// 38 39 void CUIFSystemInfo::GetSystemMetrics() 40 { 41 HDC hDC = ::GetDC(NULL); 42 m_cBitsPixels = ::GetDeviceCaps(hDC, BITSPIXEL); 43 ::ReleaseDC(NULL, hDC); 44 45 HIGHCONTRAST HighContrast = { sizeof(HighContrast) }; 46 ::SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HighContrast), &HighContrast, 0); 47 m_bHighContrast1 = !!(HighContrast.dwFlags & HCF_HIGHCONTRASTON); 48 COLORREF rgbBtnText = ::GetSysColor(COLOR_BTNTEXT); 49 COLORREF rgbBtnFace = ::GetSysColor(COLOR_BTNFACE); 50 const COLORREF black = RGB(0, 0, 0), white = RGB(255, 255, 255); 51 m_bHighContrast2 = (m_bHighContrast1 || 52 (rgbBtnText == black && rgbBtnFace == white) || 53 (rgbBtnText == white && rgbBtnFace == black)); 54 } 55 56 void CUIFSystemInfo::Initialize() 57 { 58 dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 59 ::GetVersionEx(this); 60 GetSystemMetrics(); 61 } 62 63 ///////////////////////////////////////////////////////////////////////////// 64 // CUIFTheme 65 66 HRESULT CUIFTheme::InternalOpenThemeData(HWND hWnd) 67 { 68 if (!hWnd || !m_pszClassList) 69 return E_FAIL; 70 71 if (!cicGetFN(s_hUXTHEME, s_fnOpenThemeData, TEXT("uxtheme.dll"), "OpenThemeData")) 72 return E_FAIL; 73 m_hTheme = s_fnOpenThemeData(hWnd, m_pszClassList); 74 return (m_hTheme ? S_OK : E_FAIL); 75 } 76 77 HRESULT CUIFTheme::EnsureThemeData(HWND hWnd) 78 { 79 if (m_hTheme) 80 return S_OK; 81 return InternalOpenThemeData(hWnd); 82 } 83 84 HRESULT CUIFTheme::CloseThemeData() 85 { 86 if (!m_hTheme) 87 return S_OK; 88 89 if (!cicGetFN(s_hUXTHEME, s_fnCloseThemeData, TEXT("uxtheme.dll"), "CloseThemeData")) 90 return E_FAIL; 91 92 HRESULT hr = s_fnCloseThemeData(m_hTheme); 93 m_hTheme = NULL; 94 return hr; 95 } 96 97 STDMETHODIMP 98 CUIFTheme::DrawThemeBackground(HDC hDC, int iStateId, LPCRECT pRect, LPCRECT pClipRect) 99 { 100 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeBackground, TEXT("uxtheme.dll"), "DrawThemeBackground")) 101 return E_FAIL; 102 return s_fnDrawThemeBackground(m_hTheme, hDC, m_iPartId, iStateId, pRect, pClipRect); 103 } 104 105 STDMETHODIMP 106 CUIFTheme::DrawThemeParentBackground(HWND hwnd, HDC hDC, LPRECT prc) 107 { 108 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeParentBackground, TEXT("uxtheme.dll"), "DrawThemeParentBackground")) 109 return E_FAIL; 110 return s_fnDrawThemeParentBackground(hwnd, hDC, prc); 111 } 112 113 STDMETHODIMP 114 CUIFTheme::DrawThemeText(HDC hDC, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect) 115 { 116 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeText, TEXT("uxtheme.dll"), "DrawThemeText")) 117 return E_FAIL; 118 return s_fnDrawThemeText(m_hTheme, hDC, m_iPartId, iStateId, pszText, cchText, dwTextFlags, dwTextFlags2, pRect); 119 } 120 121 STDMETHODIMP 122 CUIFTheme::DrawThemeIcon(HDC hDC, int iStateId, LPCRECT pRect, HIMAGELIST himl, int iImageIndex) 123 { 124 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeIcon, TEXT("uxtheme.dll"), "DrawThemeIcon")) 125 return E_FAIL; 126 return s_fnDrawThemeIcon(m_hTheme, hDC, m_iPartId, iStateId, pRect, himl, iImageIndex); 127 } 128 129 STDMETHODIMP 130 CUIFTheme::GetThemeBackgroundExtent(HDC hDC, int iStateId, LPCRECT pContentRect, LPRECT pExtentRect) 131 { 132 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeBackgroundExtent, TEXT("uxtheme.dll"), "GetThemeBackgroundExtent")) 133 return E_FAIL; 134 return s_fnGetThemeBackgroundExtent(m_hTheme, hDC, m_iPartId, iStateId, pContentRect, pExtentRect); 135 } 136 137 STDMETHODIMP 138 CUIFTheme::GetThemeBackgroundContentRect(HDC hDC, int iStateId, LPCRECT pBoundingRect, LPRECT pContentRect) 139 { 140 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeBackgroundContentRect, TEXT("uxtheme.dll"), "GetThemeBackgroundContentRect")) 141 return E_FAIL; 142 return s_fnGetThemeBackgroundContentRect(m_hTheme, hDC, m_iPartId, iStateId, pBoundingRect, pContentRect); 143 } 144 145 STDMETHODIMP 146 CUIFTheme::GetThemeTextExtent(HDC hDC, int iStateId, LPCWSTR pszText, int cchCharCount, DWORD dwTextFlags, LPCRECT pBoundingRect, LPRECT pExtentRect) 147 { 148 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeTextExtent, TEXT("uxtheme.dll"), "GetThemeTextExtent")) 149 return E_FAIL; 150 return s_fnGetThemeTextExtent(m_hTheme, hDC, m_iPartId, iStateId, pszText, cchCharCount, dwTextFlags, pBoundingRect, pExtentRect); 151 } 152 153 STDMETHODIMP 154 CUIFTheme::GetThemePartSize(HDC hDC, int iStateId, LPRECT prc, THEMESIZE eSize, SIZE *psz) 155 { 156 if (!cicGetFN(s_hUXTHEME, s_fnGetThemePartSize, TEXT("uxtheme.dll"), "GetThemePartSize")) 157 return E_FAIL; 158 return s_fnGetThemePartSize(m_hTheme, hDC, m_iPartId, iStateId, prc, eSize, psz); 159 } 160 161 STDMETHODIMP 162 CUIFTheme::DrawThemeEdge(HDC hDC, int iStateId, LPCRECT pDestRect, UINT uEdge, UINT uFlags, LPRECT pContentRect) 163 { 164 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeEdge, TEXT("uxtheme.dll"), "DrawThemeEdge")) 165 return E_FAIL; 166 return s_fnDrawThemeEdge(m_hTheme, hDC, m_iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect); 167 } 168 169 STDMETHODIMP 170 CUIFTheme::GetThemeColor(int iStateId, int iPropId, COLORREF *pColor) 171 { 172 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeColor, TEXT("uxtheme.dll"), "GetThemeColor")) 173 return E_FAIL; 174 return s_fnGetThemeColor(m_hTheme, m_iPartId, iStateId, iPropId, pColor); 175 } 176 177 STDMETHODIMP 178 CUIFTheme::GetThemeMargins(HDC hDC, int iStateId, int iPropId, LPRECT prc, MARGINS *pMargins) 179 { 180 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeMargins, TEXT("uxtheme.dll"), "GetThemeMargins")) 181 return E_FAIL; 182 return s_fnGetThemeMargins(m_hTheme, hDC, m_iPartId, iStateId, iPropId, prc, pMargins); 183 } 184 185 STDMETHODIMP 186 CUIFTheme::GetThemeFont(HDC hDC, int iStateId, int iPropId, LOGFONTW *pFont) 187 { 188 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeFont, TEXT("uxtheme.dll"), "GetThemeFont")) 189 return E_FAIL; 190 return s_fnGetThemeFont(m_hTheme, hDC, m_iPartId, iStateId, iPropId, pFont); 191 } 192 193 STDMETHODIMP_(COLORREF) 194 CUIFTheme::GetThemeSysColor(INT iColorId) 195 { 196 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeSysColor, TEXT("uxtheme.dll"), "GetThemeSysColor")) 197 return RGB(0, 0, 0); 198 return s_fnGetThemeSysColor(m_hTheme, iColorId); 199 } 200 201 STDMETHODIMP_(int) 202 CUIFTheme::GetThemeSysSize(int iSizeId) 203 { 204 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeSysSize, TEXT("uxtheme.dll"), "GetThemeSysSize")) 205 return 0; 206 return s_fnGetThemeSysSize(m_hTheme, iSizeId); 207 } 208 209 STDMETHODIMP_(void) 210 CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId) 211 { 212 m_iPartId = iPartId; 213 m_iStateId = iStateId; 214 m_pszClassList = pszClassList; 215 } 216 217 ///////////////////////////////////////////////////////////////////////////// 218 // CUIFObject 219 220 /// @unimplemented 221 CUIFObject::CUIFObject(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style) 222 { 223 m_pszClassList = NULL; 224 m_hTheme = NULL; 225 m_pParent = pParent; 226 m_nObjectID = nObjectID; 227 m_style = style; 228 229 if (prc) 230 m_rc = *prc; 231 else 232 m_rc = { 0, 0, 0, 0 }; 233 234 if (m_pParent) 235 { 236 m_pWindow = m_pParent->m_pWindow; 237 m_pScheme = m_pParent->m_pScheme; 238 } 239 else 240 { 241 m_pWindow = NULL; 242 m_pScheme = NULL; 243 } 244 245 m_bEnable = m_bVisible = TRUE; 246 247 m_hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); 248 m_bHasCustomFont = FALSE; 249 250 m_pszToolTip = NULL; 251 252 m_dwUnknown4[0] = -1; //FIXME: name 253 m_dwUnknown4[1] = -1; //FIXME: name 254 } 255 256 CUIFObject::~CUIFObject() 257 { 258 if (m_pWindow) 259 { 260 CUIFToolTip *pToolTip = m_pWindow->m_pToolTip; 261 if (pToolTip && pToolTip->m_pToolTipTarget == this) 262 pToolTip->m_pToolTipTarget = NULL; 263 } 264 265 if (m_pszToolTip) 266 { 267 delete[] m_pszToolTip; 268 m_pszToolTip = NULL; 269 } 270 271 for (size_t iObj = m_ObjectArray.size(); iObj > 0; ) 272 { 273 --iObj; 274 delete m_ObjectArray[iObj]; 275 } 276 m_ObjectArray.clear(); 277 278 if (m_pWindow) 279 m_pWindow->RemoveUIObj(this); 280 281 CloseThemeData(); 282 } 283 284 STDMETHODIMP_(void) CUIFObject::OnPaint(HDC hDC) 285 { 286 if (!(m_pWindow->m_style & UIF_WINDOW_ENABLETHEMED) || !OnPaintTheme(hDC)) 287 OnPaintNoTheme(hDC); 288 } 289 290 STDMETHODIMP_(BOOL) CUIFObject::OnSetCursor(UINT uMsg, LONG x, LONG y) 291 { 292 return FALSE; 293 } 294 295 STDMETHODIMP_(void) CUIFObject::GetRect(LPRECT prc) 296 { 297 *prc = m_rc; 298 } 299 300 STDMETHODIMP_(BOOL) CUIFObject::PtInObject(POINT pt) 301 { 302 return m_bVisible && ::PtInRect(&m_rc, pt); 303 } 304 305 STDMETHODIMP_(void) CUIFObject::PaintObject(HDC hDC, LPCRECT prc) 306 { 307 if (!m_bVisible) 308 return; 309 310 if (!prc) 311 prc = &m_rc; 312 313 OnPaint(hDC); 314 315 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 316 { 317 CUIFObject *pObject = m_ObjectArray[iItem]; 318 RECT rc; 319 if (::IntersectRect(&rc, prc, &pObject->m_rc)) 320 pObject->PaintObject(hDC, &rc); 321 } 322 } 323 324 STDMETHODIMP_(void) CUIFObject::CallOnPaint() 325 { 326 if (m_pWindow) 327 m_pWindow->UpdateUI(&m_rc); 328 } 329 330 STDMETHODIMP_(void) CUIFObject::Enable(BOOL bEnable) 331 { 332 if (m_bEnable == bEnable) 333 return; 334 335 m_bEnable = bEnable; 336 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 337 m_ObjectArray[iItem]->Enable(bEnable); 338 339 CallOnPaint(); 340 } 341 342 STDMETHODIMP_(void) CUIFObject::Show(BOOL bVisible) 343 { 344 if (m_bVisible == bVisible) 345 return; 346 347 m_bVisible = bVisible; 348 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 349 m_ObjectArray[iItem]->Show(bVisible); 350 351 if (m_bVisible || m_pParent) 352 m_pParent->CallOnPaint(); 353 } 354 355 STDMETHODIMP_(void) CUIFObject::SetFontToThis(HFONT hFont) 356 { 357 m_bHasCustomFont = !!hFont; 358 if (!hFont) 359 hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); 360 m_hFont = hFont; 361 } 362 363 STDMETHODIMP_(void) CUIFObject::SetFont(HFONT hFont) 364 { 365 SetFontToThis(hFont); 366 367 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 368 m_ObjectArray[iItem]->SetFont(hFont); 369 370 CallOnPaint(); 371 } 372 373 STDMETHODIMP_(void) CUIFObject::SetStyle(DWORD style) 374 { 375 m_style = style; 376 } 377 378 STDMETHODIMP_(void) CUIFObject::AddUIObj(CUIFObject *pObject) 379 { 380 m_ObjectArray.Add(pObject); 381 CallOnPaint(); 382 } 383 384 STDMETHODIMP_(void) CUIFObject::RemoveUIObj(CUIFObject *pObject) 385 { 386 if (m_ObjectArray.Remove(pObject)) 387 CallOnPaint(); 388 } 389 390 STDMETHODIMP_(LRESULT) CUIFObject::OnObjectNotify(CUIFObject *pObject, WPARAM wParam, LPARAM lParam) 391 { 392 if (m_pParent) 393 return m_pParent->OnObjectNotify(pObject, wParam, lParam); 394 return 0; 395 } 396 397 STDMETHODIMP_(void) CUIFObject::SetToolTip(LPCWSTR pszToolTip) 398 { 399 if (m_pszToolTip) 400 { 401 delete[] m_pszToolTip; 402 m_pszToolTip = NULL; 403 } 404 405 if (pszToolTip) 406 { 407 size_t cch = wcslen(pszToolTip); 408 m_pszToolTip = new(cicNoThrow) WCHAR[cch + 1]; 409 if (m_pszToolTip) 410 lstrcpynW(m_pszToolTip, pszToolTip, cch + 1); 411 } 412 } 413 414 STDMETHODIMP_(void) CUIFObject::ClearWndObj() 415 { 416 m_pWindow = NULL; 417 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 418 m_ObjectArray[iItem]->ClearWndObj(); 419 } 420 421 STDMETHODIMP_(void) CUIFObject::ClearTheme() 422 { 423 CloseThemeData(); 424 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 425 m_ObjectArray[iItem]->ClearTheme(); 426 } 427 428 void CUIFObject::StartCapture() 429 { 430 if (m_pWindow) 431 m_pWindow->SetCaptureObject(this); 432 } 433 434 void CUIFObject::EndCapture() 435 { 436 if (m_pWindow) 437 m_pWindow->SetCaptureObject(NULL); 438 } 439 440 BOOL CUIFObject::IsCapture() 441 { 442 return m_pWindow && (m_pWindow->m_pCaptured == this); 443 } 444 445 void CUIFObject::SetRect(LPCRECT prc) 446 { 447 m_rc = *prc; 448 if (m_pWindow) 449 m_pWindow->OnObjectMoved(this); 450 CallOnPaint(); 451 } 452 453 LRESULT CUIFObject::NotifyCommand(WPARAM wParam, LPARAM lParam) 454 { 455 if (m_pParent) 456 return m_pParent->OnObjectNotify(this, wParam, lParam); 457 return 0; 458 } 459 460 void CUIFObject::DetachWndObj() 461 { 462 if (m_pWindow) 463 { 464 CUIFToolTip *pToolTip = m_pWindow->m_pToolTip; 465 if (pToolTip && pToolTip->m_pToolTipTarget == this) 466 pToolTip->m_pToolTipTarget = NULL; 467 468 m_pWindow->RemoveUIObj(this); 469 m_pWindow = NULL; 470 } 471 } 472 473 BOOL CUIFObject::IsRTL() 474 { 475 if (!m_pWindow) 476 return FALSE; 477 return !!(m_pWindow->m_style & UIF_WINDOW_LAYOUTRTL); 478 } 479 480 CUIFObject* CUIFObject::ObjectFromPoint(POINT pt) 481 { 482 if (!PtInObject(pt)) 483 return NULL; 484 485 CUIFObject *pFound = this; 486 for (size_t i = 0; i < m_ObjectArray.size(); ++i) 487 { 488 CUIFObject *pObject = m_ObjectArray[i]->ObjectFromPoint(pt); 489 if (pObject) 490 pFound = pObject; 491 } 492 return pFound; 493 } 494 495 void CUIFObject::SetScheme(CUIFScheme *scheme) 496 { 497 m_pScheme = scheme; 498 for (size_t i = 0; i < m_ObjectArray.size(); ++i) 499 { 500 m_ObjectArray[i]->SetScheme(scheme); 501 } 502 } 503 504 void CUIFObject::StartTimer(WPARAM wParam) 505 { 506 if (m_pWindow) 507 m_pWindow->SetTimerObject(this, wParam); 508 } 509 510 void CUIFObject::EndTimer() 511 { 512 if (m_pWindow) 513 m_pWindow->SetTimerObject(NULL, 0); 514 } 515 516 ///////////////////////////////////////////////////////////////////////////// 517 // CUIFColorTable... 518 519 STDMETHODIMP_(void) CUIFColorTableSys::InitColor() 520 { 521 m_rgbColors[0] = ::GetSysColor(COLOR_BTNFACE); 522 m_rgbColors[1] = ::GetSysColor(COLOR_BTNSHADOW); 523 m_rgbColors[2] = ::GetSysColor(COLOR_ACTIVEBORDER); 524 m_rgbColors[3] = ::GetSysColor(COLOR_ACTIVECAPTION); 525 m_rgbColors[4] = ::GetSysColor(COLOR_BTNFACE); 526 m_rgbColors[5] = ::GetSysColor(COLOR_BTNSHADOW); 527 m_rgbColors[6] = ::GetSysColor(COLOR_BTNTEXT); 528 m_rgbColors[7] = ::GetSysColor(COLOR_CAPTIONTEXT); 529 m_rgbColors[8] = ::GetSysColor(COLOR_GRAYTEXT); 530 m_rgbColors[9] = ::GetSysColor(COLOR_HIGHLIGHT); 531 m_rgbColors[10] = ::GetSysColor(COLOR_HIGHLIGHTTEXT); 532 m_rgbColors[11] = ::GetSysColor(COLOR_INACTIVECAPTION); 533 m_rgbColors[12] = ::GetSysColor(COLOR_INACTIVECAPTIONTEXT); 534 m_rgbColors[13] = ::GetSysColor(COLOR_MENUTEXT); 535 m_rgbColors[14] = ::GetSysColor(COLOR_WINDOW); 536 m_rgbColors[15] = ::GetSysColor(COLOR_WINDOWTEXT); 537 } 538 539 STDMETHODIMP_(void) CUIFColorTableSys::InitBrush() 540 { 541 ZeroMemory(m_hBrushes, sizeof(m_hBrushes)); 542 } 543 544 STDMETHODIMP_(void) CUIFColorTableSys::DoneBrush() 545 { 546 for (size_t i = 0; i < _countof(m_hBrushes); ++i) 547 { 548 if (m_hBrushes[i]) 549 { 550 ::DeleteObject(m_hBrushes[i]); 551 m_hBrushes[i] = NULL; 552 } 553 } 554 } 555 556 HBRUSH CUIFColorTableSys::GetBrush(INT iColor) 557 { 558 if (!m_hBrushes[iColor]) 559 m_hBrushes[iColor] = ::CreateSolidBrush(m_rgbColors[iColor]); 560 return m_hBrushes[iColor]; 561 } 562 563 HBRUSH CUIFColorTableOff10::GetBrush(INT iColor) 564 { 565 if (!m_hBrushes[iColor]) 566 m_hBrushes[iColor] = ::CreateSolidBrush(m_rgbColors[iColor]); 567 return m_hBrushes[iColor]; 568 } 569 570 /// @unimplemented 571 STDMETHODIMP_(void) CUIFColorTableOff10::InitColor() 572 { 573 m_rgbColors[0] = ::GetSysColor(COLOR_BTNFACE); 574 m_rgbColors[1] = ::GetSysColor(COLOR_WINDOW); 575 m_rgbColors[2] = ::GetSysColor(COLOR_WINDOW); 576 m_rgbColors[3] = ::GetSysColor(COLOR_BTNFACE); 577 m_rgbColors[4] = ::GetSysColor(COLOR_BTNSHADOW); 578 m_rgbColors[5] = ::GetSysColor(COLOR_WINDOW); 579 m_rgbColors[6] = ::GetSysColor(COLOR_HIGHLIGHT); 580 m_rgbColors[7] = ::GetSysColor(COLOR_WINDOWTEXT); 581 m_rgbColors[8] = ::GetSysColor(COLOR_HIGHLIGHT); 582 m_rgbColors[9] = ::GetSysColor(COLOR_HIGHLIGHT); 583 m_rgbColors[10] = ::GetSysColor(COLOR_HIGHLIGHTTEXT); 584 m_rgbColors[11] = ::GetSysColor(COLOR_BTNFACE); 585 m_rgbColors[12] = ::GetSysColor(COLOR_BTNTEXT); 586 m_rgbColors[13] = ::GetSysColor(COLOR_BTNSHADOW); 587 m_rgbColors[14] = ::GetSysColor(COLOR_BTNFACE); 588 m_rgbColors[15] = ::GetSysColor(COLOR_WINDOW); 589 m_rgbColors[16] = ::GetSysColor(COLOR_HIGHLIGHT); 590 m_rgbColors[17] = ::GetSysColor(COLOR_BTNTEXT); 591 m_rgbColors[18] = ::GetSysColor(COLOR_WINDOW); 592 m_rgbColors[19] = ::GetSysColor(COLOR_BTNSHADOW); 593 m_rgbColors[20] = ::GetSysColor(COLOR_BTNFACE); 594 m_rgbColors[21] = ::GetSysColor(COLOR_BTNSHADOW); 595 m_rgbColors[22] = ::GetSysColor(COLOR_BTNFACE); 596 m_rgbColors[23] = ::GetSysColor(COLOR_BTNSHADOW); 597 m_rgbColors[24] = ::GetSysColor(COLOR_CAPTIONTEXT); 598 m_rgbColors[25] = ::GetSysColor(COLOR_HIGHLIGHT); 599 m_rgbColors[26] = ::GetSysColor(COLOR_HIGHLIGHTTEXT); 600 m_rgbColors[27] = ::GetSysColor(COLOR_BTNFACE); 601 m_rgbColors[28] = ::GetSysColor(COLOR_BTNTEXT); 602 m_rgbColors[29] = ::GetSysColor(COLOR_BTNSHADOW); 603 m_rgbColors[30] = ::GetSysColor(COLOR_BTNTEXT); 604 m_rgbColors[31] = ::GetSysColor(COLOR_WINDOWTEXT); 605 } 606 607 STDMETHODIMP_(void) CUIFColorTableOff10::InitBrush() 608 { 609 ZeroMemory(m_hBrushes, sizeof(m_hBrushes)); 610 } 611 612 STDMETHODIMP_(void) CUIFColorTableOff10::DoneBrush() 613 { 614 for (size_t i = 0; i < _countof(m_hBrushes); ++i) 615 { 616 if (m_hBrushes[i]) 617 { 618 ::DeleteObject(m_hBrushes[i]); 619 m_hBrushes[i] = NULL; 620 } 621 } 622 } 623 624 ///////////////////////////////////////////////////////////////////////////// 625 // CUIFScheme 626 627 /// @unimplemented 628 CUIFScheme *cicCreateUIFScheme(DWORD type) 629 { 630 #if 1 631 return new(cicNoThrow) CUIFSchemeDef(type); 632 #else 633 switch (type) 634 { 635 case 1: return new(cicNoThrow) CUIFSchemeOff10(1); 636 case 2: return new(cicNoThrow) CUIFSchemeOff10(2); 637 case 3: return new(cicNoThrow) CUIFSchemeOff10(3); 638 default: return new(cicNoThrow) CUIFSchemeDef(type); 639 } 640 #endif 641 } 642 643 STDMETHODIMP_(DWORD) CUIFSchemeDef::GetType() 644 { 645 return m_dwType; 646 } 647 648 STDMETHODIMP_(COLORREF) CUIFSchemeDef::GetColor(INT iColor) 649 { 650 return s_pColorTableSys->GetColor(iColor); 651 } 652 653 STDMETHODIMP_(HBRUSH) CUIFSchemeDef::GetBrush(INT iColor) 654 { 655 return s_pColorTableSys->GetBrush(iColor); 656 } 657 658 STDMETHODIMP_(INT) CUIFSchemeDef::CyMenuItem(INT cyText) 659 { 660 return cyText + 2; 661 } 662 663 STDMETHODIMP_(INT) CUIFSchemeDef::CxSizeFrame() 664 { 665 return ::GetSystemMetrics(SM_CXSIZEFRAME); 666 } 667 668 STDMETHODIMP_(INT) CUIFSchemeDef::CySizeFrame() 669 { 670 return ::GetSystemMetrics(SM_CYSIZEFRAME); 671 } 672 673 STDMETHODIMP_(void) CUIFScheme::FillRect(HDC hDC, LPCRECT prc, INT iColor) 674 { 675 ::FillRect(hDC, prc, GetBrush(iColor)); 676 } 677 678 STDMETHODIMP_(void) CUIFScheme::FrameRect(HDC hDC, LPCRECT prc, INT iColor) 679 { 680 ::FrameRect(hDC, prc, GetBrush(iColor)); 681 } 682 683 STDMETHODIMP_(void) CUIFSchemeDef::DrawSelectionRect(HDC hDC, LPCRECT prc, int) 684 { 685 ::FillRect(hDC, prc, GetBrush(6)); 686 } 687 688 STDMETHODIMP_(void) 689 CUIFSchemeDef::GetCtrlFaceOffset(DWORD dwUnknownFlags, DWORD dwDrawFlags, LPSIZE pSize) 690 { 691 if (!(dwDrawFlags & UIF_DRAW_PRESSED)) 692 { 693 if (dwDrawFlags & 0x2) 694 { 695 if (dwUnknownFlags & 0x10) 696 { 697 pSize->cx = pSize->cy = -1; 698 return; 699 } 700 pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x20); 701 } 702 else 703 { 704 if (!(dwDrawFlags & 0x1)) 705 { 706 pSize->cx = pSize->cy = -((dwUnknownFlags & 1) != 0); 707 return; 708 } 709 if (dwUnknownFlags & 0x4) 710 { 711 pSize->cx = pSize->cy = -1; 712 return; 713 } 714 pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x8); 715 } 716 return; 717 } 718 719 if (!(dwUnknownFlags & 0x40)) 720 { 721 pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x80); 722 return; 723 } 724 725 pSize->cx = pSize->cy = -1; 726 } 727 728 STDMETHODIMP_(void) 729 CUIFSchemeDef::DrawCtrlBkgd(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags) 730 { 731 ::FillRect(hDC, prc, GetBrush(9)); 732 733 if (!(dwDrawFlags & UIF_DRAW_PRESSED) && (dwDrawFlags & 0x2)) 734 return; 735 736 HBRUSH hbrDither = cicCreateDitherBrush(); 737 if (!hbrDither) 738 return; 739 740 COLORREF rgbOldText = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNFACE)); 741 COLORREF rgbOldBack = ::SetBkColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 742 743 RECT rc = *prc; 744 ::InflateRect(&rc, -2, -2); 745 ::FillRect(hDC, &rc, hbrDither); 746 ::SetTextColor(hDC, rgbOldText); 747 ::SetBkColor(hDC, rgbOldBack); 748 ::DeleteObject(hbrDither); 749 } 750 751 STDMETHODIMP_(void) 752 CUIFSchemeDef::DrawCtrlEdge( 753 HDC hDC, 754 LPCRECT prc, 755 DWORD dwUnknownFlags, 756 DWORD dwDrawFlags) 757 { 758 UINT uEdge = BDR_RAISEDINNER; 759 760 if (dwDrawFlags & 0x10) 761 { 762 if (!(dwUnknownFlags & 0x40)) 763 { 764 if (dwUnknownFlags & 0x80) 765 uEdge = BDR_SUNKENOUTER; 766 else 767 return; 768 } 769 } 770 else if (dwDrawFlags & 0x2) 771 { 772 if (!(dwUnknownFlags & 0x10)) 773 { 774 if (dwUnknownFlags & 0x20) 775 uEdge = BDR_SUNKENOUTER; 776 else 777 return; 778 } 779 } 780 else if (dwDrawFlags & 0x1) 781 { 782 if (!(dwUnknownFlags & 0x4)) 783 { 784 if (dwUnknownFlags & 0x8) 785 uEdge = BDR_SUNKENOUTER; 786 else 787 return; 788 } 789 } 790 else if (!(dwUnknownFlags & 0x1)) 791 { 792 return; 793 } 794 795 RECT rc = *prc; 796 ::DrawEdge(hDC, &rc, uEdge, BF_RECT); 797 } 798 799 STDMETHODIMP_(void) 800 CUIFSchemeDef::DrawCtrlText( 801 HDC hDC, 802 LPCRECT prc, 803 LPCWSTR pszText, 804 INT cchText, 805 DWORD dwDrawFlags, 806 BOOL bRight) 807 { 808 COLORREF rgbOldText = ::GetTextColor(hDC); 809 INT OldBkMode = ::SetBkMode(hDC, TRANSPARENT); 810 811 if (cchText == -1) 812 cchText = lstrlenW(pszText); 813 814 RECT rc = *prc; 815 if (dwDrawFlags & UIF_DRAW_DISABLED) 816 { 817 ::OffsetRect(&rc, 1, 1); 818 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 819 ::ExtTextOutW(hDC, (bRight ? rc.right : rc.left), rc.top, ETO_CLIPPED, &rc, 820 pszText, cchText, NULL); 821 ::OffsetRect(&rc, -1, -1); 822 } 823 824 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)); 825 ::ExtTextOutW(hDC, (bRight ? rc.right : rc.left), rc.top, ETO_CLIPPED, &rc, 826 pszText, cchText, NULL); 827 828 ::SetTextColor(hDC, rgbOldText); 829 ::SetBkMode(hDC, OldBkMode); 830 } 831 832 STDMETHODIMP_(void) 833 CUIFSchemeDef::DrawCtrlIcon(HDC hDC, LPCRECT prc, HICON hIcon, DWORD dwDrawFlags, LPSIZE pSize) 834 { 835 if (m_bMirroring) 836 { 837 HBITMAP hbm1, hbm2; 838 if (cicGetIconBitmaps(hIcon, &hbm1, &hbm2, pSize)) 839 { 840 DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags); 841 ::DeleteObject(hbm1); 842 ::DeleteObject(hbm2); 843 } 844 } 845 else 846 { 847 UINT uFlags = DST_PREFIXTEXT | DST_TEXT; 848 if (dwDrawFlags & UIF_DRAW_DISABLED) 849 uFlags |= (DSS_MONO | DSS_DISABLED); 850 ::DrawState(hDC, 0, 0, (LPARAM)hIcon, 0, prc->left, prc->top, 0, 0, uFlags); 851 } 852 } 853 854 STDMETHODIMP_(void) 855 CUIFSchemeDef::DrawCtrlBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags) 856 { 857 if (m_bMirroring) 858 { 859 hbm1 = cicMirrorBitmap(hbm1, GetBrush(9)); 860 hbm2 = cicMirrorBitmap(hbm2, (HBRUSH)GetStockObject(BLACK_BRUSH)); 861 } 862 863 HBRUSH hBrush = (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1); 864 BOOL bBrushCreated = FALSE; 865 if (hbm2) 866 { 867 HBITMAP hBitmap = NULL; 868 if (dwDrawFlags & UIF_DRAW_DISABLED) 869 { 870 hBitmap = cicCreateDisabledBitmap(prc, hbm2, GetBrush(9), GetBrush(11), TRUE); 871 } 872 else 873 { 874 if ((dwDrawFlags & UIF_DRAW_PRESSED) && !(dwDrawFlags & 0x2)) 875 { 876 hBrush = cicCreateDitherBrush(); 877 bBrushCreated = TRUE; 878 } 879 880 COLORREF rgbFace = ::GetSysColor(COLOR_BTNFACE); 881 COLORREF rgbHighlight = ::GetSysColor(COLOR_BTNHIGHLIGHT); 882 hBitmap = cicCreateMaskBmp(prc, hbm1, hbm2, hBrush, rgbFace, rgbHighlight); 883 } 884 885 if (hBitmap) 886 { 887 ::DrawState(hDC, NULL, NULL, (LPARAM)hBitmap, 0, 888 prc->left, prc->top, 889 prc->right - prc->left, prc->bottom - prc->top, 890 DST_BITMAP); 891 ::DeleteObject(hBitmap); 892 } 893 } 894 else 895 { 896 UINT uFlags = DST_BITMAP; 897 if (dwDrawFlags & UIF_DRAW_DISABLED) 898 uFlags |= (DSS_MONO | DSS_DISABLED); 899 900 ::DrawState(hDC, NULL, NULL, (LPARAM)hbm1, 0, 901 prc->left, prc->top, 902 prc->right - prc->left, prc->bottom - prc->top, 903 uFlags); 904 } 905 906 if (bBrushCreated) 907 ::DeleteObject(hBrush); 908 909 if (m_bMirroring) 910 { 911 ::DeleteObject(hbm1); 912 ::DeleteObject(hbm2); 913 } 914 } 915 916 STDMETHODIMP_(void) 917 CUIFSchemeDef::DrawMenuBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags) 918 { 919 DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags); 920 } 921 922 STDMETHODIMP_(void) 923 CUIFSchemeDef::DrawMenuSeparator(HDC hDC, LPCRECT prc) 924 { 925 RECT rc = *prc; 926 rc.bottom = rc.top + (rc.bottom - rc.top) / 2; 927 ::FillRect(hDC, &rc, (HBRUSH)UlongToHandle(COLOR_BTNSHADOW + 1)); 928 929 rc = *prc; 930 rc.top += (rc.bottom - rc.top) / 2; 931 ::FillRect(hDC, &rc, (HBRUSH)UlongToHandle(COLOR_BTNHIGHLIGHT + 1)); 932 } 933 934 STDMETHODIMP_(void) 935 CUIFSchemeDef::DrawFrameCtrlBkgd(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags) 936 { 937 DrawCtrlBkgd(hDC, prc, dwUnknownFlags, dwDrawFlags); 938 } 939 940 STDMETHODIMP_(void) 941 CUIFSchemeDef::DrawFrameCtrlEdge(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags) 942 { 943 DrawCtrlEdge(hDC, prc, dwUnknownFlags, dwDrawFlags); 944 } 945 946 STDMETHODIMP_(void) 947 CUIFSchemeDef::DrawFrameCtrlIcon(HDC hDC, LPCRECT prc, HICON hIcon, DWORD dwDrawFlags, LPSIZE pSize) 948 { 949 DrawCtrlIcon(hDC, prc, hIcon, dwDrawFlags, pSize); 950 } 951 952 STDMETHODIMP_(void) 953 CUIFSchemeDef::DrawFrameCtrlBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags) 954 { 955 DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags); 956 } 957 958 STDMETHODIMP_(void) 959 CUIFSchemeDef::DrawWndFrame(HDC hDC, LPCRECT prc, DWORD type, DWORD unused1, DWORD unused2) 960 { 961 RECT rc = *prc; 962 if (type && type <= 2) 963 ::DrawEdge(hDC, &rc, BDR_RAISED, BF_RECT); 964 else 965 FrameRect(hDC, &rc, 14); 966 } 967 968 STDMETHODIMP_(void) 969 CUIFSchemeDef::DrawDragHandle(HDC hDC, LPCRECT prc, BOOL bVertical) 970 { 971 RECT rc; 972 if (bVertical) 973 rc = { prc->left, prc->top + 1, prc->right, prc->top + 4 }; 974 else 975 rc = { prc->left + 1, prc->top, prc->left + 4, prc->bottom }; 976 ::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT); 977 } 978 979 STDMETHODIMP_(void) 980 CUIFSchemeDef::DrawSeparator(HDC hDC, LPCRECT prc, BOOL bVertical) 981 { 982 HPEN hLightPen = ::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 983 if (!hLightPen) 984 return; 985 986 HPEN hShadowPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); 987 if (!hShadowPen) 988 { 989 ::DeleteObject(hLightPen); 990 return; 991 } 992 993 HGDIOBJ hPenOld = ::SelectObject(hDC, hShadowPen); 994 if (bVertical) 995 { 996 ::MoveToEx(hDC, prc->left, prc->top + 1, NULL); 997 ::LineTo(hDC, prc->right, prc->top + 1); 998 ::SelectObject(hDC, hLightPen); 999 ::MoveToEx(hDC, prc->left, prc->top + 2, NULL); 1000 ::LineTo(hDC, prc->right, prc->top + 2); 1001 } 1002 else 1003 { 1004 ::MoveToEx(hDC, prc->left + 1, prc->top, NULL); 1005 ::LineTo(hDC, prc->left + 1, prc->bottom); 1006 ::SelectObject(hDC, hLightPen); 1007 ::MoveToEx(hDC, prc->left + 2, prc->top, NULL); 1008 ::LineTo(hDC, prc->left + 2, prc->bottom); 1009 } 1010 ::SelectObject(hDC, hPenOld); 1011 1012 ::DeleteObject(hShadowPen); 1013 ::DeleteObject(hLightPen); 1014 } 1015 1016 ///////////////////////////////////////////////////////////////////////////// 1017 // CUIFIcon 1018 1019 HIMAGELIST CUIFIcon::GetImageList(BOOL bMirror) 1020 { 1021 if (!m_hImageList) 1022 return NULL; 1023 1024 if (m_hIcon) 1025 { 1026 SIZE iconSize; 1027 cicGetIconSize(m_hIcon, &iconSize); 1028 1029 UINT uFlags = ILC_COLOR32 | ILC_MASK; 1030 if (bMirror) 1031 uFlags |= ILC_MIRROR; 1032 1033 m_hImageList = ImageList_Create(iconSize.cx, iconSize.cy, uFlags, 1, 0); 1034 if (m_hImageList) 1035 ImageList_ReplaceIcon(m_hImageList, -1, m_hIcon); 1036 1037 return m_hImageList; 1038 } 1039 1040 return NULL; 1041 } 1042 1043 ///////////////////////////////////////////////////////////////////////////// 1044 // CUIFBitmapDC 1045 1046 CUIFBitmapDC::CUIFBitmapDC(BOOL bMemory) 1047 { 1048 m_hBitmap = NULL; 1049 m_hOldBitmap = NULL; 1050 m_hOldObject = NULL; 1051 if (bMemory) 1052 m_hDC = ::CreateCompatibleDC(NULL); 1053 else 1054 m_hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); 1055 } 1056 1057 CUIFBitmapDC::~CUIFBitmapDC() 1058 { 1059 Uninit(); 1060 ::DeleteDC(m_hDC); 1061 } 1062 1063 void CUIFBitmapDC::Uninit(BOOL bKeep) 1064 { 1065 if (m_hOldBitmap) 1066 { 1067 ::SelectObject(m_hDC, m_hOldBitmap); 1068 m_hOldBitmap = NULL; 1069 } 1070 1071 if (m_hOldObject) 1072 { 1073 ::SelectObject(m_hDC, m_hOldObject); 1074 m_hOldObject = NULL; 1075 } 1076 1077 if (!bKeep) 1078 { 1079 if (m_hBitmap) 1080 { 1081 ::DeleteObject(m_hBitmap); 1082 m_hBitmap = NULL; 1083 } 1084 } 1085 } 1086 1087 BOOL CUIFBitmapDC::SetBitmap(HBITMAP hBitmap) 1088 { 1089 if (m_hDC) 1090 m_hOldBitmap = ::SelectObject(m_hDC, hBitmap); 1091 return TRUE; 1092 } 1093 1094 BOOL CUIFBitmapDC::SetBitmap(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount) 1095 { 1096 m_hBitmap = ::CreateBitmap(cx, cy, cPlanes, cBitCount, 0); 1097 m_hOldBitmap = ::SelectObject(m_hDC, m_hBitmap); 1098 return TRUE; 1099 } 1100 1101 BOOL CUIFBitmapDC::SetDIB(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount) 1102 { 1103 BITMAPINFO bmi; 1104 ZeroMemory(&bmi, sizeof(bmi)); 1105 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); 1106 bmi.bmiHeader.biWidth = cx; 1107 bmi.bmiHeader.biHeight = cy; 1108 bmi.bmiHeader.biPlanes = cPlanes; 1109 bmi.bmiHeader.biBitCount = cBitCount; 1110 bmi.bmiHeader.biCompression = BI_RGB; 1111 m_hBitmap = ::CreateDIBSection(m_hDC, &bmi, DIB_RGB_COLORS, NULL, NULL, 0); 1112 m_hOldBitmap = ::SelectObject(m_hDC, m_hBitmap); 1113 return TRUE; 1114 } 1115 1116 void cicInitUIFUtil(void) 1117 { 1118 if (!CUIFBitmapDC::s_phdcSrc) 1119 CUIFBitmapDC::s_phdcSrc = new(cicNoThrow) CUIFBitmapDC(TRUE); 1120 1121 if (!CUIFBitmapDC::s_phdcMask) 1122 CUIFBitmapDC::s_phdcMask = new(cicNoThrow) CUIFBitmapDC(TRUE); 1123 1124 if (!CUIFBitmapDC::s_phdcDst) 1125 CUIFBitmapDC::s_phdcDst = new(cicNoThrow) CUIFBitmapDC(TRUE); 1126 1127 if (CUIFBitmapDC::s_phdcSrc && CUIFBitmapDC::s_phdcMask && CUIFBitmapDC::s_phdcDst) 1128 CUIFBitmapDC::s_fInitBitmapDCs = TRUE; 1129 } 1130 1131 void cicDoneUIFUtil(void) 1132 { 1133 if (CUIFBitmapDC::s_phdcSrc) 1134 { 1135 delete CUIFBitmapDC::s_phdcSrc; 1136 CUIFBitmapDC::s_phdcSrc = NULL; 1137 } 1138 1139 if (CUIFBitmapDC::s_phdcMask) 1140 { 1141 delete CUIFBitmapDC::s_phdcMask; 1142 CUIFBitmapDC::s_phdcMask = NULL; 1143 } 1144 1145 if (CUIFBitmapDC::s_phdcDst) 1146 { 1147 delete CUIFBitmapDC::s_phdcDst; 1148 CUIFBitmapDC::s_phdcDst = NULL; 1149 } 1150 1151 CUIFBitmapDC::s_fInitBitmapDCs = FALSE; 1152 } 1153 1154 HBITMAP cicMirrorBitmap(HBITMAP hBitmap, HBRUSH hbrBack) 1155 { 1156 BITMAP bm; 1157 if (!CUIFBitmapDC::s_fInitBitmapDCs || !::GetObject(hBitmap, sizeof(bm), &bm)) 1158 return NULL; 1159 1160 CUIFBitmapDC::s_phdcSrc->SetBitmap(hBitmap); 1161 CUIFBitmapDC::s_phdcDst->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32); 1162 CUIFBitmapDC::s_phdcMask->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32); 1163 1164 RECT rc = { 0, 0, bm.bmWidth, bm.bmHeight }; 1165 FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrBack); 1166 1167 ::SetLayout(*CUIFBitmapDC::s_phdcMask, LAYOUT_RTL); 1168 1169 ::BitBlt(*CUIFBitmapDC::s_phdcMask, 0, 0, bm.bmWidth, bm.bmHeight, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCCOPY); 1170 1171 ::SetLayout(*CUIFBitmapDC::s_phdcMask, 0); 1172 1173 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, bm.bmWidth, bm.bmHeight, *CUIFBitmapDC::s_phdcMask, 1, 0, SRCCOPY); 1174 1175 CUIFBitmapDC::s_phdcSrc->Uninit(); 1176 CUIFBitmapDC::s_phdcMask->Uninit(); 1177 CUIFBitmapDC::s_phdcDst->Uninit(TRUE); 1178 return CUIFBitmapDC::s_phdcDst->DetachBitmap(); 1179 } 1180 1181 HBRUSH cicCreateDitherBrush(VOID) 1182 { 1183 BYTE bytes[16]; 1184 ZeroMemory(&bytes, sizeof(bytes)); 1185 bytes[0] = bytes[4] = bytes[8] = bytes[12] = 0x55; 1186 bytes[2] = bytes[6] = bytes[10] = bytes[14] = 0xAA; 1187 HBITMAP hBitmap = ::CreateBitmap(8, 8, 1, 1, bytes); 1188 if (!hBitmap) 1189 return NULL; 1190 1191 LOGBRUSH lb; 1192 lb.lbHatch = (ULONG_PTR)hBitmap; 1193 lb.lbStyle = BS_PATTERN; 1194 HBRUSH hbr = ::CreateBrushIndirect(&lb); 1195 ::DeleteObject(hBitmap); 1196 return hbr; 1197 } 1198 1199 HBITMAP 1200 cicCreateDisabledBitmap(LPCRECT prc, HBITMAP hbmMask, HBRUSH hbr1, HBRUSH hbr2, BOOL bPressed) 1201 { 1202 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1203 return NULL; 1204 1205 LONG width = prc->right - prc->left, height = prc->bottom - prc->top; 1206 1207 CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); 1208 CUIFBitmapDC::s_phdcMask->SetBitmap(hbmMask); 1209 CUIFBitmapDC::s_phdcSrc->SetDIB(width, height, 1, 32); 1210 1211 RECT rc = { 0, 0, width, height }; 1212 ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr1); 1213 1214 HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH); 1215 ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbrWhite); 1216 1217 ::BitBlt(*CUIFBitmapDC::s_phdcSrc, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCINVERT); 1218 if (bPressed) 1219 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 1, 1, width, height, 1220 *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCPAINT); 1221 else 1222 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, 1223 *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCPAINT); 1224 1225 ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbr2); 1226 1227 ::BitBlt(*CUIFBitmapDC::s_phdcSrc, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCPAINT); 1228 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCAND); 1229 1230 CUIFBitmapDC::s_phdcSrc->Uninit(); 1231 CUIFBitmapDC::s_phdcMask->Uninit(); 1232 CUIFBitmapDC::s_phdcDst->Uninit(TRUE); 1233 return CUIFBitmapDC::s_phdcDst->DetachBitmap(); 1234 } 1235 1236 HBITMAP 1237 cicCreateShadowMaskBmp(LPRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hbr1, HBRUSH hbr2) 1238 { 1239 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1240 return NULL; 1241 1242 --prc->left; 1243 --prc->top; 1244 1245 LONG width = prc->right - prc->left; 1246 LONG height = prc->bottom - prc->top; 1247 1248 CUIFBitmapDC bitmapDC(TRUE); 1249 1250 CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); 1251 CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm1); 1252 CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2); 1253 bitmapDC.SetDIB(width, height, 1, 32); 1254 1255 RECT rc = { 0, 0, width, height }; 1256 1257 ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr1); 1258 ::FillRect(bitmapDC, &rc, hbr2); 1259 1260 ::BitBlt(bitmapDC, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCPAINT); 1261 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 2, 2, width, height, bitmapDC, 0, 0, SRCAND); 1262 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCAND); 1263 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCINVERT); 1264 1265 CUIFBitmapDC::s_phdcSrc->Uninit(); 1266 CUIFBitmapDC::s_phdcMask->Uninit(); 1267 CUIFBitmapDC::s_phdcDst->Uninit(TRUE); 1268 return CUIFBitmapDC::s_phdcDst->DetachBitmap(); 1269 } 1270 1271 HBITMAP 1272 cicChangeBitmapColor(LPCRECT prc, HBITMAP hbm, COLORREF rgbBack, COLORREF rgbFore) 1273 { 1274 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1275 return NULL; 1276 1277 INT width = prc->right - prc->left; 1278 INT height = prc->bottom - prc->top; 1279 1280 CUIFSolidBrush brush(rgbFore); 1281 1282 CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); 1283 CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm); 1284 CUIFBitmapDC::s_phdcMask->SetBitmap(width, height, 1, 1); 1285 1286 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCCOPY); 1287 ::SelectObject(*CUIFBitmapDC::s_phdcDst, (HBRUSH)brush); 1288 ::SetBkColor(*CUIFBitmapDC::s_phdcDst, rgbBack); 1289 1290 ::BitBlt(*CUIFBitmapDC::s_phdcMask, 0, 0, width, height, *CUIFBitmapDC::s_phdcDst, 0, 0, MERGECOPY); 1291 ::SetBkColor(*CUIFBitmapDC::s_phdcDst, RGB(255, 255, 255)); 1292 ::SetTextColor(*CUIFBitmapDC::s_phdcDst, RGB(0, 0, 0)); 1293 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, 0xE20746u); 1294 1295 CUIFBitmapDC::s_phdcSrc->Uninit(); 1296 CUIFBitmapDC::s_phdcMask->Uninit(); 1297 CUIFBitmapDC::s_phdcDst->Uninit(TRUE); 1298 return CUIFBitmapDC::s_phdcDst->DetachBitmap(); 1299 } 1300 1301 HBITMAP 1302 cicConvertBlackBKGBitmap(LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hBrush) 1303 { 1304 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1305 return NULL; 1306 1307 if (IS_INTRESOURCE(hBrush)) 1308 hBrush = ::GetSysColorBrush(HandleToLong(hBrush) - 1); 1309 1310 LOGBRUSH lb; 1311 ::GetObject(hBrush, sizeof(lb), &lb); 1312 if (lb.lbStyle || lb.lbColor) 1313 return NULL; 1314 1315 INT width = prc->right - prc->left; 1316 INT height = prc->bottom - prc->top; 1317 1318 HBITMAP hBitmap = cicChangeBitmapColor(prc, hbm1, 0, RGB(255, 255, 255)); 1319 if ( !hBitmap ) 1320 return NULL; 1321 1322 CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); 1323 CUIFBitmapDC::s_phdcSrc->SetBitmap(hBitmap); 1324 CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2); 1325 1326 RECT rc = { 0, 0, width, height }; 1327 1328 HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH); 1329 ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrWhite); 1330 1331 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, 0x660046u); 1332 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, 0x8800C6u); 1333 1334 CUIFBitmapDC::s_phdcSrc->Uninit(); 1335 CUIFBitmapDC::s_phdcMask->Uninit(); 1336 CUIFBitmapDC::s_phdcDst->Uninit(TRUE); 1337 ::DeleteObject(hBitmap); 1338 return CUIFBitmapDC::s_phdcDst->DetachBitmap(); 1339 } 1340 1341 HBITMAP 1342 cicCreateMaskBmp(LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, 1343 HBRUSH hbr, COLORREF rgbColor, COLORREF rgbBack) 1344 { 1345 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1346 return NULL; 1347 1348 INT width = prc->right - prc->left; 1349 INT height = prc->bottom - prc->top; 1350 HBITMAP hBitmap = cicConvertBlackBKGBitmap(prc, hbm1, hbm2, hbr); 1351 if (hBitmap) 1352 return hBitmap; 1353 1354 CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); 1355 CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm1); 1356 CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2); 1357 1358 RECT rc = { 0, 0, width, height }; 1359 1360 COLORREF OldTextColor = ::SetTextColor(*CUIFBitmapDC::s_phdcDst, rgbColor); 1361 COLORREF OldBkColor = ::SetBkColor(*CUIFBitmapDC::s_phdcDst, rgbBack); 1362 ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr); 1363 ::SetTextColor(*CUIFBitmapDC::s_phdcDst, OldTextColor); 1364 ::SetBkColor(*CUIFBitmapDC::s_phdcDst, OldBkColor); 1365 1366 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCAND); 1367 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCINVERT); 1368 CUIFBitmapDC::s_phdcSrc->Uninit(); 1369 CUIFBitmapDC::s_phdcMask->Uninit(); 1370 CUIFBitmapDC::s_phdcDst->Uninit(TRUE); 1371 1372 return CUIFBitmapDC::s_phdcDst->DetachBitmap(); 1373 } 1374 1375 BOOL cicGetIconBitmaps(HICON hIcon, HBITMAP *hbm1, HBITMAP *hbm2, const SIZE *pSize) 1376 { 1377 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1378 return FALSE; 1379 1380 SIZE size; 1381 if (pSize) 1382 { 1383 size = *pSize; 1384 } 1385 else 1386 { 1387 if (!cicGetIconSize(hIcon, &size)) 1388 return FALSE; 1389 } 1390 1391 CUIFBitmapDC::s_phdcSrc->SetDIB(size.cx, size.cy, 1, 32); 1392 CUIFBitmapDC::s_phdcMask->SetBitmap(size.cx, size.cy, 1, 1); 1393 1394 RECT rc = { 0, 0, size.cx, size.cy }; 1395 ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); 1396 1397 ::DrawIconEx(*CUIFBitmapDC::s_phdcSrc, 0, 0, hIcon, size.cx, size.cy, 0, 0, DI_NORMAL); 1398 ::DrawIconEx(*CUIFBitmapDC::s_phdcMask, 0, 0, hIcon, size.cx, size.cy, 0, 0, DI_MASK); 1399 1400 CUIFBitmapDC::s_phdcSrc->Uninit(TRUE); 1401 CUIFBitmapDC::s_phdcMask->Uninit(TRUE); 1402 *hbm1 = CUIFBitmapDC::s_phdcSrc->DetachBitmap(); 1403 *hbm2 = CUIFBitmapDC::s_phdcMask->DetachBitmap(); 1404 return TRUE; 1405 } 1406 1407 void cicDrawMaskBmpOnDC(HDC hDC, LPCRECT prc, HBITMAP hbmp, HBITMAP hbmpMask) 1408 { 1409 if (!CUIFBitmapDC::s_fInitBitmapDCs) 1410 return; 1411 1412 LONG cx = prc->right - prc->left, cy = prc->bottom - prc->top; 1413 CUIFBitmapDC::s_phdcDst->SetDIB(cx, cy, 1, 32); 1414 CUIFBitmapDC::s_phdcSrc->SetBitmap(hbmp); 1415 CUIFBitmapDC::s_phdcMask->SetBitmap(hbmpMask); 1416 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, cx, cy, hDC, prc->left, prc->top, SRCCOPY); 1417 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, cx, cy, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCAND); 1418 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, cx, cy, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCINVERT); 1419 ::BitBlt(hDC, prc->left, prc->top, cx, cy, *CUIFBitmapDC::s_phdcDst, 0, 0, SRCCOPY); 1420 CUIFBitmapDC::s_phdcSrc->Uninit(FALSE); 1421 CUIFBitmapDC::s_phdcMask->Uninit(FALSE); 1422 CUIFBitmapDC::s_phdcDst->Uninit(FALSE); 1423 } 1424 1425 ///////////////////////////////////////////////////////////////////////////// 1426 // CUIFWindow 1427 1428 CUIFWindow::CUIFWindow(HINSTANCE hInst, DWORD style) 1429 : CUIFObject(NULL, 0, NULL, style) 1430 { 1431 m_hInst = hInst; 1432 m_nLeft = 200; 1433 m_nTop = 200; 1434 m_nWidth = 200; 1435 m_nHeight = 200; 1436 m_hWnd = 0; 1437 m_pWindow = this; 1438 m_pCaptured = NULL; 1439 m_pTimerObject = NULL; 1440 m_pPointed = NULL; 1441 m_bPointing = FALSE; 1442 m_pToolTip = NULL; 1443 m_pShadow = NULL; 1444 m_bShowShadow = TRUE; 1445 m_pBehindModal = NULL; 1446 CUIFWindow::CreateScheme(); 1447 } 1448 1449 CUIFWindow::~CUIFWindow() 1450 { 1451 if (m_pToolTip) 1452 { 1453 delete m_pToolTip; 1454 m_pToolTip = NULL; 1455 } 1456 if (m_pShadow) 1457 { 1458 delete m_pShadow; 1459 m_pShadow = NULL; 1460 } 1461 for (size_t i = m_ObjectArray.size(); i > 0; ) 1462 { 1463 --i; 1464 CUIFObject *pObject = m_ObjectArray[i]; 1465 m_ObjectArray[i] = NULL; 1466 m_ObjectArray.Remove(pObject); 1467 delete pObject; 1468 } 1469 if (m_pScheme) 1470 { 1471 delete m_pScheme; 1472 m_pScheme = NULL; 1473 } 1474 } 1475 1476 STDMETHODIMP_(BOOL) 1477 CUIFWindow::Initialize() 1478 { 1479 LPCTSTR pszClass = GetClassName(); 1480 1481 WNDCLASSEX wcx; 1482 ZeroMemory(&wcx, sizeof(wcx)); 1483 wcx.cbSize = sizeof(WNDCLASSEXW); 1484 if (!::GetClassInfoEx(m_hInst, pszClass, &wcx)) 1485 { 1486 ZeroMemory(&wcx, sizeof(wcx)); 1487 wcx.cbSize = sizeof(wcx); 1488 wcx.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; 1489 wcx.lpfnWndProc = CUIFWindow::WindowProcedure; 1490 wcx.cbClsExtra = 0; 1491 wcx.cbWndExtra = sizeof(LONG_PTR) * 2; 1492 wcx.hInstance = m_hInst; 1493 wcx.hIcon = NULL; 1494 wcx.hCursor = ::LoadCursor(NULL, IDC_ARROW); 1495 wcx.lpszClassName = pszClass; 1496 wcx.hbrBackground = NULL; 1497 wcx.lpszMenuName = NULL; 1498 wcx.hIconSm = NULL; 1499 ::RegisterClassEx(&wcx); 1500 } 1501 1502 cicUpdateUIFSys(); 1503 cicUpdateUIFScheme(); 1504 1505 if (m_style & UIF_WINDOW_TOOLTIP) 1506 { 1507 DWORD style = (m_style & UIF_WINDOW_LAYOUTRTL) | UIF_WINDOW_TOPMOST | 0x10; 1508 m_pToolTip = new(cicNoThrow) CUIFToolTip(m_hInst, style, this); 1509 if (m_pToolTip) 1510 m_pToolTip->Initialize(); 1511 } 1512 1513 if (m_style & UIF_WINDOW_SHADOW) 1514 { 1515 m_pShadow = new(cicNoThrow) CUIFShadow(m_hInst, UIF_WINDOW_TOPMOST, this); 1516 if (m_pShadow) 1517 m_pShadow->Initialize(); 1518 } 1519 1520 return CUIFObject::Initialize(); 1521 } 1522 1523 STDMETHODIMP_(LRESULT) 1524 CUIFWindow::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 1525 { 1526 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 1527 } 1528 1529 void CUIFWindow::UpdateUI(LPCRECT prc) 1530 { 1531 if (::IsWindow(m_hWnd)) 1532 ::InvalidateRect(m_hWnd, prc, FALSE); 1533 } 1534 1535 CUIFWindow* 1536 CUIFWindow::GetThis(HWND hWnd) 1537 { 1538 return (CUIFWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA); 1539 } 1540 1541 void 1542 CUIFWindow::SetThis(HWND hWnd, LONG_PTR dwNewLong) 1543 { 1544 ::SetWindowLongPtr(hWnd, GWLP_USERDATA, dwNewLong); 1545 } 1546 1547 void CUIFWindow::CreateScheme() 1548 { 1549 if (m_pScheme) 1550 { 1551 delete m_pScheme; 1552 m_pScheme = NULL; 1553 } 1554 1555 INT iScheme = 0; 1556 if (m_style & UIF_WINDOW_USESCHEME1) 1557 iScheme = 1; 1558 else if (m_style & UIF_WINDOW_USESCHEME2) 1559 iScheme = 2; 1560 else if (m_style & UIF_WINDOW_USESCHEME3) 1561 iScheme = 3; 1562 1563 m_pScheme = cicCreateUIFScheme(iScheme); 1564 SetScheme(m_pScheme); 1565 } 1566 1567 STDMETHODIMP_(DWORD) 1568 CUIFWindow::GetWndStyle() 1569 { 1570 DWORD ret; 1571 1572 if (m_style & UIF_WINDOW_CHILD) 1573 ret = WS_CHILD | WS_CLIPSIBLINGS; 1574 else 1575 ret = WS_POPUP | WS_DISABLED; 1576 1577 if (m_style & UIF_WINDOW_USESCHEME1) 1578 ret |= WS_BORDER; 1579 else if (m_style & UIF_WINDOW_DLGFRAME) 1580 ret |= WS_DLGFRAME; 1581 else if ((m_style & UIF_WINDOW_USESCHEME2) || (m_style & 0x10)) 1582 ret |= WS_BORDER; 1583 1584 return ret; 1585 } 1586 1587 STDMETHODIMP_(DWORD) 1588 CUIFWindow::GetWndStyleEx() 1589 { 1590 DWORD ret = 0; 1591 if (m_style & UIF_WINDOW_TOPMOST) 1592 ret |= WS_EX_TOPMOST; 1593 if (m_style & UIF_WINDOW_TOOLWINDOW) 1594 ret |= WS_EX_TOOLWINDOW; 1595 if (m_style & UIF_WINDOW_LAYOUTRTL) 1596 ret |= WS_EX_LAYOUTRTL; 1597 return ret; 1598 } 1599 1600 STDMETHODIMP_(HWND) 1601 CUIFWindow::CreateWnd(HWND hwndParent) 1602 { 1603 HWND hWnd = CreateWindowEx(GetWndStyleEx(), GetClassName(), GetWndTitle(), GetWndStyle(), 1604 m_nLeft, m_nTop, m_nWidth, m_nHeight, 1605 hwndParent, NULL, m_hInst, this); 1606 if (m_pToolTip) 1607 m_pToolTip->CreateWnd(hWnd); 1608 if (m_pShadow) 1609 m_pShadow->CreateWnd(hWnd); 1610 return hWnd; 1611 } 1612 1613 void CUIFWindow::Show(BOOL bVisible) 1614 { 1615 if (!IsWindow(m_hWnd)) 1616 return; 1617 1618 if (bVisible && (m_style & UIF_WINDOW_TOPMOST)) 1619 ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); 1620 1621 m_bVisible = bVisible; 1622 ::ShowWindow(m_hWnd, (bVisible ? SW_SHOWNOACTIVATE : 0)); 1623 } 1624 1625 STDMETHODIMP_(BOOL) 1626 CUIFWindow::AnimateWnd(DWORD dwTime, DWORD dwFlags) 1627 { 1628 if (!::IsWindow(m_hWnd)) 1629 return FALSE; 1630 1631 BOOL bVisible = !(dwFlags & 0x10000); 1632 OnAnimationStart(); 1633 BOOL ret = ::AnimateWindow(m_hWnd, dwTime, dwFlags); 1634 if (!ret) 1635 m_bVisible = bVisible; 1636 OnAnimationEnd(); 1637 return ret; 1638 } 1639 1640 void CUIFWindow::SetCaptureObject(CUIFObject *pCaptured) 1641 { 1642 if (pCaptured) 1643 { 1644 m_pCaptured = pCaptured; 1645 SetCapture(TRUE); 1646 } 1647 else 1648 { 1649 m_pCaptured = NULL; 1650 SetCapture(FALSE); 1651 } 1652 } 1653 1654 STDMETHODIMP_(void) 1655 CUIFWindow::SetCapture(BOOL bSet) 1656 { 1657 if (bSet) 1658 ::SetCapture(m_hWnd); 1659 else 1660 ::ReleaseCapture(); 1661 } 1662 1663 void CUIFWindow::SetObjectPointed(CUIFObject *pPointed, POINT pt) 1664 { 1665 if (pPointed == m_pPointed) 1666 return; 1667 1668 if (m_pCaptured) 1669 { 1670 if (m_pCaptured == m_pPointed && m_pPointed->m_bEnable) 1671 m_pPointed->OnMouseOut(pt.x, pt.y); 1672 } 1673 else if (m_pPointed && m_pPointed->m_bEnable) 1674 { 1675 m_pPointed->OnMouseOut(pt.x, pt.y); 1676 } 1677 1678 m_pPointed = pPointed; 1679 1680 if (m_pCaptured) 1681 { 1682 if (m_pCaptured == m_pPointed && m_pPointed->m_bEnable) 1683 m_pPointed->OnMouseIn(pt.x, pt.y); 1684 } 1685 else if (m_pPointed && m_pPointed->m_bEnable) 1686 { 1687 m_pPointed->OnMouseIn(pt.x, pt.y); 1688 } 1689 } 1690 1691 STDMETHODIMP_(void) 1692 CUIFWindow::OnObjectMoved(CUIFObject *pObject) 1693 { 1694 if (!::IsWindow(m_hWnd)) 1695 return; 1696 1697 POINT pt; 1698 ::GetCursorPos(&pt); 1699 ::ScreenToClient(m_hWnd, &pt); 1700 POINT pt2 = pt; 1701 CUIFObject *pFound = ObjectFromPoint(pt); 1702 SetObjectPointed(pFound, pt2); 1703 } 1704 1705 STDMETHODIMP_(void) 1706 CUIFWindow::SetRect(LPCRECT prc) 1707 { 1708 RECT Rect = { 0, 0, 0, 0 }; 1709 1710 if (::IsWindow(m_hWnd)) 1711 ::GetClientRect(m_hWnd, &Rect); 1712 1713 CUIFObject::SetRect(&Rect); 1714 } 1715 1716 STDMETHODIMP_(void) 1717 CUIFWindow::ClientRectToWindowRect(LPRECT lpRect) 1718 { 1719 DWORD style, exstyle; 1720 if (::IsWindow(m_hWnd)) 1721 { 1722 style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); 1723 exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE); 1724 } 1725 else 1726 { 1727 style = GetWndStyle(); 1728 exstyle = GetWndStyleEx(); 1729 } 1730 ::AdjustWindowRectEx(lpRect, style, FALSE, exstyle); 1731 } 1732 1733 STDMETHODIMP_(void) 1734 CUIFWindow::GetWindowFrameSize(LPSIZE pSize) 1735 { 1736 RECT rc = { 0, 0, 0, 0 }; 1737 1738 ClientRectToWindowRect(&rc); 1739 pSize->cx = (rc.right - rc.left) / 2; 1740 pSize->cy = (rc.bottom - rc.top) / 2; 1741 } 1742 1743 STDMETHODIMP_(void) 1744 CUIFWindow::OnAnimationEnd() 1745 { 1746 if (m_pShadow && m_bShowShadow) 1747 m_pShadow->Show(m_bVisible); 1748 } 1749 1750 STDMETHODIMP_(void) 1751 CUIFWindow::OnThemeChanged(HWND hWnd, WPARAM wParam, LPARAM lParam) 1752 { 1753 ClearTheme(); 1754 } 1755 1756 LRESULT 1757 CUIFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 1758 { 1759 switch (uMsg) 1760 { 1761 case WM_GETOBJECT: 1762 return OnGetObject(hWnd, WM_GETOBJECT, wParam, lParam); 1763 1764 case WM_SYSCOLORCHANGE: 1765 cicUpdateUIFScheme(); 1766 OnSysColorChange(); 1767 return 0; 1768 1769 case WM_ENDSESSION: 1770 OnEndSession(hWnd, wParam, lParam); 1771 return 0; 1772 1773 case WM_SHOWWINDOW: 1774 if (m_pShadow && m_bShowShadow) 1775 m_pShadow->Show(wParam); 1776 return OnShowWindow(hWnd, WM_SHOWWINDOW, wParam, lParam); 1777 1778 case WM_SETTINGCHANGE: 1779 cicUpdateUIFSys(); 1780 cicUpdateUIFScheme(); 1781 return OnSettingChange(hWnd, WM_SETTINGCHANGE, wParam, lParam); 1782 case WM_SETCURSOR: 1783 { 1784 POINT Point; 1785 ::GetCursorPos(&Point); 1786 ::ScreenToClient(m_hWnd, &Point); 1787 1788 if (m_pBehindModal) 1789 { 1790 m_pBehindModal->ModalMouseNotify(HIWORD(lParam), Point.x, Point.y); 1791 return TRUE; 1792 } 1793 1794 if (!m_bPointing) 1795 { 1796 ::SetTimer(m_hWnd, POINTING_TIMER_ID, 1000, NULL); 1797 m_bPointing = TRUE; 1798 } 1799 1800 if (m_pToolTip) 1801 { 1802 MSG msg = { m_hWnd, HIWORD(lParam), 0, MAKELPARAM(Point.x, Point.y) }; 1803 m_pToolTip->RelayEvent(&msg); 1804 } 1805 1806 if (!(m_style & UIF_WINDOW_NOMOUSEMSG)) 1807 HandleMouseMsg(HIWORD(lParam), Point.x, Point.y); 1808 1809 return TRUE; 1810 } 1811 case WM_MOUSEACTIVATE: 1812 return MA_NOACTIVATE; 1813 case WM_ERASEBKGND: 1814 return OnEraseBkGnd(hWnd, WM_ERASEBKGND, wParam, lParam); 1815 case WM_CREATE: 1816 SetRect(NULL); 1817 OnCreate(hWnd); 1818 return 0; 1819 case WM_DESTROY: 1820 if (m_pToolTip && ::IsWindow(*m_pToolTip)) 1821 ::DestroyWindow(*m_pToolTip); 1822 if (m_pShadow && ::IsWindow(*m_pShadow)) 1823 ::DestroyWindow(*m_pShadow); 1824 OnDestroy(hWnd); 1825 return 0; 1826 case WM_SIZE: 1827 SetRect(NULL); 1828 return 0; 1829 case WM_ACTIVATE: 1830 return OnActivate(hWnd, WM_ACTIVATE, wParam, lParam); 1831 case WM_SETFOCUS: 1832 OnSetFocus(hWnd); 1833 return 0; 1834 case WM_KILLFOCUS: 1835 OnKillFocus(hWnd); 1836 return 0; 1837 case WM_PAINT: 1838 { 1839 PAINTSTRUCT Paint; 1840 HDC hDC = ::BeginPaint(hWnd, &Paint); 1841 PaintObject(hDC, &Paint.rcPaint); 1842 ::EndPaint(hWnd, &Paint); 1843 return 0; 1844 } 1845 case WM_PRINTCLIENT: 1846 { 1847 PaintObject((HDC)wParam, NULL); 1848 return 0; 1849 } 1850 case WM_THEMECHANGED: 1851 { 1852 OnThemeChanged(hWnd, wParam, lParam); 1853 return 0; 1854 } 1855 case WM_COMMAND: 1856 { 1857 return 0; 1858 } 1859 case WM_TIMER: 1860 { 1861 switch (wParam) 1862 { 1863 case USER_TIMER_ID: 1864 { 1865 if (m_pTimerObject) 1866 m_pTimerObject->OnTimer(); 1867 break; 1868 } 1869 case POINTING_TIMER_ID: 1870 { 1871 POINT pt; 1872 ::GetCursorPos(&pt); 1873 1874 POINT pt2 = pt; 1875 ::ScreenToClient(m_hWnd, &pt2); 1876 1877 RECT rc; 1878 ::GetWindowRect(m_hWnd, &rc); 1879 1880 if (::PtInRect(&rc, pt) && ::WindowFromPoint(pt) == m_hWnd) 1881 { 1882 m_pBehindModal->ModalMouseNotify(WM_MOUSEMOVE, pt2.x, pt2.y); 1883 } 1884 else 1885 { 1886 ::KillTimer(m_hWnd, POINTING_TIMER_ID); 1887 m_bPointing = FALSE; 1888 SetObjectPointed(NULL, pt2); 1889 OnMouseOutFromWindow(pt2.x, pt2.y); 1890 } 1891 1892 if (m_pToolTip) 1893 { 1894 MSG msg = { m_hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(pt2.x, pt2.y) }; 1895 m_pToolTip->RelayEvent(&msg); 1896 } 1897 break; 1898 } 1899 default: 1900 { 1901 OnTimer(wParam); 1902 break; 1903 } 1904 } 1905 break; 1906 } 1907 case WM_MOUSEMOVE: 1908 case WM_LBUTTONDOWN: 1909 case WM_LBUTTONDBLCLK: 1910 case WM_LBUTTONUP: 1911 case WM_MBUTTONDOWN: 1912 case WM_MBUTTONDBLCLK: 1913 case WM_MBUTTONUP: 1914 case WM_RBUTTONDOWN: 1915 case WM_RBUTTONDBLCLK: 1916 case WM_RBUTTONUP: 1917 { 1918 if (m_pBehindModal) 1919 m_pBehindModal->ModalMouseNotify(uMsg, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); 1920 else 1921 HandleMouseMsg(uMsg, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); 1922 break; 1923 } 1924 case WM_KEYUP: 1925 { 1926 OnKeyUp(hWnd, wParam, lParam); 1927 break; 1928 } 1929 case WM_WINDOWPOSCHANGING: 1930 { 1931 WINDOWPOS *pwp = (WINDOWPOS *)lParam; 1932 if (m_pShadow && (pwp->flags & SWP_HIDEWINDOW)) 1933 m_pShadow->Show(FALSE); 1934 if (!(pwp->flags & SWP_NOZORDER) && pwp->hwndInsertAfter == m_pShadow->m_hWnd) 1935 pwp->flags |= SWP_NOZORDER; 1936 m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE)); 1937 return OnWindowPosChanging(hWnd, WM_WINDOWPOSCHANGING, wParam, lParam); 1938 } 1939 case WM_WINDOWPOSCHANGED: 1940 { 1941 WINDOWPOS *pwp = (WINDOWPOS *)lParam; 1942 if (m_pShadow) 1943 m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE)); 1944 return OnWindowPosChanged(hWnd, WM_WINDOWPOSCHANGED, wParam, lParam); 1945 } 1946 case WM_NOTIFY: 1947 OnNotify(hWnd, wParam, lParam); 1948 return 0; 1949 case WM_NOTIFYFORMAT: 1950 return OnNotifyFormat(hWnd, wParam, lParam); 1951 case WM_DISPLAYCHANGE: 1952 cicUpdateUIFSys(); 1953 cicUpdateUIFScheme(); 1954 return OnDisplayChange(hWnd, WM_DISPLAYCHANGE, wParam, lParam); 1955 case WM_NCDESTROY: 1956 OnNCDestroy(hWnd); 1957 return 0; 1958 case WM_KEYDOWN: 1959 OnKeyDown(hWnd, wParam, lParam); 1960 return 0; 1961 default: 1962 { 1963 if (uMsg >= WM_USER) 1964 { 1965 CUIFWindow *pThis = CUIFWindow::GetThis(hWnd); 1966 pThis->OnUser(hWnd, uMsg, wParam, lParam); 1967 break; 1968 } 1969 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 1970 } 1971 } 1972 1973 return 0; 1974 } 1975 1976 LRESULT CALLBACK 1977 CUIFWindow::WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 1978 { 1979 CUIFWindow *This; 1980 1981 if (uMsg == WM_NCCREATE) 1982 { 1983 This = (CUIFWindow*)((CREATESTRUCT*)lParam)->lpCreateParams; 1984 CUIFWindow::SetThis(hWnd, (LONG_PTR)This); 1985 This->m_hWnd = hWnd; 1986 } 1987 else 1988 { 1989 This = CUIFWindow::GetThis(hWnd); 1990 } 1991 1992 if (uMsg == WM_GETMINMAXINFO) 1993 { 1994 if (This) 1995 return This->WindowProc(hWnd, uMsg, wParam, lParam); 1996 else 1997 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 1998 } 1999 2000 if (!This) 2001 return 0; 2002 2003 if (uMsg == WM_NCDESTROY) 2004 { 2005 This->m_hWnd = NULL; 2006 ::SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); 2007 } 2008 2009 return This->WindowProc(hWnd, uMsg, wParam, lParam); 2010 } 2011 2012 BOOL 2013 CUIFWindow::GetWorkArea(LPCRECT prcWnd, LPRECT prcWorkArea) 2014 { 2015 if (!(m_style & (UIF_WINDOW_WORKAREA | UIF_WINDOW_MONITOR))) 2016 return FALSE; 2017 2018 HMONITOR hMon = ::MonitorFromRect(prcWnd, MONITOR_DEFAULTTONEAREST); 2019 MONITORINFO mi; 2020 mi.cbSize = sizeof(MONITORINFO); 2021 if (!hMon || !::GetMonitorInfo(hMon, &mi)) 2022 { 2023 if (m_style & UIF_WINDOW_WORKAREA) 2024 return ::SystemParametersInfo(SPI_GETWORKAREA, 0, prcWorkArea, 0); 2025 2026 prcWorkArea->left = prcWorkArea->top = 0; 2027 prcWorkArea->right = ::GetSystemMetrics(SM_CXSCREEN); 2028 prcWorkArea->bottom = ::GetSystemMetrics(SM_CYSCREEN); 2029 return TRUE; 2030 } 2031 2032 if (m_style & UIF_WINDOW_WORKAREA) 2033 { 2034 *prcWorkArea = mi.rcWork; 2035 return TRUE; 2036 } 2037 2038 *prcWorkArea = mi.rcMonitor; 2039 return TRUE; 2040 } 2041 2042 void 2043 CUIFWindow::AdjustWindowPosition() 2044 { 2045 RECT rc; 2046 rc.left = m_nLeft; 2047 rc.right = m_nLeft + m_nWidth; 2048 rc.top = m_nTop; 2049 rc.bottom = m_nTop + m_nHeight; 2050 2051 RECT rcWorkArea; 2052 if (!GetWorkArea(&rc, &rcWorkArea)) 2053 return; 2054 2055 if (m_nLeft < rcWorkArea.left) 2056 m_nLeft = rcWorkArea.left; 2057 if (m_nTop < rcWorkArea.top) 2058 m_nTop = rcWorkArea.top; 2059 if (m_nLeft + m_nWidth >= rcWorkArea.right) 2060 m_nLeft = rcWorkArea.right - m_nWidth; 2061 if (m_nTop + m_nHeight >= rcWorkArea.bottom) 2062 m_nTop = rcWorkArea.bottom - m_nHeight; 2063 } 2064 2065 void CUIFWindow::SetBehindModal(CUIFWindow *pBehindModal) 2066 { 2067 m_pBehindModal = pBehindModal; 2068 } 2069 2070 void CUIFWindow::SetTimerObject(CUIFObject *pTimerObject, UINT uElapse) 2071 { 2072 if (pTimerObject) 2073 { 2074 m_pTimerObject = pTimerObject; 2075 ::SetTimer(m_hWnd, USER_TIMER_ID, uElapse, NULL); 2076 } 2077 else 2078 { 2079 m_pTimerObject = NULL; 2080 ::KillTimer(m_hWnd, USER_TIMER_ID); 2081 } 2082 } 2083 2084 STDMETHODIMP_(void) 2085 CUIFWindow::PaintObject(HDC hDC, LPCRECT prc) 2086 { 2087 BOOL bGotDC = FALSE; 2088 if (!hDC) 2089 { 2090 hDC = ::GetDC(m_hWnd); 2091 bGotDC = TRUE; 2092 } 2093 2094 if (!prc) 2095 prc = &m_rc; 2096 2097 HDC hMemDC = ::CreateCompatibleDC(hDC); 2098 HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, prc->right - prc->left, prc->bottom - prc->top); 2099 2100 HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem); 2101 ::SetViewportOrgEx(hMemDC, -prc->left, -prc->top, NULL); 2102 if (FAILED(EnsureThemeData(m_hWnd)) || 2103 ((!(m_style & UIF_WINDOW_CHILD) || FAILED(DrawThemeParentBackground(m_hWnd, hMemDC, &m_rc))) && 2104 FAILED(DrawThemeBackground(hMemDC, m_iStateId, &m_rc, NULL)))) 2105 { 2106 if (m_pScheme) 2107 m_pScheme->FillRect(hMemDC, prc, 22); 2108 } 2109 2110 CUIFObject::PaintObject(hMemDC, prc); 2111 ::BitBlt(hDC, prc->left, prc->top, 2112 prc->right - prc->left, prc->bottom - prc->top, 2113 hMemDC, prc->left, prc->top, SRCCOPY); 2114 ::SelectObject(hMemDC, hbmOld); 2115 ::DeleteObject(hbmMem); 2116 ::DeleteDC(hMemDC); 2117 2118 if (bGotDC) 2119 ::ReleaseDC(m_hWnd, hDC); 2120 } 2121 2122 STDMETHODIMP_(void) 2123 CUIFWindow::Move(INT x, INT y, INT nWidth, INT nHeight) 2124 { 2125 m_nLeft = x; 2126 m_nTop = y; 2127 if (nWidth >= 0) 2128 m_nWidth = nWidth; 2129 if (nHeight >= 0) 2130 m_nHeight = nHeight; 2131 if (::IsWindow(m_hWnd)) 2132 { 2133 AdjustWindowPosition(); 2134 ::MoveWindow(m_hWnd, m_nLeft, m_nTop, m_nWidth, m_nHeight, TRUE); 2135 } 2136 } 2137 2138 STDMETHODIMP_(void) 2139 CUIFWindow::RemoveUIObj(CUIFObject *pRemove) 2140 { 2141 if (pRemove == m_pCaptured) 2142 SetCaptureObject(NULL); 2143 2144 if (pRemove == m_pTimerObject) 2145 { 2146 m_pTimerObject = NULL; 2147 ::KillTimer(m_hWnd, USER_TIMER_ID); 2148 } 2149 2150 if (pRemove == m_pPointed) 2151 m_pPointed = NULL; 2152 2153 CUIFObject::RemoveUIObj(pRemove); 2154 } 2155 2156 STDMETHODIMP_(void) 2157 CUIFWindow::HandleMouseMsg(UINT uMsg, LONG x, LONG y) 2158 { 2159 POINT pt = { x, y }; 2160 2161 CUIFObject *pFound = (CUIFWindow *)ObjectFromPoint(pt); 2162 2163 SetObjectPointed(pFound, pt); 2164 2165 if (m_pCaptured) 2166 pFound = m_pCaptured; 2167 2168 if (!pFound || OnSetCursor(uMsg, pt.x, pt.y)) 2169 { 2170 HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW); 2171 ::SetCursor(hCursor); 2172 } 2173 2174 if (pFound && pFound->m_bEnable) 2175 { 2176 switch (uMsg) 2177 { 2178 case WM_MOUSEMOVE: 2179 pFound->OnMouseMove(pt.x, pt.y); 2180 break; 2181 case WM_LBUTTONDOWN: 2182 pFound->OnLButtonDown(pt.x, pt.y); 2183 break; 2184 case WM_LBUTTONUP: 2185 pFound->OnLButtonUp(pt.x, pt.y); 2186 break; 2187 case WM_RBUTTONDOWN: 2188 pFound->OnRButtonDown(pt.x, pt.y); 2189 break; 2190 case WM_RBUTTONUP: 2191 pFound->OnRButtonUp(pt.x, pt.y); 2192 break; 2193 case WM_MBUTTONDOWN: 2194 pFound->OnMButtonDown(pt.x, pt.y); 2195 break; 2196 case WM_MBUTTONUP: 2197 pFound->OnMButtonUp(pt.x, pt.y); 2198 break; 2199 } 2200 } 2201 } 2202 2203 ///////////////////////////////////////////////////////////////////////////// 2204 // CUIFShadow 2205 2206 /// @unimplemented 2207 CUIFShadow::CUIFShadow(HINSTANCE hInst, DWORD style, CUIFWindow *pShadowOwner) 2208 : CUIFWindow(hInst, (style | UIF_WINDOW_TOOLWINDOW)) 2209 { 2210 m_pShadowOwner = pShadowOwner; 2211 m_rgbShadowColor = RGB(0, 0, 0); 2212 m_dwUnknown11[0] = 0; 2213 m_dwUnknown11[1] = 0; 2214 m_xShadowDelta = m_yShadowDelta = 0; 2215 m_bLayerAvailable = FALSE; 2216 } 2217 2218 CUIFShadow::~CUIFShadow() 2219 { 2220 if (m_pShadowOwner) 2221 m_pShadowOwner->m_pShadow = NULL; 2222 } 2223 2224 /// @unimplemented 2225 void CUIFShadow::InitSettings() 2226 { 2227 m_bLayerAvailable = FALSE; 2228 m_rgbShadowColor = RGB(128, 128, 128); 2229 m_xShadowDelta = m_yShadowDelta = 2; 2230 } 2231 2232 /// @unimplemented 2233 void CUIFShadow::InitShadow() 2234 { 2235 if (m_bLayerAvailable) 2236 { 2237 //FIXME 2238 } 2239 } 2240 2241 void CUIFShadow::AdjustWindowPos() 2242 { 2243 HWND hwndOwner = *m_pShadowOwner; 2244 if (!::IsWindow(m_hWnd)) 2245 return; 2246 2247 RECT rc; 2248 ::GetWindowRect(hwndOwner, &rc); 2249 ::SetWindowPos(m_hWnd, hwndOwner, 2250 rc.left + m_xShadowDelta, 2251 rc.top + m_yShadowDelta, 2252 rc.right - rc.left, 2253 rc.bottom - rc.top, 2254 SWP_NOOWNERZORDER | SWP_NOACTIVATE); 2255 } 2256 2257 void CUIFShadow::OnOwnerWndMoved(BOOL bDoSize) 2258 { 2259 if (::IsWindow(m_hWnd) && ::IsWindowVisible(m_hWnd)) 2260 { 2261 AdjustWindowPos(); 2262 if (bDoSize) 2263 InitShadow(); 2264 } 2265 } 2266 2267 STDMETHODIMP_(BOOL) 2268 CUIFShadow::Initialize() 2269 { 2270 InitSettings(); 2271 return CUIFWindow::Initialize(); 2272 } 2273 2274 STDMETHODIMP_(DWORD) 2275 CUIFShadow::GetWndStyleEx() 2276 { 2277 DWORD exstyle = CUIFWindow::GetWndStyleEx(); 2278 if (m_bLayerAvailable) 2279 exstyle |= WS_EX_LAYERED; 2280 return exstyle; 2281 } 2282 2283 STDMETHODIMP_(void) 2284 CUIFShadow::OnPaint(HDC hDC) 2285 { 2286 RECT rc = m_rc; 2287 HBRUSH hBrush = ::CreateSolidBrush(m_rgbShadowColor); 2288 ::FillRect(hDC, &rc, hBrush); 2289 ::DeleteObject(hBrush); 2290 } 2291 2292 STDMETHODIMP_(LRESULT) 2293 CUIFShadow::OnWindowPosChanging(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 2294 { 2295 WINDOWPOS *wp = (WINDOWPOS *)lParam; 2296 wp->hwndInsertAfter = *m_pShadowOwner; 2297 return ::DefWindowProc(hWnd, Msg, wParam, lParam); 2298 } 2299 2300 STDMETHODIMP_(LRESULT) 2301 CUIFShadow::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 2302 { 2303 InitSettings(); 2304 2305 DWORD exstyle; 2306 if (m_bLayerAvailable) 2307 exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED; 2308 else 2309 exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED; 2310 2311 ::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exstyle); 2312 2313 AdjustWindowPos(); 2314 InitShadow(); 2315 2316 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 2317 } 2318 2319 STDMETHODIMP_(void) 2320 CUIFShadow::Show(BOOL bVisible) 2321 { 2322 if (bVisible && ::IsWindow(m_hWnd) && !::IsWindowVisible(m_hWnd)) 2323 { 2324 AdjustWindowPos(); 2325 InitShadow(); 2326 } 2327 2328 if (::IsWindow(m_hWnd)) 2329 { 2330 m_bVisible = bVisible; 2331 ::ShowWindow(m_hWnd, (bVisible ? SW_SHOWNOACTIVATE : SW_HIDE)); 2332 } 2333 } 2334 2335 ///////////////////////////////////////////////////////////////////////////// 2336 // CUIFToolTip 2337 2338 CUIFToolTip::CUIFToolTip(HINSTANCE hInst, DWORD style, CUIFWindow *pToolTipOwner) 2339 : CUIFWindow(hInst, style) 2340 { 2341 m_pToolTipOwner = pToolTipOwner; 2342 m_rcToolTipMargin.left = 2; 2343 m_rcToolTipMargin.top = 2; 2344 m_rcToolTipMargin.right = 2; 2345 m_rcToolTipMargin.bottom = 2; 2346 m_pToolTipTarget = NULL; 2347 m_pszToolTipText = NULL; 2348 m_dwUnknown10 = 0; //FIXME: name and type 2349 m_nDelayTimeType2 = -1; 2350 m_nDelayTimeType3 = -1; 2351 m_nDelayTimeType1 = -1; 2352 m_cxToolTipWidth = -1; 2353 m_bToolTipHasBkColor = 0; 2354 m_bToolTipHasTextColor = 0; 2355 m_rgbToolTipBkColor = 0; 2356 m_rgbToolTipTextColor = 0; 2357 } 2358 2359 CUIFToolTip::~CUIFToolTip() 2360 { 2361 if (m_pToolTipOwner) 2362 m_pToolTipOwner->m_pToolTip = NULL; 2363 if (m_pszToolTipText) 2364 delete[] m_pszToolTipText; 2365 } 2366 2367 LONG 2368 CUIFToolTip::GetDelayTime(UINT uType) 2369 { 2370 LONG nDelayTime; 2371 switch (uType) 2372 { 2373 case 1: 2374 { 2375 nDelayTime = m_nDelayTimeType1; 2376 if (nDelayTime == -1) 2377 return ::GetDoubleClickTime() / 5; 2378 return nDelayTime; 2379 } 2380 case 2: 2381 { 2382 nDelayTime = m_nDelayTimeType2; 2383 if (nDelayTime == -1) 2384 return 10 * ::GetDoubleClickTime(); 2385 return nDelayTime; 2386 } 2387 case 3: 2388 { 2389 nDelayTime = m_nDelayTimeType3; 2390 if (nDelayTime == -1) 2391 return ::GetDoubleClickTime(); 2392 return nDelayTime; 2393 } 2394 default: 2395 { 2396 return 0; 2397 } 2398 } 2399 } 2400 2401 void CUIFToolTip::GetMargin(LPRECT prc) 2402 { 2403 if (prc) 2404 *prc = m_rcToolTipMargin; 2405 } 2406 2407 COLORREF 2408 CUIFToolTip::GetTipBkColor() 2409 { 2410 if (m_bToolTipHasBkColor) 2411 return m_rgbToolTipBkColor; 2412 return ::GetSysColor(COLOR_INFOBK); 2413 } 2414 2415 COLORREF 2416 CUIFToolTip::GetTipTextColor() 2417 { 2418 if (m_bToolTipHasTextColor) 2419 return m_rgbToolTipTextColor; 2420 return ::GetSysColor(COLOR_INFOTEXT); 2421 } 2422 2423 CUIFObject* 2424 CUIFToolTip::FindObject(HWND hWnd, POINT pt) 2425 { 2426 if (hWnd == *m_pToolTipOwner) 2427 return m_pToolTipOwner->ObjectFromPoint(pt); 2428 return NULL; 2429 } 2430 2431 void 2432 CUIFToolTip::ShowTip() 2433 { 2434 ::KillTimer(m_hWnd, TOOLTIP_TIMER_ID); 2435 2436 if (!m_pToolTipTarget) 2437 return; 2438 2439 LPCWSTR pszText = m_pToolTipTarget->GetToolTip(); 2440 if (!pszText) 2441 return; 2442 2443 if (!m_pToolTipTarget || m_pToolTipTarget->OnShowToolTip()) 2444 return; 2445 2446 POINT Point; 2447 ::GetCursorPos(&Point); 2448 ::ScreenToClient(*m_pToolTipTarget->m_pWindow, &Point); 2449 2450 RECT rc; 2451 m_pToolTipTarget->GetRect(&rc); 2452 if (!::PtInRect(&rc, Point)) 2453 return; 2454 2455 size_t cchText = wcslen(pszText); 2456 m_pszToolTipText = new(cicNoThrow) WCHAR[cchText + 1]; 2457 if (!m_pszToolTipText) 2458 return; 2459 2460 lstrcpynW(m_pszToolTipText, pszText, cchText + 1); 2461 2462 SIZE size; 2463 GetTipWindowSize(&size); 2464 2465 RECT rc2 = rc; 2466 ::ClientToScreen(*m_pToolTipTarget->m_pWindow, (LPPOINT)&rc); 2467 ::ClientToScreen(*m_pToolTipTarget->m_pWindow, (LPPOINT)&rc.right); 2468 GetTipWindowRect(&rc2, size, &rc); 2469 2470 m_bShowToolTip = TRUE; 2471 Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); 2472 Show(TRUE); 2473 } 2474 2475 void 2476 CUIFToolTip::HideTip() 2477 { 2478 ::KillTimer(m_hWnd, TOOLTIP_TIMER_ID); 2479 m_bShowToolTip = FALSE; 2480 2481 if (m_pToolTipTarget) 2482 m_pToolTipTarget->OnHideToolTip(); 2483 2484 if (m_bVisible) 2485 { 2486 if (m_pszToolTipText) 2487 { 2488 delete[] m_pszToolTipText; 2489 m_pszToolTipText = NULL; 2490 } 2491 Show(FALSE); 2492 } 2493 } 2494 2495 void 2496 CUIFToolTip::GetTipWindowSize(LPSIZE pSize) 2497 { 2498 if (!m_pszToolTipText) 2499 return; 2500 2501 HDC hDC = ::GetDC(m_hWnd); 2502 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 2503 2504 RECT rcText = { 0, 0, 0, 0 }; 2505 INT cyText; 2506 if (m_cxToolTipWidth <= 0) 2507 { 2508 cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | DT_SINGLELINE); 2509 } 2510 else 2511 { 2512 rcText.right = m_cxToolTipWidth; 2513 cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | DT_WORDBREAK); 2514 } 2515 2516 RECT rcMargin; 2517 GetMargin(&rcMargin); 2518 2519 RECT rc; 2520 rc.left = rcText.left - rcMargin.left; 2521 rc.top = rcText.top - rcMargin.top; 2522 rc.right = rcText.right + rcMargin.right; 2523 rc.bottom = rcText.top + cyText + rcMargin.bottom; 2524 ClientRectToWindowRect(&rc); 2525 2526 pSize->cx = rc.right - rc.left; 2527 pSize->cy = rc.bottom - rc.top; 2528 2529 ::SelectObject(hDC, hFontOld); 2530 ::ReleaseDC(m_hWnd, hDC); 2531 } 2532 2533 void 2534 CUIFToolTip::GetTipWindowRect(LPRECT pRect, SIZE toolTipSize, LPCRECT prc) 2535 { 2536 POINT Point; 2537 GetCursorPos(&Point); 2538 2539 HCURSOR hCursor = ::GetCursor(); 2540 ICONINFO IconInfo; 2541 INT yHotspot = 0; 2542 INT cyCursor = ::GetSystemMetrics(SM_CYCURSOR); 2543 if (hCursor && ::GetIconInfo(hCursor, &IconInfo)) 2544 { 2545 BITMAP bm; 2546 ::GetObject(IconInfo.hbmMask, sizeof(bm), &bm); 2547 if (!IconInfo.fIcon) 2548 { 2549 cyCursor = bm.bmHeight; 2550 yHotspot = IconInfo.yHotspot; 2551 if (!IconInfo.hbmColor) 2552 cyCursor = bm.bmHeight / 2; 2553 } 2554 if (IconInfo.hbmColor) 2555 ::DeleteObject(IconInfo.hbmColor); 2556 if (IconInfo.hbmMask) 2557 ::DeleteObject(IconInfo.hbmMask); 2558 } 2559 2560 RECT rcMonitor; 2561 rcMonitor.left = 0; 2562 rcMonitor.top = 0; 2563 rcMonitor.right = GetSystemMetrics(SM_CXSCREEN); 2564 rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN); 2565 2566 HMONITOR hMon = ::MonitorFromPoint(Point, MONITOR_DEFAULTTONEAREST); 2567 MONITORINFO mi; 2568 if (hMon) 2569 { 2570 mi.cbSize = sizeof(MONITORINFO); 2571 if (::GetMonitorInfo(hMon, &mi)) 2572 rcMonitor = mi.rcMonitor; 2573 } 2574 2575 pRect->left = Point.x; 2576 pRect->right = pRect->left + toolTipSize.cx; 2577 pRect->top = Point.y + cyCursor - yHotspot; 2578 pRect->bottom = pRect->top + toolTipSize.cy; 2579 2580 if (rcMonitor.right < pRect->right) 2581 { 2582 pRect->left = rcMonitor.right - toolTipSize.cx; 2583 pRect->right = rcMonitor.right; 2584 } 2585 if (pRect->left < rcMonitor.left) 2586 { 2587 pRect->left = rcMonitor.left; 2588 pRect->right = rcMonitor.left + toolTipSize.cx; 2589 } 2590 if (rcMonitor.bottom < pRect->bottom) 2591 { 2592 pRect->top = rcMonitor.bottom - toolTipSize.cy; 2593 pRect->bottom = rcMonitor.bottom; 2594 } 2595 if (pRect->top < rcMonitor.top) 2596 { 2597 pRect->top = rcMonitor.top; 2598 pRect->bottom = rcMonitor.top + toolTipSize.cy; 2599 } 2600 } 2601 2602 void 2603 CUIFToolTip::RelayEvent(LPMSG pMsg) 2604 { 2605 if (!pMsg) 2606 return; 2607 2608 switch (pMsg->message) 2609 { 2610 case WM_MOUSEMOVE: 2611 { 2612 if (m_bEnable && 2613 ::GetKeyState(VK_LBUTTON) >= 0 && 2614 ::GetKeyState(VK_MBUTTON) >= 0 && 2615 ::GetKeyState(VK_RBUTTON) >= 0) 2616 { 2617 POINT pt = { (SHORT)LOWORD(pMsg->lParam), (SHORT)HIWORD(pMsg->lParam) }; 2618 CUIFObject *pFound = CUIFToolTip::FindObject(pMsg->hwnd, pt); 2619 if (pFound) 2620 { 2621 if (m_pToolTipTarget != pFound) 2622 { 2623 HideTip(); 2624 2625 LONG DelayTime; 2626 if (!m_bVisible) 2627 DelayTime = GetDelayTime(3); 2628 else 2629 DelayTime = GetDelayTime(1); 2630 ::SetTimer(m_hWnd, TOOLTIP_TIMER_ID, DelayTime, NULL); 2631 } 2632 } 2633 else 2634 { 2635 HideTip(); 2636 } 2637 m_pToolTipTarget = pFound; 2638 } 2639 break; 2640 } 2641 case WM_LBUTTONDOWN: 2642 case WM_RBUTTONDOWN: 2643 case WM_MBUTTONDOWN: 2644 { 2645 HideTip(); 2646 break; 2647 } 2648 } 2649 } 2650 2651 STDMETHODIMP_(void) CUIFToolTip::OnPaint(HDC hDC) 2652 { 2653 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 2654 INT iBkModeOld = ::SetBkMode(hDC, TRANSPARENT); 2655 2656 COLORREF rgbTextColor = GetTipTextColor(); 2657 COLORREF rgbOldTextColor = ::SetTextColor(hDC, rgbTextColor); 2658 2659 COLORREF rgbBkColor = GetTipBkColor(); 2660 HBRUSH hbrBack = ::CreateSolidBrush(rgbBkColor); 2661 RECT rc = m_rc; 2662 if (hbrBack) 2663 { 2664 ::FillRect(hDC, &rc, hbrBack); 2665 ::DeleteObject(hbrBack); 2666 } 2667 2668 RECT rcMargin; 2669 GetMargin(&rcMargin); 2670 2671 rc.left += rcMargin.left; 2672 rc.top += rcMargin.top; 2673 rc.right -= rcMargin.right; 2674 rc.bottom -= rcMargin.bottom; 2675 2676 if (m_cxToolTipWidth <= 0) 2677 ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_SINGLELINE); 2678 else 2679 ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_WORDBREAK); 2680 2681 ::SetTextColor(hDC, rgbOldTextColor); 2682 ::SetBkMode(hDC, iBkModeOld); 2683 ::SelectObject(hDC, hFontOld); 2684 } 2685 2686 STDMETHODIMP_(void) CUIFToolTip::Enable(BOOL bEnable) 2687 { 2688 if (!bEnable) 2689 HideTip(); 2690 CUIFObject::Enable(bEnable); 2691 } 2692 2693 STDMETHODIMP_(void) CUIFToolTip::OnTimer(WPARAM wParam) 2694 { 2695 if (wParam == TOOLTIP_TIMER_ID) 2696 ShowTip(); 2697 } 2698 2699 ///////////////////////////////////////////////////////////////////////////// 2700 // CUIFButton 2701 2702 CUIFButton::CUIFButton( 2703 CUIFObject *pParent, 2704 DWORD nObjectID, 2705 LPCRECT prc, 2706 DWORD style) : CUIFObject(pParent, nObjectID, prc, style) 2707 { 2708 m_ButtonIcon.m_hIcon = NULL; 2709 m_ButtonIcon.m_hImageList = NULL; 2710 m_dwUnknown9 = 0; 2711 m_uButtonStatus = 0; 2712 m_bPressed = FALSE; 2713 m_hbmButton1 = NULL; 2714 m_hbmButton2 = NULL; 2715 m_pszButtonText = NULL; 2716 } 2717 2718 CUIFButton::~CUIFButton() 2719 { 2720 if (m_pszButtonText) 2721 { 2722 delete[] m_pszButtonText; 2723 m_pszButtonText = NULL; 2724 } 2725 2726 if (m_ButtonIcon.m_hImageList) 2727 ImageList_Destroy(m_ButtonIcon.m_hImageList); 2728 } 2729 2730 void 2731 CUIFButton::DrawBitmapProc(HDC hDC, LPCRECT prc, BOOL bPressed) 2732 { 2733 INT width = m_rc.right - m_rc.left; 2734 INT height = m_rc.bottom - m_rc.top; 2735 if (m_hbmButton2) 2736 { 2737 HBITMAP hbmMask = cicCreateMaskBmp(&m_rc, m_hbmButton1, m_hbmButton2, 2738 (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1), 0, 0); 2739 ::DrawState(hDC, NULL, NULL, (LPARAM)hbmMask, 0, 2740 prc->left + bPressed, prc->top + bPressed, 2741 width - bPressed, height - bPressed, 2742 DST_BITMAP | (m_bEnable ? 0 : (DSS_MONO | DSS_DISABLED))); 2743 ::DeleteObject(hbmMask); 2744 } 2745 else 2746 { 2747 ::DrawState(hDC, NULL, NULL, (LPARAM)m_hbmButton1, 0, 2748 prc->left + bPressed, prc->top + bPressed, 2749 width - bPressed, height - bPressed, 2750 DST_BITMAP | (m_bEnable ? 0 : (DSS_MONO | DSS_DISABLED))); 2751 } 2752 } 2753 2754 void 2755 CUIFButton::DrawEdgeProc(HDC hDC, LPCRECT prc, BOOL bPressed) 2756 { 2757 RECT rc = *prc; 2758 if (bPressed) 2759 ::DrawEdge(hDC, &rc, BDR_SUNKENOUTER, BF_RECT); 2760 else 2761 ::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT); 2762 } 2763 2764 void CUIFButton::DrawIconProc(HDC hDC, LPRECT prc, BOOL bPressed) 2765 { 2766 INT width = prc->right - prc->left; 2767 INT height = prc->bottom - prc->top; 2768 RECT rc = { 0, 0, width, height }; 2769 2770 HDC hMemDC = ::CreateCompatibleDC(hDC); 2771 if (!hMemDC) 2772 return; 2773 2774 HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, width, height); 2775 if (!hbmMem) 2776 { 2777 ::DeleteDC(hMemDC); 2778 return; 2779 } 2780 2781 HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem); 2782 if (m_bEnable) 2783 { 2784 ::BitBlt(hMemDC, rc.left, rc.top, width, height, hDC, prc->left, prc->top, SRCCOPY); 2785 } 2786 else 2787 { 2788 HBRUSH hbrWhite = (HBRUSH)::GetStockObject(WHITE_BRUSH); 2789 ::FillRect(hMemDC, &rc, hbrWhite); 2790 } 2791 2792 if (m_style & UIF_BUTTON_LARGE_ICON) 2793 { 2794 ::DrawIconEx(hMemDC, 2795 2 + bPressed, 2 + bPressed, 2796 m_ButtonIcon.m_hIcon, 2797 width - 4, height - 4, 2798 0, NULL, DI_NORMAL); 2799 } 2800 else 2801 { 2802 ::DrawIconEx(hMemDC, 2803 (width - 16) / 2 + bPressed, 2804 (height - 16) / 2 + bPressed, 2805 m_ButtonIcon.m_hIcon, 2806 16, 16, 2807 0, NULL, DI_NORMAL); 2808 } 2809 2810 ::SelectObject(hMemDC, hbmOld); 2811 ::DrawState(hDC, NULL, NULL, (LPARAM)hbmMem, 0, 2812 prc->left, prc->top, width, height, 2813 DST_BITMAP | (m_bEnable ? 0 : (DSS_MONO | DSS_DISABLED))); 2814 ::DeleteObject(hbmMem); 2815 ::DeleteDC(hMemDC); 2816 } 2817 2818 void 2819 CUIFButton::DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed) 2820 { 2821 if (!m_pszButtonText) 2822 return; 2823 2824 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 2825 INT cchText = lstrlenW(m_pszButtonText); 2826 SIZE textSize; 2827 ::GetTextExtentPoint32W(hDC, m_pszButtonText, cchText, &textSize); 2828 2829 INT xText, yText; 2830 if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER) 2831 xText = (m_rc.right - m_rc.left - textSize.cx) / 2; 2832 else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT) 2833 xText = m_rc.right - m_rc.left - textSize.cx; 2834 else 2835 xText = 0; 2836 2837 if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE) 2838 yText = (m_rc.bottom - m_rc.top - textSize.cy) / 2; 2839 else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM) 2840 yText = m_rc.bottom - m_rc.top - textSize.cy; 2841 else 2842 yText = 0; 2843 2844 ::SetBkMode(hDC, TRANSPARENT); 2845 2846 if (m_bEnable) 2847 { 2848 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)); 2849 ::ExtTextOutW(hDC, 2850 xText + prc->left + bPressed, yText + prc->top + bPressed, 2851 ETO_CLIPPED, prc, 2852 m_pszButtonText, cchText, NULL); 2853 } 2854 else 2855 { 2856 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); 2857 ::ExtTextOutW(hDC, 2858 xText + prc->left + bPressed + 1, yText + prc->top + bPressed + 1, 2859 ETO_CLIPPED, prc, 2860 m_pszButtonText, cchText, NULL); 2861 2862 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 2863 ::ExtTextOutW(hDC, 2864 xText + prc->left + bPressed, yText + prc->top + bPressed, 2865 ETO_CLIPPED, prc, 2866 m_pszButtonText, cchText, NULL); 2867 } 2868 2869 ::SelectObject(hDC, hFontOld); 2870 } 2871 2872 STDMETHODIMP_(void) 2873 CUIFButton::Enable(BOOL bEnable) 2874 { 2875 CUIFObject::Enable(bEnable); 2876 if (!m_bEnable) 2877 { 2878 SetStatus(0); 2879 if (IsCapture()) 2880 CUIFObject::EndCapture(); 2881 } 2882 } 2883 2884 void 2885 CUIFButton::GetIconSize(HICON hIcon, LPSIZE pSize) 2886 { 2887 ICONINFO IconInfo; 2888 if (::GetIconInfo(hIcon, &IconInfo)) 2889 { 2890 BITMAP bm; 2891 ::GetObject(IconInfo.hbmColor, sizeof(bm), &bm); 2892 ::DeleteObject(IconInfo.hbmColor); 2893 ::DeleteObject(IconInfo.hbmMask); 2894 pSize->cx = bm.bmWidth; 2895 pSize->cy = bm.bmHeight; 2896 } 2897 else 2898 { 2899 pSize->cx = ::GetSystemMetrics(SM_CXSMICON); 2900 pSize->cy = ::GetSystemMetrics(SM_CYSMICON); 2901 } 2902 } 2903 2904 void 2905 CUIFButton::GetTextSize(LPCWSTR pszText, LPSIZE pSize) 2906 { 2907 HDC hDC = ::GetDC(NULL); 2908 INT cchText = lstrlenW(pszText); 2909 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 2910 2911 if (!m_bHasCustomFont && SUCCEEDED(EnsureThemeData(*m_pWindow))) 2912 { 2913 RECT rc; 2914 GetThemeTextExtent(hDC, 0, pszText, cchText, 0, NULL, &rc); 2915 pSize->cx = rc.right; 2916 pSize->cy = rc.bottom; 2917 } 2918 else 2919 { 2920 ::GetTextExtentPoint32W(hDC, pszText, cchText, pSize); 2921 } 2922 2923 if (m_style & UIF_BUTTON_VERTICAL) 2924 { 2925 INT tmp = pSize->cx; 2926 pSize->cx = pSize->cy; 2927 pSize->cy = tmp; 2928 } 2929 2930 ::SelectObject(hDC, hFontOld); 2931 ::ReleaseDC(NULL, hDC); 2932 } 2933 2934 STDMETHODIMP_(void) 2935 CUIFButton::OnLButtonDown(LONG x, LONG y) 2936 { 2937 SetStatus(1); 2938 StartCapture(); 2939 if ((m_style & 0x30) == 0x20) 2940 NotifyCommand(1, 0); 2941 } 2942 2943 /// @unimplemented 2944 STDMETHODIMP_(void) 2945 CUIFButton::OnLButtonUp(LONG x, LONG y) 2946 { 2947 POINT pt = { x, y }; 2948 BOOL bCapture = IsCapture(); 2949 if (bCapture) 2950 EndCapture(); 2951 2952 BOOL bNotInObject = (m_style & 0x30) == 0x20; 2953 if ((m_style & 0x30) != 0x10) 2954 { 2955 bNotInObject = !PtInObject(pt); 2956 if (bNotInObject) 2957 { 2958 SetStatus(0); 2959 return; 2960 } 2961 } 2962 else 2963 { 2964 if (!bNotInObject) 2965 { 2966 bNotInObject = !PtInObject(pt); 2967 if (!bNotInObject) 2968 { 2969 SetStatus(2); 2970 NotifyCommand(1, 0); 2971 return; 2972 } 2973 } 2974 SetStatus(0); 2975 return; 2976 } 2977 2978 SetStatus(2); 2979 2980 if (bCapture) 2981 { 2982 m_bPressed = !m_bPressed; 2983 NotifyCommand(1, 0); 2984 } 2985 } 2986 2987 void CUIFButton::OnMouseIn(LONG x, LONG y) 2988 { 2989 if ((m_style & 0x30) == 0x20) 2990 { 2991 if (IsCapture()) 2992 SetStatus(0); 2993 else 2994 SetStatus(2); 2995 } 2996 else 2997 { 2998 if (IsCapture()) 2999 SetStatus(1); 3000 else 3001 SetStatus(2); 3002 } 3003 } 3004 3005 void CUIFButton::OnMouseOut(LONG x, LONG y) 3006 { 3007 if ((m_style & 0x30) == 0x20) 3008 SetStatus(0); 3009 else if (IsCapture()) 3010 SetStatus(3); 3011 else 3012 SetStatus(0); 3013 } 3014 3015 STDMETHODIMP_(void) 3016 CUIFButton::OnPaintNoTheme(HDC hDC) 3017 { 3018 ::FillRect(hDC, &m_rc, (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1)); 3019 3020 if (m_bPressed && ((m_uButtonStatus == 0) || (m_uButtonStatus == 3))) 3021 { 3022 HBRUSH hbr = cicCreateDitherBrush(); 3023 if (hbr) 3024 { 3025 COLORREF OldTextColor = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNFACE)); 3026 COLORREF OldBkColor = ::SetBkColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 3027 RECT rc = m_rc; 3028 ::InflateRect(&rc, -2, -2); 3029 ::FillRect(hDC, &rc, hbr); 3030 ::SetTextColor(hDC, OldTextColor); 3031 ::SetBkColor(hDC, OldBkColor); 3032 ::DeleteObject(hbr); 3033 } 3034 } 3035 3036 BOOL bPressed = (m_bPressed || (m_uButtonStatus == 1)); 3037 if (m_hbmButton1) 3038 DrawBitmapProc(hDC, &m_rc, bPressed); 3039 else if (m_ButtonIcon.m_hIcon) 3040 DrawIconProc(hDC, &m_rc, bPressed); 3041 else 3042 DrawTextProc(hDC, &m_rc, bPressed); 3043 3044 if (m_bPressed || (m_uButtonStatus == 1)) 3045 DrawEdgeProc(hDC, &m_rc, TRUE); 3046 else if (2 <= m_uButtonStatus && m_uButtonStatus <= 3) 3047 DrawEdgeProc(hDC, &m_rc, FALSE); 3048 } 3049 3050 void CUIFButton::SetIcon(HICON hIcon) 3051 { 3052 m_ButtonIcon = hIcon; 3053 3054 if (m_ButtonIcon.m_hIcon) 3055 GetIconSize(m_ButtonIcon.m_hIcon, &m_IconSize); 3056 else 3057 m_IconSize.cx = m_IconSize.cy = 0; 3058 3059 CallOnPaint(); 3060 } 3061 3062 void CUIFButton::SetStatus(UINT uStatus) 3063 { 3064 if (uStatus != m_uButtonStatus) 3065 { 3066 m_uButtonStatus = uStatus; 3067 CallOnPaint(); 3068 } 3069 } 3070 3071 void CUIFButton::SetText(LPCWSTR pszText) 3072 { 3073 if (m_pszButtonText) 3074 { 3075 delete[] m_pszButtonText; 3076 m_pszButtonText = NULL; 3077 } 3078 3079 m_TextSize.cx = m_TextSize.cy = 0; 3080 3081 if (pszText) 3082 { 3083 INT cch = lstrlenW(pszText); 3084 m_pszButtonText = new(cicNoThrow) WCHAR[cch + 1]; 3085 if (!m_pszButtonText) 3086 return; 3087 3088 lstrcpynW(m_pszButtonText, pszText, cch + 1); 3089 GetTextSize(m_pszButtonText, &m_TextSize); 3090 } 3091 3092 CallOnPaint(); 3093 } 3094 3095 ///////////////////////////////////////////////////////////////////////////// 3096 // CUIFButton2 3097 3098 CUIFButton2::CUIFButton2( 3099 CUIFObject *pParent, 3100 DWORD nObjectID, 3101 LPCRECT prc, 3102 DWORD style) : CUIFButton(pParent, nObjectID, prc, style) 3103 { 3104 m_iStateId = 0; 3105 m_iPartId = BP_PUSHBUTTON; 3106 m_pszClassList = L"TOOLBAR"; 3107 } 3108 3109 CUIFButton2::~CUIFButton2() 3110 { 3111 CloseThemeData(); 3112 } 3113 3114 DWORD CUIFButton2::MakeDrawFlag() 3115 { 3116 DWORD dwDrawFlags = 0; 3117 if (m_bPressed) 3118 dwDrawFlags |= UIF_DRAW_PRESSED; 3119 if (m_uButtonStatus == 1) 3120 dwDrawFlags |= 0x2; 3121 else if (2 <= m_uButtonStatus && m_uButtonStatus <= 3) 3122 dwDrawFlags |= 0x1; 3123 if (!m_bEnable) 3124 dwDrawFlags |= UIF_DRAW_DISABLED; 3125 return dwDrawFlags; 3126 } 3127 3128 /// @unimplemented 3129 STDMETHODIMP_(BOOL) 3130 CUIFButton2::OnPaintTheme(HDC hDC) 3131 { 3132 //FIXME 3133 return FALSE; 3134 } 3135 3136 STDMETHODIMP_(void) 3137 CUIFButton2::OnPaintNoTheme(HDC hDC) 3138 { 3139 if (!m_pScheme) 3140 return; 3141 3142 INT width = m_rc.right - m_rc.left; 3143 INT height = m_rc.bottom - m_rc.top; 3144 HDC hdcMem = ::CreateCompatibleDC(hDC); 3145 if (!hdcMem) 3146 return; 3147 3148 HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, width, height); 3149 if ( !hbmMem ) 3150 { 3151 ::DeleteDC(hdcMem); 3152 return; 3153 } 3154 3155 HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbmMem); 3156 HGDIOBJ hFontOld = ::SelectObject(hdcMem, m_hFont); 3157 RECT rcBack = { 0, 0, width, height }; 3158 3159 INT cxText = 0, cyText = 0, cxContent = 0, cyContent = 0; 3160 INT cxyBorders, cxButton, cyButton; 3161 if (m_pszButtonText) 3162 { 3163 cxText = m_TextSize.cx; 3164 cyText = m_TextSize.cy; 3165 } 3166 3167 if (m_ButtonIcon.m_hIcon) 3168 { 3169 cxContent = m_IconSize.cx; 3170 cyContent = m_IconSize.cy; 3171 } 3172 else if (m_hbmButton1) 3173 { 3174 cxContent = m_BitmapSize.cx; 3175 cyContent = m_BitmapSize.cy; 3176 } 3177 3178 if (m_style & UIF_BUTTON_VERTICAL) 3179 { 3180 cxyBorders = ((cyText && cyContent) ? 2 : 0); 3181 3182 cxButton = cxContent; 3183 cyButton = cyText + cyContent + cxyBorders; 3184 if (cxText > cxContent) 3185 cxButton = cxText; 3186 } 3187 else 3188 { 3189 cxyBorders = ((cxText && cxContent) ? 2 : 0); 3190 3191 cxButton = cxText + cxContent + cxyBorders; 3192 cyButton = cyContent; 3193 if (cyText > cyButton) 3194 cyButton = cyText; 3195 } 3196 3197 INT xOffset, yOffset; 3198 if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER) 3199 xOffset = (rcBack.left + rcBack.right - cxButton) / 2; 3200 else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT) 3201 xOffset = rcBack.right - cxText - 2; 3202 else 3203 xOffset = rcBack.left + 2; 3204 3205 3206 if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE) 3207 yOffset = (rcBack.top + rcBack.bottom - cyButton) / 2; 3208 else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM) 3209 yOffset = rcBack.bottom - cyButton - 2; 3210 else 3211 yOffset = rcBack.top + 2; 3212 3213 RECT rc = { xOffset, yOffset, xOffset + cxButton, cyButton + yOffset }; 3214 SIZE offsetSize = { 0, 0 }; 3215 DWORD dwDrawFlags = MakeDrawFlag(); 3216 m_pScheme->GetCtrlFaceOffset(((m_style & 0x200) ? 0xA5 : 0x54), 3217 dwDrawFlags, 3218 &offsetSize); 3219 ::OffsetRect(&rc, offsetSize.cx, offsetSize.cy); 3220 3221 RECT rcImage, rcText; 3222 if (m_style & UIF_BUTTON_VERTICAL) 3223 { 3224 rcImage.left = (rc.left + rc.right - cxContent) / 2; 3225 rcImage.top = rc.top; 3226 rcImage.right = rcImage.left + cxContent; 3227 rcImage.bottom = rc.top + cyContent; 3228 rcText.left = (rc.left + rc.right - cxText) / 2; 3229 rcText.top = rc.bottom - cyText; 3230 rcText.right = rcText.left + cxText; 3231 rcText.bottom = rc.bottom; 3232 } 3233 else 3234 { 3235 rcImage.left = rc.left; 3236 rcImage.top = (rc.top + rc.bottom - cyContent) / 2; 3237 rcImage.bottom = rcImage.top + cyContent; 3238 rcImage.right = rc.left + cxContent; 3239 rcText.left = rc.right - cxText; 3240 rcText.top = (rc.top + rc.bottom - cyText) / 2; 3241 rcText.right = rc.right; 3242 rcText.bottom = rcText.top + cyText; 3243 } 3244 3245 if (IsRTL()) 3246 m_pScheme->m_bMirroring = TRUE; 3247 3248 m_pScheme->DrawCtrlBkgd(hdcMem, 3249 &rcBack, 3250 ((m_style & 0x200) ? 0xA5 : 0x54), 3251 dwDrawFlags); 3252 if (m_pszButtonText) 3253 { 3254 m_pScheme->DrawCtrlText(hdcMem, &rcText, m_pszButtonText, -1, dwDrawFlags, 3255 !!(m_style & UIF_BUTTON_VERTICAL)); 3256 } 3257 3258 if (m_ButtonIcon.m_hIcon) 3259 m_pScheme->DrawCtrlIcon(hdcMem, &rcImage, m_ButtonIcon.m_hIcon, dwDrawFlags, &m_IconSize); 3260 else if (m_hbmButton1) 3261 m_pScheme->DrawCtrlBitmap(hdcMem, &rcImage, m_hbmButton1, m_hbmButton2, dwDrawFlags); 3262 3263 if (IsRTL()) 3264 m_pScheme->m_bMirroring = FALSE; 3265 3266 m_pScheme->DrawCtrlEdge(hdcMem, 3267 &rcBack, 3268 ((m_style & 0x200) ? 0xA5 : 0x54), 3269 dwDrawFlags); 3270 3271 ::BitBlt(hDC, m_rc.left, m_rc.top, width, height, hdcMem, 0, 0, SRCCOPY); 3272 ::SelectObject(hdcMem, hFontOld); 3273 ::SelectObject(hdcMem, hbmOld); 3274 ::DeleteObject(hbmMem); 3275 } 3276 3277 ///////////////////////////////////////////////////////////////////////////// 3278 // CUIFGripper 3279 3280 CUIFGripper::CUIFGripper(CUIFObject *pParent, LPCRECT prc, DWORD style) 3281 : CUIFObject(pParent, 0, prc, style) 3282 { 3283 m_iStateId = 0; 3284 m_pszClassList = L"REBAR"; 3285 if (m_style & UIF_GRIPPER_VERTICAL) 3286 m_iPartId = RP_GRIPPERVERT; 3287 else 3288 m_iPartId = RP_GRIPPER; 3289 } 3290 3291 CUIFGripper::~CUIFGripper() 3292 { 3293 } 3294 3295 STDMETHODIMP_(void) 3296 CUIFGripper::OnMouseMove(LONG x, LONG y) 3297 { 3298 if (IsCapture()) 3299 { 3300 POINT pt; 3301 ::GetCursorPos(&pt); 3302 m_pWindow->Move(pt.x - m_ptGripper.x, pt.y - m_ptGripper.y, -1, -1); 3303 } 3304 } 3305 3306 STDMETHODIMP_(void) 3307 CUIFGripper::OnLButtonDown(LONG x, LONG y) 3308 { 3309 StartCapture(); 3310 m_ptGripper.x = x; 3311 m_ptGripper.y = y; 3312 ::ScreenToClient(*m_pWindow, &m_ptGripper); 3313 RECT rc; 3314 ::GetWindowRect(*m_pWindow, &rc); 3315 m_ptGripper.x -= rc.left; 3316 m_ptGripper.y -= rc.top; 3317 } 3318 3319 STDMETHODIMP_(void) 3320 CUIFGripper::OnLButtonUp(LONG x, LONG y) 3321 { 3322 if (IsCapture()) 3323 EndCapture(); 3324 } 3325 3326 STDMETHODIMP_(BOOL) 3327 CUIFGripper::OnPaintTheme(HDC hDC) 3328 { 3329 if (FAILED(EnsureThemeData(*m_pWindow))) 3330 return FALSE; 3331 3332 if (m_style & UIF_GRIPPER_VERTICAL) 3333 { 3334 m_rc.top += 2; 3335 m_rc.bottom -= 2; 3336 } 3337 else 3338 { 3339 m_rc.left += 2; 3340 m_rc.right -= 2; 3341 } 3342 3343 if (FAILED(DrawThemeBackground(hDC, 1, &m_rc, 0))) 3344 return FALSE; 3345 3346 return TRUE; 3347 } 3348 3349 STDMETHODIMP_(void) 3350 CUIFGripper::OnPaintNoTheme(HDC hDC) 3351 { 3352 if (m_pScheme) 3353 { 3354 m_pScheme->DrawDragHandle(hDC, &m_rc, !!(m_style & UIF_GRIPPER_VERTICAL)); 3355 return; 3356 } 3357 3358 RECT rc; 3359 if (m_style & UIF_GRIPPER_VERTICAL) 3360 rc = { m_rc.left, m_rc.top + 1, m_rc.right, m_rc.top + 4 }; 3361 else 3362 rc = { m_rc.left + 1, m_rc.top, m_rc.left + 4, m_rc.bottom }; 3363 3364 ::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT); 3365 } 3366 3367 STDMETHODIMP_(BOOL) 3368 CUIFGripper::OnSetCursor(UINT uMsg, LONG x, LONG y) 3369 { 3370 HCURSOR hCursor = ::LoadCursor(NULL, IDC_SIZEALL); 3371 ::SetCursor(hCursor); 3372 return TRUE; 3373 } 3374 3375 STDMETHODIMP_(void) 3376 CUIFGripper::SetStyle(DWORD style) 3377 { 3378 m_style = style; 3379 if (m_style & UIF_GRIPPER_VERTICAL) 3380 SetActiveTheme(L"REBAR", RP_GRIPPERVERT, 0); 3381 else 3382 SetActiveTheme(L"REBAR", RP_GRIPPER, 0); 3383 } 3384 3385 ///////////////////////////////////////////////////////////////////////////// 3386 // CUIFToolbarMenuButton 3387 3388 CUIFToolbarMenuButton::CUIFToolbarMenuButton( 3389 CUIFToolbarButton *pParent, 3390 DWORD nObjectID, 3391 LPCRECT prc, 3392 DWORD style) : CUIFButton2(pParent, nObjectID, prc, style) 3393 { 3394 m_pToolbarButton = pParent; 3395 3396 HFONT hFont = ::CreateFontW(8, 8, 0, 0, FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET, 3397 0, 0, 0, 0, L"Marlett"); 3398 SetFont(hFont); 3399 SetText(L"u"); // downward triangle 3400 } 3401 3402 CUIFToolbarMenuButton::~CUIFToolbarMenuButton() 3403 { 3404 ::DeleteObject(m_hFont); 3405 SetFont(NULL); 3406 } 3407 3408 STDMETHODIMP_(void) 3409 CUIFToolbarMenuButton::OnLButtonUp(LONG x, LONG y) 3410 { 3411 CUIFButton::OnLButtonUp(x, y); 3412 m_pToolbarButton->OnUnknownMouse0(); 3413 } 3414 3415 STDMETHODIMP_(BOOL) 3416 CUIFToolbarMenuButton::OnSetCursor(UINT uMsg, LONG x, LONG y) 3417 { 3418 m_pToolbarButton->OnSetCursor(uMsg, x, y); 3419 return FALSE; 3420 } 3421 3422 ///////////////////////////////////////////////////////////////////////////// 3423 // CUIFToolbarButtonElement 3424 3425 CUIFToolbarButtonElement::CUIFToolbarButtonElement( 3426 CUIFToolbarButton *pParent, 3427 DWORD nObjectID, 3428 LPCRECT prc, 3429 DWORD style) : CUIFButton2(pParent, nObjectID, prc, style) 3430 { 3431 m_pToolbarButton = pParent; 3432 } 3433 3434 STDMETHODIMP_(LPCWSTR) 3435 CUIFToolbarButtonElement::GetToolTip() 3436 { 3437 if (m_pToolbarButton) 3438 return m_pToolbarButton->GetToolTip(); 3439 return NULL; 3440 } 3441 3442 STDMETHODIMP_(void) 3443 CUIFToolbarButtonElement::OnLButtonUp(LONG x, LONG y) 3444 { 3445 CUIFButton::OnLButtonUp(x, y); 3446 if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) == 0x20000) 3447 m_pToolbarButton->OnUnknownMouse0(); 3448 else 3449 m_pToolbarButton->OnLeftClick(); 3450 } 3451 3452 STDMETHODIMP_(void) 3453 CUIFToolbarButtonElement::OnRButtonUp(LONG x, LONG y) 3454 { 3455 if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) != 0x20000) 3456 m_pToolbarButton->OnRightClick(); 3457 } 3458 3459 ///////////////////////////////////////////////////////////////////////////// 3460 // CUIFToolbarButton 3461 3462 CUIFToolbarButton::CUIFToolbarButton( 3463 CUIFObject *pParent, 3464 DWORD nObjectID, 3465 LPCRECT prc, 3466 DWORD style, 3467 DWORD dwToolbarButtonFlags, 3468 LPCWSTR pszUnknownText) : CUIFObject(pParent, nObjectID, prc, style) 3469 { 3470 m_dwToolbarButtonFlags = dwToolbarButtonFlags; 3471 m_pszUnknownText = pszUnknownText; 3472 } 3473 3474 BOOL CUIFToolbarButton::Init() 3475 { 3476 RECT rc1, rc2; 3477 rc1 = rc2 = m_rc; 3478 3479 if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000) 3480 { 3481 rc1.right -= 12; 3482 rc2.left = rc1.right + 1; 3483 } 3484 3485 DWORD style = UIF_BUTTON_LARGE_ICON | UIF_BUTTON_V_ALIGN_MIDDLE | UIF_BUTTON_H_ALIGN_CENTER; 3486 if (m_dwToolbarButtonFlags & 0x2000) 3487 style |= 0x10; 3488 if (m_dwToolbarButtonFlags & 0x80000) 3489 style |= UIF_BUTTON_VERTICAL; 3490 m_pToolbarButtonElement = new(cicNoThrow) CUIFToolbarButtonElement(this, m_nObjectID, &rc1, style); 3491 if (!m_pToolbarButtonElement) 3492 return FALSE; 3493 3494 m_pToolbarButtonElement->Initialize(); 3495 AddUIObj(m_pToolbarButtonElement); 3496 3497 if (!m_bEnable) 3498 m_pToolbarButtonElement->Enable(FALSE); 3499 3500 if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000) 3501 { 3502 style = UIF_BUTTON_LARGE_ICON | UIF_BUTTON_H_ALIGN_CENTER; 3503 if (m_dwToolbarButtonFlags & 0x80000) 3504 style |= UIF_BUTTON_VERTICAL; 3505 3506 m_pToolbarMenuButton = new(cicNoThrow) CUIFToolbarMenuButton(this, 0, &rc2, style); 3507 if (!m_pToolbarMenuButton) 3508 return FALSE; 3509 3510 m_pToolbarMenuButton->Initialize(); 3511 AddUIObj(m_pToolbarMenuButton); 3512 3513 if (!m_bEnable) 3514 m_pToolbarMenuButton->Enable(FALSE); 3515 } 3516 3517 return TRUE; 3518 } 3519 3520 HICON CUIFToolbarButton::GetIcon() 3521 { 3522 return m_pToolbarButtonElement->m_ButtonIcon.m_hIcon; 3523 } 3524 3525 void CUIFToolbarButton::SetIcon(HICON hIcon) 3526 { 3527 m_pToolbarButtonElement->SetIcon(hIcon); 3528 } 3529 3530 STDMETHODIMP_(void) 3531 CUIFToolbarButton::ClearWndObj() 3532 { 3533 if (m_pToolbarButtonElement) 3534 m_pToolbarButtonElement->ClearWndObj(); 3535 if (m_pToolbarMenuButton) 3536 m_pToolbarMenuButton->ClearWndObj(); 3537 3538 CUIFObject::ClearWndObj(); 3539 } 3540 3541 STDMETHODIMP_(void) 3542 CUIFToolbarButton::DetachWndObj() 3543 { 3544 if (m_pToolbarButtonElement) 3545 m_pToolbarButtonElement->DetachWndObj(); 3546 if (m_pToolbarMenuButton) 3547 m_pToolbarMenuButton->DetachWndObj(); 3548 3549 CUIFObject::DetachWndObj(); 3550 } 3551 3552 STDMETHODIMP_(void) 3553 CUIFToolbarButton::Enable(BOOL bEnable) 3554 { 3555 CUIFObject::Enable(bEnable); 3556 if (m_pToolbarButtonElement) 3557 m_pToolbarButtonElement->Enable(bEnable); 3558 if (m_pToolbarMenuButton) 3559 m_pToolbarMenuButton->Enable(bEnable); 3560 } 3561 3562 STDMETHODIMP_(LPCWSTR) 3563 CUIFToolbarButton::GetToolTip() 3564 { 3565 return CUIFObject::GetToolTip(); 3566 } 3567 3568 STDMETHODIMP_(void) 3569 CUIFToolbarButton::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId) 3570 { 3571 if (m_pToolbarButtonElement) 3572 m_pToolbarButtonElement->SetActiveTheme(pszClassList, iPartId, iStateId); 3573 if (m_pToolbarMenuButton) 3574 m_pToolbarMenuButton->SetActiveTheme(pszClassList, iPartId, iStateId); 3575 3576 m_pszClassList = pszClassList; 3577 m_iPartId = iPartId; 3578 m_iStateId = iStateId; 3579 } 3580 3581 STDMETHODIMP_(void) 3582 CUIFToolbarButton::SetFont(HFONT hFont) 3583 { 3584 m_pToolbarButtonElement->SetFont(hFont); 3585 } 3586 3587 STDMETHODIMP_(void) 3588 CUIFToolbarButton::SetRect(LPCRECT prc) 3589 { 3590 CUIFObject::SetRect(prc); 3591 3592 RECT rc1, rc2; 3593 rc1 = rc2 = m_rc; 3594 3595 if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000) 3596 { 3597 rc1.right -= 12; 3598 rc2.left = rc1.right + 1; 3599 } 3600 3601 if (m_pToolbarButtonElement) 3602 m_pToolbarButtonElement->SetRect(&rc1); 3603 if (m_pToolbarMenuButton) 3604 m_pToolbarMenuButton->SetRect(&rc2); 3605 } 3606 3607 STDMETHODIMP_(void) 3608 CUIFToolbarButton::SetToolTip(LPCWSTR pszToolTip) 3609 { 3610 CUIFObject::SetToolTip(pszToolTip); 3611 if (m_pToolbarButtonElement) 3612 m_pToolbarButtonElement->SetToolTip(pszToolTip); 3613 if (m_pToolbarMenuButton) 3614 m_pToolbarMenuButton->SetToolTip(pszToolTip); 3615 } 3616 3617 ///////////////////////////////////////////////////////////////////////////// 3618 // CUIFWndFrame 3619 3620 CUIFWndFrame::CUIFWndFrame( 3621 CUIFObject *pParent, 3622 LPCRECT prc, 3623 DWORD style) : CUIFObject(pParent, 0, prc, style) 3624 { 3625 m_iPartId = 7; 3626 m_iStateId = 0; 3627 m_pszClassList = L"WINDOW"; 3628 m_dwHitTest = 0; 3629 m_cxFrame = m_cyFrame = 0; 3630 3631 if (m_pScheme) 3632 { 3633 if ((m_style & 0xF) && (m_style & 0xF) <= 2) 3634 { 3635 m_cxFrame = m_pScheme->CxSizeFrame(); 3636 m_cyFrame = m_pScheme->CySizeFrame(); 3637 } 3638 else 3639 { 3640 m_cxFrame = m_pScheme->CxWndBorder(); 3641 m_cyFrame = m_pScheme->CyWndBorder(); 3642 } 3643 } 3644 3645 m_cxMin = GetSystemMetrics(SM_CXMIN); 3646 m_cyMin = GetSystemMetrics(SM_CYMIN); 3647 } 3648 3649 void CUIFWndFrame::GetFrameSize(LPSIZE pSize) 3650 { 3651 pSize->cx = m_cxFrame; 3652 pSize->cy = m_cyFrame; 3653 } 3654 3655 DWORD CUIFWndFrame::HitTest(LONG x, LONG y) 3656 { 3657 DWORD dwFlags = 0; 3658 if ( m_rc.left <= x && x < m_rc.left + m_cxFrame) 3659 dwFlags |= 0x10; 3660 if (m_rc.top <= y && y < m_rc.top + m_cyFrame ) 3661 dwFlags |= 0x20; 3662 if (m_rc.right - m_cxFrame <= x && x < m_rc.right) 3663 dwFlags |= 0x40; 3664 if (m_rc.bottom - m_cyFrame <= y && y < m_rc.bottom) 3665 dwFlags |= 0x80; 3666 return dwFlags; 3667 } 3668 3669 STDMETHODIMP_(void) 3670 CUIFWndFrame::OnMouseMove(LONG x, LONG y) 3671 { 3672 if (!IsCapture()) 3673 return; 3674 3675 POINT Point; 3676 ::ClientToScreen(*m_pWindow, &Point); 3677 3678 RECT rc = m_rcWnd; 3679 3680 if (m_dwHitTest & 0x10) 3681 rc.left = Point.x + m_rcWnd.left - m_ptHit.x; 3682 3683 if (m_dwHitTest & 0x20) 3684 rc.top = Point.y + m_rcWnd.top - m_ptHit.y; 3685 3686 if (m_dwHitTest & 0x40) 3687 { 3688 rc.right = Point.x + m_rcWnd.right - m_ptHit.x; 3689 if (rc.right <= rc.left + m_cxMin) 3690 rc.right = rc.left + m_cxMin; 3691 } 3692 3693 if (m_dwHitTest & 0x80) 3694 { 3695 rc.bottom = Point.y + m_rcWnd.bottom - m_ptHit.y; 3696 if (rc.bottom <= rc.top + m_cyMin) 3697 rc.bottom = rc.top + m_cyMin; 3698 } 3699 3700 m_pWindow->Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); 3701 } 3702 3703 STDMETHODIMP_(void) 3704 CUIFWndFrame::OnLButtonDown(LONG x, LONG y) 3705 { 3706 POINT Point = { x, y }; 3707 DWORD hitTest = m_style & HitTest(x, y); 3708 if (!hitTest) 3709 return; 3710 3711 ::ClientToScreen(*m_pWindow, &Point); 3712 m_ptHit = Point; 3713 m_pWindow = m_pWindow; 3714 m_dwHitTest = hitTest; 3715 ::GetWindowRect(*m_pWindow, &m_rcWnd); 3716 StartCapture(); 3717 } 3718 3719 STDMETHODIMP_(void) 3720 CUIFWndFrame::OnLButtonUp(LONG x, LONG y) 3721 { 3722 if (IsCapture()) 3723 EndCapture(); 3724 } 3725 3726 STDMETHODIMP_(BOOL) 3727 CUIFWndFrame::OnPaintTheme(HDC hDC) 3728 { 3729 if (FAILED(EnsureThemeData(*m_pWindow))) 3730 return FALSE; 3731 3732 RECT rc = m_rc; 3733 rc.right = m_cxFrame; 3734 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 5, 1, NULL))) 3735 return FALSE; 3736 3737 rc = m_rc; 3738 rc.left = rc.right - m_cxFrame; 3739 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 10, 4, NULL))) 3740 return FALSE; 3741 3742 rc = m_rc; 3743 rc.bottom = m_cyFrame; 3744 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 5, 2, NULL))) 3745 return FALSE; 3746 3747 rc = m_rc; 3748 rc.top = rc.bottom - m_cyFrame; 3749 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 10, 8, NULL))) 3750 return FALSE; 3751 3752 return TRUE; 3753 } 3754 3755 STDMETHODIMP_(void) 3756 CUIFWndFrame::OnPaintNoTheme(HDC hDC) 3757 { 3758 if (!m_pScheme) 3759 return; 3760 3761 DWORD type = 0; 3762 if ((m_style & 0xF) == 1) 3763 type = 1; 3764 else if ( (m_style & 0xF) == 2 ) 3765 type = 2; 3766 3767 m_pScheme->DrawWndFrame(hDC, &m_rc, type, m_cxFrame, m_cyFrame); 3768 } 3769 3770 STDMETHODIMP_(BOOL) 3771 CUIFWndFrame::OnSetCursor(UINT uMsg, LONG x, LONG y) 3772 { 3773 DWORD dwHitTest = m_dwHitTest; 3774 if (!IsCapture()) 3775 dwHitTest = m_style & HitTest(x, y); 3776 3777 LPTSTR pszCursor = NULL; 3778 switch (dwHitTest) 3779 { 3780 case 0x30: 3781 case 0xC0: 3782 pszCursor = IDC_SIZENWSE; 3783 break; 3784 case 0x90: 3785 case 0x60: 3786 pszCursor = IDC_SIZENESW; 3787 break; 3788 case 0x10: 3789 case 0x40: 3790 pszCursor = IDC_SIZEWE; 3791 break; 3792 case 0x20: 3793 case 0x80: 3794 pszCursor = IDC_SIZENS; 3795 break; 3796 default: 3797 return FALSE; 3798 } 3799 3800 HCURSOR hCursor = ::LoadCursor(NULL, pszCursor); 3801 ::SetCursor(hCursor); 3802 return TRUE; 3803 } 3804 3805 ///////////////////////////////////////////////////////////////////////////// 3806 // CUIFBalloonButton 3807 3808 CUIFBalloonButton::CUIFBalloonButton( 3809 CUIFObject *pParent, 3810 DWORD nObjectID, 3811 LPCRECT prc, 3812 DWORD style) : CUIFButton(pParent, nObjectID, prc, style) 3813 { 3814 m_nCommandID = 0; 3815 } 3816 3817 STDMETHODIMP_(void) 3818 CUIFBalloonButton::OnPaint(HDC hDC) 3819 { 3820 RECT rc = m_rc; 3821 ::OffsetRect(&rc, -rc.left, -rc.top); 3822 3823 HDC hMemDC = ::CreateCompatibleDC(hDC); 3824 HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, rc.right, rc.bottom); 3825 HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem); 3826 3827 BOOL bPressed; 3828 COLORREF rgbShadow, rgbBorder; 3829 if (m_uButtonStatus == 1) 3830 { 3831 bPressed = TRUE; 3832 rgbShadow = ::GetSysColor(COLOR_BTNSHADOW); 3833 rgbBorder = ::GetSysColor(COLOR_BTNHIGHLIGHT); 3834 } 3835 else 3836 { 3837 bPressed = FALSE; 3838 if (m_uButtonStatus < 4) 3839 { 3840 rgbShadow = ::GetSysColor(COLOR_BTNHIGHLIGHT); 3841 rgbBorder = ::GetSysColor(COLOR_BTNSHADOW); 3842 } 3843 else 3844 { 3845 rgbShadow = ::GetSysColor(COLOR_INFOBK); 3846 rgbBorder = ::GetSysColor(COLOR_INFOBK); 3847 } 3848 } 3849 3850 COLORREF rgbInfoBk = ::GetSysColor(COLOR_INFOBK); 3851 HBRUSH hbrBack = ::CreateSolidBrush(rgbInfoBk); 3852 ::FillRect(hMemDC, &rc, hbrBack); 3853 ::DeleteObject(hbrBack); 3854 3855 DrawTextProc(hMemDC, &rc, bPressed); 3856 3857 HBRUSH hNullBrush = (HBRUSH)::GetStockObject(NULL_BRUSH); 3858 HGDIOBJ hbrOld = ::SelectObject(hMemDC, hNullBrush); 3859 3860 HPEN hPen = ::CreatePen(PS_SOLID, 0, rgbShadow); 3861 HGDIOBJ hPenOld = ::SelectObject(hMemDC, hPen); 3862 ::RoundRect(hMemDC, rc.left, rc.top, rc.right - 1, rc.bottom - 1, 6, 6); 3863 ::SelectObject(hMemDC, hPenOld); 3864 ::DeleteObject(hPen); 3865 3866 hPen = ::CreatePen(PS_SOLID, 0, rgbBorder); 3867 hPenOld = ::SelectObject(hMemDC, hPen); 3868 ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right, rc.bottom, 6, 6); 3869 ::SelectObject(hMemDC, hPenOld); 3870 ::DeleteObject(hPen); 3871 3872 hPen = ::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNFACE)); 3873 hPenOld = ::SelectObject(hMemDC, hPen); 3874 ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right - 1, rc.bottom - 1, 6, 6); 3875 ::SelectObject(hMemDC, hPenOld); 3876 ::DeleteObject(hPen); 3877 3878 ::SelectObject(hMemDC, hbrOld); 3879 ::BitBlt(hDC, m_rc.left, m_rc.top, m_rc.right - m_rc.left, m_rc.bottom - m_rc.top, 3880 hMemDC, rc.left, rc.top, SRCCOPY); 3881 ::SelectObject(hMemDC, hbmOld); 3882 ::DeleteObject(hbmMem); 3883 ::DeleteDC(hMemDC); 3884 } 3885 3886 void 3887 CUIFBalloonButton::DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed) 3888 { 3889 if (!m_pszButtonText) 3890 return; 3891 3892 UINT uFlags = DT_SINGLELINE; 3893 3894 if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER) 3895 uFlags |= DT_CENTER; 3896 else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT) 3897 uFlags |= DT_RIGHT; 3898 3899 if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE) 3900 uFlags |= DT_VCENTER; 3901 else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM) 3902 uFlags |= DT_BOTTOM; 3903 3904 COLORREF rgbOldColor = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)); 3905 INT nOldBkMode = ::SetBkMode(hDC, TRANSPARENT); 3906 3907 RECT rc = *prc; 3908 if (bPressed) 3909 ::OffsetRect(&rc, 1, 1); 3910 3911 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 3912 ::DrawTextW(hDC, m_pszButtonText, -1, &rc, uFlags); 3913 ::SelectObject(hDC, hFontOld); 3914 3915 ::SetBkMode(hDC, nOldBkMode); 3916 ::SetTextColor(hDC, rgbOldColor); 3917 } 3918 3919 ///////////////////////////////////////////////////////////////////////////// 3920 // CUIFBalloonWindow 3921 3922 CUIFBalloonWindow::CUIFBalloonWindow(HINSTANCE hInst, DWORD style) : CUIFWindow(hInst, style) 3923 { 3924 m_dwUnknown6 = -1; 3925 m_nActionID = -1; 3926 m_hRgn = NULL; 3927 m_pszBalloonText = NULL; 3928 m_bHasBkColor = m_bHasTextColor = FALSE; 3929 m_rgbBkColor = 0; 3930 m_rgbTextColor = 0; 3931 m_ptTarget.x = m_ptTarget.y = 0; 3932 ZeroMemory(&m_rcExclude, sizeof(m_rcExclude)); 3933 m_dwUnknown7 = 0; 3934 m_nBalloonType = 0; 3935 m_dwUnknown8[0] = 0; 3936 m_dwUnknown8[1] = 0; 3937 m_ptBalloon.x = m_ptBalloon.y = 0; 3938 m_cButtons = 0; 3939 m_hwndNotif = NULL; 3940 m_uNotifMsg = 0; 3941 m_rcMargin.left = 8; 3942 m_rcMargin.top = 8; 3943 m_rcMargin.right = 8; 3944 m_rcMargin.bottom = 8; 3945 } 3946 3947 CUIFBalloonWindow::~CUIFBalloonWindow() 3948 { 3949 if (m_pszBalloonText) 3950 { 3951 delete[] m_pszBalloonText; 3952 m_pszBalloonText = NULL; 3953 } 3954 } 3955 3956 STDMETHODIMP_(BOOL) 3957 CUIFBalloonWindow::Initialize() 3958 { 3959 CUIFWindow::Initialize(); 3960 3961 if ((m_style & UIF_BALLOON_WINDOW_TYPE_MASK) == UIF_BALLOON_WINDOW_OK) 3962 { 3963 AddButton(IDOK); 3964 } 3965 else if ((m_style & UIF_BALLOON_WINDOW_TYPE_MASK) == UIF_BALLOON_WINDOW_YESNO) 3966 { 3967 AddButton(IDYES); 3968 AddButton(IDNO); 3969 } 3970 3971 return TRUE; 3972 } 3973 3974 STDMETHODIMP_(void) 3975 CUIFBalloonWindow::OnCreate(HWND hWnd) 3976 { 3977 m_nActionID = -1; 3978 AdjustPos(); 3979 } 3980 3981 STDMETHODIMP_(void) 3982 CUIFBalloonWindow::OnDestroy(HWND hWnd) 3983 { 3984 SendNotification(m_nActionID); 3985 DoneWindowRegion(); 3986 } 3987 3988 STDMETHODIMP_(void) 3989 CUIFBalloonWindow::OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam) 3990 { 3991 CUIFBalloonButton *pButton = NULL; 3992 3993 switch (wParam) 3994 { 3995 case VK_RETURN: 3996 pButton = (CUIFBalloonButton *)FindUIObject(0); 3997 break; 3998 case VK_ESCAPE: 3999 m_nActionID = -1; 4000 ::DestroyWindow(m_hWnd); 4001 return; 4002 case TEXT('Y'): 4003 pButton = FindButton(IDYES); 4004 break; 4005 case TEXT('N'): 4006 pButton = FindButton(IDNO); 4007 break; 4008 } 4009 4010 if (!pButton) 4011 return; 4012 4013 m_nActionID = pButton->m_nCommandID; 4014 ::DestroyWindow(m_hWnd); 4015 } 4016 4017 STDMETHODIMP_(LRESULT) 4018 CUIFBalloonWindow::OnObjectNotify(CUIFObject *pObject, WPARAM wParam, LPARAM lParam) 4019 { 4020 CUIFBalloonButton *pButton = (CUIFBalloonButton *)pObject; 4021 m_nActionID = pButton->m_nCommandID; 4022 ::DestroyWindow(m_hWnd); 4023 return 0; 4024 } 4025 4026 STDMETHODIMP_(void) 4027 CUIFBalloonWindow::OnPaint(HDC hDC) 4028 { 4029 RECT rc; 4030 GetRect(&rc); 4031 PaintFrameProc(hDC, &rc); 4032 4033 switch (m_nBalloonType) 4034 { 4035 case 1: 4036 rc.top += 16; 4037 break; 4038 case 2: 4039 rc.right -= 16; 4040 break; 4041 case 3: 4042 rc.left += 16; 4043 break; 4044 default: 4045 rc.bottom -= 16; 4046 break; 4047 } 4048 4049 RECT rcMargin; 4050 GetMargin(&rcMargin); 4051 4052 rc.left += rcMargin.left; 4053 rc.top += rcMargin.top; 4054 rc.right -= rcMargin.right; 4055 rc.bottom -= rcMargin.bottom; 4056 4057 PaintMessageProc(hDC, &rc, m_pszBalloonText); 4058 } 4059 4060 void 4061 CUIFBalloonWindow::AddButton(UINT nCommandId) 4062 { 4063 RECT rc = { 0, 0, 0, 0 }; 4064 if (!((IDOK <= nCommandId) && (nCommandId <= IDNO))) 4065 return; 4066 4067 CUIFBalloonButton *pButton = new(cicNoThrow) CUIFBalloonButton(this, m_cButtons, &rc, 5); 4068 if (!pButton) 4069 return; 4070 4071 pButton->Initialize(); 4072 pButton->m_nCommandID = nCommandId; 4073 4074 LPCWSTR pszText; 4075 #ifdef IDS_OK 4076 extern HINSTANCE g_hInst; 4077 WCHAR szText[64]; 4078 ::LoadStringW(g_hInst, IDS_OK + (nCommandId - IDOK), szText, _countof(szText)); 4079 pszText = szText; 4080 #else 4081 switch (nCommandId) 4082 { 4083 case IDOK: pszText = L"OK"; break; 4084 case IDCANCEL: pszText = L"Cancel"; break; 4085 case IDABORT: pszText = L"&Abort"; break; 4086 case IDRETRY: pszText = L"&Retry"; break; 4087 case IDIGNORE: pszText = L"&Ignore"; break; 4088 case IDYES: pszText = L"&Yes"; break; 4089 default: pszText = L"&No"; break; 4090 } 4091 #endif 4092 4093 pButton->SetText(pszText); 4094 4095 AddUIObj(pButton); 4096 ++m_cButtons; 4097 } 4098 4099 /// @unimplemented 4100 void 4101 CUIFBalloonWindow::AdjustPos() 4102 { 4103 //FIXME 4104 } 4105 4106 HRGN 4107 CUIFBalloonWindow::CreateRegion(LPCRECT prc) 4108 { 4109 POINT Points[4]; 4110 HRGN hRgn; 4111 BOOL bFlag = FALSE; 4112 LONG x, y; 4113 4114 switch (m_nBalloonType) 4115 { 4116 case 1: 4117 hRgn = ::CreateRoundRectRgn(prc->left, prc->top + 16, prc->right, prc->bottom, 16, 16); 4118 y = prc->top + 16; 4119 bFlag = TRUE; 4120 break; 4121 4122 case 2: 4123 hRgn = ::CreateRoundRectRgn(prc->left, prc->top, prc->right - 16, prc->bottom, 16, 16); 4124 x = prc->right - 17; 4125 break; 4126 4127 case 3: 4128 hRgn = ::CreateRoundRectRgn(prc->left + 16, prc->top, prc->right, prc->bottom, 16, 16); 4129 x = prc->left + 16; 4130 break; 4131 4132 default: 4133 hRgn = ::CreateRoundRectRgn(prc->left, prc->top, prc->right, prc->bottom - 16, 16, 16); 4134 y = prc->bottom - 17; 4135 bFlag = TRUE; 4136 break; 4137 } 4138 4139 if (bFlag) 4140 { 4141 x = Points[1].x = m_ptBalloon.x; 4142 Points[1].y = m_ptBalloon.y; 4143 Points[0].y = Points[2].y = Points[3].y = y; 4144 Points[2].x = x + 10 * (2 * (m_dwUnknown8[0] == 0) - 1); 4145 } 4146 else 4147 { 4148 Points[2].x = x; 4149 y = Points[0].y = Points[1].y = Points[3].y = m_ptBalloon.y; 4150 Points[1].x = m_ptBalloon.x; 4151 Points[2].y = y + 10 * (2 * (m_dwUnknown8[0] == 2) - 1); 4152 } 4153 4154 Points[0].x = Points[3].x = x; 4155 4156 HRGN hPolygonRgn = ::CreatePolygonRgn(Points, _countof(Points), WINDING); 4157 ::CombineRgn(hRgn, hRgn, hPolygonRgn, RGN_OR); 4158 ::DeleteObject(hPolygonRgn); 4159 return hRgn; 4160 } 4161 4162 void 4163 CUIFBalloonWindow::DoneWindowRegion() 4164 { 4165 if (m_hRgn) 4166 { 4167 ::SetWindowRgn(m_hWnd, NULL, TRUE); 4168 ::DeleteObject(m_hRgn); 4169 m_hRgn = NULL; 4170 } 4171 } 4172 4173 CUIFBalloonButton * 4174 CUIFBalloonWindow::FindButton(UINT nCommandID) 4175 { 4176 for (UINT iButton = 0; iButton < m_cButtons; ++iButton) 4177 { 4178 CUIFBalloonButton *pButton = (CUIFBalloonButton *)FindUIObject(iButton); 4179 if (pButton && (pButton->m_nCommandID == nCommandID)) 4180 return pButton; 4181 } 4182 return NULL; 4183 } 4184 4185 CUIFObject * 4186 CUIFBalloonWindow::FindUIObject(UINT nObjectID) 4187 { 4188 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) 4189 { 4190 CUIFObject *pObject = m_ObjectArray[iItem]; 4191 if (pObject->m_nObjectID == nObjectID) 4192 return pObject; 4193 } 4194 return NULL; 4195 } 4196 4197 COLORREF 4198 CUIFBalloonWindow::GetBalloonBkColor() 4199 { 4200 if (m_bHasBkColor) 4201 return m_rgbBkColor; 4202 else 4203 return ::GetSysColor(COLOR_INFOBK); 4204 } 4205 4206 COLORREF 4207 CUIFBalloonWindow::GetBalloonTextColor() 4208 { 4209 if (m_bHasTextColor) 4210 return m_rgbTextColor; 4211 else 4212 return ::GetSysColor(COLOR_INFOTEXT); 4213 } 4214 4215 void 4216 CUIFBalloonWindow::GetButtonSize(LPSIZE pSize) 4217 { 4218 HDC hDisplayDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); 4219 4220 TEXTMETRIC tm; 4221 HGDIOBJ hFontOld = ::SelectObject(hDisplayDC, m_hFont); 4222 ::GetTextMetrics(hDisplayDC, &tm); 4223 ::SelectObject(hDisplayDC, hFontOld); 4224 ::DeleteDC(hDisplayDC); 4225 4226 pSize->cx = 16 * tm.tmAveCharWidth; 4227 pSize->cy = tm.tmHeight + 10; 4228 } 4229 4230 void 4231 CUIFBalloonWindow::GetMargin(LPRECT prcMargin) 4232 { 4233 if (prcMargin) 4234 *prcMargin = m_rcMargin; 4235 } 4236 4237 void 4238 CUIFBalloonWindow::SetExcludeRect(LPCRECT prcExclude) 4239 { 4240 m_rcExclude = *prcExclude; 4241 AdjustPos(); 4242 } 4243 4244 void 4245 CUIFBalloonWindow::SetTargetPos(POINT ptTarget) 4246 { 4247 m_ptTarget = ptTarget; 4248 AdjustPos(); 4249 } 4250 4251 void 4252 CUIFBalloonWindow::SetText(LPCWSTR pszText) 4253 { 4254 if (m_pszBalloonText) 4255 { 4256 delete[] m_pszBalloonText; 4257 m_pszBalloonText = NULL; 4258 } 4259 4260 if (pszText == NULL) 4261 pszText = L""; 4262 4263 size_t cch = wcslen(pszText); 4264 m_pszBalloonText = new(cicNoThrow) WCHAR[cch + 1]; 4265 if (m_pszBalloonText) 4266 lstrcpynW(m_pszBalloonText, pszText, cch + 1); 4267 4268 AdjustPos(); 4269 } 4270 4271 void 4272 CUIFBalloonWindow::InitWindowRegion() 4273 { 4274 RECT rc; 4275 GetRect(&rc); 4276 m_hRgn = CreateRegion(&rc); 4277 if (m_hRgn) 4278 ::SetWindowRgn(m_hWnd, m_hRgn, TRUE); 4279 } 4280 4281 void 4282 CUIFBalloonWindow::LayoutObject() 4283 { 4284 SIZE size; 4285 GetButtonSize(&size); 4286 4287 RECT rc; 4288 GetRect(&rc); 4289 4290 switch (m_nBalloonType) 4291 { 4292 case 1: 4293 rc.top += 16; 4294 break; 4295 case 2: 4296 rc.right -= 16; 4297 break; 4298 case 3: 4299 rc.left += 16; 4300 break; 4301 default: 4302 rc.bottom -= 16; 4303 break; 4304 } 4305 4306 RECT rcMargin; 4307 GetMargin(&rcMargin); 4308 rc.left += rcMargin.left; 4309 rc.top += rcMargin.top; 4310 rc.right -= rcMargin.right; 4311 rc.bottom -= rcMargin.bottom; 4312 4313 LONG xLeft = (rc.left + rc.right - size.cx * (((m_cButtons - 1) / 2) - m_cButtons)) / 2; 4314 for (UINT iButton = 0; iButton < m_cButtons; ++iButton) 4315 { 4316 CUIFObject *UIObject = FindUIObject(iButton); 4317 if (!UIObject) 4318 continue; 4319 4320 rcMargin.left = xLeft + iButton * (size.cx * 3 / 2); 4321 rcMargin.top = rc.bottom - size.cy; 4322 rcMargin.right = rcMargin.left + size.cx; 4323 rcMargin.bottom = rc.bottom; 4324 4325 UIObject->SetRect(&rcMargin); 4326 UIObject->Show(TRUE); 4327 } 4328 } 4329 4330 void 4331 CUIFBalloonWindow::PaintFrameProc(HDC hDC, LPCRECT prc) 4332 { 4333 HRGN hRgn = CreateRegion(prc); 4334 HBRUSH hbrBack = ::CreateSolidBrush(GetBalloonBkColor()); 4335 HBRUSH hbrFrame = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOWFRAME)); 4336 ::FillRgn(hDC, hRgn, hbrBack); 4337 ::FrameRgn(hDC, hRgn, hbrFrame, 1, 1); 4338 ::DeleteObject(hbrBack); 4339 ::DeleteObject(hbrFrame); 4340 ::DeleteObject(hRgn); 4341 } 4342 4343 void 4344 CUIFBalloonWindow::PaintMessageProc(HDC hDC, LPRECT prc, LPCWSTR pszText) 4345 { 4346 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 4347 COLORREF rgbOldColor = ::SetTextColor(hDC, GetBalloonTextColor()); 4348 INT nOldBkMode = ::SetBkMode(hDC, TRANSPARENT); 4349 ::DrawTextW(hDC, pszText, -1, prc, DT_WORDBREAK); 4350 ::SelectObject(hDC, hFontOld); 4351 ::SetTextColor(hDC, rgbOldColor); 4352 ::SetBkMode(hDC, nOldBkMode); 4353 } 4354 4355 void 4356 CUIFBalloonWindow::SendNotification(WPARAM wParam) 4357 { 4358 if (m_hwndNotif) 4359 ::PostMessage(m_hwndNotif, m_uNotifMsg, wParam, 0); 4360 } 4361 4362 ///////////////////////////////////////////////////////////////////////////// 4363 // CUIFMenu 4364 4365 CUIFMenu::CUIFMenu( 4366 HINSTANCE hInst, 4367 DWORD style, 4368 DWORD dwUnknown14) : CUIFWindow(hInst, style) 4369 { 4370 m_nSelectedID = -1; 4371 m_dwUnknown14 = dwUnknown14; 4372 SetMenuFont(); 4373 } 4374 4375 CUIFMenu::~CUIFMenu() 4376 { 4377 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 4378 delete m_MenuItems[iItem]; 4379 4380 ::DeleteObject(m_hMenuFont); 4381 ClearMenuFont(); 4382 } 4383 4384 void CUIFMenu::CancelMenu() 4385 { 4386 if (m_pVisibleSubMenu) 4387 { 4388 UninitShow(); 4389 } 4390 else if (m_bModal) 4391 { 4392 SetSelectedId(0xFFFFFFFF); 4393 ::PostMessage(m_hWnd, WM_NULL, 0, 0); 4394 } 4395 } 4396 4397 void CUIFMenu::ClearMenuFont() 4398 { 4399 SetFont(NULL); 4400 ::DeleteObject(m_hFont); 4401 } 4402 4403 CUIFMenuItem* 4404 CUIFMenu::GetNextItem(CUIFMenuItem *pItem) 4405 { 4406 size_t iItem, cItems = m_MenuItems.size(); 4407 4408 if (cItems == 0) 4409 return NULL; 4410 4411 if (!m_pSelectedItem) 4412 return m_MenuItems[0]; 4413 4414 for (iItem = 0; iItem < cItems; ) 4415 { 4416 if (m_MenuItems[iItem++] == pItem) 4417 break; 4418 } 4419 4420 for (;;) 4421 { 4422 if (iItem == cItems) 4423 iItem = 0; 4424 if (!m_MenuItems[iItem] || !m_MenuItems[iItem]->m_bMenuItemDisabled) 4425 break; 4426 ++iItem; 4427 } 4428 4429 return m_MenuItems[iItem]; 4430 } 4431 4432 CUIFMenuItem* 4433 CUIFMenu::GetPrevItem(CUIFMenuItem *pItem) 4434 { 4435 ptrdiff_t iItem, cItems = m_MenuItems.size(); 4436 4437 if (cItems == 0) 4438 return NULL; 4439 4440 if (!m_pSelectedItem) 4441 return m_MenuItems[cItems - 1]; 4442 4443 for (iItem = cItems - 1; iItem >= 0; ) 4444 { 4445 if (m_MenuItems[iItem--] == pItem) 4446 break; 4447 } 4448 4449 for (;;) 4450 { 4451 if (iItem < 0) 4452 iItem = cItems - 1; 4453 if (!m_MenuItems[iItem] || !m_MenuItems[iItem]->m_bMenuItemDisabled) 4454 break; 4455 --iItem; 4456 } 4457 4458 return m_MenuItems[iItem]; 4459 } 4460 4461 CUIFMenu* 4462 CUIFMenu::GetTopSubMenu() 4463 { 4464 CUIFMenu *pMenu; 4465 for (pMenu = this; pMenu->m_pParentMenu; pMenu = pMenu->m_pParentMenu) 4466 ; 4467 return pMenu; 4468 } 4469 4470 void CUIFMenu::HandleMouseMsg(UINT uMsg, LONG x, LONG y) 4471 { 4472 POINT pt = { x, y }; 4473 if (!::PtInRect(&m_rc, pt) && 4474 (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP)) 4475 { 4476 SetSelectedId(-1); 4477 PostMessage(m_hWnd, WM_NULL, 0, 0); 4478 } 4479 CUIFWindow::HandleMouseMsg(uMsg, x, y); 4480 } 4481 4482 STDMETHODIMP_(BOOL) 4483 CUIFMenu::InitShow(CUIFWindow *pWindow, LPCRECT prc, BOOL bFlag, BOOL bDoAnimation) 4484 { 4485 HWND hWnd = NULL; 4486 if (pWindow) 4487 hWnd = *pWindow; 4488 4489 CreateWnd(hWnd); 4490 4491 m_bHasMargin = FALSE; 4492 4493 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 4494 { 4495 if (m_MenuItems[iItem]) 4496 m_MenuItems[iItem]->InitMenuExtent(); 4497 } 4498 4499 INT cxMax = 0; 4500 4501 m_cxMenuExtent = 0; 4502 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 4503 { 4504 CUIFMenuItem *pItem = m_MenuItems[iItem]; 4505 if (!pItem) 4506 continue; 4507 4508 INT cxItem = m_cxyMargin + pItem->m_MenuLeftExtent.cx; 4509 if (cxMax < cxItem) 4510 cxMax = cxItem; 4511 m_cxMenuExtent = max(m_cxMenuExtent, pItem->m_MenuRightExtent.cx); 4512 if (!m_bHasMargin && pItem->m_hbmColor && pItem->IsCheck()) 4513 m_bHasMargin = TRUE; 4514 } 4515 4516 RECT rcItem = { 0, 0, 0, 0 }; 4517 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 4518 { 4519 CUIFMenuItem *pItem = m_MenuItems[iItem]; 4520 if (!pItem) 4521 continue; 4522 4523 INT cyItem = pItem->m_MenuLeftExtent.cy; 4524 rcItem.right = rcItem.left + cxMax + m_cxMenuExtent; 4525 rcItem.bottom = rcItem.top + cyItem; 4526 pItem->SetRect(&rcItem); 4527 rcItem.top += cyItem; 4528 AddUIObj(pItem); 4529 } 4530 4531 rcItem.top = 0; 4532 DWORD style = ::GetWindowLongPtr(hWnd, GWL_STYLE); 4533 cxMax = rcItem.right; 4534 INT cyMax = rcItem.bottom; 4535 if (style & WS_DLGFRAME) 4536 { 4537 cxMax = rcItem.right + 2 * ::GetSystemMetrics(SM_CXDLGFRAME); 4538 cyMax += 2 * ::GetSystemMetrics(SM_CYDLGFRAME); 4539 } 4540 else if (style & WS_BORDER) 4541 { 4542 cxMax = rcItem.right + 2 * ::GetSystemMetrics(SM_CXBORDER); 4543 cyMax += 2 * ::GetSystemMetrics(SM_CYBORDER); 4544 } 4545 4546 RECT rc = { 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN) }; 4547 4548 RECT rc3 = *prc; 4549 HMONITOR hMon = ::MonitorFromRect(&rc3, MONITOR_DEFAULTTONEAREST); 4550 if (hMon) 4551 { 4552 MONITORINFO mi = { sizeof(mi) }; 4553 if (::GetMonitorInfo(hMon, &mi)) 4554 rc = mi.rcMonitor; 4555 } 4556 4557 if (m_style & 0x200) 4558 rcItem.left -= cxMax; 4559 4560 INT x, y; 4561 DWORD dwFlags2 = 0; 4562 4563 if (bFlag) 4564 { 4565 INT bottom = prc->bottom; 4566 x = rcItem.left + prc->left; 4567 if (rcItem.top + bottom + cyMax > rc.bottom) 4568 { 4569 bottom = prc->top - cyMax; 4570 dwFlags2 = 8; 4571 } 4572 else 4573 { 4574 dwFlags2 = 4; 4575 } 4576 4577 y = rcItem.top + bottom; 4578 4579 if (rcItem.left + cxMax + prc->right > rc.right) 4580 x = rc.right - cxMax; 4581 } 4582 else 4583 { 4584 y = rcItem.top + prc->top; 4585 if (rcItem.left + prc->right + cxMax > rc.right) 4586 { 4587 x = rcItem.left + prc->left - cxMax; 4588 dwFlags2 = 2; 4589 } 4590 else 4591 { 4592 x = rcItem.left + prc->right; 4593 dwFlags2 = 1; 4594 } 4595 if (rcItem.top + cyMax + prc->bottom > rc.bottom) 4596 y = rc.bottom - cyMax; 4597 } 4598 4599 if (x > rc.right - cxMax) 4600 x = rc.right - cxMax; 4601 if (x < rc.left) 4602 x = rc.left; 4603 if (y > rc.bottom - cyMax) 4604 y = rc.bottom - cyMax; 4605 if (y < rc.top) 4606 y = rc.top; 4607 4608 Move(x, y, cxMax, -1); 4609 4610 SetRect(NULL); 4611 4612 BOOL bAnimation = FALSE; 4613 if (bDoAnimation && 4614 ::SystemParametersInfo(SPI_GETMENUANIMATION, 0, &bAnimation, 0) && bAnimation) 4615 { 4616 BOOL bMenuFade = FALSE; 4617 if (!::SystemParametersInfoA(SPI_GETMENUFADE, 0, &bMenuFade, 0)) 4618 bMenuFade = FALSE; 4619 4620 DWORD dwFlags = (bMenuFade ? 0x80000 : dwFlags2) | 0x40000; 4621 if (!AnimateWnd(200, dwFlags)) 4622 Show(TRUE); 4623 } 4624 else 4625 { 4626 Show(TRUE); 4627 } 4628 4629 if (m_pVisibleSubMenu) 4630 m_pVisibleSubMenu->m_pParentMenu = this; 4631 4632 return TRUE; 4633 } 4634 4635 BOOL CUIFMenu::InsertItem(CUIFMenuItem *pItem) 4636 { 4637 if (!m_MenuItems.Add(pItem)) 4638 return FALSE; 4639 4640 pItem->SetFont(m_hFont); 4641 return TRUE; 4642 } 4643 4644 BOOL CUIFMenu::InsertSeparator() 4645 { 4646 CUIFMenuItemSeparator *pSep = new(cicNoThrow) CUIFMenuItemSeparator(this); 4647 if (!pSep) 4648 return FALSE; 4649 4650 if (!m_MenuItems.Add(pSep)) 4651 { 4652 delete pSep; 4653 return FALSE; 4654 } 4655 4656 pSep->Initialize(); 4657 return TRUE; 4658 } 4659 4660 STDMETHODIMP_(void) 4661 CUIFMenu::ModalMessageLoop() 4662 { 4663 MSG msg; 4664 4665 while (::GetMessage(&msg, 0, 0, 0) && msg.message != WM_NULL && 4666 (msg.hwnd == m_hWnd || msg.message <= WM_MOUSEFIRST || WM_MOUSELAST <= msg.message)) 4667 { 4668 if (!msg.hwnd && WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) 4669 msg.hwnd = GetTopSubMenu()->m_hWnd; 4670 ::TranslateMessage(&msg); 4671 ::DispatchMessage(&msg); 4672 } 4673 } 4674 4675 STDMETHODIMP_(void) 4676 CUIFMenu::ModalMouseNotify(UINT uMsg, LONG x, LONG y) 4677 { 4678 if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) 4679 CancelMenu(); 4680 } 4681 4682 STDMETHODIMP_(void) 4683 CUIFMenu::OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam) 4684 { 4685 CUIFMenuItem *pTargetItem; 4686 4687 BYTE vKey = (BYTE)wParam; 4688 4689 switch (vKey) 4690 { 4691 case VK_ESCAPE: 4692 CancelMenu(); 4693 return; 4694 4695 case VK_LEFT: 4696 if (!m_pVisibleSubMenu) 4697 return; 4698 4699 CancelMenu(); 4700 return; 4701 4702 case VK_RIGHT: 4703 if (m_pSelectedItem && m_pSelectedItem->m_pSubMenu) 4704 { 4705 m_pSelectedItem->ShowSubPopup(); 4706 CUIFMenu *pSubMenu = m_pSelectedItem->m_pSubMenu; 4707 pTargetItem = pSubMenu->GetNextItem(NULL); 4708 pSubMenu->SetSelectedItem(pTargetItem); 4709 } 4710 return; 4711 4712 case VK_UP: 4713 pTargetItem = GetPrevItem(m_pSelectedItem); 4714 SetSelectedItem(pTargetItem); 4715 return; 4716 4717 case VK_DOWN: 4718 pTargetItem = GetNextItem(m_pSelectedItem); 4719 SetSelectedItem(pTargetItem); 4720 return; 4721 4722 case VK_RETURN: 4723 break; 4724 4725 default: 4726 { 4727 if (!(('A' <= vKey && vKey <= 'Z') || ('0' <= vKey && vKey <= '9'))) 4728 return; 4729 4730 size_t iItem; 4731 for (iItem = 0; iItem < m_MenuItems.size(); ++iItem) 4732 { 4733 CUIFMenuItem *pItem = m_MenuItems[iItem]; 4734 if (pItem->m_nMenuItemVKey == vKey) 4735 { 4736 SetSelectedItem(pItem); 4737 break; 4738 } 4739 } 4740 4741 if (iItem == m_MenuItems.size()) 4742 return; 4743 } 4744 } 4745 4746 if (m_pSelectedItem && !m_pSelectedItem->m_bMenuItemGrayed) 4747 { 4748 CUIFMenu *pSubMenu = m_pSelectedItem->m_pSubMenu; 4749 if (pSubMenu) 4750 { 4751 m_pSelectedItem->ShowSubPopup(); 4752 pTargetItem = pSubMenu->GetNextItem(NULL); 4753 pSubMenu->SetSelectedItem(pTargetItem); 4754 } 4755 else 4756 { 4757 SetSelectedId(m_pSelectedItem->m_nMenuItemID); 4758 ::PostMessage(m_hWnd, WM_NULL, 0, 0); 4759 } 4760 } 4761 } 4762 4763 void CUIFMenu::PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam) 4764 { 4765 if (m_bModal) 4766 { 4767 // NOTE: hWnd parameter will be populated in CUIFMenu::ModalMessageLoop. 4768 if (bUp) 4769 ::PostMessage(NULL, WM_KEYUP, wParam, lParam); 4770 else 4771 ::PostMessage(NULL, WM_KEYDOWN, wParam, lParam); 4772 } 4773 } 4774 4775 void CUIFMenu::SetMenuFont() 4776 { 4777 LONG height = 14; 4778 4779 NONCLIENTMETRICS ncm = { sizeof(ncm) }; 4780 if (::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0)) 4781 { 4782 HFONT hFont = ::CreateFontIndirect(&ncm.lfMenuFont); 4783 SetFont(hFont); 4784 4785 LONG lfHeight = ncm.lfMenuFont.lfHeight; 4786 if (lfHeight < 0) 4787 lfHeight = -lfHeight; 4788 height = (ncm.iMenuHeight + lfHeight) / 2; 4789 } 4790 4791 m_hMenuFont = ::CreateFontW(height, 0, 0, 0, FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET, 4792 0, 0, 0, 0, L"Marlett"); 4793 INT cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON); 4794 m_cxyMargin = max(height, cxSmallIcon) + 2; 4795 } 4796 4797 void CUIFMenu::SetSelectedId(UINT nSelectID) 4798 { 4799 CUIFMenu *pMenu = this; 4800 4801 while (pMenu->m_pVisibleSubMenu) 4802 pMenu = pMenu->m_pVisibleSubMenu; 4803 4804 pMenu->m_nSelectedID = nSelectID; 4805 } 4806 4807 void CUIFMenu::SetSelectedItem(CUIFMenuItem *pItem) 4808 { 4809 CUIFMenuItem *pOldItem = m_pSelectedItem; 4810 if (pOldItem == pItem) 4811 return; 4812 4813 m_pSelectedItem = pItem; 4814 if (pOldItem) 4815 pOldItem->CallOnPaint(); 4816 if (m_pSelectedItem) 4817 m_pSelectedItem->CallOnPaint(); 4818 } 4819 4820 UINT CUIFMenu::ShowModalPopup(CUIFWindow *pWindow, LPCRECT prc, BOOL bFlag) 4821 { 4822 CUIFObject *pCaptured = NULL; 4823 if (pWindow) 4824 { 4825 pCaptured = pWindow->m_pCaptured; 4826 CUIFWindow::SetCaptureObject(NULL); 4827 } 4828 4829 UINT nSelectedID = -1; 4830 if (InitShow(pWindow, prc, bFlag, TRUE)) 4831 { 4832 m_bModal = TRUE; 4833 pWindow->SetBehindModal(this); 4834 ModalMessageLoop(); 4835 nSelectedID = m_nSelectedID; 4836 pWindow->SetBehindModal(NULL); 4837 m_bModal = FALSE; 4838 } 4839 4840 UninitShow(); 4841 4842 if (pWindow) 4843 pWindow->SetCaptureObject(pCaptured); 4844 4845 return nSelectedID; 4846 } 4847 4848 void CUIFMenu::ShowSubPopup(CUIFMenu *pSubMenu, LPCRECT prc, BOOL bFlag) 4849 { 4850 m_pVisibleSubMenu = pSubMenu; 4851 InitShow(pSubMenu, prc, bFlag, TRUE); 4852 } 4853 4854 STDMETHODIMP_(BOOL) 4855 CUIFMenu::UninitShow() 4856 { 4857 if (m_pParentMenu) 4858 m_pParentMenu->UninitShow(); 4859 4860 Show(FALSE); 4861 4862 if (m_pVisibleSubMenu) 4863 m_pVisibleSubMenu->m_pParentMenu = NULL; 4864 4865 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 4866 RemoveUIObj(m_MenuItems[iItem]); 4867 4868 ::DestroyWindow(m_hWnd); 4869 return TRUE; 4870 } 4871 4872 ///////////////////////////////////////////////////////////////////////////// 4873 // CUIFMenuItem 4874 4875 CUIFMenuItem::CUIFMenuItem( 4876 CUIFMenu *pMenu, 4877 BOOL bDisabled) : CUIFObject(pMenu, 0, NULL, 0) 4878 { 4879 m_ichMenuItemPrefix = -1; 4880 m_nMenuItemID = 0; 4881 m_pszMenuItemLeft = m_pszMenuItemRight = NULL; 4882 m_cchMenuItemLeft = m_cchMenuItemRight = 0; 4883 m_nMenuItemVKey = 0; 4884 m_hbmColor = m_hbmMask = NULL; 4885 m_bMenuItemChecked = m_bMenuItemGrayed = FALSE; 4886 m_bMenuItemDisabled = bDisabled; 4887 m_pMenu = pMenu; 4888 } 4889 4890 CUIFMenuItem::~CUIFMenuItem() 4891 { 4892 if (m_pszMenuItemLeft) 4893 { 4894 delete[] m_pszMenuItemLeft; 4895 m_pszMenuItemLeft = NULL; 4896 } 4897 4898 if (m_pszMenuItemRight) 4899 { 4900 delete[] m_pszMenuItemRight; 4901 m_pszMenuItemRight = NULL; 4902 } 4903 4904 if (m_pSubMenu) 4905 { 4906 delete m_pSubMenu; 4907 m_pSubMenu = NULL; 4908 } 4909 } 4910 4911 BOOL CUIFMenuItem::Init(UINT nMenuItemID, LPCWSTR pszText) 4912 { 4913 m_nMenuItemID = nMenuItemID; 4914 4915 if (!pszText) 4916 { 4917 m_pszMenuItemLeft = NULL; 4918 m_cchMenuItemLeft = 0; 4919 return TRUE; 4920 } 4921 4922 INT cch = lstrlenW(pszText); 4923 m_pszMenuItemLeft = new(cicNoThrow) WCHAR[cch + 1]; 4924 if (!m_pszMenuItemLeft) 4925 return FALSE; 4926 4927 const WCHAR *pch0 = pszText; 4928 INT ich1, ich2; 4929 for (ich1 = 0; *pch0 && *pch0 != L'\t'; ++ich1, ++pch0) 4930 { 4931 if (*pch0 == L'&' && *++pch0 != L'&') 4932 { 4933 m_nMenuItemVKey = ::VkKeyScanW(*pch0); 4934 if (!m_nMenuItemVKey) 4935 m_nMenuItemVKey = (BYTE)VkKeyScanA(*(BYTE*)pch0); 4936 m_ichMenuItemPrefix = ich1; 4937 } 4938 m_pszMenuItemLeft[ich1] = *pch0; 4939 } 4940 m_pszMenuItemLeft[ich1] = 0; 4941 m_cchMenuItemLeft = lstrlenW(m_pszMenuItemLeft); 4942 4943 if (*pch0 == L'\t') 4944 { 4945 m_cchMenuItemRight = 0; 4946 m_pszMenuItemRight = new(cicNoThrow) WCHAR[cch + 1]; 4947 if (m_pszMenuItemRight) 4948 { 4949 ++pch0; 4950 WCHAR wch = *pch0; 4951 for (ich2 = 0; *pch0; ++ich2) 4952 { 4953 m_pszMenuItemRight[ich2] = wch; 4954 wch = *++pch0; 4955 } 4956 m_pszMenuItemRight[ich2] = 0; 4957 m_cchMenuItemRight = lstrlenW(m_pszMenuItemRight); 4958 } 4959 } 4960 4961 return TRUE; 4962 } 4963 4964 STDMETHODIMP_(void) 4965 CUIFMenuItem::InitMenuExtent() 4966 { 4967 if (!m_pszMenuItemLeft) 4968 { 4969 if (m_hbmColor) 4970 { 4971 BITMAP bm; 4972 ::GetObject(m_hbmColor, sizeof(bm), &bm); 4973 m_MenuLeftExtent.cx = bm.bmWidth + 2; 4974 m_MenuLeftExtent.cy = bm.bmHeight + 4; 4975 } 4976 else 4977 { 4978 m_MenuLeftExtent.cx = m_MenuLeftExtent.cy = 0; 4979 } 4980 return; 4981 } 4982 4983 HDC hDC = ::GetDC(*m_pWindow); 4984 4985 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 4986 ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_cchMenuItemLeft, &m_MenuLeftExtent); 4987 m_MenuLeftExtent.cx += 16; 4988 m_MenuLeftExtent.cy += 8; 4989 if (m_pszMenuItemRight) 4990 { 4991 ::GetTextExtentPoint32W(hDC, m_pszMenuItemRight, m_cchMenuItemRight, &m_MenuRightExtent); 4992 m_MenuRightExtent.cy += 8; 4993 } 4994 ::SelectObject(hDC, hFontOld); 4995 4996 if (m_pSubMenu) 4997 m_MenuLeftExtent.cx += m_MenuLeftExtent.cy + 2; 4998 if (m_pMenu->m_style & UIF_MENU_USE_OFF10) 4999 m_MenuLeftExtent.cx += 24; 5000 5001 ::ReleaseDC(*m_pWindow, hDC); 5002 } 5003 5004 BOOL CUIFMenuItem::IsCheck() 5005 { 5006 return m_bMenuItemChecked || m_bMenuItemForceChecked; 5007 } 5008 5009 void CUIFMenuItem::DrawArrow(HDC hDC, INT xLeft, INT yTop) 5010 { 5011 if (!m_pSubMenu) 5012 return; 5013 5014 HGDIOBJ hFontOld = ::SelectObject(hDC, m_pMenu->m_hMenuFont); 5015 ::TextOutW(hDC, xLeft, yTop, L"4", 1); // rightward triangle 5016 ::SelectObject(hDC, hFontOld); 5017 } 5018 5019 void CUIFMenuItem::DrawBitmapProc(HDC hDC, INT xLeft, INT yTop) 5020 { 5021 if (!m_pScheme || !m_hbmColor) 5022 return; 5023 5024 BITMAP bm; 5025 ::GetObject(m_hbmColor, sizeof(bm), &bm); 5026 5027 INT width = m_pMenu->m_cxyMargin, height = m_rc.bottom - m_rc.top; 5028 if (width > bm.bmWidth) 5029 { 5030 width = bm.bmWidth; 5031 xLeft += (width - bm.bmWidth) / 2; 5032 } 5033 if (height > bm.bmHeight) 5034 { 5035 height = bm.bmHeight; 5036 yTop += (height - bm.bmHeight) / 2; 5037 } 5038 5039 RECT rc = { xLeft, yTop, xLeft + width, yTop + height }; 5040 5041 if (IsRTL()) 5042 m_pScheme->m_bMirroring = TRUE; 5043 5044 if (m_pMenu->m_pSelectedItem != this || m_bMenuItemDisabled) 5045 m_pScheme->DrawFrameCtrlBitmap(hDC, &rc, m_hbmColor, m_hbmMask, 0); 5046 else 5047 m_pScheme->DrawFrameCtrlBitmap(hDC, &rc, m_hbmColor, m_hbmMask, UIF_DRAW_PRESSED); 5048 5049 if (IsRTL()) 5050 m_pScheme->m_bMirroring = FALSE; 5051 } 5052 5053 void CUIFMenuItem::DrawCheck(HDC hDC, INT xLeft, INT yTop) 5054 { 5055 if (!IsCheck()) 5056 return; 5057 5058 HGDIOBJ hFontOld = ::SelectObject(hDC, m_pMenu->m_hMenuFont); 5059 WCHAR wch = (m_bMenuItemChecked ? L'a' : L'h'); // checkmark or bullet 5060 ::TextOutW(hDC, xLeft, yTop, &wch, 1); 5061 ::SelectObject(hDC, hFontOld); 5062 } 5063 5064 void 5065 CUIFMenuItem::DrawUnderline(HDC hDC, INT xText, INT yText, HBRUSH hbr) 5066 { 5067 if (m_ichMenuItemPrefix > m_cchMenuItemLeft) 5068 return; 5069 5070 SIZE PrePrefixSize, PostPrefixSize; 5071 ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_ichMenuItemPrefix, &PrePrefixSize); 5072 ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_ichMenuItemPrefix + 1, &PostPrefixSize); 5073 5074 BOOL bHeadPrefix = (m_ichMenuItemPrefix == 0); 5075 5076 RECT rc; 5077 rc.left = xText + PrePrefixSize.cx + !bHeadPrefix; 5078 rc.right = xText + PostPrefixSize.cx; 5079 rc.top = (yText + PostPrefixSize.cy) - 1; 5080 rc.bottom = yText + PostPrefixSize.cy; 5081 ::FillRect(hDC, &rc, hbr); 5082 } 5083 5084 STDMETHODIMP_(void) 5085 CUIFMenuItem::OnLButtonUp(LONG x, LONG y) 5086 { 5087 if (!m_bMenuItemGrayed && !m_bMenuItemDisabled && !m_pSubMenu) 5088 { 5089 m_pMenu->SetSelectedId(m_nMenuItemID); 5090 ::PostMessage(*m_pWindow, WM_NULL, 0, 0); 5091 } 5092 } 5093 5094 STDMETHODIMP_(void) 5095 CUIFMenuItem::OnMouseIn(LONG x, LONG y) 5096 { 5097 if (m_pMenu->m_pParentMenu) 5098 m_pMenu->m_pParentMenu->CancelMenu(); 5099 5100 if (m_pSubMenu) 5101 { 5102 DWORD Delay; 5103 if (!::SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &Delay, 0)) 5104 Delay = 300; 5105 5106 CUIFObject::StartTimer(Delay); 5107 } 5108 5109 m_pMenu->SetSelectedItem(this); 5110 } 5111 5112 STDMETHODIMP_(void) 5113 CUIFMenuItem::OnPaint(HDC hDC) 5114 { 5115 if (m_pMenu->m_style & UIF_MENU_USE_OFF10) 5116 OnPaintO10(hDC); 5117 else 5118 OnPaintDef(hDC); 5119 } 5120 5121 STDMETHODIMP_(void) 5122 CUIFMenuItem::OnPaintO10(HDC hDC) 5123 { 5124 if (!m_pScheme) 5125 return; 5126 5127 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 5128 5129 SIZE textSize; 5130 ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_cchMenuItemLeft, &textSize); 5131 5132 LONG cySpace = m_rc.bottom - m_rc.top - textSize.cy; 5133 LONG xCheck = m_rc.left, yCheck = m_rc.top + cySpace / 2; 5134 LONG cxyMargin = (m_pMenu->m_bHasMargin ? m_pMenu->m_cxyMargin : 0); 5135 5136 LONG xBitmap = m_rc.left + cxyMargin, yBitmap = m_rc.top; 5137 LONG xText = m_rc.left + m_pMenu->m_cxyMargin + cxyMargin + 8; 5138 LONG yText = m_rc.top + cySpace / 2; 5139 LONG xArrow = m_rc.left - textSize.cy + m_rc.right - 2; 5140 LONG xRightText = m_rc.right - m_pMenu->m_cxMenuExtent - 8; 5141 5142 RECT rc; 5143 GetRect(&rc); 5144 5145 if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) 5146 { 5147 rc.right = m_pMenu->m_cxyMargin + rc.left + 2; 5148 if (m_pMenu->m_bHasMargin) 5149 rc.right += m_pMenu->m_cxyMargin; 5150 5151 ::FillRect(hDC, &rc, m_pScheme->GetBrush(9)); 5152 } 5153 else 5154 { 5155 m_pScheme->DrawCtrlBkgd(hDC, &rc, 0, UIF_DRAW_PRESSED); 5156 m_pScheme->DrawCtrlEdge(hDC, &rc, 0, UIF_DRAW_PRESSED); 5157 } 5158 5159 ::SetBkMode(hDC, TRANSPARENT); 5160 5161 if (m_bMenuItemGrayed) 5162 { 5163 ::SetTextColor(hDC, m_pScheme->GetColor(11)); 5164 ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, 5165 m_cchMenuItemLeft, NULL); 5166 } 5167 else if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) 5168 { 5169 ::SetTextColor(hDC, m_pScheme->GetColor(10)); 5170 ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, 5171 m_cchMenuItemLeft, NULL); 5172 } 5173 else 5174 { 5175 ::SetTextColor(hDC, m_pScheme->GetColor(5)); 5176 ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, 5177 m_cchMenuItemLeft, NULL); 5178 } 5179 5180 DrawUnderline(hDC, xText, yText, m_pScheme->GetBrush(5)); 5181 5182 if (m_pszMenuItemRight) 5183 { 5184 ::ExtTextOutW(hDC, xRightText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemRight, 5185 m_cchMenuItemRight, NULL); 5186 } 5187 5188 DrawCheck(hDC, xCheck, yCheck); 5189 DrawBitmapProc(hDC, xBitmap, yBitmap); 5190 DrawArrow(hDC, xArrow, yText); 5191 5192 ::SelectObject(hDC, hFontOld); 5193 } 5194 5195 STDMETHODIMP_(void) 5196 CUIFMenuItem::OnPaintDef(HDC hDC) 5197 { 5198 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); 5199 5200 SIZE textSize; 5201 ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_cchMenuItemLeft, &textSize); 5202 5203 LONG cxyMargin = (m_pMenu->m_bHasMargin ? m_pMenu->m_cxyMargin : 0); 5204 5205 LONG cySpace = m_rc.bottom - m_rc.top - textSize.cy; 5206 LONG xCheck = m_rc.left, yCheck = m_rc.top + cySpace / 2; 5207 LONG xBitmap = m_rc.left + cxyMargin, yBitmap = m_rc.top; 5208 LONG xText = m_rc.left + cxyMargin + m_pMenu->m_cxyMargin + 2; 5209 LONG yText = m_rc.top + cySpace / 2; 5210 5211 LONG xArrow = m_rc.right + m_rc.left - 10; 5212 5213 ::SetBkMode(hDC, TRANSPARENT); 5214 5215 if (m_bMenuItemGrayed) 5216 { 5217 UINT uOptions = ETO_CLIPPED; 5218 if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) 5219 { 5220 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 5221 ::ExtTextOutW(hDC, xText + 1, yText + 1, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, 5222 m_cchMenuItemLeft, NULL); 5223 DrawCheck(hDC, xCheck + 1, yCheck + 1); 5224 DrawBitmapProc(hDC, xBitmap + 1, yBitmap + 1); 5225 DrawArrow(hDC, xArrow + 1, yText + 1); 5226 } 5227 else 5228 { 5229 ::SetBkColor(hDC, ::GetSysColor(COLOR_HIGHLIGHT)); 5230 uOptions = ETO_CLIPPED | ETO_OPAQUE; 5231 } 5232 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 5233 ::ExtTextOutW(hDC, xText, yText, uOptions, &m_rc, m_pszMenuItemLeft, 5234 m_cchMenuItemLeft, NULL); 5235 DrawUnderline(hDC, xText, yText, (HBRUSH)UlongToHandle(COLOR_BTNSHADOW + 1)); 5236 } 5237 else if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) 5238 { 5239 ::SetTextColor(hDC, ::GetSysColor(COLOR_MENUTEXT)); 5240 ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, 5241 m_cchMenuItemLeft, NULL); 5242 DrawUnderline(hDC, xText, yText, (HBRUSH)UlongToHandle(COLOR_MENUTEXT + 1)); 5243 } 5244 else 5245 { 5246 ::SetTextColor(hDC, ::GetSysColor(COLOR_HIGHLIGHTTEXT)); 5247 ::SetBkColor(hDC, ::GetSysColor(COLOR_HIGHLIGHT)); 5248 ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED | ETO_OPAQUE, &m_rc, 5249 m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); 5250 DrawUnderline(hDC, xText, yText, (HBRUSH)UlongToHandle(COLOR_HIGHLIGHTTEXT + 1)); 5251 } 5252 5253 DrawCheck(hDC, xCheck, yCheck); 5254 DrawBitmapProc(hDC, xBitmap, yBitmap); 5255 DrawArrow(hDC, xArrow, yText); 5256 5257 ::SelectObject(hDC, hFontOld); 5258 } 5259 5260 STDMETHODIMP_(void) 5261 CUIFMenuItem::OnTimer() 5262 { 5263 CUIFObject::EndTimer(); 5264 if (m_pMenu->m_pPointed == this) 5265 ShowSubPopup(); 5266 } 5267 5268 void CUIFMenuItem::SetBitmapMask(HBITMAP hbmMask) 5269 { 5270 m_hbmMask = hbmMask; 5271 CallOnPaint(); 5272 } 5273 5274 void CUIFMenuItem::ShowSubPopup() 5275 { 5276 RECT rc = m_rc; 5277 ::ClientToScreen(*m_pWindow, (LPPOINT)&rc); 5278 ::ClientToScreen(*m_pWindow, (LPPOINT)&rc.right); 5279 m_pSubMenu->ShowSubPopup(m_pMenu, &rc, FALSE); 5280 } 5281 5282 ///////////////////////////////////////////////////////////////////////////// 5283 // CUIFMenuItemSeparator 5284 5285 CUIFMenuItemSeparator::CUIFMenuItemSeparator(CUIFMenu *pMenu) : CUIFMenuItem(pMenu, TRUE) 5286 { 5287 m_nMenuItemID = -1; 5288 } 5289 5290 STDMETHODIMP_(void) 5291 CUIFMenuItemSeparator::InitMenuExtent() 5292 { 5293 m_MenuLeftExtent.cx = 0; 5294 m_MenuLeftExtent.cy = 6; 5295 } 5296 5297 STDMETHODIMP_(void) 5298 CUIFMenuItemSeparator::OnPaintDef(HDC hDC) 5299 { 5300 if (!m_pScheme) 5301 return; 5302 5303 RECT rc; 5304 rc.left = m_rc.left + 2; 5305 rc.top = m_rc.top + (m_rc.bottom - m_rc.top - 2) / 2; 5306 rc.right = m_rc.right - 2; 5307 rc.bottom = rc.top + 2; 5308 m_pScheme->DrawMenuSeparator(hDC, &rc); 5309 } 5310 5311 STDMETHODIMP_(void) 5312 CUIFMenuItemSeparator::OnPaintO10(HDC hDC) 5313 { 5314 if (!m_pScheme) 5315 return; 5316 5317 LONG cx = m_rc.right - m_rc.left - 4; 5318 LONG cy = (m_rc.bottom - m_rc.top - 2) / 2; 5319 5320 RECT rc; 5321 GetRect(&rc); 5322 5323 rc.right = rc.left + m_pMenu->m_cxyMargin + 2; 5324 if (m_pMenu->m_bHasMargin) 5325 rc.right += m_pMenu->m_cxyMargin; 5326 5327 HBRUSH hBrush = m_pScheme->GetBrush(9); 5328 ::FillRect(hDC, &rc, hBrush); 5329 rc = { 5330 m_rc.left + m_pMenu->m_cxyMargin + 4, 5331 m_rc.top + cy, 5332 m_rc.left + cx + 2, 5333 m_rc.top + cy + 1 5334 }; 5335 m_pScheme->DrawMenuSeparator(hDC, &rc); 5336 } 5337 5338 ///////////////////////////////////////////////////////////////////////////// 5339 5340 void cicGetWorkAreaRect(POINT pt, LPRECT prc) 5341 { 5342 ::SystemParametersInfo(SPI_GETWORKAREA, 0, prc, 0); 5343 5344 HMONITOR hMon = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); 5345 if (hMon) 5346 { 5347 MONITORINFO mi = { sizeof(mi) }; 5348 if (::GetMonitorInfo(hMon, &mi)) 5349 *prc = mi.rcWork; 5350 } 5351 } 5352 5353 void cicGetScreenRect(POINT pt, LPRECT prc) 5354 { 5355 *prc = { 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN) }; 5356 HMONITOR hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); 5357 if (hMon) 5358 { 5359 MONITORINFO mi = { sizeof(mi) }; 5360 GetMonitorInfo(hMon, &mi); 5361 *prc = mi.rcMonitor; 5362 } 5363 } 5364 5365 BOOL cicIsFullScreenSize(HWND hWnd) 5366 { 5367 RECT rc; 5368 5369 ::GetWindowRect(hWnd, &rc); 5370 return (rc.left <= 0) && (rc.top <= 0) && 5371 (rc.right >= GetSystemMetrics(SM_CXFULLSCREEN)) && 5372 (rc.bottom >= GetSystemMetrics(SM_CYFULLSCREEN)); 5373 } 5374 5375 BOOL cicGetIconSize(HICON hIcon, LPSIZE pSize) 5376 { 5377 ICONINFO IconInfo; 5378 if (!GetIconInfo(hIcon, &IconInfo)) 5379 return FALSE; 5380 5381 BITMAP bm; 5382 ::GetObject(IconInfo.hbmColor, sizeof(bm), &bm); 5383 ::DeleteObject(IconInfo.hbmColor); 5384 ::DeleteObject(IconInfo.hbmMask); 5385 pSize->cx = bm.bmWidth; 5386 pSize->cy = bm.bmHeight; 5387 return TRUE; 5388 } 5389 5390 ///////////////////////////////////////////////////////////////////////////// 5391 5392 void cicInitUIFSys(void) 5393 { 5394 CUIFSystemInfo::s_pSystemInfo = new(cicNoThrow) CUIFSystemInfo(); 5395 if (CUIFSystemInfo::s_pSystemInfo) 5396 CUIFSystemInfo::s_pSystemInfo->Initialize(); 5397 } 5398 5399 void cicDoneUIFSys(void) 5400 { 5401 if (CUIFSystemInfo::s_pSystemInfo) 5402 { 5403 delete CUIFSystemInfo::s_pSystemInfo; 5404 CUIFSystemInfo::s_pSystemInfo = NULL; 5405 } 5406 } 5407 5408 void cicUpdateUIFSys(void) 5409 { 5410 if (CUIFSystemInfo::s_pSystemInfo) 5411 CUIFSystemInfo::s_pSystemInfo->GetSystemMetrics(); 5412 } 5413 5414 ///////////////////////////////////////////////////////////////////////////// 5415 5416 void cicInitUIFScheme(void) 5417 { 5418 CUIFColorTable *pColorTable; 5419 5420 pColorTable = CUIFScheme::s_pColorTableSys = new(cicNoThrow) CUIFColorTableSys(); 5421 if (pColorTable) 5422 { 5423 pColorTable->InitColor(); 5424 pColorTable->InitBrush(); 5425 } 5426 5427 pColorTable = CUIFScheme::s_pColorTableOff10 = new(cicNoThrow) CUIFColorTableOff10(); 5428 if (pColorTable) 5429 { 5430 pColorTable->InitColor(); 5431 pColorTable->InitBrush(); 5432 } 5433 } 5434 5435 void cicUpdateUIFScheme(void) 5436 { 5437 if (CUIFScheme::s_pColorTableSys) 5438 CUIFScheme::s_pColorTableSys->Update(); 5439 if (CUIFScheme::s_pColorTableOff10) 5440 CUIFScheme::s_pColorTableOff10->Update(); 5441 } 5442 5443 void cicDoneUIFScheme(void) 5444 { 5445 if (CUIFScheme::s_pColorTableSys) 5446 { 5447 delete CUIFScheme::s_pColorTableSys; 5448 CUIFScheme::s_pColorTableSys = NULL; 5449 } 5450 if (CUIFScheme::s_pColorTableOff10) 5451 { 5452 delete CUIFScheme::s_pColorTableOff10; 5453 CUIFScheme::s_pColorTableOff10 = NULL; 5454 } 5455 } 5456 5457 ///////////////////////////////////////////////////////////////////////////// 5458 5459 void cicInitUIFLib(void) 5460 { 5461 cicInitUIFSys(); 5462 cicInitUIFScheme(); 5463 cicInitUIFUtil(); 5464 } 5465 5466 void cicDoneUIFLib(void) 5467 { 5468 cicDoneUIFScheme(); 5469 cicDoneUIFSys(); 5470 cicDoneUIFUtil(); 5471 } 5472 5473 ///////////////////////////////////////////////////////////////////////////// 5474