吐槽
由于这学期开了一门Windows编程的选修课,在课上老师点到我说让我上去讲解一个地方,说讲了就给平时分加50。
加50分平时分是你的谎言,到底是选修课老师,说好的谁上去讲了这个给谁平时分加50,到头来平时分跟大家一样,好好好,这么玩。让我失望透顶,虽然我讲的也确实一般,但是你这么玩有点不是很说的过去吧。
但吐槽归吐槽,我还是查询了一番资料,了解了一下的,下面讲讲我的见解吧。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Windows编程是什么?
首先我从上了大学后使用的Dev-C++,然后就是使用的#include<stdio.h>来进行hello,world等操作。
我们一般学到的这种是在DOS环境下运行的程序,所以在实现功能时我们会看到这样的框框。
概括来说,我们学到的这种C语言编程是控制台应用程序,我们所有的输出结果一般来说的话都会在这个黑框框里显示或根据程序交互。
而Windows应用程序设计是窗口应用程序,(窗口这个东西下面会说),再者C语言是面向过程的,简单来说就是它的功能是根据代码顺序执行的,代码里写了什么,它就根据代码从main函数开始到最后的return 0;而Windows编程是面向对象的,是由事件驱动的,简单来说就是根据它的代码,用户会和进行交互,用户进行什么操作,根据代码进行什么样的功能。
另外C的程序入口函数是main,windows程序的入口函数是Winmain,windows定义了很多句柄和宏定义,刚开始理解起来有些困难,但我下面会讲一下我浅薄的理解吧。
二、Windows程序设计-简易菜单的实现
多说无益,直接上代码讲解:
#include <windows.h>
#pragma comment(linker, "/subsystem:windows /entry:WinMainCRTStartup")
HMENU g_menu;
// 下拉菜单
void OnCreate(HWND hWnd)
{
HMENU hMenu = CreateMenu();
HMENU hMenu1 = CreatePopupMenu();
HMENU hMenu2 = CreatePopupMenu();
HMENU hSubi = CreatePopupMenu();
g_menu = hMenu1;
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenu1, "菜单1");
AppendMenu(hMenu1, MF_STRING | MF_CHECKED, 1001, "勾选");
AppendMenu(hMenu1, MF_POPUP, (UINT_PTR)hSubi, "子菜单");
AppendMenu(hSubi, MF_STRING , 1002, "信息2");
AppendMenu(hSubi, MF_SEPARATOR, 0, "");
AppendMenu(hSubi, MF_STRING, 1003, "信息3");
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenu2, "菜单2");
AppendMenu(hMenu2, MF_STRING, 1004, "信息4");
AppendMenu(hMenu2, MF_SEPARATOR, 0, "");
AppendMenu(hMenu2, MF_STRING, 1005, "信息5");
SetMenu(hWnd, hMenu);
}
// 响应下拉菜单
void OnCommand(HWND hWnd, WPARAM wParam)
{
static int g_state = 0;//标志量
switch(LOWORD(wParam))
{
case 1001:
if(g_state)
{
CheckMenuItem(g_menu, 1001, MF_BYCOMMAND | MF_CHECKED);
}
else
{
CheckMenuItem(g_menu, 1001, MF_BYCOMMAND | MF_UNCHECKED);
}
g_state = !g_state;
break;
case 1002:
MessageBox(hWnd, "信息2", "信息", MB_OK);
break;
case 1003:
MessageBox(hWnd, "信息3", "信息", MB_OK);
break;
case 1004:
MessageBox(hWnd, "信息4", "信息", MB_OK);
break;
case 1005:
MessageBox(hWnd, "信息5", "信息", MB_OK);
break;
}
}
// 右键菜单
void OnContextMenu(HWND hWnd, LPARAM lParam)
{
HMENU hPopup = CreatePopupMenu();
static int flag = 0;
AppendMenu(hPopup, MF_STRING | (flag ? MF_CHECKED : 0), 1001, "选择");
AppendMenu(hPopup, MF_SEPARATOR, 0, "");
AppendMenu(hPopup, MF_STRING, 1002, "右键2");
switch(TrackPopupMenu(hPopup, TPM_RETURNCMD, LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL))
{
case 1001:
flag = !flag;
break;
case 1002:
MessageBox(hWnd, "右键2", "信息", MB_OK);
break;
}
}
// 回调函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
switch (msgID)
{
case WM_CONTEXTMENU:
OnContextMenu(hWnd, lParam);
break;
case WM_COMMAND:
OnCommand(hWnd, wParam);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msgID, wParam, lParam);
}
// 主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "QodeCls";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
hWnd = CreateWindow("QodeCls", "Qode", WS_OVERLAPPEDWINDOW, 100, 100, 270, 270, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg ;
while (GetMessage(&nMsg, NULL, 0, 0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
return 0;
}
其能实现的也是一个基本的菜单的功能,例如:
这是下拉式菜单,字面意思出现的菜单里面有多项内容。
这是弹出式菜单,简单来说这个的弹出是通过鼠标右键的点击,进行完这个操作后会弹出这样的一个菜单。
我们也可以看见最上面一栏的菜单1、菜单2很像我们平常看到的菜单。
这些东西很简单,都是可以自己通过Windows程序设计实现出来的。
1.从头文件开始讲
可以看到这个头文件#include<windows.h>不是我们平常做题用到C语言程序的#include<stdio.h>,在这个头文件当中,包含了大量的API函数、宏定义以及相应的数据结构。其中这个API函数是重点,我们Windows程序设计的所有过程中实现功能靠的就是这些API函数,这些API函数都是一个个写好的封装好的函数,是可以拿来直接用的,就类似我们的printf()、scanf()函数一样,它们是在头文件#include<stdio.h>里封装好的函数,方便我们实现所需要的功能。
2.从代码的执行过程开始说编程时所需要编写的模块
首先我们从主函数开始说,不管那个C语言都要从主函数开始执行,不同于我们熟知的 C/C++ 的 main 函数,Windows 用的是 WinMain,并且前面还多了个 WINAPI。
窗口程序的入口函数:WinMain
控制台窗口应用程序入口函数:main
窗口程序的步骤:
第一步需要定义窗口变量并设置其各成员分量的值;(通过定义和设置各成员分量的值,把这个窗口设计成为你想要的样子)
第二步是向系统注册窗口类;(向Windows操作系统申请注册你要设计的这个窗口)
第三步创建并显示窗口;(字面意思,定义完毕后也申请完窗口了,总要把这个窗口创建和显示出来以方便进行交互)
第四步进入消息循环;(不断捕获在窗口上进行的操作)
第五步执行窗口函数;(根据消息循环不断捕获的消息进行相应的代码执行)
第六步当捕获到WM_QUIT消息时退出消息循环,退出主函数,应用程序运行结束;
这里顺便着重说一下这个窗口,窗口是Windows本身及其应用程序的基本界面单位,是应用程序生成的显示在屏幕上的一个矩形区域,是应用程序与用户间的直接接口;应用程序控制与窗口有关的一切内容,包括窗口的大小、风格、位置及窗口内显示的内容等。Windows编程说白了,就是编一个窗口,使这个窗口具有显示和人机互动等功能。你现在看到的页面就是一个窗口,这个窗口显示了我写给你们的内容(显示功能),你们也可以对我的内容进行复制和粘贴等一系列操作(人机互动功能)。
3.主函数的大门
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
{
}
首先区别与我们常见的控制台应用程序的入口函数main,在窗口程序的入口函数是WinMain,前面的这个WINAPI是函数调用约定,WINAPI其实就是__stdcall,而__stdcall是C/C++调用约定的一种,意思是函数的参数被从右到左推送到堆栈上,被调用函数在返回之前从堆栈中弹出这些参数。
4.窗口变量的赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格,
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //要根据窗口类结构分配的额外字节数。系统将字节初始化为零。
wndclass.cbWndExtra = 0; //在窗口实例之后分配的额外字节数。
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH); //窗口背景画刷
wndclass.lpszMenuName = NULL ; //窗口菜单
wndclass.lpszClassName= szClassName; //窗口类名
窗口变量首先需要定义一个窗口类wndclass,其类型是WNDCLASSEX,声明完一个之后才可以对这个窗口类的变量的各字段进行赋值。
窗口类的字段有很多,根据需要进行赋值,一般不赋值的按默认处理。
第一个窗口风格那个的效果就是以指定无论何时窗口的水平尺寸(CS_HREDRAW)或垂直尺寸(CS_VREDRAW)被改变,所有基于该窗口类的窗口都将被重新绘制.在调整HELLOWIN的窗口尺寸时,可以发现,文本字符串被重新绘制在窗口新的中心位置上。其中CS_HREDRAW的效果是如果移动或大小调整更改了工作区的宽度,则重绘整个窗口。CS_VREDRAW的效果是如果移动或大小调整更改了工作区的高度,则重新绘制整个窗口。重新绘制整个窗口的意思是,当改变窗口的大小把窗口上的内容覆盖后,再次展开后窗口重新绘制内容,依然可以看见原来的内容,如果没有这个窗口内容的说明的话覆盖的内容将会丢失。
第二个窗口过程的赋值为窗口函数WmdProc,WndProc()函数是由CreateWindow()函数创建的窗口的窗口函数,该函数的功能是根据接收到的该窗口上发生的不同事件所产生的不同消息,去执行不同的代码段以进行不同的处理。
第六个窗口图标的赋值需要API函数LoadIcon (),函数原型为:
HICON LoadIconA(
[in, optional] HINSTANCE hInstance,
[in] LPCSTR lpIconName
);
参数
1.hInstance类型:HINSTANCE
图标资源所在模块的实例句柄。如果是标准图标,此参数必须为NULL。
2.lpIconName类型:LPCTSTR
图标资源名或资源标识符,资源标识符由16位组成,在低16位,高16位为0。宏 MAKEINTRESOURCE 可以将资源标识符强制转换成参数的资源名类型。如果使用预定义的图标,需要将hInstance参数设置成NULL,并且lpIconName值必须是以下之一:
返回值类型:HICON
如果成功,返回最近一次加载的图标句柄。
如果失败,返回NULL。
注意:
1、使用系统预定义图标,必须把第一个参数设置为NULL.
在初始化时,我们可以这样使用:
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
相应的显示:
想学自定义更改图标可以看这篇文章https://blog.csdn.net/zzwfans/article/details/103372891
第七个鼠标样式的赋值需要API函数LoadCursor(),函数原型为:
HCURSOR LoadCursorA(
[in, optional] HINSTANCE hInstance,
[in] LPCSTR lpCursorName
);
如果 hInstance 为非 NULL, 则 lpCursorName 按名称或序号指定游标资源。 必须使用 MAKEINTRESOURCE 宏打包此序号。
如果 hInstance 为 NULL, 则 lpCursorName 将指定标识符 (从要加载的预定义系统游标的 IDC_前缀) 开始 。
第八个窗口背景画刷需要函数GetStockObject(),这个函数的使用想了解的话可以再查查,我这里的使用时函数内传参的WHITE_BRUSH的效果是背景为白色,
还有别的如下:
5.注册窗口类
RegisterClassEx(&wc);
窗口类向操作系统的注册报备可以用的有两种API函数,其函数原型:
//RegisterClass
ATOM RegisterClass(
const WNDCLASS * lpWndClass //Long pointer to a WNDCLASS structure
);
//RegisterClassEx
ATOM RegisterClassEx(
CONST WNDCLASSEX * lpwcx //Pointer to a WNDCLASSEX structure
);
只需要知道这一步向操作系统注册报备窗口类这样来写就行了。
6.创建与显示窗口
hWnd = CreateWindow("QodeCls", "Qode", WS_OVERLAPPEDWINDOW, 100, 100, 270, 270, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
CreateWindow该函数创建一个重叠式窗口、弹出式窗口或子窗口。它指定窗口类,窗口标题,窗口风格,以及窗口的初始位置及大小(可选的)。函数也指该窗口的父窗口或所属窗口(如果存在的话),及窗口的菜单。若要使用除 CreateWindow 函数支持的风格外的扩展风格,则使用CreateWindowEx 函数代替 CreateWindow 函数。
函数原型:
void CreateWindowA(
[in, optional] lpClassName,
[in, optional] lpWindowName,
[in] dwStyle,
[in] x,
[in] y,
[in] nWidth,
[in] nHeight,
[in, optional] hWndParent,
[in, optional] hMenu,
[in, optional] hInstance,
[in, optional] lpParam
);
参数 | 含义 |
---|---|
lpClassName | 1. 窗口类名称,可以是一个指向 NULL 结束的字符串或一个整型数值2. 如果是字符串,它指定了窗口的类名。这个类名可以是任何用函数 RegisterClass 注册的类名,或是任何预定义的控制类名3. 如是一个整型量,它是由此前调用 theGlobalAddAtom 函数产生的全局量。这个小于 0xC000 的 16 位数必须是 lpClassName 参数字的低 16 位,该参数的高位必须是 0 |
lpWindowName | 1. 窗口标题,一个指向 NULL 结束的字符串指针2. 如果窗口风格指定了标题条,由 lpWindowName 指向的窗口标题将显示在标题条上3. 当使用 Createwindow 函数来创建控制例如按钮,选择框和静态控制时,可使用 lpWindowName 来指定控制文本 |
dwStyle | 正在创建的窗口的样式。 此参数可以是 窗口样式值以及“备注”部分中指示的控件样式的组合。 |
x | 窗口的初始水平位置。 对于重叠或弹出窗口, x 参数是窗口左上角的初始 x 坐标(以屏幕坐标表示)。 对于子窗口, x 是窗口左上角相对于父窗口工作区左上角的 x 坐标。 如果此参数设置为 CW_USEDEFAULT,系统将选择窗口左上角的默认位置,并忽略 y 参数。 CW_USEDEFAULT 仅对重叠窗口有效;如果为弹出窗口或子窗口指定,则 x 和 y 参数设置为零。 |
y | 窗口的初始垂直位置。 对于重叠或弹出窗口, y 参数是窗口左上角的初始 y 坐标(以屏幕坐标表示)。 对于子窗口, y 是子窗口左上角相对于父窗口工作区左上角的初始 y 坐标。 对于列表框, y 是列表框工作区左上角相对于父窗口工作区左上角的初始 y 坐标。如果使用 WS_VISIBLE 样式位创建重叠窗口,并且 x 参数设置为 CW_USEDEFAULT,则 y 参数确定窗口的显示方式。 如果 y 参数CW_USEDEFAULT,则窗口管理器在创建窗口后使用SW_SHOW标志调用 ShowWindow。 如果 y 参数是其他某个值,则窗口管理器会调用 ShowWindow ,该值作为 nCmdShow 参数。 |
nWidth | 窗口的宽度(以设备单位为单位)。 对于重叠窗口, nWidth 是窗口的宽度(以屏幕坐标表示)或 CW_USEDEFAULT。 如果 nWidthCW_USEDEFAULT,系统将为窗口选择默认宽度和高度;默认宽度从初始 x 坐标扩展到屏幕的右边缘,默认高度从初始 y 坐标扩展到图标区域的顶部。 CW_USEDEFAULT 仅对重叠窗口有效;如果为弹出窗口或子窗口指定 了CW_USEDEFAULT , 则 nWidth 和 nHeight 设置为零。 |
nHeight | 窗口的高度(以设备单位为单位)。 对于重叠窗口, nHeight 是窗口的高度(以屏幕坐标为单位)。 如果 nWidth 设置为 CW_USEDEFAULT,系统将忽略 nHeight。 |
hWndParent | 正在创建的窗口的父窗口或所有者窗口的句柄。 若要创建子窗口或拥有的窗口,请提供有效的窗口句柄。 此参数对于弹出窗口是可选的。若要创建 仅消息窗口,请向现有仅消息窗口提供 HWND_MESSAGE 或句柄。 |
hMenu | 菜单句柄,或指定子窗口标识符,具体取决于窗口样式。 对于重叠或弹出窗口, hMenu 标识要与窗口一起使用的菜单;如果要使用类菜单,则它可以为 NULL 。 对于子窗口, hMenu 指定子窗口标识符,即对话框控件用于通知其父级事件的整数值。 应用程序确定子窗口标识符;对于具有相同父窗口的所有子窗口,它必须是唯一的。 |
hInstance | 要与窗口关联的模块实例的句柄。 |
lpParam | 指向要通过 CREATESTRUCT 结构传递到窗口的值的指针, (WM_CREATE消息的 lParam 参数指向的 lpCreateParams 成员 ) 。 此消息在返回之前由此函数发送到创建的窗口。如果应用程序调用 CreateWindow 来创建 MDI 客户端窗口, lpParam 应指向 CLIENTCREATESTRUCT 结构。 如果 MDI 客户端窗口调用 CreateWindow 来创建 MDI 子窗口, lpParam 应指向 MDICREATESTRUCT 结构。 如果不需要其他数据,lpParam 可能为 NULL。 |
这些解释很明显的说明了该函数的用法。
ShowWindow()函数设置指定窗口的显示状态,函数原型:
BOOL ShowWindow(
[in] HWND hWnd,
[in] int nCmdShow
);
HWND是窗口句柄。
nCmdShow是控制窗口的显示方式。 如果启动应用程序的程序提供 STARTUPINFO 结构,则应用程序首次调用 ShowWindow 时将忽略此参数。 否则,首次调用 ShowWindow 时,该值应为 WinMain 函数在其 nCmdShow 参数中获取的值。 在后续调用中,此参数可以是以下值之一。
7.消息循环
MSG nMsg ;
while (GetMessage(&nMsg, NULL, 0, 0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
MSG是包含来自线程的消息队列的消息信息。函数GetMessage()的功能是从消息队列中取出消息,函数TranslateMessage()的功能是对取出的消息进行相应的转换即将虚拟键消息转换为字符消息,并将其寄送到线程的消息队列里,DispatchMessage()函数驱动对应的窗口函数去执行;当函数GetMessage()从消息队列中取出的消息为WM_QUIT时,其返回值为0,此时退出消息循环。
8.窗口函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
switch (msgID)
{
case WM_CONTEXTMENU:
OnContextMenu(hWnd, lParam);//右键菜单
break;
case WM_COMMAND:
OnCommand(hWnd, wParam);// 响应下拉菜单
break;
case WM_CREATE:
OnCreate(hWnd);// 下拉菜单
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msgID, wParam, lParam);
}
根据窗口函数接受到的消息的ID,执行不同的功能。
例子中的WM_CONTEXTMENU消息是通知窗口用户希望显示上下文菜单。 用户可能单击了鼠标右键 (在窗口中右键单击) ,按下了 Shift+F10 或按下了应用程序键, (上下文菜单键) 某些键盘上可用后产生了这一消息。然后在窗口函数中相应的执行相应的函数。
WM_COMMAND消息是当用户从菜单中选择命令项、控件将通知消息发送到其父窗口或转换加速键时发送,后产生此消息。
WM_CREATE消息是当应用程序请求通过调用 CreateWindowEx 或 CreateWindow 函数创建窗口时发送。 (消息在函数返回之前发送。) 新窗口的窗口过程在窗口创建后、窗口变为可见之前接收此消息。窗口通过其 WindowProc 函数接收此消息。(应该是当窗口被创建后就发送了这一消息)
WM_DESTROY消息在窗口被销毁时发送。 从屏幕中删除窗口后,它会发送到正在销毁的窗口的窗口过程。此消息首先发送到要销毁的窗口,然后发送到子窗口, (是否有任何) 被销毁。 在处理消息期间,可以假定所有子窗口仍然存在。窗口通过其 WindowProc 函数接收此消息。
9.跟菜单有关的API函数
HMENU CreateMenu();
创建菜单。 菜单最初为空,但可以使用 InsertMenuItem、 AppendMenu 和 InsertMenu 函数填充菜单项。
HMENU CreatePopupMenu();
创建下拉菜单、子菜单或快捷菜单。 菜单最初为空。 可以使用 InsertMenuItem 函数插入或追加菜单项。 还可以使用 InsertMenu 函数插入菜单项, 使用 AppendMenu 函数来追加菜单项。
BOOL AppendMenuW(
[in] HMENU hMenu,
[in] UINT uFlags,
[in] UINT_PTR uIDNewItem,
[in, optional] LPCWSTR lpNewItem
);
将新项追加到指定菜单栏、下拉菜单、子菜单或快捷菜单的末尾。 可以使用此函数指定菜单项的内容、外观和行为。
hMenu
类型: HMENU
要更改的菜单栏、下拉菜单、子菜单或快捷菜单的句柄。
uFlags
类型: UINT
控制新菜单项的外观和行为。 此参数可以是以下值的组合。
值 | 含义 |
---|---|
MF_BITMAP | 使用位图作为菜单项。 lpNewItem 参数包含位图的句柄。 |
MF_CHECKED | 在菜单项旁边放置一个检查标记。 如果应用程序提供检查标记位图 (请参阅 SetMenuItemBitmaps,则此标志在菜单项旁边显示检查标记位图。 |
MF_DISABLED | 禁用菜单项,以便无法选择该菜单项,但标志不会将其灰显。 |
MF_ENABLED | 启用菜单项,以便可以选择菜单项,并将其从灰显状态还原。 |
MF_GRAYED | 禁用菜单项并将其灰显,使其无法选中。 |
MF_MENUBARBREAK | 功能与菜单栏的 MF_MENUBREAK 标志相同。 对于下拉菜单、子菜单或快捷菜单,新列与旧列之间将用一条竖线分隔。 |
MF_MENUBREAK | 将项放在菜单栏) 的新行 (上,或者放置在下拉菜单、子菜单或快捷菜单) 的新列 (中,而不分隔列。 |
MF_OWNERDRAW | 指定该项是所有者绘制的项。 在首次显示菜单之前,拥有菜单的窗口会收到 WM_MEASUREITEM 消息,用于检索菜单项的宽度和高度。 然后,每当必须更新菜单项的外观时, WM_DRAWITEM消息就会 发送到所有者窗口的窗口过程。 |
MF_POPUP | 指定菜单项打开下拉菜单或子菜单。 uIDNewItem 参数指定下拉菜单或子菜单的句柄。 此标志用于向菜单栏或向下拉菜单、子菜单或快捷菜单打开子菜单的菜单项添加菜单名称。 |
MF_SEPARATOR | 绘制一条水平分割线。 此标志仅在下拉菜单、子菜单或快捷菜单中使用。 行不能灰显、禁用或突出显示。 忽略 lpNewItem 和 uIDNewItem 参数。 |
MF_STRING | 指定菜单项为文本字符串; lpNewItem 参数是指向字符串的指针。 |
MF_UNCHECKED | 不要在项旁边放置检查标记, (默认) 。 如果应用程序提供检查标记位图 (请参阅 SetMenuItemBitmaps) ,则此标志显示菜单项旁边的清除位图。 |
uIDNewItem
类型: UINT_PTR
新菜单项的标识符;如果 uFlags 参数设置为 MF_POPUP,则为下拉菜单或子菜单的句柄。
lpNewItem
类型: LPCTSTR
新菜单项的内容。 lpNewItem 的解释取决于 uFlags 参数是否包含以下值。文章来源:https://www.toymoban.com/news/detail-798942.html
总结
窗口函数的每一个过程都值得很深的去钻研,这里只是粗略的讲解一下,如果有不明白或者想更加了解的话,可以去微软的官网查看这些API函数的用法,并且使用了解它们。文章来源地址https://www.toymoban.com/news/detail-798942.html
到了这里,关于西安邮电大学Windows编程---菜单的设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!