Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Andrzejek on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to set font size and type in TXT file thru VFP6/9 3

Piotr Czekalski

Programmer
May 17, 2024
86
PL
Hi all,

is it possible to programmatically apply font to display text files by command Modi Comm File.TXT - preferably when starting program ?

I use "Modi Comm File.TXT NoEdit" command to display reports (text files contents). I manually set font via: Format-> Font and then Edit->Properites->Apply to TXT->OK. After some time VFP assigns a different font to display TXT files. Then displayed reports lose their format. I taught my clients to manually set the appropriate font format and size themselves, but it's a problem. I use Modi Comm commands in programs in many places in code. I'd rather not change that solution.

Thx for help :)
 
I wrote earlier that I couldn't find Franklin font in registers. I looked through Windows registers of VFP and it wasn't there Screen-4. In options FVP-->IDE I added FoxFont font to TextFile. FoxFont appeared in Windows registers Screen-5. I turned computer off and then turned on. Modi Comm and ModyFile still see Franklin font Screen-6. This would most likely mean that some other entry has a higher priority. I will try other methods you suggested.

This looks like an interesting investigation :cool:

Screen-4

Screen-4.jpg


Screen-5
Screen-5.jpg

Screen-6 (Elvis forever live)
Screen-6.jpg
 

Attachments

  • Screen-4.jpg
    Screen-4.jpg
    99.5 KB · Views: 0
  • Screen-5.jpg
    Screen-5.jpg
    139.4 KB · Views: 0
Last edited:
Yes Dan ! :)

This is probably the main reason.

My FoxUser.DBF
Screen-8.jpgScreen-9.jpg




Incorrect assignment of the font to the text, as I wrote earlier, certainly occurs if programs written in VFP is run several times at the same time. After closing programs, everything is OK. However when client turns off the computer before closing programs, this incorrect state remains. Then the first font alphabetically Arial is assigned to text formatting. The difference is that the incorrect record is most likely created in the FoxUser.DBF file and remains there.
 
Last edited:
Good point from Dan, some of the settings for windows, specifically to reproduce BROWSE windows whe you do BROWSE LAST are also stored in the resource file foxuser.dbf, but I think that's not stored for each and every file you open with MODIFY COMMAND or MODIFY FILE.

And, it seems, Piotr, the keys Text, TextExtension and TextFont you have do their job. I wonder why I don't have them. Ah, I see, I simply have to define them for Type "Text Files", of course!

For me that settings are used for MODIFY FILE. So you may now set this at program start and reset it to how it was at program end.

Then you don't need TEDIT, though I think you have fantastic options to have your own EXE for monospaced text display, better than just an editbox on a form. I would be annoyed with the [Read Only] part of the titlebar caption you get from MODIFY FILE, but that could be addressed with Windows API SetWindowText, if you want.
 
Okay, regarding the data entry in the foxuser.data field, I wouln't like to fiddle with that for an end user foxuser.dbf, but do you even have one?

I usually have an embedded config.fpw with RESOURCE=OFF to suppress a foxuser.dbf creation. Not only for the IDE, but in general, isn't it the DBF file that gets corrupt most often?
 
I rule out using EditBox. No horizontal scrolling. Unfortunately, my clients have a FoxUser.DBF file. Sometimes there are problems with it. Then I delete it. Most of my clients work on terminals, so a permanent system image with the FoxUser.DBF file is loaded during startup of system. I have to replace Modi Comm and Modi File with another solution because with the NoEdit clause it sometimes blocks after selecting a fragment of text by mouse.

Thank you for your help :)
 
For today I used a temporary solution. I prepared the appropriate FOXUSER.DBF file with required font assigned to TXT and other settings. At start of the program code I used SET RESOURCE OFF. In the program code I used the following sequences of commands for display raports:

Code:
Set Resource ON
Modi Comm MyFile.TXT NoEdit
Set Resource OFF

It seems that this solution works. There is no conflict when several programs are open at the same time. I will check it in practice. I think a better solution would be to put "RESOURCE=OFF" to CONFIG.FWP. This should practically limit access to the resource file to the required minimum.
 
Last edited:
I have to replace Modi Comm and Modi File with another solution because with the NoEdit clause it sometimes blocks after selecting a fragment of text by mouse.
I think that problem is due to this setting:
1733696050926.png
Uncheck it, as here, and that shouldn't be a problem anymore. It's a glitch I sometimes get within the IDE, too: While selecting code with the mouse, something causes the selection to get cut out and pasted back several lines below or above, randomly.

