728x90
300x250
[C#](OpenCVSharp 2.4.10) - 사진 출력

 

OpenCVSharp 2.4.10과 C#을 활용하여 사진을 출력하는 방법을 소개합니다.

(Introducing how to print photos using OpenCVSharp 2.4.10 and Visual C#.)

 

Nuget으로 "OpenCVSharp-AnyCPU 2.4.10"은 설치했다고 가정하고 진행합니다.

(Assume that you have installed "OpenCVSharp-AnyCPU 2.4.10" with Nuget.)

 


1. 로고 내려받기(Download the logo)

 

예제 그림으로 OpenCV 공식사이트에서 로고를 내려받습니다.

(Download the logo from the OpenCV official site as an example.)

 

https://opencv.org

 


2. 사용자 인터페이스 설계하기(Design the User Interface)

 

pictureBoxlpl1은 'SizeMode = StretchImage'로 해줍니다.

pictureBoxlpl1은 Size를 640 x 480으로 해줍니다.

(pictureBoxlpl1 is set to 'SizeMode = StretchImage'.)

(pictureBoxlpl1 sets the Size to 640 x 480.)

 

 

Form1은 Size를 800 x 600으로 해줍니다.

(Form1 sets the size to 800 x 600.)

 

 

아래 그림은 사용자 인터페이스를 임의로 그린 것입니다.

(The figure below is an arbitrary drawing of the user interface.)

 

 

Form1의 Load를 더블클릭해서 소스코드 작성할 수 있는 상태로 만들어줍니다.

 

 


3. 소스코드(Source Code)

 

소스코드입니다.(Source code.)

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;


namespace csharpImageLoad
{

    public partial class Form1 : Form
    {
        IplImage ipl;


        public Form1()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            ipl = new IplImage("opencv-logo-1.png", LoadMode.AnyColor);
            pictureBoxIpl1.ImageIpl = ipl;
           
        }

    }

}

 

 


4. 시연(Demonstrate)

 

시연입니다.

그림의 원본은 훨씬 화려하다는 것을 알 수 있습니다.

(Demonstration.)

(Source of the picture can be seen that much glamor.)

 

 

 


5. 참고자료(Reference)

 

 

반응형
728x90
300x250
[MFC] 윈도우 프로그래밍 기초 - List Control

 

이번 글은 직접 List Control을 구현해보는 것이 기본 목표입니다.

 

개념은 기본 멤버함수 몇 개 소개하는 것으로 시작하겠습니다.

 

1. CListCtrl 클래스의 멤버함수

 

 * InsertColumn

 

 int InsertColumn ( int nCol,

                           LPCTSTR lpszColumnHeading,

                           int nFormat = LVCFMT_LEFT,

                           int nWidth = -1,

                           int nSubItem = -1 );

 

-> nCol : 컬럼 헤더의 인덱스 값

-> lpszColumnHeading : 컬럼 헤더에 표시할 문자열

-> nFormat : 컬럼 헤더에 표시할 문자열의 정렬방식을 지정하며, 다음의 값들을 지정하여 사용가능.

-> Return 값 : 컬럼 추가에 성공하면 컬럼의 인덱스를 반환하며, 실패하면 -1을 반환한다.

 

 포멧 값

 정렬 방식

 LVCFMT_RIGHT

 오른쪽 정렬

 LVCFMT_LEFT

 왼쪽 정렬

 LVCFMT_CENTER

 중앙 정렬

 

-> nWidth : 컬럼 헤더의 너비

-> nSubItem : 연관된 하위 항목의 인덱스

-> Return 값 : 컬럼 추가에 성공하면 컬럼의 인덱스를 반환하며, 실패하면 -1을 반환한다.

 

 * DeleteColumn

 BOOL DeleteColumn ( int nCol ) ;

 

 -> nCol : 삭제하고자 하는 컬럼의 인덱스

 -> Return 값 : 삭제에 실패하면 0 (FALSE)을, 성공하면 1 (TRUE)을 반환한다.

 * InsertItem

 int InsertItem ( const LVITEM* pItem ) ;

 

-> pItem : 리스트 컨트롤에 등록할 LVITEM 구조체 포인터

-> Return 값 : 성공 시 추가된 아이템의 인덱스, 실패 시 -1

 * SetItemText

 BOOL SetItemText ( int nItem, int nSubItem, LPCTSTR lpszText ) ;

 

-> nItem : 아이템 인덱스

-> nSubItem : 서브 아이템 인덱스

-> lpszText : 출력할 텍스트 변수의 포인터

-> Return 값 : 실패시 0(FALSE), 성공시 1(TRUE) 반환 

 * GetItemText

 CString GetItemText ( int nItem, int nSubItem ) const

 

-> nItem : 아이템 인덱스

-> nSubItem : 서브 아이템 인덱스

-> Return 값 : 지정한 아이템 또는 서브 아이템의 문자열

 * DeleteItem

 BOOL DeleteItem ( int nItem );

 

-> nItem : 아이템 인덱스

-> Return 값 : 성공시 TRUE(1), 실패시 FALSE

 * DeleteAllItems

 BOOL DeleteAllItems( );

 

-> Return 값 : 성공시 TRUE, 실패시 FALSE

 

2. 결과물

 

 

 

 

3. 레이아웃

 

List Control에 변수를 만들어 줍니다.

 

 컨트롤 이름

 범주(T)

 변수 이름(N)

 비고

 List Control

 Control

 m_ListView

 

 

 

 

ListControl 속성의 View를 Report로 바꿔줍니다.

 

 

4. 코드

 

 

 BOOL CListControlDlg::OnInitDialog(){

 

           (중략)

            // TODO: 여기에 추가 초기화 작업을 추가합니다.

           m_ListView.InsertColumn(0, _T("번호"), NULL, 50);
           m_ListView.InsertColumn(1, _T("이름"), NULL, 150);
           m_ListView.InsertColumn(2, _T("비고"), NULL, 50);

 

           // LVITEM - 삽입 데이터 보관 장소
           LVITEM firstitem = { 0 } ;  LVITEM seconditem = { 0 } ;


           firstitem.mask = LVIF_TEXT;
           firstitem.iItem = 0;

 

           seconditem.mask = LVIF_TEXT;
           seconditem.iItem = 0;

 

           // 데이터 삽입 - Firstitem
           m_ListView.InsertItem(&firstitem);

 

           // 데이터 값 넣기 - Firstitem
           m_ListView.SetItemText(0, 0, _T("1번"));
           m_ListView.SetItemText(0, 1, _T("도도1-1"));
           m_ListView.SetItemText(0, 2, _T("도도1-2"));

 

            // 데이터 삽입 - Seconditem
           m_ListView.InsertItem(&seconditem);
 
           // 데이터 값 넣기 - Seconditem
          m_ListView.SetItemText(0, 0, _T("2번"));
          m_ListView.SetItemText(0, 1, _T("도도2-1"));
          m_ListView.SetItemText(0, 2, _T("도도2-2"));

        

          UpdateData(FALSE);

 

          return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}

 dlg.cpp 파일 내 코드

 

 

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - 프로그래스 컨트롤

 

프로그래스 컨트롤은 아래와 같이 진행되고 있는 데이터의 상태를 보여주기 위해 사용하는 컨트롤입니다.

 

 

(윈도우 탐색기의 프로그래스 컨트롤)

 

프로그래스 컨트롤이 어떠한 원리로 사용되는지 소개하겠습니다.

 


1. 배경지식


1. CProgressCtrl 클래스


a) CProgressCtrl의
멤버 함수

 

 

 * GetPos( ) 

  int GetPos( ) ;

 

  -> Return 값 : 현재 Position 값

 

 

 * GetRange( )

 void GetRange( int & nLower, int & nUpper)

 

  ->

  nLower : 영역의 최저 값을 받을 int 형 변수

  nUpper : 영역의 최대 값을 받을 int 형 변수

 

 

 * SetBkColor

 COLORREF SetBkColor( COLORREF clrNew ) ; 

 

 ->

   clrNew : 프로그래스 컨트롤의 배경색으로 지정할 색상 값

   Return 값 : 변경하기 전의 배경색 색상 값 

 

 

 * SetPos

  int SetPos( int nPos );

 

 ->

   nPos : 프로그래스 바의 포지션을 변경할 값

   Return 값 : 변경하기 전의 프로그래스 바의 포지션 값

 

 

 * SetRange

  void SetRange( short nLower, short nUpper ) ;

 

  void SetRange32 ( int nLower, int nUpper ) ;

 

 ->

   nLower : 프로그래스 바의 최저 값 (색이 채워지지 않는 값)

   nUpper : 프로그래스 바의 최대 값 (색을 모두 채우는 값)

 

  최저값 : 0

  최대값 : 100까지

 

 


