搞了一天终于弄了个完整的编辑框控件出来了,

哎,,,搞界面开发还是有点复杂的。

 #pragma once

 #include "AdvEdit.h"
// CBkgEditBox class CBkgEditBox : public CEdit
{
DECLARE_DYNAMIC(CBkgEditBox) public:
CBkgEditBox();
virtual ~CBkgEditBox(); protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
afx_msg void OnMouseLeave();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKillFocus(CWnd* pNewWnd); private:
BOOL m_bFirstDraw; // 第一次绘制背景标识
Gdiplus::Image *m_pPngBg; // 背景位图资源
BOOL m_bHover; // 鼠标是否在编辑框上标识
BOOL m_bAllowMouseTrack; // 鼠标移动时是否允许追踪鼠标移动
COLORREF m_clrBkgnd; // 默认背景Hover颜色
COLORREF m_clrHoverBkgnd; // 默认背景UnHover颜色
COLORREF m_clrText; // 字体颜色
CString m_strTipStr; // 输入提示信息
CBrush m_brhNull; // 空画刷对象
CFont* m_pTextFont; // 编辑框字体 public:
BOOL SetBackgndRes( UINT nResourceID, LPCTSTR lpszType=_T("PNG"));
void SetGrayTipString(LPCTSTR lpszTipString);
void SetTextColor(COLORREF clrText);
BOOL SetTextFont(int nHeight = , int nWidth = , LPCTSTR lpszFaceName = _T("宋体"));
BOOL IsEditEmpty();
};
 // MyEditBox.cpp : 实现文件
