VFP
Listed below are the questions that we are asked quite often. Before you write us, be sure to check here.

Programming

Programming

Why don't events fire in FoxPro?

There can be a problem with VFP responding to events. Be sure to set AutoYield = .F.

I get "Function argument, value, type, or count is invalid", while I'm using the ItemBar property. Am I doing something wrong?

A> The following method uses the Items.DefaultItem / Template methods 

The following code works for eXG2antt control, but the idea is the same for all controls that support Items.DefaultItem / Template property like: eXGantt, eXGrid, eXTree, eXList, eXComboBox, eXPlorerTree, and so on.

Let's say that your code looks like follows:

LOCAL h
SCAN
	_key="K_"+ALLTRIM(STR(projekte.ID))
	WITH THISFORM.myplan.Items
		h = .AddItem(ALLTRIM(projekte.project_name))
		.AddBar( h,"Project Summary" , DTOT(projekte.sdate),DTOT(projekte.edate), _key, "" )
		.ItemBar( h ,_key,3 ) = "my text"
	ENDWITH
ENDSCAN

The h variable indicates the handle of the newly created item. This value is always greater than 65000, so the VFP environment fires an error when compiling the AddBar and ItemBar properties because it considers accessing an array, and its limit is 65000. Of course this problem is related to VFP ignoring the fact that it is calling a property of a COM object! not an array, so our products provide a DefaultItem property that help VFP users to pass this error. So, in VFP the above code should look like follows:

SCAN
	_key="K_"+ALLTRIM(STR(projekte.ID))
	WITH THISFORM.myplan.Items
		.DefaultItem = .AddItem(ALLTRIM(projekte.project_name))
		.AddBar( 0,"Project Summary" , DTOT(projekte.sdate),DTOT(projekte.edate),_key, "" )
		THISFORM.myplan.Template = "Items.ItemBar( 0,`" + _key + "`,3 ) = `my text`"
	ENDWITH
ENDSCAN 

The difference ( marked in red ) is that the first parameter for properties like AddBar and ItemBar is 0, and before calling them the Items.DefaultItem property indicates the handle of the item being accessed. How it works? The control uses the value of the Items.DefaultItem property, when the first parameter of the ItemBar, AddBar and so on is 0. The AddItem property saves before the handle of the newly created item to the DefaultItem property, and so the VFP error is gone, and the code works like you expect.

B> The following method uses the TemplateDef / Template methods 

The following code works for eXG2antt control, but the idea is the same for all controls that support TemplateDef / Template and so on.

Let's say that your code looks like follows:

LOCAL h
with thisform.G2antt1
	.BeginUpdate
	.Columns.Add("Tasks")
	with .Chart
		.FirstVisibleDate = {^2000-12-25}
		.PaneWidth(0) = 48
	endwith
	with .Items
		h = .AddItem("Task")
		.AddBar(h,"Task",{^2001-1-2},{^2001-1-6},"K","exBarHAlignCaption = 1")
		.ItemBar(h,"K",4) = 18
	endwith
	.EndUpdate
endwith

The h variable indicates the handle of the newly created item. This value is always greater than 65000, so the VFP environment fires an error when compiling the AddBar and ItemBar properties because it considers accessing an array, and its limit is 65000. Of course this problem is related to VFP ignoring the fact that it is calling a property of a COM object! not an array, so our products provide a DefaultItem property that help VFP users to pass this error. So, in VFP the above code should look like follows:

LOCAL h
with thisform.G2antt1
	.BeginUpdate
	.Columns.Add("Tasks")
	with .Chart
		.FirstVisibleDate = {^2000-12-25}
		.PaneWidth(0) = 48
	endwith
	with .Items
		h = .AddItem("Task")
		.AddBar(h,"Task",{^2001-1-2},{^2001-1-6},"K","exBarHAlignCaption = 1")
		WITH thisform.G2antt1
			.TemplateDef = "Dim h"
			.TemplateDef = h
			.Template = "Items.ItemBar(h,`K`,4) = 18"
		ENDWITH
	endwith
	.EndUpdate
endwith
The following sample changes the Items.ItemBar(exBarCaption) and Items.ItemBar(exBarHAlignCaption) properties:
LOCAL h
with thisform.G2antt1
	.BeginUpdate
	.Columns.Add("Tasks")
	with .Chart
		.FirstVisibleDate = {^2000-12-25}
		.PaneWidth(0) = 48
	endwith
	with .Items
		h = .AddItem("Task")
		.AddBar(h,"Task",{^2001-1-2},{^2001-1-6},"K")
		WITH thisform.G2antt1
			.TemplateDef = "Dim h"
			.TemplateDef = h
			.Template = "Items.ItemBar(h,`K`,3) = `new caption and different alignment`"
			.Template = "Items.ItemBar(h,`K`,4) = 18"
		ENDWITH
	endwith
	.EndUpdate
endwith 

or:

with thisform.G2antt1
	.BeginUpdate
	.Columns.Add("Tasks")
	with .Chart
		.FirstVisibleDate = {^2000-12-25}
		.PaneWidth(0) = 48
	endwith
	with .Items
		.DefaultItem = .AddItem("Task")
		.AddBar(0,"Task",{^2001-1-2},{^2001-1-6},"K")
		WITH thisform.G2antt1
			.Template = "Items.ItemBar(0,`K`,3) = `new caption and different alignment`"
			.Template = "Items.ItemBar(0,`K`,4) = 18"
		ENDWITH
	endwith
	.EndUpdate
endwith 

The Template / TemplateDef methods can run any x-script code described here.

I get "Function argument, value, type, or count is invalid", while I'm using the HTML property. Am I doing something wrong?

The following VFP code assigns your logo, on the eXPrint's paper, but it gives "Function argument, value, type, or count is invalid" while compiling:
with thisform.Print1
	.HTMLPicture("i1") = "E:\Temp\Icons\arrow.gif"
	.ExtraCaption("A","Extra <img>i1</img>", 0, 0 )
	.PrintExt = thisform.G2antt1.Object
	.Preview
endwith

replace with:

with thisform.Print1
	.Object.HTMLPicture("i1") = "E:\Temp\Icons\arrow.gif"
	.ExtraCaption("A","Extra <img>i1</img>", 0, 0 )
	.PrintExt = thisform.G2antt1.Object
	.Preview
endwith

Calling the HTMLPicture property from Object, makes the compiler to call the property of the inside control instead confusing calling or setting an array.

Another approach, is using the Template property like in the following samples:

with thisform.ExplorerBar1
	.Template = "HTMLPicture(`pic`)= `E:/Temp/watch.gif`"
	.Groups.Add("<img>pic</img> Group 1").CaptionFormat = 1
endwith

or

with thisform.ExplorerBar1
	.Object.HTMLPicture("pic") = "E:/Temp/watch.gif"
	.Groups.Add("<img>pic</img> Group 1").CaptionFormat = 1
endwith

instead

with thisform.ExplorerBar1
	.HTMLPicture("pic") = "E:/Temp/watch.gif"
	.Groups.Add("<img>pic</img> Group 1").CaptionFormat = 1
endwith

Notes on use an ATL control (exTree) in FoxPro.

The exTree component (any ATL based component) causes a change from the normal form method firing order when placed on a form. For example, VFP normally fires the following methods in the following order when instantiating a form: Load, Init, Show, Activate, GotFocus. When the exTree object is placed on the form, the VFP method firing order changes as follows: Load, Activate, GotFocus, GotFocus, Init, Show. This is obviously a big problem. Many methods were attempted to get around this including creating the object programmatically (which did successfully correct the firing order problem, but I could not get all things to work correctly, like showing the plus sign for root items among other things). I also attempted to set the object to invisible and set to visible in gotfocus and many other things…

Eventually, I came to the solution explained below. This solution just forces the VFP method firing order to be correct by calling methods explicitly.

  1. Create a custom form property (CFP) and set it equal to 0 in form.load.
  2. Set the CFP equal to 1 in form.init. It should be done at the BOTTOM of the method.
  3. Surround all code in form.show with IF CFP>0 … ENDIF. At the end of all code within the IF stmt (as in, right before endif), explicitly call the form.activate method.
  4. Surround all code in form.activate with IF CFP>0 … ENDIF. At the end of all code within the IF stmt (as in, right before endif), explicitly call the form.gotfocus method.
  5. Surround all code in form.gotfocus with IF CFP>0 … ENDIF.
  6. Additionally, if any code is in the form.resize event, it should be surrounded by the IF CFP>0 … ENDIF statement. This may also hold true for other methods that I have not yet encountered.
  7. Another issue concerns the visibility of the form. Even with the above code, I was getting a flash of the form at position 0,0 on the desktop before it then repositioned itself where I directed it. So, set form.visible to .F. in form.load and then set it to .T. in form.gotfocus.
  8. ** ANOTHER NOTE. Have to set APPLICATION.AUTOYIELD=.F. I am doing this in my startup program (unless I have problems and if so, I will set it equal to .F. in form.load and to .T. in form.unload). The VFP help system says that this should be set to .F. (as opposed to .T. which is the default) on any form on which an activex object is placed. It will prevent the activex from executing code in the middle of foxpro execution of code. As an example, if it was set to .T., sometimes when I clicked on another choice in the treeview, it would appear as highlighted, but the remaining objects on the form did not reflect that I just changed my selection. If I click it again, the remaining objects do change correctly. Setting it to .F. corrected the problem. 

This will cause the firing order to be correct. If you don't have any code in activate, show or gotfocus you don't have to do any of this. However, if you later add code to any of these events, you would have to go back and modify to adhere to these standards. So, it may be a good idea to just put the IF STMT code in each of the events with a note that all code must be within the stmt, since 6 months later, one could easily forget what needed to be done.

Thanks to Tim Stickley, Decision Modeling, Inc who submitted the note. This note is related to VFP 7.0, and it seems to be corrected in VFP 8.0

Custom class that wraps much of the exGrid functionality.

I just wanted to say, that using the Exontrol exSuite has been really great! Thank you for making such a nice product.I mainly program in VFP (Visual FoxPro) and I am currently working with VFP 9.0 (beta).  During my experience with exGrid (which has just started), I decided to share the information I collected with other Visual Foxpro programmers.  I would also like to share it with you in case you find it useful for assisting VFP developers. The information and code I am providing is "public domain" and "free of charge" to any VFP developer, so long as the comments are left "as-is" and they are distributed free of charge. 

Check out the VFP exGrid information page: http://fox.wikis.com/wc.dll?Wiki~exGrid~VFP

Check out the VFP wrapper class (exVGrid.zip): ftp://66.132.144.112/VFP/

The zip file contains:
  VFP project
  Sample VFP Screen
  exVGrid Class code (including event handler, event logging, printing)
  exGrid #DEFINE (constants)
  VFP exGrid "events" Interface Class

I have also created an information page specific to VFP and OLE Objects that might be helpful to any VFP programmers using your controls.  You can find it at: http://fox.wikis.com/wc.dll?Wiki~OLEObjects

Thanks to Paul James, QORE, Inc, Inc who submitted the note. This note is related to VFP 9.0 ( beta ).

Loading data in FoxPro

The controls like ExComboBox, ExTree, ExGrid, ExplorerTree includes plenty of methods to load data using one or more of the followings :
  • AddItem, InsertItem, InsertControlItem
  • DataSource property
  • PutItems

In VFP, the controls provide the DefaultItem property of the Items collection that helps users to access the properties that are using HITEM type for the Item parameter. The VFP fires "Invalid Subscript Range" error, while it tries to process a number grater than 65000. Since, the HITEM is a long value that most of the time exceeds 65000, the VFP users have to use this property, instead passing directly the handles to properties.

The following sample shows to change the cell's image:

.Items.DefaultItem = .Items.AddItem("Item 1")
.Items.CellImage(0,1) = 2

In VFP the following sample fires: "Invalid Subscript Range":

i = .Items.AddItem("Item 1")
.Items.CellImage(i,1) = 2

because the i variable  is grater than 65000.

The following VFP sample loads data to an ExplorerTree control in Form.Init event using all of the mentioned methods ( The sample can be modified to run for any of the other components )

No picture is displayed in <img> HTML tags

Call the Object method so the HTMLPicture property is called for native object as in the following sample:

extree.OBJECT.HTMLpicture("pic1") = "c:\test.bmp"

Calling the HTMLPicture property of the extree directly does not fire any error, nor display the picture in the <img> fields.

The control shows as disabled on VFP when running on a modal form. Is there a fix for it?

When you show a modal window, Visual FoxPro disables all OLE host windows on the form. The ActiveX can not receive any user input related messages anymore, because the window is disabled (the WS_DISABLED windows style is added to the window that hosts the ActiveX control so actually it is disabled) . As a result, the control does not respond to mouse or keyboard events, nor does it receive the focus. 

In order to fix this, you can call the following code on form's GotFocus event:

thisform.OleControl1.Object.Enabled = .T.

where the OleControl is any of our UI components. Also, you can easily use API functions to remove the WS_DISABLED window style.

I get the "Object class is invalid for this container" error when using the _SCREEN.AddObject. What can we do?

The "Object class is invalid for this container" error may occurs, in case the parameters for the AddObject are not what it expects. For instance, the ActiveX must uses its program identifier for cOLEClass parameter, while for other elements, this parameter is not used. 

>>>> When using ActiveX, the correct syntax for object.AddObject is like follows:

LOCAL aka

aka = THISFORM
aka.AddObject("myctrl","olecontrol","Exontrol.ExMenu")
WITH aka.myctrl
  .Visible = .T.
  .Items.ToString = "A[id=10](B[id=20],C[id=30](D[id=40],E[id=50]),F[id=60])"
ENDWITH

where the "Exontrol.ExMenu", is the program identifier, which can be found on the control's help main page. For instance, On the page http://www.exontrol.com/content/products/exg2antt/help/G2antt_default.htm, you can find the "The object's program identifier is:  ... " The program identifier specifies the string to be passed for the cOLEClass ( 3rd parameter ) of the AddObject method.  

>>>> In case the aka is _SCREEN, the code fails as it gives "Object class is invalid for this container", which indicates that you can not place any ActiveX on the main Visual FoxPro window, instead you can follow the trick to do the job, inserting some UI elements to your man window.  IN this case the container is still the form, while the visual container is the _SCREEN which specifies the main Visual FoxPro window. In other words the form receives all events, so you can write there your handlers. The form does not need to be visible, so you can set its Visible property on .F..

DECLARE INTEGER SetParent IN user32;
INTEGER hWndChild,;
INTEGER hWndNewParent

SetParent( thisform.olecontrol1.hWnd, _SCREEN.HWnd )

where the olecontrol1 is the name of the object in the form..

Enabled, Edit method has no effect. What should I do?

The extended control in VFP that hosts the control, provides a few properties like Enabled, Edit, Visible, Width, Height, Edit, .... In order to call the original control's Edit, Enabled method rather than Edit, Enabled method of the wrapper control in VFP, you must call the Edit method of the Object property of the control like in the following sample:
with thisform.Grid1
	.Object.Edit()
endwith

instead of:

with thisform.Grid1
	.Edit()
endwith

or

with thisform.Grid1
	.Object.Enabled = .F.
endwith

instead of:

with thisform.Grid1
	.Enabled = .F.
endwith 

Memo file ...sct is missing or is invalid. What could be wrong?

The VFP fires the "Missing or invalid" or "File access is denied" error, when it is trying to open a sct file from a folder with no Full Control permission set

The error may looks as follows:

In order to prevent that, you can:

  • Copy the C:\Program Files\Exontrol\Control\Sample folder to some other folder, where you have Full Control.
  • Change the Security Permission of the folder where you run the sample, to include the Full Control permission.

    By default, the Security of the Sample folder my looks as:

    and it should look such as

  • Run the Microsoft VFP as administrator ( Admin )

How can I build Isolated Application using your DLL as Isolated COM (Registration-Free Activation of COM)?

An application is considered an isolated application if all of its components are side-by-side assemblies. A side-by-side assembly is a collection of resources—a group of DLLs, windows classes, COM servers, type libraries, or interfaces—available for an application to use at runtime. Typically, a side-by-side assembly is one to several DLLs. 

Isolated COM allows your application to use ActiveX components without having to register them. The original vision of this was to allow copy deployment of the application, but Isolated COM has many benefits. You can have a private copy of the DLL without worrying that another application will install an older or newer copy that breaks your application. Isolated COM also allows you to successfully install and run on non-Administrator accounts.

The solution is to include the control's manifest file to the application's resource under 24 ( Manifest Resource Type ) with the identifier 1. The solution for VFP it's a bit tricky, so please download and check the VFP sample bellow for more details.

  • Build the EXE file from your VFP project
  • Open the EXE using the Visual Studio
  • Locate the 24\1 resource in the EXE. By default, the VFP generates a manifest like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity 
	version="1.0.0.0" 
	type="win32" 
	name="Microsoft.VisualFoxPro" 
	processorArchitecture="x86"
/>
<description>Visual FoxPro</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            language="*"
            processorArchitecture="x86"
            publicKeyToken="6595b64144ccf1df"
        />
    </dependentAssembly>
</dependency>
</assembly>
  • Generates the control's manifest file, using the eXHelper tool
    • Open the eXHelper tool, and select the component whose manifest file you need to generate
    • Right-click the Middle/Template panel, and choose the Generate Assembly Manifest (exg2antt.manifest )
    • Copy the <file> section of the manifest file and you should get something like:
<file name="exg2antt.dll" hashalg="SHA1">
	<comClass clsid="{CD481F4D-2D25-4759-803F-752C568F53B7}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="Exontrol.G2antt.1" description="G2antt Class" miscStatusContent="recomposeonresize,cantlinkinside,insideout,activatewhenvisible,setclientsitefirst"></comClass>
	<comClass clsid="{2DD65709-C0BA-4764-AADF-820919FF181B}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Column.1" description="Column Class" ></comClass>
	<comClass clsid="{28AC7755-06AC-4439-9ADD-EA012B4B2F10}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Columns.1" description="Columns Class" ></comClass>
	<comClass clsid="{1801677D-52FE-4759-B10A-C4FE70EAE035}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Items.1" description="Items Class" ></comClass>
	<comClass clsid="{E2B55693-3D70-426B-9E08-ECF9DC93D98D}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.OleEvent.1" description="OleEvent Class" ></comClass>
	<comClass clsid="{919D16E8-2002-4C11-BC81-1CA0FF8FDDEF}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.OleEventParam.1" description="OleEventParam Class" ></comClass>
	<comClass clsid="{C39F7717-C8C1-44A0-A495-DB5E92FDC79D}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Appearance.1" description="Appearance Class" ></comClass>
	<comClass clsid="{9E3FB380-6CB7-4CCA-B726-FE191133A8A0}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ExDataObjectFiles.1" description="ExDataObjectFiles Class" ></comClass>
	<comClass clsid="{A30C0D8D-98A5-476B-860A-3397645BA8F8}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ExDataObject.1" description="ExDataObject Class" ></comClass>
	<comClass clsid="{4B82A833-421F-496F-BE2F-F5C41DBED707}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}"  description="Template Class" ></comClass>
	<comClass clsid="{D4D088E8-0FA5-4414-A322-D105149D6313}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}"  description="TemplatePage Class" ></comClass>
	<comClass clsid="{1AA7ABFA-8C27-4579-9F06-7CCFAF301B72}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Editor.1" description="Editor Class" ></comClass>
	<comClass clsid="{23AA3A91-C107-44B2-BD23-3978B343DB8A}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Chart.1" description="Chart Class" ></comClass>
	<comClass clsid="{7862FEFF-7FE6-401A-A692-CE4758CDD0FC}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Level.1" description="Level Class" ></comClass>
	<comClass clsid="{D6C57467-EC60-429F-87B7-3751DFB1EEAE}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Bar.1" description="Bar Class" ></comClass>
	<comClass clsid="{75A35E6C-2144-435F-96FF-0BE4A9643176}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Bars.1" description="Bars Class" ></comClass>
	<comClass clsid="{FC5F6509-4354-4D92-A9A9-24EEB081670E}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ConditionalFormat.1" description="ConditionalFormat Class" ></comClass>
	<comClass clsid="{DEDF38EB-BEEA-48D1-8D9E-AF0C81FA8E71}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ConditionalFormats.1" description="ConditionalFormats Class" ></comClass>
	<comClass clsid="{91E561B9-B514-4F1F-BAE1-3E5903C85DA3}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.InsideZoomFormat.1" description="InsideZoomFormat Class" ></comClass>
	<comClass clsid="{513CF640-A498-4800-ACEF-4473491CF282}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.InsideZoom.1" description="InsideZoom Class" ></comClass>
	<comClass clsid="{B6528DA9-8C75-4389-9B72-EE8A8C2BABA3}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.InsideZooms.1" description="InsideZooms Class" ></comClass>
	<comClass clsid="{15F8B91F-49AD-4663-B878-8A3DE05E4A30}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Notes.1" description="Notes Class" ></comClass>
	<comClass clsid="{926F669D-85C4-4D6D-BC9D-BA3759D8B237}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Note.1" description="Note Class" ></comClass>
	<typelib tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib>
</file> 
  • Go Back to Visual Studio's Resource Template, and paste the <file> before /assembly ends and you should get something like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity 
	version="1.0.0.0" 
	type="win32" 
	name="Microsoft.VisualFoxPro" 
	processorArchitecture="x86"
/>
<description>Visual FoxPro</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            language="*"
            processorArchitecture="x86"
            publicKeyToken="6595b64144ccf1df"
        />
    </dependentAssembly>
</dependency>
<file name="exg2antt.dll" hashalg="SHA1">
	<comClass clsid="{CD481F4D-2D25-4759-803F-752C568F53B7}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="Exontrol.G2antt.1" description="G2antt Class" miscStatusContent="recomposeonresize,cantlinkinside,insideout,activatewhenvisible,setclientsitefirst"></comClass>
	<comClass clsid="{2DD65709-C0BA-4764-AADF-820919FF181B}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Column.1" description="Column Class" ></comClass>
	<comClass clsid="{28AC7755-06AC-4439-9ADD-EA012B4B2F10}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Columns.1" description="Columns Class" ></comClass>
	<comClass clsid="{1801677D-52FE-4759-B10A-C4FE70EAE035}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Items.1" description="Items Class" ></comClass>
	<comClass clsid="{E2B55693-3D70-426B-9E08-ECF9DC93D98D}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.OleEvent.1" description="OleEvent Class" ></comClass>
	<comClass clsid="{919D16E8-2002-4C11-BC81-1CA0FF8FDDEF}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.OleEventParam.1" description="OleEventParam Class" ></comClass>
	<comClass clsid="{C39F7717-C8C1-44A0-A495-DB5E92FDC79D}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Appearance.1" description="Appearance Class" ></comClass>
	<comClass clsid="{9E3FB380-6CB7-4CCA-B726-FE191133A8A0}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ExDataObjectFiles.1" description="ExDataObjectFiles Class" ></comClass>
	<comClass clsid="{A30C0D8D-98A5-476B-860A-3397645BA8F8}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ExDataObject.1" description="ExDataObject Class" ></comClass>
	<comClass clsid="{4B82A833-421F-496F-BE2F-F5C41DBED707}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}"  description="Template Class" ></comClass>
	<comClass clsid="{D4D088E8-0FA5-4414-A322-D105149D6313}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}"  description="TemplatePage Class" ></comClass>
	<comClass clsid="{1AA7ABFA-8C27-4579-9F06-7CCFAF301B72}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Editor.1" description="Editor Class" ></comClass>
	<comClass clsid="{23AA3A91-C107-44B2-BD23-3978B343DB8A}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Chart.1" description="Chart Class" ></comClass>
	<comClass clsid="{7862FEFF-7FE6-401A-A692-CE4758CDD0FC}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Level.1" description="Level Class" ></comClass>
	<comClass clsid="{D6C57467-EC60-429F-87B7-3751DFB1EEAE}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Bar.1" description="Bar Class" ></comClass>
	<comClass clsid="{75A35E6C-2144-435F-96FF-0BE4A9643176}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Bars.1" description="Bars Class" ></comClass>
	<comClass clsid="{FC5F6509-4354-4D92-A9A9-24EEB081670E}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ConditionalFormat.1" description="ConditionalFormat Class" ></comClass>
	<comClass clsid="{DEDF38EB-BEEA-48D1-8D9E-AF0C81FA8E71}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.ConditionalFormats.1" description="ConditionalFormats Class" ></comClass>
	<comClass clsid="{91E561B9-B514-4F1F-BAE1-3E5903C85DA3}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.InsideZoomFormat.1" description="InsideZoomFormat Class" ></comClass>
	<comClass clsid="{513CF640-A498-4800-ACEF-4473491CF282}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.InsideZoom.1" description="InsideZoom Class" ></comClass>
	<comClass clsid="{B6528DA9-8C75-4389-9B72-EE8A8C2BABA3}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.InsideZooms.1" description="InsideZooms Class" ></comClass>
	<comClass clsid="{15F8B91F-49AD-4663-B878-8A3DE05E4A30}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Notes.1" description="Notes Class" ></comClass>
	<comClass clsid="{926F669D-85C4-4D6D-BC9D-BA3759D8B237}" tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" progid="ExG2antt.Note.1" description="Note Class" ></comClass>
	<typelib tlbid="{70337FFD-810F-4CDC-B09A-44CDCEE7DF1B}" version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib>
