Software/Programming2012. 8. 10. 22:28


1193120077_BmpTest001.rar

4개의 비트맵 파일을 불러와서 메모리비트맵에 저장한 다음

새로운 메모리비트맵에 4개의 비트맵을 차례로 출력 후 그림파일로 

저장하는 예제입니다...

소스폴더에 보시면 1.bmp부터 4.bmp까지 있는데

다른 비트맵파일로 바꾼뒤에 테스트 해보셔도 됩니다.

CMyImage클래스가 그림을 불러오고 저장하는 클래스니 확인하셔야 하구요

View클래스의 OnInitialUpdate함수에 그림파일을 불러오는 부분이 있으니

잘 해석해보시면 어떻게 해야할지 아실줄로 생각됩니다.

View클래스외에는 수정한게 없으니

CMyImage클래스와 View클래스만 보시면 될 것 같네요...

 

다운받으시려면 아래 다운로드에 마우스커서를 놓고

오른쪽 버튼을 누른 뒤 "다른 이름으로 대상 저장" 을 눌러 저장해 주세요...

아래 다운로드 소스는 제 Paran블로그에 올려두었습니다... (물론 비공개글입니다.)

Posted by 십자성군
Software/Programming2012. 8. 10. 22:10

제가 프로그램을 짜고있는데 커머파일은 되는데 실행할때 에러가 나서요ㅠㅠ

 

제 프로그램의 내용은 이미지 파일 두개를 연속으로 열고 그 후에 지정된 폴더에 있는 이미지 파일을 연속적으로 여는건데요

 

문제는 이미지 파일 두개를 연속으로 열때는 문제가 없는데 그 후에 지정된 폴더내에 있는 이미지 파일을 연속적으로 열려고 할때 에러가 난다는 겁니다. 에러의 내용은

 

 

 

이거구요ㅠㅠ

 

그림 맨위에 gray in light.bmp 파일이 첫번째로 open한 파일의 이름입니다.

 

이미지 파일 두개를 오픈하는 소스는 다음과 같구요

 

BOOL CWinColorDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
 if (!CDocument::OnOpenDocument(lpszPathName))
  return FALSE;
 //1번째 이미지 파일
 // TODO: Add your specialized creation code here
 CFile hFile;
 hFile.Open(lpszPathName,CFile::modeRead | CFile::typeBinary);
 hFile.Read(&dibHf,sizeof(BITMAPFILEHEADER)); // 파일 헤드를 읽음
 if(dibHf.bfType!=0x4D42)
 {
  AfxMessageBox("Not BMP file!!");
  return FALSE;
 } //이 파일이 BMP파일인지 검사. 0x4d42=='BM'
 hFile.Read(&dibHi,sizeof(BITMAPINFOHEADER)); //"영상정보의 Header"를 읽는다. 
 if(dibHi.biBitCount!=8 && dibHi.biBitCount!=24)
 {
  AfxMessageBox("Gray/True Color Possible!!");
  return FALSE;
 }
 if(dibHi.biBitCount==8)
  hFile.Read(palRGB,sizeof(RGBQUAD)*256);

 // 메모리 할당 (바뀐 부분)
 int ImgSize;
 if(dibHi.biBitCount==8) ImgSize = hFile.GetLength()-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER)-256*sizeof(RGBQUAD);
 else if(dibHi.biBitCount==24) ImgSize = hFile.GetLength()-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER);
 m_InImg = new unsigned char [ImgSize]; //dibHi.biSizeImage

 m_OutImg = new unsigned char [ImgSize];
 
 hFile.Read(m_InImg, ImgSize);

 height = dibHi.biHeight;
 width = dibHi.biWidth;
 
 if(dibHi.biBitCount==24){} //return TRUE;
 // 영상데이터 대입
 
 int i,j,index;
 int rwsize = WIDTHBYTES(dibHi.biBitCount*width);
 for( i=0; i<height; i++)
 {
  index = i*rwsize;
  for(j=0; j<width; j++)
   m_InImg[index+j] = (unsigned char)palRGB[(int)m_InImg[index+j]].rgbBlue;
 }
   
 
 hFile.Close();
 

 //2번째 이미지 파일
 CFile h1File;
 CFileDialog dlg(TRUE);
 if (dlg.DoModal() == IDOK )
 {
  CString lpszPathName2 = dlg.GetPathName();
  h1File.Open(lpszPathName2,CFile::modeRead | CFile::typeBinary);
  h1File.Read(&dibHf1,sizeof(BITMAPFILEHEADER)); // 파일 헤드를 읽음

  if(dibHf1.bfType!=0x4D42)
  {
   AfxMessageBox("Not BMP file!!"); return FALSE;
  } //이 파일이 BMP파일인지 검사. 0x4d42=='BM'
  h1File.Read(&dibHi1,sizeof(BITMAPINFOHEADER)); //"영상정보의 Header"를 읽는다. 
  if(dibHi1.biBitCount!=8 && dibHi1.biBitCount!=24)
  {
   AfxMessageBox("Gray/True Color Possible!!");
   return FALSE;
  }
  
  if(dibHi1.biBitCount==8)
   h1File.Read(palRGB,sizeof(RGBQUAD)*256);

  // 메모리 할당 (바뀐 부분)
  int ImgSize1;
  if(dibHi1.biBitCount==8) ImgSize1 = h1File.GetLength()-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER)-256*sizeof(RGBQUAD);
  else if(dibHi1.biBitCount==24) ImgSize1 = h1File.GetLength()-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER);
  m_InImg1 = new unsigned char [ImgSize1]; //dibHi1.biSizeImage
  m_OutImg1 = new unsigned char [ImgSize1];


        h1File.Read(m_InImg1, ImgSize1);

  height1 = dibHi1.biHeight;
  width1 = dibHi1.biWidth;

 
  h1File.Close();
 
  //return TRUE;

  // 영상데이터1 대입
  
  int i1,j1,index1;
  int rwsize1 = WIDTHBYTES(dibHi1.biBitCount*width1);
  for(i1=0; i1<height1; i1++)
  {
   index1 = i1*rwsize1;
   for(j1=0; j1<width1; j1++)
    m_InImg1[index1+j1] = (unsigned char)palRGB[(int)m_InImg1[index1+j1]].rgbBlue;
  }

 }
 //if(dibHi1.biBitCount==24) //return TRUE;

 return TRUE;
}

 

