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

📄 listbox.c

📁 MinGUI 可视化程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 /******************************************************************************
*
* Copyright  2006 National ASIC Center, All right Reserved
*
* FILE NAME:			ListBox.c
* PROGRAMMER:			ming.c
* Date of Creation:		2006/08/8
*
* DESCRIPTION: 								
*						
* NOTE:						 		
*
* FUNCTIONS LIST:
* -----------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------
*
* MODIFICATION HISTORY
*     LastModify  2006/09/20
******************************************************************************/
#include "mingui.h"
//---------------------------------------------------------------------------
#define  Default_LeftMargin             3 
#define  Default_LineMargin             4
#define  MarqueeInterval                1000  
//---------------------------------------------------------------------------
typedef struct _ListBox_Item
{ struct _ListBox_Item *next,*prev;
  int  index;
  char *caption;
}TListBoxItem;
typedef void (*TListItemCallback)(HWND,int);

typedef struct t_ListBox
{ int TotalItemCount,CountPerPage,LineMargin,LeftMargin,ItemHeight;
  TListBoxItem *Head,*PageFirst,*Selected;
  TListItemCallback fuc;
  /*--Marquee-------------------------------*/
  HANDLE MarqueeTimer;
  TListBoxItem *MarqueeItem,*NewMarquee;
  int    MarqueePos;
 }TListBox;
