guilib.cpp

来自「自己实现的一个好用的嵌入式GUI」· C++ 代码 · 共 1,048 行 · 第 1/2 页

CPP
1,048
字号
#include"stdafx.h"

#include"guilib.h"
#include<ctype.h>
#include<string.h>
#include<stdarg.h>
#include<stdio.h>
//////////////////////////////////////////////////////////////globe various//////////////////////////////////////////////////////
CNode* gl_focus = NULL;     //point to the node with text or button
CNode* gl_mainfocus = NULL; //point to the node with win
void*  gl_pointerCollector[OBJ_NUM];
int    gl_pointerType[OBJ_NUM];
CWin*  gl_desktop = NULL;
int    gl_pointerNum = 0;
CVector* gl_activeWinVec = NULL;
CMssg* gl_mssg = NULL;
void* gl_pdata = NULL;
CVector* gl_mssgVec = NULL; 
/////////////////////////////////////////////////globe pointer manage/////////////////////////////////////////////////////
void collectPointer(void* pointer, int ptrType){

	gl_pointerCollector[gl_pointerNum] = pointer;
	gl_pointerType[gl_pointerNum] = ptrType;
	gl_pointerNum++;
}
void iniGui(CWin* pstartWindow){

//	gl_pdata = newCData(NULL, DEF_TYPE);
	gl_mssg = newCMssg(NULL, WM_DEF, 0, 0); 
    gl_mssgVec = newCVector();
	gl_activeWinVec = newCVector();	
	CRect1* deskRect = newCRect(30, 30, SCREEN_X, SCREEN_Y);
    gl_desktop = newCWin(deskRect, "desktop");
//    void* pdesktopData = newCData(gl_desktop, CWIN);

//	CData* pstartWinData = newCData(pstartWindow, CWIN);//start node
	
	
//	gl_activeWinVec->push_back(gl_desktop, gl_activeWinVec);
//    gl_activeWinVec->push_back(pstartWindow, gl_activeWinVec);//push startWindow into activeWinVec
	
    show(gl_desktop);//, CWIN);
	show(pstartWindow);//, CWIN);

}
void freeAll(){

	int i=0; //void* p=NULL;
	for(i=0; i<gl_pointerNum; i++){

		//p = gl_pointerCollector[i];

		//if(p!=NULL){ free(p); p=NULL;}
		if(gl_pointerCollector[i]){
			free(gl_pointerCollector[i]);
		}
		gl_pointerCollector[i] = NULL;
		gl_pointerType[i] = TYPE_DEF;
			
	}
	gl_pointerNum = 0;
//   gl_activeWinVec->size = 0;
//	gl_activeWinVec->head = NULL;
//	gl_activeWinVec->tail = NULL;
}

void freeOne(void* pointer){
	if(pointer==NULL){  
		return; 
	}
	int i; 
	for(i=0; i<gl_pointerNum; i++){
		if(gl_pointerCollector[i]==pointer){
				gl_pointerCollector[i] = NULL;
				gl_pointerType[i] = TYPE_DEF;
				break;
		}
		
	}
	free(pointer);
}

int getPtrType(void* ptr){

	int i;
	for(i=0; i<gl_pointerNum; i++){
		if(gl_pointerCollector[i]==ptr){
			return gl_pointerType[i];
		}
	}
	return TYPE_DEF;
}
//////////////////////////////////////////////////////////////vector//////////////////////////////////////////////////////

//function for CVector operate

CVector* newCVector(){
    
	CVector* self = (CVector*)malloc(sizeof(CVector));
	self->size = 0;
	self->head = NULL;
	self->tail = NULL;
    //member function
    self->push_back = push_back;
	self->eraseByIndex = eraseByIndex;
    self->eraseByKey = eraseByKey;
	self->getByIndex = getByIndex;
	self->getIndex = getIndex;
	self->clear = clear;
    collectPointer(self, CVECTOR);//add to pointercollector
	return self;	
}
CNode* newCNode(){

	CNode* self = (CNode*)malloc(sizeof(CNode));
	self->next = NULL;
	self->pdata = NULL;
	collectPointer(self, CNODE);
	return self;
}


