Visual C#の最近のブログ記事

パスワードや機密情報などの文字列を安全に格納するクラスとして、.NET FrameworkにはSecureStringクラスが用意されている。クラスに格納した文字列は即座に暗号化され、万が一プロセス空間のメモリを外部から読み取られても、格納した文字列が盗み出されることはない。また、クラスには文字を設定するメソッドはあるが、読み出すメソッドが用意されていない。SecureStringに格納した文字列を取得するには、Marshalクラスに用意された専用のメソッドを経由する必要がある。

例えば、Webに掲載する一連のドキュメントをXHTMLでまとめ、Webサーバーでそれを読み込んでページを組み立てる。こんな風にすれば、下書きしたドキュメントをHTMLに書き直す手間が少なくなるかな、と思った。

XHTMLならXMLの一種だから、XmlDocumentクラスで読み込んで、ごにょごにょと必要箇所を取り出すようにしてみたり・・・。しようと思ったら、まず読み込みがめちゃ遅い!その上、SelectSingleNodeメソッドやSelectNodesメソッドがノードを返してくれない!

一体その原因はっ・・・!

VisualStyleで境界線を描く(前半)では、境界線を描くための準備までを説明しました。後半は境界線(非クライアント領域)の描画を中心に解説します。

WindowsXPでVisualStyleが導入され、Windowsのウィンドウと標準コントロール、コモンコントロールのデザインが一新しました。特に違いが際立つのはウィンドウのデザインですが、地味に目につくのがコントロールの境界線。前述したコントロールはVisualStyleが適用されるものの、一部のコントロールや自作のコントロールでは、境界線を3DにするとWindows2000までの旧デザインで描かれてしまい、妙に目立ってしまう。これをなんとかVisualStyleで描こう、というのが今回の主旨。

ASP.NETでLoginViewコントロールを配置すると、AnonymouseTempleteやLoggedInTempleteといった特定のタグのみを入れ子にすることができる。さらに、ユーザー認証の状況によって表示する部分を自動的に切り替えてくれる。

このように、特定の状況によって表示する部分を自動的に変更する仕組みはどうなっているのだろう??

と思って調べてみた。

たとえば次のような処理があったとする。

void Sample(string s)
{
    // sが空白なら処理しない
    if (s == "") return;

    // 処理

}

 

この処理には何らかの文字列が与えられなければならず、最初に空白文字の判定を行っている。今までこれで問題がなかったので特に気にすることもなかったけど、よくよく考えればStringは参照型だから"null"や"Nothing"が指定できてしまうわけで・・・

先日、System.Net.Mail名前空間のMailMessageクラスとSmtpClientクラスを使い、メール送信を行うテストプログラムを作成。そのメールをインターネットブラウザのOpera 9に付属されているメールクライアントで受信してみると・・・

警告: ファイルのデコード中にエラーが発生しました

というエラーが文末に赤字で表示されました。どうやら.NETから送信したメールだけがエラーを発生させている模様。原因を探っている中、メールのヘッダに気になる記述が・・・。

Color構造体(System.Drawing名前空間)は、.NETでの描画で頻繁に使う色情報。いろいろなメソッドやシステム定義の色がそろっていて便利なのだけど、色をブレンド(合成)するメソッドがなかったので自作することに。

2つのColor構造体を均等に混ぜ合わせた場合の色を作り出すロジックは単純で、それぞれの色要素(ARGB)の平均をとれば(=足して2で割れば)よい。んでも、それだとつまらないのであえて符号無し32bitでの計算に挑んでみた。

ASP.NET(IIS5.0)において、サーバーサイドで動的(リアルタイム)に作り出した画像をクライアントへ送るには、ImageクラスからResponse.OutputStreamへSaveすればよい。

 

と、考えていた。

たとえばこんな感じ。

[C#]

Image img;

// imgに対する描画は割愛

img.Save(context.Response.OutputStream, ImageFormat.Png);

 

実際に、Visual Studioでデバッグしてみてもちゃんと動作するので、安心してIIS 5.0に持って行ってみると、「GDI+で一般的なエラーが発生しました」というエラーを吐き出す。

いろいろと試してみたところ、MemoryStreamに一度書き出してからOutputStreamへ送り込めば大丈夫。おそらく、原因はOutputStreamがシークと読み取りを禁止している点。ImageクラスのSaveメソッド内で読み返しが行われているのか、CanSeek / CanReadをチェックしているのかは不明ですが、直接書き出すのは無理っぽい。

原因が判れば、OutputStreamへの書き込みを中継するストリームを自作することで、間接的に直書きができるかもしれない、と思ってやってみた。

 

UserControlを継承した独自のコントロールを使う際、FormデザイナでTextプロパティに与えた文字列はInitializeComponentに反映されない。なんとか反映できるようにならないかと、オーバーライドしたりnew(VBではShadows)で隠匿したり属性を変更したり・・・結局何やっても無理でした。 orz

バグなのか仕様なのか不明だけど、プロパティ名を変えるしかなさそう??