Lazarus - Show differents hints for every column in a TListView - lazarus

I have a TListView with 4 columns and I would like that when hovering over the title bar, a different hint is shown for each column. I have tried the following...
procedure TfConsolidados.lstDisponiblesMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (X=lstDisponibles.Columns[0].Index) then
lstDisponibles.Hint:='Incidencias'
else if (X=lstDisponibles.Columns[2].Index) then
lstDisponibles.Hint:='Incluida en hoja de ruta'
else
lstDisponibles.Hint:='';
end;
I'm starting in this programming and I would need your help.
Thank you very much.

Related

Do an IF by DBGrid Column Title

I want to create a different Popup for each column. Since the columns order can be changed I need to identify that by the column title but I have not found a solution.
These are two method I have applied without success.
procedure TForm2.DBGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
ACol, ARow: Integer;
begin
if Y < DBGrid1.DefaultRowHeight then
begin
(Sender as TDBGrid).MouseToCell(X, Y, ACol, ARow);
if Button = mbRight then
begin
if DBGrid1.SelectedColumn.FieldName = 'Title1' then
BEGIN
ShowMessage('Title1'+ IntToStr(ACol));
end;
if DBGrid1.SelectedColumn.FieldName = 'Title2' then
BEGIN
ShowMessage('Title2'+ IntToStr(ACol));
end;
end;
end;
end;
It is not functional because it identifies the columns by id and not the name so if the user change the columns order it will not work fine.
Also this faily code
procedure TForm2.Button2Click(Sender: TObject);
var
i: Integer;
CaptionText: string;
begin
for i := 0 to DBGrid1.Columns.Count - 1 do
case DBGrid1.Columns[i].FieldName of
'TEST':
begin
DBGrid1.Columns[i].Title.Caption := 'REPLACE TEXT';
end;
end;
end;
It simply replace all titles in a click.
What I'm looking to do is to create an IF like this that handle on right clicking column title:
if selected column name = 'test' then
begin
showmessage('You have selected test column');
end;
I'll use the if to create dynamic popup to apply filters.
The code below is an event handler for a TDBGrid's MouseMove event which
displays the Caption of the Title of the column the mouse is over on the caption of the form.
procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
Col,
Row : Integer;
begin
Col := DBGrid1.MouseCoord(X, Y).X;
Row := DBGrid1.MouseCoord(X, Y).Y;
if (dgIndicator in DBGrid1.Options) then
Dec(Col);
if (Col >= 0) and (Col < DBGrid1.Columns.Count) then
Caption := DBGrid1.Columns[Col].Title.Caption
else
Caption := '';
end;
Note that the
if (dgIndicator in DBGrid1.Options) then
Dec(Col);
is to adjust the behaviour for correct operation if the dgIndicator option is turned off.
Obviously, instead of
Caption := DBGrid1.Columns[Col].Title.Caption
you could do
MenuItem.Caption := DBGrid1.Columns[Col].Title.Caption
to copy the column title to a menuitem's caption. I think you probably don't need to do any comparison of the Title.Caption's value with any hard-coded constants, but obviously that's your choice.
Btw, if you would rather access the name of the dataset field which is supplying the displayed values for the Column's contents, you can read the Column's FieldName property.

Teechart: End labels on logarithmic x-axis

