GSI

해당 블로그 : http://blog.naver.com/kellio?Redirect=Log&logNo=45119872
감사 ^^


/*******************************
*  BSTR 변수에 스트링 넣기
*******************************/

BSTR  bstrTemp;
wchar_t tchar[] = L"hello world";
bstrTemp = SysAllocString(tchar);
SysFreeString(bstrTemp);
 
 // HRESULT Tempfunc(BSTR bstrArg);
Tempfunc(bstrTemp);


// BSTR의 길이 구하기

SysStringLen(bstrTemp) 함수를 이용한다~

/*****************************
* LPCTSTR to BSTR
*****************************/

LPCTSTR lpStr= _T("hello world");

BSTR bstrStr;
bstrStr = ((CString)lpStr).AllocSysString();

/*****************************
* BSTR to CString
*****************************/

CString bstrToCString(BSTR bstr)
{
   char* pbstr;
   USES_CONVERSION;  //convert를 위한 매크로
   pbstr=OLE2A(bstr);     //bstr을 char로 convert
   return CString(pbstr);
}

/*****************************
* _bstr_t to CComBSTR
*****************************/

_bstr_t bstrStr(_T("This is the test String!"));
CComBSTR bstrComStr;
bstrComStr.AppendBSTR(bstrStr);
ShowBSTR(bstrComStr);

BSTR CStringTobstr(CString str)
{
    return str.AllocSysString();    //CString을 bstr로 convert
}

[bstr-> char*]

BSTR inputdata;
char *pbstr;
pbstr=OLE2A(inputdata);

[char* -> bstr]

TCHAR szTitle[ 512 ];
_bstr_t bstrText = szTitle;
*bstrTitle = bstrText.copy();

/*******************************
* CString to CComVariant
*******************************/

 CComVariant out(str.AllocSysString());  or  CComVariant out(str);

----------- VARIANT 구조체 사용예 ----------

VARIANT vVal;
VariantInit(&vVal); //초기화
vVal.vt = VT_BOOL;
vVal.boolVal = TRUE;

---------- BSTR 사용예 --------------

1) BSTR m_pStr;
m_pStr = L"Hello CodeIn"; // 문자의 개수가 지정되지 않음

2) wchar_t Example[] = L"String";
BSTR m_pStr = SysAllocString(Example); // BSTR 문자열 영역확보

//..

SysFreeString(m_pStr); // BSTR 문자열 영역 해제

Posted by gsi
:

1. HelloWorld라는걸 노출해줘야 다른 작업이 있는건지 궁금합니다.

           -> 메소드에 [WebMethod] 어트리뷰트를 설정해주는걸로 웹서비스 메소드로의 노출 작업은 완료된상태입니다.

 

2. 웹 서비스를 준비 하는 저의 입장에서 저희 서비스에만 사용하는 형태로 할건데요.

   고려사항이 어떤게 있을지 궁금합니다. 아울러 조금이라도 조언을 해주셨으면 좋겠습니다.

           -> 저희 서비스만 사용하는 형태로고 함은 이 public하게 노출된 웹서비스를 특정 시스템에서는 사용하게 하고프신 것 같은데요.

           웹서비스의 보안은 크게 3단계로 구분할 수 있는데요..

          

첫번째, IIS영역에서 요청(접근)을 제한하는 방법입니다. 웹서비스를 서비스하고 있는 웹 사이트의 IP 접근 제한을 하시면 되구요..

           접근하려는 시스템의 IP만을 접근 허용으로 해주시면 될 듯 합니다.

          

           두번째, 접근 하려는 웹메소드에서 호출하는 사용자를 식별하는 방법이 있습니다. 자세히 설명하기는 힘들지만 메소드를 호출할때

SoapHeader에 사용자 인증 정보를 담아 호출하여 메소드 실행직전에 인증정보가 유효한지를 확인합니다.

 

세번째, 네트워크를 통해 전송되는 웹서비스 결과를 모두 암호화 하여 데이
터에 대한 보안을 설정하실 수 있습니다.

 

각 자세한 방법은 인터넷이나 책을 통해 찾아보시면 될 것 같습니다.

 

3. 인터넷 정보 서비스의 ASP.NET 1.0.**, 2.0.*** 두개가 나오게 되는데요. 웹 서비스를 net 2.0으로 제작할 때

   ASP.NET 2.0.*** 을 사용하는데요 이것으로 해야 되는건지도 궁금합니다.