I rule out using EditBox. No horizontal scrolling.
The Editbox set to necessary size (even when that's oversized for the form), setting form scrollbars on and maxwidth and maxheight to that of the Editbox - that'd become available.
 
I couldn't find any decent example, so I created a test window to display TXT files with font settings and scrolling vertically and horizontally. I followed Chris' instructions. I added some scaling by height. I gave a spare multiplier of 1.3 value. The scaling is more of an illustrative purpose. It is intended to indicate that such a mechanism is needed.

I encourage you to improve this code :)


Code:
*********************************
* example of displaying txt files
*********************************


XFont=GetFont()

XAt=AT(",",XFont)
XFontName=Substr(XFont,1,xAt-1)
XFont=Stuff(XFont,1,XAt,"")
XAt=AT(",",XFont)
XFontSize=Val(Substr(XFont,1,XAt-1))
XFontStyle=Stuff(XFont,1,XAt,"")

*Wait XFontName+","+Str(XFontSize,2)+","+XFontStyle Wind

IF Empty(XFontName) OR XFontSize=0 OR Empty(XFontStyle)
  Retu
EndIF


****
XFileTXT=GetFile("TXT","File Name TXT")
IF Empty(XFileTXT)
  Retu
EndIF
XBufTXT=FileToStr(XFileTXT)
***


***
XCurFontName  = WFont(1)
XcurFontSize  = WFont(2)
XCurFontStyle = WFont(3)

XCurFM=FontMetric(1,XCurFontName,XCurFontSize,XCurFontStyle)
XEdboxFM=FontMetric(1,XFontName,XFontSize,XFontStyle)

IF XEdboxFM>=XCurFM
  XFontFactor=(XEdboxFM/XCurFM)*1.3
Else
  XFontFactor=1.3
EndIF


XMaxEdBoxHeight=Memlines(XBufTXT)*XFontFactor
***

ob1=CREATEOBJECT("edytor")
ob1.Show()


RETU




DEFINE CLASS edytor AS FORM

ScaleMode = 0
AutoCenter = .T.

BackColor = RGB(255,255,255)
BorderStyle = 3
Caption = ""
WindowType = 1
ScrollBars=3
Visible =.T.


Top    = 10
Left   = 80
Height = 30
Width  = 80




ADD OBJECT textEdit  AS EditBox 
 
 
Procedure Init
 
With Thisform.textEdit
 
  .Value       =   XBufTXT
  .Top         =   0
  .Left        =   0
  .Height      =   XMaxEdBoxHeight
  .Width       =   600
  .Format      =    ""
  .FontName    =   XFontName
  .FontSize    =    XFontSize
  .Visible     =   .T.
  .Enabled     =   .T.
  .ScrollBars  =    0
 
EndWith
 
EndProc
 


ENDDEFINE
 
Last edited:
I think fontmetirc is imprecise, as I didn't get the correct editbox width adjusting to a given text, even with monospaced fonts. But I'll try to improve this.
 
I removed FontMetric() scaling in the code on my computer for testing. I left only Memlines(). I used a large font size. It stopped displaying properly. With one line in the text file, nothing was visible. With scaling, it displays with a slight excess ( spare multiplier of 1.3 value)

Ekran7.jpg

I slightly improved the published code.
 
Last edited:
One aspect is monospaced vs proportional fonts. The former have fixed width, but even that is not only the character width, there's also letter spacing. In proportional fonts this can even become negative (aka kerning) in letter combinations like AV, for example. Therefore character, average character width or maximum character width are not helpful. In monospaced fonts that's easier, as all letters have same width, such fonts are designed to align perfectly in successive lines.

Fontmetric, for example, gives you a large width for an Arial A and V, but AV together are not simply the sum of both width because of kerning. The best thing you have for measuring width is an autofit Label. The problem with that is it only supports captions up to 256 character length.

Another detail: Height is also not just chracter Height x linesof text, there are fontmetrics for different partial aspects of the font, one of which also is leading, the space between lines, just like there is letter spacing. Those are the major metrics to know and take into account when it comes to calculating the editbox size. Ideally you have a function that takes in text and gives you the dimensions of how large it renders.

But even in simple situation like monospaced fonts you don't get the same results from an autosize label width and height and Fontmetric, though the overall text size in such fonts should simply be character width x length of the longest line and character height x lines count.

Let's look at what a label autosizes to when giving it a single A, a double AA, and two or three lines of AA:
Code:
_screen.Fontname = "Arial"
_screen.FontSize = 12
_screen.AddObject("label1","label")
With _screen.label1
   .fontname="Courier New"
   .fontsize=12
   .autosize=.t.
   .wordwrap = .T.
   .visible = .T.
   .caption="A"
   Clear
   ? 
   ?
   ?
   ?
   ? "A", .width, .height
   ? "---"
   .caption="AA"
   ? "AA", .width, .height
   ? "---"
   .caption="AA"+Chr(13)+Chr(10)+"AA"
   ? "AA"+Chr(13)+Chr(10)+"AA", .width, .height
   ? "---"
   .caption="AA"+Chr(13)+Chr(10)+"AA"+Chr(13)+Chr(10)+"AA"
   ? "AA"+Chr(13)+Chr(10)+"AA"+Chr(13)+Chr(10)+"AA", .width, .height
   ? "---"
   ? "fontmetric: width ", Fontmetric(6,"Courier New",12,"N")," height ",Fontmetric(1,"Courier New",12,"N")
   ? "fontmetric leading (line spacing)", Fontmetric(4,"Courier New",12,"N")
EndWith
A single A label captions makes it a 10x20 rectangle area, AA simply has double width, as you can expect from a monospaced font.
A double line AA does only rise by 18 in height, not 20, but has width 22, why? A mishap aof autosizing of the label, it seems.
But then the Fontmetric height is 18 and Fontmetirc width is 10, leading is 2 pixels, which does not explain why a single line already has leading, I would only expect lines-1 times leading, as there are one less than the lie count of line gaps.

It's somewhat consistent, but when it comes to the editbox on a form, it seems to change a bit. I'll get back to this later, just wanted to share these findings now already.
 
Very interesting Chris. I ran your program.

I did some performance tests of the TXT file browsing program. Today the code allows to display 31 pages of an A4 form. The file has 324927 (325000) characters. It doesn't want to display more.

With much larger numbers of characters (rows) there is a message

"insufficient stack space"

Maybe the barrier is the line (row) counter in EditBox.

An example of a form that I am testing:

Screen-7.jpg




The txt file is loading quickly and forms scrolling smoothly. There are no delays.
 
Last edited:
I think gdiplusx will come to the rescue and make it simple to measure sizes of texts. There's a MeasureString method of a GDI+ Graphics object. Not sure, whether that's also implemented in gdiplusx, but should be doable.
 
I didn't put editbox value to extremes, but I remember I used it for a log display and it can handle a lot of lines '(100s, if not 1000s). Not sure why there would be an error about stack space. There's a maximum recursion level in VFP (usually 127), but this seems not to be about the program stack, but the RAM usage.

An idea would be using multiple editboxes, when you process the text to detmerine its size, you may also determine page breaks and use an editbox per page.

Another completely different idea would be turning txt to pdf and using a pdf viewer for the display job.

I always like to start with own classes/forms etc. to have all options of feature enhancements in the future, but if it gets out of hand, then that would likely do the job, wouldn't it? Instead of printing to PDF you could use foxypreviwers approach to use the libharu library. I once used it for creating PDFs that were printed as receipts, with a QR barcode and a line of text, I have to dig a bit to find that, but it takes far less than these samples I find by Yousfi Benameur on his overblog http://yousfi.over-blog.com/2016/04/libharu-hpdf-library.html

So don't be scared off by the length of his code samples. I think one simple option of the libary is actually what you need, rendering a simple txt file with given font and font size/style to a PDF file.

Edit: A simple solution like this seems to be this FAQ: https://www.tek-tips.com/forums/184/faqs/7355
I havent's tested it, though.
 
Last edited:
It may be a RAM issue. Old DELL computer 4 GB RAM installed, 3 GB for use. I bought one some time ago and have FVP installed on it. My clients had such computers. I had to have similar class to avoid surprises. I will compile the program to EXE and run it on a stronger machine. The TXT file was almost 800 KB. I cut aboutr 2/3 of file. NotePad slowed down operations during text procesing.

Ekran-8.jpg
 
Last edited:
I checked the program on another computer. The problem is in the limit of the Height property for EditBox. At a value slightly above 8400 it does not want to display text content. Program scrolls to the end of the documents list window and then stops scrolling. The last document is cut off. I checked it empirically. It does not show an error. The same effect occurs on my old computer. Maybe there is a way to increase this limit. I did not find such a limit anywhere in the documentation.

Insufficient stack space error message occurs for large files around 1 GB. I do not use such text files for processing. Sometimes I analyze an XML documents. Many tools then operate at the limit of their capabilities.
 
Last edited:
Well 1GB stretches VFPs limits, It's 2GB, of course, but rendering a 1GB text creates large graphics. Even if only the visible text portion is shown, that will likely cause problems in the grpahic rendering for GDI+, as used by VFP.

What about the idea to use an editbox per page? Or Griffs PDF creation. In the FAQ linked Griff tells you can specify a number of lines per page, I think that's also what you configure for txt file printing in a Generic Text printer, or your report creating a text file will put in CHR(12) for page breaks. So if you find CHR(12) characters in your text files, you can use ALINES to separate pages by using CHR(12) as the parsechar for splitting.
 

Part and Inventory Search

Sponsor

Back
Top