【VC++】エディットボックスに半角英数のみ入力できるようにする

0

    <機能>

    (1)入力は半角英数のみ、文字数の上限チェックをクラスで実装する

    (2)OnEnChangeで半角英数チェックを行う

    (3)OnKeyDownで入力文字数の上限チェックを行う

    (4)入力制限クラスを複数のエディットボックスに適用する

     

    <実行イメージ>

    半角英数チェックと文字数の上限チェックを行う

    VisualStudio,MFC,VC++,半角英数,入力チェック,クラス,
     

    <動作検証&開発環境>

    Visual Studio Community 2017

     

    <使い方>

    1.ダイアログベースでMFCApplication1プロジェクトを作成します

    2.クラスウィザードでMFCクラスを追加します

    VisualStudio,MFC,VC++,クラスウィザード,
     

    基底クラスに「CEdit」を選択

    クラス名を「CEditTest」とします

    VisualStudio,MFC,VC++,クラスウィザード,クラス追加,
     

    3.クラスウィザードでCEditTestクラスに下記イベントを追加します

    OnEnChange : このイベントで半角英数チェックを行います

    OnKeyDown : このイベントで上限文字数チェックを行います

    VisualStudio,MFC,VC++,イベント,OnEnChange,OnKeyDown,
     

    4.IDD_MFCAPPLICATION1_DIALOGにエディットボックスを2つ追加します

    VisualStudio,MFC,VC++,Edit,
     

    5.追加したエディットボックスにそれぞれメンバ変数を追加します

    ・コントロール変数にチェック

    ・カテゴリ:Control

    ・変数の種類:CEditTest(CEditTestクラスの変数とする)

    ・変数名はそれぞれm_Edit1 、 m_Edit2 とします

     

    6.ソースを追加してください

     

    CEditTest.h

    class CEditTest : public CEdit
    {
        DECLARE_DYNAMIC(CEditTest)

    public:
        CEditTest();
        virtual ~CEditTest();

    protected:
        DECLARE_MESSAGE_MAP()
    public:
        afx_msg void OnEnChange();
        afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    };


    CEditTest.cpp


    BEGIN_MESSAGE_MAP(CEditTest, CEdit)
        ON_CONTROL_REFLECT(EN_CHANGE, &CEditTest::OnEnChange)
        ON_WM_KEYDOWN()
    END_MESSAGE_MAP()


    // CEditTest メッセージ ハンドラー


    /***********************************************************
    OnEnChange
    エディットコントロールの内容を変更したイベントハンドラ
    半角英数以外の入力があった場合は文字を削除する
    ***********************************************************/

    void CEditTest::OnEnChange()
    {
        CString cs;
        this->GetWindowText(cs);


        //数値チェックを行う
        CString csChk = cs.SpanIncluding(_T("abcdefghujklmnopqrstuvwxyz ¥
                                            ABCDEFGHIJKLMNOPQRSTUVWXYZ ¥
                                            0123456789"));
        //半角英数以外が混ざっていたら取り除いて設定する
        if (csChk != cs) {
            TRACE(L"<<Error>> 半角英数以外が混ざっていました [%s]¥r¥n", cs);
            //半角英数以外の文字を取り除く
            int ichi = csChk.GetLength();
            cs.Replace(cs.Mid(ichi,1),L"");
            this->SetWindowText(cs);
        }
    }


    /***********************************************************
    OnKeyDown
    システムキー以外のキーが押下されたイベントハンドラ
    入力文字数が入力条件を超えていないかチェック
    ***********************************************************/

    void CEditTest::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
        CString cs;
        //入力上限バイト数を取得
        int iLimit = this->GetLimitText();
        //入力済み文字列を取得
        this->GetWindowText(cs);
        TRACE(L"text=[%s] limit/nowlength=%d/%d¥r¥n",cs,iLimit,cs.GetLength());

        //既に入力上限に達しているときは何もしない
        if (cs.GetLength() == iLimit) return;

        CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
    }


    MFCApplication1Dlg.h


    #pragma once
    #include "CEditTest.h"




    class CMFCApplication1Dlg : public CDialog
    {
        // 〜〜省略〜〜
    private:
        CEditTest m_Edit1;
        CEditTest m_Edit2;
    };


    MFCApplication1Dlg.cpp


    BOOL CMFCApplication1Dlg::OnInitDialog()
    {
        CDialog::OnInitDialog();

        // 〜〜省略〜〜


        // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
        //  Framework は、この設定を自動的に行います。
        SetIcon(m_hIcon, TRUE);         // 大きいアイコンの設定
        SetIcon(m_hIcon, FALSE);        // 小さいアイコンの設定


        //リミットを設定
        m_Edit1.SetLimitText(10);
        m_Edit2.SetLimitText(5);


        return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
    }


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

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



    【VC++】メールスロットで単方向プロセス間通信を行う

    0

      <機能>

      (1)メールスロットクライアントとサーバを作成します

      (2)メールスロットを使って2つのexe間でプロセス間通信を行います

      (3)クライアントは[送信]ボタン押下によりメッセージを送付します

      (4)サーバは受信メッセージをリストボックスに表示します

      (5)クライアント起動時にサーバも起動します

       (サーバからクライアントの起動ななし)

       

      <実行イメージ>

      上の実行ファイルはメールスロットクライアント(MFCApplication1)

      下の実行ファイルはメールすろっどサーバ(MFCApplication2)

      MFC,VisualStudio,MailSlot,実行サンプル,
       

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

       

      <使い方>

      1.MFCApplication1プロジェクトを作成します

      2.MFCApplication1ソリューションにMFCApplication2プロジェクトを追加します

       (どちらもダイアログベースです)

       

      サンプルのソリューション構成

      MFCApplication1(ソリューションフォルダ)

       Debug

       MFCApplication1(プロジェクトフォルダ)

       MFCApplication2(プロジェクトフォルダ)

       Release

       MFCApplication1.sln

       

      3.コントロールを追加

      MFCApplication1

      MFC,VisualStudio,MailSlot,送信,
       

      MFCApplication2

      MFC,VisualStudio,MailSlot,受信,
       

      4.メンバ変数を追加

      MFCApplication1

       IDC_EDIT1:

      MFC,VisualStudio,MailSlot,送信,メンバ変数追加,クラスウィザード,
       

      MFCApplication2

       IDC_LIST1:

      MFC,VisualStudio,MailSlot,受信,メンバ変数追加,クラスウィザード,
       

      5.MFCApplication2にイベントを追加

       WM_TIMER(タイマーイベントでメッセージを受信)

       WM_DESTROY(画面終了イベントでメールスロットとタイマー停止)

      MFC,VisualStudio,MailSlot,受信,イベント追加,クラスウィザード,
       

      5.ソースを追加

       

      MFCApplication1(クライアント「送信」側アプリ)

       

      MFCApplication1Dlg.h

       

      class CMFCApplication1Dlg : public CDialog
      {
      //〜省略〜
      // 実装
      protected:
          HICON m_hIcon;
          // 生成された、メッセージ割り当て関数
          virtual BOOL OnInitDialog();
          afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
          afx_msg void OnPaint();
          afx_msg HCURSOR OnQueryDragIcon();
          DECLARE_MESSAGE_MAP()
      private:
          CString m_sendEdt;
          HANDLE m_mailSlot;
      public:
          afx_msg void OnBnClickedButton1();
      };
      MFCApplication1Dlg.cpp
      BOOL CMFCApplication1Dlg::OnInitDialog()
      {
          //〜省略〜〜
          //受信側(MFCApplication2.exe)も一緒に起動する
          //※本サンプルでは受信側と送信側が同一フォルダに出力されているものとしますが実行環境に合わせて修正してください

          TCHAR buf[2048];
          ZeroMemory(&buf, sizeof(buf));
          GetModuleFileName(NULL, buf, sizeof(buf));
          size_t ichi = wcslen(buf) - wcslen(L"MFCApplication1.exe");
          //送信側(MFCApplication1.exe)実行ファイル名を受信側(MFCApplication2.exe)に置換
          wmemcpy_s(&buf[ichi],wcslen(buf), L"MFCApplication2.exe", wcslen(L"MFCApplication2.exe")*2);
          //受信側(MFCApplication2.exe)を起動
          ShellExecute(NULL, L"open", buf, NULL, NULL, SW_HIDE);
          //エディットボックスを初期化
          m_sendEdt = L"";
          UpdateData(FALSE);
          return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
      }
      /*************************************************
      関数名 OnBnClickedButton1
      機能   送信ボタン押下イベント
      *************************************************/

      void CMFCApplication1Dlg::OnBnClickedButton1()
      {
          CString csError;
          TCHAR cName[256];
          ZeroMemory(&cName,sizeof(cName));
          //エディットボックスの入力値を取得
          UpdateData(TRUE);
          m_sendEdt = m_sendEdt.Trim();
          //メッセージが未入力ならエラーとする
          if (m_sendEdt.IsEmpty())
          {
              AfxMessageBox(L"送信文字列を入力してください",MB_ICONERROR);
              return;
          }
          //コンピュータ名を取得
          //※本サンプルでは同一コンピュータに送信する

          DWORD wksize = sizeof(cName);
          if (!GetComputerName(cName, &wksize))
          {
              AfxMessageBox(L"コンピューター名の取得に失敗しました", MB_ICONERROR);
              return;
          }
          //メールスロットを作成
          //メールスロットの名前は ¥¥mailslot¥¥MailSlot とする

          //詳細はMSDN参照
          CString csSlot;
          csSlot.Format(L"¥¥¥¥%s¥¥mailslot¥¥MailSlot", cName);
          HANDLE hSlot = CreateFile(csSlot, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ,
                                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
          if (hSlot == INVALID_HANDLE_VALUE)
          {
              csError.Format(L"MailSlotの作成に失敗しました(ErrorCode=%d)¥r¥n%s",GetLastError(),csSlot);
              AfxMessageBox(csError, MB_ICONERROR);
              return;
          }
          //メッセージの送信
          LPTSTR cMsg = new TCHAR[2048];
          DWORD dwSize;
          DWORD dwWrite;
          BOOL bResult;
          //dwSize = wcslen(cMsg);
          dwSize = wsprintf(cMsg, L"%s", m_sendEdt);
          bResult = WriteFile(hSlot, cMsg, dwSize * 2, &dwWrite, NULL);
          if (!bResult) {
              csError.Format(L"MailSlotの送信に失敗しました(ErrorCode=%d)¥r¥n%s", GetLastError(), csSlot);
              AfxMessageBox(csError, MB_ICONERROR);
          }
          CloseHandle(hSlot);
          delete cMsg;
      }

       

      MFCApplication2(サーバ「受信」側アプリ)

       

      MFCApplication2Dlg.h
      class CMFCApplication2Dlg : public CDialog
      {
      //〜省略〜〜
      // 実装
      protected:
          HICON m_hIcon;
          // 生成された、メッセージ割り当て関数
          virtual BOOL OnInitDialog();
          afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
          afx_msg void OnPaint();
          afx_msg HCURSOR OnQueryDragIcon();
          DECLARE_MESSAGE_MAP()
      private:
          HANDLE m_Slot;
      public:
          afx_msg void OnTimer(UINT_PTR nIDEvent);
          afx_msg void OnDestroy();
      private:
          CListBox m_recvList;
      };
      MFCApplication2Dlg.cpp
      BOOL CMFCApplication2Dlg::OnInitDialog()
      {
          CDialog::OnInitDialog();
         
          //〜省略〜〜
         
          //メールスロットを作成
          //メールスロットの名前は ¥¥mailslot¥¥MailSlot とする
          //メッセージの最大長(バイト数):0(任意サイズ)
          //メッセージ読み取りタイムアウト値(ms)
          //詳細はMSDN参照

          m_Slot = CreateMailslot(L"¥¥¥¥.¥¥mailslot¥¥MailSlot", 0, 1000, NULL);
          if (m_Slot == INVALID_HANDLE_VALUE)
          {
              CString csError;
              csError.Format(L"メールスロット作成に失敗しました(ErrorCode=%d)", GetLastError());
              AfxMessageBox(csError, MB_ICONERROR);
              return FALSE;
          }
          //タイマースタート
          //1000(ms)ごとにチェック
          //コールバック関数なし

          SetTimer(DTIMER_ID, 1000, NULL);
          return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
      }
      /*************************************************
      関数名 OnTimer
      機能   タイマーイベントで受信をチェック
      *************************************************/

      void CMFCApplication2Dlg::OnTimer(UINT_PTR nIDEvent)
      {
          TCHAR cMsg[2048];
          DWORD dwRead;
          BOOL bResult;
          CString csMsg;
         
          //タイマー停止
          KillTimer(DTIMER_ID);
          //メッセージがあれば処理する
          MSG msg;
          while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
          }
         
          //メッセージの読み取り
          //詳細はMSDN参照

          ZeroMemory(&cMsg, sizeof(cMsg));
          bResult = ReadFile(m_Slot, cMsg, sizeof(cMsg), &dwRead, NULL);
          if(bResult)
          {
              //リストボックスに表示
              CTime ct;
              ct = CTime::GetCurrentTime();
              csMsg.Format(L"%04d/%02d/%02d %02d:%02d:%02d : %s", ct.GetYear(), ct.GetMonth(),
                  ct.GetDay(), ct.GetHour(), ct.GetMinute(), ct.GetSecond(), cMsg);
              m_recvList.InsertString(-1, csMsg);
              UpdateData(FALSE);
          }else
          {
              LRESULT lrlt = GetLastError();
              if ((lrlt == ERROR_SEM_TIMEOUT) || (lrlt == ERROR_ACCESS_DENIED)) {
                  //メッセージがタイムアウトのときエラーを出さない
                  //別のエラーが出るようならエラーコードを追加する

              }
              else {
                  csMsg.Format(L"MailSlotのメッセージ読み取りに失敗しました(ErrorCode=%d)", lrlt);
                  AfxMessageBox(csMsg, MB_ICONERROR);
                  SetTimer(DTIMER_ID, 1000, NULL);
              }
          }
          //タイマー起動
          SetTimer(DTIMER_ID, 1000, NULL);
          CDialog::OnTimer(nIDEvent);
      }
      /*************************************************
      関数名 OnDestroy
      機能   アプリケーションの終了処理
      *************************************************/

      void CMFCApplication2Dlg::OnDestroy()
      {
          CDialog::OnDestroy();
          //タイマー停止
          KillTimer(DTIMER_ID);
          //メールスロットを閉じる
          if (m_Slot != INVALID_HANDLE_VALUE)
          {
              CloseHandle(m_Slot);
          }
      }
       

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

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

       

       


      【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);
            }
             

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

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

             



            | 1/5PAGES | >>

            calendar

            S M T W T F S
            1234567
            891011121314
            15161718192021
            22232425262728
            2930     
            << April 2018 >>

            profile

            others

            mobile

            qrcode         スマホ表示に戻す