• [转载]椭圆窗体的实现


    转载留名!
    原文地址:椭圆窗体的实现作者:永不言敗

    代码运行效果图如下:

    我将分三部分介绍这一程序的实现过程:

    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文件。

    选择“文件”、“新建”,在“文件”选项卡中选中“cc++ 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);
    }

    编译程序,完成应用程序。

  • 相关阅读:
    独立博客,从零到千万访问,这三年我都做了什么
    Postman使用详解
    Postman安装与使用
    Python爬虫入门教程:超级简单的Python爬虫教程
    《完全用Linux工作》——转载自清华退学博士
    转:一篇搞定Python正则表达式
    文件上传的单元测试怎么写?
    功能性测试分类
    ajax 学习笔记 timer控件
    ajax 学习笔记 updatepannel控件
  • 原文地址:https://www.cnblogs.com/eagleking0318/p/6521540.html
Copyright © 2020-2023  润新知