Source language: Translate to:

Parent property on Objects to be embed on Neobook Rectangles

Questions about NeoBook PlugIns

Moderator: Neosoft Support

Parent property on Objects to be embed on Neobook Rectangles

Postby dec » Sun Aug 05, 2007 12:27 pm

Hello,

Maybe anyone can help me. Please, sorry for my poor english.

Ok. Lets go. This question is to plugins Delphi developer or directly to the NeoSoftware Support.

I working on my NeoObjects plugin, and, I have a problem that I dont know to be resolve. I try various possibilies, but, I cant find a solution that real convinced me.

Well. The problem is with the "Parent" property of Object that I try to create on a Neobook rectangle. This Object can handled the keyboard input, but, needed a "Parent" object to this, so, if you assign only the "ParentWindow" property the object can create, but, cant obtain the keyboard focus.

The object that I created rule fine... except that cant obtain the focus user, or, if you use the Neobook action "FocusObject" an error is raised. This is that not real convinced to me. I questioned me and think that other developers (like Hans Peter) create various objects to Neobook, and maybe find a solution for this issue.

This problem not succed on every objects. For example, the "TProgressBar" that includes in my NeoObjects plugin only needed the "ParentWindow", and work nice. If you try to create a "TEdit" everythink work fine too. And every plugins objects examples included on plugins SDK working well only with the "ParentWindow" property. But, in the case of the object that I try to create (and other objects... I try to remember...) maybe is needed a object to assign to the "Parent" property, and, I dont know how make this.

The error message that I obtain: "Control '' has no parent Window". Control not have a name. Maybe the problem is with the component I use, but, I know that this issue appear on other objects when you try to create on a Neobook Rectangle, and, of course, the componentes that I use work fine on Delphi.

The main problem is that the component call to "Controls.SetFocus()" procedure. This is the code of this procedure:

Code: Select all
procedure TWinControl.SetFocus;
var
  Parent: TCustomForm;
begin
  Parent := GetParentForm(Self);
  if Parent <> nil then
    Parent.FocusControl(Self)
  else if ParentWindow <> 0 then
    Windows.SetFocus(Handle)
  else
    ValidParentForm(Self);
end;


Well. ParentForm is "nil", after try with ParentWindow, but, this is 0... and after try "ValidParentForm", that termine raised the exception: "EInvalidOperation".

Ok. This is all, more or less... if you need more information, please, talk me. If you dont understand me (I know, I know), please, talk me and I try to explain more if neccesary.

You can help me? You encounter this problem some day? Any better solution? In any case thanks very much for your patience. Sorry again for my very poor english. Thanks again in advance.

Cheers,

dec

PD. I can edit the source of the components and write some like this:

Code: Select all
if CanFocus() then
  SetFocus();


But, this solution dont convinced me. The objects work more or less fine, but, dont can obtain the keyboard focus, and that I said above, if you use the "FocusObject" action with the Object rectangle... and error appear, just the mentioned above. Thanks again.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby HPW » Sun Aug 05, 2007 1:59 pm

Not sure if this will meet your problem, but once I got this mail from neosoft for a similar problem:

Yes, I think the standard string grid doesn't include the OnSetFocus and OnKillFocus events, so you need to create your own descendant object based on the string grid. For example:

THPWGrid = class(TCustomGrid)
private
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SetFOCUS;
procedure WMKillFocus(var Message: TMessage); message WM_KillFocus;

published
PROPERTY OnSetFocus : TNotifyEvent READ FOnSetFocus WRITE FOnSetFocus;
PROPERTY OnKillFocus : TNotifyEvent READ FOnKillFocus WRITE
FOnKillFocus;
....
end;
Hans-Peter
User avatar
HPW
 
Posts: 2521
Joined: Fri Apr 01, 2005 11:24 pm
Location: Germany

Postby dec » Sun Aug 05, 2007 2:12 pm

Hi Hans,

Thanks very much for your answer. I try with this, but, I not sure that I do on the Messages Handlers... In any case I investigate about "WMSetFocus" and "WMKillFocus" and if this can help me. But the problem is that the component not have a valid "Parent" (the "ParentWindow" not is sufficient, I think) and well...

In any case many thanks Hans. I try and comment here the results. Thanks again.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby dec » Sun Aug 05, 2007 2:55 pm

Hello,

Not working... Maybe I wrong, but, I think that the problems with the focus is in another part. I try explain. The component that I want to embed on a Neobook rectangle contain two component more (container in its), and the "SetFocus" procedure is to this components (the two)...

Maybe I can implement the "WMSetFocus" and "WMKillFocus" on this components too, but, for the examples of this messages that I find on Internet... this messages cant help me in this case, with the problem persists (insist, I maybe wrong), because this component dont have a valid Parent object...

OMG... I continue find a solution for this. If match it, I comment here, of course. If anyone know another possible solution I appreciate. Thanks very very much in advance.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby HPW » Sun Aug 05, 2007 10:18 pm

How I get the parent handle onCreate:

Code: Select all
    { Check NeoBook version number to make sure author is using NeoBook 4.0.9 or higher... }
    IF CheckVer THEN
      BEGIN

        { We only want one grid control per rectangle, so make sure this
          rectangle doesn't already have one... }
        RemoveGridControl( RectangleName, FALSE );

        { Get the window handle of the host NeoBook rectangle object... }
        TRY
          P := NIL;
          SetStr( P, RectangleName );
          nbInterface( 7, P );
          ObjHandle := HWND( StrToInt( P ) );
        FINALLY
          FreeStr( P );
        END;

        IF ObjHandle <> 0 THEN
          BEGIN
            { We found the rectangle's window handle, so attach a control to it... }

            HForm                           := TThpwForm.Create( NIL );
            HForm.ParentWindow              := ObjHandle;
            ...
            ...
            { Stretch the Gridform to match the bounds of the rectangle... }
            Windows.GetClientRect( ObjHandle, R );
            SetWindowPos( HForm.Handle, 0, 0, 0,
              R.Right-R.Left, R.Bottom-R.Top, SWP_SHOWWINDOW );
            ...
            ...
Hans-Peter
User avatar
HPW
 
Posts: 2521
Joined: Fri Apr 01, 2005 11:24 pm
Location: Germany

Postby dec » Mon Aug 06, 2007 1:37 am

Hello,

Thanks very much Hans Peter. This is the "standar" form that obtain the Neobook rectangle handle to be assigned to the "ParentWindow" property, and yes, work fine, and, with litle changes, I write similary code to this.

But, you know, the "ParentWindow" not is the same of "Parent". I try hundred things... try hundred things yesterday, looking for this in Google and found many many answers... But dont work fine.

1º The component create correctly, and show correctly on Neobook rectangle.

2º The component receive the "MouseDown" message and try to "SetFocus" procedure with the two subcomponents.

3º The component raise the "EInvalidOperation" exception with message, "Control '' has no parent Window".

I try to extract the creation of subcomponent of the constructor of the component that container this subcomponents. I try to assign the "ParentWindow" property to the "Handle" of the container component (of course, after that component is create), but dont work.

I try to embed the component on a Panel and on a Form, and after this embed this panel or Form on a Neobook rectangle, but, I dont work in any case.

I try many many thinks... but dont work. Some one maybe remain the focus (aparently and partially) but the error appear in any case. I can develop the component with the condition "not use the FocusObject action with..."

But this not convinced me for two reason: first, the component work fine on Delphi, and I want understand wy not work on Neobook, because this issue maybe appear on others components, I know. And second, the component dont have the keyboard support, only work with the mouse.

Ok. I looking for more information. Thanks many many thanks in any case Hans Peter. Seriosly. :o
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby dec » Mon Aug 06, 2007 4:46 am

Hello,

Here is the code to reproduce the error on Delphi, that is, create a object in a form, but, not assign the "Parent" property, and assign the "ParentWindow" property only.

I try other thinks (yes, more than I ready mentioned above) , but, unfortunatly I dont find the problem. In any case you can view the error in action, with this code, that reproduce the same problem that obtain in Neobook.

I use other components (ficticious Panel component), but, the error is the same. A component contain another component, and when this last component try to obtain the keyboard focus... crash! The control has no parent Window...

Code: Select all
unit UMainFrm;

interface

uses
  Forms, StdCtrls, ExtCtrls, Classes, Controls;

// This object is to be embedded to other
type
  TEmbeddedPanel = class(TPanel)
  protected
    procedure MouseDown(Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer); override;
  end;

// This is the object to be attach to Neobook rectangle
type
  TNeoObjectPanel = class(TPanel)
  private
    FEmbeddedPanel: TEmbeddedPanel;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy(); override;
  end;

// This a main form... only for test the problem...
type
  TmainFrm = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FNeoObjectPanel: TNeoObjectPanel;
  end;

var
  mainFrm: TmainFrm;

implementation

{$R *.dfm}

{ TEmbeddedPanel }

{ This method reproduced the behaviour of the component
  that I work to include on Neobook. The method implementation
  not is important... the important think is that here is call
  to the "SetFocus()" method.

  The problem is centraly here: When you click to the
  "TEmbeddedPanel" object, this try to call a "SetFocus()"
  method, and this cause the error:

  "Control '' has not parent Window"
 
}
procedure TEmbeddedPanel.MouseDown(Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  SetFocus();
end;

{ TNeoObjectPanel }

{ This method reproduced the behaviour of the component
  that I work to include on Neobook. On this object cons-
  tructor another object is created (TEmbeddedPanel) and
  insert it to the component.
}
constructor TNeoObjectPanel.Create(AOwner: TComponent);
begin
  inherited;
  FEmbeddedPanel := TEmbeddedPanel.Create(self);
  InsertControl(FEmbeddedPanel);
  Self.Top := 10;
  Self.Left := 10;
  Self.Width := 100;
  Self.Height := 100;
  with FEmbeddedPanel do
  begin
    Top := 10;
    Left := 10;
    Width := 50;
    Height := 50;
  end;
end;

destructor TNeoObjectPanel.Destroy();
begin
  FEmbeddedPanel.Free();
  inherited;
end;

{ TmainFrm }

{ Here I reproduce the step to create the component
  on a Neobook Rectangle object, that is, use the
  ParentWindow property (not the Parent).
}
procedure TmainFrm.FormCreate(Sender: TObject);
begin
  FNeoObjectPanel := TNeoObjectPanel.Create(nil);
  FNeoObjectPanel.ParentWindow := self.Handle;
end;

procedure TmainFrm.FormDestroy(Sender: TObject);
begin
  FNeoObjectPanel.Free();
end;

end.


Thanks for any help. I continue to be try solve this problem. Thanks again.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby dec » Mon Aug 06, 2007 5:13 am

Hello again,

I think that is a good idea if I attach the above Delphi source sample in a project, and even include the binary. Well. You can download (temporay link) the example that I use to reproduce the problem I have. Thanks again to all.

http://dec.clubdelphi.com/neoplugins/archivos/control-has-no-parent-window.zip
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby dec » Mon Aug 06, 2007 6:48 am

Hello,

A friend (Domingo Seoane) put me a partial solution... use the "CreateParented" instead of "Create" constructor.

But, this work ok on Delphi, but not in Neobook publication... The control dont have the keyboard focus, and, an access violation is random raised at the end of publication.

I continue investigation of this issue. If anybody can help me... thanks very much.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby Neosoft Support » Mon Aug 06, 2007 2:19 pm

Hello Dec,

Try creating a Delphi form and placing your controls onto the form. The form should not have a title bar or border. Then attach the form to the NeoBook rectangle. The form becomes the parent object that your component requires.

For example, create the form like this:

Code: Select all
Form := TMyForm.Create( NIL );


Then attach the form to the NeoBook rectangle like this:

Code: Select all
    { Get the handle of the host NeoBook object... }
    TRY
      P := NIL;
      SetStr( P, ObjName );
      nbInterface( 7, P );
      ObjHandle := HWND( Str2Int( P ) );
    FINALLY
      FreeStr( P );
    END;

    IF ObjHandle <> 0 THEN
      BEGIN
        Windows.GetClientRect( ObjHandle, R );

        Form.ParentWindow := ObjHandle;

        SetWindowPos( Form.Handle, 0, 0, 0, R.Right-R.Left, R.Bottom-R.Top, SWP_SHOWWINDOW );

        Form.Visible := TRUE;
      END;
NeoSoft Support
Neosoft Support
NeoSoft Team
 
Posts: 5605
Joined: Thu Mar 31, 2005 10:48 pm
Location: Oregon, USA

Postby dec » Mon Aug 06, 2007 2:24 pm

Hello,

Thanks very much for your answer. I try to attach the component on a Panel (and not working), but, not in a form and maybe work (I try this just now, when finished this message). I try with many thinks, and reading more documents, but, I cant find a real solution: the component cant obtain the keyboard focus, this is the problem.

Well. Thanks again. I try just now to the solution that you said. I inform here of results. Thanks again NeoSoft Support.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby dec » Mon Aug 06, 2007 3:11 pm

Hello,

The solution work, but, not complete. I try to explain. If I embedd the form (with the component) on a neobook rectangle, the rectangle can obtain the keyboard focus, and the forms can process the "OnKeyUp", for example, but, the component contained in the form not process the keyboard events...

This is, now we set the focus of rectangle object ("nothing is minus"), but, the component remain with no keyboard support... and this component has keyboard support: if you pulse the arrow keys, for example, a arrow is move into de component.

Well, at this moment this is not work. But advance some... now the rectangle can obtain the focus... maybe I can find another solution for the remain issues.

Another problemas appear here. Because, I cant extend a object that contain a variable of type of a Form (that contain the hell component), but, I obtain an error "Resource of TfrmXXX not found"... This occur when I create the form an attach the component in runtime.

Well... thanks very much for your attention. I will try more that found a solution of this problem. I interested of this. If match any idea or have a solution I explain here, of course, in my poor english... and if you have any ideas... I appreciated this.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby dec » Tue Aug 07, 2007 2:56 am

Hello,

Well. Maybe the problem is with te components that I use. I try with other componentes and, more or less, work fine (*). I note, however, some things that I dont undertand completly.

Ok. The problem that principle this thread is solved, used a Form become the Parent of the components, suggested by NeoSoft Support and pointer in some way from Hans Peter.

Thanks very much to all. I dont know if I work with the component that cause this problem, but, in any case, thanks very much for your help.

(*) I noted certain problems with the keyboard focus on many componentes... And this is the primary problem, even in the component that I try to use. The focus, the keyboard focus. I think...
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain

Postby Neosoft Support » Tue Aug 07, 2007 10:23 am

You may need to tell your form that it should be on the lookout for keyboard messages. Try adding the following to your form's declaration:

TMyForm = class(TForm)
...
Private
PROCEDURE WMGetDlgCode( VAR Msg : TWMGetDlgCode ); MESSAGE WM_GETDLGCODE;
...

Then add the following to your form's implementation:

PROCEDURE TMyForm.WMGetDlgCode( VAR Msg : TWMGetDlgCode );
BEGIN
INHERITED;
Msg.Result := DLGC_WANTARROWS OR DLGC_WANTTAB;
END;

Writing plug-ins is a fairly advanced programming topic. Most components can be made to work, but sometimes you have to do unusual things or have access to the source code because component writers don't anticipate that their work will be used as a NeoBook plug-in.
NeoSoft Support
Neosoft Support
NeoSoft Team
 
Posts: 5605
Joined: Thu Mar 31, 2005 10:48 pm
Location: Oregon, USA

Postby dec » Tue Aug 07, 2007 10:28 am

Hello,

Yo have completly reason Neosoft Support, and I try the code that you show. I assume that my knowledge about the Windows API no is complete, for example, and in comparation with you, I supose. I figth with it, but, in certain circunstances I loose.

Well. In any case thanks for your support. I will try with this solution. Yesterday I try to implement the "WMKeyDown" message, and then set the focus on the "problematic" component, but, not work well.

But I not said anymore... I test your code right now.
User avatar
dec
 
Posts: 1663
Joined: Wed Nov 16, 2005 12:48 am
Location: Spain


Return to PlugIn Discussions

Who is online

Users browsing this forum: No registered users and 2 guests