QQ登录

只需一步,快速开始

登录 | 立即注册 | 找回密码

主题

帖子

荣誉

VIP至尊会员

Rank: 15Rank: 15Rank: 15

积分
135
查看: 726|回复: 1

[学习笔记] win32编程(003)——绘图消息,键鼠消息,定时器消息和菜单的使用

[复制链接]
最佳答案
0 
累计签到:83 天
连续签到:3 天
zzxwbs 发表于 2017-6-15 21:53:49 7261 | 显示全部楼层 |阅读模式

马上注册加入鱼C,享用更多服务吧^_^

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 zzxwbs 于 2017-6-18 00:44 编辑

1.绘图消息WM_PAINT
当窗口需要绘制的时候,会发送窗口处理函数。

  1. #include "stdafx.h"

  2. HANDLE g_hOutout = 0;
  3. void OnPaint(HWND hWnd)
  4. {
  5.         char *pszText = "WM_PAINT\n";
  6.         WriteConsole(g_hOutout,pszText,strlen(pszText),NULL,NULL);
  7. }

  8. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  9. {
  10.         switch (msgID)
  11.         {
  12.         case WM_PAINT:
  13.                 OnPaint(hWnd);
  14.                 break;
  15.         case WM_DESTROY:
  16.                 PostQuitMessage(0);
  17.                 break;
  18.         default:
  19.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  20.         }
  21.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  22. }

  23. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  24. {
  25.         AllocConsole();//创建一个控制台
  26.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  27.         WNDCLASSEX wc = { 0 };
  28.         wc.cbSize = sizeof(wc);
  29.         wc.hIconSm = NULL;
  30.         wc.cbClsExtra = 0;
  31.         wc.cbWndExtra = 0;
  32.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  33.         wc.hCursor = NULL;
  34.         wc.hIcon = NULL;
  35.         wc.hInstance = hInstance;
  36.         wc.lpfnWndProc = WndProc;
  37.         wc.lpszClassName = "fishc";
  38.         wc.lpszMenuName = NULL;
  39.         wc.style = CS_HREDRAW | CS_VREDRAW;
  40.         RegisterClassEx(&wc);
  41.         char *pszText = "fishc";
  42.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  43.         ShowWindow(hWnd,SW_SHOW);
  44.         UpdateWindow(hWnd);
  45.         MSG nMsg= { 0 };
  46.         while (GetMessage(&nMsg, NULL, 0, 0))
  47.         {
  48.                 TranslateMessage(&nMsg);
  49.                 DispatchMessage(&nMsg);
  50.         }
  51.         return 0;
  52. }
复制代码


1.1InvalidateRect函数
在程序中,如果需要绘制窗口,调用函数声明窗口无效区域。向指定的窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制。
窗口无效区域:被声明成需要重新绘制的区域。

  1. BOOL InvalidateRect(
  2. HWND hWnd,  //窗口句柄
  3. CONST RECT* lpRect,  //区域的矩形坐标
  4. BOOL bErase  //重绘前是否先擦除
  5. );
复制代码

  1. #include "stdafx.h"

  2. HANDLE g_hOutout = 0;
  3. void OnPaint(HWND hWnd)
  4. {
  5.         char *pszText = "WM_PAINT\n";
  6.         WriteConsole(g_hOutout,pszText,strlen(pszText),NULL,NULL);
  7. }

  8. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  9. {
  10.         switch (msgID)
  11.         {
  12.         case WM_LBUTTONDOWN://鼠标左点击
  13.                 InvalidateRect(hWnd,NULL,TRUE);//将窗口声明为需要重绘
  14.                 break;
  15.         case WM_PAINT:
  16.                 OnPaint(hWnd);
  17.                 break;
  18.         case WM_DESTROY:
  19.                 PostQuitMessage(0);
  20.                 break;
  21.         default:
  22.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  23.         }
  24.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  25. }

  26. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  27. {
  28.         AllocConsole();//创建一个控制台
  29.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  30.         WNDCLASSEX wc = { 0 };
  31.         wc.cbSize = sizeof(wc);
  32.         wc.hIconSm = NULL;
  33.         wc.cbClsExtra = 0;
  34.         wc.cbWndExtra = 0;
  35.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  36.         wc.hCursor = NULL;
  37.         wc.hIcon = NULL;
  38.         wc.hInstance = hInstance;
  39.         wc.lpfnWndProc = WndProc;
  40.         wc.lpszClassName = "fishc";
  41.         wc.lpszMenuName = NULL;
  42.         wc.style = CS_HREDRAW | CS_VREDRAW;
  43.         RegisterClassEx(&wc);
  44.         char *pszText = "fishc";
  45.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  46.         ShowWindow(hWnd,SW_SHOW);
  47.         UpdateWindow(hWnd);
  48.         MSG nMsg= { 0 };
  49.         while (GetMessage(&nMsg, NULL, 0, 0))
  50.         {
  51.                 TranslateMessage(&nMsg);
  52.                 DispatchMessage(&nMsg);
  53.         }
  54.         return 0;
  55. }
复制代码


1.2绘图编程(今天只做简单介绍)
画图的几个步骤
消息处理步骤
1.2.1开始绘图处理
  1. HDC BeginPaint(
  2.         HWND hwnd, //绘图窗口
  3.         LPPAINTSTRUCT lpPaint //绘图参数的BUFF
  4. ); 返回绘图设备句柄HDC
复制代码

1.2.2绘图
1.2.3结束绘图处理
  1. BOOL EndPaint(
  2.         HWND hWnd, //绘图窗口
  3.         CONST PAINTSTRUCT *lpPaint  //绘图参数的指针BeginPaint返回
  4. );
复制代码

  1. #include "stdafx.h"

  2. HANDLE g_hOutout = 0;
  3. void OnPaint(HWND hWnd)
  4. {
  5.         char *pszText = "WM_PAINT\n";
  6.         WriteConsole(g_hOutout,pszText,strlen(pszText),NULL,NULL);
  7.         PAINTSTRUCT ps = {0};
  8.         HDC hdc = BeginPaint(hWnd,&ps);
  9.         TextOut(hdc,100,100,"fishc",5);
  10.         EndPaint(hWnd,&ps);
  11.         //以上绘图的代码必须放在WM_PAINT消息处理中调用
  12. }

  13. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  14. {
  15.         switch (msgID)
  16.         {
  17.         case WM_LBUTTONDOWN://鼠标左点击
  18.                 InvalidateRect(hWnd,NULL,TRUE);//将窗口声明为需要重绘
  19.                 break;
  20.         case WM_PAINT:
  21.                 OnPaint(hWnd);
  22.                 break;
  23.         case WM_DESTROY:
  24.                 PostQuitMessage(0);
  25.                 break;
  26.         default:
  27.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  28.         }
  29.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  30. }

  31. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  32. {
  33.         AllocConsole();//创建一个控制台
  34.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  35.         WNDCLASSEX wc = { 0 };
  36.         wc.cbSize = sizeof(wc);
  37.         wc.hIconSm = NULL;
  38.         wc.cbClsExtra = 0;
  39.         wc.cbWndExtra = 0;
  40.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  41.         wc.hCursor = NULL;
  42.         wc.hIcon = NULL;
  43.         wc.hInstance = hInstance;
  44.         wc.lpfnWndProc = WndProc;
  45.         wc.lpszClassName = "fishc";
  46.         wc.lpszMenuName = NULL;
  47.         wc.style = CS_HREDRAW | CS_VREDRAW;
  48.         RegisterClassEx(&wc);
  49.         char *pszText = "fishc";
  50.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  51.         ShowWindow(hWnd,SW_SHOW);
  52.         UpdateWindow(hWnd);
  53.         MSG nMsg= { 0 };
  54.         while (GetMessage(&nMsg, NULL, 0, 0))
  55.         {
  56.                 TranslateMessage(&nMsg);
  57.                 DispatchMessage(&nMsg);
  58.         }
  59.         return 0;
  60. }
复制代码


2.键盘消息
2.1键盘消息
  1.         WM_KEYDOWN - 按键被按下时产生
  2.         WM_KEYUP - 按键被放开时产生
  3.         WM_SYSKEYDOWN - 系统键按下时产生  比如ALT、F10
  4.         WM_SYSKEYUP - 系统键放开时产生
  5.         WM_CHAR - 字符消息
复制代码

2.2消息参数
2.2.1按键消息:
WPARAM - 按键的Virtual Key(虚拟键码),无法区分大小写
LPARAM - 按键的参数,例如按下次数                       

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;

  4. void OnPaint(HWND hWnd)
  5. {
  6.         char *pszText = "WM_PAINT\n";
  7.         WriteConsole(g_hOutout,pszText,strlen(pszText),NULL,NULL);
  8.         PAINTSTRUCT ps = {0};
  9.         HDC hdc = BeginPaint(hWnd,&ps);
  10.         TextOut(hdc,100,100,"fishc",5);
  11.         EndPaint(hWnd,&ps);
  12.         //以上绘图的代码必须放在WM_PAINT消息处理中调用
  13. }

  14. void OnKeyDown( HWND hWnd, WPARAM wParam )
  15. {
  16.         char szText[256] = { 0 };
  17.         sprintf( szText, "WM_KEYDOWN:%08X\n", wParam );
  18.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,
  19.                 NULL );
  20. }

  21. void OnKeyUp( HWND hWnd, WPARAM wParam )
  22. {
  23.         char szText[256] = { 0 };
  24.         sprintf( szText, "WM_KEYUP:%08X\n", wParam );
  25.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,
  26.                 NULL );
  27. }

  28. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  29. {
  30.         switch (msgID)
  31.         {
  32.         case WM_KEYDOWN:
  33.                 OnKeyDown( hWnd, wParam );
  34.                 break;
  35.         case WM_KEYUP:
  36.                 OnKeyUp( hWnd, wParam );
  37.                 break;
  38.         case WM_LBUTTONDOWN://鼠标左点击
  39.                 InvalidateRect(hWnd,NULL,TRUE);//将窗口声明为需要重绘
  40.                 break;
  41.         case WM_PAINT:
  42.                 OnPaint(hWnd);
  43.                 break;
  44.         case WM_DESTROY:
  45.                 PostQuitMessage(0);
  46.                 break;
  47.         default:
  48.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  49.         }
  50.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  51. }

  52. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  53. {
  54.         AllocConsole();//创建一个控制台
  55.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  56.         WNDCLASSEX wc = { 0 };
  57.         wc.cbSize = sizeof(wc);
  58.         wc.hIconSm = NULL;
  59.         wc.cbClsExtra = 0;
  60.         wc.cbWndExtra = 0;
  61.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  62.         wc.hCursor = NULL;
  63.         wc.hIcon = NULL;
  64.         wc.hInstance = hInstance;
  65.         wc.lpfnWndProc = WndProc;
  66.         wc.lpszClassName = "fishc";
  67.         wc.lpszMenuName = NULL;
  68.         wc.style = CS_HREDRAW | CS_VREDRAW;
  69.         RegisterClassEx(&wc);
  70.         char *pszText = "fishc";
  71.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  72.         ShowWindow(hWnd,SW_SHOW);
  73.         UpdateWindow(hWnd);
  74.         MSG nMsg= { 0 };
  75.         while (GetMessage(&nMsg, NULL, 0, 0))
  76.         {
  77.                 TranslateMessage(&nMsg);
  78.                 DispatchMessage(&nMsg);
  79.         }
  80.         return 0;
  81. }
复制代码


用上下左右键控制fishc的位置
  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_xPos = 100;
  5. int g_yPos = 100;
  6. void OnPaint(HWND hWnd)
  7. {
  8.         char *pszText = "WM_PAINT\n";
  9.         WriteConsole(g_hOutout,pszText,strlen(pszText),NULL,NULL);
  10.         PAINTSTRUCT ps = {0};
  11.         HDC hdc = BeginPaint(hWnd,&ps);
  12.         TextOut(hdc,g_xPos,g_yPos,"fishc",5);
  13.         EndPaint(hWnd,&ps);
  14.         //以上绘图的代码必须放在WM_PAINT消息处理中调用
  15. }

  16. void OnKeyDown( HWND hWnd, WPARAM wParam )
  17. {
  18.         char szText[256] = { 0 };
  19.         sprintf( szText, "WM_KEYDOWN:%08X\n", wParam );
  20.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,
  21.                 NULL );
  22.         switch(wParam)
  23.         {
  24.         case VK_UP:
  25.                 g_yPos--;
  26.                 break;
  27.         case VK_DOWN:
  28.                 g_yPos++;
  29.                 break;
  30.         case VK_LEFT:
  31.                 g_xPos--;
  32.                 break;
  33.         case VK_RIGHT:
  34.                 g_xPos++;
  35.                 break;
  36.         }
  37.         InvalidateRect(hWnd,NULL,TRUE);
  38. }

  39. void OnKeyUp( HWND hWnd, WPARAM wParam )
  40. {
  41.         char szText[256] = { 0 };
  42.         sprintf( szText, "WM_KEYUP:%08X\n", wParam );
  43.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,
  44.                 NULL );
  45. }

  46. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  47. {
  48.         switch (msgID)
  49.         {
  50.         case WM_KEYDOWN:
  51.                 OnKeyDown( hWnd, wParam );
  52.                 break;
  53.         case WM_KEYUP:
  54.                 OnKeyUp( hWnd, wParam );
  55.                 break;
  56.         case WM_LBUTTONDOWN://鼠标左点击
  57.                 InvalidateRect(hWnd,NULL,TRUE);//将窗口声明为需要重绘
  58.                 break;
  59.         case WM_PAINT:
  60.                 OnPaint(hWnd);
  61.                 break;
  62.         case WM_DESTROY:
  63.                 PostQuitMessage(0);
  64.                 break;
  65.         default:
  66.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  67.         }
  68.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  69. }

  70. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  71. {
  72.         AllocConsole();//创建一个控制台
  73.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  74.         WNDCLASSEX wc = { 0 };
  75.         wc.cbSize = sizeof(wc);
  76.         wc.hIconSm = NULL;
  77.         wc.cbClsExtra = 0;
  78.         wc.cbWndExtra = 0;
  79.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  80.         wc.hCursor = NULL;
  81.         wc.hIcon = NULL;
  82.         wc.hInstance = hInstance;
  83.         wc.lpfnWndProc = WndProc;
  84.         wc.lpszClassName = "fishc";
  85.         wc.lpszMenuName = NULL;
  86.         wc.style = CS_HREDRAW | CS_VREDRAW;
  87.         RegisterClassEx(&wc);
  88.         char *pszText = "fishc";
  89.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  90.         ShowWindow(hWnd,SW_SHOW);
  91.         UpdateWindow(hWnd);
  92.         MSG nMsg= { 0 };
  93.         while (GetMessage(&nMsg, NULL, 0, 0))
  94.         {
  95.                 TranslateMessage(&nMsg);
  96.                 DispatchMessage(&nMsg);
  97.         }
  98.         return 0;
  99. }
复制代码


2.2.2WM_CHAR消息:
WPARAM - 输入的字符(ASC字符编码),可以区分大小写
LPARAM - 按键的相关参数

2.3消息的使用总结
2.3.1KEYDOWN可以重复出现,KEYUP只能在按键松开时出现1次
2.3.2TranslateMessage在转换WM_KEYDOWN消息时,对于可见字符可以产生WM_CHAR,不可见字符无此消息。
2.3.3WM_KEYDOWN/UP的wParam是表示的按键,WM_CHAR是表示输入的字符。

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_xPos = 100;
  5. int g_yPos = 100;
  6. void OnPaint(HWND hWnd)
  7. {
  8.         char *pszText = "WM_PAINT\n";
  9.         WriteConsole(g_hOutout,pszText,strlen(pszText),NULL,NULL);
  10.         PAINTSTRUCT ps = {0};
  11.         HDC hdc = BeginPaint(hWnd,&ps);
  12.         TextOut(hdc,g_xPos,g_yPos,"fishc",5);
  13.         EndPaint(hWnd,&ps);
  14.         //以上绘图的代码必须放在WM_PAINT消息处理中调用
  15. }

  16. void OnKeyDown( HWND hWnd, WPARAM wParam )
  17. {
  18.         char szText[256] = { 0 };
  19.         sprintf( szText, "WM_KEYDOWN:%08X\n", wParam );
  20.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,
  21.                 NULL );
  22. }

  23. void OnKeyUp( HWND hWnd, WPARAM wParam )
  24. {
  25.         char szText[256] = { 0 };
  26.         sprintf( szText, "WM_KEYUP:%08X\n", wParam );
  27.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,
  28.                 NULL );
  29. }
  30. void OnChar(HWND hWnd,WPARAM wParam)
  31. {
  32.         char szText[256] = {0};
  33.         sprintf(szText,"WM_CHAR:0x%08X\n",wParam);
  34.         WriteConsole( g_hOutout, szText, strlen(szText), NULL,NULL );
  35. }

  36. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  37. {
  38.         switch (msgID)
  39.         {
  40.         case WM_CHAR:
  41.                 OnChar(hWnd,wParam);
  42.                 break;
  43.         case WM_KEYDOWN:
  44.                 OnKeyDown( hWnd, wParam );
  45.                 break;
  46.         case WM_KEYUP:
  47.                 OnKeyUp( hWnd, wParam );
  48.                 break;
  49.         case WM_LBUTTONDOWN://鼠标左点击
  50.                 InvalidateRect(hWnd,NULL,TRUE);//将窗口声明为需要重绘
  51.                 break;
  52.         case WM_PAINT:
  53.                 OnPaint(hWnd);
  54.                 break;
  55.         case WM_DESTROY:
  56.                 PostQuitMessage(0);
  57.                 break;
  58.         default:
  59.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  60.         }
  61.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  62. }

  63. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  64. {
  65.         AllocConsole();//创建一个控制台
  66.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  67.         WNDCLASSEX wc = { 0 };
  68.         wc.cbSize = sizeof(wc);
  69.         wc.hIconSm = NULL;
  70.         wc.cbClsExtra = 0;
  71.         wc.cbWndExtra = 0;
  72.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  73.         wc.hCursor = NULL;
  74.         wc.hIcon = NULL;
  75.         wc.hInstance = hInstance;
  76.         wc.lpfnWndProc = WndProc;
  77.         wc.lpszClassName = "fishc";
  78.         wc.lpszMenuName = NULL;
  79.         wc.style = CS_HREDRAW | CS_VREDRAW;
  80.         RegisterClassEx(&wc);
  81.         char *pszText = "fishc";
  82.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  83.         ShowWindow(hWnd,SW_SHOW);
  84.         UpdateWindow(hWnd);
  85.         MSG nMsg= { 0 };
  86.         while (GetMessage(&nMsg, NULL, 0, 0))
  87.         {
  88.                 TranslateMessage(&nMsg);//处理大小写
  89.                 DispatchMessage(&nMsg);
  90.         }
  91.         return 0;
  92. }
复制代码


3.鼠标消息

3.1 基本鼠标消息
WM_LBUTTONDOWN - 鼠标左键按下
WM_LBUTTONUP - 鼠标左键抬起
WM_RBUTTONDOWN - 鼠标右键按下
WM_RBUTTONUP - 鼠标右键抬起
WM_MOUSEMOVE - 鼠标移动消息
3.2 双击消息
WM_LBUTTONDBLCLK - 鼠标左键双击
WM_RBUTTONDBLCLK - 鼠标右键双击
3.3 滚轮消息
WM_MOUSEWHEEL - 鼠标滚轮消息

3.4鼠标消息总结

3.4.1基本鼠标消息
3.4.1.1消息参数
WPARAM - 其他按键的状态,例如Ctrl/Shift等
LPARAM - 鼠标的位置,窗口客户区坐标系。
LOWORD X坐标位置
HIWORD Y坐标位置
3.4.1.2鼠标消息使用
一般情况鼠标按下/抬起成对出现。在鼠标移动过程中,会根据移动速度产生一系列的WM_MOUSEMOVE消息。

3.4.2双击鼠标消息
3.4.2.1消息参数
WPARAM - 其他按键的状态,例如Ctrl/Shift等
LPARAM - 鼠标的位置,窗口客户区坐标系。
LOWORD X坐标位置
HIWORD Y坐标位置
3.4.2.2使用时需要在注册窗口类的时候添加CS_DBLCLKS 风格。
3.4.2.3消息产生顺序
以WM_LBUTTONDBLCLK为例:
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
WM_LBUTTONUP

3.4.3鼠标滚轮 WM_MOUSEWHEEL
3.4.3.1消息参数
WPARAM:
        LOWORD - 其他按键的状态
        HIWORD - 滚轮的偏移量,是120的倍数,通过正负值表示表示滚动方向。
        正:向前滚动
        负:向后滚动
LPARAM:鼠标当前的位置,【屏幕】坐标系
        LOWORD - X坐标
        HIWORD - Y坐标
3.4.3.2使用:通过偏移量,获取滚动的方向和倍数。

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;

  4. void OnLButtonDown(HWND hWnd,WPARAM wParam,LPARAM lParam)
  5. {
  6.         char szText[256] = {0};
  7.         sprintf(szText,"WM_LBUTTONDOWN:按键状态=%08X,X=%d,Y=%d\n",wParam,LOWORD(lParam),HIWORD(lParam));
  8.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  9. }
  10. void OnLButtonUp(HWND hWnd,WPARAM wParam,LPARAM lParam)
  11. {
  12.         char szText[256] = {0};
  13.         sprintf(szText,"WM_LBUTTONUP:按键状态=%08X,X=%d,Y=%d\n",wParam,LOWORD(lParam),HIWORD(lParam));
  14.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  15. }

  16. void OnMouseMove(HWND hWnd,WPARAM wParam,LPARAM lParam)
  17. {
  18.         char szText[256] = {0};
  19.         sprintf(szText,"WM_MOUSEMOVE:x=%d,y=%d\n",LOWORD(lParam),HIWORD(lParam));
  20.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  21. }

  22. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  23. {
  24.         switch (msgID)
  25.         {
  26.         case WM_MOUSEMOVE:
  27.                 OnMouseMove(hWnd,wParam,lParam);
  28.                 break;
  29.         case WM_LBUTTONDOWN:
  30.                 OnLButtonDown(hWnd,wParam,lParam);
  31.                 break;
  32.         case WM_LBUTTONUP:
  33.                 OnLButtonUp(hWnd,wParam,lParam);
  34.                 break;
  35.         case WM_DESTROY:
  36.                 PostQuitMessage(0);
  37.                 break;
  38.         default:
  39.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  40.         }
  41.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  42. }

  43. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  44. {
  45.         AllocConsole();//创建一个控制台
  46.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  47.         WNDCLASSEX wc = { 0 };
  48.         wc.cbSize = sizeof(wc);
  49.         wc.hIconSm = NULL;
  50.         wc.cbClsExtra = 0;
  51.         wc.cbWndExtra = 0;
  52.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  53.         wc.hCursor = NULL;
  54.         wc.hIcon = NULL;
  55.         wc.hInstance = hInstance;
  56.         wc.lpfnWndProc = WndProc;
  57.         wc.lpszClassName = "fishc";
  58.         wc.lpszMenuName = NULL;
  59.         wc.style = CS_HREDRAW | CS_VREDRAW;
  60.         RegisterClassEx(&wc);
  61.         char *pszText = "fishc";
  62.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  63.         ShowWindow(hWnd,SW_SHOW);
  64.         UpdateWindow(hWnd);
  65.         MSG nMsg= { 0 };
  66.         while (GetMessage(&nMsg, NULL, 0, 0))
  67.         {
  68.                 TranslateMessage(&nMsg);
  69.                 DispatchMessage(&nMsg);
  70.         }
  71.         return 0;
  72. }
复制代码


fishc跟着鼠标移动而移动
  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_xPos = 100;
  5. int g_yPos = 100;

  6. void OnMouseMove(HWND hWnd,WPARAM wParam,LPARAM lParam)
  7. {
  8.         g_xPos = LOWORD(lParam);
  9.         g_yPos = HIWORD(lParam);
  10.         InvalidateRect(hWnd,NULL,TRUE);
  11. }

  12. void OnPaint(HWND hWnd)
  13. {
  14.         PAINTSTRUCT ps = {0};
  15.         HDC hdc = BeginPaint(hWnd,&ps);
  16.         TextOut(hdc,g_xPos,g_yPos,"fishc",5);
  17.         EndPaint(hWnd,&ps);
  18. }

  19. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  20. {
  21.         switch (msgID)
  22.         {
  23.         case WM_PAINT:
  24.                 OnPaint(hWnd);
  25.                 break;
  26.         case WM_MOUSEMOVE:
  27.                 OnMouseMove(hWnd,wParam,lParam);
  28.                 break;
  29.         case WM_DESTROY:
  30.                 PostQuitMessage(0);
  31.                 break;
  32.         default:
  33.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  34.         }
  35.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  36. }

  37. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  38. {
  39.         AllocConsole();//创建一个控制台
  40.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  41.         WNDCLASSEX wc = { 0 };
  42.         wc.cbSize = sizeof(wc);
  43.         wc.hIconSm = NULL;
  44.         wc.cbClsExtra = 0;
  45.         wc.cbWndExtra = 0;
  46.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  47.         wc.hCursor = NULL;
  48.         wc.hIcon = NULL;
  49.         wc.hInstance = hInstance;
  50.         wc.lpfnWndProc = WndProc;
  51.         wc.lpszClassName = "fishc";
  52.         wc.lpszMenuName = NULL;
  53.         wc.style = CS_HREDRAW | CS_VREDRAW;
  54.         RegisterClassEx(&wc);
  55.         char *pszText = "fishc";
  56.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  57.         ShowWindow(hWnd,SW_SHOW);
  58.         UpdateWindow(hWnd);
  59.         MSG nMsg= { 0 };
  60.         while (GetMessage(&nMsg, NULL, 0, 0))
  61.         {
  62.                 TranslateMessage(&nMsg);
  63.                 DispatchMessage(&nMsg);
  64.         }
  65.         return 0;
  66. }
复制代码

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;

  4. void OnMouseWheel(HWND hWnd,WPARAM wParam,LPARAM lParam)
  5. {
  6.         short nDelta = HIWORD(wParam);//偏移量
  7.         char szText[256] = {0};
  8.         sprintf(szText,"偏移量=%d\n,x=%d,y=%d\n",nDelta,LOWORD(lParam),HIWORD(lParam));
  9.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  10. }

  11. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  12. {
  13.         switch (msgID)
  14.         {
  15.         case WM_MOUSEWHEEL:
  16.                 OnMouseWheel(hWnd,wParam,lParam);
  17.                 break;
  18.         case WM_DESTROY:
  19.                 PostQuitMessage(0);
  20.                 break;
  21.         default:
  22.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  23.         }
  24.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  25. }

  26. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  27. {
  28.         AllocConsole();//创建一个控制台
  29.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  30.         WNDCLASSEX wc = { 0 };
  31.         wc.cbSize = sizeof(wc);
  32.         wc.hIconSm = NULL;
  33.         wc.cbClsExtra = 0;
  34.         wc.cbWndExtra = 0;
  35.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  36.         wc.hCursor = NULL;
  37.         wc.hIcon = NULL;
  38.         wc.hInstance = hInstance;
  39.         wc.lpfnWndProc = WndProc;
  40.         wc.lpszClassName = "fishc";
  41.         wc.lpszMenuName = NULL;
  42.         wc.style = CS_HREDRAW | CS_VREDRAW;
  43.         RegisterClassEx(&wc);
  44.         char *pszText = "fishc";
  45.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  46.         ShowWindow(hWnd,SW_SHOW);
  47.         UpdateWindow(hWnd);
  48.         MSG nMsg= { 0 };
  49.         while (GetMessage(&nMsg, NULL, 0, 0))
  50.         {
  51.                 TranslateMessage(&nMsg);
  52.                 DispatchMessage(&nMsg);
  53.         }
  54.         return 0;
  55. }
复制代码


4.定时器消息
可以在程序中设置定时器,当到达时间间隔时,定时器会向程序发送一个WM_TIMER消息。
定时器的精度是毫秒,但是准确度很低。例如设置时间间隔为1000ms,但是会在非1000毫秒到达。

4.1消息的参数
WPARAM - 定时器ID
LPARAM - 定时器处理函数的指针

4.2定时器使用
4.2.1 创建定时器
  1. UINT_PTR SetTimer(
  2. HWND hWnd,//定时器窗口句柄
  3. UINT_PTR nIDEvent, //定时器ID
  4. UINT uElapse,//时间间隔
  5. TIMERPROC lpTimerFunc //定时器处理函数指针
  6. );创建成功,返回非0。
复制代码

使用窗口处理函数,做为定时器处理函数,lpTimerFunc为NULL
使用定时器处理函数处理定时器消息。

4.2.2 消息处理  WM_TIMER
4.2.3 关闭定时器
  1. BOOL KillTimer(
  2.         HWND hWnd,//定时器窗口句柄
  3.         UINT_PTR uIDEvent //定时器ID
  4. );
复制代码

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;

  4. void OnTimer(HWND hWnd,WPARAM wParam)
  5. {
  6.         char szText[256] = {0};
  7.         sprintf(szText,"定时器:%d\n",wParam);
  8.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  9. }

  10. //自定义(定时器处理函数)处理WM_TIMER消息
  11. VOID CALLBACK TimerProc(HWND hWnd,UINT msgID,UINT timeID,DWORD dwTimer)
  12. {
  13.         char szText[256] = {0};
  14.         sprintf(szText,"定时器处理函数处理:%d\n",timeID);
  15.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  16. }


  17. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  18. {
  19.         switch (msgID)
  20.         {
  21.         case WM_LBUTTONDOWN:
  22.                 KillTimer(hWnd,1);//鼠标左键关闭定时器1
  23.                 break;
  24.         case WM_TIMER:
  25.                 OnTimer(hWnd,wParam);
  26.                 break;
  27.         case WM_CREATE:
  28.                 SetTimer(hWnd,1,1000,NULL);
  29.                 SetTimer(hWnd,2,2000,TimerProc);
  30.                 break;
  31.         case WM_DESTROY:
  32.                 PostQuitMessage(0);
  33.                 break;
  34.         default:
  35.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  36.         }
  37.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  38. }

  39. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  40. {
  41.         AllocConsole();//创建一个控制台
  42.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  43.         WNDCLASSEX wc = { 0 };
  44.         wc.cbSize = sizeof(wc);
  45.         wc.hIconSm = NULL;
  46.         wc.cbClsExtra = 0;
  47.         wc.cbWndExtra = 0;
  48.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  49.         wc.hCursor = NULL;
  50.         wc.hIcon = NULL;
  51.         wc.hInstance = hInstance;
  52.         wc.lpfnWndProc = WndProc;
  53.         wc.lpszClassName = "fishc";
  54.         wc.lpszMenuName = NULL;
  55.         wc.style = CS_HREDRAW | CS_VREDRAW;
  56.         RegisterClassEx(&wc);
  57.         char *pszText = "fishc";
  58.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  59.         ShowWindow(hWnd,SW_SHOW);
  60.         UpdateWindow(hWnd);
  61.         MSG nMsg= { 0 };
  62.         while (GetMessage(&nMsg, NULL, 0, 0))
  63.         {
  64.                 TranslateMessage(&nMsg);
  65.                 DispatchMessage(&nMsg);
  66.         }
  67.         return 0;
  68. }
复制代码



5.菜单的使用
5.1菜单的分类
5.1.1 窗口的顶层菜单
5.1.2 弹出式菜单(鼠标右键,下拉菜单)
5.1.3 系统菜单(标题栏右键)
HMENU类型表示菜单,菜单每一项有相应的ID。

5.2窗口的顶层菜单
5.2.1创建菜单  
  1. HMENU CreateMenu(VOID); //创建成功返回菜单句柄
  2. 增加菜单项
  3. BOOL [url=https://msdn.microsoft.com/EN-US/library/windows/desktop/ms647616(v=vs.85).aspx]AppendMenu[/url](
  4.         HMENU hMenu, //菜单句柄
  5.         UINT uFlags, //菜单项风格
  6.         UINT_PTR uIDNewItem, //菜单项ID或下拉菜单句柄
  7.         LPCTSTR lpNewItem //菜单项的名称
  8. );
  9. uFlags:
  10. MF_POPUP - 具有这种风格的菜单项,被点击后弹出下拉菜单,uIDNewItem参数必须填写下拉菜单的句柄。
  11. MF_SEPARATOR - 具有这种风格的菜单项,为分隔线
  12. MF_STRING - 具有这种风格的菜单项,被点击后能够发出消息(WM_COMMAND),uIDNewItem参数必须填写菜单项ID

  13. 设置到窗口
  14. BOOL SetMenu(
  15.         HWND hWnd,  //窗口句柄
  16.         HMENU hMenu //菜单句柄
  17. );
复制代码


5.3菜单命令处理
5.3.1WM_COMMAND 消息
  1. WPARAM:
  2.         HIWORD - 对于菜单为0
  3.         LOWORD - 菜单项的ID
  4. LPARAM - 对于菜单为NULL
复制代码


5.3.2命令处理过程
获取WPARAM菜单ID,根据ID处理。

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;

  4. void OnCreate(HWND hWnd)
  5. {
  6.         HMENU hMain = CreateMenu();

  7.         HMENU hFile = CreatePopupMenu();
  8.         AppendMenu(hFile, MF_STRING | MF_CHECKED, 1003, "新建");
  9.         AppendMenu(hFile, MF_SEPARATOR, 0, "");
  10.         AppendMenu(hFile, MF_STRING | MF_MENUBARBREAK, 1004, "退出");

  11.         HMENU hHelp = CreatePopupMenu();
  12.         AppendMenu(hHelp, MF_STRING | MF_DISABLED, 1005, "关于");

  13.         AppendMenu(hMain, MF_POPUP, (UINT)hFile, "文件");
  14.         AppendMenu(hMain, MF_POPUP, (UINT)hHelp, "帮助");
  15.         SetMenu(hWnd, hMain);

  16. }

  17. void OnCommand(HWND hWnd, WPARAM wParam)
  18. {
  19.         switch (LOWORD(wParam))
  20.         {
  21.         case 1003:
  22.                 MessageBox(hWnd, "新建被点击", "信息", MB_OK);
  23.                 break;
  24.         case 1004:
  25.                 MessageBox(hWnd, "退出被点击", "信息", MB_OK);
  26.                 break;
  27.         case 1005:
  28.                 MessageBox(hWnd, "关于被点击", "信息", MB_OK);
  29.                 break;
  30.         }
  31. }

  32. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  33. {
  34.         switch (msgID)
  35.         {
  36.         case WM_COMMAND:
  37.                 OnCommand(hWnd, wParam);
  38.                 break;
  39.         case WM_CREATE:
  40.                 OnCreate(hWnd);
  41.                 break;
  42.         case WM_DESTROY:
  43.                 PostQuitMessage(0);
  44.                 break;
  45.         default:
  46.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  47.         }
  48.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  49. }

  50. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  51. {
  52.         AllocConsole();//创建一个控制台
  53.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  54.         WNDCLASSEX wc = { 0 };
  55.         wc.cbSize = sizeof(wc);
  56.         wc.hIconSm = NULL;
  57.         wc.cbClsExtra = 0;
  58.         wc.cbWndExtra = 0;
  59.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  60.         wc.hCursor = NULL;
  61.         wc.hIcon = NULL;
  62.         wc.hInstance = hInstance;
  63.         wc.lpfnWndProc = WndProc;
  64.         wc.lpszClassName = "fishc";
  65.         wc.lpszMenuName = NULL;
  66.         wc.style = CS_HREDRAW | CS_VREDRAW;
  67.         RegisterClassEx(&wc);
  68.         char *pszText = "fishc";
  69.         HWND hWnd = CreateWindow("fishc", "fishc", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hInstance, pszText);
  70.         ShowWindow(hWnd, SW_SHOW);
  71.         UpdateWindow(hWnd);
  72.         MSG nMsg = { 0 };
  73.         while (GetMessage(&nMsg, NULL, 0, 0))
  74.         {
  75.                 TranslateMessage(&nMsg);
  76.                 DispatchMessage(&nMsg);
  77.         }
  78.         return 0;
  79. }
复制代码


5.3.3菜单项的状态
在增加菜单项可以设置菜单项的状态。
可以使用菜单API修改状态
  1. CheckMenuItem
  2. //更改菜单项 勾选/非勾选 状态
  3. DWORD CheckMenuItem(
  4.   HMENU hmenu,        // 菜单句柄
  5.   UINT uIDCheckItem,  // 菜单项ID或菜单项位置(索引)
  6.   UINT uCheck         // 具体状态
  7. );
  8. uCheck:
  9.     MF_BYCOMMAND - 指明uIDCheckItem参数必须填写菜单项ID
  10.     MF_BYPOSITION - 指明uIDCheckItem参数必须填写菜单项位置
  11.     MF_CHECKED - 勾选
  12.     MF_UNCHECKED - 非勾选
  13. EnableMenuItem
  14. //更改菜单项 可用/不可用 状态
  15. BOOL EnableMenuItem(
  16.   HMENU hMenu,         // 菜单句柄
  17.   UINT uIDEnableItem,  // 菜单项ID或菜单项位置(索引)
  18.   UINT uEnable         // 具体状态 / 还指明第二个参数填的是什么
  19. );
复制代码


函数使用时,需要通过设置MF_BYPOSITION或者MF_BYCOMMAND,确定使用菜单索引或者菜单ID。


  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_state = 0;//标志量
  5. HMENU hFile;

  6. void OnCreate(HWND hWnd)
  7. {
  8.         HMENU hMain = CreateMenu();
  9.        
  10.         hFile = CreatePopupMenu();
  11.         AppendMenu(hFile,MF_STRING|MF_CHECKED,1003,"新建");
  12.         AppendMenu(hFile,MF_SEPARATOR,0,"");
  13.         AppendMenu(hFile,MF_STRING|MF_MENUBARBREAK,1004,"退出");

  14.         HMENU hHelp = CreatePopupMenu();
  15.         AppendMenu(hHelp,MF_STRING|MF_DISABLED,1005,"关于");

  16.         AppendMenu(hMain,MF_POPUP,(UINT)hFile,"文件");
  17.         AppendMenu(hMain,MF_POPUP,(UINT)hHelp,"帮助");
  18.         SetMenu(hWnd,hMain);

  19. }

  20. void OnCommand(HWND hWnd,WPARAM wParam)
  21. {
  22.         switch(LOWORD(wParam))
  23.         {
  24.         case 1003:
  25.                 if(g_state == 0)
  26.                 {
  27.                         CheckMenuItem(hFile,1003,MF_BYCOMMAND|MF_UNCHECKED);
  28.                 }
  29.                 else
  30.                 {
  31.                         CheckMenuItem(hFile,0,MF_BYPOSITION|MF_CHECKED);
  32.                 }
  33.                 g_state = !g_state;
  34.                 break;
  35.         case 1004:
  36.                 MessageBox(hWnd,"退出被点击","信息",MB_OK);
  37.                 break;
  38.         case 1005:
  39.                 MessageBox(hWnd,"关于被点击","信息",MB_OK);
  40.                 break;
  41.         }
  42. }

  43. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  44. {
  45.         switch (msgID)
  46.         {
  47.         case WM_COMMAND:
  48.                 OnCommand(hWnd,wParam);
  49.                 break;
  50.         case WM_CREATE:
  51.                 OnCreate(hWnd);
  52.                 break;
  53.         case WM_DESTROY:
  54.                 PostQuitMessage(0);
  55.                 break;
  56.         default:
  57.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  58.         }
  59.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  60. }

  61. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  62. {
  63.         AllocConsole();//创建一个控制台
  64.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  65.         WNDCLASSEX wc = { 0 };
  66.         wc.cbSize = sizeof(wc);
  67.         wc.hIconSm = NULL;
  68.         wc.cbClsExtra = 0;
  69.         wc.cbWndExtra = 0;
  70.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  71.         wc.hCursor = NULL;
  72.         wc.hIcon = NULL;
  73.         wc.hInstance = hInstance;
  74.         wc.lpfnWndProc = WndProc;
  75.         wc.lpszClassName = "fishc";
  76.         wc.lpszMenuName = NULL;
  77.         wc.style = CS_HREDRAW | CS_VREDRAW;
  78.         RegisterClassEx(&wc);
  79.         char *pszText = "fishc";
  80.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  81.         ShowWindow(hWnd,SW_SHOW);
  82.         UpdateWindow(hWnd);
  83.         MSG nMsg= { 0 };
  84.         while (GetMessage(&nMsg, NULL, 0, 0))
  85.         {
  86.                 TranslateMessage(&nMsg);
  87.                 DispatchMessage(&nMsg);
  88.         }
  89.         return 0;
  90. }
复制代码


5.3.4WM_INITMENUPOPUP
在菜单被激活但是未显示,窗口会收到这个消息
WPARAM – 即将显示的菜单句柄
LPARAM - LOWORD 是被点击的菜单项索引
HIWORD 是窗口菜单标识

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_state = 0;//标志量
  5. HMENU hFile;

  6. void OnCreate(HWND hWnd)
  7. {
  8.         HMENU hMain = CreateMenu();
  9.        
  10.         hFile = CreatePopupMenu();
  11.         AppendMenu(hFile,MF_STRING|MF_CHECKED,1003,"新建");
  12.         AppendMenu(hFile,MF_SEPARATOR,0,"");
  13.         AppendMenu(hFile,MF_STRING|MF_MENUBARBREAK,1004,"退出");

  14.         HMENU hHelp = CreatePopupMenu();
  15.         AppendMenu(hHelp,MF_STRING|MF_DISABLED,1005,"关于");

  16.         AppendMenu(hMain,MF_POPUP,(UINT)hFile,"文件");
  17.         AppendMenu(hMain,MF_POPUP,(UINT)hHelp,"帮助");
  18.         SetMenu(hWnd,hMain);

  19. }

  20. void OnCommand(HWND hWnd,WPARAM wParam)
  21. {
  22.         switch(LOWORD(wParam))
  23.         {
  24.         case 1003:
  25.                 if(g_state == 0)
  26.                 {
  27.                         CheckMenuItem(hFile,1003,MF_BYCOMMAND|MF_UNCHECKED);
  28.                 }
  29.                 else
  30.                 {
  31.                         CheckMenuItem(hFile,0,MF_BYPOSITION|MF_CHECKED);
  32.                 }
  33.                 g_state = !g_state;
  34.                 break;
  35.         case 1004:
  36.                 MessageBox(hWnd,"退出被点击","信息",MB_OK);
  37.                 break;
  38.         case 1005:
  39.                 MessageBox(hWnd,"关于被点击","信息",MB_OK);
  40.                 break;
  41.         }
  42. }

  43. void OnInitMenuPopup(HWND hWnd,WPARAM wParam,LPARAM lParam)
  44. {
  45.         char szText[256] = {0};
  46.         sprintf(szText,"即将显示的菜单句柄:%d,被点击顶层菜单项位置:%d,即将显示的菜单是否为窗口菜单:%d\n",wParam,LOWORD(lParam),HIWORD(lParam));
  47.         WriteConsole(g_hOutout,szText,strlen(szText),NULL,NULL);
  48. }

  49. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  50. {
  51.         switch (msgID)
  52.         {
  53.         case WM_INITMENUPOPUP:
  54.                 OnInitMenuPopup(hWnd,wParam,lParam);
  55.                 break;
  56.         case WM_COMMAND:
  57.                 OnCommand(hWnd,wParam);
  58.                 break;
  59.         case WM_CREATE:
  60.                 OnCreate(hWnd);
  61.                 break;
  62.         case WM_DESTROY:
  63.                 PostQuitMessage(0);
  64.                 break;
  65.         default:
  66.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  67.         }
  68.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  69. }

  70. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  71. {
  72.         AllocConsole();//创建一个控制台
  73.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  74.         WNDCLASSEX wc = { 0 };
  75.         wc.cbSize = sizeof(wc);
  76.         wc.hIconSm = NULL;
  77.         wc.cbClsExtra = 0;
  78.         wc.cbWndExtra = 0;
  79.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  80.         wc.hCursor = NULL;
  81.         wc.hIcon = NULL;
  82.         wc.hInstance = hInstance;
  83.         wc.lpfnWndProc = WndProc;
  84.         wc.lpszClassName = "fishc";
  85.         wc.lpszMenuName = NULL;
  86.         wc.style = CS_HREDRAW | CS_VREDRAW;
  87.         RegisterClassEx(&wc);
  88.         char *pszText = "fishc";
  89.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  90.         ShowWindow(hWnd,SW_SHOW);
  91.         UpdateWindow(hWnd);
  92.         MSG nMsg= { 0 };
  93.         while (GetMessage(&nMsg, NULL, 0, 0))
  94.         {
  95.                 TranslateMessage(&nMsg);
  96.                 DispatchMessage(&nMsg);
  97.         }
  98.         return 0;
  99. }
复制代码


5.4系统菜单的使用(了解)
5.4.1 系统菜单的获取
  1. HMENU GetSystemMenu(
  2.         HWND hWnd,//窗口句柄
  3.         BOOL bRevert //重置选项
  4. ); 返回获取到的系统菜单句柄
  5. bRevert:TRUE - 删除旧菜单,恢复到默认的系统菜单
  6.                 FALSE - 返回当前的系统菜单句柄。
复制代码


5.4.2 系统菜单的修改
AppendMenu函数
DeleteMenu函数

5.4.3 系统菜单命令响应
通过WM_SYSCOMMAND响应菜单命令。
WPARAM的LOWORD是命令ID

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_state = 0;//标志量
  5. HMENU hFile;

  6. void OnCreate(HWND hWnd)
  7. {
  8.         HMENU hMain = CreateMenu();
  9.        
  10.         hFile = CreatePopupMenu();
  11.         AppendMenu(hFile,MF_STRING|MF_CHECKED,1003,"新建");
  12.         AppendMenu(hFile,MF_SEPARATOR,0,"");
  13.         AppendMenu(hFile,MF_STRING|MF_MENUBARBREAK,1004,"退出");

  14.         HMENU hHelp = CreatePopupMenu();
  15.         AppendMenu(hHelp,MF_STRING|MF_DISABLED,1005,"关于");

  16.         AppendMenu(hMain,MF_POPUP,(UINT)hFile,"文件");
  17.         AppendMenu(hMain,MF_POPUP,(UINT)hHelp,"帮助");
  18.         SetMenu(hWnd,hMain);
  19.         HMENU hSys = GetSystemMenu(hWnd,FALSE);
  20.         for(int i=0;i<6;i++)
  21.         {
  22.                 DeleteMenu(hSys,0,MF_BYPOSITION);
  23.         }
  24.         AppendMenu(hSys,MF_SEPARATOR,0,"");
  25.         AppendMenu(hSys,MF_STRING,1001,"我的菜单项");

  26. }

  27. void OnCommand(HWND hWnd,WPARAM wParam)
  28. {
  29.         switch(LOWORD(wParam))
  30.         {
  31.         case 1003:
  32.                 if(g_state == 0)
  33.                 {
  34.                         CheckMenuItem(hFile,1003,MF_BYCOMMAND|MF_UNCHECKED);
  35.                 }
  36.                 else
  37.                 {
  38.                         CheckMenuItem(hFile,0,MF_BYPOSITION|MF_CHECKED);
  39.                 }
  40.                 g_state = !g_state;
  41.                 break;
  42.         case 1004:
  43.                 MessageBox(hWnd,"退出被点击","信息",MB_OK);
  44.                 break;
  45.         case 1005:
  46.                 MessageBox(hWnd,"关于被点击","信息",MB_OK);
  47.                 break;
  48.         }
  49. }

  50. void OnSysCommand(HWND hWnd,WPARAM wParam)
  51. {
  52.         switch(LOWORD(wParam))
  53.         {
  54.         case 1001:
  55.                 MessageBox(hWnd,"我的菜单项被点击","信息",MB_OK);
  56.                 break;
  57.         }
  58. }

  59. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  60. {
  61.         switch (msgID)
  62.         {
  63.         case WM_SYSCOMMAND:
  64.                 OnSysCommand(hWnd,wParam);
  65.                 break;
  66.         case WM_COMMAND:
  67.                 OnCommand(hWnd,wParam);
  68.                 break;
  69.         case WM_CREATE:
  70.                 OnCreate(hWnd);
  71.                 break;
  72.         case WM_DESTROY:
  73.                 PostQuitMessage(0);
  74.                 break;
  75.         default:
  76.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  77.         }
  78.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  79. }

  80. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  81. {
  82.         AllocConsole();//创建一个控制台
  83.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  84.         WNDCLASSEX wc = { 0 };
  85.         wc.cbSize = sizeof(wc);
  86.         wc.hIconSm = NULL;
  87.         wc.cbClsExtra = 0;
  88.         wc.cbWndExtra = 0;
  89.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  90.         wc.hCursor = NULL;
  91.         wc.hIcon = NULL;
  92.         wc.hInstance = hInstance;
  93.         wc.lpfnWndProc = WndProc;
  94.         wc.lpszClassName = "fishc";
  95.         wc.lpszMenuName = NULL;
  96.         wc.style = CS_HREDRAW | CS_VREDRAW;
  97.         RegisterClassEx(&wc);
  98.         char *pszText = "fishc";
  99.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  100.         ShowWindow(hWnd,SW_SHOW);
  101.         UpdateWindow(hWnd);
  102.         MSG nMsg= { 0 };
  103.         while (GetMessage(&nMsg, NULL, 0, 0))
  104.         {
  105.                 TranslateMessage(&nMsg);
  106.                 DispatchMessage(&nMsg);
  107.         }
  108.         return 0;
  109. }
复制代码


5.5右键菜单 Context Menu的使用
5.5.1 创建菜单
右键菜单是一个弹出式菜单,使用CreatePopupMenu创建。

5.5.2 显示菜单
  1. BOOL TrackPopupMenu(
  2.         HMENU hMenu, //菜单句柄
  3.         UINT uFlags, //显示方式
  4.         int x,//水平位置,屏幕坐标系
  5.         int y,//垂直位置,屏幕坐标系
  6.         int nReserved, //保留,必须0
  7.          HWND hWnd, //处理菜单消息的窗口句柄
  8.         CONST RECT *prcRect //NULL,忽略
  9. ); TrackPopupMenu是阻塞函数
