一 系统菜单

  1 执行系统提供的窗口命令,例如最大化、关闭等命令。本质上和普通菜单一样,所以我们也可以在程序中使用这个菜单
   
  2 系统菜单的使用
    2.1 获取系统菜单
       GetSystemMenu

  1. HMENU GetSystemMenu(
  2. HWND hWnd, //要获取的窗口句柄
  3. BOOL bRevert //获取时重置标示
  4. );

    bRevert: TRUE 重置 FLASE 不重置
    当Revert为TRUE时,会将菜单重新置成默认的状态,并返回菜单句柄。如果为FALSE,菜单项不重置,获取到当前系统菜单的状态。
   
    2.2 修改系统菜单,例如增加、删除
       2.2.1 AppednMenu
       2.2.2 InsertMenu
         比AppednMenu增加了一个插入菜单项的位置或ID。
       2.2.3 删除菜单项

  1. BOOL RemoveMenu( //
  2. HMENU hMenu, //菜单句柄
  3. UINT uPosition,//菜单项的位置或ID
  4. UINT uFlags );//菜单项的位置或ID的标示。

    uFlags为MF_BYCOMMAND, uPosition为菜单ID
    uFlags为MF_BYPOSITION,uPosition为菜单位置

    2.3 系统菜单的命令响应
       系统菜单的命令响应,是在WM_SYSCOMMAND中。
       WPARAM – LOWORD(wParam)为增加的菜单的ID

  1. int nID = LOWORD( wParam );
  2. switch( nID )
  3. {
  4. case 1001:
  5. //...
  6. break;
  7. }
View Code

  1. // SysMenu.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "stdio.h"
  5. HINSTANCE g_hInst = NULL;
  6. HANDLE g_hStdOut = NULL;
  7. void OnCreate( HWND hWnd, UINT nMsg,
  8. WPARAM wParam, LPARAM lParam )
  9. { // 获取系统菜单
  10. HMENU hSysMenu =
  11. GetSystemMenu( hWnd, FALSE );
  12. // 删除菜单项
  13. RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
  14. RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
  15. RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
  16. RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
  17. RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
  18. // 增加菜单项
  19. InsertMenu( hSysMenu, 0, MF_BYPOSITION|MF_STRING,
  20. 1001, "测试1" );
  21. InsertMenu( hSysMenu, 1, MF_BYPOSITION|MF_STRING,
  22. 1002, "测试2" );
  23. }
  24. void OnSysCommand( HWND hWnd, UINT nMsg,
  25. WPARAM wParam, LPARAM lParam )
  26. {
  27. CHAR szText[260] = { 0 };
  28. sprintf( szText,
  29. "OnSysCommand: WPARAM=%08X,LPARAM=%08X\n",
  30. wParam, lParam );
  31. WriteConsole( g_hStdOut, szText,
  32. strlen(szText), NULL, NULL );
  33. int nID = LOWORD( wParam );
  34. switch( nID )
  35. {
  36. case 1001:
  37. MessageBox( NULL, "Hello 1001",
  38. "SysMenu", MB_OK );
  39. break;
  40. case 1002:
  41. MessageBox( NULL, "Hello 1002",
  42. "SysMenu", MB_OK );
  43. break;
  44. }
  45. }
  46. LRESULT CALLBACK WndProc( HWND hWnd,
  47. UINT nMsg,
  48. WPARAM wParam,
  49. LPARAM lParam )
  50. {
  51. switch( nMsg )
  52. {
  53. case WM_CREATE:
  54. OnCreate( hWnd, nMsg, wParam, lParam );
  55. break;
  56. case WM_SYSCOMMAND:
  57. OnSysCommand( hWnd, nMsg, wParam, lParam );
  58. break;
  59. case WM_DESTROY:
  60. PostQuitMessage( 0 );
  61. return 0;
  62. }
  63. return DefWindowProc( hWnd, nMsg,
  64. wParam, lParam );
  65. }
  66. BOOL RegisterWnd( LPSTR pszClassName )
  67. {
  68. WNDCLASSEX wce = { 0 };
  69. wce.cbSize = sizeof( wce );
  70. wce.cbClsExtra = 0;
  71. wce.cbWndExtra = 0;
  72. wce.hbrBackground = HBRUSH(COLOR_WINDOW);
  73. wce.hCursor = NULL;
  74. wce.hIcon = NULL;
  75. wce.hIconSm = NULL;
  76. wce.hInstance = g_hInst;
  77. wce.lpfnWndProc = WndProc;
  78. wce.lpszClassName = pszClassName;
  79. wce.lpszMenuName = NULL;
  80. wce.style = CS_HREDRAW|CS_VREDRAW;
  81. ATOM nAtom = RegisterClassEx( &wce );
  82. if( 0 == nAtom )
  83. {
  84. return FALSE;
  85. }
  86. return TRUE;
  87. }
  88. HWND CreateWnd( LPSTR pszClassName )
  89. {
  90. HWND hWnd = CreateWindowEx( 0,
  91. pszClassName, "MyWnd",
  92. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
  93. CW_USEDEFAULT, CW_USEDEFAULT,
  94. CW_USEDEFAULT, NULL, NULL, g_hInst,
  95. NULL );
  96. return hWnd;
  97. }
  98. void DisplayWnd( HWND hWnd )
  99. {
  100. ShowWindow( hWnd, SW_SHOW );
  101. UpdateWindow( hWnd );
  102. }
  103. void Message( )
  104. {
  105. MSG msg = { 0 };
  106. while( GetMessage( &msg, NULL, 0, 0 ) )
  107. {
  108. TranslateMessage( &msg );
  109. DispatchMessage( &msg );
  110. }
  111. }
  112. void NewConsole( )
  113. {
  114. AllocConsole( );
  115. g_hStdOut =
  116. GetStdHandle( STD_OUTPUT_HANDLE );
  117. }
  118. int APIENTRY WinMain(HINSTANCE hInstance,
  119. HINSTANCE hPrevInstance,
  120. LPSTR lpCmdLine,
  121. int nCmdShow)
  122. {
  123. NewConsole( );
  124. g_hInst = hInstance;
  125. RegisterWnd( "MYWND" );
  126. HWND hWnd = CreateWnd( "MYWND" );
  127. DisplayWnd( hWnd );
  128. Message( );
  129. return 0;
  130. }

二 右键菜单
  1 右键菜单
    当在窗口点击鼠标右键时,弹出的菜单。
  2 右键菜单的使用
    2.1 创建菜单
      CreatePopupMenu
    2.2 菜单增加
     AppendMenu
    2.3 菜单的显示

  1. BOOL TrackPopupMenu(
  2. HMENU hMenu, //显示的菜单句柄
  3. UINT uFlags, //显示的方式
  4. int x, //菜单的X屏幕坐标
  5. int y, //菜单的Y屏幕坐标
  6. int nReserved, //保留,必须为0
  7. HWND hWnd, //处理菜单命令的窗口句柄
  8. CONST RECT *prcRect ); //忽略

    2.4 菜单的命令处理
     WM_COMMAND
    2.5 使用右键菜单的位置
      2.5.1 WM_RBUTTONUP 消息
        在WM_RBUTTONUP中,添加菜单的创建及显示,
        右键消息坐标,转换成屏幕坐标使用.
          ClientToScreen.
      2.5.2 WM_CONTEXTMENU 消息
        用于显示右键的菜单的消息.
          WPARAM – 右键抬起时对应窗口句柄
          LPARAM – 右键抬起时鼠标的屏幕坐标位置
             LOWORD(lParam) – X屏幕坐标
             HIWORD(lParam) – Y屏幕坐标
      2.5.3 WM_RBUTTONUP和WM_CONTEXTMENU对比
        1) 坐标系不同, WM_RBUTTONUP客户区坐标,WM_CONTEXTMENU屏幕坐标
        2) 先有WM_RBUTTONUP消息,后有WM_CONTEXTMENU消息

