用vc++如何在桌面画一张可响应点击的图片

tianluojiu11 2009-06-18 12:05:41
用vc++如何在桌面画一张可响应点击的图片? 就像那种桌面精灵一样.

这几天尝试了N多办法., 把图片画在一个窗口上,然后把窗口透明化.可是那图片也跟着透明化了..

把窗口透明化,把图片在桌面上跟着窗口的坐标动态显示,但是效果很差

用双缓存处理的话画图片质量有很大影响(我用的是半透明的png图片)..

有没有只让窗口透明化来响应点击而图片正常显示的办法啊?..跪求啊!
...全文
232 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
tianluojiu11 2009-06-20
  • 打赏
  • 举报
回复
额...不好意思哈.. 这几天事超多. 什么考试都有.. 那考完试我好好研究下. 谢谢你啦 还有其他几位
z888c 2009-06-20
  • 打赏
  • 举报
回复
有一种方法 设置窗体的区域

区域可以更具图片生成

图片除去透明色作为窗体的区域

然后SetWindowRgn

http://www.flipcode.com/archives/Win32_Window_Skinning.shtml

http://codeguru.earthweb.com/cpp/w-d/dislog/miscellaneous/print.php/c5003
z888c 2009-06-20
  • 打赏
  • 举报
回复
STATIC control

style = SS_BITMAP|SS_NOTIFY

在父窗体 WM_NCHITTEST 中用 PtInRect rect为图片的rect

如何



Lin 2009-06-20
  • 打赏
  • 举报
回复
俺认为楼主呐,你不是一般的懒啊。初始化GDI++只需要1句话,清理GDI++也只需要一句话,这些也需要贴代码?
那你以后工作也找人代劳么?

俺在关键的代码点醒即可,其他的还是靠自己吧,请你尊重俺的劳动。
tianluojiu11 2009-06-20
  • 打赏
  • 举报
回复
谢谢.. 等这两天考试完我试试
tianluojiu11 2009-06-20
  • 打赏
  • 举报
回复
没用过gdi++.... 只用过gdi和gdi+ ...这个...可以给个简单点基本能用的例子俺看看吗..

嫌贴代码麻烦直接把工程压缩打包发我邮箱也行.. tianluojiu11@163.com .谢谢啦.

liumu1209 2009-06-19
  • 打赏
  • 举报
回复
不知道说的是不是这个。把窗口标题栏去掉。
画图。
你要响应鼠标的什么动作?

Lin 2009-06-19
  • 打赏
  • 举报
回复
响应点击事件代码简单,就不再贴老
lanneret1234 2009-06-19
  • 打赏
  • 举报
回复
学习了
Lin 2009-06-19
  • 打赏
  • 举报
回复

BOOL SetWindowBackgroundImage(HWND hWnd, Image* pImg)
{
int nWidth = pImg->GetWidth();
int nHeight = pImg->GetHeight();

SetWindowPos(hWnd, HWND_TOP, 0, 0, nWidth, nHeight, SWP_NOMOVE);

//获取源DC
HDC hdcSource = ::GetDC(hWnd);
//创建内存兼容DC和位图
HDC hdcMemory = ::CreateCompatibleDC(hdcSource);
HBITMAP hbmp = ::CreateCompatibleBitmap(hdcSource, nWidth, nHeight);
HBITMAP hOld = (HBITMAP)::SelectObject(hdcMemory, hbmp);
//采用GDI++画图,保证质量
Graphics Canvas(hdcMemory);
Canvas.SetInterpolationMode(InterpolationModeHighQuality);
Canvas.SetCompositingQuality(CompositingQualityHighQuality);
Canvas.SetSmoothingMode(SmoothingModeAntiAlias);
Canvas.DrawImage(pImg, 0, 0, nWidth, nHeight);

//获取屏幕DC
HDC hdcScreen = ::GetDC(NULL);

CRect rc;
::GetWindowRect(hWnd, rc);
CPoint ptSource(0, 0);

SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255; //如果要改变图像的透明度,可以修改此值0~255。
//0:全透明,255:不透明,由图像本身的Alpha通道决定
bf.AlphaFormat = AC_SRC_ALPHA;
CPoint pt(rc.TopLeft());
CSize size(rc.Size());
BOOL bOK = UpdateLayeredWindow(hWnd, hdcScreen, &pt, &size, hdcMemory, &ptSource, 0, &bf, ULW_ALPHA);

::SelectObject(hdcMemory, hOld);
::DeleteObject(hbmp);
::DeleteDC(hdcMemory);
::ReleaseDC(NULL, hdcScreen);
::ReleaseDC(hWnd, hdcSource);

return bOK;
}