If I have a logarithmic x-axis with value from 10 to 400 it displays 10 and 100, but I also want it to display the end value 400.
Another problem is if the values goes from 11 to 400, it only displays label at 100. Here I want to display 11, 100 and 400.
Anyone know what axis/label property to set for this?
To draw such labels you should use custom labels.
I'll assume you are using TeeChart VCL and I'll show code in Delphi, but it would be similar with TeeChart .NET, TeeChart ActiveX or TeeChart Java.
If I have a logarithmic x-axis with value from 10 to 400 it displays 10 and 100, but I also want it to display the end value 400.
You could do it as follows:
uses Series, Math;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=False;
Chart1.Legend.Hide;
Chart1.Walls.Hide;
Chart1.Gradient.Visible:=False;
Chart1.Color:=clWhite;
Chart1.Axes.Bottom.Logarithmic:=True;
with Chart1.AddSeries(TFastLineSeries) as TFastLineSeries do
begin
for i:=10 to 400 do
AddXY(i, sin(i/100));
end;
with Chart1.Axes.Bottom.Items do
begin
Clear;
Add(10, '10');
Add(100, '100');
Add(400, '400');
end;
end;
Another problem is if the values goes from 11 to 400, it only displays label at 100. Here I want to display 11, 100 and 400.
You could do it as follows:
uses Series, Math;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=False;
Chart1.Legend.Hide;
Chart1.Walls.Hide;
Chart1.Gradient.Visible:=False;
Chart1.Color:=clWhite;
Chart1.Axes.Bottom.Logarithmic:=True;
with Chart1.AddSeries(TFastLineSeries) as TFastLineSeries do
begin
for i:=11 to 400 do
AddXY(i, sin(i/100));
end;
with Chart1.Axes.Bottom.Items do
begin
Clear;
Add(11, '11');
Add(100, '100');
Add(400, '400');
end;
end;

Pascal: Project raising External: SIGSEGV when interacting with Form

Let's say, there are 3 forms in a project (Form1, Form2, Form3). Form1 has a button on it with the OnClick event set to Form2.Show. This code executes perfectly, however if Form2's code tries to call Form3.Show, then the project raises an EXTERNAL: SIGSEGV pointing to Customform.inc
Project project1 raised exception class 'External: SIGSEGV'
In file '.\include\customform.inc' at line 2196:
Visible := True;
This is exactly what's happening to my project. All forms were properly created and declared, and the units are linked perfectly. The compilation goes fine, without any errors or warnings.
So it is impossible to make the third form visible. But I've discovered that every kind of interaction would result in an External: SIGSEGV error pointing to random pieces of code which compile and run just fine. I just can't figure out the origin of the error.
If I try to execute my project without the debugger, I get an Access Violation error. Failing code:
procedure TWarForm.FormCreate(Sender: TObject);
Begin
Form3.Show;
end;
from
unit work;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls, BGRAFlashProgressBar, AuthUnit;
type
{ TWarForm }
TWarForm = class(TForm)
ArcaneDustIMG: TImage;
ProgressBar: TBGRAFlashProgressBar;
ArcaneEDT: TEdit;
GoldEDT: TEdit;
GoldIMG: TImage;
Label1: TLabel;
Wallpaper: TImage;
procedure FormCreate(Sender: TObject);
procedure WallpaperMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure WallpaperMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure WallpaperMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ private declarations }
public
{ public declarations }
end;
var
WarForm: TWarForm;
MouseIsDown: Boolean;
PX, PY: Integer;
implementation
{$R *.lfm}
{ TWarForm }
procedure TWarForm.WallpaperMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then begin
MouseIsDown := True;
PX := X;
PY := Y;
end;
end;
procedure TWarForm.FormCreate(Sender: TObject);
Begin
Form3.Show;
end;
procedure TWarForm.WallpaperMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if MouseIsDown then begin
SetBounds(WarForm.Left + (X - PX), WarForm.Top + (Y - PY), WarForm.Width, WarForm.Height);
end;
end;
procedure TWarForm.WallpaperMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
MouseIsDown:=False;
end;
end.
You have to create the forms either manualy or set them to "auto create" in your IDE
To Create them manualy just change your code slightly:
TWarForm = class(TForm)
ArcaneDustIMG: TImage;
ProgressBar: TBGRAFlashProgressBar;
ArcaneEDT: TEdit;
GoldEDT: TEdit;
GoldIMG: TImage;
Label1: TLabel;
Wallpaper: TImage;
Form2: TForm2; // insert Form2
Form3: TForm3; // and Form3
procedure FormCreate(Sender: TObject);
procedure WallpaperMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure WallpaperMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure WallpaperMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ private declarations }
public
{ public declarations }
end;
..
procedure TWarForm.FormCreate(Sender: TObject);
Begin
Form3 := TForm3.Create(Self);
Form3.Show;
end;
If you do so, don't forget to call Form3.Free at the end of your application execution.

Defining borders for image movement in Delphi [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I need to move an image with along X-axis and, when it reaches defined borders, stop moving (I'm making my own trackbar). I can't find out how to define borders. With my code when it reaches border, it stucks there and unable to move. Here's the code
var
PinCurrentPosition,PinStartingPosition:integer;
move:boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
Image5.Picture.LoadFromFile('Untitled2.bmp');
PinStartingPosition:=Image5.Left;
end;
procedure TForm1.Image5MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (button <> mbLeft) then move:=false
else
begin
move:=true;
PinCurrentPosition:=x;
end;
end;
procedure TForm1.Image5MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if move and ((PinStartingPosition-75)<Image5.Left)
and ((PinStartingPosition+75)>Image5.Left) then
Image5.Left:=Image5.Left+x-PinCurrentPosition;
end;
procedure TForm1.Image5MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
move:=false;
end;
You should add an Else to Image5MouseMove procedure to correct image position if it is outside of movable area:
procedure TForm1.Image5MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if
move and
(Image5.Left>(PinStartingPosition-75)) and
(Image5.Left<(PinStartingPosition+75))
then
Image5.Left:=Image5.Left+x-PinCurrentPosition;
else if Image5.Left<=(PinStartingPosition-75) then
Image5.Left:= PinStartingPosition-75+1
else if Image5.Left>=(PinStartingPosition+75) then
Image5.Left:= PinStartingPosition+75-1;
end;

How to create a pan from composite image in Delphi

I'm kind of new to delphi graphics methods and I'm stucked at creating a ... viewport , thats how I call it while i was doing it for a project. I'm sorry I can't provide any code for it but I'm stuck at the logic part , searching google pointed me to some OnPaint , Draw methods. But those are not what I'm trying to accomplish, since I have , for example:
A 1600x1000 background image anchored to the client's top/bottom/right and left.
Multiple TImage elements placed at set x/y coords.
A "hotspot" like a map element in HTML where I can set the clickable areas (for the images i'm placing at step 2)
No zoom needed.
And the most important thing, while the background is dragged, those TImages placed on top of the background need to be dragged too.
My logic (in HTML/jQuery) was to create a #viewportBinder (which was the div i was dragging, transparent bg), followed by another div inside it called #viewtown (1600x1000, the background) which contains the divs (those TImages) placed at set coordinates in CSS.
So when I am dragging the viewportBinder, jQuery sets the new x/y on the #viewport. Implicitly, the divs (TImages) inside the #viewport are moving because the parent was positioned relative.
Does anybody have any experience with this kind of project ? Any snippet of code ?
To be more specific i'll give you my html example of what i accomplised and what i want to port into Delphi code: http://www.youtube.com/watch?v=9iYqzvZFnGA
Sorry if i'm not clear enough, i have no starting point since I have no experience with this in delphi at all. (using RAD Studio 2010)
A very short example how it could be realized in an easy way.
You would use a Paintbox for painting, 1 Backimage, an array of Records with info and transparent pngimages.
Canvas can be manipulated in offset/zoom/rotation.
Moving and hitdetection would happen in mousedown and mousemove.
It's not complete, but might give you an idea how it could be done.
[delphi]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls,PNGImage, StdCtrls;
type
TBuilding=Record // record for building informations
Pos:TPoint;
PNGImage:TPngImage;
// what ever needed
End;
TBuildingArray=Array of TBuilding; // array of buildings
TForm1 = class(TForm)
PaintBox1: TPaintBox;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private-Deklarationen }
FXoffs,FYOffs,FZoom:Double; // offset and zoom for painting
FMouseDownPoint:TPoint;
FBackGroundPNG:TPNGImage;
FBuildingArray:TBuildingArray;
procedure Check4Hit(X, Y: Integer);
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
uses Math;
{$R *.dfm}
Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);
var
form : tagXFORM;
Winkel:Double;
begin
Winkel := DegToRad(Angle);
SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
SetMapMode(ACanvas.Handle,MM_ANISOTROPIC);
form.eM11 := Zoom * cos( Winkel);
form.eM12 := Zoom *Sin( Winkel) ;
form.eM21 := Zoom * (-sin( Winkel));
form.eM22 := Zoom * cos( Winkel) ;
form.eDx := CenterpointX;
form.eDy := CenterpointY;
SetWorldTransform(ACanvas.Handle,form);
end;
Procedure ResetCanvas(ACanvas:TCanvas);
begin
SetCanvasZoomAndRotation(ACanvas , 1, 0, 0,0);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Path:String;
i:Integer;
begin
FZoom := 1;
DoubleBuffered := true;
Path := ExtractFilePath(Paramstr(0));
FBackGroundPNG:=TPNGImage.Create;
FBackGroundPNG.LoadFromFile(Path + 'infect.png');
SetLength(FBuildingArray,3);
for I := 0 to High(FBuildingArray) do
begin
FBuildingArray[i].PNGImage := TPngImage.Create;
FBuildingArray[i].PNGImage.LoadFromFile(Path + Format('B%d.png',[i]));
FBuildingArray[i].Pos.X := I * 300;
FBuildingArray[i].Pos.Y := Random(1000);
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i:Integer;
begin
for I := 0 to High(FBuildingArray) do
begin
FBuildingArray[i].PNGImage.Free;
end;
FBackGroundPNG.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if FZoom=0.5 then FZoom := 1 else FZoom := 0.5;
PaintBox1.Invalidate;
end;
procedure TForm1.Check4Hit(X,Y:Integer);
var
i,Index:Integer;
R:TRect;
P:TPoint;
begin
index := -1;
for I := 0 to High(FBuildingArray) do
begin
R := Rect(FBuildingArray[i].Pos.X,FBuildingArray[i].Pos.Y
,FBuildingArray[i].Pos.X + FBuildingArray[i].PNGImage.Width
,FBuildingArray[i].Pos.Y + FBuildingArray[i].PNGImage.Height);
P := Point(Round((x - FXOffs)/FZoom) ,Round((y - FYOffs)/FZoom));
if PtInRect(R,P) then Index := i;
end;
if index > -1 then
begin
Caption := Format('Last hit %d',[index]);
end
else Caption := 'No Hit';
end;
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Check4Hit(X,Y);
FMouseDownPoint.X := X;
FMouseDownPoint.Y := Y;
end;
procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
FXoffs := -( FMouseDownPoint.X - X) ;
FYoffs := -( FMouseDownPoint.Y - Y) ;
if FXoffs>0 then FXoffs := 0;
if FYoffs>0 then FYoffs := 0;
PaintBox1.Invalidate;
end;
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
i:Integer;
begin
SetCanvasZoomAndRotation(PaintBox1.Canvas,FZoom,0,FXoffs,FYOffs);
PaintBox1.Canvas.Draw(0,0,FBackGroundPNG);
for I := 0 to High(FBuildingArray) do
begin
PaintBox1.Canvas.Draw(FBuildingArray[i].Pos.X,FBuildingArray[i].Pos.Y,FBuildingArray[i].PNGImage);
end;
end;
end.
[/delphi]
Sorry, but for last several years i working with Lazarus instead of Delphi. But tis article will be informative: http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Create_a_custom_control_which_draws_itself
About relative coordinates nothing to say - it is simple.
About dragging: A long time ago in a galaxy far, far away.. that was something like:
// To start dragging
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
// To stop dragging
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
// To perform dragging
procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;

Resources