Jump to content

Gustav Schubert

Members
  • Content Count

    116
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Gustav Schubert


  1. 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;

     


  2. 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.

     


  3. 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.

     


  4. 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


  5. 20 minutes ago, Fr0sT.Brutal said:

    newer versions seem to not need it anymore

    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.

    • Like 2

  6. On 3/23/2020 at 10:54 AM, A.M. Hoornweg said:

    But a program (such as an editor) needs to know if the file is UTF8

    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. )


  7. 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.
     

    RG19-03.thumb.png.6e11ff2aa443d6c182c13cfd7b45aee8.png


  8. 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.


  9. 22 hours ago, Stefan Glienke said:

    You have to use other ways to do that,

    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.

     


  10. 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. )


  11. I don't know if it works, I am just learning - how to code against the api, I only compile and read some interesting code. It is for the original poster to test it out, waiting ...

    • Like 1

  12. So, it is best to use KeyDown and KeyUp in FMX to determine if any of the two insert keys is currently down?

     

    implementation
    
    {$R *.fmx}
    
    uses
      Windows;
    
    var
      IsInsertPressed: Boolean;
    
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
      Shift: TShiftState);
    begin
      case key of
        45:
        begin
          IsInsertPressed := True;
          UpdateCaption;
        end;
      end;
    end;
    
    procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
      Shift: TShiftState);
    begin
      case key of
        45:
        begin
          IsInsertPressed := False;
          UpdateCaption;
        end;
      end;
      case KeyChar of
        '0':
        begin
          IsInsertPressed := False;
        end;
      end;
      UpdateCaption;
    end;
    
    procedure TForm1.UpdateCaption;
    begin
      if IsInsertPressed then
        Caption := 'INSERT'
      else
        Caption := '0';
    end;
    
    end.

     


  13. Yes, this compiles - with small changes - and looks much better.

     

      AVCaptureStillImageOutput = interface(iOSapi.AVFoundation.AVCaptureStillImageOutput)
        ['{A1669519-9901-489E-BDD1-A0E697C8C6CB}']
        procedure addObserver(observer: Pointer; forKeyPath: NSString; options: NSKeyValueObservingOptions; context: Pointer); cdecl;
        procedure captureStillImageAsynchronouslyFromConnection(connection: AVCaptureConnection; completionHandler: TAVCaptureCompletionHandler); cdecl;
      end;
      TAVCaptureStillImageOutput = class(TOCGenericImport<AVCaptureStillImageOutputClass, AVCaptureStillImageOutput>)
      end;
    
    //    objc_msgSendP4((FStillImageOutput as ILocalObject).GetObjectID,
    //                 sel_getUid('addObserver:forKeyPath:options:context:'),
    //                 FVideoCaptureDelegate.GetObjectID,
    //                 (StrToNSStr('capturingStillImage') as ILocalObject).GetObjectID,
    //                 NSKeyValueObservingOptionNew,
    //                 (FAVCaptureStillImageIsCapturingStillImageContext as ILocalObject).GetObjectID);
    
        TAVCaptureStillImageOutput.Wrap(FStillImageOutput).addObserver(
            FVideoCaptureDelegate.GetObjectID,
            StrToNSStr('capturingStillImage'),
            NSKeyValueObservingOptionNew,
            NSObjectToID(FAVCaptureStillImageIsCapturingStillImageContext));
    
    {
    [stillImageOutput
       addObserver:self
       forKeyPath:@"capturingStillImage"
       options:NSKeyValueObservingOptionNew
       context:AVCaptureStillImageIsCapturingStillImageContext];
    }

    Source Link.

    • Like 1

  14. const
      libImageIO = '/System/Library/Frameworks/ImageIO.framework/ImageIO';
    
    function objc_msgSendP4(
      theReceiver: Pointer;
      theSelector: Pointer;
      P1: Pointer;
      P2: Pointer;
      P3: LongWord; // ?
      P4: Pointer): Pointer; cdecl; overload; external libobjc name _PU + 'objc_msgSend';

    You could find out if it is a long word or an Integer and if it works ...


  15. I am looking at Macapi.ObjCRuntime.
    There is a function objc_msgSendP2.
    What if you declare objc_msgSendP4?

     

    There are 5 calls to objc-msgSend in the uFMain unit.
    Three take two params, these do compile?
    One takes 4 Params, should be objc_msgSendP2?
    One takes 6 params, which should be objc_msgSendP4?
     


  16. I include a minimal test project for FMX, OSX64 target only, see attachment.

     

    ( You can change TRectangle.Fill.Color and TText.Font.Family via native dialogs, see screenshot. )

    ChangeColorTest.thumb.jpg.d15f98ccddcc47c3fcac216de60d48d4.jpg

    This seems to work somehow, but there are at least two remaining problems:
    1) Color: If you change from Apple to Developer in combo box and continue to use the dialog - it will crash the App.
    2) Font: selectedFont is the value navigated from, not the value navigated to; in the example the font family of the TText should be Arial Narrow, not Arial Black.

     

    I would like to understand the reason for problem 1, any idea?

    ChangeColorTest.zip


  17. On the OSX64 platform I want to use native Pickers for Color (TNsColorPanel) and Font (TNsFontPanel).

     

    The idea is that first the dialog must be shown (initialized) so that the user can select a color or font in the dialog.

    Then, at any time, if an action is triggered in the App, the currently selected Color or Font should be retrieved and used.

     

    It works for Color, but not for Font. I don't implement changeFont since I don't know how. But it looks as if a working handler is needed, or it won't work.

    Won't work means that the current Font cannot be retrieved via the convertFont method of the FontManager.

     

    https://github.com/federgraph/federgraph-meme-builder/blob/6e035f461e47ed0b30c46ceb36960cbfd528c6c2/MB/RiggVar.MB.Picker.Mac.pas#L104

     

    - debug on Mac (F9)


    - press button sC (show Color Panel)
    - change color in panel

    - select App window (focus)
    - press button pC (pick Color), ok


    - press button sF (show Font Panel)
    - chang Font in panel
    - ( set breakpoint in TPickerMac.SelectFontFamilyName )

    - select App window (focus)
    - press button pF (pick Font)

    - todo: make it work

     

    Should I give up at this point, and if so, why?


  18. On the desktop I call Screen.UpdateDisplayInformation just before I need it, it works for me.


    But the next problem I found with Screen.WorkAreaHeight is that the units (real pixel or scaled pixel) are different between the platforms.


    Surface Pro = real pixels given (Scale = 2.0)
    My Desktop = cannot tell (because Scale = 1.0)
    Retina iMac = scaled pixels returned (Scale = 2.0)

     

    So, on Windows Screen.WorkAreaHeight and ClientHeight are NOT using the same units, on Mac they are given in same units, but what should it be by design?

     

    ( I have a workaround that in my test App. )


  19. On 11/21/2019 at 6:32 PM, Gustav Schubert said:

    Now I have 10.3.3 CE with two days left.

    Fixed, 367 more days for my CE installation.

     

    I have requested a new license via free-download page, using same email login as always, and got email with new license key. Then I used the license dialog of Tokyo Pro to register new license and delete expired license.

     

    Quote from comment on FB page: "Please make sure your license is expired, otherwise you will get the same expiration date as before." This may very well be true.

    • Like 3

  20. Downloaded web installer. Got new license key for CE in email. Now I have 10.3.3 CE with two days left.

     

    The license manager UI still buggy btw - when you navigate the leftmost listbox with the arrow keys up and down. You need to click with the mouse on the items, to see the corresponding license details in the middle, which is relevant for the actions on the right. But there is no action reading 'extend license for one more year' or similar.

     

    RSP-16220 ('code navigation is blocked inside MACOS blocks') still reproducible, contrary to what they say. 💎


  21. TScreen.WorkAreaHeight is available in Vcl and in FMX. The Vcl help has slightly more info, but it does not mention whether the value is ever updated or not.

     

    Found out that, if you change the rotation of the form on the Surface tablet, it does not update. If you change the taskbar mode (Taskleiste automatisch ausblenden, available in taskbar context menu on Surface Pro), it does NOT update either. Any change is only reflected after restart of app. And since the implementation hides behind TPlatformServices.Current.Something it is not easy to find out. Back to square 2.

     

    Edit 1: It seems I have to call Screen.UpdateDisplayInformation manually, but when?

×