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

📄 tview.cpp

📁 俄罗斯人开发的大名鼎鼎的Pocket Pc 阅读器haaliread的源代码,visual c
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#endif
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CTView message handlers
BOOL CTView::PreCreateWindow(CREATESTRUCT& cs)
{
  if (!CWnd::PreCreateWindow(cs))
    return FALSE;

  cs.style &= ~WS_BORDER;
  cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
    NULL, NULL, NULL);

  return TRUE;
}

struct FormatterGetLine: public CTView::IGetLine {
  TextFormatter   *m_tf;
  int		  m_page;
  int		  m_off;
  int		  m_len;

  FormatterGetLine(TextFormatter *tf,int page) : m_tf(tf), m_page(page), m_off(0) {
    for (int i=0;i<page;++i)
      m_off+=tf->PageLength(i);
    m_len=tf->PageLength(page);
  }
  int		  Length() { return m_len; }
  const Line&	  At(int i) { return m_tf->GetLine(m_off+i); }
};

static inline bool Overlap(const RECT& r1,const RECT& r2) {
  return !(
      r1.right<=r2.left ||
      r1.left>=r2.right ||
      r1.bottom<=r2.top ||
      r1.top>=r2.bottom
  );
}

void CTView::OnPaint()
{
  RECT	    update_rect;
  if (!GetUpdateRect(&update_rect))
    return;
  System2Window(update_rect,m_Window.cli);

  PAINTSTRUCT ps;
  {
    // do a quick check for bookmarks
    bool    checkbmk=false;
    if (m_Window.showprogress() && m_textfile->bmk().BookmarksInRange(
			  m_formatter->Top(),m_formatter->Bottom()))
      checkbmk=true;
    // draw stuff
    CFDC	    fdc(m_hWnd,&ps);
    RECT	    col;
    col.left=col.top=0;
    col.right=m_Window.width;
    col.bottom=m_Window.rheight;
    if (m_Window.showprogress())
      col.bottom-=m_Window.progress_height;
    for (int column=0;column<m_Window.columns;++column) {
      if (Overlap(col,update_rect)) {
	FormatterGetLine	  gl(m_formatter.get(),column);
	PaintColumn(fdc,update_rect,col,m_Window.cli,
	  &gl,m_TextDisp.margin_width,checkbmk);
      }
      col.left+=m_Window.width;
      col.right+=m_Window.width;
    }
    if (m_Window.showprogress()) {
      col.left=0; col.top=m_Window.rheight-m_Window.progress_height;
      col.right=m_Window.rwidth; col.bottom=m_Window.rheight;
      if (Overlap(col,update_rect)) {
	UpdateWindowPD();
	PaintProgressBar(fdc,col,m_Window.cli);
      }
    }
    if (m_UI.visible && Overlap(m_UI.rc,update_rect))
      PaintUserInput(fdc,m_UI.rc,m_Window.cli,Unicode::ToWCbuf(m_UI.inp));
    if (m_BP.visible && Overlap(m_BP.rc,update_rect))
      PaintBookmarkPopup(fdc,m_BP.rc,m_Window.cli);
  }
}

void  CTView::RedrawProgressBar() {
  if (!m_Window.showprogress())
    return;

  CFDC	fdc(m_hWnd);
  RECT	col;
  col.left=0; col.top=m_Window.rheight-m_Window.progress_height;
  col.right=m_Window.rwidth; col.bottom=m_Window.rheight;
  UpdateWindowPD();
  PaintProgressBar(fdc,col,m_Window.cli);
}

void CTView::PaintSingleLine(int column,int line,COLORREF underline) {
  if (column<0 || column>=m_Window.columns)
    return;

  if (line<0 || line>=m_formatter->PageLength(column))
    return;

  FormatterGetLine	  gl(m_formatter.get(),column);

  RECT	  line_rect;

  line_rect.left=m_Window.width*column;
  line_rect.right=line_rect.left+m_Window.width;

  line_rect.top=0;

  for (int i=0;i<line;++i)
    line_rect.top+=gl.At(i).height;

  const Line&	line_data=gl.At(line);

  line_rect.bottom=line_rect.top+line_data.height;

  RECT	  cli;
  GetClientRect(&cli);

  CFDC	  dc(m_hWnd);
  dc.SetTextColor(C_NORM);
  dc.SetBkColor(v_C_BG());

  RECT	  tmp=line_rect;
  PaintLine(dc,cli,tmp,m_TextDisp.margin_width,line_data);

  dc.SetColor(C_TOCBM);

  HighlightBookmarks(dc,cli,line_rect.left,m_TextDisp.margin_width,
    line_rect.top,line_data,line_data.pos,gl.At(line+1).pos);

  if (underline!=CLR_DEFAULT) {
    tmp=line_rect;
    tmp.top=tmp.bottom=tmp.bottom-1;
    dc.SetColor(underline);
    TDrawLine(dc.DC(),cli,tmp);
  }

  // if this is the last line in column, then paint till column bottom
  if (line==gl.Length()-1) {
    line_rect.top=line_rect.bottom;
    line_rect.bottom=m_Window.rheight;
    TDrawText(dc.DC(),line_rect.left,line_rect.top,cli,line_rect,NULL,0,NULL);
    if (m_Window.showprogress()) {
      tmp.left=0; tmp.top=m_Window.rheight-m_Window.progress_height;
      tmp.right=m_Window.rwidth; tmp.bottom=m_Window.rheight;
      UpdateWindowPD();
      PaintProgressBar(dc,tmp,m_Window.cli);
    }
  }
}

void CTView::PaintSbItem(CFDC& dc,const wchar_t *text,int len,const RECT& rc,
			const RECT& cli,int& pb_width)
{
  if (len<0)
    len=wcslen(text);

  RECT	      ii;
  SIZE	      sz;
  int	      nch=0;

  dc.GetTextExtent(text,len,rc.right-rc.left,nch,NULL,sz);
  if (pb_width>0)
    sz.cx+=3; // XXX padding
  ii.top=rc.top-2;
  ii.bottom=rc.bottom;
  ii.left=rc.right-sz.cx-pb_width-1;
  ii.right=ii.left+sz.cx;
  TDrawText(dc.DC(),ii.left,ii.top,cli,ii,text,len,NULL,ETO_OPAQUE);
  pb_width+=sz.cx;
}

bool CTView::UpdateWindowPD() {
  bool	  upd=false;

  // calculate current position
  int	  top=m_textfile->GetTotalLength(m_formatter->DocId());
  int	  cur=m_formatter->DocId()<0 ? m_textfile->GetPStart(m_formatter->DocId(),m_formatter->Top().para) :
				       m_textfile->AbsPos(m_formatter->Bottom());
  m_Window.pd.cc=cur;
  if (m_formatter->DocId()>=0)
    cur=(cur+1)>>11;
  else
    cur=-(top ? MulDivS(100,cur,top) : 100) - 1;

  if (cur!=m_Window.pd.pos) {
    if (m_Window.pb.position)
      upd=true;
    m_Window.pd.pos=cur;
  }

  if (top!=m_Window.pd.top) {
    if (m_Window.pb.top && m_formatter->DocId()>=0)
      upd=true;
    m_Window.pd.top=top;
  }

  // find current chapter title
  if (m_Window.pb.chapter) {
    int idx=m_textfile->bmk().BFind(m_formatter->Top(),Bookmarks::SPREVCH);
    if (idx<m_textfile->bmk().GetSize() &&
	m_textfile->bmk().Ref(idx).docid==m_formatter->Top().docid)
    {
      CString cur=m_textfile->bmk().Text(idx,m_textfile.get());
      if (cur!=m_Window.pd.title) {
	upd=true;
	m_Window.pd.title=cur;
      }
    } else if (!m_Window.pd.title.IsEmpty()) {
      m_Window.pd.title.Empty();
      upd=true;
    }
  }

  cur=m_AS.delay/1000;
  if (cur!=m_Window.pd.as) {
    if (m_Window.pb.as_delay)
      upd=true;
    m_Window.pd.as=cur;
  }

  SYSTEMTIME	stm;
  ::GetLocalTime(&stm);
  cur=(stm.wHour<<8) | stm.wMinute;
  if (cur!=m_Window.pd.tm) {
    if (m_Window.pb.time)
      upd=true;
    m_Window.pd.tm=cur;
  }

#ifdef _WIN32_WCE
  SYSTEM_POWER_STATUS_EX  pws;
  BOOL		    ok=GetSystemPowerStatusEx(&pws,FALSE);
#else
  SYSTEM_POWER_STATUS	    pws;
  BOOL		    ok=GetSystemPowerStatus(&pws);
#endif
  if (ok && pws.BatteryLifePercent>=0 && pws.BatteryLifePercent<=100) {
    if (pws.ACLineStatus==1)
      cur=101;
    else
      cur=pws.BatteryLifePercent;
  } else
    cur=-1;

  if (cur!=m_Window.pd.bat) {
    if (m_Window.pb.battery)
      upd=true;
    m_Window.pd.bat=cur;
  }

  return upd;
}

