HtmlEditor :  Phorum 5 The fastest message board... ever.

This is the discussion forum for the HtmlEditor. See also the HtmlEditor home page, where you can download the control, and the Documentation Wiki, a collaborative project for documenting the control.

Goto Thread: PreviousNext
Goto: Forum ListMessage ListNew TopicSearchLog In
How to tell if the document has been modified?
Posted by: Daryl (---.ca-pasadena0.ne.earthlink.net)
Date: Thursday, 14-Dec-2006, 01:03:58

I wonder if there is away to tell if the document has been modified. Please help.

Re: How to tell if the document has been modified?
Posted by: Tim (---.gotadsl.co.uk)
Date: Monday, 18-Dec-2006, 11:21:49

A couple of ideas:

- maintain an isDirty flag and set it whenever a keystroke is received. Main problem is that you will get a kind of false positive if the user pressed a key that did not actually change the document. But that's better than changes not being saved.

- get the document source at load time and compare it to the current document source. Could be OK if you only need to do this occasionally, say when closing a document. Again, might be false positives if MSHTML decided to reformat the HTML.

Tim

Re: How to tell if the document has been modified?
Posted by: johnnyboyc_uk (82.108.133.---)
Date: Monday, 18-Dec-2006, 11:55:57

IHTMLChangeSink seems to work well for me, give that a whirl.

Re: How to tell if the document has been modified?
Posted by: itzik (---.barak.net.il)
Date: Thursday, 21-Dec-2006, 10:59:56

Can you give an example using IHTMLChangeSink?

Re: How to tell if the document has been modified?
Posted by: johnnyboyc_uk (82.108.133.---)
Date: Thursday, 21-Dec-2006, 16:04:03

A C# example?

Re: How to tell if the document has been modified?
Posted by: Daryl (---.ca-pasadena0.ne.earthlink.net)
Date: Thursday, 04-Jan-2007, 23:40:34

I found some source code here:

[itwriting.co.uk]

which is in Visual Basic, which is equivalent in C# as below:

*************

1. Cast the Document property to an IMarkupContainer2 interface
2. Declare a class that implements IHTMLChangeSink
3. Declare a variable of type IHTMLChangeLog and bind it to the IMarkupContainer2

This can be done at the form level or any other encapsulating class

private mshtml.IHTMLChangeLog mobjChangeLog;
private mshtml.IMarkupContainer2 DocumentMarkupCtr2;
private ChangeMonitor MyChangeMonitor = new ChangeMonitor();


ChangeMonitor should implement the IHTMLChangeSink interface:


public class ChangeMonitor : mshtml.IHTMLChangeSink
{
public event EventHandler ContentChanged;
public bool Dirty;

public void Notify()
{
Dirty = true;
if (ContentChanged != null) {
ContentChanged();
}
}
}

Then, when the ReadyStateChange event is raised by the HTMLEditor, bind the classes:

DocumentMarkupCtr2 = ((mshtml.IMarkupContainer2)(HTMLEditor.Document));
DocumentMarkupCtr2.CreateChangeLog(MyChangeMonitor, mobjChangeLog, 1, 1);

The IHTMLChangeSink.Notify method is then called on MyChangeMonitor to inform the class of changes to the top level DocumentMarkupCtr2.

You can set a flag in the body of this method, or perform other appropriate actions.

***************************

and further discussion here:

[itwriting.co.uk]

However, I still can't make it to work. I can't find the ReadyStateChange event.

If anyone make can make it to work, please post the source code here.

Thanks.

Re: How to tell if the document has been modified?
Posted by: Tim (---.gotadsl.co.uk)
Date: Friday, 05-Jan-2007, 10:01:21

Ah yes, I'd forgotton that Clive posted that.

The ReadyStateChanged event is the normal one fired by Mshtml and exposed by the editor.

Tim

Re: How to tell if the document has been modified?
Posted by: Daryl (---.ca-pasadena0.ne.earthlink.net)
Date: Friday, 05-Jan-2007, 19:06:10

Hi Tim,

I see there's a ReadyStateChanged event defined in this HtmlEditor. However, our existing application does not use this editor but AxSHDocVw.AxWebBrowser instead. Would you show me how do I get access to the similar event from standard AxWebBrowser?

Thanks,

Daryl

Re: How to tell if the document has been modified?
Posted by: Clyde Davies (---.range86-143.btcentralplus.com)
Date: Monday, 05-Mar-2007, 15:45:38

Sorry I haven't been around to reply to any of this. It's very frustrating because I now see exactly the same behaviour in an MFC/C++/CLI application. You can create the changelog fine, but Notify won't fire.

I wonder if it has anything to do with the document being/not being in design mode? I trun design mode off and set ContentEditable on various elements.

Ideas, please.



--------------------------------------------------------------------------------------------
deadlyvices@hotmail.com
Currently writing the GuideDog editor using MSHTML in my copious free time...

Re: How to tell if the document has been modified?
Posted by: Clyde Davies (---.range86-143.btcentralplus.com)
Date: Tuesday, 06-Mar-2007, 07:32:29

I have now tried setting Design Mode, but Notify still doesn't fire. I'll post more when I make any significant findings.



--------------------------------------------------------------------------------------------
deadlyvices@hotmail.com
Currently writing the GuideDog editor using MSHTML in my copious free time...

Re: How to tell if the document has been modified?
Posted by: Darren Sherman (---.acs2000.net)
Date: Thursday, 20-Mar-2008, 14:13:52

I found a decent article that helped me a bit in my C++ endeavors
[forums.microsoft.com]

Basically, I had to use QueryInterface on the IHTMLDocument2 object to get the proper IMarkupContainer2 (otherwise I'd get E_INVALIDARG)

<code>
// This doesn't work
//IMarkupContainer2* pIMarkupContainer2 = (IMarkupContainer2*)pIHtmlDocument2;

// This does
IMarkupContainer2* pIMarkupContainer2;
HRESULT hr = pIHtmlDocument2->QueryInterface( IID_IMarkupContainer2, (void**)&pIMarkupContainer2 );
if( (S_OK == hr) && pIMarkupContainer2 )
{
hr = pIMarkupContainer2->RegisterForDirtyRange( (IHTMLChangeSink*)pSink, &dwCookie );
}
</code>

HTH,
Darren

Re: How to tell if the document has been modified?
Posted by: Halil (---.btc-net.bg)
Date: Saturday, 04-Sep-2010, 13:47:58

This code work very well in C#:

private static Guid IMarkupContainer2GUID = typeof(mshtml.IMarkupContainer2).GUID;

private mshtml.IMarkupContainer2 GetMarkupContainer() {

object oDocument = this.browser.Document;

IntPtr pDocument = Marshal.GetIUnknownForObject(oDocument);

IntPtr pMarkupContainer = IntPtr.Zero;

// pMarkupContainer is different after a call to Navigate or designMode

Marshal.QueryInterface(pDocument, ref IMarkupContainer2GUID, out pMarkupContainer);

//object oMarkupContainer = Marshal.GetObjectForIUnknown(pMarkupContainer); // This does not work

object oMarkupContainer = Marshal.GetUniqueObjectForIUnknown(pMarkupContainer);

Marshal.Release(pDocument);

Marshal.Release(pMarkupContainer);

return (mshtml.IMarkupContainer2)oMarkupContainer;

}



Your Name: 
Your Email: 
Subject: 
Spam prevention:
Please, enter the code that you see below in the input field. This is for blocking bots that try to post this form automatically.
PXpnJ
This is a moderated forum. Your message will remain hidden until it has been approved by a moderator or administrator
This forum powered by Phorum.