Eyes

该程序通过Windows API实现了一个眼球跟踪的功能,能够使窗口内的虚拟眼睛随着鼠标指针的移动而转动。程序利用了数学计算确定虹膜的位置,并使用了多种绘图函数来呈现眼睛的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
/********************************************************************\
 EyeWatch -- Cursor Tracking Program.

 Written By:  Paul L. Yao & Malcolm Austin
\********************************************************************/


#include "windows.h"
#include <math.h>

#define IRIS_LEFT   (-22)
#define IRIS_RIGHT  ( 22)
#define IRIS_TOP    ( 19)
#define IRIS_BOTTOM (-19)
#define ID_ABOUT    100

static  HANDLE  hInst;
static  HWND  hWnd;

POINT pt;
POINT ptOld;

RECT  rOldEye1;
RECT  rOldEye2;

HBRUSH hWhiteBrush;
HBRUSH hBlackBrush;
HPEN   hWhitePen;
HBRUSH hBackgroundBrush;

char   acEyeWndProc[]  = "PlyEyes";

long FAR PASCAL MainWinProc (HWND, unsigned, WORD, LONG);
long FAR PASCAL EyeWinProc (HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL AboutboxWindowProc (HWND, unsigned, WORD, LONG);
void NEAR PASCAL DrawEyes (HDC, HWND);
void NEAR PASCAL DrawEyeLid (HDC, HWND);

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG   msg;
  RECT  r;

  if (!hPrevInstance)
  {
    WNDCLASS   rClass;

    rClass.lpszClassName = acEyeWndProc;
    rClass.hInstance     = hInstance;
    rClass.lpfnWndProc	 = EyeWinProc;
    rClass.hCursor       = LoadCursor(NULL, IDC_ARROW) ;
    rClass.hIcon         = NULL;
    rClass.lpszMenuName  = NULL;
    rClass.hbrBackground = NULL;
    rClass.style	 = CS_HREDRAW|CS_VREDRAW;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;

    RegisterClass(&rClass);

  }
  else ;

  hInst = hInstance;

  hWhiteBrush = GetStockObject (WHITE_BRUSH);
  hBlackBrush = GetStockObject (BLACK_BRUSH);
  hWhitePen   = GetStockObject (WHITE_PEN);

  hBackgroundBrush = CreateSolidBrush (GetSysColor(COLOR_BACKGROUND));

  hWnd = CreateWindow(acEyeWndProc,
		      "Eyes",
		      WS_OVERLAPPED  |
		      WS_CAPTION     |
		      WS_SYSMENU     |
                      WS_MINIMIZEBOX |
		      WS_THICKFRAME,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
		      NULL,
		      NULL,
		      hInstance,
		      NULL
                     );

  ShowWindow(hWnd, SW_MINIMIZE);

  SetTimer (hWnd, 1, 100, NULL);

  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  DeleteObject (hBackgroundBrush);

  exit(msg.wParam);

}

/********************************************************************\
\********************************************************************/
long FAR PASCAL EyeWinProc (hWnd, msg, wParam, lParam)
HWND	   hWnd;
unsigned   msg;
WORD	   wParam;
LONG	   lParam;
{
  HDC hDC;
  PAINTSTRUCT ps;
  RECT r;
  HDC  hDCBitmap;
  HBITMAP hBitmap, hOldBitmap;
  FARPROC  lpprocAbout;

  switch (msg)
  {
    case WM_SYSCOMMAND:
	switch (wParam)
	{
	case ID_ABOUT:
	    lpprocAbout = MakeProcInstance( AboutboxWindowProc, hInst);
	    DialogBox (hInst, "AboutBox", hWnd, lpprocAbout);
	    FreeProcInstance ( lpprocAbout);
	    break;
	default:
	    return(DefWindowProc(hWnd, msg, wParam, lParam));
	    break;
	}
	break;

    case WM_CREATE:
	{
	HWND hSystMenu;
	hSystMenu = GetSystemMenu(hWnd, FALSE);
	ChangeMenu (hSystMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
	ChangeMenu (hSystMenu, 0, "About...", ID_ABOUT, MF_APPEND | MF_STRING);
	}
	break;

    case WM_CLOSE:
        DestroyWindow (hWnd);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_ERASEBKGND:
        GetClientRect (hWnd, &r);
	DPtoLP ((HDC)wParam, (LPPOINT)&r, 2);
	FillRect ((HDC)wParam, &r, hBackgroundBrush);

	DrawEyeLid ((HDC)wParam, hWnd);
	return (1L);
        break;

    case WM_GETMINMAXINFO:
	{
	LPPOINT lp;

	lp = (LPPOINT)lParam + 3;

	/* Set minimum tracking size.  */
	lp-> x =  GetSystemMetrics (SM_CXMINTRACK)/2;
	}
	break;

    case WM_PAINT:
	hDC = BeginPaint (hWnd, &ps);
	DrawEyes (hDC, hWnd);
	EndPaint (hWnd, &ps);
        break;

    case WM_TIMER:
        GetCursorPos (&pt);
        if (ptOld.x != pt.x || ptOld.y != pt.y ) {
	    hDC = GetDC (hWnd);
	    GetClientRect (hWnd, &r);
	    if (r.right > 200 || r.bottom > 100) {
		DrawEyes (hDC, hWnd);
		goto CleanUp;
		}
	    hDCBitmap = CreateCompatibleDC (hDC);
	    hBitmap   = CreateCompatibleBitmap (hDC, r.right, r.bottom);
	    if (hBitmap) {
		hOldBitmap = SelectObject (hDCBitmap, hBitmap);
		FillRect (hDCBitmap, &r, hBackgroundBrush);
		DrawEyeLid (hDCBitmap, hWnd);
		DrawEyes (hDCBitmap, hWnd);
		SetMapMode (hDCBitmap, MM_TEXT);
		SetViewportOrg (hDCBitmap, 0, 0);
		BitBlt (hDC, 0, 0, r.right, r.bottom,
			hDCBitmap, 0, 0, SRCCOPY);
		SelectObject (hDCBitmap, hOldBitmap);
		DeleteObject (hBitmap);
		DeleteDC (hDCBitmap);
		}
	    else {
		DeleteDC (hDCBitmap);
		DrawEyes (hDC, hWnd);
		}
CleanUp:
	    ReleaseDC (hWnd, hDC);
            ptOld.x = pt.x;
            ptOld.y = pt.y;
            }
        break;

    default:
      return(DefWindowProc(hWnd, msg, wParam, lParam));
      break;
  }
  return(0L);
}

void NEAR PASCAL DrawEyes (HDC hDC, HWND hWnd)
{
  RECT r;
  POINT pt2;
  int   xShift;
  int   yShift;
  double dX;
  double dY;
  double dT;

    GetClientRect (hWnd, &r);
    SetMapMode (hDC, MM_ISOTROPIC);
    SetWindowExt (hDC, 200, 100);
    SetViewportExt (hDC, r.right, r.bottom);

    /*	Don't use pen for drawing eyes.  */
    SelectObject (hDC, hWhitePen);
    SelectObject (hDC, hWhiteBrush);

    /****************** Left Eye.  ***********************/

    /* Erase old eye.  */

    SetViewportOrg (hDC, r.right/4, r.bottom/2);
    Ellipse (hDC, rOldEye1.left,  rOldEye1.top,
		  rOldEye1.right, rOldEye1.bottom);

    /* Determine location of iris.  */
    pt2 = pt;
    ScreenToClient (hWnd, &pt2);
    DPtoLP (hDC, &pt2, 1);

    dX = (double) pt2.x;
    dY = (double) pt2.y;
    dT = sqrt ((dX*dX)+(dY*dY));

    xShift = (int) ( (IRIS_RIGHT<dT) ? (dX * IRIS_RIGHT/dT) : dX );
    yShift = (int) ( (IRIS_TOP<dT) ? (dY * IRIS_TOP/dT) : dY );

    /* Draw iris.  */
    SelectObject (hDC, hBlackBrush);

    rOldEye1.left   = IRIS_LEFT  +xShift;
    rOldEye1.top    = IRIS_TOP	 +yShift;
    rOldEye1.right  = IRIS_RIGHT +xShift;
    rOldEye1.bottom = IRIS_BOTTOM+yShift;
    Ellipse (hDC, rOldEye1.left,  rOldEye1.top,
		  rOldEye1.right, rOldEye1.bottom);

    /*********************** Right Eye. ************************/

    /* Erase old eye.  */
    SelectObject (hDC, hWhiteBrush);

    SetViewportOrg (hDC, (3*r.right)/4, r.bottom/2);
    Ellipse (hDC, rOldEye2.left,  rOldEye2.top,
		  rOldEye2.right, rOldEye2.bottom);

    /* Determine location of iris.  */
    pt2 = pt;
    ScreenToClient (hWnd, &pt2);
    DPtoLP (hDC, &pt2, 1);

    dX = (double) pt2.x;
    dY = (double) pt2.y;
    dT = sqrt ((dX*dX)+(dY*dY));

    xShift = (int) ( (IRIS_RIGHT<dT) ? (dX * IRIS_RIGHT/dT) : dX );
    yShift = (int) ( (IRIS_TOP<dT) ? (dY * IRIS_TOP/dT) : dY );

    /* Draw iris.  */
    SelectObject (hDC, hBlackBrush);

    rOldEye2.left   = IRIS_LEFT  +xShift;
    rOldEye2.top    = IRIS_TOP	 +yShift;
    rOldEye2.right  = IRIS_RIGHT +xShift;
    rOldEye2.bottom = IRIS_BOTTOM+yShift;
    Ellipse (hDC, rOldEye2.left,  rOldEye2.top,
		  rOldEye2.right, rOldEye2.bottom);

    }


void NEAR PASCAL DrawEyeLid (HDC hDC, HWND hWnd)
{
RECT r;

    /* Set up mapping mode. */
    GetClientRect (hWnd, &r);
    SetMapMode (hDC, MM_ISOTROPIC);
    SetWindowExt (hDC, 200, 100);
    SetViewportExt (hDC, r.right, r.bottom);

    /* Draw Outline of Left Eye.  */
    SetViewportOrg (hDC, r.right/4, r.bottom/2);
    Ellipse (hDC, -49, 42, 49, -42);

    /* Draw outline of Right eye. */
    SetViewportOrg (hDC, (3*r.right)/4, r.bottom/2);
    Ellipse (hDC, -49, 42, 49, -42);
}


/***************************************************************************/
/*    T H E   A B O U T   B O X   H A N D L I N G   P R O C E D U R E      */
/***************************************************************************/

/*   (This is the window procedure for the About dialog box.)              */


BOOL FAR PASCAL AboutboxWindowProc (hDlg, message, wParam, lParam)

HWND            hDlg;
unsigned        message;
WORD            wParam;
LONG            lParam;

{
    if (message == WM_COMMAND) {
        EndDialog (hDlg, TRUE);
        return TRUE;
        }
    else if (message == WM_INITDIALOG)
       return TRUE;
    else return FALSE;
}

资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 在本文中,我们将探讨如何通过 Vue.js 实现一个带有动画效果的“回到顶部”功能。Vue.js 是一款用于构建用户界面的流行 JavaScript 框架,其组件化和响应式设计让实现这种交互功能变得十分便捷。 首先,我们来分析 HTML 代码。在这个示例中,存在一个 ID 为 back-to-top 的 div 元素,其中包含两个 span 标签,分别显示“回到”和“顶部”文字。该 div 元素绑定了 Vue.js 的 @click 事件处理器 backToTop,用于处理点击事件,同时还绑定了 v-show 指令来控制按钮的显示与隐藏。v-cloak 指令的作用是在 Vue 实例渲染完成之前隐藏该元素,避免出现闪烁现象。 CSS 部分(backTop.css)主要负责样式设计。它首先清除了一些默认的边距和填充,对 html 和 body 进行了全屏布局,并设置了相对定位。.back-to-top 类则定义了“回到顶部”按钮的样式,包括其位置、圆角、阴影、填充以及悬停时背景颜色的变化。此外,与 v-cloak 相关的 CSS 确保在 Vue 实例加载过程中隐藏该元素。每个 .page 类代表一个页面,每个页面的高度设置为 400px,用于模拟多页面的滚动效果。 接下来是 JavaScript 部分(backTop.js)。在这里,我们创建了一个 Vue 实例。实例的 el 属性指定 Vue 将挂载到的 DOM 元素(#back-to-top)。data 对象中包含三个属性:backTopShow 用于控制按钮的显示状态;backTopAllow 用于防止用户快速连续点击;backSeconds 定义了回到顶部所需的时间;showPx 则规定了滚动多少像素后显示“回到顶部”按钮。 在 V
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值