2. 결과물

 

오늘의 실습 주제 : 파일 복사 프로그래스로 측정해보기

 

 

 

 결과물

 

 

 버튼 - 원본파일) 찾아보기

 

버튼 - 복사 경로) 찾아보기

 

 

 버튼 - 파일 복사) 클릭시 결과

 

 

 곰돌이.mp3 복사된 것을 확인 할 수 있음.

 


3. 레이아웃 디자인

 

변수 설정할 부분만 설명해놨습니다.

버튼은 여러분이 이벤트 처리기로 하시면 됩니다. (이 부분은 여러분의 감각 믿습니다.)

 

 컨트롤

 캡션

 범주(T)

 변수 이름(N)

 택스트 컨트롤

 X

 Value

 m_original

 택스트 컨트롤 

 X

 Value 

 m_copydir

 프로그래스

 X

 Control

 m_progress

 


4. 소스코드

 

 // CProgressDlg.h : 헤더 파일
 //

 #pragma once
 #include "afxcmn.h"

 

 #define PROGRESSVALUE(a, b) (int)((double)( a * 100 ) / (double) b )

 

 // 이 부분은 메크로 함수로 PROGRESS 값을 반환하도록 했는데, 여러분이 함수형으로 구현하셔도 되고 상관없습니다.

 CProgressDlg.h

 

 

 
// 원본 파일
 void CCProgressDlg::OnBnClickedButton1()
 {
      TCHAR szFilter[] = _T("All Files (*.*)|*.*|");

      CFileDialog dlg(TRUE, _T("*"), _T("*.*"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilter);

 

      if (dlg.DoModal() == IDOK)
     {
            m_original = dlg.GetPathName();

            // 데이터 갱신
            UpdateData(FALSE);

     }
}

 원본 파일 찾기 - 구현 

 
// 복사 경로
void CCProgressDlg::OnBnClickedButton2()
{
       TCHAR szFilter[] = _T("All Files (*.*)|*.*|");

       CFileDialog dlg(FALSE, _T("*"), _T("*.*"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilter);

 

       if (dlg.DoModal() == IDOK)
       {
             m_copydir = dlg.GetPathName();

             // 데이터 갱신
             UpdateData(FALSE);

       }

 복사 경로 찾기 - 구현

 // 파일 복사 DWORD CALLBACK buksa( )

DWORD CALLBACK buksa(LARGE_INTEGER TotalFileSize,
 LARGE_INTEGER TotalBytesTransferred,
 LARGE_INTEGER StreamSize,
 LARGE_INTEGER StreamBytesTransferred,
 DWORD dwStreamNumber,
 DWORD dwCallbackReason,
 HANDLE hSourceFile,
 HANDLE hDestinationFile,
 LPVOID lpData)
{
         CCProgressDlg* pDlg = (CCProgressDlg*)lpData;

        

         int pos = PROGRESSVALUE( TotalBytesTransferred.QuadPart,
                      TotalBytesTransferred.QuadPart );

 

         // Pos 설정
         pDlg->m_progress.SetPos(pos);

 

         // 100 퍼센트 전송되지 않을 때
         if (pos < 100)
               return PROGRESS_CONTINUE;

        

         // 100 퍼센트 전송되었을 때
         MessageBox(NULL, _T("복사가 완료되었습니다. "), _T("확인"), MB_ICONINFORMATION + MB_OK);

 

         return PROGRESS_QUIET;

 이 부분 원형은 외우지 말 것 (파일 복사 Routine 때문에 구현)

 

   // 대상 파일 복사
  void CCProgressDlg::OnBnClickedButton3()
  {
         // 프로그래스 초기 설정
         m_progress.SetRange(0, 100);
         m_progress.SetPos(0);

       

         // 복사 진행
         CopyFileEx(m_original, m_copydir, buksa, this, NULL, COPY_FILE_FAIL_IF_EXISTS);
}

 대상 파일 복사

 

소스코드 : CProgress.zip

 

이번 글은 약간 어려울 수 있는데, 별거 없습니다.

특히나 DWORD CALLBACK buksa( ) 의 경우 WinBase.h 정의로 이동해서 그대로 가져다가 사용하면 저 원형 그대로 사용할 수 있습니다.

이번 글에서 의도한 것은 기본적인 부분은 프로그래스를 사용하실 수 있게 해드리는 것이고, 두 번째로 코드는 힘들게 외우지 말라는 것을

알려드리고 싶어서 아래의 자료와 함께 올려드렸습니다.

 

아래의 자료는 MSDN의 CopyFileEx와 CopyRoutine 원형의 설명이 담긴 자료입니다.

저 설명은 다 외우지 말고 여러분이 원하는 방법으로 변경할 때 참고하시면 됩니다.

 


5. 참고사항1) CopyFileEx

 


BOOL
WINAPI
CopyFileEx(
    _In_        LPCWSTR lpExistingFileName,
    _In_        LPCWSTR lpNewFileName,
    _In_opt_    LPPROGRESS_ROUTINE lpProgressRoutine,
    _In_opt_    LPVOID lpData,
    _When_(pbCancel != NULL, _Pre_satisfies_(*pbCancel == FALSE))
    _Inout_opt_ LPBOOL pbCancel,
    _In_        DWORD dwCopyFlags
);

 

 CopyFileEx 함수 원형

 

 

 파라메터

 설명

 lpExistingFileName

 원본 파일 지정

 lpNewFileName

 새로 복사할 위치 지정

 lpProgressRoutine

 파일 복사 콜백 함수(Routine 함수 지정)

 lpData

 부모 함수를 포인터로 전달할 것인지에 대한 판단

 (ex : this (자기 자신을 함수 포인터로 전달)

 dwCopyFlags

 복사 플래그 지정

 

* dwCopyFlags

 

dwCopyFlags [in]

Flags that specify how the file is to be copied. This parameter can be a combination of the following values.

 

Value Meaning
COPY_FILE_ALLOW_DECRYPTED_DESTINATION
0x00000008

An attempt to copy an encrypted file will succeed even if the destination copy cannot be encrypted.

COPY_FILE_COPY_SYMLINK
0x00000800

If the source file is a symbolic link, the destination file is also a symbolic link pointing to the same file that the source symbolic link is pointing to.

Windows Server 2003 and Windows XP:  This value is not supported.

COPY_FILE_FAIL_IF_EXISTS
0x00000001

The copy operation fails immediately if the target file already exists.

COPY_FILE_NO_BUFFERING
0x00001000

The copy operation is performed using unbuffered I/O, bypassing system I/O cache resources. Recommended for very large file transfers.

Windows Server 2003 and Windows XP:  This value is not supported.

COPY_FILE_OPEN_SOURCE_FOR_WRITE
0x00000004

The file is copied and the original file is opened for write access.

COPY_FILE_RESTARTABLE
0x00000002

Progress of the copy is tracked in the target file in case the copy fails. The failed copy can be restarted at a later time by specifying the same values for lpExistingFileName and lpNewFileName as those used in the call that failed. This can significantly slow down the copy operation as the new file may be flushed multiple times during the copy operation.

 

 


6. 참고사항2) CopyProgressRoutine

CopyProgressRoutine callback function

An application-defined callback function used with the CopyFileEx, MoveFileTransacted, and MoveFileWithProgress functions. It is called when a portion of a copy or move operation is completed. The LPPROGRESS_ROUTINE type defines a pointer to this callback function. CopyProgressRoutine is a placeholder for the application-defined function name.

Syntax

C++
DWORD CALLBACK CopyProgressRoutine(
  _In_      LARGE_INTEGER TotalFileSize,
  _In_      LARGE_INTEGER TotalBytesTransferred,
  _In_      LARGE_INTEGER StreamSize,
  _In_      LARGE_INTEGER StreamBytesTransferred,
  _In_      DWORD dwStreamNumber,
  _In_      DWORD dwCallbackReason,
  _In_      HANDLE hSourceFile,
  _In_      HANDLE hDestinationFile,
  _In_opt_  LPVOID lpData
);

typedef DWORD (WINAPI *LPPROGRESS_ROUTINE)(
    _In_      LARGE_INTEGER TotalFileSize,
    _In_      LARGE_INTEGER TotalBytesTransferred,
    _In_      LARGE_INTEGER StreamSize,
    _In_      LARGE_INTEGER StreamBytesTransferred,
    _In_      DWORD dwStreamNumber,
    _In_      DWORD dwCallbackReason,
    _In_      HANDLE hSourceFile,
    _In_      HANDLE hDestinationFile,
    _In_opt_  LPVOID lpData
);

Parameters

TotalFileSize [in]

The total size of the file, in bytes.

TotalBytesTransferred [in]

The total number of bytes transferred from the source file to the destination file since the copy operation began.

StreamSize [in]

The total size of the current file stream, in bytes.

StreamBytesTransferred [in]

The total number of bytes in the current stream that have been transferred from the source file to the destination file since the copy operation began.

dwStreamNumber [in]

A handle to the current stream. The first time CopyProgressRoutine is called, the stream number is 1.

dwCallbackReason [in]

The reason that CopyProgressRoutine was called. This parameter can be one of the following values.

 

Value Meaning
CALLBACK_CHUNK_FINISHED
0x00000000

Another part of the data file was copied.

CALLBACK_STREAM_SWITCH
0x00000001

Another stream was created and is about to be copied. This is the callback reason given when the callback routine is first invoked.

 

hSourceFile [in]

A handle to the source file.

hDestinationFile [in]

A handle to the destination file

lpData [in, optional]

Argument passed to CopyProgressRoutine by CopyFileEx, MoveFileTransacted, or MoveFileWithProgress.

Return value

The CopyProgressRoutine function should return one of the following values.

Return code/value Description
PROGRESS_CANCEL
1

Cancel the copy operation and delete the destination file.

PROGRESS_CONTINUE
0

Continue the copy operation.

PROGRESS_QUIET
3

Continue the copy operation, but stop invoking CopyProgressRoutine to report progress.

PROGRESS_STOP
2

Stop the copy operation. It can be restarted at a later time.

 

Remarks
An application can use this information to display a progress bar that shows the total number of bytes copied as a percent of the total file size.

Requirements

Minimum supported client

Windows XP [desktop apps only]

Minimum supported server

Windows Server 2003 [desktop apps only]

Header

WinBase.h (include Windows.h)

 


7. 참고자료(Reference) 

 

1. https://msdn.microsoft.com/en-us/library/windows/desktop/aa363852(v=vs.85).aspx, 접속일자 2015-03-31

2. https://msdn.microsoft.com/en-us/library/windows/desktop/aa363854(v=vs.85).aspx, 접속일자 2015-03-31

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - Edit Control(에디트 컨트롤) - 택스트상자

 

이번에 만들 건 Edit Control입니다.

여러분은 아마 지금쯤이면 어느 정도 짬좀 찼을 거 같습니다.

 

 

이번에 만들 건 텍스트 상자라고도 볼 수 있는 Edit Control 입니다.

 

 

이렇게 생긴거 하나 만들어 보겠습니다.

 


1. 결과물

 

 

(레이아웃)

 

 

말 안해도 자동으로 레이아웃 그리고 계셔야 합니다.

 

짬 찼으니깐요.

자동으로 못 그리면, 다시 이전 강의로 돌아가세요. 제발~(Please)

 

컨트롤 ID

Caption

범주(T)

변수 이름(N)

최대 문자 수

이벤트 처리기이름 

ReadOnly

IDC_STATIC

입력

 

 

 

 

 

IDC_STATIC

출력

 

 

 

 

 

IDC_EDIT1

 

Value

m_strName

5

 

 

IDC_EDIT2

 

Value

m_printName

5

 

 True

IDC_BUTTON1

입력해보기

 

 

 

OnBnClickedButton

 

 


2. 소스 코드 작성

  
void CExampleDlg::OnBnClickedButton1()
{
      UpdateData(TRUE);
      m_printName = m_strName;
       UpdateData(FALSE);
}

 

코드 내용 - 이벤트 버튼에 관한 코드 

 


3. 설명 - UpdateData에 대해서

 

Visual Basic이나 다른 프로그래밍 언어에선 UpdateData() 이딴거 안써도 솔직히 바로 바뀝니다.

MFC는 불편합니다.

 

실시간 변화를 할 수 없기에 인위적으로 변화를 하도록 제어하고 있습니다.

깊은 의미는 동시접근을 임의로 하지 못하도록 마치 신호등처럼 제어하고 있습니다.

 

 

 

 

운영체제론이라는 책에서 배울 수 있습니다.

교착상태를 예방하기 위해 이러한 원리를 적용한 것입니다.

 

정확한 의미는 우리하고 관련없으므로 생략합니다.

 

 


UpdateData의 함수 원형은 아래와 같습니다.

 

BOOL UpdateData(BOOL bSaveAndValidate = TRUE);

 

-> bSaveAndValidate의 상태는

BOOL 형태이니깐

 

TRUE

 

OR

 

FALSE

 

두 가지 밖에 안됩니다.

 

TRUE 상태에선 변경 작업을 허용합니다.

FALSE 상태에선 변경 작업을 끝냅니다.

 


동작해보면 잘 돌아갑니다. 참 쉽죠??

 

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - 대화 상자 실습

 

이번 글에서는 이전에 소개한 대화 상자 글을 바탕으로 실제 대화 상자를 구현하는 방법에 대해 소개하겠습니다.

 


1. 실습 주제) MFCModal 창 만들어 보기

 

 

 

  동작 전 결과

 

 동작 후 결과

 

 


1-1. BITMAP 리소스 추가

 

 

리소스 추가(A) 클릭

 

 

새로 만들기(N) 클릭 

->참고로 "가져오기" 하셔도 됩니다.

 

 

전 이렇게 그렸습니다.

 

 

이번에 그린 그림의 이름(ID)은 IDB_EARTH로 하겠습니다.

 

 


1-2. 컨트롤 박스 배치하기

 

 

 

 

 컨트롤 꾸며보기 - 이 부분은 여러분이 도구상자 탭을 이용하여 직접 하셔야 합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

컨트롤 

 ID

 Caption

 Image

Type

Dialog

IDD_MFCMODAL_DIALOG

 

 

 

Edit Box

IDC_INPUT_NAME

 

 

 

Edit Box 

IDC_INPUT_SCHOOL

 

 

 

Edit Box

IDC_INPUT_DEPT

 

 

 

Edit Box

IDC_INPUT_GRAD

 

 

 

Static

IDC_STATIC

이름

 

 

Static

IDC_STATIC 

학교

 

 

Static

IDC_STATIC

학과

 

 

Static

IDC_STATIC

학년

 

 

Picture Control

IDC_INPUT_IMAGE

 

 IDC_EARTH

 Bitmap

Edit Box

IDC_OUTPUT_NAME

 

 

 

Edit Box

IDC_OUTPUT_SCHOOL

 

 

 

Edit Box

IDC_OUTPUT_DEPT

 

 

 

Edit Box

IDC_OUTPUT_GRAD 

 

 

 

Picture Control

IDC_OUTPUT_IMAGE

 

 

 Bitmap

Static

IDC_STATIC

이름

 

 

Static 

IDC_STATIC 

학교

 

 

Static

IDC_STATIC

학과 

 

 

Static 

IDC_STATIC

학년

 

 

Group Box

IDC_STATIC

최종입력결과

 

 

Button

IDB_BTN_COMPLETE 

입력완료 

 

 

 

리소스를 이처럼 편집해주시기 바랍니다.

 


1-3 변수 추가

 

하나를 대상으로 변수 추가 방법을 소개해드리겠습니다.

나머지는 여러분들이 아래의 테이블을 참고하여 만들어주시기 바랍니다.

 

 

 

변수 추가(B) 클릭

 

 

 

 범주(T)를 Value로 변경

 

 

변수 형식 : CString,

변수 이름 : m_staticName

최대 문자수 : 20

 

마침을 클릭합니다.

 

변수 추가 후에 코드가 변동됩니다.

변동되는 코드는

MFCModalDlg.h와 MFCModalDlg.cpp입니다.

 

 

 

 MFCModalDlg.h

 

 

 MFCModalDlg.cpp의 DoDataExchange()

-> 여기에서 사용하는 역할을 간접적으로 학습하셨으면 합니다.

 

참고로 DDX와 DDV는

앞서 살펴보셨겠지만, 대화상자에서의 최대 문자 수와 같은 제약조건을 다루는 함수입니다.

 

 

이 예제에서 만들어야 할 멤버 변수 설정 값 테이블입니다.

첫 번째 예제를 통해 변수 하나는 만들었으므로 나머지에 대한 테이블을 소개하겠습니다.

 

 컨트롤 ID

변수 형식

범주

최대 문자 수

 IDC_INPUT_SCHOOL

CString m_staticSchool

Value

50

 IDC_INPUT_DEPT

CString m_staticDept

Value

20

 IDC_INPUT_GRAD

CString m_staticGrad

Value

5

 IDC_OUTPUT_NAME

CString m_strName

Value

20

 IDC_OUTPUT_SCHOOL

CString m_strSchool

Value

50

 IDC_OUTPUT_DEPT

CString m_strDept

Value

20

 IDC_OUTPUT_GRAD

CString m_strGrad

Value

5

 IDC_OUTPUT_IMAGE

CString m_strImage

Control

 

 


1-4. 이벤트 처리기 추가

 

입력완료 버튼에서 오른쪽 버튼을 클릭한 후 이벤트 처리기 추가(A)를 클릭합니다. 

 

 

 

기본값으로 두가 추가 및 편집을 클릭합니다.

 

 

OnBnClickedBtnComplete( )라는 함수가 생성됩니다.

 

MFCModalDlg.h와 MFCModalDlg.cpp의 파일이 영향을 받게 됩니다.

어떻게 코드가 생성되었는지 확인해보겠습니다. 

 

 

 

결과)

 afx_msg void OnBnClickedBtnComplete( )라는 함수가 추가되었습니다. 

 

 

 결과)

  MFCModalDlg.cpp의 void CMFCModalDlg::OnBnClickedBtnComplete( )라는 함수 구현부가 완성되었습니다.

 