-> 네 닷넷 프레임워크의 1.1 2.0은 전혀 다른 런타임입니다. 하여 반드시 버전을 정확히 선택해줘야지만 올바른 실행이 가능합니다.


>>>

결과적으로 http:post 형태의 프로토콜을 지원 하기 위해서는 web.config 에 프로토콜을 추가해 주어야 합니다. 기본이 soap 형태만 지원하기 때문에...

<protocols>
   <add name="httpPost"/>
   <add name="httpGet"/>
   <remove name="httpPost/>
   <remove name="httpGet/>
</protocols>

Posted by gsi
:

DC 내용 복사해서 다른 곳의 DC에 적용하기

내용 구현 :

Flicker Free Code 사용한 클래스 의 이름을 CMemDC 라고 하겠습니다.
해당 코드는 위에 있습니다.

우선 CMemDC로 선언한 변수에 현재 화면에 그려진 DC를 적용시켜 줍니다.
m_pTestFormDlg->m_pParentMemDC = new CMemDC(pDC, &rect);

해당 pDC와 화면 영역 값을 넘겨 주면서 생성해 줍니다.
원래 이 부분의 rect는 제가 집어 넣은 겁니다. 안해주면 내부에서 GetClipRect()로 값을
구해서 적용하게 되어 있습니다.

DC와 같이 적용된 CMemDC 쪽에 BitBlt를 사용해서 해당 DC의 내용을 그립니다.
m_pTestFormDlg->m_pParentMemDC->BitBlt(
   0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);

이제 이 DC를 다른 곳에서 BitBlt를 해서 사용하시면 됩니다.
pdc->BitBlt(0, 0, 850, 666, m_pParentMemDC, 0, 0, SRCCOPY);

이상. ^^

Posted by gsi
:

void CChildView::SaveBitmapToDirectFile(CDC* pDC, CRect BitmapSize, int BitCount, CString strFilePath)
{
 CBitmap bmp, *pOldBmp;
 CDC dcMem; 
 BITMAP                  bm;
 BITMAPINFOHEADER        bi;
 LPBITMAPINFOHEADER      lpbi;
 DWORD                   dwLen;
 HANDLE                  handle;
 HANDLE                  hDIB;  
 HPALETTE                hPal=NULL;

 /*----- CDC의 내용을 Bitmap으로 전송 ----*/
 dcMem.CreateCompatibleDC(pDC);
 bmp.CreateCompatibleBitmap(pDC ,BitmapSize.Width(),BitmapSize.Height());   
 pOldBmp = (CBitmap*) dcMem.SelectObject(&bmp);
 dcMem.BitBlt( 0,0, BitmapSize.Width(), BitmapSize.Height(), pDC, 0,0, SRCCOPY);
 dcMem.SelectObject(pOldBmp);

 if (strFilePath == "")          return;
 /*------------------------- 비트멥 헤더를 기록함 -------------------------*/
 if (hPal==NULL)
  hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
 GetObject(HBITMAP(bmp), sizeof(BITMAP), &bm);

 bi.biSize               = sizeof(BITMAPINFOHEADER);
 bi.biWidth              = bm.bmWidth;
 bi.biHeight             = bm.bmHeight;
 bi.biPlanes             = 1;
 bi.biBitCount           = 32;      
 bi.biCompression        = BI_RGB;
 bi.biSizeImage          = bm.bmWidth * bm.bmHeight * 3;
 bi.biXPelsPerMeter      = 0;
 bi.biYPelsPerMeter      = 0;
 bi.biClrUsed            = 0;
 bi.biClrImportant       = 0;

 int nColors = (1 << bi.biBitCount);
 if( nColors > 256 )
  nColors = 0;
 dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);
 hPal = SelectPalette(pDC->GetSafeHdc(),hPal,FALSE);
 RealizePalette(pDC->GetSafeHdc());
 hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
 lpbi = (LPBITMAPINFOHEADER)hDIB;
 *lpbi = bi;
 GetDIBits(pDC->GetSafeHdc(),
  HBITMAP(bmp),
  0,
  (DWORD)bi.biHeight,
  (LPBYTE)NULL,
  (LPBITMAPINFO)lpbi,
  (DWORD)DIB_RGB_COLORS);
 bi = *lpbi;
 if (bi.biSizeImage == 0)
 {
  bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
   * bi.biHeight;
 }
 dwLen += bi.biSizeImage;
 if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
  hDIB = handle;

 lpbi = (LPBITMAPINFOHEADER)hDIB;
 GetDIBits(pDC->GetSafeHdc(),
  HBITMAP(bmp),
  0,                   
  (DWORD)bi.biHeight,     
  (LPBYTE)lpbi       
  + (bi.biSize + nColors * sizeof(RGBQUAD)),
  (LPBITMAPINFO)lpbi,  
  (DWORD)DIB_RGB_COLORS);

 BITMAPFILEHEADER      hdr;
 hdr.bfType        = ((WORD) ('M' << 8) | 'B');       
 hdr.bfSize        = GlobalSize (hDIB) + sizeof(hdr);  
 hdr.bfReserved1   = 0;                                
 hdr.bfReserved2   = 0;                                
 hdr.bfOffBits=(DWORD)(sizeof(hdr)+lpbi->biSize + nColors * sizeof(RGBQUAD));
 char* pBmpBuf;
 DWORD FileSize;
 FileSize=sizeof(hdr)+GlobalSize(hDIB);
 pBmpBuf = new char[FileSize];
 memcpy(pBmpBuf,&hdr,sizeof(hdr));
 memcpy(pBmpBuf+sizeof(hdr),lpbi,GlobalSize(hDIB));
 /*--------------------- 실제 파일에 기록함 --------------------------*/
 CFile file;
 file.Open(strFilePath, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite);
 file.Write(pBmpBuf,FileSize);
 file.Close();
 /*------------------------ 임시로 할당한 메모리를 해제.. -------------*/
 delete[] pBmpBuf;

 if(hDIB)
 {      
  GlobalFree(hDIB);
 }
 SelectPalette(pDC->GetSafeHdc(),hPal,FALSE);   
}

