Jump to content

Wil van Antwerpen

Members
  • Content Count

    69
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Wil van Antwerpen


  1. 6 hours ago, Dany Marmur said:

    There's one thing i miss from VirtualBox (and VMWare, IIRC) - the host button.

    I could hit Right-Ctrl and then Alt+Tab (or whatever) to tab amongst apps in the host (i.e. go-to-host-button).

    Don't know about Hyper-V, but on VMware Workstation, hold down Ctrl+Alt and then Alt-Tab should work.

    On Fusion that would be Ctrl+Command followed by Alt-Tab. Although on the latter -when in full screen- I prefer to use a 4 finger trackpad swipe left/right between desktops. Using that all the time to switch between VM's and host.


  2. Thanks, I've reverted my workaround and instead used the batch file solution from the first RSP.

     

    FWIW, it created the exact same files in the OSX64 redist folder except for the following files (they are still missing, not sure if that is correct, but somehow I believe the batch file better than my previous guess work)

    - bpldbtest.dylib

    - bplEMUVCLHelper270.dylib

    - bplrtl270.dylib.dSYM

     

    I guess I will find out over time.

     


  3. Hi,

    On 5/10/2021 at 6:32 PM, Darian Miller said:

     

    VMWare Workstation Pro took out the shared VM / auto-start feature in 16.0 but added it back for 16.1 after a ton of complaints.  The feature is marked as deprecated but they may be adding a new way to auto-start VMs in a future version.

    That is correct, see also: https://communities.vmware.com/t5/VMware-Workstation-Pro/Shared-VMs-are-back-in-Workstation-16-1/td-p/2811423

     

    Even if it doesn't come back, I have a product for that (Vimarun, you can find it via the link in my footer) written in Delphi of course 😉 .

    It does not only take care of auto start, but also auto suspends your VM(s) on shutdown.

     

    As for what product to use...

    Don't really ask me as I'm a long time VMware user that even has a few VMware related products and is an active user moderator at their forums.
    VMware Workstation / Fusion / Player and vSphere have always worked very well for me.

    However I strongly believe that you should use what works for you.

     

    Hyper-V, Virtualbox, KVM, Parallels etc.. are all very mature as well.

    • Like 2

  4. Hi,

     

    FYI, in case somebody else bumps into this as well.

     

    I think I have seen this before and reported it at the previous delphi forum, which now has disappeared.

    Just upgraded to 10.4.2 and when building my project I got this warning:

    [dccosx64 Hint] H2596 ld: warning: directory not found for option '-Lc:\program files (x86)\embarcadero\studio\21.0\redist\OSX64'

     

    and sure enough that folder does not exist, also for the record no OSX32 folder under the redist folder.

    I only installed windows and macOS, none of the mobile options, so that might be a reason that it is missing (it shouldn't but ok), also

    What I did now is to copy the contents of c:\program files (x86)\embarcadero\studio\21.0\binosx64 to the redist\OSX64 folder.

     

    Not sure if that's the right thing to do, but it will at the very least fix the warning.

    --
    Wil


  5. 15 minutes ago, Incus J said:

    I also get a warning that NSSTR is deprecated, but the suggested replacement StrToNSStr is not recognised.  Is there an easy way to query which system unit a function might be in?

    Hi,

     

    I have that same code and don't see a crash, not sure what else is different.

    re. the StrtoNSStr, you have to use the correct module for it to be recognized. If I'm not mistaken it is in:

     Macapi.Helpers,

     

    re. suggestion from f.m. thanks for the tip, I will check it out.

     


  6. A credential provider might work, but you would implement that in C/C++ and then debug it via a remote debugger.
    Doing that in delphi would be very very painful.

    I think that a GINA DLL no longer works since Vista?

    I haven't checked, but you probably also need to get a special agreement with Microsoft or I would expect at least a kernel mode signing certificate requirement for this type of thing.

    Fun, but not for the faint of heart.

    • Thanks 1

  7. I still think you're just going to waste a lot of energy on fighting the system here, but OK, your choice.


    You can enumerate the sessions for example: https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaenumeratelogonsessions

    You can determine the secure desktop using: https://stackoverflow.com/questions/4260878/openinputdesktop-to-determine-secure-login-desktop

    Then there's WTSQueryUserToken to get a user's token and https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser?redirectedfrom=MSDN

    to use that.


    Good luck!

    • Like 1

  8. 12 hours ago, ewong said:

    I took up @Dalija Prasnikar's idea of threads and while the UI isn't hanging,  there's a bunch of dependency control issues.  Like in the thread when I disable the controls,  I realized that I can't (by design) navigate a grid which depends on a dataset which had disablecontrol set.

    I'm now wondering if it makes sense two have two datasets.  One which is linked to a grid, the other not linked to any control so that the thread can use that non-linked dataset leaving the grid-linked dataset available for use.

     

    But as it stands, it's a definite improvement but like all things I don't understand (threads), I'll need to read up on it.

     

    Again, Thanks for the help!!  Very much appreciate it.

     

    Just buy Dalija's book "Delphi Event-based and Asynchronous Programming"

    It is very good in explaining all the pitfalls and a real bargain for all the knowledge that it carries.

    • Thanks 1

  9. Sure..

     

    unit ShellCommands;
    
    interface
    
    uses
    {$IFDEF MSWINDOWS}
      FMX.DialogService.Sync,  // for confirmation / showmessage dialogs
      System.UITypes,          // same ^^
      FMX.Types,               // same ^^
      Windows,
      ShlObj,
      WinShortCut,
      Winapi.ShellAPI,
    {$ENDIF MSWINDOWS}
    {$IFDEF POSIX}
      Posix.Stdlib, Macapi.ObjectiveC, Macapi.CocoaTypes, Macapi.Foundation, Macapi.AppKit, Macapi.Helpers,
      Posix.SysSysctl,
    {$ENDIF POSIX}
      System.SysUtils, System.StrUtils, System.Types, System.Classes;
    
    type
      TScriptArguments = array of string;
      TShell = class
        class function RunScript(sCommand: string; sArguments: TScriptArguments; out stdOut : string): integer;
      end;
    
    
    implementation
    
    
    class function TShell.RunScript(sCommand: string; sArguments: TScriptArguments; out stdOut : string): integer;
    {$IFDEF POSIX}
    var
      LTask: NSTask;
      LArgs: NSArray;
      LArray: array of Pointer;
      LPipe: NSPipe;
      fileHandler : NSFileHandle;
      data : NSData;
      i       : Integer;
      iCount  : Integer;
      nsText : NSString;
    begin
      sCommand := trim(sCommand);
      If sCommand <> '' then
      begin
        LArgs := TNSArray.Create;
        iCount := Length(sArguments);
        if iCount > 0 then
        begin
          //Create and init the arguments the correct way...
          setlength(LArray, iCount);
          for i := 0 to iCount-1 do
          Begin
            LArray[i] := RawStr(sArguments[i]);
          End;
        end;
        LArgs:=TNSArray.Wrap(TNSArray.Alloc.initWithObjects(@(LArray[0]), iCount));
    
        //Create the task the correct way.
        LTask:=TNSTask.Wrap(TNSTask.Alloc.init);
    
        LPipe := TNSPipe.Create;
        fileHandler := TNSFileHandle.Create;
    
        LTask.setLaunchPath(StrToNSStr(sCommand));
        LTask.setArguments(LArgs);
    
        LTask.setStandardOutput((LPipe as ILocalObject).GetObjectID);
        fileHandler := LPipe.fileHandleForReading;
    
        LTask.launch;
        LTask.waitUntilExit;
        data := TNSData.Create;
        data := fileHandler.readDataToEndOfFile;
        nsText := TNSString.Wrap(TNSString.Alloc.initWithData(data, NSUTF8StringEncoding));
        stdOut := NSStrToStr(nsText);
      end; // sCommand <> ''
      Result := 0;
    end; // RunScript
    {$ENDIF POSIX}
    {$IFDEF MSWINDOWS}
    var
      commandLine: string;
      i       : Integer;
      iCount  : Integer;
      Success : Boolean;
      ExitCode : Longword;
      StdOutPipeRead, StdOutPipeWrite: THandle;
      WasOK: Boolean;
      Buffer: array[0..255] of AnsiChar;
      BytesRead: Cardinal;
      SA: TSecurityAttributes;
      si: TStartupInfo;
      ProcInfo: TProcessInformation;
    begin
      stdOut := '';
      ExitCode := 0;
      with SA do begin
        nLength := SizeOf(SA);
        bInheritHandle := True;
        lpSecurityDescriptor := nil;
      end;
      CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
      try
        si := Default(TStartupInfo);
        si.cb := SizeOf(si);
        si.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
        si.wShowWindow := SW_HIDE;
        si.hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
        si.hStdOutput := StdOutPipeWrite;
        si.hStdError := StdOutPipeWrite;
    
        commandLine := sCommand;
        commandLine := '"'+commandLine+'"';
        iCount := Length(sArguments);
        if iCount > 0 then
        begin
          for i := 0 to iCount-1 do
          Begin
            commandLine := commandLine + ' ' + QuoteScriptParam(sArguments[i]);
          End;
        end;
        
        uniquestring(commandline);
    
        Success := CreateProcess(
            nil,                //no module name (use command line)
            PChar(commandLine), //Command Line
            nil,                //Process handle not inheritable
            nil,                //Thread handle not inheritable
            True,               //Do inherit handles
            0,                  //No creation flags
            nil,                //Use parent's environment block
            nil,                //Use parent's starting directory
            si,                 //Startup Info
            ProcInfo            //Process Info
        );
        CloseHandle(StdOutPipeWrite);
        if Success then
        begin
          try
            repeat
              WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
              if BytesRead > 0 then
              begin
                Buffer[BytesRead] := #0;
                stdOut := stdOut + string(Buffer);
              end;
            until not WasOK or (BytesRead = 0);
            WaitForSingleObject(ProcInfo.hProcess, INFINITE);
            GetExitCodeProcess(ProcInfo.hProcess,ExitCode);
          finally
            CloseHandle(ProcInfo.hThread);
            CloseHandle(ProcInfo.hProcess);
          end;
        end;
      finally
        CloseHandle(StdOutPipeRead);
      end;
      if stdOut <> '' then
      begin
        stdOut := stringReplace(stdOut,#$0D,'',[rfReplaceAll]); // strip all CR from the CRLF so that it is the same as for our code from macOS
      end;
      result := ExitCode;
    end;
    {$ENDIF MSWINDOWS}
    
    end.
    
    
    
    // Then from another part in my code I call it like this:
    
    function IsDarkModeEnabled: Boolean;
    {$IFDEF POSIX}
    var
      bDarkMode   : boolean;
      sCmd        : string;
      stdOut      : string;
      iErr        : integer;
      Params      : TScriptArguments;
    begin
      bDarkMode := false;
      sCmd := '/usr/bin/defaults';
      If sCmd<>'' then
      begin
        If FileExists(sCmd)=true then
        begin
          stdOut := '';
      
          SetLength(Params,3);  // defaults read -g AppleInterfaceStyle -> returns "Dark" if dark mode is enabled
          
          Params[0] := 'read';
          Params[1] := '-g';
          Params[2] := 'AppleInterfaceStyle';
        
          iErr := TShell.RunScript(sCmd,Params,stdOut);
          //if iErr > 0 then
          //  ErrorHandling;
          //WriteLog('Dark Mode '+trim(stdOut));
      
          stdOut := trim(stdOut);
          if (lowercase(stdOut)='dark') then
            bDarkMode := true;
        end
        else Begin
          TDialogServiceSync.MessageDialog('File ' + sCmd + ' does not exist.',mtConfirmation, [mbOK], mbOK, 0);
          sCmd := '';
        End;
      End;
      Result := bDarkMode;
    end;
    {$ENDIF POSIX}
    {$IFDEF MSWINDOWS}
    //Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
    // if DWORD AppsUseLightTheme does not exist -> light theme
    // if DWORD AppsUseLightTheme exists and is 0 -> dark theme
    // if DWORD AppsUseLightTheme exists and is 1 -> light theme
    var
      bDarkMode     : boolean;
      sName         : string;
      UseLightTheme : integer;
      Reg: TRegistry;
    begin
      bDarkMode := false;
      UseLightTheme := 1; // default is to use the light theme.
      Reg := TRegistry.Create(KEY_READ);
      try
        Reg.RootKey := HKEY_CURRENT_USER;
        if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Themes\Personalize', false) then
        begin
          sName := 'AppsUseLightTheme';
          If Reg.ValueExists(sName)=true then
            UseLightTheme := Reg.ReadInteger(sName);
          Reg.CloseKey;
        end;
      finally
        Reg.Free;
      end;
      if UseLightTheme = 0 then
        bDarkMode := true;
      Result := bDarkMode;
    end;
    {$ENDIF MSWINDOWS}

    Hopefully I got all the dependencies and commented out the stuff that is specific for my apps.

    I left the Windows dark/light theme logic in as well, just in case somebody wants that too.


  10. You can run this:

    defaults read -g AppleInterfaceStyle

    and if it returns "Dark" then you're in dark mode and can switch to a dark theme.

     

    It's what I"m using in Vimalin, not sure if there's anything better for macOS so far.

    --
    Wil


  11. If you're considering using Electron et al. then perhaps also have a look at freepascal/lazarus?
    Last time I looked it was pretty nice, also on macOS.
    But too big of a rewrite for me as I am pretty heavily invested in FMX.
    If your app is currently mostly using VCL then it is much easier to rewrite and use their LCL approach.


  12. Hi,

     

    Thanks for all the tips. I will check out the 3rd party products, but am a bit wary of adding 3rd party controls that are working at this low level to already released software. Especially if the component comes without source so I that it becomes more difficult for me to estimate the impact on stability, or if I need to look for another solution once the next version of macOS is released.

    If I start working on a new product it makes more sense to me as I will then have more time to test.

     

    Looks like the grjji github code might get me the basics I need for now.

     

    9 hours ago, Anders Melander said:

     

    "Time limited license"... Thanks, but let's not.

    The website is very unclear and that does not give me a good feeling about the product itself.

    Version history 0.99beta...
    There's more text in the screenshots then there is text detailing the functionality about the product, several typo's in there as well.

    Time limited how?
    After a year the code stops working?
    After a year I need to buy a new license if I want to include it into a new application?

    Something else?

    Does it come with source?
    Does it work with FMX? (I only see VCL even on the macOS/Linux screenshots)

    Does it work with Delphi 10.3/10.4?

     

    I believe that the people behind it are very very smart, but I need more details to even consider it as a solution.


    Like you say.. no thanks.

    • Like 1

  13. FWIW, the customer that triggered this issue has helped me to nail it down.

    I'm very grateful for him to do that kind of detective work.
     

    The offending code was:

    sValue := ListBox.Selected.TagString;

    There was no selection made in the ListBox and as such Selected was nil.

    Previously there would always have been a selected value in the ListBox, but due to a change elsewhere that precondition was no longer true.

     

    From the customers initial report I was under the assumption that the error was in a different form ....
    So any details I would be able to log would help (form name, method, etc...), if only the moment an AV happens can be logged then even that might be helpful as I can then implement a debuglevel to the log to catch more details.
    Just looking for ideas. :)


  14. Hi,

     

    Sometimes users report a problem with my FMX applications.
    Usually I am able to help them by asking them to email me the logs that the application creates specifically for troubleshooting purposes.


    However if the user reports an access violation it gets pretty hard to find what actually happened as my logs do not have any details on that.
    They don't even log the AV at all.

    Is there a possibility to log that kind of problem with a bit of detail?

     

    edit: FYI, both Windows as well as macOS, delphi 10.3 and 10.4

     

    Thanks


  15. On 11/20/2020 at 2:59 PM, Rollo62 said:

    Does that mean also VmWare Fusion, Win-10 guest and Rx1041 is running as before ?

    VMware is working on a VMware Fusion version for the M1 processor.
    This is not currently available, so no it does not currently work, estimated arrival somewhere 2021.


    That first M1 version will -for sure- not offer x86/x64 processor emulation. That is a whole different ballgame and rosetta is not available for virtual machines.
    As such you will only be able to run virtual machines that depend on an Arm processor to run.

    Having said that, VMware did get an overwhelming demand to also look into processor emulation and they are actively looking into this.
    That's about the only thing that the responsible VMware product manager is willing to say about this at the moment.


  16. There are many ways, lots of different nuances on exactly how you want to execute something on the different platforms.

     

    Having said that. the following is probably close to what you are asking for:

    
    class procedure TShell.Open(sCommand: string);
    begin
    {$IFDEF MSWINDOWS}
      ShellExecute(0, 'OPEN', PChar(sCommand), '', '', SW_SHOWNORMAL);
    {$ENDIF MSWINDOWS}
    {$IFDEF POSIX}
      _system(PAnsiChar('open ' + AnsiString(sCommand)));
    {$ENDIF POSIX}
    end;

     


  17. 2 hours ago, Serge_G said:

    Hi,

     

    It seems too late but you can look at my (sorry french) paper about customizing Grid https://serge-girard.developpez.com/tutoriels/Delphi/Livebindings/Grilles/

    Ok it's not about headers it's one of the Todo in my notebook I had no time to investigate (I go on listviews instead of grids) but still in my mind I think about a new column style

    At first it looked like your article was only about VCL, but you do talk about FMX near the end.

    Indeed no sort indicator, a "current row indicator" instead. Still interesting, so thanks for the article.

     

    re. French, it's OK, learned some of it over the years, just don't ask me to speak or write in it.

    Just means I have to work a bit harder and finally get to put those language skills into practice. :D

     

     

    Thanks!


  18. 3 hours ago, Rollo62 said:

    @Wil van Antwerpen

    Ok, if thats regarded off-topic I won't get deeper here too.

    Only so far that two MacBooks 2013, 2018 behaved exaclty the same, maybe I find some time to check current Vm11.5.6, if this is improved.
    At least I know who I could ask if I see such strange behaviour again 👍

    :) Off topic for the original thread as you are reporting a different problem on another product.

    But, yes I think these type of questions do have a better chance of getting resolved at VMware's forum.

    There's not just me, but many more VMware experts who are roaming those forums including a bunch of their developers who actually work on the internals of VMware Fusion and Workstation.

     

    Host crashes tend to get extra attention as that's of course not something you ever would want to see.


  19. 1 hour ago, Rollo62 said:

    Would be good to get your opinion here, since I've disabled 3D for a good reason.

    In one of the former versions of VmWare Fusion (1-2 versions earlier), it crashes the whole VmWare HOST reproducable,

    only by openening any 3D app, even MsPaint 3D.

    (VmWare Fusion, MacBook Pro, VmWare, Host Catalina,  Guest Win10 190x, ...)

     

    Have you recognized same behaviour ?

    I have not tested with latest version, as I don't need 3D at the moment.

     

    This gets a bit off topic and while I have no problem answering here.

    It is really probably better answered at the VMware communities Fusion forum  (I read every post at the Fusion and Workstation subforums, but you can always ping me there too )  Not that I am the expert on the graphics stack, but I might be able to help, if only to get the right information for others to help you.

     

    There's a lot of factors that can influence this, like your VM's configuration, what hardware you are running (not all MBP's are the same) and what version of VMware Fusion you are running. If you have an MBP then you probably have 2 graphics adapters (discrete and integrated) and you can tell VMware which one to use as a probably mitigation.

     

    I don't have your problem, nor have I seen it myself. MSPaint 3D works fine here, not that I ever use it.

    Earlier versions of VMware Fusion would use an openGL renderer at the host, while nowadays a Metal renderer is used.

    Older graphics cards work better with the openGL backend and newer ones with the Metal one.

    You can switch the background renderer if your MBP is older (like a MBP from 2014 or earlier) and it helps.

     

    Then there's the whole matter of which 3D technology you're using.

    As you are in a Windows VM, DirectX is currently limited to DX10 and openGL to version 3.3. (VMware Fusion 12/ WS 16, to be released in a few weeks go to DX11 and OpenGL 4.1)

    The DX compatibility level also depends on the virtual hardware version you choose.

    While things might be choppy on a slower configuration, none of it should ever crash the host.

     

    As you can see I need more info to investigate your issue...

    • Like 1
×