-
Content Count
2684 -
Joined
-
Last visited
-
Days Won
113
Everything posted by Remy Lebeau
-
WEB Standalone console APP “Indy http” in production ?
Remy Lebeau replied to borni69's topic in Network, Cloud and Web
Why are you using MaxInt for the timeout, and not simply using Infinite instead? Then you can get rid of the while loop. // now the server is processing requests // wait for terminate signal MyEvent.WaitFor(Infinite); -
How to draw a semitransparent ellipse on a canvas?
Remy Lebeau replied to vshvetsov's topic in General Help
TColor is an enum representing an integer, and so it is subject to endian. TRGBQuad is not. You should be using the ColorToRGB() function to convert an TColor value into an integer value, and then using the Get(R|G|B)Value() functions to obtain the individual R/G/B values of that integer. The PremultiplyAlpha() function is operating on a bitmap's raw R/G/B pixel bytes directly, it is not going through TColor at all. -
Correct, since FMX is cross-platform, but you are trying to use platform-specific code. So, you will have to #ifdef your code for Windows, and then #include the relevant header files, in this case <windows.h> and <shlobj.h> (NOT <shlobj_core.h> directly). Also, FYI, SHGetSpecialFolderLocation() is very old, so you should be using SHGetFolderPathW() instead, or even SHGetKnownFolderPath(). That is just a warning. Ignore it, and or turn it off in the compiler settings. SHGetFolderPath() was introduced in Windows 2000. Any old compiler that doesn't recognize it is too old to support FireMonkey anyway.
-
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
Just a thought - have you tried using SysInternals Process Monitor yet to see all of the Registry activity that Explorer invokes on Windows7 vs Windows 10/11 while registering the property handler and while loading the .arw file? -
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
That is a very good point, I completely forgot about that! It has been a long time since I last worked with Shell Extension handlers. -
The scanner app does not need to know the local device IP just to send data to another device. It only needs to know the receiver's IP. Probably best to use DNS/mDNS or other local network discovery protocol to discover the receiver's IP dynamically at runtime. The Android server app does not need to know the local device IP just to connect to another server. And it does not need to know the local device IP to accept connections, for that matter. So, I'm still wondering why you actually need to query the device IP at all.
-
Why do you need to retrieve an Android device's IP address in the first place? What are you planning on doing with it, exactly?
-
Add the "System.Generics.Collections" unit to your "uses" clause. https://docwiki.embarcadero.com/Libraries/en/System.Generics.Collections.TList I don't write projects for Android. I didn't say the code would actually compile, but it should give you some ideas of what to look.
-
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
Your PropertySheelHandler should not have its own ProgID assigned to it. You can assign your PropertySheetHandler to other ProgIDs as needed, but it should not have its own ProgID. So, get rid of the "HKLM\SOFTWARE\Classes\CLSID\{AF6B...}\ProgID" subkey. -
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
How would you know fore sure? You are not reporting every error that may occur. For example, if an extension does not have a ProgID yet, and you try to create a new ProgID but Reg.OpenKey() fails, you don't report that. Also, I see you creating your PropertySheetHandlers subkey only for the 1st extension in your array, because your code assumes that all extensions are using the same ProgID, which is not a guarantee, so you should be checking/creating the PropertySheetHandlers subkey for every ProgID you encounter. Try something more like this: procedure TMyDelphiPropSheetHandlerFactory.UpdateRegistry(ARegister: Boolean); var Reg : TRegistry; ClassID : String; Updated : Boolean; {$IFDEF REG_FILENAME} ProgNameVer : String; RegExtArray : TStringDynArray; Ext : String; ProgID : String; {$ENDIF} begin ClassID := GUIDToString(Class_MyDelphiPropSheetHandler); Updated := False; try Reg := TRegistry.Create; try {$IFDEF REG_FILENAME} Reg.RootKey := HKEY_LOCAL_MACHINE; ProgNameVer := ProgName + '.' + ProgVer; RegExtArray := SplitString(RegFileExts, ';'); if ARegister then begin inherited UpdateRegistry(ARegister); for Ext in RegExtArray do begin if not Reg.OpenKeyReadOnly('\Software\Classes\' + Ext) then begin if Reg.LastError = ERROR_FILE_NOT_FOUND then MyMessageBox('Ext="%s" doesn''t exist', [Ext]) else MyMessageBox('Can't open registry key for Ext="%s"', [Ext]); Continue; end; ProgID := Reg.ReadString(''); Reg.CloseKey; if ProgID = '' then begin ProgID := ProgNameVer; Reg.Access := KEY_SET_VALUE; if not Reg.OpenKey('\Software\Classes\' + Ext, True) then begin MyMessageBox('Can't open registry key to update Ext="%s"', [Ext]); Continue; end; Reg.WriteString('', ProgID); Reg.CloseKey; Updated := True; MyMessageBox('Created ProgID[%s]="%s"', [Ext, ProgID]); end else MyMessageBox('ProgID[%s]="%s"', [Ext, ProgID]); Reg.Access := KEY_SET_VALUE; if not Reg.OpenKey('\Software\Classes\' + ProgID + '\ShellEx\PropertySheetHandlers\' + ProgName, True) then begin MyMessageBox('Can''t create PropertySheetHandler="%s" for ProgID="%s"', [ProgName, ProgID]); Continue; end; Reg.WriteString('', ClassID); Reg.CloseKey; Updated := True; MyMessageBox('PropertySheetHandlers[%s]="%s"', [ProgID, ProgName]); MyMessageBox('Registered for Ext="%s"', [Ext]); end; end else begin for Ext in RegExtArray do begin if not Reg.OpenKeyReadOnly('\Software\Classes\' + Ext) then begin if Reg.LastError <> ERROR_FILE_NOT_FOUND then MyMessageBox('Can't open registry key for Ext="%s"', [Ext]); Continue; end; ProgID := Reg.ReadString(''); Reg.CloseKey; if SameText(ProgID, ProgNameVer) then begin Reg.Access := KEY_SET_VALUE; if not Reg.OpenKey('\Software\Classes\' + Ext, False) then begin MyMessageBox('Can't open registry key to update Ext="%s"', [Ext]); end else begin if Reg.DeleteValue('') then begin Reg.CloseKey; Updated := True; MyMessageBox('Deleted ProgID="%s" value for Ext="%s"', [ProgID, Ext]) end else begin Reg.CloseKey; MyMessageBox('Can''t delete ProgID="%s" value for Ext="%s"', [ProgID, Ext]); end; end; end; if ProgID <> '' then begin Reg.Access := KEY_SET_VALUE or _DELETE; if not Reg.OpenKey('\Software\Classes\' + ProgID + '\ShellEx\PropertySheetHandlers\', False) then begin if Reg.LastError <> ERROR_FILE_NOT_FOUND then MyMessageBox('Can''t open PropertySheetHandlers key for ProgID="%s"', [ProgID]); end else if Reg.DeleteKey(ProgName) or (Reg.LastError = ERROR_FILE_NOT_FOUND) then begin Reg.CloseKey; Updated := True; MyMessageBox('Deleted PropertySheetHandler="%s" for ProgID="%s"', [ProgName, ProgID]); end else begin Reg.CloseKey; MyMessageBox('Can''t delete PropertySheetHandler="%s" for ProgID="%s"', [ProgName, ProgID]); end; end; end; if Reg.DeleteKey('\Software\Classes\' + ProgNameVer) or (Reg.LastError = ERROR_FILE_NOT_FOUND) then begin Updated := True; MyMessageBox('Deleted registry key for ProgID="%s"', [ProgNameVer]) end else MyMessageBox('Can''t delete registry key for ProgID="%s"', [ProgNameVer]); inherited UpdateRegistry(ARegister); end; {$ELSE} Reg.RootKey := HKEY_CLASSES_ROOT; if ARegister then begin inherited UpdateRegistry(ARegister); Reg.Access := KEY_SET_VALUE; if Reg.OpenKey('\*\shellex\PropertySheetHandlers\' + ProgName, True) then begin Reg.WriteString('', ClassID); Reg.CloseKey; Updated := True; MyMessageBox('Created registry key for PropertySheetHandler="%s"', [ProgName]); end else MyMessageBox('Can''t create/open registry key for PropertySheetHandler="%s"', [ProgName]); end else begin if Reg.DeleteKey('\*\shellex\PropertySheetHandlers\' + ProgName) or (Reg.LastError = ERROR_FILE_NOT_FOUND) then begin Updated := True; MyMessageBox('Deleted registry key for PropertySheetHandler="%s"', [ProgName]); end else MyMessageBox('Can''t delete registry key for PropertySheetHandler="%s"', [ProgName]); inherited UpdateRegistry(ARegister); end; {$ENDIF} finally Reg.Free; end; finally if Updated then SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil); end; end; UPDATE: something else I just realized - you did not say whether you are running your code from a 32bit or 64bit executable. If 32bit on a 64bit system, you need to take WOW64 into account, by including the KEY_WOW64_32KEY or KEY_WOW64_64KEY flag in the TRegistry.Access property as needed. -
You can use ConnectivityManager.getAllNetworks() to iterate available networks, and ConnectivityManager.getLinkProperties() to get the LinkProperties of each network, for example (yes, it is in Java): private Network findVpnNetwork() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); Network[] networks = cm.getAllNetworks(); for (Network network : networks) { LinkProperties linkProperties = cm.getLinkProperties(network); List<LinkAddress> addresses = linkProperties.getLinkAddresses(); for (LinkAddress addr : addresses) { if (addr.getAddress().equals(VPN_ADDRESS)) { return network; } } } return null; } So, a Delphi translation to get available IP addresses might look something like this: function getIpAddresses: TList<JInetAddress>; begin Result := TList<JInetAddress>.Create; try var svc := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.CONNECTIVITY_SERVICE); var cm := TJConnectivityManager.Wrap((svc as ILocalObject).GetObjectID); for var network in cm.getAllNetworks do begin for var addr in cm.getLinkProperties(network).getLinkAddresses do Result.Add(addr.getAddress); end; except Result.Free; raise; end; end;
-
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
Creating a new ProgID just to define a PropertySheetHandler will not change which app opens the file type. Those are separate operations. Besides, in your example, there is no app registered for the file type anyway, since there is no ProgID registered for the file type (the file is being opened through a separately registered Thumbnail Handler instead). Simply don't create any Shell commands inside of your new ProgID, only register your ShellEx handler. -
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
That is because the extension key has a Thumbnail Provider registered, which is registered via a "ShellEx" subkey on the extension key itself. However, since you want to register a Property Sheet handler instead, the extension key must have a ProgID registered with it, as I showed earlier. Why are you being so hesitant to define one? If you want your Property Sheet Handler to work correctly, you don't have a choice, this is simply how Property Sheet Handlers operate. A "ShellEx" subkey on the extension key itself will not work for a Property Sheet Handler. -
Indy with macOS crash with socket error #53 and #61, unable to catch
Remy Lebeau replied to softtouch's topic in Network, Cloud and Web
When the client's ConnectTimeout property is set to a non-infinite value, or if you are connecting the client in the context of the main UI thread and using TIdAntiFreeze, then Indy uses a worker thread to connect the client socket to the server in order to implement timeout handling. The call stack above is showing the exception being raised in the context of that worker thread, and there is no way for you to catch that specific exception directly from that thread. However, Indy will internally catch the exception for you and re-raise it in the context of the thread that is trying to connect the client. And you should be able to catch that exception normally. If not, then the RTL is likely not doing its job correctly (IIRC correctly, Delphi's exception handling on MacOS is less stable/reliable than on Windows). The code you have shown is fine, you should be able to catch the exception. So, you are just going to have to debug the code at runtime to find out why the exception is not being propagated to your code correctly. -
Not the raw data as it came directly from the TCP socket, no. By the time you are given access to the TIdHTTPRequestInfo object, all of the raw socket data has already been parsed and re-organized for Indy's purposes. That being said, you can get the (near-raw) headers from the TIdHTTPRequestInfo.RawHeaders property, and the body data from either the TIdHTTPRequestInfo.PostStream or TIdHTTPRequestInfo.FormParams property, depending on the request's media type. Basically, yes. The only other option is to log the raw socket data immediately as it comes off the socket, before Indy parses it. You can do that by assigning a TIdConnectionIntercept-derived object to the AContext.Connection.Intercept property in the server's OnConnect event. For instance, one of the TIdLog... components, like TIdLogFile,
-
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
It is not outdated. I've used that info in the past to create shell handlers, and my machines have many 3rd party property sheet handlers installed that are registered the way I described. If your extension does not have a ProgID assigned to it (why?), you need to create and assign your own ProgID, even if just to create the Shellex subkey. All extension subkeys should have a ProgID subkey associated with them, because it is the ProgID subkey that contains the actual commands that tell Windows what to do with files that have those extensions. Multiple file extensions that share a common set of commands can be assigned to a single ProgID. -
How to register a shell property sheet for a single file type?
Remy Lebeau replied to FPiette's topic in Windows API
Per the documentation, Registering Shell Extension Handlers, you need to create your ShellEx subkey underneath the extension's ProgID subkey, not under the extension subkey, eg: HKEY_CLASSES_ROOT .arw (Default) = <MyArwProgID> MyArwProgID ShellEx PropertySheetHandlers MyDelphiPropSheetHandler (Default) = <MyClassID> For example: Reg := TRegistry.Create; try Reg.RootKey := HKEY_CLASSES_ROOT; if Reg.OpenKeyReadOnly('\.arw') then begin ProgID := Reg.ReadString(''); Reg.CloseKey; Reg.Access := KEY_CREATE_SUB_KEY or KEY_SET_VALUE; if (ProgID <> '') and Reg.OpenKey('\' + ProgID + '\ShellEx\PropertySheetHandlers\MyDelphiPropSheetHandler', True) then begin Reg.WriteString('', ClassID); Reg.CloseKey; end; end; finally Reg.Free; end; Note that you really should not be writing directly to HKEY_CLASSES_ROOT, you should be writing to either HKEY_LOCAL_MACHINE\Software\Classes\ or HKEY_CURRENT_USER\Software\Classes\ instead, per the documentation, HKEY_CLASSES_ROOT Key: For instance: Reg := TRegistry.Create; try if ForTheCurrentUserOnly then Reg.RootKey := HKEY_CURRENT_USER else Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKeyReadOnly('\Software\Classes\.arw') then begin ProgID := Reg.ReadString(''); Reg.CloseKey; Reg.Access := KEY_CREATE_SUB_KEY or KEY_SET_VALUE; if (ProgID <> '') and Reg.OpenKey('\Software\Classes\' + ProgID + '\ShellEx\PropertySheetHandlers\MyDelphiPropSheetHandler', True) then begin Reg.WriteString('', ClassID); Reg.CloseKey; end; end; finally Reg.Free; end; -
Delphi 11.1, Android API 31, FLAG_IMMUTABLE in Pending Intent
Remy Lebeau replied to nufus42's topic in FMX
I don't see any tickets open in QualityPortal about that issue yet. -
Is there a way to use a platform specific win32/win64 DEF file?
Remy Lebeau replied to alank2's topic in General Help
Tons of questions on StackOverflow on that very topic, for instance: How can I use "sizeof" in a preprocessor macro? sizeof() is not executed by preprocessor Does the sizeof operator work in preprocessor #if directives? Just to name a few... Since sizeof is a compile-time constant, I would use "if constexpr" instead: if constexpr (sizeof(ATypeName) > 20) { /*.... your code here ...*/ } -
If the Owner form assigns itself as the actual Owner (from the RTL's perspective) of the Child form, then the RTL will handle all of that for you automatically. All you would have to do in your own code is have the Owner form override the Notification() method. However, personally, I would just have the Owner form assign its own handlers to the Child form's OnClose and OnDestroy events instead. That way, the Owner, not the Child, decides whether or not to set Action=caFree in the OnClose event, and the Owner can still react to the Child being destroyed without having to override the Notification() method.
-
Is there a way to use a platform specific win32/win64 DEF file?
Remy Lebeau replied to alank2's topic in General Help
Yup. https://docwiki.embarcadero.com/RADStudio/en/C%2B%2B_Compilers There is 1 classic compiler (bcc32) and 2 separate clang compiler front-ends (bcc32c and bcc32x): -
Thanks. I have now added the .zip to Indy's repo.
-
Thanks. I would like to check in this .zip file to Indy's GitHub repo, but first can you please verify that version number? 1.0.2u was released on Dec 20 2019. What does Indy's OpenSSLVersion() function (in the IdSSLOpenSSL unit) actually return when using these .so files?
-
Is there a way to use a platform specific win32/win64 DEF file?
Remy Lebeau replied to alank2's topic in General Help
Embarcadero provides only one 64-bit compiler for Windows (unlike three 32-bit compilers for Windows), and it is clang-based. -
No, because .so files are not static-link files. Per the documentation, the Android compiler uses .a files for static linking, same as the iOS compiler. Anywhere you want, as long as it is on the compiler's search path.