【VC++】ピクチャーボックスに画像を表示する

0

    <機能>

    (1)ピクチャーボックスに直接絵をかきます

    (2)ピクチャーボックスに任意の画像を表示します

      (2)-1.画像を表示する際にピクチャーボックスのサイズに伸縮します

      (2)-2.伸縮画像が劣化しないように伸縮モードを指定します

     

    <実行イメージ>

    上はピクチャーボックスに直接グラデーションを描画

    下はJPEGをピクチャーボックスに表示(伸縮して表示)

     

    VC,MFC,PICTURECONTROL,伸縮,DC,描画モード,HALFTONE,
     

    <動作検証&開発環境>
    Visual Studio Community 2017

     

    <使い方>

    1.MFCのダイアログベースアプリケーションを作成します

      ※サンプルではプロジェクト名をPictureTestとします

    VC,MFC,PICTURECONTROL,伸縮,DC,ダイアログベース,ウィザード,
     

    2.リソースファイル(PictureTest.rc)を開いて"言語 17、"を""LANGUAGE 17,"に修正

      ※ダイアログベースでビルドエラー参照

    3.ダイアログにコントロールを追加

      ・ピクチャーボックス:IDC_PICTURE1/IDC_PICTURE2

      ・ボタンはIDOKをそのまま使用

    VC,MFC,PICTURECONTROL,伸縮,DC,描画モード,ウィザード,
     

    4.ピクチャーボックスにメンバ変数を追加

      ・IDC_PICTURE1 : m_Picture1(コントロール変数)

      ・IDC_PICTURE2 : m_Picture2(コントロール変数)


     

    5.メンバ関数setPictureControl()を追加


     

    6.ONOKのボタン押下イベント追加

    7.ソースを追加

     

    PictureTestDlg.h

    private:
     //ピクチャーコントロールの描画エリア
     RECT rect1, rect2;
     //ピクチャーコントロールへの描画処理
     void setPictureControl();
    public:
     afx_msg void OnBnClickedOk();
     CStatic m_Picture2;
     CStatic m_Picture1;

     

    PictureTestDlg.cpp

    BOOL CPictureTestDlg::OnInitDialog()

    {

        //~~省略~~

        //ピクチャーコントロールの幅と高さを取得
        m_Picture1.GetWindowRect(&rect1);
        m_Picture2.GetWindowRect(&rect2);

        //~~省略~~
    }

     

    /*************************************************
    関数名 setPictureControl
    機能   ピクチャーコントールに描画する
    *************************************************/

    void CPictureTestDlg::setPictureControl()
    {
        CDC *cdc;
        int iWidth, iHeight;

     

        //IDC_PICTURE1にグラデーションを直接描画
        cdc = m_Picture1.GetDC();
        iWidth = rect1.right - rect1.left;
        iHeight = rect1.bottom - rect1.top;
        for (int y = 0; y < iHeight; y++) {
            for (int x = 0; x < iWidth; x++) {
                COLORREF clr = RGB(0,x * 0xff / iWidth, 0);
                SetPixel(cdc->GetSafeHdc(), x,y,clr);
            }
        }

     

        //IDC_PICTURE2にファイルを描画
        cdc = m_Picture2.GetDC();
        iWidth = rect2.right - rect2.left;
        iHeight = rect2.bottom - rect2.top;

     

        //読み込む画像ファイルパス
        TCHAR buf[2048];
        CString cs;
        ZeroMemory(&buf, sizeof(buf));
        GetModuleFileName(NULL, buf, sizeof(buf));
        cs.Format(L"%s",buf);
        cs = cs.Left(cs.ReverseFind('¥¥')) + L"¥¥Sample.jpg";
       
        CImage img;
        HRESULT ret = img.Load(cs);
        if (img.IsNull()) {
            AfxMessageBox(L"画像の読み込み失敗",MB_ICONERROR);
            return;
        }
        //StretchBltで描画領域に合わせてリサイズ
        CDC bmpDC;
        CBitmap *cbmp;
        cbmp = CBitmap::FromHandle(img);
        bmpDC.CreateCompatibleDC(cdc);
        CBitmap *oldbmp = bmpDC.SelectObject(cbmp);
        //伸縮すると画像が汚くなるので伸縮モードを指定
        //詳細は
    MSDN参照
        cdc->SetStretchBltMode(STRETCH_HALFTONE);
        //ブラシのずれを防止するためSetBrushOrgExを呼び出す
        cdc->SetBrushOrg(0, 0);
        //画像を伸縮してピクチャーボックスに表示
        //詳細は
    MSDN参照
        cdc->StretchBlt(0,0,iWidth,iHeight,&bmpDC,0,0,img.GetWidth(),img.GetHeight(),SRCCOPY);
        bmpDC.SelectObject(oldbmp);
        //後片付け
        cbmp->DeleteObject();
        bmpDC.DeleteDC();
        ReleaseDC(cdc);
    }

     

    /*************************************************
    関数名 OnBnClickedOk
    機能   OKボタン押下イベントハンドラ
    *************************************************/

    void CPictureTestDlg::OnBnClickedOk()
    {
        setPictureControl();
    }

     

    よろしければポチッと押してください

    プログラマー ブログランキングへ

     


    【VC++】VS2017のダイアログベースでビルドエラーとなる場合の対応

    0

      <現象>

      Visual Studio2017のダイアログベースでリソースを編集するとビルドエラーとなる

      (英語版では発生しないが日本語版では発生する)

      RC2135 file not found

      VC++,RC2135file not found,MFC,
       

      再現手順は以下の通り

      1.Visual Stuido2017でダイアログベースアプリのプロジェクト作成

      2.ダイアログにエディットボックスなどを追加

      3.ビルドするとエラーとなる

       

      ちょっとはまったので、私の環境で行ったことをメモとして残します

       

      Visual Stuido2017も最初は大丈夫だった気がする、、、

      アップデートでしこまれたバグだと思われますが早く修正してほしい!!!

       

      <バージョン>

       

      Visual Studio Community 2017

      Version 15.5.6

       

      <ダイアログアプリ作成方法>

       

      行ったこと

      (1)MFC と ATL のサポート(x86 と x64)をインストール

      Visual Studioメニューの[ツール]→[ツールと機能を取得]または

      WindowsメニューのVisual Studio Installerを選択
      VC++,ツール,ツールと機能,VS2017,MFC,
       

      (2)新規プロジェクトを作成

      (3)MFCアプリケーションを選択
      VC++,ウィザード,VS2017,MFC,
       

      (4)アプリケーションの種類でダイアログベースを選択して[完了]押下

      VC++,ウィザード,VS2017,MFC,
       

      (5)リソースファイル(.rc)を開く

      本サンプルではMFCApplication1.rcを右クリックしたコンテキストメニューで

      [コードの表示]を選択

      VC++,修正,VS2017,MFC,
      (6)下記の箇所を全て修正する(「言語」「、」を修正する)

      修正前)"言語 171¥r¥n"

      修正後)"LANGUAGE 17,1¥r¥n"

      VC++,修正,VS2017,MFC,rc,リソースファイル,
       

      <確認方法>

      (1)ダイアログに確認用のGUIを追加

      VC++,修正,VS2017,MFC,確認,
       

      (2)ヘッダファイルにメンバ変数とイベント追加

      本サンプルではMFCApplication1Dlg.hに追加

       

      public:
          afx_msg void OnBnClickedCheck1();
          afx_msg void OnBnClickedButton1();

       

      private:
          CButton *cbtn;
          CButton *ccheck;
          CEdit *cedit;

       

      (3)処理を追加

       

      本サンプルではMFCApplication1Dlg.cppに追加

       

      BOOL CMFCApplication1Dlg::OnInitDialog()
      {

          //~~ 省略 ~~

          //初期化
          cbtn = (CButton*)GetDlgItem(IDC_BUTTON1);
          ccheck = (CButton*)GetDlgItem(IDC_CHECK1);
          cedit = (CEdit*)GetDlgItem(IDC_EDIT1);

       

          cbtn->SetWindowText(L"メッセージ表示");
          ccheck->SetCheck(FALSE);
          cedit->SetWindowText(L"");

       

          //~~ 省略 ~~

      }

       

      //チェックON/OFF
      void CMFCApplication1Dlg::OnBnClickedCheck1()
      {
          if (ccheck->GetCheck()) {
              cedit->SetWindowText(L"チェックはONです");
          }
          else {
              cedit->SetWindowText(L"チェックはOFFです");
          }
      }

       

      //ボタン押下
      void CMFCApplication1Dlg::OnBnClickedButton1()
      {
          AfxMessageBox(L"VisualStudio2017 MFCダイアログアプリケーション");
      }

       

      (4)ビルドして実行

       

      よろしければポチッと押してください

      プログラマー ブログランキングへ

       


      【VC++】デバイスコンテキストを使って帳票を出力する

      0

        <機能>

        (1)コモンダイアログ(印刷)を表示します

        (2)デバイスコンテキストに文字を線を描画して帳票を生成します

         (StartDoc→StartPage→EndPage→EndDoc)

        (3)サンプルとして領収書を作成します

         

        <イメージ>

        VC,デバイスコンテキスト帳票

         

        <動作検証&開発環境>

        Visual Studio Community 2017

         

        <使い方>

        Win32アプリケーションを作成します

        1.Windowsデスクトップを選択

        VC,ソリューション作成1

        2.アプリケーションの種類で「コンソールアプリケーション」を選択

        3.共通ヘッダの「MFC」にチェック

        VC,ソリューション作成2

        4.ソースを追加

         

        //プロトタイプ宣言
        void SamplePrintOut(CDC *pDC);
        void SetLogFont(CDC *pDC, LOGFONT& logfont, CString csFontName, int iSize);
        void DeleteFont();
        void LineOut(CDC *pDC, int stx, int sty, int edx, int edy);
        //フォントを宣言
        CFont *pFont10; //10ポイントのフォントを宣言
        CFont *pFont20; //20ポイントのフォントを宣言

        // 唯一のアプリケーション オブジェクトです。
        CWinApp theApp;
        using namespace std;
        int main()
        {
            int nRetCode = 0;
            HMODULE hModule = ::GetModuleHandle(nullptr);
            if (hModule != nullptr)
            {
                // MFC を初期化して、エラーの場合は結果を印刷します。
                if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
                {
                    // TODO: 必要に応じてエラー コードを変更してください。
                    wprintf(L"致命的なエラー: MFC の初期化ができませんでした。¥n");
                    nRetCode = 1;
                }
                else
                {

                    //コモンダイアログ[印刷]で提供されているダイアログ
                    CPrintDialog dlg(FALSE);
                    //通常使うプリンターのデバイス コンテキストを取得するとき
                    //dlg.GetDefaults();
                    //コモンダイアログを表示するとき

                    if (dlg.DoModal() != IDOK) return nRetCode;
                   
                    CDC prDC;
                    HDC hd = dlg.GetPrinterDC();
                    prDC.Attach(hd);
                   
                    //プリンタデバイスコンテキストの情報が必要な時は GetDeviceCaps で取得
                    //int iPixelx = prDC.GetDeviceCaps(LOGPIXELSX); //水平方向のピクセル数
                    //int iPixely = prDC.GetDeviceCaps(LOGPIXELSY); //垂直方向のピクセル数
                    //印刷用の論理フォント(フォント種類やサイズ情報を含む)
                    LOGFONT logfont;
                    //10ポイント「MS 明朝」フォント
                    SetLogFont(&prDC, logfont, _T("MS 明朝"), 10);
                    pFont10 = new CFont;
                    pFont10->CreateFontIndirect(&logfont);
                    //20ポイント「HG丸ゴシックM-PRO」フォント
                    SetLogFont(&prDC, logfont, _T("HG丸ゴシックM-PRO"), 20);
                    pFont20 = new CFont;
                    pFont20->CreateFontIndirect(&logfont);
                    //サンプル帳票の印刷処理開始
                    SamplePrintOut(&prDC);
                    //後処理
                    prDC.Detach();
                    DeleteDC(hd);
                    //フォントオブジェクトの破棄
                    DeleteFont();
                }
            }
            else
            {
                // TODO: 必要に応じてエラー コードを変更してください。
                wprintf(L"致命的なエラー: GetModuleHandle が失敗しました¥n");
                nRetCode = 1;
            }
            return nRetCode;
        }

        /*************************************************
        関数名 SamplePrintOut
        機能   サンプル帳票を生成
        *************************************************/

        void SamplePrintOut(CDC *pDC)
        {
            CFont *pOld;
            //印刷領域を取得
            CRect rect;
            pDC->GetClipBox(&rect);
            //印刷ドキュメント(入出力ファイル情報)の設定
            DOCINFO dinfo;
            memset((char *)&dinfo, 0x00, sizeof(DOCINFO));
            //DOCINFO構造体のサイズ
            dinfo.cbSize = sizeof(DOCINFO);
            //ドキュメント名
            dinfo.lpszDocName = _T("やさしいプログラミング備忘録 VC++サンプル");
            //ドキュメント開始
            pDC->StartDoc(&dinfo);
            //ページ開始
            pDC->StartPage();
            //大きいフォントを指定
            pOld = pDC->SelectObject(pFont20);
            //文字を出力
            pDC->TextOut(700, 900, _T("領 収 書"));
            pDC->TextOut(1700, 1400, _T("株式会社 ○○○○商事 様"));
            pDC->TextOut(1100, 2000, _T("¥   59,800(消費税込み)"));
            //小さいフォントを指定
            pDC->SelectObject(pFont10);
            pDC->TextOut(3000, 950, _T("No.○○-1234567890"));
            pDC->TextOut(3000, 1100, _T("2017年10月10日"));
            pDC->TextOut(1600, 2500, _T("但し パンフレットデザイン費、及び印刷代金として"));
            pDC->TextOut(1600, 2700, _T("上記正に領収いたしました。"));
            pDC->TextOut(2200, 3500, _T("神奈川県横浜市○○区○○○1−2−3 ××ビル2階"));
            pDC->TextOut(2700, 3650, _T("やさしいプログラミング備忘録 株式会社"));
            //線を引く
            LineOut(pDC, 3000, 1050, 4300, 1050);
            LineOut(pDC, 1050, 2200, 4000, 2200);
            //ページ終了
            pDC->EndPage();
            //ドキュメント終了
            pDC->EndDoc();
        }

        /*************************************************
        関数名 SetLogFont
        機能   フォントに種別、サイズを設定する
        *************************************************/

        void SetLogFont(CDC *pDC, LOGFONT& logfont, CString csFontName, int iSize)
        {
            memset(&logfont, 0x00, sizeof(logfont));
            lstrcpy(logfont.lfFaceName, csFontName);
            //LOGFONT構造体についてはDeveloperNetwork参照
            //出力精度を指定
            logfont.lfOutPrecision = OUT_TT_PRECIS;
            //クリッピング領域を外れた時の精度
            logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
            //出力品質を指定
            logfont.lfQuality = PROOF_QUALITY;
            //ピッチとファミリを指定
            logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
            //文字セットを指定
            logfont.lfCharSet = SHIFTJIS_CHARSET;
            //文字または文字の論理単位で、高さを指定(デバイス論理インチのピクセル数)
            //MicrosoftSupport参考
            logfont.lfHeight = -MulDiv(iSize, pDC->GetDeviceCaps(LOGPIXELSY), 72);
        }

        /*************************************************
        関数名 SetLogFont
        機能   フォントに種別、サイズを設定する
        *************************************************/

        void DeleteFont()
        {
            if (pFont10) {
                pFont10->DeleteObject();
                delete pFont10;
            }
            if (pFont20) {
                pFont20->DeleteObject();
                delete pFont20;
            }
        }

        /*************************************************
        関数名 LineOut
        機能   線を引く
        *************************************************/

        void LineOut(CDC *pDC, int stx, int sty, int edx, int edy)
        {
            CPen newPen;
            CPen *pOld = NULL;
            newPen.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
            pOld = pDC->SelectObject(&newPen);
            pDC->MoveTo(stx, sty);
            pDC->LineTo(edx, edy);
            pDC->SelectObject(pOld);
        }
         

        よろしければポチッと押してください

        プログラマー ブログランキングへ

         


        【VC++】簡単なマルチスレッド その2

        0

          <機能>

          (1)AfxBeginThreadを使用したマルチスレッドサンプルです

          (2)セマフォ(CSemaphoreクラス)を使って排他制御します

          (3)public変数 count を5スレッドからカウントアップします

           ※1スレッドあたり100カウントアップするためcount=500となります

           (排他制御(CSingleLock::Lock/Unlock)がないとcount<500)

           

          <イメージ>

          排他制御実装前の結果は、100カウントアップするスレッドを5つ起動してcount=500になりません

          CSemaphoreを使用しない結果

          セマフォを使ってcountをいずれか1スレッドからしか使えないように排他制御(CSingleLock::Lock/Unlock)するとcount=500となりました

          CSemaphoreを使用した結果

           

          <動作検証&開発環境>
          Visual Studio Community 2017

          <使い方>
          1.ダイアログベースでThreadSample2プロジェクトを作成
          2.エディットボックスとボタンを配置

           

          ダイアログにGUI配置
          IDC_EDIT1/IDC_EDIT2:ReadOnly=TRUE
          3.コントロール変数を追加
          エディットボックスにコントロース変数設定
          IDC_EDIT1 : m_EdtCount(種類EDIT/カテゴリControl)
          IDC_EDIT2 : m_EdtThread(種類EDIT/カテゴリControl)
          4.ソース追加

          ThreadSample2Dlg.h
          class CThreadSample2Dlg : public CDialogEx
          {
              //~~省略~~
          public:
              afx_msg void OnBnClickedButton1();
              int count;
              int threadno;
              CWinThread *mythread;
              CEdit m_EdtCount;
              CEdit m_EdtThread;
              //セマフォオブジェクト(スレッド間のロックに使用)
              CSemaphore m_cSmp;
          };
          ThreadSample2Dlg.cpp
          //プロトタイプ宣言
          UINT __cdecl CountUpThread(LPVOID p);
          BOOL CThreadSample2Dlg::OnInitDialog()
          {
              CDialogEx::OnInitDialog();
              // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
              //  Framework は、この設定を自動的に行います。
              SetIcon(m_hIcon, TRUE);            // 大きいアイコンの設定
              SetIcon(m_hIcon, FALSE);        // 小さいアイコンの設定
              //エディットボックスの初期表示
              m_EdtCount.SetWindowTextW(L"0");
              m_EdtThread.SetWindowTextW(L"0");
              return TRUE;
          }
          /*************************************************
          関数名 OnBnClickedButton1
          機能   セマフォで同期 ボタン押下イベント
          *************************************************/

          void CThreadSample2Dlg::OnBnClickedButton1()
          {
              MSG msg;
              count = 0;
              threadno = 0;
              //複数スレッド(5スレッド)起動
              for (int i = 0; i < 5; i++) {
                  //スレッド番号(IDC_EDIT2に表示する)
                  threadno = (i+1);
                  TRACE(L"スレッド %d 起動¥n",threadno);
                  AfxBeginThread(CountUpThread, this, 0, 0, NULL);
                  while (PeekMessage(&msg, this->GetSafeHwnd(), 0, 0, PM_REMOVE)) {
                      TranslateMessage(&msg);
                      DispatchMessage(&msg);
                  }
                  Sleep(300);
              }
          }
          /*************************************************
          関数名 CountUpThread
          機能   ダイアログの変数をカウントアップして表示
          *************************************************/

          UINT __cdecl CountUpThread(LPVOID p) {
             
              CThreadSample2Dlg* pDlg = (CThreadSample2Dlg*)p;
              CString cs;
              MSG msg;
              CSingleLock singlelock(&(pDlg->m_cSmp));
              //スレッド番号を更新
              cs.Format(L"%d", pDlg->threadno);
              pDlg->m_EdtThread.SetWindowTextW(cs);
              //1スレッドで100カウントアップする
              for(int i=0;i<100;i++){
                 
                  //複数スレッドからcountにアクセスする際に、いずれか1スレッドからしか
                  //使用できないように排他制御する
                  //CSingleLockについてはDeveloperNetWork参照

                  singlelock.Lock();
                  pDlg->count++;
                  singlelock.Unlock();
                  //ダイアログのエディットボックスに表示
                  cs.Format(L"%d", pDlg->count);
                  pDlg->m_EdtCount.SetWindowTextW(cs);
                  while (PeekMessage(&msg, pDlg->GetSafeHwnd(), 0, 0, PM_REMOVE)) {
                      TranslateMessage(&msg);
                      DispatchMessage(&msg);
                  }
                  TRACE(L"count = " + cs + L"¥n");
                  Sleep(100);
              }
              return 0;
          }
           

          よろしければポチッと押してください

          プログラマー ブログランキングへ

           


          【VC++】簡単なマルチスレッド その1

          0

            <機能>

            (1)AfxBeginThreadを使用したマルチスレッドサンプルです

            (2)マルチスレッドでカウントアップ処理を行います

            (3)バックグラウンドプログラムの中断、再開ができます

             中断:ResumeThread

             再開:SuspendThread

            (4)バックグラウンド処理が終了を通知します

            (5)ダイアログは終了通知を受け取り終了処理をします

             

            <イメージ>

            スレッド開始 ボタン押下によりカウントアップを開始

            スレッド開始イメージ,AfxBeginThread

            中断 ボタン押下により中断します(中断→再開に変更)

            中断ボタンを再開ボタンに変更,AfxBeginThread

            処理が終了したらユーザ定義メッセージで通知します

            終了メッセージ,AfxBeginThread

             

            <動作検証&開発環境>
            Visual Studio Community 2017

             

            <使い方>

            1.ダイアログベースでThreadSampleプロジェクトを作成

            2.エディットボックスとボタンを配置

            IDC_EDIT : ReadOnly=TRUE

            3.コントロール変数を追加

            IDC_EDIT : m_EdtCount(種類EDIT/カテゴリControl)

            IDC_BTNST : m_BtnStart(種類BUTTON)

            IDC_BTNSTOP : m_BtnStop(種類BUTTON)

            IDOK : m_BtnOk(種類BUTTON)

            4.終了通知イベントハンドラ追加

            カスタムWindowsメッセージ : WM_MYMSG

            メッセージハンドラ名 : OnMyMsg

            5.ソースを追加

             

            ThreadSampleDlg.h

             

            class CThreadSampleDlg : public CDialogEx
            {

              //〜〜省略〜〜

            public:
                afx_msg void OnBnClickedOk();
                int count;
                CButton m_BtnStart;
                CButton m_BtnStop;
                CButton m_BtnOk;
                afx_msg void OnBnClickedBtnst();
                afx_msg void OnBnClickedBtnstop();
                CEdit m_EdtCount;
                CWinThread* mythread;
            protected:
                afx_msg LRESULT OnMyMsg(WPARAM wParam, LPARAM lParam);
            };

             

            ThreadSampleDlg.cpp

            //プロトタイプ宣言
            UINT __cdecl CountUpThread(LPVOID p);
            //ユーザ定義メッセージ
            #define WM_MYMSG (WM_USER + 100)
            CThreadSampleDlg::CThreadSampleDlg(CWnd* pParent /*=NULL*/)
                : CDialogEx(IDD_THREADSAMPLE_DIALOG, pParent)
            {
                m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
            }
            void CThreadSampleDlg::DoDataExchange(CDataExchange* pDX)
            {
                CDialogEx::DoDataExchange(pDX);
                DDX_Control(pDX, IDC_BTNST, m_BtnStart);
                DDX_Control(pDX, IDC_BTNSTOP, m_BtnStop);
                DDX_Control(pDX, IDOK, m_BtnOk);
                DDX_Control(pDX, IDC_EDIT, m_EdtCount);
            }
            BEGIN_MESSAGE_MAP(CThreadSampleDlg, CDialogEx)
                ON_WM_SYSCOMMAND()
                ON_WM_PAINT()
                ON_WM_QUERYDRAGICON()
                ON_BN_CLICKED(IDOK, &CThreadSampleDlg::OnBnClickedOk)
                ON_BN_CLICKED(IDC_BTNST, &CThreadSampleDlg::OnBnClickedBtnst)
                ON_BN_CLICKED(IDC_BTNSTOP, &CThreadSampleDlg::OnBnClickedBtnstop)
                ON_MESSAGE(WM_MYMSG, &CThreadSampleDlg::OnMyMsg)
            END_MESSAGE_MAP()

            // CThreadSampleDlg メッセージ ハンドラー
            BOOL CThreadSampleDlg::OnInitDialog()
            {
                CDialogEx::OnInitDialog();
                // "バージョン情報..." メニューをシステム メニューに追加します。
                // IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
                ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
                ASSERT(IDM_ABOUTBOX < 0xF000);
                CMenu* pSysMenu = GetSystemMenu(FALSE);
                if (pSysMenu != NULL)
                {
                    BOOL bNameValid;
                    CString strAboutMenu;
                    bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
                    ASSERT(bNameValid);
                    if (!strAboutMenu.IsEmpty())
                    {
                        pSysMenu->AppendMenu(MF_SEPARATOR);
                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                    }
                    //バツボタン(「×」ボタン)を無効にする
                    pSysMenu->EnableMenuItem(SC_CLOSE, MF_GRAYED);
                }
                // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
                //  Framework は、この設定を自動的に行います。
                SetIcon(m_hIcon, TRUE);            // 大きいアイコンの設定
                SetIcon(m_hIcon, FALSE);        // 小さいアイコンの設定
                //ボタンの初期状態
                m_BtnStart.EnableWindow(TRUE);
                m_BtnStop.EnableWindow(FALSE);
                m_BtnOk.EnableWindow(TRUE);
                m_BtnStop.SetWindowTextW(L"中 断");
                m_EdtCount.SetWindowTextW(L"0");
                return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
            }
            /*************************************************
            関数名 OnBnClickedOk
            機能   閉じる ボタン押下イベント
            *************************************************/

            void CThreadSampleDlg::OnBnClickedOk()
            {
                CDialogEx::OnOK();
            }
            /*************************************************
            関数名 OnBnClickedBtnst
            機能   スレッド開始 ボタン押下イベント
            *************************************************/

            void CThreadSampleDlg::OnBnClickedBtnst()
            {
                DWORD dwExitCode;
                MSG msg;
                //ボタンの状態をセット(中断のみ活性化)
                m_BtnStart.EnableWindow(FALSE);
                m_BtnStop.EnableWindow(TRUE);
                m_BtnOk.EnableWindow(FALSE);
                //カウントを初期化
                count = 0;
                //新しいスレッドを作成する
                //AfxBeginThreadについてはDeveloper Network参照
                mythread = AfxBeginThread(CountUpThread, this,0,0,NULL);
              
            }
            /*************************************************
            関数名 OnBnClickedBtnstop
            機能   中断 ボタン押下イベント
            *************************************************/

            void CThreadSampleDlg::OnBnClickedBtnstop()
            {
                CString cs;
                DWORD dwExitCode;
                //ボタンの状態をセット(中断のみ活性化)
                m_BtnStart.EnableWindow(FALSE);
                m_BtnStop.EnableWindow(TRUE);
                m_BtnOk.EnableWindow(FALSE);
                //ボタンのキャプションを取得
                m_BtnStop.GetWindowTextW(cs);
                if (cs == L"中 断") {
                    m_BtnStop.SetWindowTextW(L"再 開");
                    //スレッドを再開
                    if (GetExitCodeThread(mythread->m_hThread, &dwExitCode)) {
                        if (dwExitCode == STILL_ACTIVE) {
                            mythread->SuspendThread();
                        }
                    }
                }
                else {
                    m_BtnStop.SetWindowTextW(L"中 断");
                    //スレッドを中断
                    if (GetExitCodeThread(mythread->m_hThread, &dwExitCode)) {
                        if (dwExitCode == STILL_ACTIVE) {
                            mythread->ResumeThread();
                        }
                    }
                }
            }
            /*************************************************
            関数名 CountUpThread
            機能   ダイアログの変数をカウントアップして表示
            *************************************************/

            UINT __cdecl CountUpThread(LPVOID p) {
                CThreadSampleDlg* pDlg = (CThreadSampleDlg*)p;
                CString cs;
                while(1){
                    //100までカウントアップ
                    pDlg->count++;
                    if (pDlg->count > 100) break;
                    //ダイアログのエディットボックスに表示
                    cs.Format(L"%d",pDlg->count);
                    pDlg->m_EdtCount.SetWindowTextW(cs);
                    Sleep(100);
                }
               
                ::SendMessage(pDlg->m_hWnd, WM_MYMSG, 0, 0);
                return 0;
            }
            /*************************************************
            関数名 OnMyMsg
            機能   ユーザ定義メッセージのイベントハンドラ
            *************************************************/

            afx_msg LRESULT CThreadSampleDlg::OnMyMsg(WPARAM wParam, LPARAM lParam)
            {
                AfxMessageBox(L"スレッドが終了しました", MB_ICONINFORMATION);
                //処理終了
                m_BtnStart.EnableWindow(TRUE);
                m_BtnStop.EnableWindow(FALSE);
                m_BtnOk.EnableWindow(TRUE);
               
                return 0;
            }

            よろしければポチッと押してください

            プログラマー ブログランキングへ

             



            << | 2/6PAGES | >>

            calendar

            S M T W T F S
            1234567
            891011121314
            15161718192021
            22232425262728
            293031    
            << July 2018 >>

            profile

            others

            mobile

            qrcode         スマホ表示に戻す