当滚动条在Win32触底时如何启用按钮? [英] How to enable buttons when scroll bar hits bottom with Win32?

查看:91
本文介绍了当滚动条在Win32触底时如何启用按钮?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Win32编写一个许可协议对话框,我很困惑.像往常一样,当Richedit控件的滚动条的滑块滑到底部时,我希望启用接受/不接受"按钮,但是我找不到找到该事件的通知的方法.我最早能了解到它是在用户释放鼠标左键时.

I'm writing a license agreement dialog box with Win32 and I'm stumped. As usual with these things I want the "accept/don't accept" buttons to become enabled when the slider of the scroll bar of the richedit control hits bottom, but I can't find a way to get notified of that event. The earliest I've been able to learn about it is when the user releases the left mouse button.

有没有办法做到这一点?

Is there a way to do this?

这是我到目前为止尝试过的:

Here's what I tried so far:

    Richedit的wndproc中的
  • WM_VSCROLLWM_LBUTTONUP
  • dlgproc中的
  • EN_MSGFILTER通知(是,已设置过滤器掩码)
  • dlgproc中的
  • WM_VSCROLLWM_LBUTTONUP.
  • dlgproc中的
  • EN_VSCROLL通知
  • WM_VSCROLL and WM_LBUTTONUP in richedit's wndproc
  • EN_MSGFILTER notification in dlgproc (yes the filter mask is getting set)
  • WM_VSCROLL and WM_LBUTTONUP in dlgproc.
  • EN_VSCROLL notification in dlgproc

我非常绝望,我尝试进行轮询,但是那样也没有用,因为显然当鼠标按钮在滑块上按下时,计时器消息停止到达.我都尝试过:

I got so desperate I tried polling but that didn't work either because apparently timer messages stop arriving while the mouse button is down on the slider. I tried both:

    dlgproc中的
  • 计时器回调(以轮询)
  • Richedit的wndproc中的
  • 计时器回调(以进行轮询)
  • timer callback (to poll) in dlgproc
  • timer callback (to poll) in richedit's wndproc

推荐答案

您需要对编辑框进行子分类,并截取到编辑框本身的消息. 这是有关子类化控件的MSDN文章.

You need to sub-class the edit box and intercept the messages to the edit box itself. Here's an artical on MSDN about subclassing controls.

一些代码来演示启用按钮的滚动条:

Some code to demonstrate the scroll bar enabling a button:

#include <windows.h>
#include <richedit.h>

LRESULT __stdcall RichEditSubclass
(
  HWND window,
  UINT message,
  WPARAM w_param,
  LPARAM l_param
)
{
  HWND
    parent = reinterpret_cast <HWND> (GetWindowLong (window, GWL_HWNDPARENT));

  WNDPROC
    proc = reinterpret_cast <WNDPROC> (GetWindowLong (parent, GWL_USERDATA));

  switch (message)
  {
  case WM_VSCROLL:
    {
      SCROLLINFO
        scroll_info = 
        {
          sizeof scroll_info,
          SIF_ALL
        };

      GetScrollInfo (window, SB_VERT, &scroll_info);

      if (scroll_info.nPos + static_cast <int> (scroll_info.nPage) >= scroll_info.nMax ||
          scroll_info.nTrackPos + static_cast <int> (scroll_info.nPage) >= scroll_info.nMax)
      {
        HWND
          button = reinterpret_cast <HWND> (GetWindowLong (parent, 0));

        EnableWindow (button, TRUE);
      }
    }
    break;
  }

  return CallWindowProc (proc, window, message, w_param, l_param);
}

LRESULT __stdcall ApplicationWindowProc
(
  HWND window,
  UINT message,
  WPARAM w_param,
  LPARAM l_param
)
{
  bool
    use_default_proc = false;

  LRESULT
    result = 0;

  switch (message)
  {
  case WM_CREATE:
    {
      CREATESTRUCT
        *creation_data = reinterpret_cast <CREATESTRUCT *> (l_param);

      RECT
        client;

      GetClientRect (window, &client);

      HWND
        child = CreateWindow (RICHEDIT_CLASS,
                              TEXT ("The\nQuick\nBrown\nFox\nJumped\nOver\nThe\nLazy\nDog\nThe\nQuick\nBrown\nFox\nJumped\nOver\nThe\nLazy\nDog"),
                              WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | ES_DISABLENOSCROLL,
                              0, 0, client.right, client.bottom - 30,
                              window,
                              0,
                              creation_data->hInstance,
                              0);

      SetWindowLong (window, GWL_USERDATA, GetWindowLong (child, GWL_WNDPROC));
      SetWindowLong (child, GWL_WNDPROC, reinterpret_cast <LONG> (RichEditSubclass));
      SetWindowLong (child, GWL_ID, 0);

      child = CreateWindow (TEXT ("BUTTON"), TEXT ("Go Ahead!"), WS_CHILD | WS_VISIBLE | WS_DISABLED, 0, client.bottom - 30, client.right, 30, window, 0, creation_data->hInstance, 0);

      SetWindowLong (window, 0, reinterpret_cast <LONG> (child));
      SetWindowLong (child, GWL_ID, 1);
    }
    break;

  case WM_COMMAND:
    if (HIWORD (w_param) == BN_CLICKED && LOWORD (w_param) == 1)
    {
      DestroyWindow (window);
    }
    break;

  default:
    use_default_proc = true;
    break;
  }

  return use_default_proc ? DefWindowProc (window, message, w_param, l_param) : result;
}

int __stdcall WinMain
(
  HINSTANCE instance,
  HINSTANCE unused,
  LPSTR command_line,
  int show
)
{
  LoadLibrary (TEXT ("riched20.dll"));

  WNDCLASS
    window_class = 
    {
      0,
      ApplicationWindowProc,
      0,
      4,
      instance,
      0,
      LoadCursor (0, IDC_ARROW),
      reinterpret_cast <HBRUSH> (COLOR_BACKGROUND + 1),
      0,
      TEXT ("ApplicationWindowClass")
    };

  RegisterClass (&window_class);

  HWND
    window = CreateWindow (TEXT ("ApplicationWindowClass"),
                           TEXT ("Application"),
                           WS_VISIBLE | WS_OVERLAPPED | WS_SYSMENU,
                           CW_USEDEFAULT,
                           CW_USEDEFAULT,
                           400, 300, 0, 0,
                           instance,
                           0);

  MSG
    message;

  int
    success;

  while (success = GetMessage (&message, window, 0, 0))
  { 
    if (success == -1)
    {
      break;
    }
    else
    {
      TranslateMessage (&message);
      DispatchMessage (&message);
    }
  }

  return 0;
}

以上内容无法处理用户在编辑框中移动光标的情况.

The above doesn't handle the user moving the cursor in the edit box.

这篇关于当滚动条在Win32触底时如何启用按钮?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