このまえ「Windows Live WriterプラグインからエントリのHTMLDocumentを取得する方法」というエントリでWLW編集画面のHTMLDocumentオブジェクトを取得する方法を紹介したけれども、その方法にはまだ解決できていない問題があり、今回は自分がどこで躓いているのかを説明しつつ嘆くエントリ(笑)。

さて、現在のInvalidSourceModifierは以下のようなソースになっている。

extern alias MicrosoftMshtml;
extern alias WriterInteropMshtml;

using System;
using WindowsLive.Writer.Api;
using System.Windows.Forms;
using MicrosoftMshtml.mshtml;
using WindowsLive.Writer.PostEditor;

using WriterMshtml = WindowsLive.Writer.Mshtml;


namespace InvalidSourceModifier {
    //TODO:ImagePathの設定!
    [WriterPlugin("9388e56b-c684-4e04-b7f6-b8cc224d70b2", "InvalidSourceModifier", PublisherUrl = "http://www.sharplab.net/")]
    public class InvalidSourceModifier : PublishNotificationHook {
        public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {
            
            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            WriterMshtml.MshtmlControl mshtmlControl = (WriterMshtml.MshtmlControl)findControlByName(postEditorForm, "MshtmlControl", "WindowsLive.Writer.Mshtml");

            IHTMLDocument3 doc = (IHTMLDocument3)mshtmlControl.HTMLDocument;

            IHTMLElementCollection allElement = doc.getElementsByTagName("*");
            foreach (IHTMLElement elem in allElement) {
                object align = elem.getAttribute("align", 0);
                object border = elem.getAttribute("border", 0);
                if (!(align == null || align is DBNull)) {
                    elem.removeAttribute("align", 0);
                    elem.style.styleFloat = (string)align;
                }
                if (!(border == null || border is DBNull)) {
                    elem.removeAttribute("border", 0);
                    elem.style.borderWidth = (string)border;
                }
            }

            updateTextEditorControl(postEditorForm);

            return true;
        }

        private void updateTextEditorControl(PostEditorForm postEditorForm) {

            WriterMshtml.MshtmlEditor mshtmlEditor = (WriterMshtml.MshtmlEditor)findControlByName(postEditorForm, "MshtmlEditor", "WindowsLive.Writer.Mshtml");
            mshtmlEditor.Focus();

            Control test = findControlByName(postEditorForm, "PostEditorMainControl", "WindowsLive.Writer.PostEditor");

        }

        private PostEditorForm getPostEditorForm(IWin32Window postProgressForm) {
            return (PostEditorForm)((Form)Form.FromHandle(postProgressForm.Handle)).Owner;
        }

        private Control findControlByName(Control control, string controlName, string controlNamespace) {
            
            foreach (Control cChild in control.Controls) {

                Type t = cChild.GetType();

                if (t.Name == controlName && t.Namespace == controlNamespace) {
                    return cChild;
                }

                if (cChild.HasChildren) {
                    Control returned = findControlByName(cChild, controlName, controlNamespace);
                    if (returned != null) {
                        return returned;
                    }
                }
            }

            return null;
        }
    
    }

}

まず、getPostEditorFormメソッドで投稿の進捗状況を表すプログレスバーを載せたFormを基に、親のPostEditorFormを取得、その後、findControlByNameメソッドを使い、PostEditorForm内から、nameとnamespaceを頼りにMshtmlControlコントロールを探し、そのHTMLDocumentプロパティから取得する、というやり方。

これでめでたく「標準」モードや、「Webプレビュー」モードのHTMLDocumentオブジェクトが習得できるのだけれども、HTMLDocumentオブジェクトに対して操作を加えると、「HTMLコード」画面での内容と、HTMLDocumentの不整合が起きてしまう。特に、表示モードを「HTMLコード」としていた場合、HTMLDocumentに対してプラグインから操作後に表示モードを「標準」に戻すと、HTMLDocumentに対する操作内容が飛んでしまう。

む~。なんとかならんものか。誰か知恵をお貸しくださいませ。

Trackbacks : 1

Trackback URL for this entry
http://blog.sharplab.net/blog/2008/06/21/251/trackback/

Listed below are links to weblogs that reference this entry

ピンバック from SharpLab. - Windows Live Writerの編集画面のHTMLDocumentへの安全な操作方法 08-07-29 01:18:27 UTC

[…] 前のエントリでは 表示モードを「HTMLコード」としていた場合、HTMLDocumentに対してプラグインから操作後に表示モードを「標準」に戻すと、HTMLDocumentに対する操作内容が飛んでしまう […]