Jump to content

Remy Lebeau

Members
  • Content Count

    2343
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by Remy Lebeau

  1. Even on Windows, it is a good idea to stay up-to-date.
  2. Remy Lebeau

    SSL in IOS Simulator

    Based on the QP ticket, looks like this could work: {$IF DEFINED(IOS) AND NOT DEFINED(IOSSIMULATOR)}
  3. Remy Lebeau

    Reading processing instructions from XML

    If you look at the source code for TXMLDocument, its GetPrologValue() method locates the 'xml' processing instruction and then manually parses out attribute values from its NodeValue. So, I guess that is just the way processing instructions work in the DOM. Which I guess makes sense, as the XML standard defines processing instructions as basically just arbitrary text, they don't actually contain any formal attributes, like element nodes do. But in this case, the text for the 'xml-stylesheet' instruction happens to resemble the syntax of attributes.
  4. Why are you using such an old version of Indy? The latest version is 10.6.2 (the build number was lost a few years ago when Indy moved from SVN to GitHub - open issues #292 and #328). You should upgrade to the latest from Indy's GitHub repo (and yes, it supports XE7). That error means that an HTTPS url is being requested but an SSLIOHandler component is not assigned to the TIdHTTP.IOHandler property.
  5. Remy Lebeau

    Reading processing instructions from XML

    Yes. You can enumerate the TXMLDocument.Node.ChildNodes list, looking for any children IXMLNode entries whose IXMLNode.NodeType property is ntProcessingInstr and IXMLNode.NodeName property is 'xml-stylesheet'. When you find a match, you will have to parse out its 'href' value from the IXMLNode.NodeValue property.
  6. Remy Lebeau

    Replacing Apostrophe

    However, it only supports decoding numeric entities, and references to reserved characters. Since apos is not a reserved character, it will not decode ''' The documentation even says so: https://docwiki.embarcadero.com/Libraries/en/System.NetEncoding.THTMLEncoding
  7. Remy Lebeau

    SSL in IOS Simulator

    Building OpenSSL dylibs for iOS simulator
  8. Remy Lebeau

    Application.MainForm v Self v Nil??

    The only thing that matters is whether you assign a nil Owner (ie, you are responsible for freeing the sub-Form when you are done using it) or assign a non-nil Owner (ie, the Owner will free the sub-Form when the Owner itself is freed). WHO the Owner is when non-nil is largely irrelevant, as long as the Owner outlives the usage of the sub-Form. Yes.
  9. Remy Lebeau

    SSL in IOS Simulator

    Have you read Embarcadero's documentation yet? Creating an iOS App: OpenSSL_Support libcrypto.a is a static library for iOS devices, but for the iOS Simulator you need the dynamic library libcrypto.dylib instead Why are you including the IdSSLOpenSSLHeaders unit twice? Try this instead: uses ... IdSSLOpenSSLHeaders, {$IFDEF IOS} {$IFDEF CPUARM} IdSSLOpenSSLHeaders_Static, {$ENDIF} {$ENDIF} System.IOUtils, IdTCPClient; Which can be simplified using {$IF} instead: uses ... IdSSLOpenSSLHeaders, {$IF DEFINED(IOS) AND DEFINED(CPUARM)} IdSSLOpenSSLHeaders_Static, {$ENDIF} System.IOUtils, IdTCPClient;
  10. Yes. TRegistry has never supported REG_MULTI_SZ in any capacity. No read/write methods, no copy/move semantics, nothing. I don't know why, it's been around like forever. Same with REG_QWORD, too. Correct. Which is weird that they waste effort turning the reported data type id into an enum just to turn it back into a data type id immediately afterwards. If they just used the original data type id as-is, there would be no problem. Yes, it could be fixed. It is not just you. https://quality.embarcadero.com/browse/RSP-15275 Yes, you can, actually. Until Embarcadero fixes it properly, you could simply modify the implementation (not the interface) of the System.Win.Registry.pas file (ie, to make TRegistry.MoveKey() not use TRegistry.GetData() since it doesn't report the types correctly), and then add that modified unit to your projects. The compiler will then use your modified unit instead of the original. Note that this only works if you are NOT compiling with Runtime Packages enabled, though.
  11. It doesn't really matter what you use, as long as the value is "large enough". If the value you specify is more than the number of characters actually available, Copy() will just stop when it reaches the end of the string. So, whether you use: FPath := Copy(FPath, I + 3); Or FPath := Copy(FPath, I + 3, MaxInt); Or FPath := Copy(FPath, I + 3, Length(FPath)); Or FPath := Copy(FPath, I + 3, Length(FPath) - I + 3); It is all the same as far as Copy() cares. Personally, I use MaxInt.
  12. Remy Lebeau

    Problem logging into gmail..

    FYI, there is a sasl-oauth branch in Indy's GitHub repo to add OAuth2 SASL components for TIdSMTP/TIdPOP3/TIdIMAP4 (and TIdDICT). You would still have to obtain/refresh the OAuth2 token yourself from Google (or other OAuth2 provider), such as via HTTP, but Indy can then submit the token via SASL when accessing email.
  13. Remy Lebeau

    Monterey 12.6 not recognizing bitmap files

    Seems you are not alone: Monterey 12.6 Preview app cannot open bitmaps!
  14. Remy Lebeau

    Deleting string wich does include number

    I would probably use LastDelimiter(), especially since the example in question shows digits are at the end of the strings, eg: function ContainsDigit(const _Text: string): Boolean; begin Result := LastDelimiter('0123456789', _Text) > 0; end; Or: function ContainsDigit(const _Text: string): Boolean; begin Result := _Text.LastDelimiter('0123456789') > -1; //or: //Result := _Text.LastDelimiter(['0'..'9']) > -1; end;
  15. Remy Lebeau

    save probelm in ini file vcl with tlistbox

    Yup, minor typo on my part. You should not have gotten that error. As you can see in my example, the function is a method of the Form class, so it would be using the Form's Handle.
  16. Remy Lebeau

    Error handling

    That makes sense for true unexpected/fatal errors, however... If a simple disconnect is being treated as a fatal error, that sounds like a bug that needs fixing.
  17. Remy Lebeau

    Error handling

    A client disconnect should never be treated as a fatal error that kills the server. Just close the client socket and move on. Let the server continue serving other clients normally.
  18. Remy Lebeau

    save probelm in ini file vcl with tlistbox

    First, do not store your INI file in the same folder as your EXE. If the EXE is installed in a protected folder, like under %ProgramFiles%, then this will not work. You should instead save the INI file in a subfolder you create for your app under the user's %APPDATA% folder, for instance. Second, use (Write|Read)Integer() instead of (Write|Read)String(). Third, what is the value of SkinFile? And did you verify that the restoration code is using the same value? You are not loading from the same file that you saved to. Also, why are you checking the current ItemIndex value before loading the value from the INI file? With that said, try something more like this: uses ..., SysUtils, ComObj, SHFolder; procedure TMyForm.GetINIFilePath(CanCreate: Boolean): string; var AppDataPath: array[0..MAX_PATH] of Char; begin OleCheck(SHGetFolderPath(Handle, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, AppDataPath)); Result := IncludeTrailingPathDelimiter(AppDataPath) + 'MyApp'; if CanCreate then ForceDirectories(Result); Result := IncludeTrailingPathDelimiter(Result) + 'my.ini'; end; procedure TMyForm.SaveINI; var Myinifile: TIniFile; SkinFile: string; begin SkinFile := ...; Myinifile := TIniFile.Create(GetINIFilePath(True)); try Myinifile.WriteInteger('LastDiskSkin', SkinFile, lst1.ItemIndex); ... finally Myinifile.Free; end; end; procedure TMyForm.LoadINI; var Myinifile: TIniFile; begin SkinFile := ...; Myinifile := TIniFile.Create(GetINIFilePath(False)); try lst1.ItemIndex := Myinifile.ReadInteger('LastDiskSkin', SkinFile, -1); ... finally Myinifile.Free; end; end; procedure TMyForm.FormCreate(Sender: TObject); begin LoadINI; end; procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction); begin SaveINI; end;
  19. Remy Lebeau

    Indy IMAP and Microsoft EWS

    Yes. And you don't actually need OAuth for it, you could use an App-specific password instead if you have 2-step verification enabled. Not very mature at all, considering I just created the branch a couple of months ago, and am still receiving feedback over whether it even works correctly.
  20. Remy Lebeau

    Can't make a popup form go behind the main form in z-order

    Agreed. Embarcadero has tied way too many things in the VCL's internals to the TApplication.MainFormOnTaskbar property, making it a do-all toggle switch to enable/disable all kinds of behaviors it was never meant to toggle. IMHO, they should never have made its scope reach more than it was originally intended for. Introducing MainFormOnTaskbar at the TApplication level was the wrong design choice to begin with, it should have been introduced at the TForm level instead (like WinForms did with its Form.ShowInTaskbar property), and NOT touch anything other than what its name suggests. But that is just my opinion...
  21. Remy Lebeau

    Json create Array

    In the JSON you want to create, "registration_ids" is an array of strings. But in your code, you are creating "registration_ids" as an array of objects instead. To get the result you want, between WriteStartArray() and WriteEndOfArray(), you need to get rid of WriteStartObject(), WritePropertyName(''), and WriteEndObject(): wrtString := TStringWriter.Create(); wrtJSON := TJsonTextWriter.Create(wrtString); try wrtJSON.Formatting := TJsonFormatting.Indented; wrtJson.WriteStartObject; wrtJson.WritePropertyName('registration_ids'); wrtJson.WriteStartArray; //wrtJson.WriteStartObject; // <-- //wrtJson.WritePropertyName(''); // <-- wrtJson.WriteValue(strToken); //wrtJson.WriteEndObject; // <-- wrtJson.WriteEndArray; wrtJson.WritePropertyName('notification'); wrtJSON.WriteStartObject; wrtJSon.WritePropertyName('title'); wrtJson.WriteValue(edtBaslik.Text); wrtJson.WritePropertyName('body'); wrtJson.WriteValue(edtMesaj.Text); wrtJSON.WriteEndObject; wrtJSON.WriteEndObject; That said, why are you using TJsonTextWriter at all? This would be much more straight-forward if you used TJSONObject and TJSONArray instead, eg: uses ..., System.JSON; var arr: TJSONArray; notif, obj: TJSONObject; strJSON: string; begin obj := TJSONObject.Create; try arr := TJSONArray.Create; try arr.Add(strToken); obj.AddPair('registration_ids', arr); except arr.Free; raise; end; notif := TJSONObject.Create; try notif.AddPair('title', 'Hi'); notif.AddPair('body', 'Notification test'); obj.AddPair('notification', notif); except notif.Free; raise; end; strJSON := obj.ToJSON; // or, obj.Format finally obj.Free; end; // use strJSON as needed... end;
  22. The simplest solution that will not require any code changes is to have your Outlook/Exchange users turn on 2-step verification in their accounts and then generate application-specific passwords. Otherwise, you will have to update your code to use OAuth2 when connected to Outlook/Exchange.
  23. TClientSocket is just a thin wrapper around a TCP socket. WebSocket is a protocol that runs on top of TCP. Thus, TClientSocket will happily connect to a WebSocket server... when used correctly, which you are not... But that is not the IP you are trying to connect to... This is where your mistake is. The Host and Address properties are mutually exclusive, you can only use one of them. The Host has priority over the Address. So, you are trying to connect to 'localhost' (ie 127.0.0.1) only. That is why you are getting an error, since there is no TCP server running on port 6667 on your local machine. You need to either 1) drop the assignment of the Host altogether and just use the Address, or else 2) set the Host to the Arduino's hostname/IP: Client.Host := '192.168.0.24'; As far as TClientSocket is concerned, there is no difference. It only knows about TCP, not any protocols on top of TCP (Ethernet is underneath), so if you continue using TClientSocket then you are going to have to implement the WebSocket protocol yourself from scratch. Read RFC 6455 for that. Otherwise, there are plenty of 3rd party WebSocket libraries available that you can use instead.
  24. Remy Lebeau

    Can Rad Studio 11.1 and 11.2 coexist?

    No. Embarcadero changed their versioning scheme in 11.0: https://blogs.embarcadero.com/rad-studio-11-is-coming-new-version-announcement-and-beta-invite-for-update-subscription-customers/ Unlike with 10.x, which were all major versions where 10.x.y were minor updates, 11.x are minor updates to 11.0, which is the major version. Only major versions can co-exist. Minor updates do not. Yes. No.
  25. What kind of credentials, exactly? The IDE doesn't require credentials to compile a project. Chances are, there is something inside your project itself that is requiring credentials when the app starts running. Maybe a database? Or maybe the project contains a UAC manifest that requires the app to run elevated with admin permissions? There is not enough info provided to diagnose this. Can you provide a screenshot of the credential prompt? Then someone can tell you whether it is a native OS dialog or not, at least.
×