CNode* push_back(void* pdata, CVector* self){

		CNode* p = newCNode();    //create a home node for the elem
		p->pdata = pdata;
		p->next = NULL;
		if( self && self->tail){                //not empty
			self->tail->next = p;      //add to the end of the list, become the new tail
		}else{                   //empty list
			self->head = p;
		}
		self->tail = p;
		self->size++;
		push_back_hook(p, pdata);
		return p;
}
void push_back_hook(CNode* pnewNode, void* pdata){
    
	int winType = TYPE_DEF;
	CWin* pwin = NULL;
	CButtn* pbtn = NULL;
	CText* ptxt = NULL;

	winType = getPtrType(pdata);

	switch(winType){
	case CWIN:
		    pwin = (CWin*)pdata;
			pwin->pExtra = pnewNode;
			break;
	case CBUTTN:
			pbtn = (CButtn*)pdata;
			pbtn->pExtra = pnewNode;
			break;
    case CTEXT:
			ptxt = (CText*)pdata;
			ptxt->pExtra = pnewNode;
			break;
	}
	
}
void eraseByIndex(int nindex, CVector* self){

	   	if(nindex>=0 && self && nindex<self->size){			
		    if(self->head==self->tail){      //has only one node 
		    	self->head = NULL; 
		    	self->tail = NULL;
			}else if(nindex==0){ //delete head node (list have at least two nodes)
		    	CNode* q = self->head; 
		    	self->head = self->head->next;	
			}else{
		    	CNode* p = self->head;
				int i;
		    	for(i=0; i<nindex-1; i++){  //find target node which is before p
		    		p = p->next;
				}
		    	if(p->next==self->tail){              //target node is tail
			    	self->tail = p;
				}else{                          //target node is between head and tail
			    	p->next = p->next->next;
				}
			}
		    self->size--;
		}

}
void eraseByKey(const void* pdata, CVector* self){
    
	   CNode* p = NULL;
       CNode* q = NULL;	
	   if(self && self->head && self->head->pdata==pdata){				//delete head node
        	if(self->head==self->tail){                         //has only one node
		    	self->head = NULL; 
		    	self->tail = NULL;
			}else{                                  //has at least two nodes
		    	self->head = self->head->next;	
			}
			self->size--;
			return;
		}

							//record the p's forhead
		for(p=self->head; p!=self->tail; q=p, p=p->next ){
			if(p->pdata==pdata){                       //find the target node
				q->next = p->next;                   //target is between head and tail
				self->size--;
				return;
			}
		}
		if(p && p==self->tail && p->pdata==pdata){           //delete tail node
			self->tail = q;
            self->size--;
		} 

}

void* getByIndex(int nindex, CVector* self){

	if(nindex>=0 && nindex<self->size){
			CNode* p = NULL;
			int j = 0;
			for(j=0,p=self->head; j<nindex; j++,p=p->next);
			return p->pdata;
	}
    return NULL;	
}

int getIndex(const void* pdata, CVector* self){

    int i=0;
	void* ptemp = NULL;
	for(i=0; i<self->size; i++){
        ptemp = self->getByIndex(i, self);
		if(ptemp==pdata){
			return i;
		}
	}
	return -1;
}

void clear(CVector* self){
	self->size = 0;
	self->head = NULL;
	self->tail = NULL;
}
//////////////////////////////////////////////////////////////CData////////////////////////////////////////////////////////
/*CData* newCData(void* pobj, int wintype){

	CData* self = (CData*)malloc(sizeof(CData));
	self->wintype = wintype;
	self->pobj = pobj;
	collectPointer(self, CDATA);
	return self;
}*/
//////////////////////////////////////////////////////////////CRec////////////////////////////////////////////////////////

CRect1* newCRect(int x, int y, int w, int l){

	CRect1* self = (CRect1*)malloc(sizeof(CRect1));
	self->x = x;
	self->y = y;
    self->w = w;
	self->l = l;
	collectPointer(self, CRECT);
	return self;
}
//////////////////////////////////////////////////////////////CMssg////////////////////////////////////////////////////////

CMssg* newCMssg(void* pdata, int type, int lparam, int wparam){

	CMssg* self = (CMssg*)malloc(sizeof(CMssg));
	self->pdata = pdata;
	self->type = type;
	self->lparam = lparam;
	self->wparam = wparam;
	collectPointer(self, CMSSG);
	return self;
}
//////////////////////////////////////////////////////////////CWin////////////////////////////////////////////////////////
CWin* newCWin(CRect1* prec, char* caption){

    int i;
	CWin* self = (CWin*)malloc(sizeof(CWin));
	self->prec = prec;
    self->caption = caption;
	self->pchild_vec = newCVector();
	
	for(i=0; i<MSSG_NUM; i++){
		self->winproc[i] = NULL;
	}
	self->winproc[WM_SHOW1] = OnShow;    //default proc
	self->winproc[WM_CHANGEFOCUS1] = OnChangeFocus;//focus;
	self->winproc[WM_CLOSE1] = OnClose;
//	self->addComponent = addComponent;
//	self->drawWin = drawWin;
	collectPointer(self, CWIN);
	return self;
}

