?? ch15.htm
字號:
string table there, click IDR_SHOWSTTYPE once to highlight it, and choose View, Properties
(or double-click the string). This string is saved in the document template when
a new one is constructed in CShowStringApp::InitInstance(), like this:</P>
<P>
<H4>Listing 15.12   ShowString.cpp--Excerpt from ShowStringApp::InitInstance()</H4>
<PRE> pDocTemplate = new CMultiDocTemplate(
IDR_SHOWSTTYPE,
RUNTIME_CLASS(CShowStringDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
</PRE>
<PRE> RUNTIME_CLASS(CShowStringView));
</PRE>
<P>The caption of the menu resource holds seven strings, and each is used by a different
part of the framework. They are separated by the newline character \n. The seven
strings, their purposes, and the values provided by AppWizard for ShowString are
as follows:</P>
<P>
<UL>
<LI><B>Window Title--</B>Used by SDI apps in the title bar. For ShowString: not provided.
<P>
<LI><B>Document Name--</B>Used as the root for default document names. For ShowString:
ShowSt, so that new documents will be ShowSt1, ShowSt2, and so on.
<P>
<LI><B>File New Name--</B>Prompt in the File New dialog box for file type. (For example,
in Developer Studio there are eight file types, including Text File and Project Workspace.)
For ShowString: ShowSt.
<P>
<LI><B>Filter Name--</B>An entry for the drop-down box Files of Type in the File
Open dialog box. For ShowString: not provided.
<P>
<LI><B>Filter Extension--</B>The extension that matches the filter name. For ShowString:
not provided.
<P>
<LI><B>Registry File Type ID--</B>A short string to be stored in the Registry. For
ShowString: ShowString.Document.
<P>
<LI><B>Registry File Type Name--</B>A longer string that shows in dialog boxes involving
the Registry. For ShowString: ShowSt Document.
</UL>
<P>Look again at Figure 15.5 and you can see where these values came from. Try changing
the last entry. In the Properties dialog box, change the caption so that the last
element of the string is ShowString Document and press Enter. Build the project.
Run it once and exit. In the output section of Developer Studio, you see these messages:</P>
<P>
<PRE>Warning: Leaving value `ShowSt Document' for key `ShowString.Document'
in registry
intended value was `ShowString Document'.
Warning: Leaving value `ShowSt Document' for key
`CLSID\{0B1DEE40-C373-11CF-870C-00201801DDD6}' in registry
intended value was `ShowString Document'.
</PRE>
<P>This means that the call to UpdateRegistry() did not change these two keys. There
is a way to provide parameters to UpdateRegistry() to insist that the keys be updated,
but it's even more complicated than the route you will follow. Because no code has
been changed from that provided by AppWizard, it's much quicker to delete the ShowString
directory and create it again, this time setting the long file type to ShowString
<P>
<BLOCKQUOTE>
<P>
<HR>
<strong>CAUTTION:</strong><B> </B>Always test AppWizard-generated code before you add changes
of your own. Until you are familiar with every default you are accepting, it is worth
a few moments to see what you have before moving on. Rerunning AppWizard is easy,
but if you've made several hours worth of changes and then decide to rerun it, it's
not such a simple task.
<HR>
</BLOCKQUOTE>
<P>Close Visual Studio, delete the ShowString folder entirely, and generate a new
application with AppWizard as before. This time, in Step 4, click the Advanced button
and change the file type names as shown in Figure 15.6. After you click Finish, AppWizard
asks whether you wish to reuse the existing CLSID, as shown in Figure 15.7. Click
Yes and then OK to create the project. This makes a new showstring.reg file for you
with the correct Registry values.</P>
<P><A HREF="javascript:popUp('15uvc06.gif')"><B>FIG. 15.6</B></A><B> </B><I>The Advanced
Options dialog box of Step 4 of AppWizard is the place to improve the file type names.</I></P>
<P><A HREF="javascript:popUp('15uvc07.gif')"><B>FIG. 15.7</B></A><B> </B><I>AppWizard
makes sure that you don't accidentally reuse a CLSID.</I></P>
<P>This changes the string table as well as the showstring.reg file, so you might
be tempted to build and run the application to make this fix complete. It's true,
when you run the application, it will update the Registry for you, using the values
from the new string table. Alas, the registration update will fail yet again. If
you were to try it, these messages would appear in the output window:</P>
<P>
<PRE>Warning: Leaving value `ShowSt Document' for key
`ShowString.Document' in registry
intended value was `ShowString Document'.
Warning: Leaving value `ShowSt Document' for key
`CLSID\{0B1DEE40-C373-11CF-870C-00201801DDD6}' in registry
intended value was `ShowString Document'.
Warning: Leaving value `ShowSt' for key
`CLSID\{0B1DEE40-C373-11CF-870C-00201801DDD6}\AuxUserType\2'
in registry
intended value was `ShowString'.
</PRE>
<P>So, how do you get out of this mess? You have to edit the Registry. If that doesn't
sound intimidating, it should. Messing with the Registry can leave your system unusable.
But you are not going to go in by hand and change keys; instead, you are going to
use the Registry file that AppWizard generated for you. Here's what to do:</P>
<P>
<DL>
<DD><B>1. </B>Choose Start, Run.
<P>
<DT></DT>
<DD><B>2. </B>Type <B>regedit</B> and press Enter.
<P>
<DT></DT>
<DD><B>3. </B>Choose Registry, Import Registry File from the Registry Editor menu.
<P>
<DT></DT>
<DD><B>4. </B>Using the Import Registry File dialog box, move through your folders
until you reach the one where the replacement ShowString server was just generated
by AppWizard, as shown in Figure 15.8. Click Open.
<P>
<DT></DT>
<DD><B>5. </B>A success message is shown. Click OK.
<P>
<DT></DT>
<DD><B>6. </B>Close the Registry Editor.
<P>
</DL>
<P><A HREF="javascript:popUp('15uvc08.gif')"><B>FIG. 15.8</B></A><B> </B><I>Registry
files generated by AppWizard have the extension .reg.</I></P>
<P><I><BR>
</I>Now if you run ShowString again, those error messages don't appear. Run Word
again and choose Insert, Object. The Object dialog box now has a more meaningful
ShowString entry, as shown in Figure 15.9.</P>
<BLOCKQUOTE>
<P>
<HR>
<strong>NOTE:</strong> There are three morals to this side trip. The first is that you should
think really carefully before clicking Finish on the AppWizard dialog box. The second
is that you cannot ignore the Registry if you are an ActiveX programmer. The third
is that anything can be changed if you have the nerve for it. 
<HR>
</BLOCKQUOTE>
<P>Click OK on the Object dialog box to insert a ShowString object into the Word
document. You can immediately edit it in place, as shown in Figure 15.10. You can
see that the combined server and container in-place menus are being used. There's
not much you can do to the embedded object at this point because the ShowString code
that actually shows a string has not been added. Press Esc to finish editing in place,
and the menus return to the usual Word menus, as shown in Figure 15.11.</P>
<P><A HREF="javascript:popUp('15uvc09.gif')"><B>FIG. 15.9</B></A><B> </B><I>The updated
long file type name appears in the Object dialog box of other applications.</I></P>
<P><A HREF="javascript:popUp('15uvc10.gif')"><B>FIG. 15.10</B></A><B> </B><I>While
editing in place, the in-place menus replace the Word menus.</I></P>
<P><A HREF="javascript:popUp('15uvc11.gif')"><B>FIG. 15.11</B></A><B> </B><I>When
the object is inactive, Word reminds the user of the object type.</I></P>
<P>Although this server doesn't do anything, it is a perfectly good server. You can
resize and move the embedded item while it is active or inactive, and everything
operates exactly as you expect. All that remains is to restore the ShowString functionality.</P>
<P>
<H3><A NAME="Heading3"></A>Showing a String Again</H3>
<P>As you did in Chapter 14, it is time to add the ShowString functionality to this
version of the program. If you went through this process before, it will be even
quicker this time. Remember to open the ShowString files from Chapter 8, so that
you can copy code and resources from the functional ShowString to the do-nothing
ActiveX server you have just created and explored. (If you didn't code along in Chapter
8, you can get the completed code on the Web at <A target="_new" HREF="http://www.mcp.com/info"><B>www.mcp.com/info</B></A>
or <A target="_new" HREF="http://www.gregcons.com/uvc6.htm"><B>www.gregcons.com/uvc6.htm</B></A>.)
Here's what to do:</P>
<P>
<DL>
<DT></DT>
<DD><B>1. </B>In ShowStringDoc.h, add the private member variables and public Get
functions to the class.
<P>
<DT></DT>
<DD><B>2. </B>In CShowStringDoc::Serialize(), paste in the code that saves or restores
these member variables.
<P>
<DT></DT>
<DD><B>3. </B>In CShowStringDoc::OnNewDocument(), paste in the code that initializes
the member variables. Change the default values of horizcenter and vertcenter to
FALSE. You'll see why towards the end of the chapter.
<P>
<DT></DT>
<DD><B>4. </B>Copy the entire Tools menu from the old ShowString to the new server
ShowString. Choose File, Open to open the old ShowString.rc, open the IDR_SHOWSTTYPE
menu, click the Tools menu, and choose Edit, Copy. Open the new ShowString's IDR_SHOWSTTYPE
menu, click the Window menu, and choose Edit, Paste.
<P>
<DT></DT>
<DD><B>5. </B>Paste the Tools menu into the IDR_SHOWSTTYPE_SRVR_IP (before the separator
bars) and IDR_SHOWSTTYPE_SRVR_EMB menus in the same way.
<P>
<DT></DT>
<DD><B>6. </B>Add the accelerator Ctrl+T for ID_TOOLS_OPTIONS as described in Chapter
8. Add it to all three accelerators.
<P>
<DT></DT>
<DD><B>7. </B>Delete the IDD_ABOUTBOX dialog box from the new ShowString. Copy IDD_ABOUTBOX
and IDD_OPTIONS from the old ShowString to the new.
<P>
<DT></DT>
<DD><B>8. </B>While IDD_OPTIONS has focus, choose View, ClassWizard. Create the COptionsDialog
class as in the original ShowString.
<P>
<DT></DT>
<DD><B>9. </B>Use ClassWizard to arrange for CShowStringDoc to catch the ID_TOOLS_OPTIONS
command.
<P>
<DT></DT>
<DD><B>10. </B>In ShowStringDoc.cpp, replace the ClassWizard version of CShowStringDoc::OnToolsOptions()
with the one that puts up the dialog box.
<P>
<DT></DT>
<DD><B>11. </B>In ShowStringDoc.cpp, add <B>#include "OptionsDialog.h"</B>
after the #include statements already present.
<P>
<DT></DT>
<DD><B>12. </B>Use ClassWizard to connect the dialog box controls to COptionsDialog
member variables as before. Connect IDC_OPTIONS_BLACK to m_color, IDC_OPTIONS_HORIZCENTER
to m_horizcenter, IDC_OPTIONS_STRING to m_string, and IDC_OPTIONS_VERTCENTER to m_vertcenter.
<P>
</DL>
<P>To confirm you've made all the changes correctly, build the project--there should
be no errors.</P>
<P>You haven't restored CShowStringView::OnDraw() yet because there are actually
going to be two OnDraw() functions. The first is in the view class, shown in Listing
15.13. It draws the string when ShowString is running standalone and when the user
is editing in place, and it's the same as in the old version of ShowString. Just
copy it into the new one.</P>
<P>
<H4>Listing 15.13  ShowStringView.cpp--CShowStringView::OnDraw()</H4>
<PRE>void CShowStringView::OnDraw(CDC* pDC)
{
CShowStringDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
COLORREF oldcolor;
switch (pDoc->GetColor())
{
case 0:
oldcolor = pDC->SetTextColor(RGB(0,0,0)); //black
break;
case 1:
oldcolor = pDC->SetTextColor(RGB(0xFF,0,0)); //red
break;
case 2:
oldcolor = pDC->SetTextColor(RGB(0,0xFF,0)); //green
break;
}
int DTflags = 0;
if (pDoc->GetHorizcenter())
{
DTflags |= DT_CENTER;
}
if (pDoc->GetVertcenter())
{
DTflags |= (DT_VCENTER|DT_SINGLELINE);
}
CRect rect;
GetClientRect(&rect);
pDC->DrawText(pDoc->GetString(), &rect, DTflags);
pDC->SetTextColor(oldcolor);
</PRE>
<PRE>}
</PRE>
<P>When the embedded ShowString item is inactive, CShowStringSrvrItem::OnDraw() draws
it. The code in here should be very similar to the view's OnDraw, but because it
is a member of CShowStringSrvrItem rather than CShowStringView, it doesn't have access
to the same member variables. So although there is still a GetDocument() function
you can call, GetClientRect doesn't work. It's a member of the view class but not
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -