GSI

stdafx.h 파일에 

#import "C:\Program Files\Common Files\System\ado\msado15.dll" rename("EOF", "EndOfFile") no_namespace

이 구문을 추가 한다.



Posted by gsi
:


MFC의 Dialog 베이스를 사용해서 폼을 하나 제작합니다.
그리고 picture Box 를 하나 제작한 후에 CxImage를 사용해서 png 파일을 하나 로드 한후에
picture Box에 SetBitmap 를 하고 나서 이걸 다른 형태로 테스트를 진행해 봤습니다.

기본 코드는 아래와 같아요.

// CxImage 객체 생성
m_pImage = new CxImage("D:\\Test.png", CXIMAGE_FORMAT_PNG);

// PictureBox 컨트롤에 CxImage 이미지 연동
m_pic.SetBitmap( m_pImage->MakeBitmap() );

이렇게 하고 나서 실행 하고, 종료 하게 되면 크게 문제는 안되는듯 하다.

이걸 다른 형태로 테스트를 해봤다.
타이머를 통해서 CxImage 객체 두개의 Bitmap를 m_pic(PictureBox) 컨트롤에 SetBitmap를 반복해서 처리해봤다.

void CPngToBitmapDlg::OnTimer(UINT nIDEvent)
{
 static bool bFirst = false;
 static HBITMAP hBitmap = NULL;

 if( bFirst == false )
 { 
  hBitmap = m_pic.SetBitmap( m_pImage2->MakeBitmap() );
 }
 else
 {
  hBitmap = m_pic.SetBitmap( m_pImage->MakeBitmap() );
 }

 ::DeleteObject( hBitmap );

 //
 bFirst = !bFirst;

 m_loopCount++;
 UpdateData(false);
 

 CDialog::OnTimer(nIDEvent);
}

위의 붉은색 코드를 하지 않고 계속해서 SetBitmap을 하게 되면
페이지파일(PF)가 계속 증가 하는 것을 볼 수 있다.

앞으로 코드 구현을 할때 하나 하나 단위테스트를 통해서 반복적인 메모리 및 GDI 사용량 등을
체크 하고 좀 안정성 있는 프로그램을 하도록 해야 할거 같다.

Posted by gsi
:


한동안 포스트를 못했다.
삶이 너무 바쁘게 돌아 가다 보니

이 포스트를 한건건 소스를 공개 하는건 아니다.
하지만 몇가지 경우에 대해서 공론화를 하기 위해서다.
물론 여기에 있어서 지원을 받고 싶거나, 질문을 주시면 성심 성의껏 도와줄 의양은 있어요 ^^

ActiveX를 이용해서 웹에서 실행 파일을 제어 하기 위해서
최근에 작업을 했다.

기존에 크게 문제시 되었던 부분이 아니라서 개발 일정을 짦게 잡았던게 화근이였다. -.-

참.. 쉽게 해결되지 않는게 프로그램의 일이란걸 세삼 느꼈다.

.Net 2003으로 ActiveX를 개발을 하였다.
아주 기본으로 해서 메소드를 정의 하고 웹에 붙였다.

로컬에서는 아주 잘 되었고 그래서 웹 서버에 올려서 테스트 하면 잘 되겠지
싶었다.
웹 서버에 올리고 노란바가 정상적으로 나왔다.
그래서 이제 되겠거니 했지만.
ActiveX의 메소드가 웹에서 인식이 되지 않아서 메소드 정의가 없다는 오류가 나왔다.
IE 6.0, 8.0 모두 그런 현상이 발생 하였다.

그래서 보안 탭의 신뢰할 수 있는 사이트에 넣고 하니
제대로 될때도 있었지만.
안될때가 더 많았고 안되는 pc가 더 많았다.

근데 또 이상한건 신뢰할 수 있는 사이트에 웹 주소를 넣고 나서는
ACtiveX의 버젼을 올려서 배포를 해도 노란바가 아예 뜨지를 않았다.
하지만 구동은 정상적으로 업데이트 된게 실행이 되는 상태였다.