//---------------------------------------------------------------------------
static TListBoxItem *GetItemNodeByIndex(HWND,int);
static void ListBox_MarqueeProc(HWND);
static void RepaintSubItem(HWND hWnd,int index);
static void ListBox_DirectSubFocus(HWND hWnd,BOOL UpOrDown);
static HRESULT CALLBACK DefListBoxProc(HWND hWnd,UINT Message,WPARAM WParam,LPARAM LParam);
//---------------------------------------------------------------------------
void ListBoxCreate(HWND hWnd)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  
  memset(m,0,sizeof(TListBox));

  m->fuc=(TListItemCallback)WNDPTR(hWnd)->ExtraLong[0];

  m->LeftMargin=Default_LeftMargin;
  m->LineMargin=Default_LineMargin;
  m->ItemHeight=SYS_FONT_HEIGHT+m->LineMargin;
  m->CountPerPage=(crHeight(hWnd)+SYS_FONT_HEIGHT)/m->ItemHeight;

  m->MarqueeTimer=CreateTimer(hWnd,MarqueeInterval,MarqueeInterval,ListBox_MarqueeProc,false);

  ScrollBar_Initialize(hWnd,0,0,m->CountPerPage,m->CountPerPage);
}
//---------------------------------------------------------------------------
void ListBoxDestroy(HWND hWnd)
{ TListBoxItem *node,*delNode,*head;
  TListBox *m=(TListBox *)WndClsBuf(hWnd);
  if(m)
  { DestroyTimer(m->MarqueeTimer);
	head=m->Head;
    if(head)
	{ node=head;
      do
	  { delNode=node;
        node=node->next;
        FreeMem(delNode->caption);
        FreeMem(delNode);
	  }while(node!=head);
	}
  }
}
//---------------------------------------------------------------------------
void ListBox_SelectedAssign(HWND hWnd,TListBoxItem *newselected)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  if(m->Selected!=newselected)
  { bool bNeedMarquee=false;
	if(newselected)
	{ int textwidth=strlen(newselected->caption)*SYS_FONT_WIDTH;
      int clipwidth=crWidth(hWnd)-m->LeftMargin;
	  if(textwidth>clipwidth) bNeedMarquee=true;
	}
	if(bNeedMarquee)
	{ if(WndGetAttr(hWnd,WS_FOCUS))EnableTimer(m->MarqueeTimer,true);
	  m->NewMarquee=newselected;
	}
	else
	{ m->NewMarquee=NULL;
	}
	m->Selected=newselected;	
	CMD_NotifyParent(hWnd,CM_CHANGED); 
  }
}
//---------------------------------------------------------------------------
void ListBox_MarqueeProc(HWND hWnd)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  if(m->MarqueeItem==m->NewMarquee)
  { if(m->MarqueeItem)
    { BYTE *byteCaption=(BYTE *)m->MarqueeItem->caption;
      if(byteCaption[m->MarqueePos]>0xA0) m->MarqueePos+=2;
	  else if(byteCaption[m->MarqueePos]>0)m->MarqueePos+=1;
      if(!byteCaption[m->MarqueePos]) m->MarqueePos=0;
	  RepaintSubItem(hWnd,m->MarqueeItem->index);
    }
    else 
	{ EnableTimer(m->MarqueeTimer,false);
	}
  }
  else
  { if(m->MarqueeItem && m->MarqueePos)
    { /*if need reset last marquee then just do it*/
	  m->MarqueePos=0;
	  RepaintSubItem(hWnd,m->MarqueeItem->index);
    }
    m->MarqueePos=0;
    m->MarqueeItem=m->NewMarquee;
  }
}
//---------------------------------------------------------------------------
void ListBoxPageScroll(HWND hWnd,int newtop,int step)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  if(m->PageFirst && newtop!=m->PageFirst->index && m->CountPerPage>1)
  { TListBoxItem *item=m->Head;
    int i;
	for(i=0;i<newtop;i++)item=item->next;
    m->PageFirst=item;
	
	Invalidate(hWnd);
	ScrollBar_Synchronize(hWnd,m->PageFirst->index);
  }
  else
  {  ListBox_DirectSubFocus(hWnd,(BOOL)(step<0));
  }
}
//---------------------------------------------------------------------------
void ListBoxChangeSubFocus(HWND hWnd,int newselect)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  int oldselelect=(m->Selected)?m->Selected->index:-1;
  if(newselect!=oldselelect && m->TotalItemCount>0)
  { int new_pageoffset,old_pageoffset;
	int page_first=m->PageFirst->index;
    int page_bottom=page_first+m->CountPerPage-1;
	if(page_bottom>=m->TotalItemCount)page_bottom=m->TotalItemCount-1;
	new_pageoffset=(newselect>=page_first && newselect<=page_bottom)?newselect-page_first:-1;
	old_pageoffset=(oldselelect>=page_first && oldselelect<=page_bottom)?oldselelect-page_first:-1;

    if(old_pageoffset>=0 || new_pageoffset>=0)
    {   HDC dc=GetClientDC(hWnd);
        int areaHeight,areaWidth;

        SetPenLogic(dc,PL_XOR);
        SetColor(dc,CL_SOLID);
        areaWidth=crWidth(hWnd);
        areaHeight=m->ItemHeight;
        
        if( WndGetAttr(hWnd,WS_FOCUS) )
		{
          if(old_pageoffset>=0 && new_pageoffset<0)
		  {  FillRect(dc,0,old_pageoffset*areaHeight,areaWidth,areaHeight);
		  }
          else if(new_pageoffset>=0 && old_pageoffset<0)
		  { FillRect(dc,0,new_pageoffset*areaHeight,areaWidth,areaHeight);
		  }
          else if(new_pageoffset-old_pageoffset==1)
		  { FillRect(dc,0,old_pageoffset*areaHeight,areaWidth,areaHeight<<1);
		  }
          else if(old_pageoffset-new_pageoffset==1)
		  { FillRect(dc,0,new_pageoffset*areaHeight,areaWidth,areaHeight<<1);
		  }
          else
		  { FillRect(dc,0,old_pageoffset*areaHeight,areaWidth,areaHeight);
            FillRect(dc,0,new_pageoffset*areaHeight,areaWidth,areaHeight);
		  }
		}
		else if(m->CountPerPage>1) /*单行框不需要虚线反显*/
		{ if(old_pageoffset>=0)
		  { DrawDashedRect(dc,0,old_pageoffset*areaHeight,areaWidth,areaHeight);
		  }
          if(new_pageoffset>=0)
		  { DrawDashedRect(dc,0,new_pageoffset*areaHeight,areaWidth,areaHeight);
		  }

		}
        ReleaseDC(dc);
    }
	ListBox_SelectedAssign(hWnd,GetItemNodeByIndex(hWnd,newselect));
  }
}
 
//---------------------------------------------------------------------------
void RepaintSubItem(HWND hWnd,int index)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  TListBoxItem *mn=m->PageFirst;
  if(mn && index>=mn->index)
  { int page_bottom=mn->index+m->CountPerPage-1;
	if(page_bottom>=m->TotalItemCount)page_bottom=m->TotalItemCount-1;
    if(index<=page_bottom)
	{ HDC dc;
	  int j,offset=index-mn->index;
	  int ItemWidth=crWidth(hWnd);
      int ItemHeight=m->ItemHeight;
	  for(j=0;j<offset;j++)
	  { mn=mn->next;
	  }
	  dc=GetClientDC(hWnd);
	  GroupOn(dc);
	  j = offset*ItemHeight;
      EraseBackground(dc, 0,j,ItemWidth,ItemHeight);
	  if(mn->caption && *mn->caption)
	  { char *strCaption=(mn==m->MarqueeItem)?mn->caption+m->MarqueePos:mn->caption;
		TextOut(dc,m->LeftMargin,j+(m->LineMargin>>1),strCaption);
	  }
	  if(mn==m->Selected)
	  { SetPenLogic(dc,PL_XOR);
        SetColor(dc,CL_SOLID);
		if(WndGetAttr(hWnd,WS_FOCUS))
           FillRect(dc,0,j,ItemWidth,ItemHeight);
		else if(m->CountPerPage>1) /*单行框不需要虚线反显*/
           DrawDashedRect(dc,0,j,ItemWidth,ItemHeight);
	  }
	  GroupOff(dc,0,j,ItemWidth,ItemHeight);
      ReleaseDC(dc);
	}
  }	  
 
}
//---------------------------------------------------------------------------
void ListBox_DirectSubFocus(HWND hWnd,int UpOrDown)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  TListBoxItem *ItemSelected=m->Selected;
  BOOL PageScolled=false;
  if(!ItemSelected)
  { if(!m->PageFirst)return;
	 else ItemSelected=m->PageFirst;
  }
  if(UpOrDown)
  {  if(ItemSelected!=m->Head)
     { if(ItemSelected==m->PageFirst)
       { PageScolled=true;
         m->PageFirst=m->PageFirst->prev;
       }
       ItemSelected=ItemSelected->prev;
     }
  }
  else
  {  if(ItemSelected->next!=m->Head)
     { if(ItemSelected->index==m->PageFirst->index+m->CountPerPage-1)
       { PageScolled=true;
         m->PageFirst=m->PageFirst->next;
       }
       ItemSelected=ItemSelected->next;
     }
  }
  
  if(ItemSelected!=m->Selected)
  { if(PageScolled)
    { ListBox_SelectedAssign(hWnd,ItemSelected);
      Invalidate(hWnd);
	  if(WndGetAttr(hWnd,WS_VSCROLL|WS_BORDER)==(WS_VSCROLL|WS_BORDER))
	  {  ScrollBar_Synchronize(hWnd,m->PageFirst->index);
	  }
    }
    else
    { ListBoxChangeSubFocus(hWnd,ItemSelected->index);
    }
  }
}
//---------------------------------------------------------------------------
void ListBoxDealPenEvent(HWND hWnd,DWORD Message,int yPos)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  if(m->TotalItemCount>0 && m->ItemHeight>0)
  {  int oldselect=(m->Selected)?m->Selected->index:-1;
	 int newselect=m->PageFirst->index+ ( yPos - WNDPTR(hWnd)->ClientRect.top ) / m->ItemHeight;
	 if(newselect>=m->TotalItemCount) newselect=-1;

     if(newselect !=oldselect)
	 { ListBoxChangeSubFocus(hWnd,newselect);
	 }
	 if(Message==WM_LBUTTONUP && newselect>=0)
	 { if(m->fuc) m->fuc(hWnd,newselect);
	 }
  }
}
//---------------------------------------------------------------------------
void ListBoxRepaint(HWND hWnd)
{ TListBox *m=(TListBox *)WndClsBuf(hWnd);
  TListBoxItem *mn=m->PageFirst;
  HDC dc=BeginPaint(hWnd);
  int clientwidth=crWidth(hWnd);
 
  if(mn)
  { int offsetY=0;
    int ItemHeight=m->ItemHeight;
	int textLeft=m->LeftMargin;
	int textwidth=clientwidth-m->LeftMargin;
	int LineMarginTop=m->LineMargin>>1;
	int i,page_bottom=mn->index+m->CountPerPage-1;
	if(page_bottom>=m->TotalItemCount)page_bottom=m->TotalItemCount-1;
	for(i=mn->index;i<=page_bottom;i++)
	{ if(mn->caption!=NULL && *mn->caption)
	  { TextOut(dc,textLeft,LineMarginTop+offsetY,mn->caption);
	  }

      if(mn==m->Selected)
	  { SetPenLogic(dc,PL_XOR);
        SetColor(dc,CL_SOLID);
        if(WndGetAttr(hWnd,WS_FOCUS))
          FillRect(dc,0,offsetY,clientwidth,ItemHeight);
		else if(m->CountPerPage>1) /*单行框不需要虚线反显*/
		  DrawDashedRect(dc,0,offsetY,clientwidth,ItemHeight);
        SetPenLogic(dc,PL_REPLACE);
        SetColor(dc,CL_BTNTEXT);
	  }

      offsetY+=ItemHeight;
      mn=mn->next;
    }
  }
  
  EndPaint(hWnd);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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