10320 : How can I iterate over my rows’ entities? VCL D7

Question

I am trying your component TphGant. I am using Delphi7, and using native component. I did an example. I have gant and a table with two fields. Name and duration. i am able to put these names to the gant and display duration of these names. The user can change duration with the mouse and I need to change duration in my table. but I am not able to iterate from the first TphDataEntity_Ganttime to the last in a row.

How can I iterate over my rows’ entities?

Answer

Each GantRow has a datalist that holds the drawing layers. Each drawing layer has a list that holds the time items. You can iterate them like this:

procedure TForm1.Button2Click(Sender: TObject);
var
  i,ii:integer;
begin
  for i:=0 to phGant1.RowList.Count-1 do
  begin
    for ii:=0 to phGant1.RowList.Rows[i].DataLists.Items[0].Count-1 do
    begin
      (phGant1.RowList.Rows[i].DataLists.Items[0].Items[ii] as TphDataEntity_GantTime).Start:=
    end;
  end;
end;

The same code for ActiveX in VB:

    Dim ti As IphDataEntity_GantTime2
   
    For i = 0 To phGantX1.RowList.Count – 1  ‘ loop over all gantt rows
        For ii = 0 To phGantX1.RowList.GantRow(i).DataLists.Count – 1 ‘ loop over all layers in gantt row
            For iii = 0 To phGantX1.RowList.GantRow(i).DataLists.DataList(ii).Count – 1 ‘loop over all time items          
                Set ti = phGantX1.RowList.GantRow(i).DataLists.DataList(ii).Items(iii)                
                ti.Start = ti.Start + 1
                ti.Stop = ti.Stop + 1
            Next iii
        Next ii
    Next i

10305 : How can I iterate through all loaded RootDataEntities? ( Only the loaded ones) (VCL version)

Question

Hi!
This should be easy for you, but I am lost:
Using a Gant with Grid and VirtualLoad, allowing Multiselect.
How can I iterate through all selected RootDataEntities?
( Only the loaded ones, i dont care about the unload ones ) Iterating all the BABCells gives an exception, when it comes to the unloaded ones. I cant find a way from a RootDataEntity.Item to the correspondent BABCell to check if its loaded or not.

Answer

You can go straight on the loaded grid rows; only loaded, check if they represent a root tree node then check select state:

procedure TForm1.ButtonIterareLoadedAllClick(Sender: TObject); begin
  for i:=0 to phGant1.MainGrid.AxisContentListY.LoadedCount-1 do
  begin
    if phGant1.Grid.AxisContentItemToGridTreeNode(phGant1.Grid.MainGrid.AxisContentListY.Loaded[i]).Level=0 then
    begin
    end;
  end;
end;

To check selection state on a cell in this loop you would go:
phGant_VL.Grid.Cell[x,phGant_VL.Grid.MainGrid.AxisContentListY.Loaded[i].ListIndex].Selected, where x is the column.

To be more precise:

for i:=0 to phGant2.Grid.MainGrid.AxisContentListY.LoadedCount-1 do
begin
  if phGant2.Grid.AxisContentItemToGridTreeNode(phGant2.Grid.MainGrid.AxisContentListY.Loaded[i]).Level=0 then
  begin
    If phGant2.Grid.Cell[0,phGant2.Grid.MainGrid.AxisContentListY.Loaded[i].ListIndex].Selected then
       // Do Stuff here
       // e.g. phGant2.Grid.AxisContentItemToGridTreeNode(phGant2.Grid.MainGrid.AxisContentListY.Loaded[i]).Userreference….
  end;
end;

10285 : “Canvas does not allow drawing”. Then the application crash.

Question

I use in my project a phgant object with the tree enabled. I have about 100 rows in my diagram and i set ganttime.style=tsUser and manage the event OnUserDrawTime (as shown in your example …Samples\ActiveX\VB6\UserDrawAndToolTip) .

