・Win 2k で半透明ウィンドウ (2000/5/21)

以前、Windows で半透明ウィンドウができないか 色々試してみた事がありましたが、 Win 2k ならば API 一個で簡単に半透明化できます。 詳しいことは MSDN online Libraryを見ていただくとして、具体的には SetLayeredWindowAttributes()という Win2k で新設された API を 使用します。


// Win2k で半透明ウィンドウ
// (c) tokai@fides.dti.ne.jp , 2000/5/20
//
// 16bit カラー以上で使用すること

// BOOL PrepareLayeredWindow(HWND); 
// で準備

// BOOL MySetLayeredWindowAttributes(HWND,COLORREF,BYTE,DWORD);
// で半透明化

// VOID UnprepareLayeredWindow();
// で後始末

#include <windows.h>

#define WS_EX_LAYERED 0x80000
#define LWA_COLORKEY	1
#define LWA_ALPHA		2
typedef BOOL (WINAPI *SLWINATT)(HWND,COLORREF,BYTE,DWORD);

// グローパル
HMODULE hModU32 = NULL;  // user32.dll のハンドル
SLWINATT pSetLayWinAtt;

// 半透明ウィンドウ準備
BOOL PrepareLayeredWindow(HWND hWnd)
{
	if(!hModU32){
		if(hModU32 = LoadLibrary("user32.dll"))
		{
			pSetLayWinAtt = 
				(SLWINATT)GetProcAddress(hModU32,"SetLayeredWindowAttributes");
			
			if(pSetLayWinAtt)
			{
				// スタイルに WS_EX_LAYERED をセット
				SetWindowLong(hWnd, GWL_EXSTYLE,
					GetWindowLong(hWnd, GWL_EXSTYLE)|WS_EX_LAYERED);
				
				return TRUE;
			}
			else{
				FreeLibrary(hModU32); 
				hModU32 = NULL;
			}
		}
	}
	
	return FALSE;
}


// 後始末
VOID UnprepareLayeredWindow()
{
	if(hModU32) FreeLibrary(hModU32);
}


// 半透明化
BOOL MySetLayeredWindowAttributes(HWND hwnd,
								  COLORREF crKey,
								  BYTE bAlpha,        
								  DWORD dwFlags){
	if(hModU32) return pSetLayWinAtt(hwnd,crKey,bAlpha,dwFlags);
	else return FALSE;
}


//----------------------------------------------


// プロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)

{
	
	HDC hDC;
	PAINTSTRUCT ps;
	RECT rt;
	static BYTE bAlpha = 160;
	
    switch (msg) {
		
	case WM_CREATE: // 初期化	
		PrepareLayeredWindow(hWnd);
		MySetLayeredWindowAttributes(hWnd,0,bAlpha,LWA_ALPHA);
		SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
		break;
		
	case WM_LBUTTONDOWN:
		bAlpha = (bAlpha+8) | 16;
		MySetLayeredWindowAttributes(hWnd,0,bAlpha,LWA_ALPHA);
		break;
		
	case WM_PAINT:
		
		hDC = BeginPaint(hWnd,&ps);
		GetClientRect(hWnd,&rt); 
		SetTextColor(hDC,RGB(255,255,0));
		SetBkMode(hDC,TRANSPARENT);			 
		DrawText(hDC,"半透明",-1,&rt,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
		EndPaint(hWnd,&ps);
		
		break;
		
	case WM_CLOSE: 
		UnprepareLayeredWindow();
		DestroyWindow(hWnd);
		break;
		
		
	case WM_DESTROY: 
		PostQuitMessage(0);
		break;
		
	default:
		return DefWindowProc(hWnd, msg, wp, lp);
    }
	
    return 0;
}



// メイン
char szClassName[] = "TOMEIWIN2k";
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreInst,
                   LPSTR lpszCmdLine, int nCmdShow)
{
    HWND hWnd;
    MSG lpMsg;
    WNDCLASS wndClass;
	
	// ウィンドウ登録
    if (!hPreInst) {
		memset(&wndClass,0,sizeof(WNDCLASS));
        wndClass.lpfnWndProc = WndProc;
        wndClass.hInstance = hInst;
        wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wndClass.lpszClassName = szClassName;
        if (!RegisterClass(&wndClass)) return FALSE;
    }
	
	// ウィンドウ作成
    hWnd = CreateWindow(
		szClassName,"半透明2k",
        WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,
        CW_USEDEFAULT,CW_USEDEFAULT,
        200,200,NULL,NULL,hInst,NULL);
	
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
	
	// メッセージループ
    while (GetMessage(&lpMsg, NULL, 0, 0)) {
        TranslateMessage(&lpMsg);
        DispatchMessage(&lpMsg);
    }
	
    return lpMsg.wParam;
}

// EOF