</file>
</assembly>
  • Save the 24\1 resource, and close the Visual Studio.

Now, copy the generated EXE and the exg2antt.dll to a client machine, and run the EXE.

You can download it here the VFP project.

See also: How to Generate Assembly Manifest File (Registration-Free)?

Anchor property for drop down components

The Anchor property defines which borders of the parent container that a visual control is anchored to when resizing the container. In other words, the Anchor defines the position /size of the control based on its parent. The Anchor property works for all components that you can resize in design-mode. The eXComboBox, eXCalendar, or any other library that provides drop down components, works in the same way, excepts that control's height is not the same as the control's label height ( by design ). In case, you need to use the Anchor property with any of these components, you need to change the control's LabelHeight when the form's Resize event occurs. As a separate issue, you can use the Anchor and the eXComboBox, with no change, if you are using the control's Style property on Simple. In this case, you are allowed to change the size of the control on the form, and so Anchor property will change all borders of the control when user resizes the form.

In order to change the control's label height and Anchor property on 240, you should do the following:

  • Place the control to a form in design mode
  • Define the control's Name property ( for instance ComboBox1 )
  • Specify the control's Style property to what you need to have. If using the control's Simple mode nothing than change the Anchor property to 240 is required, else
  • Resize and move the control in design mode to desired position
  • Change the control's Anchor property to 240
  • Save and run the form

If using the control's Simple mode, you will notice that all margins of the control are adjusted based on the Anchor property. If using the control's DropDown or DropDownList mode, you will notice that the control's top and bottom margins of the control ( label ), are not changed if resizing the control, and this is happen because the Anchor property changes the control's height not the control's label height. In order to change the control's label height too, you need to add a handler for Resize event, as shown bellow:

  • Go to design mode, select the component, and change the LabelHeight and Height properties to have the same values
  • Select the Form, and add the Resize event for the form, with the following code
WITH thisform.ComboBox1
  .LabelHeight = .Height
ENDWITH 
  • Save and run the form

Now, everything works smoothly. This behavior is not a problem of VFP or of the control's itself. 

In case, you are wondering why the eXComboBox, eXCalendar ( drop down components ) are the single one that work this way, please insert any of the following:

  • "Microsoft DBCombo Control, version 6.0"
  • "Microsoft DataCombo Control, version 6.0"
  • "Microsoft ImageComboBox Control, version 6.0" 

and you will notice exactly the same behavior.

Arrays (Syntax Error)

An array is an ordered series of data values, called elements, which are referenced by number. Because arrays exist in memory, they provide fast data access and easy manipulation. You can easily specify, locate, or manipulate elements in an array. Unfortunately, the VFP is not able to pass any array to a property of a COM object, so we need to use the TemplatePut method as shown bellow:

For instance, the following code:

LOCAL laMyArray(3)

laMyArray(1)=1
laMyArray(2)=3
laMyArray(3)=5

WITH thisform.exGrid as EXGRIDLib.Grid
	.SingleSel = .F.
	.Items.Selection = @laMyArray
ENDWITH 

 generates the "Syntax Error" at compiling time, so instead you have to use the following code:

LOCAL laMyArray(3)

laMyArray(1)=1
laMyArray(2)=3
laMyArray(3)=5

WITH thisform.exGrid as EXGRIDLib.Grid
	.SingleSel = .F.
	.TemplateDef = "Dim selArray"
	.TemplatePut(@laMyArray)
	.Template = "Items.Selection = selArray"
ENDWITH 

 The green section is a replica of exactly what red section should do. Shortly, the sample passes the VFP reference of the laMyArray to an internal variable selArray, which using the Template method is passed to the Items.Selection property using the x-script language.

Copyright 1999-2017 Exontrol. All rights reserved.