接上一篇:

 

  1. case WM_CREATE: 
  2.     HMENU hMenu, hSubMenu; 
  3.     HICON hIcon, hIconSm; 
  4.  
  5.     hMenu = CreateMenu();//创建主菜单 
  6.      
  7.     hSubMenu = CreatePopupMenu();//创建弹出菜单 
  8.     AppendMenu(hSubMenu,MF_STRING,IDM_FILE_OPEN,TEXT("打开(&O)"));//打开菜单 
  9.     AppendMenu(hSubMenu,MF_SEPARATOR,0,NULL);//分隔线 
  10.     AppendMenu(hSubMenu, MF_STRING, IDM_FILE_EXIT, TEXT("退出(&X)"));//退出菜单 
  11.      
  12.     AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, TEXT("文件(&F)"));//加入File菜单 
  13.  
  14.     hSubMenu = CreatePopupMenu(); 
  15.     AppendMenu(hSubMenu, MF_STRING, IDM_EDIT_UNDO, TEXT("撤销(&U)")); 
  16.     AppendMenu(hSubMenu,MF_STRING,IDM_EDIT_REDO,TEXT("重做(&R)")); 
  17.      
  18.     AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, TEXT("编辑(&E)"));//加入编辑菜单 
  19.  
  20.     SetMenu(hWnd, hMenu);//设置为窗口的主菜单 
  21.      
  22.     hIcon = (HICON)LoadImage(NULL, TEXT("tao.ico"), IMAGE_ICON, 32, 32, LR_LOADFROMFILE); 
  23.     if(hIcon) 
  24.         SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 
  25.     else 
  26.         MessageBox(hWnd, TEXT("不能加载大图标!"), TEXT("错误"), MB_OK | MB_ICONERROR); 
  27.  
  28.     hIconSm = (HICON)LoadImage(NULL, TEXT("tao.ico"), IMAGE_ICON, 16, 16, LR_LOADFROMFILE); 
  29.     if(hIconSm) 
  30.         SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); 
  31.     else 
  32.         MessageBox(hWnd, TEXT("不能加载小图标!"), TEXT("错误"), MB_OK | MB_ICONERROR); 
  33.          
  34.     return 0; 

当然也可以在窗口创建时动态设置菜单,而不是加载资源菜单。

这里同时修改了窗口的图标,通过WM_SETICON消息。

有了菜单,但是现在单击没有什么反应,我们还需要处理WM_COMMAND窗体通告消息。

 

  1. The WM_COMMAND message is sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, or when an accelerator keystroke is translated.  

对应菜单来说,wParam和lParam这2个参数具体说明如下:

wParam这个32位参数的高位字(高16位)为0,低位字存储的菜单的标识符IDM_*那些。lParam这个参数为0.

我们只需要处理WM_COMMAND,根据标识符不同处理每个菜单的行为。

  1. case WM_COMMAND: 
  2.     switch(LOWORD(wParam)) 
  3.     { 
  4.         case IDM_FILE_EXIT: 
  5.             PostMessage(hWnd,WM_CLOSE,0,0); 
  6.             break
  7.         case IDM_FILE_OPEN: 
  8.             OPENFILENAME ofn; 
  9.             TCHAR szFileName[256]; 
  10.             TCHAR title[50]; 
  11.              
  12.             ZeroMemory(&ofn,sizeof(ofn)); 
  13.             ofn.lStructSize=sizeof(ofn); 
  14.              
  15.             ofn.hwndOwner=hWnd;//Owner窗口 
  16.             ofn.lpstrFile=szFileName;//接收文件名的buffer 
  17.             ofn.lpstrFile[0] = '\0'
  18.             ofn.nMaxFile = sizeof(szFileName); 
  19.             ofn.lpstrFilter = TEXT("所有文件 (*.*)\0*.*\0文本文件 (*.txt)\0*.TXT\0图片文件 (*.bmp;*.jpg;*.png;*.gif)\0*.bmp;*.jpg;*.png;*.gif\0\0"); 
  20.             ofn.nFilterIndex = 2;/*默认显示过滤器:图片文件的*/ 
  21.             ofn.lpstrFileTitle = NULL; 
  22.             ofn.nMaxFileTitle = 0; 
  23.             ofn.lpstrInitialDir = NULL; 
  24.             ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 
  25.             ofn.lpstrTitle=TEXT("打开一个文件吧");//设置对话框的标题 
  26.              
  27.             if(GetOpenFileName(&ofn)==TRUE) 
  28.             { 
  29.                 MessageBox(hWnd,szFileName,TEXT("文件名"),0); 
  30.             } 
  31.             break
  32.     } 
  33.     return 0; 
  34. }    

详细的OPENFILENAME结构体,参考MSDN.

完整代码:

  1. #include <windows.h> 
  2. #include "resource.h" 
  3.  
  4. LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); 
  5.  
  6. int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd) 
  7.     WNDCLASSEX wClass; 
  8.     ZeroMemory(&wClass,sizeof(WNDCLASSEX)); 
  9.     wClass.cbClsExtra=NULL; 
  10.     wClass.cbSize=sizeof(WNDCLASSEX); 
  11.     wClass.cbWndExtra=NULL; 
  12.     wClass.hbrBackground=(HBRUSH)COLOR_WINDOW; 
  13.     wClass.hCursor=LoadCursor(NULL,IDC_ARROW); 
  14.     wClass.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_MYICON)); 
  15.     wClass.hIconSm=(HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0); 
  16.     wClass.hInstance=hInst; 
  17.     wClass.lpfnWndProc=(WNDPROC)WinProc; 
  18.     wClass.lpszClassName=TEXT("窗口类名"); 
  19.     wClass.lpszMenuName=NULL;/*MAKEINTRESOURCE(IDR_MYMENU)*/ 
  20.     wClass.style=CS_HREDRAW|CS_VREDRAW; 
  21.  
  22.     if(!RegisterClassEx(&wClass)) 
  23.     { 
  24.         int nResult=GetLastError(); 
  25.         MessageBox(NULL, 
  26.             TEXT("注册窗口类失败."), 
  27.             TEXT("失败"), 
  28.             MB_ICONERROR); 
  29.     } 
  30.      
  31.     //HMENU hMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_CNMENU)); 
  32.     HWND hWnd=CreateWindowEx(NULL, 
  33.             TEXT("窗口类名"), 
  34.             TEXT("win32应用程序"), 
  35.             WS_OVERLAPPEDWINDOW, 
  36.             200, 
  37.             200, 
  38.             640, 
  39.             480, 
  40.             NULL, 
  41.             NULL,/*hMenu*/ 
  42.             hInst, 
  43.             NULL); 
  44.  
  45.     if(!hWnd) 
  46.     { 
  47.         int nResult=GetLastError(); 
  48.  
  49.         MessageBox(NULL, 
  50.             TEXT("窗口创建失败."), 
  51.             TEXT("失败"), 
  52.             MB_ICONERROR); 
  53.     } 
  54.  
  55.     ShowWindow(hWnd,nShowCmd); 
  56.  
  57.     MSG msg; 
  58.     ZeroMemory(&msg,sizeof(MSG));/*清零*/ 
  59.  
  60.     while(GetMessage(&msg,NULL,0,0) > 0) 
  61.     { 
  62.         TranslateMessage(&msg); 
  63.         DispatchMessage(&msg); 
  64.     } 
  65.  
  66.     return 0; 
  67.  
  68. LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) 
  69.     switch(msg) 
  70.     { 
  71.         case WM_CREATE: 
  72.         { 
  73.             HMENU hMenu, hSubMenu; 
  74.             HICON hIcon, hIconSm; 
  75.  
  76.             hMenu = CreateMenu();//创建主菜单 
  77.              
  78.             hSubMenu = CreatePopupMenu();//创建弹出菜单 
  79.             AppendMenu(hSubMenu,MF_STRING,IDM_FILE_OPEN,TEXT("打开(&O)"));//打开菜单 
  80.             AppendMenu(hSubMenu,MF_SEPARATOR,0,NULL);//分隔线 
  81.             AppendMenu(hSubMenu, MF_STRING, IDM_FILE_EXIT, TEXT("退出(&X)"));//退出菜单 
  82.              
  83.             AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, TEXT("文件(&F)"));//加入File菜单 
  84.  
  85.             hSubMenu = CreatePopupMenu(); 
  86.             AppendMenu(hSubMenu, MF_STRING, IDM_EDIT_UNDO, TEXT("撤销(&U)")); 
  87.             AppendMenu(hSubMenu,MF_STRING,IDM_EDIT_REDO,TEXT("重做(&R)")); 
  88.              
  89.             AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, TEXT("编辑(&E)"));//加入编辑菜单 
  90.  
  91.             SetMenu(hWnd, hMenu);//设置为窗口的主菜单 
  92.              
  93.             hIcon = (HICON)LoadImage(NULL, TEXT("tao.ico"), IMAGE_ICON, 32, 32, LR_LOADFROMFILE); 
  94.             if(hIcon) 
  95.                 SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 
  96.             else 
  97.                 MessageBox(hWnd, TEXT("不能加载大图标!"), TEXT("错误"), MB_OK | MB_ICONERROR); 
  98.  
  99.             hIconSm = (HICON)LoadImage(NULL, TEXT("tao.ico"), IMAGE_ICON, 16, 16, LR_LOADFROMFILE); 
  100.             if(hIconSm) 
  101.                 SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); 
  102.             else 
  103.                 MessageBox(hWnd, TEXT("不能加载小图标!"), TEXT("错误"), MB_OK | MB_ICONERROR); 
  104.                  
  105.             return 0; 
  106.         } 
  107.         case WM_COMMAND: 
  108.         { 
  109.             switch(LOWORD(wParam)) 
  110.             { 
  111.                 case IDM_FILE_EXIT: 
  112.                     PostMessage(hWnd,WM_CLOSE,0,0); 
  113.                     break
  114.                 case IDM_FILE_OPEN: 
  115.                     OPENFILENAME ofn; 
  116.                     TCHAR szFileName[256]; 
  117.                     TCHAR title[50]; 
  118.                      
  119.                     ZeroMemory(&ofn,sizeof(ofn)); 
  120.                     ofn.lStructSize=sizeof(ofn); 
  121.                      
  122.                     ofn.hwndOwner=hWnd;//Owner窗口 
  123.                     ofn.lpstrFile=szFileName;//接收文件名的buffer 
  124.                     ofn.lpstrFile[0] = '\0'
  125.                     ofn.nMaxFile = sizeof(szFileName); 
  126.                     ofn.lpstrFilter = TEXT("所有文件 (*.*)\0*.*\0文本文件 (*.txt)\0*.TXT\0图片文件 (*.bmp;*.jpg;*.png;*.gif)\0*.bmp;*.jpg;*.png;*.gif\0\0"); 
  127.                     ofn.nFilterIndex = 2;/*默认显示过滤器:图片文件的*/ 
  128.                     ofn.lpstrFileTitle = NULL; 
  129.                     ofn.nMaxFileTitle = 0; 
  130.                     ofn.lpstrInitialDir = NULL; 
  131.                     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 
  132.                     ofn.lpstrTitle=TEXT("打开一个文件吧");//设置对话框的标题 
  133.                      
  134.                     if(GetOpenFileName(&ofn)==TRUE) 
  135.                     { 
  136.                         MessageBox(hWnd,szFileName,TEXT("文件名"),0); 
  137.                     } 
  138.                     break
  139.             } 
  140.             return 0; 
  141.         }    
  142.         case WM_LBUTTONDOWN: 
  143.         { 
  144.             TCHAR szFileName[MAX_PATH]; 
  145.             HINSTANCE hInstance = GetModuleHandle(NULL); 
  146.             GetModuleFileName(hInstance, szFileName, MAX_PATH); 
  147.             MessageBox(hWnd, szFileName, TEXT("此程序是:"), MB_OK | MB_ICONINFORMATION);     
  148.             return 0;         
  149.         } 
  150.         case WM_DESTROY: 
  151.         { 
  152.             PostQuitMessage(0); 
  153.             return 0; 
  154.         } 
  155.         break
  156.     } 
  157.  
  158.     return DefWindowProc(hWnd,msg,wParam,lParam); 

 

注:不足,字符串都是硬编码的。