.net」タグアーカイブ

Double.NaN

びっくりした事

あれ?C# って Double ならモロに 0 で除算してもコンパイルエラーにならないんだ。
clr なら同じかなと思って IronPython で為してみたけど実行エラーが出るだけだった。
てか文法が合っているなら普通の Python でもこの強引なコードで読み取りは通るんだね。

def check():
    print 0/0
input("wait: ")
check()

C# も為してみようと思ったけど仮想 Vista を立ち上げるのが面倒なので mono でやってみる。
Mandriva One GNOME は gcc がデフォでは入っていないくせに gmcs はしっかりあるんだよね。
ま、最近の GNOME なら全部入っているだろうけど。

ということで

Console.WriteLine(0/0);

だと mono でもしっかりコンパイルエラーになります、忠実に再現しているのね。

Double.NaN フィールド (System)

コレも当然動く。
こういうのって便利なのだろうか?普通に例外を吐くだけのほうが楽だと思うのだが。

P/Invoke CharSet.Unicode

間違いに気づいたまま放置はアレなので書き換えた。
しかし SHGetFileInfo C# なんかでググると笑った、皆 SHFILEINFO の第二引数が IntPtr だ。
32bit でしか動作確認していないんだねぇ、私もそうだったけど。

ついでに P/Invoke で SHGetFileInfoW の UNICODE 関数化したんだけど…

C# で SHGetFileInfo を使ってアイコンと種類を取ってくる例

SHGetFileInfoW てか UNICODE を P/Invoke で指定するにはこんなに面倒なのか!
CharSet = CharSet.Unicode を指定しなければ Ansi 関数呼び出しになってしまうのかい。
更に Ansi 文字列に変換を全自動で行うなんて今の時代としては逆だと思うんだが。

ぱぇぽぃ2 ? Blog Archive ? UNICODE にならん

を以前自分でやっていなかったら気がつかなかったかもだよ。
前回書いたように IronPython なら関数名直で str をそのまま渡せばいいだけなのに。

てか .NET Framework 2.0 からは XP 以降でしか動かないのにこの仕様…
Microsoft がやっていることは本当によく解らない。

.NET アプリでバージョン情報の統一

SeeMe for Windows のバージョン情報が滅茶苦茶なのでなんとかせねば。

まず Explorer から本体のプロパティ。

explorer_prop

これは Visual Studio でプロジェクトのプロパティから「アセンブリ情報(I)…」ボタンを押して

assy_prop

で変更するんだがよく忘れるんだコレが。
最近は公開直後に即バージョンをインクリメントという対策をしているんだけど…
Visual Studio というより Windows が久々なので忘れていたわい。

ぱぇぽぃ2 ? Blog Archive ? SeeMe for Windows v4.0.1

のとおりダイアログのバージョンを書き換えるのを忘れていたし。
というか毎回ダイアログ文字列を変更ではおかしいので本体からバージョンを取得したい。

デルヒャァで作っていた頃はやっていたんですけどね。

procedure TAboutDlg1.FormShow(Sender: TObject);
var
  BuffSize, Ignore: Cardinal;
  P: Pointer;
  FileDescription: PChar;
begin
  BuffSize := GetFileVersionInfoSize(PChar(Application.ExeName), Ignore);
  P := AllocMem(BuffSize);
  GetFileVersionInfo(PChar(Application.ExeName), Ignore, BuffSize, P);

  VerQueryValue(P, PChar('\StringFileInfo\041103A4\FileVersion'),
                Pointer(FileDescription), Ignore);
  Label1.Caption := 'Y901 v' + FileDescription;

  FreeMem(P);
end;

こんな感じで、我ながら Object Pascal が懐かしい…
これを .NET Framework で同じようにするには

自分自身のバージョン情報を取得する: .NET Tips: C#, VB.NET, Visual Studio

やはり Windows で C# なら日本語でアッサリ見つかるなぁ…
日本語で GTK+ だと UNIX 臭さ全開かサル以前かの両極端しか無いのだが。

var version = System.Diagnostics.FileVersionInfo.GetVersionInfo(
    System.Reflection.Assembly.GetExecutingAssembly().Location);
v[0].Inlines.Add(new Bold(new Run("SeeMe for Windows " + version.FileVersion + "\n")));

と前回のコードを書き換えればオケのようで。
これであらかじめ本体のバージョン情報を更新しておけば追従してくれる。

cpanel_prop

インストーラのバージョンと本体のバージョンが合わない。
そう思って Version プロパティを弄くったら複数インストール可能になって困ったし。
それとアップデート毎に前バージョンの削除をさせるのも考え物だ。
実は前バージョンを削除してインストールする方法が解らなかっただけなんだが。

セットアッププロジェクトにて前のバージョンを削除してから新バージョンをインストールする(VisualStudio, Setup, msi) – いろいろ備忘録日記

うっ!それだけだったのかというか Version プロパティってそういうことか。
リンク先が無くなってしまったら困るので簡易で覚え書き。

セットアッププロジェクトのプロパティ
DetectNewerInstalledVersion = true
RemovePreviousVersion = true
Version をインクリメントすると ProductCode 変更ダイアログが出るので「はい」

を試してみたらアッサリと、プロジェクトのプロパティだけでイケたのね。
これでインストーラのバージョンと実行ファイルのバージョンを合わせることができた。

それと ToolBarTray を IsLocked=”True” にして動くように見えていたのをなんとかして。
ToolBar OverflowMode=”Never” にしてもオーバーフローボタンは消せないのね…
正直 WPF を使うには Visual Studio でないと厳しいと感じてきた。
そうそう、インストーラの名前に beta の意味な b が入っているのを消さなきゃ。

ということで修正のみだけど SeeMe for Windows v4.0.2 公開。

おまけ

2009-08-19 – 当面C#と.NETな記録 Visual Studio で一行だけコピーや削除するときには行を選択しなくてもよかった件について

マジだぁ!
トリプルクリックで一行選択してくれないけど、秀丸も EmEditor も Gedit さえもできるのに。
Visual Studio はトリプルクリックする必要すら無かった。

てゆーか空白やインデントがおかしいコードも貼り付けで勝手に整形してくれるぞ!

url.Click +=new RoutedEventHandler(url_Click);
// をコピーして貼り付けると同じソースコード中でも下のように
url.Click += new RoutedEventHandler(url_Click);

へたに手書きするよりコピペのほうが綺麗なコードになるとはね。

MediaElement is WMP

どうやら WPF の MediaElement について勘違いしていたようだ。

[WPF]MediaElementの罠

Vista で MediaElement が WMV しか再生できなかった理由はコレだったか。
だって WMP なんて使ったことが無い、ffdshow の有効に追加したのは私は当然 Cinema のみ。
Windows 7 用 WMP なら H.264 に標準対応だから最初から H.264 が再生できたというわけだ。

つまりは MediaElement で WPF アプリや Silverlight サイトを作ってとなると…
Vista で他形式を再生させるために WMP 用レジストリを弄くって codec 入れてもらって…
自分のマシンでしか使わないならそれでいいけど…これじゃ配れない。

WPF になっても WMP ActiveX コントロールに縛られるのと同じ結果なんだね。
Webbrouser も当然 IE コンポと同じなんだしそういうものか。

正直 Windows 用アプリはもう作る気が…

と思っていたたけど SeeMe のダウンロード数が Windows 版と Linux 版で百倍以上差がある…
Y901x なんて百に届かない、Windows 用プレイヤーを作っていた頃から考えるとありえない。
それさえも半数以上が Windows ユーザーが興味で落としたのだろう、これが現実だよ
解っていたけど Linux 用 GUI アプリをやってみたかっただけだ。

当分は Windows のオンラインソフト作者と二足のわらじを続けるしかなさそう。
Windows 自体をあまり使わなくなったけど何か新しいアプリでも考えとかなきゃ。
実は MediaElement で Y901w を作ってみようかと思っていたとかいないとか。
少なくともレイアウタが無い GUI 部品はもう使う気が起こらないんですけど。

SeeMe for Windows v4.0.1

あわわ、v4.0.0 はプロファイル編集ができないじゃんコレ。
ここは弄くっていないので前からか、まぁ普通はデフォルト位置で十分だし。

とはいえ放置もアレなので修正しようかどうか、そういえば

ぱぇぽぃ2 ? Blog Archive ? GetFullPath

のようにファイルドロップでフルパス指定にしようとして忘れていた!
なんたってそうすれば System.Windows.Form への参照を排除できる。
WPF なのに OpenFileDialog のためだけに WindowsForm を参照していたし。
よく見たら System.Xml.Linq まで…こんなの SeeMe で使っていないよ。

ということで AboutDlg のように上記 IronPython コードを C# 化…
しようと思ったけど面倒なのでハンドラの追記だけで済ませた。

ちなみに

ぱぇぽぃ2 ? Blog Archive ? WPF Hyperlink class for IronPython

の C# 化はこうやった。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Text;
using System.Windows.Media;
using System.Collections.Generic;

namespace SeeMe4
{
    class About : Window
    {
        public About(Window owner)
        {
            this.Owner = owner;
            this.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            this.Title = "About SeeMe for Windows";
            this.SizeToContent = SizeToContent.WidthAndHeight;
            this.ResizeMode = ResizeMode.NoResize;
            this.Icon = owner.Icon;
            // StackPanel
            var panel = new StackPanel();
            // Dialog Icon and Image
            var img = new Image();
            img.Source = owner.Icon;
            img.Width = 32;
            img.Height = 32;
            panel.Children.Add(img);
            // Create TextBlock List
            var v = new List<TextBlock>();
            for (int i = 0; i < 5; i++)
            {
                var b = new TextBlock();
                panel.Children.Add(b);
                v.Add(b);
            }
            v[0].Inlines.Add( new Bold(new Run("SeeMe for Windows 4.0.0\n")));
            v[1].Text = "Windows Version ( " + Environment.OSVersion.Version + " )";
            v[2].Text = "CLR Version ( " + Environment.Version.ToString() + " )\n";
            v[3].Text = "Copyright(c)2003-2009 by sasakima-nao";
            var url = new Hyperlink(new Run("http://palepoli.skr.jp/"));
            url.Click +=new RoutedEventHandler(url_Click);
            v[4].Inlines.Add(url);
            // Align Right button
            var btn = new Button();
            btn.Content = "Close";
            btn.Click += new RoutedEventHandler(btn_Click);
            DockPanel.SetDock(btn, Dock.Right);
            var dp = new DockPanel();
            dp.LastChildFill = false;
            dp.Children.Add(btn);
            panel.Children.Add(dp);
            // Append
            this.Content = panel;
        }

        void btn_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        void url_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://palepoli.skr.jp/");
        }
    }
}

スクリーンショットを撮って気がついたが About のバージョンが 4.0.0 のままだ…
まあいいや、次の更新で直しておこう。

about_win

型指定がメンドクサイので var を使ったが何もかも IronPython より面倒。
中括弧とセミコロンと new と var が増えリストを System.Collections.Generic です。
特にハンドラ指定の RoutedEventHandler みたいなのってマジ書かなくてもよくないか?
こんなの Visual Studio エディタの助けが無かったら私は書けなかったかもだよ。

やっぱりこれからは IronPython だよ、EmEditor だけでデバッグもできるし。