안녕하세요

프로그램 과정에서 막혔던 문제들에 대한 해결책 정리


페이지 목록

2013년 1월 25일 금요일

Unresolved Externals 해결 방법

참조 : http://www.chilkatsoft.com/p/p_124.asp

Win32 Visual C++ 링커 문제를 해결하는 방법을 알려드립니다.

아래와 같이 문제가 있을 때,

ChilkatDbgDll.lib(CryptoSP.obj) : error LNK2001: unresolved external symbol __imp__CryptAcquireContextA@20
ChilkatDbgDll.lib(Hashing.obj) : error LNK2019: unresolved external symbol __imp__CryptGetHashParam@20 referenced in function "public: bool __thiscall Hashing::hashSha1(class DataBuffer const &,class DataBuffer &,class LogBase &)" (?hashSha1@Hashing@@QAE_NABVDataBuffer@@AAV2@AAVLogBase@@@Z)
ChilkatDbgDll.lib(Hashing.obj) : error LNK2019: unresolved external symbol __imp__CryptDestroyHash@4 referenced in function "public: bool __thiscall Hashing::hashSha1(class DataBuffer const &,class DataBuffer &,class LogBase &)" (?hashSha1@Hashing@@QAE_NABVDataBuffer@@AAV2@AAVLogBase@@@Z)
…
여기에는 몇개의 unresolved 한 함수가 있습니다.
CryptAcquireContextA
CryptGetHashParam
CryptDestroyHash

등인데요. ( "___imp___" 와 "@" 뒤에 나오는 쓰레기 값들은 그냥 C++에서 이름을 알아 보기 힘들게 만들어 놓은 거니깐 무시하세요)
A로 끝나는 함수는 ANSI version의 함수고, W로 끝나는 것은 Unicode 버전 입니다.

A 와 W 를 없애면
CryptAcquireContext
CryptGetHashParam
CryptDestroyHash

함수가 나타나는데, 이제 검색엔진을 이용해서 위 함수를 검색하세요.
search engine (Yahoo, Microsoft, Google, etc.) "site:microsoft.com"
등에서 MSDN result 페이지가 나오면, 맨 밑의 Requirements 세션으로 가서,
무슨 Library가 필요한지 찾아서, VC++ Project에 add 하면 됩니다.

libcurl 설치 중 Libcurl.dll 빌드 시 문제

Linking...
   Creating library DLL-Debug/libcurld_imp.lib and object DLL-Debug/libcurld_imp.exp
md5.obj : error LNK2001: unresolved external symbol __imp__CryptCreateHash@20
md5.obj : error LNK2001: unresolved external symbol __imp__CryptAcquireContextA@20
md5.obj : error LNK2001: unresolved external symbol __imp__CryptHashData@16
md5.obj : error LNK2001: unresolved external symbol __imp__CryptReleaseContext@8
md5.obj : error LNK2001: unresolved external symbol __imp__CryptDestroyHash@4
md5.obj : error LNK2001: unresolved external symbol __imp__CryptGetHashParam@20
DLL-Debug/libcurld.dll : fatal error LNK1120: 6 unresolved externals
Error executing link.exe.

Unresolved Externals 문제는 환경 세팅 (lib 파일을 제공하지 않는 문제) 로 인해 발생하는 거 같습니다.
위 문제에 대한 해결책을 제시합니다.

Project -> Settings -> Link -> Object/library modules 에

Windows Server Platform SDK 의 AdvAPI32.lib 파일을 추가합니다.

아래의 Windows Server Platform SDK를 참조하세요.

http://dreamchallenger.blogspot.kr/2013/01/msvc-60-windows-server-psdk.html

MSVC 6.0 용 Windows Server PSDK 설치 방법

http://social.msdn.microsoft.com/Forums/en/windowssdk/thread/e1147034-9b0b-4494-a5bc-6dfebb6b7eb1

위 사이트가 MSVC 6.0에서 사용할 수 있는 마지막 PSDK

Microsoft Platform SDK Febuary 2003 (Last version with VC6 support)

을 받을 수 있는 사이트 입니다.

다운 받은 후,

cmd 창을 넣어, 다운 받은 폴더로 이동 후

PSDK-FULL Setup Folder 하면 설치파일이 인스톨 됩니다.

예) PSDK-FULL C:\

이렇게 하여, 다운로드 후, setup 파일을 클릭하면 Setup 할 수 있는

인터넷 창이 나타나고, 거기서 Install 하면 됩니다.

Install 완료 후에는,

MSVC 6.0에 환경 설정을 해야 합니다.

MSVC 6.0 -> Tool -> Option -> Directories 로 이동하여,

Include Files 항목에

설치 된 경로의 Include 폴더를 넣은 후, 맨 위로 올립니다.

