VCSamples/VC2010Samples/MFC/advanced/DllScreenCap at master · microsoft/VCSamples · GitHub
Skip to content
This repository has been archived by the owner on Feb 9, 2021. It is now read-only.

Latest commit

 

History

History

DllScreenCap

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
<!--TO READ THIS HELP FILE, RIGHT-CLICK ON THE FILE NAME IN THE
    SOLUTION EXPLORER PANE AND SELECT "VIEW IN BROWSER"-->

<html><head><title>DLLScreenCap Sample: Demonstrates a Regular DLL That Statically or Dynamically Links to MFC</title></head><body><h1>DLLScreenCap Sample: Demonstrates a Regular DLL That Statically or Dynamically Links to MFC</h1><div id="mainSection"><div id="mainBody"><div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()"></div><p /><p>The DLLScreenCap sample illustrates a dynamic-link library (DLL) version of a screen capture tool. DLLScreenCap supercedes the DLLTRACE sample, which is obsolete. DLLTRACE was introduced in MFC version 1.0 to illustrate how to write a DLL that is itself statically linked to the MFC library. DLLScreenCap provides a C-based program interface to the Microsoft Windows–based application to which it is dynamically linked. A DLL that is statically linked to the MFC library cannot successfully export member functions of any classes that are derived from MFC classes.</p><p>The technique of statically linking a DLL to the MFC library is discussed in <MSHelp:link keywords="76753E9C-59DC-40F6-B6A7-F6BB9A7C4190" tabindex="0" >Technical Note 11: Using MFC as Part of a DLL</MSHelp:link>. The DLLScreenCap sample can also be linked to MFC dynamically, without being an extension DLL. Before you decide to implement a custom DLL by statically linking to MFC, consider implementing it as an MFC extension DLL, as explained in <MSHelp:link keywords="B6F1080B-B66B-4B1E-8FB1-926C5816392C" tabindex="0" >Technical Note 33: DLL Version of MFC</MSHelp:link> and as illustrated by the DLLHUSK sample.</p><p>A non-extension DLL that is linked to the MFC library needs to have a <b>CWinApp</b>-derived class and a single object of that application class, as does an executable MFC application. The <b>CWinApp</b> object of the DLL, however, does not have a main message pump, as does the <b>CWinApp</b> object of an application. If the DLL opens modeless dialog boxes or has a main frame window of its own, the application's main message pump must call a routine exported by the DLL, which in turn calls the <b>CWinApp::PreTranslateMessage</b> member function of the DLL's application object. This is illustrated by the <code>FilterDllMsg</code> function exported by DLLScreenCap.dll.</p><p>ScreenCapApi.h shows that a way to provide a DLL interface to client applications is to declare functions with <b>extern</b> "C". The use of <b>extern</b> "C" has several advantages. First, it makes your DLL usable by non-C++ client applications. Second, it reduces DLL overhead, because C++ name decoration will not be applied to the exported name. Third, it makes it easier to explicitly add to a .def file (for exporting by ordinal), without having to worry about C++ name decoration.</p><div class="alert"><table width="100%" cellspacing="0" cellpadding="0"><tr><th align="left">Security Note </th></tr><tr><td><p>This sample code is provided to illustrate a concept and should not be used in applications or Web sites, as it may not illustrate the safest coding practices.</p></td></tr></table></div><h1 class="heading">Building and Running the Sample</h1><div id="sectionSection0" class="seeAlsoNoToggleSection"><p>The DLLScreenCap sample consists of two projects: DLLScreenCap, a DLL project, and ScreenCap, an EXE project that calls into the DLL.</p><p>Building ScreenCap from the provided solution will automatically build DLLScreenCap and copy the DLL into ScreenCap's output directory. </p><p><b>Note</b>   Because this sample uses a custom build step to copy a file, you should not open the solution using a UNC path; put the sample files on a directory with a drive letter. </p><h4 class="subHeading">To build and run the DLLScreenCap sample</h4><div class="subSection"><ol><li><p>Open the solution DllScreenCap.sln. </p></li><li><p>In Solution Explorer, right-click the ScreenCap project folder and click <b>Set as Startup Project</b> on the shortcut menu.</p></li><li><p>On the <b>Build</b> menu, click <b>Build</b>. </p></li><li><p>On the <b>Debug</b> menu, click <b>Start Without Debugging</b>. </p></li></ol></div><p>The ScreenCap window displays the last screen captured after being scaled to the window's size. Click <b>Configure Screen Capture</b> on the <b>File</b> menu. This opens a dialog box to specify whether to capture the screen or the active window as well as a path to where the captured file should be saved. Click <b>Screen Capture</b> to create a captured file and update the client window display.</p></div><h1 class="heading">Converting DLLScreenCap to Dynamically Link with the MFC DLL</h1><div id="sectionSection1" class="seeAlsoNoToggleSection"><p>DLLScreenCap demonstrates how to create a regular DLL with an exported function that can be called to display a modal dialog box. In older versions of Visual C++, this was the only option available for regular DLLs. These kinds of DLLs were formerly known as _USRDLLs.</p><p>Now, it is possible for a regular DLL to use MFC from the shared MFCx0 DLL. Because of the potential to reduce the size of the build, you might want to build the DLLScreenCap sample using the shared MFC DLL. Supporting the shared library in DLLScreenCap.dll will reduce the size of a release-build DLL from over 100K to about 16K and will reduce the size of the debug build from over 1 megabyte to 100K. To support linking dynamically in DLLScreenCap, use the macro AFX_MANAGE_STATE to switch the global MFC module state correctly.</p><h4 class="subHeading">To verify that DLLScreenCap can be used in a shared library</h4><div class="subSection"><ol><li><p>In Solution Explorer, right-click the ScreenCap project node and click <b>Properties</b> on the shortcut menu. </p><p>The <b>Property Pages</b> dialog box appears. </p></li><li><p>From the <b>Configuration</b> drop-down menu, select <b>Multiple Configurations</b>. See <MSHelp:link keywords="9B0D6F8B-7D4E-4E61-AA75-7D14944816CD" tabindex="0" >Setting Visual C++ Project Properties</MSHelp:link> for more information about the <b>Property Pages</b> dialog box.</p></li><li><p>Select both the <b>Release</b> and <b>Debug </b>builds to change their settings.</p></li><li><p>In the <MSHelp:link keywords="593B383C-CD0F-4DCD-AD65-9EC9B4B19C45" tabindex="0" >General Property Page</MSHelp:link> for the project, verify that the <b>Use of MFC</b> property to use MFC in a shared DLL property is checked.</p></li><li><p>Verify that the following line of code is in the beginning of every function exported from the DLL (see <MSHelp:link keywords="81889C11-0101-4A66-AB3C-F81CF199E1BB" tabindex="0" >Managing the State Data of MFC Modules</MSHelp:link> for a discussion): </p><div class="code"><span codeLanguage="other"><table width="100%" cellspacing="0" cellpadding="0"><tr><td colspan="2"><pre>AFX_MANAGE_STATE(AfxGetStaticModuleState())</pre></td></tr></table></span></div></li></ol></div><p>For example, DllScreenCap.dll exports four functions:  </p><ul><li><p><code>CaptureScreen</code></p></li><li><p><code>ConfigureCapture</code></p></li><li><p><code>ProcessDLLIdle</code></p></li><li><p><code>FilterDLLMsg</code></p></li></ul><p><code>FilterDLLMsg</code> should look like this in the converted form:</p><div class="code"><span codeLanguage="other"><table width="100%" cellspacing="0" cellpadding="0"><tr><td colspan="2"><pre>BOOL WINAPI FilterDllMsg(LPMSG lpMsg)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState())
   TRY
   {
       return AfxGetApp()-&gt;PreTranslateMessage(lpMsg);
   }
   END_TRY
return FALSE;
}</pre></td></tr></table></span></div></div><h1 class="heading">Keywords</h1><div id="sectionSection2" class="seeAlsoNoToggleSection"><p>This sample demonstrates the following keywords:</p><p>CDialog::DoModal, CWinApp::InitInstance, CWinApp::OnIdle, CWinApp::PreTranslateMessage, CWnd::DoDataExchange, CWnd::GetClientRect, CWnd::OnPaint, ShowWindow, UpdateWindow, CImage, AFX_MANAGE_STATE, AfxGetStaticModuleState, CWnd::GetDesktopWindow, CWnd::GetActiveWindow, CImage::Create, CImageDC, CImage::Save, SHBrowseForFolder, CImage::Load, CDC::SetStretchBltMode, CImage::StretchBlt, CWnd::OnEraseBkgnd, CWindowDC</p></div></div><div id="footer"><div class="footerLine"></div>
          © Microsoft Corporation. All rights reserved.  Send <a href="mailto:DevDocs@microsoft.com?subject=Documentation Feedback :DLLScreenCap Sample: Demonstrates a Regular DLL That Statically or Dynamically Links to MFC">comments</a> about this topic to Microsoft.
      </div></div></body></html>