2011/08/14

980えん

ビックカメラで FF14 の通常版が 980 円だったのでポチってしまった。

水着でアイテム欄きつくなってたところだったし、丁度良かった。

2011/08/07

Windows Live Writer プラグインのつくりかた

  1. .NET Framework クラスライブラリを作成し、ターゲットフレームワークを .NET Framework 2.0 に設定する
  2. Writer のインストールフォルダにある WindowsLive.Writer.Api.dll を参照設定に追加する
  3. WindowsLive.Writer.Api.ContentSource クラスを継承したクラスを適当に作る
  4. WindowsLive.Writer.Api.WriterPluginAttribute を作成したクラスに設定する
    1. id には適当な GUID を設定する(ブラケットは含まない)
    2. name にはプラグイン名を設定する
    3. プラグイン名の横にアイコンを設定したい場合は ImagePath で指定する
  5. WindowsLive.Writer.Api.InsertableContentSourceAttribute を作成したクラスに設定する
    1. menuText にメニューに表示されるテキストを設定する
  6. ContentSource.CreateContent メソッドをオーバーライドして実装する
    1. 範囲選択されている場合、content にはそのコードが格納されている
    2. 挿入したいコードを content に代入する
    3. DialogResult.OK を返すとコンテンツが作成され、DialogResult.Cancel を返すと操作がキャンセルされる
  7. Writer のインストールフォルダにある Plugins フォルダにビルドした DLL をコピーすれば自動で認識される(レジストリを使って、別の場所にあるプラグインを認識させることもできる。→MSDN))
  8. おつかれさまでした

コード例:

[WriterPlugin("B6854B3A-2CB1-4932-8458-372F34D91268", "VSHighlight")]
[InsertableContentSource("VSHighlight")]
public class VSHighlight : ContentSource
{
    public override DialogResult CreateContent(IWin32Window dialogOwner, ref string content)
    {
        var clipboard = GetRTFFromClipboard();
        if (clipboard != string.Empty)
        {
            content = Rtf2Html(clipboard);
            return DialogResult.OK;
        }
        else
        {
            return DialogResult.Cancel;
        }
    }

2011/08/05

打倒文字化け

すごくめんどくさかったというお話。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using System.Runtime.InteropServices;

namespace VSClipboardTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // にほんご

        [DllImport("user32.dll")]
        private static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("user32.dll")]
        private static extern int IsClipboardFormatAvailable(int wFormat);
        [DllImport("user32.dll")]
        private static extern IntPtr GetClipboardData(int wFormat);
        [DllImport("user32.dll")]
        private static extern int CloseClipboard();
        [DllImport("user32.dll")]
        private static extern int RegisterClipboardFormat(string lpszFormat);

        private void button1_Click(object sender, EventArgs e)
        {
            OpenClipboard(IntPtr.Zero);
            int wFormat = RegisterClipboardFormat("Rich Text Format");
            IntPtr clipboard = GetClipboardData(wFormat);
            if (clipboard != IntPtr.Zero)
            {
                textBox1.Text = Marshal.PtrToStringAnsi(clipboard);
                textBox2.Text = Rtf2Html(textBox1.Text);
            }
            CloseClipboard();
        }

        private string Rtf2Html(string rtf)
        {
            var fontTable = new List<string>();
            var colorTable = new List<Color>();
            
            // load font table
            int fontTablePosition = rtf.IndexOf(@"{\fonttbl");
            if (fontTablePosition >= 0)
            {
                int fontTableEnd = rtf.IndexOf("}}", fontTablePosition + 10);
                if (fontTableEnd >= 0)
                {
                    string fontTableData = rtf.Substring(fontTablePosition + 10, fontTableEnd - fontTablePosition - 10);
                    foreach (string tableItem in fontTableData.Split(new[] { ';' }))
                    {
                        string[] pair = tableItem.Split(new[] { ' ' }, 2);
                        if (pair.Length == 2)
                        {
                            fontTable.Add(pair[1]);
                        }
                    }
                    
                    rtf = rtf.Remove(fontTablePosition, fontTableEnd - fontTablePosition + 2);
                }
            }

            // load color table
            colorTable.Add(Color.Black);
            int colorTablePosition = rtf.IndexOf(@"{\colortbl");
            if (colorTablePosition >= 0)
            {
                int colorTableEnd = rtf.IndexOf("}", colorTablePosition + 11);
                if (colorTableEnd >= 0)
                {
                    string colorTableData = rtf.Substring(colorTablePosition + 11, colorTableEnd - colorTablePosition - 11);
                    foreach (string colorItem in colorTableData.Split(new[] { ';' }))
                    {
                        Regex colorRegex = new Regex(@"\\red(?<r>\d+)\\green(?<g>\d+)\\blue(?<b>\d+)");
                        Match colorMatch = colorRegex.Match(colorItem);
                        if (colorMatch.Success)
                        {
                            colorTable.Add(
                                Color.FromArgb(
                                    int.Parse(colorMatch.Groups["r"].Value),
                                    int.Parse(colorMatch.Groups["g"].Value),
                                    int.Parse(colorMatch.Groups["b"].Value)));
                        }
                    }
                rtf = rtf.Remove(colorTablePosition, colorTableEnd - colorTablePosition + 1);
                }
            }

            // remove \rtf\ansi
            var rtfansiPattern = new Regex(@"(?<!\\)\\rtf\\ansi");
            rtf = rtfansiPattern.Replace(rtf, "");

            // remove header
            rtf = rtf.Remove(0, 1);
            rtf = rtf.Remove(rtf.Length - 1, 1);

            // convert return codes
            var crlfPattern = new Regex(@"(?<!\\)\\par ");
            rtf = crlfPattern.Replace(rtf, "\r\n");

            // html special characters
            rtf = rtf.Replace("&""&amp;").Replace("<""&lt;").Replace(">""&gt;");
            var spacePattern = new Regex(@"(?<!\\[a-zA-Z0-9]+?) ");
            rtf = spacePattern.Replace(rtf, "&nbsp;");

            // coloring
            var cf0Pattern = new Regex(@"(?<!\\)\\cf0 ");
            rtf = cf0Pattern.Replace(rtf, "</span>");
            for (int i = 1; i < colorTable.Count; i++)
            {
                var cfnPattern = new Regex(@"(?<!\\)\\cf" + i.ToString() + " ");
                rtf = cfnPattern.Replace(rtf, string.Format("<span style='color: #{0:X6};'>", colorTable[i].ToArgb() & 0x00FFFFFF));
            }
            if (rtf.LastIndexOf("</span") < rtf.LastIndexOf("<span") && rtf.LastIndexOf("</span") >= 0)
            {
                rtf += "</span>";
            }

            // unicode
            var unicodeInput = new Regex(@"(?<!\\)\\uinput2\\u(?<code>\d+) ..");
            while (true)
            {
                var match = unicodeInput.Match(rtf);
                if (match.Success)
                {
                    char c = (char)int.Parse(match.Groups["code"].Value);
                    rtf = unicodeInput.Replace(rtf, c.ToString(), 1);
                }
                else
                {
                    break;
                }
            }

            // remove rtf tags
            Regex rtfTag = new Regex(@"(?<!\\)\\[a-zA-Z0-9]+?[\s{}]");
            rtf = rtfTag.Replace(rtf, "");

            // convert special characters
            rtf = rtf.Replace("\\\\""\\");
            rtf = rtf.Replace("\\{""{");
            rtf = rtf.Replace("\\}""}");

            // add pre
            rtf = "<pre class='code'>" + rtf + "</pre>";

            return rtf;
        }
    }
}

あとは Live Writer 用のプラグイン作れば完了な感じなんだろうか。

しかし酷いコードだ。

2011/08/04

VSPaste

Windows Live Writer に Visual Studio のソースコードをコピペできるプラグインがあったので入れてみた。

MainWindow.xaml

<Window x:Class="DiskView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListView Name="listView1">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Drive" Width="80">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Label Content="{Binding Path=Name}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn x:Name="UseColumn" Header="Use" Width="150" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Grid Width="{Binding ElementName=UseColumn, Path=Width}">
                                    <ProgressBar Margin="0,0,12,0" Maximum="100" Value="{Binding Path=Percentage}" Foreground="{Binding Path=Color}" />
                                    <TextBlock Margin="0,0,12,0" Text="{Binding Path=ProgressText}" HorizontalAlignment="Center" VerticalAlignment="Center" />
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn x:Name="FreeColumn" Header="Free" Width="150">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Grid Width="{Binding ElementName=FreeColumn, Path=Width}">
                                    <Label Margin="0,0,12,0" Content="{Binding Path=Free}" HorizontalAlignment="Right" />
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
            <ListViewItem />
        </ListView>
    </Grid>
</Window>

 

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace DiskView
{
    /// <summary>
    /// MainWindow.xaml のI相?互Y作i用pロ?ジWッbクN
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var action = new Action(() =>
            {
                listView1.Items.Clear();
                listView1.Items.Add(new ListItem(new DriveInfo("C")));
                listView1.Items.Add(new ListItem(new DriveInfo("D")));
                listView1.Items.Add(new ListItem(new DriveInfo("E")));
            });
            action.Invoke();

            var timer = new System.Timers.Timer();
            timer.Elapsed += new System.Timers.ElapsedEventHandler((x, y) =>
            {
                Dispatcher.Invoke(action, null);
            });
            timer.Interval = 5000;
            timer.Start();
        }
    }

    public class ListItem
    {
        public string Name { get; set; }
        public int Percentage { get; set; }
        public Brush Color { get; set; }
        public string ProgressText { get; set; }
        public string Free { get; set; }

        public ListItem(DriveInfo di)
        {
            Name = di.Name;
            Percentage = (int)((double)(di.TotalSize - di.TotalFreeSpace) / (double)di.TotalSize * 100);
            if (Percentage > 70)
            {
                Color = Brushes.Yellow;
            }
            else if (Percentage > 90)
            {
                Color = Brushes.DarkRed;
            }
            else
            {
                Color = Brushes.Lime;
            }
            ProgressText = string.Format(
                "{0:F1}%",
                ((double)(di.TotalSize - di.TotalFreeSpace) / (double)di.TotalSize * 100));
            Free = string.Format("{0:F1}MB", di.TotalFreeSpace / 1024.0 / 1024.0);
        }
    }
}

日本語が化けるなぁ

2011/08/03

ファミ通

昨日宝箱5個の RAID に参加させてもらったのだけど、どうやらファミ通の方々だったらしい。

エオルゼア通信買ってあげよう。

 

http://www.famitsu.com/blog/ff14/2011/08/post_43.html

ちくちくオンライン

image

25 分以内クリア報酬の弓を手に入れて、RAID 攻略も一段落ついた感じ。

ウルダハンロングボウやクラブボウと比べると、物凄い勢いで矢が撃てる。

でも物凄い勢いでヘイトも貯まる。