Page 1 of 1

An strange behaviour following the SDK statements

PostPosted: Mon Apr 30, 2012 8:21 am
by dec
Hi to all,

One of my friend/customer tell me that found a problem with one of my plugins, which is related with the size of the rectangle in which the plugin put certain control. My suprise is this problem is not exclusively related with this plugin and can be reproduced in all, for example, the SDK plugin samples that attach a control to a rectangle: SpinEdit and Calendar samples.

To reproduce this problem you can use a publication with at least two pages. In the first page, place a rectangle occuping all the page (snap to center) and a button who goto the next page. On the next page just add a button who goto to the previos page. Once this controls are prepared, use a plugin that attach a control to the refered rectangle, for example, the refered Spin Edit or Calendar plugin samples.

Execute the publication and try to resize it. As you can see, all work like expected: the rectangle change their size with the new page size. But now press the goto to next page button, and then, just goto to the previous page again. Try once to resize the publication page... in most cases the plugin control dissapear from the rectangle in wich it's attached. If you don't change the page, everything is OK, but if change between pages, the described problem occur.


The first attempt to found a possible solution pass to take a look at the "WMPluginNotification" method. This method, described in the plugin's SDK, can be used to take care about some important NeoBook messages, for example, this method is invoked when the plugin control host rectangle is resized. Continue to follow the SDK instructions and samples we can found that this message need to be used to resize their plugin control attached to the resized rectangle.

For this this code (in Delphi) is proposed:

Code: Select all
  r: TRect;
  Windows.GetClientRect( Self.ParentWindow, r );

    ( r.Right - r.Left ),
    ( r.Bottom-r.Top ),

And this code work like expected in a normal scenario, and you can see this code on the SDK plugin samples and my plugins as well. However, if you follow the steps I described above in order to reproduce the problem, this code don't provide the appropiated result when the publication has change to another page, and then back to the page that contain the rectangle/plugin control. In this last case, the obtained rect is "out of range", for example, the "r.Right" can have a value of "20238934".

This "out of range" values implied the behaviour descripted by my friend/customer: the plugin control simply "dissapear", without any error or something else. The problem is that I try to get if we have here some problem getting the "parent window handle", and not: apparently this handle is the same (the right handle) in any case, but, for some reason (out of my scope at this momment) the rect is not filled with the correct values, and then the control is situated "out of your eyes".


I found a possible workaround that apparently solve the problem. In fact we can use the "nbInterface" in order to get the object handle that corresponde to the rectangle in wich the plugin control is attached, based on the rectangle name. To my surprise, even when then we use this handle to the their rect, this solution apparently work well, rather than the above code, which apparently fail to retrieve the object rect, as I described, only in you change to another page and then back, etc.

But before I implement my found solution in all my plugins that used a host rectangle, I want to know the opinion of others developers, mainly the opinion of Dave, who maybe can tell us why the above code run like expected in a "one page" scenario, but fail in a "more than one page" scenario. Maybe he can propose another solution that can be better than mine, even when my solution apparently work very well, with no strange or "overload" issues.

Hope this thread can be useful to others plugins developers too, since if we follow the plugin's SDK, maybe we use the above code, and then we share the same problem, since I can test with various of my plugins and the SDK samples plugins and all have the same problem, I think that others developers who used similar code can experiment the same problem too. So maybe you can use my proposed solution or a better solution proposed by NeoSoftware.

And that's all.. if anyone have question about this or need more information or details, please don't hesitate to place a comment on this thread. I now wait for a NeoSoftware answer in order to continue implementing my found solution or maybe I can use another proposed way to do the same in a more elegant way, if is possible.

Thanks to all.

PostPosted: Mon Apr 30, 2012 8:28 am
by dec
Hi again,

Here is a sample compiled publication that used the SDK Calendar sample plugin, try it to view the problem described above:

PostPosted: Mon Apr 30, 2012 10:14 am
by HPW
Hello Dec,

I ran across this problem long time ago and with the help from Dave I solve it. Not sure why it does not find the way into the sample code of the SDK. When I remember right, neobook does delete his objects when it leave a page and recreates it when it enter a page. This will save memory on applications with huge number of pages.

I use this code fragment in WMNotifyPlugIn in all my graphical plugins.
Code: Select all
    P         : PCHAR;
    ObjHandle : HWND;
  CASE Msg.lParam OF
    4 : BEGIN
        IF Assigned( nbInterface ) THEN
             P := NIL;
             SetStr( P, RectangleName );
             nbInterface( 7, P );
             ObjHandle := HWND( StrToInt64Def( P , 0 ) );
             FreeStr( P );

        Windows.GetClientRect( ObjHandle, R );

Use StrToInt64Def for converting the handle since it can become > 32 bit.
That was a long bug hunt in the past to find out that running a windows pc 24/7 can get such big handles.



PostPosted: Mon Apr 30, 2012 11:28 am
by dec
Hi Hans,

Your proposed solution is exactly that I found for my own hands (taken the handle from the host rectangle and use this handle to retrieve the window rect) and yes, apparently this work propertly. However:

Not sure why it does not find the way into the sample code of the SDK. When I remember right, neobook does delete his objects when it leave a page and recreates it when it enter a page.

I can't understand this, since on my tests, if we finally don't use the code exposed above in my first post here, the control stay on their host rectangle like expected, of course it's not resized, but the control is not free. But I think this is not that you want to said: maybe you mean that Neobook made something with the host rectangle which affect to the hosted control?

Well. Anyway, since you found the same solution that I found, and apparently this work propertly (because you use it on your own plugins) I think that can be a good solution, so if Dave don't say any other thing, I implement on my plugins in order to solve this kind of problems, not certaintly in a very rare scenario: since the "crash" is produced only when a page change to another, which is a common task on NeoBook.

Thank you very much for your comments Hans. ;)

PostPosted: Mon Apr 30, 2012 5:24 pm
by dec
Hi there,

Some things that I learn from the related issue. Even when the SDK offer a solution in order to deal with control resize needs, and this this "fail" (on the described scenario) the problem is mine, in the sense that, apparently, it's not possible to assume only one way to do it.

In fact I take an experience with certaion plugin, which use a host rectangle, and I solve the problem using the proposed solution. Well. When I take a look at all the others plugins that use the SDK approach, I found that someones need this approach, and cannot work with others.

So? I learn that every control is different, even when the most of them can be resized in a similar way, others can need an special attention. More now, when I know that "changing a page" can be a possible problem in some specific cases. So the only thing we need is to test a plugin in this scenario.

And then try to do the work: following the SDK approach, follow the proposed above, or, in some cases, a combination of these.