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

📄 ledemuwnd.cpp

📁 魅族M8 LED源码 wince的。。。需要的下
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			}

			int ScreenStaSave = ScreenSta;
			if(AccY < -30)
			{
				ScreenSta = 2;//左横屏
			}
			else if(AccY > 30)
			{
				ScreenSta = 3;//右横屏
			}

	//		if(AccX < - 30)
	//		{
	//			ScreenSta = 0;//正常屏
	//		}
	//		else if(AccX > 30)
	//		{
	//			ScreenSta = 1;//反向屏
	//		}

			if(ScreenStaSave != ScreenSta)
			{
				if(AutoPause && Pause)
				{
					AutoPause = 0;
					Pause = 0;
				}
			}

			if(ScrollSize != 0 && !Pause)//如果需要卷动的长度为0...不处理
			{
				//挨个将虚拟LED缓冲中的数据拷贝到实际显示缓冲中
				//如果相同则不置刷新标志
				CopyVirtruaLed2DisBuf();
				ScrollPos++;
				ScrollPos %= (ScrollSize-LedSizeX);
				//	ScrollPos = 0;
				Invalidate();

			}
			if(GetTickCount() - TimeSave > 8000)
			{
				HANDLE  hd = SetPowerRequirement(L"BKL1:",D1,POWER_NAME,NULL,0);
				SystemIdleTimerReset();//10秒内必须重新调用一次
				SetSystemPowerState(NULL,POWER_STATE_ON,POWER_FORCE);
				ReleasePowerRequirement(hd);

				TimeSave = GetTickCount();
			}
			break;
		}
		return TRUE;
		break;
	}
	return CMzWndEx::MzDefWndProc(message,wParam,lParam);
}

//由Text创建虚拟LED数据缓冲(cVirtualLedDotBuf)
void CLedEmuWnd::LoadVirtualLedFromText(wchar_t *sDis)
{
	RECT tstRect;
	int i;


	HDC tmpDC;
	HBITMAP tmpBmp;
	tmpDC = CreateCompatibleDC(GetDC(m_hWnd));

    HPEN hpenBlack,hpenOld;
    HBRUSH hbrushBlack,hbrushOld;

	//这儿为什么使用这种笨方法,是因为这样可以关闭ClearType,否则会出现问题
	//因为ClearType会出现中间色。
	LOGFONT logFont =
	{
		20,0,0,
		0,	FW_BOLD, 
		FALSE, FALSE, 0, DEFAULT_CHARSET, 
		OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, 
		DEFAULT_PITCH | FF_SWISS, L"楷体"
	};

//	tmpBmp = CreateCompatibleBitmap(GetDC(m_hWnd),tstRect.right,tstRect.bottom);
	logFont.lfHeight = 10;
    HFONT font1= CreateFontIndirect(&logFont);//不使用FontHelper,因为要关闭ClearType;

	HFONT hFontOld = (HFONT)::SelectObject(tmpDC, font1);

	//用GDI函数测试最合适的字体大小
	for(i = LedSizeY-5;i < LedSizeY+5;i++)
	{
		tstRect.left = 0;
		tstRect.top = 0;
		tstRect.right = 0;
		tstRect.bottom = 0;

		logFont.lfHeight = i;
		DeleteObject((HGDIOBJ)(font1));
		font1= CreateFontIndirect(&logFont);//不使用FontHelper,因为要关闭ClearType;

		SelectObject(tmpDC, font1);
		DrawText(tmpDC,sDis,wcslen(sDis),&tstRect,DT_CALCRECT|DT_TOP|DT_LEFT);

		if(tstRect.bottom == 0)//全是空格,加载失败
		{
			//字串出错,也暂停
			//因为图片功能是后面加的,所以出错处理不统一
			Pause = TRUE;
			if(cVirtualLedDotBuf != NULL)
			{
				delete [] cVirtualLedDotBuf;
			}
			return;
		}

		if(tstRect.bottom > LedSizeY)
			break;
	}
	if(tstRect.bottom > LedSizeY+1)//如果字体大了点
	{
		i--;
		logFont.lfHeight = i;
		DeleteObject((HGDIOBJ)(font1));
		font1= CreateFontIndirect(&logFont);//不使用FontHelper,因为要关闭ClearType;

		SelectObject(tmpDC, font1);

		tstRect.left = 0;
		tstRect.top = 0;
		tstRect.right = 0;
		tstRect.bottom = 0;
		DrawText(tmpDC,sDis,wcslen(sDis),&tstRect,DT_CALCRECT|DT_TOP|DT_LEFT);
	}

	if(tstRect.bottom > LedSizeY+1)//这儿有个细节问题,就是一个点的差距
		tstRect.bottom = LedSizeY+1;

	//在有效数据两边各创建一个屏幕长的空白
	tstRect.right+=LedSizeX*2;
	tstRect.left+=LedSizeX;

	//创建BMP
	tmpBmp = CreateCompatibleBitmap(GetDC(m_hWnd),tstRect.right,tstRect.bottom);
	SelectObject(tmpDC, (HGDIOBJ)(tmpBmp));

	//背景画黑(图片也应该类似处理才安全,偷懒了)
	hpenBlack = CreatePen(PS_SOLID, 1,RGB(0, 0, 0));
	hbrushBlack = CreateSolidBrush(RGB(0, 0, 0));

	hpenOld=(HPEN)GetCurrentObject(tmpDC,OBJ_PEN);
	hbrushOld=(HBRUSH)GetCurrentObject(tmpDC,OBJ_BRUSH);

	SelectObject(tmpDC, (HGDIOBJ)hpenBlack);
	SelectObject(tmpDC, (HGDIOBJ)hbrushBlack);

	Rectangle(tmpDC,tstRect.left,tstRect.top,tstRect.right,tstRect.bottom);

	//绘制文字
	SetTextColor(tmpDC,AllColors[Color]);
	SetBkMode(tmpDC,TRANSPARENT);
	DrawText(tmpDC,sDis,wcslen(sDis),&tstRect,DT_TOP|DT_LEFT);

	GetDCPixel2LedBuf(tmpDC,tstRect.right,tstRect.bottom);

	(HFONT)::SelectObject(tmpDC, hFontOld);


	SelectObject(tmpDC, (HGDIOBJ)hpenOld);
	SelectObject(tmpDC, (HGDIOBJ)hbrushOld);

	DeleteObject(hpenBlack);
	DeleteObject(hbrushBlack);
	DeleteObject((HGDIOBJ)(tmpBmp));
	DeleteDC(tmpDC);

	DeleteObject((HGDIOBJ)(font1));

}

