关于异形窗口,在PC上正常到WINCE上就不行了。

xiaoxiaobai 2006-11-23 02:50:45
我在网上找到的一段代码,使窗口基于BMP变成异形,在VC6 + XP上编译运行正常,但是转到 EVC4.0 sp3 + PPC2003SE 系统上编译可以完成,但是在机器上运行窗口却不见了,超级郁闷。
我找了一整晚没有找出原因,各位XD帮我看看哪里出问题了。

void CoolWindowC(HWND hWnd,HBITMAP hBmp,COLORREF BackColor)
{//要改变外形的窗口的句柄,用来设置外形的位图句柄,位图透明色
HDC hDC,hPaper; //窗口设备上下文和窗口内存设备上下文
BITMAP BmpInfo; //位图信息结构
RECT Rect; //窗口矩形
HRGN hRgn,hTempRgn; //窗口区域和临时区域
TCHAR buf[100];
int i,j; //循环变量
int StartX=-1; //不透明行的起始位置,-1表示尚未找到不透明行的起始点
long Style; //窗口风格
//==========重新设置窗口风格========================================
Style=GetWindowLong(hWnd,GWL_STYLE); //得到窗口风格
Style=Style&(!WS_CAPTION); //去掉标题栏
SetWindowLong(hWnd,GWL_STYLE,Style); //为窗口设置新的风格
//------------------------------------------------------------------
Style=GetWindowLong(hWnd,GWL_EXSTYLE); //得到窗口扩展风格
Style=Style&(!WS_EX_WINDOWEDGE); //去掉边框风格
SetWindowLong(hWnd,GWL_EXSTYLE,Style); //为窗口设置新的扩展风格
//------------------------------------------------------------------
Style=GetWindowLong(hWnd,GWL_STYLE); //得到窗口风格
Style=Style|WS_SYSMENU; //加上系统菜单和窗口图标
SetWindowLong(hWnd,GWL_STYLE,Style); //为窗口设置新的风格
//==========核心部分开始============================================
GetObject(hBmp, sizeof(BITMAP), &BmpInfo); //取得位图信息
GetWindowRect(hWnd,&Rect); //得到窗口矩形
//使窗口与位图大小相同
MoveWindow(hWnd, Rect.left, Rect.top, BmpInfo.bmWidth, BmpInfo.bmHeight, false);

hDC = GetDC(hWnd); //得到窗口设备上下文
hPaper = CreateCompatibleDC(hDC); //为窗口设备上下文创建内存设备上下文
SelectObject(hPaper, hBmp); //将位图选进内存设备上下文
hRgn = CreateRectRgn(0, 0, 0, 0); //初始化窗口区域

for(j=0;j<BmpInfo.bmHeight;j++)
for(i=0;i<BmpInfo.bmWidth;i++)
{
if(GetPixel(hPaper,i,j)!=BackColor) //此点是不透明点
{
if(StartX==-1) //是一个不透明行(点)的开始
StartX=i; //标记不透明行(点)的开始位置
//如所有行的最后一点一定是透明的,则去掉下面这个if更快
if(i+1==BmpInfo.bmWidth) //本行的最后一个点是不透明的才需要合并
{
hTempRgn=CreateRectRgn(StartX,j,i+1,j+1); //为不是透明色的点创建临时区域
CombineRgn(hRgn,hRgn,hTempRgn, RGN_OR); //将临时区域合并到窗口区域中
DeleteObject(hTempRgn); //删除每次创建的临时区域以防资源不足
StartX=-1; //重新初始化StartX
}
}else //若此点透明
if(StartX!=-1) //这一点的前一点是不透明行的最后一点
{
hTempRgn=CreateRectRgn(StartX,j,i,j+1); //为不是透明色的点创建临时区域
CombineRgn(hRgn,hRgn,hTempRgn, RGN_OR); //将临时区域合并到窗口区域中
DeleteObject(hTempRgn); //删除每次创建的临时区域以防资源不足
StartX=-1; //重新初始化StartX
}
}

if (SetWindowRgn(hWnd,hRgn,true) == 0) //用作好的区域作为窗口的外形
{
wsprintf(buf, TEXT("SetWindowRgn Error %d !"), GetLastError());
MessageBox(hWnd, buf, TEXT("错误"), MB_ICONERROR);
}

//将位图画到窗口上
if (!BitBlt(hDC,0,0,BmpInfo.bmWidth,BmpInfo.bmHeight,hPaper,0,0,SRCCOPY))
{
wsprintf(buf, TEXT("BitBlt Error %d !"), GetLastError());
MessageBox(hWnd, buf, TEXT("错误"), MB_ICONERROR);
}
//==========善后工作================================================
DeleteObject(hRgn); //删除窗口区域
DeleteObject(hTempRgn); //删除临时区域
DeleteDC(hPaper); //删除位图的内存设备上下文
ReleaseDC(hWnd,hDC); //删除窗口设备上下文
}


void CoolWindow(HWND hWnd,HBITMAP hBmp,int x,int y)
{//以指定点的颜色作为透明色产生异形窗口
HDC hDC,hPaper; //窗口和内存设备上下文句柄
COLORREF BackColor; //透明色
hDC=GetDC(hWnd); //得到窗口设备上下文
hPaper=CreateCompatibleDC(hDC); //为窗口设备上下文创建内存设备上下文
SelectObject(hPaper,hBmp); //将位图选进内存设备上下文
BackColor=GetPixel(hPaper,x,y); //在指定位置取得透明色
DeleteDC(hPaper); //删除内存设备上下文句柄
ReleaseDC(hWnd,hDC); //删除窗口设备上下文句柄
CoolWindowC(hWnd,hBmp,BackColor); //使用指定透明色产生异形窗口
}
...全文
220 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
载舟之水 2006-11-27
  • 打赏
  • 举报
回复
//定义全局变量
HRGN g_hRgn = NULL;
HBITMAP g_hBitmap = NULL;


//调用过程

case WM_CREATE:
{
...
g_hBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_TEST));
CoolWindow(hWnd, g_hBitmap, RGB(255, 0, 255));
DeleteObject(g_hBitmap);
}
break;

case WM_DESTROY:
{
...
DeleteObject(g_hRgn);
}
break;




//

void CoolWindow(HWND hWnd, HBITMAP hBmp, COLORREF BackColor)
{

HDC hDC = NULL;
HDC hPaper = NULL;
int i = 0;
int j = 0;
int StartX = -1;
HRGN hTempRgn = NULL;
HBITMAP hOldBmp = NULL;

BITMAP BmpInfo;

hDC = GetDC(hWnd);
hPaper = CreateCompatibleDC(hDC);
hOldBmp = (HBITMAP)SelectObject(hPaper, hBmp);
g_hRgn = CreateRectRgn(0, 0, 0, 0);

GetObject(hBmp, sizeof(BmpInfo), &BmpInfo);

// Get RGN from Mask Bitmap
for(j = 0; j < BmpInfo.bmHeight; j++)
{
for(i = 0; i < BmpInfo.bmWidth; i++)
{
if(GetPixel(hPaper, i, j) != BackColor)
{
if(StartX == -1)
StartX = i;

if(i + 1 == BmpInfo.bmWidth)
{
hTempRgn = CreateRectRgn(StartX, j, i+1, j+1);
CombineRgn(g_hRgn, g_hRgn, hTempRgn, RGN_OR);
DeleteObject(hTempRgn);
StartX = -1;
}
}
else
{
if(StartX != -1)
{
hTempRgn = CreateRectRgn(StartX, j, i, j+1);
CombineRgn(g_hRgn, g_hRgn, hTempRgn, RGN_OR);
DeleteObject(hTempRgn);
StartX = -1;
}
}
}
}

// Set RGN to Window
SetWindowRgn(hWnd, g_hRgn, true);

DeleteObject(hTempRgn);
SelectObject(hPaper, hOldBmp);
DeleteDC(hPaper);
ReleaseDC(hWnd, hDC);
}
载舟之水 2006-11-27
  • 打赏
  • 举报
回复
我写了一个Sample发给你,有编译好的Bin文件,主要修正了你提供的代码的Bug,本来有几个比较快速的方法,但是需要解决一点问题,比较忙就没时间调了,所以先给你能用的版本。
egxsun 2006-11-26
  • 打赏
  • 举报
回复
to:nbcool(载舟之水),你好!
你写的可以贴在这儿,让大家也学习学习呀。
载舟之水 2006-11-24
  • 打赏
  • 举报
回复
我想到在PPC上有十分高效的做法,可能全部代码就10行,^O^ 不过我没安装evc,用vs.net2005编辑没问题吧,有空给你写个sample。email?
xiaoxiaobai 2006-11-24
  • 打赏
  • 举报
回复
这些代码我是明白,只不过弄不明白为什么在PC上面正常,到了PPC上就不行。
xiaoxiaobai 2006-11-24
  • 打赏
  • 举报
回复
谢谢载舟之水,我的 email lorndragon#gmail.com
meric 2006-11-23
  • 打赏
  • 举报
回复
花ing~再看看
navi_dx 2006-11-23
  • 打赏
  • 举报
回复
把代码贴出来对你不会有什么好处,原理不复杂,你把上面的代码看懂自己琢磨一下就明白,这样印象比较深刻
xiaoxiaobai 2006-11-23
  • 打赏
  • 举报
回复
我只是想让窗口跟位图形状一样
xiaoxiaobai 2006-11-23
  • 打赏
  • 举报
回复
楼上的各位,十来行代码就行?贴出来看看 ^^
载舟之水 2006-11-23
  • 打赏
  • 举报
回复
眼都花了,没这么复杂,这样的代码如果放在PPC上就垃圾了,你的目的只是想让窗口和位图形状一样吧。
navi_dx 2006-11-23
  • 打赏
  • 举报
回复
异性窗口原理很简单就是吧根据透明色把窗口的RGN对象掏空或填充,关键地方十来行代码就够了,那要这么多
zaodt 2006-11-23
  • 打赏
  • 举报
回复
异形!!!

一共出了四部了,我都看过,我最喜欢其中的第二部。听说,第一部是1979年拍的,真早啊!

19,504

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