看了几个用MFC做的显示镂空图片的程序(像瑞星的狮子),想用SDK模仿着做一个,可是怎么也不成功。目前一旦窗口隐形,图片也跟着隐形。打算发问,可是上传了半个小时都是显示无法打开文件,只好这样贴了#include <windows.h>int g_iWinX=200;  //  X coordinate of the main window in screen
int g_iWinY=100;  //  Y coordinate of the main window in screen
int g_iWinW=400;  //  Width of the main window
int g_iWinH=300;  //  heigh of the main windowLRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);// set some stuff
#define WS_EX_LAYERED   0x00080000  // extention type of the main window which used in the funtion createwindowex(); 
#define LWA_ALPHA       0x00000002  // 
#define LWA_COLORKEY 0x00000001  // // set the SLWA type
typedef BOOL(WINAPI *SLWA)(HWND, COLORREF, BYTE, DWORD);  
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
SLWA pSetLayeredWindowAttributes = NULL;  //create a new object of type SLWA
HINSTANCE hmodUSER32 = LoadLibrary("USER32.DLL");   //load the user32.dll
pSetLayeredWindowAttributes =(SLWA)GetProcAddress(hmodUSER32,"SetLayeredWindowAttributes");  //set the pSetLayeredWindowAttributes with the output of funtion Set...utes in user32.dll
HWND hWnd;     
MSG uMsg;
WNDCLASSEX wcex;   
wcex.cbSize = sizeof(WNDCLASSEX); 
wcex.style = CS_HREDRAW | CS_VREDRAW| CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "TSKIN";
wcex.hIconSm =  LoadIcon(NULL, IDI_WINLOGO); if(!RegisterClassEx(&wcex))
{
MessageBox(NULL,"注册失败,窗口将关闭!!","失败信息",MB_ICONERROR);
return 0;
} hWnd=CreateWindowEx( WS_EX_LAYERED,
"TSKIN", 
"TSKIN", 
WS_OVERLAPPEDWINDOW,
g_iWinX, 
g_iWinY, 
g_iWinW, 
g_iWinH,  
NULL,
NULL,
hInstance,
NULL
); if(!hWnd)
{
MessageBox(NULL,"创建失败,窗口将关闭!!","失败信息",MB_ICONERROR);
return 0;
}    pSetLayeredWindowAttributes(hWnd, 0, 100, LWA_ALPHA);     // Make it transparent ShowWindow(hWnd,nShowCmd);
UpdateWindow(hWnd); while(GetMessage(&uMsg,NULL,0,0))
{
TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}
return uMsg.wParam;
}LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static HBITMAP hBitmapImage,hBitmapMask;
static HINSTANCE hInstance;
static int l_siClientW,l_siClientH,l_siBitmapW,l_siBitmapH;
BITMAP O_Image,O_Mask;  // Image object  and Mask object
HDC hdc,hdcImage,hdcMask;
int l_iBitmapX,l_iBitmapY;
PAINTSTRUCT ps;
switch(uMsg)
{
case WM_CREATE:
hInstance=((LPCREATESTRUCT)lParam)->hInstance;  //get the Instance handle from system

// Load the original image and get its size
//hBitmapImage=LoadBitmap(hInstance,TEXT("Skin/Skin1.bmp"));//make the path be a value;
hBitmapImage=(HBITMAP)::LoadImage(NULL,"Skin/Skin1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); 
GetObject(hBitmapImage,sizeof(BITMAP),&O_Image);
l_siBitmapW=O_Image.bmWidth;
l_siBitmapH=O_Image.bmHeight; //Select the orginal image to a dc
hdcImage=CreateCompatibleDC(NULL);
SelectObject(hdcImage,hBitmapImage); // Load the mask image and get its size
//hBitmapMask=LoadBitmap(hInstance,TEXT("Skin/Skin1Mask.bmp"));//make the path be a value;
hBitmapMask=(HBITMAP)::LoadImage(NULL,"Skin/Skin1Mask.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
GetObject(hBitmapMask,sizeof(BITMAP),&O_Mask); //Select the mask image to a dc
hdcMask=CreateCompatibleDC(NULL);
SelectObject(hdcMask,hBitmapMask); //mask the original image
BitBlt(hdcImage,0,0,l_siBitmapW,l_siBitmapH,hdcMask,0,0,SRCAND); DeleteDC(hdcImage);
DeleteDC(hdcMask);
return 0; case WM_SIZE: //get the client width and heigh
l_siClientW=LOWORD(lParam);
l_siClientH=HIWORD(lParam);
return 0; case WM_PAINT:

hdc=BeginPaint(hWnd,&ps); //select the hdc of image
hdcImage=CreateCompatibleDC(hdc);
SelectObject(hdcImage,hBitmapImage); //select the hdc of mask
hdcMask=CreateCompatibleDC(hdc);
SelectObject(hdcMask,hBitmapMask); //paint the image in the center of the client
l_iBitmapX=(l_siClientW-l_siBitmapW)/2;
l_iBitmapY=(l_siClientH-l_siBitmapH)/2;

//Do the BitBlt
BitBlt(hdc,l_iBitmapX,l_iBitmapY,l_siBitmapW,l_siBitmapH,hdcMask,0,0,0x220326);
BitBlt(hdc,l_iBitmapX,l_iBitmapY,l_siBitmapW,l_siBitmapH,hdcImage,0,0,SRCPAINT);
DeleteDC(hdcImage);
DeleteDC(hdcMask);
EndPaint(hWnd,&ps);
return 0;

case WM_DESTROY: case WM_CLOSE:
DeleteObject(hBitmapImage);
DeleteObject(hBitmapMask);
PostQuitMessage(0);
return 0; }
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
图片无法上传。一张是skin1,一张是skin1mask。skin1是一张中心是不规则图案,其余为白色的图片。 skin1mask跟skin1的大小一样,中心图案为全白色,其余黑色。
请知道原因的高手赐教。

解决方案 »

  1.   

    那个要用SetWomdowRgn设置异形窗口。
      

  2.   

    SetLayeredAttributes也可以实现的,并且效果更好。千千静听就是用的这样的方法。
    lz的程序错误在于,一旦使用了SetLayeredAttributes设置成了alpha窗口之后,窗口就不会再有WM_PAINT消息了,必须自己在需要的时候调用UpdateLayeredWindow来刷新窗口。
      

  3.   

    已经成功了,不用UpdateLayeredWindow。直接用
    pSetLayeredWindowAttributes(hWnd, RGB(255,255,255), 100, LWA_COLORKEY);而BitBlt也不用mask图片了,用一张图片就足够了。答谢大家,分数平分!!