我正在win32中为Windows Mobile平台制作一个程序(在WM6.1上测试)。大多数主窗口都包含一个文本框,我想用手指滚动它而不是选择文本。我该怎么做呢?
答案 0 :(得分:1)
如果不进入技术细节,您应该考虑将“鼠标”点击事件分为“鼠标”和“鼠标”事件。
如果指针位置自down事件以来没有改变,则对up事件执行选择。因此,您需要将指针位置存储在向下事件中。
然后你可以处理指针移动事件来执行滚动。
答案 1 :(得分:1)
我得到了它的工作。这并不像我希望的那样微不足道。顺便说一下,这应该适用于普通的窗户,而不仅仅是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
);
}
然后在main函数(主消息循环)中:
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()。它们在我的程序中很长很复杂,因为我让它们做其他事情(这与绘制窗口BTW有关)。如果你真的想要那些代码,那么给我发消息或者其他什么。如果我以正确的方式发布内容,请告诉我,因为我刚刚在论坛上发帖等。