Click here to Skip to main content
15,896,606 members
Articles / Programming Languages / Objective C

Running State Machine Based Win32/WinCE Programs

Rate me:
Please Sign up or sign in to vote.
4.37/5 (9 votes)
17 May 20065 min read 70.9K   1.3K   35  
This article describes how to run state machine application framework based Win32/WinCE programs using the window message hooking technology. (Open source project)
/* Display.c
*/

#include "display.h"

/*

x:0--DISPLAY_SCREEN_SIZE_WIDTH-1
y:0--DISPLAY_SCREEN_SIZE_HEIGHT-1

*/

#define display_screen_valid( x, y ) \
	( (x < DISPLAY_SCREEN_SIZE_WIDTH) && (y < DISPLAY_SCREEN_SIZE_HEIGHT) )

#define display_menu_valid( x, y ) \
	( (x < DISPLAY_MENU_SIZE_WIDTH) && (y < DISPLAY_MENU_SIZE_HEIGHT) )

#define display_image_menu_valid( x, y ) \
	( (x < DISPLAY_IMAGE_MENU_SIZE_WIDTH) && (y < DISPLAY_IMAGE_MENU_SIZE_HEIGHT) )

#define display_screen_width_valid(x) \
	( x < DISPLAY_SCREEN_SIZE_WIDTH )

#define display_screen_height_valid(y) \
	( y < DISPLAY_SCREEN_SIZE_HEIGHT )

/* Set a specific bit to 1 (if it's already been 1,
then don't care) (bit_pos 0--7 from left to right)	*/
BOOL SetBit(unsigned char* pU8,int bit_pos){
	if(bit_pos>=0 && bit_pos<8 && pU8){
		(*pU8)|=(1<<(7-bit_pos));
		return TRUE;
	}
	return FALSE;
}

/* Set a whole byte with pData,If there're some bits
having already been 1,they won't be changed			*/
BOOL SetByte(unsigned char* pU8,const unsigned char* pData){
	if(pU8 && pData){
		*pU8=*pData;
		return TRUE;
	}
	else 
		return FALSE;
}

BOOL GetData(unsigned char* pU8,int data_pos,
			 DISPLAY_COLOR_T* pColor){
	if(data_pos>=0 && data_pos<DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL 
	   && pU8 && pColor){
		*pColor=(DISPLAY_COLOR_T)*pU8>>(8-(data_pos+1)*DISPLAY_BIT_PER_PIXEL);
		*pColor&=(int)DISPLAY_ADJUST_NUMBER;
		return TRUE;
	}
	return FALSE;
}

/* Set a specific data_pos to the data given by color
*/
BOOL SetData(unsigned char* pU8,int data_pos,
			 DISPLAY_COLOR_T color){
	if(data_pos>=0 && data_pos<DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL 
	   && pU8){
		(*pU8)&=~((unsigned char)DISPLAY_ADJUST_NUMBER<<(8-(data_pos+1)*DISPLAY_BIT_PER_PIXEL));
		(*pU8)|=(unsigned char)color<<(8-(data_pos+1)*DISPLAY_BIT_PER_PIXEL);
		return TRUE;
	}
	return FALSE;
}

BOOL SnapShot(DISPLAY_BUFFER Data){
	unsigned int i=0;
	if(Data){
		for(;i<64*DISPLAY_BYTE_PER_LINE;i++)
			Data[i]=Buf[i];
		return TRUE;
	}
	else
		return FALSE;
}

BOOL ClearScreen(){
	/*Set the whole buffer to 0xff*/
	unsigned char* pU8=(unsigned char*)Buf;
	int i,j;
	if(pU8){
		for(i=0;i<DISPLAY_SCREEN_SIZE_HEIGHT;i++)
			for(j=0;j<DISPLAY_BYTE_PER_LINE;j++){
				*pU8=DISPLAY_DEFAULT_BG_COLOR;
				pU8++;
			}
		return TRUE;
	}
	else
		return FALSE;
}