//由图片创建虚拟LED数据缓冲(cVirtualLedDotBuf)
void CLedEmuWnd::LoadVirtualLedFromBmp(wchar_t *BmpName)
{
	int i;
	HDC tmpDC;
	HBITMAP tmpBmp;
	BOOL Error=FALSE;

	ImagingHelper pDotImg;
	if(pDotImg.LoadImage(BmpName,false,true,false))
	{
		//图片高度*点的宽度 必须等于 屏幕宽度(480)
		for(DotSizeSelect = 0;DotSizeSelect < 3;DotSizeSelect++)
		{
			if(SaveLedSize[DotSizeSelect]* pDotImg.GetImageHeight() == GetWidth())
				break;
		}
		if(DotSizeSelect == 3)
		{
			Error = TRUE;
			MzMessageBoxEx(m_hWnd,L"图片高度错误", L"错误", MB_OK);
		}

		if(!Error)
		{
			LedSizeX = (GetHeight())/(SaveLedSize[DotSizeSelect]);
			LedSizeY = (GetWidth())/(SaveLedSize[DotSizeSelect]);

			RECT rcImg;
			rcImg.left = 0;
			rcImg.top = 0;
			rcImg.right = pDotImg.GetImageWidth();
			rcImg.bottom = pDotImg.GetImageHeight();

			rcImg.right+=LedSizeX*2;
			rcImg.left+=LedSizeX;

			//创建内存DC和内存BMP
			tmpDC = CreateCompatibleDC(GetDC(m_hWnd));
			tmpBmp = CreateCompatibleBitmap(GetDC(m_hWnd),rcImg.right,rcImg.bottom );
			SelectObject(tmpDC, (HGDIOBJ)(tmpBmp));

			rcImg.right -= LedSizeX;
			pDotImg.Draw(tmpDC,&rcImg);//将图片绘制到保存点图片的内部DC上
			rcImg.right += LedSizeX;

			if(cLedDotBuf != NULL)
				delete [] cLedDotBuf;

			cLedDotBuf = new UCHAR[LedSizeX*LedSizeY];
			for(i = 0;i < LedSizeX*LedSizeY;i++)
			{
				cLedDotBuf[i]=0x80;//清除所有显示
			}

			//将图片缓冲到LED缓冲区
			GetDCPixel2LedBuf(tmpDC,rcImg.right,rcImg.bottom);

			DeleteObject((HGDIOBJ)(tmpBmp));
			DeleteDC(tmpDC);
		}
	}
	else
	{
		Error = TRUE;
	}

	if(Error)
	{
		if(cLedDotBuf != NULL)
			delete [] cLedDotBuf;

		DotSizeSelect = 0;

		LedSizeX = (GetHeight())/(SaveLedSize[DotSizeSelect]);
		LedSizeY = (GetWidth())/(SaveLedSize[DotSizeSelect]);

		cLedDotBuf = new UCHAR[LedSizeX*LedSizeY];

		for(i = 0;i < LedSizeX*LedSizeY;i++)
		{
			cLedDotBuf[i]=0x80;//清除所有显示
		}

		if(cVirtualLedDotBuf != NULL)
		{
			delete [] cVirtualLedDotBuf;
		}
		cVirtualLedDotBuf = NULL;
		Pause = TRUE;//不能刷新屏幕
		MzMessageBoxEx(m_hWnd,L"打开图片错误", L"错误", MB_OK);
	}
}

//由HDC创建虚拟LED数据缓冲(cVirtualLedDotBuf)
//为上面两个函数服务,上面两个函数只是创建一个HDC,将此HDC和大小调用此函数就OK了
void CLedEmuWnd::GetDCPixel2LedBuf(HDC srcDC,int SizeX,int SizeY)
{
	COLORREF color;
	int i;
	if(cVirtualLedDotBuf != NULL)
	{
		delete [] cVirtualLedDotBuf;
	}
	cVirtualLedDotBuf = new UCHAR[SizeX*SizeY];
	
	int x,y;
	for(x = 0;x < SizeX;x++)
	{
		for(y = 0;y < SizeY;y++)
		{
			color = GetPixel(srcDC,x,y);
			//color = 1;
			if(color != 0)
			{
				//对取到的颜色进行计算,转换为支持的颜色
				int red = color & 0xff;
				int green = (color>>8) & 0xff;
				int blue = (color>>16) & 0xff;
				
				//得到亮度最高的那个分量
				i = red;
				if(green > i)
				{
					i = green;
				}

				if(blue > i)
				{
					i = blue;
				}
				
				//简单转换到支持的颜色
				int index = 0;
				if(red*3 > i*2)
				{
					index|=0x1;
				}
				if(green*3 > i*2)
				{
					index|=0x2;
				}
				if(blue*3 > i*2)
				{
					index|=0x4;
				}
				//index中的.0 .1 .2位
				// B G R
				// 0 0 0 //底色 - 在这儿不可能存在
				// 0 0 1 //红色
				// 0 1 0 //绿色
				// 0 1 1 //黄色
				// 1 0 0 //蓝色
				// 1 0 1 //紫色
				// 1 1 0 //青色
				// 1 1 1 //白色

				int depth = i >> 5;
				if(depth == 0)
				{
					cVirtualLedDotBuf[y*SizeX+x]=0;
				}
				else
				{
					UCHAR index2color[] = {0,0,1,2,3,4,5,6};
					cVirtualLedDotBuf[y*SizeX+x] = depth+(index2color[index]<<3);
				}
			}
			else
			{
				cVirtualLedDotBuf[y*SizeX+x]=0;
			}
		}
	}
	for(i = 0;i < LedSizeX*LedSizeY;i++)
	{
		cLedDotBuf[i]=0x80;//清除所有显示
	}

	ScrollSize = SizeX;
	ScrollPos = 0;//一开始要显示空白

	CopyVirtruaLed2DisBuf();

	ScreenSta = 0;//竖屏
	Pause = TRUE;//暂停
	AutoPause = TRUE;//自动暂停
	Invalidate();//刷新
}

//从完整虚拟LED缓冲区cVirtualLedDotBuf拷贝到cLedDotBuf(显示缓冲)
void CLedEmuWnd::CopyVirtruaLed2DisBuf()
{
	int x,y;
	UCHAR *pTarget;
	UCHAR *pSource;

	//有一个空指针就不能继续
	if(cVirtualLedDotBuf == NULL || cLedDotBuf == NULL)
		return;

	switch(ScreenSta)
	{
	case 1:
	case 3:
		for(y = 0;y < LedSizeY;y++)
		{
			pTarget = cLedDotBuf+y*LedSizeX;
			pSource = cVirtualLedDotBuf+y*ScrollSize+ScrollPos;
			for(x = 0;x < LedSizeX;x++)
			{

				if(*pTarget & 0x80)//点未刷新
				{
					*pTarget = *pSource|0x80;//直接置为新点
				}
				else
				{
					if(((*pTarget & 0x7) == 0) && ((*pSource & 0x7) == 0))
					{
						//都为黑点,不需要刷新
					}
					else if(*pTarget == *pSource)
					{
						//相同点,不需要刷新
					}
					else
					{
						*pTarget = *pSource|0x80;//需要刷新
					}
				}
				pTarget++;
				pSource++;
			}
		}
		break;
	case 0:
	case 2:
		for(y = 0;y < LedSizeY;y++)
		{
			pTarget = cLedDotBuf+(LedSizeX*(LedSizeY-y))-1;
			pSource = cVirtualLedDotBuf+y*ScrollSize+ScrollPos;
			for(x = 0;x < LedSizeX;x++)
			{

				if(*pTarget & 0x80)//点未刷新
				{
					*pTarget = *pSource|0x80;//直接置为新点
				}
				else
				{
					if(((*pTarget & 0x7) == 0) && ((*pSource & 0x7) == 0))
					{
						//都为黑点,不需要刷新
					}
					else if(*pTarget == *pSource)
					{
						//相同点,不需要刷新
					}
					else
					{
						*pTarget = *pSource|0x80;//需要刷新
					}
				}
				pTarget--;
				pSource++;
			}
		}
		break;
	}
}

⌨️ 快捷键说明

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