Jump to content

Remy Lebeau

Members
  • Content Count

    2343
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by Remy Lebeau

  1. Remy Lebeau

    how to change the color of the top row of stringgrid.

    See the TStringGrid.FixedColor property. See the TStringGrid.Color property. See the TStringGrid.DefaultColWidth, TStringGrid.ColWidths, and TStringGrid.GridLineWidth properties.
  2. Remy Lebeau

    Using Continue in repeat statement

    As others have stated, it is working as designed. You need to change your 'until True' condition to 'until False' instead so the loop can run more than once. Personally, I would just re-write the condition to not use 'Continue' at all: program RepContinue; {$APPTYPE CONSOLE} {$R *.res} var i: Integer; begin i := 5; repeat Writeln(i); Dec(i); until i <= 0; Readln; end.
  3. Remy Lebeau

    Restart the same App?

    You definitely don't want to use those kind of functions in this situation. You don't need that. A process knows its own ID, you can query it directly. You need something like this: uses ..., Windows; function RestartApp: Boolean; var si: STARTUPINFO; pi: PROCESS_INFORMATION; CmdLine: string; begin CmdLine := Format('"%s" /pid:%d', [ParamStr(0), GetCurrentProcessID()]); ZeroMemory(@si, sizeof(si)); GetStartupInfo(@si); Result := CreateProcess(nil, PChar(CmdLine), nil, nil, False, 0, nil, nil, si, pi); if Result then begin CloseHandle(pi.hThread); CloseHandle(pi.hProcess); Application.Terminate; end; end; Then in your app's startup code, such as in your main DPR file, you can do this before initializing your UI or anything else: uses ..., Windows; var pid: string; h: THandle; begin if FindCmdLineSwitch('pid', pid) then begin h := OpenProcess(SYNCHRONIZE, FALSE, StrToInt(pid)); if h <> 0 then begin WaitForSingleObject(h, INFINITE); CloseHandle(h); end; end; ... continue starting up normally ... end;
  4. Remy Lebeau

    Indy - rev.5507 compile problem

    The fix is checked in now.
  5. Remy Lebeau

    NTP which component to use?

    More accurately, it just says that the NIST ITS's usage of the TIME protocol is obsolete and NTP is preferred, not that the TIME protocol itself is obsolete. This page explains it a bit better: https://www.nist.gov/pml/time-and-frequency-division/services/internet-time-service-its Yes.
  6. Remy Lebeau

    Indy - rev.5507 compile problem

    My bad, there are a few erroneous {$ENDIF} statements that don't belong. Try the following instead, it should work. If so, I will check in the fix: type {$IFDEF HAS_ComponentPlatformsAttribute} [ComponentPlatformsAttribute( {$IFDEF HAS_ComponentPlatformsAttribute_AllPlatforms}pidAllPlatforms {$ELSE} pidWin32 {$IFDEF HAS_ComponentPlatformsAttribute_Win64} or pidWin64{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_OSX32} or pidOSX32{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32}or pidiOSSimulator32{$ELSE} {$IFDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} or pidiOSSimulator{$ENDIF}{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_Android32Arm} or pidAndroid32Arm{$ELSE} {$IFDEF HAS_ComponentPlatformsAttribute_Android} or pidAndroid{$ENDIF}{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_Linux32} or pidLinux32{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_iOS_Device32} or pidiOSDevice32{$ELSE} {$IFDEF HAS_ComponentPlatformsAttribute_iOS_Device} or pidiOSDevice{$ENDIF}{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_Linux64} or pidLinux64{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_WinNX32} or pidWinNX32{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_WinIoT32} or pidWinIoT32{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_iOS_Device64} or pidiOSDevice64{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_WinARM32} or pidWinARM32{$ELSE} {$IFDEF HAS_ComponentPlatformsAttribute_WinARM} or pidWinARM{$ENDIF}{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_OSXNX64} or pidOSXNX64{$ELSE} {$IFDEF HAS_ComponentPlatformsAttribute_OSX64} or pidOSX64{$ENDIF}{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_Linux32Arm} or pidLinux32Arm{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_Linux64Arm} or pidLinux64Arm{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_Android64Arm} or pidAndroid64Arm{$ELSE} {$IFDEF HAS_ComponentPlatformsAttribute_Android64} or pidAndroid64{$ENDIF}{$ENDIF} {$IFDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} or pidiOSSimulator64{$ENDIF} {$ENDIF} )] {$ENDIF} TIdAntiFreeze = class(TIdAntiFreezeBase) public procedure Process; override; end;
  7. Remy Lebeau

    10.3.2 as next or waiting for 10.4?

    It was released today: http://blog.marcocantu.com/blog/2019-august-delphi-1032.html https://community.idera.com/developer-tools/b/blog/posts/announcing-the-release-of-delphi-c-builder-and-rad-studio-10-3-2
  8. Actually, a manual critical section is not good enough, because behind the scenes the main UI thread will periodically reach inside any TCanvas objects that are not locked via their Lock() method. A manual critical section will not prevent that, you have to use the critical section that TCanvas.Lock() uses internally.
  9. Yes, very sure. This is a very well-known issue with TBitmap's implementation. If your threads are not calling Canvas.Lock() on their TBitmap objects then your rendering code is not thread-safe, and you have just been lucky so far that it hasn't failed on you yet. For instance, if your main UI thread is not processing any messages while your threads are rendering, then the main thread's GDI garbage collection will not occur to trash your TBitmap resources. But that is not a guarantee you should rely on, unless you explicitly code for that situation, ie by blocking the main UI thread while your rendering threads are running, which is probably not what you want to do. Otherwise, don't use TBitmap in threads, use a different implementation that doesn't suffer from threading issues, such as TBitmap32 from http://www.graphics32.org. Or, simply don't manipulate TBitmap objects in worker threads. Prepare the pixel data as needed, and then sync with the main UI thread to transfer the data into TBitmap.
  10. Remy Lebeau

    How to know that a file is not used by another program?

    The FileExists() check is unnecessary and should be removed. It introduces a race condition (the file may exist before FileExists() is called, and then gets deleted before CreateFile() is called) as well as a possible failure point (FileExists() is not 100% accurate in all possible situations, there are cases where it returns a wrong result). Calling CreateFile() by itself with OPEN_EXISTING is good enough. If the file really does not exist, CreateFile() will fail with an ERROR_FILE_NOT_FOUND error code. Also, your code does not take ERROR_SHARING_VIOLATION into account, which would mean the file is actually in use but you don't have access to open it. Try this instead: function IsFileInUse(FileName: TFileName): Boolean; var HFileRes: THandle; begin HFileRes := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (HFileRes <> INVALID_HANDLE_VALUE) then begin CloseHandle(HFileRes); Result := False; end else Result := (GetLastError() = ERROR_SHARING_VIOLATION); end;
  11. Remy Lebeau

    Android 8.0 Permissions errors using Delphi Rio 10.3

    I don't have Rio installed to look at, but the implementations you have shown are not invoking any Android APIs to request permissions from the user. That makes me think you are looking at implementation code which is meant to run on Android versions prior to v6.0, in which case it makes sense that AOnDisplayRationale would not be called since permissions would be implicitly granted by app manifest only, which would explain why the implementation code you show is populating the GrantResults array with TPermissionStatus.Granted regardless of what is being requested, and ignoring AOnDisplayRationale. There is no simply reason to display a rationale prompt to the user in that situation. So, have you looked at the implementation code that is meant to run on Androidd 6.0+? Does THAT code call AOnDisplayRationale as expected? On a side note, application code should be calling PermissionsService.IsPermissionGranted() or PermissionsService.IsEveryPermissionGranted() before calling PermissionsService.RequestPermissions(), eg: procedure TForm6.btnStartScanClick(Sender: TObject); begin if PermissionsService.IsPermissionGranted(FLocationPermission) then StartBLEDiscovery else PermissionsService.RequestPermissions([FLocationPermission], RequestPermissionsResult, DisplayRationale); end;
  12. In VCL, the TBitmap.Canvas must be locked while using the TBitmap in a worker thread. The RTL keeps track of all GDI resources it allocates, and the main UI thread runs a routine periodically that frees GDI resources that are not locked. Which is very bad for TBitmap used in a worker thread. The alternative is to not use TBitmap at all, just use the Win32 API directly for all GDI operations in a worker thread.
  13. Remy Lebeau

    What options do I have to control custom releases?

    You could put that information in your program's Version info. Define an .rc file that builds the version details conditionally. Then use compiler conditionals to control which features are turned on/off in code, and which details are shown/hidden in the version info when the .rc file is compiled.
  14. Remy Lebeau

    POSTing binary data with TIdHTTP

    Why not continue using TIdMultipartFormDataStream for that? It has an overloaded AddFormField() method that lets you specify a TStream for the input data. You could store your bytes in a TMemoryStream or TBytesStream, or use Indy's own TIdMemoryBufferStream, etc. For example: procedure SendFromBytes( const buffer: array of byte ); var Strm: TIdMemoryBufferStream; Params: TIdMultipartFormDataStream; begin ... Strm := TIdMemoryBufferStream.Create(PByte(buffer), Length(buffer)); try Params := TIdMultipartFormDataStream.Create; try Params.AddFormField('name', 'application/octet-stream', '', Strm, 'filename'); http.Post('http://x.x.x.x:8996/service', Params, responseStream); finally end; finally Strm.Free; end; ... end; Yes, whatever value is specified in the "boundary" header, in the body it needs to have a leading "--" in front of each new MIME part, and a trailing "--" at the end of the last MIME part. TIdMultipartFormDataStream handles that internally for you.
  15. Remy Lebeau

    Funny Code in System.Types

    https://quality.embarcadero.com/browse/RSP-24834
  16. Remy Lebeau

    Firedac and simultaneous connection to different version of Firebird

    I don't know how FireDAC works internally, or how it loads fbclient.dll, but have a look at Activation Contexts, which allow a process to load multiple versions of a DLL at the same time. Create a context for one DLL and connect to Firebird while that context is active, then create another context for the other DLL and connect to Firebird again. Not sure if it will work in your situation, but it is worth a try.
  17. Remy Lebeau

    UDP multicast issues

    Good catch. VERY hard to see that...
  18. Remy Lebeau

    Best delphi so far?

    Yes, sadly. In my experience, XE2 is quite stable. Although I do have newer versions installed in VMs, I never really used any of them. I never upgraded my projects beyond XE2.
  19. Remy Lebeau

    UDP multicast issues

    Like I said earlier, 255.255.255.255 is not a valid multicast group IP. If that is what you are seeing being used on the network, then it is not multicast to begin with. Where EXACTLY are you seeing that?
  20. Remy Lebeau

    UDP multicast issues

    In addition to what has already been said, 255.255.255.255 is not a valid Multicast group IP, it is a UDP subnet broadcast IP. Subnet broadcasts are very different than Multicast broadcasts. Valid multicast group IPs (for IPv4) are in the range of 224.0.0.0 to 239.255.255.255.
  21. Using Process Explorer, you can actually force-close a given handle to a file in any process. So, if you find an unexpected handle is open to your file, try simply closing it before resorting to a reboot.
  22. https://stackoverflow.com/a/36716715/65863
  23. Did you try using SysInternals' Process Explorer or Process Monitor tools to see exactly which process(es) have your EXE file open at the time of the error?
  24. See Uwe Raabe's blog articles about the Visitor Pattern in Delphi: Part 1 Part 2 Part 3 Part 4 He shows how to work around the circular referencing issue using interfaces and multiple units.
  25. Remy Lebeau

    JSON string value

    Um, yes it can. It has a full JSON library built-in.
×