-
Content Count
2998 -
Joined
-
Last visited
-
Days Won
135
Everything posted by Remy Lebeau
-
Sending email by Delphi Sydney on windows 7
Remy Lebeau replied to NBilov's topic in Network, Cloud and Web
TIdSMTP.Send() will call TIdSMTP.Authenticate() for you if authentication hasn't succeeded yet. If you try to send an email without being adequately authenticated, the server will report a failure, which TIdSMTP will raise as an exception. So really, there is little reason to check TIdSMTP.DidAuthenticate and call TIdSMTP.Authenticate() manually.- 10 replies
-
Only components increment GStack's usage count, utility classes do not. If you use GStack without creating any components, you are expected to call TIdStack.IncUsage()/DecUsage() directly, eg: TIdStack.IncUsage; // use GStack as needed... TIdStack.DecUsage; It doesn't hurt to call IncUsage()/DecUsage() if you are not sure whether they should be called. Just make sure they are balanced correctly. TIdStack is reference-counted, the 1st usage increment creates the instance, and the last usage decrement destroys it. I'll consider it for a future release when more design-breaking changes are being worked on.
-
In RAD Studio 11 (and since 10.3), only the Windows clang compilers support C++14 and C++17, the rest of the clang compilers support only C++11. See Modern C++ Features Supported by RAD Studio Clang-enhanced C++ Compilers for details. You should not have to do anything extra to enable C++17 by default when compiling for Windows. However, if you want to specify a specific standard version, you can do so manually in the project options via "C++ Compiler > Advanced > Other options > Additional options to pass to the compiler", eg: Also see How to set C++ language standard in C++ Builder on StackOverflow.
-
Technically, the correct name is Quality Portal. Quality Central was its predecessor.
-
AddStrings() has an overload that takes a TArray<string> instead of a dynamic "array of string" (even in 10.2 Tokyo), eg: type //TMyArrToStoreTheResulted = array of string; TMyArrToStoreTheResulted = TArray<string>;
-
Sending email by Delphi Sydney on windows 7
Remy Lebeau replied to NBilov's topic in Network, Cloud and Web
That is an extremely old version of OpenSSL. You should be using openssl-1.0.2u-i386-win32.zip instead. Or, you can use this SSLIOHandler (work in progress) and then you can use a newer OpenSSL 1.1.x version instead.- 10 replies
-
If the root path already has a '\' on the end of it, you would be adding another '\' unnecessarily. Better to use IncludeTrailingPathDelimiter() instead, eg: LContinue := FindFirst(IncludeTrailingPathDelimiter(AFolderRoot) + APatternToSearch, faAnyFile, LSearchRecord) = 0; That comparison wont work correctly if the file name begins with any character that is lexicographically less-than '.' (a few of them are reserved, but many of them are not), namely: ! # $ % & ' ( ) + , - You need to check for '.' and '..' specifically instead, eg: if (LSearchRecord.Name = '.') or (LSearchRecord.Name = '..') then
-
Sending email by Delphi Sydney on windows 7
Remy Lebeau replied to NBilov's topic in Network, Cloud and Web
Most servers are phasing out TLS 1.0, or already have, You should enable TLS 1.1 and TLS 1.2 as well: IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; If you allow the Port to be configurable, you should also allow the UseTLS value to be configurable as well. There is a functional difference between utUseImplicitTLS vs utUsseExplicitTLS, so you should let your config indicate which to use on a non-default Port. As mentioned earlier, this is wrong. You need to use utUseImplicitTLS on port 465. Use utUseExplicitTLS on port 587 instead.- 10 replies
-
That zipped code was submitted by another user on a comment to the open PR in Indy's repo. I don't think that code was every merged into the repo where the PR originates from: https://github.com/mezen/Indy/tree/NewOpenSSL_PR (see https://github.com/mezen/Indy/issues/12).
-
Makes sense, because by default assigning a raw char* string to a UnicodeString has no way of knowing that the char string is encoded as UTF-8, so it assumes the string is encoded as ANSI instead. You might try using SetMultiByteConversionCodePage(), but it would be better to put the UTF-8 char sequence inside of a UTF8String object instead, eg: Edit1->Text = UTF8String("\xf0\x9f\x98\x82"); More generically, you can use RawByteString for handle any 'char'-based encoding: RawByteString str("\xf0\x9f\x98\x82"); SetCodePage(str, CP_UTF8, false); Edit1->Text = str; The RTL knows how to convert a UTF8String/RawByteString to a UnicodeString, and vice versa.
-
void __fastcall TForm1::Button1Click(TObject *Sender) { int x = Sysutils::StrToInt(Edit1->Text); // alternatives: // int x = Edit1->Text.ToInt(); // int x = std::stoi(Edit1->Text.c_str()); // int x = CSpinEdit1->Value; (using a TCSpinEdit instead of a TEdit) int y = Sysutils::StrToInt(Edit2->Text); // same as above... int sum = x + y; Label3->Caption = _D("The sum is ") + String(sum); // alternatives: // Label3->Caption = Sysutils::Format(_D("The sum is %d", ARRAYOFCONST((sum)) ); // Label3->Caption = String{}.sprintf(_D("The sum is %d", sum); // Label3->Caption = std::format(L"The sum is {}", sum).c_str(); // Label3->Caption = (std::wostringstring{} << L"The sum is " << sum).str().c_str(); }
-
Yes, it reallocates when its Capacity is exceeded. And, it uses an array internally. But, that reallocation won't happen on every add, since the Capacity grows algorithmically (see SysUtils.GrowCollection()). It is very inefficient to reallocate on every add.
-
Have you considered setting up a personal VPN on your home network, and then connect to it from your work office?
-
Not really. Your way reallocates the array on every item added. Whereas TList has a Capacity so it doesn't reallocate on every individual add, and then the final array is allocated only 1 time based on the TList's final Count.
-
Use the Length() function. Use this instead: for var i := 0 to Length(Instances)-1 do Memo1.Lines.Add(Instances[i]); Alternatively, you can use the Low()/High() functions to get the first and last indexes of the array: for var i := Low(Instances) to High(Instances) do Memo1.Lines.Add(Instances[i]); Alternatively, you can use a for..in loop instead, no indexes needed: for var elem in Instances do Memo1.Lines.Add(elem); However, in your particular example, the TMemo.Lines property has an overloaded method that accepts a TArray<string> as input, so you don't even need a loop at all: Memo1.Lines.AddStrings(Instances); You don't need that. Dynamic arrays know their own length.
-
Delphi does not have any native classes named TProcess or TProcessList. Your example is clearly based on 3rd party code that you don't have installed, which is why the classes are undefined.
-
Whitespace between tokens doesn't matter in C/C++. Thus, "Type* VarName" and "Type *VarName" and "Type * VarName" all mean the same thing.
-
Not that I'm aware of. But its funny, because the RTL does have an AdjustLineBreaks() function, so it would have been trivial for the IDE to adjust pasted text to the editor's native format.
-
COleDataSource is just a Microsoft C++ helper class that implements the IDataObject interface, which can be put on the clipboard using the OleSetClipboard() function. In Delphi, you would have to implement the IDataObject interface manually (it is declared in the Winapi.Ole2 unit), or use a 3rd party implementation, such as from Melanders' Drag&Drop suite (probably via TDropEmptySource+TDataFormatAdapter).
-
All the more reason to try the route I suggested. Application A could send its file list to Application B, then B can immediately put CFSTR_FILEDESCRIPTOR and CFSTR_FILECONTENTS items on its local clipboard for each file, having each CFSTR_FILECONTENTS hold an IStream to access its file data. Then, when the user pastes the clipboard somewhere (or an app reads the clipboard directly), the individual CFSTR_FILECONTENTS streams can/will be read from, which can then transfer the actual file data from machine A to B as needed. You could even go as far as having A transfer the file data to B in the background while waiting for a paste to happen, caching the data locally on B, and when CFSTR_FILECONTENTS is read from it can read from the local cache if available, otherwise initiate/wait-for the transfer to finish (even provide the data while it is begin transferred). When the clipboard gets cleared, the IStream's will be released, and their destructors can cancel any transfers in progress and delete any local caches as needed. There are examples/tutorials online about working with CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS, for instance: https://www.codeproject.com/Articles/15576/How-to-drag-a-virtual-file-from-your-app-into-Wind https://www.codeproject.com/Articles/23139/Transferring-Virtual-Files-to-Windows-Explorer-in I'm sure they have, but it is very specialized work, so you are not likely to see it talked about publicly very much.
-
That is the OLD way to monitor the clipboard. Since Vista, the NEW way is using a Clipboard Format Listener instead, registered via AddClipboardFormatListener() and handling WM_CLIPBOARDUPDATE messages. Have you read Microsoft's documentation on Transferring Shell Objects with Drag-and-Drop and the Clipboard and Handling Shell Data Transfer Scenarios yet? Per Shell Clipboard Formats, you will likely want to implement the CFSTR_FILEDESCRIPTOR and CFSTR_FILECONTENTS formats. That way, you can put descriptions of the files onto the clipboard, and when they are pasted then you can stream in the actual file data as needed.
-
When your code is calling TIdHTTP.Post(), if it catches any non-HTTP exception, it is reading the TIdHTTP.ResponseCode property, which won't have a valid number in that case and so returns -1. Indy does, in fact, raise an exception if the OpenSSL DLLs are missing or otherwise are unable to be loaded - EIdOSSLCouldNotLoadSSLLibrary. After that exception is raised, you can call Indy's WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit, and it will tell you whether the DLLs themselves could not be loaded, or whether any of the required exports are missing (ie, because the DLLs are the wrong version for what Indy is expecting). There are other exception classes you can catch for other OpenSSL-related errors, too. Most of them derive from either EIdOpenSSLAPISSLError or EIdOpenSSLAPICryptoError, both of which provide error codes. For example: try FidHttp.Post(FURL, Params, FResponse); FResponseCode := FidHttp.ResponseCode; FResponse.Seek(0, soFromBeginning); except on E: EIdHTTPProtocolException do begin FResponseCode := E.ErrorCode; ErrorEvent(Self, 'HTTP Protocol Exception:' + #$D#$A + AdjustLineBreaks(E.ErrorMessage, tlbsCRLF)); ErrorEvent(Self, 'HTTP Protocol RawHeaders=' + #$D#$A + FidHttp.Request.RawHeaders.Text); end; on E: EIdOSSLCouldNotLoadSSLLibrary do begin FResponseCode := -1; // or whatever you want ErrorEvent(Self, 'SSL/TLS Library Exception: ' + E.Message); ErrorEvent(Self, 'SSL/TLS Didnt Load=' + #$D#$A + WhichFailedToLoad); end; on E: EIdOpenSSLAPISSLError do begin FResponseCode := -1; // or whatever you want ErrorEvent(Self, 'SSL/TLS API Exception: [' + E.ClassName + '] ' + E.Message); ErrorEvent(Self, 'SSL/TLS API ErrorCode=' + IntToStr(E.ErrorCode)); ErrorEvent(Self, 'SSL/TLS API RetCode=' + IntToStr(E.RetCode)); end; on E: EIdOpenSSLAPICryptoError do begin FResponseCode := -1; // or whatever you want ErrorEvent(Self, 'SSL/TLS Crypto Exception: [' + E.ClassName + '] ' + E.Message); ErrorEvent(Self, 'SSL/TLS Crypto ErrorCode=' + IntToStr(E.ErrorCode)); end; on E: Exception do begin FResponseCode := -1; // or whatever you want ErrorEvent(Self, 'Unknown Exception: [' + E.ClassName + '] ' + E.Message); end; end;
-
What exactly is reporting that error? Can you provide the exact and complete error message? And what does your code look like? That is not very helpful. Anything is possible, though you should be getting a different error if that were the case. More likely, those PCs are probably running firewalls that are blocking your connection. The 2 OpenSSL DLLs, libeay32.dll and ssleay32.dll. And make sure they are for OpenSSL 1.0.2u or earlier, as TIdSSLIOHandlerSocketOpenSSL does not support newer versions. You can get those DLLs from https://github.com/IndySockets/OpenSSL-Binaries If you want to use newer DLLs, use this WIP SSLIOHandler instead.
-
This is entirely a matter of personal choice. The compiler doesn't care one way or the other, it ignores whitespace between language tokens. So use whichever format is easier for you to read/write. Personally, I don't use whitespace around '->'.
-
Seriously? Can't you just use a standard For loop? I don't understand the issue.