11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 12. Screen Capturing & Printing<br />

For picture controls,<br />

we can display various<br />

types of images<br />

Figure 12-4. Set the properties of a picture control<br />

Variable CSelDlg::m_hWnd is used to store the handle of the selected window. Also, variable<br />

CSelDlg::m_rectSelect is used to indicate the rectangle of the previously selected window. If this<br />

rectangle is empty, no window is currently being reversed.<br />

As the mouse moves, we will keep on receiving WM_MOUSEMOVE messages. In the sample, function<br />

CSelDlg::DrawSelection(…) is implemented to handle this message. Within this function, first we create a<br />

region that contains all of the desktop window excluding the area occupied by the application window. We<br />

select this region into the desktop window DC before reversing any window. By doing this, if the selected<br />

window is overlapped by the application window, the reversing effect does not apply to the application<br />

window. The following portion of function CSelDlg::DrawSelection(…) shows how the region is created:<br />

void CSelDlg::DrawSelection(CPoint point, BOOL bErase)<br />

{<br />

if(m_bCaptureOn == TRUE)<br />

{<br />

CWnd *pWnd;<br />

CWindowDC dc(CWnd::GetDesktopWindow());<br />

int nRop2Mode;<br />

CRgn rgn;<br />

CRgn rgnDesk;<br />

CRect rect;<br />

……<br />

GetWindowRect(rect);<br />

rgn.CreateRectRgnIndirect(rect);<br />

AfxGetApp()->m_pMainWnd->GetWindowRect(rect);<br />

rgnDesk.CreateRectRgnIndirect(rect);<br />

rgn.CombineRgn(&rgnDesk, &rgn, RGN_OR);<br />

rgnDesk.DeleteObject();<br />

CWnd::GetDesktopWindow()->GetWindowRect(rect);<br />

rgnDesk.CreateRectRgnIndirect(rect);<br />

rgn.CombineRgn(&rgnDesk, &rgn, RGN_DIFF);<br />

dc.SelectClipRgn(&rgn);<br />

In order to resume the reversed window, the drawing mode should be set to R2_NOT, which will reverse<br />

all the pixels contained in the rectangle when function CDC::Rectangle(…) is called. The drawing mode<br />

can be set by calling function CDC::SetROP2(…):<br />

……<br />

……<br />

nRop2Mode=dc.SetROP2(R2_NOT);<br />

Then we call function CWnd::WindowFromPoint(…) to see if the current mouse cursor is over any<br />

window. We use the returned pointer to retrieve the handle of that window, and compare it with the handles<br />

of our application windows (both mainframe window and dialog box window). If there is a match, we<br />

should not draw the rectangle because the cursor is over the application window (In this case, if there exists<br />

a window that has been reversed, we should resume it). Otherwise, we further compare it with the handle<br />

stored in CSelDlg::m_hWnd, if they are the same, we don’t do anything because the window under the<br />

cursor has been reversed. If not, this means a new window is being selected and we should resume the old<br />

reversed window (If there exists such a window) then reverse the newly selected one:<br />

……<br />

if<br />

377

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!