Jump to content

Remy Lebeau

Members
  • Content Count

    2333
  • Joined

  • Last visited

  • Days Won

    94

Posts posted by Remy Lebeau


  1. Just because the Labels are disabled does not mean the Panel will handle mouse activity when over them.  You are still mousing over the Labels, so you need to catch and forward the event activity from the Labels if you want to handle them the same as events on the Panel.

     

    Otherwise, you can subclass the Panel to handle the underlying mouse messages before they get dispatched to children.  Since the Panel is a windowed control and the Labels are graphical controls, the Panel is the one receiving the messages from the OS and passing them along to the Labels.

    • Like 1

  2. 14 hours ago, shineworld said:

    I've used a TComboBox set as List because arguments start from None, 1, 2 .. 256 and use can fastly move to any using key:
    image.thumb.png.0560ec6e284bbf42a3da5955cec6b376.png

     

    You say you have hundreds of TComboBoxes, but the screenshot above only shows 7 (presumably 11?).  If this screen is similar for the rest of the app, where each item on the side list displays its own page with just a handful of ComboBoxes on it, then a simple solution would be to NOT load every page at one time, but instead to load one page at a time only when it is made visible to the user, and then unload it when it is no longer visible to the user.  That will greatly speed up your load times, and then you don't have to resort to using hacks like owner-drawing, OnDropDown refreshes, etc.  You can move each page to its own TFrame that you create and destroy when needed, that way you still regain design-time support for your page layout.

    • Like 4

  3. 2 hours ago, shineworld said:
    
    SendMessage(Handle, WM_SETREDRAW, Ord(False), 0);
    SendMessage(Handle, CB_INITSTORAGE, I_O.MAX_DIGITAL_INPUTS + 1, COMBOBOX_MAX_TEXT_LENGTH * (I_O.MAX_DIGITAL_INPUTS + 1));
    for J := 0 to I_O.MAX_DIGITAL_INPUTS do
      Items.Insert(J, InputsList.Strings[J]);
    SendMessage(Handle, WM_SETREDRAW, Ord(True), 0);

     

    Some suggestions:

    • don't use WM_SETREDRAW directly. Use the TComboBox.Items.(Begin|End)Update() instead, which will use WM_SETREDRAW internally for you.
    • CB_INITSTORAGE helps, but simply don't waste time putting actual string values in so many TComboBoxes to begin with.  Instead, fill them with blank strings, and set their Style property to csOwnerDrawFixed and use their OnDrawItem event to render the actual text whenever a drop-down list is visible.
    • consider using a different UI control, such as a TListBox, or a TListView in vsReport mode. Both have true virtual modes that can handle a lot of items very quickly.
    • Like 1

  4. 4 hours ago, DelphiUdIT said:

    RFC 5322 was updated to RFC 6854 in 2013.

    In the Indy sources the last comment is on the RFC 2822 regulation (obsolete and replaced by RFC 5322).

    However, it is known that the comments have not been updated, nor have the existing manuals and docs been updated.

    The only one who could answer you is @Remy Lebeau

    Indy does not implement RFC 6854 (I didn't even know that existed). It does implement 822/2822, but I don't recall to what extent it implements 5322 (perhaps just aspects of it?).

    6 hours ago, duzzell said:

    Can I use Indy's TIdMessage to construct this message

    Most likely, yes, as long as you don't need to use some modern email features, like signing, etc.  If you run into problems, let me know.

     

    Do be aware that, by default, TIdMessage saves its data to a TStream/file using a dot-transparency format (ie, lines that begin with a period are escaped with an extra period) that is intended for use with the SMTP and POP3 protocols but not with other protocols.  So, you will likely need to utilize the class helper in the IdMessageHelper unit, which adds an AUsesDotTransparency parameter to the TIdMessage.SaveTo...() methods, then you can set that parameter to False.


  5. 27 minutes ago, PeaShooter_OMO said:

    I also need my applications to be able to send network data to the other side at any point and from any thread ... Now that I think of it, I wonder if that is not perhaps the reason for my issue with the current Indy implementation.... maybe Indy also does not like that I do that.

    Indy allows that just fine - provided you adequately serialize access to the socket to avoid multiple threads overlapping their outgoing packets.  Although multiple threads CAN send to the same socket provided they don't overlap, it is generally a better idea to handle all of the sends in a single thread instead.

    • Like 1

  6. 1 hour ago, DelphiUdIT said:

    May be this is the cause:

    I was referring to this code:

    18 hours ago, Connie McBride said:

    Ucrpe.pas is failing on this line :

     

    function TCrpe.SendOutput : Boolean;
    var
      nLeft, nTop,
      nWidth, nHeight : DWord;
      xHandle         : hWnd;
    begin

    ....

            if FWindowSize.FLeft = -1 then
              nLeft := CW_USEDEFAULT  <<<<<<HERE 

     

    nLeft is defined as DWord.

    Why were nLeft, etc declared as DWord to begin with and not as Integer, as the Win32 API expects?


  7. In VCL, I would simply custom-draw an image of a "button" directly onto the ListView item, and then use mouse events on the ListView to detect a click on the "button" to invoke the dialog.


  8. 1 hour ago, jaenicke said:

    He needs help to make a pull request, because this fix should be included in the INDY source.

     

    Perhaps someone can do this for him. I do not have the time at the moment, otherwise I would have done it already when I saw the german post.

    I have opened a ticket on Indy's GitHub repo and will work on a fix:

    #523: EConvertError in TIdX509.notBefore and TIdX509.notAfter properties for 4-digit years

     

    UPDATE: I have now checked in a fix.  Let me know if it works.

    • Like 2
    • Thanks 1

  9. 15 hours ago, Snubber said:

    I want to download the Delphi Community Edition.

    But it show me the messgae as follow

    The CE installer requires the GetIt server to download various components during installation.  But CE is still at version 11, and due to the recent server outages, GetIt has been restored for only RAD Studio 12 so far. They are still working on restoring GetIt for version 11 and earlier.  So, it is not surprising that they would disable any downloads for older versions right now.


  10. 7 hours ago, Willicious said:

    Does anyone know of a way to get a new serial for 10.4.2 CE?

    Sorry, but you simply can't, as 10.4.2 CE is no longer available. The terms of the CE license require that you download and install the latest CE version every year.  No exception.

     

    If you need to stick with 10.4.2 then you will have to pay for that license, you can't avoid it.  Otherwise, you will have to address the problem that is preventing you from migrating the project to the latest CE version.


  11. 50 minutes ago, IMG SPA said:

    So I wanted to know if it is possible to receive the result from another application when it is closed and how to handle it

    Yes, it is possible. If it is just a simple integer, you can return it in the process exit code and then retrieve it via GetExitCodeProcess(). But for anything more complex, you can create an Inter-Process Communication channel between the two apps, such as with a pipe, socket, shared memory, etc and exchange data that way.


  12. 4 hours ago, FearDC said:

    I'm having hard time to understand what an "unsolicited" notification/response is - kind of "unexpected"

    Meaning, the server sends something to a client that it did not explicitly ask for.  Such as a notification when another client connects/disconnects, or when a client sends a message to other client.  Things which can happen at any time, outside of the normal request/response flow of "I want something" -> "Here you go" (solicited). "Oh, BTW, here is something else I have for you but you didn't ask for" (unsolicited).

    4 hours ago, FearDC said:

    Client to server handshake:

    That contains a mix of solicited and unsolicited messaging.

     

    The new client connects, gets a greeting, says hello, and gets acknowledged.  The client initiated an action and got a direct response before doing anything else.  That is solicited messaging.

     

    Then, all of the other clients get notified of the new connection.  They didn't have to send any requests to receive that event, they are just blindly told that it happened, when it happened.  It happened in the background, and they have to passively watch out for it.  That is unsolicited messaging.

    4 hours ago, FearDC said:

    Next part is a free communication where client talks first

    That is unsolicited messaging.  Client1 sends a request to the server (solicited), but then the server notifies Client2/etc (unsolicited).  Client2/etc did not send a request to receive that event, it/they are blindly told when the event happens.

    4 hours ago, FearDC said:

    Another moment is where server talks first notifying everyone that someone enters or leaves:

    Same thing.

     

    All that extra messaging that the server does in the background needs to be handled properly.  But if you code your server to just receive a request and send a response, you won't be able to handle that extra messaging at all.

    4 hours ago, FearDC said:

    When a client connects, the server creates a separate thread where it handles reads and writes from/to client. It first welcomes the client, exchanges the handshake information and waits for requests from client. Possibly sends public notifications to client.

    And right there is the problem.  The code you showed doesn't handle that last part.  You can't just write to a given client connection whenever and from wherever you want.  You have to serialize your outgoing messaging.  Think of what would happen if 2 clients happen to connect/disconnect at the same moment and thus need to notify the same target client.  Or if multiple clients send private messages to the same target client at the same moment.  You don't want multiple messages to that target client to overlap, that will corrupt your socket communications.

     

    So, you must provide some mechanism to make sure that subsequent messages wait their turn while an earlier message is still being written to the socket.  That could as simple as putting a critical section or other exclusive lock around socket writes.  But, that can cause unwanted blockages in threads that want to write to a socket, so that is where my earlier suggestion to use a per-client queue comes into play instead.  That way, only the thread that actually writes the queue to the socket may block, while other threads are free to continue putting new messages into the queue.

    4 hours ago, FearDC said:

    do you mean that client will not be written to while server is reading the client - client thread is frozen and waiting for data from client? In that case there is timeout

    Well, that is certainly true, if you do the writing in the OnExecute event (as you usually should).  But, if OnExecute never writes, only reads, then you can do the writing from another thread.

    4 hours ago, FearDC said:

    is that the delay you are talking about?

    I didn't say anything about a delay.

    • Like 1
    • Thanks 1

  13. 1 hour ago, William23668 said:

    Yes I get code 32 but all drives are local

    Locality has nothing to do with it.

     

    You are opening the drive with just FILE_SHARE_READ specified by itself.  You are telling the OS that you are willing to share access to the drive with other open handles only if they open the drive for read-only access.  If anybody else already has the drive open for writing, then you won't be able to open it since you are not willing to share write access.  And clearly someone does have the drive open for writing (you can verify this with a tool like SysInternals' Handle or Process Monitor utilities), which is why you are getting the "sharing violation" error.

     

    Try adding FILE_SHARE_WRITE for your sharing rights:

    Handle := CreateFile(..., FILE_SHARE_READ or FILE_SHARE_WRITE, ...);

    But be aware that this will allow other open handles to potentially write to the drive while you are reading from it.  If that is not what you want, then omit FILE_SHARE_WRITE and simply warn your user that you can't gain read-only access to the drive.

    • Thanks 1
×