一、菜单
1)分类
-
- 系统菜单: 程序左上角的图标点击鼠标左键、或者在标题栏点击鼠标右键,出现的就是系统菜单。主要内容有:还原、移动、大小、最小化、最大化、关闭。
- 顶层菜单: 一般出现在程序左上角位置。
- 弹出菜单: 程序的窗口中点击鼠标右键(必要的时候左键也可以)弹出的菜单,或者顶层菜单点击后出现的菜单,都称为弹出式菜单(也称为右键菜单)。
2)添加菜单
菜单创建方式:
1.从资源中加载菜单。
右键项目-》添加-》资源-》menu ,然后加载菜单资源
wc.lpszMenuName = MAKEINTRESOURCEW(菜单id);
2.自己通过API函数创建。
①创建系统菜单
void OnCreate(HWND hWnd) { HMENU hMain = CreateMenu(); //hFile、hHelp必须是全局变量 hFile = CreatePopupMenu(); hHelp = CreatePopupMenu(); AppendMenu(hFile, MF_STRING, 1001, __TEXT("新建")); AppendMenu(hFile, MF_SEPARATOR, 1002, __TEXT("分割线")); AppendMenu(hFile, MF_STRING, 1003, __TEXT("退出")); AppendMenu(hHelp, MF_STRING, 1004, __TEXT("关于")); AppendMenu(hMain, MF_POPUP, (UINT)hFile, __TEXT("文件")); AppendMenu(hMain, MF_POPUP, (UINT)hHelp, __TEXT("帮助")); SetMenu(hWnd, hMain); }
②创建右键弹出菜单
case WM_RBUTTONDOWN: { HMENU hMenu = CreatePopupMenu(); // 创建一个弹出式菜单 AppendMenu(hMenu, MF_CHECKED, 3001, __TEXT("第一个菜单项")); // 添加第一个菜单项,打勾的 HMENU hMenu1 = CreateMenu(); // 创建子菜单1 AppendMenu(hMenu1, MF_CHECKED, 5001, L"菜单1.1(&A)"); // 菜单1的第1个项 AppendMenu(hMenu1, 0, 5002, __TEXT("菜单1.2(&B)")); // 菜单1的第2个项 AppendMenu(hMenu1, 0, 5003, __TEXT("菜单1.3")); // 菜单1的第3个项 AppendMenu(hMenu, MF_POPUP, (UINT)hMenu1, __TEXT("子菜单2(&P)"));// MF_POPUP,将菜单1作为弹出菜单的子菜单 HMENU hMenu2 = CreateMenu(); AppendMenu(hMenu2, MF_BYPOSITION | MF_CHECKED, 6001, __TEXT("菜单2.1"));// 菜单2的第1个项 AppendMenu(hMenu2, MF_BYPOSITION, 6002, __TEXT("菜单2.2")); // 菜单2的第2个项 AppendMenu(hMenu2, MF_BYCOMMAND, 6003, __TEXT("菜单2.3")); // 菜单2的第3个项 InsertMenu(hMenu2, 6003, MF_BYCOMMAND | MF_SEPARATOR, 6004, __TEXT("-")); // 一条水平区分线 AppendMenu(hMenu, MF_POPUP, (UINT)hMenu2, __TEXT("子菜单2(&E)"));// MF_POPUP,将菜单2作为弹出菜单的子菜单 POINT pt; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); ClientToScreen(hWnd, &pt); // 把客户区坐标转换为屏幕坐标 //弹出右键菜单 TrackPopupMenu(hMenu,//哪一个菜单 TPM_LEFTALIGN | TPM_TOPALIGN,//菜单风格,对齐方式 pt.x, pt.y,//鼠标点击的位置 0, hWnd, nullptr); }break;
3)响应菜单事件
void OnCommand(HWND hWnd,WPARAM wParam) { SHORT nMenuID = LOWORD(wParam); switch(nMenuID) { case 1001: { if (g_State) { CheckMenuItem(hFile,1001,MF_BYCOMMAND | MF_CHECKED); EnableMenuItem(hHelp,1004,MF_BYCOMMAND | MF_ENABLED);
g_State = FALSE;
}
else
{
CheckMenuItem(hFile,0,MF_BYPOSITION | MF_UNCHECKED);
EnableMenuItem(hHelp,1004,MF_BYCOMMAND | MF_DISABLED);
g_State = TRUE;
}
MessageBox(hWnd,__TEXT("点击了新建"),__TEXT("提示"),MB_OK);
}
break;
case 1003:
{
PostQuitMessage(0);
}
break;
case 1004:
{
MessageBox(hWnd,__TEXT("点击了关于"),__TEXT("提示"),MB_OK);
}
break;
case 1005:
MessageBox(hWnd,__TEXT("点击了NEW"),__TEXT("提示"),MB_OK);
break; }}
二、dialog窗口
1)对话框一般分为两种类型:模态类型(modal)与非模态类型(modeless)。
所谓模态对话框,就是指除非采取有效的关闭手段,用户的鼠标焦点或者输入光标将一直停留在其上的对话框。非模态对话框则不会强制此种特性,用户可以在当前对话框以及其他窗口间进行切换。模式对话 框一般是在栈中生成的,所以EndDialog可能只是隐藏窗口,并没有销毁,当模式对话框对应的对象离开生命区时即销毁对话框。
非模式的对话框一般在堆中,所以要主动用DestroyWindow销毁它。
2)DialogBox函数创建模态对话框
INT_PTR DialogBox( HINSTANCE hInstance,LPCTSTR lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc);
函数功能:这个函数根据对话框资源,创建一个模式对话框,这个对话框应该用EndDialog来结束。
参数:
hInstance 当前应用程序实例句柄。
lpTemplate 标识对话框模板资源,有两种使用方式:一种是把对话框模板的ID强制转为LPCTSTR,一种可以使用MAKEINTRESOURCE宏得到标识ID。
hWndParent 父窗口的句柄。
lpDialogFunc 对话框消息处理函数。
3)CreateDialog函数创建非模态对话框
HWND CreateDialog( HINSTANCE hInstance,LPCTSTR lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc);
函数功能:这个函数根据对话框资源,创建一个非模式对话框,这个对话框应该用DestroyWindow来结束。
参数:函数的参数跟上面的DialogBox用法相同。
四、常用控件
HWND hBtn, hEdit, hText, hCombBox; hBtn = CreateWindow( //按钮创建 "button", "创建的按钮", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_CENTER|BS_VCENTER, 100,100,90,28, m_hWnd, NULL, AfxGetInstanceHandle(), 0); hEdit = CreateWindow( //edit控件 "edit", "create", WS_VISIBLE|WS_CHILD|WS_BORDER/*|DT_CENTER*/|DT_VCENTER, 100,70,100,25, m_hWnd, NULL, NULL, NULL); HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); ::SendMessage(hEdit,WM_SETFONT,(WPARAM)hFont,1); //设置控件字体 ::SendMessage(hBtn,WM_SETFONT,(WPARAM)hFont,1); hCombBox = CreateWindow( "combobox", "1", WS_CHILD|WS_VISIBLE|WS_BORDER|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST, 220, 100, 100, 25, m_hWnd, NULL, NULL, NULL);