当前位置:松语文学 > 其他类型 >VC++_6.0程序设计从入门到精通最新章节 > VC++_6.0程序设计从入门到精通TXT下载
错误举报

第 36 章

  ct tagSIZE {

  LONG cx;

  LONG cy;

  } SIZE, *PSIZE;

  通过计算字符串的起始坐标与字符串宽度之和,即可得到后续文本的起始坐标。例如,

  枫叶文学网www.fywxw.com

  第6 章 文本和字体类

  ·153·

  X 轴起始坐标为cx0,如果当前字符串的尺寸信息存储在size 指向的SIZE 结构中,则后续文

  本的起始坐标cx1 为:

  cx1 = cx0 + size.cx;

  (2)确定换行时的文本坐标

  通过计算当前行文本字符的高度与行间隔之和,即可得到换行时文本的起始坐标,上述

  两个数值可通过获取当前字体的信息得到,如果当前字体的信息存储在tm 指向的

  TEXTMETRICS 结构中,则换行时Y 轴上文本的起始坐标cy 为:

  cy = tm.tmHeight + tm.tmExternalLeading;

  3.文本输出

  Windows 程序设计时用得最多的文本输出函数便是Textout,其API 的函数原型如下:

  BOOL TextOut(

  HDC hdc, // DC 句柄

  int nXStart, // 起始点X 坐标

  int nYStart, //起始点Y 坐标

  LPCTSTR lpString, // 输出的字符串

  int cbString // 输出的字符串中字符数目

  );

  通过调用此函数,可以在指定位置输出文本。

  6.4 字体和文本输出实例

  实例6-1:字体和文本输出实例。源代码在光盘中“\06\实例6-1\gundong”目录下。

  本节实现了一个动态字幕的例子。从本例中读者可以学习到动态地改变文本坐标来实现

  实现动态字幕的方法。该示例是基于对话框模式的,通过改变文本的坐标然后进行实时刷新

  来显示字幕,屏幕刷新通过定时器来实现。。

  本例的部分核心源代码如下。

  CGundongDlg::CGundongDlg(CWnd* pParent /*=NULL*/)

  : CDialog(CGundongDlg::IDD, pParent)

  {

  //{{AFX_DATA_INIT(CGundongDlg)

  // NOTE: the ClassWizard will addcommber initialization here

  //}}AFX_DATA_INIT

  // Note that LoadIcon does not require a subsequent DestroyIcon in Win32

  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

  WidthX=200;

  minWidth=10;

  Heighty=15;

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·154·

  maxHeight=200;

  m_str="欢迎使用本程序!";

  TIMER=0;

  m_brush.CreateSolidBrush(RGB(180,240,210)); //改变对话框背景

  m_brush1.CreateSolidBrush(RGB(255,0,0));

  }

  void CGundongDlg::DoDataExchange(CDataExchange* pDX)

  {

  CDialog::DoDataExchange(pDX);

  //{{AFX_DATA_MAP(CGundongDlg)

  // NOTE: the ClassWizard will add DDX and DDV calls here

  //}}AFX_DATA_MAP

  }

  BEGIN_MESSAGE_MAP(CGundongDlg, CDialog)

  //{{AFX_MSG_MAP(CGundongDlg)

  ON_WM_SYSCOMMAND()

  ON_WM_PAINT()

  ON_WM_QUERYDRAGICON()

  ON_WM_TIMER()

  ON_WM_CTLCOLOR()

  ON_WM_DESTROY()

  //}}AFX_MSG_MAP

  END_MESSAGE_MAP()

  /////////////////////////////////////////////////////////////////////////////

  // CGundongDlgcomssage handlers

  BOOL CGundongDlg::OnInitDialog()

  {

  CDialog::OnInitDialog();

  // Add "About..."comnu item to systemcomnu.

  // IDM_ABOUTBOX must be in the system command range.

  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

  ASSERT(IDM_ABOUTBOX < 0xF000);

  CMenu* pSysMenu = GetSystemMenu(FALSE);

  if (pSysMenu != NULL)

  {

  CString strAboutMenu;

  枫叶文学网www.fywxw.com

  第6 章 文本和字体类

  ·155·

  strAboutMenu.LoadString(IDS_ABOUTBOX);

  if (!strAboutMenu.IsEmpty())

  {

  pSysMenu->AppendMenu(MF_SEPARATOR);

  pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

  }

  }

  // Set the icon for this dialog. The frcomwork does this automatically

  // when the application’s main window is not a dialog

  SetIcon(m_hIcon, TRUE); // Set big icon

  SetIcon(m_hIcon, FALSE); // Set small icon

  // TODO: Add extra initialization here

  TIMER=SetTcomr(ID_TIMER1,150,NULL);

  return TRUE; // return TRUE unless you set the focus to a control

  }

  void CGundongDlg::OnSysCommand(UINT nID, LPARAM lParam)

  {

  if ((nID & 0xFFF0) == IDM_ABOUTBOX)

  {

  CAboutDlg dlgAbout;

  dlgAbout.DoModal();

  }

  else

  {

  CDialog::OnSysCommand(nID, lParam);

  }

  }

  // If you add a minimize button to your dialog, you will need the code below

  // to draw the icon. For MFC applications using the doccomnt/view model,

  // this is automatically done for you by the frcomwork.

  void CGundongDlg::OnPaint()

  {

  if (IsIconic())

  {

  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle

  int cxIcon = GetSystemMetrics(SM_CXICON);

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·156·

  int cyIcon = GetSystemMetrics(SM_CYICON);

  CRect rect;

  GetClientRect(&rect);

  int x = (rect.Width() - cxIcon + 1) / 2;

  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon

  dc.DrawIcon(x, y, m_hIcon);

  }

  else

  {

  CPaintDC dc(this); // device context for painting

  dc.SetTextColor(RGB (180,240,210));

  dc.SetBkMode(TRANSPARENT); //设置背景为透明!

  CRect rect;

  rect.left=150;

  rect.right=350;

  rect.top=10;

  rect.bottom=40;

  dc.Rectangle(&rect);

  dc.FillRect(&rect,&m_brush1);

  rect.left=10;

  rect.right=135;

  rect.top=40;

  rect.bottom=200;

  dc.Rectangle(&rect);

  dc.FillRect(&rect,&m_brush1);

  dc.TextOut(WidthX,15,m_str);

  dc.TextOut(15,Heighty,m_str);

  // CDialog::OnPaint();

  }

  }

  // The system calls this to obtain the cursor to display while the user drags

  // the minimized window.

  HCURSOR CGundongDlg::OnQueryDragIcon()

  {

  return (HCURSOR) m_hIcon;

  }

  void CGundongDlg::OnTcomr(UINT nIDEvent)

  {

  枫叶文学网www.fywxw.com

  第6 章 文本和字体类

  ·157·

  // TODO: Add yourcomssage handler code here and/or call default

  DrawV();

  DrawH();

  CDialog::OnTcomr(nIDEvent);

  }

  void CGundongDlg::DrawV() //竖直方向滚动函数

  {

  CRect rect; //每次重画区域大小

  rect.left=10;

  rect.right=m_str.GetLength()+rect.left+120;

  CFont * font=GetFont();

  LOGFONT logFont;

  font->GetLogFont(&logFont);

  rect.top=Heighty;

  rect.bottom=rect.top+logFont.lfHeight+40;

  InvalidateRect(&rect);

  Heighty+=logFont.lfHeight+18; //每步向下移动距离

  if(Heighty>=maxHeight) Heighty=15; //回到起始位置

  UpdateWindow();

  }

  void CGundongDlg::DrawH() //水平向滚动函数

  {

  CRect rect; //每次重画区域大小

  rect.top=15;

  CFont * font=GetFont();

  LOGFONT logFont;

  font->GetLogFont(&logFont);

  rect.bottom=rect.top+logFont.lfHeight+80;

  rect.left=WidthX-m_str.GetLength()-10;

  rect.right=rect.left+m_str.GetLength()+150;

  InvalidateRect(&rect);

  if(WidthX<10) WidthX=350; //回到起始位置

  WidthX=WidthX-6; //每步向左移动距离

  UpdateWindow();

  }

  HBRUSH CGundongDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

  {

  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

  // TODO: Change any attributes of the DC here

  return m_brush; //改变对话框背景颜色

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·158·

  // return hbr;

  }

  void CGundongDlg::OnDestroy()

  {

  CDialog::OnDestroy();

  // TODO: Add yourcomssage handler code here

  if(TIMER!=0)

  KillTcomr(TIMER);

  }

  运行结果如图6-2 所示。

  图6-2 “动态字幕”示例运行结果

  技巧:制作3D 空心字

  有时在编程实践中需要输出一些特效文字,比如3D 空心文字。要在Visual C++程序中输

  出3D 空心效果的文字,可以先输入3D 文字然后建立一个路径对象,向路径对象输出该文

  字,之后用当前画刷填充区域内部并用当前画笔勾画路径的轮廓就可达到此目的。下面通

  过一个实际的示例来说明具体的实现方法。

  实例6-2:字体和文本输出实例。源代码在光盘中“\06\实例6-2\HollowFont”目录下。

  下面的例子是基于SDI 结构的,其中核心源代码如下:

  CHollowFontView::CHollowFontView()

  {

  LOGFONT lf;

  lf.lfHeight = -180; //字体字符的高度

  lf.lfWeight = 0; //字符平均宽度

  lf.lfEscapcomnt =0;

  lf.lfOrientation=0; //字符角度

  lf.lfWeight=FW_HEAVY; //字符的粗细度

  lf.lfItalic = FALSE; //倾斜

  枫叶文学网www.fywxw.com

  第6 章 文本和字体类

  ·159·

  lf.lfUnderline = FALSE; //下划线

  lf.lfStrikeOut = FALSE; //删除线

  lf.lfCharSet = GB2312_CHARSET; //中文字符集

  lf.lfOutPrecision = OUT_STROKE_PRECIS; //字体输出结果和要求的匹配程度

  lf.lfClipPrecision = CLIP_STROKE_PRECIS; //如何裁剪落于裁剪区之外的字符

  lf.lfQuality = DRAFT_QUALITY; //字体属xìng匹配的精确程度

  lf.lfPitchAndFamily = VARIABLE_PITCH|FF_MODERN;//字体间距和字体族

  strcpy(lf.lfFaceNcom,"楷体_GB2312"); //楷体

  m_font.CreateFontIndirect(&lf);

  m_sText=_T("空心汉字");

  }

  void CHollowFontView::OnDraw(CDC* pDC)

  {

  CHollowFontDoc* pDoc = GetDoccomnt();

  ASSERT_VALID(pDoc);

  // TODO: add draw code for native data here

  if(m_font.GetSafeHandle()!=NULL) //如果成功建立字体

  {

  CFont *pOldFont = (CFont *)pDC->SelectObject(&m_font);

  pDC->SetBkMode(TRANSPARENT);

  int cx = 100, cy = 100; //文本输出位置

  CString sTemp = m_sText;

  cx += 3;

  cy += 3;

  pDC->SetTextColor(GetSysColor(COLOR_3DDKSHADOW)); //以下先输出突出的3D 文本

  pDC->TextOut(cx+2,cy-2,sTemp);

  pDC->TextOut(cx+2,cy+2,sTemp);

  pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));

  pDC->TextOut(cx+1,cy-2,sTemp);

  pDC->TextOut(cx-2,cy+1,sTemp);

  pDC->TextOut(cx-2,cy-2,sTemp);

  pDC->SetTextColor(GetSysColor(COLOR_3DSHADOW));

  pDC->TextOut(cx-1,cy+1,sTemp);

  pDC->TextOut(cx+1,cy-1,sTemp);

  pDC->TextOut(cx+1,cy+1,sTemp);

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·160·

  pDC->SetTextColor(GetSysColor(COLOR_3DLIGHT));

  pDC->TextOut(cx,cy-1,sTemp);

  pDC->TextOut(cx-1,cy,sTemp);

  pDC->TextOut(cx-1,cy-1,sTemp);

  //然后通过路径对象将以上要输出的文本变成空心

   //向路径输出“汉字”

  pDC->BeginPath();

  pDC->TextOut(cx,cy,sTemp,8);

  pDC->EndPath();

  //填充路径

  pDC->SetPolyFillMode(WINDING); //设置填充模式

  pDC->StrokeAndFillPath();//绘制路径外观

  pDC->SelectObject(pOldFont);

  }

  }

  函数pDC->StrokeAndFillPath 用于先封闭所有的开放路径,然后用当前画刷和

  松语文学免费小说阅读_www.16sy.com