Posted by gsi
:

CScrollView를 사용해서 화면을 처리 하다 보면 셀 단위의 뷰를구현할때 즉, 화면이 일정 범위의 간격을 두고 움직이고자 할때 스크롤 바를 움직이면 한픽셀씩 움직이지 않고 한 단위씩 움직이도록 하고자 할때가 있다. 이때는 OnVScroll()를 오버라이드 한다.

void CColorPlayScrollView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 UINT newpos = 0;
 switch(nSBCode) {
  case SB_LINEUP:
  case SB_LINEDOWN:
  case SB_PAGEUP:
  case SB_PAGEDOWN:
  case SB_THUMBPOSITION:
  case SB_THUMBTRACK:
  case SB_TOP:
  case SB_BOTTOM:
  case SB_ENDSCROLL:
   {
    if(nPos%30 == 0) {
//     SetScrollPos(SB_VERT,nPos,TRUE);
     CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
    }
   }
   break;
 }

// SetScrollPos(SB_VERT,newpos,TRUE);

// CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}

여기서 모든 메시지를 가져와서 해당 값이 되었을때만 호출하도록 처리 해봤습니다.
CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
이 함수를 호출하면 화면이 이동 되도록 해봤습니다. 결과는 아래와 같아요.^^

사용자 삽입 이미지

Posted by gsi
:

mfc 프로젝트 생성후에 dll을 추가해서 사용할때 실행 파일과 동일한 경로에 해당 데이터들이 있어야 한다.

속성 페이지에서 몇가지 만져 줘야 하는데요.

아래와 같습니다.

dll 프로젝트 생성시...
1. 일반 항목
   - 출력 디렉터리 = $(SolutionDir)lib
   - 중간 디렉터리 = $(SolutionDir)/Obj/$(ProjectName)/Debug

2. 링커 항목
   - 출력파일 = $(SolutionDir)lib\TestForm1.dll

3. 빌드 이벤트 > 빌드 후 이벤트 항목
   - 명령줄 = xcopy $(SolutionDir)\lib\TestForm1.dll $(SolutionDir)\bin\ /y
     ( dll 을 복사한다.)
Posted by gsi
:

기존 CScrollView를 사용하면서 mfc의 DC 드로잉 부분에서 부족했던 저로서는 번쩍 거리는 화면이 너무 안좋게 보였습니다.
하지만 지금 테스트해본 결과가 맞는 정답은 아니겠지만 많은 부분 개선되는 것을 확인했습니다.

스크롤 사이즈를 10240000 까지 늘려서 테스트를 진행했습니다.
sizeTotal.cx = sizeTotal.cy = 10240000;
SetScrollSizes(MM_TEXT, sizeTotal);

