-
Content Count
2684 -
Joined
-
Last visited
-
Days Won
113
Everything posted by Remy Lebeau
-
There is code for exactly that in David's answer on the StackOverflow post you linked to. If you are running your app (or the IDE) with elevated rights, then you also need to call ChangeWindowMessageFilter/Ex() to allow lesser-privileged processes, like File Explorer, to send WM_DROPFILES messages to your app.
-
@GuilhermeJMO https://en.delphipraxis.net/topic/10835-fyi-several-embarcadero-services-are-currently-unavailable/
-
Preventing and allowing things to happen in a Thread???
Remy Lebeau replied to Ian Branch's topic in General Help
Anything is possible, yes. You are going to have to be more specific about your particular situation. It sounds like you just want to disable your UI while the thread is running. But then why use a thread at all? -
Delphi 10.4 install gives gateway time-out on Platform selection
Remy Lebeau replied to ArcoW's topic in Delphi IDE and APIs
-
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
It does not affect an already-installed IDE, unless you want to add/remove installed features. But, it does affect the online installer (not the ISO installer), which uses GetIt behind the scenes to download features. And the CE edition uses only the online installer, there is no ISO. -
Collect JSON ajax data from a local zigbee web server
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
Probably, yes. Indy's documentation hasn't been updated in a VERY LONG time. Mainly because the system used to generate the documentation at the time no longer exists, so all of that content would have to be migrated to a completely new system, and noone has had the time to do that migration. On the other hand, Indy's public interface hasn't changed TOO much in a very long time, either. Certainly it's had plenty of new features/interfaces added over the years, but they haven't been added to the documentation. Yes, in fact it is REQUIRED to do so, because TIdHTTP derives from Delphi's TObject class, which MUST be constructed only in heap memory. On the C++ side, you can (and should) use a smart pointer class like std::unique_ptr to manage the 'new'/'delete' calls for you. But you CAN use them manually if you choose to. You CAN, but you have to very VERY CAREFUL with it. If you construct the TXMLDocument object with a non-null Owner, you can safely use 'delete' to destroy the object. But, if you construct the TXMLDocument object with a null Owner, that will enable the object's reference counting semantics, so DO NOT use 'delete' on it! You MUST use its AddRef()/Release() methods instead. The smart pointer _di_IXMLDocument class will handle that for you. They are still having server problems with other services, but DocWiki is working again, yes. I have never heard of interface_cast before. That is a new one for me. A better option is to use the standalone NewXMLDocument(), LoadXMLDocument(), or LoadXMLData() function instead of 'new'ing the TXMLDocument class directly. They return a properly prepared ownerless/ref-counted _di_IXMLDocument, eg: _di_IXMLDocument xml = NewXMLDocument();- 10 replies
-
- c++ builder 11
- json
-
(and 4 more)
Tagged with:
-
It has the public Receive() method inherited from TIdStack, but that takes only a socket handle and a TIdBytes as parameters. I assume you want access to the flags parameter of recv()? For that, you can use the protected TIdStackBSDBase.WSRecv() method. type TIdStackBSDBaseAccess = class(TIdStackBSDBase) end; TIdStackBSDBaseAccess(GBSDStack).WSRecv(AContext.Binding.Handle, buffer, length, MSG_PEEK);
-
https://github.com/IndySockets/Indy/issues/410
-
Indy's TIdSocketHandle class does not have a SetSockOpt() overload for non-integer inputs, but its TIdStackBSDBase class does (for BSD-based socket stacks, like Linux and Windows): uses ..., IdStackBSDBase; GBSDStack.SetSocketOption(AContext.Binding.Handle, Id_SOL_SOCKET, Id_SO_RCVTIMEO, mTime, SizeOf(TTimeVal)); I probably need to update Indy to expose this overload in TIdSocketHandle and TIdStack for easier use.
-
That's good to hear (not that you are tired, but that you got it working). FYI, if the mapped host/port is wrong and the connection can't be established, the TIdMappedPortTCP's OnException event will be triggered. On a side note: the way you are using TThread.Queue() is a potential crash waiting to happen. TThread.Queue() is asynchronous, and your anonymous procedures are capturing the local TIdContext variable, which points to an object that may or may not be valid anymore if the client disconnects before the Queue request is processed by the main thread. Instead, you should first save the desired values locally and then capture those variables instead, eg: procedure TMyClass.OnServerConnect(AContext: TIdContext); var lPeerIP: string; lPort: TIdPort; begin lPeerIP := AContext.Binding.PeerIP; lPort := AContext.Binding.Port; TThread.Queue(nil, procedure begin WriteLn('OnConnect from ' + lPeerIP + ' to ' + lPort.ToString); end ); end; procedure TMyClass.OnServerExecute(AContext: TIdContext); var lPeerIP: string; lPort: TIdPort; begin lPeerIP := AContext.Binding.PeerIP; lPort := AContext.Binding.Port; TThread.Queue(nil, procedure begin WriteLn('OnExecute from ' + lPeerIP + ' to ' + lPort.ToString); end ); end;
-
Multipart/form-data vs x-www-form-urlencoded (Indy HTTP server)
Remy Lebeau replied to Joe Sansalone's topic in Network, Cloud and Web
That will only work if the email is entirely textual, no binary attachments. And also, only if the sender actually sends the text data as UTF-8, which is not a guarantee. Try this instead: var MsgEnd: Boolean; Decoder, NewDecoder: TIdMessageDecoder; Line, Boundary, BoundaryStart, BoundaryEnd: String; Dest: TStream; begin ... Boundary := ExtractHeaderSubItem(ARequestInfo.ContentType, 'boundary', QuoteHTTP); BoundaryStart := '--' + Boundary; BoundaryEnd := BoundaryStart + '--'; repeat Line := ReadLnFromStream(ARequestInfo.PostStream, -1, True); if Line = BoundaryEnd then Exit; until Line = BoundaryStart; Decoder := TIdMessageDecoderMIME.Create(nil); try MsgEnd := False; repeat TIdMessageDecoderMIME(Decoder).MIMEBoundary := Boundary; Decoder.SourceStream := ARequestInfo.PostStream; Decoder.FreeSourceStream := False; Decoder.ReadHeader; case Decoder.PartType of mcptText, mcptAttachment: begin Dest := TMemoryStream.Create; try NewDecoder := Decoder.ReadBody(Dest, MsgEnd); try // use Dest as needed... finally Decoder.Free; Decoder := NewDecoder; end; finally Dest.Free; end; end; mcptIgnore: begin FreeAndNil(Decoder); Decoder := TIdMessageDecoderMIME.Create(nil); end; mcptEOF: begin MsgEnd := True; end; end; until (Decoder = nil) or MsgEnd; finally Decoder.Free; end; end; What you SHOULD be doing is actually parsing the MIME data according to the official MIME RFC specifications. -
[Question/Feature] SSL/TLS fallback using magic bytes
Remy Lebeau replied to FearDC's topic in ICS - Internet Component Suite
That is the basic jist of it, yes. Though, detecting a viable handshake is slightly more complex than just testing the first 2 bytes. I did write some code for this a long time ago, I'll have to look for it. -
Multipart/form-data vs x-www-form-urlencoded (Indy HTTP server)
Remy Lebeau replied to Joe Sansalone's topic in Network, Cloud and Web
That depends on how you are parsing it. TIdHTTPServer does not parse 'multipart/form-data' for you (that is on the todo list), so you have to parse the raw data yourself. What does your code look like for that? You can use Indy's TIdMessageDecoderMIME class to help you parse 'multipart/form-data' from the ARequestInfo.PostStream data. -
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
Yup 😢 -
IOHandler.Write() problems with SocketError # 10053 exception
Remy Lebeau replied to SneakyPeaky99's topic in Indy
First, that is a lot of code to go through, and blue text on black a background is very difficult to read. Second, there is no mention of this failing AddStr() method being called anywhere in those screenshots. -
Collect JSON ajax data from a local zigbee web server
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
There are countless examples of that online all over the place. Start with the TThread class, overriding its virtual Execute() method, and use its Synchronize() or Queue() method when you need to communicate with the main UI thread. Seems like you already know how to do that. So, what's stopping you from using that? That would be a perfectly valid approach. And? It still works. All that means is that code which touches VCL controls needs to run in the context of the main UI thread. There are many different way to do that. One way is TThread::Synchronize()/TThread::Queue(). Another way is using window messages (for example, wParam and lParam can hold pointers to data). Another way is using a thread-safe container and having the main thread poll it periodically, such as in a timer. Or any combination of these approaches (for example, putting data in a thread-safe container, then posting a message to poll the container). Are you planning on writing portable code in C++Builder only, or do you need to support other C++ compilers? If you stick with just C++Builder then there is no reason not to use what it provides, like TThread (which does run on all supported platforms). But, if you want to support other compilers, then you have to stick with only the standard C++ library and 3rd party cross-platform libraries. Those headers were introduced in C++11. Are you using one of the clang-enhanced C++ compilers that support C++11? The "classic" Borland compiler only supports a small subset of C++11 language features, but no C++ standard library features. So make sure you are using a compiler that supports what you want.- 10 replies
-
- c++ builder 11
- json
-
(and 4 more)
Tagged with:
-
TIdHTTP->Get UnicodeString trouble
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
This issue has nothing to do with Unicode. You simply have a logic bug in your code. You are already doing it. You just have a mistake in your format string. BTW, you can get rid of the char[] array and use the (s)printf() method of AnsiString/UnicodeString instead, eg: AnsiString url; url.printf("http://%s/ajax.xml", ethTcp_ip); String us = IdHTTP1->Get(url); out << "Response" << endl << AnsiString(us).c_str() << endl; Memo1->Lines->Text = us; Another option, albeit a little heavier-handed, is to use Indy's TIdURI class, eg: #include <IdURI.hpp> #include <memory> std::unique_ptr<TIdURI> idUri(new TIdURI); // or: auto idUri = std::make_unique<TIdURI>(); idUri->Protocol = _D("http"); idUri->Host = ethTcp_ip; idUri->Path = _D("/"); idUri->Document = _D("ajax.xml"); String url = idUri->URI; Look VERY CAREFULLY at the two URLs you are passing to TIdHTTP::Get(). What do you see that is different between them? In the bad example, there is an extra erroneous '/' character in front of the filename: good: "http://192.168.1.123/ajax.xml" bad: "http://192.168.1.123//ajax.xml" ^ Fix your format string to remove the erroneous '/' character. https://www.indyproject.org/2021/02/10/links-to-old-indy-website-pages-are-currently-broken/ https://blogs.embarcadero.com/we-are-experiencing-a-hardware-outage/ https://ideasawakened.com/post/embarcadero-network-issues Yes, but you are not experiencing a Unicode problem, since your URL contains only ASCII characters. https://github.com/IndySockets/Indy/wiki/Documentation -
[Question/Feature] SSL/TLS fallback using magic bytes
Remy Lebeau replied to FearDC's topic in ICS - Internet Component Suite
If you want to do this TLS handshake detection in TIdMappedPortTCP, the best place to handle this is in the OnBeforeConnect event, which is fired immediately after a new client is accepted by TIdMappedPortTCP and before its associated OutboundClient is connected to the next server. The OnExecute event is fired after the OutboundClient is connected to the next server and the accepted client has sent data which has been read into its InputBuffer. By then, its too late for the TLS detection since the connection is already receiving application data after the TLS session is established. No, you do not. You can't "undo" a socket read. Nor will doing so help you with detecting the TLS handshake, anyway. You have to peek the bytes directly from the socket itself, not from the InputBuffer that is on top of the socket. -
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
-
Why are access violations not shown in popups with EurekaLog ?
Remy Lebeau replied to dormky's topic in General Help
Then there IS a try..except involved, but its inside the VCL framework wrapping the call to the event handler (and most other events, for that matter). That is why, for example, if you raise an exception inside an OnClick event and don't catch it yourself, you will still see a default popup message appear. There is a default try..except inside the framework for handling UI errors. -
I was just thinking the same thing! So many QC tickets were lost, and not linked/duplicated into QP tickets.
-
Delphi 12 requires missing DLL on Server 2008
Remy Lebeau replied to Tsagoth's topic in RTL and Delphi Object Pascal
Delphi 12 does not support Server 2008 or 2008 R2 as a deployment platform. The minimum supported Server version is 2019. Because Window 7 (SP1+) is a supported deployment platform. See: https://docwiki.embarcadero.com/RADStudio/Athens/en/Supported_Target_Platforms -
Access violation when creating thread
Remy Lebeau replied to ErikT's topic in Algorithms, Data Structures and Class Design
On a side note, you should not be passing an Owner to your thread. You are creating the TPing object inside your worker thread, so don't assign a component from the main thread as its Owner. Set the Owner to nil instead, and then Free() the object when you are done using it. -
Unfortunately, that does not work. The LastError property is set only if THandleObject.Wait() fails with an OS error. If a creation or acquisition/release fails, an exception is raised instead. If a creation succeeds with a non-zero error code, the LastError property is not set to reflect that. I have now opened a ticket for that feature: RSP-44312: THandleObject.LastError should be set during object creation
-
Collect JSON ajax data from a local zigbee web server
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
@dan27125 I commented earlier on your same question on StackOverflow: https://stackoverflow.com/questions/77868076/collect-json-ajax-data-from-a-local-zigbee-web-server Now that I see this post, the StackOverflow post appears to be a direct copy/paste of this post? That would explain why it mentions "Attached is ajax.xml, debug.html" without actually providing those files. It is generally frowned upon by internet etiquette to post the same question in multiple forums at the same time. It shows a lack of patience on your part, and a disrespect for people who might take time out of their day to answer. That being said, now that I see the relevant data files are on this post and not the StackOverflow post, I can fill in some gaps from my StackOverflow comment. The HTML is running a client-side JavaScript that uses a timer to invoke the browser's built-in AJAX client at regular intervals to send an HTTP request to download the XML file, parse the XML, and inject the results into the HTML elements using the browser's DOM. There is no streaming involved at all, each data update is an independent HTTP request. In C++Builder, you would simply do the same thing. Run a timer that uses any HTTP client you want (TIdHTTP, T(Net)HTTPClient, libcurl, etc) to download the XML from the appropriate URL, and then you can use any XML library, such as (T|I)XMLDocument, to parse the XML and do what you need with the data values.- 10 replies
-
- c++ builder 11
- json
-
(and 4 more)
Tagged with: