Jump to content

Ian Branch

Members
  • Content Count

    1274
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Ian Branch


  1. Hi Team,

    Despite my pitiful efforts I have managed to get App Tethering working between two Apps.

    But, I have a problem.  IIUC, the Sender has to be running before the Receiver.  Something about establishing a socket

    This I can't guarantee.  😞

    Is there any way to configure App Tethering so it dosn't matter if the Sender or Receiver starts first??

     

    Regards & TIA,

    Ian


  2. 10 hours ago, Dalija Prasnikar said:

    before you change global FormatSettings to avoid user changes to be applied if the application is already running.

    Ahhh.  Tks for the tip.

    10 hours ago, Dalija Prasnikar said:

    Any code that uses own settings will behave in similar way.

    That was always a/the risk.

    10 hours ago, Dalija Prasnikar said:

    users are allowed to have their preferer format used for viewing purposes,

    Won't happen.

     

    Tks to all for your inputs and guidance.

     

    Regards,

    Ian


  3. Hi Dalija,

    Thank you for your input.  Appreciated.

    Have you ever worked with Pacific Islanders?

    I have been dealing with them for the past 7 years and they can be extremely frustrating.

    They will do things with their PC just because.  Including changing their date & time formats. and in a couple of cases their Region.

    My Customer wants all the Apps to operate to a standard format, interestingly, to en-AU, despite what the User may have done with his/her PC.

    I thought this would be a good way to enforce it.

     

    Regards,

    Ian


  4. Hi Guys,

    D11.3.1.

    This is what I understand att.  Feel free to correct me if my understanding is incorrect.
    1.  If I set FormatSettings with a Country code, i.e. "var FormatSettings := TFormatSettings.Create('en-AU');", then that action will configure the various TFormatSettings properties in SysUtils to the Australian formats.
    2.  I can then forget about the variable FormatSettings.
    3.  Having set these properties in SysUtils, whatever Unit has SysUtils will have/use the set properties.
    4.  Any function/procedure that uses a FormatSettings property will now use the relevant set TFormatSettings property according to the Country/Region code employed in the '.Create()'.

    Are my understandings correct?

    Regards & TIA,
    Ian


  5. Hi Team,

    Win 11, D11.3.1.

    I am playing around with TFormatsettings and I am using this Emba code..

    procedure Test;
    var
       str1, str2: string;
       FS: TFormatSettings;
       strResult, strFormat: TStringBuilder;
    begin
       strResult := TStringBuilder.Create;
       strFormat := TStringBuilder.Create;
    
       FS := TFormatSettings.Create('en-AU');
       strFormat.AppendFormat('%s %s', [FS.LongDateFormat, FS.LongTimeFormat]);
       str1 := FormatDateTime(strFormat.ToString, Now());
       strResult.AppendLine('1.'+str1);
       ShowMessage(FS.NormalizedLocaleName);
       strResult.AppendLine(FS.NormalizedLocaleName);
    
       //A second instance with a different locale (used for comparison)
       FS := TFormatSettings.Create('ro-RO');
       strFormat.Clear;
       strFormat.AppendFormat('%s %s', [FS.LongDateFormat, FS.LongTimeFormat]);
       str2 := FormatDateTime(strFormat.ToString, Now());
       strResult.AppendLine('2.'+str2);
       strResult.AppendLine(FS.NormalizedLocaleName);
    
       ShowMessage(strResult.ToString);
       //
    end;

    What should FS.NormalizedLocaleName return?  Emba Help says a string but I am getting nothing back.  Or maybe I am and it is blank.  Not expected.

     

    Regards & TIA,

    Ian


  6. Hi Team,

    D11.3.

    I have an App that populates the captions of two labels.  It all works fine.

    What I would like to do is make this captions availabe to other Apps rather than regerating them in the other Apps.

    All the Apps are on a Windows 2012 Server.   Multi-User.  Some of the Apps may be running via RDP, the same and other Apps may be running via LAN, i.e. called from the Server and running physically on the User's PC.  Users are using Win 7 & Win 10 workstations.

    The generating App may be being used at any time by many Users.

    The term Message Broker came to my mind and IIRC there was something by one of the inhabitants of this Forum that might be my solution.

    Can somebody refresh my memory and point me in the correct direction please?

    Or, alternatives.  The simpler the better.  🙂

     

    Regards & TIA,

    Ian

    • Like 1

  7. Solved.  I added the count to the function.

    function GetApplicationInstances(const FileName: string; out Count: Integer): TArray<string>;
    var
      ProcessEntry: TProcessEntry32;
      Snapshot: THandle;
      ProcessList: TList<string>;
    begin
      ProcessList := TList<string>.Create;
      try
        Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if Snapshot <> INVALID_HANDLE_VALUE then
        begin
          ProcessEntry.dwSize := SizeOf(ProcessEntry);
          if Process32First(Snapshot, ProcessEntry) then
          begin
            repeat
              if (ProcessEntry.szExeFile = FileName) then // Replace with appropriate condition
              begin
                ProcessList.Add(ProcessEntry.szExeFile);
              end;
            until not Process32Next(Snapshot, ProcessEntry);
          end;
          CloseHandle(Snapshot);
        end;
    
        Result := ProcessList.ToArray;
        Count := ProcessList.Count;
      finally
        ProcessList.Free;
      end;
    end;

    Tks Guys.

     

    Regards,

    Ian


  8. OK.  Moving on.  Using Enums rather than TProcess.

    function GetApplicationInstances(const FileName: string): TArray<string>;
    var
      ProcessEntry      : TProcessEntry32;
      Snapshot          : THandle;
      ProcessList       : TList<string>;
    begin
      ProcessList := TList<string>.Create();
      try
        Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if Snapshot <> INVALID_HANDLE_VALUE then
        begin
          ProcessEntry.dwSize := SizeOf(ProcessEntry);
          if Process32First(Snapshot, ProcessEntry) then
          begin
            repeat
              if (ProcessEntry.szExeFile = FileName) then // Replace with appropriate condition
              begin
                ProcessList.Add(ProcessEntry.szExeFile);
              end;
            until not Process32Next(Snapshot, ProcessEntry);
          end;
          CloseHandle(Snapshot);
        end;
    
        Result := ProcessList.ToArray;
      finally
        ProcessList.Free;
      end;
    end;

    I have the following lines.

    var Instances: TArray<string>;
    Instances := GetApplicationInstances(sFileName);

    I can't see a way to get the number of elements in the TArray.

    I thought "for var i := 0 to TArray(Instances).Count do Memo1.Lines.Add(Instances);" would be a monty, but no.

    How please?

     


  9. Hi Team,

    I found that bit of code and thought it would do the trick.  Oh well.

    What I am try to achieve is a delphi function that when given a full application path/name, return how many instances are in use and who is using them.

     


  10. Hi Team,

    D11.3.1.

    I have the following function I am trying to get to work..

    function GetApplicationInstances(const FileName: string): TArray<string>;
    var
      ProcessList: TProcessList;
      Process: TProcess;
      i: Integer;
    begin
      Result := TArray<string>.Create;
      ProcessList := TProcessList.Create;
      try
        for i := 0 to ProcessList.Count - 1 do begin
          Process := ProcessList[i];
          if Process.FileName = FileName then begin
            Result.Add(Process.UserName);
          end;
        end;
      finally
        ProcessList.Free;
      end;
    end;

    I have bothe System.SysUtils and System.Diagnostics in my Uses clause but I am still gettin an 'undeclared identifier' for TProcessList and TProcess.

    What have I missed please?

     

    Regards & TIA,

    Ian


  11. Hi Lajos,

    Great call.  I found that if I had the System.Zlib after the VCL.Graphics, all is fine.  Before and I get the issue.

    Tks for the assist.

     

    Regards,

    Ian

     

    Edit:  I didn't need VCL.Graphics in the library anyway. 😉


  12. Hi Team,

    D11.3.1.

    I have this compression routine.

    procedure CompressStream(SourceStream: TMemoryStream; DestStream: TMemoryStream);
    var
      ZStream           : TCompressionStream;
    begin
      ZStream := TCompressionStream.Create(clDefault, DestStream);
      try
        ZStream.CopyFrom(SourceStream, SourceStream.Size);
      finally
        ZStream.Free;
      end;
    end;

    If I have this procedure in my main form it is happy.

    If I move it to my Function library, I get this..

    image.thumb.png.3fc1547c071d42ad820ad427757014dd.png

     

    Why should it be happy in the main form an not in the library?

    Yes, I have System.ZLib in the uses in both cases

    Thoughts/suggestions?

     

    Regards & TIA,

    Ian

     


  13. Hi Remy,

    Yes, seriously. 

    I don't really understand what goes on in Threads and therefore what you can and can't do.

    I am still learning about them.

     

    p2k,

    Tks.  I will have a look.

     

    Tks to both of you.

     

    Regards,

    Ian


  14. Hi Team,

    I have ths construct:

        var GeneralThread := TThread.CreateAnonymousThread(procedure
          begin
            //
            tqServerSessions.Close;
            //
            try
              if TEDBEngineSessionManager(DBSWhoIsOn.Handle).TryLock(1) then
              begin
                TEDBEngineSessionManager(DBSWhoIsOn.Handle).Unlock;
                { Session is not locked and is safe for you to use }
                tqServerSessions.ExecSQL;
              end
              else
                // Delay for the specified amount of time
                TThread.Sleep(500);
              //
            except
              ...
              ...
            end;
            //
            tqServerSessions.Last;
            //
            ...
            ...
          end);

    How do I safely loop the Try-Else  for x times, and then break out after x times?


  15. Hi Renate,

    That looks like a winner but this..

    SetDBSessionNames(Self, sSessionName);

    Gives me this in this case..

    Quote

    [dcc32 Error] dmCurrent.pas(821): E2010 Incompatible types: 'TForm' and 'TdmC'

    In this case it is a Datamodule the function is being called from.

     

    Ian

     

    Edit:  Solved - I made it an overload method and created one that use a TDataModule.

×