The thought was to make a screen magnifier using a "transparent" MFC dialog and try to calculate its relative position inside the whole screen.
I've spent 2 days on these problem and finally solved it using a MFC CDialog class to simulate a magnifier. The CMagifierDlg is inherited from the CDialog Class and has its own attributs and methods:
int m_nZoom;
CDC *m_pMemDC;
BOOL m_bIsActived;
int m_nH, m_nW; //Screen width and height
HICON m_hIconI; HICON m_hIconO; HICON m_hIconE;
void OwnerDraw();
void SaveScreen();
The UI is like:

And the events are:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnPaint();
afx_msg void OnWindowPosChanged(WINDOWPOS FAR* lpwndpos);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnExit();
afx_msg void OnZoomin();
afx_msg void OnZoomout();
Then, you make a memory DC of the screen and in the OnPaint(CDC *pDC) function, you write:
void CMagnifierDlg::OwnerDraw()
{
CDC *pDC = GetDC();
if (pDC && m_pMemDC)
{ CRect clientRect;
CRect windowRect;
GetClientRect(clientRect);
GetWindowRect(windowRect);
if (!m_nZoom) //ZOOM = 0
{
pDC->BitBlt( clientRect.left, clientRect.top, clientRect.Width(), clientRect.Height(), m_pMemDC, windowRect.left, windowRect.top, SRCCOPY ); }
else //ZOOM > 0
{ int cx, cy, cw, ch;
cx = clientRect.left; cy = clientRect.top; cw = clientRect.Width(); ch = clientRect.Height();
int wx, wy, ww, wh;
wx = windowRect.left; wy = windowRect.top;
ww = windowRect.Width(); wh = windowRect.Height();
//////////////////////////////////////////////////////////////////////////
// Confine the magnifier's movable region in the screen
if (wx <>
{ ww += wx; cx = wx*(-1); cw += wx; wx *= -1; }
if (wy <>
{ wh += wy; cy = wy*(-1); ch += wy; wy *= -1; }
//////////////////////////////////////////////////////////////////////////
// Core algorithm for Magnifier //
int x_ = 0, y_ = 0; //视口原点 P'(x', y')
int w_ = 0, h_ = 0; //视口尺寸 M'(w', h')
int mw = 0, mh = 0; //可移动区域 Sm (m_nW - ww, m_nH - wh)
int mw_ = 0, mh_ = 0; //视口可移动区域,相对于放大镜 Sm' (ww - w_, wh - h_)
double xk = 0.0, yk = 0.0; //放大镜在屏幕中的位置比
w_ = ww / (m_nZoom + 1); h_ = wh / (m_nZoom + 1);
mw = m_nW - ww; mh = m_nH - wh; mw_ = ww - w_; mh_ = wh - h_;
xk = (double)wx / (double)mw; yk = (double)wy / (double)mh;
x_ = wx + (int)(double(mw_) * xk); y_ = wy + (int)(double(mh_) * yk);
StretchBlt( pDC->m_hDC, cx, cy, cw, ch, m_pMemDC->m_hDC, x_, y_, w_, h_, SRCCOPY );
//////////////////////////////////////////////////////////////////////////
}
}
//Draw buttons CRect r,rb; GetWindowRect(&r);
CButton* bt = (CButton*)GetDlgItem(IDC_ZOOMIN);
bt->GetWindowRect(&rb);
int _x = r.Width() - rb.Width() * 3 - 9;
int _y = r.Height() - rb.Height() - 5;
bt->MoveWindow(_x,_y,rb.Width(),rb.Height());
bt->SetIcon(m_hIconI);
bt = (CButton*)GetDlgItem(IDC_ZOOMOUT);
bt->GetWindowRect(&rb);
_x = r.Width() - rb.Width() * 2 - 7;
_y = r.Height() - rb.Height() - 5;
bt->MoveWindow(_x,_y,rb.Width(),rb.Height());
bt->SetIcon(m_hIconO);
bt = (CButton*)GetDlgItem(IDC_EXIT);
bt->GetWindowRect(&rb);
_x = r.Width() - rb.Width() - 5;
_y = r.Height() - rb.Height() - 5;
bt->MoveWindow(_x,_y,rb.Width(),rb.Height());
bt->SetIcon(m_hIconE);
}

No comments:
Post a Comment
(Coding && Eating) || Sleeping