- 创建一个菜单,其中有三个菜单项,分别为“文件”、“计算”和“帮助”,其中,“文件”菜单项包含“打开”、“保存”、“画图”、“退出”等菜单选项;“计算”菜单包含“总和”、“方差”、“均方根”等菜单选项;“帮助”菜单项包含“计算总和帮助”、“计算方差帮助”和“计算均方根帮助”以及“关于”等项 。
- 若单击“画图”菜单项,则绘出如下图形。
- 若在用户区内按下鼠标左键,则动态创建一个包括“删除计算总和”、“添加计算平均值”和“修改计算均方差”三个菜单项的弹出式菜单,由此菜单控制“计算”菜单中菜单项删除、添加与修改。(要求新的弹出式菜单开始时不可用,按下右键后变为可用。) 单击“修改计算均方差”菜单项后,“计算”菜单下的“计算均方差”项改为“线性拟合”,单击“添加计算平均值”菜单项后,“计算”菜单中添加上了“计算平均值”菜单项 。
完整代码实现:
#include "windows.h"
#include "resource.h"
#include <tchar.h>
#define IDM_Delete 40040
#define IDM_Update 40041
#define IDM_AddAvg 40042
#define IDM_jisuan 40043
HWND hwnd;
HDC hdc;
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if (!InitWindowClass(hInstance, nCmdShow)) {
MessageBox(NULL, "创建窗口失败!", "创建窗口", NULL);
return 1;
}
HACCEL hAccel = LoadAccelerators(hInstance, "IDR_MENU1");
while (GetMessage(&msg, NULL, 0, 0))
{ //在消息循环中截获加速键消息
if (!TranslateAccelerator(hwnd, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMENU hmenu, haddmenu;
PAINTSTRUCT ps;
HPEN hP; //画笔句柄
HBRUSH hB; //画刷句柄
switch (message)
{
case WM_TIMER:
if (wParam == 9999) //定时刷新
InvalidateRect(hwnd, NULL, true);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_PAINT:
hdc = GetDC(hwnd); //不是WM_PAINT响应消息用GetDC函数
//hdc = BeginPaint(hwnd, &ps); //取得设备环境句柄
SetMapMode(hdc, MM_TEXT); //设置映射模式
hP = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
SelectObject(hdc, hP);
hB = CreateHatchBrush(HS_CROSS, RGB(255, 0, 0));//红色网格画刷
SelectObject(hdc, hB);
RoundRect(hdc, 213, 100, 287, 137, 20, 20);
Pie(hdc, 213, 137, 288, 212, 240, 137, 260, 137);
Rectangle(hdc, 213, 212, 287, 250);
hP = CreatePen(PS_DASHDOT, 1, RGB(0, 255, 0));//绿色点画线
SelectObject(hdc, hP);
MoveToEx(hdc, 100, 180, NULL);
LineTo(hdc, 400, 180);
MoveToEx(hdc, 250, 50, NULL);
LineTo(hdc, 250, 300);
hP = CreatePen(PS_DASHDOT, 1, RGB(0, 255, 0));//绿色点画线
SelectObject(hdc, hP);
hB = CreateSolidBrush(RGB(255, 0, 0));
SelectObject(hdc, hB);
Rectangle(hdc, 400, 200, 500, 250);
DeleteObject(hP);
DeleteObject(hB);
EndPaint(hwnd, &ps);
break;
case IDM_Update://单击“修改计算均方差”菜单项后,“计算”菜单下的“计算均方差”项改为“线性拟合”
hmenu = GetMenu(hwnd);
haddmenu = CreateMenu(); //动态创建菜单
AppendMenu(haddmenu, MF_ENABLED, IDM_qiuhe, "求和");
AppendMenu(haddmenu, MF_ENABLED, IDM_fangcha, "方差");
AppendMenu(haddmenu, MF_ENABLED, IDM_junfanggen, "线性拟合");
ModifyMenu(hmenu, 1, MF_POPUP | MF_BYPOSITION, (UINT)haddmenu, "计算");
DrawMenuBar(hwnd);
break;
case IDM_AddAvg://单击“添加计算平均值”菜单项后,“计算”菜单中添加上了“计算平均值”菜单项
hmenu = GetMenu(hwnd);
haddmenu = CreateMenu();
//AppendMenu(hmenu, MF_ENABLED, IDM_AddAvg, ("计算平均值"));
AppendMenu(haddmenu, MF_ENABLED, IDM_qiuhe, "求和");
AppendMenu(haddmenu, MF_ENABLED, IDM_fangcha, "方差");
AppendMenu(haddmenu, MF_ENABLED, IDM_junfanggen, "线性拟合");
AppendMenu(haddmenu, MF_BYPOSITION, IDM_jisuan, "计算平均值");
ModifyMenu(hmenu, 1, MF_POPUP | MF_BYPOSITION, (UINT)haddmenu, "计算");
DrawMenuBar(hwnd);
break;
case IDM_EXIT:
SendMessage(hwnd, WM_DESTROY, 0, 0);
break;
}
break;
case WM_LBUTTONDOWN://创建一个动态菜单
hmenu = GetMenu(hwnd); //获取主菜单句柄
haddmenu = CreateMenu(); //动态创建菜单
AppendMenu(haddmenu, MF_GRAYED, IDM_Delete, "删除计算总和");
AppendMenu(haddmenu, MF_GRAYED, IDM_AddAvg, "添加计算平均值");
AppendMenu(haddmenu, MF_GRAYED, IDM_Update, "修改计算均方差");
InsertMenu(hmenu, 3, MF_POPUP | MF_BYPOSITION, (UINT)haddmenu, "编辑");
DrawMenuBar(hwnd);
break;
case WM_RBUTTONDOWN:
hmenu = GetMenu(hwnd);
EnableMenuItem(hmenu, IDM_Delete, MF_ENABLED);
EnableMenuItem(hmenu, IDM_AddAvg, MF_ENABLED);
EnableMenuItem(hmenu, IDM_Update, MF_ENABLED);
DrawMenuBar(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
break;
}
return 0;
}
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wcex;
TCHAR szWindowClass[] = "实验二";
TCHAR szTitle[] = "实验二";
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadCursorFromFile(TEXT("icon2.ico"));
wcex.hCursor = LoadCursorFromFile(TEXT("icon1.ico"));
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);//"将IDR_MENU1的菜单加载为窗口的菜单"
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&wcex)) {
MessageBeep(0);
return FALSE;
}
hwnd = CreateWindow(szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL
);
if (!hwnd)
return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
注意点:
1.单击“画图”菜单项画图,不能使用BeginPaint函数,要使用GetDC,并用ReleaseDC释放
2.修改菜单后用DrawManubar重画窗口