如何實現(xiàn)透明窗口
使用MFC的AppWizard生成一個基于對話框的工程,刪除Didalog上的所有控件,并設置其附加屬性Extended Styles為 Tool Window。
使用SetLayeredWindowAttributes可以方便的制作透明窗體,此函數(shù)在w2k以上才支持,而且如果希望直接使用的話,可能需要下載最新的SDK。不過此函數(shù)在w2k的user32.dll里有實現(xiàn),所以如果你不希望下載巨大的sdk的話,可以直接使用GetProcAddress獲取該函數(shù)的指針。
SetLayeredWindowAttributes的函數(shù)原型如下:
BOOL SetLayeredWindowAttributes(
HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
);
Windows NT/2000/XP: Included in Windows 2000 and later.
Windows 95/98/Me: Unsupported.(注意了,在win9x里沒法使用的)
Header: Declared in Winuser.h; include Windows.h.
Library: Use User32.lib.
一些常量:
WS_EX_LAYERED = 0x80000;
LWA_ALPHA = 0x2;
LWA_COLORKEY=0x1;
其中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
////////////////////////以下實現(xiàn)窗體的透明///////////////////////////////////
//加入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函數(shù)指針
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
}
如何實現(xiàn)浮動窗口的拖動
一般的窗體,只有鼠標位于非客戶區(qū)是,才可拖動。因此,只要我們將客戶區(qū)“變”為“非客戶區(qū)”不就可以拖動了了嗎!真是一個讓人驚奇的發(fā)現(xiàn)?。海墒菃栴}來了,非客戶區(qū)無法加載快捷菜單,我們?nèi)绾谓鉀Q這一問題呢,那我們想想什么動作觸發(fā)快捷菜單呢?對了,WM_RBUTTONDOWN,WM_RBUTTONUP,那拖動呢?哈哈,是WM_LBUTTONDOWN,OK,那就有方法解決了,那就是在鼠標左鍵按下時才將客戶區(qū)“變”為“非客戶區(qū)”。重載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);
}