After having zoom and scrolled the diagram (vertical and horizontal) many times the GantPyjamas disappears, vertical scrollbar fails and if i try to resize the tree i obtain the error “Canvas does not allow drawing”. Then the application crash.

To test this behavior create in your example UserDrawAndToolTip 100 nodes with ganttime having style tsuser, and then manipulate the diagram.

I tried this also with last patch of phgant.

Thank you.

Answer

What you describe is consistent with what happens if the resources allocated to draw in the OnUserDrawTime event is not properly deleted. You must make sure that pens and brushes are handled in one of two ways;

#1 Created pens and brushes in the OnUserDrawTime MUST be deleted (DeleteObject, see further info in win32 documentation). If you leave only one pen handle un-deleted your application will run out of resources if you scroll back and forth a couple of times.

or

#2 Keep global pens and brushes that you use to draw in the OnUserDrawTime event; in this case do not delete and do not create these objects inside the OnUserDrawTime, but rather create them in FormLoad or were appropriate.

After further investigation by Carlo he found that even when he called DeleteObject it still used up resources. Eventually he found the error: the problem was due to the declaration of function DeleteObject: in your vb example the prototypes of the API funcion DeleteObject and SelectObject are missing of ByVal keyword and so both fail (SelectObject does not return the previous handle of the object).

Public Declare Function DeleteObject Lib “gdi32” (ByVal hgdiobj As Long) As Boolean
Public Declare Function SelectObject Lib “gdi32” (ByVal HDC As Long, hgdiobj As Long) As Long

(The sample has been updated for new future releases, but you may change the module1 declaration to match the lines above)

10243 : Printing in VCL

Question

Using the TPhGant-component I would like to print the gantview as well. However the PrintToHDC seems to be available in the ActiveX-version only.

After some experiments with methods such as PrintWithGrid (causing an AV for unknown reasons) and PhGanttPrinting. TphPrintGantt.Print (is printing but timeobjects are missing?) I would like to have an example on how to print the gantview including treeview and timeobjects since there is not one available for the VCL-component (or i might havnt discovered it yet 😉 )

Tnx in advance 4 your help

Answer

There is a sample in the Samples\VCLNative\VCL\MultiPagePrint folder.

Is does this to start the print:

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  usedwidth,
  usedHeight:integer;
begin
  //showmessage(‘I have no idea how to do this ???’);
  //Answer#
  Printer.BeginDoc;
  Printer.Handle;
  TphPrintGantt.PrintWithGrid(G1,Printer.Handle,10,10,2,2,G1.TreeWidth,nil,-1,true,g1.Start,g1.Stop,g1.Width-g1.TreeWidth,g1.ScalerHeight,usedwidth,usedHeight,0,0,nil);
  Printer.EndDoc;
end;

and also has this in the OnPrintToHdcNewPage event:

procedure TForm1.G1PrintToHdcNewPage(theGant: TphGant_ComBasic;
  aPageNo: Integer; var pageHeight, pageWidht: Integer; var goahead,
  render: Boolean);
begin
    //Answer# continued

  pageHeight:=Printer.PageHeight;
  pageWidht:=Printer.PageWidth;
  goahead:=true;
  render:=true;
  if aPageNo>1 then
    Printer.NewPage;

end;

I would guess that your problems is due to that you are not using the grid option. If you are using the tree you can use the TphPrintGantt.Print call instead…

 

10223 : Page break in printing

Question

Now I have another problem with ” OnPrintToHdcNewPage”.

When I enter to this event, my parameter apageno=1 – always!

In the “gant.printToHdc” func. I have ‘theStopDate’ parameter more then may see on the screen,and I have item in this invisible on the screen’period.

What I must define for getting 2 page?

Answer

The page breaking functionality of the phGantTimePackage will help you to break up your data in pages over the Y axis (ie  the Grid rows).
Bad news: The OnPrintToHdcNewPage will be of much use if you only want to break pages over the x-axis (ie time axis)
Good news: Splitting a print over the X-Axis is much easier than splitting over the Y-axis. You simply call PrintToHdc twice. First one time, then update your Start and Stop time interval, possibly change the grid width, then call printToHdc with the same devicecontext (hdc) again.
 
If you want to combine a split of pages for both X and Y axis you simple implement the OnPrintToHdcNewPage and handle the more complex Y-axis split.
 
You get page one all the time in OnPrintToHdcNewPage because you do not have enough data in the grid to flow over your bounds of printing one page.
 

10208 : In VCL version, may I know how to use onDependencyAction?

Question

In VCL version, may I know how to use onDependencyAction? How to set theFirst and theSecond? How the userIntergerReference be used in the TphDataEntity_Ganttime? Thanks in advance.

Answer

In the TphGant you can set the StickyMode=smDependency. This will set the mouse into a mode were a click and drag from one time item draw an outline  of a link from the time item (start). If the user lets go of the mouse over another time item (target) the OnDependencyAction is fired…

In this event you get theFirst,theSecond:TphDataEntity_GantTime , that is the start and the target.

To exit from this mode you must call StickyMode=smNone…

You are free to use UserReference properties to whatever you need. It is commonly used to store some kind of unique information that leads you back to the original data.

 

10205 : OnHintInfo

Question

We’ve been looking desperately for an event or a property that gives back the current start and stop value of a GantTime when it is dragged. We need to know these values at any time while it is dragged so that the one who drags (or changes the GantTime in another way)  knows the current values of the time period  b e f o r e  he
stops.

Answer

Use IphGantX3.OnHintInfo,

private void axphGantX1_OnHintInfo(object sender,
AxphGantXControl.IphGantXEvents_OnHintInfoEvent e)
{
  labelHint.Text=”Starts”+e.theStart.ToString()+” and This long:”+e.theLength.ToString();
}

Use the e.theStart and e.theLength parameters to get the would be
time/length if the user were to drop now.

10485 : I set the style property to tsUser but the OnUserDrawTime Event does never fired?

Question

How can i draw a brushed item in phSchemaX1? I set the style property to tsUser but the OnUserDrawTime Event does never fired?

Answer

This should not be a problem, and you are doing the right thing setting the tsUser… The only known explenation to this is if you are in FoxPro; check the issues described in this article http://plexityhide.dyndns.org/InstantKB13/Article.aspx?id=10193

If you are not in FoxPro you should send us a repeating sample.TIA

10348 : Color and font of cells in phGantTimePackage grid

Question

Using property TPhGantX.SetGridCellString(X, Y, sText).
With the above property, I am able to display the text (stext) on the left side.

Is there any way that I can change the color and font of this sText?

Answer

Yes. Each cell can be assigned a IphGridLayoutPropX. You can choose to set the same layout on all cells, unique layouts to all cells or anything in between.

Use IphGantX3.GetGridCellLayoutPropIndex, and IphGantX3.SetGridCellLayoutPropIndex to control each cell.

Once you have the hang of that you can set/control the following properties:

BackColor 
EndEllipsis 
Font 
FontColor 
FrameBottom 
FrameColor 
FrameLeft 
FrameOptionsUse 
FrameRight 
FrameTop 
HorzAlignCenter 
HorzAlignRight 
MinHeight 
MinWidth 
UseFontInfo 
VertAlignCenter 
WrapTextAndFit

Note that you must set UseFontInfo=true for Font and FontColor to be applied.

10254 : Setting top row in phGantTimePackage VCL

Question

Using the VCL-version of the ganttview how can I make a row of the gantt the toprow ? Or: why does the MakeSureRowInView (in the way like shown in the example below) not work ? Do additional properties to be set ?

_gantrow := phgant1.RowList.Rows[20];

phgant1.MakeSureRowInView(_gantrow);

Answer

If you are using the Grid option you can control the TopLeftCell like this
    Gantt.Grid.TopLeftCell…

Using the tree you go like this:
    Gantt.TreeView.TopItem…

The MakeSureRowInView(theGantRow:TGantRow) looks for time items on this row and changes the time settings so that they show.