Home > Mobile >  How to create a non visual component without any icon on the form?
How to create a non visual component without any icon on the form?

Time:09-23

I would like to create a non visual component (like TTimer for example) that I can drop on the form and that I can set up directly from the Object Inspector, but I don't want to see its icon on the form (it'd just obstruct anything). For example TFloatAnimation works like this but I don't understand how.

CodePudding user response:

The GExperts library (http://www.gexperts.org/) has a plug-in which can toggle the visibility of non-visual components on a form, and it is apparently not Delphi-version-specific but it is not exactly trivial.

The method which does this is

    procedure THideNonVisualCompsExpert.ToggleNonVisualVisible(Form: TCustomForm);
    const
      NonVisualClassName = 'TContainer';
    var
      VisibleState: Boolean;
      FormHandle: THandle;
      CompHandle: THandle;
      WindowClass: string;
      FirstCompFound: Boolean;
      WinControl: TWinControl;
      ChildControl: TWinControl;
      i: Integer;
    begin
      Assert(Assigned(Form));
      Assert(Form.Handle > 0);
      FirstCompFound := False;
      WinControl := Form;
      if InheritsFromClass(WinControl.ClassType, 'TWinControlForm') then
      begin
        for i := WinControl.ComponentCount - 1 downto 0 do
        begin
          if WinControl.Controls[i] is TWinControl then
          begin
            ChildControl := WinControl.Controls[i] as TWinControl;
            if InheritsFromClass(ChildControl.ClassType, 'TCustomFrame') then
            begin
              WinControl := ChildControl;
              Break;
            end;
          end;
        end;
      end;

      FormHandle := GetWindow(WinControl.Handle, GW_CHILD);
      CompHandle := GetWindow(FormHandle, GW_HWNDLAST);
      VisibleState := False;
      GxOtaClearSelectionOnCurrentForm;

      while (CompHandle <> 0) do
      begin
        WindowClass := GetWindowClassName(CompHandle);
        if AnsiSameText(WindowClass, NonVisualClassName) then
        begin
          if not FirstCompFound then
          begin
            VisibleState := not IsWindowVisible(CompHandle);
            FirstCompFound := True;
          end;
          if VisibleState then
            ShowWindow(CompHandle, SW_SHOW)
          else
            ShowWindow(CompHandle, SW_HIDE);
        end;
        CompHandle := GetWindow(CompHandle, GW_HWNDPREV);
      end;
    end;

in the unit GX_HideNonVisualComps.Pas.

As written, it toggles the visibility of all the non-visual components on the target form, but looking at the code of the ToggleNonVisualVisible method it looks like it ought to be possible (but I have not tried) to adapt it to operate on a selected component class and force instances of the class to a non-visible state. Once you have done that, you would probably need to experiment with how and when to invoke the method at design-time; if I was doing it, I would probably start with somewhere like the target component's Loaded method.

(I would feel more comfortable posting this "answer" as a comment but obviously it would be too long)

CodePudding user response:

I have thought about this. A Non Visual Component does not do any painting, in a Windows environment (like the IDE) it has no Window, and therefore cannot influence how the IDE chooses to render it.

One approach would be to derive from TWinControl, making your component a Visual Component, and then to ensure that it is not drawn. Try setting the positioning properties to be non-published, and when you are parented, always set your position outside the parent window. This means that your control is always clipped and never painted.

I haven't tried this, but I can see no reason why it wouldn't work.

You can also use this approach to have an apparently non visual component that renders information in the IDE at designtime, but not at runtime.

  • Related