No announcement yet.

Window Cursor Subclassing

  • Filter
  • Time
  • Show
Clear All
new posts

  • Window Cursor Subclassing

    If have a set of windows which belong to the same registered class. Is it possible to change the cursor shape for only one of that windows? Or must I have two different registered classes?


    Rgds, Aldo

  • #2
    I'm going from memory here, since I'm not at my DEV PC nor anyt reference books, but you can use a %NULL cursor in the window class, and use SetCursor() for each window of that class during, say, %WM_CREATE.

    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    mailto:[email protected]


    • #3
      Lance, thanks for your quick reply.

      ...a window should set the cursor shape only when the cursor is in its client area or when the window is capturing mouse input...
      I already knew SetCursor, but I'm puzzled about it. This is since that API call doesn't need of a window handler... I'm not confident WHICH window will get the new cursor. But if you say it works...

      Rgds, Aldo


      • #4
        I beleive that to duplicate a class is much easy.
           #Compile Exe
           #Register None
           #Dim All
           #Include "WIN32API.INC"
           Function DuplicateClass(OldClassName As String, NewClassName As String) As Long
              Local wc As WNDCLASSEX
              wc.cbSize = SizeOf(wc)
              If GetClassInfoEx(ByVal 0&, ByVal StrPtr(OldClassName), wc) Then
                 wc.hInstance = GetModuleHandle(ByVal 0&)
                 wc.lpszClassName = StrPtr(NewClassName)
                 Function = RegisterClassEx(wc)
              End If
           End Function
           Function PbMain()
              If IsFalse(DuplicateClass("BUTTON", "nBUTTON")) Then Exit Function
              Dim hDlg As Long
              Dialog New 0 ,"Test", , , 100, 55, %WS_CAPTION Or %WS_SYSMENU To hDlg
              Control Add Button,  hDlg, 101, "&Arrow", 10, 10, 80, 14
              Control Add "nButton",  hDlg, 102, "&Hand", 10, 30, 80, 14, %WS_CHILD Or %WS_VISIBLE Or %WS_TABSTOP
              SetClassLong GetDlgItem(hDlg, 102), %GCL_HCURSOR, LoadCursor (ByVal 0&, ByVal %IDC_HAND)
              Dialog Show Modal hDlg
           End Function
        E-MAIL: [email protected]


        • #5
          Semen, thanks for the idea. My question was to reduce the number of registered classes my program uses; when I register the first class, I can also register the second by only changing the name and the cursor handler members of the WNDCLASSEX UDT. I think your code is very good to subclass an existing class, like global classes. I already know where I'll use it...

          Rgds, Aldo


          • #6

            Windows is constantly polling the windows and controls
            to see what the cursor should be through the WM_SETCURSOR

            In your Window (or Dialog) Procedure you can process the
            WM_SETCURSOR message.

                CASE %WM_SETCURSOR
                    SetCursor hCursor&
            According to the API docs, the DefWindowProc will send the WM_SETCURSOR
            to a controls Parent first. If the Parent sets the cursor and returns
            true, then the controls cursor is overridden.

            Otherwise, the childs class cursor is used for the client area and
            the arrow is used for the non-client area.

            Chris Boss
            Computer Workshop
            Developer of "EZGUI"


            • #7
              You can change your cursors anytime within your single class. In the
              visual designer I started (available form PB's files downloads) I change
              the cursors during a drag/size operation and later restore it to
              the classes default. If you use a %NULL pointer, it is your responsability
              to make sure you have default cursor loaded up in the wm_create handler.

              'window class...
              wc.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
              'Set the appropiate Sizing cursor during some operation...
              Call SetCursor(LoadCursor(%NULL,ByVal %IDC_SIZENWSE))
              'Restore the cursor, the Client window will do this for us anyway.
              'but if you register your class with %NULL cursor, you need to do it always.
              Call SetCursor(LoadCursor(%NULL,ByVal %IDC_ARROW))



              • #8
                Chris, Jules --

                I tested SetCursor() inside the WM_SETCURSOR message. It works, but I'm not satisfied of the results. There are many exceptions to verify... it is absolutely easier to have two registered classes and make DefWindowProc work for me! Thanks

                Rgds, Aldo