2012-11-26

heroku上のtDiaryに引っ越してみた
2012-09-10
■[ruby][rails]rails-3.1.0をcygwinでやるメモ
sqlite
javascript engine
なんとなくspidermonkeyにする。
http://ftp.mozilla.org/pub/mozilla.org/js/
から
をダウンロードする。
$ cd /usr/local/src $ wget http://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz $ tar xzf js-1.7.0.tar.gz $ cd js/src $ make -f Makefile.ref OS_ARCH=Linux LD=gcc $ cp cp Linux_All_DBG.OBJ/js.exe /usr/local/bin/
export EXECJS_RUNTIME=SpiderMonkey
2012-09-04
■[CSharp]JSONと相互変換できるXMLの記述
JsonReaderWriterFactoryはどんなJSONでもParseしてXElemnt化できるが、XmlをJSON化するには特定の構造を持っている必要がある。
objectとarrayとその他の単一項目(number, boolean, stringなど)の持ち方が決まっている。
見た目に分かるようなものをwpfで作ってみた。あとで続きを作るかもしれないが原型ができたのでメモ。
<Window x:Class="XMLExperiment.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> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TreeView x:Name="tree" Grid.Column="0" ItemsSource="{Binding Root.Children}"> <!--DirectoryViewModel のデータを表示するときに使うテンプレート--> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Children}"> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> <TextBox x:Name="xml" Grid.Column="1" Text="{Binding Xml}" /> <TextBox x:Name="json" Grid.Column="2" Text="{Binding Json}" /> </Grid> </Window>
namespace XMLExperiment { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var tree = new Tree(); DataContext = tree; } } }
namespace XMLExperiment { public class Node : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } private XElement _e; private ObservableCollection<Node> _children; public Node(XElement e) { _e = e; } public String Name { get { return _e.Name.ToString(); } } public ObservableCollection<Node> Children { get { if (_children == null) { _children = new ObservableCollection<Node>(_e.Elements().Select(e => new Node(e))); } return _children; } } } public class Tree { public Tree() { Json = @"{ ""hoge"":[ 1 ,2 ,3 ,{ ""nazo"": true } ] }"; } private XElement _root; public Node Root { get { return new Node(_root); } } public String Xml { set { } get { return _root.ToString(); } } public String Json { set { using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.Unicode.GetBytes(value), XmlDictionaryReaderQuotas.Max)) { _root=XElement.Load(reader); } } get { using (var ms = new MemoryStream()) using (var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.Unicode)) { _root.WriteTo(writer); writer.Flush(); return Encoding.Unicode.GetString(ms.ToArray()); } } } } }
自分はobjectをシリアライズしたりデシリアライズしたいのではなくて動的に組み立ててそれをJSONと相互に変換したいので、
いまいち既存のライブラリとは目的が一致しないのだよな・・・。
泥臭いXElementラッパを作るのが早いかも知れぬ。
参考
2012-08-24
■[WPF]ファイラーその4
アイコンをつける。
Win32apiのSHGetFileInfoを呼べるようにする
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
class Win32
{
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(
string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
[DllImport("user32")]
public static extern int DestroyIcon(IntPtr hIcon);
}
ファイルパスからアイコン画像を得る。ObservableCollection<Item>
class Item
{
public FileSystemInfo Info
{
set;
get;
}
public String Name
{
get { return Info.Name; }
}
public String Length
{
get
{
var file = Info as FileInfo;
if (file == null)
{
return "";
}
else
{
return file.Length.ToString();
}
}
}
public BitmapSource Bitmap
{
get
{
SHFILEINFO shinfo = new SHFILEINFO();
var hImgLarge = Win32.SHGetFileInfo(Info.FullName, 0,
ref shinfo, (uint)Marshal.SizeOf(shinfo),
Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
BitmapSource source = Imaging.CreateBitmapSourceFromHIcon(shinfo.hIcon, Int32Rect.Empty, null);
Win32.DestroyIcon(shinfo.hIcon);
return source;
}
}
};
ListViewのDataTemplateにBitmapをバインディングする
<ListView Grid.Row="1" ItemsSource="{Binding Path=Files}" AlternationCount="2">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding Path=Bitmap}" Margin="5,0,5,0" />
<Label Grid.Column="1" Content="{Binding Path=Name}"/>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Size">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=Length}" HorizontalAlignment="Right"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" >
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<EventSetter Event="MouseDoubleClick" Handler="listBoxItem_DoubleClick"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
アイコンが出るようになった。
別スレッドでアイコン画像の読み込みをする
public DirectoryInfo Current
{
get { return current_; }
set
{
current_ = value;
NotifyPropertyChanged("Current");
NotifyPropertyChanged("Path");
files_.Clear();
var workList=new List<Item>();
try
{
foreach (var e in current_.GetFileSystemInfos())
{
// FileSystemInfoだけのリストを作って、
// 後でアイコン画像をロードする
var item=new Item
{
Info = e
};
files_.Add(item);
workList.Add(item);
}
// 別スレッドでビットマップ更新を呼び出す
var task = new Task(() =>
{
foreach (var item in workList)
{
var source = LoadBitmapSource(item.Info);
source.Freeze(); // 重要
Action action = () =>
{
// UIスレッド
item.Bitmap = source;
};
dispatcher_.Invoke(action);
}
});
task.Start();
}
catch (UnauthorizedAccessException e)
{
// do nothing
}
catch (DirectoryNotFoundException e)
{
// do nothing
}
}
}
github作った。

