熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> C編程 >> 正文

如何自繪ListView表頭

2013-11-12 23:33:59  來源: C編程 

  TlistView 控件是vcl 對windows公用控件庫的一個封裝用戶TlistView控件並未提供自繪表頭的事件 一般情況下 要想自繪表頭比較困難 但是windows 所有控件的繪制都是由於消息WM_PAINT的產生而由窗口過程來繪制的 這樣我們似乎就有可能通過WM_PAINT消息能夠繪制TlistView表頭 經過分析發現TlistView 的組成實際上包括了兩部分 一部分是TlistView本省 另外一部分就是TlistView的表頭 該表頭實際上是一個嵌入TlistView裡面的獨立的窗口 該窗口的類名為SysHeader(可以使用ccrun寫的窗口探測工具spywin觀察的到) 綜合上述依據 實現TlistView表頭的自繪可以分為一下幾個步驟:

   查找TlistView的表頭窗口句柄

   替換表頭窗口的窗口過程

   表頭的WM_PAINT消息

   在窗口過程中編寫繪制代碼

  這樣就能繪制TlistView 的表頭了具體實現方式如下 :

   查找表頭有三種方式

  一 使用FindWindowEx :

  以類名SysHeader來查找TlistView的子窗口 由於TlistView只有一個名為SysHeader的子窗口(就是表頭) 所以一定能夠獲取到表頭窗口的句柄

  二 使用windows提供的幫助宏ListView_GetHeader

  這種方式實際上是通過發送消息來獲取表頭句柄 返回值即表頭句柄

   替換表頭的窗口過程

  使用SetWindowLong這個API 就可以替換掉一個窗口的窗口過程(詳細步驟請參看MSDN)

   請參看示例代碼

   請參看示例代碼

  具體代碼

  h文件
    //

  #ifndef UnitH
    #define UnitH
    //
    #include
    #include
    #include
    #include
    #include

  //
    class TForm : public TForm
    {
    __published: // IDEmanaged Components
        TListView *ListView;

  private: // User declarations
    public: // User declarations
        __fastcall TForm(TComponent* Owner);
        __fastcall~TForm();
    };

  //
    extern PACKAGE TForm *Form;
    //
    #endif

  cpp文件
    //

  #include
    #pragma hdrstop

  #include Unith
    //
    #pragma package(smart_init)
    #pragma resource *dfm
    TForm *Form;
    typedef LRESULT(CALLBACK * TCallBack)(HWND UINT WPARAM LPARAM);

  TCallBack g_oldListViewWndProc;
    HWND g_hListViewHeader;

  LRESULT CALLBACK ListViewWindowProc(HWND hwnd UINT uMsg WPARAM wParam
        LPARAM lParam)
    {
        PAINTSTRUCT ps ={ };
        RECT rect = { };
        HDC hPen = NULL;
        HDC hBrush = NULL;
        int iCount = ;
        int i = ;
        BYTE red = green = blue = ;
        BYTE red = green = blue = ;
        BYTE red green blue;
        int j m n;

  switch(uMsg)
        {
        case WM_PAINT:
            BeginPaint(g_hListViewHeader
            hPen = SelectObject(pshdc GetStockObject(DC_PEN));
            iCount = Header_GetItemCount(g_hListViewHeader); // 獲取表頭數目
    // 本文轉自 C++Builder研究 ?i=
            SetDCPenColor(pshdc ColorToRGB((TColor)(xEFDBCE)));
            red = GetRValue((TColor)(xEFDBCE));
            green = GetGValue((TColor)(xEFDBCE));
            blue = GetBValue((TColor)(xEFDBCE));
            for (int i = ; i Font>Handle);
                i = ((rectbottom recttop) abs(Form>Font>Height)) / ;
                hBrush = SelectObject(pshdc GetStockObject(NULL_BRUSH));
                SetBkMode(pshdc TRANSPARENT); // 這是設置背景為透明的
                TextOut(pshdc rectleft + recttop + i
                    Form>ListView>Columns>Items[i]>Captionc_str()
                    Form>ListView>Columns>Items[i]>CaptionLength());
                SelectObject(pshdc hBrush);
            }
            hPen = SelectObject(pshdc hPen);
            EndPaint(g_hListViewHeader
            break;
        default:
            return CallWindowProc((FARPROC)g_oldListViewWndProc g_hListViewHeader
                uMsg wParam lParam);
        }

  return ;
    }

  //
    __fastcall TForm::TForm(TComponent* Owner) : TForm(Owner)
    {
        g_hListViewHeader = FindWindowEx(ListView>Handle NULL SysHeader
            NULL);
        g_oldListViewWndProc = (TCallBack)GetWindowLong
            (g_hListViewHeader GWL_WNDPROC);
        SetWindowLong(g_hListViewHeader GWL_WNDPROC long(ListViewWindowProc));
    }

  //
    __fastcall TForm::~TForm()
    {
        SetWindowLong(g_hListViewHeader GWL_WNDPROC (long)g_oldListViewWndProc);
    }


From:http://tw.wingwit.com/Article/program/c/201311/11101.html
  • 上一篇文章: 没有了

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.