如何实现透明窗口
如何实现透明窗口 使用MFC的AppWizard生成一个基于对话框的工程,删除Didalog上的所有控件,并设置其附加属性Extended Styles为 Tool Window。 使用SetLayeredWindowAttributes可以方便的制作透明窗体,此函数在w2k以上才支持,而且如果希望直接使用的话,可能需要下载最新的SDK。不过此函数在w2k的user32.dll里有实现,所以如果你不希望下载巨大的sdk的话,可以直接使用GetProcAddress获取该函数的指针。
SetLayeredWindowAttributes的函数原型如下: BOOL SetLayeredWindowAttributes(
一些常量: WS_EX_LAYERED = 0x80000; 其中dwFlags有LWA_ALPHA和LWA_COLORKEY LWA_ALPHA被设置的话,通过bAlpha决定透明度. LWA_COLORKEY被设置的话,则指定被透明掉的颜色为crKey,其他颜色则正常显示. 要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性(旧的sdk没有定义这个属性,所以可以直接指定为0x80000).
例子代码:BOOL CFloatDlgDlg::OnInitDialog() { CDialog::OnInitDialog(); ///////////////////////////控制窗体大小和位置///////////////////////////////////////////// CRect rect; CWnd *pWnd = this->GetDesktopWindow(); pWnd->GetWindowRect(&rect); this->MoveWindow(rect.left + rect.Width() - 200, rect.top + 100, 42, 42); SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); // Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } }
// Set the icon for this dialog. The framework does this automatically // when the application’s main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here ////////////////////////以下实现窗体的透明/////////////////////////////////// //加入WS_EX_LAYERED扩展属性 SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE, GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000); 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(this->GetSafeHwnd(),0,128,2); FreeLibrary(hInst); } ////////////////////////////////////////////////////////////////////////////////// ModifyStyle( WS_CAPTION, WS_MINIMIZEBOX, SWP_DRAWFRAME );//设置图标 m_bmpBackground.LoadBitmap(IDB_FLOAT); return TRUE; // return TRUE unless you set the focus to a control } 如何实现浮动窗口的拖动 一般的窗体,只有鼠标位于非客户区是,才可拖动。因此,只要我们将客户区“变”为“非客户区”不就可以拖动了了吗!真是一个让人惊奇的发现!:),可是问题来了,非客户区无法加载快捷菜单,我们如何解决这一问题呢,那我们想想什么动作触发快捷菜单呢?对了,WM_RBUTTONDOWN,WM_RBUTTONUP,那拖动呢?哈哈,是WM_LBUTTONDOWN,OK,那就有方法解决了,那就是在鼠标左键按下时才将客户区“变”为“非客户区”。重载OnLButtonDown(UINT nFlags, CPoint point) ,OnLButtonUp(UINT nFlags, CPoint point),OnMouseMove(UINT nFlags, CPoint point),OnNcHitTest(CPoint point): void CFloatDlgDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_oldpoint = point; SetCapture(); drag = TRUE; CDialog::OnLButtonDown(nFlags, point); } |
|