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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

FPW2.6 screen in VFP9 1

Status
Not open for further replies.

foxmuldr3

Programmer
Jul 19, 2012
170
US
Code:
@ y1,x1 to y2,x2 PATTERN ... PEN ...

This type of code in FPW 2.6 (and VFP9) will draw a rectangle on the screen within a given set of coordinates. If I execute this code on a converted FPW 2.6 screen in VFP9, it works properly (uses the correct coordinates). However, if I try to convert the @..PATTERN..PEN source code lines to shape or label objects, I am unable to replicate the upper-left coordinates and proper width and height in VFP9 when I manually convert the coordinates through the FONTMETRIC() functions. They are always a few pixels off, sometimes even 10 pixels.

I have modified the code to use any specified fonts, sizes and styles if present. The example code below does not include that logic because it adds unnecessary complexity to the example.

This code appears on a DEFINE CLASS method that is called after the object is added at the same location in the original source file where the @..PATTERN..PEN line exists, so it is using the same font references that would be used on that @.. line.

Example:
Code:
**********
* Load the font metric info
*****
    lnFontHori  = FONTMETRIC(6)
    lnFontVert  = FONTMETRIC(1)


**********
* It was observed that the covers don't align quite right in VFP9.
* The 1.005 and 1.064 were trial-and-error values determined to
* get them closer.
*****
    this.Left   =  tfUlx * 1.005 * lnFontHori
    this.Width  = (tfLrx * 1.005 * lnFontHori) - this.Left
    this.Top    =  tfUly * 1.064 * lnFontVert
    this.Height = (tfLry * 1.064 * lnFontVert) - this.Top

Does anyone know what I'm doing wrong? If I take out the constant adjustments, it's even worse.

Best regards,
Rick C. Hodgin
317-879-6374
 
At defaults (Arial 9pt, _sceen.Scalemode = 3) I get the following two boxes drawn in excact alignment:

Code:
Clear
_screen.ForeColor=Rgb(255,0,0)
@ 10,20 to 30,40 PATTERN 1 PEN 1
wait window '' timeout 1
_screen.ForeColor=Rgb(0,0,0)
_screen.Box(20*fontmetric(6),10*Fontmetric(1),40*fontmetric(6),30*Fontmetric(1))

And _screen.Box surely draws in pixels 1:1

So, have you set Scalemode to 1 (Foxels) perhaps? Making Pixel computations in Foxels mode would perhaps cause that shift.

Bye, Olaf.
 
When you create FPW 2.6 screens, they use fractions out to the thousands for exact placement. Here is an example which shows the bottom of this rectangle off by at least one pixel. Click on the alternate "Draw" and "Object" buttons to switch back and forth.

Code:
#REGION 0
REGIONAL m.currarea, m.talkstat, m.compstat

IF SET("TALK") = "ON"
	SET TALK OFF
	m.talkstat = "ON"
ELSE
	m.talkstat = "OFF"
ENDIF
m.compstat = SET("COMPATIBLE")
SET COMPATIBLE FOXPLUS

m.rborder = SET("READBORDER")
SET READBORDER ON

m.currarea = SELECT()

IF NOT WEXIST("_3mo10i7u5")
	DEFINE WINDOW _3mo10i7u5 ;
		AT 0.000, 0.000 ;
		SIZE 22.000,98.400 ;
		FONT "MS Sans Serif", 8 ;
		FLOAT ;
		NOCLOSE ;
		MINIMIZE ;
		SYSTEM
ENDIF

#REGION 1
IF WVISIBLE("_3mo10i7u5")
	ACTIVATE WINDOW _3mo10i7u5 SAME
ELSE
	ACTIVATE WINDOW _3mo10i7u5 NOSHOW
ENDIF
@ 16.615,29.200 GET foo ;
	PICTURE "@*HN Draw" ;
	SIZE 1.769,7.000,0.667 ;
	DEFAULT 1 ;
	FONT "MS Sans Serif", 8 ;
	STYLE "B" ;
	VALID _3mo10i7ua()