근데 그것도 이상하게 메소드가 없는 오류가 나올때가 있었다.

여러가지를 테스트해본 결과 IObjectSafety 인가 그 인터페이스 추가에서 문제가 나왔던거 같다.
이 코드를 적용하는데 있어서 helper.h, cpp 파일을 추가 하고 Ctrl.cpp에 추가 하고 하는 과정에서
오류가 있었던거 같다.

이제는 어려 곳의 컴퓨터에서 실행을 해봤지만 잘 되는거 같다.

ActiveX에서 많이 어려움을 가지는 초보 개발자가 있다면
언제든 쪽지 및 네이트온 추가를 통해서 질문해 주시기 바랍니다.
프로그래머는 항상 자료를 공유 하고 많이 나누면서 서로 발전해야 한다고 생각해요

그럼 오늘도 해결 안되는 문제를 안고 씨름 하는 많은 개발자들 화이팅 ^^
Posted by gsi
:


VS2003에서 InitializeCriticalSectionAndSpinCount 함수를 사용할려고 적용을 해보면
아래와 같은 컴파일 오류가 생긴다.

...\lock.cpp(50): error C3861: 'InitializeCriticalSectionAndSpinCount': 인수 종속성을 조회해도 식별자를 찾을 수 없습니다.

이런 경우는 window.h 이전에 _WIN32_WINNT의 디파인된 내용이 잘못되서 그런거 같다.

mfc의 경우 stdafx.h의 상단에 보면
#ifndef _WIN32_WINNT  // Windows NT 4 이후 버전에서만 기능을 사용할 수 있습니다.
#define _WIN32_WINNT 0x400   // Windows 98과 Windows 2000 이후 버전에 맞도록 적합한 값으로 변경해 주십시오.
#endif 

이란 부분에 있다.

여기서 0x400 부분을 0x403으로 수정해 주면 해결이 된다.
Posted by gsi
:


이걸로 해도 웹 페이지의 설정은 다 바꾸어 주어야 하는듯 하다.

설치파일 :
.

인터넷 옵션은 아래와 같은 부분을 "사용" 으로 해줘야 제대로 되는 것을 확인할 수 있다.
Posted by gsi
:

void ChoiceDirectoryPath(char* pathFolder)
{
 ASSERT( pathFolder );
 
 sprintf( pathFolder, "" );
 
 //CString m_strDirPath;
 ITEMIDLIST *pidlBrowse;
 char pszPathname[MAX_PATH];
 BROWSEINFO BrInfo;
 BrInfo.hwndOwner = NULL; //GetSafeHwnd();
 BrInfo.pidlRoot = NULL;
 memset( &BrInfo, 0, sizeof(BrInfo) );
 BrInfo.pszDisplayName = (LPSTR)pszPathname;
 BrInfo.lpszTitle = _T("폴더를 선택해 주세요.");
 BrInfo.ulFlags = BIF_RETURNONLYFSDIRS;
 // 다이얼로그 뛰우기
 pidlBrowse = SHBrowseForFolder(&BrInfo);
 if(pidlBrowse != NULL)
 {
  BOOL bSuccess = ::SHGetPathFromIDList(pidlBrowse, (LPSTR)pszPathname);
  if( bSuccess )
  {
   sprintf( pathFolder, "%s", pszPathname );
  }
 }
}

// 사용할때
 char szDirectory[MAX_PATH];
 ZeroMemory( szDirectory, sizeof(szDirectory) );
 ChoiceDirectoryPath( szDirectory );
 if( strlen(szDirectory) <= 0 )
  return 0;

Posted by gsi
:

void CDlgProgPage::OnBnClickedBtnProgBackgroundload()
{
 // 이미지 로드 - 여기에 오픈 다이얼로그를 적용해야징.
 // 이미지가 로드 되고 나면 화면을 업데이트 한다.
 CFileDialog OpenDlg( TRUE, "Add Files", "*.*", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT,
  "Bitmap Files(*.*)|*.bmp|Jpeg Files(*.*)|*.jpg|PNG Files(*.*)|*.png|AVI Files(*.*)|*.avi|All Files(*.*)|*.*|" );

 if( OpenDlg.DoModal() == IDOK )
 {
  // 이미지 정보를 View로 보낸다.
  g_ProgView->SetBackgroundImage(GetImage(OpenDlg.GetPathName()));
  // 백그라운드 이미지가 있다면 체크박스 속성을 활성화 한다.
  CheckBackgroundImage();
 }
}

Posted by gsi
:

특정 폴더를 기준으로 하위 폴더를 찾아 내는 코드 입니다.
그리고 그 폴더 내용을 xml 형태로 만들어 주는 코드도 포함되어 있습니다.
xml 데이터로 만들어진 내용은 CEdit 컨트롤에 표시되며, 그 내용을
저장할 수 있습니다.


관련 소스 :



.

Posted by gsi
:

MFC에서 xml 데이터를 읽어 들이는 예제입니다.
아래의 내용을 계층구조를 통해서 읽어 들이게 됩니다.
자세한 소스는 소스 코드를 참조 하세요.
  - XmlParser.h, cpp

[xml 샘플]

<?xml version="1.0" encoding="EUC-KR"?>

<PATHS>
 <PATH NAME="Install Files">
  <PATH NAME="Dev">
  </PATH>
  <PATH NAME="Dev2">
  </PATH>
  <PATH NAME="Dev3">
   <PATH NAME="Dev3_a">
   </PATH>
   <PATH NAME="Dev3_b">
    <PATH NAME="Dev3_b_a">
    </PATH>
    <PATH NAME="Dev3_b_b"/>
   </PATH>
  </PATH>
 </PATH>
 <PATH NAME="temp">
  <PATH NAME="temp_a"/>
  <PATH NAME="temp_b">
   <PATH NAME="temp_b_a">
   </PATH>
   <PATH NAME="temp_b_b">
    <PATH NAME="temp_b_c"/>
   </PATH>
  </PATH>
 </PATH>
</PATHS>

계층 구조를 읽어 들이는 코드 (재귀호출)

1. 초기화 및 도입부

 ///
 MSXML2::IXMLDOMNodePtr nodeList = m_pDoc->selectSingleNode( Token.c_str() );
 _bstr_t bsElements("PATHS");

 if ( nodeList )
  FindName( nodeList->GetchildNodes() );

 nodeList.Release();

2. 재귀호출 부분

int tabCount = 0;

HRESULT CXmlParser::FindName( MSXML2::IXMLDOMNodeListPtr& lparam )
{
 long elementCount = lparam->Getlength();
 for( int i = 0; i < elementCount; i++ )
 {
  MSXML2::IXMLDOMElementPtr Element = lparam->nextNode();
  if( Element == NULL )
   break;

  _bstr_t bsNodename = Element->GetnodeName();
  _bstr_t bsElement("PATH");
  if( bsNodename == bsElement )
  {
   _bstr_t bsname("NAME");
   _variant_t varElementName = Element->getAttribute(bsname);

   // 해당하는 엘러먼트 Name의 이름 == 폴더 이름을 의미한다.
   CString strName;
   strName.Format( "%S", varElementName.bstrVal );    

   // 탭 카운터를 통한 출력
   CString strTabMergy;
   for( int tc = 0; tc < tabCount; tc++ )
   {
    strTabMergy += "\t";
   }
   strTabMergy += strName;
   TRACE( "%s\n", (LPSTR)(LPCSTR)strTabMergy);

   MSXML2::IXMLDOMNodeListPtr childElementlist = Element->GetchildNodes();
   if( childElementlist )
   {
    tabCount++;
    FindName( childElementlist );
   }
  }

  Element.Release();
 }

 tabCount--;
 lparam.Release();

 return S_OK;
}

아래의 콘솔 화면 내용입니다.

사용자 삽입 이미지


소스 코드 :


.

Posted by gsi
:

기본 소스는 아래 주소의 포스트를 사용했어요.. ^^
[MFC] Ruler 소스.. 메모리 DC 사용한 자연스러운 효과구현..


중점 :
  1. 줌인 줌아웃 처리를 위한 float 변수를 하나 추가 했습니다.
  2. ScrollView의 페이지 크기를 저장하는 CSize 변수를 하나 추가 했습니다.
  3. 방향키 UP, DOWN 을 사용해서 줌인, 줌아웃 처리를 보여 줍니다.

이제 설명을 시작하겠습니다.

Ruler 보완

Ruler의 기존 소스를 보게 되면 마우스로 스크롤 할때 Ruler가 따라 가지 않습니다.
기존 코드를 볼가요?
 // 기본 Ruler
 CRect rulerRect;
 rulerRect.left = scrollPosition.x;
 rulerRect.right = rulerRect.left + curArea.Width();
 rulerRect.top = scrollPosition.y;
 rulerRect.bottom = rulerRect.top + 20;
 m_RulerHorz.Draw( pDC, rulerRect.left, rulerRect.top, rulerRect.Width(), rulerRect.Height(), scrollPosition.x );

분명히 scrollPosition.y를 해줬는데도 안됩니다.
이걸 해결 하기 위해서는 휠을 움직여서 화면을 업데이트 한 것이기 때문에
아래의 OnMouseWheel함수를 오버라이드(?) 해서 Invalidate()를 해줘야 됩니다.

BOOL CRulerSampleView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
 Invalidate();
 return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
}

그리고 Scroll의 Bar를 움직여도 화면이 업데이트 되어야 하기 때문에 아래의 함수들도 같이 처리

void CRulerSampleView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 Invalidate( true );
 CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CRulerSampleView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 Invalidate( true );
 CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}

이렇게 하고 나면 휠 또는 스크롤바를 움직여도 Ruler가 자연스럽게 화면에 보이는걸 알 수 있습니다.

자자..
이제 줌인 줌아웃 처리를 해볼까요..


줌인 줌아웃 처리를 위해서 아래의 코드를 RulerSampleView.h 에 추가 합니다.
 CSize     m_PageSize;
 float     m_Zoom;

그리고 RulerSampleView.cpp 에는 아래와 같이 해봅시다.

> 우선 줌 성분 초기화를 생성자 함수에 추가
m_Zoom = 1.f;

> ScrollVew이기 때문에 페이지의 크기를 추가
void CRulerSampleView::OnInitialUpdate()
{
 CScrollView::OnInitialUpdate();

 m_PageSize = CSize( 1000, 1000 );
 SetScrollSizes(MM_TEXT, m_PageSize);
}

> 드로잉 코드에 m_Zoom을 적절하게 수정해 줍니다.
테스트를 위한 위치값을 10개를 생성했습니다. 이건 코드 보시면 알수 있어요..
드로잉 할때 아래와 같이 처리 합니다.
 vector< CPoint >::iterator iter;
 for( iter = m_TestData.begin(); iter != m_TestData.end(); iter++ )
 {
  CRect rect;
  rect.left  = (*iter).x;
  rect.top  = (*iter).y;
  rect.right  = rect.left + 50;
  rect.bottom  = rect.top + 50;

  rect.left  *= m_Zoom;
  rect.top  *= m_Zoom;
  rect.right  *= m_Zoom;
  rect.bottom  *= m_Zoom;

  pDC->FillRect( &rect, &redbrush );
 }
위의 붉은 부분을 m_Zoom으로 곱해줍니다.

> 이렇게 하고 나서 이제 이벤트를 추가해줘야 겠죠.
방향키를 통해서 줌인 줌아웃 성분을 증가 감소 합니다.

void CRulerSampleView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 if( nChar == VK_UP )
 {
  m_Zoom -= 0.1f;

  CClientDC dc(this);
  m_RulerHorz.CreateDC( &dc, 10000, 20, m_Zoom );

  m_PageSize = CSize( 1000*m_Zoom, 1000*m_Zoom );
  SetScrollSizes(MM_TEXT, m_PageSize);

  Invalidate();
 }

 if( nChar == VK_DOWN )
 {
  m_Zoom += 0.1f;

  CClientDC dc(this);
  m_RulerHorz.CreateDC( &dc, 10000, 20, m_Zoom );

  m_PageSize = CSize( 1000*m_Zoom, 1000*m_Zoom );
  SetScrollSizes(MM_TEXT, m_PageSize);

  Invalidate();
 }

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

위의 코드에서 보듯이 Ruler도 줌 성분이 달라지면, Ruler의 줌 성분을 보정해서 메모리 DC를 생성합니다.
그리고 ScrollView의 페이지도 m_Zoom에 따라서 사이즈를 제조정 해줍니다.

이렇게 하면 아래와 같은 프로그램을 만들 수 있습니다.

사용자 삽입 이미지
사용자 삽입 이미지

관련샘플 :


.


.


Posted by gsi
:

흑백의 이미지를 CxImage로 만들때 8비트, 24비트의 이미지로 만들 필요가 없습니다.
이때 1비트의 이미지로 해도 충분한 공간이 나온다는 얘긴데요.
아래의 코드는 1비트의 이미지를 생성하는 코드 입니다.

void GToleranceImage::MakeBuffer2Image()
{
 SAFE_DELETE( _pbuffer2Image );
 assert( _pbuffer2Image == NULL );
  // 넓이와 폭을 사용해서 이미지 버퍼를 생성합니다.
  // 이때 1비트의 이미지로 설정합니다.
 _pbuffer2Image = new CxImage( _width, _height, 1, CXIMAGE_FORMAT_BMP );

  // 이미지의 팔레트를 지정합니다.
  // 흑백 이미지를 만들거기 때문에 0번과 1번 팔레트를 설정합니다.
 _pbuffer2Image->SetPaletteColor(0, RGB(0, 0, 0));
 _pbuffer2Image->SetPaletteColor(1, RGB(255, 255, 255));

  // 해당 내용을 추가합니다.
  // SetPixelColor로 하지 않고, SetPixelIndex로 하게 됩니다.
 for( int y = 0; y < _height; y++ )
 {
  for( int x = 0; x < _width; x++ )
  {
   BYTE color = _bufferXY[y][x];
   if( color == 255 )
    _pbuffer2Image->SetPixelIndex( x, y, 1 );
   else
    _pbuffer2Image->SetPixelIndex( x, y, 0 );
  }
 }
 _pbuffer2Image->Flip();
}

Posted by gsi
:

사용자 삽입 이미지

그레이 스케일로 표현해주는 코드가 일부 들어가 있는 소스입니다.
MFC DLL 형태로 제작되어 있으며, 바로 이전의 게시물과 거의 동일한 구조입니다.
몇가지 단위 테스트를 위해서 제작된 샘플 프로젝트입니다.

관련 소스 :


.
Posted by gsi
:

사용자 삽입 이미지

MFC DLL : 한장의 이미지를 보여 주는 dll 파일입니다.
                현재 jpg의 파일만 인코딩이 가능합니다.
                (이 부분은 확장자를 사용해서 처리 하시면 됩니다. 아직 그건 추가 하지 않았네요. )

사용시에는 아래의 코드를 이용 하시면 됩니다.

 CDlgImage dlg( "E:\\Gsi_Project\\정상옥_프로젝트\\Project\\2008_06_23_LAM_ModuleTest\\bin\\blue.jpg" );
 dlg.DoModal();

이외의 생성자 인자로서는 해당 width, height를 입력해줄 수 있으며,
내부 코드에서는 해당 다이얼로그에 맞도록 리셈플링 처리가 되어 있습니다.


실행파일 :



.

프로젝트 파일 :


.

Posted by gsi
:


http://www.codeproject.com/KB/graphics/cximage.aspx

CxImage 6.0 Full 코드를 컴파일 해서
png, jpg, bmp, gif 를 지원하도록 처리 해서 생성해 놓은 코드 임.



.
Posted by gsi
:

데이터 암호화 방법

1.요약
데이터를 암호화하는 방법에는 여러가지가 있는데 가장 간단한 방법이 배타적 논리합(Exclusive OR)를 이용하는 방법이 있습니다.

이 방법은 너무 간단해서 보안에 치명적이죠. 특별한 암호방법을 고안해낼려면 그쪽 분야에 많은 연구와 노력이 필요한데 저를 포함해 대부분 암호화에 대한 지식이 거의 전무할겁니다.

저같은 사람들을 위해 MS에서 암호화를 위한 API를 제공하고 있습니다.
하지만 이것도 사용하기가 너무 복잡하고 여러 단계를 거져야하는 불편함이 있습니다.

그래서 최대한 사용하기 간단하게 Class로 만들어 보았습니다.


2.본문

먼저 암호에 필요한 API함수는 어떤것이 있는지 알아보겠습니다.
BOOL WINAPI CryptAcquireContext(HCRYPTPROV *phProv, LPCTSTR Container,
                LPCTSTR pszProvider, DWORD dwProvType, DWORD dwFlags);

BOOL WINAPI CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid,
                CRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash);

BOOL WINAPI CryptHashData(HCRYPTHASH hHash, BYTE *pbData,
                DWORD dwDataLen, DWORD dwFlags);

BOOL WINAPI CryptDeriveKey(HCRYPTPROV hProv, ALG_ID Algid,
                HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey);

BOOL WINAPI CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash,
                BOOL Final, DWORD dwFlags, BYTE *pbData,
                DWORD *pdwDataLen, DWORD dwBufLen);

BOOL WINAPI CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash,
                BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen);
자세한 사용법은 MSDN을 참고하세요.
이러한 API의 사용법을 설명하지 않겠습니다. 사실 저도 자세히는 모름니다. Class 멤버 함수와 사용법을 소개드리겠습니다.

BOOL CCrypt::Create(LPBYTE pHashData, DWORD dwHashDataLen)
- 암호화나 해독에 필요한 Key를 생성하는 함수. 쉽게 여기에 Password가 들어간다고 생각하면 됩니다.
void CCrypt::Destroy()
- Create에서 만들어진 Handle을 제거합니다.
BOOL CCrypt::Encrypt(LPBYTE lpBuffer, DWORD& dwBufferLen, BOOL bFanal)
- 데이터를 암호화하는 함수
BOOL CCrypt::Decrypt(LPBYTE lpBuffer, DWORD& dwBufferLen, BOOL bFanal)
- 암호화된 데이터를 해독하는 함수

3.예제

dwDataLen = strPassword.GetLength(); 
CopyMemory(lpData, (LPVOID)(LPCTSTR)strPassword, strPassword.GetLength()); 

// 암호화 
CCrypt Crypt; 
Crypt.Create((LPBYTE)(LPCTSTR)strPassword, strPassword.GetLength()); 
Crypt.Encrypt(lpData, dwDataLen); 
Crypt.Destroy(); 

// 암호화된 데이터 해독 
Crypt.Create((LPBYTE)(LPCTSTR)strPassword, strPassword.GetLength()); 
Crypt.Decrypt(lpData, dwDataLen); 
lpData[dwDataLen] = '\0'; 

::MessageBox(NULL, (LPCTSTR)lpData, "", MB_OK);
Crypt.zip 다운로드

















- 2001.08.19 Smile Seo -



http://www.debuglab.com/knowledge/dataencrypt.html

Posted by gsi
: