2013年11月19日火曜日

神戸・三ノ宮でのiPhoneの修理

夜道でGoogleMapを頼りに進んでたら段差に気付かずコケてしまった。
そのときに手に持ってたiPhoneはガラス部分がヒビだらけになってしまった。

買い替えると5-6万円はするので青ざめたけど
この手のトラブルはよくあるのでAppleやSoftbankとは関係ない
修理屋に持ち込むことにした。

ネットで調べて適当に店舗の当たりをつける。
今回はこの店舗にした。
Smart Doctor 三宮店
http://www.iphone-kobe.biz/

高架下の狭い店舗で行ってみると服屋の店員みたいなチャラそうな兄ちゃんが一人。
ちょっと不安になったけど話してみると受け答えは社会人らしくしっかりしてたので
お願いしてみることに。

フロントガラス・液晶の交換は12,600円とのこと。
免責事項などの書類へのサインを求められる。
不安なのは預けてから調査費やら何やら難癖つけられて当初見積もりよりも高額な料金を取ろうとすること。
まあちゃんと店舗を構えてるのでその手のボッタクリ店ではあるまいと踏んでサインする。

修理時間は30分とのことなのでラーメン食ってから25分後に再訪すると既に終わってた。
軽く動作確認して見積もり通りの12,600円を支払い完了。


非公式の修理屋は初めてだったので不安だったけど問題無しだった。
チャラそうとか疑ってごめんね>店員の兄ちゃん
また同様の事態があれば利用すると思います。

2013年10月11日金曜日

WPFの描画処理の実行順について

下記のコードはLabel1の表示を更新してから3秒間UIスレッドをフリーズさせて処理が戻ることを期待している。
private void button1_Click(object sender, RoutedEventArgs e)
{
    this.Label1.Content = DateTime.Now.ToString();
    System.Threading.Thread.Sleep(3000);
}
しかし結果はそうはならない。3秒間フリーズした後に表示が更新されてUIに処理が戻る。
これはLabel1.Contentプロパティの値自体は意図したタイミングで更新されるが、実際の描画処理はPriority=7(Render)でキューイングされるがこの優先順位はPriority=9(Normal)より低いためイベントハンドラを抜けた後に実行される。つまりSleep()が先に実行される。

これが問題になるのは処理に時間がかかる場合なので別スレッドからInvoke/BeginInvokeする時にPriorityを変更してやればいい(通常変更する必要も無いが)。 ともかくこの現象を知っておかないと「おや?」と思う挙動をすることがあるので注意。

2012年6月13日水曜日

FTPでのファイル一覧取得の壁

FTPで指定したディレクトリ下のファイル一覧はFTPの"LIST"コマンドによって取得できる。しかし、このコマンドで取得できる結果のフォーマットについて標準的な規定は無く、FTPサーバーの実装に依存する。

つまり結果がどんなフォーマットで来るか分からないために、パース処理の実装が極めて難しい。FileZillaのような優秀なFTPクライアントがこの問題をどう解決しているかというと、メジャーな各FTPサーバーに依存した血反吐を吐きそうなパース処理を頑張って書いているのである(directorylistingparser.cppを見ると3000行弱あった)。

CDirectoryListingParser::ParseAsUnix()とCDirectoryListingParser::ParseAsDos()で大体のFTPサーバーをカバーできてるっぽい。
マネージコードだったら、このソースをまんま使いとこだけどC++だしGPLだし厄介だなあ。

更に厄介なことにFTPはディレクトリを丸ごと削除ができず、子階層のファイルを一件一件削除していって空のディレクトにしてからでないと"RMD"コマンドでディレクトリ削除ができない。従って"LIST"コマンドでファイル一覧取得→各ファイルを"DELE"コマンドで削除していく→空になったフォルダを"RMD"コマンドで消す、といった手順を踏まないといけない。これでは最初の"LIST"の時点でもう躓いてしまう。

今回はIISへの対応になりそうだからやっつけパーサーで誤魔化すしかないのか・・・。

2012年6月8日金曜日

WPFでスクロールバーを付ける

初歩的なことだけど使う機会がなく知らなかったので備忘録。

WPFではコントロールのサイズは動的に決定されるのが望ましい。例えば多言語対応を行った場合、日本語と英語とでは表記の長さが異なり、日本語用にサイズを固定化すると、英語化した際にはみ出たりする。あるいはファイル、DB、ネットワークに依存する値などは事前に固定化するのが難しい。

ということでSystem.Windows.WindowのSizeToContentプロパティをWidthAndHeightに設定することを自分はよくやる。Width/Heightは大体Auto。MinWidthやMaxWidthなども指定しない。こうするとウィンドウの内容は0x0まで小さくできる。

800x600を切るようなサイズまで小さくしたとき、全てのコントロールがウィンドウに収まるとは限らない。この場合、スクロールバーを実装していないと一部コントロールはウィンドウ外にはみ出てしまう。「最大化すりゃ最近の画面サイズなら収まるだろうからいいじゃん」て意見もあるかもしれないが小さいサイズにして画面端に待機させておきたいことはままある。

前置きが長くなったけどWPFには標準でScrollBarとScrollViewerというコントロールが用意されている。 ScrollViewerはScrollBarをラップ・拡張しており、上記のようなニーズにはScrollViewerを使うことになる。 使い方はスクロールバーを付けたいレイアウトコントロールを丸ごとScrollViewerの子要素にしてやる。

デフォルトでは縦方向のスクロールバーだけが表示される。 これはHorizontalScrollBarVisibilityプロパティの規定値がHiddenになっているからだ。この値はSystem.Windows.Controls.ScrollBarVisibilityを見れば分かるように4種類あるが、基本的にAutoでいいだろう。VerticalScrollBarVisibilityについても同様に設定する。

XAMLでいうとこんな感じ
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight">
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <!-- 分かりやすいようにMarginをでかくする -->
            <Label Content="設定値1" Margin="30" />
            <TextBox Width="300" Grid.Column="1" Margin="30" />
            <Label Content="設定値2" Grid.Row="1" Margin="30" />
            <TextBox Width="300" Grid.Row="1" Grid.Column="1" Margin="30" />
        </Grid>
    </ScrollViewer>
</Window>

Windows用インストーラ作成環境

無料で利用できる選択肢としては下記のものが有名。
  • WIX
  • Inno Setup
  • NSIS
  • Visual Studioセットアッププロジェクト(正式名称は何だろ?)
  • InstallShield Limited Edition
単一バイナリでの多言語対応を考えると
  • Inno Setup
  • NSIS
まで絞られる。メンテナンス頻度を見るとNSISは2009年から更新が無い。 両社は機能的に大差は無いと思われるが、Inno Setupを選択するのが無難かな。 いいトコどりすると製品版InstallShieldになるけど、あまりにも高い。

Innoも情報や参考になるコードが少なくて厳しいけど、それは他のも同じ。参考になるサイトを忘れないように貼っておく。
http://inno-setup.sidefeed.com/
http://bitassociates.jp/tools/innosetup/index.html 

2012年6月7日木曜日

LINQ to SQLでの接続テスト

LINQ to SQLで接続情報が間違っていたり SQLサーバーが死んでたりして接続できないとき どうやって判定すんのかな、ってのが分かんなかったのでメモ。 System.Data.Linq.DataContextは コンストラクタで接続文字列を指定できる。 その接続文字列でアクセスできたかどうかはDatabaseExists()で判定可能。 以下、WPF前提のコード例。
using (var db = new DataClasses1DataContext(builder.ConnectionString)) {
    if (!db.DatabaseExists()) {
        MessageBox.Show("Database open error.");
        this.Close();
    }
    else {
        var t_Customer = from a in db.T_Customer select a;
        this.ListView1.ItemsSource = t_Customer;
    }
}
LINQ to SQLが自動生成するクラスは、 Modelが実装済みなのでViewModelとしてそのままViewに突っ込める。 トランザクションは http://msdn.microsoft.com/ja-jp/library/bb387002.aspx にあるようにスコープで囲むだけでいいみたいだ。

2012年6月6日水曜日

SyntaxHighlighter導入

ソースコードを貼っつける際に 見やすく装飾してくれるらしいウィジェットのテスト
for (int i = 0; i < 10; ++i) {
    Console.WriteLine("i = {0}", i);
}
まーこんなもんかな? SyntaxHighlighterというらしい。