【发布时间】:2011-01-22 05:01:41
【问题描述】:
我正在为 Windows Mobile 平台编写一个 win32 程序(在 WM6.1 上测试)。大多数主窗口由一个文本框组成,我想用手指滚动它而不是选择文本。我该怎么做呢?
【问题讨论】:
标签: windows-mobile winapi textbox scroll
我正在为 Windows Mobile 平台编写一个 win32 程序(在 WM6.1 上测试)。大多数主窗口由一个文本框组成,我想用手指滚动它而不是选择文本。我该怎么做呢?
【问题讨论】:
标签: windows-mobile winapi textbox scroll
在不涉及技术细节的情况下,您应该考虑将“鼠标”点击事件分为“鼠标”向下和“鼠标”向上事件。
如果指针位置自向下事件以来未更改,则在向上事件上执行选择。因此,您需要将指针位置存储在向下事件中。
然后你可以处理指针移动事件来执行滚动。
【讨论】:
我让它工作了。这并不像我希望的那样微不足道。顺便说一句,这应该适用于普通 Windows,而不仅仅是 Windows Mobile。它是这样的:
创建窗口时(作为主窗口的子窗口)
HWND createCustomDrawArea(const LPCTSTR className, const HWND hWndParent) {
WNDCLASS wndClass = {
CS_HREDRAW | CS_VREDRAW,
(WNDPROC)wndProc,
0,
0,
hInstMain,
NULL,
0,
(HBRUSH)GetStockObject(HOLLOW_BRUSH),
0,
className
};
RegisterClass(&wndClass);
return CreateWindow(
className,
className,
WS_CHILD | WS_TABSTOP,
0, 0, 0, 0,
hWndParent,
NULL,
hInstMain,
NULL
);
}
然后在主函数中(主消息循环):
while(GetMessage(&msg, NULL, 0, 0)) {
if(!handleScrollingMessages(msg.hwnd, msg.message, msg.wParam, msg.lParam) && !TranslateAccelerator(msg.hwnd, NULL, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
我这样做是为了一旦手指(鼠标)按下,您就可以将手指移动到其他地方(仍然在同一个程序中,但可以在滚动窗口之外),它会继续滚动直到您松开(鼠标向上)。消息处理程序如下所示:
inline BOOL handleScrollingMessages(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
static BOOL mouseIsDown = FALSE;
static BOOL isScrolling;
static POINT firstMousePos;
static POINT lastMousePos;
POINT currentMousePos;
switch(message) {
case WM_MOUSEMOVE:
if(!mouseIsDown) {
return FALSE;
}
GetCursorPos(¤tMousePos);
scrollText(currentMousePos.y - lastMousePos.y);
if(!isScrolling && (
firstMousePos.x currentMousePos.x + FINGER_SCROLL_SENSITIVITY ||
firstMousePos.y currentMousePos.y + FINGER_SCROLL_SENSITIVITY
)) {
isScrolling = TRUE;
}
lastMousePos = currentMousePos;
return TRUE;
case WM_LBUTTONDOWN:
if(hWnd == whichPrimaryIsVisible) {
if(!mouseIsDown) {
GetCursorPos(&firstMousePos);
lastMousePos = firstMousePos;
mouseIsDown = TRUE;
isScrolling = FALSE;
}
return TRUE;
}
return FALSE;
case WM_LBUTTONUP:
if(mouseIsDown) {
mouseIsDown = FALSE;
if(isScrolling) {
isScrolling = FALSE;
} else {
if(hWnd == whichPrimaryIsVisible) {
jumpToSong(HIWORD(lParam));
}
}
return TRUE;
}
return FALSE;
}
return FALSE;
}
在普通消息处理程序中,您必须捕获 WM_ERASEBKGND 和 WM_PAINT 消息:
case WM_ERASEBKGND:
if(hWnd == whichPrimaryIsVisible) {
drawBackground(hWnd, (HDC)wParam);
return 1;
}
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_PAINT:
if(hWnd != hWndMain && drawWindowSection(hWnd)) {
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
然后您必须分别绘制背景和文本(前景)。滚动功能如下所示:
inline void scrollText(const int mouseChange) {
RECT wholeAreaRect;
RECT invalidatedRect;
scrollPos += mouseChange;
GetClientRect(whichPrimaryIsVisible, &wholeAreaRect);
ScrollWindowEx(whichPrimaryIsVisible, 0, mouseChange, NULL, &wholeAreaRect, NULL, &invalidatedRect, SW_ERASE | SW_INVALIDATE);
UpdateWindow(whichPrimaryIsVisible);
}
记住 whichPrimaryIsVisible 是滚动窗口(全局变量),而 scrollPos 是一个全局 int。
唯一剩下的就是drawBackground() 和drawWindowSection()。它们在我的程序中很长而且很复杂,因为我让它们也做其他事情(与绘制窗口有关)。如果您真的想要该代码,请给我发消息或其他内容。如果我以正确的方式发布内容,也请告诉我,因为我是在论坛等上发帖的新手。
【讨论】: