Loading [MathJax]/extensions/tex2jax.js

2016年10月22日土曜日

GlyphTypeFace を new したときに NullReferenceException

発生したこと
Windowsのフォントフォルダに存在するフォントファイルの一覧を取得し、
各フォントファイルのGlyphTypeFaceを生成する処理を実装したところ、
一部のフォントでNullReferenceException
( オブジェクト参照がオブジェクト インスタンスに設定されていません。 )
が発生する場合があることがわかりました。

※EnumCharのユーザー様からの障害報告で気づきました。

例外のスタックトレース
場所 MS.Internal.FontCache.FontFaceLayoutInfo.IntMap.TryGetValue(Int32 key, UInt16& value)
場所 System.Windows.Media.GlyphTypeface.Initialize(Uri typefaceSource, StyleSimulations styleSimulations)
場所 System.Windows.Media.GlyphTypeface..ctor(Uri typefaceSource)
場所 ConsoleApplication1.Program.Main(String[] args)
原因
フォントを上書きインストールしたことのある環境では、
古いフォントがフォントフォルダに残っており、
その古いフォントにアクセスしようとすると、実体が無いようで、
exceptionが発生するというのが原因でした。

下記のサイトが参考になります。
http://d.hatena.ne.jp/itouhiro/20120603
コード
実際にexception が発生するコードがこちらになります。
※実際にビルドするには、PresentationCoreを参照設定する必要があります。
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows.Media; // 参照設定で PresentationCoreをONにする必要がある。  
  6.   
  7. namespace ConsoleApplication1  
  8. {  
  9.     class Program  
  10.     {  
  11.         static void Main(string[] args)  
  12.         {  
  13.             // フォントファイルのパス取得   
  14.             string fontfolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);  
  15.   
  16.             // フォントファイルの一覧取得  
  17.             string[] fontfiles = System.IO.Directory.GetFiles(fontfolder);  
  18.   
  19.             foreach (string fontfile in fontfiles)  
  20.             {  
  21.                 // 拡張子を切り出す  
  22.                 string ext = System.IO.Path.GetExtension(fontfile);  
  23.   
  24.                 if ((String.Compare(ext, ".ttf"true) == 0) || (String.Compare(ext, ".otf"true) == 0))   
  25.                 {  
  26.                     /* TTF, OTF  */  
  27.                     try  
  28.                     {  
  29.                         Console.WriteLine(fontfile); // debug  
  30.   
  31.                         GlyphTypeface typeface = new GlyphTypeface(new Uri(fontfile));  
  32.                     }  
  33.                     catch (NullReferenceException nullex)  
  34.                     {  
  35.                         Console.WriteLine(nullex.Message); // debug  
  36.                     }  
  37.                 }  
  38.             }  
  39.             Console.ReadKey();  
  40.         }  
  41.     }  
  42. }  
実行結果
苦労したこと
・フォントフォルダをExplorerで見る限りは、フォントが1個しか存在しないため、
 原因の特定に時間がかかりました。
・また、現象が発生するフォントをアンインストールしても現象が発生したため、迷宮入りしそうになりました。

2016年10月9日日曜日

UWP で Hello World!

やりたいこと
UWP(Universal Windows Platform) で Hello World! をしたい。
XAMLはいじらないような方針で作成します。

環境 : Visual Studio 2015 community

どんなのを作るか?
小さいですが、Hello World!と表示されてます。
Step1 プロジェクト作成
ファイルメニュー - 新規作成 - プロジェクト を選択する。

新しいプロジェクトダイアログで、Universal - Blank App(Universal Windows)を選択する。
※他はデフォルトで結構です。


Step2 UIデザインにテキストを追加
ソリューションエクスプローラーにて、MainPage.xamlをダブルクリックする。


UIのデザインが表示されるので、ツールボックスから、TextBlockを白いところにドラッグ&ドロップする。

Step3 追加したテキストをHello World!に替える
UIデザインの画面で、Step2で追加したTextBlockを選択し、プロパティウィンドウで、いなづまマークをクリックする。

Loadingの空欄をダブルクリックする。(イベントハンドラを追加してます。)

ダブルクリックすると、空欄にtextBlock_Loadingが入力され、
メイン画面がMainPage.xaml.csに切り替わります。
MainPage.xaml.csのtextBlock_Loadingの中に「textBlock.Text = "Hello World!";」を入力し、
再生ボタンを押すと、立ち上がります。

※自分の環境では、しばらく緑の画面で、でかでかと✕が書かれたものが表示されますが、そのうちHello Worldが表示されます。