Bloggerのガジェット『フィード』は二種類ある

このブログの『Recent Posts』に使用している『フィード』というガジェットなんですが、最近どうも表示がおかしい。

おかしな点は以下の二つ

日付の表示形式が以前と変わり、そしてブラウザによってもその形式が変わる

Chromeの場合



Firefox3の場合


※以前の表示形式はこの投稿の文末付近で確認できます。

『ul』タグがネストしている

HTMLではリストなんですが、"ul"タグの中にもう一つ"ul"タグを入れてしまっている。

Firebugで見るとこのようになっています。






以前の状態に戻す

簡単に解決する方法として、以前の状態に戻すという方法があります。
内部的にはフィードガジェットは二種類あり、それをid属性により分けているようです。
因みに以前のモノのidは『Feed1_feedItemListDisplayOld』と末尾に『Old』が付きます。

以前の『フィード』ガジェットに戻すには、id属性を以前のモノに書き換えることで可能です。
具体的には
『Feed1_feedItemListDisplay』

『Feed1_feedItemListDisplayOld

方法:
テンプレートの編集から『』にチェックを入れ、『_feedItemListDisplay』という文字列を検索し、『Old』という文字を書き加えます。
すると、以前の状態に戻ります。






日付の表示形式については、恐らくローカル形式で表示させたかった、ということなのでしょうが、皮肉にも自身(Google)が出しているブラウザ(Chrome)で上手く表示できない、という結果にはちょっと笑っちゃいますね。

Visual C# 2008 Express Edition のインテリセンスを日本語化する

C# 2008を使用しているのですが私の環境ではインテリセンスの文字が英語のまま。
「いつかアップデートされたときにでも日本語化されるだろう」と、放っといたんですが、残念ながらいつまで経っても自動的には日本語化されないようなので探してきました。

こちらから該当の修正プログラムをダウンロードできます。



上記のサイトを巡り、最終的に以下の場所から
「VS90SP1-KB957507-JPN-x86.exe」
というファイルをダウンロードして実行します。


これでインテリセンスが日本語になっているはずです。

C#だけでなく、インストルーされている全てのVisual Studio 2008の製品に適用されます。

ビット演算を理解してフラグを使いこなす - C#

フラグの取得、設定(追加)、解除を行います。

理解しやすくするために0~9の数値に該当するビットを対象に、そして比較しやすいように桁数を4桁に統一し、話を進めます。

2進数対応表
10進数2進数
00000
10001
20010
30011
40100
50101
60110
70111
81000
91001
ビット演算子
演算子説明
&論理積
|論理和
^排他的論理和
~反転


ビット演算表

ビット&|^
000 00
01011
10011
11110



10進数の「2」を出力してみます。
出力される結果を見やすくするため、2進数はPadLeftを使用し、4桁で揃えています。

int flag = 2; //0010
Console.WriteLine(
    "10進数 : {0}\n 2進数 : {1}\n\n",
    flag,
    Convert.ToString(flag, 2).PadLeft(4, '0')
);

Result
10進数 : 2
2進数 : 0010



フラグの取得

フラグが立っているか否かを調べます。

フラグを取得する式
x & y
ビット演算子「&」は"x"と"y"の両方のフラグが立っている場合に1となります。

Example
3 & 2
    ↓
0011 & 0010
    ↓
結果: 0010
上記の場合、右から二番目の値だけが"1"なのでそれのみを残し、他は"0"となります。

これによってフラグの値のみを抽出できます。


Example
int flag1 = 2;//0010
int flag2 = 3;//0011

Console.WriteLine(flag1 & 2); //2
Console.WriteLine((flag1 & 2) != 0); //True
Console.WriteLine(flag2 & 2); //2
Console.WriteLine((flag2 & 2) != 0); //True
10進数の「2」、「3」ともに2番目のフラグが立っているのでTrueを返します。



フラグの設定

フラグが立っていない場合、フラグを設定します。

フラグを設定する式
x | y
ビット演算子「|」はどちらか一方、あるいは両方のフラグが立っていれば1となります。

Example
int flag1 = 2;//0010
int flag2 = 3;//0011
int flag3 = 4;//0100

var ret1 = flag1 | flag2;
Console.WriteLine(ret1); //3

//2進数に変換します。
Console.WriteLine(
    Convert.ToString(ret1, 2).PadLeft(4, '0'));
//0011


var ret2 = flag2 | flag3;
Console.WriteLine(ret2); //7

//2進数に変換します。
Console.WriteLine(
    Convert.ToString(ret2, 2).PadLeft(4, '0'));
//0111


var ret3 = flag3 | flag1;
Console.WriteLine(ret3); //6

//2進数に変換します。
Console.WriteLine(
    Convert.ToString(ret3, 2).PadLeft(4, '0'));
//0110


フラグの解除

フラグが立っている場合、フラグを解除します。

フラグを解除する式
x & ~y


まず「~」を使用して反転させます。
例えば10進数の「2」を反転させると
「0010」→「1101」(4桁揃え)
その後、&演算子を使用し、論理積を求めます。

Example
int flag = 2;
int xor = (byte)~flag;

Console.WriteLine(xor);//253

//2進数に変換します
Console.WriteLine(
    Convert.ToString(flag, 2).PadLeft(4, '0'));
//0010
Console.WriteLine(
    Convert.ToString(xor, 2).PadLeft(4, '0'));
//11111101

//論理積を出力します。
Console.WriteLine(2 & xor); //0
Console.WriteLine(2 & ~2); //0


フラグを使う具体例

もう少し具体的な例を挙げてみます。

権限を設定することを想定し、以下のようなenumを作成してみます。
[FlagsAttribute]
enum PermissionFlags
{
    None   = 0,
    Read   = 1,
    Create = 1 << 1,
    Write  = 1 << 2,
    Delete = 1 << 3,
    All    = 1 | 1 << 1 | 1 << 2 | 1 << 3
}

上のPermissionFlagsを使用して権限の取得、追加、削除を行ってみます。
var p = PermissionFlags.Create | PermissionFlags.Read;

Console.WriteLine(p);
//Read, Create

//取得
Console.WriteLine((p & PermissionFlags.Create) != 0);
//true

//追加
p |= PermissionFlags.Delete;
Console.WriteLine(p);
//Read, Create, Delete

//削除
p &= ~PermissionFlags.Create;
Console.WriteLine(p);
//Read, Delete

16進数文字列をintに変換するための事前検証と変換メソッド [C#]

16進数を表現した文字列をintに変換します。

ポイントは以下の二つです。

事前検証を行う

『Uri.IsHexDigit』を使用して事前検証を行います。
Uri.IsHexDigit(charValue)
対象文字列を「ToCharArray」でChar配列にし、一文字ずつ16進数に使用される文字であるかを検証します。
Regexによって文字列検証を行わずとも、このメソッドを使用すれば良いわけです。

16進数文字列をintに変換する

左側にゼロが埋め込まれていることを許す16進数文字列を32 ビット符号付き整数に変換します。
int.Parse(HexString, NumberStyles.AllowHexSpecifier));
16進数文字列をintに変換するにはこれが一番簡単です。


Sample Code

static void Main(string[] args)
{
    Console.WriteLine("16進数を入力して下さい.");

    while (true)
    {
        //1 行分の文字を読み取ります。
        string hex = Console.ReadLine();

        //対象文字が空であれば終了します。
        if (string.IsNullOrEmpty(hex)) return;


        if (IsHexString(hex))
        {
            Console.WriteLine(
                //文字列をそれと等価な 32 ビット符号付き整数に変換し、表示します。
                int.Parse(hex, NumberStyles.AllowHexSpecifier));
        }
        else
        {
            Console.WriteLine("is not hexadecimal number.");
        }
    }
}

/// <summary>
/// 指定した文字列が有効な 16 進数の数字かどうかを検証します。
/// </summary>
/// <param name="hx">検証対象文字列</param>
/// <returns>
/// 文字列が有効な 16 進数の値である場合は true。
/// それ以外の場合は false。
/// </returns>
static bool IsHexString(string hx)
{
    foreach (char c in hx.ToCharArray())
    {
        if(!Uri.IsHexDigit(c)) return false;
    }
    return true;
}

パスを取得 & 操作する [C#]

MyDocumentsフォルダなど、環境によって場所が異なる可能性のあるフォルダのパスを取得するには「Environment.GetFolderPath」を使用します。

string Environment.GetFolderPath(Environment.SpecialFolder folder)

For example
Console.WriteLine("MyPictures : {0}",Environment.GetFolderPath(Environment.SpecialFolder.MyPictures));



パスの操作

特定のパスから拡張子を取得するなどの操作を行うには『System.IO.Path』を使用します。

static void Main(string[] args)
{
    string fileName = "test.jpg";
    string dir = "C:\\mydir";
    string path = Path.Combine(dir, fileName);

    Console.WriteLine(
        //ファイル名を除いたパス(ディレクトリ)を返します。
        "GetDirectoryName : {0}" +
        //拡張子を返します。
        "\nGetExtension : {1}" +
        //ファイル名と拡張子を返します。
        "\nGetFileName : {2}" +
        //ファイル名のみを返します。
        "\nGetFileNameWithoutExtension : {3}" +
        //指定したパス文字列の絶対パスを返します。
        "\nGetFullPath : {4}" +
        //指定したパスのルート ディレクトリを返します。
        "\nGetPathRoot : {5}" +
        //ランダムなファイル名を返します。
        "\nGetRandomFileName : {6}" +
        //拡張子を変更します。
        "\nChangeExtension : {7}" +
        //ルートディレクトリを返します。
        "\nIsPathRooted : {8}",
        Path.GetDirectoryName(path),
        Path.GetExtension(path),
        Path.GetFileName(path),
        Path.GetFileNameWithoutExtension(path),
        Path.GetFullPath(fileName),
        Path.GetPathRoot(path),
        Path.GetRandomFileName(),
        Path.ChangeExtension(path, "bmp"),
        Path.IsPathRooted(path)
    );
}


カレントディレクトリとステムディレクトリを取得するメソッドの重複

カレントディレクトリ
  • Directory.GetCurrentDirectory()
  • Environment.CurrentDirectory


システムディレクトリ
  • Environment.GetFolderPath(Environment.SpecialFolder.System)
  • Environment.SystemDirectory






もう少し現実的な例を2つほど…

MyPicturesフォルダ直下にあるフォルダ名を取得し表示します

foreach (string p in Directory.GetDirectories(
    Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)))
{ 
    Console.WriteLine(p.Split('\\').Last()); 
}
'\'で分けて最後の値を取得しています。


MyPicturesフォルダ直下にあるファイル名を取得し表示します

foreach (string f in Directory.GetFiles(
    Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)))
{ 
    Console.WriteLine(Path.GetFileName(f));
}
「Path.GetFileName」を使用してファイル名を取得しています。

イメージのファイルフォーマットを拡張子から判断し取得する [C#]

ImageCodecInfoを使用したデモみたいなものです。
下記ではファイルの中身と拡張子が一致しているかを調べています。

.Net Frameworkでサポートされている拡張子

BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,EMF,WMF,TIF,TIFF,PNG,ICO

フォーマット分類される拡張子
BMPBMP,DIB,RLE
JPEGJPG,JPEG,JPE,JFIF
GIFGIF
EMFEMF
WMFWMF
TIFTIF,TIFF
PNGPNG
ICOICO

「RawFormat.Guid」プロパティによって取得できるファイルフォーマット、つまり中身と拡張子を比較するため、拡張子によって分類されるファイルフォーマットを取得する必要があります。

対象イメージのファイルフォーマットを拡張子から判断し取得します

public static IEnumerable GetFileNameExtensions(ImageCodecInfo ici)
{
    //FilenameExtensionで返される文字列を";"で分割します。
    foreach (string s in ici.FilenameExtension.Split(';'))
    {
        //"."は不要なので省きます
        yield return s.Substring(s.IndexOf('.'));
    }
}


public static string GetImageFormat(string ext)
{
    foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageDecoders())
    {
        foreach (string s in GetFileNameExtensions(ici))
        {
            if (s.ToUpper() == ext.ToUpper())
            {
                //該当するFormatDescriptionを返します。
                return ici.FormatDescription;
            }
        }
    }
    return null;
}

対象イメージのファイルフォーマットをRawFormatから判断し取得します

public static string GetFileFormat(Image img)
{
    try
    {
        foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageDecoders())
        {
            if (ici.FormatID == img.RawFormat.Guid)
                //該当するFormatDescriptionを返します。
                return ici.FormatDescription;
        }
        return string.Empty;
    }
    catch
    {
        return string.Empty;
    }
}

For example

static void Main(string[] args)
{
    string path = @"C:\test.png";

    string fileFormat1 = GetFileFormat(Path.GetExtension(path));
    string fileFormat2 = GetFileFormat(new Bitmap(path));

    Console.WriteLine(
        "fileFormat1 = {0}\nfileFormat2 = {1}\nEquals : {2}",
        fileFormat1, fileFormat2, fileFormat1 == fileFormat2);

    Console.ReadLine();
}

別スレッドからの操作 [C#]

ThreadやBackgroundWorkerなどを使用して別スレッドで処理を行うことがありますが、通常の方法では別スレッドからFormにあるコントロールのプロパティなどを操作することは出来ません。

例えば、以下のようにBackgroundWorkerを使用するとします。

BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);

以下の処理を「bw.RunWorkerAsync()」によって実行すると実行時にエラーとなります。
void bw_DoWork(object sender, DoWorkEventArgs e)
{
    //有効でないスレッド間の操作:
    //コントロールが作成されたスレッド以外のスレッドから
    //コントロール 'progressBar1' がアクセスされました。
    progressBar1.Maximum = 100;
}
上記ではプログレスバーのMaximumプロパティを設定していますが、別スレッドから行うことはできません。
(プロパティの値を取得することは可能です。)

そこで「Invoke」メソッドを使用します。
Invokeメソッドに渡すDelegate型のメソッドはdelegateで型を定義するか、戻り値、引数が必要ないならMethodInvokerを使用するのが良いでしょう。

MethodInvoker Sample
this.Invoke((MethodInvoker)delegate()
    {
        progressBar1.Maximum = 100;
    }
);



引数を必要とする場合の例

まず、渡すメソッドの型を定義します。
delegate void SetPrgrsBarProp(int max, int step);

そして以下がInvokeメソッドに渡すメソッドになります。
SetPrgrsBarProp spbp = (max, step) =>
{
    progressBar1.Maximum = max;
    progressBar1.Step = step;
};

Invokeメソッドにはメソッドとそれに使用する引数を別々に渡します。
this.Invoke(spbp, new object[] {200, 10});



Sample Code

上記をまとめたモノですので、Maximumプロパティを2度設定しています。
while文でプログレスバーをIncrementしています。
delegate void PrgrsBarIncrement();
delegate void SetPrgrsBarProp(int max, int step);
void bw_DoWork(object sender, DoWorkEventArgs e)
{
    this.Invoke((MethodInvoker)delegate()
        {
            progressBar1.Maximum = 100;
        }
    );


    SetPrgrsBarProp spbp = (max, step) =>
    {
        progressBar1.Maximum = max;
        progressBar1.Step = step;
    };

    this.Invoke(spbp, new object[] { 200, 10 });


    PrgrsBarIncrement pi = () =>
    {
        progressBar1.Increment(1);
    };

    while (progressBar1.Value < progressBar1.Maximum)
    {
        this.Invoke(pi);
        Thread.Sleep(50);
    }
}

コードスニペットを作成する [C#]

コードスニペットを作成するにはまず、VSでXMLファイルを新規作成、拡張子を「.snippet」に変更します。
既存のコードスニペットや以下を参考に必要な項目を書き加えます。


VBならCode Snippet Editorというものもありますが、エディタを使用しなくとも簡単なものならVSのインテリセンス機能により容易に作成できます。

Sample Code

<?xml version="1.0" encoding="UTF-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
        <Title>cr</Title>
        <Author>Y@$</Author>
        <Description>Console.ReadLine に対するコード スニペット</Description>
        <Shortcut>cr</Shortcut>
        <SnippetTypes>
            <SnippetType>Expansion</SnippetType>
        </SnippetTypes>
    </Header>
    <Snippet>
        <Declarations>
            <Literal Editable="false">
                <ID>ConsoleClass</ID>
                <Function>SimpleTypeName(System.Console)</Function>
            </Literal>
        </Declarations>
      <Code Language="CSharp">
        <![CDATA[$ConsoleClass$.ReadLine();]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

"Code"タグ内の「$」で囲まれた「$ConsoleClass$」が"Literal"タグに囲まれた"ID"にあたり、その"Function"に記述されたコードが挿入される、という仕組みです。


作成したスニペットをインポートする

[ツール]メニューの[コード スニペット マネージャ]を選択します。


コード スニペット マネージャ ダイアログが表示されます。
[インポート]ボタンを押下し、作成したsnippetファイルを選択します。


上記Sampleのスニペットの場合、"Shortcut"タグで指定したキーワード「cr」を入力し、Tabキーを2回押下するとスニペットが挿入されます。

GetFullPathとCombine [C#]

GetFullPath

名前空間System.IOのPath.GetFullPathを使用すると、同名前空間のDirectory.GetCurrentDirectory()で取得できるパスが自動で付加されます。

例)
string fileName = "foo.txt";
string fullpath = Path.GetFullPath(fileName);
「カレントディレクトリ + fileName」という文字列を返します。
カレントディレクトリが仮に『C:\fuga』とすると上記『fullpath』には『C:\fuga\foo.txt』が入ります。

また、以下のような途中までのパスを渡すと、
string path= "\mydir\foo.txt";
string fullpath = Path.GetFullPath(path);
//fullpath = C:\mydir\foo.txt"
「ルートディレクトリ + param」という形で返します。

Combine

Path.Combineは以下のように使用します。
string path = Path.Combine(dir,filename);
渡された文字列(上記の場合"dir"と"filename")の間に"\"を挿入してくれます。
必要性があまり感じられませんが、凡ミスを防ぐ意味で使うのもアリかなと。

Sample

『Directory.GetCurrentDirectory()』によって取得されるディレクトリと『Path.GetFullPath()』によって付加されるディレクトリが同じかを確かめています。
static void Main(string[] args)
{
    string fileName = "foo.txt";
    string currentDir = Directory.GetCurrentDirectory();

    string fullPath1 = Path.GetFullPath(fileName);
    string fullPath2 = Path.GetFullPath(Path.Combine(currentDir, fileName));
    
    Console.WriteLine(fullPath1);
    Console.WriteLine(fullPath2);
    Console.WriteLine(fullPath1 == fullPath2);
}

簡単にコードスニペット(Code Snippets)を挿入する[C#]

コードスニペット(ブロック)を挿入するには以下のような方法があります。

キーボード ショートカット

  • [Ctrl] + [K] Next [X] → スニペットの挿入
  • [Ctrl] + [K] Next [S] → ブロックの挿入


右クリックメニュー

  • 右クリック → [ショートカット メニュー]を表示
  • [スニペットの挿入(I)] or [ブロックの挿入(S)] を選択




しかし、もっと簡単に挿入する方法があります

キーワード + Tabキーを2回押下

コードスニペットのショートカットに登録された単語を入力し、その後Tabキーを2回押下するだけでコードスニペットを挿入することができます。

例)
if文を挿入する場合
「if」と入力し、その後Tabキーを2回押下する。
「Console.WriteLine();」を挿入する場合
「cw」と入力し、その後Tabキーを2回押下する。


msdnで公開されているコードスニペット

Visual Studio 2005 コード スニペット
今現在のVSは2008ですが、これしか見当たりませんでした…

Sony Style(ソニースタイル)
デル株式会社

Recent Posts