Jump to content

Anders Melander

Members
  • Content Count

    2771
  • Joined

  • Last visited

  • Days Won

    147

Everything posted by Anders Melander

  1. Anders Melander

    Load form icon while using styles

    That's pretty easy: RecreateWnd is part of the documented public API. CM_RECREATEWND is undocumented. The VCL core is the implementation of the API so there's no surprise there. No I am not. I said "it seems" so I'm talking about appearances. I have no idea about why you do what you do so I can only guess. Calm down. I'm free to state what I think he means since it seems you misunderstood what he said. There is no conspiracy here and we're not all out to get you. We just disagree with you.
  2. Anders Melander

    Load form icon while using styles

    I think the point is that you are violating the API contract; You are supposed to call the API but instead you are circumventing the API and calling the implementation directly - for no good reason. Sometimes there are good reasons to do so but this isn't one of them so it seems you are doing so just because you can, because you don't know better or because you are stubborn. There are multiple definitions of perverse. In this case I think David meant obstinate in opposing what is right, reasonable, or accepted (from Merriam-Webster).
  3. Anders Melander

    How to make an "About" for a simple component?

    The OP asked for design time functionality. I replied with a design time solution and stated that there's no need for a run time package, so I don't understand what you are arguing about; You are the only one mentioning run-time executables. Here's a complete solution in a single design-time package: The component unit: unit amAwesome; interface uses Classes; type TMyAwesomeComponent = class(TComponent) // You awesome code here end; implementation end. The design time unit: unit amAwesomeDesign; interface procedure Register; implementation uses Classes, VCL.Dialogs, DesignIntf, DesignEditors, amAwesome; type TMyAwesomeComponentEditor = class(TComponentEditor) public function GetVerb(Index: Integer): string; override; function GetVerbCount: Integer; override; procedure ExecuteVerb(Index: Integer); override; end; procedure Register; begin RegisterComponents('Awesome', [TMyAwesomeComponent]); RegisterComponentEditor(TMyAwesomeComponent, TMyAwesomeComponentEditor); end; procedure TMyAwesomeComponentEditor.ExecuteVerb(Index: Integer); begin var LocalIndex := Index - inherited GetVerbCount; case (LocalIndex) of 0: ShowMessage('TMyAwesomeComponent 1.0'); else inherited ExecuteVerb(Index); end; end; function TMyAwesomeComponentEditor.GetVerb(Index: Integer): string; begin var LocalIndex := Index - inherited GetVerbCount; case (LocalIndex) of 0: Result := 'About...'; else Result := inherited GetVerb(Index); end; end; function TMyAwesomeComponentEditor.GetVerbCount: Integer; begin Result := inherited GetVerbCount + 1; end; end. The design time package source: package AwesomeSuite; {$R *.res} {yada yada yada lots of options here...} {$DESIGNONLY} requires rtl, designide; contains amAwesome in 'amAwesome.pas', amAwesomeDesign in 'amAwesomeDesign.pas'; end.
  4. Anders Melander

    How to make an "About" for a simple component?

    There's no requirement for both run- and design-time packages. A design time package alone is enough. Assuming you mean component editor the purpose is to separate run- and design-time functionality. The end-user doesn't need to know that the application uses TAwesomeComponent version x.y.z and there's no need to include the about form in the compiled application.
  5. Anders Melander

    Hints and ShowHint

    Yes of course and it does but ShowHint controls if the control supplies hint text when the mouse hovers over the control. If it doesn't then it will try to get the hint from the parent control, etc. The help is pretty clear on how it works.
  6. Anders Melander

    How to make an "About" for a simple component?

    Okay. What you need is a component editor. With this you can specify what happens when the user double clicks your component (at design time) and you can add menu items to the context menu. For example a "About My Awesome Component..." menu item. The help is a bit sparse on how to implement a component editor for VCL (there's a good example for FireMonkey though) but there's plenty of examples available on the net: https://www.google.com/search?q=delphi+component+editor There might also be an example installed with Delphi.
  7. Anders Melander

    Hints and ShowHint

    Don't do that. You're trying to eliminate the symptoms of a problem somewhere else in your application. Hint/ShowHint works just fine. If you manage to "hide" the problem by setting ShowHint=False then you will just have removed the only lead you currently have to the underlying problem. By the way, ShowHint does more than controlling if the control displays hints. It also controls if the child controls display hints - if Child.ParentShowHint=True. You usually set ShowHint=True on the form and then ParentShowHint=True on all child controls. Setting ParentShowHint=True just means that the parent ShowHint value propagates down to the child control. Anyway, what I would do is install MadExcept and configure it to "Instantly crash on buffer overrun". I'm guessing you have a stale pointer or a memory overwrite somewhere.
  8. Anders Melander

    How to make an "About" for a simple component?

    I think you need to explain a little bit better what you are trying to do. Start with an example of how you would like to use your component. Once we understand that we can better help you with how to implement it.
  9. Anders Melander

    Should Delphi have native interfaces?

    Sorry to continue this but I simply don't get it; Your example works exactly as I would expect. You're telling the compiler to use two different implementations for IBar.Foo and IFoo.Foo. Even though interface B inherits from A and we have an object that implements both A and B, their shared methods (the ones from A) need not be the same (but they can be if you choose that). In fact COM explicitly states that it's the API that is inherited, not the implementation. Your example more or less corresponds to: type IFoo = interface ['{1E77F313-1C93-4A59-957B-751FB23EC63F}'] end; IBar = interface(IFoo) ['{49FC3BDA-7A09-4596-A80C-5EBEF73BA201}'] end; TFooBar = class(TInterfacedObject, IFoo, IBar) private FFoo: IFoo; FBar: IBar; public property Foo: IFoo read IFoo implements IFoo; property Bar: IBar read FBar implements IBar; end; That's a secondary source. I'm looking for a primary one or at least a more reputable one.
  10. Anders Melander

    Should Delphi have native interfaces?

    Do you have any sources for this bug in COM or can you explain what bug is? Edit: Never mind. You just did.
  11. Anders Melander

    Should Delphi have native interfaces?

    Thank you! This is in line with my understanding of the rules of COM. It seems that, unlike Kaster (it's a bug, it's a bug), Chuck (it's by design) actually read the books.
  12. Anders Melander

    Should Delphi have native interfaces?

    Why would you need a GUID if this is supposed to be "COM free"?
  13. Anders Melander

    Should Delphi have native interfaces?

    You are correct: type IBar = interface ['{570FBD40-8ECF-4B4B-9898-EF3F4146FFF9}'] end; IFooBar = interface(IBar) ['{F99BAE4A-6612-4714-96B4-237763239C7F}'] end; type TFooBar = class(TInterfacedObject, IFooBar) end; procedure test; begin var FooBar: IFooBar := TFooBar.Create; var Bar: IBar := FooBar; end; ...but as we already know... var FooBar: IFooBar := TFooBar.Create; Assert(Supports(FooBar, IBar)); ...will fail, so there's a bug somewhere - or at least a really bad inconsistency. Supports just does a IUnknown.QueryInterface which ends up in TObject.GetInterface. The assignment on the other hand just copies the pointer and calls _AddRef. From my understanding on what interface inheritance is in Delphi, Supports() is correct and the compiler is wrong but there are obviously different interpretations of this.
  14. Anders Melander

    Should Delphi have native interfaces?

    But it isn't true. The IFooBar interface inherits the methods of IBar - at compile time. The implementing object doesn't inherit the contract that it must implement the IBar interface. I'm not convinced that John Kaster knew what he was talking about when he wrote that. I mostly included the link because it seems to be the earliest mention of the feature. The limitation as-is matches my recollection of "the rules of COM" but I could be mistaken. I'm not up to reading the COM bible again just to find out. It was hard enough the first time(s).
  15. Anders Melander

    Should Delphi have native interfaces?

    I agree. Interface inheritance is just syntactic sugar. http://edn.embarcadero.com/article/29779 (warning this links contain references to The Version That Must Not Be Mentioned: Delphi 8)
  16. Anders Melander

    Should Delphi have native interfaces?

    I think I have encountered this problem on rare occasions but I can't remember the circumstances. Did you mean interface inheritance? For example the following works fine: type IFoo = interface ['{F99BAE4A-6612-4714-96B4-237763239C7F}'] end; IBar = interface ['{570FBD40-8ECF-4B4B-9898-EF3F4146FFF9}'] end; type TFoo = class(TInterfacedObject, IFoo) end; TBar = class(TFoo, IBar) end; type TFooObject = class(TComponent, IFoo) end; TBarObject = class(TFooObject, IBar) end; procedure Test; begin // Supports(interface) var FooBar := TBar.Create as IUnknown; Assert(Supports(FooBar, IFoo)); Assert(Supports(FooBar, IBar)); // Supports(instance) var FooBarObject := TBarObject.Create(nil); Assert(Supports(FooBarObject, IFoo)); Assert(Supports(FooBarObject, IBar)); end;
  17. Anders Melander

    TMemoryStream.Write

    It sounds like you fell into the premature optimization trap; "Optimized" something because it looked inefficient without actually measuring if it would matter.
  18. Anders Melander

    Your RAD Studio 10.4 Sydney issues

    Pfft. That is up to the customer to decide. [edit: before I start a sh*t storm let me rephrase that] It should be up to the customer to decide. Not you, not Embarcadero and not Microsoft. If the customer wants to run on Windows 7, which I perfectly understand in many cases, then I will support it. They are paying for that privilege. We are here to serve their needs, not the other way around. Windows 7 has a market share around 20%. Slightly higher than OS X... Works for me. It complained to install but I haven't encountered any issues that I can pin on Windows 7.
  19. Anders Melander

    Your RAD Studio 10.4 Sydney issues

    @Kazantsev Alexey Yes now I understand. Thanks.
  20. Anders Melander

    Converting project from Delphi 2006 to Delphi 10.2

    Yes. Like I implied. Or just use the code I used: In the OP's example it doesn't matter much but a real StrLPas would be more efficient as it would avoid the reallocation (like your example).
  21. Anders Melander

    Converting project from Delphi 2006 to Delphi 10.2

    Okay, so do we agree that it's not equivalent to StrLPas?
  22. Anders Melander

    Your RAD Studio 10.4 Sydney issues

    Um... Aren't you responsible for initializing the record yourself if you have declared an initializer for the record?
  23. Anders Melander

    Converting project from Delphi 2006 to Delphi 10.2

    In my example there's already room for 65 characters in the destination since Delphi strings have an implicit null terminator.
  24. Anders Melander

    Converting project from Delphi 2006 to Delphi 10.2

    I can't tell from the documentation if SetString copies up to Length characters or always Length characters and it seems to be an intrinsic function so I can't check the source.
  25. Anders Melander

    Converting project from Delphi 2006 to Delphi 10.2

    You need to use StrLCopy instead of StrPas since there's no guarantee that the source string is null terminated. You actually need a StrLPas function but fo some reason they've never implemented that variant. Also remember that the buffer is a static array[] of Char[0..63] so you need to iterate the outer array somehow. var Buffer: PChar; GetMem(Buffer, PaperCount*SizeOf(Char)); try var p := Buffer; for i := 0 to PaperCount-1 do begin var PaperName: string; SetLength(PaperName, 64); StrLCopy(PChar(PaperName), p, 64); PaperName := PChar(PaperName); // or SetLength(PaperName, StrLen(PChar(PaperName))) ... Inc(p, 64); end; finally FreeMem(Buffer); end;
×