最近在做一个皮肤库,大概的问题都弄明白了,就是用钩子和子类化来实现。但问题是MFC的一些对话框和控件等,会因为加入皮肤库的原因导致重复subclass的问题,程序会崩溃。所以感觉uskin等换肤库不是直接调用subclass等函数,请问各位有没有详细一点关于这方面的实现的资料?

解决方案 »

  1.   

    有两种原理:一种是源代码的,用继承的窗口类替换原来的窗口类,或者说子类化,一般用于专门针对一个开发中的程序;一种是提供一个可执行程序,Hook系统的绘制界面的函数和消息,一般用于系统级的换肤。你说的“把相关的位图作不同的两分,分别调用”没错,一般也不止两份。
    http://topic.csdn.net/t/20051209/20/4449877.html
      

  2.   

    看看设计模式MVC   
        
      将外部表示与内部实现操作分开是关键   
        
      具体细节就是换图片和字体了
    重载FORM的ONPAINT方法.   
        
      每一个皮肤均是一组     图片资源文件,   
        
      换肤函数只要在重画时,读取不同的资源图片组,   
        
      再画到FORM上,就可以实现换肤了.
    如果是WEBFORM的话,定义几组不同的CSS,在数据库里定义几组不同的图片地址,然后定义一个字段ISDEFAULT,来判断哪组数据是当前使用的“皮肤”
    关于换肤,有一种是只换背景或其它的外观,而不改变窗口形状.   
        
      这种只要在OnPaint函数中加入背景图片的paint段就行了,标题栏的重绘可以重载NCPatin()实现.这一点比较简单.就不多说了   
        
      另外还有一种不但背景图片要发生改变的.窗体的形状也会发生变化.对于这种比较复杂.首先有一张图片.因为图片一般都是以矩形的方式存在的.所以我们要指定一种背景颜色.背景色我们自已指定的.如:用红色作为其背景色.背景色的选取上,要注意一下,应该不同于图片中的其它任何一种颜色,这样才能正角区别出背景和前景.   
          建立两个CRegion,一个用来存储整个有效区,是最后的分析结果,这里我们用区域winrgn表示.另外一个是辅助程序得到最后区域的,它只有一行,用区域linergn.具体如下,把图片载入后,逐行对图片进行扫描,将非背景加入linergn中.(这个区域只有一行).这一行扫描完成后,将linergn合并到winrgn中.再开始新的一行扫描.直到最后扫描结束.   
      winrgn即为有效的窗体区域.通过SetWindowRgn()函数设置窗体的有效区.
      

  3.   

    Hook系统的绘制界面的函数和消息 这个希望能有具体的描述。
    据我所分析的skinmagic,uskin等软件,肯定不是采用subclass方法来实现的,因为这样的话,他的运用不可能那么广。可能是直接的窗口过程更换等,或者像楼上所说的,只处理某些画图消息,连窗口过程都不用替换。
      

  4.   

    Hook这些都明白,现在希望能有详细一点的资料,到底hook后该处理哪些消息,希望有这方面的资料。