用控制台程序开发浮动窗口

 
/**
* @file FloatingWindow.h
* @brief 
* @author Don Hao
* @date 2011-08-21
* @version 
* <pre><b>copyright: </b></pre>
* <pre><b>email: </b>[email protected]</pre>
* <pre><b>company: </b>http://blog.csnd.net/donhao</pre>
* <pre><b>All rights reserved.</b></pre>
* <pre><b>modification:</b></pre>
* <pre>Write modifications here.</pre>
*/
#ifdef WIN32
#ifndef _FLOATINGWINDOW_H
#define _FLOATINGWINDOW_H

#define SWM_UPDATE WM_APP + 1  //点击菜单更新选项
#define SWM_CANCEL WM_APP + 2  //点击菜单取消更新选项

#define SWM_START  WM_APP + 3  //点击菜单取消更新选项
#define SWM_SHOW   WM_APP + 4  //点击菜单更新选项
#define SWM_HIDE   WM_APP + 5  //点击菜单取消更新选项

#define WS_EX_LAYERED 0x00080000  

#ifndef LWA_ALPHA
#define LWA_ALPHA 2 
#endif

#include <winsock2.h>
#include <process.h>

#pragma warning(disable:4786)

/**
* @class FloatingWindow
* @brief 浮动窗口实现
* 
* Detailed description.
*/
class FloatingWindow
{
public:

	/** 
	* @brief Constructor for FloatingWindow.
	*/
	FloatingWindow();

	/** 
	* @brief Destructor for FloatingWindow.
	*/
	~FloatingWindow();

	/** 
	* @brief WinSunProc 
	* @param[in] hwnd 
	* @param[in] uMsg 
	* @param[in] wParam 
	* @param[in] lParam 
	* @return LRESULT CALLBACK  
	*/
	static LRESULT CALLBACK WinSunProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

	/** 
	* @brief CreateFloatingWindow 
	* @param[in] pArguments 
	* @return unsigned WINAPI  
	*/
	static unsigned WINAPI CreateFloatingWindow(void *pArguments);

	/** 
	* @brief GetTransparent 
	* @param[in] hWnd 
	* @return byte  
	*/
	byte GetTransparent(HWND hWnd);

	/** 
	* @brief SetTransparent 
	* @param[in] hWnd 
	* @param[in] bAlpha 
	*/
	static void SetTransparent(HWND hWnd, byte bAlpha);

	/** 
	* @brief show 
	*/

	void show();

	/** 
	* @brief hide 
	*/
	void hide();

	/** 
	* @brief start 
	*/
	void start();
protected:
private:
	static HWND hwnd; 
	static HMENU hMenu;
	static HWND hButton;
};

#endif // _FLOATINGWINDOW_H
#endif //WIN32


/**
* @file FloatingWindow.c
* @brief 
* @author Don Hao
* @date 2011-08-21
* @version 
* <pre><b>copyright: </b></pre>
* <pre><b>email: </b>[email protected]</pre>
* <pre><b>company: </b>http://blog.csnd.net/donhao</pre>
* <pre><b>All rights reserved.</b></pre>
* <pre><b>modification:</b></pre>
* <pre>Write modifications here.</pre>*/
#ifdef WIN32
#define _WIN32_IE 0x0500

#include <winsock2.h>
#include "commctrl.h"
#include "TCHAR.h"

HINSTANCE hInst;

#include "FloatingWindow.h"
#include <shlobj.h>
#include <string>

FloatingWindow::FloatingWindow()
{
	DWORD threadID;
	_beginthreadex(NULL, 0, CreateFloatingWindow, this, 0, (unsigned int*)&threadID);
}

CFloatingWindow::~CFloatingWindow()
{
	if (hwnd)
	{
		::PostMessage(hwnd, WM_CLOSE, 0, 0);
	}
	Sleep(100);
}

void FloatingWindow::start()
{
	::PostMessage(hwnd, SWM_START, 0, 0);
}

void FloatingWindow::show()
{
	::PostMessage(hwnd, SWM_SHOW, 0, 0);
}

void FloatingWindow::hide()
{
	::PostMessage(hwnd, SWM_HIDE, 0, 0);
}

LRESULT CALLBACK FloatingWindow::WinSunProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
	HDC hDC;
	RECT line_rect;
/*	TCHAR tip[256]=_T("有新更新,请在绿色区域点击鼠标右键。");*/
	switch (uMsg) 
	{ 
	case SWM_START:
/*		ToolTip::AddTip(hwnd, hInst, tip, 50, TRUE);*/
		::SetWindowPos(hwnd, HWND_TOPMOST, GetSystemMetrics(SM_CXSCREEN) - 60, 0, 60, 60, SWP_NOSIZE | SWP_DRAWFRAME);
		HBRUSH brush;   
		brush = CreateSolidBrush(RGB(0, 255, 0));


		SetClassLong(hwnd, GCL_HBRBACKGROUND, (long)brush);
		SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); 
		brush = CreateSolidBrush(RGB(255, 0, 0));
		SetClassLong(hButton, GCL_HBRBACKGROUND, (LONG)brush);

		::ShowWindow(hwnd, SW_SHOWNORMAL);

		SetTransparent(hwnd, 180); 
		UpdateWindow(hwnd);

		hDC = GetDC(hwnd);
		SetBkMode(hDC, TRANSPARENT);
		SetTextColor(hDC, RGB(255, 0, 0));

		ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &line_rect, "拖动区域", strlen("拖动区域"), 0);

		ReleaseDC(hwnd, hDC);
		break;
	case SWM_SHOW:
		ShowWindow(hwnd, SW_SHOW);
		hDC = GetDC(hwnd);
		SetBkMode(hDC, TRANSPARENT);
		SetTextColor(hDC, RGB(255, 0, 0));
		ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &line_rect, "拖动区域", strlen("拖动区域"), 0);
		ReleaseDC(hwnd, hDC);
		break;
	case SWM_HIDE:
		ShowWindow(hwnd, SW_HIDE);
		break;
	case WM_CLOSE : 
		DestroyWindow(hwnd);
		break;
	case WM_LBUTTONDOWN:
		ReleaseCapture(); 
		SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
		break;
	case WM_RBUTTONDOWN:
		POINT pt;
		GetCursorPos(&pt);
		hMenu = CreatePopupMenu();
		if (hMenu)
		{
			InsertMenu(hMenu, - 1, MF_BYPOSITION, SWM_UPDATE, "更新");
			InsertMenu(hMenu, - 1, MF_BYPOSITION, SWM_CANCEL, "稍后更新");

			SetForegroundWindow(hwnd);

			TrackPopupMenu(hMenu, TPM_BOTTOMALIGN, pt.x, pt.y, 0, hwnd, NULL);
			DestroyMenu(hMenu);
		}
		break; 
	case WM_NOTIFY:
		
		break; 
	case WM_COMMAND:
		{
			int wmId, wmEvent;
			wmId = LOWORD(wParam);
			wmEvent = HIWORD(wParam); 

			if(LOWORD(wParam == 50))
			{
				POINT pt;
				GetCursorPos(&pt);
				hMenu = CreatePopupMenu();
				if (hMenu)
				{
					InsertMenu(hMenu, - 1, MF_BYPOSITION, SWM_UPDATE, "更新");
					InsertMenu(hMenu, - 1, MF_BYPOSITION, SWM_CANCEL, "稍后更新");

					SetForegroundWindow(hwnd);

					TrackPopupMenu(hMenu, TPM_BOTTOMALIGN, pt.x, pt.y, 0, hwnd, NULL);
					DestroyMenu(hMenu);
				}
			}

			switch (wmId)
			{

			case SWM_UPDATE:
				if (IDOK == MessageBox(NULL, "确认更新\?", "提示", MB_OKCANCEL))
				{
					::SetWindowPos(hwnd, HWND_TOPMOST, GetSystemMetrics(SM_CXSCREEN) - 60, 0, 60, 60, SWP_NOSIZE | SWP_DRAWFRAME | SWP_HIDEWINDOW);
				}
				else
				{
				}
				break;
			case SWM_CANCEL:
				break;
			}
		}
		break;
	default: 
		return DefWindowProc(hwnd, uMsg, wParam, lParam); 
	} 
	return 0; 
} 

byte FloatingWindow::GetTransparent(HWND hWnd) 
{ 
	BYTE bAlpha = 0; 
	HINSTANCE hInst = LoadLibrary("User32.DLL"); 
	if (hInst) 
	{ 
		typedef BOOL(WINAPI *MYFUNC)(HWND hwnd, COLORREF *pcrKey, BYTE *pbAlpha, DWORD *pdwFlags); 
		MYFUNC fun = NULL; 
		// GetLayeredWindowAttributes 
		fun = (MYFUNC)GetProcAddress(hInst, "GetLayeredWindowAttributes"); 
		if (fun) 
		{ 
			fun(hWnd, NULL, &bAlpha, NULL); 
		} 
		FreeLibrary(hInst); 
	} 
	return bAlpha; 
} 


void FloatingWindow::SetTransparent(HWND hWnd, byte bAlpha) 
{ 
	long lRt = ::GetWindowLong(hWnd, GWL_EXSTYLE); 
	lRt = lRt | WS_EX_LAYERED; 
	::SetWindowLong(hWnd, GWL_EXSTYLE, lRt); 
	HINSTANCE hInst = LoadLibrary("User32.DLL"); 
	if (hInst) 
	{ 
		typedef BOOL(WINAPI *MYFUNC)(HWND, COLORREF, BYTE, DWORD); 
		MYFUNC fun = NULL; 
		// 取得SetLayeredWindowAttributes函数指针 
		fun = (MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes"); 
		if (fun) 
		{ 
			fun(hWnd, 0, bAlpha, LWA_ALPHA); 
		} 
		FreeLibrary(hInst); 
	} 
} 

unsigned WINAPI FloatingWindow::CreateFloatingWindow(void *pArguments)
{
	WNDCLASSEX wndclass;

	wndclass.cbSize = sizeof(WNDCLASSEX);
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hIcon = NULL;
	wndclass.hIconSm = NULL;
	wndclass.hInstance = GetModuleHandle(NULL);
	wndclass.lpfnWndProc = WinSunProc;
	wndclass.lpszClassName = "FloatWindow";
	wndclass.lpszMenuName = NULL;
	wndclass.style = CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS;
	RegisterClassEx(&wndclass);

	hwnd = CreateWindowEx(0, "FloatWindow", TOOLTIPS_CLASS, WS_POPUP |TBSTYLE_FLAT | WS_BORDER | TBSTYLE_TOOLTIPS, 
		GetSystemMetrics(SM_CXSCREEN) - 60, 0, 60, 60, NULL, NULL, GetModuleHandle(NULL), NULL); 

	hButton = CreateWindowEx(0, "Button", "提示信息", WS_CHILD| WS_VISIBLE, 
		0, 30, 60, 30, hwnd, (HMENU)50, GetModuleHandle(NULL), NULL); 

	::PostMessage(hwnd, SWM_START, 0, 0);

	MSG msg; 
	while (GetMessage(&msg, NULL, 0, 0)) 
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	} 
	return EXIT_SUCCESS;
}

HWND FloatingWindow::hwnd; 
HMENU FloatingWindow::hMenu;
HWND FloatingWindow::hButton;

#endif


你可能感兴趣的:(用控制台程序开发浮动窗口)