修改编辑框禁用状态文字颜色的方法

由来.
 
    最近在重绘ComboBox. 按网上说的,ComboBox是一个组合框, 在CBS_DROPDOWN模式下, 是  edit + listbox ;  在 CBS_DROPDONWLIST模式下是  static + listbox.

    但是实际的情况却有些出人意料,  CBS_DROPDOWN模式是没有什么异议,.  但是在CBS_DROPDONWLIST却根本不是所谓的 static + listbox.  就只有一个ComboxBox本身的窗口+listbox,  static根本是不存在的. 
    而我的的重绘ComboBox中, 需要在文字显示位置的 左边和右边都空出一些位置来摆放一些可其它内嵌控件, 比如button, 比如checkbox等等, 如果是CBS_DROPDOWN模式, 因为有edit, 可以很方便的调整其位置, 但是在CBS_DROPDONWLIST模式下, 什么也没有, 只有靠DrawItem来绘制, 但是这个会绘制一个白色区域, 并且更厉害的是, 不管你怎么绘制, 总会有一个白边绘制不掉(这里是我一直未突破的地方).  并且, 如果我响应了OnPaint函数,绘制了ComboBox的背景后,  CBS_DROPDONWLIST模式下, 就不能正常显示选中项了.
   所以, 为了能调整文字绘制区域,和正常显示CBS_DROPDONWLIST模式下的选中项, 我选择了使用CBS_DROPDOWN下的编辑框来模拟CBS_DROPDONWLIST模式. 即让编辑框禁用, 不显示光标, 鼠标状态也不要变成 工字型. 
  
   这时就遇到问题了, 编辑框在禁用状态时, 颜色竟然无法改变,  即使响应了WM_CTLCOLOR相关的消息, 也最多只能改变 正常状态和只读状态的文字颜色, 禁用状态还是无能为力.
 
解决方法:

1. 完全重截edit.  用一个基本的窗口, 自己 处理文字显示, 输入光标显示, 鼠标光标显示, 还有汉字输入等复杂的东西, 编辑框的完全自实现是非常的复杂的, 这种方式就暂时不用考虑,
 
我也没有去实现, 怕功力不够. 这时只是一种思路.
 
2.  SetSysColors方式修改 系统中保存的颜色, 即是让GetSysColor得到自己定义的颜色.
int typeElm[1] = {COLOR_GRAYTEXT};
COLORREFclr[1] = {RGB(255,0,0)};
SetSysColors(1, typeElm, clr);
这种方法虽然是可以实现 , 但是这个也会修改系统全局的颜色, 可能不是我想要的.

3. API hook 方式.
这个是基于上面的猜想, 猜想在编辑框绘制 禁用状态 文字颜色的时候, 会调用 GetSysColor去获取颜色, 只要hoo中掉这个api, 然后返回我们想它返回的颜色, 即可改变禁用状态的颜色.  

由于 hook API比较复杂,  虽然网上有现成的, 但我还是比较懒, 没有去实现验证它.
 
 
4. 模拟禁用状态.
  为什么叫模拟禁用状态呢? 因为实际上编辑框还是可编辑状态的正常文本框, 只是不让其获取输入焦点, 和获得鼠标消息.
  看了前面一句话, 可能大家已经想到怎么做了.
  对, 没错, 就是拦截 WM_SETFOCUS消息 和 WM_NCHITTEST消息.
  WM_SETFOCUS消息中, 可以让编辑框不能获取焦点. 方法就是设置其它窗口为焦点, 可以遍历父窗口的下一个子窗口的为焦点窗口, 也可以直接设置父窗口为焦点窗口.
  WM_NCHITTEST消息中, 就直接返回一个HTTRANSPARENT ,即让鼠标穿透到父窗口中去.
  这样编辑框还是编辑框的样子, 但是不能编辑, 不会显示编辑光标, 鼠标移动上去也不会变成工字型. 就好像一个静态文本框一样. 当然颜色那些就随意修改了.
其实写了那么多, 主要目的就是分享最后一种方法.

参考:
http://bbs.csdn.net/topics/390621123?page=1

你可能感兴趣的:(VC/MFC)