home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / C / CKTBL / MFC / CKTBLCTR.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-09  |  33.2 KB  |  1,171 lines

  1. // cktblctr.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h" 
  5. #include "cktblctr.h"
  6.           
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char BASED_CODE THIS_FILE[] = __FILE__;
  10. #endif
  11.      
  12. struct CKTBLPrintStruct {
  13.     CFont    cellFont,labelFont;
  14.     CPoint    cellInset;
  15.     int        thinlinex;
  16.     int        thinliney; 
  17.     int        logpixelSX;
  18.     int        logpixelSY;
  19.     };                
  20.        
  21. IMPLEMENT_DYNCREATE( CCKTBLControl, CWnd )
  22.                                     
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CCKTBLControl
  25.  
  26. CCKTBLControl::CCKTBLControl()
  27. {
  28. }
  29.  
  30. CCKTBLControl::~CCKTBLControl()
  31. {
  32.     DestroyWindow();
  33. }  
  34.    
  35. BOOL CCKTBLControl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd )
  36. {
  37.     return CWnd::Create(CKTBL_CLASS, NULL, dwStyle, rect, pParentWnd, NULL);
  38. }
  39.  
  40. WNDPROC* CCKTBLControl::GetSuperWndProcAddr()
  41. {   
  42.     static WNDPROC NEAR pfnSuper;
  43.     return &pfnSuper;
  44. }          
  45.   
  46. /////////////////////////////////////////////////////////////////////////////
  47. // High Level CCKTBLControl Operations
  48.                                   
  49. void CCKTBLControl::AddFlags( DWORD flags )
  50. {                
  51.     SetFlags( GetFlags() | flags );
  52. }
  53.  
  54. void CCKTBLControl::RemoveFlags( DWORD flags )
  55. {
  56.     SetFlags( GetFlags() & ~flags );
  57. }
  58.      
  59. void CCKTBLControl::SetFlagsTo( DWORD flags, BOOL value )
  60. {
  61.     if(value)
  62.         AddFlags(flags);
  63.     else
  64.         RemoveFlags(flags);
  65. }
  66.      
  67. void CCKTBLControl::GetText( int row, int col, CString * text )
  68. {                 
  69.     int length;
  70.     LPSTR buffer;
  71.                                     
  72.     length = GetTextLength(row,col)+1;
  73.     buffer = text->GetBuffer( length );
  74.     GetText( row, col, buffer, length );
  75.     text->ReleaseBuffer();
  76. }       
  77.  
  78. void CCKTBLControl::UpdateSelectionRowHeighths()
  79. {   
  80.     int sel, nsel, row, height;
  81.     CRect rect;
  82.     
  83.     nsel = GetSelectionSize();
  84.     for(sel=1; sel<=nsel; sel++) {
  85.         GetSelection( &rect, sel );
  86.         for( row=rect.top; row<=rect.bottom; row++) { 
  87.             //UpdateRowHeight(row);
  88.             height = GetRowTextHeight( row, -1 );
  89.             if( GetRowHeight( row ) != height ) SetRowHeight( row, height );
  90.         }
  91.  
  92.     }
  93. }
  94.                    
  95. /////////////////////////////////////////////////////////////////////////////
  96. //  CCKTBLControl Printing
  97.                                   
  98.  
  99. void CCKTBLControl::OnPrint( CDC* pDC, CPrintInfo* pInfo )
  100. {               
  101.      DrawTable( pDC, pInfo );
  102. }   
  103.   
  104. void CCKTBLControl::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
  105. {
  106.     // page rectangle is not set when MFC calls OnBeginPrinting
  107.          
  108.     pInfo->m_rectDraw.SetRect( 0,0,pDC->GetDeviceCaps(HORZRES),pDC->GetDeviceCaps(VERTRES));
  109.     pDC->DPtoLP(&pInfo->m_rectDraw);
  110.   
  111. }  
  112.  
  113. void CCKTBLControl::Paginate(CDC* pDC, CPrintInfo* pInfo)
  114. {
  115.     // Purpose: This routine paginates the table for the current CDC specified.
  116.     // It stores the number of pages in pInfo
  117.  
  118.     int         sx, sy, sxCKTBL, syCKTBL;
  119.     CWindowDC     tempDC(this);                 // nur um sxCKTBL,syCKTBL zu ermitteln
  120.     CRect        cells;                        // rectangle of cells to print
  121.     int            row, col;   
  122.     int            rows, cols;  
  123.     int            currentx, currenty;          // current pos when drawing in printer coordinates
  124.     int            colSize, rowSize;              // dimensions of current row and column in printer coordinates
  125.     int            page;
  126.     BOOL        morePages;
  127.      
  128.     // get dc capabilities of target and CKTBL dc
  129.             
  130.     sx = pDC->GetDeviceCaps( LOGPIXELSX );
  131.     sy = pDC->GetDeviceCaps( LOGPIXELSY ); 
  132.     sxCKTBL = tempDC.GetDeviceCaps( LOGPIXELSX );
  133.     syCKTBL = tempDC.GetDeviceCaps( LOGPIXELSY ); 
  134.                              
  135.     rows = GetRows();
  136.     cols = GetColumns();
  137.     
  138.     // paginate
  139.     cells.SetRect( 0, 0, 0, 0 );
  140.     row = 0; 
  141.     col = 0; 
  142.  
  143.     for( page = 0,morePages = TRUE; morePages; page++ ) 
  144.     {
  145.         // go down one page from row 
  146.         
  147.            cells.top = row;
  148.         currenty = pInfo->m_rectDraw.top; 
  149.         for( ; row<=rows && currenty<pInfo->m_rectDraw.bottom; row++ ) {
  150.              rowSize = GetRowHeight(row);
  151.             rowSize = (int)((long)rowSize*sy/syCKTBL);    // convert from CKTBL to printer coord
  152.             currenty += rowSize;
  153.         }                          
  154.         row--;        
  155.         if( currenty > pInfo->m_rectDraw.bottom ) {
  156.             row--;    
  157.         } 
  158.         cells.bottom = min(row,rows); 
  159.         row = cells.top;
  160.     
  161.         // go left one page from col
  162.   
  163.           cells.left = col;                          
  164.            currentx = pInfo->m_rectDraw.left;
  165.         for( ; col<=cols && currentx<pInfo->m_rectDraw.right; col++ ) { 
  166.             colSize = GetColumnWidth(col);
  167.             colSize = (int)((long)colSize*sx/sxCKTBL);    // convert from CKTBL to printer coord
  168.               currentx += colSize;
  169.         }       
  170.         col--;                         
  171.          if( currentx > pInfo->m_rectDraw.right ) {
  172.             col--;    
  173.         } 
  174.         cells.right = min(col,cols); 
  175.         col = cells.right + 1;                    
  176.  
  177.         // move right one page
  178.         // move down one page if at leftmost page
  179.         // end printjob if at last page
  180.         
  181.         if(col>cols) {
  182.             col = 0;
  183.             row = cells.bottom+1;
  184.             if( row>rows ) morePages = FALSE;
  185.         }
  186.     }       
  187.     pInfo->SetMaxPage( page );    
  188. }
  189.     
  190. void CCKTBLControl::SetMargins( CDC *pDC, CPrintInfo * pInfo, int left, int top, int right, int bottom )
  191. {
  192.     int sx = pDC->GetDeviceCaps( LOGPIXELSX );
  193.     int sy = pDC->GetDeviceCaps( LOGPIXELSY );
  194.     
  195.     pInfo->m_rectDraw.left         += (int)((long)left * sx * 10 / 254);
  196.     pInfo->m_rectDraw.top         += (int)((long)top * sy * 10 / 254);
  197.     pInfo->m_rectDraw.right     -= (int)((long)right * sx * 10 / 254);
  198.     pInfo->m_rectDraw.bottom     -= (int)((long)bottom * sy * 10 / 254);
  199. }
  200.               
  201. void CCKTBLControl::DrawTable(CDC* pDC, CPrintInfo* pInfo )
  202. {         
  203.     int         sx, sy, sxCKTBL, syCKTBL;
  204.     CWindowDC     tempDC(this);                 // nur um sxCKTBL,syCKTBL zu ermitteln
  205.     CSize        pageSize;                   // size of page
  206.     CRect        cells;                        // rectangle of cells to print
  207.     int            row, col;   
  208.     int            rows, cols;  
  209.     int            currentx, currenty;          // current pos when drawing in printer coordinates
  210.     int            colSize, rowSize;              // dimensions of current row and column in printer coordinates
  211.     CRect        cellRect;                    // coordinates of current cell in printer coordinates
  212.     CKTBLPrintStruct ps;     
  213.     CPen        grayPen, blackPen, * oldPen;    
  214.     CRect        pageRect;                    // page excluding labels   
  215.     int            page;
  216.     BOOL        morePages;
  217.  
  218.  
  219.     // get dc capabilities of target and CKTBL dc
  220.                
  221.     sx = pDC->GetDeviceCaps( LOGPIXELSX );
  222.     sy = pDC->GetDeviceCaps( LOGPIXELSY ); 
  223.     sxCKTBL = tempDC.GetDeviceCaps( LOGPIXELSX );
  224.     syCKTBL = tempDC.GetDeviceCaps( LOGPIXELSY ); 
  225.                              
  226.     // create gdi objects and fill paint structure                             
  227.                              
  228.     ps.cellInset.x = 2 * sx / sxCKTBL;
  229.     ps.cellInset.y = 2 * sy / syCKTBL;  
  230.     ps.logpixelSX = sx;
  231.     ps.logpixelSY = sy;
  232.     ps.thinlinex =  (int)((long)sx / 254);        // 1/10 mm
  233.     ps.thinliney =     (int)((long)sy / 254);        // 1/10 mm
  234.              
  235.     //    BOOL CreateFont( int nHeight, int nWidth, int nEscapement, 
  236.     //        int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, 
  237.     //        BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, 
  238.     //        BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,  
  239.     //        LPCSTR lpszFacename );                                
  240.                                 
  241.     ps.cellFont.CreateFont( 10*sy/72,0,0,0,FW_NORMAL,0,0,0,0,OUT_TT_PRECIS,0,0,0,"MS Sans Serif");
  242.     ps.labelFont.CreateFont( 10*sy/72,0,0,0,FW_BOLD,0,0,0,0,OUT_TT_PRECIS,0,0,0,"MS Sans Serif");
  243.             
  244.     rows = GetRows();
  245.     cols = GetColumns();
  246.     
  247.     // move to page to print by paginating
  248.     
  249.     cells.SetRect( 0, 0, 0, 0 );
  250.     row = 0; 
  251.     col = 0; 
  252.  
  253.     for( page = 0,morePages = TRUE;
  254.          page!=(int)pInfo->m_nCurPage && morePages;
  255.          page++ ) 
  256.     {
  257.         // go down one page from row 
  258.         
  259.            cells.top = row;
  260.         currenty = pInfo->m_rectDraw.top; 
  261.         for( ; row<=rows && currenty<pInfo->m_rectDraw.bottom; row++ ) {
  262.              rowSize = GetRowHeight(row);
  263.             rowSize = (int)((long)rowSize*sy/syCKTBL);    // convert from CKTBL to printer coord
  264.             currenty += rowSize;
  265.         }                          
  266.         row--;        
  267.         if( currenty > pInfo->m_rectDraw.bottom ) {
  268.             row--;    
  269.         } 
  270.         cells.bottom = min(row,rows); 
  271.         row = cells.top;
  272.     
  273.         // go left one page from col
  274.   
  275.           cells.left = col;                          
  276.            currentx = pInfo->m_rectDraw.left;
  277.         for( ; col<=cols && currentx<pInfo->m_rectDraw.right; col++ ) { 
  278.             colSize = GetColumnWidth(col);
  279.             colSize = (int)((long)colSize*sx/sxCKTBL);    // convert from CKTBL to printer coord
  280.               currentx += colSize;
  281.         }       
  282.         col--;                         
  283.          if( currentx > pInfo->m_rectDraw.right ) {
  284.             col--;    
  285.         } 
  286.         cells.right = min(col,cols); 
  287.         col = cells.right + 1;                    
  288.  
  289.         // move right one page
  290.         // move down one page if at leftmost page
  291.         // end printjob if at last page
  292.         
  293.         if(col>cols) {
  294.             col = 0;
  295.             row = cells.bottom+1;
  296.             if( row>rows )     morePages = FALSE;
  297.         }
  298.     }   
  299.     
  300.     // paint table
  301.     // range of cells on this page is in 'cells'
  302.     
  303.     pageRect.SetRect( 0,0,0,0 );        
  304.         
  305.     currenty = pInfo->m_rectDraw.top;
  306.     for( row=cells.top; row<=cells.bottom; row++ ) {
  307.          rowSize = GetRowHeight(row);
  308.         rowSize = (int)((long)rowSize*sy/syCKTBL);    // convert from CKTBL to printer coord
  309.          
  310.            currentx = pInfo->m_rectDraw.left;
  311.         for( col=cells.left; col<=cells.right; col++ ) { 
  312.             colSize = GetColumnWidth(col);
  313.             colSize = (int)((long)colSize*sx/sxCKTBL);    // convert from CKTBL to printer coord
  314.              
  315.             cellRect.SetRect( currentx, currenty, currentx+colSize, currenty+rowSize);
  316.             DrawCell(pDC,row,col,&cellRect, &ps );
  317.  
  318.              currentx += colSize;
  319.         }
  320.         currenty += rowSize;
  321.     }
  322.     
  323.     // Draw gridlines
  324.                               
  325.     pageRect.left = pInfo->m_rectDraw.left; // + (int)((long)(cktbl.GetColumnWidth(0))*sx/sxCKTBL);
  326.     pageRect.top =  pInfo->m_rectDraw.top;    // + (int)((long)(cktbl.GetRowHeight(0))*sy/syCKTBL);
  327.      pageRect.right = currentx;                                  
  328.        pageRect.bottom = currenty;   
  329.       
  330.     grayPen.CreatePen( PS_SOLID, (ps.thinlinex+ps.thinliney)/2, RGB(0,0,0));
  331.     blackPen.CreatePen( PS_SOLID,(ps.thinlinex+ps.thinliney)/2, RGB(0,0,0));
  332.     oldPen = pDC->SelectObject( &grayPen );
  333.      
  334.     currenty = pInfo->m_rectDraw.top;
  335.     for( row=cells.top; row<=cells.bottom; row++ ) {
  336.          rowSize = GetRowHeight(row);
  337.         rowSize = (int)((long)rowSize*sy/syCKTBL);    // convert from CKTBL to printer coord
  338.         pDC->MoveTo( pageRect.left, currenty );
  339.         pDC->LineTo( pageRect.right, currenty );
  340.            currenty += rowSize;
  341.     }  
  342.     pDC->MoveTo( pageRect.left, currenty );
  343.     pDC->LineTo( pageRect.right, currenty );
  344.     
  345.     currentx = pInfo->m_rectDraw.left;
  346.     for( col=cells.left; col<=cells.right; col++ ) { 
  347.         colSize = GetColumnWidth(col);
  348.         colSize = (int)((long)colSize*sx/sxCKTBL);    // convert from CKTBL to printer coord
  349.         pDC->MoveTo( currentx, pageRect.top );
  350.         pDC->LineTo( currentx, pageRect.bottom  );
  351.         currentx += colSize;
  352.     }
  353.     pDC->MoveTo( currentx, pageRect.top );
  354.     pDC->LineTo( currentx, pageRect.bottom  );
  355.     
  356.     pDC->SelectObject( oldPen );        
  357. }     
  358.   
  359. void CCKTBLControl::DrawCell(CDC * pDC, int row, int col, CRect * rectArg, CKTBLPrintStruct * ps )
  360. {        
  361.     CKTBL_ATTRIB     attrib;   
  362.     CString         text;         
  363.     CFont            *font;
  364.     WORD            wFormat;      
  365.     CRect            rect;
  366.     int                x,y;
  367.     HFONT            hFont,hOldFont;
  368.                       
  369.     GetAttr( row, col, &attrib );
  370.     GetText( row, col, &text );     
  371.             
  372.      rect.SetRect( rectArg->left, rectArg->top, rectArg->right, rectArg->bottom );                   
  373.     rect.left     += ps->cellInset.x;
  374.     rect.top     += ps->cellInset.x;
  375.     rect.right    -= ps->cellInset.y;
  376.     rect.bottom    -= ps->cellInset.y;
  377.  
  378.     font = (row==0 || col==0) ? &ps->labelFont : &ps->cellFont;     
  379.     hFont = (HFONT)font->GetSafeHandle();
  380.     hOldFont = (HFONT) ::SelectObject( pDC->m_hDC, hFont );
  381.     
  382.     if((attrib.format & CKTBL_FMT_MULTI_LINE)) {
  383.         // multiline cells
  384.         wFormat = DT_NOPREFIX;
  385.         if( attrib.format & CKTBL_FMT_WORDBREAK ) wFormat |= DT_WORDBREAK;
  386.         switch( attrib.format & CKTBL_MASK_HALIGN) {
  387.             case CKTBL_FMT_CENTER:  wFormat |= DT_CENTER; break;
  388.             case CKTBL_FMT_LEFT:    wFormat |= DT_LEFT;    break;
  389.             case CKTBL_FMT_RIGHT:     wFormat |= DT_RIGHT; break;
  390.         }
  391.         pDC->SetTextAlign( 0 );              // DrawText or's this with wFormat
  392.         pDC->SetBkMode( TRANSPARENT );
  393.         pDC->DrawText( text, -1, &rect, wFormat);
  394.     } else {
  395.         // singleline cells
  396.         if((attrib.format & CKTBL_MASK_VALIGN)==CKTBL_FMT_TOP) {
  397.             wFormat = TA_TOP;
  398.             y = rect.top;
  399.         } else {
  400.             wFormat = TA_BOTTOM;
  401.             y = rect.bottom;
  402.         }
  403.         switch( attrib.format & CKTBL_MASK_HALIGN) {
  404.             case CKTBL_FMT_CENTER:
  405.                 wFormat |= TA_CENTER;
  406.                 x = (rect.left + rect.right)/2;
  407.                 break;
  408.             case CKTBL_FMT_RIGHT:
  409.                 wFormat |= TA_RIGHT;
  410.                 x = rect.right;
  411.                 break;
  412.             case CKTBL_FMT_LEFT: default:
  413.                 wFormat |= TA_LEFT;
  414.                 x = rect.left;
  415.                 break;
  416.         }   
  417.         pDC->SetBkMode( TRANSPARENT );
  418.         pDC->SetTextAlign( wFormat );
  419.         pDC->ExtTextOut( x,y, ETO_CLIPPED, &rect, text, strlen(text), NULL );
  420.     }
  421.     ::SelectObject( pDC->GetSafeHdc(), hOldFont );
  422. }
  423.     
  424.      
  425. /////////////////////////////////////////////////////////////////////////////
  426. //  CArchiveReadStream reads tab delimited chunks from an archive 
  427. //  
  428.    
  429. class CArchiveReadStream : public CObject {
  430. public:   
  431.     CArchiveReadStream();
  432.     ~CArchiveReadStream();
  433.             
  434.     void ResetOn( CArchive &ar );
  435.     BOOL FillBuffer();
  436.     BOOL AtEOF()    { return lastBuffer && bp>=bufferTail; }
  437.     BOOL GetNextChunk( char *chunk, int max ); 
  438.     BOOL SkipToNextLine();
  439.     
  440. protected:   
  441.     int bufferSize;
  442.     char *buffer, *bufferTail, *bp;
  443.     CArchive * ar;          
  444.     int    lastBuffer;
  445. };
  446.            
  447. CArchiveReadStream::CArchiveReadStream()
  448. {             
  449.     bufferSize = 8192;                  
  450.     buffer=(char*)malloc(bufferSize); 
  451. }
  452.  
  453. CArchiveReadStream::~CArchiveReadStream()
  454. {
  455.     free(buffer);
  456. }        
  457.         
  458. void CArchiveReadStream::ResetOn( CArchive &theArchive )
  459. {
  460.     ar = &theArchive; 
  461.     lastBuffer=FALSE;
  462.     bp=bufferTail=buffer;
  463.     FillBuffer(); 
  464. }                             
  465.  
  466. BOOL CArchiveReadStream::FillBuffer()
  467. {     
  468.     int bytes;
  469.     
  470.     if(AtEOF()) return FALSE;
  471.     bytes = ar->Read( buffer, bufferSize ); 
  472.     bufferTail = buffer+bytes;
  473.     bp = buffer;      
  474.     lastBuffer=(bytes<bufferSize);
  475.     return !AtEOF();
  476. }
  477.  
  478. BOOL CArchiveReadStream::GetNextChunk( char *chunk, int max )
  479. {
  480.     char *src, *dst; 
  481.     int copy;
  482.     
  483.     if(AtEOF()) return FALSE;               
  484.     if(bp>=bufferTail && !FillBuffer()) return FALSE;
  485.     if(*bp=='\r' || *bp=='\n') return FALSE;
  486.     
  487.     src = bp;
  488.     dst = chunk;               
  489.     
  490.     while( *bp!='\t' && *bp!='\r' && *bp!='\n' ) {
  491.         bp++;
  492.         if(bp>=bufferTail) {  
  493.             copy = min((bp-src),(max-(dst-chunk)));
  494.             strncpy( dst, src, copy );
  495.             dst+=copy;
  496.             *dst=0;
  497.             if(!FillBuffer()) return TRUE;
  498.             src=bp;
  499.         }
  500.     }
  501.     copy = min((bp-src),(max-(dst-chunk)));
  502.     if(*bp=='\t') bp++;
  503.     strncpy( dst,src,copy);
  504.     dst+=copy;
  505.     *dst=0;
  506.     return TRUE;
  507. }
  508.   
  509.   
  510. BOOL CArchiveReadStream::SkipToNextLine()
  511. {    
  512.     if(AtEOF()) return FALSE;
  513.     if(bp>=bufferTail && !FillBuffer()) return FALSE;
  514.     
  515.     while( *bp!='\n' ) {
  516.         bp++;
  517.         if(bp>=bufferTail && !FillBuffer()) return FALSE;
  518.     }        
  519.     bp++;
  520.     return TRUE;
  521. }    
  522.  
  523. /////////////////////////////////////////////////////////////////////////////
  524. //  CCKTBLControl Archive support 
  525. // these functions support reading and writing from tab separated ascii files
  526.    
  527.                    
  528. void CCKTBLControl::ReadFromArchive(CArchive& ar)
  529. {           
  530.     CArchiveReadStream in;
  531.     const int textSize = 32000;                              
  532.     char    *text;
  533.     int     row, col, maxCols;
  534.     
  535.     ASSERT_VALID(this);
  536.     
  537.     text = (char*)malloc( textSize+1 );
  538.     if(!text) AfxThrowMemoryException();
  539.  
  540.     maxCols = 1;                                  
  541.     row = -1;         // so that first row==0 for labels
  542.     col = 0;
  543.                              
  544.     in.ResetOn(ar);
  545.     while(!in.AtEOF()) {
  546.         if(in.GetNextChunk(text, textSize)) {
  547.             if(col==0) row++;
  548.             SetText( row, ++col, text );        
  549.         } else {     
  550.             in.SkipToNextLine();
  551.             maxCols = max( maxCols, col );
  552.             col=0;
  553.         }
  554.     }   
  555.     
  556.     free(text); 
  557.     SetSize(max(row,1),max(maxCols,1));
  558.                     
  559.     Invalidate();
  560.     ASSERT_VALID(this);
  561. }
  562.  
  563. void CCKTBLControl::WriteToArchive(CArchive& ar)
  564. {
  565.     static char    tab[] = "\t";
  566.     static char    crlf[] = "\r\n";
  567.     int         row, col, maxCols, maxRows;
  568.     CString     text;
  569.     
  570.     ASSERT_VALID(this);
  571.             
  572.     maxCols = GetColumns();            
  573.     maxRows = GetRows();
  574.     
  575.     for( row=0; row<=maxRows; row++) {
  576.         for( col=1; col<=maxCols; col++) {
  577.             GetText( row, col, &text );
  578.             ar.Write( text, text.GetLength() );
  579.             if(col<maxCols) ar.Write( tab, 1 );
  580.         }
  581.         ar.Write( crlf, 2 );
  582.     }
  583.     
  584.     ASSERT_VALID(this);
  585. }
  586.  
  587.  
  588. void CCKTBLControl::SerializeRaw(CArchive& ar)
  589. {
  590.     ASSERT_VALID(this);
  591.     if (ar.IsStoring())    {
  592.         WriteToArchive(ar);
  593.     } else {
  594.         ReadFromArchive(ar );
  595.     }
  596.     ASSERT_VALID(this);
  597. }
  598.                  
  599.                    
  600. /////////////////////////////////////////////////////////////////////////////
  601. // Basic CCKTBLControl Operations (map directly to C API)
  602.                                   
  603. void CCKTBLControl::Clear()
  604. {
  605.     CKTBLClear( GetSafeHwnd() );
  606. }
  607.  
  608. void CCKTBLControl::SetSize( int rows, int columns )
  609. {   
  610.     CKTBLSetSize( GetSafeHwnd(), rows, columns );
  611. }
  612.  
  613. void CCKTBLControl::SetColumns( int columns )
  614. {  
  615.     CKTBLSetColumns( GetSafeHwnd(), columns );
  616. }
  617.  
  618. void CCKTBLControl::SetRows( int rows )
  619. {    
  620.     CKTBLSetRows( GetSafeHwnd(), rows );
  621. }
  622.   
  623. int CCKTBLControl::GetColumns( )
  624. {   
  625.     return CKTBLGetColumns( GetSafeHwnd() );
  626. }                            
  627.  
  628. int CCKTBLControl::GetRows()
  629. {   
  630.     return CKTBLGetRows( GetSafeHwnd() );
  631. }
  632.  
  633. void CCKTBLControl::SetFlags(DWORD flags )
  634. {  
  635.     CKTBLSetFlags( GetSafeHwnd(), flags );
  636. }
  637.  
  638. long CCKTBLControl::GetFlags()
  639.     return CKTBLGetFlags( GetSafeHwnd() );
  640. }
  641.  
  642. int CCKTBLControl::GetCurrentRow()
  643. {              
  644.     return CKTBLGetCurrentRow( GetSafeHwnd() );
  645. }
  646.  
  647. int CCKTBLControl::GetCurrentColumn()
  648. {    
  649.     return CKTBLGetCurrentColumn( GetSafeHwnd() );
  650. }
  651.  
  652. void CCKTBLControl::SetCurrentCell(int row, int col )
  653. {     
  654.     CKTBLSetCurrentCell( GetSafeHwnd(), row, col );
  655. }
  656.  
  657. int CCKTBLControl::GetTopRow()
  658. {        
  659.     return CKTBLGetTopRow( GetSafeHwnd() );
  660. }
  661.  
  662. int CCKTBLControl::GetLeftColumn()
  663. {      
  664.     return CKTBLGetLeftColumn( GetSafeHwnd() );
  665. }
  666.  
  667. void CCKTBLControl::SetLeftTop(int left, int top )
  668. {      
  669.     CKTBLSetLeftTop( GetSafeHwnd(), left, top );
  670. }
  671.  
  672. BOOL CCKTBLControl::InEdit()
  673. {           
  674.     return CKTBLInEdit( GetSafeHwnd() );
  675. }
  676.  
  677. void CCKTBLControl::StartEdit(int row, int column, LPSTR text )
  678. {    
  679.     CKTBLStartEdit( GetSafeHwnd(), row, column, text );
  680. }
  681.  
  682. void CCKTBLControl::StartEditRequest(int row, int column, LPSTR text )
  683. {  
  684.     CKTBLStartEditRequest( GetSafeHwnd(), row, column, text );
  685. }
  686.  
  687. BOOL CCKTBLControl::EndEdit(BOOL acceptChanges )
  688. {  
  689.     return CKTBLEndEdit( GetSafeHwnd(), acceptChanges );
  690. }
  691.  
  692. void CCKTBLControl::ShowCell(int row, int col  )
  693. {
  694.     CKTBLShowCell( GetSafeHwnd(), row, col );
  695. }
  696.         
  697. void CCKTBLControl::SetCellAttr( CKTBL_ATTRIB FAR* attrib )
  698. {
  699.     CKTBLSetCellAttr( GetSafeHwnd(), attrib );
  700. }
  701.  
  702. void CCKTBLControl::GetCellAttr( CKTBL_ATTRIB FAR* attrib )
  703. {
  704.     CKTBLGetCellAttr( GetSafeHwnd(), attrib );
  705. }
  706.                            
  707. void CCKTBLControl::SetLabelAttr( CKTBL_ATTRIB FAR* attrib )
  708. {
  709.     CKTBLSetLabelAttr( GetSafeHwnd(), attrib );
  710. }
  711.  
  712. void CCKTBLControl::GetLabelAttr( CKTBL_ATTRIB FAR* attrib )
  713. {
  714.     CKTBLGetLabelAttr( GetSafeHwnd(), attrib );
  715. }
  716.     
  717. void CCKTBLControl::SetDefaultColumnWidth( int width )
  718. {
  719.     CKTBLSetDefaultColumnWidth( GetSafeHwnd(), width );
  720. }
  721.  
  722. void CCKTBLControl::SetDefaultRowHeight( int height )
  723. {
  724.     CKTBLSetDefaultRowHeight( GetSafeHwnd(), height );
  725. }
  726.  
  727. int CCKTBLControl::GetDefaultColumnWidth()
  728. {
  729.     return CKTBLGetDefaultColumnWidth( GetSafeHwnd() );
  730. }
  731.  
  732. int CCKTBLControl::GetDefaultRowHeight()
  733. {
  734.     return CKTBLGetDefaultRowHeight( GetSafeHwnd() );
  735. }
  736.  
  737. void CCKTBLControl::SetColumnWidth(int column, int width )
  738.     CKTBLSetColumnWidth( GetSafeHwnd(), column, width );
  739. }
  740.  
  741. void CCKTBLControl::SetRowHeight( int row, int height )
  742. {     
  743.     CKTBLSetRowHeight( GetSafeHwnd(), row, height );
  744. }
  745.  
  746. int CCKTBLControl::GetColumnWidth( int column  )
  747. {   
  748.     return CKTBLGetColumnWidth( GetSafeHwnd(), column );
  749. }
  750.  
  751. int CCKTBLControl::GetRowHeight( int row )
  752. {   
  753.     return CKTBLGetRowHeight( GetSafeHwnd(), row );
  754. }
  755.                          
  756. int CCKTBLControl::GetTextHeight( int row, int col, LPCSTR text )
  757. {  
  758.     return CKTBLGetTextHeight( GetSafeHwnd(), row, col, text );
  759. }
  760.                             
  761. int CCKTBLControl::GetRowTextHeight( int row, int skipColumn )
  762. {  
  763.     return CKTBLGetRowTextHeight( GetSafeHwnd(), row, skipColumn );
  764. }
  765.                             
  766. void CCKTBLControl::UpdateRowHeight( int row )
  767. {     
  768.     CKTBLUpdateRowHeight( GetSafeHwnd(), row );
  769. }
  770.     
  771. void CCKTBLControl::InsertRowsAfter( int row, int number )
  772. {  
  773.     CKTBLInsertRowsAfter( GetSafeHwnd(), row, number );
  774. }
  775.                             
  776. void CCKTBLControl::InsertColumnsAfter( int column ,int number )
  777. {   
  778.     CKTBLInsertColumnsAfter( GetSafeHwnd(), column, number );
  779. }
  780.    
  781. void CCKTBLControl::RemoveRows( int rowStart, int rowEnd )
  782. {          
  783.     CKTBLRemoveRows( GetSafeHwnd(), rowStart, rowEnd );
  784. }
  785.                             
  786. void CCKTBLControl::RemoveColumns( int columnStart, int columnEnd)
  787. {     
  788.     CKTBLRemoveColumns( GetSafeHwnd(), columnStart, columnEnd );
  789. }
  790.    
  791. void CCKTBLControl::SetText( int row, int column, LPCSTR text )
  792. {  
  793.     CKTBLSetText( GetSafeHwnd(), row, column, text );
  794. }
  795.                             
  796. void CCKTBLControl::SetTextPrim( int row, int column, LPCSTR text )
  797. {                                                    
  798.     CKTBLSetTextPrim( GetSafeHwnd(), row, column, text );
  799. }
  800.                             
  801. void CCKTBLControl::SetRowText( int row, LPCSTR text, int colSep, int lineSep )
  802. {    
  803.     CKTBLSetRowText( GetSafeHwnd(), row, text, colSep, lineSep );
  804. }
  805.     
  806. int CCKTBLControl::GetTextLength( int row, int column )
  807. {  
  808.     return CKTBLGetTextLength( GetSafeHwnd(), row, column  );
  809. }
  810.                             
  811. void CCKTBLControl::GetText( int row, int column, LPSTR text, int maxLength )
  812. {
  813.     CKTBLGetText( GetSafeHwnd(), row, column, text, maxLength );
  814. }
  815.          
  816. int CCKTBLControl::GetRowTextLength( int row  ) 
  817.     return CKTBLGetRowTextLength( GetSafeHwnd(), row );
  818. }
  819.                             
  820. void CCKTBLControl::GetRowText( int row, LPSTR text, int maxLength, int colSep, int lineSep )
  821. {     
  822.     CKTBLGetRowText( GetSafeHwnd(), row, text, maxLength, colSep, lineSep );
  823. }
  824.                             
  825. void CCKTBLControl::SetAttr( int row, int column, CKTBL_ATTRIB FAR* attrib )
  826. {  
  827.     CKTBLSetAttr( GetSafeHwnd(), row, column, attrib );            
  828. }
  829.                             
  830. void CCKTBLControl::ModifyAttr( int row, int column, CKTBL_ATTRIB FAR* attrib, short fields, DWORD formatMask  ) 
  831. {
  832.     CKTBLModifyAttr( GetSafeHwnd(), row, column, attrib, fields, formatMask  ); 
  833. }
  834.                             
  835. void CCKTBLControl::GetAttr( int row, int column, CKTBL_ATTRIB FAR* attrib )
  836. {    
  837.     CKTBLGetAttr( GetSafeHwnd(), row, column, attrib );
  838. }
  839.                             
  840. void CCKTBLControl::SetRectText( RECT FAR* rect, LPSTR text )
  841. {
  842.     CKTBLSetRectText( GetSafeHwnd(), rect, text );
  843. }
  844.                             
  845. void CCKTBLControl::SetRectAttr( RECT FAR* rect, CKTBL_ATTRIB FAR* attrib )
  846. {          
  847.     CKTBLSetRectAttr( GetSafeHwnd(), rect, attrib );
  848. }
  849.                             
  850. void CCKTBLControl::ModifyRectAttr( RECT FAR* rect, CKTBL_ATTRIB FAR* attrib, short fields, DWORD formatMask )
  851. {
  852.      CKTBLModifyRectAttr( GetSafeHwnd(), rect, attrib, fields, formatMask );
  853. }
  854.                                            
  855. void CCKTBLControl::SetSelAttr( CKTBL_ATTRIB FAR* attrib )     
  856. {
  857.     CKTBLSetSelAttr( GetSafeHwnd(), attrib ); 
  858. }
  859.                             
  860. void CCKTBLControl::ModifySelAttr( CKTBL_ATTRIB FAR* attrib, short fields, DWORD formtMask )    
  861. {
  862.     CKTBLModifySelAttr( GetSafeHwnd(), attrib, fields, formtMask );    
  863. }
  864.                             
  865. void CCKTBLControl::ClearSelection()
  866. {       
  867.     CKTBLClearSelection(GetSafeHwnd() );
  868. }
  869.                             
  870. void CCKTBLControl::SetSelection( RECT FAR* cells ) 
  871. {                  
  872.     CKTBLSetSelection( GetSafeHwnd(), cells );
  873. }
  874.                             
  875. void CCKTBLControl::ChangeSelection( RECT FAR* cells, int index )
  876. {     
  877.     CKTBLChangeSelection( GetSafeHwnd(), cells,  index );
  878. }
  879.                             
  880. void CCKTBLControl::AddSelection( RECT FAR* cells )
  881. {              
  882.     CKTBLAddSelection( GetSafeHwnd(), cells );
  883. }
  884.                             
  885. void CCKTBLControl::SetSelectionOrg( RECT FAR* cells, POINT FAR* origin )
  886. {                                        
  887.     CKTBLSetSelectionOrg( GetSafeHwnd(), cells, origin );
  888. }
  889.                             
  890. void CCKTBLControl::AddSelectionOrg( RECT FAR* cells, POINT FAR* origin )
  891. {                                  
  892.     CKTBLAddSelectionOrg( GetSafeHwnd(), cells, origin );
  893. }
  894.                             
  895. int CCKTBLControl::GetSelectionSize()
  896. {       
  897.     return CKTBLGetSelectionSize( GetSafeHwnd() );
  898. }
  899.                             
  900. BOOL CCKTBLControl::GetSelection( RECT FAR * cells, int n )
  901. {                            
  902.     return CKTBLGetSelection( GetSafeHwnd(), cells, n );
  903. }
  904.         
  905. /////////////////////////////////////////////////////////////////////////////
  906. // CCKTBLControl Message Map
  907.       
  908.  
  909. BEGIN_MESSAGE_MAP(CCKTBLControl, CWnd)
  910.     //{{AFX_MSG_MAP(CCKTBLControl) 
  911.     ON_MESSAGE( CKTBL_EDIT_START,         OnMsgEditStart )
  912.     ON_MESSAGE( CKTBL_EDIT_END,         OnMsgEditEnd )
  913.     ON_MESSAGE( CKTBL_EDIT_CANCELLED,     OnMsgEditCancelled )
  914.                                                                    
  915.     ON_MESSAGE( CKTBL_RESIZE_COLUMN_START,     OnMsgResizeColumnStart )
  916.     ON_MESSAGE( CKTBL_RESIZE_COLUMN_END,     OnMsgResizeColumnEnd )
  917.     ON_MESSAGE( CKTBL_RESIZE_ROW_START,     OnMsgResizeRowStart )
  918.     ON_MESSAGE( CKTBL_RESIZE_ROW_END,         OnMsgResizeRowEnd )
  919.     
  920.     ON_MESSAGE( CKTBL_CHANGED_CURRENTCELL,     OnMsgChangedCurrentCell )
  921.     ON_MESSAGE( CKTBL_CHANGED_SELECTION,     OnMsgChangedSelection )
  922.     ON_MESSAGE( CKTBL_CLICKED_CELL,         OnMsgClickedCell )
  923.     ON_MESSAGE( CKTBL_DOUBLECLICKED_CELL,     OnMsgDoubleClickedCell )
  924.     
  925.     ON_MESSAGE( CKTBL_CHANGE_CURSOR,     OnMsgChangeCursor )
  926.      
  927.     ON_MESSAGE( CKTBL_HSCROLL_BEGIN,     OnMsgHScrollBegin )
  928.     ON_MESSAGE( CKTBL_HSCROLL_END,         OnMsgHScrollEnd )
  929.     ON_MESSAGE( CKTBL_VSCROLL_BEGIN,     OnMsgVScrollBegin )
  930.     ON_MESSAGE( CKTBL_VSCROLL_END,         OnMsgVScrollEnd )
  931.     //}}AFX_MSG_MAP  
  932.  
  933. END_MESSAGE_MAP()
  934.            
  935.      
  936.            
  937. /////////////////////////////////////////////////////////////////////////////
  938. // CCKTBLControl overridables (default implementations)
  939.                                   
  940.           
  941. //----------------------------------------------------------------------------------- 
  942. // Overridables that provide hooks for resizing rows and columns 
  943. // return TRUE to use default behavior
  944. // return FALSE to inhibit default behavior
  945.                    
  946. BOOL CCKTBLControl::OnEditStart( int row, int col, CString text )
  947. {               
  948.     // called when a cell is to be edited
  949.     // text contains the current contents of the cell 
  950.     // return FALSE to inhibit editing of cell
  951.     
  952.     return TRUE;
  953. }
  954.  
  955. BOOL CCKTBLControl::OnEditEnd( int row, int col, CString text)
  956. {      
  957.     // called when a cell has been successfully edited
  958.     // return FALSE to inhibit storing of 'text' into cell
  959.     
  960.     return TRUE;
  961. }
  962.  
  963. //----------------------------------------------------------------------------------- 
  964. // Overridables that provide notification on editing of cells
  965.  
  966. void CCKTBLControl::OnEditCancelled(int row, int col )
  967. {
  968.     // called when user has cancelled editing of a cell
  969. }
  970.                          
  971.        
  972. //----------------------------------------------------------------------------------- 
  973. // Overridables that provide hooks for resizing rows and columns 
  974. // return TRUE to use default behavior
  975. // return FALSE to inhibit default behavior
  976.                          
  977. BOOL CCKTBLControl::OnResizeColumnStart( int column )
  978. {              
  979.     // called when the user tries to adjust the width of a column 
  980.     return TRUE;
  981. }
  982.  
  983. BOOL CCKTBLControl::OnResizeColumnEnd( int column, long width )
  984. {          
  985.     // called after the user has changed the column width
  986.     return TRUE;
  987. }
  988.  
  989. BOOL CCKTBLControl::OnResizeRowStart( int row  )
  990. {     
  991.     // called when the user tries to adjust the height of a row 
  992.     return TRUE;
  993. }
  994.  
  995. BOOL CCKTBLControl::OnResizeRowEnd( int row, long height )
  996. {
  997.     // called after the user has changed the row height
  998.     return TRUE;
  999. }
  1000.            
  1001. //----------------------------------------------------------------------------------- 
  1002. // Overridables that provide general notification on actions performed by the user
  1003.            
  1004. void CCKTBLControl::OnChangedCurrentCell()
  1005. {              
  1006.     // called when current cell has changed
  1007. }
  1008.  
  1009. void CCKTBLControl::OnChangedSelection()
  1010. {
  1011.     // called when selection has changed
  1012. }
  1013.  
  1014. void CCKTBLControl::OnClickedCell( int row, int col )
  1015. {
  1016.     // called when user has clicked on a cell
  1017. }
  1018.  
  1019. void CCKTBLControl::OnDoubleClickedCell( int row, int col )
  1020.     // called when user has double clicked on a cell
  1021. }
  1022.              
  1023. //----------------------------------------------------------------------------------- 
  1024. // Overridables that provide hooks for custom mouse cursors  
  1025. // return TRUE to use default behavior
  1026. // return FALSE to override default behavior
  1027.              
  1028. BOOL CCKTBLControl::OnChangeCursor( int state )
  1029. {    
  1030.     // called when the mouse cursor is to be changed
  1031.     // return FALSE from this method if you want override the default behaviour and
  1032.     // set the mouse cursor according to following constants from cktbl.h
  1033.     //    CKTBL_CURSOR_NULL            0
  1034.     //    CKTBL_CURSOR_STD             Normal cursor over cells
  1035.     //    CKTBL_CURSOR_RESIZE_ROW         Cursor for resizing rows
  1036.     //    CKTBL_CURSOR_RESIZE_COL         Cursor for resizing columns
  1037.       
  1038.     return TRUE;
  1039. }
  1040.          
  1041. //----------------------------------------------------------------------------------- 
  1042. // Overridables that provide hooks for dynamically extending the table
  1043. // when the user scrolls over the bounds
  1044.                  
  1045. void CCKTBLControl::OnHScrollBegin()
  1046. {     
  1047.     // called when use tries to scroll to the left of the leftmost column 
  1048.     // i.e. user presses cursor left in the leftmost column
  1049. }
  1050. void CCKTBLControl::OnHScrollEnd()
  1051.     // called when use tries to scroll to the right of the rightmost column
  1052.     // i.e. user presses cursor right in the rightmost column
  1053. }
  1054.  
  1055. void CCKTBLControl::OnVScrollBegin()
  1056. {    
  1057.     // called when use tries to scroll above first row
  1058.     // i.e. user presses cursor up in the first row
  1059. }                                 
  1060.  
  1061. void CCKTBLControl::OnVScrollEnd()
  1062. {
  1063.     // called when use tries to scroll below the last row  
  1064.     // i.e. user presses cursor right in the last row
  1065. }
  1066.          
  1067.            
  1068.            
  1069. /////////////////////////////////////////////////////////////////////////////
  1070. // CCKTBLControl message handlers
  1071.                                   
  1072.  
  1073. LRESULT CCKTBLControl::OnMsgEditStart( WPARAM wParam, LPARAM lParam )
  1074. {    
  1075.     CKTBL_EDITARG * editArg = (CKTBL_EDITARG*) lParam; 
  1076.     if( OnEditStart(editArg->row, editArg->column, editArg->text ))        
  1077.         Default();     
  1078.     return 0;
  1079. }
  1080. LRESULT CCKTBLControl::OnMsgEditEnd( WPARAM wParam, LPARAM lParam )
  1081. {                  
  1082.     CKTBL_EDITARG * editArg = (CKTBL_EDITARG*) lParam;         
  1083.     if( OnEditEnd( editArg->row, editArg->column, editArg->text ))        
  1084.         Default();
  1085.     return 0;
  1086. }
  1087. LRESULT CCKTBLControl::OnMsgEditCancelled( WPARAM wParam, LPARAM lParam )
  1088. {
  1089.     OnEditCancelled( wParam, (int) lParam );
  1090.     return 0;
  1091. }                                                                        
  1092. LRESULT CCKTBLControl::OnMsgResizeColumnStart( WPARAM wParam, LPARAM lParam )
  1093. {
  1094.     if(OnResizeColumnStart(wParam)) 
  1095.         return Default();
  1096.     else    
  1097.         return FALSE;
  1098.     return 0;
  1099. }
  1100. LRESULT CCKTBLControl::OnMsgResizeColumnEnd( WPARAM wParam, LPARAM lParam )
  1101. {
  1102.     if(OnResizeColumnEnd(wParam,lParam))
  1103.         Default();
  1104.     return 0;
  1105. }
  1106. LRESULT CCKTBLControl::OnMsgResizeRowStart( WPARAM wParam, LPARAM lParam )
  1107. {
  1108.     if(OnResizeRowStart(wParam))
  1109.         return Default();
  1110.     else
  1111.         return FALSE;
  1112.     return 0;
  1113. }                 
  1114. LRESULT CCKTBLControl::OnMsgResizeRowEnd( WPARAM wParam, LPARAM lParam )
  1115. {
  1116.     if(    OnResizeRowEnd(wParam,lParam))
  1117.         Default();
  1118.     return 0;
  1119. }
  1120. LRESULT CCKTBLControl::OnMsgChangedCurrentCell( WPARAM wParam, LPARAM lParam )
  1121. {
  1122.     OnChangedCurrentCell();
  1123.     return 0;
  1124. }
  1125. LRESULT CCKTBLControl::OnMsgChangedSelection( WPARAM wParam, LPARAM lParam )
  1126. {
  1127.     OnChangedSelection();
  1128.     return 0;
  1129. }
  1130. LRESULT CCKTBLControl::OnMsgClickedCell( WPARAM wParam, LPARAM lParam )
  1131. {
  1132.     OnClickedCell(wParam, (int)lParam);
  1133.     return 0;
  1134. }
  1135. LRESULT CCKTBLControl::OnMsgDoubleClickedCell( WPARAM wParam, LPARAM lParam )
  1136. {
  1137.     OnDoubleClickedCell(wParam, (int)lParam);
  1138.     return 0;
  1139. }
  1140. LRESULT CCKTBLControl::OnMsgChangeCursor( WPARAM wParam, LPARAM lParam )
  1141. {
  1142.     if(OnChangeCursor(wParam))
  1143.         Default();
  1144.     return 0;
  1145. }    
  1146. LRESULT CCKTBLControl::OnMsgHScrollBegin( WPARAM wParam, LPARAM lParam )
  1147. {
  1148.     OnHScrollBegin();
  1149.     return 0;
  1150. }
  1151. LRESULT CCKTBLControl::OnMsgHScrollEnd( WPARAM wParam, LPARAM lParam )
  1152. {
  1153.     OnHScrollEnd();
  1154.     return 0;
  1155. }
  1156. LRESULT CCKTBLControl::OnMsgVScrollBegin( WPARAM wParam, LPARAM lParam )
  1157. {
  1158.     OnVScrollBegin();
  1159.     return 0;
  1160. }
  1161. LRESULT CCKTBLControl::OnMsgVScrollEnd( WPARAM wParam, LPARAM lParam )
  1162. {         
  1163.     OnVScrollEnd();
  1164.     return 0;
  1165. }                               
  1166.