Skip to main content
Participating Frequently
June 17, 2008
Question

FDK F_ApiAddText() for pgfs in selected cells crashing FM 7.2?

  • June 17, 2008
  • 9 replies
  • 892 views
I have developed an extension that walks any selection, deletes a few characters and adds new ones. It deals well with text selections, including table anchors and footnotes, and also handles all text in cells of a table selected via an anchor quite well. Text selections within cells also are handled quite well.

If, however, the selection is only individual cells of a table, F_ApiDeleteText() works well on the current pgfId in the cell, and the immediately following F_ApiAddText() first does the right thing as can be seen on screen, and then crashes FM 7.2 with an unhandled exception 0xC0000005 with a read access violation on 0x24.

Why would F_ApiAddText() work fine if I iterate over a whole table with all cells, but fail abysmally if I try to run on a single selected cell?

I even checked all F_ApiAddText() arguments for my test cell and the working and crashing call specify the same docId, pgfId, and offset.

I found in the fdkguide.pdf a cryptic ref that to add text to a cell you need to specify the cell instead of a pgf (which I don't understand as you can have multiple pgf's to work on in a cell), but I am working on a pgf within a cell and it works well ... except if the current selection is only individual cells.

Any suggestions what I am overlooking?

Thanks

Heinz
    This topic has been closed for replies.

    9 replies

    Participating Frequently
    June 19, 2008
    Speaking of an FDK FAQ .. I set up a KB system for FDK issues (and DITA/FM issues) a while back. The idea was that it could be a community-supported knowledge base (hence the name "Community KB"). I'm planning to make the DITA/FM version available soon, but haven't really touched the FDK KB yet.

    Feel free to add your tips (quite useful I might add) to the KB and I'll send out an announcement encouraging others to contribute. Keep in mind that this KB system is still under development, so feel free to let me know about any problems you run into or any improvements you might suggest.

    http://kb.leximation.com/fdk/

    Cheers!

    ...scott

    Scott Prentice
    Leximation, Inc.
    www.leximation.com
    Participating Frequently
    June 19, 2008
    One more for the general public.

    If you want to ensure that F_ApiAddText() and F_ApiDeleteText() work reliably also with a combination of multiple Undo and Selections make sure that you have set a text insertion point before calling those functions. I recommend setting the tr.beg as insertion point. If you don't have an insertion point, Undo will not work reliably. Don't ask my why.

    Maybe we should start an FDK FAQ.

    Heinz
    Legend
    June 19, 2008
    Heinz,

    Many thanks for your report. It is uncommon for someone to report back their solution in such detail. Indeed, the FDK can be a quirky thing. Mostly very stable and reliable, but sometimes requires a little bit of "innovation" to achieve the desired goal. Luckily, there is almost always a way, with an ample amount of said innovation.

    Russ
    Participating Frequently
    June 18, 2008
    Ok, I found a solution. These are my rules now on selections and cells on Windows FM 7.2:

    - Never ever do text manipulations while any selection, text or table cells, is in effect. Always remember the selection, turn it off, change things, and then reset the selection. Read only is ok, but do not modify with active selections. If you try it anyway, rest assured you might spend a few days hunting for phantom crashes.
    - Visible/Editable cells always contain at least one pgf. There is no visible/editable cell without a pgf.
    - The FDK guide states to add text and delete text to a cell by using the cellId, not the pgfId with the Api functions. This is apparently a half truth. Using the cellId is equivalent to targetting the first pgf only. To modify text in any pgf within a cell, you have to specify the containing pgf in any F_TextLocT or Api call as usual. Ensure you don't have any text/cell selections active while doing modifications.
    - When remembering a text selection, you should convert the tr.end.offset into an OffsetFromEnd by obtaining the FTI_PgfEnd for tr.end.objId and then doing an endoffset = FV_OBJ_END_OFFSET - 1 - (ti.val[0].offset - endoffset); Otherwise, modifications within the selection in your last paragraph will change all offsets, and reinstating the selection will be incorrect after the modifications.
    - If your modification actually deletes pgf or cell objects, ensure that you adapt any remembered selection ranges appropriately to not reference deleted objects.
    - Use FP_Displaying=false, but reinstate the previous remembered value and do F_ApiRedisplay() in the end only if it was True before. Don't just blast a True back into the value in your code.

    Std Disclaimer. This works for me. Your mileage may vary. If it helps you fine, if not, sorry.
    Legend
    June 18, 2008
    Heinz,

    I think that the part in the guide is about a cell that currently contains no text at all. If not, then your confusion seems justified... I can't see how that would work.

    Given all that you've said, I don't have any idea what is causing the problem. Have you considered the workaround of simply deselecting the cell, at least while you process, then reselecting it at the end? It might be a little clunky (but should be fast once implemented) to determine, store, and restore the current cell selection but it might be your only option, if this is a bug in the FDK.

    Russ
    Participating Frequently
    June 18, 2008
    One more comment, the FDKguide states as you state that you should pass in a cellId as objId instead of an FO_Pgf.

    I am not quite clear how this should work at all.

    If a cell has multiple pgfs, I would have to add text to a specific pgf, e.g., the 3rd one. if I specify the cell id, how would FM know which paragraph to add to? Or do I have to calculate and aggregate offset by adding the pgf sizes to find the right location in the right pgf while specifying the cell id?! That is nowhere even hinted at.

    Heinz
    Participating Frequently
    June 18, 2008
    For the specific case here, I pass the cell's FP_FirstPgf pgfId in the F_TextLocT with the exact same offset as for deleting characters, i.e., I pass tr.beg as used for deleting characters. I also commented out the delete call to simply add text so that I definitely don't have an invalid location. Still crashed if only cells were selected.

    The really confusing part is that it depends on the initial selection if the call crashes or not, even though it's the identical document. If my iterator function walks selected flow text and then walks the table found by the anchor, it works. If it walks the selected cell directly via the directly selected table if only cells are selected it fails.

    I will look hard at your suggestion about text ranges. Maybe it's a subtle off-by-one bug somewhere that should really crash all the time.
    Legend
    June 17, 2008
    After posting that, I decided to look up that part in the FDK guide. I see I mistated when I said "text range," actually it's a text location that you pass in. I thought that the example in there was reasonably clear... when adding text to a cell (presumably an empty cell only, although it doesn't explicitly say that), the text location structure references the cell ID as the objId, rather than the typical use of an FO_Pgf object. Did you try to do this? Again, I guess I go back to my original question of how you are populating the text location structure.

    Russ
    Legend
    June 17, 2008
    Heinz,

    I'm not completely clear on what you are doing, but I can say that I've seen crashes with F_ApiAddText() when the text range passed in is invalid. If you are attempting to derive the text range from the selection when only a cell is selected, then the range is probably invalid. A cell represents a special kind of text flow... there are no paragraph objects involved when calling the FP_TextSelection property on the document. But, you do say that F_ApiDeleteText() is working, so it seems that you must be getting something right.

    How are you creating the text range structure to send to F_ApiAddText()?

    Russ