📄 ch20.htm
字号:
<P><I>Listing </I><I>20.4—DierollCtl.cpp—CDierollCtrl::CDierollCtrlFactory::UpdateRegistry()</I></P>
<pre><font color="#008000">BOOL CDierollCtrl::CDierollCtrlFactory::UpdateRegistry(BOOL bRegister)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> // TODO: Verify that your control follows apartment-model threading rules.</font></pre>
<pre><font color="#008000"> // Refer to MFC TechNote 64 for more information.</font></pre>
<pre><font color="#008000"> // If your control does not conform to the apartment-model rules, then</font></pre>
<pre><font color="#008000"> // you must modify the code below, changing the 6th parameter from</font></pre>
<pre><font color="#008000"> // afxRegInsertable | afxRegApartmentThreading to afxRegInsertable.</font></pre>
<pre><font color="#008000"> if (bRegister)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> HRESULT hr = S_OK ;</font></pre>
<pre><font color="#008000"> // register as safe for scripting</font></pre>
<pre><font color="#008000"> hr = CreateComponentCategory(CATID_SafeForScripting,</font></pre>
<pre><font color="#008000"> L"Controls that are safely scriptable");</font></pre>
<pre><font color="#008000"> if (FAILED(hr))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> hr = RegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting);</font></pre>
<pre><font color="#008000"> if (FAILED(hr))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> // register as safe for initializing</font></pre>
<pre><font color="#008000"> hr = CreateComponentCategory(CATID_SafeForInitializing,</font></pre>
<pre><font color="#008000"> L"Controls safely initializable from persistent data");</font></pre>
<pre><font color="#008000"> if (FAILED(hr))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> hr = RegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing);</font></pre>
<pre><font color="#008000"> if (FAILED(hr))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> return AfxOleRegisterControlClass(</font></pre>
<pre><font color="#008000"> AfxGetInstanceHandle(),</font></pre>
<pre><font color="#008000"> m_clsid,</font></pre>
<pre><font color="#008000"> m_lpszProgID,</font></pre>
<pre><font color="#008000"> IDS_DIEROLL,</font></pre>
<pre><font color="#008000"> IDB_DIEROLL,</font></pre>
<pre><font color="#008000"> afxRegInsertable | afxRegApartmentThreading,</font></pre>
<pre><font color="#008000"> _dwDierollOleMisc,</font></pre>
<pre><font color="#008000"> _tlid,</font></pre>
<pre><font color="#008000"> _wVerMajor,</font></pre>
<pre><font color="#008000"> _wVerMinor);</font></pre>
<pre><font color="#008000"> else</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> HRESULT hr = S_OK ;</font></pre>
<pre><font color="#008000"> hr = UnRegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting);</font></pre>
<pre><font color="#008000"> if (FAILED(hr))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> hr = UnRegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing);</font></pre>
<pre><font color="#008000"> if (FAILED(hr))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> return AfxOleUnregisterClass(m_clsid, m_lpszProgID);</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000">}</font></pre>
<P>To confirm that this works, open Explorer and set your safety level to Medium. Load the HTML page that uses the control; it should warn you the control is unsafe. Then make these changes, build the control, and reload the page. The warning will not
reappear.</P>
<H3><A ID="I6" NAME="I6"><B>Choosing Between ActiveX and Java</B></A></H3>
<P>Java is an application development language as well as an applet development language, which means you can develop ActiveX controls in Java if you choose to, using a tool like Microsoft’s Visual J++ integrated into Developer Studio. But when most
people frame a showdown like "ActiveX vs. Java," they mean ActiveX vs. Java <I>applets</I>, which are little tightly contained applications that run on a Web page and cannot run stand-alone.</P>
<P>Many people are concerned about the security of running an application they did not code, when they do not know the person or organization supplying the application. The Java approach attempts to restrict the actions that applets can perform, so that
even malicious applets cannot do any real damage. But regular announcements of flaws in the restriction approach are damaging the credibility of Java. Even if a Java applet was guaranteed to be safe, these same restrictions keep applets from doing certain
useful tasks.</P>
<P>The approach taken by Microsoft with ActiveX is the trusted supplier approach, which is extendable to Java and any other code that can run. Code is digitally signed so that you are sure who provided it, and that it has not been changed since it was
signed. This won't prevent bad things from happening if you run the code, but will guarantee that you know who is to blame if bad things do occur. This is just the same as buying shrink-wrapped software from the shelf in the computer store. For more
details, look at <A HREF="tppmsgs/msgs0.htm#24" tppabs="http://www.microsoft.com/ie/most/howto/trusted.htm" target="_top"><B>http://www.microsoft.com/ie/most/howto/trusted.htm</B></A> and follow some of the links from that page.</P>
<P>Probably the biggest difference between the ActiveX approach and the Java applet approach is downloading. Java code is downloaded every time you load the page that contains it. ActiveX code is downloaded once, unless you already have the control
installed some other way (perhaps a CD was sent to you in a magazine, for example) and then never again. A copy is stored on the user's machine and entered into the Registry. The Java code that is downloaded is small, because most of the code that's
involved is in the Java Virtual Machine installed on your computer, probably as part of your browser.</P>
<P>The ActiveX code that’s downloaded can be much larger, though the optimizations discussed in the next section can reduce the size significantly by relying on DLLs and other code already on the user's computer. If users will come to this page once
and never again, they may be annoyed to find ActiveX controls cluttering up their disk and Registry. On the other hand, if they come to the same page repeatedly, they will be pleased to find that there is no download time: The control simply activates and
runs.</P>
<P>There are still other differences. Java applets cannot fire events to notify the container that something has happened. Java applets cannot be licensed, and often don’t distinguish between design-time and run-time use. Java applets can’t be
used in Visual Basic forms or VC++ programs or Word documents in the same way that ActiveX controls can. ActiveX controls are about 10 times faster than Java applets. In their favor, Java applets are genuinely multi-platform and typically smaller than the
equivalent ActiveX control.</P>
<H3><A ID="I7" NAME="I7"><B>Using AppWizard to Create Faster ActiveX Controls</B></A></H3>
<P>Microsoft did not develop OCX controls to be placed into web pages, and changing their name to ActiveX controls didn't magically make them smaller, or faster to load. So the AppWizard that comes with Visual C++ has a number of options available to
achieve those ends. This chapter will change these options in the Dieroll control that was aleady created just to show how it's done. Since Dieroll is a fairly lean control already, and loads quickly, these simple changes won't make much difference. It's
worth learning the techniques, though, for your own controls, which will surely be fatter than Dieroll.</P>
<P>The first few options to reduce the size of your control have always been available on Step 2 of the ActiveX Control Wizard:</P>
<ul>
<li> Activates when visible</P>
<li> Invisible at runtime</P>
<li> Available in Insert Object dialog box</P>
<li> Has an About box</P>
<li> Acts as a simple frame control</P>
</ul>
<P>If you are developing your control entirely for the web, many of these settings won't matter anymore. For example, it doesn’t matter whether or not your control has an About box; users won't be able to bring it up when they are viewing the control
in a web page.</P>
<P>The Activates When Visible option is very important. Activating a control takes a lot of overhead activity, and should be postponed as long as possible so that your control appears to load quickly. If your control activates as soon as it is visible,
you will add to the time it takes to load your control. To deselect this option in the existing Dieroll code, open the Dieroll project in Developer Studio, and open DierollCtl.cpp with FileView. Look for a block of code like the one in Listing 20.5.</P>
<P><I>Listing 20.5—Excerpt from DierollCtl.cpp—Setting Activates When </I><I>Visible</I></P>
<pre><font color="#008000">/////////////////////////////////////////////////////////////////////////////</font></pre>
<pre><font color="#008000">// Control type information</font></pre>
<pre><font color="#008000">static const DWORD BASED_CODE _dwDierollOleMisc =</font></pre>
<pre><font color="#008000"> OLEMISC_ACTIVATEWHENVISIBLE |</font></pre>
<pre><font color="#008000"> OLEMISC_SETCLIENTSITEFIRST |</font></pre>
<pre><font color="#008000"> OLEMISC_INSIDEOUT |</font></pre>
<pre><font color="#008000"> OLEMISC_CANTLINKINSIDE |</font></pre>
<pre><font color="#008000"> OLEMISC_RECOMPOSEONRESIZE;</font></pre>
<pre><font color="#008000">IMPLEMENT_OLECTLTYPE(CDierollCtrl, IDS_DIEROLL, _dwDierollOleMisc)</font></pre>
<P>Delete the <font color="#008000">OLEMISC_ACTIVATEWHENVISIBLE</font> line. Build a release version of the application. Though the size of the Dieroll OCX file is unchanged, web pages with this control should load more quickly, since the window is not
created until the user first clicks on the die. If you reload the web page with the die in it, you'll see the first value immediately, even though the control is inactive. The window is created to catch mouse clicks, not to display the die roll.</P>
<P>There are more optimizations available. Figure 20.5 shows the list of advanced options for ActiveX Control Wizard, reached by clicking the Advanced button on Step 2. You can choose each of these options when you first build the application through the
Control Wizard. They can also be changed in an existing application, saving you the trouble of redoing AppWizard and adding your own functionality again. The options are:</P>
<ul>
<li> Windowless Activation</P>
<li> Unclipped Device Context</P>
<li> Flicker-free Activation</P>
<li> Mouse Pointer Notifications When Inactive</P>
<li> Optimized Drawing Code</P>
<li> Loads Properties Asynchronously</P>
</ul>
<A HREF="Vfigs05.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch20/Vfigs05.gif"><b>Fig. 20.5</b></A>
<P><I>The Advanced button on Step 2 of the ActiveX Control Wizard leads to a choice of optimizations.</I></P>
<P>Windowless Activation is going to be very popular because of the benefits it provides. If you want a transparent control or one that is not a rectangle, you must use Windowless Activation. However, because it reduces code size and speeds execution,
every control should consider using this option. Modern containers will provide the functionality for the control. In older containers, the control will create the window anyway, denying you the savings but ensuring the control still works.</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -