Jump to content

Remy Lebeau

Members
  • Content Count

    2811
  • Joined

  • Last visited

  • Days Won

    123

Remy Lebeau last won the day on February 17

Remy Lebeau had the most liked content!

Community Reputation

1500 Excellent

Technical Information

  • Delphi-Version
    Delphi 12 Athens

Recent Profile Visitors

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

  1. Remy Lebeau

    Using a DLL in MSVC

    If you want to quote multiple messages at one time, you can click on the '+' button on the bottom of each message, and then click the resulting "Quote # posts" popup when ready. If you want to quote multiple sections of a single message, that takes a little more work. In an original message, you can highlight the text you want to quote, then roll the mouse over the selection and click on the resulting "Quote selection" popup. Repeat as needed. Alternatively (on a desktop browser only, don't try this on a mobile browser, it doesn't work well)... after quoting a message, if you put the edit caret inside of the quote text where desired and then insert a few line breaks, SOMETIMES that will automatically split the quote into 2 separate quotes, and then you can add your responses in between them. But, that split does not always work, in which case I end up having to copy/paste/edit the quotes to get what I want. Roll the mouse over a quote and you will see a little box appear in the top-left corner of the quote. Left-click on that box to select the quote as an object, then you can copy/paste the quote, and then edit the quotes as needed. You can also drag&drop quotes using that little corner box, too. Quoting can be a headache, err, art form on this forum! Yes. How would I do that? Adjust these: Default8087CW, DefaultMXCSR, DefaultFPSCR, and DefaultFPSCR Somehow in the older compiler version? Have you read the documentation yet? https://docwiki.embarcadero.com/Libraries/en/System.Default8087CW https://docwiki.embarcadero.com/Libraries/en/System.DefaultMXCSR https://docwiki.embarcadero.com/RADStudio/en/Floating_Point_Operation_Exception_Masks
  2. Remy Lebeau

    TDirectory - file lock out on Win 10 LTSC

    Hard to say. I find it very unlikely that file I/O would report that particular error. It would be helpful to see your actual file I/O and error handling code. I wonder if something is sitting in between your file I/O and error handling that might be affecting the error code unexpectedly. When retrieving the OS error code, you need to retrieve it as close to the failed API call as possible, you can't make any other system calls first. All the more reason why I don't like using IOUtils with all the extra overhead it has, particularly any memory cleanup.
  3. Remy Lebeau

    Using a DLL in MSVC

    I've written a fair share of DLLs in BCB6 that work just fine in other compilers, including MSVC. Never had a problem with that. Makes me think that either you are doing something weird/incompatible that you are not showing, or maybe you are linking in another library into your DLL and that library is incompatible in some way. Hard to say without a reproducible test case. You can call the Form's Update() method to force an immediate repaint. That implies your EXE is calling the DLL functions in a loop that is not processing your UI's message queues in between calls into the DLL. That is not a good design choice, especially for a DLL with a UI. I would suggest either: moving your DLL's UI into a worker thread with its own message loop. having the DLL export a function that the EXE can call periodically to pump your UI's message queue. If the EXE has its own UI, then simply break up the EXE's logic to work asynchronously so its own message loop can also service your DLL's UI. Have you considered using the Remote Debugger? Now we're getting somewhere useful. RAD Studio 12.0 did make changes to how it handles floating-point exceptions: https://docwiki.embarcadero.com/RADStudio/Athens/en/What's_New#Disabling_Floating-Point_Exceptions_on_All_Platforms On older versions, sometimes you do need to adjust the exception masks manually. Particularly for MSVC compatibility.
  4. Remy Lebeau

    Guidance on FreeAndNil for Delphi noob

    Use it ONLY when you NEED it. When freeing an object that is pointed at by a given pointer variable, and that variable may be used again later, then nil'ing that variable makes sense, as future code will be sensitive to what the variable is (or is not) pointing at. But, if the pointer variable is not going to be used after freeing the object, then there is simply no point is nil'ing the variable.
  5. I don't have an older version installed right now to verify this with, but I would expect ALL compiler versions to have a problem with this. Yes, the 'type' specifier in Delphi creates a new distinct type, which you can declare overloads with. But in C++, AnsiString is just a typedef alias for AnsiStringT<0>, and your ObjectIdentifier is just a typedef alias for AnsiString, and thus is also an alias for AnsiStringT<0>. And since typedef just creates aliases, not distinct types, they are both actually the same type, which you can't use to declare overloads with. I'm sure this has come up before in past versions.
  6. Wow. A Microsoft scanner being lenient on an app written by a Microsoft compiler, and harder on an app written by a competitor's compiler. Who would have thought... 😜 And we all know how well AI writes good code...
  7. Remy Lebeau

    Using a DLL in MSVC

    They are using the same DLL instance? That is not how you should make the import lib for MSVC. Use MSVC's command-line DUMPBIN and LIB tools to create a new import lib from the DLL itself. Use DUMPBIN to create a .DEF file for the DLL's exports, and then use LIB to generate a import lib from the .DEF file. Which items are you referring to exactly? There is nothing "bold" in what you showed. You really should not be calling Application->ProcessMessages() at all. What is the actual crash? What is the error message, verbatim? Does the crash happen while the DLL is being loaded into memory, or inside of DllEntryPoint()? Have you tried debugging the DLL in the IDE? Configure your DLL project with your MSVC app exe as its Host. Then put breakpoints in the DLL code as needed. When you run the DLL project, it will execute the MSVC app, which will then load your DLL, and the debugger should attach to it so it can step through the DLL code normally.
  8. Hard to say when you didn't show the Delphi code to compare. On a side note... That is not the correct way to convert a char* string to a std::wstring. That just makes a copy of each char as-is to wchar_t, which does not actually translate the characters from one encoding to another. You need MultiByteForWideChar() or equivalent for that task to avoid data loss/corruption. Since you have a ConvertToWideChar() function, why not use it? Hopefully it does a proper conversion: std::wstring iniFilePath; ConvertToWideChar(exeDir + "\\" + std::string(iniFileName), iniFilePath); Though, why does ConvertToWideChar() take a std::wstring variable as an output parameter, instead of returning the std::wstring? If it did that instead, you could eliminate your wIniFile, wsection, and wkey variables. Why char* here? You are converting from char* to std::string to std::wstring, which is a bit overkill. You could have the array store wchar_t* instead, and get rid of the std::string and std::wstring variables, since WritePrivateProfileStringW() takes wchar_t* strings. If you use std::to_wstring() instead of std::to_string(), you can get rid of these std::string variables and ConvertToWideChar() calls.
  9. I use AVG. You might consider adding an exception to it for your data folder.
  10. Must be something specific on your PC. Using Delphi 12.2 Patch 2 on Windows 10 64-bit, when I create an INI file with the specifications you have described, it takes only 150ms with TIniFile. Switch to TMemIniFile and that drops to under 5ms.
  11. Remy Lebeau

    Modern StandBy

    A TTimer HWND shouldn't change, but any VCL UI control can recreate for any number of reasons. Can't rule anything out at this point. So do it manually. Create a temporary button or something that you can trigger at will to log the current HWNDs, then invoke a standby+wakeup, then trigger the log again and compare the results.
  12. Remy Lebeau

    Modern StandBy

    According to MSDN: TTimer is based on a window-based WM_TIMER message. TTimer has an internal HWND that it receives WM_TIMER messages with. And TMemo is another window-based UI control. Are you ABSOLUTELY SURE that your app's message queue is not generating WM_TIMER messages? Never mind whether they are being DELIVERED to TTimer or TMemo - are they being GENERATED at all? The TApplication[Events].OnMessage event should be able to very that, since it sees all messages coming out of the main thread's message queue. Or even a tool like Spy++ or Winsight. For all we know, your windows got recreated and that is why messages are being lost. Who knows. Did you try verifying that the TTimer's HWND and the TMemo's HWND are still the same before the Standby and after the Wakeup? You are looking at multiple things at one time which are acting on top of each other, and not verifying the behavior at the ROOT of the chain of actions.
  13. Remy Lebeau

    Modern StandBy

    That is highly unlikely. If that were true, then all applications would be dead upon wakeup. I think you are misdiagnosing the problem. But, as I don't have an S0-enabled computer, I can't help you diagnose that better. Have you tried using the TApplication[Events].OnMessage event, and TApplication.HookMainWindow() and overriding the TForm.WndProc() method, to actually check that window messages are really no longer being processed? In any case, an application can detect support for Modern Standby by checking the AoAc field returned by GetPwrCapabilities(). And register for notification of Modern Standby/Resume using RegisterSuspendResumeNotification().
  14. Remy Lebeau

    Looking for containskey when processing data

    True, though it is inherited from TJSONValue and not specific to TJSONObject, it has a little more overhead as it performs path processing on the input string and type validation on the output value, and it requires the caller to declare a variable to receive the output value whether the caller actually wants it or not.
  15. Remy Lebeau

    Looking for containskey when processing data

    TJSONObject does not have a ContainsKey() method, in any version of Delphi. If you want that, you can use a class helper, eg: type TJSONObjectHelper = class helper for TJSONObject function ContainsKey(const AKeyName: String): Boolean; end; function TJSONObjectHelper.ContainsKey(const AKeyName: String): Boolean; begin Result := Self.GetValue(AKeyName) <> nil; end; ... if JSONObject.ContainsKey('keyvalue') then As you can see above, you can use the TJSONObject.GetValue() method, which returns nil if the specified key is not found, eg: if (JSONObject.GetValue('keyvalue') <> nil) then
×