void CTView::StartWindowPDTimer() {
  if (m_Window.showprogress() && (m_Window.pb.battery || m_Window.pb.time))
    m_Window.pd_timer=SetTimer(TM_PD,2000,NULL);
  else {
    KillTimer(m_Window.pd_timer);
    m_Window.pd_timer=0;
  }
}

void CTView::UpdateProgressBar() {
  if (UpdateWindowPD()) {
    CFDC	fdc(m_hWnd);
    RECT	col;
    col.left=0; col.top=m_Window.rheight-m_Window.progress_height;
    col.right=m_Window.rwidth; col.bottom=m_Window.rheight;
    PaintProgressBar(fdc,col,m_Window.cli);
  }
}

void CTView::PaintProgressBar(CFDC& dc,const RECT& rc,const RECT& cli) {
  RECT	      col;
  wchar_t     buf[128];
  int	      fonthdpi = MulDivS(PROGRESS_F, GetDeviceCaps(dc.DC(), LOGPIXELSY), 72);
  dc.SelectFontAbs(fonthdpi,CFDC::FORCENORMALWEIGHT|CFDC::FORCETAHOMA);
  ::SetBkMode(dc.DC(),OPAQUE);

  // clear area
  dc.SetBkColor(v_C_BG());
  TDrawText(dc.DC(),rc.left,rc.top,m_Window.cli,rc,NULL,0,NULL);
  m_Window.pb_width=0;

  if (m_Window.pb.battery && m_Window.pd.bat>=0) {
    if (m_Window.pd.bat>100)
      wcscpy(buf,L"AC");
    else
      swprintf(buf,L"%d%%",m_Window.pd.bat);
    PaintSbItem(dc,buf,-1,rc,m_Window.cli,m_Window.pb_width);
  }

  if (m_Window.pb.time) {
    swprintf(buf,L"%02d:%02d",m_Window.pd.tm>>8,m_Window.pd.tm&0xff);
    PaintSbItem(dc,buf,-1,rc,m_Window.cli,m_Window.pb_width);
  }

  if (m_Window.pb.as_delay && m_AS.timer) {
    swprintf(buf,L"%d",m_Window.pd.as);
    PaintSbItem(dc,buf,-1,rc,m_Window.cli,m_Window.pb_width);
  }

  // draw vpage number for normal docs, or a back button for dictionary
  if (m_Window.pb.position || (m_Window.pb.top && m_Window.pd.pos>=0)) {
    if (m_Window.pd.pos>=0) {
      if (m_Window.pb.top)
	swprintf(buf,L"%d/%d",m_Window.pd.pos,m_Window.pd.top>>11);
      else
	swprintf(buf,L"%d",m_Window.pd.pos);
    } else
      swprintf(buf,L"%d%%",-m_Window.pd.pos-1);
    PaintSbItem(dc,buf,-1,rc,m_Window.cli,m_Window.pb_width);
  }

  
  if (m_Window.pb.chapter && !m_Window.pd.title.IsEmpty()) {
    // draw chapter title
    RECT  rc2=rc;
    rc2.top-=2;
    rc2.left+=3; // XXX padding
    rc2.right-=m_Window.pb_width+2; // XXX padding
    SIZE    sz;
    int	    nch=0;
    CString tmp(m_Window.pd.title);
    dc.SelectFontAbs(fonthdpi,CFDC::FORCENORMALWEIGHT|CFDC::FORCETAHOMA,true);
    dc.GetTextExtent(tmp,tmp.GetLength(),rc2.right-rc2.left,nch,NULL,sz);
    if (nch<tmp.GetLength()) { // doesnt fit
      int     nch2;
      wchar_t ch=0x2026;
      dc.GetTextExtent(&ch,1,8192,nch2,NULL,sz);
      dc.GetTextExtent(tmp,tmp.GetLength(),rc2.right-rc2.left-sz.cx,nch,NULL,sz);
      if (nch>0) {
	tmp.Delete(nch,tmp.GetLength()-nch);
	tmp+=ch;
      } else
	tmp.Empty();
    }
    dc.SelectFontAbs(fonthdpi,CFDC::FORCENORMALWEIGHT|CFDC::FORCETAHOMA);
    TDrawText(dc.DC(),rc2.left,rc2.top,cli,rc2,tmp,tmp.GetLength(),NULL,ETO_OPAQUE|ETO_CLIPPED);
  } else {
    // draw position bar
    RECT  rc2=rc;
    rc2.top += 1 + (m_Window.progress_height - 5) / 2;

    int	  bw=rc2.right-rc2.left-2*PROGRESS_M-2*PROGRESS_A-m_Window.pb_width;
    int	  pos=m_Window.pd.top ? MulDivS(bw,m_Window.pd.cc,m_Window.pd.top) : bw;
    col.left=rc2.left+PROGRESS_M+PROGRESS_A; col.top=rc2.top+1;
    col.right=col.left+pos; col.bottom=col.top;
    dc.SetColor(C_GAUGE);
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.top+=2;
    col.bottom=col.top;
    TDrawLine(dc.DC(),m_Window.cli,col);
    // draw a thin black line
    col.left=rc2.left+PROGRESS_M; col.top=col.bottom=rc2.top+2;
    col.right=rc2.right-PROGRESS_M-m_Window.pb_width;
    dc.SetColor(C_TOCL0); // XXX
    TDrawLine(dc.DC(),m_Window.cli,col);
    // draw arrows
    col.top=rc2.top+1;
    col.bottom=col.top+3;
    col.left=col.right=rc2.left+PROGRESS_M+1;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.left=col.right=rc2.left+PROGRESS_M+4;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.left=col.right=rc2.right-PROGRESS_M-m_Window.pb_width-5;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.left=col.right=rc2.right-PROGRESS_M-m_Window.pb_width-2;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.top=rc2.top;
    col.bottom=col.top+5;
    col.left=col.right=rc2.left+PROGRESS_M+2;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.left=col.right=rc2.left+PROGRESS_M+5;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.left=col.right=rc2.right-PROGRESS_M-m_Window.pb_width-6;
    TDrawLine(dc.DC(),m_Window.cli,col);
    col.left=col.right=rc2.right-PROGRESS_M-m_Window.pb_width-3;
    TDrawLine(dc.DC(),m_Window.cli,col);
    // draw chapter ticks
    if (m_Window.pd.top) {
      Bookmarks& bm=m_textfile->bmk();
      bool  doall=bm.GetSize()<(rc2.right-rc2.left)/3;
      bool  doch=bm.NumTopMarks()<(rc2.right-rc2.left)/3;
      bool  dobm=bm.NumBookmarks()<(rc2.right-rc2.left)/3;
      if (doch||dobm||doall) {
	for (int ii=0;ii<bm.GetSize();++ii) {
	  if (bm.Ref(ii).docid!=m_formatter->DocId())
	    continue;
	  COLORREF	  color=C_TOCL0;
	  col.top=rc2.top;
	  col.bottom=col.top+5;
	  if (bm.Flags(ii)&Bookmarks::BMK) {
	    if (!dobm)
	      continue;
	    color=C_TOCBM;
	  } else if (bm.Level(ii)>0) {
	    if (!doall)
	      continue;
    	    col.top=rc2.top+1;
	    col.bottom=col.top+3;
	  } else if (!doch)
	      continue;
	  col.left=col.right=rc2.left+PROGRESS_M+PROGRESS_A+MulDivS(bw,
	    m_textfile->AbsPos(bm.Ref(ii)),m_Window.pd.top);
	  dc.SetColor(color);
	  TDrawLine(dc.DC(),m_Window.cli,col);
	}
      }
    }
  }
}

void CTView::PaintBookmarkPopup(CFDC& dc,const RECT& rc,const RECT& cli) {
  // bascially it's a rectangle+paintcolumn
  // draw frame first
  POINT	  pt[5];
  pt[0].x=rc.left; pt[0].y=rc.top;
  pt[1].x=rc.right-1; pt[1].y=rc.top;
  pt[2].x=rc.right-1; pt[2].y=rc.bottom-1;
  pt[3].x=rc.left; pt[3].y=rc.bottom-1;
  pt[4]=pt[0];
  dc.SetColor(C_NORM);
  TDrawPolyLine(dc.DC(),cli,pt,5);
  // shrink rc a bit to avoid overwriting frame
  RECT	  nrc=rc;
  nrc.left++; nrc.right--;
  nrc.top++; nrc.bottom--;
  PaintColumn(dc,nrc,nrc,cli,&m_BP,FRAME_SIZE-1,false);
}

void CTView::OnSize(UINT nType, int cx, int cy) {
  CWnd::OnSize(nType, cx, cy);
  if (cx==0 || cy==0) // don't bother with invalid sizes
    return;
  GetClientRect(&m_Window.cli);
  CalcSizes();
}

void CTView::PaintLine(CFDC& dc,const RECT& cli,RECT& line,
		       int margin,const Line& l)
{
  int	  x=margin+l.ispace;
  if (l.flags&Line::image) {
    Image img;
    if (m_textfile->GetImage(l.href,dc.DC(),l.base,l.imageheight,
	m_TextDisp.angle,img))
    {
      // clean left and right margins
      RECT  rma=line;

⌨️ 快捷键说明

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