-
Content Count
3000 -
Joined
-
Last visited
-
Days Won
135
Everything posted by Remy Lebeau
-
TBitmap to TBytes for ESC/POS Thermal Printer
Remy Lebeau replied to at3s's topic in RTL and Delphi Object Pascal
It really depends on the format that the ESC/POS is expecting. It might be as simply as using TBitmap.SaveToStream() to save to a TBytesStream, and then using the stream's Bytes and Size properties. Or it may be more complex, like having to extract the individual pixels, like that other code is doing. You are going to have to provide more details about your particular situation. -
Just on a side note, I probably would have used FormatDateTime() instead of DecodeDate() for for this, eg: uses ..., System.SysUtils; procedure TfAccounts.Button1Click(Sender: TObject); begin Label1.Caption := FormatDateTime('"Today is Day "d" of Month "m" of Year "yyyy', Now); end;
-
VCL's TMediaPlayer has an OnNotify event, which you can use to detect the end of playback. Load the video file paths into a list, start playing the 1st file, and use OnNotify to play the next file in the list, repeating until the list is finished.
-
[Android] [FMX] Task synchronization problem with Android
Remy Lebeau replied to Fabian1648's topic in FMX
The 2nd approach is correct - do the REST request in a background thread, leaving the UI thread free to manage the UI. You can update the UI to hide the progress screen when the thread is finished. We can't tell you why the progress screen is not displaying correctly, as you did not show a complete example. Maybe you are still blocking the UI thread in a way that we can't see. Are you able to display the screen if you disable the REST request? Please show a more complete example from start to finish. -
Delphi is 26 years old - Marco's blog
Remy Lebeau replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
And now we are drawing particles instead, my how far things have come -
[Rio][FMX]How to compile for iOS without an Apple device?
Remy Lebeau replied to Fabian1648's topic in FMX
The nice thing about this one is that it already provides support for RAD Studio, you don't have to do anything extra for that. I don't know if this one supports RAD Studio by default or not. -
No. GitHub provides an SVN interface. I was referring more to the fact that Indy doesn't use its own SVN server anymore now that it has migrated to GitHub: https://www.indyproject.org/2019/11/28/indy-svn-retiring-long-live-github/
-
Instructions can be found here: https://web.archive.org/web/20200925081341/http://ww2.indyproject.org/Sockets/Docs/Indy10Installation.EN.aspx (the live page on Indy's main website is offline right now). Indy doesn't use SVN anymore.
-
Yes. Is your project using VCL or FMX? VCL is compiled with OFF by default. FMX is compiled with ON by default. AFAIK, there is no IDE setting for Scoped Enums, they are controlled only via the {$SCOPEDENUMS} compiler directive. Should, yes. Indy's IdGlobal unit.
-
First off, you DO NOT need to set the IOHandler's Destination, Host, and Port properties. Those are handled internally by Indy for you. As for the error, check if Scoped Enums is enabled. If so, you will have to fully-qualify the value by the enum's type name, eg: MaxLineAction := TIdMaxLineAction.maException; That being said, the MaxLineAction property defaults to maException anyway, so there is no need to set that value explicitly in this case.
-
Undocumented language enhancements
Remy Lebeau replied to vfbb's topic in RTL and Delphi Object Pascal
Undocumented intrinsic routines Undocumented Delphi routines Undocumented Delphi record alignment directive Just to name a few. I know there are other sites that document more, I just don't have the time to hunt them down. -
Create a Delphi Dll and load it with DllMain
Remy Lebeau replied to BlueOrange's topic in General Help
You already asked this on StackOverflow, and were basically told DON'T DO THIS, IT IS NOT SAFE! https://stackoverflow.com/questions/66233151/ -
Comunicate with POS terminal (Ingenico)
Remy Lebeau replied to boris.nihil's topic in Network, Cloud and Web
I already explained to you earlier why your use of the IOHandler's ReadLn() method is incorrect in this situation, and how to use ReadLn() (or WaitFor()) to read the POS's messages correctly. The ACK doesn't change what I said earlier. You would simply do an extra read with ACK, #6, as the line terminator instead. However, since the ACK is only 1 byte, the IOHandler's ReadByte() method would be more appropriate, especially if the POS can ever send a NAK instead of an ACK. You can use the IOHandler's Write(Byte) method for that. No, it is not sufficient by itself. I am not at a computer right now to write you working code, it will have to wait until tomorrow. -
It is perfectly safe to call Free() on a Form (or any other TComponent descendant) that has an Owner assigned. The Form/component will simply remove itself from its Owner's internal list, so that the Owner will not try to destroy it a 2nd time when the Owner is destroyed.
-
Yes, it is perfectly safe. Using Action=caFree in the Form's OnClose event will call the Form's Release() method, which is a *delayed* destruction. A CM_RELEASE message is posted to the Form's window. The Form is not actually destroyed until that message is processed at a later time. If the Form/window is destroyed before that happens, the message is discarded. Then something else in your project is freeing the Form prematurely. It is not your OnClose handler doing it. Run your code in the debugger and put a breakpoint in the Form's destructor or OnDestroy event, and look at the call stack to track down where the Form is being destroyed.
-
There is no standard multi-calendar component in the VCL, so you would have to look around for a 3rd party solution, or just use the VCL's standard TDateTimePicker component alongside the TMonthCalendar, TCalendarView, or TCalendarPicker components.
-
There is no standard format for WHOIS data. You are just going to have to check the retrieved data for multiple formats until you find one that matches. For example, I would suggest using a TStringList, eg: const FieldNames: array[0..2] of string = ('Registry Expiry Date', 'Expiry date', 'paid-till'); var sl: TStringList; I: Integer; expiry: string; begin sl := TStringList.Create; try sl.Assign(Memo1.Lines); for I := 0 to sl.Count-1 do begin sl[I] := TrimLeft(sl[I]); end; sl.NameValueSeparator := ':'; for I := Low(FieldNames) to High(FieldNames) do begin expiry := Trim(sl.Values[FieldNames[I]]); if expiry <> '' then Break; end; finally sl.Free; end; Edit3.Text := expiry; end;
-
Why are you asking this again? Why are you creating different accounts across the Internet just to ask the same question over and over? You have already been told several times before, in other forums (here and here), that the WHOIS protocol simply does not work the way you are asking for, regardless of which socket library you use to send the query. You have to retrieve the entire WHOIS data and parse it yourself to get the data you want from it, there is no other option.
-
Comunicate with POS terminal (Ingenico)
Remy Lebeau replied to boris.nihil's topic in Network, Cloud and Web
There are POS systems that use serial-like protocols over TCP. That is what I'm thinking, too. -
Comunicate with POS terminal (Ingenico)
Remy Lebeau replied to boris.nihil's topic in Network, Cloud and Web
Do you need to send an actual *hex-encoded string* for the <message> (ie, '303030...', bytes $33 $30 $33 $30 $33 $30 ...), or do you need to send actual binary bytes ($30 $30 $30 ...)? It makes a BIG difference. Do you have documentation for this POS protocol that you can share? Yes, you are using the wrong code. On the send, you should not be using WriteLn() at all, since there is no CRLF in this protocol. Use Write() instead. But whether you should use Write(string) or Write(TIdBytes) depends on what you are actually expected to send. On the receive, to use ReadLn() properly, you would need to specify ETX, #3, as the line terminator (or, you can use WaitFor(#3)), and then do a ReadByte() afterwards to read the checksum that follows the ETX. Otherwise, you would need to call ReadByte() in a loop until you encounter ETX (or, you could copy the code from ReadLn()/WaitFor() and adapt it for bytes instead of strings, not that hard). That is wrong. I have worked in the past with STX/ETX protocols and a few POS protocols, you definitely need to send the <STX>, <FS> and <ETX> as binary bytes, not as hex-encoded strings. Try something more like this: var s: string; s := #2#2'303030303030303030303031303030'#28'31303030'#28#28'2B30'#28'313931'#28#28#28#28#28#28#28#28#28#28#28'3030'#28'31'#12#28#28#28#28#28#28#28#28#3'2C'; IdTCPClient1.IOHandler.Write(s, IndyTextEncoding_8bit); Though I suspect the POS is actually expecting binary data for the message content, not hex-encoded strings, so try something more like this: var s: string; s := #2#2'000000000001000'#28'1000'#28#28'+0'#28'191'#28#28#28#28#28#28#28#28#28#28#28'00'#28'1'#12#28#28#28#28#28#28#28#28#3','; IdTCPClient1.IOHandler.Write(s, IndyTextEncoding_8bit); That is fine, if you change the reading according to what I said above. Though, if you send a request and are expecting an immediate reply, why use a timer at all? Just read the reply immediately after sending the request. -
Shutting down TidTCPServer (kbmMWTCPIPIndyServerTransport)causing Window Service timeout
Remy Lebeau replied to c0d3r's topic in Indy
Without seeing your TIdTCPServer code, there is no way to help you diagnose why your TIdTCPServer is freezing up. What you describe is a classic deadlock scenario, but there are so many different ways a deadlock could happen. -
Shutting down TidTCPServer (kbmMWTCPIPIndyServerTransport)causing Window Service timeout
Remy Lebeau replied to c0d3r's topic in Indy
That is why I keep asking you to SHOW YOUR CODE (or at least a small demo that reproduces the same issue). We can't tell you what is wrong if we can't see what you are actually doing. No. It is your responsibility to not write code that blocks the socket threads from terminating properly. -
Shutting down TidTCPServer (kbmMWTCPIPIndyServerTransport)causing Window Service timeout
Remy Lebeau replied to c0d3r's topic in Indy
Well, then that goes back to my earlier question - what do those methods actually look like? Because there is likely a deadlock happening inside one of them, preventing one or more socket threads from terminating correctly, thus causing the TIdTCPServer.Active property setter to hang waiting for it. -
Casting pointer to TBytes
Remy Lebeau replied to Jacek Laskowski's topic in RTL and Delphi Object Pascal
The only way to do that is to make the memory area MIMIC a real TBytes, by adjusting the size of the GetMem() allocation to include a fake TBytes header whose reference count is set to 1 or higher so the method doesn't try to free the allocated memory internally as it passes around and uses the TBytes. For example: type // these are defined only in the System unit's implementation, so // they need to be defined manually in your code... PDynArrayRec = ^TDynArrayRec; TDynArrayRec = packed record {$IFDEF CPUX64} _Padding: LongInt; // Make 16 byte align for payload.. {$ENDIF} RefCnt: LongInt; Length: NativeInt; end; var MemBlk: Pointer; MyByteArr: PByte; begin //GetMem(MyByteArr, DesiredSize); GetMem(MemBlk, SizeOf(TDynArrayRec) + DesiredSize); try PDynArrayRec(MemBlk).RefCnt := 1; PDynArrayRec(MemBlk).Length := DesiredSize; MyByteArr := PByte(MemBlk) + SizeOf(TDynArrayRec); // fill MyByteArr as needed ... Something(TBytes(MyByteArr)); // ... finally //FreeMem(MyByteArr); FreeMem(MemBlk); end; end; If that is not an option, and changing the method (or calling a different method) is also not possible, then your only remaining options are to either: - copy the GetMem() data to a temp TBytes, and then copy it back afterwards if needed. - change the GetMem() allocation to TBytes to begin with. -
Shutting down TidTCPServer (kbmMWTCPIPIndyServerTransport)causing Window Service timeout
Remy Lebeau replied to c0d3r's topic in Indy
You can't use TIdTCPServer without at least an OnExecute event handler, otherwise setting the Active property to true will raise an EIdTCPNoOnExecute exception. Are you suggesting that your OnExecute handler is blank, doing nothing at all? I'm not familiar with kbmMW, why are you using TIdTCPServer at all if it does nothing? I don't understand the rational here. As I said earlier, setting TIdTCPServer.Active to False will handle the disconnect of active client sockets, closing the listening sockets, and waiting for their threads to fully terminate.