@ 16.615,57.600 GET done ;
	PICTURE "@*HT Exit" ;
	SIZE 1.769,5.667,0.667 ;
	DEFAULT 1 ;
	FONT "MS Sans Serif", 8 ;
	STYLE "B"
@ 16.615,40.800 GET fooo ;
	PICTURE "@*HN Object" ;
	SIZE 1.769,8.333,0.667 ;
	DEFAULT 1 ;
	FONT "MS Sans Serif", 8 ;
	STYLE "B" ;
	VALID _3mo10i7uh()

IF NOT WVISIBLE("_3mo10i7u5")
	ACTIVATE WINDOW _3mo10i7u5
ENDIF

READ CYCLE

RELEASE WINDOW _3mo10i7u5
SELECT (m.currarea)

#REGION 0

SET READBORDER &rborder

IF m.talkstat = "ON"
	SET TALK ON
ENDIF
IF m.compstat = "ON"
	SET COMPATIBLE ON
ENDIF

FUNCTION _3mo10i7ua     &&  foo VALID
#REGION 1
@ 1.102,4.002 to 13.402,25.002  PATTERN 1  PEN 1, 0  COLOR RGB(,,,192,192,192)

FUNCTION _3mo10i7uh     &&  fooo VALID
#REGION 1

* Original @..pattern..pen line:
*@ 1.102,4.002 to 13.402,25.002  PATTERN 1  PEN 1, 0  COLOR RGB(,,,192,192,192)

* Get screen coordinates
lnUlY =  1.102 * FONTMETRIC(1)
lnUlX =  4.002 * fontmetric(6)
lnLrY = 13.402 * fontmetric(1)
lnLrX = 25.002 * fontmetric(6)

IF TYPE("gnIterator") != "N"
	PUBLIC gnIterator
	gnIterator = 0
ENDIF

IF LEFT(VERSION(),2) >= "3."
    gnIterator = gnIterator + 1
    lcName = "foo" + ALLTRIM(STR(gnIterator,3,0))
	k = "_screen.forms(1).addObject('" + lcName + "', 'shape')"
	&k
	k = "_screen.forms(1)." + lcName + ".left = lnUlX"
	&k
	k = "_screen.forms(1)." + lcName + ".top = lnUlY"
	&k
	k = "_screen.forms(1)." + lcName + ".width = lnLrX - lnUlX"
	&k
	k = "_screen.forms(1)." + lcName + ".height = lnLrY - lnUlY"
	&k
	k = "_screen.forms(1)." + lcName + ".backColor = RGB(255,255,0)"
	&k
	k = "_screen.forms(1)." + lcName + ".visible = .t."
	&k
ENDIF

Best regards,
Rick C. Hodgin
 
OK, so it's

@ 1.102,4.002 to 13.402,25.002 PATTERN 1 PEN 1, 0 COLOR RGB(,,,192,192,192)

vs a Box with coordinates

lnUlY = 1.102 * fontmetric(1)
lnUlX = 4.002 * fontmetric(6)
lnLrY = 13.402 * fontmetric(1)
lnLrX = 25.002 * fontmetric(6)

These result in non int coordinates. There's no such thing as fractional pixels, so I'd try with ROUND() or FLOOR() or even CEILING().

In this case, FLOOR seems to work well:

lnUlY = Floor( 1.102 * fontmetric(1))
lnUlX = Floor( 4.002 * fontmetric(6))
lnLrY = Floor(13.402 * fontmetric(1))
lnLrX = Floor(25.002 * fontmetric(6))

I haven't checked with other coordinates, though.

Bye, Olaf.
 
Olaf,

In this one case it may be integer rounding. But I am seeing computations for coordinates that work correctly in 2.6 being off by 10+ pixels when using fontmetric() to derive their coordinates, and replacing the @..PATTERN..PEN lines with shape or label objects.

I am convinced it has to do with varying font metric values, where FPW is using one set, and I am using another.

Perhaps the 2.6 screen font is sticky, meaning the last font used is the one which is now the default font for the screen... Hmm...

Best regards,
Rick C. Hodgin
 
Font dependence may be one reason, yes.

