【问题标题】:winapi BN_CLICKED how to identify which button was clicked?winapi BN_CLICKED 如何识别点击了哪个按钮?
【发布时间】:2014-01-05 13:54:51
【问题描述】:

我正在使用 c++ 创建一个简单的 win32 程序,尽管我认为我只在这个应用程序中使用了 c。我需要确定在应用程序上按下了哪个 HWND 按钮。我搜索了 msdn 参考,它只告诉我 HIWORD 是通知代码,而 LOWORD 是标识符,用于 BN_CLICKED 消息。我已经设法确定何时单击按钮,但它仅适用于所有按钮。我所有的按钮都是在 WM_CREATE 消息中创建的。到目前为止,这是我设法完成的:

case: WM_CREATE:
    HWND hPlus = CreateWindowEx( 0, L"BUTTON", L"+", WS_CHILD | WS_VISIBLE, 130, 240, 35, 30, hwnd, ( HMENU )IDC_MENU, GetModuleHandle( NULL ), NULL );
    HWND hEquals = CreateWindowEx( 0, L"BUTTON", L"=", WS_CHILD | WS_VISIBLE, 170, 205, 65, 65, hwnd, ( HMENU )IDC_MENU, GetModuleHandle( NULL ), NULL );
break;

case WM_COMMAND:
    switch( HIWORD( wParam ) )
    {
        case BN_CLICKED:
            MessageBox( hwnd, L"OK", "OK", MB_OK );
            break;
    }
    break;

我尝试将 hEquals 与 LOWORD( wParam ) 进行比较,但这在编译时给了我一个错误。我想我也尝试将它与 lParam 的 HIWORD 和 LOWORD 进行比较,这也没有编译。现在我不知道下一步该做什么。

【问题讨论】:

  • 很高兴能帮上忙。你为什么不接受这两个答案之一?
  • 嗨文斯。我又来了,因为有人刚刚对我的回答投了赞成票。你为什么不接受答案?只是好奇。
  • 我非常忙。我接受答案很糟糕哈哈。我很容易分心,甚至不记得这是为了什么项目。
  • 那是在 2013 年......无论如何,编程愉快!

标签: winapi button click


【解决方案1】:

给每个按钮一个自己的 ID,并将其传递给 hMenu 参数中的CreateWindowEx,用于此:

菜单句柄,或指定子窗口标识符,具体取决于 关于窗口样式。

#define BTN_PLUS  100
#define BTN_EQUAL 101

CreateWindowEx( 0, L"BUTTON", L"+", WS_CHILD | WS_VISIBLE, 130, 240, 35, 30,
                hwnd, ( HMENU )BTN_PLUS, GetModuleHandle( NULL ), NULL );

CreateWindowEx( 0, L"BUTTON", L"=", WS_CHILD | WS_VISIBLE, 170, 205, 65, 65,
               hwnd, ( HMENU )BTN_EQUAL , GetModuleHandle( NULL ), NULL );

然后,在WM_COMMAND,您可以测试ID:

case WM_COMMAND: {
    if ( LOWORD( wParam ) == BTN_PLUS ) {
        [...]
    }
    [...]
    break;
}

【讨论】:

  • 哇,我从来不知道。我一直认为菜单是窗口的实际菜单,例如。文件、编辑、窗口、帮助等。
  • @Vince:顶级窗口有菜单,子窗口有控件 ID。该参数用于两者。
  • 文档中清楚地说明了这一事实。
【解决方案2】:

你只需要看看lParam它是按钮句柄:

if ((HWND)lParam == hPlus)
{
    // "plus" clicked ... etc.
}

尽管在您的代码中,您需要将 HWND 保留在全局变量中以进行比较。

// somewhere global
HWND hPlus = NULL;
HWND hEquals = NULL;

// in your WndProc ...

case: WM_CREATE:
    hPlus = CreateWindowEx( 0, L"BUTTON", L"+", WS_CHILD | WS_VISIBLE, 130, 240, 35, 30, hwnd, ( HMENU )IDC_MENU, GetModuleHandle( NULL ), NULL );
    hEquals = CreateWindowEx( 0, L"BUTTON", L"=", WS_CHILD | WS_VISIBLE, 170, 205, 65, 65, hwnd, ( HMENU )IDC_MENU, GetModuleHandle( NULL ), NULL );
break;

case WM_COMMAND:
    switch( HIWORD( wParam ) )
    {
        case BN_CLICKED:
            // see which button was clicked
            if ((HWND)lParam == hPlus)
            {
                MessageBox( hwnd, L"hPlus was clicked", "OK", MB_OK );
            }
            break;
    }
    break;

你明白了,我敢肯定....

【讨论】:

  • 拥有很多全局变量不是坏习惯吗?在我看过的很多 c++ 教程中,他们都说有很多全局变量不好。
  • @Vince 是的,完全正确,但这不是您最初的问题,很难判断在单个特定答案中投入多少。我只是为您提供了解决最初问题的最少代码更改。
  • 我之前确实尝试过这种方式,但我没有将它与 (HWND)hPlus 或其他任何东西进行比较。相反,我想做的是(HIWORD)hPlus,然后(LOWORD)hPlus......完全忘记了它必须转换为HWND。
猜你喜欢
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 2018-05-15
  • 2021-04-25
  • 2017-04-26
相关资源
最近更新 更多