1. 半透明窗体实现 : 使用GDI+绘图,调用UpdateLayeredWindow函数实现
2. 程序代码如下:(win32项目)
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include "resource.h"
#pragma comment(lib, "GdiPlus.lib")
#include <GdiPlus.h>
using namespace Gdiplus;
GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_gdiplusToken;
Image *m_pImageClock;
BOOL UpdateClockDisplay(HWND hwnd,int Transparent = 255);
LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
//从资源中加载
//ImageFromIDResource(IDR_PNG2,"PNG",m_pImageClock);
m_pImageClock = Gdiplus::Image::FromFile(L"e:\\clockx05.PNG");
WNDCLASS wndclass;
wndclass.style = CS_VREDRAW|CS_HREDRAW;
wndclass.lpfnWndProc = MainProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ERROR));
wndclass.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
wndclass.hbrBackground= (HBRUSH)COLOR_WINDOW;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName= TEXT("MainForm");
if(!RegisterClass(&wndclass))
return 0 ;
HWND hwnd = CreateWindow(TEXT("MainForm"), TEXT("The Hello Program"), WS_OVERLAPPEDWINDOW, //WS_POPUP|WS_DLGFRAME
200, 200, 600, 400, NULL, NULL, NULL, NULL);
if(!hwnd)
return 0;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
delete m_pImageClock;
GdiplusShutdown(m_gdiplusToken);
return (int)msg.wParam;
}
LRESULT CALLBACK MainProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInstance ;
switch(message)
{
case WM_CREATE:
{
DWORD dwExStyle=GetWindowLong(hwnd,GWL_EXSTYLE);
if((dwExStyle&0x80000)!=0x80000)
SetWindowLong(hwnd ,GWL_EXSTYLE,dwExStyle^0x80000);
//或者使用WS_EX_LAYERED 定义 CreateWindowEx
//CreateWindow 只能用setWindowLong 修改
SetWindowPos(hwnd, HWND_BOTTOM,0,0,
m_pImageClock->GetWidth(),m_pImageClock->GetHeight(),SWP_NOSIZE|SWP_NOMOVE);
//禁止显示移动矩形窗体框
::SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,TRUE,NULL,0);
UpdateClockDisplay(hwnd);
}
break;
case WM_PAINT:
{
}
break;
case WM_LBUTTONDOWN:
SendMessage(hwnd,WM_NCLBUTTONDOWN,HTCAPTION,0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
BOOL UpdateClockDisplay(HWND hwnd,int Transparent)
{
if( Transparent<0||Transparent>100)
Transparent=100;
int bakWidth = m_pImageClock->GetWidth();
int bakHeight = m_pImageClock->GetHeight();
HDC hdcScreen = GetDC(hwnd);
HDC hdcMemory = CreateCompatibleDC(hdcScreen);
HBITMAP hBitMap = CreateCompatibleBitmap(hdcScreen, bakWidth, bakHeight);
SelectObject(hdcMemory,hBitMap);
Graphics graph(hdcMemory);
Point points[] = {Point(0, 0), Point(bakWidth, 0), Point(0, bakHeight)};
graph.DrawImage(m_pImageClock, points, 3);
graph.ReleaseHDC(hdcMemory);
POINT ptWinPos = {0, 0};
SIZE sizeWindow = {bakWidth,bakHeight};
POINT ptSrc = {0,0};
BLENDFUNCTION blend;
blend.BlendOp = 0;
blend.BlendFlags = 0;
blend.AlphaFormat = 1;
blend.SourceConstantAlpha = int(Transparent*2.55);//1~255
BOOL bRet = UpdateLayeredWindow(hwnd,hdcScreen,&ptWinPos,
&sizeWindow,hdcMemory,&ptSrc,0,&blend,2);
DeleteObject(hBitMap);
DeleteDC(hdcMemory);
ReleaseDC(hwnd,hdcScreen);
return bRet;
}
BOOL Update(HWND hwnd,int Transparent)
{
if( Transparent<0||Transparent>100)
Transparent=100;
Image *bitmap = Image::FromFile(L"e:\\clockx05.PNG");
int bakWidth = bitmap->GetWidth();
int bakHeight = bitmap->GetHeight();
Graphics g(bitmap);
HDC hdcMemory = g.GetHDC();
Graphics graph(hdcMemory);
graph.DrawImage(bitmap, 0, 0, bakWidth, bakHeight);
g.ReleaseHDC(hdcMemory);
SIZE sizeWindow = {bakWidth,bakHeight};
POINT ptSrc = {0,0};
BLENDFUNCTION blend;
blend.BlendOp = 0;
blend.BlendFlags = 0;
blend.AlphaFormat = 1;
blend.SourceConstantAlpha = int(Transparent*2.55);//1~255
UpdateLayeredWindow(hwnd,NULL,NULL,
&sizeWindow,hdcMemory,&ptSrc,NULL,&blend,ULW_ALPHA);
delete bitmap;
return TRUE;
}
/*
BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
if (!hRsrc)
return FALSE;
// load resource into memory
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!lpRsrc)
return FALSE;
// Allocate global memory on which to create stream
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,lpRsrc,len);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
// load from stream
pImg=Gdiplus::Image::FromStream(pstm);
// free/release stuff
GlobalUnlock(m_hMem);
pstm->Release();
FreeResource(lpRsrc);
return TRUE;
}*/