欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[WTL/ATL]_[初级]_[设置超链接字体颜色]

程序员文章站 2022-05-29 09:26:05
...

场景

1.在开发WTL(Win32)程序时,超链接控件是很常见的,比如需要跳转网页或者打开本地文件夹等,都需要用到。Win32本身就有提供系统自带的WC_LINK控件,而我们用WTL有相应的封装类CLinkCtrl<atlctrls.h>.

2.有时需要根据界面的颜色主题需要修改超链接的颜色以适配界面。但是CLinkCtrl并没有提供修改字体颜色的方法, 而微软的MSDN里对Link也没有相应修改颜色的例子或说明. 如何做?

说明

1.一般情况下我们知道修改系统控件的字体颜色都是通过响应WM_CTLCOLORSTATIC,WM_CTLCOLOREDIT,WM_CTLCOLORBTN等相关消息来修改。超链接控件也是一样的,需要响应WM_CTLCOLORSTATIC并修改如下:

BEGIN_MSG_MAP 里添加

MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)

OnCtlColor 实现增加.

SetBkMode(hDC,TRANSPARENT);
SetTextColor(hDC,RGB(255,0,0));
return (LRESULT)AtlGetStockBrush(HOLLOW_BRUSH);

但是不生效,咋办?如果我们有时间和耐心看完官方的SysLink里的Link Attributes也有说明. 里面用到一个结构体LITEMstate的值LIS_DEFAULTCOLORS,原来SysLink的默认颜色是不能改的,需要通过设置LIS_DEFAULTCOLORS来启用颜色可修改, 那就好办了。只要通过在创建SysLink之后设置LIS_DEFAULTCOLORS启用颜色可修改。我们的OnCtlColor里的更改字体颜色就会生效.

LITEM item = { 0 };
item.iLink = 0;
item.mask = LIF_ITEMINDEX | LIF_STATE;
item.state = LIS_DEFAULTCOLORS; // 修改默认超链接颜色需要vista以上系统才支持.
item.stateMask = LIS_DEFAULTCOLORS;
SendMessage(link_support_, LM_SETITEM, 0, (LPARAM)&item);

代码

View.h

// View.h : interface of the CView class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

enum
{
	kMyDeviceLinkSupportId = WM_USER+1
};

class CView : public CWindowImpl<CView>
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg);

	BEGIN_MSG_MAP_EX(CView)
		MSG_WM_CREATE(OnCreate)
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	int OnCreate(LPCREATESTRUCT lpCreateStruct);
	LRESULT OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

private:
	CLinkCtrl link_support_;
	CFont font_16_normal_;
};

View.cpp

// View.cpp : implementation of the CView class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "View.h"
#include <CommCtrl.h>
#include <string>
#include <atlmisc.h>

BOOL CView::PreTranslateMessage(MSG* pMsg)
{
	pMsg;
	return FALSE;
}

LRESULT CView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	CPaintDC dc(m_hWnd);

	//TODO: Add your drawing code here

	return 0;
}

static HFONT CreateFont(int pixel,bool bold,const wchar_t* font_name)
{
	LOGFONT lf; 
	memset(&lf, 0, sizeof(LOGFONT)); // zero out structure 
	lf.lfHeight = pixel; // request a 8-pixel-height font
	if(bold)
	{
		lf.lfWeight = FW_BOLD;  
	}
	lstrcpy(lf.lfFaceName, font_name); // request a face name "Arial"
	
	HFONT font = ::CreateFontIndirect(&lf);
	return font;
}

LRESULT CView::OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	HDC hDC = (HDC)wParam;
	HWND hWnd = (HWND)lParam;

	if(hWnd == link_support_){
		SetBkMode(hDC,TRANSPARENT);
		SetTextColor(hDC,RGB(255,0,0));
		return (LRESULT)AtlGetStockBrush(HOLLOW_BRUSH);
	}
	return 0;
}

int CView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	LITEM item = { 0 };
    item.iLink = 0;
    item.mask = LIF_ITEMINDEX | LIF_STATE;
    item.state = LIS_DEFAULTCOLORS; // 修改默认超链接颜色需要vista以上系统才支持.
    item.stateMask = LIS_DEFAULTCOLORS;

	std::wstring text_link_connectfail;
	text_link_connectfail.append(L"hello <A HREF=\"https://infoworld.blog.csdn.net\">tobey</A>, "
		L"good good study,<A HREF=\"https://infoworld.blog.csdn.net\">day day up</A>.");

	font_16_normal_ = CreateFont(16,false,L"Arial");
	link_support_.Create(m_hWnd,NULL,text_link_connectfail.c_str(),
		WS_CHILD |WS_VISIBLE| WS_CLIPCHILDREN,0,kMyDeviceLinkSupportId);
	link_support_.SetFont(font_16_normal_);
	
	CSize size;
	link_support_.GetIdealSize(size);
	int rc = link_support_.SetWindowPos(NULL,100, 100, size.cx, size.cy,
			(SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOACTIVATE));
	
    SendMessage(link_support_, LM_SETITEM, 0, (LPARAM)&item);
	item.iLink = 1;
	SendMessage(link_support_, LM_SETITEM, 0, (LPARAM)&item);

	return 0;
}


图1:
[WTL/ATL]_[初级]_[设置超链接字体颜色]

项目

https://download.csdn.net/download/infoworld/12062541

参考

create-syslink-controls

change-color-of-syslink-control

syslink-overview

ns-commctrl-litem