C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: WebBrowserコントロールの折り返し制御


(過去ログ 139 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■81727 / inTopicNo.1)  WebBrowserコントロールの折り返し制御
  
□投稿者/ キム (1回)-(2016/11/02(Wed) 12:24:11)

分類:[C#] 

開発環境
Windows 7 Professional SP1 64bit OS
Visual Studio 2010 SP1
.Net Frame 4 Client Profile
C# Windows フォーム アプリケーション
ソリューション プラットフォーム x86
IE 11

実行環境
Windows 7 Professional SP1 32/64bit OS
IE 7〜11

お世話になります。
WebBrowserコントロールでhtmlファイルを表示しています。
このとき、表示内容がWebBrowserコントロールの幅で自動的に折り返されてしまいます。
(厳密には、WebBrowserコントロールの幅を超えない単語区切り)

具体例として、下記のようなシンプルなHTMLファイルを表示したとします。

test.html --------------
<HTML>
<BODY>
  <P>123 456 789 012 @AB CDE 〜中略〜 uvw xyz</P>
</BODY>
</HTML>
-----------------------

すると、下記のように折り返されて表示されてしまいます。

123 456 789 012 @AB CDE FGH IJK
LMN OPQ RST...

この動作を変更することは可能でしょうか?
具体的には、WebBrowserコントロールの幅で折り返さずに、水平スクロールバーを表示
するように変更したいのです。

1.最初の目標は、WebBrowserコントロールの幅より大きい固定の表示幅を設定して、水平
スクロールバーを表示することです。

2.最終的には、htmlの内容が折り返さずに表示できる最適幅を求めて設定し、必要に応じ
て水平スクロールバーを表示することです。

3.また、WebBrowserコントロールの幅で折り返すかどうかをオプション設定で切り替えら
れるようにもしたいです。

動作確認は、WindowsフォームにWebBrowserコントロールを貼り付けて、DockプロパティをNone、
Sizeプロパティを(300, 200)、ScrollBarsEnabledプロパティをtrue, Urlプロパティに上記html
ファイルのPathを指定して行いました。
上記のHTMLを表示した時の、ログは以下のとおりです。
Zoom: 100%
webBrowser1.Size: {Width=300, Height=200}
webBrowser1.Document.Window.Size: {Width=300, Height=200}
HTML  Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=300,Height=200}
HEAD  Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=  0,Height=  0}
TITLE Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=  0,Height=  0}
BODY  Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=283,Height= 90}
P     Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=263,Height= 60}

また、単語区切りで折り返されているようなので、Pタグ内の空白を除いてみたところ、
折り返されずに表示され、水平スクロールバーが表示されました。
ログは以下のとおりです。
Zoom: 100%
webBrowser1.Size: {Width=300, Height=200}
webBrowser1.Document.Window.Size: {Width=300, Height=200}
HTML  Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=300,Height=200}
HEAD  Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=  0,Height=  0}
TITLE Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=  0,Height=  0}
BODY  Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=581,Height= 50}
P     Document.Window.Size{Width=300, Height=200} ScrollRectangle{X=0,Y=0,Width=561,Height= 20}

ScrollRectangleを見ると、コンテンツの表示幅で子ウィンドウが作成されているようですが、
Document.Window.Sizeは固定なので、子ウィンドウは別にあるように思えます。
また、その表示幅計算にワードラップ設定が絡んでいるように思えます。
そこで、子ウィンドウのサイズを設定するか、ワードラップ設定を操作できれば目的が実現できると考えました。
しかし、現状では有効な手法を見つけられていません。

・各要素のDocument.Window.Sizeの設定を試みましたが、値に変化なしで効果なし。
・各要素のDocument.Window.DomWindowを得てresizeTo()での設定を試みましたが、値に変化なしで効果なし。
・ワードラップ関連のプロパティやメソッドを探しましたが現状ではまだ見つけられていません。

苦肉の策として、BODYの中身全体をTABLEで囲って、widthを指定してやればテーブル幅分は
折り返されないことがわかったので、下記のコードで折り返しを制御してみました。

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    System.Windows.Forms.WebBrowser wb = sender as System.Windows.Forms.WebBrowser;
    if (wb != null)
    {
        string html = "<TABLE border=0 align=left width=800><TR><TD>"
                    + wb.Document.Body.InnerHtml
                    + "</TD></TR></TABLE>";
        wb.Document.Body.InnerHtml = html;
    }
}

その結果、取り敢えずは折り返しの制御ができ、水平スクロールバーも表示されました。
あとは、折り返さずに表示するのに必要な幅が求められれば、この方法でも解決できそうです。
しかし、この方法が万能かどうか(内容によって問題が出ないか)確証がもてませんし、可能であれば
C#のプロパティやメソッド、またはIWebBrowser2等のインターフェースで解決したいと考えています。

また、WebBrowserコントロールはIEのコンポーネントを利用すると聞きました。
今回の確認はIE11で行いましたが、実際にはIE7〜11を動作対象にしたいと思っています。

何か初歩的な勘違いや見落としをしている気がします。
部分的なヒントや、検索キーワードなどでも結構ですので、ご教示頂けると嬉しいです。

以上、よろしくお願いします。

引用返信 編集キー/
■81728 / inTopicNo.2)  Re[1]: WebBrowserコントロールの折り返し制御
□投稿者/ WebSurfer (1062回)-(2016/11/02(Wed) 16:30:39)
No81727 (キム さん) に返信

