windows程序设计-第七章 BLOKOUT1 备注


如有错误请指正~

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	static TCHAR	szAppName[] = TEXT ("BlokOut1") ;
	HWND			hwnd ;
	MSG				msg ;
	WNDCLASS		wndclass ;

	wndclass.cbClsExtra = 0 ;
	wndclass.cbWndExtra = 0 ;
	wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH) ;
	wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;						//窗口类的类光标
	wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hInstance = hInstance ;
	wndclass.lpfnWndProc = WndProc ;
	wndclass.lpszClassName = szAppName ;
	wndclass.lpszMenuName = NULL ;
	wndclass.style = CS_HREDRAW | CS_VREDRAW ;

	if (!RegisterClass (&wndclass)){
		MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR) ;
		return 0 ;
	}

	hwnd = CreateWindow (szAppName, TEXT("Mouse Button Demo"), WS_OVERLAPPEDWINDOW, 
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;
	ShowWindow (hwnd, iCmdShow);
	UpdateWindow (hwnd) ;

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

void DrawBoxOutline (HWND hwnd, POINT ptBeg, POINT ptEnd) 
{
	HDC hdc ;
	hdc = GetDC(hwnd) ;

	SetROP2 (hdc, R2_NOT) ;											// 用背景色的反色画图
	SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
	Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;

	ReleaseDC (hwnd, hdc) ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static BOOL		fBlocking, fValidBox ;					//fblocking 用于标识当前是否正按下鼠标左键移动鼠标
															//当完成一次 BUTTONDOWN,BUTTONUP 后,得到一个矩形,fValidBox此时便为TRUE,该矩形被画刷填充
	static POINT	ptBeg, ptEnd, ptBoxBeg, ptBoxEnd ;
	HDC				hdc ;
	PAINTSTRUCT		ps ;
	
	switch (message)
	{
	case WM_LBUTTONDOWN :
		ptBeg.x = ptEnd.x = LOWORD (lParam) ;
		ptBeg.y = ptEnd.y = HIWORD (lParam) ;

		DrawBoxOutline (hwnd,  ptBeg, ptEnd) ;				//在鼠标左键点下的地方画了一个黑点

		SetCursor (LoadCursor (NULL, IDC_CROSS)) ;			//光标从左键按下的那一刻开始变为 十字架光标

		fBlocking = TRUE ;
		return 0 ;

	case WM_MOUSEMOVE :
		if (fBlocking)
		{
			SetCursor (LoadCursor (NULL, IDC_CROSS)) ;	//如果应用程序必须在窗口中设置光标,必须确保指定窗口类的类光标被设为NULL,如果类光标不是NULL,则每次移动鼠标时,系统都要恢复类光标。
			DrawBoxOutline (hwnd,  ptBeg, ptEnd) ;		

			ptEnd.x = LOWORD (lParam) ;
			ptEnd.y = HIWORD (lParam) ;

			DrawBoxOutline (hwnd,  ptBeg, ptEnd) ;		//为什么画两个个矩形线框? (其实不是两个,而是把之前的那个擦除了再画)不理解的话可以看看代码后面给的那个链接
		}
		return 0 ;

	case WM_LBUTTONUP :
		if (fBlocking)
		{
			DrawBoxOutline (hwnd,  ptBeg, ptEnd) ;	

			ptBoxBeg	= ptBeg ;
			ptBoxEnd.x	= LOWORD (lParam) ;
			ptBoxEnd.y	= HIWORD (lParam) ;

			SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
			fBlocking = FALSE ;
			fValidBox = TRUE ;

			InvalidateRect (hwnd, NULL, TRUE) ;
		}
		return 0 ;

	case WM_CHAR :								//按下鼠标左键拖动的时候,按Esc建可以撤销本次操作
		if(fBlocking & (wParam == '\x1B'))      //'x1B' (中间的是数字1,不是小写字母l) 对应的是 键盘左上角的 Esc
		{
			DrawBoxOutline (hwnd, ptBeg, ptEnd) ;

			SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

			fBlocking = FALSE ;
		}
		return 0 ;

	case WM_PAINT :
		hdc = BeginPaint (hwnd, &ps) ;

		if(fValidBox){
			SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;

			Rectangle (hdc, ptBoxBeg.x, ptBoxBeg.y, ptBoxEnd.x, ptBoxEnd.y) ;
		}

		if(fBlocking){
			SetROP2 (hdc, R2_NOT) ;
			SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
			Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;
		}

		EndPaint (hwnd, &ps) ;
		return 0 ;

	case WM_DESTROY :
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

http://blog.youkuaiyun.com/dellaserss/article/details/38390223

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值