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

📄 ch2p2_text.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 CPP
字号:
/*
#############################################################################

  Ch2p2_Text.cpp: a program that uses the Windows GDI to output text
  using different colors, fonts, and functions.

  Note that this program is exactly the same as Ch2p1_Shapes, except the
  PaintWindow function is different.  
  
#############################################################################
*/

// include files ////////////////////////////////////////////////////////////

#include <windows.h> // needed for windows
#include <stdio.h>   // for sprintf

// global variables /////////////////////////////////////////////////////////

const char *g_strAppName = "Windows GDI Text";   // name of our application
int g_iScreenWidth = 640;                        // screen width, in pixels.
int g_iScreenHeight = 480;                       // screen height, in pixels.

/****************************************************************************

 DrawTextAndMoveYPos: This is a helper function that PaintWindow calls.
 Basically, given a y position and some text, it uses DrawText to render
 the text (with word-wrapping), and adds the height of the text block
 onto the y position.

  Note that ypos is a reference, so our changes to it are not lost.

 ****************************************************************************/
void DrawTextAndMoveYPos(HDC hdc, int &ypos, char *text)
{
  // there are two steps to using DrawText.  First, we know the width we
  // can use, but we don't know how much vertical space our text block needs
  // for that width.  So we make a call to DrawText and tell it to calculate
  // our rectangle.
  RECT rectDrawText; // the rectangle Windows will draw the text in.

  // populate our rect with everything but the bottom.

  rectDrawText.left = 0;
  rectDrawText.right = g_iScreenWidth;
  rectDrawText.top = ypos;
  
  int textheight=0;

  textheight = DrawText(hdc, text, strlen(text), &rectDrawText, 
    DT_CALCRECT | DT_WORDBREAK);

  // extend our window by as much as DrawText says it takes.
  rectDrawText.bottom = rectDrawText.top + textheight;

  // now that we know how much room we need, we can render the text.
  DrawText(hdc, text, strlen(text), &rectDrawText, 
    DT_WORDBREAK);

  ypos += textheight + 3; // move our cursor down and give it 3 pixels
                          // of extra space.
}
/****************************************************************************

 RandomNumber: returns a random number between iMin and iMax.

 ****************************************************************************/
int RandomNumber(int iMin, int iMax)
{
  return((rand() % (abs(iMax-iMin)+1))+iMin);
}

/****************************************************************************

 PaintWindow: called by WindowProc when our window needs painting.  Draws
 200 shapes in various pen and fill styles.

 ****************************************************************************/
void PaintWindow(HDC hdc)
{
  int ypos=0; // the text outputs at this vertical coordinate.

  // set our mapping mode as text.  this means 1 logical unit = 1 pixel.
  SetMapMode(hdc, MM_TEXT);

  // set our text background to transparent.
  int oldbkmode = SetBkMode(hdc, TRANSPARENT);

  char strTextMadeWithGDI[] = 
    "This is text made using the GDI. Press a key to redraw!";

  TextOut(hdc, 0, ypos, strTextMadeWithGDI, strlen(strTextMadeWithGDI));
  
  // move our "cursor" down 20.
  ypos += 20;

  // --------------------------------------------------------------

  char strTextMadeWithDrawText[] =
    "This is a whole bunch of text that really doesn't mean anything in and"
    " of itself, but illustrates how the GDI DrawText function can break"
    " lines apart at word boundries for you.  Size the window to see it!";

  DrawTextAndMoveYPos(hdc, ypos, strTextMadeWithDrawText);
  
  // --------------------------------------------------------------

  // create a 50 pixel tall Times New Roman font!
  HFONT fontTimesNewRoman = CreateFont(
    -25, // height (negative means use character heights
    0, // width (0 means use default)
    0, // escapement (0 means none)
    0, // orientation (0 means none)
    FW_NORMAL, // "boldness" of font
    false, // italic?  true or false
    false, // underline? true or false
    false, // strikeout?  true or false
    ANSI_CHARSET, // desired character set
    OUT_TT_PRECIS, // output precision - use TrueType only
    CLIP_DEFAULT_PRECIS, // clip precision - use default
    PROOF_QUALITY, // proof quality
    DEFAULT_PITCH | FF_DONTCARE, // pitch and family
    "Times New Roman" // name of font face desired
    );

  // select our font
  HFONT oldfont = (HFONT)SelectObject(hdc, fontTimesNewRoman);

  // draw text
  char strTimesNewRomanText[] = "This is text in 25 pixel tall Times New Roman.";

  DrawTextAndMoveYPos(hdc, ypos, strTimesNewRomanText);

  // --------------------------------------------------------------

  int red = RandomNumber(0,255);
  int green = RandomNumber(0,255);
  int blue = RandomNumber(0,255);

  char strColoredText[128];
  sprintf(strColoredText, "This is colored text.  It is colored RGB (%d,%d,%d).",
    red, green, blue);

  COLORREF oldcolor = SetTextColor(hdc, RGB(red,green,blue));
  
  DrawTextAndMoveYPos(hdc, ypos, strColoredText);

  // --------------------------------------------------------------

  char strGreenTextOnBlue[] = "This is centered green text on a blue background.";
  COLORREF oldbackground = SetBkColor(hdc, RGB(0,0,255));
  SetTextColor(hdc, RGB(0,255,0));
  SetBkMode(hdc, OPAQUE);
  
  // draw this text centered! (can't use DrawText for this!)

  // set up alignment
  UINT oldtextalign = SetTextAlign(hdc, TA_CENTER);

  // draw the text
  ExtTextOut(hdc, g_iScreenWidth/2, ypos, 0, NULL, 
    strGreenTextOnBlue, strlen(strGreenTextOnBlue), NULL);
  
  // deselect font object and delete
  SelectObject(hdc, oldfont);
  DeleteObject(fontTimesNewRoman);

  // --------------------------------------------------------------

  // set our text color and background back to whatever it was before.
  SetTextAlign(hdc, oldtextalign);
  SetTextColor(hdc, oldcolor);
  SetBkColor(hdc, oldbackground);
  SetBkMode(hdc, oldbkmode);

}
/****************************************************************************

 WindowProc: Windows calls this function when we dispatch messages.

 ****************************************************************************/
LRESULT CALLBACK WindowProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
  switch(uMsg) {
  
  // we get the WM_CLOSE message when our close (X) box has been clicked.
  // we need to respond to it to make sure our program stops when its window
  // is closed.

  case WM_PAINT:
    {
      PAINTSTRUCT ps;

      // get the DC we're supposed to use from Windows
      BeginPaint(hwnd, &ps);
      HDC hdc = ps.hdc;
      
      // paint our window (function is defined above)
      PaintWindow(hdc);
      
      // tell Windows we're done painting.
      EndPaint(hwnd, &ps);
    }
    // we processed the message, so return 0.
    return(0);

  case WM_CHAR:
    // a key has been hit!  repaint!

    // InvalidateRect tells windows that our window contents have become
    // invalid somehow... Windows will turn around and issue a paint
    // message.  We could have just as easily called PaintWindow here,
    // but this is the somewhat more "Windows" way of doing things.
    InvalidateRect(hwnd, NULL, true); 
    return(0);

  case WM_CLOSE: // our close button has been hit!  quit!
    PostQuitMessage(0);
    return(0);

  case WM_SIZE: // our windows dimensions have changed

    // stash the new width and height in the global variables.  PaintWindow
    // uses these global variables when it draws our window contents.

    g_iScreenWidth  = LOWORD(lParam);  // new width of client area 
    g_iScreenHeight = HIWORD(lParam); // new height of client area

    // break, not return.  We want to fall through this case and let
    // DefWindowProc handle the specifics of sizing the window itself.
    break; 
  }

  // all the other messages, we don't care about, so we let DefWindowProc
  // handle them.
  return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}
 
/****************************************************************************
 
 InitWindow: creates a window class and a window.

 ****************************************************************************/
HWND InitWindow(HINSTANCE hinst, int nCmdShow)
{
  HWND                hwnd;
  WNDCLASSEX          wc;
  
  // set up and register window class
  memset(&wc, 0, sizeof(wc));
  wc.cbSize = sizeof(wc);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = WindowProc; // change this to NULL and crash!
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hinst;
  wc.hIcon = NULL;
  wc.hIconSm = NULL;
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_APPWORKSPACE); // this can be changed for different colors
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "MyCoolWindow";
  RegisterClassEx(&wc);
  
  // create a window that's 640 pixels wide, 480 tall.
  hwnd = CreateWindowEx(0, "MyCoolWindow", g_strAppName,
	    WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, 
      10, 10, g_iScreenWidth, g_iScreenHeight, NULL, NULL, hinst, NULL);
  
  if (!hwnd) {
    ::MessageBox(NULL, "CreateWindow failed!", g_strAppName, MB_ICONSTOP);
    exit(-1);
  }
  
  ShowWindow(hwnd, nCmdShow);
  return(hwnd);
} 

/****************************************************************************

 WinMain: program execution starts here.

 ****************************************************************************/
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  // create a window
 	HWND hwnd = InitWindow(hInstance, nCmdShow);

  // message pump
  while (1) {
    MSG msg;
    if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
    {
      int result = GetMessage(&msg, NULL, 0, 0);
      if (!result) return(msg.wParam);

      TranslateMessage(&msg); 
      DispatchMessage(&msg);
    }
  }

  // we'll never get here, but the compiler will complain if we don't
  // have this line.
  return 0;
}

⌨️ 快捷键说明

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