1-5 기능 구현

 


{
         CBitmap MyImageView;

       

         UpdateData(TRUE);  // UpdateData(TRUE)함수를 통해 데이터가 전송됩니다.

         m_strName = m_staticName;
         m_strSchool = m_staticSchool;
         m_strDept = m_staticDept;
         m_strGrad = m_staticGrad;

 

         MyImageView.LoadBitmap(IDB_EARTH);

         m_staticImage.SetBitmap(MyImageView);

 

         UpdateData(FALSE);

 
}
 

 OnBnClickedBtnComplete( ) 구현

 


1-6. 동작해보기

 

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 기초 - 대화 상자 만들기

 

이번에는 윈도우 프로그래밍 기초로 "대화 상자 만들기"에 대해서 소개하고자 합니다.

 


1. 프로젝트 만들기

 

 

 

 새 프로젝트 -> 이름 : MFCModal, 확인 클릭

 

 

 대화 상자 기반에 체크한 후 마침을 누릅니다.

 

 

 Welcome to 대화상자 월드

 


2. 소스 코드 살펴보기

 

 

 


2-1. 응용 프로그램 클래스

 

앞전에 http://yyman.tistory.com/494 ([MFC] 윈도우 프로그래밍 기초 - 팝업메뉴 만들기(리소스의 이해))의 글에서는
SDI 기반으로 응용 프로그램을 작성했습니다.

 

