程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 橢圓窗體的實現

橢圓窗體的實現

編輯:關於VC++

代碼運行效果圖如下:

我將分三部分介紹這一程序的實現過程:

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],謝謝。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved