Example #1
0
LRESULT CFrameHolder::OnNcPaint(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	RecalculateFrameSizes();

	if (!gpSet->isTabsInCaption)
	{
		LRESULT lRc = DefWindowProc(hWnd, uMsg, wParam, lParam);
		return lRc;
	}

	FrameDrawStyle fdt = gpConEmu->DrawType();

	if (fdt == fdt_Aero || fdt == fdt_Win8)
	{
		LRESULT lRc = DefWindowProc(hWnd, uMsg, wParam, lParam);
		//TODO: Может быть на "стекле" сразу рисовать, а не в WM_PAINT?
		return lRc;
	}

	if (!gpSet->isTabs)
	{
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}


	RECT dirty_box, dirty, wr = {}, tr = {}, cr = {}, xorRect;
	BOOL fRegionOwner = FALSE;
	HDC hdc;
	HRGN hrgn = (HRGN)wParam;

	GetWindowRect(hWnd, &wr);
	CalculateCaptionPosition(wr, &cr);
	CalculateTabPosition(wr, cr, &tr);

	// --- Регион формируем всегда сами, иначе в некоторых случаях (XP+ Theming)
	// --- при выезжании окна из-за пределов экрана (обратно в видимую область)
	// --- сильно мелькает текст в заголовке
	//Create a region which covers the whole window. This
	//must be in screen coordinates
	//if(TRUE || hrgn == (HRGN)1 || hrgn == NULL)
	{
		hrgn = CreateRectRgnIndirect(&wr);
		dirty_box = wr;
		fRegionOwner = TRUE;
		//#ifdef _DEBUG
		//	wchar_t szDbg[255];
		//	wsprintf(szDbg, L"CFrameHolder::OnNcPaint - New region({%ix%i}-{%ix%i})\n", wr.left,wr.top,wr.right,wr.bottom);
		//	OutputDebugStringW(szDbg);
		//#endif
	}
	//else
	//{
	//	GetRgnBox((HRGN)wParam, &dirty_box);
	//	#ifdef _DEBUG
	//		wchar_t szDbg[255];
	//		wsprintf(szDbg, L"CFrameHolder::OnNcPaint - Existing region({%ix%i}-{%ix%i})\n", dirty_box.left,dirty_box.top,dirty_box.right,dirty_box.bottom);
	//		OutputDebugStringW(szDbg);
	//	#endif
	//}



	xorRect = tr;
	xorRect.top = cr.top;
	if (gpConEmu->DrawType() == fdt_Aero)
	{
	}
	else if (gpConEmu->DrawType() == fdt_Themed)
	{
		xorRect.left = cr.left;
		xorRect.right = cr.right;
	}
	else
	{
		xorRect.left = cr.left;
		//xorRect.right = cr.right;
	}
	OffsetRect(&xorRect, wr.left, wr.top);


	if (IntersectRect(&dirty, &dirty_box, &xorRect))
	{
		// This must be in screen coordinates
		HRGN hrgn1 = CreateRectRgnIndirect(&xorRect);

		//Cut out a button-shaped hole
		CombineRgn(hrgn, hrgn, hrgn1, RGN_XOR);

		DeleteObject(hrgn1);
	}
	//#ifdef _DEBUG
	//else
	//{
	//	OutputDebugStringW(L"CFrameHolder::OnNcPaint --- IntersectRect failed\n");
	//}
	//#endif

	//if (!mb_NcAnimate)
	DefWindowProc(hWnd, uMsg, (WPARAM)hrgn, lParam);


//#ifdef _DEBUG
//	Sleep(150);
//#endif

	// Собственно отрисовка табов
	hdc = GetWindowDC(hWnd);

	//HRGN hdcrgn = CreateRectRgn(cr.left, cr.top, cr.right, tr.bottom);
	//hdc = GetDCEx(hWnd, hdcrgn, DCX_INTERSECTRGN);

	PaintDC dc = {};
	gpConEmu->BeginBufferedPaint(hdc, cr, dc);

	gpConEmu->mp_TabBar->PaintTabs(dc, cr, tr);

	gpConEmu->EndBufferedPaint(dc, TRUE);

	//if (mb_WasGlassDraw && gpConEmu->isZoomed())
	//{
	//	//mb_WasGlassDraw = FALSE;
	//	// Какой-то странный глюк DWM. При отключении Glass несколько верхних строк
	//	// клиентской области оказываются "разрушенными" - у них остается атрибут "прозрачности"
	//	// хотя прозрачность (Glass) уже отключена. В результате эти строки - белесые

	//	BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER)};
	//	bi.biWidth = cr.right-cr.left+1;
	//	bi.biHeight = GetFrameHeight()+1;
	//	bi.biPlanes = 1;
	//	bi.biBitCount = 32;
	//	COLORREF *pPixels = NULL;
	//	HDC hdcPaint = CreateCompatibleDC(hdc);
	//	HBITMAP hbmp = CreateDIBSection(hdcPaint, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pPixels, NULL, 0);
	//	HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcPaint, hbmp);

	//	//memset(pPixels, 0xFF, bi.biWidth*bi.biHeight*4);
	//	int i = 0;
	//	for (int y = 0; y < bi.biHeight; y++)
	//	{
	//		for (int x = 0; x < bi.biWidth; x++)
	//		{
	//			pPixels[i++] = 0xFF000000;
	//		}
	//	}

	//	BitBlt(hdc, cr.left, tr.bottom, bi.biWidth, bi.biHeight, hdcPaint, 0, 0, SRCCOPY);

	//	SelectObject(hdcPaint, hOldBmp);
	//	DeleteObject(hbmp);
	//	DeleteDC(hdcPaint);
	//}

	ReleaseDC(hWnd, hdc);

	if(fRegionOwner)
		DeleteObject(hrgn);

	return 0;
}
Example #2
0
LRESULT CFrameHolder::OnPaint(HWND hWnd, BOOL abForceGetDc)
{
	HDC hdc;
	PAINTSTRUCT ps = {0};
	RECT wr, cr, tr;
	
	RecalculateFrameSizes();

	hdc = BeginPaint(hWnd, &ps);

	GetClientRect(hWnd, &wr);

	if (gpSet->isStatusBarShow)
	{
		int nHeight = gpSet->StatusBarHeight();
		if (nHeight < (wr.bottom - wr.top))
		{
			RECT rcStatus = {wr.left, wr.bottom - nHeight, wr.right, wr.bottom};
			gpConEmu->mp_Status->PaintStatus(hdc, rcStatus);
			wr.bottom = rcStatus.top;
		}
	}

	cr = wr;

	if (gpConEmu->DrawType() == fdt_Aero)
	{
		int nOffset = gpConEmu->GetDwmClientRectTopOffset();
		// "Рамка" расширена на клиентскую область, поэтому
		// нужно зарисовать заголовок черной кистью, иначе идет
		// искажение цвета для кнопок Min/Max/Close

		if (gpSet->isTabs && gpSet->isTabsInCaption)
		{
			RECT captrect;
			CalculateCaptionPosition(cr, &captrect);
			CalculateTabPosition(cr, captrect, &tr);

			gpConEmu->mp_TabBar->PaintTabs(hdc, captrect, tr);

			mb_WasGlassDraw = TRUE;
		}

		cr.top += nOffset;
	}


	int nWidth = (cr.right-cr.left);
	int nHeight = (cr.bottom-cr.top);

	WARNING("Пока табы рисуем не сами и ExtendDWM отсутствует - дополнительные изыски с временным DC не нужны");
	if (!gpSet->isTabsInCaption)
	{
		OnPaintClient(hdc, nWidth, nHeight);
	}
	else

	// Создадим временный DC, для удобства отрисовки в Glass-режиме и для фикса глюка DWM(?) см.ниже
	// В принципе, для режима Win2k/XP временный DC можно не создавать, если это будет тормозить
	{
		HDC hdcPaint = CreateCompatibleDC(hdc);
		HBITMAP hbmp = CreateCompatibleBitmap(hdc, nWidth, nHeight);
		HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcPaint, hbmp);

		OnPaintClient(hdcPaint, nWidth, nHeight);

		if ((gpConEmu->DrawType() == fdt_Aero) || !(mb_WasGlassDraw && gpConEmu->isZoomed()))
		{
			BitBlt(hdc, cr.left, cr.top, nWidth, nHeight, hdcPaint, 0, 0, SRCCOPY);
		}
		else
		{
			//mb_WasGlassDraw = FALSE;
			// Какой-то странный глюк DWM. При отключении Glass несколько верхних строк
			// клиентской области оказываются "разрушенными" - у них остается атрибут "прозрачности"
			// хотя прозрачность (Glass) уже отключена. В результате эти строки - белесые

			BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER)};
			bi.biWidth = cr.right-cr.left+1;
			bi.biHeight = GetFrameHeight()+1;
			bi.biPlanes = 1;
			bi.biBitCount = 32;
			COLORREF *pPixels = NULL;
			HDC hdcTmp = CreateCompatibleDC(hdc);
			HBITMAP hTmp = CreateDIBSection(hdcTmp, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pPixels, NULL, 0);
			if (hTmp == NULL)
			{
				_ASSERTE(hTmp == NULL);
				BitBlt(hdc, cr.left, cr.top, nWidth, nHeight, hdcPaint, 0, 0, SRCCOPY);
			}
			else
			{
				HBITMAP hOldTmp = (HBITMAP)SelectObject(hdcTmp, hTmp);

				BitBlt(hdcTmp, 0, 0, bi.biWidth, bi.biHeight, hdcPaint, 0, 0, SRCCOPY);

				int i = 0;
				for (int y = 0; y < bi.biHeight; y++)
				{
					for (int x = 0; x < bi.biWidth; x++)
					{
						pPixels[i++] |= 0xFF000000;
					}
				}

				BitBlt(hdc, cr.left, cr.top, bi.biWidth, bi.biHeight, hdcTmp, 0, 0, SRCCOPY);
				if (nHeight > bi.biHeight)
					BitBlt(hdc, cr.left, cr.top+bi.biHeight, nWidth, nHeight-bi.biHeight, hdcPaint, 0, bi.biHeight, SRCCOPY);

				SelectObject(hdcTmp, hOldTmp);
				DeleteObject(hbmp);
			}
			DeleteDC(hdcTmp);
		}

		SelectObject(hdcPaint, hOldBmp);
		DeleteObject(hbmp);
		DeleteDC(hdcPaint);
	}

	EndPaint(hWnd, &ps);

	return 0;
}