BOOL ClearRectangle(DISPLAY_COORDINATE_T x,
				    DISPLAY_COORDINATE_T y, 
				    DISPLAY_COORDINATE_T width,
					DISPLAY_COORDINATE_T height){
	DISPLAY_COORDINATE_T i,j;
	if(display_screen_valid(x+width-1,y+height-1)){
		for(i=y;i<y+height;i++)
			for(j=x;j<x+width;j++){
				DrawPoint(j,i,0xff);	
			}
		return TRUE;
	}
	else
		return FALSE;
}

BOOL SetRectangle(DISPLAY_COORDINATE_T x,
				     DISPLAY_COORDINATE_T y,
				     DISPLAY_COORDINATE_T width,
					 DISPLAY_COORDINATE_T height,
					 DISPLAY_BUFFER Data){

	DISPLAY_COORDINATE_T i,j;
	DISPLAY_COLOR_T color;
	unsigned char* pSource=(unsigned char*)Data;
	unsigned char* pDest=(unsigned char*)Buf;
	int pixel_per_byte=(DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL);
	int blk,pos;

	if(display_screen_valid(x+width-1,y+height-1)){
		for(i=y;i<y+height;i++)
			for(j=x;j<x+width;j++){
				blk=DISPLAY_BYTE_PER_LINE*i+j/pixel_per_byte;
				pos=j%pixel_per_byte;
				GetData(&pSource[blk],pos,&color);
				SetData(&pDest[blk],pos,color);
			}
		return TRUE;
	}
	else
		return FALSE;
}

unsigned char* GetPointHandler(DISPLAY_COORDINATE_T x,
							   DISPLAY_COORDINATE_T y,
							   int* pDataPos){
	unsigned char* pU8=(unsigned char*)Buf;
	int blk,pixel_per_byte=(DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL);
	if(display_screen_valid(x, y) && pU8){
		blk=DISPLAY_BYTE_PER_LINE*y+x/pixel_per_byte;
		*pDataPos=x%pixel_per_byte;
		return &pU8[blk];
	}
	else{
		*pDataPos=0;
		return NULL;
	}
}

BOOL DrawPoint(DISPLAY_COORDINATE_T x,
			   DISPLAY_COORDINATE_T y,
			   DISPLAY_COLOR_T color){
	unsigned char* pData;
	int num=0;
	if(pData=GetPointHandler(x,y,&num)){
		if(SetData(pData,num,color))
			return TRUE;
		else
			return FALSE;
	}
	else
		return FALSE;
}

BOOL DrawVertical(DISPLAY_COORDINATE_T x,
				  DISPLAY_COORDINATE_T y0,
				  DISPLAY_COORDINATE_T y1,
			      DISPLAY_COLOR_T color){
	DISPLAY_COORDINATE_T y;
	if(display_screen_valid(x,y0) && display_screen_valid(x,y1) && Buf){
		for(y=y0;y<y1;y++)
			if(!DrawPoint(x,y,DISPLAY_DEFAULT_PEN_COLOR))
				return FALSE;
		return TRUE;
	}
	else
		return FALSE;
}

BOOL DrawHorizontal(DISPLAY_COORDINATE_T x0,
				    DISPLAY_COORDINATE_T x1,
				    DISPLAY_COORDINATE_T y,
			        DISPLAY_COLOR_T color){
	DISPLAY_COORDINATE_T x;
	if(display_screen_valid(x0,y) && display_screen_valid(x1,y) && Buf){
		for(x=x0;x<x1;x++)
			if(!DrawPoint(x,y,DISPLAY_DEFAULT_PEN_COLOR))
				return FALSE;
		return TRUE;
	}
	else
		return FALSE;
}

BOOL DrawLine(DISPLAY_COORDINATE_T x0,
			  DISPLAY_COORDINATE_T y0,
			  DISPLAY_COORDINATE_T x1,
			  DISPLAY_COORDINATE_T y1,
			  DISPLAY_COLOR_T color){
	if(x0==x1 && Buf)
		return DrawVertical(x0,y0,y1,DISPLAY_DEFAULT_PEN_COLOR);
	if(y0==y1 && Buf)
		return DrawHorizontal(x0,x1,y0,DISPLAY_DEFAULT_PEN_COLOR);
	else
		return FALSE;
}

