Jump to content

Remy Lebeau

Members
  • Content Count

    3000
  • Joined

  • Last visited

  • Days Won

    135

Everything posted by Remy Lebeau

  1. Remy Lebeau

    How to "dim" a TabSheet?

    A LONG time ago (9 years!), I posted a demo on StackOverflow for displaying an alpha-blended TForm as a dimming shadow over top of another TForm, while allowing individual controls to remain uncovered and interactive through the shadow: How do I put a semi transparent layer on my form Basically, the shadow TForm uses its AlphaBlend/Value properties to provide the dimming effect, and its TransparentColor/Value properties to mask out holes in the shadow where individual controls want to peek through. I'm sure a similar technique can be adapted for this situation.
  2. Remy Lebeau

    How to "dim" a TabSheet?

    Do note that solution is applying the WS_EX_LAYERED window style to a child window, which is supported only in Windows 8 onwards, and only if the app manifest specifies Windows 8 as a <supportedOS>.
  3. Remy Lebeau

    changing inherited control

    Makes sense. You didn't put TCustDBGrid into a package and install it into the IDE, so you can't use TCustDBGrid in a DFM resource, unless you call RegisterClass(TCustDBGrid) before the DFM is loaded when the TForm object is created. Because you are trying to actually call TForm1's inherited MouseDown() method and then assign its result to the event. Use this instead: unit Unit1; interface uses ..., Vcl.DBGrid, ...; type TDBGrid = class(Vcl.DBGrid.TDBGrid) protected procedure MouseDown(Sender: TObject; Button: TMouseButton; ShiftState: TShiftState; X, Y: Integer); override; end; TForm1 = class(TForm) ... recentinfo: TDBGrid; .. end; implementation procedure TDBGrid.MouseDown(Sender: TObject; Button: TMouseButton; ShiftState: TShiftState; X, Y: integer); begin if Button = mbRight then ShowMessage("testing"); inherited; end; No, because you are not registering the TCustDBGrid class with the DFM streaming system.
  4. Remy Lebeau

    Range Check Error ERangeError

    32bit vs 64bit? You really should not be casting to Integer at all. Cast to WPARAM instead, which is what PostMessage() is expecting procedure TEqlistFrm.VenueEditMainKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin PostMessage(Handle, CM_SEARCH, WPARAM(Sender), LPARAM(Key)); end;
  5. Remy Lebeau

    QueryPerformanceCounter precision

    See https://hero.handmade.network/forums/code-discussion/t/7485-queryperformancefrequency_returning_10mhz_bug Also of interest, see MSDN: https://docs.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps
  6. It can be passed in as a normal parameter, and even used in ClassType comparisons, but it can't be used for type-casts, eg: function CreateAnObjectByClassName(const ClassName: string; BaseClass: TPersistentClass): TPersistent; var Cls: TPersistentClass; begin Cls := GetClass(ClassName); if not Cls.InheritsFrom(BaseClass) then raise Exception.Create('...'); Result := BaseClass(Cls).Create; // <-- doesn't work end; The compiler needs to know the actual class type that exposes the necessary constructor in order to call it directly. Otherwise, you have to resort to using RTTI to call the constructor, as demonstrated in the code Stefan linked to. There are alternative ways to accomplish that, just not as clean as what you are thinking.
  7. That is because neither TObject, TPersistent, nor TInterfacedObject have a virtual constructor that your descendants can override. The lowest RTL class that introduces a virtual constructor is TComponent. You need to add a virtual constructor to TMyClass and have desccendants override it as needed. And then declare your own metaclass type for your creation function to use. For example: type TMyClass = class(TInterfacedPersistent, IMyInterface) public constructor Create; virtual; end; TMyClassType = class of TMyClass; function CreateAnObjectByClassName(const AClassName: string): TPersistent; begin Result := TMyClassType(GetClass(AClassName)).Create; end; ... type TMyClass1 = class(TMyClass) public constructor Create; override; end; TMyClass2 = class(TMyClass) public constructor Create; override; end; RegisterClasses([TMyClass1, TMyClass2, ...]);
  8. Nope. There is no method of TRttiContext that takes an object instance as input. FindType() takes in a class type as a string, and GetType() takes in a class type as a TClass or PTypeInfo.
  9. Remy Lebeau

    TIdHTTP to TNetHTTPRequest

    In what way exactly? Rather than someone translating your TIdHTTP code, can you show your existing TNetHTTPRequest code that is not working for you?
  10. Remy Lebeau

    Where I can find the SSL DLLs for Indy?

    https://github.com/IndySockets/OpenSSL-Binaries https://www.indyproject.org/2020/06/16/openssl-binaries-moved-to-github/
  11. Remy Lebeau

    TMemo and unicode

    The code shown is not the correct logic to parse an RFC2047-encoded string. Try something more like the instead (though this could be simplified using IdGlobal.Fetch(), for instance): uses IdGlobal, IdGobalProtocols, IdCoderMIME, idCoderQuotedPrintable; procedure TForm1.convertbuttonclick(Sender: TObject); var s, s2, charset, encoding, data : string; i, j: Integer; begin s := Memo1.Lines[0]; s2 := s; i := Pos('=?', s); if i > 0 then begin Inc(i, 2); j := Pos('?', s, i); if j > 0 then begin charset := Copy(s, i, j-i); i := j+1; j := Pos('?', s, i); if j > 0 then begin encoding := Copy(s, i, j-i); i := j + 1; j := Pos('?=', s, i); if j > 0 then begin data := Copy(s, i, j-i); if TextIsSame(encoding, 'B') then s2 := idDecoderMIME.DecodeString(data, CharsetToEncoding(charset)) else if TextIsSame(encoding, 'Q') then s2 := idDecoderQuotedPrintable1.DecodeString(data, CharsetToEncoding(charset)); end; end; end; end; Memo2.Lines.Clear; Memo2.Lines.Add(s2); end; That being said, Indy already implements a decoder for RFC2047-encoded strings, in the DecodeHeader() function of the IdCoderHeader unit, eg: uses IdCoderHeader; procedure TForm1.convertbuttonclick(Sender: TObject); var s, s2 : string; begin s := Memo1.Lines[0]; // '=?UTF-8?B?5aaC5L2V6K6TIGFydC1tYXRlIOaIkOeCug==?=' s2 := DecodeHeader(s); Memo2.Text := s2; end;
  12. Remy Lebeau

    Smtp avoid spam classification

    It is hard to diagnose your issue without seeing the raw email data, and/or your code that is creating the email, and even knowing which version of which Pascal compiler you are using (Delphi vs FreePascal), since string handling varies by compiler and even by version. I can't answer that with the limited details you have provided so far. For instance, if you are using a Unicode version of Delphi (2009+ or later) or FreePascal (3.0+ with UnicodeStrings enabled), then yes, it should be converting to UTF-8 property. But if you are using a pre-Unicode version of Delphi/FreePasscal, then no, it will not convert to UTF-8 automatically, so you are responsible for encoding your own strings to UTF-8 before giving them to Indy. What does your actual text look like? This score implies that you have a lot of script changes happening inside of individual words. Which might just be a side effect of UTF-8 not being encoded properly. Hard to say without seeing the raw data. What do you have the TIdMessage.Encoding property set to? It is set to meDefault by default, which will be auto-updated to either mePlainText or meMIME depending on whether the TIdMessage.MessageParts collection is empty or not, respectively. A 'MIME-Version' header is generated only when TIdMessage.Encoding is meMIME. In general, you don't need to use MIME if your email contains only plain text, but it sounds like the provider may be requiring MIME. So, you may need to force the TIdMessage.Encoding to meMIME. UTF-8 is an 8-bit encoding, so it requires a transfer encoding that supports 8-bit data. '7bit' will truncate/zero the high bit of each byte, thus corrupting non-ASCII characters. So, you need to set the TIdMessage.ContentTransferEncoding property (and the TIdMessagePart.ContentTransfer property in entries of the TIdMessage.MessageParts collection) to either '8bit', 'base64', or 'quoted-printable' when using UTF-8 text to avoid any potential data loss. Note that '8bit' emails do require additional support from an SMTP server (features which Indy does not currently implement), so use 'base64' or 'quoted-printable', which are compatible with 7-bit systems. If the text is mostly ASCII characters, I would use 'quoted-printable'. If the text is mostly non-ASCII characters, I would use 'base64' instead.
  13. Remy Lebeau

    problem with file attributes

    Then you likely did not create the file where you are expecting. Are you using relative paths, for instance? What is the actual value of your fn variable? The filesystem does not lie about file existence. If it says a file does not exist, then it really does not exist. Double-check your input. With the same ERROR_FILE_NOT_FOUND error? I suggest you use SysInternals Process Monitor to see EXACTLY which file path your app is REALLY trying to access, and make sure it matches your expectation.
  14. Remy Lebeau

    problem with file attributes

    Then you likely don't have access to the file, or at least don't have permissions to ask the filesystem for its attributes. You need to call GetLastError() to find out why GetFileAttributes() is failing.
  15. Remy Lebeau

    problem with file attributes

    GetFileAttributes() can return INVALID_FILE_ATTRIBUTES for a number of different reasons, not just because the file does not exist. You have to use GetLastError() to differentiate the actual cause.
  16. Remy Lebeau

    IdHttp not connect IP Camera error 401

    I suggested EITHER approach, not BOTH. Use either BASIC or DIGEST. Did you verify that TIdHTTP is actually trying to send BASIC/DIGEST authentication in its request? I'm guessing either you are not setting the TIdHTTP.Request.Username/Password correctly (are you ABSOLUTELY SURE you are using the correct credentials? Are there any non-ASCII characters present in them?), or the camera is not accepting Indy's flavor of DIGEST authentication (BASIC is very, well, basic and difficult to get wrong). Can you provide an example showing the raw HTTP messages from start to end?
  17. Until a few months ago, I also depended on BCB6 for my full-time job (my software has reached its End-Of-Life, so this is no longer an issue), but in the past 15-odd years, moving it into a VM was never really an option. The physical machine it ran in was over 500GB of logs, databases, backups, etc, so cloning it would have taken forever. But more importantly, it had specialized PCI hardware installed that didn't work inside a VM, and I never had the time to create a new VM with just BCB6 installed. I would have had to continue running my apps on the physical machine, but used the remote debugger inside a VM, and I wasn't too keen on that approach, either,
  18. Remy Lebeau

    IdHttp not connect IP Camera error 401

    Your camera supports BASIC and DIGEST authentications. By default, TIdHTTP enables only BASIC authentication, which you are explicitly disabling by setting the TIdHTTP.Request.BasicAuthorization property to False. You need to either: re-enable BASIC authentication by setting TIdHTTP.Request.BasicAuthorization to True. enable DIGEST authentication by adding the IdAuthenticationDigest, or IdAllAuthentications, unit to your Form's uses clause.
  19. Remy Lebeau

    Delete a Registry Key...

    KEY_ALL_ACCESS is meant for admins only. You should specify only the exact rights you actually need (which FYI, TRegistry.DeleteKey() also requires KEY_QUERY_VALUE, since it calls RegQueryInfoKey() to determine the number of subkeys and the maximum subkey name length), eg: reg := TRegistry.Create(_DELETE or KEY_ENUMERATE_SUB_KEYS or KEY_QUERY_VALUE); Otherwise, just use the Win32 RegDeleteTree() or SHDeleteKey() function instead of TRegistry.DeleteKey(), and let the OS handle the necessary recursion.
  20. Correct. There is no Win32 API to enumerate and query existing tray icons. In the old days, the Tray was a simple toolbar that you could enumerate with standard Toolbar messages, but that would not get you any details about the app/window associated with each icon. With the redesign of the Taskbar and Tray in Windows 7 onward, I don't think that is doable anymore, or at least not 100%, due to the user's ability to hide icons.
  21. Remy Lebeau

    Close a TIdTCPClient connection

    No, they are not. All you really need is Disconnect(), or at least Socket.Close() if closing the socket from another thread. That is not an Indy error message, or any OS error message I have ever seen. So I am assuming you mean it is coming from the Barcoder Reader or Ethernet base (what is that supposed to be?) instead. Does the reader/base only allow 1 connection at a time? If you just yank out the network cable, it won't matter what you do on the client side, the connection will be lost on the server side and it will need time to process that loss, which may take awhile, depending on the server's implementation. Disconnect()/Close() will perform a graceful disconnect (send a FIN packet to notify the peer that the connection is being closed intentionally). That should allow the reader/base to free up the used slot immediately. However, it won't matter what you do in the case of the connection being lost abnormally, like from a network outage. All you can do in that case is wait for the reader/base to handle the loss on its end in its own time to make the slot available again.
  22. Maybe possible, but not easily. Once upon a time, you could use a WH_CALLWNDPROC hook to intercept WM_COPYDATA messages being sent to the Taskbar's "Shell_TrayWnd" window, and then extract the NOTIFYICONDATA info from those messages. But I'm not sure if that still applies anymore, what with all of the changes Microsoft has made to the Taskbar's system tray icon handling in the past decade.
  23. Remy Lebeau

    Install recent Delphi versions on Windows XP

    In that case, I don't recall offhand the last version that officially supported XP as a target platform. In the current DocWiki, versions prior to 10.1 Berlin do not say the specific Windows versions they target. 10.1 says Windows 7 SP1+, Windows 8-10, and Windows Server 2008-2012. I do know that there are a few areas of the modern RTL/VCL that make use of newer APIs that don't exist on XP, so 10.x-compiled executables are not likely to run as-is on XP.
  24. Remy Lebeau

    Thread Issues: using resume and start

    If the sole purpose of the thread is just to delay a UI notification, then TThread.ForceQueue() would be better, no thread needed at all: procedure THeaderFooterForm.Button1Click(Sender: TObject); begin TThread.ForceQueue(nil, procedure begin HeaderLabel.Text := 'My Job'; end ); end;
  25. Remy Lebeau

    Thread Issues: using resume and start

    The device should not matter, no. This is strictly an RTL error message that TThread.Start() raises if it can't resume a suspended thread, either because the thread is not allowed to resume (e, it is already finished), or the OS failed to resume the thread properly. Hard to say for sure what is going on without seeing the latest source code for TThread.
×