View Code

  1. // PopMenu.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. HINSTANCE g_hInst = NULL;
  5. void OnRButtonUp( HWND hWnd, UINT nMsg,
  6. WPARAM wParam, LPARAM lParam )
  7. { // 创建弹出式菜单
  8. HMENU hPopMenu = CreatePopupMenu( );
  9. // 增加菜单项
  10. AppendMenu( hPopMenu, MF_STRING, 1001, "测试1");
  11. AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
  12. AppendMenu( hPopMenu, MF_STRING, 1002, "退出");
  13. // 获取菜单位置
  14. POINT point = { 0 };
  15. point.x = LOWORD( lParam );
  16. point.y = HIWORD( lParam );
  17. ClientToScreen( hWnd, &point );
  18. // 显示菜单
  19. TrackPopupMenu( hPopMenu, TPM_LEFTALIGN,
  20. point.x, point.y, 0, hWnd, NULL );
  21. }
  22. void OnContextMenu( HWND hWnd, UINT nMsg,
  23. WPARAM wParam, LPARAM lParam )
  24. { // 创建弹出式菜单
  25. HMENU hPopMenu = CreatePopupMenu( );
  26. // 增加菜单项
  27. AppendMenu( hPopMenu, MF_STRING, 1001, "测试2");
  28. AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
  29. AppendMenu( hPopMenu, MF_STRING, 1002, "退出");
  30. // 坐标获取
  31. int nX = LOWORD( lParam );
  32. int nY = HIWORD( lParam );
  33. // 显示菜单
  34. TrackPopupMenu( hPopMenu, TPM_LEFTALIGN,
  35. nX, nY, 0, hWnd, NULL );
  36. // 删除菜单
  37. DestroyMenu( hPopMenu );
  38. }
  39. void OnCommand( HWND hWnd, UINT nMsg,
  40. WPARAM wParam, LPARAM lParam )
  41. {
  42. int nCmdID = LOWORD( wParam );
  43. switch( nCmdID )
  44. {
  45. case 1001:
  46. MessageBox( NULL, "Hello Popmenu",
  47. "PopMenu", MB_OK );
  48. break;
  49. case 1002:
  50. PostQuitMessage( 0 );
  51. break;
  52. }
  53. }
  54. LRESULT CALLBACK WndProc( HWND hWnd,
  55. UINT nMsg,
  56. WPARAM wParam,
  57. LPARAM lParam )
  58. {
  59. switch( nMsg )
  60. {
  61. case WM_RBUTTONUP:
  62. //OnRButtonUp( hWnd, nMsg, wParam, lParam );
  63. break;
  64. case WM_CONTEXTMENU:
  65. OnContextMenu( hWnd, nMsg, wParam, lParam );
  66. break;
  67. case WM_COMMAND:
  68. OnCommand( hWnd, nMsg, wParam, lParam );
  69. break;
  70. case WM_DESTROY:
  71. PostQuitMessage( 0 );
  72. return 0;
  73. }
  74. return DefWindowProc( hWnd, nMsg,
  75. wParam, lParam );
  76. }
  77. BOOL RegisterWnd( LPSTR pszClassName )
  78. {
  79. WNDCLASSEX wce = { 0 };
  80. wce.cbSize = sizeof( wce );
  81. wce.cbClsExtra = 0;
  82. wce.cbWndExtra = 0;
  83. wce.hbrBackground = HBRUSH(COLOR_WINDOW);
  84. wce.hCursor = NULL;
  85. wce.hIcon = NULL;
  86. wce.hIconSm = NULL;
  87. wce.hInstance = g_hInst;
  88. wce.lpfnWndProc = WndProc;
  89. wce.lpszClassName = pszClassName;
  90. wce.lpszMenuName = NULL;
  91. wce.style = CS_HREDRAW|CS_VREDRAW;
  92. ATOM nAtom = RegisterClassEx( &wce );
  93. if( 0 == nAtom )
  94. {
  95. return FALSE;
  96. }
  97. return TRUE;
  98. }
  99. HWND CreateWnd( LPSTR pszClassName )
  100. {
  101. HWND hWnd = CreateWindowEx( 0,
  102. pszClassName, "MyWnd",
  103. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
  104. CW_USEDEFAULT, CW_USEDEFAULT,
  105. CW_USEDEFAULT, NULL, NULL, g_hInst,
  106. NULL );
  107. return hWnd;
  108. }
  109. void DisplayWnd( HWND hWnd )
  110. {
  111. ShowWindow( hWnd, SW_SHOW );
  112. UpdateWindow( hWnd );
  113. }
  114. void Message( )
  115. {
  116. MSG msg = { 0 };
  117. while( GetMessage( &msg, NULL, 0, 0 ) )
  118. {
  119. TranslateMessage( &msg );
  120. DispatchMessage( &msg );
  121. }
  122. }
  123. int APIENTRY WinMain(HINSTANCE hInstance,
  124. HINSTANCE hPrevInstance,
  125. LPSTR lpCmdLine,
  126. int nCmdShow)
  127. {
  128. g_hInst = hInstance;
  129. RegisterWnd( "MYWND" );
  130. HWND hWnd = CreateWnd( "MYWND" );
  131. DisplayWnd( hWnd );
  132. Message( );
  133. return 0;
  134. }

三 资源的使用

  1 资源文件
    图标、光标、字符串、菜单、加速键和对话框资源,位图资源等等。
    资源脚本文件 – 扩展名为RC文件。定义了资源和相关文件等等信息。
    资源编译器 – RC.exe
   
  2 图标资源ICON
  
    2.1 常用的几种大小: 16X16, 32X32,48X48
    2.2 使用
       HICON LoadIcon(
     HINSTANCE hInstance, //应用程序的句柄
      LPCTSTR lpIconName );//图标的ID字符串
    2.3 系统提供的图标
       hInstance为空, lpIconName为定义的系统图标.
    2.4 自己绘制的图标
       hInstance为图标所在的应用程序的实例句柄
    2.5 注意点:
      一个图标文件中,可以包含多种大小、颜色不同的图标,系统使用图标时,通过大小来匹配,如果未找到大小完全一致的,那么会使用大小最接近的图标格式替换。
   
  3 光标资源
   
    3.1 光标资源
      热点 Hotspot – 可以产生鼠标点击的位置
    3.2 使用
      HCURSOR LoadCursor(
    HINSTANCE hInstance, //应用程序实例句柄
      LPCTSTR lpCursorName); //光标的ID
    3.3 系统的光标
      hInstance为空,lpCursorName指定为系统的光标即可获得
    3.4 自绘制的光标
      hInstance不能为空。
    3.5 WM_SETCURSOR消息
      当鼠标在窗口内就会产生。可以在程序执行的过程中修改鼠标样式。
        wParam – 窗口句柄;
        LOWORD(lParam) – 所在位置的标识
        HIWORD(lParam) – 鼠标的消息ID
      SetCursour 设置当前窗口的光标

View Code

  1. // WinRes.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h"
  5. HINSTANCE g_hInst = NULL;
  6. BOOL OnSetCursor( HWND hWnd, UINT nMsg,
  7. WPARAM wParam, LPARAM lParam )
  8. {
  9. int nHitTest = LOWORD( lParam );
  10. if( HTCLIENT != nHitTest )
  11. {
  12. return FALSE;
  13. }
  14. //获得窗口的客户区
  15. RECT rcClient = { 0 };
  16. GetClientRect( hWnd, &rcClient );
  17. //获得当前光标的位置
  18. POINT ptPos = { 0 };
  19. GetCursorPos( &ptPos );
  20. ScreenToClient( hWnd, &ptPos );
  21. //根据位置加载光标
  22. HCURSOR hCursor = NULL;
  23. if( ptPos.x < rcClient.right/2 )
  24. {
  25. if( ptPos.y < rcClient.bottom/2 )
  26. {
  27. hCursor = LoadCursor( NULL, IDC_SIZEALL );
  28. }
  29. else
  30. {
  31. hCursor = LoadCursor( NULL, IDC_CROSS );
  32. }
  33. }
  34. else
  35. {
  36. if( ptPos.y < rcClient.bottom/2 )
  37. {
  38. hCursor = LoadCursor( NULL, IDC_WAIT );
  39. }
  40. else
  41. {
  42. hCursor = LoadCursor( NULL, IDC_UPARROW );
  43. }
  44. }
  45. // 设置光标
  46. SetCursor( hCursor );
  47. return TRUE;
  48. }
  49. LRESULT CALLBACK WndProc( HWND hWnd,
  50. UINT nMsg,
  51. WPARAM wParam,
  52. LPARAM lParam )
  53. {
  54. switch( nMsg )
  55. {
  56. case WM_SETCURSOR:
  57. if( TRUE == OnSetCursor( hWnd, nMsg,
  58. wParam, lParam ) )
  59. {
  60. return 0;
  61. }
  62. break;
  63. case WM_DESTROY:
  64. PostQuitMessage( 0 );
  65. return 0;
  66. }
  67. return DefWindowProc( hWnd, nMsg,
  68. wParam, lParam );
  69. }
  70. BOOL RegisterWnd( LPSTR pszClassName )
  71. {
  72. WNDCLASSEX wce = { 0 };
  73. wce.cbSize = sizeof( wce );
  74. wce.cbClsExtra = 0;
  75. wce.cbWndExtra = 0;
  76. wce.hbrBackground = HBRUSH(COLOR_WINDOW);
  77. wce.hCursor =
  78. LoadCursor( g_hInst, MAKEINTRESOURCE(IDC_CURSOR1) );
  79. wce.hIcon =
  80. LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_MAIN) );
  81. wce.hIconSm = NULL;
  82. wce.hInstance = g_hInst;
  83. wce.lpfnWndProc = WndProc;
  84. wce.lpszClassName = pszClassName;
  85. wce.lpszMenuName = NULL;
  86. wce.style = CS_HREDRAW|CS_VREDRAW;
  87. ATOM nAtom = RegisterClassEx( &wce );
  88. if( 0 == nAtom )
  89. {
  90. return FALSE;
  91. }
  92. return TRUE;
  93. }
  94. HWND CreateWnd( LPSTR pszClassName )
  95. {
  96. HWND hWnd = CreateWindowEx( 0,
  97. pszClassName, "MyWnd",
  98. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
  99. CW_USEDEFAULT, CW_USEDEFAULT,
  100. CW_USEDEFAULT, NULL, NULL, g_hInst,
  101. NULL );
  102. return hWnd;
  103. }
  104. void DisplayWnd( HWND hWnd )
  105. {
  106. ShowWindow( hWnd, SW_SHOW );
  107. UpdateWindow( hWnd );
  108. }
  109. void Message( )
  110. {
  111. MSG msg = { 0 };
  112. while( GetMessage( &msg, NULL, 0, 0 ) )
  113. {
  114. TranslateMessage( &msg );
  115. DispatchMessage( &msg );
  116. }
  117. }
  118. int APIENTRY WinMain(HINSTANCE hInstance,
  119. HINSTANCE hPrevInstance,
  120. LPSTR lpCmdLine,
  121. int nCmdShow)
  122. {
  123. g_hInst = hInstance;
  124. RegisterWnd( "MYWND" );
  125. HWND hWnd = CreateWnd( "MYWND" );
  126. DisplayWnd( hWnd );
  127. Message( );
  128. return 0;
  129. }

  4 字符串资源
 
    4.1 包含字符串的资源
    4.2 使用
      int LoadString(
      HINSTANCE hInstance,//程序句柄
       UINT uID, //字符串资源的ID
        LPTSTR lpBuffer, //存放字符串的BUFF
        int nBufferMax ); //BUFF的大小
      返回获取字符串的长度
     
  5 菜单资源
    5.1 添加菜单资源
    5.2 加载菜单资源
     HMENU LoadMenu(
      HINSTANCE hInstance, //应用程序句柄
      LPCTSTR lpMenuName );//菜单ID字符串
     返回加载成功的菜单的句柄
    5.3 命令处理
      使用添加的菜单ID的宏,在WM_COMMAND消息中,处理菜单命令.

View Code

  1. // WinRes.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h"
  5. HINSTANCE g_hInst = NULL;
  6. BOOL OnSetCursor( HWND hWnd, UINT nMsg,
  7. WPARAM wParam, LPARAM lParam )
  8. { //判断是否是位于客户区之上
  9. int nHitTest = LOWORD( lParam );
  10. if( HTCLIENT != nHitTest )
  11. { //不在客户区,返回FALSE,
  12. //让DefWindowProc处理
  13. return FALSE;
  14. }
  15. //获得窗口的客户区
  16. RECT rcClient = { 0 };
  17. GetClientRect( hWnd, &rcClient );
  18. //获得当前光标的位置
  19. POINT ptPos = { 0 };
  20. GetCursorPos( &ptPos );
  21. ScreenToClient( hWnd, &ptPos );
  22. //根据位置加载光标
  23. HCURSOR hCursor = NULL;
  24. if( ptPos.x < rcClient.right/2 )
  25. {
  26. if( ptPos.y < rcClient.bottom/2 )
  27. {
  28. hCursor = LoadCursor( NULL, IDC_SIZEALL );
  29. }
  30. else
  31. {
  32. hCursor = LoadCursor( NULL, IDC_CROSS );
  33. }
  34. }
  35. else
  36. {
  37. if( ptPos.y < rcClient.bottom/2 )
  38. {
  39. hCursor = LoadCursor( NULL, IDC_WAIT );
  40. }
  41. else
  42. {
  43. hCursor = LoadCursor( NULL, IDC_UPARROW );
  44. }
  45. }
  46. // 设置光标
  47. SetCursor( hCursor );
  48. return TRUE;
  49. }
  50. void OnCommand( HWND hWnd, UINT nMsg,
  51. WPARAM wParam, LPARAM lParam )
  52. {
  53. int nCmdID = LOWORD( wParam );
  54. switch( nCmdID )
  55. {
  56. case ID_EXIT:
  57. PostQuitMessage( 0 );
  58. break;
  59. case ID_ABOUT:
  60. break;
  61. }
  62. }
  63. LRESULT CALLBACK WndProc( HWND hWnd,
  64. UINT nMsg,
  65. WPARAM wParam,
  66. LPARAM lParam )
  67. {
  68. switch( nMsg )
  69. {
  70. case WM_COMMAND:
  71. OnCommand( hWnd, nMsg, wParam, lParam );
  72. break;
  73. case WM_SETCURSOR:
  74. if( TRUE == OnSetCursor( hWnd, nMsg,
  75. wParam, lParam ) )
  76. {
  77. return 0;
  78. }
  79. break;
  80. case WM_DESTROY:
  81. PostQuitMessage( 0 );
  82. return 0;
  83. }
  84. return DefWindowProc( hWnd, nMsg,
  85. wParam, lParam );
  86. }
  87. BOOL RegisterWnd( LPSTR pszClassName )
  88. {
  89. WNDCLASSEX wce = { 0 };
  90. wce.cbSize = sizeof( wce );
  91. wce.cbClsExtra = 0;
  92. wce.cbWndExtra = 0;
  93. wce.hbrBackground = HBRUSH(COLOR_WINDOW);
  94. wce.hCursor =
  95. LoadCursor( g_hInst, MAKEINTRESOURCE(IDC_CURSOR1) );
  96. wce.hIcon =
  97. LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_MAIN) );
  98. wce.hIconSm = NULL;
  99. wce.hInstance = g_hInst;
  100. wce.lpfnWndProc = WndProc;
  101. wce.lpszClassName = pszClassName;
  102. wce.lpszMenuName = NULL;
  103. wce.style = CS_HREDRAW|CS_VREDRAW;
  104. ATOM nAtom = RegisterClassEx( &wce );
  105. if( 0 == nAtom )
  106. {
  107. return FALSE;
  108. }
  109. return TRUE;
  110. }
  111. HWND CreateWnd( LPSTR pszClassName )
  112. {
  113. //加载字符串资源
  114. CHAR szText[260] = { 0 };
  115. LoadString( g_hInst, IDS_MAIN, szText, 260 );
  116. //加载菜单
  117. HMENU hMenu = LoadMenu( g_hInst,
  118. MAKEINTRESOURCE(IDR_MAIN) );
  119. //创建窗口
  120. HWND hWnd = CreateWindowEx( 0,
  121. pszClassName, szText,
  122. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
  123. CW_USEDEFAULT, CW_USEDEFAULT,
  124. CW_USEDEFAULT, NULL, hMenu, g_hInst,
  125. NULL );
  126. return hWnd;
  127. }
  128. void DisplayWnd( HWND hWnd )
  129. {
  130. ShowWindow( hWnd, SW_SHOW );
  131. UpdateWindow( hWnd );
  132. }
  133. void Message( )
  134. {
  135. MSG msg = { 0 };
  136. while( GetMessage( &msg, NULL, 0, 0 ) )
  137. {
  138. TranslateMessage( &msg );
  139. DispatchMessage( &msg );
  140. }
  141. }
  142. int APIENTRY WinMain(HINSTANCE hInstance,
  143. HINSTANCE hPrevInstance,
  144. LPSTR lpCmdLine,
  145. int nCmdShow)
  146. {
  147. g_hInst = hInstance;
  148. RegisterWnd( "MYWND" );
  149. HWND hWnd = CreateWnd( "MYWND" );
  150. DisplayWnd( hWnd );
  151. Message( );
  152. return 0;
  153. }

  6 加速键资源
    6.1 加速键的作用
      可以使用加速键执行命令. 例如Ctrl+S存盘.
    6.2 加速键资源的添加
    6.3 加速键的使用
      6.3.1 加载
       HACCEL LoadAccelerators(
     HINSTANCE hInstance,//资源所在的应用程序句柄
        LPCTSTR lpTableName ); //加速键表的ID字符串
        加载成功返回加速键表的句柄
      6.3.2 增加消息处理

  1. int TranslateAccelerator(
  2. HWND hWnd, //处理加速键的窗口句柄
  3. HACCEL hAccTable, //加速键表
  4. LPMSG lpMsg );//MSG结构的地址

    6.4 关于加速键的消息
      TranslateAccelerator的作用是将WM_KEYDOWN或者WM_SYSKEYDOWN消息,翻译成WM_COMMAND或者WM_SYSCOMMAND消息.
      当收到KEYDOWN或者SYSKEYDOWN的消息时,会根据加速键表中按键和命令ID对应关系,找到相应的命令ID,然后调用窗口处理函数,执行WM_COMMAND或者WM_SYSCOMMAND消息.
      当找到对应命令ID并执行后,TranslateAccelerator返回非零,那么就不再执行后续的处理,消息循环等候下一条消息。否则,继续让消息循环中的TansnlateMessage和DispatchMessage处理。

View Code

  1. // WinRes.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h"
  5. HINSTANCE g_hInst = NULL;
  6. BOOL OnSetCursor( HWND hWnd, UINT nMsg,
  7. WPARAM wParam, LPARAM lParam )
  8. { //判断是否是位于客户区之上
  9. int nHitTest = LOWORD( lParam );
  10. if( HTCLIENT != nHitTest )
  11. { //不在客户区,返回FALSE,
  12. //让DefWindowProc处理
  13. return FALSE;
  14. }
  15. //获得窗口的客户区
  16. RECT rcClient = { 0 };
  17. GetClientRect( hWnd, &rcClient );
  18. //获得当前光标的位置
  19. POINT ptPos = { 0 };
  20. GetCursorPos( &ptPos );
  21. ScreenToClient( hWnd, &ptPos );
  22. //根据位置加载光标
  23. HCURSOR hCursor = NULL;
  24. if( ptPos.x < rcClient.right/2 )
  25. {
  26. if( ptPos.y < rcClient.bottom/2 )
  27. {
  28. hCursor = LoadCursor( NULL, IDC_SIZEALL );
  29. }
  30. else
  31. {
  32. hCursor = LoadCursor( NULL, IDC_CROSS );
  33. }
  34. }
  35. else
  36. {
  37. if( ptPos.y < rcClient.bottom/2 )
  38. {
  39. hCursor = LoadCursor( NULL, IDC_WAIT );
  40. }
  41. else
  42. {
  43. hCursor = LoadCursor( NULL, IDC_UPARROW );
  44. }
  45. }
  46. // 设置光标
  47. SetCursor( hCursor );
  48. return TRUE;
  49. }
  50. void OnCommand( HWND hWnd, UINT nMsg,
  51. WPARAM wParam, LPARAM lParam )
  52. {
  53. int nCmdID = LOWORD( wParam );
  54. switch( nCmdID )
  55. {
  56. case ID_EXIT:
  57. PostQuitMessage( 0 );
  58. break;
  59. case ID_ABOUT:
  60. break;
  61. }
  62. }
  63. LRESULT CALLBACK WndProc( HWND hWnd,
  64. UINT nMsg,
  65. WPARAM wParam,
  66. LPARAM lParam )
  67. {
  68. switch( nMsg )
  69. {
  70. case WM_COMMAND:
  71. OnCommand( hWnd, nMsg, wParam, lParam );
  72. break;
  73. case WM_SETCURSOR:
  74. if( TRUE == OnSetCursor( hWnd, nMsg,
  75. wParam, lParam ) )
  76. {
  77. return 0;
  78. }
  79. break;
  80. case WM_DESTROY:
  81. PostQuitMessage( 0 );
  82. return 0;
  83. }
  84. return DefWindowProc( hWnd, nMsg,
  85. wParam, lParam );
  86. }
  87. BOOL RegisterWnd( LPSTR pszClassName )
  88. {
  89. WNDCLASSEX wce = { 0 };
  90. wce.cbSize = sizeof( wce );
  91. wce.cbClsExtra = 0;
  92. wce.cbWndExtra = 0;
  93. wce.hbrBackground = HBRUSH(COLOR_WINDOW);
  94. wce.hCursor =
  95. LoadCursor( g_hInst, MAKEINTRESOURCE(IDC_CURSOR1) );
  96. wce.hIcon =
  97. LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_MAIN) );
  98. wce.hIconSm = NULL;
  99. wce.hInstance = g_hInst;
  100. wce.lpfnWndProc = WndProc;
  101. wce.lpszClassName = pszClassName;
  102. wce.lpszMenuName = NULL;
  103. wce.style = CS_HREDRAW|CS_VREDRAW;
  104. ATOM nAtom = RegisterClassEx( &wce );
  105. if( 0 == nAtom )
  106. {
  107. return FALSE;
  108. }
  109. return TRUE;
  110. }
  111. HWND CreateWnd( LPSTR pszClassName )
  112. {
  113. //加载字符串资源
  114. CHAR szText[260] = { 0 };
  115. LoadString( g_hInst, IDS_MAIN, szText, 260 );
  116. //加载菜单
  117. HMENU hMenu = LoadMenu( g_hInst,
  118. MAKEINTRESOURCE(IDR_MAIN) );
  119. //创建窗口
  120. HWND hWnd = CreateWindowEx( 0,
  121. pszClassName, szText,
  122. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
  123. CW_USEDEFAULT, CW_USEDEFAULT,
  124. CW_USEDEFAULT, NULL, hMenu, g_hInst,
  125. NULL );
  126. return hWnd;
  127. }
  128. void DisplayWnd( HWND hWnd )
  129. {
  130. ShowWindow( hWnd, SW_SHOW );
  131. UpdateWindow( hWnd );
  132. }
  133. void Message( HWND hWnd )
  134. {
  135. //加载加速键表
  136. HACCEL hAccel = LoadAccelerators(
  137. g_hInst, MAKEINTRESOURCE(IDR_ACCEL) );
  138. //消息循环
  139. MSG msg = { 0 };
  140. while( GetMessage( &msg, NULL, 0, 0 ) )
  141. { // 增加加速键的消息处理
  142. if( !TranslateAccelerator( hWnd, hAccel, &msg ) )
  143. { //字符消息处理
  144. TranslateMessage( &msg );
  145. //消息派发
  146. DispatchMessage( &msg );
  147. }
  148. }
  149. }
  150. int APIENTRY WinMain(HINSTANCE hInstance,
  151. HINSTANCE hPrevInstance,
  152. LPSTR lpCmdLine,
  153. int nCmdShow)
  154. {
  155. g_hInst = hInstance;
  156. RegisterWnd( "MYWND" );
  157. HWND hWnd = CreateWnd( "MYWND" );
  158. DisplayWnd( hWnd );
  159. Message( hWnd );
  160. return 0;
  161. }

