-
Content Count
3002 -
Joined
-
Last visited
-
Days Won
135
Posts posted by Remy Lebeau
-
-
indy + LDAP
in Indy
I've never worked with (or even looked at) Indy's LDAP classes before. But just looking at them right now, it appears that they are meant just for parsing/producing LDAP messages, not for receiving/transmitting them over TCP/UDP. So, you would likely need to handle the actual transmission yourself via TIdTCPClient or TIdUDPClient. For example, via TCP, connect a TIdTCPClient to an LDAP server, using an SSLIOHandler to handle SSL/TLS if needed, and then use TIdLDAPV3Encoder to prepare an LDAP message and save it to a TIdTCPStream to transmit it, and then use TIdLDAPV3Decoder with TIdTCPStream to receive messages. I have no idea if that actually works, but worth a try.
-
1
-
-
8 hours ago, Manlio Laschena said:At the moment I can only code under release mode, but I must find a solution.
A solution could be to turn the entry phase into a dll and start from scratch the real application hoping withou the invalid compiler directive.
I am confused. Never seen an exception only on debug mode.
You still haven't shown the actual 'invalid compiler directive' error, or what code the error is referring to. That error is a compile-time error. But you said your code compiles and runs, it was just experiencing a runtime error instead, due to accessing an array out of bounds. So, what is the REAL problem here?
-
5 hours ago, David Heffernan said:I came across this code in the RTL:
...
I'm wanting to call RegQueryInfoKey and wondering if I also need to mimic this far east if statement.
No. It is a remnant from Delphi's pre-Unicode days (going all the way back to Delphi 5, if not earlier). Even then, I question why it was ever added in the first place, since the API always returned the correct sizes to begin with. So, this will cause the caller to unnecessarily waste memory (if they enumerate subkey/value names afterwards) and should be taken out.
QuoteIs it possible that this code is bogus?
Yes. The increment is not necessary. I have filed a bug report:
RSP-41787: TRegistry.GetKeyInfo() doubles size of MaxSubKeyLen and MaxValueLen
-
4
-
-
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.
-
4 hours ago, Scalmax said:One thing that stuck me the most: GStack variable. If you do not create something that does TIdStack.IncUsage you will quickly find nil-related exceptions.
I personally stuck with it by manually creating TIdSocketHandle objects and calling AllocateSocket on them. I know that TIdComponent.InitComponent does the job, but, IdBuffer.Create also does it.
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.
QuoteMy first thought was: remove GStack and make TIdStack.Instance(), probably with lock free pattern https://stackoverflow.com/a/24657705 and without slow critical section. It would be code-breaking change.
I'll consider it for a future release when more design-breaking changes are being worked on.
QuoteAnyway, it is time to stop complain, create github account, and start asking for pull requests.
-
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.
-
1
-
-
21 hours ago, gwideman said:On Quality Central ...
Technically, the correct name is Quality Portal. Quality Central was its predecessor.
-
File Search
in VCL
52 minutes ago, robertjohns said:This line does not work in Tokyo
MyFindFilePattern('d:\MyZip', ['*.*', '*.txt', '*.zip'], LMyResult);
ListBox1 .Items.AddStrings(LMyResult);There is no overloaded version of 'AddStrings' that can be called with these arguments
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>;
-
9 hours ago, NBilov said:Archive/Experimental/openssl-0.9.8o-i386-win32-fips-1.2.zip
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.
-
1
-
-
File Search
in VCL
59 minutes ago, programmerdelphi2k said:LContinue := FindFirst(AFolderRoot + '\' + APatternToSearch, faAnyFile, LSearchRecord) = 0;
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;
Quoteif (LSearchRecord.Name <= '..') then
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
-
3
-
-
55 minutes ago, NBilov said:IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1;
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];
55 minutes ago, NBilov said:if EmPort>0 then
IdSMTP1.Port := EmPort
elseIf 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.
55 minutes ago, NBilov said:IdSMTP1.Port := 465;
IdSMTP1.UseTLS := utUseExplicitTLS;As mentioned earlier, this is wrong. You need to use utUseImplicitTLS on port 465. Use utUseExplicitTLS on port 587 instead.
-
6 hours ago, AndreL said: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).
-
On 5/19/2023 at 1:56 PM, alank2 said:So as a test I tried to set a TEdit to a UTF-8 sequence and it ended up as a series of characters and not the smile face I was testing.
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.
QuoteIs there a way to make it recognizing a narrow string assignment as UTF-8 - some sort of code page setting in the application maybe? or will it not do that?
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(); }
-
1 minute ago, programmerdelphi2k said:for sure, but in sometime it do it! capacity > n = reallocate it please! at end, a List will do it, expand the items like a array! or a array-of-pointers!
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.
-
3 hours ago, shineworld said:Since I have little time at home to develop I, unhappily, thought of taking advantage of the hour and a half of free time for lunch break I have at the office, to continue development on my personal notebook BUT attached to the company WIFI network to access the sources, do push and everything else.
Have you considered setting up a personal VPN on your home network, and then connect to it from your work office?
-
1
-
-
12 hours ago, programmerdelphi2k said:UNnecessary usage:
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.
-
1 hour ago, Ian Branch said:I can't see a way to get the number of elements in the TArray.
Use the Length() function.
QuoteI thought "for var i := 0 to TArray(Instances).Count do Memo1.Lines.Add(Instances);" would be a monty, but no.
How please?
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);
QuoteSolved. I added the count to the function.
You don't need that. Dynamic arrays know their own length.
-
2
-
-
48 minutes ago, Ian Branch said: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?
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.
-
13 hours ago, PeaShooter_OMO said:I am no C++ expert but shouldn't the asterisks of the parameters be immediately following the types and not precede the parameter names?
Whitespace between tokens doesn't matter in C/C++. Thus, "Type* VarName" and "Type *VarName" and "Type * VarName" all mean the same thing.
-
33 minutes ago, Brandon Staggs said:Is there a way to have the IDE automatically convert line endings on paste?
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.
-
22 hours ago, gioma said:I had seen the first example and in fact I would like to try to derive the COleDataSource class, I just need to understand in which Delphi unit it is present!
6 hours ago, gioma said:In Delphi not Exist class COleDataSource ( Or I haven't found it yet )
COleDataSource has the virtual function OnRenderData that I might need.
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).
-
1
-
-
8 hours ago, gioma said:My specific case is as follows:
I have two applications, A and B, connected by a socket connection.
Application A intercepts the modification of its clipboard and sends the event to application B.
Here we have two cases:
1 if it is a text, it copies it directly to the clipboard
2 if it is a file, it copies the list to the clipboard.
Up to point 1 there are, while I have difficulty understanding how to pass the list of files to PC B (or rather I can do this phase) and make sure that when I press "paste" (here is the real problem which I'm racking my brain over) the file list transfer begins and the system waits for the files to be transferred before completing the paste command.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.
QuoteI can't find half an example of this on the net
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
QuoteI can't believe no one has ever done this before, maybe even in C, C++.
I'm sure they have, but it is very specialized work, so you are not likely to see it talked about publicly very much.
-
1
-
-
22 hours ago, programmerdelphi2k said:I'm not an expert on Windows messages, but you would have to intercept the "WM_DRAWCLIPBOARD" message, to receive notification that MSExplorer intends to copy some object (file/folder/etc...).
But first your app must be registered with a "Clipboard Viewer" ( SetClipboardViewer() ), and when you finish the app, do the "Un-Register" ( ChangeClipboardChain() )
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.
22 hours ago, gioma said:Thanks for the reply.
I already do this, in fact if I copy paste a text it works perfectly.
The problem instead I have with the files because they are not yet available on the file system because they come from the other PC.
I send the list of files but I would like it to start the transfer only when "paste" is pressed and then the "paste window" waits for the files to be completely transferred and therefore available.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.
-
2
-
LinkedIn job offer: Remote Senior Software Engineer with Evisions
in Job Opportunities / Coder for Hire
Posted · Edited by Remy Lebeau
I have a recruiter messaging me on LinkedIn offering a position for a Sr Software Engineer with Embarcadero RAD Studio experience:
Anyone interested?