Beiträge von delphidoc

    Duh, found a really old version of my pas file that underlined in another procedure:

    Code
    with Page.CurrAttr do begin    if (afsUnderline in Style) then DeleteStyle([afsUnderline])      else AddStyle([afsUnderline]);  end;

    I'm curious as to why it works for bold when I use the other way:

    Code
    with Page.CurrAttr do begin
        if afsBold in Style then Style := Style - [afsBold]
          else Style := Style + [afsBold];
      end;

    That way also works for italics, but not underline. Any idea why?

    (edited for typo)

    I'm working on an editor with a TWPRichText component. I have buttons for bold, italics, and underline. The code I have for underlining is:

    Code
    with Page.CurrAttr do begin    if (afsUnderline in Style) then Style := Style - [afsUnderline]      else Style := Style + [afsUnderline];  end;

    The bold and italics buttons' codes are identical, substituting afsBold and afsItalic where appropriate. The selelected text will show bold or italics immediately. Selected text will not show the underline during the current editing session. The underline attribute has been applied, as I'm prompted to save the file when exiting, and the Undo button is activated. When I close the file and then reopen it, the underline is there. On that second edit, if I remove the underline and reapply it, the underline will show immediately.

    I'm using WPTools Standard 5.303, BDS 2006 with Update 2 (Win32 Personality), Windows XP SP2. The same problem occurred with the previous version as well. I looked at some archived project files from about 2005, and I seem to have had a similar problem with underlining then, too.

    In unit WPCTRRich, the procedure TWPCustomRichText.DoUpdateCharAttr has the following code for underlining:

    Code
    a := CurrAttr.UnderlineMode;  UpdateIconCheck(WPI_GR_STYLE, WPI_CO_UNDER, (afsUnderline in    NewStyle) or ((a > 0) and (a < WPUND_NoLine)));

    This is completely different than the code for any other attributes- they don't have anything corresponding to

    Code
    or ((a > 0) and (a < WPUND_NoLine)))

    at the ends of their lines. I experimented by making the underline code the same for the other attributes, but it didn't help. When I right-click on afsUnderline in my pas file and try to Find Declaration, an error box states that WPRTEDefs.pas cannot be located, but the dcu file is located in the WPTools directory. The search path includes that directory.

    I've tried adding Page.ReformatAll and Page.Refresh without success, and bold and italics don't require those lines after them.

    Any ideas?

    Thanks in advance for your time.

    Here's how I do it:

    My app has a TStatusBar named SBar with 7 panels on it.
    Panels[1] is for page #.
    Panels[2] is for line #.
    Panels[3] is for col #.
    The other panels are for other information, or for spacing.

    My app's TWPRichText object is named Page. Its OnChangeSelection event contains the following code:

    Thanks for your quick reply. I'll look at the GlobalStyle demo today when I get some time.

    I've already got a version of my app that inserts each cell's text into the second TWPRichText object, using GetText and InputString.

    I still would like to get AGetDef to work, though. Last night I tried every coding variation I could think of, but I could never get a nonzero result for the WPAT_CharStyleMask and WPAT_CharStyleON variables. What is keeping my code from working here? Last night I made sure that I was parsing each table cell and making it the ActiveParagraph, so that's not the problem. Any hints?

    My project has two TWPRichText objects. The first one is a template for data entry. I'm trying to sequentially parse the cells from the first TWPRichText object's table and append them to the second TWPRichText object. I'll do some formatting of the first object's cell contents on the second object to prepare it for printing.

    I'm trying to see if each cell from the first TWPRichText object's table has bold or underline attributes and then format each TParagraph on the second object accordingly.

    I'm having trouble getting results from AGetDef. The integer values iiMask and iiOn always evaluate to 0. The ShowMessage lines never produce a message box, as (iiMask and WPSTY_BOLD) always returns 0.


    It was the way I was replacing the bookmarked text that was the problem. Only 255 letters would be included within the bookmark if I used the following code:


    FormMain.Chart.BookmarkSelect('PE', False);
    FormMain.Chart.SelText := ss;
    FormMain.Chart.Update;
    FormMain.Chart.BookmarkInput('PE');


    I found a demo with the following code that doesn't produce this problem:


    if FormMain.Chart.BookmarkMoveTo('PE') then begin
    FormMain.Chart.CPMoveNext;
    FormMain.Chart.SelectionAsString := ss;

    I have a form with several bookmarked text areas. A ShowModal window can be brought up that will populate the bookmarked areas with text when it closes. I kept having problems with the bookmarked areas not accepting all of the new text, with some of the text being left out of the new bookmarked areas. Now that I've looked at the size of the text being bookmarked, it looks like bookmarked text has a size limit of 255 letters.

    Has anybody run into a similar problem with bookmarks? Any solutions? (I've considered splitting the large bookmarked text into two chunks, but there's no logical way to split it up.)

    //Here's how I did it. The form's OnCreate event sets the combo box selection to the System printer:

    Code
    procedure TFormPrint.FormCreate(Sender: TObject);begin  Printer.PrinterIndex := -1; // sets to System default  Combo.Items := Printer.Printers;  Combo.ItemIndex := Printer.PrinterIndex;end;


    //When you click BtnOK it stores the System default printer as the integer variable, iPrinter. It's used afterward to restore the default printer.

    Code
    procedure TFormPrint.BtnOKClick(Sender: TObject);begin  iPrinter := Printer.PrinterIndex;  SetDefaultPrinter(Combo.ItemIndex);end;


    //SetDefaultPrinter(Sender:TObject) is my procedure that temporarily sets a different printer to default.

    Code
    procedure TFormPrint.SetDefaultPrinter(APrinterIndex: Integer);var  pDevice: PChar;  pDriver: PChar;  pPort: PChar;  hDeviceMode: THandle;  pp: TPrinter;begin   GetMem(pDevice, 255);  GetMem(pDriver, 255);  GetMem(pPort, 255);  pp := TPrinter.Create;  try    pp.PrinterIndex := APrinterIndex;    pp.GetPrinter(pDevice, pDriver, pPort, hDeviceMode);    StrCat(pDevice, ',');    StrCat(pDevice, pDriver);    StrCat(pDevice, pPort);    WriteProfileString('windows', 'device', pDevice);    StrCopy(pDevice, 'windows');    SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(@pDevice));  finally    pp.Free;  end;   FreeMem(pDevice, 255);  FreeMem(pDriver, 255);  FreeMem(pPort, 255);end;


    //When finished printing, restore the previous printer to the System default with this line of code:

    Code
    SetDefaultPrinter(iPrinter);

    Looks like that should work. The error always occurred with the first iteration of the loop. I was wondering if the violation occurred because the variable hadn't been initialized, but I hadn't had time to work on it yet (I hate it when work gets in the way of the fun stuff ;) ). Thanks for the tip.

    Thanks for the pointer!

    procedure TFormMain.JustifyText();
    var
    ii, iPar: Integer;
    begin

    {remove double spaces from earlier code}
    with WPRichText1.Finder do begin
    ToStart;
    ReplaceAll(' ', ' ');
    end;

    {iterate through paragraphs}
    iPar := WPRichText1.CountParagraphs;
    for ii := 1 to iPar do begin
    WPRichText1.CPParNr := ii;
    WPRichText1.CurrAttr.Alignment := paralBlock;
    end;

    WPRichText1.Update;
    end;

    Here's an RTF generated by Wordpad (Win XP Home, SP1) that also contains just the word "testing":

    {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\fnil\fcharset0 Courier New;}}
    {\*\generator Msftedit 5.41.15.1503;}\viewkind4\uc1\pard\f0\fs20 testing\f1\par
    }

    This is more what I'm looking for. I like the visual effect of a TWPRichText object, as it looks like a piece of paper on the screen, but I don't require all the extra embedded code in the generated files. Is there a way to pare down the RTF code to something like what's above? Thanks.

    I looked at an rtf file generated with a TWPRichText object. The only word in the file is "testing." The amount of rtf code for one word is staggering. My intended use for the program is to generate a letter to be printed. I only use one font, and I don't use any tables, headers/footers, bold/italics/etc, just monotonous text. I don't use any colors except black. I'm not sure why the font WingDings is even in here- I've never used it before. Is there a way to streamline the code generated?


    Here's what's generated for a file containing the word "testing":

    {\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fnil\fcharset0 Times New Roman;}{\f1\fnil\fcharset2 WingDings;}}{\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;}\wptoolsver4\wpprheadfoot0\paperw12240\paperh15840\margl2302\margr1440\margt1440\margb1440\headery720\footery720{\*\listtable{\list\listtemplateid19690212{\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc1{\leveltext\'02\'00.;}{\levelnumbers\'01;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc3{\leveltext\'02\'01.;}{\levelnumbers\'01;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'02\'02.;}{\levelnumbers\'01;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc4{\leveltext\'02\'03);}{\levelnumbers\'01;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc2{\leveltext\'03(\'04);}{\levelnumbers\'02;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc4{\leveltext\'03(\'05);}{\levelnumbers\'02;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'03(\'06);}{\levelnumbers\'02;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'03(\'07);}{\levelnumbers\'02;}}
    {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'03(\'08);}{\levelnumbers\'02;}}
    \listid1194737}}{\*\listoverridetable{\listoverride\listid1194737\listoverridecount0\ls1}}\endnhere\sectdefaultcl{\pard{\ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 testing}}
    }

    How can I make a TWPRichText object justify the text (line up the right edges of each line of text)? I would have guessed WordWrap would do this, but that just makes the lines stretch from one side of the component to the other. Thanks.

    Here's the code I wrote for a dialog box that lets you print to a non-default printer. It saves Printer.PrinterIndex to an integer variable (iPrinter), changes the default printer to what was selected in the combo box, and then prints the selected text.

    When you're through printing you can restore the default printer with this line:

    SetDefaultPrinter(iPrinter);

    Not to be argumentative, but PrintPages doesn't work correctly. That's why I was trying other solutions.

    Here's what PrintPages did for me today with a 2-page RTF document. The document does not appear to be corrupted, as it views, edits, and prints correctly with WordPad:

    Chart.PrintPages(0,1); // print both pages
    Chart.PrintPages(1,2); //prints both pages also
    Chart.PrintPages(2,3); //prints blank page- no range error messages

    Chart.PrintPages(0,0); //prints blank page- this should be the 1st page
    Chart.PrintPages(1,1); //prints 1st page- this should print the 2nd page
    Chart.PrintPages(2,2); //prints 2nd page TWICE

    I'm going to try my hand at overriding PrintPages and/or SelectPages. If I have any luck I'll report back on it. Thanks.

    This is buggy. The code above works if you want to print the first page. I'm running into problems if I try to print the last page, or all but the first page.

    The endpage in SelectPages is excluded from the selection. CountPages is zero-based.

    If you try SelectPages(0, 1) and plug it into the code from my second post, you'll print the first page.

    If you try SelectPages(1, Chart.CountPages-1) and plug it into the code from my second post, you'll print All pages.

    If you try SelectPages(1, Chart.CountPages), which would logically give you an error, it prints the second page of a 2-page document TWICE.

    I also played around with adding a blank page to the end of the temporary document, doing a SelectPages to a second temporary document, and I still got the same results.

    I'm still trying to find a way to print the last page or all but the first page. Any hints will be greatly appreciated.

    I found a work-around to enable printing of the first page. Got it from the online manual. I added a second TWPRichText object, selected the first page with the original TWPRichText object, copied it AsString to the second object, invoked the Print method, then Freed the second object:

    procedure TFormMain.BtnPrintClick(Sender: TObject);
    var
    WPPrint: TWPRichText;
    begin
    // (truncated)
    WPPrint := TWPRichText.Create(Application);
    WPPrint.Parent := FormMain;
    Chart.SelectPages(0,1);
    WPPrint.AsString := Chart.SelectionAsString;
    WPPrint.Print;
    WPPrint.Free;
    // (truncated)
    end;

    I'm trying programatically to print only the first page of a multipage document. The code I've written contains the line:

    Chart.PrintPages(0,0);

    It always prints the second page, not the first. Looking through the code in WPWinCtr.pas I found this:

    procedure TWPCustomRtfEdit.PrintPages(from_p, to_p: LongInt);
    begin
    if not HandleAllocated then CreateWnd;
    if MemoryFormat = fmPlainText then
    Memo.ClearFontCache;
    if from_p = 0 then from_p := 1;

    // (truncated)

    end;


    I believe this is why my program is printing page 2 instead of page 1. Why was the code written this way? What would happen if I commented out this line of code?