直列つなぎ。 -とある発達障害者の記録

知識と知識を繋ぐためのblog。 広汎性発達と診断されました。ぜんぜん役に立ってないけど。月収13万円、家賃4万円で生活するひつじ人間。

【C#】自作付箋紙アプリFakeSticky Notesの改良

 
 FakeSticky : http://mojakouinfotaker.blog.fc2.com/blog-entry-890.html


 10秒ごとに自動保存させる仕様は廃止。代わりに閉じる前に保存させるとか。

 ●付箋を増やす
 これは難しく考えずに、Form1を呼び出して内容をクリアするようにした。
 
  Form1 frm = new Form1();
            frm.Show();
            frm.richTextBox1.Clear();
  これで付箋紙アプリと同等の動作をするのかどうか。
 




 ●メインフォーム(mainForm)を閉じたときにアプリ自体が終了してしまう。
 調べたところ、
  1.メインフォームを隠してしまう
  2.全てのフォームをメインフォームとして扱う 
    というやり方があるらしい。
 1でもいい気がするが、2で行こうかと思う。



サンプル
 https://note.chiebukuro.yahoo.co.jp/detail/n331218 
     static class Program
    {

        private static ApplicationContext mainApplicationContext;
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
       Application.SetCompatibleTextRenderingDefault(false);
           //冒頭に置いておく 
     //Form1生成後に置くなどするとエラー


            mainApplicationContext = new ApplicationContext();
     //インスタンス化
            Form1 f = new Form1();
            // メインフィームに、最初に開くフォームを設定する
            mainApplicationContext.MainForm = f;
    //こうしておかないとApplocationContextががnullになってしまう。フォーム側でも利用するためにForm1を代入しておく。
    

      Application.Run(mainApplicationContext);

       
        }

 この後、フォームのイベント側でApplicationContextを移し替えれば良いことが分かった。
 こんな感じである。

        private void plusButton_Click(object sender, EventArgs e)
        {
          
            Form1 frm = new Form1();
            Program.mainApplicationContext.MainForm = frm;
            frm.Show();


           
            frm.richTextBox1.Clear();           
        }
 躓いた割には恐ろしく簡単な内容だ。
 こんな遅々とした進歩でも実現できるとちょっとうれしかった。

 しかし、これでも不十分で、直前にmainApplicationContextに設定されたフォームを終了させると、アプリ自体も終了してしまう(全部同じForm1だし)。名前を付け直すか、スレッド単位で動的生成させるか・・・。

 ....いや、ここはメインフォーム隠しちゃおう。良いサンプルが見つからん。




 
起こったエラー 
結果:"obj\Release\FakeStickyNote.exe" を "bin\Release\FakeStickyNote.exe" にコピーできませんでした。10 回の再試行回数を超えたため、失敗しました。  
    "obj\Release\FakeStickyNote.exe" を "bin\Release\FakeStickyNote.exe" にコピーできませんでした。1000 ミリ秒以内に 1 回目の再試行を開始します。別のプロセスで使用されているため、プロセスはファイル 'bin\Release\FakeStickyNote.exe' にアクセスできません。      


 型 'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました
   Application.SetCompatibleTextRenderingDefault(false); が最後にあったために起こった。
          
追加情報:最初の IWin32Window オブジェクトがアプリケーションで作成される前に、SetCompatibleTextRenderingDefault が呼び出されなければなりません。


 これは     Application.SetCompatibleTextRenderingDefault(false); が先じゃないと通りませんよって事らしかった。 前に移したらあっさり通った。



 Form1を継承したFormを作らないとダメなのか?
 mainForm を継承したForm1とか?抽象クラス?
   ....などと考えてみた。もちろんそんなことしても面倒なだけである。




 
サンプル メインのフォームが2個あるアプリケーション <ただフォームを表示するだけのサンプル>  https://note.chiebukuro.yahoo.co.jp/detail/n191524

 問題なく。付箋ソフトに応用するには、フォームを動的生成して名前を付け直す必要がありそう。
 
 .....などと考えたが、やはりForm1をそのまま使う方が簡単である。




 メインフォームを隠し、操作可能な全てのフォームをサブフォームとして扱う。
  これならまあカンタンそうだ。が、もっといいやり方が見つかった。
 一応、サンプルのURLは置いとく。
   http://mithrilworks.jp/others/program/cs/hideform.html




 
 ●各フォームをスレッド単位で起動させる。 https://note.chiebukuro.yahoo.co.jp/detail/n191524  ここのサンプルは分かりやすいんだが、このように処理内容を単位として記述すべきでは・・・・同じようなものを幾つも並べられても困る
 

 using System.Threading;
 
    private void button1_Click(object sender, EventArgs e)
        {
            Form1 mForm = new Form1();

            Thread ThreadObj1 = new Thread(new ParameterizedThreadStart(RunFormThread));
            ThreadObj1.SetApartmentState(ApartmentState.STA);
            ThreadObj1.Start(mForm);


        }
       // フォームを実行するスレッド用メソッド
        // 第1引数: 実行対象フォーム 
    以下も丸写し。 

  このような簡便な方法がある事に目からうろこが落ちる思い。
  ・・・・が、別スレッドでの起動であるため、  frm.richTextBox1.Clear(); は働かないようだ。というか、ファイルのロードの方が後になっている=新規起動という事に。
 結局不採用か。


いや、Form1を継承した上で派生クラスにファイルのロードを実装する → plusButtonを押した場合はrtfのロードを行わないという分岐を作れればいいのでは。多分。


 
関連記事
スポンサーサイト

 C#

0 Comments

Leave a comment