Ejemplo n.º 1
0
void GraphicsInterface::DisplayTimerCallback()
{
	RECT rcScreen;
	CMonitors cm;
	POINT pt = { 0, 0 };

	if (0 == TryEnterCriticalSection(&_csCreateDisplay))
		return;

	DeleteTimerQueueTimer(_hTimerQueue, _hDisplayTimer, NULL);
	_hDisplayTimer = NULL;

	if (m_ssSettings.bOSDAlwaysUp && _nDisplayType == 1 && !_override_always_up)
	{
		// Position display
		if (!cm.GetMonitorRect(m_ssSettings.nOSDMonitor, rcScreen))
			SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0);

		pt.x = rcScreen.left + (LONG)ceilf((m_ssSettings.nOSDHoriz / 100.0f) * (rcScreen.right - rcScreen.left));
		pt.y = rcScreen.top + (LONG)ceilf((m_ssSettings.nOSDVert / 100.0f) * (rcScreen.bottom - rcScreen.top));

		// Restore old info screen
		if (NULL == wcsstr(m_ssSettings.wcOSDFormat, L"%track_position%"))
		{
			for (const auto& ge : _ges)
			{
				ge->BeginRender();
			}

				if (m_ssSettings.bOSDAllMonitors)
				{
					int monitor = 1;

					for (const auto& ge : _ges)
					{
						// Position display
						cm.GetMonitorRect(monitor, rcScreen);

						pt.x = rcScreen.left + (LONG)ceilf((m_ssSettings.nOSDHoriz / 100.0f) * (rcScreen.right - rcScreen.left));
						pt.y = rcScreen.top + (LONG)ceilf((m_ssSettings.nOSDVert / 100.0f) * (rcScreen.bottom - rcScreen.top));

						ge->EndRender(pt, _bmInfo, rcScreen);

						++monitor;
					}
				}
				else
				{
					for (const auto& ge : _ges)
					{
						ge->EndRender(pt, _bmInfo, rcScreen);
					}
				}

			DisplayShow();
		}
		_nDisplayType = 0;
	}
	else
		DisplayHide();

	LeaveCriticalSection(&_csCreateDisplay);

	return;
}
Ejemplo n.º 2
0
void GraphicsInterface::DisplayInfo(wstring wstrText, bool bArtwork, wchar_t *wcArt, int display_time, bool bUpdateOnly)
{
	GraphicsEngineOptions geo;
	RECT rcScreen;
	CMonitors cm;
	POINT pt = { 0, 0 };
	Color cNull = Color(0, 0, 0, 0);
	Color cTemp;
	Color cOutline;
	Color cArtOutline;
	Color cDropShadow;
	REAL rTemp;

	if (!m_ssSettings.bVisualFeedback)
		return;

	if (m_ssSettings.bNoDisplayWhenActive && m_ITCom->IsActiveWindow())
		return;

	if (bUpdateOnly && (_nDisplayType == 1 || !IsDisplayVisible()))
		return;

	EnterCriticalSection(&_csCreateDisplay);
	_nDisplayType = 0;

	// Configure
	geo.nDisplayAlpha = m_ssSettings.nOSDAlpha;
	geo.bDisplayTopMost = m_ssSettings.bOSDTopMost;
	geo.nMaxWidth = m_ssSettings.nOSDMaxWidth;
	geo.nArtScaleMode = m_ssSettings.nArtMode == 3 ? ART_SCALEMODEHEIGHT : ART_SCALEMODESIZE;
	geo.saAlign = (Gdiplus::StringAlignment)m_ssSettings.nOSDTextJustify;
	geo.bForceToWidth = m_ssSettings.bOSDForceWidth;

	if (!bArtwork || NULL == wcArt || 0 == wcscmp(wcArt, L""))
	{
		for (const auto& ge : _ges)
		{
			ge->SetOptions(geo);
			ge->BeginRender(5);
		}
	}
	else
	{
		for (const auto& ge : _ges)
		{
			ge->SetOptions(geo);
			ge->BeginRender(m_ssSettings.nDisplayLayout);
		}
	}

	// Set background and borders
	rTemp = (REAL)m_ssSettings.nOSDBorderSize;
	cOutline = Color(GetRValue(m_ssSettings.lOSDBorderColor), GetGValue(m_ssSettings.lOSDBorderColor), GetBValue(m_ssSettings.lOSDBorderColor));
	cTemp = Color(GetRValue(m_ssSettings.lOSDBkColorRef), GetGValue(m_ssSettings.lOSDBkColorRef), GetBValue(m_ssSettings.lOSDBkColorRef));
	cDropShadow = Color(GetRValue(m_ssSettings.lDropShadowColor), GetGValue(m_ssSettings.lDropShadowColor), GetBValue(m_ssSettings.lDropShadowColor));
	cArtOutline = Color(GetRValue(m_ssSettings.lArtBorderColor), GetGValue(m_ssSettings.lArtBorderColor), GetBValue(m_ssSettings.lArtBorderColor));
	for (const auto& ge : _ges)
	{
		ge->SetDisplayBorder(m_ssSettings.bOSDOutlineMode ? cNull : cOutline, rTemp);
		ge->SetDisplayBackground(m_ssSettings.bOSDOutlineMode ? cNull : cTemp);
	}

		// Add album art if needed
		if (bArtwork && m_ssSettings.bShowArtwork)
		{
			for (const auto& ge : _ges)
			{
				ge->AddArt(wcArt, false, cArtOutline, 1.5f, (float)m_ssSettings.nArtConstSize, m_ssSettings.nArtMode == 3 ? IMG_SCALENONE : IMG_SCALEALL);
			}
		}

	// Cache text height for shapes
	static REAL text_height;
	if (!bUpdateOnly)
		text_height = _ges.at(0)->GetTextHeight(m_ssSettings.wcFontFace, (float)m_ssSettings.nOSDFontPoint, m_ssSettings.nOSDFontStyle);

	// Break string into lines, add to display
	wchar_t *lpToken = NULL;
	wchar_t *lpContext = NULL;
	std::wstring line;
	size_t current_position = 0;
	size_t next_rating = 0;
	size_t next_format = 0;
	int old_font_style = m_ssSettings.nOSDFontStyle;
	cTemp = Color(GetRValue(m_ssSettings.lOSDColorRef), GetGValue(m_ssSettings.lOSDColorRef), GetBValue(m_ssSettings.lOSDColorRef));
	Color cShapeFill = Color(GetRValue(m_ssSettings.lRatingShapeFill), GetGValue(m_ssSettings.lRatingShapeFill), GetBValue(m_ssSettings.lRatingShapeFill));
	Color cShapeOutline = Color(GetRValue(m_ssSettings.lRatingShapeOutline), GetGValue(m_ssSettings.lRatingShapeOutline), GetBValue(m_ssSettings.lRatingShapeOutline));
	lpToken = wcstok_s(const_cast<wchar_t*>(wstrText.c_str()), L"\n", &lpContext);

	while (NULL != lpToken && m_ssSettings.nDisplayLayout != 4)
	{
		for (const auto& ge : _ges)
		{
			ge->BeginLine();
		}

			line = lpToken;
		current_position = 0;
		do
		{
			next_rating = line.find(L"%rating%", current_position);
			next_format = line.find(L"<", current_position);

			if ((next_rating == std::wstring::npos && next_format != std::wstring::npos) ||
				(next_format != std::wstring::npos && next_rating != std::wstring::npos &&
					next_format < next_rating))
			{
				// format
				if ((next_format - current_position) > 0)
				{
					for (const auto& ge : _ges)
					{
						ge->AddString(line.substr(current_position, next_format - current_position).c_str(), false,
							m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint, cTemp, m_ssSettings.wcFontFace,
							m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f, m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f,
							cDropShadow);
					}
				}
				if (line.compare(next_format, 3, L"<b>") == 0)
				{
					m_ssSettings.nOSDFontStyle |= FontStyleBold;
					current_position = next_format + 3;
				}
				else if (line.compare(next_format, 3, L"<i>") == 0)
				{
					m_ssSettings.nOSDFontStyle |= FontStyleItalic;
					current_position = next_format + 3;
				}
				else if (line.compare(next_format, 4, L"</b>") == 0)
				{
					m_ssSettings.nOSDFontStyle &= ~FontStyleBold;
					current_position = next_format + 4;
				}
				else if (line.compare(next_format, 4, L"</i>") == 0)
				{
					m_ssSettings.nOSDFontStyle &= ~FontStyleItalic;
					current_position = next_format + 4;
				}
				else
				{
					for (const auto& ge : _ges)
					{
						ge->AddString(line.substr(next_format, 1).c_str(), false,
							m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint, cTemp, m_ssSettings.wcFontFace,
							m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f, m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f,
							cDropShadow);
					}
					current_position = next_format + 1;
				}
			}
			else if ((next_format == std::wstring::npos && next_rating != std::wstring::npos) ||
				(next_format != std::wstring::npos && next_rating != std::wstring::npos &&
					next_rating < next_format))
			{
				// rating
				if ((next_rating - current_position) > 0)
				{
					for (const auto& ge : _ges)
					{
						ge->AddString(line.substr(current_position, next_rating - current_position).c_str(), false,
							m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint, cTemp, m_ssSettings.wcFontFace,
							m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f, m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f,
							cDropShadow);
					}
				}

				// Add rating
				long lRating = m_ITCom->GetTrackRating();
				long lWhole = (lRating - (lRating % 20)) / 20;
				lRating = lRating - lWhole * 20;
				long lHalf = (lRating - (lRating % 10)) / 10;
				long lEmpty = 5 - lWhole - lHalf;

				RectF rfShape = RectF(0, 0, text_height, text_height);
				for (int i = 0; i < lWhole; i++)
				{
					for (const auto& ge : _ges)
					{
						if (m_ssSettings.nRatingType == 1)
							ge->AddImage(m_ssSettings.wcRatingFullPath);
						else
							ge->AddShape((ShapeType)m_ssSettings.nRatingShapeType, FillAll, rfShape, false, cShapeOutline, 3.0, cShapeFill);
					}
				}
				for (int i = 0; i < lHalf; i++)
				{
					for (const auto& ge : _ges)
					{
						if (m_ssSettings.nRatingType == 1)
							ge->AddImage(m_ssSettings.wcRatingHalfPath);
						else
							ge->AddShape((ShapeType)m_ssSettings.nRatingShapeType, (ShapeStyle)(m_ssSettings.nRatingShapeStyle + 2), rfShape, false, cShapeOutline, 3.0, cShapeFill);
					}
				}
				for (int i = 0; i < lEmpty; i++)
				{
					for (const auto& ge : _ges)
					{
						if (m_ssSettings.nRatingType == 1)
							ge->AddImage(m_ssSettings.wcRatingEmptyPath);
						else
							ge->AddShape((ShapeType)m_ssSettings.nRatingShapeType, FillNone, rfShape, false, cShapeOutline, 3.0, cShapeFill);
					}
				}

				current_position = next_rating + 8;
			}
			else
			{
				// no special processing needed
				if (line.substr(current_position, std::wstring::npos).length() > 0)
				{
					for (const auto& ge : _ges)
					{
						ge->AddString(line.substr(current_position, std::wstring::npos).c_str(), false,
							m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint, cTemp, m_ssSettings.wcFontFace,
							m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f, m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f,
							cDropShadow);
					}
				}
			}
		} while (next_format != std::wstring::npos || next_rating != std::wstring::npos);

		for (const auto& ge : _ges)
		{
			ge->EndLine();
		}

		lpToken = wcstok_s(NULL, L"\n", &lpContext);
	}

	// Restore font style
	m_ssSettings.nOSDFontStyle = old_font_style;

	// Show display, start timer
	if (_bmInfo)
	{
		delete _bmInfo;
		_bmInfo = NULL;
	}

	if (m_ssSettings.bOSDAllMonitors)
	{
		bool has_track_pos = (NULL != wcsstr(m_ssSettings.wcOSDFormat, L"%track_position%"));
		int monitor = 1;

		for (const auto& ge : _ges)
		{
			// Position display
			cm.GetMonitorRect(monitor, rcScreen);

			pt.x = rcScreen.left + (LONG)ceilf((m_ssSettings.nOSDHoriz / 100.0f) * (rcScreen.right - rcScreen.left));
			pt.y = rcScreen.top + (LONG)ceilf((m_ssSettings.nOSDVert / 100.0f) * (rcScreen.bottom - rcScreen.top));

			if (has_track_pos)
				ge->EndRender(pt, rcScreen);
			else
				ge->EndRender(pt, rcScreen, m_ssSettings.bOSDAlwaysUp, &_bmInfo);

			++monitor;
		}
	}
	else
	{
		// Position display
		if (!cm.GetMonitorRect(m_ssSettings.nOSDMonitor, rcScreen))
			SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0);

		pt.x = rcScreen.left + (LONG)ceilf((m_ssSettings.nOSDHoriz / 100.0f) * (rcScreen.right - rcScreen.left));
		pt.y = rcScreen.top + (LONG)ceilf((m_ssSettings.nOSDVert / 100.0f) * (rcScreen.bottom - rcScreen.top));

		if (NULL != wcsstr(m_ssSettings.wcOSDFormat, L"%track_position%"))
		{
			for (const auto& ge : _ges)
			{
				ge->EndRender(pt, rcScreen);
			}
		}
		else
		{
			for (const auto& ge : _ges)
			{
				ge->EndRender(pt, rcScreen, m_ssSettings.bOSDAlwaysUp, &_bmInfo);
			}
		}
	}

	// Display should be shown for xx seconds, then hidden
	if (!bUpdateOnly)
	{
		if (!m_ssSettings.bOSDAlwaysUp)
		{
			if (NULL != _hDisplayTimer)
				DeleteTimerQueueTimer(_hTimerQueue, _hDisplayTimer, INVALID_HANDLE_VALUE);
			_hDisplayTimer = NULL;
			CreateTimerQueueTimer(&_hDisplayTimer, _hTimerQueue, DisplayTimerCallback, (PVOID)this, display_time, 0, WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE);
		}


		DisplayShow();
	}

	LeaveCriticalSection(&_csCreateDisplay);

	return;
}
Ejemplo n.º 3
0
void GraphicsInterface::DisplayStatus(wstring wstrText, int display_time)
{
	GraphicsEngineOptions geo;
	RECT rcScreen;
	CMonitors cm;
	POINT pt = { 0, 0 };
	Color cNull = Color(0, 0, 0, 0);
	Color cTemp;
	Color cOutline;
	Color cDropShadow;
	REAL rTemp;

	if (!m_ssSettings.bVisualFeedback)
		return;

	if (m_ssSettings.bNoDisplayWhenActive && m_ITCom->IsActiveWindow())
		return;

	EnterCriticalSection(&_csCreateDisplay);
	_nDisplayType = 1;

	// Configure
	geo.nDisplayAlpha = m_ssSettings.nOSDAlpha;
	geo.bDisplayTopMost = m_ssSettings.bOSDTopMost;
	geo.nMaxWidth = m_ssSettings.nOSDMaxWidth;
	geo.nArtScaleMode = m_ssSettings.nArtMode == 3 ? ART_SCALEMODEHEIGHT : ART_SCALEMODESIZE;
	geo.saAlign = (Gdiplus::StringAlignment)m_ssSettings.nOSDTextJustify;
	geo.bForceToWidth = m_ssSettings.bOSDForceWidth;
	for (const auto& ge : _ges)
	{
		ge->SetOptions(geo);
		// Begin render process
		ge->BeginRender(5);
	}

		// Set background and borders
		rTemp = (REAL)m_ssSettings.nOSDBorderSize;
	cOutline = Color(GetRValue(m_ssSettings.lOSDBorderColor), GetGValue(m_ssSettings.lOSDBorderColor), GetBValue(m_ssSettings.lOSDBorderColor));
	cTemp = Color(GetRValue(m_ssSettings.lOSDBkColorRef), GetGValue(m_ssSettings.lOSDBkColorRef), GetBValue(m_ssSettings.lOSDBkColorRef));
	cDropShadow = Color(GetRValue(m_ssSettings.lDropShadowColor), GetGValue(m_ssSettings.lDropShadowColor), GetBValue(m_ssSettings.lDropShadowColor));
	for (const auto& ge : _ges)
	{
		ge->SetDisplayBorder(m_ssSettings.bOSDOutlineMode ? cNull : cOutline, rTemp);
		ge->SetDisplayBackground(m_ssSettings.bOSDOutlineMode ? cNull : cTemp);
	}

		// Cache text height for shapes
		REAL text_height = _ges.at(0)->GetTextHeight(m_ssSettings.wcFontFace, (float)m_ssSettings.nOSDFontPoint, m_ssSettings.nOSDFontStyle);

	// Break string into lines, add to display
	wchar_t *lpToken = NULL;
	wchar_t *lpContext = NULL;
	wchar_t *lpRating = NULL;
	wchar_t *lpVolume = NULL;
	wchar_t *lpBeforeRating = NULL;
	cTemp = Color(GetRValue(m_ssSettings.lOSDColorRef), GetGValue(m_ssSettings.lOSDColorRef), GetBValue(m_ssSettings.lOSDColorRef));
	Color cShapeFill = Color(GetRValue(m_ssSettings.lRatingShapeFill), GetGValue(m_ssSettings.lRatingShapeFill), GetBValue(m_ssSettings.lRatingShapeFill));
	Color cShapeOutline = Color(GetRValue(m_ssSettings.lRatingShapeOutline), GetGValue(m_ssSettings.lRatingShapeOutline), GetBValue(m_ssSettings.lRatingShapeOutline));
	lpToken = wcstok_s(const_cast<wchar_t*>(wstrText.c_str()), L"\n", &lpContext);
	while (NULL != lpToken && m_ssSettings.nDisplayLayout != 4)
	{
		for (const auto& ge : _ges)
		{
			ge->BeginLine();
		}
			// check for %rating% in string, replace with img rating
			lpRating = wcsstr(lpToken, L"%rating%");
		lpVolume = wcsstr(lpToken, L"%volume%");
		if (NULL != lpVolume)
		{
			// Break up line
			lpBeforeRating = new wchar_t[lpVolume - lpToken + 1];
			wcsncpy_s(lpBeforeRating, lpVolume - lpToken + 1, lpToken, lpVolume - lpToken);

			// Add text before rating
			for (const auto& ge : _ges)
			{
				ge->AddString(lpBeforeRating, false, m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint,
					cTemp, m_ssSettings.wcFontFace, m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f,
					m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f, cDropShadow);
			}

				// Add rating
				unsigned int lVolume = m_ITCom->GetVolumeLevel();

			RectF rfShape = RectF(0, 0, text_height*10.0f, text_height*1.5f);
			for (const auto& ge : _ges)
			{
				ge->AddShape(ShapeVolume, FillCustom, rfShape, false, cShapeOutline, 3.0, cShapeFill, lVolume);
				// Add text after rating
				ge->AddString(lpVolume + 8, false, m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint,
					cTemp, m_ssSettings.wcFontFace, m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f,
					m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f, cDropShadow);
			}

				delete[] lpBeforeRating;
		}
		else if (NULL != lpRating)
		{
			// Break up line
			lpBeforeRating = new wchar_t[lpRating - lpToken + 1];
			wcsncpy_s(lpBeforeRating, lpRating - lpToken + 1, lpToken, lpRating - lpToken);

			// Add text before rating
			for (const auto& ge : _ges)
			{
				ge->AddString(lpBeforeRating, false, m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint,
					cTemp, m_ssSettings.wcFontFace, m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f,
					m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f, cDropShadow);
			}

				// Add rating
				long lRating = m_ITCom->GetTrackRating();
			long lWhole = (lRating - (lRating % 20)) / 20;
			lRating = lRating - lWhole * 20;
			long lHalf = (lRating - (lRating % 10)) / 10;
			long lEmpty = 5 - lWhole - lHalf;

			RectF rfShape = RectF(0, 0, text_height, text_height);
			for (int i = 0; i < lWhole; i++)
			{
				for (const auto& ge : _ges)
				{
					if (m_ssSettings.nRatingType == 1)
						ge->AddImage(m_ssSettings.wcRatingFullPath);
					else
						ge->AddShape((ShapeType)m_ssSettings.nRatingShapeType, FillAll, rfShape, false, cShapeOutline, 3.0, cShapeFill);
				}
			}
			for (int i = 0; i < lHalf; i++)
			{
				for (const auto& ge : _ges)
				{
					if (m_ssSettings.nRatingType == 1)
						ge->AddImage(m_ssSettings.wcRatingHalfPath);
					else
						ge->AddShape((ShapeType)m_ssSettings.nRatingShapeType, (ShapeStyle)(m_ssSettings.nRatingShapeStyle + 2), rfShape, false, cShapeOutline, 3.0, cShapeFill);
				}
			}
			for (int i = 0; i < lEmpty; i++)
			{
				for (const auto& ge : _ges)
				{
					if (m_ssSettings.nRatingType == 1)
						ge->AddImage(m_ssSettings.wcRatingEmptyPath);
					else
						ge->AddShape((ShapeType)m_ssSettings.nRatingShapeType, FillNone, rfShape, false, cShapeOutline, 3.0, cShapeFill);
				}
			}

			// Add text after rating
			for (const auto& ge : _ges)
			{
				ge->AddString(lpRating + 8, false, m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint,
					cTemp, m_ssSettings.wcFontFace, m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f,
					m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f, cDropShadow);
			}

				delete[] lpBeforeRating;
		}
		else
		{
			for (const auto& ge : _ges)
			{
				ge->AddString(lpToken, false, m_ssSettings.nOSDFontStyle, (float)m_ssSettings.nOSDFontPoint,
					cTemp, m_ssSettings.wcFontFace, m_ssSettings.bOSDOutlineMode ? cOutline : cNull, 1.5f,
					m_ssSettings.bUseDropShadow ? m_ssSettings.fDropShadowOffset : 0.0f, cDropShadow);
			}
		}

		for (const auto& ge : _ges)
		{
			ge->EndLine();
		}

			lpToken = wcstok_s(NULL, L"\n", &lpContext);
	}

	// Position display
	if (!cm.GetMonitorRect(m_ssSettings.nOSDMonitor, rcScreen))
		SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0);

	pt.x = rcScreen.left + (LONG)ceilf((m_ssSettings.nOSDHoriz / 100.0f) * (rcScreen.right - rcScreen.left));
	pt.y = rcScreen.top + (LONG)ceilf((m_ssSettings.nOSDVert / 100.0f) * (rcScreen.bottom - rcScreen.top));

	// Show display, start timer
	if (m_ssSettings.bOSDAllMonitors)
	{
		int monitor = 1;

		for (const auto& ge : _ges)
		{
			// Position display
			cm.GetMonitorRect(monitor, rcScreen);

			pt.x = rcScreen.left + (LONG)ceilf((m_ssSettings.nOSDHoriz / 100.0f) * (rcScreen.right - rcScreen.left));
			pt.y = rcScreen.top + (LONG)ceilf((m_ssSettings.nOSDVert / 100.0f) * (rcScreen.bottom - rcScreen.top));

			ge->EndRender(pt, rcScreen);

			++monitor;
		}
	}
	else
	{
		for (const auto& ge : _ges)
		{
			ge->EndRender(pt, rcScreen);
		}
	}

	// Display should be shown for xx seconds, then hidden
	if (NULL != _hDisplayTimer)
		DeleteTimerQueueTimer(_hTimerQueue, _hDisplayTimer, INVALID_HANDLE_VALUE);
	_hDisplayTimer = NULL;
	CreateTimerQueueTimer(&_hDisplayTimer, _hTimerQueue, DisplayTimerCallback, (PVOID)this, display_time, 0, WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE);

	DisplayShow();

	LeaveCriticalSection(&_csCreateDisplay);

	return;
}