Announcement

Collapse
No announcement yet.

Big Browser Cursor

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Big Browser Cursor

    Howdy, Jose!

    I wanted to replace the small browser pointer with a large one, so I subclassed the browser and put some code into %WM_SetCursor to make it happen. But, while the cursor changed for the rest of the dialog, it did not change for the browser.

    Can I not simply subclass the embedded browser and take control of the cursor? What I tried below did not work.


    Code:
    'Compilable Example:
    #Compile Exe
    #Dim All
    %Unicode = 1
    %UseWebBrowser = 1            ' // Use the WebBrowser control
    #Include Once "CWindow.inc"   ' // CWindow class
    %IDC_WebBrowser = 1001
    Global hDlg, hBrowser, hCursor As Dword, OldProc&, pWindow As IWindow
    
    Function PBMain
       Dialog New Pixels, 0, "WebBrowser", , , 800, 600, %WS_OverlappedWindow To hDlg
       pWindow = Class "CWindow"
       hBrowser = pWindow.AddWebBrowserControl(hDlg, %IDC_WEBBROWSER, "http://www.powerbasic.com",Nothing, 0, 0, 600,400)
       Dialog Show Modal hDlg, Call DlgProc
    End Function
    
    CallBack Function DlgProc() As Long
       Select Case CbMsg
          Case %WM_InitDialog
             hCursor = LoadImage (ByVal 0, "c:\windows\cursors\larrow.cur", %IMAGE_ICON, 125, 125, %LR_LOADFROMFILE)
             OldProc& = SetWindowLong(hBrowser, %GWL_WndProc, CodePtr(NewProc))  'subclass
          Case %WM_SetCursor
             SetCursor hCursor
             Function = 1
          Case %WM_Destroy
             SetWindowLong hBrowser, %GWL_WNDPROC, OldProc&   'un-subclass
      End Select
    End Function
    
    Function NewProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
       Select Case Msg
          Case %WM_SetCursor
             SetCursor hCursor
             Function = 1
             Exit Function
       End Select
       Function = CallWindowProc(OldProc&, hWnd, Msg, wParam, lParam)
    End Function

  • #2
    > Can I not simply subclass the embedded browser and take control of the cursor?

    You're not subclassing the web browser control, but the window that hosts it. The Webrowser control is not a standard Windows control, but an ActiveX control that renders html code.

    To change the cursor, your html page may need to use CSS styles and set the CSS Cursor property.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      Howdy, Jose!

      Thanks for that clarification.

      The pages I'm viewing are not of my making, so as best I know, changing the original CSS isn't possible. But, perhaps I can find a way to override that. I'll nose around.

      Comment


      • #4
        The cursor is a system resource, therefore, one method is to have the OLE container implement the IOleInPlaceSiteEx and IOleInPlaceSiteWindowless interfaces to manipulate it.
        The following is an excerpt from the OLE Control 96 specification:

        An object can indicate that it did not process a mouse message by returning S_FALSE. The container should then perform the default behavior for the message. For all mouse message except WM_SETCURSOR, it should just call DefWindowProc. For WM_SETCURSOR the container can either set the cursor itself or do nothing. Objects can also use IOleInPlaceWindowlessSite::OnDefWindowMessage to obtain the default message processing from the container. In the case of the WM_SETCURSOR message, this allows an object to take action if the container did not set the cursor.

        Only a few methods from each of the interfaces will have to be implemented. Samples of two crucial ones follows:

        Code:
        '*** IOleInPlaceSiteEx::OnInPlaceActivateEx
        
        FUNCTION tntIOleInPlaceSiteEx_OnInPlaceActivateEx(BYVAL pThis AS DWORD, pfNoRedraw AS LONG, BYVAL dwFlags AS DWORD) AS LONG
        
          LOCAL pCIFace       AS CIFace PTR
          LOCAL pTenant       AS Tenant PTR
        
        #IF %DEF(%OLEDEBUG)
          SaveToLog "IOleInPlaceSiteEx::OnInPlaceActivateEx"
        #ENDIF
        
          pCIFace = pThis
          pTenant = @pCIFace.pObject
        
          IF (dwFlags AND %ACTIVATE_WINDOWLESS) = %ACTIVATE_WINDOWLESS THEN
            @pTenant.m_bWindowless = %TRUE
          ELSE
        '    IF ISTRUE VARPTR(pfNoRedraw) THEN
        ' pfNoRedraw = %FALSE
        '    END IF
          END IF
        
            IF ISTRUE VARPTR(pfNoRedraw) THEN
              pfNoRedraw = %TRUE
            END IF
        
          FUNCTION = tntIOleInPlaceSiteEx_OnInPlaceActivate(pThis)
        
        END FUNCTION

        Code:
        FUNCTION tntIOleInPlaceSiteWindowless_OnDefWindowMessage _
          ( _
          BYVAL pThis   AS DWORD, _ ' [IN] IOleInPlaceSiteWindowless interface pointer
          BYVAL msg     AS DWORD, _ ' [IN] Identifier for the window message provided to the container by Windows
          BYVAL wParam  AS DWORD, _ ' [IN] Parameter for the window message provided to the container by Windows
          BYVAL lParam  AS LONG, _  ' [IN] Parameter for the window message provided to the container by Windows
                plResult  AS LONG _ ' [OUT] Pointer to result code for the window message as defined in the Windows API
          ) AS LONG
        
          LOCAL pCIFace       AS CIFace PTR
          LOCAL pTenant       AS Tenant PTR
          LOCAL lRet          AS LONG
        
          pCIFace = pThis
          pTenant = @pCIFace.pObject
        
        #IF %DEF(%OLEDEBUG)
          SaveToLog "IOleInPlaceSiteWindowless::OnDefWindowMessage"
        #ENDIF
        
          SELECT CASE msg
            CASE %WM_SETCURSOR, %WM_CONTEXTMENU, %WM_HELP
              FUNCTION = %S_FALSE
        
            CASE ELSE
              lRet = DefWindowProc(@pTenant.m_hWndSite, msg, wParam, lParam)
              FUNCTION = %S_OK
          END SELECT
        
          IF ISTRUE VARPTR(plResult) THEN plResult = lRet
        
        END FUNCTION
        Dominic Mitchell
        Phoenix Visual Designer
        http://www.phnxthunder.com

        Comment


        • #5
          Howdy, Dominic!

          Somehow I missed your post - just saw it. Thanks for the example and I'll look it over this morning!
          Last edited by Gary Beene; 15 Aug 2017, 08:08 AM.

          Comment


          • #6
            Gary, perhaps this might help as the customized cursor is nicer

            Code:
            ' Nice Browser cursor.bas
            'https://forum.powerbasic.com/forum/jose-s-corner/discussion/763266-big-browser-cursor
            #COMPILE EXE
            #DIM ALL
            %Unicode = 1
            %UseWebBrowser = 1            ' // Use the WebBrowser control
            #INCLUDE ONCE "CWindow.inc"   ' // CWindow class
            
            
            %IDC_WebBrowser = 1001
            %IDC_ButtonExit = 1003
            %IDC_LabelExit = 1006
            
            
            GLOBAL hDlg, hBrowser, hCursor AS DWORD
            GLOBAL OldProc&, pWindow AS IWindow
            
            ' for the image button
            #RESOURCE BITMAP, 700, "door small2.bmp"
            '  special cursor
            #RESOURCE RES "HdCursor.res"
            
            
            '========================
            FUNCTION PBMAIN
               LOCAL  hFONTb  AS DWORD
            
               FONT END hFONTb
               FONT NEW "Arial",9,1 TO hFONTb
            
                ' setup the main large window
               DIALOG NEW PIXELS, 0, "WebBrowser", , , 1000, 700, %WS_BORDER  OR %WS_DLGFRAME TO hDlg
               pWindow = CLASS "CWindow"
            
               ' set up a smaller window showing the web page
               hBrowser = pWindow.AddWebBrowserControl(hDlg, %IDC_WEBBROWSER, _
                         "https://forum.powerbasic.com/",NOTHING, 0, 0, 1000,500)
            
            
               CONTROL ADD LABEL, hDlg, %IDC_LabelExit, "Click to exit after viewing ", 35, 580, 150, 15
               CONTROL SET FONT hDlg, %IDC_LabelExit , hFONTb
               CONTROL SET COLOR hDlg, %IDC_LabelExit, %RGB_MAGENTA  , -2
            
               ' Add an Exit button
               CONTROL ADD IMGBUTTONX, hDlg, %IDC_ButtonExit,"#700", 185, 580, 25, 25
            
               DIALOG SHOW MODAL hDlg, CALL DlgProc
            
            END FUNCTION
            
            
            
            '============================
            CALLBACK FUNCTION DlgProc() AS LONG
               SELECT CASE CBMSG
            
                  CASE %WM_INITDIALOG
                       '  special cursor handle
                         hCursor = LoadCursor(GetModuleHandle( BYVAL %Null), "#800")
            
                     OldProc& = SetWindowLong(hBrowser, %GWL_WndProc, CODEPTR(NewProc))  'subclass
            
                  CASE %WM_SetCursor
                     SetCursor hCursor
                     FUNCTION = 1
            
                 CASE %WM_COMMAND
                     SELECT CASE CBCTL
                         CASE %IDC_ButtonExit
                          IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                              DIALOG END CBHNDL
                         END IF
                     END SELECT
            
            
                  CASE %WM_DESTROY
                     SetWindowLong hBrowser, %GWL_WNDPROC, OldProc&   'un-subclass
              END SELECT
            END FUNCTION
            
            
            '============================================
            FUNCTION NewProc(BYVAL hWnd AS LONG, BYVAL Msg AS LONG, _
                 BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
               SELECT CASE Msg
                  CASE %WM_SetCursor
                     SetCursor hCursor
                     FUNCTION = 1
                     EXIT FUNCTION
               END SELECT
               FUNCTION = CallWindowProc(OldProc&, hWnd, Msg, wParam, lParam)
            END FUNCTION
            This is package in here Nice browser cursor.zip

            Comment


            • #7
              Hi Anne!

              Thanks for the example. But when I run your EXE, the embedded browser does not use the custom cursor. It worked for you? I can see the custom cursor outside the browser, just not inside.

              Your code is similar to what I posted in #1, I think, where I used subclassing. But as Jose pointed out in #2, that doesn't work as I expected it to work!

              Comment

              Working...
              X