MFC 控件子类化

程序中用到Windows通用控件。比如按钮控件,进度条控件等等。但是有时我们需要给控件更多的特色,这就需要做控件的子类化(subclassing).
子类化,通俗来讲就是用自己的窗口处理函数来处理特定消息,并将自己其他消息还给标准(默认)窗口处理函数。在SDK中,通过SetWindowLong来指定一个自定义窗口处理函数:SetWindowLong(hwnd, GWL_WNDPROC, (LONG)UserWndProc);

_editHwnd = _editHtmlBody.GetSafeHwnd();//获得窗口对象(CWnd的派生对象)指针的句柄(HWND)
    //_lpEditProc 为内置窗口处理地址
_lpEditProc(WNDPROC)::SetWindowLong(_editHtmlBody.GetSafeHwnd(),GWLP_WNDPROC(LONG)&CTabHtmlBody::SubEditProc);
    //该函数用来改变指定窗口的属性       GWLP_WNDPROC  为窗口设定一个新的处理函数。



long CTabHtmlBody::SubEditProc(HWND hWnd,UINT uMsg,WPARAM wparam,LPARAM lparam)
{
    PAINTSTRUCT  ps;
    if(uMsg == WM_PAINT)
    {
        ::CallWindowProc(_lpEditProc,hWnd,uMsg,wparam,lparam);
        ::BeginPaint(hWnd,&ps);
        ShowLineNum(_editHwnd);      //该函数设置RichEdit控件左侧40像素显示行号
        return ::EndPaint(hWnd,&ps);
    }
    return ::CallWindowProc(_lpEditProc, hWnd, uMsg, wparam, lparam);
}


void CTabHtmlBody::ShowLineNum(HWND hEdit)
{
	RECT ClientRect;    //RechEdit客户区大小
	HDC  hdcEdit;       //RechEdit的DC
	HDC  hdcCpb;		//与RechEdit兼容的DC
	HBITMAP hdcBmp;		//与RechEdit兼容的位图dc
	int  CharHeigh;
	int  chHeigh;
	int  FirstLine;		//文本框第一个可见行的行号
	int  ClientHeigh;   //RechEdit的客户去高度
	int  LineCount;
	wchar_t  countBuf[10]; //显示行号的缓冲区
	CHARFORMAT CharFmt;

	hdcEdit = ::GetDC(hEdit);
	::GetClientRect(hEdit,&ClientRect);
	ClientHeigh = ClientRect.bottom - ClientRect.top;
	hdcCpb = ::CreateCompatibleDC(hdcEdit);
	hdcBmp = ::CreateCompatibleBitmap(hdcEdit,40,ClientHeigh);
	SelectObject(hdcCpb,hdcBmp);


	::FillRect(hdcCpb,&ClientRect,::CreateSolidBrush(0x8080ff));
	::SetBkMode(hdcCpb,TRANSPARENT);

	LineCount = ::SendMessage(hEdit,EM_GETLINECOUNT,0,0);


	RtlZeroMemory(&CharFmt,sizeof(CharFmt));
	CharFmt.cbSize = sizeof(CharFmt);

	::SendMessage(hEdit,EM_GETCHARFORMAT,TRUE,(long)&CharFmt);
	CharHeigh = CharFmt.yHeight/15;
	chHeigh = CharHeigh;
	CharHeigh = 2;

	SetTextColor(hdcCpb,0x000000);

	FirstLine = ::SendMessage(hEdit,EM_GETFIRSTVISIBLELINE,0,0);
	FirstLine++;

	while(FirstLine < LineCount)
	{
		::TextOut(hdcCpb,1, CharHeigh, countBuf,wsprintf(countBuf,L"%4u", FirstLine++));
		CharHeigh += chHeigh + 3;
		if(CharHeigh > ClientHeigh) break;
	}

	::BitBlt(hdcEdit,0,0,40,ClientHeigh,hdcCpb,0,0,SRCCOPY);
	::DeleteDC(hdcCpb);
	::ReleaseDC(hEdit,hdcEdit);
	::DeleteObject(hdcBmp);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值