代碼運行效果圖如下:
我將分三部分介紹這一程序的實現過程:
1.生成橢圓形圖形界面,並在上面寫斜體帶顏色的子和鼠標拖動功能。
2.增加鼠標右鍵菜單,並實現總在前面和其他程序自動覆蓋的功能。
3.生成鼠標的全局鉤子,截獲鼠標事件,返回****的值。
1.生成橢圓形圖形界面,並在上面寫斜體帶顏色的子。
在VC集成編譯環境中,選擇“文件”,“新建”,然後選擇“工程”選項卡。在左側的工程選擇項中選取“MFC AppWizard[exe]”,在右側工程標題下的編輯框中輸入“EllipseWindow”。
單擊“確定”按鈕,進入“MFC AppWizard step-1”選擇頁,選中“D基本對話框”左側的單選按鈕,將應用程序的類型設為基本對話框,然後點擊“完成”按鈕後點擊“確定”即可。
在自動生成的“IDD_ELLIPSEWINDOW_DIALOG”對話框資源中刪除“取消”,“確定”按鈕和標題為“TODO:在這裡設置對話框”的文本框。此時,編譯運行這個程序,應該能在窗口彈出一個空的對話框。
橢圓窗體的實現主要是靠CRgn類來實現的。
1.1 生成橢圓窗體
在類CEllipseWindowDlg的定義中填加CRgn m_rgnWnd的protected型變量。在CEllipseWindowDlg::OnInitDialog()中加入如下代碼:
CRect rc;
GetClientRect(rc);
m_rgnWnd.CreateEllipticRgn(rc.left+32,rc.top+32,rc.Width()-64,rc.Height()-20);
SetWindowRgn((HRGN)m_rgnWnd,TRUE);
此時運行這個程序,將出現一個灰色的橢圓窗體。如果不能關閉這個應用程序,可用Alt+F4關閉這個程序。
1.2 按下鼠標左鍵後,用鼠標拖動橢圓的實現方法。
使用類向導,添加CEllipseWindowDlg的WM_MOUSEMOVE的處理函數CEllipseWindowDlg::OnMouseMove(UINT nFlags, CPoint point),代碼如下:
static CPoint p;
ClientToScreen(&point);
if(nFlags & MK_LBUTTON)
{
SetCursor(LoadCursor(NULL,IDC_CROSS));
CRect rc;
GetWindowRect(rc);
MoveWindow(rc.left+point.x-p.x,rc.top+point.y-p.y,rc.Width(),rc.Height());
}
p=point;
此時運行程序,按下鼠標左鍵,就可以拖動橢圓窗體了。
1.3 為這個窗體添加漸變的背景顏色。
在CEllipseWindowApp增加public成員函數void CEllipseWindowApp::SetBkColor(),代碼為:
static BYTE x=80,y=40,z=30;
static BOOL flagx=TRUE,flagy=FALSE,flagz=TRUE;
if(flagx)
{
x++;
if(x>120)
flagx=FALSE;
}
else
{
x--;
if(x<10)
flagx=TRUE;
}
if(flagy)
{
y+=2;
if(y>100)
flagy=FALSE;
}
else
{
y-=2;
if(y<20)
flagy=TRUE;
}
if(flagz)
{
z+=3;
if(z>80)
flagz=FALSE;
}
else
{
z-=3;
if(z<20)
flagz=TRUE;
}
SetDialogBkColor(RGB(x,y,z),RGB(x+100,y+120,140));
此時運行程序,橢圓界面的顏色就會自動發生漸變。
在EllipseWindowDlg.cpp中加入代碼:
extern CEllipseWindowApp theApp;
在CEllipseWindosDlg中加入定時器void CEllipseWindowDlg::OnTimer(UINT nIDEvent),其中的實現代碼為:
theApp.SetBkColor();
Invalidate();
在BOOL CEllipseWindowDlg::OnInitDialog()中加入對初始化定時器代碼:
SetTimer(1,20,NULL);
1.4 在窗體上顯示歡迎詞“enjoy!!!”
添加CEllipseWindowDlg的protected數據成員 CFont m_font;
在BOOL CEllipseWindowDlg::OnInitDialog()中創建字體,代碼如下:
LOGFONT lf;
SystemParametersInfo(SPI_GETICONTITLELOGFONT,sizeof(LOGFONT),&lf,SPIF_SENDWININICHANGE);
lf.lfHeight=60;
lf.lfEscapement=100;
lf.lfItalic=TRUE;
lf.lfQuality=DRAFT_QUALITY;
m_font.CreateFontIndirect(&lf);
在void CEllipseWindowDlg::OnPaint()中加入顯示代碼:
CPaintDC dc(this);
dc.SetBkMode(TRANSPARENT);
dc.SetTextAlign(TA_BASELINE|TA_CENTER);
CRect rc;
GetClientRect(rc);
CFont *oldfont=dc.SelectObject(&m_font);
dc.TextOut(rc.Width()/2,rc.Height()/2,"enjoy!!!");
dc.SelectObject(oldfont);
好了,第一步完成了,也累了,have a rest :-)
檢查一下我們的成果:程序運行,顯示橢圓窗體,顯示 “enjoy!!!”,並且背景顏色在不停的改變,按下鼠標左鍵後可以拖動。
2.增加鼠標右鍵菜單,並實現總在前面和其他程序自動覆蓋的功能。
2.1 增加鼠標右鍵菜單
添加資源中添加菜單資源,添加後的結果如下:
MENUITEM "關閉", IDCANCEL
MENUITEM "關於...", ID_APP_ABOUT
MENUITEM SEPARATOR
MENUITEM "開始識別密碼", ID_START
MENUITEM "終止識別密碼", ID_STOP, GRAYED
MENUITEM SEPARATOR
MENUITEM "總在前面", ID_TOPMOST
MENUITEM "自動隱藏", ID_ZORDER, GRAYED
在CEllipseWindowDlg中加入鼠標右鍵按下的處理,是按下鼠標左鍵後彈出異彩單,實現代碼為:
ClientToScreen(&point);
pMenu->TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,this);
2.2 加入橢圓窗口界面總在前面和自動隱藏的處理。
在BOOL CEllipseWindowDlg::OnInitDialog()中加在菜單項,代碼如下:
m_menu.LoadMenu(IDR_RIGHT_CLICK);
pMenu=m_menu.GetSubMenu(0);
使用類向導生成菜單項的處理函數,對於ID_TOPMOST中的處理世界面總是顯示在最前面,而且是該菜單選項變灰,處理代碼為:
CRect rc;
GetWindowRect(rc);
SetWindowPos(&wndTopMost,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW);
pMenu->EnableMenuItem(ID_TOPMOST,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_ZORDER,MF_BYCOMMAND|MF_ENABLED);
相應的,自動隱藏的代碼為:
CRect rc;
GetWindowRect(rc);
SetWindowPos(&wndBottom,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW);
SetWindowPos(&wndTop,rc.left,rc.top,rc.Width(),rc.Height(),SWP_SHOWWINDOW); pMenu->EnableMenuItem(ID_ZORDER,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_TOPMOST,MF_BYCOMMAND|MF_ENABLED);
3.生成鼠標的全局鉤子,截獲鼠標事件,返回****的值
在VC集成開發環境中,選擇“文件”、“新建”,選中“工程”選項卡中的“Win32 Dynamic-link Library”選項。工程的名稱為“finder”,點擊“下一步”按鈕。 在“win32 Dynamic-Link Library step 1 of 1”中,選擇創建“A simple Dll project”,然後單擊“完成”按鈕。
3.1 創建finder.h文件。
選擇“文件”、“新建”,在“文件”選項卡中選中“c\c++ header file”選項,文件名為finder。
#ifndef __FINDER_H__
#define __FINDER_H__
#ifdef FINDER_EXPORTS
#define FINDER_API __declspec(dllexport)
#else
#define FINDER_API __declspec(dllimport)
#endif
HHOOK FINDER_API start();
#endif __FINDER_H__
3.2 在finder.cpp中加入鼠標處理代碼,詳見finder.cpp文件。
編譯程序,生成finder.dll動態連接軟件。將finder.h和編譯生成的finder.dll,finder.lib程序拷貝到EllipseWindow文件夾。
3.3 在EllipseWindow的EllipseWindowDlg.cpp中加入開始和終止鼠標鉤子的代碼(使用想到,可簡化操作),代碼如下。
void CEllipseWindowDlg::OnStart()
{
// TODO: Add your command handler code here
m_hMouse=start();
pMenu->EnableMenuItem(ID_START,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_STOP,MF_BYCOMMAND|MF_ENABLED);
}
void CEllipseWindowDlg::OnStop()
{
// TODO: Add your command handler code here
CloseHandle(m_hMouse);
pMenu->EnableMenuItem(ID_STOP,MF_BYCOMMAND|MF_GRAYED);
pMenu->EnableMenuItem(ID_START,MF_BYCOMMAND|MF_ENABLED);
}
編譯程序,完成應用程序。
備注:如果出現問題,請仔細閱讀源代碼或參照MSDN。不當之處或改進的地方敬請指點,如怎樣除去顏色漸變過程中的閃爍問題,請發mail到[email protected],謝謝。
本文配套源碼