home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Unleashed / Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso / repease / rep_fmt.c < prev    next >
C/C++ Source or Header  |  1995-08-14  |  19KB  |  516 lines

  1. /*==============================================================================
  2.    REP_FMT.C
  3.    ReportEase Plus formatting and font functions.
  4.  
  5.    ReportEase Plus
  6.    Sub Systems, Inc.
  7.    ReportEase Plus, Copyright (c) 1993, Sub Systems, Inc. All Rights Reserved.
  8.    159 Main Street, #8C, Stoneham,  MA 02180 
  9.    (617) 438-8901.
  10.  
  11.    Software License Agreement  (1993)              
  12.    ----------------------------------
  13.    This license agreement allows the purchaser the right to modify the 
  14.    source code to incorporate in their application.
  15.    The target application must not be distributed as a standalone report writer
  16.    or a mail merge product.
  17.    Sub Systems, Inc. reserves the right to prosecute anybody found to be 
  18.    making illegal copies of the executable software or compiling the source
  19.    code for the purpose of selling there after.
  20.  
  21. ===============================================================================*/
  22. #include "windows.h"
  23.  
  24. #if defined (_WIN32)
  25.    #if !defined(WIN32)
  26.      #define WIN32
  27.    #endif
  28. #endif
  29. #if !defined(WIN32) 
  30.   #include "print.h"
  31. #endif
  32.  
  33. #include "stdio.h"
  34. #include "stdlib.h"
  35. #include "ctype.h"
  36. #include "fcntl.h"
  37. #include "io.h"
  38. #include "sys\types.h"
  39. #include "sys\stat.h"
  40. #include "math.h"
  41. #include "string.h"
  42. #include "setjmp.h"
  43.  
  44. #include "commdlg.h"
  45.  
  46. #include "rep.h"
  47.  
  48. #define  PREFIX extern
  49. #include "rep1.h"
  50.  
  51. /******************************************************************************
  52.     FrFonts:
  53.     Allow the user to select a font for the current item.
  54. ******************************************************************************/
  55. FrFonts()
  56. {
  57.     int i,NewFont,SaveHeight,SaveWidth,GroupItem;
  58.     CHOOSEFONT cFont;
  59.     LOGFONT lFont;
  60.     int font;
  61.  
  62.     if (SelItem<0) return TRUE;   // no item selected
  63.     if (item[SelItem].type!=LABEL && item[SelItem].type!=FIELD && item[SelItem].type!=GROUP) return TRUE; // aplicable to label and field only
  64.     if (item[SelItem].type==FIELD && field[item[SelItem].field].type==TYPE_PICT) return TRUE;  // picture type item does not use font
  65.  
  66.     // make a copy of the old font
  67.     font=item[SelItem].font;
  68.     FarMove(&(FrFont[font].lFont),&lFont,sizeof(LOGFONT));
  69.     
  70.     // convert the height and width to the pixel units (ChooseFont requirement)
  71.     SaveHeight=lFont.lfHeight;
  72.     lFont.lfHeight=UnitToPixY(SaveHeight);
  73.     if (SaveHeight>=0) {                // compensate for rouding
  74.        if (SaveHeight>PixToUnitY(lFont.lfHeight)) lFont.lfHeight++;
  75.     }
  76.     else {
  77.        if (SaveHeight<PixToUnitY(lFont.lfHeight)) lFont.lfHeight--;
  78.     }
  79.  
  80.     SaveWidth=lFont.lfWidth;
  81.     lFont.lfWidth=UnitToPixX(SaveWidth);
  82.     if (SaveWidth>PixToUnitX(lFont.lfWidth)) lFont.lfWidth++;
  83.  
  84.  
  85.     // fill the CHOOSEFONT structure
  86.     FarMemSet(&cFont,0,sizeof(CHOOSEFONT));
  87.     cFont.lStructSize=sizeof(CHOOSEFONT);
  88.     cFont.hwndOwner=hFrWnd;
  89.     cFont.hDC=hPrtDC;                 // print device context
  90.     cFont.lpLogFont=&lFont;
  91.     cFont.Flags=CF_BOTH|CF_EFFECTS|CF_INITTOLOGFONTSTRUCT;
  92.     cFont.rgbColors=item[SelItem].TextColor;
  93.     
  94.     if (!ChooseFont(&cFont)) return FALSE;
  95.  
  96.     // apply the chosen color to the item 
  97.     item[SelItem].TextColor=cFont.rgbColors;
  98.     
  99.     // convert the height and width to the logical units
  100.     lFont.lfHeight=PixToUnitY(lFont.lfHeight);
  101.     lFont.lfWidth=PixToUnitX(lFont.lfWidth);
  102.                     
  103.     // apply the chosen font to the item 
  104.     for (i=0;i<TotalFonts;i++) {       // check for any exising font
  105.        if (!FrFont[i].InUse) continue;
  106.        if (FrFont[i].IsPict) continue;
  107.        if (IsSameFont(&(FrFont[i].lFont),&(lFont))) {  // matching font already exists
  108.           item[SelItem].font=i;        // select the match font
  109.           break;
  110.        }
  111.     }
  112.  
  113.     if (i==TotalFonts) {               // create new font
  114.        // create a new font slot
  115.        NewFont=FindOpenSlot();
  116.        if (NewFont==-1) {
  117.           MessageBox(hFrWnd,"Ran out of Font Table",NULL,MB_OK);
  118.           return FALSE;
  119.        }
  120.  
  121.        // copy the font specifications
  122.        FarMove(&lFont,&(FrFont[NewFont].lFont),sizeof(LOGFONT));
  123.        if (!CreateOneFont(hFrDC,NewFont)) {
  124.           InitFrObject(NewFont);
  125.           return FALSE;
  126.        }
  127.  
  128.        item[SelItem].font=NewFont;             // select the new font
  129.     }
  130.     if (item[SelItem].type==FIELD) CreateFieldLabel(item[SelItem].field,item[SelItem].label,item[SelItem].width,item[SelItem].font);  // create field label
  131.     if (item[SelItem].type==LABEL) UpdateLabelSize(SelItem);
  132.  
  133.     // if the current item is a group item, apply this font to all group items
  134.     if (item[SelItem].type==GROUP) {// update all items in the group
  135.        GroupItem=SelItem;
  136.        MarkGroupItems();       // mark the items in the group
  137.        for (i=0;i<TotalItems;i++) {
  138.           if (item[i].InGroup) {
  139.              if (item[i].type==LABEL || item[i].type==FIELD) {
  140.                  item[i].font=item[GroupItem].font;
  141.                  item[i].TextColor=item[GroupItem].TextColor;
  142.              }
  143.              if (item[i].type==FIELD) CreateFieldLabel(item[i].field,item[i].label,item[i].width,item[i].font);  // create field label
  144.              if (item[i].type==LABEL) UpdateLabelSize(i);
  145.              item[i].InGroup=FALSE;
  146.           }
  147.        }
  148.     }
  149.  
  150.     FrPaint();
  151.     FrModified=TRUE;
  152.  
  153.     return TRUE;
  154. }
  155.  
  156. /******************************************************************************
  157.     FindOpenSlot:
  158.     Find an empty slot in the FrFont arrays to create a new font/picture.
  159.     If not slots are available,  the document is checked for duplicate 
  160.     and deleted fonts to free up a slot.
  161.     If successful, the routine returns the index to the FrFont array,
  162.     otherwise it returns -1
  163. ******************************************************************************/
  164. FindOpenSlot()
  165. {
  166.     int i,j,NewFont,SimilarFont[MAX_FONTS];
  167.     BOOL FontUsed[MAX_FONTS];
  168.     BYTE font1,font2;
  169.     BOOL OneSlotFreed;
  170.  
  171.  
  172.     // find an unused slot 
  173.     LOOK_FOR_UNUSED_SLOT:
  174.     for (i=0;i<TotalFonts;i++) {
  175.        if (!(FrFont[i].InUse)) {
  176.          InitFrObject(i);
  177.          return i;
  178.        }
  179.     }
  180.     
  181.     if (TotalFonts<MAX_FONTS) {    // create a new font in a new slot 
  182.        NewFont=TotalFonts;
  183.        TotalFonts++;
  184.        InitFrObject(NewFont);
  185.        return NewFont;
  186.     }
  187.     
  188.     // consolidate fonts in the current file to open up a slot 
  189.     
  190.     // examine the font table for similar fonts 
  191.     SimilarFont[0]=0;
  192.     for (i=1;i<MAX_FONTS;i++) {
  193.        SimilarFont[i]=i;
  194.        if (FrFont[i].IsPict) continue; // don't touch the pictures 
  195.        
  196.        for(j=0;j<=i;j++) {       // compare this font with earlier fonts 
  197.         if(!(FrFont[j].IsPict)
  198.            && IsSameFont(&(FrFont[j].lFont),&(FrFont[i].lFont)) ){
  199.               SimilarFont[i]=j;
  200.               break;
  201.            } 
  202.        }
  203.     }
  204.     
  205.     //* adjust the fonts in the document 
  206.     for (i=0;i<MAX_FONTS;i++) FontUsed[i]=FALSE;  // initialize 'font use' table 
  207.  
  208.     for (i=0;i<TotalItems;i++) {
  209.        if (item[i].type!=LABEL && item[i].type!=FIELD) continue;
  210.        font1=item[i].font;
  211.        font2=SimilarFont[font1];
  212.        item[i].font=font2;             // use the new font
  213.        FontUsed[font2]=TRUE;           // keep track of fonts actually used 
  214.     }
  215.  
  216.     //** mark the freed fonts as unused **
  217.     OneSlotFreed=FALSE;
  218.     for (i=1;i<MAX_FONTS;i++) {         // the default font (1) never freed 
  219.        if (FrFont[i].InUse && SimilarFont[i]!=i) {DeleteFrObject(i);OneSlotFreed=TRUE;}            // delete font/picture 
  220.        if (FrFont[i].InUse && !FontUsed[i])      {DeleteFrObject(i);OneSlotFreed=TRUE;}
  221.     }
  222.  
  223.     if (OneSlotFreed) goto LOOK_FOR_UNUSED_SLOT;
  224.     else {
  225.         MessageBox(hFrWnd,"Ran Out of Font/Picture Table",NULL,MB_OK);
  226.         return -1;
  227.     }
  228. }
  229.  
  230. /******************************************************************************
  231.     IsSameFont:
  232.     This routine compares two LOGFONT structures and returns a TRUE value
  233.     if they are the same.
  234. ******************************************************************************/
  235. BOOL IsSameFont(LOGFONT far *lFont1,LOGFONT far *lFont2)
  236. {
  237.     if (lFont1->lfHeight!=lFont2->lfHeight) return FALSE;
  238.     if (lFont1->lfWidth!=lFont2->lfWidth) return FALSE;
  239.     if (lFont1->lfEscapement!=lFont2->lfEscapement) return FALSE;
  240.     if (lFont1->lfOrientation!=lFont2->lfOrientation) return FALSE;
  241.     if (lFont1->lfWeight!=lFont2->lfWeight) return FALSE;
  242.     if (lFont1->lfItalic!=lFont2->lfItalic) return FALSE;
  243.     if (lFont1->lfUnderline!=lFont2->lfUnderline) return FALSE;
  244.     if (lFont1->lfStrikeOut!=lFont2->lfStrikeOut) return FALSE;
  245.     if (lFont1->lfCharSet!=lFont2->lfCharSet) return FALSE;
  246.     if (lFont1->lfOutPrecision!=lFont2->lfOutPrecision) return FALSE;
  247.     if (lFont1->lfClipPrecision!=lFont2->lfClipPrecision) return FALSE;
  248.     if (lFont1->lfQuality!=lFont2->lfQuality) return FALSE;
  249.     if (lFont1->lfPitchAndFamily!=lFont2->lfPitchAndFamily) return FALSE;
  250.     if (lstrcmp(lFont1->lfFaceName,lFont2->lfFaceName)!=0) return FALSE;
  251.     return TRUE;
  252. }
  253.  
  254. /******************************************************************************
  255.     SelectBestFont:
  256.     This routine creates a font of the specified typeface and pointsize.
  257.     This routine constructs the LOGFONT structure for the font and creates
  258.     the font handle.
  259. ******************************************************************************/
  260. SelectBestFont(HDC hDC,int NewFont,LPSTR Typeface,int PointSize)
  261. {
  262.     LOGFONT far *lFont;
  263.  
  264.     if (FrFont[NewFont].IsPict) return TRUE;      // not a true font 
  265.  
  266.  
  267.     // File the logfont structure
  268.     lFont=&(FrFont[NewFont].lFont);
  269.     FarMemSet(lFont,0,sizeof(LOGFONT));
  270.     lFont->lfHeight=-(int)((PointSize*(long)UNITS_PER_INCH)/72);   // specify in logical units.
  271.     lstrcpy(lFont->lfFaceName,Typeface); 
  272.  
  273.     if (!CreateOneFont(hDC,NewFont)) return FALSE; // create a font
  274.     
  275.     return TRUE;
  276. }
  277.  
  278. /******************************************************************************
  279.     CreateOneFont:
  280.     This routine creates a font whose table index is given by the argument.
  281.     This  table must already have the LOGFONT structure filled.
  282.     This routine selects the new font into the display context.
  283.     The new font is created for the specified display context.
  284. ******************************************************************************/
  285. CreateOneFont(HDC hDC,int NewFont)
  286. {
  287.     int i;
  288.     TEXTMETRIC met;
  289.     LOGFONT lFont;
  290.  
  291.     if (FrFont[NewFont].IsPict) return TRUE;   // not a true font 
  292.  
  293.     if (FrFont[NewFont].hFont) {               // delete old font 
  294.        hFrCurFont=GetStockObject(SYSTEM_FONT); // deselect first 
  295.        SelectObject(hFrDC,hFrCurFont);
  296.        SelectObject(hMemDC,hFrCurFont);
  297.        
  298.        DeleteObject(FrFont[NewFont].hFont);
  299.        FrFont[NewFont].hFont=NULL;
  300.     }
  301.  
  302.     lFont=FrFont[NewFont].lFont;
  303.     FrFont[NewFont].hFont=CreateFontIndirect(&lFont);
  304.  
  305.     if (FrFont[NewFont].hFont==NULL) return FALSE;
  306.  
  307.     //** setup the character width table for the new font 
  308.     if (NULL==SelectObject(hDC,FrFont[NewFont].hFont)) return FALSE;
  309.     if (!GetTextMetrics(hDC,&met)) return FALSE;
  310.     if (met.tmAscent==0) return FALSE;
  311.     if (NewFont==0) FrTextMet=met;           // default font metrics 
  312.  
  313.     // build the character width table
  314.     if (SessionType=='F' && GetCharWidth(hDC,0,255,FrFont[NewFont].CharWidth)) {
  315.        for (i=0;i<256;i++) {                             // adjust the character width table 
  316.           FrFont[NewFont].CharWidth[i]=FrFont[NewFont].CharWidth[i]-met.tmOverhang;
  317.        }
  318.     }
  319.     else {      // try alternate method now
  320.        SIZE  size;
  321.        FrFont[NewFont].CharWidth[0]=0;
  322.        for (i=1;i<256;i++) {
  323.           msg[0]=i;  //get the text extent of each character
  324.           msg[1]=0;
  325.           GetTextExtentPoint(hDC,msg,1,&size);
  326.           FrFont[NewFont].CharWidth[i]=size.cx;
  327.        }
  328.     }
  329.  
  330.     //** calculate the distance from the base of the font to the top of the font 
  331.     FrFont[NewFont].BaseHeight=met.tmAscent;
  332.     FrFont[NewFont].height=met.tmHeight;        // actual font height
  333.     
  334.     FrFont[NewFont].InUse=TRUE;
  335.  
  336.     return TRUE;
  337. }
  338.  
  339. /******************************************************************************
  340.     FrCreateDIB:
  341.     This routine creates a device indenpendent bitmap from a source
  342.     bitmap.  The source bitmap is assumed to be compatible with the
  343.     current display context.
  344.     The newly created device independent bitmap is stored in the FrFont
  345.     structure in an open slot.
  346.     If successful, the routine returns the index of the newly created
  347.     bitmap, otherwise it returns -1.
  348. ******************************************************************************/
  349. FrCreateDIB(HBITMAP hBM)
  350. {
  351.     HANDLE hInfo,hImage;
  352.     LPSTR  pImage;
  353.     LPBITMAPINFOHEADER pInfo;
  354.     int   pict;
  355.     DWORD  InfoSize,ImageSize;
  356.     BITMAP bm;
  357.  
  358.     //**** find an empty slot in the font/picture table ****
  359.     if ((pict=FindOpenSlot())==-1) return -1;
  360.  
  361.     GetObject(hBM,sizeof(BITMAP),(LPSTR)&bm);     // get the dimension of bit map 
  362.     
  363.     //********** create the device independent bitmap ***********************
  364.     InfoSize=sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);  // create a 16 color bitmap structure 
  365.  
  366.     if (NULL==(hInfo=GlobalAlloc(GMEM_MOVEABLE,InfoSize))
  367.       ||NULL==(pInfo=(LPBITMAPINFOHEADER)GlobalLock(hInfo)) ) {
  368.         MessageBox(hFrWnd,"Ran out of memory for Bitmap Info!",NULL,MB_OK);
  369.         return -1;
  370.     }
  371.  
  372.     //***** fill in the info structure ******
  373.     pInfo->biSize=sizeof(BITMAPINFOHEADER);
  374.     pInfo->biWidth=bm.bmWidth;
  375.     pInfo->biHeight=bm.bmHeight;
  376.     pInfo->biPlanes=1;                       // DIB have plane = 1 
  377.     pInfo->biBitCount=8;                     // 8 bits per pixel or color 
  378.     pInfo->biCompression=BI_RGB;
  379.     pInfo->biSizeImage=0;                    // initialize to zero 
  380.     pInfo->biXPelsPerMeter=0;
  381.     pInfo->biYPelsPerMeter=0;
  382.     pInfo->biClrUsed=256;                    // 256 colors
  383.     pInfo->biClrImportant=0;                 // all colors important 
  384.  
  385.     if (!GetDIBits(hFrDC,hBM,0,bm.bmHeight,NULL,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
  386.         MessageBox(hFrWnd,"Error Creating Device Independent Bitmap Structure!",NULL,MB_OK);
  387.         return -1;
  388.     }
  389.  
  390.  
  391.     ImageSize=pInfo->biSizeImage;
  392.     if (NULL==(hImage=GlobalAlloc(GMEM_MOVEABLE,ImageSize))
  393.       ||NULL==(pImage=GlobalLock(hImage)) ) {
  394.         MessageBox(hFrWnd,"Ran out of memory for Bitmap Image!",NULL,MB_OK);
  395.         return -1;
  396.     }
  397.  
  398.     if (!GetDIBits(hFrDC,hBM,0,bm.bmHeight,pImage,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
  399.         MessageBox(hFrWnd,"Error Creating Device Independent Bitmap Image!",NULL,MB_OK);
  400.         return -1;
  401.     }
  402.     
  403.     GlobalUnlock(hInfo);
  404.     GlobalUnlock(hImage);
  405.  
  406.     FrFont[pict].InUse=TRUE;
  407.     FrFont[pict].PictHeight=(UINT)((DWORD)(bm.bmHeight)*72L/(DWORD)ResY); // dimension in point sizes 
  408.     FrFont[pict].PictWidth=(UINT)((DWORD)(bm.bmWidth)*72L/(DWORD)ResX);
  409.     FrFont[pict].ImageSize=ImageSize;
  410.     FrFont[pict].hImage=hImage;
  411.     FrFont[pict].InfoSize=InfoSize;
  412.     FrFont[pict].hInfo=hInfo;
  413.     FrFont[pict].IsPict=TRUE;
  414.  
  415.     return pict;
  416. }
  417.  
  418. /******************************************************************************
  419.     FrXlateDIB:
  420.     This routine creates a device specific bitmap from a device independent
  421.     bit map.  The first argument specifies the device context to build
  422.     the bitmap for. The second argument specifies an index into the FrFont
  423.     structure that contains the handle to the device independent image and
  424.     information.
  425. ******************************************************************************/
  426. FrXlateDIB(HDC hDC,int pict)
  427. {
  428.      int i;
  429.      BYTE planes,BitsPerPixel;
  430.      LPBITMAPINFOHEADER pInfo;
  431.      LPSTR pImage;
  432.      BITMAP bm;
  433.  
  434.  
  435.      if (!(FrFont[pict].IsPict)) return TRUE;   // not a picutre element 
  436.  
  437.      //*********** lock the DIB handles ***********
  438.      if (NULL==(pImage=GlobalLock(FrFont[pict].hImage)) 
  439.       || NULL==(pInfo=(LPBITMAPINFOHEADER)GlobalLock(FrFont[pict].hInfo)) ) { 
  440.          MessageBox(hFrWnd,"Ran out of memory for Bitmap Image and info!",NULL,MB_OK);
  441.          return FALSE;
  442.      }
  443.      
  444.      //******** delete old bitmap if present *******
  445.      if (FrFont[pict].hBM) {                      // delete the old bit map 
  446.         DeleteObject(FrFont[pict].hBM);
  447.         FrFont[pict].hBM=0;
  448.      }
  449.  
  450.     //********* create our bitmap *******************************************
  451.     planes=GetDeviceCaps(hDC,PLANES);             // get the device charistrics 
  452.     BitsPerPixel=GetDeviceCaps(hDC,BITSPIXEL);
  453.  
  454.     if (NULL==(FrFont[pict].hBM=CreateBitmap((UINT)(pInfo->biWidth),(UINT)(pInfo->biHeight),planes,BitsPerPixel,NULL))) {
  455.                 MessageBox(hFrWnd,"Error Creating the Bitmap",NULL,MB_OK);
  456.         return FALSE;
  457.     }
  458.     
  459.     if (!SetDIBits(hDC,FrFont[pict].hBM,0,(UINT) pInfo->biHeight,pImage,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
  460.         MessageBox(hFrWnd,"Error Initializing the Bitmap",NULL,MB_OK);
  461.         return FALSE;
  462.     }
  463.  
  464.     GetObject(FrFont[pict].hBM,sizeof(BITMAP),(LPSTR)&bm);    // get the dimension of bit map 
  465.     FrFont[pict].bmHeight=bm.bmHeight;                        // actual dimensions 
  466.     FrFont[pict].bmWidth=bm.bmWidth;
  467.     
  468.     //************ calculate the display height ******************
  469.     FrFont[pict].height=FrFont[pict].BaseHeight=(int)(((long)FrFont[pict].PictHeight*(long)UNITS_PER_INCH)/72L);
  470.     FrFont[pict].CharWidth[0]=(int)(((long)FrFont[pict].PictWidth*(long)UNITS_PER_INCH)/72L);
  471.     for (i=1;i<256;i++) FrFont[pict].CharWidth[i]=FrFont[pict].CharWidth[0];
  472.  
  473.     //******** unlock the DIB info and image ********************
  474.     GlobalUnlock(FrFont[pict].hImage);
  475.     GlobalUnlock(FrFont[pict].hInfo);
  476.  
  477.     return TRUE;
  478.  
  479. }
  480.  
  481. /******************************************************************************
  482.     DeleteFrObject:
  483.     This routine deletes the font or bitmap for a specified FrFont element.
  484. ******************************************************************************/
  485. DeleteFrObject(int idx)
  486. {
  487.     if (FrFont[idx].InUse) {
  488.        if (FrFont[idx].IsPict) {
  489.           if (FrFont[idx].hBM)    DeleteObject(FrFont[idx].hBM);  // delete bitmap 
  490.           if (FrFont[idx].hImage) GlobalFree(FrFont[idx].hImage); // delete DIB image 
  491.           if (FrFont[idx].hInfo)  GlobalFree(FrFont[idx].hInfo);  // delete DIB info 
  492.        }
  493.        else {
  494.           if (FrFont[idx].hFont)  DeleteObject(FrFont[idx].hFont);
  495.        }
  496.        InitFrObject(idx);
  497.     }
  498.     return TRUE;
  499. }
  500.  
  501. /******************************************************************************
  502.     InitFrObject:
  503.     Initialize a Fr Font Object (font or picutre)
  504. ******************************************************************************/
  505. InitFrObject(int idx)
  506. {
  507.     FrFont[idx].InUse=FALSE;
  508.     FrFont[idx].IsPict=FALSE;
  509.     FrFont[idx].hFont=NULL;
  510.     FarMemSet(&(FrFont[idx].lFont),0,sizeof(LOGFONT));
  511.     FrFont[idx].hBM=NULL;
  512.     FrFont[idx].ImageSize=FrFont[idx].InfoSize=0;
  513.     FrFont[idx].hImage=FrFont[idx].hInfo=NULL;
  514.     return TRUE;
  515. }
  516.