BOOL SetWindowBackgroundImage(HINSTANCE hInst, HWND hWnd, UINT uID, LPCTSTR lpszType)
{
if (!::IsWindow(hWnd)) return FALSE;
BOOL bSuccessed = FALSE;

HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(uID), lpszType); //查找资源
if (hRsrc)
{
DWORD dwSize = SizeofResource(hInst, hRsrc); //获取资源大小
if (dwSize > 0)
{
HGLOBAL hSrc = LoadResource(hInst, hRsrc); //装载资源
if (hSrc)
{
LPVOID lpSrc = LockResource(hSrc); //资源加锁
if (lpSrc)
{
// Allocate global memory on which to create stream
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_ZEROINIT, dwSize);
if (hMem)
{
LPVOID pMem = GlobalLock(hMem);
if (pMem)
{
CopyMemory(pMem, lpSrc, dwSize);
IStream* pstm = NULL;
HRESULT hStatus = CreateStreamOnHGlobal(hMem, FALSE, &pstm);
if (hStatus == S_OK)
{
//从流创建资源图像
Gdiplus::Image* pImg = Gdiplus::Image::FromStream(pstm);
if (pImg)
{
bSuccessed = SetWindowBackgroundImage(hWnd, pImg);
delete pImg;
}

pstm->Release();
}

GlobalUnlock(hMem);
}

GlobalFree(hMem);
}
UnlockResource(hSrc);
}
FreeResource(hSrc);
}
}
}
return bSuccessed;
}


由于使用了GDI++,请自己进行GDI++的初始化和扫尾工作。
Lin 2009-06-19
  • 打赏
  • 举报
回复
俺刚好写了个这样的函数,可以把exe文件中的PNG资源图片设置为窗口背景。
但是有一条:这样的窗口只有图片,其他组件都不可见,虽然还起作用,如输入,响应事件等。过会贴上代码
tianluojiu11 2009-06-19
  • 打赏
  • 举报
回复
哦 谢谢..等这两天期末考试完了好好研究下32位的bmp...

貌似UpdateLayerWindow 可以实现多个透明度, 哪位老大可以发个例子吗..
norsd 2009-06-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tianluojiu11 的回复:]
可以给个用GDI+的DrawImage画32位bmp的小例子吗.. 我咋画不出来..

难道  Image image(L"xx.bmp",FALSE); 这种方法不能读入32位的bmp?
[/Quote]

当初我是做过的, gdi+应该能花32bit的, 现在,俺全忘了,当初的代码是在磁盘里的,现在电脑没磁盘......
您只能看msdn啦.
tianluojiu11 2009-06-19
  • 打赏
  • 举报
回复
和正常窗口一样的 点击或者拖动.. 你说的那个方法画bitmap图片可以实现 .. 我想画半透明的png.
fengrx 2009-06-18
  • 打赏
  • 举报
回复
不可能只显示图片,不使用窗口的。windows系统中显示的东西都使用窗口的吧。

楼主原来的思路是正确的。把代码优化下应该就可以。
楼主说效果不好是不是有闪烁问题,这应该是程序代码问题。
tianluojiu11 2009-06-18
  • 打赏
  • 举报
回复
可以给个用GDI+的DrawImage画32位bmp的小例子吗.. 我咋画不出来..

难道 Image image(L"xx.bmp",FALSE); 这种方法不能读入32位的bmp?
tkminigame 2009-06-18
  • 打赏
  • 举报
回复
把窗口的标题栏和框都去掉。wm_paint里面直接画图片。
norsd 2009-06-18
  • 打赏
  • 举报
回复
bmp图像有一种是32bit(alpha,R , G , B )的,创建这样的位图对象,可以实现png的透明效果。
tianluojiu11 2009-06-18
  • 打赏
  • 举报
回复
回1楼:那样画不出来透明效果..

回2楼:
不是闪烁..闪烁用双缓存可以解决..但是问题就出在这. 双缓存需要用CreateCompatibleBitmap在内存创建一个位图..

但是这个位图是带信息的..全0的话就是一片黑.全1的话一片白..

但是我用的图片是png的..边缘有透明部分..那样的话透明部分的颜色就被内存里的图片给影响了..

等到我用TransparentBlt过滤掉底色.把图片传到需要绘制的窗口上时.那png图片已经不透明了. 现在就想解决这个"不透明"的问题



有把窗口和图片分别设置透明度的函数吗?? 那样可以直接画在窗口上,把窗口透明,图片不变就解决了..

SetLayeredWindowAttribute只能设置一个透明度.那样的话把窗口设成透明,图片也看不到了

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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