异形窗口拉伸问题方案求解 如下 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 问题: 做一个异形窗口,同时能够拉伸窗口大小。(不拉伸的很简单)例如: 做一个圆角窗口,支持拉伸。(如QQ是圆角窗口,但可能更复杂的形状,只能根据透明色来抠图)要求: 窗口背景使用的是一张 bmp 图片,图片中的透明色为 RGB(255,0,255)。 不能使用分层窗口。已完成: 1. 窗口无边框、标题栏,但为了支持拉伸,附带了WS_THICKFRAME样式。 2. 利用9宫格将背景图分为9块,在抠掉透明色的时候为了加快效率,只去遍历背景图片9宫格中非中心区域(即四周8个区域),因为中心区域一般不需要透明处理,只需要对边框进行透明。结合CombineRgn函数得到窗口rgn 3. 通过SetWindowRgn设置窗口异形 现在出现的问题是:如果窗口拉伸的很快的话,界面上还是会显示出RGB(255,0,255)的透明色。我看很多软件都能够实现该功能,拉伸的时候没有透明色出现,SkinMagic在这方面做的不错。但昨天周末想了一天没什么好的方案,网上搜索到得资料都只是怎么实现拉伸的,对我没什么用。今天早上又想了一个办法,大致思路如下:// 在窗口大小改变的时候调用: 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 );} // 在绘制窗口背景的时候调用:(为了解决拉伸时显示透明色RGB(255,0,255),这里使用TransparentBlt )OnEraseBkgnd(){ // 1. 绘制9宫图到一个 Mem DC TransparentBlt( 左上 ); TransparentBlt( 上 ); TransparentBlt( 右上 ); TransparentBlt( 左 ); Stretch( 中心 ); TransparentBlt( 右 ); TransparentBlt( 左下 ); TransparentBlt( 下 ); TransparentBlt( 右下 );}这样一来就能够保证在窗口区域是rgn,绘制出来的窗口背景也没有透明色。 但总感觉这种方法有些歪门邪道,或者效率太低,因此求各位兄弟姐妹帮忙,各位在做异形窗口拉伸是怎么解决的 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 );} 居然没人回答?我帮楼主找了一下,可以参考一下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拉伸无延时的。 刚看了下它的拉伸机制,貌似它的这个九宫理解的不太一样哈,不过我认为它的这个九宫切法不太合理,对中部的拉伸效果不会太好的。从SkinMagic中可以看到,它的9宫切法是:┌────────────────────────┐│ 1┊ 2 ┊ 3││┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈││ ┊ ┊ ││ 4┊ 5 ┊ 6││ ┊ ┊ ││ ┊ ┊ ││┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈││ 7┊ 8 ┊9 │└────────────────────────┘ kao!贴不好?┌─────────────┐│ 1┊ 2 ┊ 3││┈┈┈┈┈┈┈┈┈┈┈┈┈││ ┊ ┊ ││ 4┊ 5 ┊ 6││ ┊ ┊ ││ ┊ ┊ ││┈┈┈┈┈┈┈┈┈┈┈┈┈││ 7┊ 8 ┊9 │└─────────────┘ http://www.iuishop.com/download/Resize.zip我帮楼主做了个拉伸的demo。可以看一下。 相当不规则的窗口。用的是RGN。 3Q,等会下下来了我看看(公司只让访问csdn) 给我一个exe?要例子到处都有吧 不过你这个Demo的拉伸效率很好!哎,还是得我自己想方案了! LibUIDK.h是用了这个库实现的,但是,这个库,psbeond却没有给.psbeond是在想推销自己的货吗???即然不让我们看,就不要发说能行?只有exe,像楼主说的,比你做得好的多得数不清了 将HRGN的创建方法修改了,使用 RGNDATA 来创建 ExtCreateRegion ,比一个像素点一个像素点的去CombineRgn速度能提高很多。不过突然发现拉伸的时候现在又不再出现透明色RGB(255,0,255)了,搞不明白以前哪个环节出了问题,得晚上回家再试试了。 我猜测: 可能是因为你的那种9宫切法(拉伸算法),可以保证4个角的RGN可以直接保存下来,而不会涉及到stretchBlt,剩下的那5块区域因为只是一个像素的拉伸,也比较好算,因此最终将这几块RGN拼起来就得到了窗口的最终RGN。 所以可以感觉出来你做的那个Demo的拉伸效率很高。不知道我说的对不对。 终于解决拉伸时出现背景色的问题了。原因就出在 我把所有的绘制代码都放在了 WM_ERASEBKGND 中,而有时只产生 WM_PAINT消息和WM_SIZE消息,没有WM_ERASEBKGND消息。 另外需要注意的是:在对背景图进行缩小的时候,有的背景色会被压缩成被的颜色,导致界面出现类似RGB(255,0,255)的颜色,因此还必须响应 WM_GETMINMAXINFO 消息对窗口进行限制。最后将代码编译成release版本,速度还行,晚上再改进改进提高速度。 如何使RadioButton控件不可选?(在线等) 求助listctrl中加入图标的问题 请问,怎么才能上父窗体在子窗体前面 ws2_32.dll 怎么替换掉 调试问题 浮动工具条开发 csdn中还有能解决CForView中CTabCtrl的tab页点击事件处理问题的人吗,如果有就来看看,这问题还几天了 问一个基础问题 问题来咯:我想继承CFormView并且写一个特殊的OnPaint消息处理函数,但发现有很多问题。 那位会写浏览器插件 如何生成用于编译 代理/占位dll的mk文件 请教模拟鼠标的程序
1. 窗口无边框、标题栏,但为了支持拉伸,附带了WS_THICKFRAME样式。
2. 利用9宫格将背景图分为9块,在抠掉透明色的时候为了加快效率,只去遍历背景图片9宫格中非中心区域(即四周8个区域),因为中心区域一般不需要透明处理,只需要对边框进行透明。结合CombineRgn函数得到窗口rgn
3. 通过SetWindowRgn设置窗口异形
现在出现的问题是:如果窗口拉伸的很快的话,界面上还是会显示出RGB(255,0,255)的透明色。我看很多软件都能够实现该功能,拉伸的时候没有透明色出现,SkinMagic在这方面做的不错。但昨天周末想了一天没什么好的方案,网上搜索到得资料都只是怎么实现拉伸的,对我没什么用。今天早上又想了一个办法,大致思路如下:// 在窗口大小改变的时候调用:
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 );
}
OnEraseBkgnd()
{
// 1. 绘制9宫图到一个 Mem DC
TransparentBlt( 左上 );
TransparentBlt( 上 );
TransparentBlt( 右上 );
TransparentBlt( 左 );
Stretch( 中心 );
TransparentBlt( 右 );
TransparentBlt( 左下 );
TransparentBlt( 下 );
TransparentBlt( 右下 );
}
这样一来就能够保证在窗口区域是rgn,绘制出来的窗口背景也没有透明色。 但总感觉这种方法有些歪门邪道,或者效率太低,因此求各位兄弟姐妹帮忙,各位在做异形窗口拉伸是怎么解决的
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 );
}
│ 1┊ 2 ┊ 3│
│┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈│
│ ┊ ┊ │
│ 4┊ 5 ┊ 6│
│ ┊ ┊ │
│ ┊ ┊ │
│┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈│
│ 7┊ 8 ┊9 │
└────────────────────────┘
┌─────────────┐
│ 1┊ 2 ┊ 3│
│┈┈┈┈┈┈┈┈┈┈┈┈┈│
│ ┊ ┊ │
│ 4┊ 5 ┊ 6│
│ ┊ ┊ │
│ ┊ ┊ │
│┈┈┈┈┈┈┈┈┈┈┈┈┈│
│ 7┊ 8 ┊9 │
└─────────────┘
我帮楼主做了个拉伸的demo。可以看一下。
但是,这个库,psbeond却没有给.psbeond是在想推销自己的货吗???即然不让我们看,就不要发说能行?只有exe,像楼主说的,比你做得好的多得数不清了
可能是因为你的那种9宫切法(拉伸算法),可以保证4个角的RGN可以直接保存下来,而不会涉及到stretchBlt,剩下的那5块区域因为只是一个像素的拉伸,也比较好算,因此最终将这几块RGN拼起来就得到了窗口的最终RGN。 所以可以感觉出来你做的那个Demo的拉伸效率很高。不知道我说的对不对。