您的位置:首页 > 其它

使用GDI+实现漂亮的不规则窗体制作

2009-12-06 10:39 393 查看
  如果使用一幅位图,通过挖图的方式来做成一个不规则的窗体,是很累人的一件事。

  而使用GDI+,可以直接用PNG图片,通过图片本身的透明度,自动创建不规则窗体。

  比如,你手中有个美女图,通过PhotoShop等工具,把美女的身体抠出来,保存为PNG格式的图片,除了美女的身体,图片的其他部门都是透明的。后面的工作就是,写一个windows小程序,加载这幅美女图,让她成为我们程序的界面。

 

  Win32程序的框架我就懒得贴了,直接贴关键代码了。

 

#include<GdiPlus.h>
using namespace Gdiplus;

#define MAX_LOADSTRING 100
//Gdiplus start up params
ULONG_PTR m_gdiplusToken;
GdiplusStartupInput m_gdiplusStartupInput;
//rendering prarams
BLENDFUNCTION m_Blend;
//images
Bitmap * m_BackgoundImage;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR    lpCmdLine,
int       nCmdShow)
{
//....
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//...
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
m_Blend.BlendOp     = AC_SRC_OVER;
m_Blend.AlphaFormat = AC_SRC_ALPHA;
m_Blend.BlendFlags  = 0;
m_Blend.SourceConstantAlpha = 255;
m_BackgoundImage = Bitmap::FromFile(L"meinv.png");
if(m_BackgoundImage == NULL)
{
MessageBox(hWnd, (LPCSTR)"it is null", (LPCSTR)"OO", 0);
exit(0);
}

int DesktopWidth  = GetSystemMetrics(SM_CXSCREEN);
int DesktopHeight = GetSystemMetrics(SM_CYSCREEN);

g_WindowWidth  = m_BackgoundImage->GetWidth();
g_WindowHeight = m_BackgoundImage->GetHeight();

int StartX = (DesktopWidth - g_WindowWidth)/2;
int StartY = (DesktopHeight - g_WindowHeight)/2;
SetWindowPos(hWnd, HWND_TOP, StartX, StartY ,g_WindowWidth, g_WindowHeight, SWP_DRAWFRAME);
}
break;
case WM_PAINT:
{
UpdateWindowView(hWnd);
}
break;
case WM_NCHITTEST:
{
PostMessage(hWnd, WM_LBUTTONDOWN, wParam, lParam);
return HTCAPTION;
}
break;
case WM_DESTROY:
GdiplusShutdown(m_gdiplusToken);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void UpdateWindowView(HWND hWnd)
{
//window position
RECT rct;
GetWindowRect(hWnd, &rct);
POINT ptWinPos = {rct.left,rct.top};
SIZE szWinSize = {g_WindowWidth - 1, g_WindowHeight - 1};

HDC dcScreen = GetDC(hWnd);
HDC dcmemory = CreateCompatibleDC(dcScreen);

HBITMAP canvas = CreateCompatibleBitmap(dcScreen, g_WindowWidth, g_WindowHeight);

SelectObject(dcmemory, canvas);

Graphics * graphics = Graphics::FromHDC(dcmemory);

Point points[] =
{
Point(0, 0),
Point(g_WindowWidth, 0),
Point(0, g_WindowHeight)
};
graphics->DrawImage(m_BackgoundImage, points, 3);

POINT ptSrc = {0, 0};

DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
if((dwExStyle&0x80000) != 0x80000)
{
SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle^0x80000);
}

BOOL res = UpdateLayeredWindow(hWnd, dcScreen, &ptWinPos, &szWinSize, dcmemory, &ptSrc, 0, &m_Blend, ULW_ALPHA);
DWORD dw = GetLastError();
delete graphics;

DeleteObject(canvas);
canvas = NULL;

//Create出来的dc要用DeleteDC来释放,Get到的要用ReleaseDC释放
DeleteDC(dcmemory);
ReleaseDC(hWnd, dcScreen);
/*最后的这些资源一定记得释放,不然内存泄漏很严重,窗体在拖动的时候很慢。*/
}
 

 

  不过呢,这么做也有个不爽的地方,你使用的PNG图片必须也和你的程序一起发布,不能隐藏在程序代码中。当然了一般的游戏都是有专门的资源包,并且做了加密的。我看剑侠叁的启动界面应该就是使用GDI+来做的,很漂亮。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息