-
Content Count
2684 -
Joined
-
Last visited
-
Days Won
113
Everything posted by Remy Lebeau
-
I don't know if this is covered in the documentation (I can't find it), but in TMetaFile's source code is the following comment: So, you just need to Draw() the existing TMetaFile onto the TMetafileCanvas before drawing anything else onto the Canvas - hmmm, but you are already doing that! Looking at the docs and the source code, TMetafileCanvas should not be clearing anything in the TMetaFile at all. Also, the ReferenceDC in the TMetaFileCanvas constructor can be 0, in which case the screen HDC will be used instead. Based on the info above, you don't need a clone at all, since modifications made to the Canvas will be applied to the original TMetaFile only when the Canvas is destroyed, eg: OrigMF := // my metafile in memory MFCanvas := TMetafileCanvas.Create(OrigMF, 0); try MFCanvas.Draw(0, 0, OrigMF); // Draw my stuff on MFCanvas finally MFCanvas.Free; end;
-
I don't have 11.2.1 to verify this, but the checkbox should be in the initial dialog when creating a new DLL project. It is not something you can toggle in the Project Options after the project is created.
-
Delphi 11.2 - TTreeview issue not in debug but release mode - Node.HasAsParent(myParentNode) myParentNode
Remy Lebeau replied to rudy999's topic in VCL
Both TTreeNode.Level and TTreeNode.HasAsParent() are recursive, they walk the entire TTreeNode.Parent chain until the root of the tree is reached, or in the case of HasAsParent(), until the specified node is reached. You don't really need that recursiveness in your situation. Paul's solution is more efficient and will suit your situation just fine: if Assigned(Node.Parent) then // or: if Node.Parent <> nil then begin strParentText := Node.Parent.Text; end; Alternatively, to eliminate a redundant function call: var myParentNode: TTreeNode := Node.Parent; if Assigned(myParentNode) then // or: if myParentNode <> nil then begin strParentText := myParentNode.Text; end; -
NetHTTPCLient, NetHTTPRequest and CURL
Remy Lebeau replied to sfrazor's topic in Network, Cloud and Web
Using TNetHTTPRequest, you can do something like this: type TReadOnlyMemoryBufferStream = class(TCustomMemoryStream) public constructor Create(APtr: Pointer; ASize: NativeInt); function Write(const Buffer; Count: Longint): Longint; override; end; constructor TReadOnlyMemoryBufferStream.Create(APtr: Pointer; ASize: NativeInt); begin inherited Create; SetPointer(APtr, ASize); end; function TReadOnlyMemoryBufferStream.Write(const Buffer; Count: Longint): Longint; begin Result := 0; end; ... DataStream := TReadOnlyMemoryBufferStream.Create(databuf, data_len); try PostData := TMultipartFormData.Create; try PostData.AddStream('data', DataStream, 'filename', 'application/octet-stream'); NetHTTPRequest1.Post(url, PostData); finally PostData.Free; end; finally DataStream.Free; end; Using Indy's TIdHTTP instead, you can do this: DataStream := TIdReadOnlyMemoryBufferStream.Create(databuf, data_len); try PostData := TIdMultiPartFormDataStream.Create; try PostData.AddFormField('data', 'application/octet-stream', '', DataStream, 'filename'); IdHTTP1.Post(url, PostData); finally PostData.Free; end; finally DataStream.Free; end; -
The message's coordinates are expressed as screen coordinates, but a control's BoundsRect is expressed as client coordinates within the parent's client area. So, you would need to normalize the two sets of coordinates to the same coordinate space before you can compare them. Also, it turns out that TWinControl already handles CM_DESIGNHITTEST, by forwarding the message to any child control that is at the specified coordinates. By default, TControl returns 0 for the message's result. So, another option may be to have your Frame class subclass its child controls and have them unconditionally return 1 for CM_DESIGNHITTEST, instead of handling the message at the TFrame level. Just a thought. That flag only affects right mouse clicks, by converting them into left mouse clicks. Maybe. I've never tried to make a component out of a Frame before. Have you tried basing the component on TPanel instead?
-
You can add a message handler to the Frame class to handle the CM_DESIGNHITTEST message, setting the message's result to 1 if the mouse is over a child control within the Frame's client area. That will allow the child control to handle the mouse click.
-
TRESTClient Security Error 12175 following Windows Update
Remy Lebeau replied to Andrew Spencer's topic in Network, Cloud and Web
There is always Indy's TIdHTTP component The standard TIdSSLIOHandlerSocketOpenSSL component will support up to TLS 1.2 with OpenSSL 1.0.2, and this WIP SSLIOHandler will handle TLS 1.3 with OpenSSL 1.1+. -
TidHTTP under FMX for android does not work
Remy Lebeau replied to JohnLM's topic in Network, Cloud and Web
I don't know. Worse case, you could simply not install Indy into the IDE at all, and just have your project refer to Indy's source files directly. -
Rtti Is it possible One Property Attribute
Remy Lebeau replied to 3ddark's topic in Algorithms, Data Structures and Class Design
In this code: var LDay: TSysDay; LFieldName: string; LFieldName := GetAttribute(LDay.Day); You are passing in the value that is returned by reading the Day property. You are not passing in the property itself. You can't pass around properties, that is simply not allowed. You will have to pass in the property's name as a string and use RTTI to access it, eg: function GetFieldAttribute(Obj: TObject; const PropName: string): string; var LC: TRttiContext; LT: TRttiType; LP: TRttiProperty; LA: TCustomAttribute; begin Result := ''; LC := TRttiContext.Create; try LT := LC.GetType(Obj.ClassType); LP := LT.GetProperty(PropName); if LP <> nil then begin for LA in LP.GetAttributes() do begin if LA is TFieldNameAttribute then Exit(TFieldNameAttribute(LA).Name); end; end; end; finally LC.Free end; end; var LDay: TSysDay; LFieldName: string; LFieldName := GetFieldAttribute(LDay, 'Day'); LFieldName := GetFieldAttribute(LDay, 'A'); LFieldName := GetFieldAttribute(LDay, 'B'); LFieldName := GetFieldAttribute(LDay, 'C'); -
TidHTTP under FMX for android does not work
Remy Lebeau replied to JohnLM's topic in Network, Cloud and Web
https://github.com/IndySockets/Indy/wiki/Updating-Indy -
TidHTTP under FMX for android does not work
Remy Lebeau replied to JohnLM's topic in Network, Cloud and Web
Even on Windows, it is a good idea to stay up-to-date. -
Based on the QP ticket, looks like this could work: {$IF DEFINED(IOS) AND NOT DEFINED(IOSSIMULATOR)}
-
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.
-
TidHTTP under FMX for android does not work
Remy Lebeau replied to JohnLM's topic in Network, Cloud and Web
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. -
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.
-
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
-
Building OpenSSL dylibs for iOS simulator
-
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.
-
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;
-
TRegistry.MoveKey does not move MultiSZ values correctly?
Remy Lebeau replied to Nigel Thomas's topic in RTL and Delphi Object Pascal
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. -
Weird code in THttpConnection.ProcessWellKnownDir
Remy Lebeau replied to Kyle_Katarn31's topic in ICS - Internet Component Suite
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. -
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.
-
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;
-
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.