BOOL DrawRectangle(DISPLAY_COORDINATE_T x0,
				   DISPLAY_COORDINATE_T y0, 
				   DISPLAY_COORDINATE_T x1,
				   DISPLAY_COORDINATE_T y1,
				   DISPLAY_COLOR_T color){
	DISPLAY_COORDINATE_T x,y;
	if(display_screen_valid(x0,y0) && display_screen_valid(x0,y1)
	&& display_screen_valid(x1,y0) && display_screen_valid(x1,y1) && Buf){
		for(y=y0;y<=y1;y++)
			for(x=x0;x<=x1;x++)
				DrawPoint(x,y,color);
		return TRUE;
	}
	else
		return FALSE;
}

/*Draw Font Character*/
/*Notes: if MBCS, the code needs to be converted
  with the formulor: 0xB0A1+94*(0xB9-0xB0)+(0xA6-0xA1) 
  (0xB9A6)
*/
BOOL DrawFontBitmap(DISPLAY_COORDINATE_T x,
					DISPLAY_COORDINATE_T y,
					unsigned long nFontID,
					unsigned short nChar,
				    DISPLAY_COLOR_T color){

	unsigned char* pFontData;
	unsigned char* pU8;
	unsigned long length;
	int width,height;
	int i,j,num,cnt,bit_pos=0;
	SME_FONT_INFO_T fontInfo;

	if(SmeGetFontBitmap(nFontID,nChar,&pFontData,&length) && Buf){
		SmeGetFontInfo(nFontID,&fontInfo);
		if(nChar<fontInfo.nStartChar || nChar>fontInfo.nEndChar)
			return FALSE;
		width=fontInfo.nWidth;
		height=fontInfo.nHeight;
		if(!display_screen_valid(x+width-1,y+height-1))
			return FALSE;
		pU8=(unsigned char*)Buf;
		for(i=y;i<y+height;i++)
			for(j=x;j<x+width;j++){
				cnt=(i-y)*width+(j-x);
				if((*pFontData << (bit_pos % DISPLAY_BIT_PER_BYTE)) & 0x80)
					if(pU8=GetPointHandler(j,i,&num)){
						SetData(pU8,num,color);
					}
				if((bit_pos % DISPLAY_BIT_PER_BYTE)==DISPLAY_BIT_PER_BYTE-1 || cnt%width==width-1){
					pFontData++;
					bit_pos=0;
				}
				else
					bit_pos++;
			}
		return TRUE;
	}
	else
		return FALSE;
}

BOOL DrawCharacterAt(int line,
					 int num,
					 unsigned long nFontID,
					 unsigned short nChar,
					 DISPLAY_COLOR_T color){
	SME_FONT_INFO_T fontInfo;
	DISPLAY_COORDINATE_T x,y;
	int height,width;
	SmeGetFontInfo(nFontID,&fontInfo);
	height=fontInfo.nHeight;
	width=fontInfo.nWidth;
	x=(DISPLAY_COORDINATE_T)((num-1)*width);
	y=(DISPLAY_COORDINATE_T)((line-1)*height)+4;
	return DrawFontBitmap(x,y,nFontID,nChar,color);
}

BOOL DrawDigit(DISPLAY_COORDINATE_T x,
			   DISPLAY_COORDINATE_T y,
			   int digit,
			   DISPLAY_COLOR_T color){
	if(digit>=0 && digit<=9)
		return DrawFontBitmap(x,y,DEFAULT_DIGIT_FONT,(unsigned short)('0'+digit),color);
	else
		return FALSE;
}

BOOL DrawNumber(DISPLAY_COORDINATE_T x,
			    DISPLAY_COORDINATE_T y,
			    int num,
			    DISPLAY_COLOR_T color){
	int width=GetFontWidth(DEFAULT_DIGIT_FONT);
	int base=10,digit,pos=x;
	while(num/base)
		base*=10;
	if(num<10){
		DrawDigit(x,y,0,color);
		x+=width;
	}
	while(base>=10){
		num%=base;
		base/=10;
		digit=num/base;
		DrawDigit(x,y,digit,color);
		x+=width;
	}
	return TRUE;
}