폴더내에 있는 이미지 파일을 연속적으로 오픈하는 부분은 다음과 같습니다.

 

void CWinColorDoc::OnBatchAccumhist()
{
 // TODO: Add your command handler code here
/* CFileDialog dlg(TRUE);
 if (dlg.DoModal() == IDOK )
 {
 */
 CFileFind find; //file 검색을 위한 클래스
  CString path1 = "C:\\temp1\\*.bmp"; //원하는 폴더경로 지정
 CString fname;
 CString pname;

 int pWorking = find.FindFile((LPCTSTR)path1);//원하는 폴더 경로에  조건에 맞는 파일이 있으면 1, 없으면 0

  if (pWorking==0) {

   AfxMessageBox("파일이 없습니다.");

  }

  while(pWorking)
  {
   pWorking = find.FindNextFile(); //다음 파일 찾기
   fname = find.GetFileName(); //파일 이름 넘겨주기
   pname = find.GetFilePath(); //파일 경로 넘겨주기


 
   CFile h2File;//원하는 파일이 있을 경우 파일을 읽어들이기 위한 함수

   // CString lpszPathName3 = dlg.GetPathName();

    h2File.Open(pname,CFile::modeRead | CFile::typeBinary);

    h2File.Read(&dibHf2,sizeof(BITMAPFILEHEADER)); // 파일 헤드를 읽음

    h2File.Read(&dibHi2,sizeof(BITMAPINFOHEADER)); //"영상정보의 Header"를 읽는다.
   
     if(dibHi2.biBitCount!=8 && dibHi2.biBitCount!=24)
     {
      AfxMessageBox("Gray/True Color Possible!!");
    
     }

     if(dibHi2.biBitCount==8)

      h2File.Read(palRGB,sizeof(RGBQUAD)*256);


     // 메모리 할당 (바뀐 부분)
     double ImgSize=0.0;

         if(dibHi2.biBitCount==8)
       ImgSize = h2File.GetLength() -sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER)-256*sizeof(RGBQUAD);
      else if(dibHi2.biBitCount==24)
       ImgSize = h2File.GetLength()-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER);
   
      m_InImg2 = new unsigned char [ImgSize]; //dibHi.biSizeImage
    
      h2File.Read(m_InImg2, ImgSize);

      height2 = dibHi2.biHeight;
      width2 = dibHi2.biWidth;
    
      //if(dibHi2.biBitCount==24){} //return TRUE;
   
      // 영상데이터 대입  
   
      int i,j,index;
      int rwsize = WIDTHBYTES(dibHi2.biBitCount*width2);

      for( i=0; i<height2; i++)
      {
       index = i*rwsize;
       for(j=0; j<width2; j++)
        m_InImg2[index+j] = (unsigned char)palRGB[(int)m_InImg2[index+j]].rgbBlue;
      }
   

      OnAccFeatHisto();

      if (find.IsDirectory()) //디렉토리가 있으면
      {
       CString ffilename = pname+"\\";

       AfxMessageBox(ffilename);
       //fileopen. fullfilename
       // fclose
      } else { //디렉토리가 없으면-bmp 파일이면                                                        
       CString ffilename = pname;
       AfxMessageBox(ffilename);
       //fileopen. fullfilename                                                                                                                                                  
       //OnAcchisto();
       // fclose
      } 
   
      h2File.Close();
         delete m_InImg2;   
   }
  
  
