我正在用Win32编写许可协议对话框,我很难过。像往常一样,当richedit控件的滚动条的滑块触及底部时,我希望“接受/不接受”按钮变为启用,但我找不到通知该事件的方法。我最早能够了解到的是当用户松开鼠标左键时。
有办法做到这一点吗?
这是我到目前为止所尝试的内容:
WM_VSCROLL
和WM_LBUTTONUP
在richedit的wndproc EN_MSGFILTER
通知(是的,过滤器掩码已设置)WM_VSCROLL
和WM_LBUTTONUP
。EN_VSCROLL
通知
我非常绝望,我尝试了轮询,但这也不起作用,因为显然计时器消息在滑块上的鼠标按钮停止时停止到达。我试过了两个:
答案 0 :(得分:1)
您需要对编辑框进行子类化,并将消息拦截到编辑框本身。 Here's an artical on MSDN about subclassing controls
编辑:一些代码用于演示启用按钮的滚动条:
#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;
}
上述操作无法处理用户在编辑框中移动光标。
答案 1 :(得分:0)
我建议启动 Spy ++ 并查看哪些Windows消息已发送到哪里。
http://msdn.microsoft.com/en-us/library/aa264396(VS.60).aspx
答案 2 :(得分:0)
为什么不使用EM_GETTHUMB消息。 (假设Rich Edit 2.0或更高版本)。
如果幸运的话,这个最低位置将与EM_GETLINECOUNT匹配。
答案 3 :(得分:-2)
即使有可能,我也不认为你应该这样做 - 用户将不知道为什么按钮被禁用。这可能非常令人困惑,应该不惜一切代价避免混淆用户; - )
这就是为什么大多数许可证对话框都有默认启用拒绝接受/拒绝的单选按钮,因此您必须主动启用接受。