미리 선과제로 OnEraseBkgnd()는 return false로 변경을 하고 시작했습니다.

BOOL CScrollViewTestView::OnEraseBkgnd(CDC* pDC)
{
     return false;
}

하나더 해줘야 할게 CScrollView의 스크롤이 16bit로 되는 현상을 32bit로 전환처리. (이건 제 블로그나 기타 다른 곳에도 기술되어 있습니다.)

BOOL CScrollViewTestView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
{
 // When you drag the scroll box, the nPos value send from WM_HSCROLL/WM_VSCROLL is 16bit value.
 // Therefore retrieve the 32bit scroll box position value.
 if(SB_THUMBTRACK == LOBYTE(nScrollCode)) // WM_HSCROLL
 {
  SCROLLINFO info;
  if(GetScrollInfo(SB_HORZ, &info, SIF_TRACKPOS))
  {
   nPos = info.nTrackPos; // 32bit position value.
  }
 }
 else if(SB_THUMBTRACK == HIBYTE(nScrollCode)) // WM_VSCROLL
 {
  SCROLLINFO info;
  if(GetScrollInfo(SB_VERT, &info, SIF_TRACKPOS))
  {
   nPos = info.nTrackPos; // 32bit position value.
  }
 }

 return CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);
}

이후에 OnDraw(CDC* pDC) 에서 테스트를 했습니다.

스크롤 내부의 총 사이즈를 사용해서 드로잉을 해봤습니다.

CSize size = GetTotalSize()
... 중략...
 for(int x = 0; x < size.cx; x += 10) {
  pDC->MoveTo(x, 0);
  pDC->LineTo(x, size.cy);
 }

 for(int y = 0; y < size.cy; y += 10) {
  pDC->MoveTo(0, y);
  pDC->LineTo(size.cx, y);
 }

이렇게 테스트를 하니까. tick를 찍어 봤을때 2250 이 나오네요. -.-;

그래서 우선  Flicker Free Drawing 를 사용해서 해봤습니다.

 CRect rcBounds = CRect(0, 0, size.cx, size.cy);
 CMemDC pDCEx(pDC);
 pDCEx->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

 for(int x = 0; x < size.cx; x += 10) {
  pDCEx->MoveTo(x, 0);
  pDCEx->LineTo(x, size.cy);
 }

 for(int y = 0; y < size.cy; y += 10) {
  pDCEx->MoveTo(0, y);
  pDCEx->LineTo(size.cx, y);
 }

하지만 tick는 2500 으로 더 많게 되네요. 왜냐하면. 메모리 DC를 만들고 하다 보니 그런거 같아요.

그래서 스크롤은 안보이는 부분을 드로잉하지 않는 처리를 해야 하는거 같아서
아래와 같이 값을 구한다음에 처리를 해봤습니다.

 CSize size = GetTotalSize();  // 페이지의 총 사이즈(안보이는 부분까지 싹다)
 CRect clientRect;
 GetClientRect(&clientRect);    // 현재 화면에 보이는 클라이언트 정보

 CPoint scrollpos = GetScrollPosition();  // 스크롤 된 위치 좌측 상단
 CPoint devicescrollpos = GetDeviceScrollPosition();  // 디바이스별... 이건 위와 같네요(현재 상태에서는)

// 드로잉 간격을 10씩 했기 때문에 시작 지점을 보정해 줬습니다.
 CPoint startpos = CPoint(scrollpos.x%10, scrollpos.y%10);
 startpos.x = scrollpos.x - startpos.x;
 startpos.y = scrollpos.y - startpos.y;

// 시작지점과 클라이언트 영역을 사용해서 끝 점을 구했습니다.
 CPoint endpos = CPoint(scrollpos.x + clientRect.Width(), scrollpos.y + clientRect.Height());

드로잉은 아래와 같이 테스트...

 CRect rcBounds = CRect(0, 0, size.cx, size.cy);
 CMemDC pDCEx(pDC);
 pDCEx->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

 for(int x = startpos.x; x < endpos.x; x += 10) {
  pDCEx->MoveTo(x, 0);
  pDCEx->LineTo(x, size.cy);
 }

 for(int y = startpos.y; y < endpos.y; y += 10) {
  pDCEx->MoveTo(0, y);
  pDCEx->LineTo(size.cx, y);
 }

이렇게 작업을 해서 안보이는 부분을 처리 했습니다.
처음 시작할때는 조금 딜레이가 있지만. 번쩍 거리는 현상의 거의 없어 지네요.
앞으로 복잡한 부분이 아닌 적당한 드로잉 방법에는 Flicker Free Drawing를 사용해야 겠습니다. ^^..


여기서 사용한 CMemDC는 아래 코드가 있습니다.




스크롤 테스트한 총 예제는 아래 코드..

Posted by gsi
:

웹 서비스 연동 방법 - <웹 서비스를 사용하다.!>

웹 서비스를 이용하면 응용 프로그램을 서버를 경유 하지 않고, 네트윅을 접근할 수 있다는 장점이 있습니다.
그래서 이번 프로젝트는 응용 프로그램 + 웹 서비스를 연동해서 어플리케이션을 제작할려고 합니다.
그 내용 중에서 웹 서비스 최초 연동 부분만 우선 살펴 보겠습니다.

웹 서비스를 제작하기 위해서 프로젝트를 생성합니다.
참고로 전 2008 beta2를 만지고 있어서 그쪽에서 했습니다.

사용자 삽입 이미지


ASP.NET Web Service 를 선택하고 File System, C#을 선택한 후에 프로젝트를 생성합니다.

테스트기 때문에 HelloWorld를 그대로 사용하겠습니다.

    [WebMethod]
    public string HelloWorld() {
        return "Hello World";
    }

이후에 서비스를 사용할 클라이언트를 만들어야 하는데요.
전 mfc로 싱글뷰를 사용했습니다.
내부에 MFC 확장 DLL을 사용해서 CDialog를 상속 받은 클래스를 하나 제작하고
그 쪽에서 웹 서비스를 연동해 봤습니다. (결과는 잘 되는군요.)

우선 웹 서비스를 참조 해야 하기 때문에 웹 서비스를 iis쪽에 등록 하시던지 간단하게
 테스트만 할 거라면 우선 디버그 상태로 뛰우게 되면 아래와 같은 임시 주소가 생기게 됩니다.
이거 보면서 참 편하다는 생각이 들었죠.

이 주소가 나왔으니 mfc 프로젝트에서 참조 추가를 해보겠습니다.
사용자 삽입 이미지
위와 같이 참조 라는 곳에서 "웹 참조 추가"를 선택 합니다.

사용자 삽입 이미지

이런 화면이 나오게 되는데요 여기서 URL 쪽에 아까 디버그로 실행한 웹 주소나 iis에 추가한
주소를 적어 주시고 "이동" 버튼을 누르면 해당 내용이 나오게 됩니다.
웹 참조 이름은 다르게 수정이 가능합니다.

"참조 추가" 버튼을 누르면 프로젝트에 포함이 됩니다.
사용자 삽입 이미지
이런 몇개의 파일이 자동으로 생성되게 됩니다.
이제 이것을 사용하기 위해서 우선 클래스 상태를 보기 위해서 "개체 브라우저"를 엽니다.
사용자 삽입 이미지
위와 같이 LoginSvr 이라는 네임 스페이스와 CLoginSvr 이라는게 보입니다.
CLoginSvr은 아래와 같이 typedef 되어 있네요.

typedef class LoginSvr::CLoginSvrT<> CLoginSvr
    LoginSvr의 멤버

이제 사용하는 방법만 남았네요.
아래와 같이 사용해서 처리 하시면 됩니다.

LoginSvr::CLoginSvr svr;
BSTR bstrStatus2;
svr.HelloWorld(&bstrStatus2);
m_szEdit = bstrStatus;
::SysFreeString( bstrStatus2 );
UpdateData(false);

여기서 보면 C#이나 asp.net 쪽의 프로그램과는 좀 불편한 감이 있네요.
HelloWorld()의 형태가 인자가 없고 리턴을 string 형태로 받게 되어 있지만
mfc 쪽에서 사용할때는 인자 형태의 포인터로 받게 되어 있으며 stringBSTR 형태로
 취환이 되어서 처리 되게 되어 있습니다.

아.. 이 내용은 대충 여기까지..
앞으로 작업 하면서 여러가지 문제점에 봉착할거 같은데요. 우선 세세하게 작업 내용들을 올리도록 할께요 ^^.
Posted by gsi
:

CScrollView 클래스는 스크롤바 관련 메시지 처리를 구현하고 있다. CSrollView::OnHScroll(), CScrollView::ONVScroll() 루틴이 그것인데, 이 두 루틴은 CScrollView::OnScroll()를 호출하도록 구현하고 있다.

그런데 스크롤 메시지(WM_HSCROLL/WM_VSCROLL)의 스크롤 코드가 SB_THUMBTRACK일때, wParam의 상위 워드(16bit)로 전달되는 스크롤 박스의 현재 위치 값이 CScrollView::OnScroll()의 nPos 파라미터로 전달되어 그대로 사용된다. SB_THUMBTRACK이 아닌 다른 스크롤 코드에 대해서는 CScrollView::OnScroll() 루틴이 직접 GetScrollPos() 함수를 호출함으로 스크롤 박스의 현재 위치 값이 32bit값으로 사용된다.

CScrollView::SetScrollSizes()를 사용하여 스크롤 뷰의 크기를 일반적으로 크게 설정할 때, (맵핑모드에 따라 차이는 있겠지만) 결과적으로 다바이스 단위로 변환된 스크롤 뷰의 크기가 16bit int(0 ~ 32767)의 범위를 넘어가면 문제가 발생한다. 스크롤바의 스크롤 박스를 마우스로 드래그할 때 (즉, SB_THUMBTRACK 코드가 발생될 때) 드래그 위치가 16bit int 값으로 짤려서 전달되기 때문에 음수로 해석이 되어 스크롤 박스위치가 0으로 리셋되는 (튕겨지는) 현상이 발생한다.

이 문제를 해결하려면 아래의 예와 같이 CScrollView::OnScroll()를 오버라이드 해야 한다. 다행이 CScrollView::OnScroll()은 버추얼 함수로 되어 있다.

BOOL CPixelMapView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
{
 // When you drag the scroll box, the nPos value send from WM_HSCROLL/WM_VSCROLL is 16bit value.
 // Therefore retrieve the 32bit scroll box position value.
 if(SB_THUMBTRACK == LOBYTE(nScrollCode)) // WM_HSCROLL
 {
  SCROLLINFO info;
  if(GetScrollInfo(SB_HORZ, &info, SIF_TRACKPOS))
  {
   nPos = info.nTrackPos; // 32bit position value.
  }
 }
 else if(SB_THUMBTRACK == HIBYTE(nScrollCode)) // WM_VSCROLL
 {
  SCROLLINFO info;
  if(GetScrollInfo(SB_VERT, &info, SIF_TRACKPOS))
  {
   nPos = info.nTrackPos; // 32bit position value.
  }
 }

 return CZoomView::OnScroll(nScrollCode, nPos, bDoScroll);
}

발췌 : http://blog.naver.com/lonekid?Redirect=Log&logNo=60045291285
감사 ^^.

Posted by gsi
:

1. C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 의 등록정보의 보안 탭에 ASP.NET 계정을 추가한다. 쓰기 속성을 부여 한다.
2. C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 에서 아래와 같이 적용합니다.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -r
ASP.NET(2.0.50727)을 설치하고 모든 스크립트맵의 ASP.NET DLL을 현재 버전으로 바꿉
니다.
......................................
ASP.NET(2.0.50727)을 설치하고 모든 스크립트맵의 ASP.NET DLL을 현재 버전으로 바꿨
습니다.

이렇게 하니까 되었네요.
혹시 몰라서 .net 3.0도 지웠는데.. 움.. 이건 상관이 없는듯 보이는데요.
Posted by gsi
:

GDI+ 를 하다 보면 일반 string 을 그대로 사용하지 못한다. wchar로 바꿔서 해야 하는데 이때 이것을 사용하자.

  char* -> wchar를 바꾸는 방법
  std::string 이라면 str.c_str()을 넘겨주자.


  LPWSTR lpszW = new WCHAR[MAX_PATH];
  int nLen = MultiByteToWideChar(CP_ACP, 0, pstrSrc, -1, NULL, NULL);
  MultiByteToWideChar(CP_ACP, 0, pstrSrc, -1, lpszW, nLen);

Posted by gsi
:

CDialog를 서브클래싱 해서 다른 컨트롤에 적용할려고 할때 보통 Create를 오버라이드 해서 사용하게 되는데 이때 보면 Create의 원형은 아래와 같습니다.

BOOL CGDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
{
 return CDialog::Create(lpszTemplateName, pParentWnd);
}


하지만 여기서 보면 Dialog 니까. Dialog의 아이디를 넣으면 되겠지 하지만 이건 int 형을 LPCTSTR형으로 바꿀수 없다는 에러만 발생하게 됩니다. (솔직히 TemplateName라는게 어떤건지 잘 모르겠습니다.

하지만 우리가 알고 있는 Dialog의 아이디 값을 LPCTSTR형으로 바꾸어 주는 함수를 사용하면 됩니다.

보통 다른 컨트롤에서 생성하기 때문에 Create를 하나더 만듭니다.
왜냐하면 굳이 아이디 값을 노출하거나 더 적어줄 필요가 없으니 아래와 같이 함수를 만들면 될듯합니다.

BOOL CGDialog::Create(CWnd* pParentWnd)
{
 return Create(MAKEINTRESOURCE(IDD_GDIALOG), pParentWnd);
}


여기서 보는바와 같이 MAKEINTRESOURCE 라는 디파인 문을 사용하면 LPCTSTR형태로 변환해 주면 가능합니다.

위의 함수를 다른 컨트롤 쪽에서 아래와 같이 사용하면 해당 컨트롤에 추가해서 사용할 수 있습니다.

 m_Dialog.Create(this);
 m_Dialog.ShowWindow(SW_SHOW);
 m_Dialog.MoveWindow(CRect(200, 200, 400, 400));


[팁]
다이얼로그의 스타일이 3가지가 있는데요. Overlapped, PopUp, Child 형태가 있습니다.
Overlapped, PopUp 형태로 하게 되면 컨트롤에 추가 되지만 컨트롤 안에 종속되지는 않네요. 밖으로 이동이 가능하게 되는데요 꼭, 모달 다이얼로그와 비슷한 형태인듯 합니다.
그리고 Child 형태로 하게 되면 컨트롤 내부에서만 동작을 하게 되네요.

이때 타이틀바가 나오거나 안나오거나 상관 없이 동작하게 됩니다.

Posted by gsi
:

사용자 삽입 이미지

MFC 에서 싱글뷰로 해서 Doc 없애고, CChildView로만 생성했습니다.
내부에 Static, Button을 서브클래싱 해서 클래스를 각각 제작.

CChildView 내부에 멤버 변수로 선언
CGStatic m_Static;
CGButton m_Button;


OnCreate 함수를 오버라이드 하여 컨트롤을 생성합니다.
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CWnd::OnCreate(lpCreateStruct) == -1)
  return -1;

 m_Static.Create("test", WS_CHILDWINDOW|SS_NOTIFY, CRect(10, 10, 100, 100), this, 1000);
 m_Static.ShowWindow(SW_SHOW);

 m_Button.Create("", WS_CHILDWINDOW, CRect(100, 100, 200, 200), this, 1001);
 m_Button.ShowWindow(SW_SHOW);

 return 0;
}


CStatic 컨트롤의 마우스 이벤트를 먹게 할려면 SS_NOTIFY를 추가해야 합니다.

CStatic, CButton의 마우스 이벤트 코드는 동일하기 때문에 CButton 의 내용만 서술합니다.
이전 위치를 기억 하기 위해서 변수를 하나 생성
CPoint  oldPos;

생성자 쪽에서 초기화를 해줍니다.
oldPos = CPoint(0, 0);

나머지 OnLButtonDown, OnLButtonUp, OnMouseMove 이벤트를 추가하고
아래와 같이 작성해 줍니다.
void CGButton::OnLButtonDown(UINT nFlags, CPoint point)
{
 SetCapture();
 
 // 최초 위치를 oldpos에 입력하고 시작한다.
 CPoint curpos;
 GetCursorPos(&curpos);
 GetParent()->ScreenToClient(&curpos);
 oldPos = curpos;

 CButton::OnLButtonDown(nFlags, point);
}

void CGButton::OnLButtonUp(UINT nFlags, CPoint point)
{
 ReleaseCapture();
 CButton::OnLButtonUp(nFlags, point);
}

void CGButton::OnMouseMove(UINT nFlags, CPoint point)
{
 if(GetCapture() == this) {

  // 현재 컨트롤이 포함되어 있는 부모 컨트롤에서의 위치값을 가져온다.
  CRect thisRect;
  GetWindowRect(&thisRect);
  GetParent()->ScreenToClient(&thisRect);

  // 현재 마우스 위치값을 컨트롤의 위치 값으로 변환한다.
  CPoint curpos;
  GetCursorPos(&curpos);
  GetParent()->ScreenToClient(&curpos);

  // 변경된 위치값을 사용해서 이동범위를 구한다.
  CPoint newpos = curpos - oldPos;

  // 이동할 위치와 크기값을 보정한다.
  thisRect.left += newpos.x;
  thisRect.top += newpos.y;
  thisRect.right = thisRect.left+100;
  thisRect.bottom = thisRect.top+100;
 
  // 윈도우를 이동시킨다.
  MoveWindow(&thisRect);

  // 계속 움직임을 위해서 현재 값을 저장한다.
  oldPos = curpos;

  Invalidate();
 }

 CButton::OnMouseMove(nFlags, point);
}

Posted by gsi
:

버튼을 CView에 추가..

 m_Button.Create("", WS_CHILDWINDOW, CRect(50, 100, 150, 200), this, 1001);
 m_Button.ShowWindow(SW_SHOW);


그리고 버튼 내부에 클릭 이벤트를 통해서 해당 위치에 버튼을 MoveWindow 시켜보자.

void CGButton::OnLButtonUp(UINT nFlags, CPoint point)
{
 CPoint curpos;
// 커서의 스크린 위치를 가져온다.
 GetCursorPos(&curpos);
// 부모 객체에서의 스크린 좌표를 클라이언트 좌표로 바꾼다.
 GetParent()->ScreenToClient(&curpos);
// 좌표값을 사용해서 윈도우의 크기를 지정한다.
 CRect rt(curpos.x, curpos.y, curpos.x+100, curpos.y+100);
// 자신 객체를 이동시킨다.
 MoveWindow(&rt);

 CButton::OnLButtonUp(nFlags, point);
}


이 코드가 완성되었으니. 클릭후 드래그로 컨트롤을 View에서 이동가능할듯 하다. ^^
(아마도 다 아는거겠지만. 요즘 mfc에 대해서 조금씩 방법적인 면이 늘어 나는거 같다.)

Posted by gsi
:


The Sysinternals web site was created in 1996 by Mark Russinovich and Bryce Cogswell to host their advanced system utilities and technical information. Microsoft acquired Sysinternals in July, 2006. Whether you’re an IT Pro or a developer, you’ll find Sysinternals utilities to help you manage, troubleshoot and diagnose your Windows systems and applications. If you have a question about a tool or how to use them, please visit the Sysinternals Forum for answers and help from other users and our moderators.

Featured Resources



What's New (November 27th, 2007)

This Zoomit update enables you to center the mouse with the space bar when in drawing mode, adds an option to view time elapsed after the break timer expires, and reverses the keys used to draw lines and arrows.

PsExec’s new release fixes a bug in the -i option that prevented it from correctly displaying windows on the console desktop.

What's New (November 5th, 2007)

Introducing ADInsight, an LDAP (Light-weight Directory Access Protocol) real-time monitoring tool aimed at troubleshooting Active Directory client applications. Use its detailed tracing of Active Directory client-server communications to solve Windows authentication, Exchange, DNS, and other problems.

This version of PsExec, a command-line tool for executing programs locally and remotely, significantly improves handling of arguments passed to the specified application by not modifying spacing or quotation marks. It also fixes a number of minor bugs, including ones related to running programs in alternate terminal server sessions.

What's New (October 26th, 2007)

This update to Process Explorer, an advanced process information utility, has a number of miscellaneous improvements. For example, the thread support in the process properties dialog is enhanced with Wow64 thread stacks on 64-bit Windows and kernel stacks on Windows Vista and Server 2008. In addition, tooltips on the service hosting processes now show service names, the user SID is displayed on the security properties page, and column headers have tooltips when they’re too small to display their text.

What's New (October 15th, 2007)

See how Mark uses the Windows Debugger and Sysinternals Process Explorer to troubleshoot a Windows Vista Sidebar Clock gadget issue. This example will show how symbols can be leveraged for deep Windows troubleshooting.

This Handle update adds support for Vista object types and the –accepteula switch.

Next month Mark will be speaking at Microsoft's TechEd IT-Forum International on several Windows kernel, security, and troubleshooting topics.

What's New (October 3rd, 2007)

Check out Mark's new blog where he uses Process Monitor to uncover the root cause for a file copy error. Process Monitor is uniquely useful for exposing file, registry, and process activity within Windows.

What's New (September 28th, 2007)

Version 4.11 comes with a couple bug fixes and now supports images that span multiple monitors! See the site blog for more details on the bug fixes.

What's New Archive

Posted by gsi
: