Jump to content

uligerhardt

Members
  • Content Count

    83
  • Joined

  • Last visited

Posts posted by uligerhardt


  1. 49 minutes ago, David Schwartz said:

    Just comment out a line then save the file. The ones that are needed will be added at the end.

     

    No compilation needed.

    That's only true for the uses-clause entries that the form designer manages. (Which is a tiny fraction in my development.)

    • Like 1

  2. 6 hours ago, Anders Melander said:

    Isn't this just something that read metadata from WinMD and write wrappers? You can do that already so I guess the news is that they're generating WinMD from the SDK headers.

     

    This is about generating wrappers for classic Win32 API, Not some WinRT stuff. Autogenerate Windows.pas! 😎


  3. 13 hours ago, Remy Lebeau said:

    Did you try the WH_CBT hook, like I suggested?  For example:

    
    uses
      ..., Windows;
    
    type
      TPrintLLReportEventHandler = class
      private
        FHook: HHOOK;
      public
        constructor Create;
        destructor Destroy; override;
        procedure OnViewerButtonClicked(Sender: TObject; Button: TViewerButton; var PerformDefaultAction: Boolean);
      end;
    
    { TPrintLLReportEventHandler }
    
    var
      gPrintReportWnd: HWND = 0;
    
    function CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    begin
      if nCode = HCBT_ACTIVATE then
      begin
        if gPrintReportWnd = 0 then
          gPrintReportWnd := HWND(wParam);
      end;
      Result := CallNextHookEx(0, nCode, wParam, lParam);
    end;
    
    constructor TPrintLLReportEventHandler.Create;
    begin
      inherited;
      gPrintReportWnd := 0;
      FHook := SetWindowsHookEx(WH_CBT, @CBTProc, HInstance, GetCurrentThreadId);
    end;
    
    destructor TPrintLLReportEventHandler.Destroy;
    begin
      if FHook <> 0 then
        UnhookWindowsHookEx(FHook);
      gPrintReportWnd := 0;
      inherited;
    end;
    
    procedure TPrintLLReportEventHandler.OnViewerButtonClicked(Sender: TObject; Button: TViewerButton; var PerformDefaultAction: Boolean);
    begin
      if Button = vbExit then
      begin
        MessageBox(gPrintReportWnd, ...);
      end;
    end;
    
    var
      evh: TPrintLLReportEventHandler;
    begin
      evh := TPrintLLReportEventHandler.Create;
      try
        MyLLReportInstance.OnViewerButtonClicked := evh.OnViewerButtonClicked;
        // Show preview here (using LL_PRINT_PREVIEW)
      finally
        evh.Free;
      end;
    end;

     

    I tried it just now, and it works AFAICT - I used

    GetWindowText(gPrintReportWnd, ...)

    to verify. Thanks a lot.


  4. Here is the relevant code, a bit condensed:

    type
      TPrintLLReportEventHandler = class
      public
        procedure OnViewerButtonClicked(Sender: TObject; Button: TViewerButton; var PerformDefaultAction: Boolean);
      end;
    
    { TPrintLLReportEventHandler }
    
    procedure TPrintLLReportEventHandler.OnViewerButtonClicked(Sender: TObject; Button: TViewerButton; var PerformDefaultAction: Boolean);
    begin
      if Button = vbExit then
      begin
        MessageBox(AWnd, .....); // <= I'd like to get the preview form's window handle here for AWnd
      end;
    end;
    var
      evh: TPrintLLReportEventHandler;
    
        evh := TPrintLLReportEventHandler.Create;
        try
          MyLLReportInstance.OnViewerButtonClicked := evh.OnViewerButtonClicked;
          // Show preview here (using LL_PRINT_PREVIEW)
        finally
          evh.Free;
        end;

     


  5. 20 hours ago, Schokohase said:

    You cannot rely on something that is wrong - it does not happen that way. Period.

     

    But you can rely on a unit test.

    
    unit UnitTests.System.Types.TPoint;
    
    interface
    
    uses
      System.Types,
      DUnitX.TestFramework;
    
    type
    
      [TestFixture]
      TPointTests = class(TObject)
      public
        [Test]
        procedure ExplicitTSmallPointHigh();
        [Test]
        procedure ExplicitTSmallPointLow();
        [Test]
        procedure ExplicitTSmallPointHighPlus1();
        [Test]
        procedure ExplicitTSmallPointLowMinus1();
      end;
    
    implementation
    
    procedure TPointTests.ExplicitTSmallPointHigh;
    var
      p: TPoint;
      sp: TSmallPoint;
    begin
      // arrange
      p := TPoint.Create(High(SmallInt), High(SmallInt));
      // act
      sp := TSmallPoint(p);
      // assert
      Assert.AreEqual(High(SmallInt), sp.x, 'TSmallPoint.X');
      Assert.AreEqual(High(SmallInt), sp.y, 'TSmallPoint.Y');
    end;
    
    procedure TPointTests.ExplicitTSmallPointHighPlus1;
    var
      p: TPoint;
      sp: TSmallPoint;
    begin
      // arrange
      p := TPoint.Create(High(SmallInt)+1, High(SmallInt)+1);
      // act
      sp := TSmallPoint(p);
      // assert
      Assert.AreEqual(High(SmallInt), sp.x, 'TSmallPoint.X');
      Assert.AreEqual(High(SmallInt), sp.y, 'TSmallPoint.Y');
    end;
    
    procedure TPointTests.ExplicitTSmallPointLow;
    var
      p: TPoint;
      sp: TSmallPoint;
    begin
      // arrange
      p := TPoint.Create(Low(SmallInt), Low(SmallInt));
      // act
      sp := TSmallPoint(p);
      // assert
      Assert.AreEqual(Low(SmallInt), sp.x, 'TSmallPoint.X');
      Assert.AreEqual(Low(SmallInt), sp.y, 'TSmallPoint.Y');
    end;
    
    procedure TPointTests.ExplicitTSmallPointLowMinus1;
    var
      p: TPoint;
      sp: TSmallPoint;
    begin
      // arrange
      p := TPoint.Create(Low(SmallInt)-1, Low(SmallInt)-1);
      // act
      sp := TSmallPoint(p);
      // assert
      Assert.AreEqual(Low(SmallInt), sp.x, 'TSmallPoint.X');
      Assert.AreEqual(Low(SmallInt), sp.y, 'TSmallPoint.Y');
    end;
    
    initialization
    
    TDUnitX.RegisterTestFixture(TPointTests);
    
    end.

    Boom 2 times

    
    **********************************************************************
    *        DUnitX - (c) 2015-2018 Vincent Parrett & Contributors       *
    *                                                                    *
    *        License - http://www.apache.org/licenses/LICENSE-2.0        *
    **********************************************************************
    
    DUnitX - [UnitTests.exe] - Starting Tests.
    
    .F.F....
    
    Tests Found   : 4
    Tests Ignored : 0
    Tests Passed  : 2
    Tests Leaked  : 0
    Tests Failed  : 2
    Tests Errored : 0
    
    Failing Tests
    
      UnitTests.System.Types.TPoint.TPointTests.ExplicitTSmallPointHigh
      Message: Expected 32767 is not equal to actual 6692 TSmallPoint.X
    
      UnitTests.System.Types.TPoint.TPointTests.ExplicitTSmallPointLow
      Message: Expected -32768 is not equal to actual 6693 TSmallPoint.X
    
    
    Done.. press <Enter> key to quit.

    The funny thing is, we have a random number generator.

    I wasn't clear enough... Why would you rely on this even if it worked?

    • Like 1

  6. 20 hours ago, stijnsanders said:

    Guys, are all of you missing this? Due to the Pascal calling convention, the first (plain!) argument of a function maps into the same register(s), so in fact this is valid and correct code. Though strictly I agree it looks weird and like as if in 'normal' cases the Value members aren't assigned to Result members. Bit in fact, they're already there! So what is actually needed is a 'type size limiting' cast, which is exactly what Result.x:=SmallInt(Result.x); is.

    Why would you rely on this? Without the tiniest comment?


  7. 10 hours ago, Rudy Velthuis said:

    Yes, indeed, so would I. But you have to create and free those, to really stay inside the type system.

    No, that's why I'm talking about class methods. You can use them like this:

    type
      TMyEventHandler = class
      public
        class procedure OnError(const AMessage: string);
      end;
    
    Something.OnError := TMyEventHandler.OnError;

    The method has to be non-static to provide the needed Self parameter.

    • Like 3
×