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

I created couple of games in VFP.

Status
Not open for further replies.

Jureczek13

Programmer
Apr 19, 2023
5
1
3
CA
I created couple of games in VFP.
They are running fine on my computer (that has VFP installed of course).
I run these games on another computer that doesn't have VFP.
They are running fine, becasue I copied to this computer all needed VFP dll's.

Then I created another game that is using "xfcbitmap object".
And when I run on other compter (without VFP) I'm getting error "loBmp is not an object".
On my compter it's OK. Here is the code:

DO LOCFILE("system.app")

WITH _SCREEN.System.Drawing
LOCAL lobmp AS xfcbitmap

lobmp = .Bitmap.FromFile(GETPICT())
loBmp.Width

ENDWITH

Thanks for any help!
 
The system.app and its usage hint on it being from the GDIPlusX project of VFPX. Well, it doesn't come with the gdiplus DLL itself, though. And in modern Windows OS versions, there is no system gdiplus.dll. So, did you forget to add C:\Program Files (x86)\Common Files\Microsoft Shared\VFP\gdiplus.dll? This dll is also part of the VFP runtime DLLs because of it not being a standard system dll in any windows version, and it is in this folder of VFP runtimes you find in a PC that has VFP installed.

Chriss
 
Thanks for your answer. I had gdiplus DLL.
But when I changed the line from: loBmp = .Bitmap.FromFile(GETPICT()) to: loBmp = .Bitmap.New(GETPICT()) the error is gone!

But then I got another error when excuting the next part of the program:
loRect=.Rectangle.New(lnCellLeft,lnCellTop,lnCellWidth,lnCellHeight)
loCropped=loBmp.Clone(loRect)

"loCropped is not an object".

The bottom line is that I need 2 methods:
1. Resize picture:
On the hard disk I have a picture, let say"Test.bmp".
I want to create on the hard disk another file which is resized of the Test.bmp and call it "Resized.bmp"

2. Crop picture:
I need to crop "Resized.bmp" to, let's say, 12 pictures (4 columns x 3 rows),
and show them on the left side of the screen.
These cropped pitures are created on the hard disk.

Maybe there would be another method, insted saving on hard disk Resized.bmp and 12 cropped pictures,
have all of them in memory? But VFP Image.Picture property requires name of the picture on the hard disk.

I'm writing "Mosaic" game.
Mosaic_ltma6h.jpg
 
I wonder if you mixed code that is intended to be used with gdiplusx system.app and code that was intended to be used with VFP9s own Home()+'\ffc\_gdiplus.vcx' class library.

Well, I have one a batch resize for shrinking photos down to website usage, it does these steps (boiled down from my code):

Code:
* after intitializing system.app:
LOCAL loOriginal, loResized, loGfx, lnNewWidth, lnNewHeight
lnNewWidth = 800
lnNewHeight = 600
With _Screen.System.Drawing
      loOriginal = .Bitmap.New(Getpict())
      loResized = .Bitmap.New(lnNewWidth, lnNewHeight, .Imaging.PixelFormat.Format32bppARGB)
      loResized.SetResolution(loOriginal.HorizontalResolution, loOriginal.VerticalResolution) && keep the dpi
      loGfx = .Graphics.FromImage(loResized)
      loGfx.InterpolationMode = .Drawing2D.InterpolationMode.HighQualityBicubic
      loGfx.DrawImage(loSrcImage, 0, 0, lnNewWidth, lnNewHeight)
      loResized.Save('resized.jpg', .Imaging.ImageFormat.Jpeg)
Endwith
There's a lot to adapt to your needs, I use variables for width and height. I skipped code to keep the original image aspect ratio, for example. But the main thing is you can use the DrawImage() method not only to resize an image, it has further parameters to pick a section of the original image so you don't necessarily resize but just cut out a rectangle. And I did use single coordinate values instead of rectangle objects.

Besides that, you don't need files for the image control, you can also set PictureVal. And here's a post about how to do that with the method GetPictureVal of the graphics object:

Chriss
 
In testing I now had "loGfx is not an object" error. When suspending at that error it turns out loGfx then is .T.
Then rerunnning the same code fails at the same point where loGfx should be created but becomes .T. instead. I couldn't reproduce the problem after restarting VFP, though.

Since you encountered this error, too, with other objects, I get the feeling in some situations the GDI+ DLL might get into an unusable state. I know that the usage of the GDI+ API functions does need an initialization (calling the API function GdiplusStartup from within the gdiplus.dll is done, for example, and also a deinitialization is done using GdiplusShutdown), so the GDI+ functions depend on a healthy state of what is loaded into memory. I surely wouldn't want to write code that always checks results expected to be an object to actually be an object, but even if you do, you can only restart to get back to a healthy state.

So maybe your code isn't even wrong and only conditionally stops working in a somehow unstable DLL state.

Chriss

PS: I might be onto something, as I think the unstable states are related to wrong calls, when you test some code changes. Once the usage of gdiplus.dll works, it works stable. So you just might need to restart more often during development.
 
Thanks Chris for taking your time.
The problem is solved:
In my code I had hard-coded path "D:\Mosaic\Pictures"!!!
So when I run on my wife's computer I got error "loBmp is not an object".
When I change path to "Pictures" everything is working.

Another thing, I deleted gdi dll, and it's still working!
Thanks again.
 
I see.

Regarding the gdiplus.dll: Looking into Resource Monitor I see vfp9.exe uses a gdiplus.dll version 10.0.19041.2251 from a subfolder of C:\WINDOWS\WinSxS\.
That's much more recent than the version 5.2.6001.22319 in the Microsoft Shared/VFP folder of the VFP runtimes.

So you don't depend on the gdiplus.dll it seems. I just don't know if problems would only be related to wrong filenames and paths, VFP could also fail to use a "too new" version. Since VFP9 is a deprecated product, testing whether vfp9 can work with the latest gdiplus.dll is not among system update tests anymore.

Chriss
 
B.T.W. In C:\Program Files (x86)\Common Files\Microsoft Shared\VFP\ and don't have any gdi dll.
In Windows\WinSxS I have 11 gdi files:
gdi32full.dll
GdiPlus.dll
gdi32.dll
with sizes from 9KB to 1,669KB.
And others in Windows, Program Files

Jerzy
 
What's your exact version? You can paste it into a post after setting _cliptext=Version(4).
I think gdiplus.dll is put into C:\Program Files (x86)\Common Files\Microsoft Shared\VFP\ from an installation. If you moved an installation from an old PC to a new one and registered it there and installed runtimes by using the runtime installers it might be missing. Or it could be in the instructions of a hotfix to put the gdiplus.dll from the hotfix there. And

Anyway, you can find out which gdi+ DLL VFP9.exe or your own EXE uses from resource monitor, as said. Start resource monitor. In the overview tab in the CPU section sort by the images column and find your EXE name there and check the checkbox. Then go to the CPU tab. In the "Associated Modules" tab you find DLLs that are loaded by your process. There is indeed also gdi32.dll in my list, taken from System32, even. But the only one of interest is really the gdiplus.dll

If you google for that version number 5.2.6001.22319 I have in MS Shared you find MS09-062: Description of the security update for GDI+. It's nothing to worry about now, it has already been pushed out by windows update and as you will see you'll also have a much newer version, I think.

It's just that the gdiplusx project originated in the year VFP9 was quite new and the gdi+ DLL security fix was released. I don't think the gdiplusx app will offer any more functionality from a newer gdiplus.dll you just benefit from performance improvements but could fail on something not downward compatible. That's the only reason I think it's better to use the one gdiplus.dll that came from that security fix back then.

I just remember back then you actually had to make the gdiplus.dll fix yourself and it was not within one of the vfp9 service packs or hotfixes, but might have been added to them as a runtime file. It is also listed in the runtime explainer on to which nobody can get, currently. But you can see it here:
It's actually mentioned as second file after the msvcr71.dll c++ runtime DLL and said to be in Microsoft Shared\VFP.
The wiki also says about gdiplus.dll: "GDIPLUS.DLL is only required for versions of Windows prior to 2000 (per Microsoft document entitled Visual Foxpro 9 - Application Distribution Process."
When my suspicion a newer version could contribute to problems is true, that might need to be modified to say prior to 2000 or later than 2023.

One thing I am certainly sure about is that it can't hurt to use the older gdiplus.dll as vfp9 itself does not depend on anything newer and your own built EXE only, if you explicitly would make use of new or changed API functions. The only other benefit is downward compatible performance improvements. That speaks for the newest gdipluls.dll and new graphics hardware only working with the newest gdiplus.dll versions could also be a problem. So in the end this could even become a situation of neither DLL works for all concerns about compatibility with VFP and hardware support at the same time.

But let's take it relaxed: Since everything works now for both of us, we should perhaps do what's the simplest option: Do nothing.
If you're interested in getting the 5.2.6001.22319 version I attach it here.

I can just say it's not used by vfp9.exe itself, the MS shared/VFP folder is actually there for you to find all runtime DLLs necessary for your setups, if you don't use InstallShield and the merge modules of C++ 7.1 runtimes and VFP runtimes for creating a setup with them. VFP9.exe also doesn't use any other DLL from that MS Shared folder. The IDE, the vFp9.exe itself, does not need the vfp9r.dll, too, as that's all integrated into vfp9.exe. To have a different language IDE, you also can't use the vfp9rXYZ.dlls with XYZ being one of the languages. The IDE needs other resource DLLs, which only exist for older VFP versions, officially. I think VFP7 was the last version with multiple language IDE.

In short, that's why your VFP9 setup is still okay, VFP itself doesn't depend on MS Shared/VFP to work.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top