复制代码


5.5.3 命令处理
WM_COMMAND,与窗口菜单一致
如果TrackPopupMenu设置了TPM_RETURNCMD选项,那么点击的菜单项ID通过函数的返回值获取。

5.5.4 菜单项的状态
WM_INITMENUPOPUP,按照弹出菜单处理

5.5.5菜单处理位置
5.5.5.1 鼠标右键抬起
WM_RBUTTONUP 鼠标右键消息窗口坐标系坐标,要使用需要转换成屏幕坐标系
ClientToScreen
ScreenToClient

  1. //将 客户区坐标系下的坐标 转换为 屏幕坐标系下的坐标
  2. BOOL ClientToScreen(
  3.   HWND hWnd,       // 窗口句柄
  4.   LPPOINT lpPoint  // [IN/OUT]
  5.                 输入:客户区坐标系下的一个坐标
  6.                 输出 : 转换后屏幕坐标系下的坐标
  7. );
复制代码

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_state = 0;//标志量
  5. HMENU hFile;

  6. void OnCreate(HWND hWnd)
  7. {
  8.         HMENU hMain = CreateMenu();
  9.        
  10.         hFile = CreatePopupMenu();
  11.         AppendMenu(hFile,MF_STRING|MF_CHECKED,1003,"新建");
  12.         AppendMenu(hFile,MF_SEPARATOR,0,"");
  13.         AppendMenu(hFile,MF_STRING|MF_MENUBARBREAK,1004,"退出");

  14.         HMENU hHelp = CreatePopupMenu();
  15.         AppendMenu(hHelp,MF_STRING|MF_DISABLED,1005,"关于");

  16.         AppendMenu(hMain,MF_POPUP,(UINT)hFile,"文件");
  17.         AppendMenu(hMain,MF_POPUP,(UINT)hHelp,"帮助");
  18.         SetMenu(hWnd,hMain);
  19. }

  20. void OnCommand(HWND hWnd,WPARAM wParam)
  21. {
  22.         switch(LOWORD(wParam))
  23.         {
  24.         case 1003:
  25.                 if(g_state == 0)
  26.                 {
  27.                         CheckMenuItem(hFile,1003,MF_BYCOMMAND|MF_UNCHECKED);
  28.                 }
  29.                 else
  30.                 {
  31.                         CheckMenuItem(hFile,0,MF_BYPOSITION|MF_CHECKED);
  32.                 }
  33.                 g_state = !g_state;
  34.                 break;
  35.         case 1004:
  36.                 MessageBox(hWnd,"退出被点击","信息",MB_OK);
  37.                 break;
  38.         case 1005:
  39.                 MessageBox(hWnd,"关于被点击","信息",MB_OK);
  40.                 break;
  41.         case 1010:
  42.                 MessageBox(hWnd,"右键新建被点击","信息",MB_OK);
  43.                 break;
  44.         case 1011:
  45.                 MessageBox(hWnd,"右键退出被点击","信息",MB_OK);
  46.                 break;
  47.         }
  48. }


  49. void OnRButtonUp(HWND hWnd,LPARAM lParam)
  50. {
  51.         HMENU hPopup = CreatePopupMenu();
  52.         AppendMenu(hPopup,MF_STRING,1010,"新建");
  53.         AppendMenu(hPopup,MF_SEPARATOR,0,"");
  54.         AppendMenu(hPopup,MF_STRING,1011,"退出");
  55.         POINT pt = {0};
  56.         pt.x = LOWORD(lParam);
  57.         pt.y = HIWORD(lParam);
  58.         ClientToScreen(hWnd,&pt);
  59.         TrackPopupMenu(hPopup,TPM_CENTERALIGN|TPM_VCENTERALIGN,pt.x,pt.y,0,hWnd,NULL);
  60. }

  61. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  62. {
  63.         switch (msgID)
  64.         {
  65.        
  66.         case WM_RBUTTONUP:
  67.                 OnRButtonUp(hWnd,lParam);
  68.                 break;
  69.         case WM_COMMAND:
  70.                 OnCommand(hWnd,wParam);
  71.                 break;
  72.         case WM_CREATE:
  73.                 OnCreate(hWnd);
  74.                 break;
  75.         case WM_DESTROY:
  76.                 PostQuitMessage(0);
  77.                 break;
  78.         default:
  79.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  80.         }
  81.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  82. }

  83. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  84. {
  85.         AllocConsole();//创建一个控制台
  86.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  87.         WNDCLASSEX wc = { 0 };
  88.         wc.cbSize = sizeof(wc);
  89.         wc.hIconSm = NULL;
  90.         wc.cbClsExtra = 0;
  91.         wc.cbWndExtra = 0;
  92.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  93.         wc.hCursor = NULL;
  94.         wc.hIcon = NULL;
  95.         wc.hInstance = hInstance;
  96.         wc.lpfnWndProc = WndProc;
  97.         wc.lpszClassName = "fishc";
  98.         wc.lpszMenuName = NULL;
  99.         wc.style = CS_HREDRAW | CS_VREDRAW;
  100.         RegisterClassEx(&wc);
  101.         char *pszText = "fishc";
  102.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  103.         ShowWindow(hWnd,SW_SHOW);
  104.         UpdateWindow(hWnd);
  105.         MSG nMsg= { 0 };
  106.         while (GetMessage(&nMsg, NULL, 0, 0))
  107.         {
  108.                 TranslateMessage(&nMsg);
  109.                 DispatchMessage(&nMsg);
  110.         }
  111.         return 0;
  112. }
复制代码

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_state = 0;//标志量
  5. HMENU hFile;

  6. void OnCreate(HWND hWnd)
  7. {
  8.         HMENU hMain = CreateMenu();
  9.        
  10.         hFile = CreatePopupMenu();
  11.         AppendMenu(hFile,MF_STRING|MF_CHECKED,1003,"新建");
  12.         AppendMenu(hFile,MF_SEPARATOR,0,"");
  13.         AppendMenu(hFile,MF_STRING|MF_MENUBARBREAK,1004,"退出");

  14.         HMENU hHelp = CreatePopupMenu();
  15.         AppendMenu(hHelp,MF_STRING|MF_DISABLED,1005,"关于");

  16.         AppendMenu(hMain,MF_POPUP,(UINT)hFile,"文件");
  17.         AppendMenu(hMain,MF_POPUP,(UINT)hHelp,"帮助");
  18.         SetMenu(hWnd,hMain);
  19. }

  20. void OnCommand(HWND hWnd,WPARAM wParam)
  21. {
  22.         switch(LOWORD(wParam))
  23.         {
  24.         case 1003:
  25.                 if(g_state == 0)
  26.                 {
  27.                         CheckMenuItem(hFile,1003,MF_BYCOMMAND|MF_UNCHECKED);
  28.                 }
  29.                 else
  30.                 {
  31.                         CheckMenuItem(hFile,0,MF_BYPOSITION|MF_CHECKED);
  32.                 }
  33.                 g_state = !g_state;
  34.                 break;
  35.         case 1004:
  36.                 MessageBox(hWnd,"退出被点击","信息",MB_OK);
  37.                 break;
  38.         case 1005:
  39.                 MessageBox(hWnd,"关于被点击","信息",MB_OK);
  40.                 break;
  41.         case 1010:
  42.                 MessageBox(hWnd,"右键新建被点击","信息",MB_OK);
  43.                 break;
  44.         case 1011:
  45.                 MessageBox(hWnd,"右键退出被点击","信息",MB_OK);
  46.                 break;
  47.         }
  48. }


  49. void OnRButtonUp(HWND hWnd,LPARAM lParam)
  50. {
  51.         HMENU hPopup = CreatePopupMenu();
  52.         AppendMenu(hPopup,MF_STRING,1010,"新建");
  53.         AppendMenu(hPopup,MF_SEPARATOR,0,"");
  54.         AppendMenu(hPopup,MF_STRING,1011,"退出");
  55.         POINT pt = {0};
  56.         pt.x = LOWORD(lParam);
  57.         pt.y = HIWORD(lParam);
  58.         ClientToScreen(hWnd,&pt);
  59.         BOOL nRet = TrackPopupMenu(hPopup,TPM_CENTERALIGN|TPM_VCENTERALIGN|TPM_RETURNCMD,pt.x,pt.y,0,hWnd,NULL);
  60.         switch(nRet)
  61.         {
  62.         case 1010:
  63.                 MessageBox(hWnd,"没发出COMMAND消息,右键新建被点击","信息",MB_OK);
  64.                 break;
  65.         case 1011:
  66.                 MessageBox(hWnd,"没发出COMMAND消息,右键退出被点击","信息",MB_OK);
  67.                 break;
  68.         }
  69. }

  70. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  71. {
  72.         switch (msgID)
  73.         {
  74.        
  75.         case WM_RBUTTONUP:
  76.                 OnRButtonUp(hWnd,lParam);
  77.                 break;
  78.         case WM_COMMAND:
  79.                 OnCommand(hWnd,wParam);
  80.                 break;
  81.         case WM_CREATE:
  82.                 OnCreate(hWnd);
  83.                 break;
  84.         case WM_DESTROY:
  85.                 PostQuitMessage(0);
  86.                 break;
  87.         default:
  88.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  89.         }
  90.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  91. }

  92. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  93. {
  94.         AllocConsole();//创建一个控制台
  95.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  96.         WNDCLASSEX wc = { 0 };
  97.         wc.cbSize = sizeof(wc);
  98.         wc.hIconSm = NULL;
  99.         wc.cbClsExtra = 0;
  100.         wc.cbWndExtra = 0;
  101.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  102.         wc.hCursor = NULL;
  103.         wc.hIcon = NULL;
  104.         wc.hInstance = hInstance;
  105.         wc.lpfnWndProc = WndProc;
  106.         wc.lpszClassName = "fishc";
  107.         wc.lpszMenuName = NULL;
  108.         wc.style = CS_HREDRAW | CS_VREDRAW;
  109.         RegisterClassEx(&wc);
  110.         char *pszText = "fishc";
  111.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  112.         ShowWindow(hWnd,SW_SHOW);
  113.         UpdateWindow(hWnd);
  114.         MSG nMsg= { 0 };
  115.         while (GetMessage(&nMsg, NULL, 0, 0))
  116.         {
  117.                 TranslateMessage(&nMsg);
  118.                 DispatchMessage(&nMsg);
  119.         }
  120.         return 0;
  121. }