int GetFontHeight(unsigned long nFontID){
	SME_FONT_INFO_T fontInfo;
	SmeGetFontInfo(nFontID,&fontInfo);
	return fontInfo.nHeight;
}

int GetFontWidth(unsigned long nFontID){
	SME_FONT_INFO_T fontInfo;
	SmeGetFontInfo(nFontID,&fontInfo);
	return fontInfo.nWidth;
}

/*Get the data of a string from its handler*/
const SME_CHAR* GetTextStr(unsigned long nRcId, unsigned char nLang){
	SME_CHAR* pText;
	if(SmeGetTextString(nRcId,nLang,&pText))
		return pText;
	else
		return NULL;
}

/*Get the length of a string from its handler*/
int GetStrLen(const SME_CHAR* pText){
	int len=0;
	SME_CHAR* pFlag=(SME_CHAR*)pText;
	if(!pText)
		return 0;
	while(pFlag && *pFlag){
		len++;
		pFlag++;
	}
	if(pText[0]>=0)
		return len;
	else
		return len/2;
}

/*Get the data of a specific character in the string*/
unsigned short GetStrCh(const SME_CHAR* pText,int ch_pos){
	unsigned char high,low;
	if(ch_pos<GetStrLen(pText))
		if(pText[0]>=0)/*ANSI*/
			return pText[ch_pos];
		else/*MBCS*/{
			high=pText[ch_pos*2];
			low=pText[ch_pos*2+1];
			return 0xB0A1+94*(high-0xB0)+(low-0xA1);
		}
	else
		return 0;
}

/*Draw text string to the screen*/
BOOL DrawTextStr(DISPLAY_COORDINATE_T x,
				 DISPLAY_COORDINATE_T y,
				 const SME_CHAR* pStr,
				 unsigned long nFontID,
				 DISPLAY_COLOR_T color){
	SME_FONT_INFO_T fontInfo;
	int width,size;
	int j=x;
	SME_CHAR* str=(SME_CHAR*)pStr;
	SmeGetFontInfo(nFontID,&fontInfo);
	width=fontInfo.nWidth;
	if(Buf){
		for(size=0;size<GetStrLen(pStr);size++){
			if(!DrawFontBitmap(j,y,nFontID,GetStrCh(str,size),color))
				break;
			j+=width;
		}
		return TRUE;
	}
	else
		return FALSE;
}

/*Draw a line of text string to the screen*/
/*Line:start from 1*/
BOOL DrawTextStrAt(int line,
				   int mode,
				   const SME_CHAR* pStr,
				   unsigned long nFontID,
				   DISPLAY_COLOR_T color){
	SME_FONT_INFO_T fontInfo;
	DISPLAY_COORDINATE_T x,y;
	int height,width,length,margin;
	SmeGetFontInfo(nFontID,&fontInfo);
	height=fontInfo.nHeight;
	width=fontInfo.nWidth;
	length=GetStrLen(pStr);
	margin=DISPLAY_TEXTAREA_SIZE_WIDTH-length*width;
	switch(mode){
	case MODE_LEFT:
		x=0;
		break;
	case MODE_CENTER:
		if(margin>0)
			x=margin/2;
		else
			x=0;
		break;
	case MODE_RIGHT:
		if(margin>0)
			x=margin;
		else
			x=0;
		break;
	};
	y=(DISPLAY_COORDINATE_T)((line-1)*height)+4;
	return DrawTextStr(x,y,pStr,nFontID,color);
}

/* Get item_num,menu_pointer of nRcId */
int GetMenuData(unsigned long nRcId,int menu_pos,
						   POINTER_OF_MENU_DATA* pMenuData){
	int i=0;
	unsigned short num;
	SmeGetMenuData(nRcId,&num,pMenuData);
	for(;i<menu_pos;i++)
		(*pMenuData)++;
	return num;
}

