2008-10-03 18 views
7

के बाद SetCursor reverts मैं सिस्टम कर्सर को अपनी छवि पर सेट करने के लिए SetCursor का उपयोग कर रहा हूं। कोड इस तरह दिखता है:माउस कर्सर

// member on some class 
HCURSOR _cursor; 

// at init time 
_cursor = LoadCursorFromFile("somefilename.cur"); 

// in some function 
SetCursor(_cursor); 

जब मैं इस कर्सर करता परिवर्तन करते हैं, लेकिन पहले माउस चाल संदेश पर इसे वापस डिफ़ॉल्ट सिस्टम तीर कर्सर को बदल जाता है। प्रोजेक्ट में यह एकमात्र कोड है जो कर्सर सेट कर रहा है। कर्सर को जिस तरह से सेट किया गया है, उसे बनाने के लिए मुझे क्या करने की ज़रूरत है?

उत्तर

9

ऐसा लगता है कि मेरे पास दो विकल्प हैं। पहला यह है कि मार्क रांसॉम ने यहां सुझाव दिया है, जो विंडोज WM_SETCURSOR संदेश का जवाब देना है और उस समय सेटकसर को उस समय के आधार पर कॉल करें जहां माउस है। आम तौर पर खिड़कियां आपको WM_SETCURSOR भेजती हैं जब कर्सर आपकी खिड़की पर होता है, तो आप केवल कर्सर को अपनी विंडो में सेट करेंगे।

दूसरा विकल्प विंडो हैंडल के लिए डिफ़ॉल्ट कर्सर को उसी समय सेट करना है जब मैं SetCursor पर कॉल करता हूं। यह कर्सर को डिफ़ॉल्ट हैंडलर द्वारा WM_SETCURSOR पर सेट करता है। आप दूसरी विधि आप कॉल करने के लिए दोनों SetCursor और SetClassLong या अपने कर्सर अगले माउस चाल जब तक अपडेट नहीं होगा है का उपयोग करते हैं

// defined somewhere 
HWND windowHandle; 
HCURSOR cursor; 

SetCursor(cursor); 
SetClassLong(windowHandle, GCL_HCURSOR, (DWORD)cursor); 

: यह कोड कुछ इस तरह दिखेगा।

5

आपको विंडोज संदेश WM_SETCURSOR पर प्रतिक्रिया देने की आवश्यकता है।

2

आपको अपने HCURSOR हैंडल को दायरे से बाहर नहीं जाने की आवश्यकता है। जब माउस चलता है, तो विंडोज़ संदेश सभी जगह उड़ने लगते हैं, और यह आपके हैंडल को मिटा देगा (ऊपर दिए गए उदाहरण में)।

कक्षा के एक निजी सदस्य एचसीयूआरएसओआर बनाएं, और जब आप LoadCursor ...() और SetCursor() को कॉल करते हैं तो उस हैंडल का उपयोग करें। जब आप कर लेंगे, इसे मुक्त करना न भूलें, और इसे साफ़ करें, या आप संसाधन रिसाव के साथ समाप्त हो जाएंगे।

1

यह व्यवहार इस तरह से होना है। मुझे लगता है कि सबसे सरल समाधान यह है: अपनी विंडो क्लास (RegisterClass || RegisterClassEx) बनाते समय, WNDCLASS.hCursor || WNDCLASSEX.hCursor सदस्य को NULL पर सेट करें।

+0

नल में बदलने से समस्या हल नहीं हुई। कर्सर को बदलने की अनुमति देने के बजाय, कर्सर हमेशा सामान्य तीर के बजाय <-> था। और संदेश WM_SETCURSOR संदेश हमेशा भेजे जा रहे थे, क्योंकि मैं जासूस ++ 64 बिट का उपयोग करके सत्यापित कर सकता था। हालांकि, मैंने उकसाया क्योंकि आपने मुझे कुछ नया सीख लिया है। – sergiol

0

@Heinz Traub के रूप में यह समस्या RegisterClass या RegisterClassEx कॉल पर परिभाषित कर्सर से आती है। आप शायद है कोड की तरह:

BOOL CMyWnd::RegisterWindowClass() 
{ 
    WNDCLASS wndcls; 
    // HINSTANCE hInst = AfxGetInstanceHandle(); 
    HINSTANCE hInst = AfxGetResourceHandle(); 

    if (!(::GetClassInfo(hInst, _T("MyCtrl"), &wndcls))) 
    { 
     // otherwise we need to register a new class 
     wndcls.style   = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; 
     wndcls.lpfnWndProc  = ::DefWindowProc; 
     wndcls.cbClsExtra  = wndcls.cbWndExtra = 0; 
     wndcls.hInstance  = hInst; 
     wndcls.hIcon   = NULL; 
     wndcls.hCursor   = AfxGetApp()->LoadStandardCursor(IDC_ARROW); 
     wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1); 
     wndcls.lpszMenuName  = NULL; 
     wndcls.lpszClassName = _T("MyCtrl"); 

     if (!AfxRegisterClass(&wndcls)) 
     { 
      AfxThrowResourceException(); 
      return FALSE; 
     } 
    } 

    return TRUE; 
} 

जहां wndcls.hCursor कहते हैं जब WM_SETCURSOR संदेश फेंक दिया जाता है क्या कर्सर उपयोग किया जाएगा; यह हर बार होता है जब यह माउस चाल होता है और न केवल।

कक्षा में 'संदेश नक्शा WM_SETCURSOR संदेश के लिए एक प्रवेश जोड़ें::

BEGIN_MESSAGE_MAP(CMyWnd, CWnd) 
    //... other messages 
    ON_WM_SETCURSOR() 
END_MESSAGE_MAP() 

विधि OnSetCursor है, जो माता-पिता वर्ग को पार कर जाएगी जोड़ें'

मैं एक ऐसी ही समस्या इस तरह से हल कार्यान्वयन :

BOOL CMyWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{ 
    if (SomeCondition()) 
     return FALSE; 

    return __super::OnSetCursor(pWnd, nHitTest, message); 
} 

स्पष्टीकरण: जब SomeCondition() सच है, आप माता-पिता के कार्यान्वयन फोन नहीं होंगे।हो सकता है आप हमेशा चाहते हैं माता पिता वर्ग व्यवहार के साथ अधिक्रमण नहीं एक कर्सर के लिए है, तो आप सिर्फ एक भी कम विधि की जरूरत है:

BOOL CMyWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{ 
    return FALSE; 
} 

और हेडर फाइल में विधि की घोषणा है:

afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); 
संबंधित मुद्दे