// } 
 
}

Posted by 십자성군
Software/Programming2012. 8. 10. 22:08

// 1. 파일에서 비트맵 데이터를 읽어들임

HBITMAP dibLoadFromFile(LPCTSTR lpFileName)
{
    HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ,
                        NULL, OPEN_EXISTING, 0, NULL);

    if(hFile == INVALID_HANDLE_VALUE) return NULL;

 

    BITMAPFILEHEADER bmfh;

    DWORD dwRead;
    ReadFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwRead, NULL);

 

    DWORD dwInfoLength = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
    LPBITMAPINFO lpbmi = (LPBITMAPINFO)new BYTE[dwInfoLength];
    ReadFile(hFile, lpbmi, dwInfoLength, &dwRead, NULL);

 

    HDC hDC = GetDC(GetDesktopWindow());

 

    LPVOID lpDIBits;
    HBITMAP hDIB = CreateDIBSection(hDC, lpbmi, DIB_RGB_COLORS, &lpDIBits, NULL, 0);

    ReleaseDC(GetDesktopWindow(), hDC);

 

    ReadFile(hFile, lpDIBits, lpbmi->bmiHeader.biSizeImage, &dwRead, NULL);

    CloseHandle(hFile);

 

    delete [] lpbmi;

 

    return hDIB;
}

 

// 2. 비트맵 데이터를 24비트 트루칼라로 바꿈

void dibSetTrueColor(HBITMAP* phDIB)
{
    DIBSECTION ds;
    GetObject(*phDIB, sizeof(DIBSECTION), &ds);

    if(ds.dsBmih.biBitCount == 24) return;

 

    HDC hDC = GetDC(GetDesktopWindow());

    HBITMAP hDDB = CreateCompatibleBitmap(hDC, ds.dsBm.bmWidth, ds.dsBm.bmHeight);
    SetDIBits(hDC, hDDB, 0, ds.dsBm.bmHeight, ds.dsBm.bmBits,

                    (LPBITMAPINFO)&ds.dsBmih, DIB_RGB_COLORS);

 

    BITMAPINFOHEADER bmih;
    ZeroMemory(&bmih, sizeof(BITMAPINFOHEADER));
    bmih.biSize = sizeof(BITMAPINFOHEADER);
    bmih.biWidth = ds.dsBm.bmWidth;
    bmih.biHeight = ds.dsBm.bmHeight;
    bmih.biPlanes = 1;
    bmih.biBitCount = 24;
    bmih.biCompression = BI_RGB;

 

    LPVOID lpDIBits;
    HBITMAP hDIB = CreateDIBSection(hDC, (LPBITMAPINFO)&bmih, DIB_RGB_COLORS,

                    &lpDIBits, NULL, 0);
    GetDIBits(hDC, hDDB, 0, ds.dsBm.bmHeight, lpDIBits, (LPBITMAPINFO)&bmih,

                    DIB_RGB_COLORS);

    ReleaseDC(GetDesktopWindow(), hDC);

 

    DeleteObject(hDDB);
    DeleteObject(*phDIB);

    *phDIB = hDIB;
}

 

// 3. 비트맵의 밝기를 조절

void dibSetBrightness(HBITMAP hDIB, int nLevel)
{
    DIBSECTION ds;
    GetObject(hDIB, sizeof(DIBSECTION), &ds);
    if(ds.dsBmih.biBitCount != 24) return;

 

    for(int y = 0; y < ds.dsBm.bmHeight; y++) {
        RGBTRIPLE* lpLine = (RGBTRIPLE*)ds.dsBm.bmBits + (y * ds.dsBm.bmWidth);
        for(int x = 0; x < ds.dsBm.bmWidth; x++) {
            RGBTRIPLE rgbT = lpLine[x];
            int r = (int)rgbT.rgbtRed + nLevel;
            int g = (int)rgbT.rgbtGreen + nLevel;
            int b = (int)rgbT.rgbtBlue + nLevel;
            rgbT.rgbtRed = (r > 255) ? 255 : ((r < 0) ? 0 : r);
            rgbT.rgbtGreen = (g > 255) ? 255 : ((g < 0) ? 0 : g);
            rgbT.rgbtBlue = (b > 255) ? 255 : ((b < 0) ? 0 : b);
            lpLine[x] = rgbT;

            }
        }
}

 

// 4. 비트맵 데이터를 파일에 저장

BOOL dibSaveToFile(LPCTSTR lpFileName, HBITMAP hDIB)
{
    HANDLE hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,

                        FILE_ATTRIBUTE_NORMAL, NULL);
    if(hFile == INVALID_HANDLE_VALUE) return FALSE;

 

    DIBSECTION ds;
    GetObject(hDIB, sizeof(DIBSECTION), &ds);

 

    int nColors = 0;
    if(ds.dsBmih.biBitCount <= 8)
        nColors = (ds.dsBmih.biClrUsed) ? ds.dsBmih.biClrUsed : (1 << ds.dsBmih.biBitCount);

 

    BITMAPFILEHEADER bmfh;
    bmfh.bfType = 'MB';
    bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)

                            + nColors * sizeof(RGBQUAD);
    bmfh.bfSize = bmfh.bfOffBits + ds.dsBmih.biSizeImage;
    bmfh.bfReserved1 = bmfh.bfReserved2 = 0;

 

    DWORD dwWritten;
    WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
    WriteFile(hFile, &ds.dsBmih, sizeof(BITMAPINFOHEADER) + nColors * sizeof(RGBQUAD),

                        &dwWritten, NULL);
    WriteFile(hFile, ds.dsBm.bmBits, ds.dsBmih.biSizeImage, &dwWritten, NULL);
    CloseHandle(hFile);


    return TRUE;
}

Posted by 십자성군
Software/Programming2012. 8. 10. 00:31

http://nenunena.tistory.com/66

'Software > Programming' 카테고리의 다른 글

MFC 비트맵 파일처리 3. (수정필요)  (0) 2012.08.10
MFC 비트맵 파일 다루기 1.  (0) 2012.08.10
MFC의 흐름  (0) 2012.08.10
도큐먼트 뷰 객체 설명  (0) 2012.08.10
CFileDialog  (0) 2012.08.10
Posted by 십자성군
Software/Programming2012. 8. 10. 00:30

MFC의 흐름

http://blog.naver.com/gorory?Redirect=Log&logNo=20031488529

Posted by 십자성군
Software/Programming2012. 8. 10. 00:28

Visual C++ 프로그램

    -. 어렵게만 느껴졌던 도큐먼트 뷰구조

    -. 비주얼C++프로그램 쉽게 분석하기

    -. 도큐먼트 뷰 구조 자세히 공부하기

    -. 도대체 애플리케이션 프레임워크가 뭡니까?


  가. 어렵게만 느껴졌던 도큐먼트 뷰구조


    1) 도큐먼트 뷰구조

      ? theApp : 애플리케이션의 수행과 관련된 일

      ② CMainFrame클래스로 동적할당한 객체 : 프레임윈도우와 관련된일

      ③ 도큐먼트 객체 : 파일입출력만 전문적으로 담당

      ④ 뷰 객체 : 화면 출력만 전문적으로 담당


    2) 애플리케이션 유형과 애플리케이션 위저드

      ? 프레임윈도우 객체: 메뉴, 툴바, 상태바

      ② 뷰윈도우 : 프레임윈도우가 둘러싸는 공간. 즉 클라이언트 영역

      ③ 윈도우를 갖지 않는 객체 : theApp(애플리케이션객체)와 도큐먼트 객체

      ④ 도큐먼트와 뷰가 필요없는 경우 =>대화상자(계산기, 전화걸기등)

      ⑤ 도큐먼트가 하나인 경우 =>SDI애플리케이션(워드패트)

      ⑤ 도큐먼트가 여러개인 경우 =>MDI애플리케이션(MS워드)


  나. 비주얼C++프로그램 쉽게 분석하기

     

  // 윈도우 생성

  hwnd = CreateWindow(szAppName)

  "Hello2",

  WS_OVERLAPPENDWINDOW,

  CW_USEDFAULT,

  CW_USEDFAULT,     

  CW_USEDFAULT, 

  CW_USEDFAULT,

  NULL,

  NULL,

  hInstance,

  NULL);

  





      ① WS_OVERLAPPENDWINDOW :두꺼운 프레임과 최소/최대 상자,

                                      그리고 시스템 메뉴가 있는 윈도우 형식

      ② WS_OVERLAPPEND : 윈도우 크기 조절할 수 없다

      ③ ShowWIndow : API프로그램에서 윈도우 표시 최소화/ 최대화


  다. 도큐먼트 뷰구조 자세히 공부하기

    1) 메인프레임 윈도우 객체가 할 수 있는 일들

      ? 윈도우 위치와 크기 지정하기

         - PreCreateWindow함수

            :메인프레임윈도우 객체가 생성된 후 윈도우가 생성되기 바로전에 실행되는 함수      

 // 화면 가운데

        cs.cx=::GetSystemMetrics(SM_CXSCREEN) /2;

        cs.cy=::GetSystemMetrics(SM_CYSCREEN) /2;

        cs.x=((cs.cx*2)-cs.cx)/2;

        cs.y=((cs.cy*2)-cs.cy)/2;

       - ActivateFrame(int nCmdShow)

           : 최대화, 최소화 지정

 cs.style = WS_OVERLAPPED 

          | WS_CAPTION 

          | WS_SYSMENU            // 우위  종료

          | WS_THICKFRAME        // 두께

          | WS_MINIMIZEBOX        // - 박스

          | WS_MAXIMIZEBOX;       // 확대 박스


      ② 오른쪽 마우스 클릭시 종료

