반응형
MFC를 하다보면 Bitmap Image를 직접 출력하고 싶을 때가 있습니다.
아래는 이미지를 출력 하기 위한 방법 및 소스입니다. 확대(Zoom in)와 축소(Zoom out)의 기능도 추가하였으니 참고바랍니다!
1. Picture Control을 선택하여 다이얼로그에 그려줍니다.
2. 그려놓은 Picture Control의 ID값을 기억해 놓습니다. 예제에서는 IDC_BITMAP_CTRL로 정하였습니다.
3. 프로젝트에 아래 소스 및 헤더를 추가합니다. (BitmapCtrl.cpp, BitmapCtrl.h)
//BitmapCtrl.cpp
#include "stdafx.h"
#include "BitmapCtrl.h"
float Magnification[] = { 0.5, 0.8, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0 };
CBitmapCtrl::~CBitmapCtrl()
{
if(memDC.GetSafeHdc() != NULL)
{
memDC.SelectObject(pOldBitmap);
if(pBitmap != NULL)
delete pBitmap;
}
}
BEGIN_MESSAGE_MAP(CBitmapCtrl, CWnd)
//{{AFX_MSG_MAP(CBitmapCtrl)
ON_WM_PAINT()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CBitmapCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd)
{
scrollbar_width = GetSystemMetrics(SM_CXVSCROLL);
// create window
BOOL ret;
static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,AfxGetApp()->LoadStandardCursor(IDC_ARROW));
ret = CWnd::CreateEx(WS_EX_CLIENTEDGE,className,NULL,dwStyle,
rect.left,rect.top,rect.right - rect.left,rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(),0);
// init virtual screen
GetClientRect(rcClient);
CClientDC dc(this);
if(memDC.GetSafeHdc() == NULL)
{
memDC.CreateCompatibleDC(&dc);
memZoomDC.CreateCompatibleDC(&memDC);
if((pBitmap = new CBitmap()) == NULL) return FALSE;
pBitmap->CreateCompatibleBitmap(&dc,rcClient.Width(),rcClient.Height());
pOldBitmap = memDC.SelectObject(pBitmap);
memDC.SelectStockObject(ANSI_VAR_FONT);
memDC.SetBkMode(TRANSPARENT);
}
x_offset = 0;
y_offset = 0;
memDC.FillSolidRect(&rcClient,RGB(128,128,128));
MagnificationIdx = 2;
nZoomMagnification = Magnification[MagnificationIdx];
return ret;
}
void CBitmapCtrl::OnPaint()
{
CPaintDC dc(this);
if(memDC.GetSafeHdc() != NULL)
dc.BitBlt(0,0,rcClient.Width(),rcClient.Height(),&memDC,0,0,SRCCOPY);
}
void CBitmapCtrl::SetNewBitmap(HBITMAP hBmp)
{
MagnificationIdx = 2;
nZoomMagnification = Magnification[MagnificationIdx];
SetBitmap(hBmp);
}
void CBitmapCtrl::SetBitmap(HBITMAP hBmp)
{
//reset offsets
x_offset = 0;
y_offset = 0;
//reset scrollbar
SCROLLINFO si;
si.fMask = SIF_PAGE | SIF_RANGE;
si.nMin = 0;
si.nMax = 0;
si.nPage = 0;
SetScrollInfo(SB_HORZ, &si, TRUE);
SetScrollInfo(SB_VERT, &si, TRUE);
//redraw background
GetClientRect(&rcClient);
memDC.FillSolidRect(&rcClient,RGB(128,128,128));
//get bitmap handle
hBitmap = hBmp;
if (hBitmap == 0)
{
memDC.TextOut(0,0,_T("File not found."));
Invalidate();
return;
}
//get image size
CPoint point(x_offset,y_offset);
BITMAP bmpInfo;
CBitmap::FromHandle(hBitmap)->GetBitmap(&bmpInfo);
image_size.cx = bmpInfo.bmWidth;
image_size.cy = bmpInfo.bmHeight;
//check image size
BOOL x_fit;
BOOL y_fit;
int test = rcClient.Width();
x_fit = (bmpInfo.bmWidth <= rcClient.Width());
if (!x_fit)
rcClient.bottom -= scrollbar_width;
y_fit = (bmpInfo.bmHeight <= rcClient.Height());
if (!y_fit)
{
rcClient.right -= scrollbar_width;
x_fit = (bmpInfo.bmWidth <= rcClient.Width());
}
if (!x_fit)
{
// show scrollbar
ShowScrollBar(SB_HORZ);
/*CRect scroll_rect;
GetScrollBarCtrl(SB_HORZ)->GetWindowRect(&scroll_rect);
char sz[256];
sprintf(sz,"%d",scroll_rect.left - scroll_rect.right);
MessageBox(sz);*/
// update scrollbar
SCROLLINFO si;
si.fMask = SIF_PAGE | SIF_RANGE;
si.nMin = 0;
si.nMax = (bmpInfo.bmWidth-1)* (float)nZoomMagnification;
si.nPage = rcClient.Width();
SetScrollInfo(SB_HORZ, &si, TRUE);
}
if (!y_fit)
{
// show scrollbar
ShowScrollBar(SB_VERT);
// update scrollbar
SCROLLINFO si;
si.fMask = SIF_PAGE | SIF_RANGE;
si.nMin = 0;
si.nMax = (bmpInfo.bmHeight-1)* (float)nZoomMagnification;
si.nPage = rcClient.Height();
SetScrollInfo(SB_VERT, &si, TRUE);
}
DrawBitmap();
}
void CBitmapCtrl::DrawBitmap()
{
CBitmap bitmap;
bitmap.m_hObject=hBitmap;
CPoint point(-x_offset,-y_offset);
memZoomDC.SelectObject(&bitmap);
memDC.StretchBlt(-x_offset,-y_offset,image_size.cx * (float)nZoomMagnification, image_size.cy* (float)nZoomMagnification, &memZoomDC, 0, 0, image_size.cx , image_size.cy, SRCCOPY);
Invalidate();
}
void CBitmapCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int nSmall = 1;
int nLarge = 20;
if(pScrollBar == GetScrollBarCtrl(SB_HORZ))
{
if(nSBCode == SB_LEFT || nSBCode == SB_LINELEFT)
x_offset -= nSmall;
if(nSBCode == SB_PAGELEFT)
x_offset -= nLarge;
if(nSBCode == SB_RIGHT || nSBCode == SB_LINERIGHT)
x_offset += nSmall;
if(nSBCode == SB_PAGERIGHT)
x_offset += nLarge;
if(nSBCode == SB_THUMBPOSITION)
x_offset = (int)nPos;
if(nSBCode == SB_THUMBTRACK)
x_offset = (int)nPos;
if (x_offset<0)
x_offset = 0;
if (x_offset>image_size.cx * (float)nZoomMagnification - rcClient.Width())
x_offset = image_size.cx - rcClient.Width();
SetScrollPos(SB_HORZ, x_offset, TRUE);
DrawBitmap();
}
}
void CBitmapCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int nSmall = 1;
int nLarge = 20;
if(pScrollBar == GetScrollBarCtrl(SB_VERT))
{
if(nSBCode == SB_TOP || nSBCode == SB_LINEUP)
y_offset -= nSmall;
if(nSBCode == SB_PAGEUP)
y_offset -= nLarge;
if(nSBCode == SB_BOTTOM || nSBCode == SB_LINEDOWN)
y_offset += nSmall;
if(nSBCode == SB_PAGEDOWN)
y_offset += nLarge;
if(nSBCode == SB_THUMBPOSITION)
y_offset = (int)nPos;
if(nSBCode == SB_THUMBTRACK)
y_offset = (int)nPos;
if (y_offset<0)
y_offset = 0;
if (y_offset>image_size.cy * (float)nZoomMagnification - rcClient.Height())
y_offset = image_size.cy - rcClient.Height();
SetScrollPos(SB_VERT, y_offset, TRUE);
DrawBitmap();
}
}
void CBitmapCtrl::LoadFile(CString filename)
{
HBITMAP hBitmap = (HBITMAP) LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
SetBitmap(hBitmap);
}
void CBitmapCtrl::ZoomInOut(int nInOut)
{
switch ( nInOut )
{
case 0 : //in
if (MagnificationIdx < (sizeof(Magnification)/sizeof(float)) -1 )
MagnificationIdx++;
break;
case 1 : //out
if (0 < MagnificationIdx )
MagnificationIdx--;
break;
}
nZoomMagnification = Magnification[MagnificationIdx];
SetBitmap(hBitmap);
}
// BitmapCtrl.h : header file
//
#pragma once
/////////////////////////////////////////////////////////////////////////////
// CBitmapCtrl window
#include "afxwin.h"
class CBitmapCtrl : public CWnd
{
public:
void SetNewBitmap(HBITMAP hBmp);
void SetBitmap(HBITMAP hBmp);
void DrawBitmap();
void ZoomInOut(int nInOut);
CRect rcClient;
int scrollbar_width;
int x_offset;
int y_offset;
CSize image_size;
HBITMAP hBitmap;
float nZoomMagnification;
int MagnificationIdx;
private:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBitmapCtrl)
public:
virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd);
//}}AFX_VIRTUAL
// Implementation
public:
void LoadFile(CString filename);
virtual ~CBitmapCtrl();
// Generated message map functions
protected:
//{{AFX_MSG(CBitmapCtrl)
afx_msg void OnPaint();
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CDC memDC;
CDC memZoomDC;
CBitmap* pBitmap;
CBitmap* pOldBitmap;
};
/////////////////////////////////////////////////////////////////////////////
4. 이제 다이얼로그 소스에 아래 구문을 추가합니다.
//다이얼로그.cpp
BOOL Dlg::OnInitDialog()
{
....생략
//create bitmap control
CRect brect;
GetDlgItem(IDC_BITMAP_CTRL)->GetWindowRect(brect);
ScreenToClient(brect);
m_bmpCtrl.Create(WS_CHILD|WS_VISIBLE,brect,this);
}
void Dlg::BtnLoadImage()
{
unsigned char pBmpImage[100000];
..생략
pBmpImage = //BmpImage를 로드하여 pBmpImage 버퍼에 저장.
//View
HBITMAP hbmp = Create_DiBitmapWithBitmapData(pBmpImage);
m_bmpCtrl.SetNewBitmap(hbmp);
}
5. 이후 실행하면 이미지를 보여줍니다.
참 쉽죠? 잘 활용하시길 바랍니다. :)
반응형
'Windows > DLL,MFC' 카테고리의 다른 글
[Windows DLL] 참고3. Release와 Debug의 차이 (0) | 2022.10.26 |
---|---|
[Windows DLL] 참고2. MFC으로 개발한 프로그램을 배포할시 유의사항 (0) | 2022.10.21 |
[Windows DLL] 참고1. Test 프로그램과 DLL을 동시에 컴파일 하기. (0) | 2022.10.21 |
[DLL 만들기] 5. DLL을 load하여 동작 확인 해보기. (MFC 기준) (0) | 2022.10.21 |
[DLL 만들기] 4. 생성한 DLL 동작 확인을 위한 프로젝트 생성하기. (MFC 기준) (0) | 2022.10.21 |