void changeFocus(){
	
	//get topwin in activeWinVec;

	eraseFocus();

	CNode* ptopNode= gl_activeWinVec->tail;     
	if(ptopNode == NULL){

		gl_mainfocus = NULL;
		gl_focus = NULL;

	}else if(gl_mainfocus!=ptopNode){//if top win is changed, renew the two globe pointer         
	
		gl_mainfocus = ptopNode;
		gl_focus = gl_mainfocus;

	}else if(gl_focus!=gl_mainfocus){ //gl_mainfocus==ptopNode && gl_mainfocus!=gl_focus                                                       
		if(gl_focus && getPtrType(gl_focus)==CNODE && gl_focus->next){
	//	if(gl_focus && gl_focus->next){
			gl_focus = gl_focus->next;
		}else{
			gl_focus = gl_mainfocus;
		}
    
	}else{								//gl_focus==gl_mainfocus
        CWin* pwin = (CWin*)gl_mainfocus->pdata;
//		if(pwin && getPtrType(pwin)==CWIN && pwin->pchild_vec && pwin->pchild_vec->head)
//		int nPtrTp = getPtrType(pwin);
//	    if(nPtrTp==CWIN && pwin->pchild_vec->size>0)
			gl_focus = pwin->pchild_vec->head;
	}
//	if(gl_activeWinVec->size!=1){//if only desktop left, need no focustag
		tagFocus();
//	}else{
//		eraseFocus();
//	}
	
}

void tagFocus(){

	void* pdata = NULL;
	CWin* pwin = NULL;
	CButtn* pbtn = NULL;
	CText* ptxt = NULL;
    CDC *pDC = (AfxGetApp()->m_pMainWnd)->GetDC();
    int nptrTp = getPtrType(gl_focus);
	if(gl_focus && nptrTp==CNODE && gl_focus->pdata){
//    if(gl_focus && gl_focus->pdata){
		pdata = gl_focus->pdata;
		int winType = getPtrType(pdata); 
		switch(winType){
		case CWIN:
			pwin = (CWin*)pdata;
			if(pwin->caption != "desktop")
				pDC->TextOut(pwin->prec->x-10, pwin->prec->y, '>');
			break;
		case CBUTTN:
			pbtn = (CButtn*)pdata;
            pDC->TextOut(pbtn->prec->x-10, pbtn->prec->y, '>');
			break;
		case CTEXT:
			ptxt = (CText*)pdata;
			pDC->TextOut(ptxt->prec->x-10, ptxt->prec->y, '>');
			break;
		}
	}
	(AfxGetApp()->m_pMainWnd)->ReleaseDC(pDC);
}
void eraseFocus(){

	void* pdata = NULL;
	CWin* pwin = NULL;
	CButtn* pbtn = NULL;
	CText* ptxt = NULL;
    CDC *pDC = (AfxGetApp()->m_pMainWnd)->GetDC();
    int nptrTp = getPtrType(gl_focus);
	if(gl_focus && nptrTp==CNODE && gl_focus->pdata){
//	if(gl_focus && gl_focus->pdata){

		pdata = gl_focus->pdata;
        int winType = getPtrType(pdata); 
		switch(winType){
		case CWIN:
			pwin = (CWin*)pdata;
            pDC->TextOut(pwin->prec->x-10, pwin->prec->y, "  ");
			break;
		case CBUTTN:
			pbtn = (CButtn*)pdata;
            pDC->TextOut(pbtn->prec->x-10, pbtn->prec->y, "  ");
			break;
		case CTEXT:
			ptxt = (CText*)pdata;
			pDC->TextOut(ptxt->prec->x-10, ptxt->prec->y, "  ");
			break;
		}
	}
    (AfxGetApp()->m_pMainWnd)->ReleaseDC(pDC);
}