void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point)

{

        // TODO: Add your message handler code here

        PostQuitMessage(0);

}


      ③ 툴바 상태바 제어하기: 툴바 왼쪽에 붙이기

 DockControlBar(&m_wndToolBar, AFX_IDW_DOCKBAR_LEFT);


    2) 애플리케이션객체가 할 수 있는 일들(즉 theApp)

      ① 윈도우 클래스정의, 생성, 표시 그리고 메시지루프

           - InitApplication멤버함수

           - InitInstance멤버함수

           - Run멤버함수

           - ExitInstance멤버함수: 프로그램 종료

           중요: 멤버함수가 가상함수일 경우 상속받은 함수가 아닌 해당클래스에서

                 정의됨 함수가 호출됨.

         

      ② 도큐먼트객체와 메인프레임윈도우객체, 뷰객체 생성

        // Dispatch commands specified on the command line

        if (!ProcessShellCommand(cmdInfo))

                return FALSE;

        OnFileNew();

        pDocTemplate->OpenDocumentFile(NULL);

          - 3가지 모두 동일한 결과

          - OpenDocumentFile를 호출해도 됨(우선 도큐먼트객체 정의)

            

      ③ 도큐먼트 템플리트객체

        CSingleDocTemplate* pDocTemplate;

        pDocTemplate = new CSingleDocTemplate(

                IDR_MAINFRAME,

                RUNTIME_CLASS(CMyDoc),

                RUNTIME_CLASS(CMainFrame),     // SDI frame window

                RUNTIME_CLASS(CMyView));

        AddDocTemplate(pDocTemplate);

          - CMyDoc클래스, CMainFrame클래스, CMyView클래스이용

            세 개의 객체들 동적으로 할당한 후 객체들을 적절히 연결.

      ④ 윈도우 최대화/최소화

        m_pMainWnd->ShowWindow(SW_SHOW);

          - 메인프레임윈도우 객체의 AcrivateFrame에서 구현

          - InitInstance멤버함수에서도 수행함.


    3) 뷰 객체가 할 수 있는 일들

      ① 그리기

          - 메인프레임윈도우의 클라이언트영역 뷰가 덮어 버림

          - 예제로 왼쪽마우스로 문자열 출력시 뷰클래스멤버로 정의해야함.

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{

        CClientDC dc(this);

        dc.TextOut(0,0, "왼쪽 마우스 버튼 누름");

        CView::OnLButtonDown(nFlags, point);

}

         (문제) 화면크기를 변경하면 사라짐

void CMyView::OnPaint()

{

        CPaintDC dc(this); // device context for painting

        dc.TextOut(0,0,"안녕 페이트");

}

         (문제) 인쇄미리보기 안나타남


void CMyView::OnDraw(CDC* pDC)

{

        CMyDoc* pDoc = GetDocument();

        ASSERT_VALID(pDoc);

        pDC->TextOut(0,0,"안녕 페이트");

}

         (문제) 미리보기에는 나타나는 데 화면과 불일치

               => 클래스위저드로 OnPaint멤버함수 삭제


      ② 도큐먼트주소 알아내기

         - 뷰가 도큐먼트에 있는 데이터를 출력 하기위해서 도큐먼트 주소를 알아야 함.

           (즉, GetDocument()멤버함수 호출

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{

        CString szStr;

        szStr.Format("도큐먼트객체번지: %p.", GetDocument());

        MessageBox(szStr);

        

        CView::OnLButtonDown(nFlags, point);

}


    3) 도큐먼트 객체가 할 수 있는 일들

      ① 직렬화

         - 도큐먼트존재: 동적으로 할당되어 메모리 어딘가에존재함

         - 도큐먼트위치: 프레임윈도우클라이언트영역, 뷰윈도우 바로 아래

         - 도큐먼트객체: 파일로 저장하고 읽어오기

         - 직렬화(serialization) : 도큐먼트객체 멤버변수에 저장되어 있는 자료를

                                 일렬로 저장하거나 읽어오기(즉 파일입출력을 말함)

// 도큐먼트 멤버변수 정의

   CString m_szData;

// 도큐먼트초기화

BOOL CMyDoc::OnNewDocument()

{

   ...

   m_szData = "";

   return true;

}

// 직렬화 수행

void CMyDoc::Serialize(CArchive& ar)

{

        if (ar.IsStoring())

        {

                // 파일 저장하기

                ar << m_szData;

        }

        else

        {

                // 파일 불러오기

                ar >> m_szData;

        }

}

// 뷰화면에 표현

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{       

     CString szCoord;

     szCoord.Format("마우스를 좌표:(%d, %d)", point.x, point.y);

        GetDocument()->m_szData=szCoord;

        Invalidate();   // 강제로 WM_PAINT메시지 발생  

        CView::OnLButtonDown(nFlags, point);

}

// 저장자료로 표시

void CMyView::OnDraw(CDC* pDC)

{

        CMyDoc* pDoc = GetDocument();

        ASSERT_VALID(pDoc);

        pDC->TextOut(0,0,GetDocument()->m_szData);

}


  라. 도대체 애플리케이션 프레임워크가 뭡니까?

    1) 도큐먼트 뷰 구조 및 애플리케이션 프레임워크

      ① 정의

         - 애플리케이션 객체(theApp)와 메인프레임윈도우 객체, 도큐먼트객체와

           뷰객체로 이루어진 애플리케이션을 말함

      ② 도큐먼트 뷰구조 목적

         - 역할 분담을 위함, 자료를 유지관리 역할을 하는 도큐먼트객체와

            자료를 표시하는 뷰객체를 둠

      ③ 각각의 객체가 특정 작업만을 수행=>모듈성 강화


    2) 애플리케이션프레임워크 안

      ① 디버깅 : Debug-Step Into , F11키누름

                  F10: 한줄씩 통째로

                  F11: 함수가 있을 경우 안으로 들어감

         - 애플리케이션 프레임워크 코드

             :tWinMain함수를 시작으로 일정한 순서대로 실행

         - 애플리케이셔 프레임워크 추적

             :F10키와 F11키를 번갈아 눌러서 처음부터 추적

      ② CTRL+F5: 운영체제는 tWinMain 함수를 가장 먼저 실행

      ③ AfxWinMain함수

         - 이함수 직접작성한 WinMain함수에 해당

         - theApp객체의 InitApplication멤버함수호출(정의,등록,생성,실행)


      ④ CAfxApp theApp

         - 반드시 하나만 존재 변경도 안됩니다

         - 두 개 입력시 에러(Debug Assertion Failed)


      ④ InitAppication 멤버함수

         - CAfxApp의 멤버로 정의하며 CWinApp로부터 상속

         - theApp의 객체는 두 개의 InitAppication멤버함수를 가지는데

           CAfxApp::InitAppication가 실행 됩니다.

           (이유 가상함수이기때문, 가상함수가 아니면 상속받은 멤버함수가 실행)

<변영철 비주얼C++ 참조>

Posted by 십자성군
Software/Programming2012. 8. 10. 00:00

관련글 :

■ MFC CFileDialog - 파일선택 다이얼로그

□ 디렉토리 및 파일 선택하기 - GetOpenFileName, CFileDialog, SHBrowseForFolder

□ SHELL 프로그램 - 디렉토리의 위치를 얻기위한 프로그램

 

 

파일 선택을 위한 클래스가  CFileDialog 이다.

 

 

한개의 파일만 선택할 경우

char szFilter[] = "Image (*.BMP, *.GIF, *.JPG) | *.BMP;*.GIF;*.JPG | All Files(*.*)|*.*||";

CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter);

if(IDOK == dlg.DoModal()) {

        CString strPathName = dlg.GetPathName();

}

 

 

여러개의 파일을 복수 선택할 경우

 

dwFlag에 OFN_ALLOWMULTISELECT 설정한다.

        선택된 여러 파일 리스트가 저장될 버퍼가 제공되야 한다.

        만일 기본 버퍼 이상의 파일을 선택해 확인 버튼을 누른다면,

        DoModal을 실행시켰을 때, IDCANCEL이 리턴되고, 파일 리스트가 넘어오지 않을 것이다.

 

char szFilter[] = "All Files(*.*) | *.* ||";
CFileDialog dlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, szFiilter);

dlg.m_ofn.lpstrInitialDir = _T("D:/"); // 오픈할때 초기 경로 지정
// 여기서 버퍼 크기 늘려줘야 함.

char    strFile[4096] = { 0, };               CString fileName;
dlg.m_ofn.lpstrFile = strFile;                 dlg.m_ofn.lpstrFile = fileName.GetBuffer( 4096 );
dlg.m_ofn.nMaxFile = sizeof(strFile);      dlg.m_ofn.nMaxFile = 4096

if (IDOK == dlg.DoModal()) { 
   for (POSITION pos=dlg.GetStartPosition(); pos != NULL;) 
       CString strPathName =
 dlg.GetNextPathName(pos);
}

 

파일 선택 필터

static TCHAR BASED_CODE szFilter[] = 
_T("Chart Files (*.xlc)|*.xlc|") _T("Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|")
_T("*.xlc; *.xls|All Files (*.*)|*.*||");

 

 

예제

void CMyClass::OnFileOpen() 
{
// szFilters is a text string that includes two file name filters:
// "*.my" for "MyType Files" and "*.*' for "All Files."
TCHAR szFilters[]= _T("MyType Files (*.my)|*.my|All Files (*.*)|*.*||");

// Create an Open dialog; the default file name extension is ".my".
CFileDialog fileDlg(TRUE, _T("my"), _T("*.my"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);

// Display the file dialog. When user clicks OK,

fileDlg.DoModal()

// returns IDOK.
if (fileDlg.DoModal() == IDOK)
{
CString pathName = fileDlg.GetPathName();

// Implement opening and reading file in here.
// Change the window's title to the opened file's title.

CString fileName = fileDlg.GetFileTitle();
SetWindowText(fileName);
}
}

============================================================================

 

CFileDialog dlgFile(TRUE);


CString fileName;
const int c_cMaxFiles = 100;
const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;


dlgFile.GetOFN().lpstrFile = fileName.GetBuffer(c_cbBuffSize);
dlgFile.GetOFN().nMaxFile = c_cMaxFiles;

 

dlgFile.DoModal();


fileName.ReleaseBuffer();

 

 

============================================================================

 

 

CFileDialog::CFileDialog

 

 

explicit CFileDialog( BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE );

 

BOOL bOpenFileDialog
       생성하는 다이얼로그 박스 타입을 지정해 주는 매개변수
       TRUE => 파일열기 다이얼로그 박스 
       FALSE => 파일 저장 다이얼로그 박스

LPCTSTR lpszDefExt
      기본 파일 확장자명(저장할 경우 사용)
       만약 유저가 파일이름 상자 안에 확장자를 포함하지 않는 경우
       lpszDefExt의 파일 확장자명을 자동으로 지정 함
       NULL => 확장자명을 추가하지 않음

lpszFileName
       시작할 때 파일이름 상자에 나타낼 이름 지정
        NULL => 시작할 때 파일이름을 나타내지 않음


dwFlags
       하나이상의 플래그를 사용하여 사용자가 원하는 다이얼로그 박스로 조합

        많이 사용되는 플래그 
        OFN_ALLOWMULTISELECT        한번에 여러개의 파일들을 선택 가능하게 함
        OFN_CREATEPROMPT              존재하지 않는 파일명을 입력했을 경우 새로 생성하겠냐는 대화상자 표시
        OFN_EXPLOPER                       열기나 저장하기를 윈도우 탐색기 스타일로 출력
        OFN_FILEMUSTEXIST               기존에 존재하는 파일 이름만 입력할 수 있도록 함
        OFN_HIDEREADONLY                읽기전용 파일은 출력하지 않음
        OFN_LONGNAMES                   긴 파일 이름을 사용할 수 있도록 함
        OFN_OVERWRITEPROMPT        저장할려고 하는 파일명이 존재할 경우 덮어쓰겠냐는 대화 상자 표시
        OFN_PATHMUSTEXIST             오직 유효한 경로나 파일명만을 입력(아님 경고 메세지 출력)

        추가 플래그 참조 : 
http://msdn.microsoft.com/ko-kr/library/ms646839(en-us,VS.85).aspx


lpszFilter
    사용할 파일들이 걸러지도록 파일명들을 연속으로 나열 함

pParentWnd
    부모나 소유자 윈도우의 파일 다이얼로그 박스의 포인터

dwSize
    OPENFILENAME 구조체의 크기

Posted by 십자성군
Software/Programming2012. 8. 9. 19:08

1. 여러개의 파일을 여는 함수를 만들 때 CFileDialog에서 문자관련 문제발생


void CWinTestApp::OnFileOpen()

{

// TODO: 여기에 명령 처리기 코드를 추가합니다.

//다중 열기 처리

char filter[] = "Raw files (*.raw)|*.raw||";

CFileDialog dlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, filter);

if(dlg.DoModal() ==IDOK){

for(POSITION pos = dlg.GetStartPosition(); pos !=NULL;)

OpenDocumentFile(dlg.GetNextPathName(pos));

}


}

여기서 CFileDialog에서 TRUE를 인수로 못받아 들인다.


2. raw 파일을 열때 대화상자 문자관련 문제 발생

void CWinTestDoc::Serialize(CArchive& ar)

{

if (ar.IsStoring())

{

// TODO: 여기에 저장 코드를 추가합니다.

ar.Write(m_OutImg,256*256);

}

else

{

// TODO: 여기에 로딩 코드를 추가합니다.

CFile *infile = ar.GetFile();

if(infile->GetLength() != 256*256)

{

AfxMessageBox("파일 크기가 256x256 사이즈가 아닙니다.");

return;

}

ar.Read(m_InImg,infile->GetLength());

}

}


AfxMessageBox에서 표현을 못한단다.


해결

Alt+f7로 들어가서 구성속성->일반->프로젝트 기본값->문자집합을 멀티바이트 문자 집합 사용으로

'Software > Programming' 카테고리의 다른 글

MFC의 흐름  (0) 2012.08.10
도큐먼트 뷰 객체 설명  (0) 2012.08.10
CFileDialog  (0) 2012.08.10
[MFC] OnFileOpen 함수 재정의 해서 사용하기.  (0) 2012.08.09
게시판 프로그램  (0) 2011.10.11
Posted by 십자성군
Software/Programming2012. 8. 9. 16:47

SDI나 MDI 구조의 경우 문서 열기를 재정의 해서 사용해야 할 때가 있다.

이럴때는...

1. XXXXAPP.cpp 파일을 열어서

코드의 가장 위에 있는 메시지를 아래와 같이 다시 정의한다.

  1. BEGIN_MESSAGE_MAP(CCudaTestApp, CWinAppEx)    
  2. ON_COMMAND(ID_APP_ABOUT, &CCudaTestApp::OnAppAbout)   
  3. // 표준 파일을 기초로 하는 문서 명령입니다.    
  4. ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)        
  5. //기존의 OnFileOpen 임.   
  6. //ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)    
  7. //OnOpenDocument 함수를 호출할 때, 자신이 만든 함수를 호출하도록      
  8. //ID_FILE_OPEN를 사용자 임의로 재정의 한다.   
  9. ON_COMMAND(ID_FILE_OPEN, &CCudaTestApp::OnFileOpen)           
  10. // 표준 인쇄 설정 명령입니다.    
  11. ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)     
  12. ON_COMMAND(ID_FILE_OPEN, &CCudaTestApp::OnFileOpen)  
  13. END_MESSAGE_MAP()  


2. 클래스 위자드나 이벤트 재정의에서 다음과 같이 OnFileOpen 함수를 추가해 준다.



3. OnFileOpen함수 내부를 아래와 같이 작성. (원하는 파일 다이얼로그를 만들기 위한 코드를 여기에 작성한다)

  1. void CCudaTestApp::OnFileOpen(){      
  2. // TODO: 여기에 명령 처리기 코드를 추가합니다.    
  3. char filter[] = "Raw files (*.raw)|*.raw||";      
  4. CFileDialog dlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, filter);      
  5.    if(dlg.DoModal() == IDOK){         
  6.      for(POSITION pos = dlg.GetStartPosition(); pos !=NULL;)              
  7.           OpenDocumentFile(dlg.GetNextPathName(pos));     
  8.    }  
  9. }  


현재 코드는 여러 파일을 동시에 읽어들일 수 있도록 해놓은 상태이다.

4. 컴파일 후 실행하면 원하는 파일 다이얼로그를 볼 수 있다.

'Software > Programming' 카테고리의 다른 글

MFC의 흐름  (0) 2012.08.10
도큐먼트 뷰 객체 설명  (0) 2012.08.10
CFileDialog  (0) 2012.08.10
MFC에서 유니코드 관련해서 문제가 생겼다.  (1) 2012.08.09
게시판 프로그램  (0) 2011.10.11
Posted by 십자성군
Software/Programming2011. 10. 11. 18:39

Board.zip

3일걸렸다

'Software > Programming' 카테고리의 다른 글

MFC의 흐름  (0) 2012.08.10
도큐먼트 뷰 객체 설명  (0) 2012.08.10
CFileDialog  (0) 2012.08.10
MFC에서 유니코드 관련해서 문제가 생겼다.  (1) 2012.08.09
[MFC] OnFileOpen 함수 재정의 해서 사용하기.  (0) 2012.08.09
Posted by 십자성군