Jump to content

ErikT

Members
  • Content Count

    25
  • Joined

  • Last visited

Community Reputation

1 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I am unsure if this is even possible in Delphi. I have a GUI, designed for customer use, My employer wishes to have a version of the same software for internal use, where some extra features are available. I intend to put these extra features on an extra TabSheet in a PageControl object. For regular customers, this TabSheet is invisible. My intention was to have two different build configurations: One for customers and one for internal use. Then use a preprocessor symbol to let the code know which configuration it is. However, I have read elsewhere, that Delphi doesn't have a preprocessor, so is this even possible to do? I have defined this symbol in the IDE: Then, in the FormCreate procedure, I have added this line: {$IFDEF __BuilderGUI} TabSheet4.TabVisible := true; {$ENDIF} However, the pascal line is never run. The compiler doesn't seem to "see" the symbol. I've also tried defining the symbol this way (even though I didn't believe in it): If I add {$DEFINE __BuilderGUI} in my code, the $IFDEF recognizes the symbol and acts accordingly. So at least that part works. Am I doing something wrong in the symbol definition, or is what I'm trying to do simply not possible? Should I instead include the $DEFINE in a file that is not included in the customer configuration?
  2. ErikT

    Ping-pong between two Application.ProcessMessages

    I have no idea what an immutable object is. Will need to look into that.
  3. ErikT

    Ping-pong between two Application.ProcessMessages

    Of course! If the calls happen in the "wrong" order, so process B's Application.ProcessMessages call ends up waiting for process A to end, then they are well and surely stuck there. Thanks! Often, the only feasible way around using an Application.ProcessMessages call is to use multiple threads. And, to quote "dummzeuch" in a blog entry, that opens another can of worms. https://blog.dummzeuch.de/2018/09/29/calling-application-processmessages-in-a-delphi-program/
  4. This one might generate some frowns... I've used Application.ProcessMessages quite often, for several reasons. Most of my applications communicate with an external device via a serial port, USB or Ethernet. Each transaction can take some time, and since it is often crucial that my application gets a response before moving on, I include a while loop (with a timeout). In this loop, apart from checking if data has been received, I make sure to make an Application.ProcessMessages call, so the rest of my application isn't blocked. In the past, this has worked fine. Why this method? Because I think multiple threads are way too difficult to work with, so I don't use them unless it is absolutely necessary. And, as I wrote, it works fine. Until now, that is. In my current application, I communicate almost continuously with the external device, to get some monitoring values, status bits and such from the device. This is run by a timer, as this is the only way I can figure out how to make something run seemingly continuously. A bit like the while (1) loop in a C program for a microcontroller. Apart from the timer based "main loop", I have a few buttons that can be used for sending various commands to the device. These access the same physical port as the "main loop", so I have some boolean variables that are set and cleared, so one process can wait for the other to finish. Now for the juicy part. I have had problems with the application seemingly stalling once in a while, and couldn't figure out why. When this happens, debug stepping just keeps looping through a limited number of instructions in the CPU tab. So for quite some time, I didn't know which part of my own code started the problem. I also noticed that the application wasn't actually completely stalled, as there was a separate timer that kept feeding data into some graphs. So it was clearly only certain parts that didn't work. Now I added some global debug variables, and added lines in the code, giving the variables different values. Such as (...) repeat ButtonDebugValue := 2; while (CommBusy or CommCycle) do begin ButtonDebugValue := 3; Application.ProcessMessages; ButtonDebugValue := 4; (...) I did that in the suspected procedures, and made sure to place some before and after Application.ProcessMessages, as I had become particularly suspicious about this. As it turned out, two events (OnTimer and OnClick) were both stuck in an Application.ProcessMessages procedure. At the same time. Not even rolling around in the loop, but just stuck in the procedure. My theory: Application.ProcessMessages messes up if it is called more than once at a time. What I mean is: Process C (the button click) is waiting for process B (the timer), which is waiting for process A (comms receive). When the Application.ProcessMessages call in one event allows a different Application.ProcessMessages call in another event, things go south. The application doesn't stall as such, but those two Application.ProcessMessages never get any further, They are just blocked. What do you think? Is this theory plausible? I am not in need of help to fix this – I would just like to know if I am right or wrong. And maybe let this act as a warning against frivolous use of Application.ProcessMessages.
  5. ErikT

    TeeChart constraints on automatic axis

    When I began poking around, it turned out to be not-so-complicated after all. I've made this piece of code, which seems to work nicely: procedure AdjustAxis(WhichChart : TChart; MinInterval : Double); var ChartMaxY : Double; ChartMinY : Double; ChartCenter : Double; begin ChartMaxY := WhichChart.MaxYValue(WhichChart.LeftAxis); ChartMinY := WhichChart.MinYValue(WhichChart.LeftAxis); if ((ChartMaxY - ChartMinY) < MinInterval) then begin ChartCenter := (ChartMaxY + ChartMinY) / 2; WhichChart.LeftAxis.SetMinMax(ChartCenter - (MinInterval / 2), ChartCenter + (MinInterval / 2)); WhichChart.LeftAxis.AutomaticMaximum := false; WhichChart.LeftAxis.AutomaticMinimum := false; end else begin WhichChart.LeftAxis.AutomaticMaximum := true; WhichChart.LeftAxis.AutomaticMinimum := true; end; end; The parameters are WhichChart, which is the name of the chart, and MinInterval, which is the smallest acceptable numerical difference between minimum and maximum on the left axis. Must be positive, by the way. The chart graph is centered between maximum and minimum in the chart window. Of course it can be made smarter. For instance, this only works on the left axis. Feel free to use and modify.
  6. ErikT

    TeeChart constraints on automatic axis

    Okaaaay... Definitely one to consider. Thanks!
  7. I am using TeeChart in a GUI that continuously displays some readouts from a device. Generally, it works fine, but there is one annoyance. I use the automatic axis scaling, but would like to be able to set some constraints to that. A sort of "maximum zoom". The thing is that when a readout has been quite stable for a while, the automatic scaling feature zooms in so much that the numeric resolution becomes annoyingly visible. Example: If the example above is allowed to run for a while, the chart may be complete filled with one big blue rectangle due to this. It would be nice to be able to set a minimum distance between minimum and maximum, so the left axis in the example above would go from 42 to 52, for instance, with the blue graph being nicely centered in the chart. However, I haven't found such a setting. But since I don't exactly understand every explanation of the properties and methods in the help document, I wonder if I just haven't found it. So... does anyone have a cool solution, or do I need to go the complicated way of setting the axis minimum and maximum manually in my code, based on the series values?
  8. @Attila Kovacs Thanks, but I have no idea how to do that in the Sagecom router that I have. Cannot find any menu item like that. However, it won't really make a difference, because if this can happen at my place, then it can happen at the customers as well. So even if I do get it solved here, it won't be a general solution. I will just have to use a different method to identify the devices.
  9. @Brian Evans Yes, sounds plausible. A very good guess. Thank you for that! I think I'll write to the manufacturer of the access point and ask what is going on, and if there is a way to make it behave. My device is definitely not changing its MAC address by itself, as the firmware isn't designed to do that.
  10. @DelphiUdIT Thanks, but I am not quite sure what I am looking at.
  11. I have run into a snag regarding MAC addresses, or retrieving them from devices. I don't know if this is the correct forum for this question, but it is the best that comes to my mind. Background: I have created a GUI that communicates with a PCB that has a standard Ethernet port (wired). My GUI searches for available IP addresses, and then retrieves the MAC address for each of these, using the WinAPi.IpHlpApi SendARP function. The 36 most significant bits of the MAC address are then used for filtering. Recently, my lab has been moved to a new location, with no wired access to the Router / DHCP server. Since my PCB only has a standard wired Ethernet port, I have set up an access point in "client mode", to make a tiny wired network in the lab. (TP-Link WA801N) This seems to work nicely, except... The problem: My GUI cannot find the PCB, and I've figured out that the reported MAC address is wrong when the PCB is connected to the access point. I can find the board's IP address with Advanced IP Scanner, but the reported MAC address is the same as the access point's MAC address. For security, I have partially obscured the MAC addresses, but the two MAC addresses marked with yellow are identical. The DOS command arp -a says basically the same thing. However, if I connect a computer to the same ethernet switch as my PCB (with a network cable), then I get the correct MAC address through that connection. Can anyone explain what is going on here? Is it natural that an access point overrides the MAC addresses of the connected devices? Could there be some obscure setting that I need to change? Or is there something wrong with the access point? Any help will be greatly appreciated.
  12. @Remy Lebeau Thank you for your comment.
  13. @Christophe E. After some further error-fixing, it now seems to work. Thank you very much! Best regards, Erik
  14. Oh, crap. This is so obvious. I've stared myselft blind at that. Thanks! True. I need to destroy Ping1 when done. Well spotted. About blocking: This is an example, just to get the thread to work. In the final version, there is supposed to be a number of threads, and the main thread will not be blocked.
×