WebBrowser は IE と同様に(デフォルトで IE7 相当)、web サーバーから受信した html ソ
ースを、それに定義されているスタイルに従って表示するというのが基本なので、質問者さん
がやりたいことを実現するには、質問者さんがやった「苦肉の策」のように DOM を書き換える
以外に方法はなさそうに思います。

具体例にあった「シンプルなHTMLファイル」しか対象としないのならそれでも対応可能かもし
れませんが、巷のネットにあるような千差万別の html ソースやスタイルでは何ともならない
のではないでしょうか?
引用返信 編集キー/
■81730 / inTopicNo.3)  Re[1]: WebBrowserコントロールの折り返し制御
□投稿者/ 魔界の仮面弁士 (937回)-(2016/11/02(Wed) 18:11:40)
No81727 (キム さん) に返信
> このとき、表示内容がWebBrowserコントロールの幅で自動的に折り返されてしまいます。
> (厳密には、WebBrowserコントロールの幅を超えない単語区切り)


すでに WebSurfer さんも指摘されていますが、スクロールの挙動は
Web ページの内容に依存しますので、汎用的にするのは難しいでしょう。

幅を動的に決めるのではなく、固定サイズで大きめに取るだけなら
水平スクロールな DIV 内に巨大なインラインフレームを入れて
そこにロードさせるという手も使えるかも知れません。お奨めはしませんが。



> test.html --------------
> <HTML>
> <BODY>
> <P>123 456 789 012 @AB CDE 〜中略〜 uvw xyz</P>
> </BODY>
> </HTML>
> -----------------------

たとえば上記を

<HTML>
<BODY style="white-space:nowrap; overflow-x:scroll; overflow-y:hidden">
<P>123 456 789 012 @AB CDE 〜中略〜 uvw xyz</P>
</BODY>
</HTML>

などとすれば、水平スクロールでの表示になると思います。


静的な html ファイルではないのなら DOM 操作で指定してみてください。

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
 var wb = sender as System.Windows.Forms.WebBrowser;
 if ( wb == null ) { return; }

 dynamic doc = wb.Document.DomDocument;
 dynamic element;
 if (doc.compatMode == "BackCompat")
 {
  element = wb.Document.Body.DomElement;
 }
 else if (doc.compatMode == "CSS1Compat")
 {
  element = doc.documentElement;
 }
 else
 {
  return;
 }
 var style = element.runtimeStyle;
 style.whiteSpace = "nowrap";
 style.overflowX = "scroll";
 style.overflowY = "hidden"; // あるいは "auto"
}
引用返信 編集キー/
■81731 / inTopicNo.4)  Re[2]: WebBrowserコントロールの折り返し制御
□投稿者/ キム (2回)-(2016/11/02(Wed) 21:13:23)
No81728 (WebSurfer さん) に返信
No81730 (魔界の仮面弁士 さん) に返信

WebSurferさん、魔界の仮面弁士さん、お返事ありがとうございます。

お二方のご指摘どおり、汎用性の点は不安に思っています。
出来れば内容は操作したくないので、パネルの中にWebBrowserコントロールを置いて、
WebBrowserコントロール自体のサイズを変更するようにしようとかも考えました。
(こうすれば、WebBrowserコントロール自体のサイズを大きくしてもコントロールの外観は
変化しませんし、スクロールバーはパネル側で表示出来るので)
しかし、結局最適なサイズの計算方法が見つからず、苦肉の策を取らざるを得ない状況です。

ただ、表示するHTMLは既存の1システムが吐き出したもののみなので何とかなるかもしれません。
頂いたサンプルはほぼ<P>タグ、<A>タグ、<HR>タグで構成されており、ログのようなものでした。
今回は、文の折り返しの有無をオプション指定で切り替えたいという要望が急遽挙がったため検討しましたが、
対応しない(対応できない)という選択肢も視野に入れて慎重に最終決定をしたいと思います。

尚、魔界の仮面弁士さんにご教示頂いたDOM操作でスタイルを指定する方法はうまくいきました。
TABLEだと最適なサイズの計算方法がわからず困りましたが、この方法だと自動計算されるので、
対応する場合は使わさせていただこうと思います。
とても助かりました。ありがとうございます。

インラインフレームにロードする方法についてはお奨めしないとのことなので試していませんが、
<IFRAME>タグ内に対象HTMLファイルのURLを書いて読み込ませるのかなと理解しました。
こちらは、他の方法で問題があったときに試させていただこうと思います。

もう少し検討してから解決にチェックを付けようと思います。
よろしくお願いします。
引用返信 編集キー/
■81732 / inTopicNo.5)  Re[3]: WebBrowserコントロールの折り返し制御
□投稿者/ WebSurfer (1063回)-(2016/11/03(Thu) 09:52:59)
No81731 (キム さん) に返信

> 頂いたサンプルはほぼ<P>タグ、<A>タグ、<HR>タグで構成されており、ログのようなものでした。

表示する html ソースはログのような完全に定型ということでいいのですか?

であれば、ブラウザ(WebBrowser を含む)ではなくて、別の手段を使うことを検討したほうがいい
のではないでしょうか?(例えば、HttpWebRequest / HttpWebResponse を使ってコンテンツを取得
し、それをパースして Windows Forms などで表示するとか)


WebBrowser を使うというのが絶対的な要件であれば話は別ですが。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -