/** * @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