walnutcy

用VC模拟一个点阵屏之初步 (原创)

0
阅读(2335)

做过几个基于点阵屏的项目,每次都是在屏调通后才开始写界面,

这次改了,考虑通过Win32建一个工程,把一个缓冲区的数据更新到界面上,理论上即为动态生成图像并画出来,具体实现如下:

为便于更新与保存,做的时候我是利用Butoon的自绘功能实现位图的显示,这里只是演示原理,就以单色屏为研究对象,每个像素点只有0,1两种状态。

首先定义屏的大小,这里我以240×160为例。

#define     DISP_BITMAP_W       240
#define     DISP_BITMAP_H       160
#define     DISP_BITMAP_Wbyte   ((DISP_BITMAP_W+7)/8)
unsigned char mDispBitMap[DISP_BITMAP_Wbyte*DISP_BITMAP_H];

这就是屏缓存了,接着我们就实现一个接口,刷屏函数。

void CUpdateWindow(void)
{ // 直接更新屏的显示区域,这里只是发了一个消息
 InvalidateRect(GetDlgItem(g_hDlgHwnd, IDC_BUTTON_LCD), NULL, FALSE);
}
我们还需要实现BUTTON的自绘函数,

对于基于Win32的工程,可以实现这个消息处理:

 case WM_DRAWITEM:
 {
  LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
  if (lpdis) DrawGraph(lpdis->hwndItem); // 这个就是我们要实现的画屏函数了
  return TRUE;
 }

画屏函数定义:BOOL DrawGraph(HWND hwndDraw);

要将一个点阵数据显示到屏上,目前我想到了两种办法:

方法1) 采用DOS下显示汉字的原理,一个点一个点地画,利用SetPixel

主要实现部分如下:

 for(i=0;i<DISP_BITMAP_H;i++)
 {
  pBufText = lcdMem + i * APP_LCD_Wbyte;
  for (j=0;j<DISP_BITMAP_Wbyte;j++)
  {
   for(k=0;k<8;k++)
   {
    if((k+j*8)>=DISP_BITMAP_W )  break;
    if(pBufText[j]&(0x80>>k))
    {
     SetPixel(hDC,(k + j*8), i, RGB(0xFF,0xFF,0xFF));
    }
    else
    {
     SetPixel(hDC,(k + j*8), i, RGB(0x00,0x00,0xFF));
    }
   }           
  }
 }

这种实现方式刷屏慢,但也有一个好处,可以实现蓝底白字等较好的对比效果。

方法2) 直接利用缓冲区的数据创建BMP对象,

完整实现如下:

 HDC hDC;
 HDC hdcSrc = CreateCompatibleDC(NULL);
 if(!(hDC = GetDC(hwndDraw)))
 {
  return FALSE;
 }
 HBITMAP hbmNew = CreateBitmap(APP_LCD_W,APP_LCD_H,1,1,(&mDispBitMap[0][0]));
 SelectObject(hdcSrc, hbmNew);
 BitBlt(hDC, 0, 0,APP_LCD_W,APP_LCD_H, hdcSrc, 0, 0, SRCCOPY);
 DeleteDC(hdcSrc);
 ReleaseDC(hwndDraw, hDC);

采用这种方法刷屏较快,但只能实现黑白两色。

对于此感兴趣请继续关注,下一贴将讲一讲如何填充LCD的屏缓冲,即单色的界面生成。