Well, ScaleMode Foxels is depending on the "current font" in terms of the Foxpro help. So the same values used with different fonts mean different pixel sizes or offsets.

Perhaps take a look at what you find in the help, when searching for Foxels.

One interesting finding I had, which I wasn't aware of until now, is CurrentX and CurrentY properties. They are not available at designtime and read/write at runtime and apply to many (visual) objects and controls:
[URL unfurl="true"]http://msdn.microsoft.com/en-us/library/aa977485%28v=vs.71%29.aspx[/url].

Bye, Olaf.
 
In short: Your solution may be to put forms in the unusual Scalemode 0 and actually simpley use the coordinates 1:1 as by @.

Bye, Olaf.
 
Olaf,

The issue is ... I'm supporting an app that is running in FPW 2.6 (and has been since mid-1990s). We have ported it to VFP9 using some auto-conversion utilities which fixup 2.6 code for VFP9 so it runs in 64-bit versions of Windows.

All of that code is working. And in the process we've found a dozen or so differences between 2.6 and 9.0 in supporting 2.6 SPRs, with workarounds for every case except this one.

The code has to be left as it is, but then can be modified for VFP9 using the auto-converter utility which converts the auto-generated SPR code at the source code level. However, there are over 800 screens ... and it's just too big to validate everything properly. So, it has to be a "proper" solution in all cases ... which is sometimes hard to do because the code was written by 20 different developers over 18+ years. It's been hard to accommodate all the variables, but as of right now we're there.

This last issue has a workaround as well. I've created a utility called "bumper" which takes the converted-to-shape/label objects and bumps them around on the screen. I use a SHA1 value for the line of source code coupled to the form name, however there is another issue there in that FoxPro sometimes re-uses windows if screen1 calls screen2, and internally the .name property is the original name even though it's referenced in code by its screen2 name, etc.

It's just really, really something. I see a lot of hacking behind-the-scenes in VFP to get FPW 2.6 screens to work.

Best regards,
Rick C. Hodgin
 
Rick,

I never have done this and been there, but if there is a converter it shouldn't be hard to let it set Scalemode =0 for all screens to convert and with the same unit as in FPW I would expect no conversion problems with Foxel coordinates, as there is no conversion to Pixels done, then.

If that also doesn't make objects fall in place, well, it was just a shot worth making additional to looking for a better pixel conversion.

But if you say the problem is solved already, then it's solved.

Bye, Olaf.
 
Olaf,

I wrote the converter we're using. It has the workarounds we've discovered for issues in converting 2.6 screens to work (as SPR files) in VFP9, and does about 0 to 300 fixups per SPR, depending on what's on it/them.

This has allowed us to do maintenance on both systems (FPW 2.6 and VFP9) simultaneously, by making nearly all of our changes only in FPW 2.6, and then allowing the converter to fix them up for VFP9's requirements.

It's a great solution. But I am not understanding the logic involved in translating foxels to pixels because the fontmetric(1|6) conversions don't always work.

Best regards,
Rick C. Hodgin
 
Well, if you set the VFP9 forms to foxels, you don't need FONTMETRIC any more, you can take the coordinates as they are. No conversion. It's unusual to work in Foxels in forms, but it's possible to position objects in Foxels, too.

Bye, Olaf.
 
Olaf, Hmmm.... I will try that. I'll let you know how it turns out ... because that's the kind of guy I am. :)

Best regardaroonoes,
Rick C. Hodginski-Polaris
 
Well, I got one further clue: VFP9 draws controls and Text with gdiplus, while earlier versions didn't. Like in the report engine, where that also can cause report controls to have an overflow and display ****, this may be the root cause for computations in Foxels not giving the same results as back in FPW. You would need to use VFP8 or earlier to determine eventual differences in FONTMETRIC for certain fonts. Also Fontmetric(6) only returns int numbers, while the real average font width would most likely not be exactly N pixels.

Bye, Olaf.
 
Olaf,

You're a genius! It worked!

If I'm ever in Germany I'll buy you a tall glass of some type of German beer that you like. And if you don't like beer, then I'll buy you a soda pop. And if you don't like soda pop, then I'll buy you a bottle of water. And if you don't like bottled water, then ... well ... I guess I'll apologize for not being able to give back to you properly, perhaps ask you a few questions about the peculiar nature of your existence, and then continue on with my life unabated. :)

Best regards,
Rick C. Hodgin
 
Rick,

Glad it works. Don't "crow too soon", perhaps. Your sample @ 1.102,4.002 to 13.402,25.002 PATTERN 1 PEN 1, 0 COLOR RGB(,,,192,192,192) didn't worked out for me with _screen.scalemode=0 and a shape set to the same coordinates. But, well, if it works for you in the cases you tested so far, it's already a good sign and an improvement, even if you would run into some cases not matching.

I like beer, but typically drink a mix with citrus lemonade called "Radler" in whole germany (could be translated by Cyclist, as it's an alcohol reduced drink suitable for cyclists), and "Alsterwasser" in Hamburg. (Alster is a lake in Hamburg and wasser is water, so it's a kind of joke, as the drink looks as cloudy as the water of that lake) and most often I drink it with alcohol free beer. There are quite some well tasting beers with no alcohol.

Well, you could also get me with a single malt old Bushmills or that sort of mild whiskey.

If you ever would travel to Hamburg, the second thursday of each month there is a regular meeting of developers (we call it "Hamburger developer regulars") at 1900 in the "Laufauf", a restaurant near the center/town hall, here.

We're typically 4-6 members and just have a nice evening, sometimes with a session about some topic so Christof can rehearse for conferences ;), often enough showing off the latest gadgets (eg smartphones or one of the last times the Raspberry Pi).

Bye, Olaf.
 
Olaf,

There are items which seem to be off by a single pixel on a side, which I'm sure is do to the different rounding modes being used in different code sections.

I'm just about to the point of identifying every case where these @..PATTERN..PEN references are used in code and converted to shape objects, and then overlay them in different colors on an artificially created window explicitly for this purpose, to then get the bitmap bits of that window and scan for how far off they are visually. I'll then create a table of adjustments which correct them on a line-by-line basis by adjusting the values slightly, such as from 1.102 to 1.108, etc.

Oh Microsoft ... it would not surprise me at all to learn that this was done exactly on purpose to make 2.6 screens work, but not exactly correctly, so that the FoxPro users would be annoyed just enough to support its developer base to move forward with new, expensive revisions of software that already worked perfectly in the prior version, while still being able to operate their older software base while waiting for the upgrades.

If it's true, it's criminal. And it shouldn't be like that. Ever. We see it time and time again through every Microsoft product though. It has to be by design because no company is that incompetent. :-(

Best regards,
Rick C. Hodgin
 
Well, I doubt it was done intentionally, to force migration. Actually if MS would have forced more migration by introducing planned incompatibilities (for the virtue of a better redesign of some things, for example), VFP might have been sold better in late versions, would have been a business success, and therefore not been discontinued. In dotNet I see more stuff being redone in that spirit of replacing something with a better design, maybe too often. I don't want to rant on ado vs. linq vs. entity framework, though, but you get the point for sure.

I think in regard of the FPW conversion, influences making slightly different sizes are mainly because of changing from natively drawing all visual things to supporting Themes and letting GDI+ draw everything.

So you may try if these last influences are gone, if you set form.Themes = .f., but I doubt that, it will most probably not change positions, it will only influence, if eg backcolor of grid headers are respected or overridden by Windows Theme colors.

You say you have done your own converters, have you tried the conversion of screens as done by MS? I don't remember you have said something about that, but having written your own converters I guess you were not satisfied with the results done by the converters comeing with VFP.

As a side note:

A very good foundation and quality of products is double-edged. I can tell, because I own a sofa by a furniture manufacturer gone out of business. The sofa's durability is so good, they only see a customer come back, if he wants more furniture, not if he needs new furniture. The sofas are actually cheaper per day of usage, but that doesn't count for customers, does it? Things you buy for a lifetime are becoming very seldom. A house perhaps. What else?

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top