Jump to content

pyscripter

Members
  • Content Count

    785
  • Joined

  • Last visited

  • Days Won

    42

Posts posted by pyscripter


  1. 45 minutes ago, Uwe Raabe said:

    Well, I see the font size (and thus TFont.Size) as an invariant in regard to the dpi of the media it is displayed. Keeping the font size constant when changing dpi will always neutralize any rounding errors due to consecutive dpi changes. It doesn't matter if that the current and past implementation doesn't follow this approach. It is never too late to do it right.

    I actually agree, but I wish this was implemented a few years back.

     

    46 minutes ago, Uwe Raabe said:

    BTW, regarding TFontDialog and High DPI: https://quality.embarcadero.com/browse/RSP-34122

    Voted for that.


  2. 5 minutes ago, Uwe Raabe said:

    The advantage of my suggested approach is, that it fixes a whole bunch of scaling errors still existent in Delphi 11.

    With due respect, I think the bugs can be fixed without implementing your proposal.  I have made a number of components (SpTBXLIB, zControls, VirtualExplorerTree, JvDocking, SynEdit, helped with VirtualTreeView) and applications per monitor DPI aware, so I am talking from experience.


  3. 6 hours ago, Uwe Raabe said:

    I may be wrong, but I think the underlying reason is: Font.Size and Font.PixelsPerInch do not respect per-monitor scaling

     

    This has been discussed a lot and font scaling is now re-evaluated.

    A few points related to this:

     

    • It has been like this since High DPI support came to Delphi many versions back.
    • Developers of High Dpi apps have been taking this into account.  Changing this now will break many applications.
    • PixelPerInch is not part of FontData.  It is Delphi that sets it to Screen.PixelsPerInch when a font is created.  Bear in mind that the same font can be used in different devices with different  DPI
    • Font.Size is a calculated property.  It has always been.  Font. Height is what is persisted.
    • The correct way to set a Font to a GivenSize in a form is:  Form.Font.Height := MultDiv(GivenSize, Form.CurrentPPI, 72)
    • When a form is scaled it is the Font.Height that is scaled.
    • Given that both Font.Height and Font.Size are integer properties, they will never be in perfect match.  One of them will be off by a little.  I think it is better to get the pixels right and get used to think in terms of Font.Height.

     

    Also bear in mind that the Windows Font dialog is not per monitor DPI aware and should not be used to set the Font size in per Monitor DPI aware applications.  See High DPI Scaling Improvements for Desktop Applications and “Mixed Mode” DPI Scaling in the Windows 10 Anniversary Update (1607) - Windows Developer Blog for a way to work around this, but it is messy.   It is better to just let the user select a font size from a drop down box and set the Font.Height as suggested above.


  4. The following statement compiles under Delphi 11 64 bits but produces an error in 32 bits.

     

    Assert.AreEqual(Rec.SubRecord.DoubleField, 3.14);

    [dcc32 Error] WrapDelphiTest.pas(357): E2532 Couldn't infer generic type argument from different argument types for method 'AreEqual'

     

    Here is the definition of Assert.AreEqual

     

    class procedure Assert.AreEqual<T>(const expected, actual: T; const message: string);

    Any idea why?


  5. Hard to answer this question in a meaningful way, since it depends a great deal on what you are trying to do.  In general though:


  6. 3 hours ago, Soulflesh said:

    Unfortunately I cannot find anything like "PyBeginAllowThreads" or "AllowThreads" in all sources

    class procedure TPythonThread.Py_Begin_Allow_Threads;

     

    You also need to call Py_End_Allow_Threads when all threads finish.

    • Thanks 1

  7. FProgramName should have a lenght of 0 (empty string) unless you call SetProgramName.

    Could you please check whether UCS4StringToUnicodeString fails with an empty string?

    UCS4String is defined as an array of UCS4Char.

     

    Could this be a fix?


     

    function  TPythonEngine.GetProgramName: UnicodeString;
    begin
    {$IFDEF POSIX}
      if Length(FProgramName) = 0 then
        Result := ''
      else
        Result := UCS4StringToUnicodeString(FProgramName);
    {$ELSE}
      Result := FProgramName;
    {$ENDIF}
    end;

     


  8. 13 hours ago, Mark- said:

    Thanks for the response.

    Are you saying the examples demonstrate an IDE, with debugging, breakpoints, stepping through Python code, variable examination, etc.?

     

    Not quite.   You can use PyScripter code as a basis for providing embedded IDE functionality, however that would be non-trivial.


  9. 1 hour ago, wuwuxin said:

    To be exact,  Py_Begin_Allow_Threads should be called inside PythonEngine.OnAfterInit event,  NOT OnAfterLoad event as advised by @pyscripter 

    I said "after loading" loosely speaking and not "in the OnAfterLoad event".  Indeed you can only call Py_Begin_Allow_Threads after the engine is initialized.

     

    I have not tested, but you can set AutoFinalize to False and in the OnBeforeUnload do

    Py_End_Allow_Threads;
    Finalize;

     

    Also probably, skipping the above when the application closes down may not be necessary.

    • Like 1

  10.  

    3 hours ago, wuwuxin said:

    PyGILState_Ensure is not blocking at all

    Of course it is.   If another thread holds the lock, PyGILState_Ensure blocks until the GIL becomes available, i.e. the holding thread calls PyGILState_Release.  If more than one threads are waiting for GIL then I think it is assigned of FCFS basis.  The automatic switching that you described only applies to threads created with the threading code.  All other threads need to get the GIL before executing python code and then release it.

     

    14 hours ago, wuwuxin said:

    If I use your utility function IPyEngineAndGIL, do I still need to call TPythonThread.Py_Begin_Allow_Threads  (calls PyEval_SaveThread) in the main thread, after loading the Python DLL?

    Yes you do need to call Py_Begin_Allow_Threads in the main thread.   When the python DLL loads, the main thread owns the GIL and it needs to release it before other threads can execute python code.

     

     

    • Like 1

  11. The OleSetClipboardData documentation claims that the Clipboard implements delayed rendering, meaning that it renders a given format of the IDataObject implementation, only when the format is actually requested.

     

    My DataObject implements CF_UNICODETEXT and CF_HTML formats.  As soon as I call OleSetClipboardData both formats are rendered.   Any idea why is that?  How can one implement delayed (lazy) rendering of clipboard formats?

×