windows程序设计之鼠标,键盘,绘制文本简介

写了一个小程序,大概介绍SDK里面鼠标点击,键盘输入,文本绘制的要点。至于前面一大堆的基本窗口的创建,网上的资料很多,这里就不做多的介绍了。这个程序主要介绍键盘按键的统计,将所有按下的键都写到一个文件里面。其次是点击鼠标的操作,大概是一个怎样的过程。再是一些绘制文本的基本要点。先看代码吧(*^__^*)

#include "Windows.h"
#include <stdio.h>
#include "tchar.h"

HWND hWinMain;
TCHAR szClassName[] = _T("MyClass");
TCHAR szCaptionMain[] = _T("My Window!");
TCHAR FontName[] = _T("script");
TCHAR FileName[MAX_PATH] = {"TEST.txt"};
FILE  *fp;
BOOL MouseClick = FALSE;
POINT hitPoint;
WNDCLASSEX stdWndClass;
WPARAM keyChar = 0x20;				//0x20是空格的ascii码,保证没有按键的时候程序正常显示。
LRESULT CALLBACK ProcWinMain(   HWND hWnd, 
							 UINT Msg, 
							 WPARAM wParam, 
							 LPARAM lParam 
							 )
{
	PAINTSTRUCT stPs;
	HDC hDC;
	HFONT hFont,hOldFont;
	switch(Msg)
	{
	case WM_PAINT:
		{
			hDC = BeginPaint(hWnd,&stPs);
			hFont = CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,
				CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_SCRIPT,FontName);//产生一种逻辑字体

			hOldFont = (HFONT)SelectObject(hDC,hFont);			//将字体获取的句柄选择进入“设备环境”
			SetTextColor(hDC,RGB(200,200,50));					
			SetBkColor(hDC,RGB(0,0,255));
			TextOut(hDC,0,0,(char *)&keyChar,1);				//绘制出按下键
			if(MouseClick)
			{
				TextOut(hDC,hitPoint.x,hitPoint.y,szCaptionMain,lstrlen(szCaptionMain));
			}
			SelectObject(hDC,hOldFont);							//“绘制”完成后,必须恢复“设备环境”。
			EndPaint(hWnd,&stPs);
		}
		break;
	case WM_KEYDOWN:
		{
		//	MessageBox(hWinMain,"key down","",MB_OK);
		}
		break;
	case WM_KEYUP:
		{
		//	MessageBox(hWinMain,"key UP","",MB_OK);
		}
		break;
	case WM_CHAR:
		{
			keyChar = wParam;									//将按下的键存到keyChar
			fputc(keyChar,fp);									//输出到文件中
			InvalidateRect(hWnd,NULL,TRUE);						//使区域无效,产生WM_PAINT消息,绘制出按下的字符
		}	
		break;
	case WM_LBUTTONDOWN:										//鼠标左键按下
		{
			hitPoint.x = LOWORD(lParam);						//记录下位置
			hitPoint.y = HIWORD(lParam);
			MouseClick = TRUE;
			InvalidateRect(hWnd,NULL,TRUE);						//重绘区域
		}
		break;
	case WM_DESTROY:
		{
			PostQuitMessage(NULL);
		}
		break;

	default:
		return DefWindowProc(hWnd, Msg, wParam, lParam ); 
	}
	return 0;
}

int WINAPI WinMain(     HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow
				   )
{
	MSG stMsg;
	WNDCLASSEX stdWndClass;
	RtlZeroMemory(&stdWndClass, sizeof(stdWndClass));
	stdWndClass.hCursor = LoadCursor(0,IDC_ARROW);
	stdWndClass.cbSize = sizeof(stdWndClass);
	stdWndClass.style = CS_HREDRAW|CS_VREDRAW;
	stdWndClass.lpfnWndProc = ProcWinMain;
	stdWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
	stdWndClass.lpszClassName = szClassName;
	stdWndClass.hInstance = hInstance;

	RegisterClassEx(&stdWndClass);

	hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\
		WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);

	if(!hWinMain)
		return 0;
	fp = fopen(FileName,"w");					//创建一个文件来写入所有按下的键
	if(NULL == fp)
		MessageBox(hWinMain,TEXT("cant't open file!"),TEXT(""),MB_ICONERROR);

	ShowWindow(hWinMain,SW_SHOWNORMAL);
	UpdateWindow(hWinMain);


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

	return stMsg.wParam;
}


 

 

绘制文本:当您想在一个图像输出设备(屏程序幕或者打印机)上绘图时,您首先必须获得一个设备描述表(设备环境 DC)的句柄,将句柄返回给程序的时候,Windows才会给您使用设备的权限,也就是绘制的权限。Windows就会告诉你客户区的大小,字体,颜色等其他GUI(图形用户界面)对象的属性
获取DC句柄的方法:
1.最常用的就是在处理WM_PAINT消息时候调用BegPaint和EndPaint
hDC=BeginPaint(hWnd,&Ps);     
//code
EndPaint(hWnd,&Ps);
//Ps是PAINTSTRUCT的结构,hDC就是获取的设备描述句柄,BeginPaint使得区域有效.这里解释下“无效区域”:windows把最小的需要重绘的正方形区域叫做“无效区域”,一旦出现了无效区域,马上就会产生WM_PAINT消息,要消除无效区域,用BeginPaint或者ValidateRect让无效区有效,这是必须的,不然无效区域的存在就会一直产生WM_PAM_PAINT消息
2.想要在非WM_PAINT获取DC句柄的方法是
hdc = GetDC(hwnd);
//code
ReleaseDC(hwnd,hdc);
然而GetDC不使客户区中的任何可能的无效区域变有效
需要注意的是:必须在一个消息处理里面获取DC并且释放DC,不能在这个消息中获取,而企图在另一个消息中释放。
绘制字符串的要点:
1.必须在开始处和结束处分别调用 BeginPaint 和 EndPaint
2.在 BeginPaint 和 EndPaint 之间调用所有的绘制函数;
3.如果在其它的消息处理(非WM_PAINT)中重新绘制客户区,您可以有两种选择:
(1)用GetDC和ReleaseDC代替BeginPaint和EndPaint;
(2)调用InvalidateRect或UpdateWindow让客户区无效,这将迫使WINDOWS把WM_PAINT放入应用程序消息队列,从而使得客户区重绘。

 

 

键盘消息处理:

WINDOWS将负责把击键消息送到具有输入焦点的那个应用程序中去。尽管屏幕上可能同时有几个应用程序窗口,但一个时刻仅有一个窗口有输入焦点。有输入焦点的那个应用程序的标题条总是高亮度显示的。当您按下一个键时,WINDOWS就会发送一个WM_KEYDOWN给有输入焦点的那个应用程序,提醒它有一个键被按下。当您释放键时,WINDOWS又会发送一个WM_KYEUP消息,告诉有一个键被释放。每当你按下一个键,WINDOWS发送一个WM_CHAR消息给有输入焦点的应用程序。由于MessageBox是阻塞的,再者操作系统处理消息是迅速的,当您按下键的时候弹出一个框,阻塞在那,不能进行下一次输入,我在代码中加的只是用作检验而已。在这个程序代码中,一旦有键按下,调用InvalidateRect使得区域无效,产生WM_PAINT消息重绘,处理绘制的消息里面把按下的键输出来。每次按键都会产生WM_CHAR。

 

 

处理鼠标输入消息
和键盘输入一样,Windows自动捕捉鼠标的动作,左,右键按下,移动,双击,滚轮之类的。但是处理鼠标消息和键盘消息可不一样。鼠标的消息不存在输入焦点这个概念,任何鼠标经过的窗口都会接收到鼠标的消息。比如鼠标的移动消息WM_NCMOVE,当然大多数都输忽略的。对于所有的消息,窗口过程函数传入的参数lParam包含了鼠标的位置,其中底位为x坐标,高位为y坐标,这些坐标值都是相对于窗口客户区的左上角的值,wParam中则包含了鼠标按钮的状态。对于鼠标消息
窗口处理函数传入的参数lParam是一个32位长的数,其中高、底16位分别包括了x、y坐标,现在做一些小处理,两个宏LOWORD和HIWORD拿出高十六位和低十六位。
#define LOWORD(l)           ((WORD)(l))
 #define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
 

就差不多介绍这些,因为里面细节很多,我只是个新手,只能了解到九牛一毛。有什么不足,希望大家指正。(*^__^*)

 

参考资料《Windows程序设计》

       《Windows+sdk编程系列》

你可能感兴趣的:(windows,File,null,callback,FP,winapi)