如下

解决方案 »

  1.   

    问题: 做一个异形窗口,同时能够拉伸窗口大小。(不拉伸的很简单)例如: 做一个圆角窗口,支持拉伸。(如QQ是圆角窗口,但可能更复杂的形状,只能根据透明色来抠图)要求: 窗口背景使用的是一张 bmp 图片,图片中的透明色为 RGB(255,0,255)。 不能使用分层窗口。已完成:
        1. 窗口无边框、标题栏,但为了支持拉伸,附带了WS_THICKFRAME样式。
        2. 利用9宫格将背景图分为9块,在抠掉透明色的时候为了加快效率,只去遍历背景图片9宫格中非中心区域(即四周8个区域),因为中心区域一般不需要透明处理,只需要对边框进行透明。结合CombineRgn函数得到窗口rgn
        3. 通过SetWindowRgn设置窗口异形
      

  2.   


    现在出现的问题是:如果窗口拉伸的很快的话,界面上还是会显示出RGB(255,0,255)的透明色。我看很多软件都能够实现该功能,拉伸的时候没有透明色出现,SkinMagic在这方面做的不错。但昨天周末想了一天没什么好的方案,网上搜索到得资料都只是怎么实现拉伸的,对我没什么用。今天早上又想了一个办法,大致思路如下:// 在窗口大小改变的时候调用:
      

  3.   

        BYTE* pBits = GetDIBits(...);    // 4. 遍历像素(从左至右,从下至上)
        for( int i = bm.bmHeight; i>0; i-- )
        {  
            for( int j = 0; j < bm.bmWidth; j ++ )
            {
                 if( 这个点不是9宫格的center区域 )
                 {
                       if( 这个点的颜色 == RGB(255,0,255) )
                       {
                              CombineRgn( hWindowRgn, hWindowRgn, hThisPointRgn ); 
                       }
                 }
             }
         }     // 5. 设置窗口的新rgn
         SetWindowRgn( hWindowRgn );
    }
      

  4.   

    // 在绘制窗口背景的时候调用:(为了解决拉伸时显示透明色RGB(255,0,255),这里使用TransparentBlt )
    OnEraseBkgnd()
    {
        // 1. 绘制9宫图到一个 Mem DC
        TransparentBlt( 左上 );
        TransparentBlt( 上 );
        TransparentBlt( 右上 );
        TransparentBlt( 左 );
        Stretch( 中心 );
        TransparentBlt( 右 );
        TransparentBlt( 左下 );
        TransparentBlt( 下 );
        TransparentBlt( 右下 );
    }
    这样一来就能够保证在窗口区域是rgn,绘制出来的窗口背景也没有透明色。  但总感觉这种方法有些歪门邪道,或者效率太低,因此求各位兄弟姐妹帮忙,各位在做异形窗口拉伸是怎么解决的
      

  5.   

    3楼漏了// 在窗口大小改变的时候调用:
    ChangeWindowRgn( )
    {
        // 1. 绘制9宫图到一个 Mem DC
        BitBlt( 左上 );
        StretchBlt( 上 );
        BitBlt( 右上 );
        Stretch( 左 );
        Stretch( 中心 );
        Stretch( 右 );
        BitBlt( 左下 );
        Stretch( 下 );
        BitBlt( 右下 );    // 2. 得到刚才画到MemDC中的bitmap
        HBITMAP hBitmap = (HBITMAP) GetCurrentObject( memDC, OBJ_BITMAP );    // 3. 获取hBitmap中的像素颜色
        BYTE* pBits = GetDIBits(...);    // 4. 遍历像素(从左至右,从下至上)
        for( int i = bm.bmHeight; i>0; i-- )
        {  
            for( int j = 0; j < bm.bmWidth; j ++ )
            {
                 if( 这个点不是9宫格的center区域 )
                 {
                       if( 这个点的颜色 == RGB(255,0,255) )
                       {
                              CombineRgn( hWindowRgn, hWindowRgn, hThisPointRgn ); 
                       }
                 }
             }
         }     // 5. 设置窗口的新rgn
         SetWindowRgn( hWindowRgn );
    }
      

  6.   

    居然没人回答?我帮楼主找了一下,可以参考一下LibUIDK的拉伸算法。http://www.iuishop.com/index.php?option=com_content&view=article&id=112:libuidk&catid=41:2008-10-17-13-52-08&Itemid=41拉伸无延时的。
      

  7.   

    刚看了下它的拉伸机制,貌似它的这个九宫理解的不太一样哈,不过我认为它的这个九宫切法不太合理,对中部的拉伸效果不会太好的。从SkinMagic中可以看到,它的9宫切法是:┌────────────────────────┐
    │ 1┊          2       ┊ 3│
    │┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈│
    │  ┊                  ┊  │
    │ 4┊         5        ┊ 6│
    │  ┊                  ┊  │
    │  ┊                  ┊  │
    │┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈│
    │ 7┊       8          ┊9 │
    └────────────────────────┘
      

  8.   

    kao!贴不好?
    ┌─────────────┐
    │ 1┊          2       ┊ 3│
    │┈┈┈┈┈┈┈┈┈┈┈┈┈│
    │  ┊                  ┊  │
    │ 4┊         5        ┊ 6│
    │  ┊                  ┊  │
    │  ┊                  ┊  │
    │┈┈┈┈┈┈┈┈┈┈┈┈┈│
    │ 7┊       8          ┊9 │
    └─────────────┘
      

  9.   

    http://www.iuishop.com/download/Resize.zip
    我帮楼主做了个拉伸的demo。可以看一下。
      

  10.   

    相当不规则的窗口。用的是RGN。
      

  11.   

    3Q,等会下下来了我看看(公司只让访问csdn)
      

  12.   

    给我一个exe?要例子到处都有吧
      

  13.   

    不过你这个Demo的拉伸效率很好!哎,还是得我自己想方案了!
      

  14.   

    LibUIDK.h是用了这个库实现的,
    但是,这个库,psbeond却没有给.psbeond是在想推销自己的货吗???即然不让我们看,就不要发说能行?只有exe,像楼主说的,比你做得好的多得数不清了
      

  15.   

    将HRGN的创建方法修改了,使用 RGNDATA 来创建 ExtCreateRegion ,比一个像素点一个像素点的去CombineRgn速度能提高很多。不过突然发现拉伸的时候现在又不再出现透明色RGB(255,0,255)了,搞不明白以前哪个环节出了问题,得晚上回家再试试了。
      

  16.   

    我猜测:
        
        可能是因为你的那种9宫切法(拉伸算法),可以保证4个角的RGN可以直接保存下来,而不会涉及到stretchBlt,剩下的那5块区域因为只是一个像素的拉伸,也比较好算,因此最终将这几块RGN拼起来就得到了窗口的最终RGN。    所以可以感觉出来你做的那个Demo的拉伸效率很高。不知道我说的对不对。
      

  17.   

    终于解决拉伸时出现背景色的问题了。原因就出在 我把所有的绘制代码都放在了 WM_ERASEBKGND 中,而有时只产生 WM_PAINT消息和WM_SIZE消息,没有WM_ERASEBKGND消息。 另外需要注意的是:在对背景图进行缩小的时候,有的背景色会被压缩成被的颜色,导致界面出现类似RGB(255,0,255)的颜色,因此还必须响应 WM_GETMINMAXINFO 消息对窗口进行限制。最后将代码编译成release版本,速度还行,晚上再改进改进提高速度。