2011-10-28
■[cakephp] CakePHPのflashメッセージを通知用とエラー用でデザインを変更する
コントローラで下記のようにsetFlashメソッドを呼び出す。
通知用、エラー用にそれぞれcssクラスを作って指定してやる。
//通知用 $this->setFlash("データを登録しました", "default", array("class" => "flash-notice")); //エラー用 $this->setFlash("エラーが発生しました", "default", array("class" => "flash-error"));
下記のような感じでCSSを定義しておく
.flash-error { padding: 10px; margin: 15px auto; border: #FF6666 2px solid; background: #FFF0F0; color: #FF0000; } .flash-notice { padding: 10px; margin: 15px auto; border: #66CC66 2px solid; background: #F0FFF0; color: #008800; }
2011-07-23
■[Silverlight] generic.xamlでカスタムコントロールのスタイルを定義する時の決まりごと
http://d.hatena.ne.jp/kaorun/20110323/1300874396
から学んだこと。
2011-07-07
■[Silverlight] SilverlightでWebカメラの映像を表示する
こちらを参考に作成した。
http://msdn.microsoft.com/ja-jp/library/ff602282(v=vs.95).aspx
Webカメラに接続して映像を画面上に表示できるだけのサンプル。
BrushとしてRectangleのFillに設定してるので、Brushが設定できるところなら
どこでも映像を表示できるっぽい。
画像を切り出して保存もできるらしいので、色々面白いことできそうだなぁ。思いつかないけど。
MainPage.xaml
<UserControl x:Class="CameraTest.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <ComboBox x:Name="Devices" Grid.Column="0"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding FriendlyName}" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <Button Grid.Column="1" Content="Start" x:Name="StartButton" Click="StartButton_Click" /> <Button Grid.Column="2" Content="Stop" x:Name="StopButton" Click="StopButton_Click" /> </Grid> <Rectangle Grid.Row="1" x:Name="webcamDisplay" Width="150" Height="100" Stroke="Black" /> </Grid> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace CameraTest { public partial class MainPage : UserControl { CaptureSource captureSource = new CaptureSource(); public MainPage() { InitializeComponent(); Devices.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices(); VideoBrush webcamBrush = new VideoBrush(); webcamBrush.SetSource(captureSource); webcamDisplay.Fill = webcamBrush; } private void StartButton_Click(object sender, RoutedEventArgs e) { captureSource.VideoCaptureDevice = (VideoCaptureDevice)Devices.SelectedItem; if (CaptureDeviceConfiguration.RequestDeviceAccess() && captureSource.VideoCaptureDevice != null) { try { captureSource.Start(); } catch (InvalidOperationException ex) { MessageBox.Show("カメラの起動に失敗しました"); } } } private void StopButton_Click(object sender, RoutedEventArgs e) { if (captureSource.VideoCaptureDevice != null) { captureSource.Stop(); } } } }
■[Silverlight] Silverlightでファイルをアップロードして保存する
複数ファイルアップロードが結構簡単にできるみたい。
下記のサイトを参考(ほぼそのまま)に作ってみた。
Silverlight 4でドロップされたデータをサーバに保存
http://d.hatena.ne.jp/okazuki/20100330/1269949623
Silverlightでユーザがアップロードしたファイルをダウンロードする
http://d.hatena.ne.jp/coma2n/20080421/1208784501
ファイルを開くダイアログで選択された複数のファイルをサーバにアップロードして保存するサンプル。
WCF RIA Servicesのドメインサービスを使ってサーバ側と連携してる。
MainPage.xaml
<UserControl x:Class="SilverFileUpload.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <StackPanel x:Name="LayoutRoot" Background="White"> <Button x:Name="OpenFileButton" Content="open file" Click="OpenFileButton_Click" /> <TextBox x:Name="MessageTextBox" Width="200" Margin="10" AcceptsReturn="True" Height="200" /> </StackPanel> </UserControl>
using System; using System.Text; using System.IO; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using SilverFileUpload.Web; namespace SilverFileUpload { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void OpenFileButton_Click(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Text Files (.txt)|*.txt|All Files (.*)|*.*"; openFileDialog.FilterIndex = 1; openFileDialog.Multiselect = true; bool? isOKClicked = openFileDialog.ShowDialog(); if (isOKClicked == true) { IEnumerable<FileInfo> files = openFileDialog.Files; StringBuilder sb = new StringBuilder(); foreach (FileInfo file in files) { using (var stream = file.OpenRead()) { var ms = new MemoryStream(); byte[] buffer = new byte[1024 * 100]; while (stream.Read(buffer, 0, buffer.Length) != 0) { ms.Write(buffer, 0, buffer.Length); } var ctx = new FileUploadDomainContext(); ctx.Upload(file.Name, ms.ToArray(), result => { // 終了後処理 }, null); } sb.Append(file.Name + "\r\n"); } MessageTextBox.Text = sb.ToString(); } } } }
FileUploadDomainService.cs
namespace SilverFileUpload.Web { using System; using System.IO; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.ServiceModel.DomainServices.Hosting; using System.ServiceModel.DomainServices.Server; // TODO: アプリケーション ロジックを含むメソッドを作成します。 [EnableClientAccess()] public class FileUploadDomainService : DomainService { public bool Upload(string fileName, byte[] data) { try { using (var w = new FileStream(Path.Combine(@"ファイル保存先ディレクトリ", fileName), FileMode.OpenOrCreate, FileAccess.Write)) { w.Write(data, 0, data.Length); } return true; } catch { return false; } } } }
AppEngineでもサンプルを作ってみたいところ。
2011-07-06
■[C#][NAnt] 指定したフォルダ内のファイルの文字コードをUTF-8に変換するタスク
指定フォルダ内の全ファイルについて、文字コードを自動判定して読み込み、
文字コード自動判定については、下記のページでJcode.pmを参考にした関数が
紹介されているので、そちらを使わせていただく。
http://dobon.net/vb/dotnet/string/detectcode.html
紹介されているGetCode関数を、UtilsフォルダにJcode.csとして保存したとする。
作ったタスクはこんな感じ。
文字コードがShift_JISかEUC-JPの場合のみUTF-8に変換するようにしてる。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using MyTasks.Utils;
namespace MyTasks.Tasks
{
[TaskName("encode2utf8")]
class Encode2UTF8Task : Task
{
private string _dirPath;
[TaskAttribute("dir", Required = true)]
[StringValidator(AllowEmpty = false)]
public string DirPath
{
get { return this._dirPath; }
set { this._dirPath = value; }
}
protected override void ExecuteTask()
{
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(this._dirPath);
IEnumerable<System.IO.FileInfo> fileList = dirInfo.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
var queryMatchingFiles = from file in fileList
select file.FullName;
System.Text.Encoding enc_utf8 = System.Text.Encoding.GetEncoding("utf-8");
System.Text.Encoding enc = null;
System.IO.FileStream fs = null;
byte[] bs = null;
foreach (string fileName in queryMatchingFiles)
{
fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
bs = new byte[fs.Length];
fs.Read(bs, 0, bs.Length);
fs.Close();
enc = Jcode.GetCode(bs);
if (enc != null)
{
if (enc.CodePage == 932 || enc.CodePage == 51932)
{
System.IO.File.WriteAllText(fileName, enc.GetString(bs), enc_utf8);
Log(Level.Info, string.Format("{0}から{1}に変換しました: {2}", enc.EncodingName, enc_utf8.EncodingName, fileName));
}
}
}
}
}
}
buildファイルにはこんな感じでタスクを定義する
<target name="load"> <loadtasks assembly="C:\ht\data\workspace\MyTasks\MyTasks\bin\Debug\MyTasks.dll" /> </target> <target name="encode2utf8" depends="load"> <if test="${not property::exists('dirPath')}"> <property name="dirPath" value="${basic::getInput()}" /> </if> <encode2utf8 dir="${dirPath}" /> </target>
使う時は、コマンドプロンプトで下記のようなコマンドを実行する
nant encode2utf8 -D:dirPath=C:\sjis_folder
既存ファイルを上書きしちゃうので、使う時はご注意ください。
2011-07-05
■[C#][Nant] NAntのカスタムタスクで実行時にユーザー入力を受け付ける
便利タスクを作っていく上で、実行時に処理対象を指定したりできた方がいい、
ということでユーザー入力を受け付ける方法を調査した。
方法としては2つあって、どちらもプロパティ(変数みたいなもの)に
ユーザーからの入力を代入するというもの。
1つ目の -D オプションによるプロパティ定義は、buildファイルにpropertyタグを書くのと同じ効果。
こんな感じで指定する
nant タスク名 -D:プロパティ名=プロパティ値 nant greetings -D:message=Hello!
これは、buildファイルに下記のタグを書くのと同じ。
<property name="message" value="Hello!" />
実行時に入力を受け付けるにはこれで十分なのだけど、せっかく調べたので
カスタムファンクションを作成する方法も書いておく。
どうやらNAntにはユーザー入力を受け付ける関数なりタスクは用意されていないようで、
自分でカスタムファンクションとしてユーザーに入力を促す処理を書くことで実現する。
入力処理についてはここを参考にした。
http://www.mail-archive.com/nant-users%40lists.sourceforge.net/msg11606.html
カスタムファンクションについては、ソースを見るのが一番良いようだけど、
ここからヒントをもらった。
http://efreedom.com/Question/1-284120/NAnt-Extension-Function-Project-Object
上記を参考にこんなクラスを作成。
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
namespace MyTasks.Funcs
{
[FunctionSet("basic", "Basic")]
class BasicFunctions : FunctionSetBase
{
public BasicFunctions(Project project, PropertyDictionary properties)
:base(project, properties)
{
}
[Function("getInput")]
public static string GetInput()
{
Console.WriteLine("Enter a string:");
string s = Console.ReadLine();
return s.ToString();
}
}
}
buildファイルに下記のようなpropertyタグを作成すると、ユーザー入力を促して
プロパティ値に設定することができる。
<property name="message" value="${basic::getInput()}" />
この2つの入力方法を組み合わせて、コマンド実行時にプロパティを指定していなければ
ユーザー入力を促す、という処理を作成するとしたら、こんな感じでビルドファイルに定義する。
... <target name="greetings" depends="load"> <if test="${not property::exists('message')}"> <property name="message" value="${basic::getInput()}" /> </if> <greetings mesg="${message}" /> </target> ...
