Announcement

Collapse
No announcement yet.

%LB_GETITEMRECT

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

  • %LB_GETITEMRECT

    I try to display a popup-menu in a listbox when the user dblclick on a listitem.
    But %LB_GETITEMRECT does not seem to return correct values.(Always 0)
    Any Ideas How to do this?
    Code:
    CallBack Function CBF_LISTBOX()
    Static Li&,LiTxt$,Id&,hPopUp&
    Local R As RECT 
      If CBCtlMsg = %LBN_DBLCLK Then
       LiTxt$=Space$(300)
       Control Send CBHndl,CBCtl,%LB_GETCURSEL,0,0 To Li&
       If Li& = %LB_ERR Then Exit Function
       Control Send CBHndl,CBCtl,%LB_GETTEXT,Li&,StrPtr(LiTxt$) To Li&
       If Li& = %LB_ERR Then Exit Function
       LiTxt$ = Trim$(Left$(LiTxt$,Li&))
       Select Case CBHndl
        Case ghDlg_Logg
        Case ghDlg_Gate
        Case ghDlg_Jobb
        Case ghDlg_DtaQ
        Case ghDlg_AlertQue
        Case ghDlg_AlertHold
        Case ghDlg_ErrList
         If Li& > -1 Then
         SendMessage CBlParam,%LB_GETITEMRECT,Li&,ByVal VarPtr(R)                       
         MsgBox Str$(R.nleft)+Str$(R.nTop)
         Menu New Popup To hPopup&
         Menu Add String, hPopup&, "Visa Transaktionen",900, %MF_ENABLED
         Menu Add String, hPopup&, "-",901, %MF_ENABLED
         Menu Add String, hPopup&, "Radera list-raden", 902, %MF_ENABLED
         Menu Add String, hPopup&, "Best Choice", 903, %MF_ENABLED
         Id& =TrackPopupMenu(hPopup&, %TPM_LEFTALIGN Or %TPM_RIGHTBUTTON Or %TPM_RETURNCMD,ByVal R.nRight,ByVal R.nBottom, 0,CBHndl, ByVal 0)
         MsgBox "Meny = " & Format$(Id&)
        End If 
       End Select 
      End If
    End Function
    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

  • #2
    Maybe it'll help if you remove BYVAL for the RECT structure? Not
    sure, but the following is what I have used in my checklistbox -
    it works fine, so maybe it can help you find a solution:
    Code:
            IF wParam = %MK_LBUTTON  THEN                             'respond to mouse click
               LOCAL pt AS POINTAPI, rc AS RECT, t AS LONG
               pt.x = LOWRD(lParam) : pt.y = HIWRD(lParam)            'get cursor pos
               t = SendMessage(hWnd, %LB_ITEMFROMPOINT, 0, MAKLNG(pt.x, pt.y)) 'get sel. item
               CALL SendMessage(hWnd, %LB_GETITEMRECT, t, VARPTR(rc)) 'get sel. item's rect
               '..etc.
    ------------------

    Comment


    • #3
      Thanks Börje!
      You got me back on the original idea to use a context-menu.
      This is the code
      I still have to figure out how to convert list-item to screen-coordinates
      to enable keyboard-triggering of the context-menu
      Code:
      CallBack Function DlgProc_List
      Local CurItem&,x&,y&,hPopUp&
      LOCAL pt AS POINTAPI
        Select Case CBMsg
         Case %WM_CONTEXTMENU                             
          Select Case GetDlgCtrlID(CBwParam )
           'Mask other than listboxes
           Case %Listbox
            'check for keyboard-generated 
            x& = LoWrd(CBlParam ) : y& = HiWrd(CBlParam )
            If (x&=65535) Or (y&=65535) Then
             'Get the LOC of the listitem in focus if keyboard
             Exit Function 
            End If
            '-Convert mousepos to list-item------------------         
            pt.x = x& : pt.y = y&
            ScreenToClient CBwParam,pt
            CurItem& = LoWrd(SendMessage(CBwParam,%LB_ITEMFROMPOINT,0,MakLng(pt.x,pt.y)))
            '--If valid list-item, select it,and show popup-menu
            If CurItem& > -1 Then
             SendMessage CBwParam,%LB_SETCURSEL,CurItem&,0
             Menu New Popup To hPopup&
             Menu Add String, hPopup&, "Visa Transaktionen",900, %MF_ENABLED
             Menu Add String, hPopup&, "-",901, %MF_ENABLED
             Menu Add String, hPopup&, "Radera raden", 902, %MF_ENABLED
             Menu Add String, hPopup&, "Flytta rad till Alert", 903, %MF_ENABLED
             mnuId& =TrackPopupMenu(hPopup&, %TPM_LEFTALIGN Or %TPM_RIGHTBUTTON Or %TPM_RETURNCMD, x&, y&, 0,CBwParam, ByVal 0)
             Select Case mnuId&
              Case 900
              Case 902
              Case 903
             End Select 
            End If      
           End Select
      End Function
      ------------------
      Fred
      mailto:[email protected][email protected]</A>
      http://www.oxenby.se

      Fred
      mailto:[email protected][email protected]</A>
      http://www.oxenby.se

      Comment


      • #4
        Looked again - problem seems to have been wrong handle with %LB_GETCURSEL.
        I did a subclassed sample here, to also trap keyboard input. Following
        works fine:
        Code:
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        ' Simple sample of menu in listbox
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        #COMPILE EXE
        #INCLUDE "WIN32API.INC"
         
        GLOBAL oldListProc AS LONG 'for address of original Listbox procedure
        DECLARE CALLBACK FUNCTION DlgProc
        DECLARE CALLBACK FUNCTION ListProc
         
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        ' Create dialog and controls, etc
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        FUNCTION PBMAIN
           LOCAL I AS LONG, hDlg AS LONG, hList AS LONG
           DIALOG NEW 0, "Double-click for menu",,, 120, 110, %WS_CAPTION OR %WS_SYSMENU TO hDlg
           CONTROL ADD LABEL, hDlg, -1, "Or use Arrow keys and Enter", 4, 98, 112, 10, %SS_CENTER
           CONTROL ADD LISTBOX, hDlg, 100, , 4, 4, 112, 100, %WS_CHILD, %WS_EX_CLIENTEDGE
         
          CONTROL HANDLE hDlg, 100 TO hList                                   'Subclass List control
          oldListProc = SetWindowLong(hList, %GWL_WNDPROC, CODEPTR(ListProc)) 'to trap keyboard input
          SetFocus hList                                                      'Give Listbox focus
         
           FOR I = 1 TO 50
               LISTBOX ADD hDlg, 100, "This is item " + FORMAT$(I)
           NEXT
         
           DIALOG SHOW MODAL hDlg CALL DlgProc
         
          IF oldListProc THEN SetWindowLong hList, %GWL_WNDPROC, oldListProc  'Restore from subclass at exit
        END FUNCTION
         
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        ' Main dialog callback
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        CALLBACK FUNCTION DlgProc
           SELECT CASE CBMSG
              CASE %WM_COMMAND
                 SELECT CASE CBCTL    'result from menu selection
                    CASE 900 : MSGBOX "Visa Transaktionen"
                    CASE 902 : MSGBOX "Radera list-raden"
                    CASE 903 : MSGBOX "Best Choice"
                 END SELECT
           END SELECT
        END FUNCTION
         
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        ' Listbox callback
        '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        CALLBACK FUNCTION ListProc
          SELECT CASE CBMSG
             CASE %WM_KEYUP
                IF CBWPARAM = %VK_RETURN THEN    'Trap Enter key on up, trigger menu
                   CONTROL SEND GetParent(CBHNDL), 100, %WM_LBUTTONDBLCLK, 0, 0
                   FUNCTION = 0 : EXIT FUNCTION
                END IF
                
             CASE %WM_LBUTTONDBLCLK
                BEEP
                LOCAL I AS LONG, R AS RECT
                I = SendMessage(CBHNDL, %LB_GETCURSEL, 0, 0)
                IF I <> %LB_ERR THEN
                   CALL SendMessage(CBHNDL, %LB_GETITEMRECT, I, VARPTR(R))
                   MENU NEW POPUP TO hPopup&
                   MENU ADD STRING, hPopup&, "Visa Transaktionen", 900, %MF_ENABLED
                   MENU ADD STRING, hPopup&, "-",                  901, %MF_ENABLED
                   MENU ADD STRING, hPopup&, "Radera list-raden",  902, %MF_ENABLED
                   MENU ADD STRING, hPopup&, "Best Choice",        903, %MF_ENABLED
                   CALL MapWindowPoints(CBHNDL, %HWND_DESKTOP, BYVAL VARPTR(R), 2)
                   Id& =TrackPopupMenu(hPopup&, %TPM_LEFTALIGN OR %TPM_RIGHTBUTTON, _
                                       BYVAL R.nRight, BYVAL R.nBottom, 0, GetParent(CBHNDL), BYVAL 0)
                   FUNCTION = 0 : EXIT FUNCTION
                END IF
          END SELECT
         
          FUNCTION = CallWindowProc(oldListProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
        END FUNCTION
        ------------------

        Comment


        • #5
          Börje,
          My original idea was to generate WM_CONTEXTMENU (mouse RightButton) in the listbox
          I had problems to select the listitem closest to mousepointer, but that
          problem is solved now.
          I have also solved the problem with keyboard-generated WM_CONTEXTMENU

          Code:
            
          #Compile Exe
          #Register None
          #Dim All         
          #Include "win32api.inc" 
            
            
          %LBText             = 100
          %LISTBOX            = 101
          '--------------------------------------------------
          Declare CallBack Function Form_DlgProc
            
          Function PbMain
          Local hDlg&,Style&,ExStyle&,Lst$(),i&
            
            Style& = %WS_POPUP OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR _
                     %DS_SYSMODAL OR %DS_CENTER
            ExStyle& = 0
            
            Dialog New %HWND_DESKTOP,"Context-Menu in Listbox", 0, 0,267,177, _
                       Style&, ExStyle& TO hDlg&
            
            Control Add Label,hDlg&,%LBText,"", 3, 5,259, 12, _
                       %WS_CHILD OR %WS_VISIBLE OR %SS_LEFT OR %WS_DLGFRAME
            
            ReDim LST$(0:99)
            For i& = 0 to 99
             lst$(i&)="**This is listindex " & Str$(i&) & "    ---------"
            Next i&
               
            Control Add ListBox,hDlg&,%LISTBOX,lst(), 3, 20,259,153, _
              %WS_CHILD OR %WS_VISIBLE OR %LBS_NOTIFY OR %WS_VSCROLL OR %WS_BORDER OR %WS_TABSTOP 
              
           Dialog Show Modal hDlg&, Call Form_DlgProc
          End Function
          
          CallBack Function Form_DlgProc
          Local CurSel&,CurItem&,x&,y&,hPopUp&,Id&
          Local R As RECT
          Local pt AS POINTAPI
          Local TopItem&,ItemHight&,Tmp$
               
            Select Case CBMsg
             Case %WM_TIMER
             Case %WM_SIZE
             Case %WM_CLOSE 
             Case %WM_CONTEXTMENU                             
              Select Case GetDlgCtrlID(CBwParam )
               Case %Listbox
          '--Execute only if in listbox----------------------------------------
                CurSel& = SendMessage(CBwParam,%LB_GETCURSEL,0,0)
                x& = LoWrd(CBlParam ) : y& = HiWrd(CBlParam )
                If (x&=65535) Or (y&=65535) Then
          '--Keyboard Shift F10 is used to trigger WM_CONTEXTMENU--------------
                 If CurSel& < 0 Then Exit Function 
                 TopItem&   = SendMessage(CBwParam,%LB_GETTOPINDEX, 0, 0)
                 ItemHight& = SendMessage(CBwParam,%LB_GETITEMHEIGHT,0,0)
                 GetClientRect CBwParam,ByVal VarPtr(R)
                 pt.x = (R.nRight-R.nLeft)/4
                 pt.y = ItemHight&*(CurSel&-TopItem&)+ItemHight&
                 ClientToScreen CBwParam,pt
                 x&=pt.x:y&=pt.y
                Else
          '--Mouse Right button is used to trigger WM_CONTEXTMENU--------------               
                 pt.x = x& : pt.y = y&
                 ScreenToClient CBwParam,pt
                 CurItem& = LoWrd(SendMessage(CBwParam,%LB_ITEMFROMPOINT,0,MakLng(pt.x,pt.y)))
                 If CurItem& <> CurSel& Then _
                    SendMessage CBwParam,%LB_SETCURSEL,CurItem&,0:CurSel& = CurItem&
                End If 
          '--Build & Show the PopUp-menu---------------------------------------
                Menu New Popup To hPopup&
                Menu Add String, hPopup&, "Show Listindex",900, %MF_ENABLED
                Menu Add String, hPopup&, "Show List-Text",901, %MF_ENABLED
                Menu Add String, hPopup&, "Delete this Line", 902, %MF_ENABLED
                Menu Add String, hPopup&, "Add a line here", 903, %MF_ENABLED
                Menu Add String, hPopup&, "Add a line at end", 904, %MF_ENABLED
                Id& =TrackPopupMenu(hPopup&, _
                                    %TPM_LEFTALIGN Or %TPM_RIGHTBUTTON Or %TPM_RETURNCMD, _
                                    x&, y&, 0,CBwParam, ByVal 0)
          '--Execute menu-command----------------------------------------------
                Select Case Id&
                 Case 900
                  Control Set Text CBHndl,%lbText,"Selected Listitem is no " & Format$(CurSel&)
                 Case 901
                  ListBox Get Text CBHndl,%Listbox To Tmp$
                  Control Set Text CBHndl,%lbText,"Selected text is " & UCase$(Tmp$)
                 Case 902
                  ListBox Delete CBHndl,%ListBox,CurSel& + 1
                  Control Set Text CBHndl,%lbText,"Line " & Format$(CurSel&) & " is deleted"
                 Case 903
                  Control Set Text CBHndl,%lbText,"No code to execute"
                 Case 904 
                  CurItem& = SendMessage(CBwParam,%LB_GETCOUNT,0,0)
                  Tmp$="**This is listindex " & Str$(CurItem&) & "    ---------"
                  Control Set Text CBHndl,%lbText,"This line hopefully added at end " & UCase$(Tmp$)
                  ListBox Add CBHndl,%ListBox,Tmp$
                 Case Else
                  Control Set Text CBHndl,%lbText,"No selection"
                End Select      
               End Select
            End Select
          End Function
          ------------------
          Fred
          mailto:[email protected][email protected]</A>
          http://www.oxenby.se

          Yes, I haave changed ListBox Delete ....




          [This message has been edited by Fred Oxenby (edited February 28, 2001).]
          Fred
          mailto:[email protected][email protected]</A>
          http://www.oxenby.se

          Comment


          • #6
            I see. BTW, you've probably already notised this, but LISTBOX DELETE
            starts from 1 and %LB_GETCURSEL from 0. Easy to make mistakes there.
            In other words, wrong item is deleted in your code. Should be:
            LISTBOX DELETE CBHNDL,%ListBox, CurSel& + 1


            ------------------

            Comment


            • #7
              BTW, a tip: By adding %DS_MODALFRAME to a dialog, you automatically
              get possibility to maximize it via the system menu, in minimized mode.
              I have seen this in many samples here, worth checking out, since we
              don't always want to allow our users to do this (usually looks real bad).

              Test and see. Run your code, minimize the prog, right-click over
              minimized prog in taskbar and you can maximize it (at least in Win98).
              Remove %DS_MODALFRAME from style, and problem is fixed..

              ------------------


              [This message has been edited by Borje Hagsten (edited February 28, 2001).]

              Comment


              • #8
                Originally posted by Borje Hagsten:
                Remove %DS_MODALFRAME from style, and problem is fixed..
                It works correctly in WIN2000/PRO but not in WIN2000/ME

                ------------------
                Fred
                mailto:[email protected][email protected]</A>
                http://www.oxenby.se



                [This message has been edited by Fred Oxenby (edited February 28, 2001).]
                Fred
                mailto:[email protected][email protected]</A>
                http://www.oxenby.se

                Comment


                • #9
                  Yet another interesting difference between what should be basically
                  similar systems (2000 and 2000PRO). Guess how fun this will be when
                  next version, XP is released..


                  ------------------

                  Comment


                  • #10
                    PMJI, but there's no such thing as 2000/ME, unless MS has changed something very recently.

                    The NT series of Windows is NT, 2000, and (soon) XP.

                    The 9x series of Windows is 95, 98, and ME. ME is the official end of the line.

                    XP, while it is part of the NT series, is intended to be the replacement for ME. But they are from different "families". XP is intended to replace ME because the 9x series has been terminated.

                    There is quite a bit of consistency within the two families, but they are significantly different from each other.

                    Personally, I don't expect XP to be greatly different from NT and 2000.

                    -- Eric

                    ------------------
                    Perfect Sync: Perfect Sync Development Tools
                    Email: mailto:[email protected][email protected]</A>



                    [This message has been edited by Eric Pearson (edited February 28, 2001).]
                    "Not my circus, not my monkeys."

                    Comment


                    • #11
                      Like they say in this line of business - expect nothing, be prepared
                      for anything. There are at least two different versions of Win2000.
                      Also, there are at least two different versions of Win95/98 and ME.
                      The last one currently causing *a lot* of problems, because it
                      depends on how people have got it. If bought in fancy box in a store,
                      no DOS and some new system files. If downloaded as a Win98-upgrade
                      from MS, same as 98, but with additional Multmedia support.

                      Then of course, NT and a bunch of service packs, all of them with
                      slightly different "features" to consider. To be somewhat sure our
                      software is safe enough for public release, one actually need to
                      have at least 15 different clean systems installed for test. Like
                      I have said before, this is become ridiculous..

                      For private development or corporate work, no big problem, we can
                      target the system directly. For public use, like shareware, etc,
                      Windows is becoming impossible to work with. I'm very much involved
                      in the shareware biz and this last year, several people I know has
                      given up and resorted to contract programming instead. I myself is
                      about to do the same, or whatever else I can find. Had hoped working
                      for PB could be a way out of it, since I'm so dedicated to this
                      language, but they weren't interested (or probably more like I
                      couldn't explain/present myself well enough..

                      When you have a popular program out there, the support burdon today
                      has become too much for many of us. Not only because the user base
                      has less knowledge today. That's the easy part. When you get a 100
                      mail saying the program works fine in this or that system, and another
                      100 saying it don't, you're in for a lot of work.

                      You test on your own systems and all works fine. You ask your Beta-
                      testers for help, and all works fine. You know you have at least 10000
                      users with almost exact same system, all works fine. Still, a 100 is
                      waiting for your answer on why it doesn't work in their systems, and
                      tomorrow, another 100 will be knocking on the door. Sigh..

                      I've been selling my shareware since -95, and must say, support burdon
                      from this last year alone has been heavier than all those years before
                      put together - this mostly caused by Microsofts inconsistent systems..

                      I am not looking forward to yet another buggy version of Windows..


                      ------------------

                      Comment


                      • #12
                        Originally posted by Borje Hagsten:
                        [B]Like they say in this line of business - expect nothing, be prepared
                        for anything. There are at least two different versions of Win2000.
                        Also, there are at least two different versions of Win95/98 and ME.
                        Eric is right on the money.

                        To be clear, the are indeed a few versions of Windows 2000, but none of them are _closely_ related to Windows ME, since ME is a hybrid update of Win95/98, yet 2000 is a pure 32-bit update to NT4. In other words, ME is more like a cousin of the 2000 series, rather than a brother.

                        In the case of Microsoft's Windows branding, "2000" and "Millennium" mean quite different things!

                        In the NT5 series, there is Win2000 Professional, Server, Advanced Server (and a couple more even more advanced/expensive versions I can't remember the name of).

                        In the hybrid 16/32 bit series, there is Win95a, 95b, OSR2, OSR2.1, ORS2.5, 98, 98SE, and ME.

                        Therefore the term "2000/2000Pro" refers to just one O/S.

                        Maybe you ment to say "ME vs. 2000"?

                        (E&OE excepted!)

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

                        Comment

                        Working...
                        X