.net」タグアーカイブ

SeeMe V5 002

SeeMe for Windows v4 で一番気にしている部分。
エディット部の XAML が超テキトーであること…

Grid のレイアウトがよく解らなかったので StackPanelのみでレイアウト。
自分で見ても解り辛い、何故か下方から積み上げる最悪のコーディング。
今の私ならパネルを噛ませる技なんかを使うけど当事は手探りだったし。

IronPython でゼロから作り変えするんだ、そろそろなんとかしなければ。
ということで Grid を利用して Linux 版の GTK+ と同じになるようにする。
ちなみに Linux 版のエディット部は GtkTable を継承して

class IniEditor(gtk.Table):
    """
        カスタムタブのエディタ部
    """
    def __init__(self):
        gtk.Table.__init__(self, 6, 7)
        label = []
        for i in range(len(editor_labels)):
            l = gtk.Label(editor_labels[i])
            label.append(l)
        self.edit_name = gtk.Entry()
        self.attach(self.edit_name, 1, 2, 0, 1)
        self.edit_key = gtk.Entry()
        self.attach(self.edit_key, 3, 5, 0, 1, 0)
        self.edit_url = gtk.Entry()
        self.attach(self.edit_url, 1, 6, 1, 2)
        self.edit_query = gtk.Entry()
        self.attach(self.edit_query, 1, 6, 2, 3)
        self.edit_uniqueid = gtk.Entry()
        self.attach(self.edit_uniqueid, 1, 5, 3, 4)
        self.check_post = gtk.CheckButton(editor_checks[0])
        self.attach(self.check_post, 5, 6, 3, 4, gtk.FILL)
        self.edit_icon = gtk.Entry()
        self.attach(self.edit_icon, 1, 5, 4, 5)
        self.check_separator = gtk.CheckButton(editor_checks[1])
        self.attach(self.check_separator, 5, 6, 4, 5, gtk.FILL)
        self.edit_encode = gtk.Entry()
        self.attach(self.edit_encode, 1, 4, 5, 6)
        self.edit_type = gtk.Entry()
        self.attach(self.edit_type, 5, 6, 5, 6, 0)
        # Label
        self.attach(label[0], 0, 1, 0, 1, gtk.FILL)
        self.attach(label[1], 2, 3, 0, 1, 0, xpadding=10)
        self.attach(label[2], 0, 1, 1, 2, 0)
        self.attach(label[3], 0, 1, 2, 3, 0)
        self.attach(label[4], 0, 1, 3, 4, 0)
        self.attach(label[5], 0, 1, 4, 5, 0)
        self.attach(label[6], 0, 1, 5, 6, 0)
        self.attach(label[7], 4, 5, 5, 6, 0)
        self.etc_label = gtk.Label("<span color=\"darkgreen\">Verfbtext =  Position =  NameID =  UseTLD =  </span>")
        self.etc_label.set_use_markup(True)
        #self.etc_label.set_justify(gtk.JUSTIFY_LEFT)
        self.etc_label.set_alignment(0.1, 1.0)
        self.attach(self.etc_label, 0, 6, 6, 7)
        # Button
        self.button = gtk.Button("リストに反映")
        self.attach(self.button, 5, 6, 0, 1, 0)

こうはやりたくないなぁ…
やはりメニュー等と同様に XAML で綺麗に仕上げたい。

とりあえず基本的にコントロールサイズに Column を合わせるには Auto を指定。
サイズ変更した時に表示名エディット部は連動して広がるように。
マージンが必要な所は Margin プロパティを指定。

editor_str = """<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Label Grid.Row='0' Grid.Column='0'>表示名</Label>
    <TextBox Grid.Row='0' Grid.Column='1' Grid.ColumnSpan='1' Name="edit_name" />
    <Label Grid.Row='0' Grid.Column='2'>キー</Label>
    <TextBox Grid.Row='0' Grid.Column='3' Grid.ColumnSpan='2' Name="edit_key" />
    <Button Grid.Row='0' Grid.Column='6' Grid.ColumnSpan='1' Margin="20,0,20,0" Name="button">リストに反映</Button>

    <Label Grid.Row='1' Grid.Column='0'>URL</Label>
    <TextBox Grid.Row='1' Grid.Column='1' Grid.ColumnSpan='5' Name="edit_url" />

    <Label Grid.Row='2' Grid.Column='0'>クエリ</Label>
    <TextBox Grid.Row='2' Grid.Column='1' Grid.ColumnSpan='5' Name="edit_query" />

    <Label Grid.Row='3' Grid.Column='0'>UNIQUEID</Label>
    <TextBox Grid.Row='3' Grid.Column='1' Grid.ColumnSpan='4' Name="edit_uniqueid" />
    <CheckBox Grid.Row='3' Grid.Column='5' Grid.ColumnSpan='2' Name="check_post">POSTで送信</CheckBox>

    <Label Grid.Row='4' Grid.Column='0'>ICON</Label>
    <TextBox Grid.Row='4' Grid.Column='1' Grid.ColumnSpan='4' Name="edit_icon" />
    <CheckBox Grid.Row='4' Grid.Column='5' Grid.ColumnSpan='2' Name="check_separator">下にセパレータ</CheckBox>

    <Label Grid.Row='5' Grid.Column='0'>エンコード</Label>
    <TextBox Grid.Row='5' Grid.Column='1' Grid.ColumnSpan='3' Name="edit_encode" />
    <Label Grid.Row='5' Grid.Column='4'>サーチタイプ</Label>
    <TextBox Grid.Row='5' Grid.Column='5' Grid.ColumnSpan='2' Name="edit_type" />

    <Label Grid.Row='6' Grid.Column='0' Grid.ColumnSpan='6' Name="label_etc" Foreground="DarkGreen">Verbtext Position NameID UseTLD</Label>
</Grid>"""

なんとか同じようになった、しかし

GTK+ と違って WPF は縮めるとこうなってしまう…
MinWidth とか数値プロパティでではなくコントロールサイズを最小サイズにしたい。
知らないだけで方法があるのだろうか?

んで、コントロール名を元にアトリビュートを作成。
ということで下記のようなコードを書いてみたのだが。

self.editor = XamlReader.Parse(editor_str)
self.editor.edit_name = self.editor.FindName("edit_name")
self.editor.edit_name.Text = "abcde"
DockPanel.SetDock(self.editor, Dock.Bottom)

なんでだよ、Python なのにアトリビュートにできないじゃん。
しかたがないからダミーのクラスを作ってみる。

class Editor():
    pass

class SeeMe(Window):
    def __init__(self, sset):
        # ...
        self.editor = Editor()
        edit = XamlReader.Parse(editor_str)
        self.editor.edit_name = edit.FindName("edit_name")
        self.editor.edit_name.Text = "abcde"
        DockPanel.SetDock(edit, Dock.Bottom)

これなら上手くいく。
XAML から作成すると Python オブジェクトとして扱ってくれないようだ。
IronPython は Python クローンだと思って使うと色々落とし穴がありますね。

seeme5_002.zip

どうでもいいけど readme.txt と ChangeLog.txt を BOM 付き UTF-8 に。
Python コードは BOM 無し UTF-8 に、色々と事情があってコレに統一。
それと改行を CRLF にしとかないと notepad.exe で改行してくれない。
Windows って面倒くさいなぁ…

見た目はなんとかなったので後は編集コードの作成だ。
連休だけど月曜は仕事だ、明日には仕上がるだろうか…

追記 @ 2010.07.19
進んでいないけど盗難が怖いのでバックアップ、畜生、夏のやろう!

seeme5_003.zip

追記 @ 2010.07.20
エディタ部への設定書き出しを実装、思っていたより手間が掛かる。
そういえば Linux 版は競合キーチェックを入れ忘れしていた…
ついでに Has endseparator をマイナスにしていない、10.60 では無意味な部分だが。

seeme5_004.zip

追記 @ 2010.07.21
__init__.pyw というファイル追加、コレを ipyw(64).exe に関連付けかドロップ。
としておけば Python ワカンネな人でも理解しやすいかも?と思ったので…
ini 保存は色々あって UTF-8 に BOM を付けるようにした。
デフォルト uuid 指定タブもなんとか完成、もう変更できるようにしておいた。
Item の編集と削除は実装したけど新規追加や並べ替え処理はまだ実装していない。
Linux 版とアトリビュート名やメソッド名合わせを考えなければもっと早く作れるけど…
次の日の仕事に影響が出ない範囲で作っているのもあって我ながら遅い…

seeme5_005.zip

Microsoft.Win32.OpenFileDialog for .NET 4.0

今日 IronPython を少し試していて気が付いたのだが

# -*- coding: UTF-8 -*-

import clr

clr.AddReferenceByPartialName("PresentationFramework")

import Microsoft

def dlg_open():
    dlg = Microsoft.Win32.OpenFileDialog()
    dlg.ShowDialog()

dlg_open()

あれ?Windows 7 標準のダイアログになった。
この関数だと XP 時代の古いダイアログになってしまうはずなのに。
x64 の Windows 7 だからなのか IronPython が .NET 4.0 版だからなのか?

IronPython – Release: 2.6.1

試しに .NET 2.0 版の IronPython zip 版も落として実験。
同じコードを動かしてみる。

やはり 2.0 版だと Windows 7 でも古いまんまだ。
なるほど、.NET 4.0 は同じ関数でも地味に改良してくれているんだね。
WPF を使うのが少し楽になった、地味に調べてみると面白いかもしれない。

.NET 4.0 on IronPython

.NET Framework 4.0 の日本語版が出たようだ。

窓の杜 – 【NEWS】マイクロソフト、“.NET Framework”の最新版「.NET Framework 4」を公開

そういえば Windows 7 を立ち上げるのは一ヶ月ぶりくらいのような…
もう Windows に対しては .NET がどうなった?以外に興味が無いのかも…
せっかく買ったんだから使いたいんだけど Linux のほうが圧倒的に便利だし…

とにかく早速インストール。
二十分くらいで終わった、以外に早かった。

早速 4.0 を動かして…
ってアプリが無い。

そういえば IronPython 2.6.1 の .NET 4.0 版ってのがあった。
.NET 2.0 版を削除して入れ替えて使ってみよう。
普通にダウンロードすると 4.0 版が落ちてくるんだね。

IronPython.net /

4.0 版のデフォルトインストール位置は以下になる。

C:\Program Files (x86)\IronPython 2.6 for .NET 4.0

2.0 版から入れ替える人は環境変数の変更なんかを忘れずに。

それから、これは IronPython が悪いわけではないけど。
私は IronPython 関連の関連付けをこうしていた。

ぱぇぽぃ2 ? Blog Archive ? IronPython への関連付け

んでこんなのを作ってスタートアップ登録して利用していた。

ぱぇぽぃ2 ? Blog Archive ? NotifyIcon to use from IronPython

ファイルの右クリでプロパティから新しい ipyw64.exe に関連付け変更ができない!
2.0 時の情報がレジストリに残っていて存在しない exe 扱いになっちまったようだ。

HKEY_CLASSES_ROOT\pyw_auto_file
HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\MuiCache

なんかの関連するものを丸ごと削除したけど EXE 情報が空になる。

HKEY_CLASSES_ROOT\Applications\ipyw64.exe\shell\open\command

を書き換えて、まあコレで関連付けはなんとかなったが…

なんだこりゃ、これはレジストリのドコを弄くれば修正できるのだ?
とにかく何でもかんでもキャッシュするのは迷惑なだけだ、特にアイコンキャッシュが。
Linux のほうがイイや、こういう細かいところで Windows を使う気が失せる。

ってコレは Windows への不満だし、気を取り直して実行。

さて ipy64.exe の初期化速度は、全然変わっておらずスゲェ遅い。
予想していたけど DLR はもう少しなんとかならないものか。
初期化さえ終われば実行速度も不満が無いし 2.0 版と同様に使えるのだけど。

上記の自作トレイアイコンもそのまんま動いた。

ぱぇぽぃ2 ? Blog Archive ? WPF Simple TextEditor example

も問題なく動く、3.5 までのコードはほとんど弄くらないまま 4.0 で動きそう。
新機能は知らないので後で調べる。

クライアント領域のサイズ

GetWindowRect とか自分で書いて思い出したので書いておこう。
Windows の SDK を含む GUI ツールキットと Linux での GTK+ のサイズについて。
とりあえず全部 300×300 サイズなウインドウを作ってみる

SDK

hWnd = CreateWindow(
    szWindowClass,
    szTitle,
    WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    300, // Width
    300, // Height
    NULL,
    NULL,
    hInstance,
    NULL);

WindowsForm

WPF

<Window x:Class="_wpf.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        
    </Grid>
</Window>

PyGtk (Linux)

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import gtk

class Template(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self)
        self.connect("delete-event", gtk.main_quit)
        self.resize(300, 300)
        self.show_all()

if __name__ == "__main__":
    w = Template()
    gtk.main()

MFC や Qt は知らない、MFC は SDK と結果は同じになるはずだが。
とにかく結果、Windows の画像は VirtualBox ose 上である。

GTK+ はクライアント領域のサイズ、Windows は全部が全体サイズです。
いやいや、Windows は WPF になってもまだデフォルトは外枠を含んだサイズなんですね。
よく見るとメニューさえクライアント領域に食い込んで含まれてしまうのが解る。

Windows でクライアント領域のサイズを指定するには

SDK の場合
AdjustWindowRectEx 関数を使うか GetClientRect との差を自力計算する。

WindowsForm の場合

this.ClientSize = new Size(300, 300);

WPF の場合
SizeToContent を WidthAndHeight に指定し 300×300 のコンテンツを入れる。

何故クライアント領域のサイズがどうだというと。
メニューやツールバー、ステータスバーなんかも当然クライアント領域内に食い込む。
画像ビューアや動画プレイヤーを作る場合は当然実寸で表示したくなるよね。
そうするとメニューやステータスバーのサイズまで計算し加算しなくてはいけないハメに…
ちなみに私の作った Cinema はそうやっている、ステータスバーは面倒で付けなかった。

コンテンツのサイズでクライアント領域サイズを決めたほうがイイに決まっている。
本当に GTK+ や WPF のレイアウタって神ですよ。

SDK はしかたがないとして WindowsForm はどうなんだ?ですよね。
WPF は古い考え方をブチ壊したのだから最初からクライアントサイズにすればいいのに。

Windows 7 の csc.exe で遊んでみる

最近の Linux で GNOME ならばデフォルトで C# のコンパイルが可能。
Mono が入っている環境であれば必ず gmcs があるからである。

と以前書いたけど実は Windows 7 も可能だったりします。

C:\Windows\Microsoft.NET\Framework64\v2.0.50727

を Explorer で開いてみて、32bit の人は 64 を外してください。

csc.exe という C# コンパイラがあるのが解ります。
つまりコンパイルするファイルが一つであればこうやればいいわけです。
C# コードは BOM 付き UTF-8 で保存してくださいね。

フルパスを打ち込むのが面倒であればパスを通しておきましょう。
これで csc と打ち込むだけでパス指定しなくてもコンパイルが可能になる。

コマンドラインオプションのサンプルは MSDN にあります。
csc.exe を使用したコマンド ラインからのビルド

又、MSBuild を利用したコンパイルも普通に可能です。
幸い私は SeeMe をオープンソースにしているのでコイツで実験してみます。

SeeMe は現在 .NET Framework 3.5 でビルドしているので v3.5 の MSBuild.exe を使う。
コレに SeeMe4.sln というファイルを渡します。

なんかエラー?が出るけどしばらく待っていると SeeMe4.exe が出来上がってしまった。
SDK なんかインストールしないでもビルドできちゃうんですね、自分で驚いたよマジで。

MSDN に細かい解説が日本語であるけど手書きは少々辛いかも。
MSBuild

無償版 VC# が存在する今だけどこんな方法で何もインストールしないで遊べるよ。
開発環境をインストールだけやってプログラマー気取りの人を笑ってあげましょう。

実は .NET Framework 3.5 導入済みなら Windows 7 である必要は無いんですけど…
Vista より前てか XP では .NET が遅すぎて使わないだろうしやはり 7 を進めておくよ。
たった 1.2GB の CULV ノートでも快適に .NET が動きますので。