⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 activex.cpp

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				{
					RECT rc;
					GetClientRect(m_displayWindow, &rc);
					BitBlt(hdc, 0, 0, rc.right, rc.bottom, m_displayBuffer, 0, 0, SRCCOPY);
				}
				else
				{
					PAINTSTRUCT ps;
					hdc = BeginPaint(m_displayWindow, &ps);

					if(!m_smartSizing)
					{
						BitBlt
						(
							hdc,
							ps.rcPaint.left,
							ps.rcPaint.top,
							ps.rcPaint.right - ps.rcPaint.left,
							ps.rcPaint.bottom - ps.rcPaint.top,
							m_displayBuffer,
							ps.rcPaint.left,
							ps.rcPaint.top,
							SRCCOPY
						);
					}
					else
					{
						// bleh. There has to be a better way
						SetStretchBltMode(hdc, HALFTONE);

						StretchBlt
						(
							hdc,
							0,
							0,
							m_consoleWidth,
							m_consoleHeight,
							m_displayBuffer,
							0,
							0,
							m_displayBufferWidth,
							m_displayBufferHeight,
							SRCCOPY
						);
					}

					EndPaint(m_displayWindow, &ps);
				}

				LeaveCriticalSection(&m_displayBufferMutex);
			}

			return 0;

		default:
			break;
		}

		return DefWindowProc(m_displayWindow, uMsg, wParam, lParam);
	}

	/* Screen repainting */
	void Display_RepaintRect(const RECT * lprc)
	{
		if(m_smartSizing)
			return Display_RepaintAll();

		RECT rcDamage;
		IntersectRect(&rcDamage, lprc, &m_displayBufferClip);
		InvalidateRect(m_displayWindow, &rcDamage, FALSE);
	}

	void Display_RepaintArea(int x, int y, int cx, int cy)
	{
		if(m_smartSizing)
			return Display_RepaintAll();

		RECT rcDamage;
		rcDamage.left = x;
		rcDamage.top = y;
		rcDamage.right = x + cx;
		rcDamage.bottom = y + cy;
		Display_RepaintRect(&rcDamage);
	}

	void Display_RepaintPolygon(POINT * point, int npoints, int linewidth)
	{
		if(m_smartSizing)
			return Display_RepaintAll();

		RECT rcDamage;

		rcDamage.left = MAXLONG;
		rcDamage.top = MAXLONG;
		rcDamage.right = 0;
		rcDamage.bottom = 0;

		for(int i = 0; i < npoints; ++ i)
		{
			if(point[i].x < rcDamage.left)
				rcDamage.left = point[i].x;

			if(point[i].y < rcDamage.top)
				rcDamage.top = point[i].y;

			if(point[i].x > rcDamage.right)
				rcDamage.right = point[i].x;

			if(point[i].y > rcDamage.bottom)
				rcDamage.bottom = point[i].y;
		}

		InflateRect(&rcDamage, linewidth, linewidth);
		Display_RepaintRect(&rcDamage);
	}

	void Display_RepaintAll()
	{
		InvalidateRgn(m_displayWindow, NULL, FALSE);
	}