四 程序编写

  1 定时器设置
    实现定时器的关闭和打开

代码如下,这个是新建一个win32程序,选择简单的hello word程序。和之前的有点小不一样。

View Code

  1. // WinCase.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h"
  5.  
  6. #define MAX_LOADSTRING 100
  7.  
  8. // Global Variables:
  9. HINSTANCE hInst; // current instance
  10. TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
  11. TCHAR szWindowClass[MAX_LOADSTRING];
  12. int g_nX = 0;
  13. int g_nY = 0; // The title bar text
  14. // Foward declarations of functions included in this code module:
  15. ATOM MyRegisterClass(HINSTANCE hInstance);
  16. BOOL InitInstance(HINSTANCE, int);
  17. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  18. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  19. int APIENTRY WinMain(HINSTANCE hInstance,
  20. HINSTANCE hPrevInstance,
  21. LPSTR lpCmdLine,
  22. int nCmdShow)
  23. {
  24. // TODO: Place code here.
  25. MSG msg;
  26. HACCEL hAccelTable;
  27. // Initialize global strings
  28. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  29. LoadString(hInstance, IDC_WINCASE, szWindowClass, MAX_LOADSTRING);
  30. MyRegisterClass(hInstance);
  31. // Perform application initialization:
  32. if (!InitInstance (hInstance, nCmdShow))
  33. {
  34. return FALSE;
  35. }
  36. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WINCASE);
  37. // Main message loop:
  38. while (GetMessage(&msg, NULL, 0, 0))
  39. {
  40. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  41. {
  42. TranslateMessage(&msg);
  43. DispatchMessage(&msg);
  44. }
  45. }
  46. return msg.wParam;
  47. }
  48. //
  49. // FUNCTION: MyRegisterClass()
  50. //
  51. // PURPOSE: Registers the window class.
  52. //
  53. // COMMENTS:
  54. //
  55. // This function and its usage is only necessary if you want this code
  56. // to be compatible with Win32 systems prior to the \'RegisterClassEx\'
  57. // function that was added to Windows 95. It is important to call this function
  58. // so that the application will get \'well formed\' small icons associated
  59. // with it.
  60. //
  61. ATOM MyRegisterClass(HINSTANCE hInstance)
  62. {
  63. WNDCLASSEX wcex;
  64. wcex.cbSize = sizeof(WNDCLASSEX);
  65. wcex.style = CS_HREDRAW | CS_VREDRAW;
  66. wcex.lpfnWndProc = (WNDPROC)WndProc;
  67. wcex.cbClsExtra = 0;
  68. wcex.cbWndExtra = 0;
  69. wcex.hInstance = hInstance;
  70. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WINCASE);
  71. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  72. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  73. wcex.lpszMenuName = (LPCSTR)IDC_WINCASE;
  74. wcex.lpszClassName = szWindowClass;
  75. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  76. return RegisterClassEx(&wcex);
  77. }
  78. //
  79. // FUNCTION: InitInstance(HANDLE, int)
  80. //
  81. // PURPOSE: Saves instance handle and creates main window
  82. //
  83. // COMMENTS:
  84. //
  85. // In this function, we save the instance handle in a global variable and
  86. // create and display the main program window.
  87. //
  88. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  89. {
  90. HWND hWnd;
  91. hInst = hInstance; // Store instance handle in our global variable
  92. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  93. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  94. if (!hWnd)
  95. {
  96. return FALSE;
  97. }
  98. ShowWindow(hWnd, nCmdShow);
  99. UpdateWindow(hWnd);
  100. return TRUE;
  101. }
  102. //
  103. // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
  104. //
  105. // PURPOSE: Processes messages for the main window.
  106. //
  107. // WM_COMMAND - process the application menu
  108. // WM_PAINT - Paint the main window
  109. // WM_DESTROY - post a quit message and return
  110. //
  111. //
  112. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  113. {
  114. int wmId, wmEvent;
  115. PAINTSTRUCT ps;
  116. HDC hdc;
  117. TCHAR szHello[MAX_LOADSTRING];
  118. LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
  119. switch (message)
  120. {
  121. case WM_COMMAND:
  122. wmId = LOWORD(wParam);
  123. wmEvent = HIWORD(wParam);
  124. // Parse the menu selections:
  125. switch (wmId)
  126. {
  127. case ID_BEGIN:
  128. SetTimer( hWnd, 1001, 1 * 1000, NULL );
  129. break;
  130. case ID_STOP:
  131. KillTimer( hWnd, 1001 );
  132. break;
  133. case IDM_ABOUT:
  134. DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  135. break;
  136. case IDM_EXIT:
  137. DestroyWindow(hWnd);
  138. break;
  139. default:
  140. return DefWindowProc(hWnd, message, wParam, lParam);
  141. }
  142. break;
  143. case WM_PAINT:
  144. {
  145. hdc = BeginPaint(hWnd, &ps);
  146. CHAR szText[] = "Hello Ball";
  147. TextOut( hdc, g_nX, g_nY, szText,
  148. strlen(szText) );
  149. EndPaint(hWnd, &ps);
  150. }
  151. break;
  152. case WM_DESTROY:
  153. PostQuitMessage(0);
  154. break;
  155. case WM_TIMER:
  156. g_nX += 5;
  157. g_nY += 5;
  158. InvalidateRect( hWnd, NULL, TRUE );
  159. break;
  160. default:
  161. return DefWindowProc(hWnd, message, wParam, lParam);
  162. }
  163. return 0;
  164. }
  165. // Mesage handler for about box.
  166. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  167. {
  168. switch (message)
  169. {
  170. case WM_INITDIALOG:
  171. return TRUE;
  172. case WM_COMMAND:
  173. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  174. {
  175. EndDialog(hDlg, LOWORD(wParam));
  176. return TRUE;
  177. }
  178. break;
  179. }
  180. return FALSE;
  181. }

 

 

版权声明:本文为tangzhengyue原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/tangzhengyue/archive/2012/08/14/2638900.html