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
: