Rick Strahl's FoxPro and Web Connection Web Log

My Links
Blog Stats
Archives
February 2012 (1) January 2012 (3) November 2011 (4) October 2011 (2) September 2011 (1) August 2011 (1) May 2011 (1) December 2010 (1) August 2010 (1)
West Wind News
West Wind Internet and Client Tools 4.62 released
Yesterday
West Wind Technologies has released version 5.62 of West Wind Client Tools. Client Tools provide a host of Internet functionality to client desktop...

West Wind Message Board Update
Monday
The West Wind Message Board we use for support has gotten a visual and slight functional makeover. We've updated the styling to look a bit more...

Html Help Builder 4.66 released
Jan. 19, 2012
West Wind Technologies has released version 4.66 of West Wind Html Help Builder. Help Builder produces documentation for Html Help (CHM), Web ready...

Html Help Builder 4.65 released
Dec. 14, 2011
West Wind Technologies has released version 4.65 of West Wind Html Help Builder. Help Builder produces documentation for Html Help (CHM), Web ready...

West Wind Web Service Proxy Generator 1.20 released
Nov. 18, 2011
West Wind Technologies has released an update to the Web Service Proxy Generator tool which lets you easily create FoxPro clients to call complex...

  



Show last 50 comments

Feb. 5, 2012 12:58am | by Rick Strahl

@Frank - yup Craigs encryption library is good, but I try to avoid external dependencies as much as possible since this stuff ends up in Web Connection and Client Tools and the HashMD5 code predates his library by a bit :-)
Feb. 5, 2012 9:41am | by Frank Dietrich

Rick!

Nice and easy. For the MD5 part You could also employ Craig Boyd's vfp encrytion fll, that offers MD5 support also:

http://www.sweetpotatosoftware.com/spsblog/2009/08/09/MajorVFPEncryptionUpdate.aspx

Regards from Berlin

Frank

Jan. 31, 2012 16:03pm | by ADAM

I'm trying to display some Unicode data stored in dbf fields/memo fiels on a form. I'm using only fox native DBF. All the examples relating to Unicode are SQL so it's complicating for me.

Could any of you pls give me a simpler way to do this. I would appreciate some simpler code that would display a form with a textbox and a dbf (not SQL).

Thanks in advance.

adam7171@gmail.com

Jan. 27, 2012 11:16am | by Luis Maria Guayan

Very good tip. I did not know and have dealt with this feature.

Jan. 19, 2012 15:01pm | by Sean Gowens

Rick - Thanks for looking into my original request and coming up with this really helpful article. Historically I used FTP for most everything inside of our desktop app, but found more and more issues with firewalls so I transitioned to HTTP. This is going to help tremendously.
Jan. 10, 2012 0:07am | by Klaus Eichert

Hello,

i want to use the mplayer in slave-mode with my vfp-application, so i have to write in the mplayer-console. do you have any informations for me.

Klaus

Jan. 6, 2012 8:41am | by Frank Camp

Always respect Lisa G. (Load, Init, Show, Activate, GotFocus)

So here, you want the Setfocus just before the Gotfocus, which means the Activate is the most logical place (just don't forget to add code that it is only done the first time the activate gets called)

Dec. 27, 2011 14:02pm | by P.C.

Create your own listener which will override your Unicode string duplicate conversion to Unicode in records having certain User data:

loListener = CREATEOBJECT("RLUTF8")

TRY
REPORT FORM YourReport OBJECT loListener prev
CATCH TO loExc
MESSAGEBOX(loExc.Message)
ENDTRY

DEFINE CLASS RLUTF8 AS REPORTLISTENER

ListenerType = 1

PROCEDURE Render
LPARAMETERS nFRXRecNo ;
, nLeft, nTop, nWidth, nHeight ;
, nObjectContinuationType ;
, cContentsToBeRendered ;
, GDIPlusImage

LOCAL lcExpr, lcResult, llStrConv

SET DATASESSION TO This.FRXDataSession
GO nFRXRecNo
*-- Check User data in report definition
IF User = "<UTF-8>" OR User = "<UNICODE>"
lcExpr = Expr
llStrConv = User = "<UTF-8>"
ENDIF
SET DATASESSION TO This.CurrentDataSession

IF !EMPTY(lcExpr)
lcResult = EVALUATE(lcExpr)
IF VARTYPE(lcResult) = "C"
IF llStrConv
*-- Report field is in UTF-8 - convert it to Unicode
cContentsToBeRendered = STRCONV(lcResult, 12)
ELSE
*-- Report field is in Unicode already
cContentsToBeRendered = lcResult
ENDIF
ENDIF
ENDIF

DODEFAULT(nFRXRecNo ;
, nLeft, nTop, nWidth, nHeight ;
, nObjectContinuationType, cContentsToBeRendered, GDIPlusImage)

NODEFAULT

ENDPROC
ENDDEFINE

Dec. 20, 2011 11:46am | by Rick Strind.comahl

@Christof - Uhm... how do you do that? And if you did, does the app still run as a Windows app? Basically what I would really need is an app that does both - provide Console output AND still run as a Windows application :-)
Dec. 6, 2011 14:02pm | by Christof Wollenhaupt

Why don't you change the type of the subsystem in the EXE header from windows to console?
Nov. 21, 2011 19:08pm | by Dennis H

Thanks Rick--this solved some problems for me.

I have some .net controls I use in VFP that were created with the Interop Forms Toolkit. Is there any way to host these directly, and if so, how would one go about it?

Thanks

Dennis

Nov. 19, 2011 16:11pm | by Rick Strahl

Thanks Cesar. I'll be posting more FoxPro content over the next few weeks as I've been working more extensively in Fox recently (bunch of Web Connection stuff). I have a backload of posts scheduled to be posted here.
Nov. 18, 2011 16:54pm | by Cesar

Great post Rick. Excellent sample, and as always, super well explained.
Thanks very much for all this great stuff you've been posting about COM Interop with .NET
BTW, your session on this subject in SWFOX 2010 was great as well, and opened many, many doors to me :-D

Cheers

Cesar

Nov. 7, 2011 13:22pm | by Rick Strahl

@Phil - AllocConsole will create a new Console window from within a Windows GUI app. This might be useful for other things but the problem is again that you can't capture the console externally from the command line.

Nov. 7, 2011 9:12am | by Phil

I haven't tried this before, but I have you checked out using AllocConsole?

http://www.pinvoke.net/default.aspx/kernel32.allocconsole

Oct. 7, 2011 12:00am | by tch

Thanks Rick,

I finally found it. Under Project Properties, Linker, Input, Additional Dependencies, it was hardcoded to look for the path:

C:\programs\vs2005\SDK\v2.0\Lib\mscoree.lib

I had been modifying the VC++ Directories settings and not the Linker paths. Sheesh....

But that brings up a question that maybe you have run into? I work on two different laptops (well 3 actually). Two of them are Win7 64 and one is Win7 32. On the 64 bit machines mscoree.lib is located here:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\mscoree.lib

but on the 32 bit of course it is located here:

C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib\mscoree.lib

As a test, I put the invalid directory path there along with the valid (x86) path hoping I could compile on either/or machine, but of course the invalid path errors. Is there anyway to set that so it looks only at the valid location and ignores the invalid path so I can compile on either machine so I don't have to change the setting if I compile on the 32 bit Win7 machine?

Oct. 5, 2011 16:02pm | by Rick Strahl

@tch - you need to include the reference to mscoree.lib in the compiler options. It's installed with the Windows SDK which more recently lives in %program files%\Microsoft SDKs\Windows 7.0a. Any of the Windows SDKs since V2.0 should have that file in it.
Oct. 5, 2011 5:58am | by tch

I can see how that would work for the runtime, however, when I build the clrhost, it still looks for 'C:\programs\vs2005\SDK\v2.0\Lib\mscoree.lib' I am missing something and too blind to see it....
Oct. 4, 2011 8:54am | by TCH

