mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-22 21:19:24 +02:00
parent
002ec43393
commit
8ff1532ca9
@ -34,7 +34,7 @@ uses
|
|||||||
// LazUtils
|
// LazUtils
|
||||||
LazTracer, LazUtilities,
|
LazTracer, LazUtilities,
|
||||||
// LCL
|
// LCL
|
||||||
LCLStrConsts, LMessages, LCLType, LResources, GraphType, Controls, Graphics,
|
LCLStrConsts, LMessages, LCLType, LCLIntf, LResources, GraphType, Controls, Graphics,
|
||||||
Dialogs, StdCtrls, Buttons, MaskEdit, ExtCtrls, Calendar, ImgList;
|
Dialogs, StdCtrls, Buttons, MaskEdit, ExtCtrls, Calendar, ImgList;
|
||||||
|
|
||||||
Type
|
Type
|
||||||
@ -714,6 +714,7 @@ Type
|
|||||||
TCustomDBComboBox = class(TCustomComboBox)
|
TCustomDBComboBox = class(TCustomComboBox)
|
||||||
private
|
private
|
||||||
FDataLink: TFieldDataLink;
|
FDataLink: TFieldDataLink;
|
||||||
|
FDetectedEvents: Word;
|
||||||
function GetDataField: string;
|
function GetDataField: string;
|
||||||
function GetDataSource: TDataSource;
|
function GetDataSource: TDataSource;
|
||||||
function GetField: TField;
|
function GetField: TField;
|
||||||
@ -722,8 +723,13 @@ Type
|
|||||||
procedure SetDataSource(const AValue: TDataSource);
|
procedure SetDataSource(const AValue: TDataSource);
|
||||||
procedure SetReadOnly(const AValue: Boolean);
|
procedure SetReadOnly(const AValue: Boolean);
|
||||||
procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK;
|
procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK;
|
||||||
|
protected
|
||||||
|
function DoEdit: boolean;
|
||||||
|
procedure DoOnCloseUp;
|
||||||
|
procedure LMDeferredEdit(var Message: TLMessage); message LM_DEFERREDEDIT;
|
||||||
protected
|
protected
|
||||||
procedure CloseUp; override;
|
procedure CloseUp; override;
|
||||||
|
Procedure Select; override;
|
||||||
procedure DataChange(Sender: TObject); virtual; abstract;
|
procedure DataChange(Sender: TObject); virtual; abstract;
|
||||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||||
procedure Change; override;
|
procedure Change; override;
|
||||||
@ -748,11 +754,9 @@ Type
|
|||||||
|
|
||||||
TDBComboBox = class(TCustomDBComboBox)
|
TDBComboBox = class(TCustomDBComboBox)
|
||||||
protected
|
protected
|
||||||
procedure Change; override;
|
|
||||||
procedure DataChange(Sender: TObject); override;
|
procedure DataChange(Sender: TObject); override;
|
||||||
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||||||
procedure KeyPress(var Key: char); override;
|
procedure KeyPress(var Key: char); override;
|
||||||
procedure Select; override;
|
|
||||||
procedure UpdateData(Sender: TObject); override;
|
procedure UpdateData(Sender: TObject); override;
|
||||||
published
|
published
|
||||||
property Align;
|
property Align;
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
|
|
||||||
// included by dbctrls.pp
|
// included by dbctrls.pp
|
||||||
|
|
||||||
|
CONST
|
||||||
|
DBCBEVENT_CHANGE = 1; // Detected change event
|
||||||
|
DBCBEVENT_SELECT = 2; // Detected select event
|
||||||
|
DBCBEVENT_CLOSEUP = 4; // Detected closeup event
|
||||||
|
|
||||||
{TCustomDBComboBox}
|
{TCustomDBComboBox}
|
||||||
|
|
||||||
function TCustomDBComboBox.GetDataField: string;
|
function TCustomDBComboBox.GetDataField: string;
|
||||||
@ -34,8 +39,8 @@ end;
|
|||||||
|
|
||||||
procedure TCustomDBComboBox.Change;
|
procedure TCustomDBComboBox.Change;
|
||||||
begin
|
begin
|
||||||
FDataLink.Modified;
|
FDetectedEvents := FDetectedEvents or DBCBEVENT_CHANGE;
|
||||||
inherited Change;
|
PostMessage(Handle, LM_DEFERREDEDIT, 0, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomDBComboBox.GetReadOnly: Boolean;
|
function TCustomDBComboBox.GetReadOnly: Boolean;
|
||||||
@ -43,6 +48,69 @@ begin
|
|||||||
Result:=FDataLink.ReadOnly;
|
Result:=FDataLink.ReadOnly;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomDBComboBox.DoEdit: boolean;
|
||||||
|
var
|
||||||
|
oldDataChange: TNotifyEvent;
|
||||||
|
|
||||||
|
procedure RestoreDataChange;
|
||||||
|
begin
|
||||||
|
FDataLink.OnDataChange := oldDataChange;
|
||||||
|
if not result then begin
|
||||||
|
FDatalink.Reset;
|
||||||
|
SelectAll;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
oldDataChange := FDataLink.OnDataChange;
|
||||||
|
FDataLink.OnDataChange := nil;
|
||||||
|
|
||||||
|
try
|
||||||
|
try
|
||||||
|
|
||||||
|
result := FDatalink.Edit;
|
||||||
|
RestoreDataChange;
|
||||||
|
|
||||||
|
if result then begin
|
||||||
|
FDatalink.Modified;
|
||||||
|
if FDetectedEvents and DBCBEVENT_CHANGE <> 0 then
|
||||||
|
inherited Change;
|
||||||
|
if FDetectedEvents and DBCBEVENT_SELECT <> 0 then
|
||||||
|
inherited Select;
|
||||||
|
end;
|
||||||
|
if FDetectedEvents and DBCBEVENT_CLOSEUP <> 0 then
|
||||||
|
DoOnCloseUp;
|
||||||
|
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
|
||||||
|
result := false;
|
||||||
|
RestoreDataChange;
|
||||||
|
if FDetectedEvents and DBCBEVENT_CLOSEUP <> 0 then
|
||||||
|
DoOnCloseUp;
|
||||||
|
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
FDetectedEvents := 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCustomDBComboBox.DoOnCloseUp;
|
||||||
|
begin
|
||||||
|
if Assigned(OnCloseUp) then OnCloseUp(Self);
|
||||||
|
if AutoSelect then
|
||||||
|
begin
|
||||||
|
SelectAll;
|
||||||
|
if (SelText = Text) then
|
||||||
|
AutoSelected := True;
|
||||||
|
end;//End if FAutoSelect
|
||||||
|
FDetectedEvents := 0; // reset because closeup may occur without editing
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomDBComboBox.SetDataField(const AValue: string);
|
procedure TCustomDBComboBox.SetDataField(const AValue: string);
|
||||||
begin
|
begin
|
||||||
FDataLink.FieldName:=AValue;
|
FDataLink.FieldName:=AValue;
|
||||||
@ -64,12 +132,23 @@ begin
|
|||||||
Message.Result := PtrUInt(FDataLink);
|
Message.Result := PtrUInt(FDataLink);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomDBComboBox.LMDeferredEdit(var Message: TLMessage);
|
||||||
|
begin
|
||||||
|
DoEdit;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomDBComboBox.CloseUp;
|
procedure TCustomDBComboBox.CloseUp;
|
||||||
begin
|
begin
|
||||||
if [csLoading,csDestroying,csDesigning]*ComponentState<>[] then exit;
|
if [csLoading,csDestroying,csDesigning]*ComponentState<>[] then exit;
|
||||||
if not ReadOnly then
|
if FDetectedEvents and DBCBEVENT_CHANGE = 0 then
|
||||||
EditingDone;
|
DoOnCloseUp
|
||||||
inherited CloseUp;
|
else
|
||||||
|
FDetectedEvents := FDetectedEvents or DBCBEVENT_CLOSEUP;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCustomDBComboBox.Select;
|
||||||
|
begin
|
||||||
|
FDetectedEvents := FDetectedEvents or DBCBEVENT_SELECT;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomDBComboBox.Notification(AComponent: TComponent; Operation: TOperation);
|
procedure TCustomDBComboBox.Notification(AComponent: TComponent; Operation: TOperation);
|
||||||
@ -83,7 +162,8 @@ end;
|
|||||||
|
|
||||||
procedure TCustomDBComboBox.EditingDone;
|
procedure TCustomDBComboBox.EditingDone;
|
||||||
begin
|
begin
|
||||||
FDataLink.UpdateRecord;
|
if FDatalink.Editing and FDatalink.IsModified then
|
||||||
|
FDataLink.UpdateRecord;
|
||||||
inherited EditingDone;
|
inherited EditingDone;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -95,16 +175,7 @@ begin
|
|||||||
LM_PASTE:
|
LM_PASTE:
|
||||||
begin
|
begin
|
||||||
if FDataLink.CanModify then
|
if FDataLink.CanModify then
|
||||||
begin
|
inherited WndProc(Message)
|
||||||
//LCL changes the Text before LM_PASTE is called and not after like Delphi. Issue 20330
|
|
||||||
//When Edit is called the Text property is reset to the previous value
|
|
||||||
//Add a workaround while bug is not fixed
|
|
||||||
FDataLink.OnDataChange := nil;
|
|
||||||
FDatalink.Edit;
|
|
||||||
FDataLink.Modified;
|
|
||||||
FDataLink.OnDataChange := @DataChange;
|
|
||||||
inherited WndProc(Message);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
Message.Result := 1; // prevent calling default window proc
|
Message.Result := 1; // prevent calling default window proc
|
||||||
end;
|
end;
|
||||||
|
@ -17,22 +17,6 @@ begin
|
|||||||
FDataLink.Field.Text := Text;
|
FDataLink.Field.Text := Text;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDBComboBox.Change;
|
|
||||||
begin
|
|
||||||
try
|
|
||||||
if FDataLink.CanModify then begin
|
|
||||||
FDataLink.OnDataChange := nil;
|
|
||||||
if FDataLink.Edit then begin
|
|
||||||
FDataLink.Field.AsString := Text;
|
|
||||||
FDatalink.Modified;
|
|
||||||
end;
|
|
||||||
FDataLink.OnDataChange := @Datachange;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
inherited Change;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDBComboBox.DataChange(Sender: TObject);
|
procedure TDBComboBox.DataChange(Sender: TObject);
|
||||||
var
|
var
|
||||||
DataLinkField: TField;
|
DataLinkField: TField;
|
||||||
@ -52,10 +36,6 @@ begin
|
|||||||
FDataLink.Reset;
|
FDataLink.Reset;
|
||||||
SelectAll;
|
SelectAll;
|
||||||
Key := VK_UNKNOWN;
|
Key := VK_UNKNOWN;
|
||||||
end else
|
|
||||||
if Key in [VK_DELETE, VK_BACK] then begin
|
|
||||||
if not FDataLink.Edit then
|
|
||||||
Key := VK_UNKNOWN;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -63,34 +43,9 @@ procedure TDBComboBox.KeyPress(var Key: char);
|
|||||||
begin
|
begin
|
||||||
inherited KeyPress(Key);
|
inherited KeyPress(Key);
|
||||||
case Key of
|
case Key of
|
||||||
#8: // special keys
|
|
||||||
if not FDatalink.Edit then
|
|
||||||
Key:=#0;
|
|
||||||
|
|
||||||
#32..#255: //standard keys
|
#32..#255: //standard keys
|
||||||
if not FieldCanAcceptKey(FDataLink.Field, Key) or not FDatalink.Edit then
|
if not FieldCanAcceptKey(FDataLink.Field, Key) then
|
||||||
Key:=#0;
|
Key:=#0;
|
||||||
end;//case
|
end;//case
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDBComboBox.Select;
|
|
||||||
begin
|
|
||||||
//avoid reseting text when calling select
|
|
||||||
FDataLink.OnDataChange := nil;
|
|
||||||
try
|
|
||||||
if FDataLink.Edit then
|
|
||||||
begin
|
|
||||||
FDataLink.Modified;
|
|
||||||
FDataLink.UpdateData;
|
|
||||||
inherited Select;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
// if cannot modify, let it reset
|
|
||||||
FDatalink.Reset;
|
|
||||||
DataChange(Self);
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
FDataLink.OnDataChange := @DataChange;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
@ -90,6 +90,7 @@ const
|
|||||||
|
|
||||||
LM_GRABFOCUS = LM_LCL + 80;
|
LM_GRABFOCUS = LM_LCL + 80;
|
||||||
LM_DRAWLISTITEM = LM_LCL + 81;
|
LM_DRAWLISTITEM = LM_LCL + 81;
|
||||||
|
LM_DEFERREDEDIT = LM_LCL + 82; // used in customdbcombobox
|
||||||
|
|
||||||
// these IDs are reserved for internal messages in the interfaces
|
// these IDs are reserved for internal messages in the interfaces
|
||||||
LM_INTERFACEFIRST = LM_LCL + 99;
|
LM_INTERFACEFIRST = LM_LCL + 99;
|
||||||
|
Loading…
Reference in New Issue
Block a user