// #include "stdafx.h"
#include "BkgEditBox.h" // CBkgEditBox IMPLEMENT_DYNAMIC(CBkgEditBox, CEdit) CBkgEditBox::CBkgEditBox()
{
m_bFirstDraw = TRUE;
m_pPngBg = NULL;
m_bHover = FALSE;
m_bAllowMouseTrack = TRUE; m_clrBkgnd = RGB(,,);
m_clrHoverBkgnd = RGB(,,);
m_clrText = RGB(,,);
m_strTipStr = _T(""); m_brhNull.CreateStockObject(NULL_BRUSH);
m_pTextFont = NULL;
} CBkgEditBox::~CBkgEditBox()
{
if (NULL != m_pTextFont)
{
delete m_pTextFont;
m_pTextFont = NULL;
}
} BEGIN_MESSAGE_MAP(CBkgEditBox, CEdit)
ON_WM_ERASEBKGND()
ON_WM_SETFOCUS()
ON_WM_MOUSEHOVER()
ON_WM_MOUSELEAVE()
ON_WM_MOUSEMOVE()
ON_WM_CTLCOLOR()
ON_WM_CTLCOLOR_REFLECT()
ON_WM_CHAR()
ON_WM_KILLFOCUS()
END_MESSAGE_MAP() // CBkgEditBox 消息处理程序 BOOL CBkgEditBox::OnEraseBkgnd(CDC* pDC)
{
// 图片背景与编辑框的距离顶点
int nLeftStep,nTopStep,nWidthStep,nHeightStep;
nLeftStep = ;
nTopStep = ;
nWidthStep = ;
nHeightStep = ;
CDC* pOldDC = pDC;
if (NULL != m_pPngBg)
{
pDC = GetParent()->GetDC();
CRect rect;
GetWindowRect(&rect);
this->GetParent()->ScreenToClient(&rect); int nWidth = m_pPngBg->GetWidth();
int nHeight = m_pPngBg->GetHeight(); // 不是第一次绘制时需要调整位置
if (!m_bFirstDraw)
{
rect.left -= nLeftStep;
rect.top -= nTopStep;
}else
{
MoveWindow(rect.left + nLeftStep, rect.top + nTopStep,
nWidth - nWidthStep, nHeight - nHeightStep);
} CDC MemDc;
MemDc.CreateCompatibleDC(pDC); CBitmap bitMemMap;
bitMemMap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
MemDc.SelectObject(&bitMemMap); Gdiplus::Graphics graphics(MemDc.m_hDC);
graphics.DrawImage(m_pPngBg, , , nWidth, nHeight);
pDC->BitBlt(rect.left, rect.top, nWidth,nHeight, &MemDc, , ,SRCCOPY); bitMemMap.DeleteObject();
MemDc.DeleteDC();
m_bFirstDraw = FALSE; pDC = pOldDC;
} { // 内阴影
CBrush brhInnerShadow;
if (!m_bHover)
{
brhInnerShadow.CreateSolidBrush(m_clrBkgnd);
}else
{
brhInnerShadow.CreateSolidBrush(m_clrHoverBkgnd);
} CBrush* pOldBrh = pDC->SelectObject(&brhInnerShadow);
pDC->SelectStockObject(NULL_PEN);
CRect rcShadow;
GetClientRect(&rcShadow);
if (NULL != m_pPngBg)
{
rcShadow.right = rcShadow.left + m_pPngBg->GetWidth() - nWidthStep;
rcShadow.bottom = rcShadow.top + m_pPngBg->GetHeight() - nHeightStep;
}
pDC->Rectangle(&rcShadow);
if(NULL!=pOldBrh)
{
pDC->SelectObject(pOldBrh);
}
brhInnerShadow.DeleteObject();
this->UpdateWindow(); } return CEdit::OnEraseBkgnd(pDC);
} BOOL CBkgEditBox::SetBackgndRes( UINT nResourceID, LPCTSTR lpszType/*=_T("PNG")*/ )
{
return G_ImageFromIDResource(nResourceID, lpszType, m_pPngBg);
} void CBkgEditBox::OnMouseHover(UINT nFlags, CPoint point)
{
m_bHover = TRUE;
Invalidate(); CEdit::OnMouseHover(nFlags, point);
} void CBkgEditBox::OnMouseLeave()
{
// Hover结束
m_bHover = FALSE;
// 重绘背景
Invalidate(); // 鼠标离开,继续追踪HOVER消息
m_bAllowMouseTrack = TRUE; //CWnd* pWnd =this->GetParent(); //CRect rcTmp;
//GetClientRect(rcTmp);
//rcTmp.OffsetRect(3, 3);
////InvalidateRect(rcTmp);
//this->ClientToScreen(&rcTmp);
//pWnd->ScreenToClient(&rcTmp);
//pWnd->InvalidateRect(&rcTmp);
//pWnd->UpdateWindow(); CEdit::OnMouseLeave();
} void CBkgEditBox::OnMouseMove(UINT nFlags, CPoint point)
{
// 默认情况下,窗口是不响应 WM_MOUSELEAVE 和 WM_MOUSEHOVER 消息的,
// 所以要使用 _TrackMouseEvent 函数来激活这两个消息
// https://msdn.microsoft.com/en-us/library/ms645604 if (m_bAllowMouseTrack)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER|TME_LEAVE;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = ; // 超过10ms才会认为HOVER _TrackMouseEvent(&tme);
m_bAllowMouseTrack = FALSE;
} CEdit::OnMouseMove(nFlags, point);
} BOOL CBkgEditBox::IsEditEmpty()
{
CString strText;
GetWindowText(strText);
if (strText.IsEmpty())
{
return TRUE;
}
if (strText == m_strTipStr)
{
return TRUE;
}
return FALSE;
} HBRUSH CBkgEditBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CEdit::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何特性 // TODO: 如果默认的不是所需画笔,则返回另一个画笔 return hbr;
} HBRUSH CBkgEditBox::CtlColor( CDC* pDC, UINT nCtlColor )
{
// 设置透明背景
pDC->SetBkMode(TRANSPARENT); CString sText;
GetWindowText(sText);
if (sText == m_strTipStr)
{
pDC->SetTextColor(RGB(,,));
}else
{
pDC->SetTextColor(m_clrText);
} return m_brhNull;
} void CBkgEditBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
Invalidate(TRUE); CEdit::OnChar(nChar, nRepCnt, nFlags);
} void CBkgEditBox::OnSetFocus(CWnd* pOldWnd)
{
CEdit::OnSetFocus(pOldWnd); CString sText;
GetWindowText(sText);
if (sText == m_strTipStr)
{
SetWindowText(_T(""));
}
Invalidate(TRUE);
return ; }
void CBkgEditBox::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd); CString sText;
GetWindowText(sText);
if (_T("") == sText)
{
SetWindowText(m_strTipStr);
}
} void CBkgEditBox::SetGrayTipString( LPCTSTR lpszTipString )
{
m_strTipStr = lpszTipString; SetWindowText(lpszTipString);
} void CBkgEditBox::SetTextColor( COLORREF clrText )
{
m_clrText = m_clrText;
} // https://msdn.microsoft.com/zh-tw/library/vstudio/2ek64h34.aspx
BOOL CBkgEditBox::SetTextFont( int nHeight /*= 20*/, int nWidth /*= 12*/, LPCTSTR lpszFaceName /*= _T("宋体")*/ )
{
if (NULL != m_pTextFont)
{
delete m_pTextFont;
m_pTextFont = NULL;
}
m_pTextFont = new CFont;
m_pTextFont->CreateFont(
nHeight, // nHeight
nWidth, // nWidth
, // nEscapement
, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
lpszFaceName); this->SetFont(m_pTextFont);
return TRUE;
}

自定义编辑框VC,可加载更改字体,添加背景图片,显示输入提示信息的更多相关文章

  1. VC 下加载 JPG / JPEG / GIF / PNG 图片最简单的方法

    VC MFC 提供的 API LoadBitmap / LoadImage 类 CBitmap 等都只能操作 BMP 位图,图标.对于其他常用的 JPG / JPEG / GIF / PNG 格式,它 ...

  2. 用 SDL2 加载PNG平铺背景并显示前景

    上一篇中加载的是BMP,这次可以引用 SDL2_image.lib,加载更多格式的图像. LoadImage函数做了改动,区别在于不用将surface转换成texture了. 环境:SDL2 + VC ...

  3. 在element-ui的select下拉框加上滚动加载

    在项目中,我们需要运用到很多来自后端返回的数据.有时是上百条,有时甚至上千条.如果加上后端的多表查询或者数据量过大,这就导致在前端的显示就会及其慢,特别是在网络不好的时候更是如此. 自然,后端就做了一 ...

  4. VC中加载LIB库文件的三种方法

    VC中加载LIB库文件的三种方法 在VC中加载LIB文件的三种方法如下: 方法1:LIB文件直接加入到工程文件列表中   在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中&quo ...

  5. 淘宝购物车页面 智能搜索框Ajax异步加载数据

    如果有朋友对本篇文章的一些知识点不了解的话,可以先阅读此篇文章.在这篇文章中,我大概介绍了一下构建淘宝购物车页面需要的基础知识. 这篇文章主要探讨的是智能搜索框Ajax异步加载数据.jQuery的社区 ...

  6. vue2 自定义全局组件(Loading加载效果)

    vue2 自定义全局组件(Loading加载效果) github地址: https://github.com/ccyinghua/custom-global-component 一.构建项目 vue ...

  7. 代码: 两列图片瀑布流(一次后台取数据,图片懒加载。下拉后分批显示图片。图片高度未知,当图片onload后才显示容器)

    代码: 两列图片瀑布流(一次后台取数据,无ajax,图片懒加载.下拉后分批显示图片.图片高度未知,当图片onload后才显示容器) [思路]: 图片瀑布流,网上代码有多种实现方式,也有各类插件.没找到 ...

  8. iOS-仿支付宝加载web网页添加进度条

    代码地址如下:http://www.demodashi.com/demo/11727.html 目前市场上APP常会嵌入不少的h5页面,参照支付宝显示web页面的方式, 做了一个导航栏下的加载进度条. ...

  9. swing实现QQ登录界面1.0( 实现了同一张图片只加载一次)、(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件)

    swing实现QQ登录界面1.0( 实现了同一张图片只加载一次).(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件) 代码思路分析: 1.(同一张图片仅仅需要加载一次就够了,下 ...

随机推荐

  1. 微信开发token验证失败

    遇到token验证时: 1.首先检验是否是80端口或443端口,能否接收到微信的响应信息,如果使用域名,域名要备注,否则接收不到响应信息: 2.其次判断是否能正常echo $echoStr,之前不能有 ...

  2. java基础篇3之反射

    1.反射的基础 反射的基石---->Class类 java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class 获取字节码对应的实例对象(Class类型) class ...

  3. 选择一个 Python Web 框架:Django vs Flask vs Pyramid

    Pyramid, Django, 和 Flask都是优秀的框架,为项目选择其中的哪一个都是伤脑筋的事.我们将会用三种框架实现相同功能的应用来更容易的对比三者.也可以直接跳到框架实战(Framework ...

  4. Java 线程第三版 第五章 极简同步技巧 读书笔记

    一.能避免同步吗? 取得锁会由于下面原因导致成本非常高:     取得由竞争的锁须要在虚拟机的层面上执行很多其它的程序代码.     要取得有竞争锁的线程总是必须等到锁被释放后. 1. 寄存器的效应 ...

  5. spring-web中的WebDataBinder理解

    Spring可以自动封装Bean,也就是说前台通过SpringMVC传递过来的属性值会自动对应到对象中的属性并封装成javaBean,但是只能是基本数据类型(int,String等).如果传递过来的是 ...

  6. Html5 meta 笔记

    摘抄:原文地址:http://www.kmapk.com/html/help/02/127.html 一.天猫 <title>天猫触屏版</title> <meta co ...

  7. FZU 2124 FOJ 2124 吃豆人【BFS】

     Problem 2124 吃豆人 Accept: 134    Submit: 575 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  8. php迭代器模式

    其实就是遍历数组 然后对数组中的元素进行操作 实现iterator接口即可.

  9. Spring Resource框架体系介绍

    Resource介绍 在使用spring作为容器进行项目开发中会有很多的配置文件,这些配置文件都是通过Spring的Resource接口来实现加载,但是,Resource对于所有低级资源的访问都不够充 ...

  10. oracle 误删数据的回复操作

    update operator t set t.username = (select username from operator  AS OF TIMESTAMP TO_TIMESTAMP('201 ...