Delphi 2010 " is" statement behaves differently than Delphi 7's? - delphi

Why does the code below return TRUE in Delphi 7 and FALSE in Delphi 2010? TBitBtn is a descendant of TButton.
type
TForm1 = class(TForm)
Button1: TButton;
BitBtn1: TBitBtn;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TestControl( aControl: TControl);
begin
if (aControl is TButton) then showmessage('TRUE') else showmessage('FALSE');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TestControl(BitBtn1);
end;

is did not change. TBitBtn is a subtype of TCustomButton, not TButton, as you state.

Related

How access webcam that's running in a separated thread?

I have this class to handle my webcam and want know how can stop the webcam started in a separated thread. Camera.Destroy not is working and the camera keep on.
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Panel1: TPanel;
Image1: TImage; // To load camera Bitmap from stream
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TCameraThread = class(TThread)
protected
procedure Execute; override;
end;
var
Form1: TForm1;
implementation
uses
Webcam;
{$R *.dfm}
procedure TCameraThread.Execute;
begin
Camera := TCamera.Create(Form1.Panel1);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
mCamera: TCameraThread;
begin
mCamera := TCameraThread.Create(False);
mCamera.Resume;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if Assigned(Camera) then
Camera.Destroy;
end;
end.

Delphi - Panel & Button Click Effect

I have a CheckBox that shows and hides a Panel that has a Button & two TEdits (for entering an IP address & its port).
The problem is the Button has no effect, it stays gray, also the Panel still shows. I tried different methods, e.g. ModalResult := mrOk;, which didn't change anything.
Here is my code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
Panel1: TPanel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
procedure CheckBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked = True then begin
Panel1.Visible := True;
end
else
if CheckBox1.Checked = False then begin
Panel1.Visible := False;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Button1: TButton;
begin
Button1 := Sender as TButton;
ShowMessage(Button1.Caption + ' Changes');
end;
end.
I hope I'm understanding your question..
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
Panel1: TPanel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
procedure CheckBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
procedure Showpanel(AShow: boolean);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Showpanel(AShow: boolean);
begin
Checkbox1.checked := AShow;
Panel1.Visible := AShow;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
ShowPanel(false);
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
Panel1.visible := Checkbox1.Checked;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Showmessage(Button1.Caption + ' Changes');
end;
end.

Event OnChange doesn't fired when I call method LoadFromFile of TSynEdit.Lines

I have a project using TSynEdit. I found that when I call SynEdit1.Lines.LoadFromFile(), event OnChange doesn't be fired.
For instance:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
SynEdit1: TSynEdit;
procedure Button1Click(Sender: TObject);
procedure SynEdit1Change(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
SynEdit1.Lines.LoadFromFile('unit1.pas');
end;
procedure TForm1.SynEdit1Change(Sender: TObject);
begin
Caption:=Caption + '!';
end;
end.
In above example, I created a form which have a button and a SynEdit.
How can I make event OnChange be fired when SynEdit1.Lines.LoadFromFile() was called?
If you try to assign all the events handler of a synedit, the best you can get is a notification when the editor is cleared. For example if you test the following code the form caption will be set to 'cleared' after the button click event:
uses
Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
StdCtrls, LazSynEditText;
type
TSynEditEx = class helper for TSynEdit
function getTextBuffer: TSynEditStrings;
end;
TForm1 = class(TForm)
Button1: TButton;
SynEdit1: TSynEdit;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure textCleared(sender: TObject);
procedure textHistoryModified(sender: TObject);
procedure textBuffChanged(sender: TObject);
procedure textLineChanged(sender: TObject);
procedure textEditAction(sender: TObject);
procedure textModdChanged(sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
function TSynEditEx.getTextBuffer: TSynEditStrings;
begin
exit(TextBuffer);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SynEdit1.getTextBuffer.AddNotifyHandler(senrCleared, #textCleared);
SynEdit1.getTextBuffer.AddNotifyHandler(senrUndoRedoAdded, #textHistoryModified);
SynEdit1.getTextBuffer.AddNotifyHandler(senrTextBufferChanged, #textBuffChanged);
SynEdit1.getTextBuffer.AddNotifyHandler(senrLineChange, #textLineChanged);
SynEdit1.getTextBuffer.AddNotifyHandler(senrModifiedChanged, #textModdChanged);
end;
procedure TForm1.textModdChanged(sender: TObject);
begin
Caption := Caption + ' ModdChanged';
end;
procedure TForm1.textEditAction(sender: TObject);
begin
Caption := Caption + ' EditAction';
end;
procedure TForm1.textLineChanged(sender: TObject);
begin
Caption := Caption + ' LineChanged';
end;
procedure TForm1.textBuffChanged(sender: TObject);
begin
Caption := Caption + ' BuffChanged';
end;
procedure TForm1.textCleared(sender: TObject);
begin
Caption := Caption + ' Cleared';
end;
procedure TForm1.textHistoryModified(sender: TObject);
begin
Caption := Caption + ' HistoryModified';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SynEdit1.Lines.LoadFromFile('unit1.pas');
end;
So the only solution is to subclass TSynEdit and introduce a custom LoadFromFile method and then trigger the onChange event inside. AFAIK, based on a short investigation, this is the only way, a bit like this:
uses
Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
StdCtrls, LazSynEditText;
type
TSynEditEx = class helper for TSynEdit
procedure LoadFromFile(const aFilename: string);
end;
TForm1 = class(TForm)
Button1: TButton;
SynEdit1: TSynEdit;
procedure Button1Click(Sender: TObject);
procedure SynEdit1Change(Sender: TObject);
private
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
procedure TSynEditEx.LoadFromFile(const aFilename: string);
begin
Lines.LoadFromFile('unit1.pas');
if assigned(onChange) then
onChange(self);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SynEdit1.LoadFromFile('unit1.pas');
end;
procedure TForm1.SynEdit1Change(Sender: TObject);
begin
caption := caption + '!';
end;
In the real world you wouldn't use a class helper but you'd rather subclass, but I think you should get the idea.

Listbox (Listing Error)

Hi Im doing a raffle program for my friend.Everything was going good but then when i delete a value,the result was changing... Please help me!
Example:
Listbox;
1-a
2-c
3-b
4-f
5-h
6-j
After delete line 3:
1-a
2-c
4-f
5-h
6-j
6-g
What i want:
1-a
2-c
3-f
4-h
5-j
6-g
Here are the codes:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Label1: TLabel;
ComboBox1: TComboBox;
Edit1: TEdit;
Button1: TButton;
Label2: TLabel;
ComboBox2: TComboBox;
Label3: TLabel;
Button2: TButton;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Button3: TButton;
Button4: TButton;
SaveDialog1: TSaveDialog;
OpenDialog1: TOpenDialog;
Button5: TButton;
Button6: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
b,sayac:integer;
sonkayit,deneme:integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
sayac:=0;
listbox1.MultiSelect:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
sayac:=sayac+1;
b:=listbox1.Count + 1;
listbox1.Items.Add(IntToStr(b) + ' ' + edit1.Text);
edit1.Text:='';
end;
procedure TForm1.Button2Click(Sender: TObject);
var
a:integer;
kisi:string;
begin
Randomize;
a:=Random(b);
kisi:= listbox1.Items.Strings[a];
edit2.Text:=(kisi);
if combobox1.ItemIndex=0 then
begin
edit2.Visible:=true;
edit3.Visible:=false;
edit4.Visible:=false;
edit5.Visible:=false;
edit6.Visible:=false;
end;
if combobox1.ItemIndex=1 then
begin
edit2.Visible:=true;
edit3.Visible:=true;
edit4.Visible:=false;
edit5.Visible:=false;
edit6.Visible:=false;
end;
if combobox1.ItemIndex=2 then
begin
edit2.Visible:=true;
edit3.Visible:=true;
edit4.Visible:=true;
edit5.Visible:=false;
edit6.Visible:=false;
end;
if combobox1.ItemIndex=3 then
begin
edit2.Visible:=true;
edit3.Visible:=true;
edit4.Visible:=true;
edit5.Visible:=true;
edit6.Visible:=false;
end;
if combobox1.ItemIndex=4 then
begin
edit2.Visible:=true;
edit3.Visible:=true;
edit4.Visible:=true;
edit5.Visible:=true;
edit6.Visible:=true;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
savedialog1.FileName:='çekiliş';
if savedialog1.Execute then
begin
listbox1.Items.SaveToFile(savedialog1.FileName + '.txt');
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
if opendialog1.Execute then
begin
listbox1.Items.LoadFromFile(opendialog1.FileName);
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
listbox1.DeleteSelected;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
listbox1.Clear;
end;
end.
listbox1.Items.Add(IntToStr(b) + ' ' + edit1.Text);
instead of directly adding to listbox,store both IntToStr(b) and edit1.Text seperate in two string list,and populate the listbox data from the stringlists.
also performing delete delete from the second stringlist the corresponding index,and repopulate in listbox
or you can just store the edit1.Text in a stringlist,and delete the string from stringlist that you delete from listbox . and populate the data in listbox with the index+string combination.....
I would use a virtual list box here. These are the basic steps:
Store the data in a container other than the GUI control, for instance a string list. This is good practise in any case.
Set the Style to lbVirtual.
Implement on OnData event handler for the list. It needs to return a string composed of the index, and the underlying item in your container.
When you delete an item, delete it from the string list container and call Invalidate on the list box to force a paint cycle. That paint cycle will request new values by calling OnData and your code can supply the updated text.
Whenever the underlying container is modified, you must let the control know how many items it is displaying by setting the Count property of the list box control.
Here is a very simple example:
Pascal unit
unit Unit1;
interface
uses
SysUtils, Classes, Controls, StdCtrls, Forms;
type
TForm1 = class(TForm)
List: TListBox;
Delete: TButton;
procedure FormCreate(Sender: TObject);
procedure ListData(Control: TWinControl; Index: Integer; var Data: string);
procedure DeleteClick(Sender: TObject);
private
FItems: TStringList;
end;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
c: Char;
begin
FItems := TStringList.Create;
for c := 'a' to 'z' do
FItems.Add(c);
List.Count := FItems.Count;
end;
procedure TForm1.ListData(Control: TWinControl; Index: Integer;
var Data: string);
begin
Data := Format('%d %s', [Index+1, FItems[Index]]);
end;
procedure TForm1.DeleteClick(Sender: TObject);
var
Index: Integer;
begin
for Index := FItems.Count-1 downto 0 do
if List.Selected[Index] then
FItems.Delete(Index);
List.Count := FItems.Count;
List.Invalidate;
end;
end.
Associated form file
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 303
ClientWidth = 307
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object List: TListBox
Left = 8
Top = 8
Width = 201
Height = 287
Style = lbVirtual
Anchors = [akLeft, akTop, akRight, akBottom]
MultiSelect = True
TabOrder = 0
OnData = ListData
end
object Delete: TButton
Left = 224
Top = 8
Width = 75
Height = 23
Anchors = [akTop, akRight]
Caption = 'Delete'
TabOrder = 1
OnClick = DeleteClick
end
end

Where the TDBGrid Columns resize event was triggered

I have a TDBGrid component. I need to catch the event triggered when I'm resizing a column of the grid.
the only place to get an events seems to be overriding ColWidthChanged...
type
TDBgrid=Class(DBGrids.TDBGrid)
private
FColResize:TNotifyEvent;
procedure ColWidthsChanged; override;
protected
Property OnColResize:TNotifyEvent read FColResize Write FColResize;
End;
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
DBGrid1: TDBGrid;
ADODataSet1: TADODataSet;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
private
procedure ColResize(Sender: TObject);
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TDBgrid }
procedure TDBgrid.ColWidthsChanged;
begin
inherited;
if Assigned(FColResize) then FColResize(self);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DBgrid1.OnColResize := ColResize;
end;
procedure TForm1.ColResize(Sender:TObject);
begin
Caption := FormatDateTime('nn:zzz',now) ;
end;
you need to create a descendent of TDBGrid and implement the event by yourself. Something like this:
unit MyDBGrid;
interface
type
TMyDBGrid = class(TDBGrid)
private
FOnColResize: TNotifyEvent;
protected
procedure ColWidthsChanged; override;
public
published
property OnColResize: TNotifyEvent read FOnColResize write FOnColResize;
end;
implementation
{ TMyDBGrid }
procedure TMyDBGrid.ColWidthsChanged;
begin
inherited;
if (Datalink.Active or (Columns.State = csCustomized)) and
AcquireLayoutLock and Assigned(FOnColResize) then
FOnColResize(Self);
end;
end.
this should work, I don't have time now to test it.

Resources