Thanks Rick! We have your wwip stuff. For this specific need, I'm trying to go as light as possible (fewer pieces). The goal is to talk to a C#.net plugin to a 3rd party system sitting on a mobile laptop in vehicles. I'm trying to avoid building a C# proxy with com interop and registering it on every laptop (the current com interop route plan that works but is not ideal). The nice part of com interop is firing events in VFP of course. But I'm thinking the clrhost is fewer parts that would require support (and your wwwdotnetbridge seems to allow for multiple parameters) and hopefully fewer pieces to install and maintain/update on hundreds of laptops that only come in periodically for updates....
Oct. 4, 2011 3:14am | by Rick Strahl

@tch - When the runtime is loaded you need to specify the version number initially. I have updated code in wwIPStuff.dll that deals with this - it basically passes the exact version number as a string into ClrCreateInstance.

Here's what I did: I added a property for ClrVersion and a method to set it via an API function call:

BSTR ClrVersion = NULL;

DWORD WINAPI SetClrVersion(char *version)
{
ClrVersion = CComBSTR(version);
return 1;
}

Then in the call to CorBindToRuntimeEx that version number is used:

//Retrieve a pointer to the ICorRuntimeHost interface
HRESULT hr = CorBindToRuntimeEx(
ClrVersion, //Retrieve latest version by default
L"wks", //Request a WorkStation build of the CLR
STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN | STARTUP_CONCURRENT_GC,
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(void**)&spRuntimeHost
);

This allows your code to specify which version gets loaded. You can still pass NULL to select the latest version, but this was broken with .NET 4.0 which got a new set of hosting APIs that are different, so NULL with .NET 4.0 usually still loads .NET 2.0 unless that's not installed - which is very lame.

Oct. 3, 2011 19:28pm | by tcH

Hi Rick,

Just testing this and the error returned is:

The assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

I tried recompiling ClrHost under VS2010 (the same version my .net dll is built from) and the project cannot find mscoree.lib for some reason:

error LNK1104: cannot open file 'C:\programs\vs2005\SDK\v2.0\Lib\mscoree.lib'

I went to the project's properties and added :
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\x64;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib;$(LibraryPath)

to the Library Directories under Configuration Properties VC++ Directories to no avail.

Any ideas?

May. 26, 2011 22:46pm | by Mike James

Thanks for the aside on how to move a window back onto the primary monitor under Windows 7 - great tip, apply to FoxPro itself, which is the only app I know that doesn't know how to re-set itself.
May. 17, 2011 12:45am | by BeginnerPHP

I am working on the following settings: windows 7 and PHP on eclipse IDE, and Zend debugger, and IIS server!
May. 17, 2011 12:43am | by BeginnerPHP

Still getting the error "
HTTP Error 404.0 - Not FoundThe resource you are looking for has been removed, had its name changed, or is temporarily unavailable." Even after making the modifications to ApplicationHost.Config file!
Mar. 21, 2011 15:06pm | by Roger Zacharczyk

Hi there,

Sorry for posting here - couldn't find your e-mail address.

I'm the leading editor of Software Developer's Journal which is a new e-magazine. I'm looking for developers who want to share their knowledge with other developers. If you are interested in cooperation (articles writing, proofreading, ads) just please let me know - roger.zacharczyk@software.com.pl

Mar. 8, 2011 13:54pm | by Rodolfo Bravo

Would you help me for resolving this error? The message error on my notebook is:
PS C:\Users\Administrador\downloads\MoodleWindowsInstaller-latest-19\server\apache\bin> .\httpd.exe -k install
Installing the Apache2.2 service
The Apache2.2 service is successfully installed.
Testing httpd.conf....
Errors reported here must be corrected before the service can be started.
(OS 10013)Intento de acceso a un socket no permitido por sus permisos de acceso. : make_sock: could not bind to address
0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
PS C:\Users\Administrador\downloads\MoodleWindowsInstaller-latest-19\server\apache\bin>

Thanks a lot for your help!

Feb. 2, 2011 19:41pm | by charlie arehart

Just a minor correction to your otherwise helpful article (as always). You point out that:

"ApplicationHost.config lives in the <windows>\system32\inetsvr directory"

In case someone may (as I did) try to copy paste that to find it, it should instead be:

<windows>\system32\inetsrv\config

And Rick, in case you may consider changing it in the original entry, note that it's not just adding the \config, but also changing intsvr to inetsrv.

Jan. 26, 2011 6:47am | by Jones

O, its great post! <a href="http://essay-writer.org/prices.php">essay sale</a>
Dec. 21, 2010 12:32am | by Jon

I am trying to use this in Excel vba.
I have everything converted except this line

loObject = SYS(3096, lnDispHandle)

can you tell me what the equivalent command would be in vb

Oct. 6, 2010 14:11pm | by Rick Strahl

That's exactly where hosting your own runtime can come in. This lets you call the runtime via COM and clients don't need to compile anything CLR related. But it's COM interop we're talking about here - not sure if that's better than forcing a compile with /CLR switch :-). Remember the runtime does need to be there.
Oct. 6, 2010 11:58am | by Louis

Tell me if I'm crazy...

I'm writing an API that will be called by others. The API can be exposed to .NET clients as well as unmanaged C++ clients. One of my APIs actually pops a nice looking dialog that is implemented with WPF using .NET 3.5. I don't want to force the clients of my API to enable /CLR on their unmanaged apps so I will just load the CLR for them whenever they call the relevant APIs.

OK, the window I'm showing has some very custom UI elements and would be prohibitively difficult to implement in MFC or to-the-metal Win32 APIs.... This seems to be the easiest way to show WPF UI in an unmanaged client without forcing the /CLR build option on the clients.

Any thoughts? I know there will be some performance penalties (memory and speed) but probably no more than any other .NET app...

Sep. 20, 2010 3:31am | by Rick Strahl

In the updated version of wwDotNetBridge (in Client Tools and Web Connection) arrays are returned as a special COM object. So you can do:

laFiles = loBridge.InvokeStaticMethod("System.IO.Directory", "GetFiles","c:\")
? laFiles
? laFiles.Count
? laFiles.Item(0)

Sep. 19, 2010 13:57pm | by Mr. T

thank you for your post , u are a life saver !
Sep. 18, 2010 2:28am | by Asif Chouhan

I have hosted my web application on II7 now it is blocking all the pop up and it is giving above error.
Aug. 9, 2010 14:36pm | by Mike McDonald

The line in the sample code above..
lnOld2335 = lnSys(2335)
..should be..
lnOld2335 = Val(Sys(2335))
..since Sys(2335) returns a character but expects a numeric input parameter.

Thanks for the details on this setting.

Aug. 5, 2010 14:37pm | by Dan Scott

Thanks Rick. Yes, I thought that would be the case (even though the UI that report form shows when called with NOCONSOLE TO FILE is only a printing progress dialog). I wrapped the command in SYS(2335,0) and all worked fine. Of course if the FRX uses some cursors that aren't available then the server will still lock up with a file dialog, but I can't see any way around that! Thanks for your help.
Aug. 5, 2010 3:37am | by Rick Strahl

REPORT FORM includes UI and so causes an error when running in unattended mode. The workaround is to turn of unattended mode before the report and then turn it back on afterwards (ie. SYS(2335,0) run report then SYS(2335,1)). This will work in an EXE. Note that DLL servers can't run REPORT FORM commands at all.
Aug. 4, 2010 21:28pm | by Dan Scott

Is there any chance this same issue could affect the VFP REPORT FORM command? As we are using the wwPDF class and when lunattendedmode is set to .T. we get User-interface operation not allowed at this time errors when trying to produce PDF. Works fine in file mode or if we set SYS(2335,1) before the:

REPORT FORM (lcReport) &lcExtraReportClauses NOCONSOLE TO FILE &lcTFile

command? Can't find any info on this and from my testing this is the case.

Jul. 1, 2010 12:31am | by Rick Strahl

I think you can make Media Player Rip a CD from songs, but not record music.

The Lame driver is a converter and it's a DLL you can access fairly easily with WinAPI code in Fox. However, that doesn't help with recording first. Audio recorder might be automatable but there are probably better solutions out there in the form of ActiveX controls. Jim Murez (Harvey Mushman) had been playing around with some of this some time ago and I remember the controls he used weren't very pricey.

Jul. 1, 2010 8:18am | by hm@zam.net

Did you discover anyway to also record in MP3? If I have the LAME driver on the system, I would think this might be possible but not sure if media player can also record.

--jim

Jun. 3, 2010 13:13pm | by Rick Strahl

There's a checkbox when you create a script map. It's under the handler mappings and Request Restrictions.

Also make sure that if you're mapping to an ISAPI extension you set the ISAPI/CGI restriction to allow access to the DLL.

Jun. 3, 2010 11:03am | by Nick

I'm trying to install on IIS 7 & Windows Server 2008, and I keep getting a 404.0 error. It's trying to find a file with the extension that I've mapped, and of course it does not exists. Any suggestions?
May. 14, 2010 1:34am | by Dexter

Thank you very much for this article, Rick - you saved my day, again :)
May. 4, 2010 0:19am | by Eliza Sahoo

To enable it open an aspx page and follow the following steps:

1. Click on "View"
2. Click on "Formatting Marks"
3. Click on "Show"
4. Repeat step-1 and step-2
5. Click on "Tag Marks"
Now tags will be shown in the design view.
Apr. 21, 2010 12:35am | by Rick Strahl

I don't know... haven't looked at FoxISAPI in ages. IIS 7 has restrictions against using .dll links directly. you might try using script map links instead.
Apr. 21, 2010 9:34am | by Simon

Hi Rick, I really need to run FoxIsapi.dll on IIS7, but following the above for adding the CGI and ISAPI restrictions, when ever I try to run the following url: localhost/scripts/foxisapi.dll/status?
I get the 500.0 - Internal Server Error, is it possible to get FoxIsapi.dll working under IIS7, if so what is the correct procedure to get this working,
Thanks
Simon
Mar. 25, 2010 17:47pm | by Gunnar Weisskamp

Hi I am using Code Charge to create a simple first "Hello World" ASP application. My operating system is Windows Seven Professional. Now when I try to view page in browser I am getting
"HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map."

Now I have tried the following

1 - Checked to make sure that certain settings in the "Turn Windows Features On / Off" for IIS are checked

2 - When I did this I followed you above instructions and made sure that the "IIS Metabase and IIS 6 configuration compatibility" is set.

3 - I even turned the "virtual directory" that I had created in IIS into an “application” directory.

4 – I then explored the “MIME Types” area and added a “.asp” extension. This did get rid of the above initial error “HTTP Error 404.3” but then when I tried to view the page a dialog box “File Download – Security Warning” came up saying “Do you want to open or save this file”. You can click on “open”, “save” or “cancel”. Whichever one you chose does not matter as this is not the expected result in the first place as the page should have just opened up in the browser.
5 – I also made sure that in IIS the page being requested was set as the default page to display

Any help you may have would be great. Kind regards Gunnar

Mar. 9, 2010 12:52am | by Keith

Thanks for the tip about NOT using Integrated, Rick! It solved the problem I was having with virtual ASPX page links.
Feb. 25, 2010 14:32pm | by Scobee

Awesome.. This is exacly the fix that did the trick for me had a binary in the a "bin" directory and this fixed it right away.. though not happy about the vulnerabilty that now exists it is low risk for our internally hosted app.


Jan. 25, 2010 2:45am | by Eliza Sahoo

Hi,
Its a good one.I also want to share a similar tips with you.
If a table has firstname and lastname as its fields and also we want to show full name on the screen or in a report. The first expression that comes to mind is something of this sort :

SELECT TRIM(lastname)+' , ' + firstname from table .......

Or

SELECT ALLTR(lastname)+' , ' + firstname from table .......


However a easier way is :-

SELECT lastname - (', '+firstname) from table .........

The '-' is a another concatenation operator that removes trailing blanks from the element preceding the operator then joins two elements
there is a difference between using the '-' operator and ALLT in the above example.

The latter removes all blanks from last name while the former moves the trailing blanks from last name and adds them to the end of the resulting expression.
This is handy if you want the size of the resulting field to be equal to the total size of its elements.


© Rick Strahl, West Wind Technologies, 2004 - 2012