void setFocus(void* p){

	eraseFocus();
	CWin* pwin = NULL;
	CButtn* pbtn = NULL;
	CText* ptxt = NULL;
	int winType = getPtrType(p);
	switch(winType){
	case CWIN:
		pwin = (CWin*)p;
		if(pwin->pExtra && gl_focus!=pwin->pExtra){
			gl_mainfocus = (CNode*)pwin->pExtra;
			gl_focus= gl_mainfocus;
		}
		break;
	case CBUTTN:
		pbtn = (CButtn*)p;
		if(pbtn->pExtra && gl_focus!=pbtn->pExtra){
			gl_focus = (CNode*)pbtn->pExtra;
			gl_mainfocus = (CNode*)pbtn->parentWin->pExtra;
		}
		break;
	case CTEXT:
		ptxt = (CText*)p;
		if(ptxt->pExtra && gl_focus!=ptxt->pExtra){
			gl_focus = (CNode*)ptxt->pExtra;
			gl_mainfocus = (CNode*)ptxt->parentWin->pExtra;
		}
		break;
	}
	tagFocus();
}
void OnChangeFocus(CMssg* pmssg){

    changeFocus();

}

void addComponent(CWin* pwin, void* pdata){//, int wintype){

//	 CData* pdata = newCData(pobj, wintype);
	

	 pwin->pchild_vec->push_back(pdata, pwin->pchild_vec);

	 
}

void drawWin(CWin* self){

	 CDC *pDC = (AfxGetApp()->m_pMainWnd)->GetDC();
	 pDC->Rectangle(self->prec->x, self->prec->y, self->prec->x+self->prec->w, self->prec->y+self->prec->l);
     pDC->TextOut(self->prec->x+DSP_GAP, self->prec->y+DSP_GAP, self->caption );
	 (AfxGetApp()->m_pMainWnd)->ReleaseDC(pDC);
}
//////////////////////////////////////////////////////////////CButtn///////////////////////////////////////////////////////
CButtn* newCButtn(CWin* parentWin, CRect1* prec, char* caption){
	int i;
	CButtn* self = (CButtn*)malloc(sizeof(CButtn));
	self->prec = prec;
    self->caption = caption;
	self->parentWin = parentWin;

	for(i=0; i<MSSG_NUM; i++){
		self->winproc[i] = NULL;
	}
	self->winproc[WM_SHOW1] = OnShow;    //default proc
	self->winproc[WM_CHANGEFOCUS1] = OnChangeFocus;//focus;
	self->winproc[WM_CLOSE1] = OnClose;
	self->winproc[WM_CLICK1] = OnButtnClick;//for test
	collectPointer(self, CBUTTN);
	if(parentWin){
		addComponent(parentWin, self);//, CBUTTN);
	}
//	self->drawButtn = drawButtn;
	
	
	return self;
}


void drawButtn(CButtn* self){

	 CDC *pDC = (AfxGetApp()->m_pMainWnd)->GetDC();
	 pDC->Rectangle(self->prec->x, self->prec->y, self->prec->x+self->prec->w, self->prec->y+self->prec->l);
     pDC->TextOut(self->prec->x+DSP_GAP, self->prec->y+DSP_GAP, self->caption );
	 (AfxGetApp()->m_pMainWnd)->ReleaseDC(pDC);
}


//////////////////////////////////////////////////////////////CText///////////////////////////////////////////////////////
CText* newCText(CWin* parentWin, CRect1* prec, char* caption, int font_x, int font_y){
	int i=0;
	CText* self = (CText*)malloc(sizeof(CText));
	self->parentWin = parentWin;
	self->prec = prec;
	self->caption = caption;
	self->font_x = font_x;
	self->font_y = font_y;
	self->pformatVec = newCVector();
	self->curPos = 0;
	self->endPos = 0;
	self->dspChBgn = 0;
	self->dspChEnd = 0;
	self->dspLnBgn = 0;	
	self->text[0] = '\0';
	
	for(i=0; i<MSSG_NUM; i++){
		self->winproc[i] = NULL;
	}
	self->winproc[WM_CHANGEFOCUS1]=OnChangeFocus;
	self->winproc[WM_KEYDOWN1]=OnKeyDown;
    self->winproc[WM_DBKEYDOWN1]=OnDbKeyDown;
	self->winproc[WM_TRIKEYDOWN1]=OnDbKeyDown;
	collectPointer(self, CTEXT);
	if(parentWin){
		addComponent(parentWin, self);//, CBUTTN);
	}
	
	return self;
}
void drawText(CText* self){
     

⌨️ 快捷键说明

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