예) C:\Program Files\MICROSOFT PLATFORM SDK\INCLUDE

library Files 항목에

설치 된 경로의 Lib 폴더를 넣은 후, 맨 위로 올립니다.

이제, Windows Server PSDK 를 사용할 수 있습니다.

2013년 1월 17일 목요일

[MFC] OnEraseBkgnd 사용해서 배경화면 그리기

 각탭을 구성하는 대화상자인 TabView1, TabView2 의 배경색을 
 변경하고자 한다면 OnPaint 가 아닌 OnEraseBkgnd 함수에서 하셔야 합니다. 

 WM_ERASEBKGND 메시지는 대화상자기반에서 클래스위저드 목록에 나오지않습니다. 하지만, 설정
 만 조금 바꾸시면 사용하실수 있습니다. ^^;; 일단, 클래스 위저드를 실행하고.. class info 탭을 
 선택하고, Message filter를 Dialog에서 window로 바꾸어 주시고 다시 Message Maps에 가시면 
 해당 메시지가 보일겁니다... ^^;

출처 : http://www.tipssoft.com/bulletin/board.php?bo_table=QnA&wr_id=10381

위와 같이 WM_ERASEBKGND 메세지를 이용하여,
OnEraseBkgnd를 사용한다.

BOOL CHoneybeeView::OnEraseBkgnd(CDC* pDC)
{
 // TODO: Add your message handler code here and/or call default
 CBrush backBrush(RGB(255, 255, 255)); // <- 흰색칼러로.
 CBrush* pOldBrush = pDC->SelectObject(&backBrush);
 CRect rect;
 pDC->GetClipBox(&rect);
 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
 pDC->SelectObject(pOldBrush);

 return TRUE; //흰 배경이 아닌 배경을 그리면 true, 흰 배경 false
}

OnEraseBkgnd 함수에 위와 같이 넣으면, RGB 컬러로 배경이 지정되게 된다.

OnEraseBkgnd는 OnDraw와 달리, 배경을 그려주는 것이라서,

새로 배경을 그리게 될 때, 다른 탭 위에 나타나지 않는 듯하다.

OnDraw의 경우, 새로 그릴 때, 탭 위에 잠시 나타났다 사라지지만,

OnEraseBkgnd의 경우는 그렇지 않다.

2013년 1월 16일 수요일

[MFC] Bitmap의 크기 알아내는 방법

비트맵 이미지 크기를 알아 낼 수 있다. 가로, 세로... 즉, 이미지 사이즈.

[Source Code]        :
     CBitmap m_bitmap;
     m_bitmap.LoadBitmap(IDB_BITMAP1);     // 비트맵 로드...
        :
     BITMAP bmp;
     m_bitmap.GetObject(sizeof(BITMAP), &bmp);   // 비트맵 오브젝트

    // bmp.bmWidth, bmp.bmHeight  이용하여 가로, 세로 크기 알수 있다....

     //CString str;                   // 확인을 위해서.... 메세지 박스로...  여기서 부터는 사실상 필요 없는 코드...
     //str.Format("%d, %d", bmp.bmWidth, bmp.bmHeight);
     //AfxMessageBox(str);          
출처 : http://i0nucleus.egloos.com/2737113

[MFC] Bitmap 출력하기

BITMAP
DIB(Device Independent Bitmap, *.bmp)
- 장치 독립적 : *.bmp로 존재 하며 운영체제에서 사용하기 위해서 DDB로 변환하는 작업을 거처야 한다.
DDB(Device Dependent Bitmap, *.raw)
- 장치 종속적 : 해당 장치에서만 사용

Window 생성시 반드시 생성되는 것
- Message Queue
- DC → CGDIObject [ (CBitmap), (CPen, CBrush, CFont) ]
- CBitmap :     GDIObject 3개와는 성격이 다르다, 도화지의 성격,
                SelectObject 사용으로 CBitmap 변경시 도화지가 바뀐다.

DC 생성 (메모리 DC)
- Window 생성시 기본으로 생성되는 DC 외에 사용자가 추가로 DC를 생성할수있다, 이를 메모리 DC라 부른다.

CBitmap class
BITMAP을 사용에 필요한 API를 모아놓은 MFC Class

Member Function
LoadBitmap( UINT nIDResource );
- 비트맵 리소스를 읽어온다, DIB 포맷을 DDB 포맷으로 변환.

BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );
- 하나의 DC에 있는 비트맵을 다른 DC로 복사하는 비트맵 함수

StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
- BitBlt와 동작하는 방식이 같다, 크기와 높이를 따로 지정할 수 있어 확대및 축소 복사가 가능.

GetBitmap( BITMAP* pBitMap );
- BITMAP 정보를 BITMAP Struct에 넘겨준다.

Example
CPaintDC dc(this);
CDC temp_dc;
//temp_dc.CreateDC( ... ); // 속성을 다 지정해야 한다.
temp_dc.CreateCompatibleDC(&dc); // 넘겨받은 dc와 호환가능한 DC를 생성한다.
temp_dc.SelectObject(&m_my_bitmap); //CBitmap class  멤버변수 m_my_bitmap 선언
dc.BitBlt(200, 0, 60, 60, &temp_dc, 50, 50, SRCCOPY);
dc.DeleteDC();












① - 전체 window
② - 전체 window중 bitmap이 보여질 위치 및 범위.

***위 함수를 이용한 간단한 Bitmap 출력하기

비트맵 로드는 OnCreate()에서 하고
그리기 코드는 OnDraw() 내에서 실행함.

int CTetris_copyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO: Add your specialized creation code here
   CBitmap m_coverBitMap; // Bitmap 변수를 선언하고 그 변수에 LoadBitmap 하여
                                            // Bitmap 로드함
    m_coverBitMap.LoadBitmap(IDB_BITMAP1);
    return 0;
}

void CTetris_copyView::OnDraw(CDC* pDC)
{
    CTetris_copyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);
    CBitmap *pOldBitmap = memDC.SelectObject(&m_coverBitMap);
    pDC->BitBlt(0, 0, 715, 543, &memDC, 0, 0, SRCCOPY);
    memDC.SelectObject(pOldBitmap);
    memDC.DeleteDC();
}

출처 : http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=68372414&qb=bWZjIG9uZHJhdyBiaXRtYXA=&enc=utf8&section=kin&rank=1&search_sort=0&spq=0&pid=RniKs35Y7thssc3XcGCsssssssh-101170&sid=UPZLTHJvLBYAAH4LFTU

2013년 1월 4일 금요일

[MFC] 실행 중인 프로그램 리스트를 얻어오고 제어하기

<<함수 선언부>>

//콜백 함수 선언
BOOL CALLBACK EnumWindowCallBack(HWND hwnd, LPARAM lParam);
//

<<InitInstance() 내부에 선언>>

// 이미 프로그램이 실행 중이면 종료하고 아니면, 업데이트 진행
BOOL RTSnotRun = EnumWindows(EnumWindowCallBack,0);

 if(RTSnotRun == FALSE)
 {
  AfxMessageBox("프로그램 종료 후 실행해 주시기 바랍니다.");
  return FALSE;
 }
 //

<<CallBack 함수 선언>>

//프로그램 이름 가져오기
BOOL CALLBACK EnumWindowCallBack(HWND hwnd, LPARAM lParam)
{
 char str_title[255];
 int length;
 GetWindowText(hwnd, str_title,255);
 length = GetWindowTextLength(hwnd);

 // Windows ctrl + alt + delete 에 나오는 프로그램 명
 if (IsWindowVisible(hwnd) && length > 0 && !strncmp(str_title, "프로그램명",10))  {
  printf("callback enumwindows in str_title : %s\n", str_title);
  return FALSE;
 }
 return TRUE;
}
CallBack 함수를 호출하여, 실행 중인 프로그램 리스트를 얻어 온다.

얻어 온 리스트 중 제어할려는 프로그램 명을 적은 후, 반환 받아서 제어.

위 소스에서 "프로그램명" 에 해당 하는 프로그램 이름을 적으면 된다.

예) Excel  => "Excel" 로 적고, strncmp 기능을 이용하여, 자신이 비교할려는

문자 수를 정하고, 해당 문자와 같은 문자가 있는 프로그램일 경우, false를 반환,

그렇지 않을 경우, true를 반환 한다.

 false 를 반환 할 경우, 동일 프로그램이 실행 중임으로 이 때 해당하는 프로세스 진행

true 를 반환 할 경우, 프로그램이 실행 하고 있지 않을 때 코드를 작성하면 된다.

IsWindowVisible(hwnd) && length > 0 은 ctrl+Alt + del 키를 눌렀을 때 나오는 프로그램인지

확인 하는 것이고, str_title에 ctrl + Alt + del 키를 눌렀을 때 나오는 프로그램 이름이 저장

되게 된다.


참조 : http://frog3147.tistory.com/entry/MFC%EC%97%90%EC%84%9C-%ED%98%84%EC%9E%AC-%EC%8B%A4%ED%96%89-%EC%A4%91%EC%9D%B8-%EC%9D%91%EC%9A%A9%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EB%AA%A9%EB%A1%9D-%EC%96%BB%EC%96%B4%EC%98%A4%EA%B8%B0

http://blog.naver.com/PostView.nhn?blogId=qblan&logNo=60135883727&categoryNo=47&viewDate=&currentPage=1&listtype=0