BOOKS i'm reading |
Add clipboard copy functionality easily to Windows programs with metafiles in C++
Contents
IntroductionWhile I was reading Charles Petzold's Programming Windows book, more specifically the chapter on metafiles, I was wondering what could be the potential usages of such a feature in a real world application. The chapter describes in length what metafiles do and how they work, but little is said about what you can do with them or why you should use them. I think that I found a worthwhile application for metafiles and I am going to share it. This article has no claims of inventing a revolutionary technique as it is ridiculously simple, but in the same time, it does not seem to be widely known. This technique is for sharing data among different applications, as for sharing the data among the same application, private data formats might be more appropriate. In this C++ Windows programming tutorial, I will give a brief overview of what metafiles are, and then I will present the technique.
BackgroundThere are two types of metafiles: the original ones that have been around since Windows 1.0, and the enhanced metafiles. The difference between them is very small. The enhanced metafiles have a slightly more detailed header which makes them more self contained. There is no good reason to use the original metafiles unless you have to keep compatibility with an old Win16 application. If it is not the case, then you should stick with the enhanced metafiles. Metafiles are GDI objects that once opened will return a device context. Metafiles store all the GDI function calls performed with their DC and then allow the user to perform a playback of the stored GDI calls. They are one of the standard data formats that the clipboard accepts. MFC encapsulates metafiles functionality in the class Using the codeThe technique consists of putting your drawing code in a function that takes a device context object pointer as an input parameter: void Draw(CDC *pdc); This function can be called from your void CChildView::OnPaint() { CPaintDC dc(this); // device context for painting Draw(&dc); } Now, your new copy handler will look like this: void CChildView::OnEditCopy() { CMetaFileDC mfdc; if( mfdc.CreateEnhanced(NULL,NULL,NULL,NULL) ) { Draw(&mfdc); HENHMETAFILE hmf; if( (hmf = mfdc.CloseEnhanced()) ) { if( OpenClipboard() ) { EmptyClipboard(); SetClipboardData(CF_ENHMETAFILE, hmf); CloseClipboard(); } else { /* * The metafile is deleted only when it has not been set in * the clipboard. */ ::DeleteEnhMetaFile(hmf); } } } } This is all that your program needs, to be able to copy the client area content and paste it in any application supporting metafiles. The demo programThe demo program is just a simple MFC AppWizard generated SDI application where a bogus drawing function has been added to prove the concept. Then, the copy handler has been added to the Points of InterestYou can easily adapt this code to a MFC View/Document program or a Win32 API program. Also, an astute reader pointed out that if your CMetaFileDC mfdc; if( mfdc.CreateEnhanced(NULL,NULL,NULL,NULL) ) { // Create a second device context that points to the screen, in order to make // functions like GetTextExtent work correctly CDC cdc; VERIFY(cdc.CreateIC(__TEXT("DISPLAY"),NULL,NULL,NULL)); mfdc.SetAttribDC(cdc.m_hAttribDC); Draw(&mfdc); ... } You cannot call
When it is CPoint CDC::MoveTo(int x, int y) { ASSERT(m_hDC != NULL); CPoint point; if (m_hDC != m_hAttribDC) VERIFY(::MoveToEx(m_hDC, x, y, &point)); if (m_hAttribDC != NULL) VERIFY(::MoveToEx(m_hAttribDC, x, y, &point)); return point; } ConclusionThat is it! I hope you that enjoyed this C++ Windows programming tutorial and that you have found it useful. In the next section, you will find the books that I have consulted to build this C++ Windows programming tutorial. Those books are great and filled with Windows programming gems that you should know. It is strongly recommended that you get yourself a copy of these books especially since from time to time, you can find these books at a bargain price. Take the time to check the prices. This is maybe your lucky day today! Bibliography
|