上記に以前、投稿し助けていただきました。
その節はありがとうございまいした。
今回はその続きの質問となります。
if (this->m_redoStack.Count > 0)と書いているのに起動してからすぐに
Ctrl+ZをやるとUndoのスタックがEmptyとエラーが出てしまいます。
またUndo、Redo時にカーソルの位置が0番目になってしまうのですが前回の位置にと直せないでしょうか?
// カーソル操作
this->TextBox1.Focus()
this->TextBox1.Select(番目, 0)
でできるとわかったのですがどこに移動させればいいのかということと
このソースで作ったテキストボックスだと強制的に0番目にカーソルがあってしまいます。
どのようにすれば直せるでしょうか。
お忙しいかとは思いますがアドバイスを頂けますと助かります。
#pragma once
public ref class UndoTextBox : public System::Windows::Forms::TextBox
{
private:
System::Collections::Generic::Stack<System::String^> m_redoStack;
System::Collections::Generic::Stack<System::String^> m_undoStack;
bool m_change;
public:
UndoTextBox(void)
{
InitializeComponent();
// メンバの初期化
init();
}
UndoTextBox(System::ComponentModel::IContainer ^container)
{
container->Add(this);
InitializeComponent();
// メンバの初期化
init();
}
protected:
~UndoTextBox()
{
if (components)
{
delete components;
}
}
virtual void OnTextChanged(System::EventArgs^ e) override
{
// フラグがtrueの場合は…
if (this->m_change == true)
{
// UNDOかREDOによってTEXTが変化したので、フラグをfalseにするだけで何もしない
this->m_change = false;
}
else
{
// REDO用Stackの中身を削除する
this->m_redoStack.Clear();
// UNDO用Stackへ最新のTEXTを挿入する
this->m_undoStack.Push(this->Text);
}
TextBox::OnTextChanged(e);
}
virtual void OnKeyDown(System::Windows::Forms::KeyEventArgs^ e) override
{
if (e->Control == true)
{
switch (e->KeyCode)
{
case System::Windows::Forms::Keys::A:
// 全選択
SelectAll();
return;
case System::Windows::Forms::Keys::Z:
// UNDO処理
undo();
return;
case System::Windows::Forms::Keys::Y:
// REDO処理
redo();
return;
}
}
TextBox::OnKeyDown(e);
}
private:
/// <sammary>
/// メンバの初期化
/// <sammary>
void init(void)
{
// Stackの中身を削除する
this->m_redoStack.Clear();
this->m_undoStack.Clear();
// UNDO用Stackの最初の要素として、空文字を挿入しておく
this->m_undoStack.Push(System::String::Empty);
// フラグをfalseで初期化
this->m_change = false;
}
/// <sammary>
/// UNDO
/// <sammary>
void undo(void)
{
// UNDO用のStackが空っぽでなければ…
if (this->m_undoStack.Count > 0)
{
// Stackの先頭要素がTextBox内のTEXTと同じの場合は…
if (this->m_undoStack.Peek() == this->Text)
{
// 一度だけ空読みして先頭要素を削除する
this->m_undoStack.Pop();
}
// UNDOによってTEXTが変化するのでフラグをTRUEにする
this->m_change = true;
// TextBox内のTEXTをREDO用Stackの先頭へ挿入する
this->m_redoStack.Push(this->Text);
// UNDO用のStackの先頭要素をTextBox内のTEXTへコピーする
this->Text = this->m_undoStack.Pop();
}
}
/// <sammary>
/// REDO
/// <sammary>
void redo(void)
{
// REDO用のStackが空っぽでなければ…
if (this->m_redoStack.Count > 0)
{
// REDOによってTEXTが変化するのでフラグをTRUEにする
this->m_change = true;
// TextBox内のTEXTをUNDO用Stackの先頭へ挿入する
this->m_undoStack.Push(this->Text);
// REDO用のStackの先頭要素をTextBox内のTEXTへコピーする
this->Text = this->m_redoStack.Pop();
}
}
private:
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
components = gcnew System::ComponentModel::Container();
}
#pragma endregion
};