/*pos ��1��specifying the initial position��2��return the last position been drawed 
on the screen*/
BOOL DrawMenu(unsigned long nRcId,
			  unsigned char nLang,unsigned long nFontID,int* pPos,
			  DISPLAY_COLOR_T color){
	int i,cnt=0,height=GetFontHeight(nFontID);
	unsigned short num;
	unsigned short minus='-',plus='+';
	int sep=2;
	SME_MENU_DATA_T* pData=NULL;
	SmeGetMenuData(nRcId,&num,&pData);
	if(!pPos || num<0 || *pPos>=num || *pPos<0 || !Buf)
		return FALSE;
	for(i=0;i<*pPos;i++)
		pData++;
	for(;i<num;i++){
		if(display_menu_valid(15,(int)((i-*pPos+1)*height-1+3))){
			if(pData->nSubMenuID>=0)
				DrawFontBitmap(0,(int)((i-*pPos)*height+sep),0,plus,color);
			else
				DrawFontBitmap(0,(int)((i-*pPos)*height+sep),0,minus,color);
			DrawTextStr(10,(int)((i-*pPos)*height+sep),GetTextStr(pData->nMenuTitleID,nLang),nFontID,color);
			cnt++;
			pData++;
			sep++;
		}
	}
	*pPos=(int)cnt;
	return TRUE;
}

BOOL DrawImageMenu(unsigned long nMenuId,unsigned long nBitmapId,
				   unsigned char nLang,unsigned long nFontID,int pos,DISPLAY_COLOR_T color){
	SME_MENU_DATA_T* pData=NULL;
	int i;
	unsigned short num;
	SmeGetMenuData(nMenuId,&num,&pData);
	if(!Buf || num<0 || pos>=num || pos<0)
		return FALSE;
	for(i=0;i<pos;i++)
		pData++;
	DrawBitmapAt(1,MODE_CENTER,nFontID,nBitmapId);
	DrawTextStrAt(3,MODE_CENTER,GetTextStr(pData->nMenuTitleID,nLang),nFontID,color);
	return TRUE;
}

/*Reverse the color of select aera*/
/*TURE:reverse , FALSE:cancel*/
BOOL DrawReverseArea(DISPLAY_COORDINATE_T x,
					 DISPLAY_COORDINATE_T y,
					 DISPLAY_COORDINATE_T width,
					 DISPLAY_COORDINATE_T height,
					 BOOL mode)
{
	unsigned char* pDis=(unsigned char*)Buf;
	int i,j,num,color;
	if(pDis){
		for(i=y;i<y+height;i++)
			for(j=x;j<x+width;j++)
			{
				if(display_screen_valid(x+width-1,y+height-1))
					if(pDis=GetPointHandler(j,i,&num)){
						GetData(pDis,num,&color);
						if(mode){
							switch(color){
							case 0:
								color=0xff;
								break;
							case 0xff:
								color=0xfc;
								break;
							};
						}
						else{
							switch(color){
							case 0xfc:
								color=0xff;
								break;
							case 0xff:
								color=0x00;
								break;
							};
						}
						SetData(pDis,num,color);
					}
			}
		return TRUE;
	}
	else
		return FALSE;
}

//if old pos < 0, no modification is needed 
BOOL SetMenuFocus(unsigned long nRcId,
				  unsigned long nFontID,int old_pos,int new_pos){
	int height=GetFontHeight(nFontID);
	unsigned short num;
	int sep=2;
	SME_MENU_DATA_T* pData=NULL;
	SmeGetMenuData(nRcId,&num,&pData);
	if(old_pos>=0 && old_pos<num){
		DrawReverseArea(0,(int)(old_pos*(height+1)+sep),80,(int)(height+2),FALSE);
	}
	if(new_pos>=0 && new_pos<num){
		return DrawReverseArea(0,(int)(new_pos*(height+1)+sep),80,(int)(height+2),TRUE);
	}
	else
		return FALSE;
}

int GetBitmapHeight(unsigned long nRcId){
	SME_BITMAP_DATA_T bitmap_data;
	if(SmeGetBitmap(nRcId,&bitmap_data))
		return bitmap_data.nHeight;
	else
		return 0;
}

int GetBitmapWidth(unsigned long nRcId){
	SME_BITMAP_DATA_T bitmap_data;
	if(SmeGetBitmap(nRcId,&bitmap_data))
		return bitmap_data.nWidth;
	else
		return 0;
}

/*Draw a bitmap to the screen*/
BOOL DrawBitmap(DISPLAY_COORDINATE_T x,
				DISPLAY_COORDINATE_T y,
				unsigned long nRcId){
	SME_BITMAP_DATA_T bitmap_data;
	unsigned char* pDis=(unsigned char*)Buf;
	unsigned char* pBmp;
	int i,j,color,count=0;
	int bmp_bpp,bmp_width,bmp_height,data_width,
		           pixel_per_byte=(DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL);

	if(SmeGetBitmap(nRcId,&bitmap_data) && Buf){
		pBmp=(unsigned char*)(bitmap_data.pData);
		data_width=(int)bitmap_data.nLength/bitmap_data.nHeight;
		bmp_width=bitmap_data.nWidth;
		bmp_height=bitmap_data.nHeight;
		bmp_bpp=bitmap_data.nBitCountPerPixel;
		if(display_screen_valid(x+bmp_width-1,y+bmp_height-1)
		   && bmp_bpp==DISPLAY_BIT_PER_PIXEL){
			for(i=y;i<y+bitmap_data.nHeight;i++)
				for(j=x;j<x+data_width*pixel_per_byte;j++){
					if(j>=x+data_width*pixel_per_byte-bmp_width){
						color=(*pBmp>>((count%pixel_per_byte)*DISPLAY_BIT_PER_PIXEL)) & (unsigned char)DISPLAY_ADJUST_NUMBER;
						DrawPoint((int)(x+bmp_width-(j-x)-1),i,color);
					}
					if (count%pixel_per_byte==pixel_per_byte-1)
						pBmp++;
					count++;
				}
			return TRUE;
		}
		else
			return FALSE;
	}
	else
		return FALSE;
}

BOOL DrawBitmapAt(int line,
				  int mode,
				  unsigned long nFontID,
				  unsigned long nRcId){
	DISPLAY_COORDINATE_T x,y;
	int font_height,bmp_width,margin;
	font_height=GetFontHeight(nFontID);
	bmp_width=GetBitmapWidth(nRcId);
	margin=DISPLAY_TEXTAREA_SIZE_WIDTH-bmp_width;
	switch(mode){
	case MODE_LEFT:
		x=0;
		break;
	case MODE_CENTER:
		if(margin>0)
			x=margin/2;
		else
			x=0;
		break;
	case MODE_RIGHT:
		if(margin>0)
			x=margin;
		else
			x=0;
		break;
	};
	y=(DISPLAY_COORDINATE_T)((line-1)*font_height)+4;
	return DrawBitmap(x,y,nRcId);
}

/*Draw the softkey to the screen , but you need to Set them before you use
this function*/
BOOL DrawSoftkey(const SOFTKEY_INFO_T* pSoftkey,
				 unsigned char nLang,
				 unsigned long nFontId,
			     DISPLAY_COLOR_T color){
	const SME_CHAR* str;
	if(pSoftkey->isDefined && Buf){
		str=GetTextStr(pSoftkey->sklStrId,nLang);
		DrawTextStr(0,DISPLAY_SOFTKEY_SIZE_TOP+1,str,nFontId,DISPLAY_DEFAULT_PEN_COLOR);
		DrawReverseArea(0,DISPLAY_SOFTKEY_SIZE_TOP,DISPLAY_SOFTKEY_SIZE_WIDTH,DISPLAY_SOFTKEY_SIZE_HEIGHT,TRUE);
		str=GetTextStr(pSoftkey->skrStrId,nLang);
		DrawTextStr(56,DISPLAY_SOFTKEY_SIZE_TOP+1,str,nFontId,DISPLAY_DEFAULT_PEN_COLOR);
		DrawReverseArea(56,DISPLAY_SOFTKEY_SIZE_TOP,DISPLAY_SOFTKEY_SIZE_WIDTH,DISPLAY_SOFTKEY_SIZE_HEIGHT,TRUE);
		return TRUE;
	}
	else
		return FALSE;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Web Developer
China China
Jerome. (Free to speak, free to use.)

Comments and Discussions