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

📄 faq76.htm

📁 C++builder学习资料C++builder
💻 HTM
📖 第 1 页 / 共 3 页
字号:
    <font color="navy">// and then assign our method to the WindowProc property</font>

    FOriginalProc <b>=</b> ListView1<b>-></b>WindowProc<b>;</b>

    ListView1<b>-></b>WindowProc <b>=</b> ListViewProc<b>;</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

<b>__fastcall</b> TForm1<b>:</b><b>:</b><b>~</b>TForm1<b>(</b><b>)</b>

<b>{</b>

    <font color="navy">// Set the window proc back to the original function</font>

    ListView1<b>-></b>WindowProc <b>=</b> FOriginalProc<b>;</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

<b>void</b> <b>__fastcall</b> TForm1<b>:</b><b>:</b>ListViewProc<b>(</b>TMessage <b>&</b>msg<b>)</b>

<b>{</b>

    msg<b>.</b>Result <b>=</b> <font color="blue">0</font><b>;</b>

    <b>switch</b><b>(</b>msg<b>.</b>Msg<b>)</b>

    <b>{</b>

        <b>case</b> WM_ERASEBKGND<b>:</b>

            PaintListView<b>(</b><b>(</b>HDC<b>)</b>msg<b>.</b>WParam<b>)</b><b>;</b>

            msg<b>.</b>Result <b>=</b> <font color="blue">0</font><b>;</b>

            <b>break</b><b>;</b>

        <b>case</b> WM_HSCROLL<b>:</b>

        <b>case</b> WM_VSCROLL<b>:</b>

            LockWindowUpdate<b>(</b>ListView1<b>-></b>Handle<b>)</b><b>;</b>

            FOriginalProc<b>(</b>msg<b>)</b><b>;</b>

            InvalidateRect <b>(</b>ListView1<b>-></b>Handle<b>,</b> <font color="blue">0</font><b>,</b> <b>true</b><b>)</b><b>;</b>

            LockWindowUpdate<b>(</b>NULL<b>)</b><b>;</b>

            <b>break</b><b>;</b>

        <b>default</b><b>:</b>

            FOriginalProc<b>(</b>msg<b>)</b><b>;</b>

            <b>break</b><b>;</b>

    <b>}</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

<b>void</b> <b>__fastcall</b> TForm1<b>:</b><b>:</b>PaintListView<b>(</b>HDC <b>&</b>dc<b>)</b>

<b>{</b>

    <font color="navy">//Same painting code as before</font>

    <b>...</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

<b>void</b> <b>__fastcall</b><b>/</b> TForm1<b>:</b><b>:</b>FormResize<b>(</b>TObject <b>*</b>Sender<b>)</b>

<b>{</b>

    ListView1<b>-></b>Repaint<b>(</b><b>)</b><b>;</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

</pre>



<P>

<B>Note:</B> Notice that value returned by the <TT>WindowProc</TT> property is of the type <TT>TWndMethod</TT> and

not <TT>WNDPROC</TT>. This has an important consequence. <TT>TWndMethod</TT> functions already know how to deal with

the VCL's <TT>TMessage</TT> structure. This means that you can call the original <TT>WindowProc</TT> function without

bothering with the API <TT>CallWindowProc</TT> function. You simply call the original <TT>WindowProc</TT> and pass it

the <TT>TMessage</TT> structure.

</P>





<BR>



<H4>

Subclassing by deriving a new control</H4>

<P>

It turns out all VCL classes that inherit from <TT>TWinControl</TT> already subclass the window handle of the control.

The subclassing is done so that the VCL class can respond to messages sent to the control. Without subclassing, none

of the internal message maps or <TT>WndProc</TT> functions would ever get called. In fact, the base class uses

<TT>MakeObjectInstance</TT> to perform the subclassing, and the subclassed proc executes the function stored

by the <TT>WindowProc</TT> property to handle the message (see <TT>TWinControl.MainWndProc</TT> in CONTROLS.PAS).

</P>

<P>

Because VCL classes already subclass the window handle, you can intercept messages by deriving a new class from a

VCL base class. When you utilize this technique, you subclass a window handle by subclassing, or inheriting from, a

existing base class. The code below shows how to derive a class from <TT>TListView</TT> that paints the custom

background.

</P>

<pre>

<font color="navy">//-------------------------------------------------------</font>

<font color="navy">// header file</font>

<b>class</b> PACKAGE TXListView <b>:</b> <b>public</b> TListView

<b>{</b>

<b>private</b><b>:</b>

<b>protected</b><b>:</b>

    <b>void</b> <b>__fastcall</b> WndProc<b>(</b>TMessage <b>&</b>msg<b>)</b><b>;</b>

    <b>void</b> <b>__fastcall</b> PaintListView<b>(</b>HDC <b>&</b>dc<b>)</b><b>;</b>

<b>public</b><b>:</b>

    <b>__fastcall</b> TXListView<b>(</b>TComponent<b>*</b> Owner<b>)</b><b>;</b>

<b>}</b><b>;</b>





<font color="navy">//-------------------------------------------------------</font>

<font color="navy">// source file</font>



<font color="navy">//-------------------------------------------------------</font>

<b>__fastcall</b> TXListView<b>:</b><b>:</b>TXListView<b>(</b>TComponent<b>*</b> Owner<b>)</b>

    <b>:</b> TListView<b>(</b>Owner<b>)</b>

<b>{</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

<b>void</b> <b>__fastcall</b> TXListView<b>:</b><b>:</b>WndProc<b>(</b>TMessage <b>&</b>msg<b>)</b>

<b>{</b>

    msg<b>.</b>Result <b>=</b> <font color="blue">0</font><b>;</b>

    <b>switch</b><b>(</b>msg<b>.</b>Msg<b>)</b>

    <b>{</b>

        <b>case</b> WM_ERASEBKGND<b>:</b>

            PaintListView<b>(</b><b>(</b>HDC<b>)</b>msg<b>.</b>WParam<b>)</b><b>;</b>

            msg<b>.</b>Result <b>=</b> <font color="blue">0</font><b>;</b>

            <b>break</b><b>;</b>

        <b>case</b> WM_HSCROLL<b>:</b>

        <b>case</b> WM_VSCROLL<b>:</b>

            LockWindowUpdate<b>(</b>Handle<b>)</b><b>;</b>

            TListView<b>:</b><b>:</b>WndProc<b>(</b>msg<b>)</b><b>;</b>

            InvalidateRect <b>(</b>Handle<b>,</b> <font color="blue">0</font><b>,</b> <b>true</b><b>)</b><b>;</b>

            LockWindowUpdate<b>(</b>NULL<b>)</b><b>;</b>

            <b>break</b><b>;</b>

        <b>default</b><b>:</b>

            TListView<b>:</b><b>:</b>WndProc<b>(</b>msg<b>)</b><b>;</b>

            <b>break</b><b>;</b>

    <b>}</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

<b>void</b> <b>__fastcall</b> TXListView<b>:</b><b>:</b>PaintListView<b>(</b>HDC <b>&</b>dc<b>)</b>

<b>{</b>

    TRect rect <b>=</b> BoundsRect<b>;</b>



    Graphics<b>:</b><b>:</b>TBitmap <b>*</b>MemBitmap <b>=</b> <b>new</b> Graphics<b>:</b><b>:</b>TBitmap<b>;</b>

    MemBitmap<b>-></b>Width <b>=</b> rect<b>.</b>Right <b>-</b> rect<b>.</b>Left<b>;</b>

    MemBitmap<b>-></b>Height<b>=</b> rect<b>.</b>Bottom<b>-</b> rect<b>.</b>Top<b>;</b>

    MemBitmap<b>-></b>Canvas<b>-></b>Brush<b>-></b>Style <b>=</b> bsSolid<b>;</b>

    MemBitmap<b>-></b>Canvas<b>-></b>Brush<b>-></b>Color <b>=</b> clAqua<b>;</b>

    MemBitmap<b>-></b>Canvas<b>-></b>FillRect<b>(</b>Rect<b>(</b><font color="blue">0</font><b>,</b><font color="blue">0</font><b>,</b>

                                   MemBitmap<b>-></b>Width<b>,</b>

                                   MemBitmap<b>-></b>Height<b>)</b><b>)</b><b>;</b>



    MemBitmap<b>-></b>Canvas<b>-></b>Pen<b>-></b>Color <b>=</b> clNavy<b>;</b>

    MemBitmap<b>-></b>Canvas<b>-></b>Pen<b>-></b>Width <b>=</b> <font color="blue">20</font><b>;</b>

    MemBitmap<b>-></b>Canvas<b>-></b>MoveTo<b>(</b><font color="blue">0</font><b>,</b><font color="blue">0</font><b>)</b><b>;</b>

    MemBitmap<b>-></b>Canvas<b>-></b>LineTo<b>(</b>MemBitmap<b>-></b>Width<b>,</b> MemBitmap<b>-></b>Height<b>)</b><b>;</b>



    <b>:</b><b>:</b>BitBlt<b>(</b>dc<b>,</b><font color="blue">0</font><b>,</b><font color="blue">0</font><b>,</b>MemBitmap<b>-></b>Width<b>,</b> MemBitmap<b>-></b>Height<b>,</b>

           MemBitmap<b>-></b>Canvas<b>-></b>Handle<b>,</b><font color="blue">0</font><b>,</b><font color="blue">0</font><b>,</b>SRCCOPY<b>)</b><b>;</b>

    <b>delete</b> MemBitmap<b>;</b>

<b>}</b>





<font color="navy">//-------------------------------------------------------</font>

<font color="navy">// using the component from a form</font>

<b>__fastcall</b> TForm1<b>:</b><b>:</b>TForm1<b>(</b>TComponent<b>*</b> Owner<b>)</b>

    <b>:</b> TForm<b>(</b>Owner<b>)</b>

<b>{</b>

    TXListView <b>*</b>ListView1 <b>=</b> <b>new</b> TXListView<b>(</b><b>this</b><b>)</b><b>;</b>

    ListView1<b>-></b>Align <b>=</b> alClient<b>;</b>

    ListView1<b>-></b>Parent <b>=</b> <b>this</b><b>;</b>

    ListView1<b>-></b>LargeImages <b>=</b> ImageList1<b>;</b>

    ListView1<b>-></b>IconOptions <b>-></b>Arrangement <b>=</b> iaLeft<b>;</b>



    <b>int</b> nCount <b>=</b> ImageList1<b>-></b>Count<b>;</b>

    <b>for</b><b>(</b><b>int</b> j<b>=</b><font color="blue">0</font><b>;</b> jItems<b>-></b>Add<b>(</b><b>)</b><b>;</b>

        item<b>-></b>Caption <b>=</b> <font color="blue">"item "</font> <b>+</b> IntToStr<b>(</b>j<b>)</b><b>;</b>

        item<b>-></b>ImageIndex <b>=</b> j<b>;</b>

    <b>}</b>

<b>}</b>

<font color="navy">//-------------------------------------------------------</font>

</pre>



<P>

<B>Note:</B> Of all the subclassing techniques described in this article, the technique of inheriting a new class is

probably the best strategy from an object oriented standpoint. It is a bad design practice to litter a form class with

a bunch of code that subclasses and paints the background of a listview control. It is wiser to derive a new class and

encapsulate the custom behavior while maintaining the default behavior of the base class.

</P>

<P>

Notice that you don't have

to write code that subclasses the window handle when you derive a new class from <TT>TListView</TT>. The base class

already does that, and deriving a new class leverages that code in the base classes. Also, you don't have to worry

about listview messages being sent to a form that is in the middle of being destroyed. Not only is deriving a new

class cleaner from an object oriented point of view, it is probably more robust and less prone to failure.

</P>



<BR>

<TABLE  BORDER=1 CELLPADDING=10 CELLSPACING=0 WIDTH="100%">

<TR> <TD colspan = 2><B>Downloads for this FAQ</B> </TD> </TR>

<TR> <TD><TT><A HREF="download/subclass1.zip" >subclass1.zip </A></TT></TD> <TD>BCB3 project that demonstrates <TT>SetWindowLong</TT> to subclass a listview.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass1x.zip">subclass1x.zip</A></TT></TD> <TD>Same as subclass1.zip. Includes an EXE. Zip is 170k.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass2.zip" >subclass2.zip </A></TT></TD> <TD>BCB3 project that uses <TT>MakeObjectInstance</TT> to subclass a listview.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass2x.zip">subclass2x.zip</A></TT></TD> <TD>Same as subclass2.zip. Includes an EXE. Zip is 170k.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass3.zip" >subclass3.zip </A></TT></TD> <TD>BCB3 project that subclasses a listview through its <TT>WindowProc</TT> property.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass3x.zip">subclass3x.zip</A></TT></TD> <TD>Same as subclass3.zip. Includes an EXE. Zip is 170k.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass4.zip" >subclass4.zip </A></TT></TD> <TD>BCB3 project that shows how to subclass a listview by deriving a new class.</TD> </TR>

<TR> <TD><TT><A HREF="download/subclass4x.zip">subclass4x.zip</A></TT></TD> <TD>Same as subclass4.zip. Includes an EXE. Zip is 170k.</TD> </TR>

</TABLE>

</TD> </TR>



</TABLE>

</CENTER>

</BODY>

</HTML>

⌨️ 快捷键说明

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