|ハイブリッドOS|File System|ARM|Android|Java|制御システム|オープンシステム

 

VC

 
フォーム
 
フォルダ内のファイル名取得
2014-02-17
今回は、フォルダ内のファイル名取得方法です。
以下の例は、button1を押すと、
C:\TEMPフォルダ内のファイル名を取得し
TextBoxに表示します。

namespace GetDirFileNames {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::IO;                    // Add
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
        }
        :<略>
    //
    private: System::Void button1_Click(System::Object^  sender,
System::EventArgs^  e)
        {
            int  i;
            int  f_maxno;
            String ^target_dir = gcnew String("C:\\TEMP");
            String ^wk_str = gcnew String("");

            // C:\TEMPフォルダの情報取得
            DirectoryInfo ^dir = gcnew DirectoryInfo(target_dir);
            f_maxno = dir->GetFiles()->Length;
            array<FileInfo^, 1> ^fi = gcnew array<FileInfo^, 1>(f_maxno);
            fi = dir->GetFiles();            // フォルダ内のファイル情報取得
            // 取得したフォルダ内ファイル名を1個づつ、TextBoxに表示
            for(i=0; i<f_maxno; i++) {
                wk_str = fi[i]->Name;
                wk_str = String::Concat(wk_str, "\n");
                textBox1->AppendText(wk_str);
            }
        }
    };
}
(WindowsアプリケーションForm (Framework3.5) VS2008 VC++環境でのお話しです。)
 
関数テーブル
2014-01-06
 今回は、C言語の関数テーブルを、VC++で実現してみました。
 実装方法や使い方はいろいろあると思いますが
 以外に便利な場合もあります。
 以下の例は、
 Form起動時に関数(メソッド)テーブル作成、ボタン1が押されると
 関数テーブルの関数を全部実行しまします。
 関数は例なので2個のみ用意でそれぞれ、引き数に+1、+2する関数です。
 はじめ引数1で開始するので
 1+1+2 となり、応え "4"がTextBoxに表示されます。

namespace functionPointer {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
        }
    :<略>
    delegate int MyDelegate(int);        // delegate宣言
    // 関数ポインタ管理用構造体の宣言
    value struct FUNC_TBL {                // FuctionTbl
        MyDelegate ^myfunc;                // このクラスのメンバメソッドポインタ
    };
    array<FUNC_TBL, 1> ^f1_functbl;

    int func1(int a) {    // +1 function
        int b;
        b = a + 1;
        return b;
    }
    int func2(int a) {    // +2 function
        int b;
        b = a + 2;
        return b;
    }
 
    // Form1起動処理
    private: System::Void Form1_Load(System::Object^  sender,
System::EventArgs^  e)
        {
            // 関数テーブル作成
            f1_functbl = gcnew array<FUNC_TBL, 1>(2);
            f1_functbl[0].myfunc = gcnew MyDelegate(this,
&functionPointer::Form1::func1);    // func1登録
            f1_functbl[1].myfunc = gcnew MyDelegate(this,
&functionPointer::Form1::func2);    // func2登録
        }
    // Button1実行
    private: System::Void button1_Click(System::Object^  sender,
System::EventArgs^  e)
        {
            int i;
            int data;
            data = 1;
            // func1、func2連続実行
            for(i=0; i<2; i++)
                data = f1_functbl[i].myfunc(data);
            textBox1->Text = data.ToString();
        }
    };
}
 
(WindowsアプリケーションForm (Framework3.5) VS2008 VC++環境でのお話しです。)
 
スレッドからのForm上のControlへのアクセス
2013-12-24
 今回は、スレッドから Form上にあるボタンの許可禁止のアクセス方法についてまとめます。
 VisualStadio2008 VC++ では
 スレッドから直接 Form上のControlを制御するこは許されていません。
 delegate と Invoke をしようすることで、スレッドから Form側のスレッドに処理を写し
 Contorlを制御できるようにします。
 以下の例は、
 Form起動時にスレッドを起動、約2秒おきに button1(スレッド終了要求ボタン)を許可、禁止を
 繰り返すものです。この許可禁止で、delegate と Invokeを使用しています。
 
namespace ThreadSample2 {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::Threading;            // <------ 追加
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
        }
        :<略>
        // Thread処理用メンバ宣言
        Thread^ WorkThread;
        ThreadStart^ WorkThreadDelegate;
        bool thread_stop_req;
        // Controlの制御のための delegate
        delegate void fm1_void_void(void);

    // button1許可
    void button1_enb(void)
    {
        if(this->InvokeRequired){
            // スレッドのときはここへ来る
            fm1_void_void ^dgt = gcnew fm1_void_void(this,
&ThreadSample2::Form1::button1_enb);    //Deleateオブジェクト
            this->Invoke( dgt );
        }
        else {
            // Invokeで呼び出すことで Formのプロセスでこちらへ来る
            button1->Enabled = true;
        }
    }
    // button1禁止
    void button1_dsb(void)
        {
            if(this->InvokeRequired){
                // スレッドのときはここへ来る
                fm1_void_void ^dgt = gcnew fm1_void_void(this,
&ThreadSample2::Form1::button1_dsb);    //Deleateオブジェクト
                this->Invoke( dgt );
            }
            else {
                // Invokeで呼び出すことで Formのプロセスでこちらへ来る
                button1->Enabled = false;
            }
        }

    // Thread処理メソッド
    void ThreadProcessing(void)
        {
            bool enb_f;
            enb_f = true;
            button1_dsb();
            while(true) {
                Thread::Sleep(2000);        // 約2秒Sleep
                if(thread_stop_req==true)
                    break;                    // Thread停止要求があった
                if(enb_f==true) {
                    button1_enb();            // button1許可
                    enb_f = false;
                }
                else {
                    button1_dsb();            // button1禁止
                    enb_f = true;
                }

            }
            MessageBox::Show("Thread終了します。");
        }
    // Form1 起動時処理
    private: System::Void Form1_Load(System::Object^  sender,
System::EventArgs^  e)
        {
            WorkThread = nullptr;
            if(WorkThread==nullptr) {
                // Thread生成
                WorkThreadDelegate = gcnew ThreadStart(this,
&ThreadSample2::Form1::ThreadProcessing);
                WorkThread = gcnew Thread(WorkThreadDelegate);
                WorkThread->Start();
            }
        }
    // スレッド停止要求
    private: System::Void button1_Click(System::Object^  sender,
System::EventArgs^  e)
        {
            thread_stop_req = true;        // Thread終了要求
        }
    // Form終了時 処理
    private: System::Void Form1_FormClosing(System::Object^  sender,
System::Windows::Forms::FormClosingEventArgs^  e)
        {
            bool bret;
            thread_stop_req = true;        // Thread終了要求
            // Thread終了待ち
            if(WorkThread!=nullptr) {
                bret = WorkThread->Join(10000);    // 10秒 Threadの終了を待つ
                if(bret==true)
                    MessageBox::Show("正常終了。");
                else
                    MessageBox::Show("Timeout終了。");
            }
        }
    };
}
(WindowsアプリケーションForm (Framework3.5) VS2008 VC++環境でのお話しです。)
 
Delegate
2013-12-16
Delegateは、関数ポインタににていますがちょっと違うところがあります。
第4回目ででてきた、EventHandlerへの登録なども Delegate を使用しています。
以下、第4回より
"fm2->Closed += gcnew EventHandler(this, &TestForm2close::Form1::Form2_End);"
以下の例は、
plus と minus の Methodがあって、これらを delegate(委譲)を使用することで別の Method dgt_calc で plus や minus を処理することができるようになります。
namespace SampleDeletgate {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    // 戻り値int型、2つの引数を持つ Method のDelegate型を宣言
    delegate int delegate_plus( int a, int b );
 
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
        }
        :<略>
        // 足し算 Method
        int plus( int a, int b )
        {
            return a+b;
        }
        // 引き算 Method
        int minus( int a, int b )
        {
            return a-b;
        }

    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
        {
            int result;
            delegate_plus ^dgt_calc;

            // dgt_calc に plusを委譲
            dgt_calc = gcnew delegate_plus(this, &SampleDeletgate::Form1::plus);
            result = dgt_calc(2, 1);                // 足し算処理
            textBox1->Text = result.ToString();    // 結果を出力に表示。('3')
 
            // dgt_calc に minusを委譲
            dgt_calc = gcnew delegate_plus(this, &SampleDeletgate::Form1::minus);
            result = dgt_calc(2, 1);                // 引き算処理
            textBox2->Text = result.ToString();    // 結果を出力に表示。('1')
        }
    };
}

(WindowsアプリケーションForm (Framework3.5) VS2008 VC++環境でのお話しです。)
 
スレッド
2013-12-11
スレッドの生成方法についてまとめます。
スレッドについて説明をすると長くなるため、ここでは省略させていただきます。

例:TopForm に button1 を配置し、button1が押されたら、スレッド ThreadProcessing() を生成し、スレッド内で MesageBox表示させます。
    また、TopFormの×ボタンが押されたとき、終了Event でスレッドが終了するのを10秒待ちます。
    通上、スレッドの終了は、スレッド用に自分が用意したメソッド(関数)を returnすれば終了です。
    たとえば、ThreadProcessing()の処理内容をbutton1 押しEvent( button1_Click )に処理させえるとMessageBoxの"OK"ボタンを押さない限り、TopForm にアクセスできなくなります。
   しかし、ThreadProcessing()で MessageBoxを表示させると
   OKボタンを押しても押さなくても、TopFormにアクセスできます。
   今ままでは、TopForm 1プロセスだったのをスレッドを生成することにより
   並列処理できるようになります。
   注意:Threadを終了してから、アプリケーションを終了する必要があります。
      本サンプルでは、button1を押して、Threadを生成し、そこでMesageBox表示
      "OK"を押さなければ Threadは残ります。そこで、TopForm×ボタンを押すと
      TopFormのみ閉じてThreadで生成した、MessageBoxは残ってしまいます。
      画面上はわかりにくくても本アプリケーションのプロセスは残ってしまうので
      必ず、Threadを終了して、アプリケーションを終了するようにしましょう。
 
namespace ThreadSample {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::Threading;        // <--- ★追加★

    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            WorkThread = nullptr;
        }
        :
        :<略>
        :
        // Thread処理用メンバ宣言
        Thread^ WorkThread;
        ThreadStart^ WorkThreadDelegate;

    // Thread処理メソッド
    void ThreadProcessing(void)
        {
            MessageBox::Show("Threadで処理しました。");
        }

    // Thread Startボタン押し処理
    private: System::Void button1_Click(System::Object^  sender,
System::EventArgs^  e)
        {
            if(WorkThread==nullptr) {
                // Thread生成
                WorkThreadDelegate = gcnew ThreadStart(this,
&ThreadSample::Form1::ThreadProcessing);
                WorkThread = gcnew Thread(WorkThreadDelegate);
                WorkThread->Start();
            }
            else {
                MessageBox::Show("Threadは生成ずみです。");
            }
        }
    // TopForm終了時 処理
    private: System::Void Form1_FormClosing(System::Object^  sender,
System::Windows::Forms::FormClosingEventArgs^  e)
        {
            bool bret;
            // Thread終了待ち
            if(WorkThread!=nullptr) {
                bret = WorkThread->Join(10000);    // 10秒 Threadの終了を待つ
                if(bret==true)
                    MessageBox::Show("正常終了。");
                else
                    MessageBox::Show("Timeout終了。");
            }
        }
    };
}
 
(WindowsアプリケーションForm (Framework3.5) VS2008 VC++環境でのお話しです。)
2