Jump to content

Gustav Schubert

  • Content Count

  • Joined

  • Last visited

  • Days Won


Gustav Schubert last won the day on December 11 2019

Gustav Schubert had the most liked content!

Community Reputation

12 Good

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Gustav Schubert

    Programmatically Change Properties of a Custom style

    I found out why and I post the test code without talking too much: unit FrmMain; interface uses System.SysUtils, System.Classes, System.UITypes, System.Rtti, FMX.Types, FMX.Forms, FMX.StdCtrls, FMX.Objects, FMX.Controls, FMX.Controls.Presentation; type TMyPanel = class(TPanel) public function FindStyleResource(const AStyleLookup: string; const AClone: Boolean = False): TFmxObject; override; end; TFormMain = class(TForm) procedure FormCreate(Sender: TObject); private Button: TButton; Panel: TPanel; procedure Button1Click(Sender: TObject); end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); begin Panel := TMyPanel.Create(Self); Panel.Parent := Self; Panel.Position.X := 100; Panel.Position.Y := 100; Button := TButton.Create(Self); Button.Parent := Self; Button.Text := 'Test'; Button.OnClick := Button1Click; end; procedure TFormMain.Button1Click(Sender: TObject); begin Panel.StylesData['Something.Fill.Color']:= TAlphaColors.Dodgerblue; // Panel.StylesData['.Fill.Color']:= TAlphaColors.Dodgerblue; end; { TMyPanel } function TMyPanel.FindStyleResource(const AStyleLookup: string; const AClone: Boolean): TFmxObject; function FindOnTopLevel(const Name: string): TFmxObject; var Child: TFmxObject; begin for Child in Children do begin if SameText(Child.StyleName, Name) then begin Exit(Child); end; end; Result := nil; end; begin result := nil; { New: try something even if ResourceLink has no children ! } if ResourceLink.ChildrenCount = 0 then begin result := FindOnTopLevel(''); if result is TRectangle then Exit; end; inherited; end; (* There is a problem when FindStyleResource is called on a FResourceLink instance which has no children. function TFmxObject.FindStyleResource(const AStyleLookup: string; const Clone: Boolean = False): TFmxObject; begin if (AStyleLookup <> '') and (FChildren <> nil) and (FChildren.Count > 0) then begin // not executed because TPanel.ResourceLink has no children end; end; FMX.Types.TFmxObject.FindStyleResource('',False) FMX.Controls.TStyledControl.FindStyleResource(???,???) FMX.Controls.Presentation.TPresentedControl.FindStyleResource('',False) FMX.Controls.TStyledControl.StyleDataChanged(???) FMX.Controls.Presentation.TPresentedControl.StyleDataChanged('.Fill.Color') FMX.Controls.TStyledControl.SetStyleData('.Fill.Color') FrmMain.TFormMain.Button1Click($3F30880) *) end.
  2. Gustav Schubert

    Windows Build 1909

    I see the same OsHardwareAbstractionlayer = 10.0.18362.752 But my Operating System Build Number shown in Settings/System/Info is 18363.778
  3. Gustav Schubert

    Why this code fail?

    If global variable myQuery was a field of a class then it would be automatically initialized to nil. And if the procedure createMyQuery was a method of that class you would not need to pass the myQuery instance around as a parameter. Classes can be used with console application as well, just saying.
  4. Gustav Schubert

    Why this code fail?

    MyQuery should be initialized to nil. //procedure createMyQuery(query: TFDQuery; const Sql: String=''); procedure createMyQuery(var query: TFDQuery; const Sql: String=''); begin if query = nil then query := TFDQuery.Create(nil); query.Connection := myDatabase; query.SQL.Text := Sql; end; var myQuery: TFDQuery; begin myQuery := nil; createMyQuery(myQuery,'select * from table'); end;
  5. Gustav Schubert

    Which component to use as base class for SpeedPanel

    Setting StyleLookup to 'panelstyle' works, but the question remains - why is it not needed in a direct descendant?
  6. FMX feature: If you inherit from TPanel twice it becomes transparent, like TLayout. Context: I have a base class which inherits from TPanel. And then I actually use a class that inherits from that base class. I think I will use a TLayout, but do you have an explanation why my Panel is loosing style? unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts; type // TSpeedPanelClass = TToolbar; // TSpeedPanelClass = TLayout; TSpeedPanelClass = TPanel; TSpeedPanelBase = class(TSpeedPanelClass); TSpeedPanel = class(TSpeedPanelBase); TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private Counter: Integer; Y: Integer; procedure InitSpeedPanel(sp: TSpeedPanelClass); procedure SpeedButtonClick(Sender: TObject); end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); begin Button1.Position.X := 24.0; Button1.Position.Y := 8.0; Button2.Position.X := 112.0; Button2.Position.Y := 8.0; Fill.Color := TAlphaColors.Cornflowerblue; Fill.Kind := TBrushKind.Solid; Y := 50; end; procedure TForm1.Button1Click(Sender: TObject); var sp: TSpeedPanelClass; begin sp := TSpeedPanelBase.Create(Self); InitSpeedPanel(sp); end; procedure TForm1.Button2Click(Sender: TObject); var sp: TSpeedPanelClass; begin sp := TSpeedPanel.Create(Self); InitSpeedPanel(sp); end; procedure TForm1.InitSpeedPanel(sp: TSpeedPanelClass); var sb: TSpeedButton; begin Inc(Counter); sp.Parent := Self; sp.Position.X := 0; sp.Position.Y := Y; sp.Height := 40; sp.Width := 200; sb := TSpeedButton.Create(sp); sb.Parent := sp; sb.Text := 'SpeedButton' + IntToStr(Counter); sb.Tag := Counter; sb.OnClick := SpeedButtonClick; Y := Y + 50; end; procedure TForm1.SpeedButtonClick(Sender: TObject); begin Caption := Format('Btn %d clicked.', [(Sender as TComponent).Tag]); end; end.
  7. Gustav Schubert


    A Hello World program featuring TMemo, holding exactly one line of text, which is initially hidden - but which can be scrolled into view, interactively! I think this a now a finished piece. ( When you see the empty Memo, scroll the mouse wheel over the Memo, away from yourself, or click. ) unit Unit1; interface uses System.SysUtils, System.UITypes, FMX.Types, FMX.Controls, FMX.Forms, FMX.Memo; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private Memo: TMemo; Timer: TTimer; procedure TimerTimer(Sender: TObject); end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); begin Memo := TMemo.Create(Self); Memo.Parent := Self; Timer := TTimer.Create(Self); Timer.OnTimer := TimerTimer; end; procedure TForm1.TimerTimer(Sender: TObject); var i: Integer; begin Memo.Position.X := 10; Memo.Position.Y := 10; Memo.Width := 300; Memo.Height := 300; Memo.ControlType := TControlType.Styled; Memo.StyledSettings := []; Memo.TextSettings.Font.Family := 'Courier New'; Memo.TextSettings.Font.Size := 24; Memo.TextSettings.FontColor := TAlphaColors.Red; Memo.ShowScrollBars := False; for i := 0 to 15 do begin Memo.Lines.Add(''); end; Memo.Lines.Clear; Memo.Lines.Add('Hello World'); Caption := 'Memo.Lines.Count = ' + IntToStr(Memo.Lines.Count); Timer.Enabled := False; Memo.ScrollTo(0, 1000); end; end.
  8. Gustav Schubert


    I have a Memo on my Form the content of which is updated often, programatically. It contains no more than a few lines, ScrollBars should never appear, by design, so I set property ShowScrollBars to False, when reviewing the code. But I needed to reverse the setting (should be true), because - if not - the user can scroll the content out of view, off the top edge of the control! ( My app in a nutshell will allow the user to select the current parameter, and then change the value of that parameter with the mouse wheel, when shift or ctrl is down. A normal mouse wheel delta will continue to be available for normal scrolling, of content in a Memo or Listbox, as expected. ) ( I also searched in quality portal, and found that the most relevant entry already had a test case project attached, uploaded by - guess who. RSP-12137 - FMX Memo Scrolling Bug. ) I attach the new test app here (zipped form), for "future reference". MemoWheelTest.zip
  9. I am using latest CE. If I open a file without BOM in Delphi, which was saved from VS Code, it is interpreted wrongly as ANSI. Changes to project options would go into the the .dproj file which I do not want to rely on. And further, I do not want to rely on the configuration of the IDE, when I come to another machine and check out a project. It is good thing if code reading ini files can cope with a BOM. Whether you want your files to have a BOM may be determined by factors that have nothing to do with ini files.
  10. Such as the Delphi IDE when loading pascal files. Visual Studio Code, which I use to do git, will assume UTF8. Using a file between the two environments only works if BOM is present. And my Merge tool (Araxis) also needs to be configured to copy with BOM. So for me it is three programs which need to be fine tuned as a set. ( When I work with a jekyll project, then BOM is forbidden, and I have to switch the configuration of the Merge tool. )
  11. Gustav Schubert

    IDE Screenshot too large?

    OK, I did not try to google it, admitted, but there is at least one more thing I did not do: suggest that there might be a bug, or search for RSP.
  12. Gustav Schubert

    IDE Screenshot too large?

    I have the Delphi IDE (10.3.3) maximized on HD-Monitor and create a screenshot with Alt-Print. Screenshot dimensions: exp: 1920 x 1040 act: 1928 x 1048 How come? Long version: I have a two Monitor setup, 2 x 1920 * 1080. My Windows Taskbar is at the bottom of the screen, height 40, standard. When I make a screenshot with Print key, it is too large, two screens horizontally. So I tried Alt-Print instead, after maximizing the App (IDE). Pasted Screenshot into MS-Paint and noticed extra space, bottom and right edge. Other apps, including my own VCL app, 'screenshot' as expected.
  13. I want to determine at runtime whether the app was compiled in Normal configuration or Application-Store configuration. Depending on this piece of info I plan to set my internal boolean IsSandboxed property. True - show standard dialogs to choose file name. False - read and save directly from/to a known filename according to convention. {$if defined(IOS) or defined(Android)} // Mobile Apps are sandboxed, but my internal IsSandboxed flag needs to be false, ok. IsSandboxed := false; // do not show file name dialogs {$endif} {$ifdef MACOS} // OSX Apps are sandboxed, have permissions set IsSandboxed := true; // use dialogs {$endif} {$ifdef MSWINDOWS} // I myself (dev) don't want to be bothered with the dialogs. IsSandboxed := false; // Normal configuration {$endif} // pseudo code follows, does not work {$if defined(MSWINDOWS) and defined(Configuration == App_Store)} IsSandboxed := true; // for Windows Store, play it safe, earn full_trust. {$endif} ( So far I have been reluctant to rename my IsSandboxed property. ) But what is the best way to know if my App runs in Application-Store config vs. Normal config? This question applies to VCL apps as well as FMX apps.
  14. Gustav Schubert

    No KeyUp for numpad keys after relese Shift

    Using ScanCode perhaps, in VCL? unit Unit1; interface uses Winapi.Windows, Winapi.Messages, Vcl.Forms; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private ScanCode: Word; public procedure WMKeyDown(var Msg: TMessage); message WM_KEYDOWN; procedure WMKeyUp(var Msg: TMessage); message WM_KEYUp; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin ScanCode := Lo(MapVirtualKey(VK_INSERT, 0)); end; procedure TForm1.WMKeyDown(var Msg: TMessage); var w: Word; b: Byte; begin w := Msg.LParamHi; b := LoByte(w); if b = ScanCode then Caption := 'down'; inherited; end; procedure TForm1.WMKeyUp(var Msg: TMessage); var w: Word; b: Byte; begin w := Msg.LParamHi; b := LoByte(w); if b = ScanCode then Caption := 'up'; inherited; end; end.
  15. Gustav Schubert

    No KeyUp for numpad keys after relese Shift

    VK_INSERT tests a virtual key not a real key, this is how I understand it after testing. Windows is reporting the insert STATE - on or off - when you call GetKeyState, possible return values: 0, -1, -127, or -128. You cannot even tell which of the insert keys or key combinations were used to toggle the state. In VCL, FormKeyPress triggers for KeyDown only, and FormKeyUp does not respond to the numpad numbers at all? ( In FMX, you can use FormKeyUp to successfully detect the '0' up character and know that the key was lifted. )