⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch21.htm

📁 VC使用大全。里面集合了VC使用的各种使用技巧。非常有用。
💻 HTM
📖 第 1 页 / 共 5 页
字号:

<pre><font color="#008000">    m_Data = NULL;</font></pre>
<pre><font color="#008000">    m_DataLength = 0;</font></pre>
<pre><font color="#008000">    m_bstrImage = newVal;</font></pre>
<pre><font color="#008000">    LPSTR string = 
W2A(m_bstrImage);</font></pre>
<pre><font color="#008000">    if (string != NULL &amp;&amp; strlen(string) &gt; 0)</font></pre>
<pre><font color="#008000">    {</font></pre>
<pre><font color="#008000">        // not a null string so try to load 
it</font></pre>
<pre><font color="#008000">        BOOL relativeURL = FALSE;</font></pre>
<pre><font color="#008000">        if (strchr(string, ':') == NULL)</font></pre>
<pre><font color="#008000">        {</font></pre>
<pre><font color="#008000">            
relativeURL = TRUE;</font></pre>
<pre><font color="#008000">        }</font></pre>
<pre><font color="#008000">        m_nReadyState = READYSTATE_LOADING;</font></pre>
<pre><font color="#008000">        HRESULT ret = 
CBindStatusCallback&lt;CDieRoll&gt;::Download(this, </font></pre>
<pre><font color="#008000">            OnData, m_bstrImage, m_spClientSite, relativeURL);</font></pre>
<pre><font color="#008000">    }    else</font></pre>
<pre><font color="#008000">    
{</font></pre>
<pre><font color="#008000">        // was a null string so don't try to load it</font></pre>
<pre><font color="#008000">        m_nReadyState = READYSTATE_INTERACTIVE;</font></pre>
<pre><font color="#008000">}</font></pre>
<pre><font 
color="#008000">    SetDirty(TRUE);</font></pre>
<pre><font color="#008000">    FireOnChanged(dispidImage);</font></pre>
<pre><font color="#008000">    return S_OK;</font></pre>
<pre><font color="#008000">}</font></pre>
<P>As with Numbers and Dots, the 
<font color="#008000">get</font> function is straightforward, and the <font color="#008000">put</font> function is a bit more complicated. The beginning and end of the function is like <font color="#008000">put_Dots(),</font> firing notifications to check 
if the variable can be changed, then other notifications that it was changed. In between is the code unique to an asynchronous property. </P>
<P>To start the download of the asynchronous property, this function will call <font 
color="#008000">CBindStatusCallback&lt;CDieRoll&gt;::Download()</font> but first it needs to determine whether the URL in m_bstrImage is a relative or absolute URL. Use the ATL macro <font color="#008000">W2A</font> to convert the wide <font 
color="#008000">BSTR</font> to an ordinary C string so that the C function <font color="#008000">strchr()</font> can be used to search for a <font color="#008000">:</font> character in the URL. A URL with no <font color="#008000">:</font> in it is assumed 
to be a relative URL.</P>
<blockquote><p><img src="note.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/note.gif">
<P>A <font color="#008000">BSTR</font> is a wide (double-byte) character on all 32-bit Windows platforms. It is a narrow (single-byte) string on a PowerMac.</P>
<p><img 
src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>
<P>In the MFC version of the dieroll control with an asynchronous image property, whenever a block of data came through, the <font color="#008000">OnDataAvailable()</font> function was called. The call to Download() arranges 
for a function called <font color="#008000">OnData() to be called when data arrives. You will write the </font><font color="#008000">OnData() function</font>. Add it to the class with the other public functions and add the implementation shown in Listing 
21.9 to DieRoll.cpp.</P>
<P><I>Listing 21.9&#151;DieRoll.cpp&#151;CDieRoll::OnData()</I></P>
<pre><font color="#008000">void CDieRoll::OnData(CBindStatusCallback&lt;CDieRoll&gt;* pbsc, </font></pre>
<pre><font color="#008000">                      BYTE * 
pBytes, DWORD dwSize)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000">    char *newData = new char[m_DataLength + dwSize];</font></pre>
<pre><font color="#008000">    memcpy(newData, m_Data, m_DataLength);</font></pre>

<pre><font color="#008000">    memcpy(newData+m_DataLength, pBytes, dwSize);</font></pre>
<pre><font color="#008000">    m_DataLength += dwSize;</font></pre>
<pre><font color="#008000">    delete m_Data;</font></pre>
<pre><font color="#008000">    m_Data = 
newData;</font></pre>
<pre><font color="#008000">    if (ReadBitmap())</font></pre>
<pre><font color="#008000">    {</font></pre>
<pre><font color="#008000">        m_nReadyState = READYSTATE_COMPLETE;</font></pre>
<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">}</font></pre>
<P>Since there is no <font color="#008000">realloc()</font> when using new, this function uses<font color="#008000"> new </font>to allocate enough <font color="#008000">char</font>s to hold the data that has 
already been read (<font color="#008000">m_DataLength</font>) and the new data that is coming in (<font color="#008000">dwSize</font>), then copies <font color="#008000">m_Data</font> to this block, and the new data (<font color="#008000">pBytes</font>) 
after <font color="#008000">m_Data</font>. It then attempts to convert the data that has been recieved so far into a bitmap: if this succeeds the download must be complete and the call to <font color="#008000">FireViewChange()</font> sends a notification 
to the container to redraw the view. You can get the <font color="#008000">ReadBitmap()</font> function from the CD and add it to your project: it's much like the MFC version but it does not use any MFC classes like <font color="#008000">Cfile</font>.</P>

<H3><B>Drawing the Control</B></H3>
<P>Now that all the properties have been added, you can code <font color="#008000">OnDraw().</font> While the basic structure of this function is the same as in the MFC version of <A HREF="index20.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index20.htm" 
target="text">Chapter 20</A>, &#147;Building an Internet ActiveX Control,&#148; there is a lot more work to be done because you cannot rely on MFC to do some of it for you.</P>
<P>The structure of <font color="#008000">OnDraw()</font> is:</P>
<pre><font 
color="#008000">HRESULT CDieRoll::OnDraw(ATL_DRAWINFO&amp; di)</font></pre>
<pre><font color="#008000">// if the bitmap is ready, draw it</font></pre>
<pre><font color="#008000">// else draw a plan background using BackColor</font></pre>
<pre><font 
color="#008000">// if !Dots draw a number in ForeColor</font></pre>
<pre><font color="#008000">// else draw the dots</font></pre>
<P>First, you need to test if the bitmap is ready, and draw it if possible. This code is in Listing 21.10: add it to the 
existing <font color="#008000">OnDraw()</font> in place of the code left for you by AppWizard. Notice that if <font color="#008000">ReadyState</font> is <font color="#008000">READYSTATE_COMPLETE</font> but the call to <font 
color="#008000">CreateDIBitmap()</font> doesn't result in a valid bitmap handle, the bitmap member variables are cleared away to make subsequent calls to this function give up a little faster. This chapter will not discuss how to draw bitmaps.</P>

<P><I>Listing 21.10&#151;CDieRoll::OnDraw()&#151;Use the Bitmap</I></P>
<pre><font color="#008000">    int width = (di.prcBounds-&gt;right - di.prcBounds-&gt;left + 1);</font></pre>
<pre><font color="#008000">    int height = (di.prcBounds-&gt;bottom - 
di.prcBounds-&gt;top + 1); </font></pre>
<pre><font color="#008000">    BOOL drawn = FALSE;</font></pre>
<pre><font color="#008000">    if (m_nReadyState == READYSTATE_COMPLETE)</font></pre>
<pre><font color="#008000">    {</font></pre>
<pre><font 
color="#008000">        if (BitmapDataLoaded)</font></pre>
<pre><font color="#008000">        {</font></pre>
<pre><font color="#008000">            hBitmap = ::CreateDIBitmap(di.hdcDraw, &amp;bmih, CBM_INIT, lpvBits, </font></pre>
<pre><font 
color="#008000">                lpbmi, DIB_RGB_COLORS);</font></pre>
<pre><font color="#008000">            if (hBitmap)</font></pre>
<pre><font color="#008000">            {</font></pre>
<pre><font color="#008000">                HDC hmemdc;</font></pre>

<pre><font color="#008000">                hmemdc = ::CreateCompatibleDC(di.hdcDraw);</font></pre>
<pre><font color="#008000">                ::SelectObject(hmemdc, hBitmap);</font></pre>
<pre><font color="#008000">                DIBSECTION 
ds;</font></pre>
<pre><font color="#008000">                ::GetObject(hBitmap,sizeof(DIBSECTION),(LPSTR)&amp;ds);</font></pre>
<pre><font color="#008000">                ::StretchBlt(di.hdcDraw,</font></pre>
<pre><font color="#008000">                                
di.prcBounds-&gt;left, // left</font></pre>
<pre><font color="#008000">                                di.prcBounds-&gt;top,  // top</font></pre>
<pre><font color="#008000">                                width, // target width</font></pre>
<pre><font 
color="#008000">                                height, // target height</font></pre>
<pre><font color="#008000">                                hmemdc,        // the image</font></pre>
<pre><font color="#008000">                                0,            
//offset into image -x</font></pre>
<pre><font color="#008000">                                0,            //offset into image -y</font></pre>
<pre><font color="#008000">                                ds.dsBm.bmWidth, // width</font></pre>
<pre><font 
color="#008000">                                ds.dsBm.bmHeight, // height</font></pre>
<pre><font color="#008000">                                SRCCOPY);    //copy it over</font></pre>
<pre><font color="#008000">                drawn = 
TRUE;</font></pre>
<pre><font color="#008000">                ::DeleteObject(hBitmap);</font></pre>
<pre><font color="#008000">                hBitmap = NULL;</font></pre>
<pre><font color="#008000">                ::DeleteDC(hmemdc);</font></pre>

<pre><font color="#008000">            }</font></pre>
<pre><font color="#008000">            else</font></pre>
<pre><font color="#008000">            {</font></pre>
<pre><font color="#008000">                GlobalUnlock(hmem1);</font></pre>
<pre><font 
color="#008000">                GlobalFree(hmem1);</font></pre>
<pre><font color="#008000">                GlobalUnlock(hmem2);</font></pre>
<pre><font color="#008000">                GlobalFree(hmem2);</font></pre>
<pre><font color="#008000">                
BitmapDataLoaded = FALSE;</font></pre>
<pre><font color="#008000">            }</font></pre>
<pre><font color="#008000">        }</font></pre>
<pre><font color="#008000">    }</font></pre>
<P>If the bitmap was not drawn, either because <font 
color="#008000">ReadyState</font> is not <font color="#008000">READYSTATE_COMPLETE</font> yet or because there was a problem with the bitmap,<font color="#008000"> </font><font color="#008000">OnDraw()</font> draws a solid background by using the <font 
color="#008000">BackColor</font> property, as shown in Listing 21.11. Add this code to OnDraw(). The SDK calls are very similar to the MFC calls used in the MFC version of DieRoll: for example <font color="#008000">::OleTranslateColor()</font> corresponds 
to <font color="#008000">TranslateColor()</font>.</P>
<P><I>Listing 21.11&#151;CDieRoll::OnDraw()&#151;Draw a solid background</I></P>
<pre><font color="#008000">    if (!drawn)</font></pre>
<pre><font color="#008000">    {</font></pre>
<pre><font 
color="#008000">        COLORREF back;</font></pre>
<pre><font color="#008000">        ::OleTranslateColor(m_clrBackColor, NULL, &amp;back);</font></pre>
<pre><font color="#008000">        HBRUSH backbrush = ::CreateSolidBrush(back);</font></pre>

<pre><font color="#008000">        ::FillRect(di.hdcDraw, (RECT *)di.prcBounds, backbrush);</font></pre>
<pre><font color="#008000">        ::DeleteObject(backbrush);</font></pre>
<pre><font color="#008000">    }</font></pre>
<P>With the background drawn, 
either as a bitmap image or a solid color, <font color="#008000">OnDraw()</font> must now tackle the foreground. Getting the foreground color is quite simple. Add these two lines to OnDraw():</P>
<pre><font color="#008000">    COLORREF fore;</font></pre>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -