什么是winapi HMENU以及我如何使用它
What is winapi HMENU and how do i use it?
我刚刚开始学习winapi,我想制作一个带有两个按钮和一个文本框的简单表单。当我按下一个按钮时,我希望文本框说一件事,当我按下另一个按钮,我希望它说其他事情。为了区分这两个按钮,我必须知道它们的控制id,它们位于WM_COMMAND消息的wParam的低位。我想我应该自己在CreateWindowEx()函数的hMenu参数中指定这些ID(或者windows默认情况下会这样做吗?如果是,我如何获得ID?)。但是,我找不到任何关于HMENU对象的文档,也找不到关于如何使用它的任何解释。什么是HMENU?
HMENU
是菜单的句柄,例如由LoadMenu
创建(它根据资源中的规范创建菜单)。
但是,CreateWindow
函数为了两个不同的目的重新使用了相同的参数。对于顶级窗口,这是一个菜单句柄,但对于子窗口,它是子窗口id,应该在16位整数范围内(我不确定到底支持什么范围,请查看文档)。
创建子窗口时,只需将id强制转换为HMENU
即可。
一个常见的约定是使用-1
表示"不在乎"id。
0
,因为0
是OK按钮的id,符号名称为IDOK
编辑:在MessageBox
文档中,IDOK
值(正确地)记录为1。我不确定我上面转述的信息是从哪里来的。尽管如此,避免0作为id可能是个好主意。
下面是一些说明基本方法的代码。它不会在您的系统上编译,因为这里使用的头是我自己的。此外,虽然代码可以工作,但它只是一种支持其他代码的框架,稍后将被更合适的代码取代,所以不要过于重视设计选择等。
#pragma once
// Copyright (c) 2013 Alf P. Steinbach
#include <rfc/winapi/Atomlike_id.h> // Atomlike_id, pseudopointer_from
#include <rfc/winapi/geometry/Rect.h> // winapi::geometry::Rect
#include <rfc/winapi/gui/general_windowclass.h> // general_windowclass_atom
#include <rfc/winapi/gui/windowclass_names.h> // richedit_classname
#include <rfc/winapi/gui/Window_handle_.h> // Window_handle, Toplevel_window_handle
namespace winapi{ namespace gui{
inline
auto new_toplevel_window(
Toplevel_window_handle const owner = Toplevel_window_handle( nullptr )
)
-> Toplevel_window_handle
{
HWND const handle = ::CreateWindow(
general_windowclass_atom().raw(),
L"", // Title
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
owner,
HMENU(),
::GetModuleHandle( nullptr ),
nullptr // param
);
hopefully( handle != 0 )
|| fail( "::CreateWindow", ::GetLastError() );
return Toplevel_window_handle( handle );
}
inline
auto new_child_window(
Atomlike_id const windowclass_id,
Window_handle const parent,
geometry::Rect const& placement = geometry::Rect(),
DWORD const stylebits = 0,
int const id = -1
)
-> Child_window_handle
{
if( windowclass_id == Atomlike_id( richedit_classname ) )
{
static auto const richedit_dll_name = L"Msftedit.dll";
if( !GetModuleHandle( richedit_dll_name ) )
{
::LoadLibrary( richedit_dll_name )
|| fail( "LoadLibrary("Msftedit.dll")", ::GetLastError() );
}
}
auto const& r = placement;
HWND const handle = ::CreateWindow(
windowclass_id.raw(),
L"", // Text
stylebits | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
r.x(), r.y(), r.w(), r.h(), // CW_USEDEFAULT is not valid for child window.
parent,
reinterpret_cast<HMENU>( id ),
::GetModuleHandle( nullptr ),
nullptr // param
);
hopefully( handle != 0 )
|| fail( "::CreateWindow", ::GetLastError() );
return Child_window_handle( handle );
}
} } // namespace winapi::gui
相关文章:
- 如何在桌面C++上使用 WinApi 画线
- 在 C++ 的 Qt 中使用 WINAPI 线程时出现问题
- 如何使用 WINAPI 和 C++ 提取可执行文件的文件描述?
- 避免在使用WinAPI(Windows Core Audio)时无效的指针
- 如何使用WinAPI每帧只重新绘制一次子窗口
- 可靠地知道卷是否可使用 WinApi 移动
- 使用winapi使用按钮更改窗口的背景颜色
- 使用 WinAPI 创建自定义菜单的最佳方法是什么
- 使用 WinApi 获取与面板中相同的显示名称"Advanced display settings"
- 如何在 c++ 中使用 winapi 事件解决生产者-消费者
- 如何使用 WINAPI 读取整个二进制文件
- 如何在类中使用WINAPI函数(不是回调)?
- 使用 winAPI 获取计算机工作时间
- 如何使用Winapi设置最小窗口尺寸
- 使用Winapi从文件中读取数据
- 使用 winAPI 设置窗口的高性能电源计划C++
- 如何使用 winapi 类
- 有没有办法使用 WINAPI 或 Embarcadero C++ Builder XE 创建共享目录/文件夹
- 如何在使用winapi(C++)时同时更新Listview和Edit
- 使用winapi从桌面用c++打开一个文件