public:
	void Display_SetClip(int x, int y, int cx, int cy)
	{
		m_displayBufferClip.left = x;
		m_displayBufferClip.top = y;
		m_displayBufferClip.right = x + cx + 1;
		m_displayBufferClip.bottom = y + cy + 1;

		HRGN hrgn = CreateRectRgnIndirect(&m_displayBufferClip);
		SelectClipRgn(m_displayBuffer, hrgn);
		DeleteObject(hrgn);
	}

	void Display_ResetClip()
	{
		m_displayBufferClip.left = 0;
		m_displayBufferClip.top = 0;
		m_displayBufferClip.right = m_displayBufferWidth;
		m_displayBufferClip.bottom = m_displayBufferHeight;
		SelectClipRgn(m_displayBuffer, NULL);
	}

	void Display_PaintBitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
	{
		GdiFlush();

		int fromstride = alignup(width * m_displayBufferByteDepth, 4);
		int sizex = cx * m_displayBufferByteDepth;

		const uint8 * src = data;

		uint8 * dst =
			(uint8 *)m_displayBufferRaw +
			(m_displayBufferHeight - y - cy) * m_displayBufferStride +
			x * m_displayBufferByteDepth;

		for(int i = 0; i < cy; ++ i)
		{
			memcpy(dst, src, sizex);
			src += fromstride;
			dst += m_displayBufferStride;
		}

		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_DestBlt(uint8 opcode, int x, int y, int cx, int cy)
	{
		int dcsave = SaveDC(m_displayBuffer);
		SelectObject(m_displayBuffer, GetStockObject(BLACK_BRUSH));
		PatBlt(m_displayBuffer, x, y, cx, cy, MAKELONG(0, opcode));
		RestoreDC(m_displayBuffer, dcsave);
		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_PatBlt(uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour, int fgcolour)
	{
		HBRUSH hbr = win32_create_brush(brush, fgcolour);

		int dcsave = SaveDC(m_displayBuffer);

		SetBkColor(m_displayBuffer, bgcolour);
		SetTextColor(m_displayBuffer, fgcolour);
		SetBrushOrgEx(m_displayBuffer, brush->xorigin, brush->yorigin, NULL);
		SelectObject(m_displayBuffer, hbr);

		PatBlt(m_displayBuffer, x, y, cx, cy, MAKELONG(0, opcode));

		RestoreDC(m_displayBuffer, dcsave);

		DeleteObject(hbr);

		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_ScreenBlt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy)
	{
		BitBlt(m_displayBuffer, x, y, cx, cy, m_displayBuffer, srcx, srcy, MAKELONG(0, opcode));
		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_MemBlt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy)
	{
		HDC hdcSrc = CreateCompatibleDC(m_displayBuffer);
		HGDIOBJ hOld = SelectObject(hdcSrc, src);

		BitBlt(m_displayBuffer, x, y, cx, cy, hdcSrc, srcx, srcy, MAKELONG(0, opcode));

		SelectObject(hdcSrc, hOld);
		DeleteDC(hdcSrc);

		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_TriBlt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy, BRUSH * brush, int bgcolour, int fgcolour)
	{
		// TODO
		HDC hdcSrc = CreateCompatibleDC(m_displayBuffer);
		HGDIOBJ hOld = SelectObject(hdcSrc, src);

		//SELECT_BRUSH(brush, bgcolour, fgcolour);

		BitBlt(m_displayBuffer, x, y, cx, cy, hdcSrc, srcx, srcy, MAKELONG(0, opcode));

		//RESET_BRUSH();

		SelectObject(hdcSrc, hOld);
		DeleteDC(hdcSrc);

		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_Line(uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen)
	{
		HPEN hpen = CreatePen(pen->style, pen->width, pen->colour);

		int dcsave = SaveDC(m_displayBuffer);

		SetROP2(m_displayBuffer, opcode);
		SelectObject(m_displayBuffer, hpen);
		MoveToEx(m_displayBuffer, startx, starty, NULL);

		LineTo(m_displayBuffer, endx, endy);

		RestoreDC(m_displayBuffer, dcsave);

		DeleteObject(hpen);

		RECT rcDamage;

		if(startx < endx)
		{
			rcDamage.left = startx;
			rcDamage.right = endx;
		}
		else
		{
			rcDamage.left = endx;
			rcDamage.right = startx;
		}

		if(starty < endy)
		{
			rcDamage.top = starty;
			rcDamage.bottom = endy;
		}
		else
		{
			rcDamage.top = endy;
			rcDamage.bottom = starty;
		}

		InflateRect(&rcDamage, pen->width, pen->width);
		Display_RepaintRect(&rcDamage);
	}

	void Display_Rect(int x, int y, int cx, int cy, int colour)
	{
		HBRUSH hbr = CreateSolidBrush(colour);

		int dcsave = SaveDC(m_displayBuffer);

		SelectObject(m_displayBuffer, hbr);
		SelectObject(m_displayBuffer, GetStockObject(NULL_PEN));

		Rectangle(m_displayBuffer, x, y, x + cx + 1, y + cy + 1);

		RestoreDC(m_displayBuffer, dcsave);

		DeleteObject(hbr);

		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_Polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints, BRUSH * brush, int bgcolour, int fgcolour)
	{
		HBRUSH hbr = win32_create_brush(brush, fgcolour);

		int dcsave = SaveDC(m_displayBuffer);

		SetBkColor(m_displayBuffer, bgcolour);
		SetTextColor(m_displayBuffer, fgcolour);
		SetPolyFillMode(m_displayBuffer, fillmode);
		SelectObject(m_displayBuffer, hbr);

		Polygon(m_displayBuffer, point, npoints);

		RestoreDC(m_displayBuffer, dcsave);

		Display_RepaintPolygon(point, npoints, 0);
	}

	void Display_Polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
	{
		POINT last = points[0];

		for(int i = 1; i < npoints; ++ i)
		{
			points[i].x += last.x;
			points[i].y += last.y;
			last = points[i];
		}

		HPEN hpen = CreatePen(pen->style, pen->width, pen->colour);

		int dcsave = SaveDC(m_displayBuffer);

		SetROP2(m_displayBuffer, opcode);
		SelectObject(m_displayBuffer, hpen);

		Polyline(m_displayBuffer, points, npoints);

		RestoreDC(m_displayBuffer, dcsave);

		DeleteObject(hpen);

		Display_RepaintPolygon(points, npoints, pen->width);
	}

	void Display_Ellypse(uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour, int fgcolour)
	{
		// TODO

		Display_RepaintArea(x, y, cx, cy);
	}

	// TBD: optimize text drawing
	void Display_DrawGlyph(int mixmode, int x, int y, int cx, int cy, HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
	{
		HBITMAP hbmGlyph = (HBITMAP)glyph;
		HDC hdcGlyph = CreateCompatibleDC(m_displayBuffer);
		HGDIOBJ hOld = SelectObject(hdcGlyph, hbmGlyph);

		int dcsave = SaveDC(m_displayBuffer);

		switch(mixmode)
		{
		case MIX_TRANSPARENT:
			{
				/*
					ROP is DSPDxax:
					 - where the glyph (S) is white, D is set to the foreground color (P)
					 - where the glyph (S) is black, D is left untouched

					This paints a transparent glyph in the specified color
				*/
				HBRUSH hbr = CreateSolidBrush(fgcolour);
				SelectObject(m_displayBuffer, hbr);
				BitBlt(m_displayBuffer, x, y, cx, cy, hdcGlyph, srcx, srcy, MAKELONG(0, 0xe2));
				DeleteObject(hbr);
			}

			break;

		case MIX_OPAQUE:
			{
				/* Curiously, glyphs are inverted (white-on-black) */
				SetBkColor(m_displayBuffer, fgcolour);
				SetTextColor(m_displayBuffer, bgcolour);
				BitBlt(m_displayBuffer, x, y, cx, cy, hdcGlyph, srcx, srcy, SRCCOPY);
			}

			break;
		}

		RestoreDC(m_displayBuffer, dcsave);

		SelectObject(hdcGlyph, hOld);
		DeleteDC(hdcGlyph);

		Display_RepaintArea(x, y, cx, cy);
	}

	void Display_DoGlyph(uint8 font, uint8 flags, int mixmode, int& x, int& y, int bgcolour, int fgcolour, const uint8 * ttext, int& idx)
	{
		FONTGLYPH * glyph;

		glyph = cache_get_font(/*This*/NULL, font, ttext[idx]);

		if(!(flags & TEXT2_IMPLICIT_X))
		{
			int xyoffset = ttext[++ idx];

			if((xyoffset & 0x80))
			{
				if (flags & TEXT2_VERTICAL)
					y += ttext[idx + 1] | (ttext[idx + 2] << 8);
				else
					x += ttext[idx + 1] | (ttext[idx + 2] << 8);

			  idx += 2;
			}
			else
			{
				if (flags & TEXT2_VERTICAL)
					y += xyoffset;
				else
					x += xyoffset;
			}
		}

		if(glyph)
		{
			Display_DrawGlyph
			(
				mixmode,
				x + (short)glyph->offset,
				y + (short)glyph->baseline,
				glyph->width,
				glyph->height,
				glyph->pixmap,
				0,
				0,
				bgcolour,
				fgcolour
			);

			if(flags & TEXT2_IMPLICIT_X)
				x += glyph->width;
		}
	}

	void Display_DrawText
	(
		uint8 font,
		uint8 flags,
		uint8 opcode,
		int mixmode,
		int x,
		int y,
		int clipx,
		int clipy,
		int clipcx,
		int clipcy,
		int boxx,
		int boxy,
		int boxcx,
		int boxcy,
		BRUSH * brush,
		int bgcolour,
		int fgcolour,
		uint8 * text,
		uint8 length
	)
	{
		int i, j;
		DATABLOB *entry;

		HBRUSH hbr = CreateSolidBrush(bgcolour);
		HGDIOBJ holdbrush = SelectObject(m_displayBuffer, hbr);
		HGDIOBJ holdpen = SelectObject(m_displayBuffer, GetStockObject(NULL_PEN));

		if (boxcx > 1)
			Rectangle(m_displayBuffer, boxx, boxy, boxx + boxcx + 1, boxy + boxcy + 1);
		else if (mixmode == MIX_OPAQUE)
			Rectangle(m_displayBuffer, clipx, clipy, clipx + clipcx + 1, clipy + clipcy + 1);

		SelectObject(m_displayBuffer, holdpen);
		SelectObject(m_displayBuffer, holdbrush);

		DeleteObject(hbr);

		if(boxcx > 1)
			Display_RepaintArea(boxx, boxy, boxcx, boxcy);
		else
			Display_RepaintArea(clipx, clipy, clipcx, clipcy);

		/* Paint text, character by character */
		for (i = 0; i < length;)
		{
			switch (text[i])
			{
				case 0xff:
					/* At least two bytes needs to follow */
					if (i + 3 > length)
					{
						warning("Skipping short 0xff command:");
						for (j = 0; j < length; j++)
							fprintf(stderr, "%02x ", text[j]);
						fprintf(stderr, "\n");
						i = length = 0;
						break;
					}
					cache_put_text(NULL /* TODO */, text[i + 1], text, text[i + 2]);
					i += 3;
					length -= i;
					/* this will move pointer from start to first character after FF command */
					text = &(text[i]);
					i = 0;
					break;

				case 0xfe:
					/* At least one byte needs to follow */
					if (i + 2 > length)
					{
						warning("Skipping short 0xfe command:");
						for (j = 0; j < length; j++)
							fprintf(stderr, "%02x ", text[j]);
						fprintf(stderr, "\n");
						i = length = 0;
						break;
					}
					entry = cache_get_text(/*This*/NULL, text[i + 1]);
					if (entry->data != NULL)
					{
						if ((((uint8 *) (entry->data))[1] == 0)
							&& (!(flags & TEXT2_IMPLICIT_X)) && (i + 2 < length))
						{
							if (flags & TEXT2_VERTICAL)
								y += text[i + 2];
							else
								x += text[i + 2];
						}
						for (j = 0; j < entry->size; j++)
							Display_DoGlyph(font, flags, mixmode, x, y, bgcolour, fgcolour, ((uint8 *) (entry->data)), j);
					}
					if (i + 2 < length)
						i += 3;
					else
						i += 2;
					length -= i;
					/* this will move pointer from start to first character after FE command */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -