ページ 1 / 1
オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月17日(木) 22:59
by もみじ
オリジナルのメモ帳を作りたい
VC++.netでオリジナルのメモ帳を作りたいです。
といいますのも仕事柄メモすることが増えて管理に困っております。
メモ.txtの中身
--------------------
//○○○の手順
~略~
//×××の手順
~略~
//□□□の手順
~略~
--------------------
みたいな感じで一つのテキストに色々な項目をまとめております。
但しこれでは見にくいのでこの機会に自分専用のツールを作りたいです。
デザイナを使って何とかデザインは出来ました。
ファイルなどへの書き込み方も調べてみてわかったのですが
データの管理の仕方がよくわかりません。
また、テキストの中身の範囲をわかりやすく出来るように疑似XMLにしたいです。
※XML形式にしないでも上記みたいな感じで管理できるならそちらの方がいいです。
XML.txtの中身
--------------------
<title>111</title>
<body>あああ</body>
<title>222</title>
<body>いいい</body>
<title>333</title>
<body>あああ
いいい
ううう
</body>
--------------------
添付しました画像は現在の開発画面イメージです。
皆様のアドバイスを頂けないでしょうか。
お手数お掛け致しますが何卒お願いします。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月17日(木) 23:01
by もみじ
現在のソースになります。
長くて申し訳ないです。
コード:
#pragma once
namespace MultiEditor {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Form1 の概要
///
/// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた
/// マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを
/// 変更する必要があります。この変更を行わないと、
/// デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、
/// 正しく相互に利用できなくなります。
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: ここにコンストラクタ コードを追加します
//
// 読み込み
/*
System::IO::StreamReader^ sr =
gcnew System::IO::StreamReader("XML.txt",System::Text::Encoding::GetEncoding(932));
sr->ReadLine();
String^ Item;
while((Item = sr->ReadLine()) != nullptr){
}
sr->Close();
*/
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::ListBox^ listBoxTitle;
private: System::Windows::Forms::RichTextBox^ richTextBoxBody;
private: System::Windows::Forms::MenuStrip^ menuStrip1;
private: System::Windows::Forms::ToolStripMenuItem^ ファイルFToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ menuSave;
private: System::Windows::Forms::SaveFileDialog^ saveFileDialog1;
private: System::Windows::Forms::TextBox^ textBoxTitle;
private: System::Windows::Forms::Button^ buttonNew;
protected:
protected:
private:
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->listBoxTitle = (gcnew System::Windows::Forms::ListBox());
this->richTextBoxBody = (gcnew System::Windows::Forms::RichTextBox());
this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
this->ファイルFToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->menuSave = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->saveFileDialog1 = (gcnew System::Windows::Forms::SaveFileDialog());
this->textBoxTitle = (gcnew System::Windows::Forms::TextBox());
this->buttonNew = (gcnew System::Windows::Forms::Button());
this->menuStrip1->SuspendLayout();
this->SuspendLayout();
//
// listBoxTitle
//
this->listBoxTitle->FormattingEnabled = true;
this->listBoxTitle->HorizontalScrollbar = true;
this->listBoxTitle->ItemHeight = 12;
this->listBoxTitle->Location = System::Drawing::Point(12, 36);
this->listBoxTitle->Name = L"listBoxTitle";
this->listBoxTitle->Size = System::Drawing::Size(241, 376);
this->listBoxTitle->TabIndex = 0;
this->listBoxTitle->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::listBoxTitle_SelectedIndexChanged);
//
// richTextBoxBody
//
this->richTextBoxBody->Location = System::Drawing::Point(259, 59);
this->richTextBoxBody->Name = L"richTextBoxBody";
this->richTextBoxBody->Size = System::Drawing::Size(361, 377);
this->richTextBoxBody->TabIndex = 1;
this->richTextBoxBody->Text = L"";
//
// menuStrip1
//
this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) {this->ファイルFToolStripMenuItem});
this->menuStrip1->Location = System::Drawing::Point(0, 0);
this->menuStrip1->Name = L"menuStrip1";
this->menuStrip1->Size = System::Drawing::Size(632, 24);
this->menuStrip1->TabIndex = 2;
this->menuStrip1->Text = L"menuStrip1";
//
// ファイルFToolStripMenuItem
//
this->ファイルFToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) {this->menuSave});
this->ファイルFToolStripMenuItem->Name = L"ファイルFToolStripMenuItem";
this->ファイルFToolStripMenuItem->Size = System::Drawing::Size(66, 20);
this->ファイルFToolStripMenuItem->Text = L"ファイル(&F)";
//
// menuSave
//
this->menuSave->Name = L"menuSave";
this->menuSave->Size = System::Drawing::Size(109, 22);
this->menuSave->Text = L"保存(&S)";
this->menuSave->Click += gcnew System::EventHandler(this, &Form1::menuSave_Click);
//
// textBoxTitle
//
this->textBoxTitle->Location = System::Drawing::Point(259, 36);
this->textBoxTitle->Name = L"textBoxTitle";
this->textBoxTitle->Size = System::Drawing::Size(361, 19);
this->textBoxTitle->TabIndex = 3;
this->textBoxTitle->TextChanged += gcnew System::EventHandler(this, &Form1::textBoxTitle_TextChanged);
//
// buttonNew
//
this->buttonNew->Location = System::Drawing::Point(12, 418);
this->buttonNew->Name = L"buttonNew";
this->buttonNew->Size = System::Drawing::Size(241, 23);
this->buttonNew->TabIndex = 4;
this->buttonNew->Text = L"新規追加";
this->buttonNew->UseVisualStyleBackColor = true;
this->buttonNew->Click += gcnew System::EventHandler(this, &Form1::buttonNew_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(632, 446);
this->Controls->Add(this->buttonNew);
this->Controls->Add(this->textBoxTitle);
this->Controls->Add(this->richTextBoxBody);
this->Controls->Add(this->listBoxTitle);
this->Controls->Add(this->menuStrip1);
this->KeyPreview = true;
this->MainMenuStrip = this->menuStrip1;
this->Name = L"Form1";
this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"MultiEditor";
this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::Form1_KeyDown);
this->menuStrip1->ResumeLayout(false);
this->menuStrip1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
// 保存を押したら
private: System::Void menuSave_Click(System::Object^ sender, System::EventArgs^ e) {
//System::IO::StreamWriter^ sw = gcnew System::IO::StreamWriter("XML.txt",false,System::Text::Encoding::GetEncoding(932));
//sw->Write( "あああ" );
//sw->Close();
if(saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK){
System::IO::StreamWriter^ sw = gcnew System::IO::StreamWriter(saveFileDialog1->FileName,false,System::Text::Encoding::GetEncoding(932));
sw->Write( "あああ" );
sw->Close();
}
}
// リストボックス選択番号が変わったら
private: System::Void listBoxTitle_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
this->richTextBoxBody->Text = "aaaaa";
this->textBoxTitle->Text = this->listBoxTitle->Text;
}
private: System::Void Form1_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
switch(e->KeyCode){
// アプリケーションの終了
case System::Windows::Forms::Keys::Escape:
Application::Exit();
break;
// リストボックスの削除
case System::Windows::Forms::Keys::Delete:
if( this->listBoxTitle->SelectedIndex != -1 )
this->listBoxTitle->Items->RemoveAt( this->listBoxTitle->SelectedIndex );
break;
}
// 新規追加
if (e->Control == true){
switch (e->KeyCode){
case System::Windows::Forms::Keys::N:
int i = this->listBoxTitle->SelectedIndex;
if( i != -1 ) this->listBoxTitle->Items[i] = i.ToString();
break;
}
}
}
private: System::Void textBoxTitle_TextChanged(System::Object^ sender, System::EventArgs^ e) {
int i = this->listBoxTitle->SelectedIndex;
if( i != -1 ) this->listBoxTitle->Items[i] = this->textBoxTitle->Text;
}
private: System::Void buttonNew_Click(System::Object^ sender, System::EventArgs^ e) {
this->listBoxTitle->Items->Add("aaa");
}
};
}
// 0309 0630~0715
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月18日(金) 18:44
by もみじ
すみません・・・やはりよくわかりません。
色々と試してはみたのですが右下の本文の管理に仕方がわかりません・・・。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月18日(金) 19:35
by softya(ソフト屋)
すいません、こちらのサイトはC++は得意でもC++/CLIや.Net系に詳しい人が少ないので返答をしばらくお待ち頂けますか。
私も詳しくないので良い回答を思いつきません。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月18日(金) 20:01
by lriki
ちゃんとした XML を使うのでしたら
using namespace System::Xml
が使えると思います。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月18日(金) 21:08
by もみじ
>>softya(ソフト屋) 様
ご回答ありがとうございます!!
ゲーム関連の掲示板なのに質問してしまい申し訳ございませんでした。
急かすような言い方ですみません。
急いではおりませんのでお分かりになる方がおりましたらで構いません。
>>梨樹様
ご回答ありがとうございます。
そのようなメソッドも用意されているのですね。
ただ今回は出来ればXMLを使いたくないのですが使わないと出来ない?気がしたので書かせて頂きました。
勉強になりました。ありがとうございます。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月18日(金) 21:17
by softya(ソフト屋)
ここは別にゲーム専門では無いのですが、やはりピュア(ネイティブ)C++のユーザーが多いことは確かです。
.NET(フォーム)系ではなくMFCやWin32APIなら答えられたのですが。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月18日(金) 22:45
by lriki
こんなの書いてみました。
一応テキストボックスからの入力ということで System::String 使ってます。
コード:
String^ xml_text = gcnew String(
L"<title>11</title>\n"
L"<body>あああ</body>\n"
L"<title>222</title>\n"
L"<body>いいい</body>\n"
L"<title>333</title>\n"
L"<body>あああ\n"
L"いいい\n"
L"ううう\n"
L"</body>" );
int mode = 0;
int head = 0;
// ループ回数 ( 文字列比較時の範囲外参照を防ぐために最後となるタグの文字数分を減算 )
int loop_num = xml_text->Length - ( wcslen( L"</body>") - 1 );
// 結果を格納するリスト
Generic::List< String^ >^ result = gcnew Generic::List< String^ >();
for ( int i = 0; i < loop_num; )
{
switch ( mode )
{
// <title> を探している状態
case 0:
// <title> が見つかった場合
if ( String::Compare( xml_text, i, L"<title>", 0, wcslen( L"<title>") ) == 0 )
{
// <title> の後ろまで位置を進める
i += wcslen( L"<title>");
// タイトル文字列の先頭位置を記憶
head = i;
// </title> を探す状態にする
mode = 1;
continue;
}
break;
// </title> を探している状態
case 1:
if ( String::Compare( xml_text, i, L"</title>", 0, wcslen( L"</title>") ) == 0 )
{
// head の位置から長さ len の文字列を tmp にコピーして取り出す
String^ tmp = xml_text->Substring( head, i - head );
// 取り出した文字列を結果リストに追加する
result->Add( tmp );
// </title> の後ろまで位置を進めて <body> を探しに行く
i += wcslen( L"</title>");
mode = 2;
continue;
}
break;
// <body> を探している状態
case 2:
// <title> が見つかった場合
if ( String::Compare( xml_text, i, L"<body>", 0, wcslen( L"<body>") ) == 0 )
{
i += wcslen( L"<body>");
head = i;
mode = 3;
continue;
}
break;
// </body> を探している状態
case 3:
if ( String::Compare( xml_text, i, L"</body>", 0, wcslen( L"</body>") ) == 0 )
{
String^ tmp = xml_text->Substring( head, i - head );
result->Add( tmp );
i += wcslen( L"</body>");
mode = 0;
continue;
}
break;
}
++i;
}
// 結果リストの内容を表示 ( 偶数番目にタイトル、奇数番目に本文 )
for ( int i = 0; i < result->Count; ++i )
{
if ( i % 2 == 0 )
{
Console::WriteLine("▼タイトル\n{0}", result[i] );
}
else
{
Console::WriteLine("▼本文\n{0}\n", result[i] );
}
}
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月19日(土) 17:34
by YuO
もみじ さんが書きました:ただ今回は出来ればXMLを使いたくないのですが使わないと出来ない?気がしたので書かせて頂きました。
「XMLを使いたくない」理由は何でしょうか。
ざっと見た感じ,単純なKey-Valueですから,それが簡単に取り扱える方法であればストレージはなんでも良いのですが,
ストレージをXMLにしてしまって,あとはDataSetを使ってバインディング,というのがよくある方法だと思います。
大規模になればデータベースを使うのでしょうが,この方法ならあまり変化させる必要もなくなります。
# XML自体のスキーマを決定してXmlSerializerで入出力,という方法もありますが。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月19日(土) 19:26
by YuO
せっかくなので,コード (C# and C++/CLI on VS 2010 SP1) を書いてみました。
C#の方は名前付きデータセットに対するIDEサポートがあるので名前付きデータセットですが,C++/CLIにはないので生のデータセットをWindowsFormのデザイナで処理しています。
構成としては,WindowsFormデザイナで全部バインドしてしまい,あとは
- 「新規作成」ボタンで行を追加
- 読み込み時に分離ストレージにファイルがあれば読み込む
- OnFormClosingで分離ストレージにファイルを出力
です。デモなので分離ストレージに出力していますが,普通のディレクトリでも良いと思います。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月19日(土) 21:39
by もみじ
お二方ともご回答及びサンプルありがとうございます。
他人のソースを見れる機会なんて滅多にないので助かります。
>> 梨樹様
XMLについてありがとうございます。
助かります。
>>YuO様
サンプルソースをありがとうございます。
PGではないので詳細な単語についてはわからないです。
申し訳ないです><
XMLを使いたくない理由として1つは私が理解していないので今後、改修が発生した時に困るかもしれないので。
ただお話しを聞くとXMLで管理するのが主流なようですね・・・。
XMLの方が別のアプリケーションとの連携等もなくそうなので今やっているのが終ったらそちらに改修したいです。
C++だけでなく#までありがとうございます。
短時間でくみ上げられるなんて天才ですかΣ
私には到底できないです。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月19日(土) 21:42
by もみじ
自分なりに書いたものです。
箱を有限に用意して無理やりやっております。
なんとか動いて希望通りには保存できるようになったっぽいのですが不具合があります。
デリートキーを押してしまうと予期せぬエラーが起こります。
trycatchで書こうとも思ったのですがそうすると項目の削除自体が行えないです。
宜しければ今一度ソースをみては頂けないでしょうか。
マズイ点等を指摘して頂けますと助かります。
コード:
#pragma once
#define MAX 256
namespace MultiEditor {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Form1 の概要
///
/// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた
/// マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを
/// 変更する必要があります。この変更を行わないと、
/// デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、
/// 正しく相互に利用できなくなります。
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: ここにコンストラクタ コードを追加します
//
title = gcnew array<String^>(MAX);
body = gcnew array<String^>(MAX);
int index = -1;
// 読み込み
System::IO::StreamReader^ sr =
gcnew System::IO::StreamReader("XML.txt",System::Text::Encoding::GetEncoding(932));
sr->ReadLine();
String^ Item;
while((Item = sr->ReadLine()) != nullptr){
String^ str = Item;
if(str->IndexOf("//") >= 0) index++;//->Substring(0,2)
// 値を挿入する
if( index != -1 ){
if( str->IndexOf("//") >= 0 ) this->listBoxTitle->Items->Add(Item->Replace("//",""));
else body[index] += Item + "\n";
}
}
sr->Close();
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::ListBox^ listBoxTitle;
private: System::Windows::Forms::RichTextBox^ richTextBoxBody;
private: System::Windows::Forms::MenuStrip^ menuStrip1;
private: System::Windows::Forms::ToolStripMenuItem^ ファイルFToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ menuSave;
private: System::Windows::Forms::SaveFileDialog^ saveFileDialog1;
private: System::Windows::Forms::TextBox^ textBoxTitle;
private: System::Windows::Forms::Button^ buttonNew;
private: array<String^>^ title;
private: array<String^>^ body;
protected:
protected:
private:
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->listBoxTitle = (gcnew System::Windows::Forms::ListBox());
this->richTextBoxBody = (gcnew System::Windows::Forms::RichTextBox());
this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
this->ファイルFToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->menuSave = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->saveFileDialog1 = (gcnew System::Windows::Forms::SaveFileDialog());
this->textBoxTitle = (gcnew System::Windows::Forms::TextBox());
this->buttonNew = (gcnew System::Windows::Forms::Button());
this->menuStrip1->SuspendLayout();
this->SuspendLayout();
//
// listBoxTitle
//
this->listBoxTitle->FormattingEnabled = true;
this->listBoxTitle->HorizontalScrollbar = true;
this->listBoxTitle->ItemHeight = 12;
this->listBoxTitle->Location = System::Drawing::Point(12, 36);
this->listBoxTitle->Name = L"listBoxTitle";
this->listBoxTitle->Size = System::Drawing::Size(241, 376);
this->listBoxTitle->TabIndex = 0;
this->listBoxTitle->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::listBoxTitle_SelectedIndexChanged);
//
// richTextBoxBody
//
this->richTextBoxBody->Location = System::Drawing::Point(259, 59);
this->richTextBoxBody->Name = L"richTextBoxBody";
this->richTextBoxBody->Size = System::Drawing::Size(361, 377);
this->richTextBoxBody->TabIndex = 1;
this->richTextBoxBody->Text = L"";
this->richTextBoxBody->TextChanged += gcnew System::EventHandler(this, &Form1::richTextBoxBody_TextChanged);
//
// menuStrip1
//
this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) {this->ファイルFToolStripMenuItem});
this->menuStrip1->Location = System::Drawing::Point(0, 0);
this->menuStrip1->Name = L"menuStrip1";
this->menuStrip1->Size = System::Drawing::Size(632, 24);
this->menuStrip1->TabIndex = 2;
this->menuStrip1->Text = L"menuStrip1";
//
// ファイルFToolStripMenuItem
//
this->ファイルFToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) {this->menuSave});
this->ファイルFToolStripMenuItem->Name = L"ファイルFToolStripMenuItem";
this->ファイルFToolStripMenuItem->Size = System::Drawing::Size(66, 20);
this->ファイルFToolStripMenuItem->Text = L"ファイル(&F)";
//
// menuSave
//
this->menuSave->Name = L"menuSave";
this->menuSave->Size = System::Drawing::Size(109, 22);
this->menuSave->Text = L"保存(&S)";
this->menuSave->Click += gcnew System::EventHandler(this, &Form1::menuSave_Click);
//
// saveFileDialog1
//
this->saveFileDialog1->Filter = L"テキストファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*";
//
// textBoxTitle
//
this->textBoxTitle->Location = System::Drawing::Point(259, 36);
this->textBoxTitle->Name = L"textBoxTitle";
this->textBoxTitle->Size = System::Drawing::Size(361, 19);
this->textBoxTitle->TabIndex = 3;
this->textBoxTitle->TextChanged += gcnew System::EventHandler(this, &Form1::textBoxTitle_TextChanged);
//
// buttonNew
//
this->buttonNew->Location = System::Drawing::Point(12, 418);
this->buttonNew->Name = L"buttonNew";
this->buttonNew->Size = System::Drawing::Size(241, 23);
this->buttonNew->TabIndex = 4;
this->buttonNew->Text = L"新規追加";
this->buttonNew->UseVisualStyleBackColor = true;
this->buttonNew->Click += gcnew System::EventHandler(this, &Form1::buttonNew_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(632, 446);
this->Controls->Add(this->buttonNew);
this->Controls->Add(this->textBoxTitle);
this->Controls->Add(this->richTextBoxBody);
this->Controls->Add(this->listBoxTitle);
this->Controls->Add(this->menuStrip1);
this->KeyPreview = true;
this->MainMenuStrip = this->menuStrip1;
this->Name = L"Form1";
this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"MultiEditor";
this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::Form1_KeyDown);
this->menuStrip1->ResumeLayout(false);
this->menuStrip1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
// 保存を押したら
private: System::Void menuSave_Click(System::Object^ sender, System::EventArgs^ e) {
//System::IO::StreamWriter^ sw = gcnew System::IO::StreamWriter("XML.txt",false,System::Text::Encoding::GetEncoding(932));
//sw->Write( "あああ" );
//sw->Close();
String^ save = "";
for(int i=0; i<this->listBoxTitle->Items->Count; i++){
save += "//" + this->listBoxTitle->Items[i] + "\r\n" + body[i] + "\r\n";
}
if(saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK){
System::IO::StreamWriter^ sw = gcnew System::IO::StreamWriter(saveFileDialog1->FileName,false,System::Text::Encoding::GetEncoding(932));
sw->Write( save );
sw->Close();
}
}
// リストボックス選択番号が変わったら
private: System::Void listBoxTitle_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
this->richTextBoxBody->Text = body[this->listBoxTitle->SelectedIndex];
this->textBoxTitle->Text = this->listBoxTitle->Text;
}
private: System::Void Form1_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
switch(e->KeyCode){
// アプリケーションの終了
case System::Windows::Forms::Keys::Escape:
Application::Exit();
break;
// リストボックスの削除
case System::Windows::Forms::Keys::Delete:
if( this->listBoxTitle->SelectedIndex != -1 )
this->listBoxTitle->Items->RemoveAt( this->listBoxTitle->SelectedIndex );
break;
}
// 新規追加
if (e->Control == true){
switch (e->KeyCode){
case System::Windows::Forms::Keys::N:
int i = this->listBoxTitle->SelectedIndex;
if( i != -1 ) this->listBoxTitle->Items[i] = i.ToString();
break;
}
}
}
private: System::Void textBoxTitle_TextChanged(System::Object^ sender, System::EventArgs^ e) {
int i = this->listBoxTitle->SelectedIndex;
if( i != -1 ) this->listBoxTitle->Items[i] = this->textBoxTitle->Text;
}
private: System::Void buttonNew_Click(System::Object^ sender, System::EventArgs^ e) {
this->listBoxTitle->Items->Add("New");
}
private: System::Void richTextBoxBody_TextChanged(System::Object^ sender, System::EventArgs^ e) {
body[this->listBoxTitle->SelectedIndex] = this->richTextBoxBody->Text;
}
};
}
// 0309 0630~0715
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月20日(日) 03:54
by lbfuvab
変な話かもですが、
無理に1ファイルに格納せず、
1つのiniファイル(タイトルなどの管理用)+いくつかのtxtファイル(本文保存用)
とかの形式にした方が楽チンかも知れません。
そうすれば、iniファイルはGet/WritePrivateProfileStringで読み書きできますし、txtファイルを丸ごと読み込む処理は関数化してやれば良いだけですし。
Re: オリジナルのまとめて管理できるメモ帳を作りたい
Posted: 2011年3月20日(日) 03:58
by YuO
もみじ さんが書きました:ただお話しを聞くとXMLで管理するのが主流なようですね・・・。
主流と言うより,単純に処理するのに.NET Frameworkによるサポートがあるために私はXMLを出しています。
ストレージ入出力に独自形式をわざわざ作る必要が無ければ,XMLは構造化データの入出力が簡単にできる,ということです。
もみじ さんが書きました:短時間でくみ上げられるなんて天才ですかΣ
私には到底できないです。
単に慣れです。
私の場合はC#屋なのでC#で書いてC++/CLIにポートしただけですし,
WinFormsのデータバインドもそれなりに作っているので,
時間がかかっていないのです。
もみじ さんが書きました:デリートキーを押してしまうと予期せぬエラーが起こります。
trycatchで書こうとも思ったのですがそうすると項目の削除自体が行えないです。
デバッグ実行でちゃんと追ってみましょう。
例外クラスに情報がいろいろ含まれますし,例外発生時のそれぞれの値を調べれば,原因を調べられるのですから。
今回の場合だと,
- リストボックスから項目を削除したタイミングで,リストボックスの選択は解除される
- リストボックスの選択が解除されるとSelectedIndexの値は-1になる
- SelectedIndexの値が変化するとSelectedIndexChangedイベントが発生する
- listBoxTitle_SelectedIndexChanged関数ではSelectedIndexの値をチェックせずにbodyの配列添字に使ってしまっている
以上のことから,リストボックスの項目を削除した結果としてlistBoxTitle_SelectedIndexChanged関数でbody[-1]と同等のコードになり,配列外アクセスになってしまいます。
これに関してはSelectedIndexの値をちゃんとチェックしてアクセスする必要があります。
ただ,根本的にtitleおよびbodyがリストボックスに同期していないので,削除したタイミングでデータがおかしくなります。
私はDataTableをバインドして一元管理することで回避しましたが,追加・削除のタイミングでちゃんとデータを同期させていくように変更が必要です。
この場合であれば,配列よりもSystem::Collections::Generic::List<System::String ^>^を使った方がよいでしょう。
さらに,複数の配列やリストで管理するよりも,titleとbodyを纏めてクラスにして,それの配列やリストにした方がよいと思います。
通常だとToStringメソッドを呼び出した結果が表示されますが,
リストボックスのDisplayMemberにメンバ名を書いておくと,そのメンバを表示してくれます。