home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_17 / CodePrint / progview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  9.9 KB  |  446 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : progview.cpp                                                         //
  10. //  Description: KProgramPageCanvas window                                           //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define _WIN32_WINNT 0x0500
  16. #define NOCRYPT
  17.  
  18. #pragma pack(push, 4)
  19. #include <windows.h>
  20. #pragma pack(pop)
  21.  
  22. #include <assert.h>
  23. #include <tchar.h>
  24. #include <math.h>
  25. #include <stdio.h>
  26.  
  27. #include "..\..\include\win.h"
  28. #include "..\..\include\FrameWnd.h"
  29. #include "..\..\include\GDIObject.h"
  30. #include "..\..\include\pen.h"
  31. #include "..\..\include\filedialog.h"
  32. #include "..\..\include\outputsetup.h"
  33. #include "..\..\include\fonttext.h"
  34. #include "..\..\include\pagecanvas.h"
  35.  
  36. #include "resource.h"
  37. #include "progview.h"
  38.  
  39. typedef enum
  40. {
  41.     class_plain,
  42.     class_keyword,
  43.     class_comment,
  44.     class_number,
  45.     class_string,
  46.     class_unknown
  47. };
  48.  
  49. COLORREF crText[] =
  50. {
  51.     RGB(0x00, 0x00, 0x00),    // black
  52.     RGB(0x00, 0x00, 0xFF),  // blue
  53.     RGB(0x00, 0x80, 0x00),  // dark green
  54.     RGB(0x80, 0x00, 0x00),  // dark red
  55.     RGB(0x00, 0xF0, 0x80),  // dark blue
  56.     RGB(0xFF, 0x00, 0x00)   // red
  57. };
  58.  
  59. const char * keywordlist[] =
  60. {   
  61.     "#pragma",
  62.     "#define",
  63.     "#include",
  64.     "#ifdef",
  65.     "#ifndef",
  66.     "#else",
  67.     "#endif",
  68.  
  69.     "__asm",        "__assume",
  70.     "__based",
  71.     "__cdecl", 
  72.     "__declspec",
  73.     "__except",        "__export",
  74.     "__far",        "__fastcall",    "__fortran",    "__finally"
  75.     "__huge",                                                        
  76.     "__inline",     "__int8",        "__int16",        "__int32",      "__int64",
  77.     "__interrupt",
  78.     "__leave",      "__loadds",
  79.     "__multiple_inheritance",
  80.     "__near",
  81.     "__pascal",        
  82.     "__saveregs",    "__segment",    "__segname",    "__self",        "__single_inheritance",
  83.     "__stdcall",
  84.     "__try",
  85.     "__uuidof",
  86.     "__virtual_inheritance",
  87.   
  88.     "_asm",
  89.     "_cdecl",
  90.     "_export",
  91.     "_far",
  92.     "_huge",
  93.     "_interrupt",
  94.     "_loadds",
  95.     "_near",
  96.     "_pascal",
  97.     "_saveregs",
  98.     
  99.     "asm",            "auto",
  100.     "bool",            "break",                                        
  101.     "case",            "catch",        "char",            "class",         "const",        
  102.     "const_cast",    "continue",
  103.     "default",        "delete",        "dllexport",    "dllimport",     "do",
  104.     "double",        "dynamic_cast",
  105.     "else",            "enum",            "explicit",        "extern",        
  106.     "false",        "far",            "fastcall",        "float",        "for",            
  107.     "friend",
  108.     "goto",
  109.     "huge",
  110.     "if",            "inline",        "int",
  111.     "long",
  112.     "main",            "mutable",
  113.     "naked",        "namespace",    "near",            "new",            "noreturn",
  114.     "operator",
  115.     "private",        "protected",    "public",
  116.     "register",        "reinterpret_cast",                "return",
  117.     "short",        "signed",        "sizeof",        "static",         "static_cast",    
  118.     "struct",        "switch",
  119.     "template",        "this",            "thread",        "throw",        "true",            
  120.     "try",            "typedef",        "typeid",        "typename",
  121.     "union",        "using",        "unsigned",        "uuid",
  122.     "virtual",        "void",            "volatile",
  123.     "while",        "wmain"
  124. };
  125.  
  126. bool IsKeyword(const TCHAR * word, unsigned len)
  127. {
  128.     for (int k=0; k<sizeof(keywordlist)/sizeof(keywordlist[0]); k++)
  129.         if ( (word[0]==keywordlist[k][0])  && 
  130.              (len==strlen(keywordlist[k])) &&
  131.              (strncmp(word, keywordlist[k], len)==0) )
  132.              return true;
  133.  
  134.     return false;
  135. }
  136.  
  137.  
  138. int skipchar(const TCHAR * text)
  139. {
  140.     if ( text[0]=='\\' )     // escape
  141.         switch ( text[1] )
  142.         {
  143.             case 'a' : case 'b' : case 'f' : case 'n' : 
  144.             case 'r' : case 't' : case 'v' : case '?' : 
  145.             case '\'': case '"' : case '\\':            
  146.                 return 2;
  147.             
  148.             case '0' : case '1' : case '2' : case '3' :
  149.             case '4' : case '5' : case '6' : case '8' : 
  150.                 return 4;
  151.                       
  152.             case 'x': 
  153.                 return 3;
  154.         }
  155.  
  156.     return 1;
  157. }
  158.  
  159. void ColorText(const TCHAR * text, BYTE * flag)
  160. {
  161.     while ( text[0] )
  162.         if ( (text[0]=='#') || (text[0]=='_') || (text[0]>='a') && (text[0]<='z') || (text[0]>='A') && (text[0]<='Z') )
  163.         {
  164.             int i = 1;
  165.             
  166.             while ( (text[i]=='_') || (text[i]>='a') && (text[i]<='z') || (text[i]>='A') && (text[i]<='Z') || (text[i]>='0') && (text[i]<='9') )
  167.                 i ++;
  168.  
  169.             memset(flag, class_plain, i);
  170.  
  171.             if ( IsKeyword(text, i) )
  172.                 memset(flag, class_keyword, i);
  173.             else
  174.                 memset(flag, class_plain, i);
  175.             
  176.             text += i;
  177.             flag += i;
  178.         }
  179.         else if ( (text[0]>='0') && (text[0]<='9') )
  180.         {
  181.             int i = 0;
  182.             while ( (text[i]>='0') && (text[i]<='9') )
  183.                 i ++;
  184.  
  185.             memset(flag, class_number, i);
  186.             text += i;
  187.             flag += i;
  188.         }
  189.         else switch ( text[0] )
  190.         {
  191.             case '/':
  192.                 if ( text[1]=='/' )
  193.                 {
  194.                     memset(flag, class_comment, _tcslen(text));
  195.                     return;
  196.                 }
  197.  
  198.             case '{':
  199.             case '}':
  200.             case '(': 
  201.             case ')':
  202.             case '[':
  203.             case ']':
  204.             case '+':
  205.             case '-':
  206.             case '*':
  207.             case '?':
  208.             case ' ':
  209.             case '<':
  210.             case '>':
  211.             case '.':
  212.             case '=':
  213.             case ';':
  214.             case ',':
  215.             case '&':
  216.             case '~':
  217.             case '|':
  218.             case '^':
  219.             case '!':
  220.             case ':':
  221.                 * flag ++ = class_plain;
  222.                 text ++; 
  223.                 break;
  224.         
  225.             case '\'':
  226.                 {
  227.                     int len = skipchar(text+1) + 2;
  228.                     memset(flag, class_string, len);
  229.                     text += len; flag += len;
  230.                 }
  231.                 break;
  232.  
  233.             case '"':
  234.                 {
  235.                     int len = 1;
  236.                     while ( text[len] && text[len]!='"' )
  237.                     {
  238.                         len += skipchar(text+len);
  239.                     }
  240.  
  241.                     if ( text[len]=='"' )
  242.                         len ++;
  243.  
  244.                     memset(flag, class_string, len);
  245.                     text += len; flag += len;
  246.                 }
  247.                 break;
  248.  
  249.             default:
  250.                 * flag ++ = class_unknown;
  251.                 text ++;
  252.         }
  253. }
  254.  
  255.  
  256. void KProgramPageCanvas::SyntaxHighlight(HDC hDC, int x, int y, const TCHAR * mess)
  257. {
  258.     BYTE  flag[MAX_PATH];
  259.  
  260.     int len = _tcslen(mess);
  261.  
  262.     assert(len < MAX_PATH-50);
  263.  
  264.     memset(flag, 0, MAX_PATH);
  265.     ColorText(mess, flag);
  266.  
  267.     float width = 0.0;
  268.  
  269.     for (int k=0; k<len; )
  270.     {
  271.         int next = 1;
  272.                 
  273.         while ( (k+next<len) && (flag[k]==flag[k+next]) )
  274.             next ++;
  275.  
  276.         SetTextColor(hDC, crText[flag[k]]);
  277.  
  278.         m_formator.TextOut(hDC, (int) (x + width + 0.5), y, mess+k, next);
  279.  
  280.         float w, h;
  281.         m_formator.GetTextExtent(hDC, mess+k, next, w, h);
  282.         width += w;
  283.  
  284.         k += next;
  285.     }
  286. }
  287.  
  288. // getting lines from text buffer
  289. class KGetline
  290. {
  291.     const char * m_text;
  292.     int             m_size;
  293.  
  294. public:
  295.     char         m_line[MAX_PATH];
  296.  
  297.     KGetline(const char * text, int size)
  298.     {
  299.         m_text = text;
  300.         m_size = size;
  301.     }
  302.  
  303.     int Nextline(void)
  304.     {
  305.         if ( m_size<=0 )
  306.             return 0;
  307.  
  308.         int len = 0;
  309.  
  310.         while ( (m_size>0) && m_text[0] && (m_text[0]!='\r') ) // get char until CR
  311.         {
  312.             if ( m_text[0] == '\t' )
  313.             {
  314.                 do
  315.                 {
  316.                     m_line[len++] = ' ';
  317.                 }
  318.                 while ( len % 4);
  319.             }
  320.             else
  321.                 m_line[len++] = m_text[0];
  322.  
  323.             m_text ++; m_size --;
  324.         }
  325.  
  326.         if ( m_text[1]=='\n' ) // skip LF
  327.         {
  328.             m_size -= 2;
  329.             m_text += 2;
  330.         }
  331.         else
  332.         {
  333.             m_size -= 1;
  334.             m_text += 1;
  335.         }
  336.  
  337.         m_line[len] = 0;
  338.  
  339.         return max(1, len);
  340.     }
  341. };
  342.  
  343. int CountLine(const char * text, int size)
  344. {
  345.     KGetline parser(text, size);
  346.  
  347.     int lineno = 0;
  348.     while ( parser.Nextline() )
  349.         lineno ++;
  350.  
  351.     return lineno;
  352. }
  353.  
  354.  
  355. void KProgramPageCanvas::UponDrawPage(HDC hDC, const RECT * rcPaint, int width, int height, int pageno)
  356. {
  357.     if ( rcPaint )    // skip painting is current page does not intersect with rcPaint
  358.     {
  359.         RECT rect = { 0, 0, width, height };
  360.  
  361.         LPtoDP(hDC, (POINT *) & rect, 2);
  362.  
  363.         if ( ! IntersectRect(& rect, rcPaint, & rect) )
  364.             return;
  365.     }
  366.  
  367.     HGDIOBJ hOld = SelectObject(hDC, m_hFont);
  368.  
  369.     SetBkMode(hDC, TRANSPARENT);
  370.     SetTextAlign(hDC, TA_LEFT | TA_TOP);
  371.  
  372.     KGetline parser(m_pBuffer, m_nSize);
  373.  
  374.     int skip = pageno * m_nLinePerPage;
  375.  
  376.     for (int i=0; i<skip; i++)
  377.         parser.Nextline();
  378.  
  379.     for (i=0; i<m_nLinePerPage; i++)
  380.         if ( parser.Nextline() )
  381.         {
  382.             SyntaxHighlight(hDC, 0, 
  383.                 (int)(m_formator.GetLinespace() * i + 0.5), parser.m_line);
  384.         }
  385.         else
  386.             break;
  387.  
  388.     SelectObject(hDC, hOld);
  389. }
  390.  
  391. void KProgramPageCanvas::OnCreate(void)
  392. {
  393.     KPageCanvas::OnCreate();
  394. }
  395.  
  396.  
  397. void KProgramPageCanvas::RefreshPaper(void)
  398. {
  399.     KSurface::RefreshPaper();
  400.  
  401.     if ( m_hFont==NULL )
  402.     {
  403.         int pointsize = 9;
  404.  
  405.         KLogFont logfont(- pointsize * ONEINCH / 72, "Courier New");
  406.         
  407.         m_hFont = logfont.CreateFont();
  408.     
  409.         HDC hDC         = GetDC(NULL);
  410.         HGDIOBJ hOld = SelectObject(hDC, m_hFont);
  411.  
  412.         m_formator.SetupPixel(hDC, m_hFont, (float)(pointsize * ONEINCH/72));
  413.         SelectObject(hDC, hOld);
  414.  
  415.         ReleaseDC(NULL, hDC);
  416.     }
  417. }
  418.  
  419. int KProgramPageCanvas::OnCommand(int cmd, HWND hWnd)
  420. {
  421.     switch ( cmd )
  422.     {
  423.         case IDM_VIEW_ZOOM400  : return SetZoom(400);
  424.         case IDM_VIEW_ZOOM200  : return SetZoom(200); 
  425.         case IDM_VIEW_ZOOM150  : return SetZoom(150); 
  426.         case IDM_VIEW_ZOOM100  : return SetZoom(100);
  427.         case IDM_VIEW_ZOOM75   : return SetZoom( 75);
  428.         case IDM_VIEW_ZOOM50   : return SetZoom( 50);
  429.         case IDM_VIEW_ZOOM25   : return SetZoom( 25);
  430.         case IDM_VIEW_ZOOM10   : return SetZoom( 10);
  431.  
  432.         case IDM_FILE_PRINT    : UponFilePrint();     GetDimension(); return View_Resize;
  433.         case IDM_FILE_PAGESETUP: UponFilePageSetup(); GetDimension(); return View_Resize;
  434.  
  435.         case IDM_FILE_PROPERTY :
  436.             {
  437.                 int nControlID[] = { IDC_LIST, IDC_DEFAULT, IDC_PRINTERS, 
  438.                     IDC_PRINTERPROPERTIES, IDC_ADVANCEDDOCUMENTPROPERTIES, IDC_DOCUMENTPROPERTIES };
  439.             
  440.                 ShowProperty(m_OutputSetup, m_hInst, nControlID, IDD_PROPERTY);
  441.             }
  442.     }
  443.  
  444.     return View_NoChange;
  445. }
  446.