Phantasm

久しぶりに東方妖々夢をやってみました。
未クリアだったのですが、ようやくクリアできたので記念のリプレイ。
ラスト5つくらいのスペルがひどいことになってます。
自分はPSのコントローラでやってます。
2009年 11月 の記事

久しぶりに東方妖々夢をやってみました。
未クリアだったのですが、ようやくクリアできたので記念のリプレイ。
ラスト5つくらいのスペルがひどいことになってます。
自分はPSのコントローラでやってます。
ソース自体は前回と殆ど変わってないんですが、簡単な説明を。
XMLファイルとXML DOMの相互変換を行うクラス。
XML DOMのルートでもある。
XMLの要素を表すツリーノード。
このノードは1つの値と複数の子ノードを持つことができる。
イベント引数。
今のところ使用しない。
使用する名前空間はSiki.Configure。
1 2 3 4 5 6 7 | using System; using System.Drawing; using System.Windows.Forms; using Siki.Configure; namespace ConfigureSample { public partial class Form1 : Form { |
GlobalConfigureインスタンスにアクセスするためのプロパティ。
8 9 10 11 | private GlobalConfigure Configure { get; set; } |
コンストラクタ。
GlobalConfigureインスタンスの作成。
ここでは設定ファイルにconfigure.xmlを指定。
(別のコンストラクタを使えばディレクトリやXMLのルート要素なども指定できます。)
フォームのLoadとFormClosingイベントにハンドラを設定。
12 13 14 15 16 17 18 | public Form1() { InitializeComponent(); Configure = new GlobalConfigure("configure.xml"); Load += new EventHandler(Form1_Load); FormClosing += new FormClosingEventHandler(Form1_FormClosing); //StartPosition = FormStartPosition.Manual; } |
Loadイベントハンドラで位置とサイズの復元を行う。
FormClosingイベントハンドラで位置とサイズを記録し、設定ファイルに保存する。
19 20 21 22 23 24 25 26 27 28 | private void Form1_Load(object sender, EventArgs e) { RestoreLocation(); RestoreSize(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { SaveLocation(); SaveSize(); Configure.Save(); } |
位置の復元メソッド。
Configureを使用し、連想配列のようにアクセスできる。
返される値はすべてstringなので、他の型への変換は自分で行う必要がある。
指定された要素が存在し、32ビット整数に変換可能ならばtry内で例外は発生しないはず。
以下のコードで
Configure["window"]
Configure["window"]["location"]
Configure["window"]["location"]["x"]
は、いずれもConfigureNodeのインスタンスであり、stringへの変換は暗黙に行われる。
29 30 31 32 33 34 35 36 37 38 39 | public void RestoreLocation() { try { string strx = Configure["window"]["location"]["x"], stry = Configure["window"]["location"]["y"]; int x = Convert.ToInt32(strx, 10), y = Convert.ToInt32(stry, 10); Location = new Point(x, y); } catch { } } |
位置の記録メソッド。
要素に書き込むにはConfigureNode.Valueに代入する必要がある。
40 41 42 43 | public void SaveLocation() { Configure["window"]["location"]["x"].Value = Location.X.ToString(); Configure["window"]["location"]["y"].Value = Location.Y.ToString(); } |
サイズの復元と記録メソッド。
ほぼ同上。
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | public void RestoreSize() { try { string strw = Configure["window"]["size"]["width"], strh = Configure["window"]["size"]["height"]; int width = Convert.ToInt32(strw, 10), height = Convert.ToInt32(strh, 10); Size = new Size(width, height); } catch { } } public void SaveSize() { Configure["window"]["size"]["width"].Value = Size.Width.ToString(); Configure["window"]["size"]["height"].Value = Size.Height.ToString(); } } } |
設定ファイルのディレクトリを明示的に指定しない場合、「~~\ユーザー名\AppData\Roaming\組織名\アプリケーション名\バージョン\」をデフォルトのディレクトリとして扱います。(XP以前では若干違うかも)
今書いてるソースを上げてみる。
連想配列(のようなもの)<->XML を簡単に行うためのクラスです。詳細はいずれ。
作りかけなので、全く整理してないです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using System.Xml; namespace Siki.Configure { /// <summary> /// アプリケーションの設定を管理するクラス /// </summary> public class GlobalConfigure { #region フィールド /// <summary>ファイルのパス</summary> private string m_fullpath = ""; /// <summary>現在のアプリケーション設定を表すDOM</summary> private XmlDocument m_dom = null; #endregion フィールド #region イベント /// <summary>DOMが初期化されたときに発生するイベント</summary> public event EventHandler<ConfigureEventArgs> Initialized; /// <summary>ファイルから読み込まれたときに発生するイベント</summary> public event EventHandler<ConfigureEventArgs> Loaded; /// <summary>ファイルに保存されたときに発生するイベント</summary> public event EventHandler<ConfigureEventArgs> Saved; #endregion イベント #region プロパティ /// <summary> /// 設定ファイルのフルパスを取得する. /// </summary> public string FullPath { get { return m_fullpath; } protected set { m_fullpath = value; } } /// <summary> /// XmlDocumentを取得する /// </summary> protected XmlDocument Dom { get { return m_dom; } } public ConfigureNode this[string name] { get { foreach (XmlNode node in Dom.DocumentElement.ChildNodes) { if (node.Name == name && node is XmlElement) { // 見つかった場合 return new ConfigureNode(node as XmlElement); } } // 見つからなかった場合 // 要素を作成 XmlElement element = Dom.CreateElement(name); // 要素を追加 Dom.DocumentElement.AppendChild(element); // return new ConfigureNode(element); } } #endregion プロパティ #region コンストラクタ /// <summary> /// デフォルトコンストラクタ. /// 設定ファイルをデフォルトのパスに指定する. /// </summary> public GlobalConfigure() : this("conf.xml") { } #endregion コンストラクタ /// <summary> /// コンストラクタ. /// 設定ファイルをデフォルトのフォルダの @a filename に指定する. /// </summary> /// <param name="filename">設定ファイル名</param> public GlobalConfigure(string filename) : this(Application.UserAppDataPath, filename) { } /// <summary> /// コンストラクタ. /// 設定ファイルを @a dir フォルダの @a filename に指定する. /// </summary> /// <param name="dir">設定ファイルのフォルダ</param> /// <param name="filename">設定ファイル名</param> public GlobalConfigure(string dir, string filename) { FullPath = (dir.EndsWith("\\") ? dir : dir + "\\") + filename; m_dom = new XmlDocument(); Load(); } /// <summary> /// 設定ファイルを読み込む. /// ファイルが存在しない場合は新規に作成する. /// </summary> /// <returns>XMLの読み込みor作成に成功したか.</returns> public virtual bool Load() { try { if (File.Exists(FullPath)) { // 設定ファイルが存在するとき // ファイルを読み込む Dom.Load(FullPath); } else { // 設定ファイルが存在しないとき Dom.AppendChild(Dom.CreateXmlDeclaration("1.0", "UTF-8", "yes")); Dom.AppendChild(Dom.CreateElement("alert")); Save(); } } catch (XmlException) { // XMLに関する例外 throw; } catch (Exception) { // その他の例外 return false; } return true; } /// <summary> /// Initializedイベントを発行する. /// </summary> /// <param name="e"></param> public virtual void OnInitialized(ConfigureEventArgs e) { if (Initialized != null) { Initialized(this, e); } } /// <summary> /// Loadedイベントを発行する. /// </summary> /// <param name="e"></param> public virtual void OnLoaded(ConfigureEventArgs e) { if (Loaded != null) { Loaded(this, e); } } /// <summary> /// 現在のDOMの状態を設定ファイルに書き込む. /// </summary> /// <returns></returns> public virtual bool Save() { try { Dom.Save(FullPath); OnSaved(new ConfigureEventArgs(FullPath)); } catch (XmlException) { // XMLに関する例外 throw; } catch { // その他の例外 return false; } return true; } /// <summary> /// Savedイベントを発行する. /// </summary> /// <param name="e"></param> public virtual void OnSaved(ConfigureEventArgs e) { if(Saved != null){ Saved(this, e); } } /// <summary> /// @a groupname で指定された名前のグループを取得する. /// </summary> /// <param name="groupname"></param> /// <returns></returns> public ConfigureNode GetGroup(string groupname){ foreach (XmlNode node in Dom.DocumentElement.ChildNodes) { if (node.Name == groupname && node is XmlElement) { return new ConfigureNode(node as XmlElement); } } XmlElement element = Dom.CreateElement(groupname); Dom.DocumentElement.AppendChild(element); return new ConfigureNode(element); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; namespace Siki.Configure { /// <summary> /// 設定ノード. /// </summary> public class ConfigureNode { /// <summary> /// 対応するXmlElementを取得する. /// </summary> public XmlElement Element { get; private set; } /// <summary> /// 最初のXmlTextを取得する. /// </summary> private XmlText Text { get { foreach (XmlNode node in Element.ChildNodes) { if (node is XmlText) { return node as XmlText; } } return null; } } /// <summary> /// 子ノードを名前で取得するインデクサ. /// </summary> /// <param name="name"></param> /// <returns></returns> public ConfigureNode this[string name] { get { foreach (XmlNode node in Element.ChildNodes) { if(node.Name == name && node is XmlElement){ // 見つかった場合 return new ConfigureNode(node as XmlElement); } } // 見つからなかった場合 XmlDocument xmldoc = Element.OwnerDocument; // 要素を作成 XmlElement element = xmldoc.CreateElement(name); // 要素を追加 Element.AppendChild(element); // return new ConfigureNode(element); } } /// <summary> /// このノードの名前を取得する. /// </summary> public string Name { get { return Element.Name; } } /// <summary> /// このノードの値を取得、設定する /// </summary> public string Value { get { XmlText text = Text; return text != null ? text.Value : ""; } set { XmlDocument doc = Element.OwnerDocument; XmlText text = Text; if (text != null) { text.Value = value; } else { text = doc.CreateTextNode(value); Element.AppendChild(text); } } } /// <summary> /// コンストラクタ. /// </summary> /// <param name="element">対応するXmlElement</param> public ConfigureNode(XmlElement element) { Element = element; } /// <summary> /// ノードの値を取得する. /// </summary> /// <param name="node"></param> /// <returns></returns> public static implicit operator string(ConfigureNode node) { return node.Element.Value; } /// <summary> /// このノードが値を持っているか調べる. /// </summary> /// <returns>値を持っていれば真.</returns> public bool HasValue() { return Text != null; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Siki.Configure { /// <summary> /// /// </summary> public class ConfigureEventArgs : EventArgs{ private string m_path; public string Path { get { return m_path; } } public ConfigureEventArgs(string path){ m_path = path; } } } |
ファイル・フォルダのリンクとしてWindowsでは一般的な形式。
手軽な反面、問題も多い(特にプログラマにとっては)。
ファイルに別名を付けたもの。あまり使われていない印象。
制限つきのシンボリックリンクのようなもの。
Windows 2000以降(NTFS)に対応。
Windows Vista以降に対応。
ファイルに対しては
フォルダに対しては