您的位置:首页 > 其它

win32学习09.系统消息触发的总结

2017-06-08 17:24 183 查看
#include <Windows.h>
#include <iostream>
using namespace std;

/**********************
点击鼠标滑动弹起,取坐标画圆,然后根据键盘上下左右移动圆。
鼠标移动也可以让圆一起动。
鼠标滚轮滑动可以让圆变大小。
***********************/

HINSTANCE g_hInstance = 0; //接收应用程序实例句柄
HANDLE g_hOutput = 0;
int g_xPos = 100,g_yPos = 100;//圆外接矩形左上角坐标
int nD = 100;//diameter直径

BOOL bPaint = FALSE; //为了让防止移动消息对画圆的干扰
//也可以用两次按下鼠标消息确定坐标来避免

//初始化创建
void OnCreate(HWND hwnd)
{
SetTimer(hwnd,1,1000,NULL);
}

//绘制
void OnPaint(HWND hWnd)
{
PAINTSTRUCT ps = {0};
HDC hdc = BeginPaint(hWnd,&ps);
RECT rc = {0};
GetClientRect(hWnd,&rc);
if (bPaint)
{
Ellipse(hdc,g_xPos,g_yPos,g_xPos+nD,g_yPos+nD);
//Sleep(1000); //避免鼠标移动过快看不清
}

EndPaint(hWnd,&ps);
}

//定时器消息
void OnTimer(HWND hWnd,WPARAM wParam)
{
CHAR szText[256] = {0};
sprintf(szText,"定时器触发\n");
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);
}

//鼠标左键按下
void OnLButtonDown(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
LONG xPos = LOWORD(lParam);
LONG yPos = HIWORD(lParam);
CHAR szText[256] = {0};
sprintf(szText,"鼠标左键按下状态:X=%d,Y=%d\n",xPos,yPos);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);

g_xPos = xPos;
g_yPos = yPos;
}

//鼠标左键弹起
void OnLButtonUp(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
LONG xPos = LOWORD(lParam);
LONG yPos = HIWORD(lParam);
CHAR szText[256] = {0};
sprintf(szText,"鼠标左键弹起状态:X=%d,Y=%d\n",xPos,yPos);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);

nD = yPos - g_yPos;
bPaint = TRUE;
InvalidateRect(hWnd,NULL,TRUE);//重绘
}

//鼠标移动
void OnMouseMove(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
LONG xPos = LOWORD(lParam);
LONG yPos = HIWORD(lParam);
CHAR szText[256] = {0};
sprintf(szText,"鼠标移动状态:X=%d,Y=%d\n",xPos,yPos);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);

if (bPaint)
{
g_xPos = xPos - nD/2;
g_yPos = yPos - nD/2;
InvalidateRect(hWnd,NULL,TRUE);
}
}

//鼠标滚轮
void OnMouseWheel(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
short nXPos = LOWORD(lParam);
short nYPos = HIWORD(lParam);
short nDelta = HIWORD(wParam);

POINT ptPos = {nXPos,nYPos};
ScreenToClient(hWnd,&ptPos);
CHAR szText[256] = {0};
sprintf(szText,"鼠标滚轮状态:X=%d(%d),Y=%d(%d),Delta=%d\n",nXPos,ptPos.x,nYPos,ptPos.y,nDelta);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);

nD = nD + (nDelta/120)*2;
InvalidateRect(hWnd,NULL,TRUE);
}

//键盘按下:
void OnKeyDown(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
CHAR szText[256] = {0};
sprintf(szText,"键盘按下:%08X\n",wParam);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);
switch(wParam){
case VK_UP: g_yPos;break;
case VK_DOWN: g_yPos++;break;
case VK_LEFT: g_xPos--;break;
case VK_RIGHT: g_xPos++;break;
}

InvalidateRect(hWnd,NULL,TRUE);//重绘
}

//键盘弹起
void OnKeyUp(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
CHAR szText[256] = {0};
sprintf(szText,"键盘弹起:%08X\n",wParam);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);
}

//可见字符消息
void OnChar(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
char szText[200];
sprintf(szText,"可见字符按下,char is %d\n",wParam);
WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);
}

//注册窗口类
BOOL RegisterWindowClass(
LPSTR lpClassName,
WNDPROC wndproc
)
{
//设计窗口类
WNDCLASS wndcls;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = wndproc;
wndcls.cbClsExtra = 200;//字节为单位,一般为4的倍数,long型数据4字节
wndcls.cbWndExtra = 200;
wndcls.hInstance = g_hInstance;
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor = LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon = LoadIcon(NULL,IDI_ERROR);
wndcls.lpszClassName = lpClassName;
wndcls.lpszMenuName = NULL;
ATOM nAtom = RegisterClass(&wndcls);//注册窗口类
if (nAtom == 0)
{
return FALSE;
}
return TRUE;
}

//窗口过程函数
LRESULT CALLBACK WinSunProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_CREATE:
OnCreate(hwnd);
break;
case WM_LBUTTONDOWN:
OnLButtonDown(hwnd,wParam,lParam);
break;
case WM_LBUTTONUP:
OnLButtonUp(hwnd,wParam,lParam);
break;
case WM_MOUSEMOVE:
OnMouseMove(hwnd,wParam,lParam);
break;
case WM_MOUSEWHEEL:
OnMouseWheel(hwnd,wParam,lParam);
break;
case WM_KEYDOWN:
OnKeyDown(hwnd,wParam,lParam);
break;
case WM_SYSKEYUP:
OnKeyUp(hwnd,wParam,lParam);
break;
case WM_CHAR: //按下字符键
OnChar(hwnd,wParam,lParam);
break;
case WM_PAINT: //重绘
OnPaint(hwnd);
break;
case WM_TIMER:
OnTimer(hwnd,wParam);
break;
case WM_CLOSE://关闭
if(IDYES==MessageBox(hwnd,"Close?","HappyTeemo",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY://销毁
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}

//创建父窗口
HWND CreateFather(LPSTR lpClassName,LPSTR lpWndName)
{
HWND hwnd;
hwnd = CreateWindow(lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,g_hInstance,NULL);
return hwnd;
}

//创建子窗口
HWND CreatChild(LPSTR lpClassName,LPSTR lpWndName,HWND hParent)
{
HWND hwnd;
hwnd = CreateWindow(lpClassName,lpWndName,WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,0,0,100,100,hParent,NULL,g_hInstance,NULL);
return hwnd;
}

//设置额外信息
void SetExtra(HWND hwnd)
{
LPCTSTR str = "hello";
//SetClassLong(hwnd,0,100);
SetClassLong(hwnd,250,(LONG)str); //从250开始放
//窗口类的附加数据缓冲区:是所以基于该类创建的窗口共享的
SetWindowLong(hwnd,0,100);
//窗口自己私有的缓冲区
}

//获取额外信息
void GetExtra(HWND hwnd)
{
LONG nClassExtra = GetClassLong(hwnd,250);//从250开始读
LONG nWndExtra = GetWindowLong(hwnd,0);
char Test[256] = {0};
sprintf(Test,"ClS:%s,Hwnd:%d",(char*)nClassExtra,nWndExtra);
MessageBox(NULL,Test,"Info",MB_OK);
}

//显示窗口欧
void DisplayWindow(HWND hwnd)
{
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
}

//消息循环
void MyMessage()
{
//定义消息结构体,开始消息循环
MSG msg = {0};
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

int  APIENTRY WinMain(
HINSTANCE hInstance,//当前程序的实例句柄,找到本进程的内存
HINSTANCE hPrevInstance,  //前一个实例句柄,已经废弃,一般为NULL
LPSTR lpCmdLine, //命令行参数字符串
int nShowCmd //窗口的显示方式:最大化,最小化,原样。
)
{
AllocConsole();
g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
g_hInstance = hInstance;
LPSTR ClassName = "HappyTeemo";
RegisterWindowClass(ClassName,WinSunProc);

HWND hMwndF = CreateFather(ClassName,"ParentWindow");
//HWND hMwndC1 = CreatChild(ClassName,"ChildWindow1",hMwndF);
//HWND hMwndC2 = CreatChild(ClassName,"ChildWindow2",hMwndF);

//MoveWindow(hMwndC2,310,100,200,200,TRUE); //最后一个参数表示是否删除移动前的窗口

//SetExtra(hMwndC1);
//GetExtra(hMwndC2);//只能读到窗口类的缓冲区,读不到子窗口1的缓冲区

DisplayWindow(hMwndF);
MyMessage();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  win32 鼠标 移动