2010-03-01 99 views

回答

1

没有进入你应该关注的技术问题,将“鼠标”点击事件分为“鼠标”向下和“鼠标”向上事件。

如果自从关闭事件后指针位置没有改变,则执行up事件的选择。所以你需要在down事件中存储指针位置。

然后你可以处理指针移动事件来执行滚动。

+0

嘿,我为什么没有想到这一点。非常感谢,我会试一试。 – Warpspace 2010-03-01 11:48:00

1

我得到它的工作。这并不像我所希望的那样微不足道。顺便说一下,这应该在普通的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(&currentMousePos); 

      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()。他们在我的程序中冗长而令人费解,因为我也让他们做其他事情(与绘制窗口有关)。如果你真的想要这个代码,那么给我发一条消息或其他东西。也让我知道,如果我已经发布的东西正确的方式,因为我是新的发布论坛等

相关问题