SDI는 Single Document Interface의 약자로서 단일 Document를 의미합니다.

하지만, 이번에 살펴볼 대화상자는 SDI기반과는 다른 구조로 되어있음을 소개하고자 합니다.

 

SDI 기반에서는

 

CDocument, CView 

 

로 구성되어 있었습니다.

 

하지만, 대화상자에서는

CDialogi 클래스 대체되고, 공통 클래스는 CWinApp

 

로 구성됩니다.

 

MFCModal.cpp를 열어보면,

// MFCModal.cpp : 응용 프로그램에 대한 클래스 동작을 정의합니다.
//

#include "stdafx.h"
#include "MFCModal.h"
#include "MFCModalDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMFCModalApp

BEGIN_MESSAGE_MAP(CMFCModalApp, CWinApp)
     ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CMFCModalApp 생성

CMFCModalApp::CMFCModalApp()
{
          // 다시 시작 관리자 지원
         m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

         // TODO: 여기에 생성 코드를 추가합니다.
         // InitInstance에 모든 중요한 초기화 작업을 배치합니다.
}


// 유일한 CMFCModalApp 개체입니다.

CMFCModalApp theApp;


// CMFCModalApp 초기화

BOOL CMFCModalApp::InitInstance()
{
          // 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
          // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요합니다.
          // InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
          INITCOMMONCONTROLSEX InitCtrls;
          InitCtrls.dwSize = sizeof(InitCtrls);
          // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록
          // 이 항목을 설정하십시오.
          InitCtrls.dwICC = ICC_WIN95_CLASSES;
          InitCommonControlsEx(&InitCtrls);

          CWinApp::InitInstance();


          AfxEnableControlContainer();

          // 대화 상자에 셸 트리 뷰 또는
          // 셸 목록 뷰 컨트롤이 포함되어 있는 경우 셸 관리자를 만듭니다.
          CShellManager *pShellManager = new CShellManager;

          // MFC 컨트롤의 테마를 사용하기 위해 "Windows 원형" 비주얼 관리자 활성화
          CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

 

          SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램"));

          CMFCModalDlg dlg;
          m_pMainWnd = &dlg;
          INT_PTR nResponse = dlg.DoModal();
      

          if (nResponse == IDOK)
          {
             // TODO: 여기에 [확인]을 클릭하여 대화 상자가 없어질 때 처리할
            //  코드를 배치합니다.
          }
          else if (nResponse == IDCANCEL)
          {
                 // TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
                 //  코드를 배치합니다.
          }
          else if (nResponse == -1)
         {
               TRACE(traceAppMsg, 0, "경고: 대화 상자를 만들지 못했으므로 응용 프로그램이 예기치 않게 종료됩니다.\n");
               TRACE(traceAppMsg, 0, "경고: 대화 상자에서 MFC 컨트롤을 사용하는 경우 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS를 수행할 수 없습니다.\n");
         }

           // 위에서 만든 셸 관리자를 삭제합니다.
          if (pShellManager != NULL)
         {
             delete pShellManager;
         }

         // 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고  응용 프로그램을 끝낼 수 있도록 FALSE를
         // 반환합니다.
        return FALSE;
}

 

이처럼 코드가 구성되어 있습니다.

 


2-2) 대화 상자 클래스

 

MFCModelDlg.cpp 소개

 


// MFCModalDlg.cpp : 구현 파일
//

#include "stdafx.h"
#include "MFCModal.h"
#include "MFCModalDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.

class CAboutDlg : public CDialogEx
{
         public:
                  CAboutDlg();

                 // 대화 상자 데이터입니다.
                 enum { IDD = IDD_ABOUTBOX };

         protected:
                 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.

// 구현입니다.
         protected:
                 DECLARE_MESSAGE_MAP()
};

 

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{

 

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
          CDialogEx::DoDataExchange(pDX);
}

 

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMFCModalDlg 대화 상자

 

CMFCModalDlg::CMFCModalDlg(CWnd* pParent /*=NULL*/)
 : CDialogEx(CMFCModalDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

 

void CMFCModalDlg::DoDataExchange(CDataExchange* pDX)
{
           CDialogEx::DoDataExchange(pDX);
}

 

BEGIN_MESSAGE_MAP(CMFCModalDlg, CDialogEx)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()


// CMFCModalDlg 메시지 처리기

BOOL CMFCModalDlg::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);
                     }
            }

 

            // 이 대화 상자의 아이콘을 설정합니다.  응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
            //  프레임워크가 이 작업을 자동으로 수행합니다.

 

            SetIcon(m_hIcon, TRUE);   // 큰 아이콘을 설정합니다.
            SetIcon(m_hIcon, FALSE);  // 작은 아이콘을 설정합니다.

 

            // TODO: 여기에 추가 초기화 작업을 추가합니다.

            return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.


}

void CMFCModalDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialogEx::OnSysCommand(nID, lParam);
 }
}

// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
//  아래 코드가 필요합니다.  문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
//  프레임워크에서 이 작업을 자동으로 수행합니다.

void CMFCModalDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // 아이콘을 그립니다.
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialogEx::OnPaint();
 }
}

// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
//  이 함수를 호출합니다.
HCURSOR CMFCModalDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}

 

 

눈 여겨 봐야할 부분만 블록으로 칠해놨습니다.

DoDataExchange() 함수와 OnInitDialog() 함수는 대화상자에서 중요한 역할을 합니다.

실제로 다음 장 글에서 컨트롤 배치와 실습을 통해 변화를 관찰하면 될 것 같습니다.

반응형
728x90
300x250

[MFC] 윈도우 프로그래밍 - 대화 상자(Dialog)

 


1. Introduce

 

Dialog -> 영어시간에 많이 들어보셨을 겁니다.

 

 

Dialog Box는 응용 프로그램과 사용자의 의사소통을 하는 통로라고 설명할 수 있습니다.

 

 

 Figure 1) Visual Basic 6.0 (Visual Basic for Application으로 시연함)

 

대부분 Visual Studio의 C++ 모달 환경을 처음 접하게 되면, 프로그래밍을 접고 싶다는 생각을 종종할 수 있습니다.

왜냐하면, 초보자분들 입장에선 위에 그림과 같은 환경에서 개발하면 편하고 해볼만하다는 생각을 할 수 있습니다.

하지만, MFC는 조금 복잡합니다. 만져야 할 게 조금 있습니다. (코드 부분, 화면 부분, 컨트롤러 부분)

 

 

 

 Figure 2) 코드 환경 ( C++ MFC )

 

 

 

 

 Figure 3) 모달 영역

 

모달 영역은 모달 영역대로 분리되어 있습니다.

 


2. 큰 나무를 그려보면,

 

 

 

실제로는 별거 없습니다.

화면 작업이라는 영역은,

 

 

 

 리소스 뷰의 영역 -> Dialog

 

여러분이 만든 버튼의 이벤트 코드는?

 

 

 

 

 버튼 예시 - 실제 화면 캡처함

 이벤트 처리기 추가(A) 마법사

 

마법사를 이용하면, 자동 생성됩니다.

 

 

이벤트 마법사의 예 - 이미 추가된 이벤트 버튼이므로 '추가 및 편집'이 비활성화되어 있음.

 

 


3. 대화상자의 예를 소개합니다.

 

 

 

 

 

 Dialog의 예1) 인터넷 익스플로러 - 파일-> 열기

 Dialog의 예2) 실행 - Dialog

 

 

 

 

 Dialog의 예3) 파일 열기

 Dialog의 예4) 찾기 및 바꾸기

 

이렇게 많은 다이얼로그가 존재하는지 알았으면, 대화상자를 구현할 준비가 된 것입니다.

한번 일상 속에서 다이얼로그가 어떤게 존재하는지 탐구해보셨으면 합니다.

반응형
728x90
300x250

[PC 활용] (C++.NET MFC) Visual Studio 2013 버그 - error RC2108: expected numerical dialog constant

 

이번에는 오류에 대해서 해결하는 방법에 대해서 소개하고자 합니다.

 


1. 오류 출력

 

 

 

picture control을 이용하는 분들중에 Visual Studio 2013을 사용하시는 분들이라면 오류가 발생합니다.

 


2. 문의

error RC2108: expected numerical dialog constant

 

마이크로소프트에 익명의 유저가 "고객 문의 결과"를 한 글로 보입니다. 참고하면 도움될 것입니다.

https://connect.microsoft.com/VisualStudio/feedback/details/806403/bug-in-ressourceneditor

 


3. 결론

 

첫 번째로, 임시 조치 방법으로는 아래와 같이 수동으로 코드를 바꿀 수 있습니다.

 

변경 전 (오류 발생)

변경 후

 CONTROL IDB_BITMAP1,IDC_STATIC,2,2,89,82,NOT WS_GROUP

CONTROL IDB_BITMAP1, IDC_STATIC, "Static", SS_BITMAP, 2, 2, 89, 82, NOT WS_GROUP

 

두 번째로, Visual Studio 2013 Update 버전을 설치하면 됩니다.

주소 https://www.visualstudio.com/downloads/

 

 

반응형

+ Recent posts