学习了Windows也有一个星期左右了,刚开始还挺难的,慢慢的就有了感觉,觉得也挺好玩的,那一个个的窗口看着就让人喜欢。好了,废话不多说,下面是一些关于鼠标消息的一些基本操作。代码都是书上的源码,基本上重要的地方我都做了解释说明,大家可以参考一下,
#include<windows.h>
#define MAXPOINTS 1000
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//首先是一个回调函数的声明
int WINAPI WinMain(HINSTANCE hInstance,//应用程序当前实例的句柄
HINSTANCE hPrevInstance,//应用程序先前的实例句柄
PSTR szCmdLine,//指向应用程序命令行的字符串的指针
int iCmdShow)//指明窗口如何显示
{
static TCHAR szAppName[]=TEXT("Connect");//
HWND hwnd;//当前实例的句柄
MSG msg;//消息
WNDCLASS wndclass;//类名
wndclass.style=CS_HREDRAW | CS_VREDRAW;//窗口的显示方式,此处为水平重画和竖直重画
wndclass.cbClsExtra=0;//窗口扩展,此处为0
wndclass.cbWndExtra=0;//窗口实例扩展,此处为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;//窗口菜单,此处没菜单设为NULL
//注册窗口,若注册失败,产生如下的信息
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("Program requires Windows NT!"),
szAppName,MB_ICONERROR);
return 0;
}
//创建窗口,如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。
hwnd=CreateWindow(szAppName,//
TEXT("Connect-the-Points Mouse Demo"),//窗口的名字
WS_OVERLAPPEDWINDOW,//指定创建窗口的风格
CW_USEDEFAULT,//指定窗口的初始水平位置,如果该参数被设为CW_USEDEFAULT则系统为窗口选择缺省的左上角坐标并忽略Y参数。
CW_USEDEFAULT,//指定窗口的初始垂直位置
CW_USEDEFAULT,//以设备单元指明窗口的宽度。若是CW_USEDEFAULT,则系统为窗口选择一个缺省的宽度
CW_USEDEFAULT,//以设备单元指明窗口的高度。若被设为CW_USEDEFAULT,则系统忽略nHeight参数。
NULL,//指向被创建窗口的父窗口或所有者窗口的句柄,此处为NULL
NULL,//菜单句柄,或依据窗口风格指明一个子窗口标识,此处为NULL
hInstance,//与窗口相关联的模块实例的句柄。
NULL);//指向一个值的指针,该值传递给窗口WM_CREATE消息。
ShowWindow(hwnd,iCmdShow);//显示窗口,hWnd:指窗口句柄。iCmdShow:指定窗口如何显示。
UpdateWindow(hwnd);//更新窗口,hWnd:指窗口句柄。
while(GetMessage(&msg,NULL,0,0))//消息循环
{
TranslateMessage(&msg);//该函数将虚拟键消息转换为字符消息
DispatchMessage(&msg);//该函数分发一个消息给窗口程序。
}
return msg.wParam;//wParam是消息携带的参数,可以是个值,也可以是个地址
}
//回调函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
static POINT pt[MAXPOINTS];//点的结构体
static int iCount;//当前鼠标点的个数
HDC hdc;//句柄
int i,j;
PAINTSTRUCT ps;//包含窗口需要绘制的信息
switch(message)
{
case WM_LBUTTONDOWN://鼠标左击
iCount=0;
//该函数向指定的窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制。
//hwnd:要更新的客户区所在的窗体的句柄。
//第二个参数是无效区域的矩形代表,它是一个结构体指针,存放着矩形的大小。如果为NULL,全部的窗口客户区域将被增加到更新区域中。
//第三个参数的作用为指出无效矩形被标记为有效后,是否重画该区域,重画时用预先定义好的画刷。当指定TRUE时需要重画。
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_MOUSEMOVE://鼠标移动
if(wParam & MK_LBUTTON && iCount<1000)//判断是否为左击并且当前鼠标点数小于1000
{
pt[iCount].x=LOWORD(lParam);//获取鼠标的坐标保存到点结构体中
pt[iCount++].y=HIWORD(lParam);
hdc=GetDC(hwnd);//获取环境句柄
//该函数将指定坐标处的像素设为指定的颜色。
//第一个参数为设备环境句柄。
//第二个第三个参数分别为点在屏幕上的横纵坐标
//第四个参数指定要用来绘制该点的颜色
SetPixel(hdc,LOWORD(lParam),HIWORD(lParam),0);
ReleaseDC(hwnd,hdc);//释放环境句柄
}
return 0;
case WM_LBUTTONUP:
InvalidateRect(hwnd,NULL,FALSE);//参考上面的解释
return 0;
case WM_PAINT:
//BeginPaint函数为指定窗口进行绘图工作的准备,并用将和绘图有关的信息填充到一个PAINTSTRUCT结构中。(即ps中)
hdc = BeginPaint (hwnd, &ps) ;
SetCursor (LoadCursor (NULL, IDC_WAIT)) ;//该函数确定光标的形状
ShowCursor (TRUE) ;//该函数显示或隐藏光标
for(i = 0 ; i < iCount - 1 ; i++)//运用for循环,使得建立的点都和除了本身之外的点连线
for(j = i + 1 ; j < iCount ; j++)
{
MoveToEx (hdc, pt[i].x, pt[i].y , NULL) ;
LineTo (hdc, pt[j].x, pt[j].y) ;
}
ShowCursor (FALSE);//该函数显示或隐藏光标
SetCursor (LoadCursor (NULL, IDC_ARROW)) ;//该函数确定光标的形状
EndPaint (hwnd, &ps) ;//释放句柄
return 0 ;
case WM_DESTROY:
PostQuitMessage(0);//该函数向系统表明有个线程有终止请求。通常用来响应WM_DESTROY消息。
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);//该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理。
}
上面的解释大部分都是我从百度或者是MSDN上查来的,大家如果觉得那句解释不太懂,或者不太准确就联系我。大家一起进步!最后上传一个程序运行图片记录一下自己的学习历程