-
Content Count
2982 -
Joined
-
Last visited
-
Days Won
134
Everything posted by Remy Lebeau
-
There are numerous examples and tutorials online for how to work with webcams using the Win32 API. That information is accessible via webcam APIs. You don't need VCL or FMX for that. Or, you could simply take the screenshot using an in-memory GDI bitmap, and then copy the raw pixel data from that bitmap into an FMX TBitmap as needed. Look at CreateCompatibleDC(), CreateCompatibleBitmap(), GetObject(), and TBitmap.Canvas.MapBitmap()/UnmapBitmap().
-
The fact that you are even getting an HTTP 403 error at all means the SSL portion is working fine, since HTTPS is encrypted and you are able to see a decrypted response. So the problem has to be related to something else. Maybe you are not accessing the correct URL. Maybe you are not authenticated properly with the server. Maybe you are missing a client-side certificate. We don't know, since we don't know your setup or what the server is expecting. One thing you could try is capture the HTTP request the browser is sending (using your browser's built-in debugger, or an external HTTPS debug proxy like Fiddler), and then capture the HTTP request that TIdHTTP is sending (assign one of Indy's TIdLog... component to the TIdHTTP.Intercept property), and compare them for any differences. If you don't see anything apparent at the HTTP layer (cookies, login credentials, etc), then the issue could be at the SSL layer (ie, certificates, etc) You likely need to talk to the server admins about this, ask them what the server requires to get permission to access it. Have them look at the HTTPS requests on their end to see why the server is rejecting them. You should contact AToZed to double-check, but I do not believe that paid support is still provided, at least for Indy. Probably only for IntraWeb, if at all.
-
Record Circular References
Remy Lebeau replied to Bernard's topic in Algorithms, Data Structures and Class Design
Yeah, THAT is not going to happen anytime soon, either. -
TThread always raises OS Errror
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
It wasn't resetting the last-error at all. That was, and always has been, the sole job of the OS to handle. Whatever value was assigned to the last-error going into the RTL's ThreadProc(), that is the value that was still set when going into TThread.Execute(). And since the issue is reproducible in FPC and Visual Studio then it has nothing to do with Delphi's RTL at all. Something has clearly changed internal to the OS itself, and you are not going to figure out what that is unless you trace into the OS's internal source code for yourself. That is because CreateThread() in Win9x does not allow the lpThreadId parameter to be NULL. If it is, CreateThread() fails with ERROR_INVALID_PARAMETER (87). That behavior was changed in NT4 onward to allow the lpThreadId parameter to be NULL, as the thread's ID is not typically needed by most users. That restriction used to be documented: The restriction is no longer documented since Win9x is no longer supported: -
Record Circular References
Remy Lebeau replied to Bernard's topic in Algorithms, Data Structures and Class Design
Not going to happen. You can't forward-declare records. -
That doesn't sound right. All shipped BPL files should have the IDE's package version in their filenames. Their corresponding BPI/DCP file may not, but Indy does not make use of {$LIBSUFFIX} yet, so even its DCP files should have the package version in their filenames. Unless Embarcadero has created their own unversioned packages. I haven't installed a new IDE in several years, so I wouldn't know how the shipped Indy is compiled anymore.
-
TThread always raises OS Errror
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
Um, maybe I'm missing something, but that test is not passing a NULL pointer for the threadid. But, it doesn't matter anyway, because that test code belongs to WINE's emulated implementation of the Win32 API, it does not belong to the actual Win32 API on Windows. -
TThread always raises OS Errror
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
But, if you decide to use GetLastError() the way it is MEANT to be used, you would never see this happen AT ALL, because you would NOT be calling GetLastError() until after an API function actually overwrites the calling thread's last-error with a meaningful value first. That user's mistake (using a thread procedure of the wrong signature) has no bearing on how GetLastError() works. If anything, all that mistake would do is cause an extra value to be pushed on the call stack before entry to the thread procedure (LPVOID lpParameter), and that value would not be popped off the call stack properly after exiting the procedure. But inside the procedure, there is no effect. I don't think it is anyone's bug, except maybe yours if you choose to misuse GetLastError() in the first place. That is absolutely not needed when using GetLastError() the proper way. GetLastError() simply does not return a meaningful value when GetOverlappedResult() returns TRUE, only when it returns FALSE. As is the case with most API functions. Most API functions DO NOT overwrite the calling thread's last-error on success, only on failure, unless explicitly documented otherwise (for example, CreateEvent(), etc). Or, if they do overwrite the last-error on success, it could just be as a side effect of internal operations that were handled as needed, and you are supposed to ignore the last-error since the API returned success to you. Socket Overlapped I/O operations use the WSAOVERLAPPED struct and WSAGetOverlappedResult() function. Which just HAPPEN to currently be binary compatible with OVERLAPPED and GetOverlappedResult() as an implementation detail. Don't rely on that. Use the proper API. I do not have 10.3.3, but I cannot reproduce or confirm it in other versions. There is no difference between an anonymous thread and any other TThread. TThread.CreateAnonymousThread() merely creates a TAnonymousThread object, a TThread descendant whose Execute() simply calls the provided user procedure, no frills, no other logic: type TAnonymousThread = class(TThread) private FProc: TProc; protected procedure Execute; override; public constructor Create(const AProc: TProc); end; constructor TAnonymousThread.Create(const AProc: TProc); begin inherited Create(True); FreeOnTerminate := True; FProc := AProc; end; procedure TAnonymousThread.Execute; begin FProc(); end; class function TThread.CreateAnonymousThread(const ThreadProc: TProc): TThread; begin Result := TAnonymousThread.Create(ThreadProc); end; So, any issues with GetLastError() used in TThread.CreateAnonymousThread() would also have to affect all TThread objects in general. Which would imply a problem is present in Classes.ThreadProc() itself before TThread.Execute() is called. And that is not likely given how little code is present before that call. On Windows, there are only 2 lines of code executed before Execute() is called (unless something has changed in recent RTL versions): the assignment of TThread.FCurrentThread (a threadvar), and the opening of a try..finally block. Exception handling blocks do not affect a thread's last-error, but TLS storage can. But it is unlikely that the assignment of FCurrentThread would fail, unless the RTL were not initialized properly at process startup. -
TThread always raises OS Errror
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
Why does it matter? In your example, the error code would have to be getting set before your thread procedure is even called, in which case it would be internal to the OS when preparing the thread, or even internal to the RTL before calling TAnonymousThread.Execute(), but either way it is not in your own code, so who cares about WHY it happens? You are not supposed to be using that error to begin with, since it has no meaningful value in the context you are using it in. Its value is indeterminate in that context. In fact, I just did a quick test of my own, and the value of GetLastError() upon entering the thread procedure WAS NOT 87, it was 0. So the result you are observing has to be environmental in nature. -
There is no "generic" Indy. The IDE ships with Indy 10 pre-installed. You can't have multiple versions of Indy 10 installed in the IDE at the time same. But you can have multiple copies in different folders on your HDD, and then tweak the IDE search paths when needed to refer to one copy or the other at any given time. And possibly create multiple Registry configs for the IDE to use at different times (see the -r command-line parameter). But, if you didn't backup the original Indy before updating it, then the only way to restore it is to reinstall the whole IDE fresh. Otherwise, you could just recompile the 3rd party library so it uses the updated Indy 10 that you installed, if you have the source code for that library.
-
TThread always raises OS Errror
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
(Get|Set)LastError() use thread-local storage internally. The last-error code is stored inside the OS thread object itself. It doesn't matter how you create the thread, calling SetLastError() in one thread context and then calling GetLastError() in another thread context will NEVER work. The last-error simply can't cross thread boundaries. This is documented behavior: https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setlasterror https://docs.microsoft.com/en-us/windows/win32/debug/last-error-code -
Hard to answer without knowing which articles you are actually reading. But most likely, the way to sort a grid in FMX has likely not changed much, if at all.
-
Filling and submitting a form programmatically with ICS
Remy Lebeau replied to Carlos Tré's topic in ICS - Internet Component Suite
The same way you encode any other <input> field - as a "name=value" pair, where the "name" and "value" are properly url-encoded. The "type" of the <input> field doesn't matter. Yes. The <form> in question specifies "method=post", so you would need to send the encoded parameters in a POST body, not in the query component of a URL, eg: POST /envia_arq2.htm HTTP/1.1 Host: www.trivial.com.br Content-Type: application/x-www-form-urlencoded Content-Length: 36 Connection: close senha=violeta&nome=tre&enviar=Enviar However that translates to TSslHttpCli/TSslHttpRest (I don't use ICS). -
In my Service I want to to receive notification when the system is suspended or resumed
Remy Lebeau replied to AllanF's topic in Windows API
You can, but not the way you are thinking. If you call RegisterServiceCtrlHandler/Ex() manually, then you can't use any pre-existing service framework (TService, DDService, SvCom, etc), as they make their own call to RegisterServiceCtrlHandler/Ex() for you. You would have to make ALL of the SCM-related API calls manually, starting with StartServiceCtrlDispatcher() and implementing ServiceMain() to call RegisterServiceCtrlHandler/Ex(). Read MSDN for more details: Service Program Tasks I'm not sure. I've seen conflicting info on that. Some people say yes, some say no. I haven't tried it myself to check. How can I Execute a Function from service program when Windows Fast Startup How to detect wake up from sleep mode in windows service? Detect resume from hibernate in a windows service Detecting Hibernation / Standby and resume in a Service Chapter 6: OnNow/ACPI Support That code will not work: - a service's Handler/Ex() cannot call RegisterServiceCtrlHandler/Ex(), because it has already been called before the OnStart event is called. - WM_POWERBROADCAST is a window message, not a service notification. A service would need to handle SERVICE_CONTROL_POWEREVENT notifications instead. -
Filling and submitting a form programmatically with ICS
Remy Lebeau replied to Carlos Tré's topic in ICS - Internet Component Suite
Also, it is common for webservers to use cookies with webforms, so you should first GET the webpage that contains the webform so that you download any initial cookies, then parse the webform fields (ie, in case any contain randomly generated field values), then submit the webform as directed. Also, make sure you submit ALL <input> fields that have a non-empty value - including the submit button itself! Sometimes webforms have multiple buttons, in which case the webserver needs to know which one is performing the submission. -
See Raymond Chen's blog for why: Modality, part 3: The WM_QUIT message and Why is there a special PostQuitMessage function?
-
It is not. That is what you will have to do.
-
Extend the system PATH
Remy Lebeau replied to miab's topic in Algorithms, Data Structures and Class Design
SetEnvironmentVariable() updates the environment of the calling process only, changes are not persisted when the process exits. You don't need to update the PATH to handle that. Use SetDllDirectory() or AddDllDirectory() instead. -
TIdSSLIOHandlerSocketOpenSSL and TLS 1.3 ?
Remy Lebeau replied to Lars Fosdal's topic in Network, Cloud and Web
https://en.delphipraxis.net/topic/2769-indy-openssl-111-tls-13/ At this time, it has not been merged yet, though. Still pending review... -
I don't use ICS, but that would imply that THttpCli uses a non-blocking socket that relies on window messages to progress its state. In which case, yes, the THttpCli would need to be created in the same thread context that the message window is created in, ie created in the thread's Execute method or Run event, not in its constructor. Another argument in favor of using Indy's socket components, like TIdHTTP, is that they use only blocking sockets and no window messages, so they can be created and used across thread boundaries.
-
That kind of "check for empty buffer" logic makes sense in a UI timer, to prevent blockage of the UI. It makes less sense to use that kind of logic in a worker thread, as demonstrated in that same post.
-
RTTI info for TBytes using runtime packages
Remy Lebeau replied to Wagner Landgraf's topic in RTL and Delphi Object Pascal
Yes, and you need to make sure that is enabled for not just the EXE but also for your own Packages, too. Yes, but only if your packages actually use functionality from the RTL package so its linkage is not optimized out. It would be really useful if you could post an actual code example that is not working for you. -
RTTI info for TBytes using runtime packages
Remy Lebeau replied to Wagner Landgraf's topic in RTL and Delphi Object Pascal
It is not enough to just enable "runtime packages" in the main application. Package1 and Package2 must also be compiled with "runtime packages" enabled, and the "common unit" must be in a 3rd runtime package that they both require. Yes, the RTL package is sufficient, but you have to make sure Package1 and Package2 are linking to it dynamically (ie, you need to ship "rtl240.bpl" alongside your own BPLs) and not statically, otherwise they end up using separate copies of the RTL. -
I was thinking the same thing. Yes, TIdThread is part of Indy. So, why wouldn't you want to use Indy's TIdHTTP component if you are using Indy for other things?
-
The point was, if you use the plain vanilla TCP client/server components, then you have to design your own protocol on top of them, and implement both sides of that protocol. If you use a standard protocol, like FTP or HTTP, then you don't need to implement both sides (unless you really need to customize both sides), you can use pre-existing implementations. And HTTP has benefits over FTP. "check buffer is empty" is not a good way to approach this task in the first place.