Beiträge von Leander

    I can't demonstrate problem 1 with just a html file, because the problem occurs when the _OnInternPaintPar event is used for drawing. I would need to construct a demo application to demonstrate this. Right now i don't have the time to produce one, but i feel the code itself should be obvious.

    simple application to demonstrate problem 2:

    You'll notice the first paragraph is no longer hidden when wpFormatAsWebpage is set.

    WpTools 6.13.1

    In our application we have started using the (relatively new) AsWebPage property. This could finally enable us to use wptools as a html viewer for email. Prior to this we could only use wptools for composing an email, but when we our application for example received a newsletter we relied on different components to view them.

    So, a big thank you for this.

    So this week i have started implementing and testing the feature and found a few problems with it.

    Problem 1:
    Painting before line text seems to occur after the line text is drawn. For us this only seems to go wrong with certain tables. (If needed i can provide a demo)
    I do not yet understand why wpFormatAsWebpage influences the behavior, but i did find the following in the code that seems wrong.

    Code
    if assigned( _OnInternPaintPar ) then      begin         _OnInternPaintPar(_EditBox, wpBeforeLineText, Self, LineData, rtfpage, LineData.Par,            LineData.LineNr, DestCanvas, ParColorOverride, TextColorOverride, AnyObject, StandardIgnore);      end;.....if assigned( _OnInternPaintPar ) then      begin         _OnInternPaintPar(_EditBox, wpAfterLineText, Self, LineData, rtfpage, LineData.Par,            LineData.LineNr, DestCanvas, ParColorOverride, TextColorOverride, AnyObject, StandardIgnore);      end;      {$ENDIF}.....            {$IFDEF WP6}      ParColorOverride := clNone;      TextColorOverride:= clNone;      AnyObject := nil;      StandardIgnore := false;      if assigned( _OnInternPaintPar ) then      begin         _OnInternPaintPar(_EditBox, wpBeforeLineText, Self, LineData, rtfpage, LineData.Par,            LineData.LineNr, DestCanvas, ParColorOverride, TextColorOverride, AnyObject, StandardIgnore);      end;      {$ENDIF}if ...elsebegin  ....  if ...  begin  end  else  try     ...    PaintLine    if assigned( _OnInternPaintPar ) then      begin         _OnInternPaintPar(_EditBox, wpAfterLineText, Self, LineData, rtfpage, LineData.Par,            LineData.LineNr, DestCanvas, ParColorOverride, TextColorOverride, AnyObject, StandardIgnore);      end;  except  end;

    It seems the second call to _OnInternPaintPar with parameter wpBeforeLineText should be within the same compound statement as the call with PaintLine and the last _OnInternPaintPar. Now it is possible "wpBeforeLineText" is executed without a following call to "LineText" and "wpAfterLineText"

    Problem 2:
    Hiding paragraphs with paragraph property paprHidden doesn't work anymore.
    Tracing this in the code was difficult, but it seems wpFormatAsWebPage calls a different format routine for the paragraph, which means that it differs on several thousands lines of code. This does make me wonder how much more paragraph functionality is now lost, but maybe i'm looking at it the wrong way.

    I did find a way to "solve" this in the code. See below. Change has been marked with {$IFDEF OBEC}

    It is difficult to see if there is a downside to this fix. And i'm not sure it will prove strong enough.

    I upgraded WPTools recently from 6.0.3 to 6.13.1 and today ran into what seems to be the exact same problem.

    The problem is that the html writer now only saves images if they have an objref. The objref won't be assigned though by the RTF reader, unless you implement the OnRequestHTTPImage event.
    This isn't very efficient though for converting RTF - HTML, because you will need to load all the images.

    Took me a few hours to track this one down...

    Code
    function TWPHTMLWriter.WriteObject.... if (txtobj.ObjType = wpobjImage) and (txtobj.ObjRef<>nil) then....

    This used to be

    Code
    function TWPHTMLWriter.WriteObject
    ....
     if (txtobj.ObjType = wpobjImage) then
    ....

    ( Perhaps this issue has been resolved already. I have not tried the latest version yet. )

    Hi Roy.

    I experienced the exact same problem you are having after having updated WpTools 5 to WpTools 6.
    I managed to track down the problem to the following code inside unit WPRTEPaint.pas

    Code
    {$IFDEF WP6} 
                  if aCursor.active_posinpar = 0 then
                  begin
                    apar := aCursor.active_paragraph;
                    while (apar <> nil) and (apar.prev <> nil) and (apar.CharCount = 0) do apar := apar.prev;
                    protmode := IsProtected(apar, apar.CharCount - 1);
                  end else
    {$ENDIF}

    The same code appears on 2 different places inside the method:
    function TWPRTFEnginePaint.InputString(const Text: string;
    HandlePaint: Boolean = FALSE; CodePage: Integer = 0): Boolean;

    If you comment this code i believe all your problems will be gone, at least thats what it did for me.

    I also do not understand the logic behind it. If you are at the first position in a empty paragraph the paragraph protection will be decided by the protection on a previous paragraph. It doesn't seem like something most people would consider helpfull.

    I'm probably doing something wrong with adding 1 new paragraph, because i used this:

    Code
    lvRtfDataCollection.SelectBody;lvRTFDataCollection.FirstPar.AppendNewPar(True); //added this linelvTable := TParagraph.CreateTable(lvRTFDataCollection.FirstPar)

    This still failed for me, but i'm not certain that a paragraph was added after the table. Its more as if the table replaces the paragraph.

    The following however did work:

    Code
    lvRtfDataCollection.SelectBody;
    lvRTFDataCollection.FirstPar.AppendNewPar(True).AppendNewPar(True); //added this line
    lvTable := TParagraph.CreateTable(lvRTFDataCollection.FirstPar)

    So you were correct.

    It's a shame though that hiding this paragraph (paprHidden), will have the same effect for me as not creating a paragraph at all. And setting the lineheight with lvPar.Aset(WPAT_LineHeight, 1); doesn't seem to effect the paragraph at all.

    So i'll be forced to show an empty paragraph, but that's still acceptable.

    Many thanks.

    I already tried adding an additional paragraph, and i'm sure this will work for the WPT format, but unfortunately we need to use the RTF Format.

    I have been able to change the rtf reader so the closing field is placed after the table, but all content after the closing tag will then obtain (some of) the same attributes as the closing tag itself. Particulary making the text uneditable (protected).

    I've saved the following RTF from a TWPRichtext. The table is inserted into the mergefield using the mergetext routine.

    Zitat

    {\rtf1\ansi\deff0\uc1\ansicpg1252\deftab720{\fonttbl{\f0\fnil\fcharset1 Arial;}{\f1\fnil\fcharset0 Arial;}{\f2\fnil\fcharset1 Wingdings;}{\f3\fnil\fcharset0 Univers;}{\f4\fnil\fcharset0 Arial Black;}}{\colortbl\red0\green0\blue0;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red255\green255\blue0;\red255\green0\blue255;\red128\green0\blue128;\red128\green0\blue0;\red0\green255\blue0;\red0\green255\blue255;\red0\green128\blue128;\red0\green0\blue128;\red255\green255\blue255;\red192\green192\blue192;\red128\green128\blue128;\red0\green0\blue0;\red230\green230\blue230;\red128\green128\blue0;}\wpprheadfoot1\paperw12240\paperh15840\margl1880\margr1880\margt1440\margb1440\headery720\footery720\endnhere\sectdefaultcl{\*\generator WPTools_5.350;}{\*\userprops {\propname papername}\proptype30{\staticval Letter} }{\pard\plain\plain\fs22\par \pard\plain\plain\fs22\par \plain\fs22 TEST\par \pard\plain\plain\fs22\par \plain\fs22{\field{\*\fldinst{MERGEFIELD recxml_sndAdressen|TXMLAddressListbox_LSTTABLE$COL#Adres}}{\*\wpfldparam{[recxml_sndAdressen|TXMLAddressListbox_LSTTABLE$COL#Adres]}}{\fldrslt{\par \tblstart1{\trowd\trleft0\trbrdrl\brdrs\trbrdrr\brdrs\trbrdrt\brdrs\trbrdrb\brdrs\trftsWidth2\trwWidth5000\clbrdrb\brdrs\brdrw10\clbrdrr\brdrs\brdrw10\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clcbpat13\clftsWidth3\clwWidth4230\clvertalt\cellx4230\clbrdrb\brdrs\brdrw10\clbrdrr\brdrs\brdrw10\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clcbpat13\clftsWidth3\clwWidth4230\clvertalt\cellx8460\pard\intbl\itap1\li0\fi0\ri0\sb0\sa0\ql\clcbpat13\plain\fs22 zakelijk\cell\pard\intbl\itap1\li0\fi0\ri0\sb0\sa0\ql\clcbpat13\plain\fs22 Hazestraat 1 5555 AB VALKENSWAARD\cell\row}{\trowd\trleft0\trbrdrl\brdrs\trbrdrr\brdrs\trbrdrt\brdrs\trbrdrb\brdrs\trftsWidth2\trwWidth5000\clbrdrb\brdrs\brdrw10\clbrdrr\brdrs\brdrw10\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clcbpat13\clftsWidth3\clwWidth4230\clvertalt\cellx4230\clbrdrb\brdrs\brdrw10\clbrdrr\brdrs\brdrw10\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clcbpat13\clftsWidth3\clwWidth4230\clvertalt\cellx8460\pard\intbl\itap1\li0\fi0\ri0\sb0\sa0\ql\clcbpat13\plain\fs22\cell\pard\intbl\itap1\li0\fi0\ri0\sb0\sa0\ql\clcbpat13\plain\fs22 Kastanjelaan 1 6666 AA HETEREN\cell\row}\tblend1\pard\plain\plain\fs22}}}\par \pard\plain\plain\fs22\par \plain\fs22 TEST\par \pard\plain\plain\fs22\par \pard\plain\plain\fs22\par }}

    If i load this file into the same WpTools editor and use mergetext once more, the merge content will be placed before the previous table, instead of replacing the table that is inside the mergefield.

    It looks as if the mergefield closing object is placed on the first paragraph of the table when loading it inside wptools. When it should be placed after the table.

    Is there anything i can do to fix this behavior.

    Thanks in advance,

    Leander


    WpTools 5.36

    Since Julian is on his vacation i have dug up this code that i wrote a long time ago. This code has not been used or maintained since, so i can't be certain if it will still work, but it is something we are going to use sometime soon.

    TCsTreeDoc is an override class for TWpRichtext.

    I think WpTools will generate HTML with the correct Content Identifiers for the attachments. These content identifiers must match the content identifiers in the email file (content-id) for the TIdAttachment object.

    Hi Julian,

    discoverd the following problem with code in WPIOHTML.pas:

    Notice how a font with size 9 will never have its size stored inside the html.
    Only change i needed to make here was:

    if (FontSize <= WPHTFONTSIZES[i].smax) and
    (FontSize >= WPHTFONTSIZES[i].smin) then

    Hi Julian,

    I have a user option to switch layoutmodes from wpLayNormal to wpLayFullLayout. In the full layout mode i have the formatoption [wpfAlwaysFormatWithScreenRes] disabled and i normal layout it is enabled.

    Now i've noticed on a very rare occasion that this creates problems on empty paragraphs, where it seems that the paragraph height is still calculated with 600 dpi, but the engine paints it at 96 dpi. Resulting in the paragraph taking up more space than it should. The opposite is also possible where the height is calculated with 96 dpi and drawn at 600 dpi.

    Now since i have relied so much on your help recently i was really determined to figure out the cause for this myself, but my understanding of the wptools code is still limited. This is what i did find though:

    When disabling the following line (i marked this with {$IFNDEF OBEC}) in the TWPRTFEnginePaint.InitializePar method everything works fine for me:

    I found this because i was looking at code that was setting the par._DefaultHeight value that seemed to be the cause for my problem. I noticed the defaultheight being set twice for the same paragraph, the above code being the first time but it still had an incorrect value here unless i disabled the condition.

    I have been unabled to reproduce my problem in a small application, so it could very well be happening because of a combination of actions that happen on the editor.

    I'm not certain at all that my solution is correct, so i'm just checking here wether i've done something wrong. And perhaps this information is of some use to you or other WpTools users as well.

    WpTools 5.30.3

    Hi Julian,

    I'm trying to implement the same mailmerge concept used for mergefields into hyperlink urls. The text in the hyperlink however must remain static. I need to be able to save and load this in RTF and the urls must also work in other applications (but not with merge functionality)

    For example: "click here". When clicking on the word "here" it might link to http://wpcubed.com or any other site depending on the mailmerge result.

    The problem i'm having though is that contrary to mergefields, hyperlink objects do not really have a name stored inside the RTF. Or the name always changes to 'HYPERLINK'. This means that i can't use the name for the hyperlink to determine the URL content.
    Is there any way i can store the name for the hyperlink? Or link the hyperlink object to another invisible object that can contain a name?

    Thanks in advance

    PS.

    I know the simple solution would be to have a mailmerge field create the url, but i would rather not use a mailmerge field since i have those protected (can't type inside a mailmerge field). Also if i can get this running i might have a hyperlink with a dynamically generated url where the text also contains a mergefield. I hope this makes some sense :|

    I don't really see the point in having a newline at the beginning of a paragraph either, but somehow our users manage to create such a structure. Perhaps inserted by accident or copied from somewhere else.

    Maybe i can use the reformatting routine to split the paragraph and remove the newline? I haven't noticed any problems with newline characters if they are anywhere else besides the start of a paragraph.

    <!WPTools_Format V=518/>
    <GlobalPageFormat wpcss="landscape:0;paperw:12240;paperh:15840;margr:1880;margl:1880;margt:1440;margb:1440;marg_header:720;marg_footer:720;deftabstop:720;marginmirror:0;"/><StandardFont wpcss="CharFont:'Times New Roman';CharFontSize:1100;"/>
    <numberstyles></numberstyles>
    <stylesheet></stylesheet><cs nr=1 wpsty=[[CharCharset:1;CharFontSize:1000;CharColor:clBlack;]]/><div cs=1><c nr=1/>Strange empty paragraph below this one.</div>
    <div cs=1><c nr=1/>
    Weird paragraph above</div>
    <div cs=1><c nr=1/>Correct paragraph below</div>
    <div cs=1></div>
    <div cs=1><c nr=1/>Correct paragraph above</div>


    When loading this into WpTools 5.30.3 it looks like the document contains 2 "empty" paragraphs, but the first empty line is actually a paragraph containing 2 lines. (at least i think that is the case).

    It seems though many of wptools functions are not prepared for this empty line. For example MoveUpLine will place the cursor on this line, but might set active_posinpar to 1 (happens if active_posinpar <> 0). Any further attempts after that will not move the cursor up. Also editing will result in characters being placed on the next line.

    I can create such an empty line by pressing enter while holding the shift key.

    Messing around with this more i also managed to get the cursor displaced, although i haven't been able to reproduce this.

    I'm sorry if this message is very vague, i'm trying to describe this as best i can.

    Zitat

    loading it into a seperate editor and copying the relvant parts from it

    Problem would be finding out what the relevant parts are since i have no markers after loading it into another wptools editor.

    Reading the msdn it seems THtmlviewer does not really follow the examples there either. Perhaps i can modify that component to write something else to the clipboard.

    I also tested copying from outlook, internet explorer, ms word and everything pasted nicely into a TWPRichtext component.

    I tried the following inside TWPCustomRtfEdit.PasteFromClipboard...

    Code
    SetLength(lvStr, siz2);
            CopyMemory(PChar(lvStr), p, siz2);
            lvStr := Uppercase(lvStr);
            lvStartFrag := Pos(Uppercase('<StartFragment>'), lvStr);
            lvEndFrag := Pos(Uppercase('<EndFragment>'), lvStr);
            if (lvStartFrag > 0) and (lvEndFrag > 0) then
            begin
              inc(p, lvStartFrag + length('<StartFragment>') - 1);
              siz2 := lvEndFrag - lvStartFrag - length('<StartFragment>');
            end;

    ... but although the part between the text is correctly written to the memory stream. Nothing is being pasted. (probably because it is now missing all the html tags). I didn't expect it to be that simple, but figured i would try anyway.

    Some of our components (THmtlViewer) use fragment tags when storing html data on the clipboard during copy. When pasting into wptools such fragment tags are ignored and the entire clipboard content is copied.

    <!--StartFragment-->
    <!--EndFragment-->

    I fear other html viewers may result in similar clipboard formatting. And give unexpected results when pasting into WpTools.

    Is there anything that can be done to prevent this behavior by WpTools?

    See also: http://support.microsoft.com/kb/274326

    Thanks in advance