电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

如何自绘ListView表头


发布日期:2023/8/27
 

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);

}

上一篇:一个求logk(int n)整数部分的程序

下一篇:世界杯破门移动博客—社区网站的新契机