알송의 데스크탑 가사창을 어떻게 구현했을까.

우선 알송의 가사창을 자세히 보면 Alpha Blending으로 윈도우를 반투명 처리 되었지만

마우스 이벤트가 가사창 윈도우에 먹지 않습니다.

클릭을 하면 가사창 아래의 창에 클릭이 되고, 마우스 포인터(보통 화살표)도 가사창 아래의 윈도우에 투영됩니다.

이런것은 어떻게 처리 했을까?

정답은, API 함수의 윈도우 생성 함수중

CreateWindowEx() 함수의 Extended Style 인자에

WS_EX_TRANSPARENT 와 WS_EX_LAYERED 속성을 추가하면 됩니다

각각, 이 윈도우는 투명화 처리, 윈도우 레이어 임의 설정이 됩니다 

MFC에서 Jpg나 png 이미지 로드하고 보여주기

CBitmap 클래스 대신 CImage 클래스 로 교체
CImage 클래스중
Load() : 함수를 이용 클래스 인스턴트에 이미지 로드
Draw() : 함수를 이용 대하상자에 이미지 출력.
Destroy() : 함수를 써서 이전 이미지 언로드 시키고, 두번째 이미지를 로드하기 위한 준비


1. stdafx.h 해더에 마지막 줄에 다음을 추가
#include <atlimage.h>

2. 메인 프로그램 헤더 파일을 열어서
// CBitmap m_bmpBitmap;  주석처리
CImage m_bmpBitmap; 추가


3. 로드를 실행시킬 함수 (OnCreate 나 OnInit 함수등)에 다음 소스를 추가하자
m_bmpBitmap.Destroy();
m_bmpBitmap.Load("BackPic.png");

// 현제 대화상자 다시 그려주는 함수 로드


4. ShowBitmap() 함수 수정
void PaintDlg::ShowBitmap(CPaintDC *pdc)
{
 // 포인터를 메인 대화상자 클래스 포인터로 변경
 CGraphicsDlg *pWnd = (CGraphicsDlg*)GetParent();
// 대략 pWnd는 Dialog의 this 포인터를 위함..
 CDC dcMem;
 CRect rRect;

 // 보여줄 영역을 얻는다
 GetClientRect(rRect);
 rRect.NormalizeRect();

 // 대화상자 윈도우로 비트맵을 복사하면서 크기 조절
 pWnd->m_bmpBitmap.Draw(pdc->m_hDC, rRect);
}

// 무슨 코드인지 궁금하면 Visual C++6.0 21일 완성 책을 참조..

데브피아에선

void CTestDlg::OnPaint()
{
    if (IsIconic()) //여기서는 그려봐야 소용 없습니다.
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else // 여기서 그리셔야죠.
    {
        CPaintDC dc(this); // device context for painting
        dc.Rectangle(0, 0, 100, 100);  

        CDialog::OnPaint();
    }
}
시도해 보라는..

http://www.devpia.com/Search/MAEULResult.aspx?boardID=50&MAEULNo=20&keyw=Dialog%bf%a1+%b1%d7%b8%b2&keyr=title
MFC

// Exam.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include "Exam.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 유일한 응용 프로그램 개체입니다.

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
 int nRetCode = 0;

 // MFC를 초기화합니다. 초기화하지 못한 경우 오류를 인쇄합니다.
 if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
 {
  // TODO: 오류 코드를 필요에 따라 수정합니다.
  _tprintf(_T("심각한 오류: MFC를 초기화하지 못했습니다.\n"));
  nRetCode = 1;
 }
 else
 {
  if(argc < 2)
  {
   cout << "입력된 행이 없음" << endl;
   return 2;
  }

  // TODO: 응용 프로그램의 동작은 여기에서 코딩합니다.
   
  CString acount = argv[1];

  int iPos = acount.FindOneOf("+-*/");
  if(iPos == -1)
  {
   cout << "사칙 연산 프로그램 띄어쓰지마, +,-,*,/만" << endl;
   return 3;
  }

  CString strFrontEnd = acount.Left(iPos);
  CString strBackEnd = acount.Mid(iPos + 1);
  CString strOperator = acount.Mid(iPos,1);

  int iFrontEnd = atoi(strFrontEnd);
  int iBackEnd = atoi(strBackEnd);
  int iResult = 0;

  if(strOperator == "+")
   iResult = iFrontEnd + iBackEnd;

  else if(strOperator == "-")
   iResult = iFrontEnd - iBackEnd;

  else if(strOperator == "*")
   iResult = iFrontEnd * iBackEnd;

  else if(strOperator == "/")
   iResult = iFrontEnd / iBackEnd;
 
  cout << "계산결과 : "<< iFrontEnd << strOperator << iBackEnd << " = " << iResult << endl;
 }

 return nRetCode;
}

// 파일 사용시 공유 DLL 사용을 체크해야 함

// API의 windows.h 와 같은거
#include <afxwin.h>

// WinMain 부분 음... 여기에 메시지 루프가 들어가 있음
class CHelloApp : public CWinApp
{
public:
 virtual BOOL InitInstance();
};

// 이부분이 API의 WndProc 부분, 메시지를 Catch 해서 처리해줌
class CMainFrame : public CFrameWnd
{
public:
 CMainFrame();

protected:
 afx_msg void OnPaint();
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
 DECLARE_MESSAGE_MAP()
};

// 프로그램 객체
CHelloApp theApp;

// 클래스 정의
// 이부분은 API의 CreateWindow와 같은 역활을 해줌
BOOL CHelloApp::InitInstance()
{
 m_pMainWnd = new CMainFrame;   // 객체 만들어 지면서 생성자 실행
 m_pMainWnd ->ShowWindow(m_nCmdShow); // ShowWindow 명령 실행
 m_pMainWnd ->UpdateWindow();   // UodateWindow 명령 실행
 return TRUE;
}

// 각 함수의 플러그를 보고 싶으면
// 함수에 커서를 대고 F12키를 눌러보자! 그함수를 정의한 헤더 파일등을 볼수 있다

CMainFrame::CMainFrame()
{
 Create(NULL,"HelloMFC Application");
}

// WM_PAINT 할때의 명령
void CMainFrame::OnPaint()
{
 char *msg = "Hello, MFC";
 CPaintDC dc(this);

 dc.TextOut(100,100,msg,lstrlen(msg));
}

// WM_LBUTTONDOWN 의 명령
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
 MessageBox("마우스클릭했지?","마우스",MB_YESNOCANCEL | MB_ICONQUESTION);
}

// 메시지 맵
// 이 메시지 맵은 CMainFrame의 소속이다
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
// MFC에이미 정의가 되어있는 키워드
 ON_WM_PAINT()    
 ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
// 맨 마지막 줄은 DefWnidowProc 와 같은 명령을 해준다

// 이 다음에 WinMain 함수가 생략되어 있음.
// 이 소스에서 실행하는건 프로그램 객체 선언 CHelloApp theApp; 이 한줄 뿐임.
// WinMain 함수는 어느 윈도우나 같으므로 아예 생략되었음. (컴파일할때 자동 처리)
// WinMain 함수를 보고 싶으면 BOOL CHelloApp::InitInstance() 줄에 브레이크 포인트를 걸어볼껏
// .net 에서만 유효, 호출 스택을 잘 보면 나옴

+ Recent posts