If you need to go any further the MSHTML option is not at all hard to
implement. As far as I can determine you can keep to a basic core
functionality that reaches back as far as IE5 (or even IE4 if you must).

Also the Mozzilla Component is becoming much more Delphi friendly and can
ship as as component apart from the whole distribution -  I have been
recently given to understand. I have not attempted this yet but am looking
into it incase MS becomes too "in house" under .NET. Further this would
release the MS MSHTML  version concern.

Much much more than shown here can be achieved with just a little more
effort.

Use TembeddedWB  from the Euromind site instead of TWebBrowser that ships
with later Delphis. Throw in MSHTML_TLB  OleCtrls, SHDocVw_TLB, EmbeddedWB,
{depending on your delphi} ComCtrls, ComObj and placing the TEmbeddedWB
should add anything else needed, possibly add ActiveX for earlier versions
of Delphi.
(see There is a Yahoo Group on the topic.
http://groups.yahoo.com/group/delphi-webbrowser/

(TEmbeddedWB the  better replacement for TWebBrowser which can both be used
virtually for some aspects of mass production drops from databases. See
http://www.euromind.com/iedelphi/embeddedwb.htm) handles printing pages
setup , saving , opening  loadfrom Stram string etc .. and I think now print
preview and a host of other issues.

Undo and Redo are little bit more exotic, coverd at end of this posting.

For a WYSIWYG direct HTML editor, try this.
==================================

You can make normal toolbar ( and or  Menu) with Word processing style
buttons and do direct implementations of the properly worded button hints,
even avoiding all IHTMLdahdah with olevariant based code no more difficult
than the following. Where TemailFax is just an average form,  faxEmailDoc is
a TEmbededWB, Toolbar  Button Hints are

Underline
Italic
Bold
Delete
Cut
Copy
Paste
Select All
Justify Right
Justify Left
Justify Center
Justify Full
Remove Format
Indent
Outdent
Insert Horizontal Rule
Insert Paragraph

There is a list of possible commands in (and I am looking at the MSDN 2001
April edition)

mk:@MSITStore:c:\Documents%20and%20Settings\All%20Users\Documents\Program%20
Files\Microsoft\Microsoft%20Visual%20Studio\MSDN\2001APR\1033\

inet.chm::/workshop/author/dhtml/reference/commandids.htm


//=================================================================
PROCEDURE TemailFax.ToolButtonPlainClick(Sender: TObject);
 var cmd :string;
begin
  //using hint string as command verb so first remove all spaces from hint
string
  if (sender is TToolButton) then
CMD :=stringreplace((Sender as TToolButton).Hint,#32,'',[rfreplaceall])
 else
   if (sender is Tmenuitem) then
CMD :=stringreplace((Sender as Tmenuitem).caption,#32,'',[rfreplaceall]);

// for Delphi 7 menus that can  auto add an ampersaand for underline effect
CMD :=stringreplace(CMD,'&','',[rfreplaceall]);

if returnSelect.queryCommandEnabled(CMD) then // checks for availablity of
command first

//like type could be used elsewhere to set state of button

// queryCommandValue from memory
   returnSelect.execCommand(CMD,false,true);
end;
//=================================================================
FUNCTION TemailFax.returnSelect:olevariant;
var selected :olevariant;
begin
        selected :=
faxDoc.OleObject.document.selection.createRange;

      returnSelect := selected;
end;
//=================================================================

//UNDO AND REDO FOLLOW

PROCEDURE TemailFax.toolButtonUndoClick(Sender: TObject);
  var
   vaIn , vaOut :olevariant;
begin
faxdoc.InvokeCMD(FALSE, OLECMDID_UNDO, OLECMDEXECOPT_DODEFAULT, vaIn,
vaOut);
end;

PROCEDURE TemailFax.ToolButtonRedoClick(Sender: TObject);
var
   vaIn , vaOut :olevariant;
begin
faxdoc.InvokeCMD(FALSE, OLECMDID_REDO, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut)
;
end;

Font size and font face and image insertion have to be handled seperately.
(unit MSHTML_stuff is given below it handles basic OLevariant use of
TWebBrowser and TEmbeddedWB. allows for direct handling of selected browser
display as root HTML. retrieve, and paste back.

one way of doing it as it allows the toolbar button with the Hint: Remove
Format
to clear the fonting. Appears to remove anything at all  placed using the
FONT tag. Faint name may be handled the same way.

procedure TemailFax.COurierFontSizeClick(Sender: TObject); //drop down
preset.
begin
mshtml_stuff.selPasteHtml(faxDoc,
                 '<font style="FONT-SIZE:'+COurierFontSize.text+'pt">'
                 + mshtml_stuff.selHtml(faxDoc)+'</font>');
end;

Inserting image (standard Outlook Express type no picture graphic locator)
is a button with this hint

Insert Image

Use this procedure:

procedure TemailFax.ToolButtonTrueNullClick(Sender: TObject);
var CMD :string;
begin
CMD :=stringreplace((Sender as TToolButton).Hint,#32,'',[rfreplaceall]);
if returnSelect.queryCommandEnabled(CMD) then
   returnSelect.execCommand(CMD,true,NULL);
 end;

===========MSHTML_STUFF.PAS very simplistic but also simply effective -
designed for both TWebBrowser TEmbeddedWB

unit mshtml_stuff;

{ This unit provides simple functions and procedures to enable simple
editing
  functions on a TwebBrowser or TembededdWB component which is being used
for
  interactive editing.

  Each of the routines is briefly explained in the body of the unit.

  Please use if useful, I've taken all care but all the responsability for
using this
  unit is yours.

  GNU license.

  Paul A Norman   http://PaulANorman.com   [EMAIL PROTECTED] }

interface

uses
 SysUtils,comctrls, classes, menus, SHDocVw_TLB, mshtml_tlb, EmbeddedWB,
jpeg, clipbrd,
 graphics, dialogs;

{below is not developed yet}
 type
 THtmlTags = class(tcomponent)
         public
          crLf : string;
          tblTDclosed :string; tblTDOpening :string; tblTDClosing :string;
          tblTRclosed : string; tblTROpening : string; tblTRClosing :
string;
          tblTHclosed  : string; tblTHOpening  : string; tblTHClosing  :
string;
          tblTBodyClosed : string; tblTBodyOpening : string; tblTBodyClosing
: string;
          tblTHeadClosed :string; tblTHeadOpening :string; tblTHeadClosing
:string;
          tblTFootClosed : string; tblTFootOpening : string; tblTFootClosing
: string;
          tblTableClosed :string; tblTableOpening :string; tblTableClosing
:string;
          tbl5colsx3rows : string;
          constructor setup;
          destructor finished;
         private

         protected
          end;



function returnAllHtml(editor:tembeddedWB):string ; overload;
function returnAllHtml(editor:twebbrowser):string ; overload;

procedure saveAllHtmlTo(editor:tembeddedWB; fileName :string;
JpgQuality100Max : integer) ; overload;
procedure saveAllHtmlTo(editor:twebbrowser; fileName :string;
JpgQuality100Max : integer) ; overload;

function editable(editor:tembeddedWB) : string; overload;
function editable(editor:twebbrowser) : string; overload;

procedure makeEditable(editor:tembeddedWB); overload;
procedure makeEditable(editor:twebbrowser);  overload;

procedure selPasteHtml(editor:twebbrowser;HTML :string); overload;
procedure selPasteHtml(editor:tembeddedWB;HTML :string); overload;

function selHtml(editor:twebbrowser) :string; overload;
function selHtml(editor:tembeddedWB) :string; overload;

function selText(editor:tembeddedWB) :string; overload;
function selText(editor:twebbrowser) :string; overload;

function selTextRange(editor:twebbrowser) : olevariant; overload;
function selTextRange(editor:tembeddedWB) : olevariant; overload;

function selSelection(editor:twebbrowser):olevariant; overload;
function selSelection(editor:tembeddedWB):olevariant; overload;

function selBodyRange(editor:twebbrowser):olevariant; overload;
function selBodyRange(editor:tembeddedWB):olevariant; overload;

procedure selCurrentTag(editor:tembeddedWB); overload;
procedure selCurrentTag(editor:twebbrowser); overload;

function selType(editor:tembeddedWB) :string; overload;
function selType(editor:twebbrowser) :string; overload;


procedure ToolButtonPlainClick(editor:tembeddedWB;Sender: TObject);overload;
procedure ToolButtonPlainClick(editor:twebbrowser;Sender: TObject);overload;

function returnSelect(editor:tembeddedWB):olevariant; overload;
function returnSelect(editor:twebbrowser):olevariant; overload;

procedure convertBmptoJpg( filename:string; const quality100Max :integer);

function plainPath(path:string):string;

      var
          currentTag:olevariant;
      const
          docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0
Transitional//EN">';

                        crLf = #13#10;
          tblTD ='<TD> </TD>'; tblTDa ='<TD>'; tblTDz ='</TD>';
          tblTR = '<TR> </TR>'; tblTRa = '<TR>'; tblTRz = '</TR>';
          tblTH  = '<TH> </TH>'; tblTHa  = '<TH>'; tblTHz  = '</TH>';
          tblTBody = '<TBODY></TBODY>'; tblTBodya = '<TBODY>'; tblTBodyz =
'</TBODY>';
          tblTHead ='<THEAD></THEAD>'; tblTHeada ='<THEAD>'; tblTHeadz
='</THEAD>';
          tblTFoot = '<TFOOT></TFOOT>'; tblTFoota = '<TFOOT>'; tblTFootz =
'</TFOOT>';
          tblTable ='<TABLE></TABLE>'; tblTablea ='<TABLE>'; tblTablez
='</TABLE>';
          tbl5x3 =   {tblTablea} '<TABLE border=1 rules=all frame=box
bgcolor=lightBlue>'  +crLf
                   + tblTHead   +crLf
                   + tblTBodya + crlf
                   + tblTra +tblTH +tblTH +tblTH +tblTH +tblTH +tblTH
+tblTrz+crlf
                   + tblTra +tblTd +tblTd +tblTd +tblTd +tblTd +tblTd
+tblTrz+crlf
                   + tblTra +tblTd +tblTd +tblTd +tblTd +tblTd +tblTd
+tblTrz+crlf
                   + tblTbodyz + crlf
                   + tblTFoot + crLf
                   + tblTablez;


implementation

   // if you use tool buttons or menu items with the hint set to words like
   // (no quote marks) "Justify Full"  "Bold" "Underline" etc ..
   // then this routine will implement the commnads
   // (see mk:@MSITStore:c:\ [somewhere]
inet.chm::/workshop/author/dhtml/reference/commandids.htm
   //   leave the "IDM_" portion off.
   //
   //Allows for the Delphi 7 happening where the menu items are often auto
'&'-ed
   //If it happens to you you'll know about it.
procedure ToolButtonPlainClick(editor:tembeddedWB;Sender: TObject);
 var cmd :string;
begin
  // using hint string as command verb so first remove all spaces and any
ampersands
  // from hint string
  if (sender is TToolButton) then
CMD :=stringreplace((Sender as TToolButton).Hint,#32,'',[rfreplaceall])
 else
   if (sender is Tmenuitem) then
CMD :=stringreplace((Sender as Tmenuitem).caption,#32,'',[rfreplaceall]);
CMD :=stringreplace(CMD,'&','',[rfreplaceall]);

if returnSelect(editor).queryCommandEnabled(CMD) then
   returnSelect(editor).execCommand(CMD,false,true);
end;

procedure ToolButtonPlainClick(editor:twebbrowser;Sender: TObject);
 var cmd :string;
begin
  // using hint string as command verb so first remove all spaces  and any
ampersands
  // from hint string
  if (sender is TToolButton) then
CMD :=stringreplace((Sender as TToolButton).Hint,#32,'',[rfreplaceall])
 else
   if (sender is Tmenuitem) then
CMD :=stringreplace((Sender as Tmenuitem).caption,#32,'',[rfreplaceall]);
CMD :=stringreplace(CMD,'&','',[rfreplaceall]);

if returnSelect(editor).queryCommandEnabled(CMD) then
   returnSelect(editor).execCommand(CMD,false,true);
end;

         // returns  a range from a selected area
function returnSelect(editor:tembeddedWB):olevariant;
var selected :olevariant;
begin
        selected :=
editor.OleObject.document.selection.createRange;

      returnSelect := selected;
end;

function returnSelect(editor:twebbrowser):olevariant;
var selected :olevariant;
begin
        selected :=
editor.OleObject.document.selection.createRange;

      returnSelect := selected;
end;

         // returns a string telling you what kind of thing is selected
         // None or Text or Control
function selType(editor:twebbrowser) :string;
begin
    result := selSelection(editor).type;
end;

function selType(editor:tembeddedWB) :string;
begin
    result := selSelection(editor).type;
end;


         // creates a textRange over a selected portion of text
         // establishes what the parent (enclosing) <tag> is
         // moves the textRange to those limits and
         // shows the new textRangs as a selection.
         //
         // Also sets the Global varible (in this unit's var clause)
currentTag
         //  as the current tag.
         //
         //  (You can do things like:
         //          currentTag.style.border := 'solid 1pt black';
         //       showmessage(currentTag.style.cssText);
procedure selCurrentTag(editor:twebbrowser);
var textRange:olevariant;
begin
         textRange := selTextRange(editor);
       currentTag := textRange.parentElement;
        TextRange:= selBodyRange(editor);
        TextRange.moveToElementText(currentTag);
        TextRange.select;
end;

procedure selCurrentTag(editor:tembeddedWB);
var textRange:olevariant;
begin
         textRange := selTextRange(editor);
       currentTag := textRange.parentElement;
        TextRange:= selBodyRange(editor);
        TextRange.moveToElementText(currentTag);
        TextRange.select;
end;


        // returns a textrange object created on the document Body
function selBodyRange(editor:twebbrowser):olevariant;
begin
result:=    editor.OleObject.document.body.createTextRange;
end;

function selBodyRange(editor:tembeddedWB):olevariant;
begin
result:=    editor.OleObject.document.body.createTextRange;
end;


            // returns the selection object
            // exposed by the document object
function selSelection(editor:tembeddedWB):olevariant;
begin
    result := editor.OleObject.document.selection;
end;

function selSelection(editor:twebbrowser):olevariant;
begin
    result := editor.OleObject.document.selection;
end;


        // returns the Range represented by a selection
function selTextRange(editor:twebbrowser) : olevariant;
begin
    result := selSelection(editor).createRange;
end;

function selTextRange(editor:tembeddedWB) : olevariant;
begin
    result := selSelection(editor).createRange;
end;


       // returns the plain Text in a selected area
function selText(editor:tembeddedWB) :string;
begin
   result:=selTextRange(editor).text;
end;

function selText(editor:twebbrowser) :string;
begin
   result:=selTextRange(editor).text;
end;


      // returns the HTML underlying a selected area
function selHtml(editor:twebbrowser) :string;
begin
   result := selTextRange(editor).htmlText;
end;

function selHtml(editor:tembeddedWB) :string;
begin
   result := selTextRange(editor).htmlText;
end;


      // Replaces the selected text underlying HTML with the HTML you
      // Supply
procedure selPasteHtml(editor:twebbrowser;HTML :string);
begin
    seltextRange(editor).pasteHTML(HTML);
end;

procedure selPasteHtml(editor:tembeddedWB;HTML :string);
begin
    seltextRange(editor).pasteHTML(HTML);
end;


     //tells you if the BODY tag is set for user editing
function editable(editor:tembeddedWB) : string;
begin
    result :=editor.OleObject.document.body.contentEditable;
end;

function editable(editor:twebbrowser) : string;
begin
    result :=editor.OleObject.document.body.contentEditable;
end;



     //tells you if the BODY tag is set for user editing
procedure makeEditable(editor:tembeddedWB);
begin
  editor.OleObject.document.body.contentEditable := true;
end;

procedure makeEditable(editor:twebbrowser) ;
begin
    editor.OleObject.document.body.contentEditable := true;
end;

procedure saveAllHtmlTo(editor:tembeddedWB; fileName :string;
JpgQuality100Max : integer) ; overload;

 var
  pageSave :tstringlist;
  document: ihtmldocument2;
  all : ihtmlElementCollection;
  htmlTag: ihtmlelement;
  images :  ihtmlElementCollection;
  image : ihtmlimgelement;
  counter : integer;
  filepath, holdName, newName :string;
 begin

    document := editor.document as ihtmldocument2;
    filepath := extractfilepath(filename);

   if  (JpgQuality100Max >0) and (pos('email', lowercase(filepath)) > 0)
then
        //filepath has 'email' in it
   begin

        images :=  document.images;

        for counter := 0 to images.length -1 do
          begin
              image := images.item(counter, counter) as  ihtmlimgelement;
              holdName := plainPath(image.src);
              if lowercase(extractfileext(holdname)) = '.bmp' then
                      // conversion needed
                 begin
                     newName := changefileext(holdname,'.JPG');
                       if not fileexists(newName) then
                               // the user has not made a JPEG version
                          begin
                        convertBmptoJpg(holdName,85);
                        image.src := newName;
                          end; // the user has not made a JPEG version
                 end; // conversion needed
          end;// counter to number of images

   end; //filepath has 'email' in it

    all := document.all.tags('HTML') as ihtmlElementCollection;
    htmlTag := all.item(0,0)  as ihtmlelement ;
    //htmlTag.outerHTML

      try
      pageSave := tstringlist.create;
      pageSave.add(docType);
      pageSave.Add(htmlTag.outerHTML);
      pageSave.SaveToFile(filename);

      finally
       pageSave.Free;
      end;
 end;

procedure saveAllHtmlTo(editor:twebbrowser; fileName :string;
JpgQuality100Max : integer) ; overload;
 var
  pageSave :tstringlist;
  document: ihtmldocument2;
  all : ihtmlElementCollection;
  htmlTag: ihtmlelement;
 begin
    document := editor.document as ihtmldocument2;
    all := document.all.tags('HTML') as ihtmlElementCollection;
    htmlTag := all.item(0,0)  as ihtmlelement ;
    //htmlTag.outerHTML

      try
      pageSave := tstringlist.create;
      pageSave.add(docType);
      pageSave.Add(htmlTag.outerHTML);
      pageSave.SaveToFile(filename);

      finally
       pageSave.Free;
      end;
 end;

function returnAllHtml(editor:tembeddedWB):string ; overload;
var
  pageSave :tstringlist;
  document: ihtmldocument2;
  all : ihtmlElementCollection;
  htmlTag: ihtmlelement;
 begin
    document := editor.document as ihtmldocument2;
    all := document.all.tags('HTML') as ihtmlElementCollection;
    htmlTag := all.item(0,0)  as ihtmlelement ;
    //htmlTag.outerHTML

      try
      pageSave := tstringlist.create;
      pageSave.add(docType);
      pageSave.Add(htmlTag.outerHTML);

      returnAllHtml:=pageSave.text;

      finally
       pageSave.Free;
      end;
end;

function returnAllHtml(editor:twebbrowser):string ; overload;
var
  pageSave :tstringlist;
  document: ihtmldocument2;
  all : ihtmlElementCollection;
  htmlTag: ihtmlelement;
 begin
    document := editor.document as ihtmldocument2;
    all := document.all.tags('HTML') as ihtmlElementCollection;
    htmlTag := all.item(0,0)  as ihtmlelement ;
    //htmlTag.outerHTML

      try
      pageSave := tstringlist.create;
      pageSave.add(docType);
      pageSave.Add(htmlTag.outerHTML);

      returnAllHtml:=pageSave.text;

      finally
       pageSave.Free;
      end;
end;

procedure convertBmptoJpg( filename:string; const quality100Max :integer);
 var
 jpg : TJpegImage;
 bmp : tbitmap;
begin
    try  // try images creation
    jpg:= tjpegimage.Create;   bmp := tbitmap.create;

   bmp.loadfromfile(fileName);
   jpg.Assign(bmp);
   jpg.CompressionQuality:= quality100Max;
   jpg.Compress;
   filename := changefileext(filename,'.JPG') ;
   jpg.SaveToFile(filename);
    finally
    jpg.Free; bmp.free          end;// try images creation
end;

function plainPath(path:string):string;
   begin

    path:=stringreplace(copy(path,9,length(path)),'%20',#32,[rfreplaceall]);

       Path:= stringreplace(path, '/','\',[rfreplaceall]);
       Path:= stringreplace(path, '&amp;','&',[rfreplaceall]);
       Path:= stringreplace(path, '&gt;','>',[rfreplaceall]);
       Path:= stringreplace(path, '&lt;','<',[rfreplaceall]);
       Path:= stringreplace(path, '&quot;',#34,[rfreplaceall]);
       Path:= stringreplace(path, '%26',#22,[rfreplaceall]);
     //  path:=hyperstr.URLDecode(path) ;
       plainPath := path;
   // if fileexists(path) then
//       showmessage('OK: '+path);
       clipboard.AsText:=path;
   end;






{ THtmlTags }

destructor THtmlTags.finished;
begin
 inherited free;
end;

constructor THtmlTags.setup;
begin

 self.crLf := crLf;
 self.tblTDclosed := tblTD;
  self.tblTDOpening := tblTDa;
  self.tblTDClosing := tblTDz;
 self.tblTRclosed := tblTR ;
  self.tblTROpening := tblTRa ;
  self.tblTRClosing :=  tblTRz ;
 self.tblTHclosed := tblTH;
  self.tblTHOpening := tblTha ;
  self.tblTHClosing := tblThz ;
 self.tblTBodyClosed := tblTBody;
  self.tblTBodyOpening := tblTBodya;
  self.tblTBodyClosing := tblTBodyz;
 self.tblTHeadClosed :=  tblTHead ;
  self.tblTHeadOpening :=  tblTHeada ;
  self.tblTHeadClosing :=  tblTHeadz ;
 self.tblTFootClosed := tblTFoot ;
  self.tblTFootOpening  := tblTFoota ;
  self.tblTFootOpening  := tblTFootz ;
 self.tblTableClosed := tblTable ;
 self.tblTableOpening := tblTablea ;
 self.tblTableClosing := tblTablez ;
 self.tbl5colsx3rows := tbl5x3;
    inherited create(nil);
 end;

end.


_______________________________________________
Delphi mailing list
[EMAIL PROTECTED]
http://ns3.123.co.nz/mailman/listinfo/delphi

Reply via email to