复制代码


5.5.5.2 WM_CONTEXTMENU
WParam - 右键点击的窗口句柄
LPARAM - LOWORD X坐标,屏幕坐标系
HIWORD Y坐标,屏幕坐标系
WM_CONTEXTMENU消息是在WM_RBUTTONUP消息之后产生。

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. HANDLE g_hOutout = 0;
  4. int g_state = 0;//标志量
  5. HMENU hFile;

  6. void OnCreate(HWND hWnd)
  7. {
  8.         HMENU hMain = CreateMenu();
  9.        
  10.         hFile = CreatePopupMenu();
  11.         AppendMenu(hFile,MF_STRING|MF_CHECKED,1003,"新建");
  12.         AppendMenu(hFile,MF_SEPARATOR,0,"");
  13.         AppendMenu(hFile,MF_STRING|MF_MENUBARBREAK,1004,"退出");

  14.         HMENU hHelp = CreatePopupMenu();
  15.         AppendMenu(hHelp,MF_STRING|MF_DISABLED,1005,"关于");

  16.         AppendMenu(hMain,MF_POPUP,(UINT)hFile,"文件");
  17.         AppendMenu(hMain,MF_POPUP,(UINT)hHelp,"帮助");
  18.         SetMenu(hWnd,hMain);
  19. }

  20. void OnCommand(HWND hWnd,WPARAM wParam)
  21. {
  22.         switch(LOWORD(wParam))
  23.         {
  24.         case 1003:
  25.                 if(g_state == 0)
  26.                 {
  27.                         CheckMenuItem(hFile,1003,MF_BYCOMMAND|MF_UNCHECKED);
  28.                 }
  29.                 else
  30.                 {
  31.                         CheckMenuItem(hFile,0,MF_BYPOSITION|MF_CHECKED);
  32.                 }
  33.                 g_state = !g_state;
  34.                 break;
  35.         case 1004:
  36.                 MessageBox(hWnd,"退出被点击","信息",MB_OK);
  37.                 break;
  38.         case 1005:
  39.                 MessageBox(hWnd,"关于被点击","信息",MB_OK);
  40.                 break;
  41.         case 1010:
  42.                 MessageBox(hWnd,"右键新建被点击","信息",MB_OK);
  43.                 break;
  44.         case 1011:
  45.                 MessageBox(hWnd,"右键退出被点击","信息",MB_OK);
  46.                 break;
  47.         }
  48. }


  49. void OnContextMenu(HWND hWnd,LPARAM lParam)
  50. {
  51.         HMENU hPopup = CreatePopupMenu();
  52.         AppendMenu(hPopup,MF_STRING,1010,"新建");
  53.         AppendMenu(hPopup,MF_SEPARATOR,0,"");
  54.         AppendMenu(hPopup,MF_STRING,1011,"退出");
  55.         POINT pt = {0};
  56.         pt.x = LOWORD(lParam);
  57.         pt.y = HIWORD(lParam);
  58.         BOOL nRet = TrackPopupMenu(hPopup,TPM_CENTERALIGN|TPM_VCENTERALIGN|TPM_RETURNCMD,pt.x,pt.y,0,hWnd,NULL);
  59.         switch(nRet)
  60.         {
  61.         case 1010:
  62.                 MessageBox(hWnd,"没发出COMMAND消息,右键新建被点击","信息",MB_OK);
  63.                 break;
  64.         case 1011:
  65.                 MessageBox(hWnd,"没发出COMMAND消息,右键退出被点击","信息",MB_OK);
  66.                 break;
  67.         }
  68. }

  69. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  70. {
  71.         switch (msgID)
  72.         {
  73.         case WM_CONTEXTMENU:
  74.                 OnContextMenu(hWnd,lParam);
  75.                 break;
  76.         case WM_COMMAND:
  77.                 OnCommand(hWnd,wParam);
  78.                 break;
  79.         case WM_CREATE:
  80.                 OnCreate(hWnd);
  81.                 break;
  82.         case WM_DESTROY:
  83.                 PostQuitMessage(0);
  84.                 break;
  85.         default:
  86.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  87.         }
  88.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  89. }

  90. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  91. {
  92.         AllocConsole();//创建一个控制台
  93.         g_hOutout = GetStdHandle(STD_OUTPUT_HANDLE);
  94.         WNDCLASSEX wc = { 0 };
  95.         wc.cbSize = sizeof(wc);
  96.         wc.hIconSm = NULL;
  97.         wc.cbClsExtra = 0;
  98.         wc.cbWndExtra = 0;
  99.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  100.         wc.hCursor = NULL;
  101.         wc.hIcon = NULL;
  102.         wc.hInstance = hInstance;
  103.         wc.lpfnWndProc = WndProc;
  104.         wc.lpszClassName = "fishc";
  105.         wc.lpszMenuName = NULL;
  106.         wc.style = CS_HREDRAW | CS_VREDRAW;
  107.         RegisterClassEx(&wc);
  108.         char *pszText = "fishc";
  109.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  110.         ShowWindow(hWnd,SW_SHOW);
  111.         UpdateWindow(hWnd);
  112.         MSG nMsg= { 0 };
  113.         while (GetMessage(&nMsg, NULL, 0, 0))
  114.         {
  115.                 TranslateMessage(&nMsg);
  116.                 DispatchMessage(&nMsg);
  117.         }
  118.         return 0;
  119. }
复制代码


下期预告:资源的使用,windows 绘图
题外话:好多东西我都没有细说,等你们问呢,win32好多都是实践和思考的东西,并不难,然而发了这么多,连回复都没有几个。。。

不定时停更

评分

参与人数 1鱼币 +8 收起 理由
小甲鱼 + 8 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

楼层
跳转到指定楼层
最佳答案
0 
累计签到:86 天
连续签到:1 天
duhui 发表于 2018-1-18 20:51:28 | 显示全部楼层
用vs2015如何创建菜单资源,能把过程详细说一下吗?包括.rc文件的创建

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

小甲鱼强烈推荐 上一条 /2 下一条

    移动客户端下载(未启用)
    微信公众号

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备11014136号

Copyright 2018 鱼C论坛 版权所有 All Rights Reserved.

Powered by Discuz! X3.1 Copyright
© 2001-2018 Comsenz Inc.    All Rights Reserved.

小黑屋|手机版|Archiver|鱼C工作室 ( 粤公网安备 44051102000370号 | 粤ICP备11014136号

GMT+8, 2018-2-20 15:26

快速回复 返回顶部 返回列表