PowerBASIC Peer Support Forums
 

Go Back   PowerBASIC Peer Support Forums > User to user Discussions > PowerBASIC for Windows

PowerBASIC for Windows User to user discussions about the PB/Win (formerly PB/DLL) product line. Discussion topics include PowerBASIC Forms, PowerGEN and PowerTree for Windows.

Reply
 
Thread Tools Display Modes
  #1  
Old Aug 26th, 2011, 09:13 AM
Bill Scharf Bill Scharf is offline
Member
 
Join Date: Aug 2003
Posts: 123
Question ListView_getsubItemRect for first column?

I don't see any other posts about this, so I will throw this out there. I am having issues with getting the RECT size for the first column in a listview. The r.right returned is always huge (by huge, I mean bigger than the width of the entire control). Here is an example I slapped together in PB form1 1.5, but compiled with PBwin 10:

Code:
#COMPILE EXE
#DIM ALL

'------------------------------------------------------------------------------
'   ** Includes **
'------------------------------------------------------------------------------
#PBFORMS BEGIN INCLUDES
%USEMACROS = 1
#IF NOT %DEF(%WINAPI)
    #INCLUDE "WIN32API.INC"
#ENDIF
#IF NOT %DEF(%COMMCTRL_INC)
    #INCLUDE "COMMCTRL.INC"
#ENDIF
#INCLUDE "PBForms.INC"
#PBFORMS END INCLUDES
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Constants **
'------------------------------------------------------------------------------
#PBFORMS BEGIN CONSTANTS
%IDD_DIALOG1         =  101
%IDC_SYSLISTVIEW32_1 = 1001
%IDC_BUTTON1         = 1002
#PBFORMS END CONSTANTS
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Declarations **
'------------------------------------------------------------------------------
DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
DECLARE FUNCTION SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
    lColCnt AS LONG, BYVAL lRowCnt AS LONG) AS LONG
DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
#PBFORMS DECLARATIONS
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Main Application Entry Point **
'------------------------------------------------------------------------------
FUNCTION PBMAIN()
    PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _
        %ICC_INTERNET_CLASSES)

    ShowDIALOG1 %HWND_DESKTOP
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** CallBacks **
'------------------------------------------------------------------------------
CALLBACK FUNCTION ShowDIALOG1Proc()
LOCAL hctl AS LONG
LOCAL r AS rect
    SELECT CASE AS LONG CBMSG
        CASE %WM_INITDIALOG
            ' Initialization handler

        CASE %WM_NCACTIVATE
            STATIC hWndSaveFocus AS DWORD
            IF ISFALSE CBWPARAM THEN
                ' Save control focus
                hWndSaveFocus = GetFocus()
            ELSEIF hWndSaveFocus THEN
                ' Restore control focus
                SetFocus(hWndSaveFocus)
                hWndSaveFocus = 0
            END IF

        CASE %WM_COMMAND
            ' Process control notifications
            SELECT CASE AS LONG CBCTL
                CASE %IDC_SYSLISTVIEW32_1

                CASE %IDC_BUTTON1
                    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_1 TO hCtl
'lets get the bounds of the first cell
                            ListView_getsubItemRect hCtl, 0, 0, %LVIR_BOUNDS, BYVAL VARPTR(R)
                        MSGBOX "r.right=  " + FORMAT$(r.right) + $CRLF + _
                                "r.top=  " + FORMAT$(r.top) + $CRLF + _
                                "r.bottom=  " + FORMAT$(r.bottom) + $CRLF + _
                                "r.left=  " + FORMAT$(r.left),,"rect size"

'Why is r.right returning 294?
'the control is only 210 in width?
                    END IF

            END SELECT
    END SELECT
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Sample Code **
'------------------------------------------------------------------------------
FUNCTION SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lColCnt _
    AS LONG, BYVAL lRowCnt AS LONG) AS LONG
    LOCAL lCol   AS LONG
    LOCAL lRow   AS LONG
    LOCAL hCtl   AS DWORD
    LOCAL tLVC   AS LV_COLUMN
    LOCAL tLVI   AS LV_ITEM
    LOCAL szBuf  AS ASCIIZ * 32
    LOCAL lStyle AS LONG

    CONTROL HANDLE hDlg, lID TO hCtl

    lStyle = ListView_GetExtendedListViewStyle(hCtl)
    ListView_SetExtendedListViewStyle(hCtl, lStyle OR %LVS_EX_FULLROWSELECT _
        OR %LVS_EX_GRIDLINES)

    ' Load column headers.
    tLVC.mask    = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM
    tLVC.fmt     = %LVCFMT_LEFT
    tLVC.pszText = VARPTR(szBuf)
    FOR lCol = 0 TO lColCnt - 1
        szBuf       = USING$("Column #", lCol)
        tLVC.iOrder = lCol
        ListView_InsertColumn(hCtl, lCol, tLVC)
    NEXT lCol

    ' Load sample data.
    FOR lRow = 0 TO lRowCnt - 1
        tLVI.stateMask = %LVIS_FOCUSED
        tLVI.pszText   = VARPTR(szBuf)
        tLVI.iItem     = lRow
        FOR lCol = 0 TO lColCnt - 1
            szBuf         = USING$("Column # Row #", lCol, lRow)
            tLVI.iSubItem = lCol
            tLVI.lParam   = lRow
            IF lCol = 0 THEN
                tLVI.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
                ListView_InsertItem(hCtl, tLVI)
            ELSE
                tLVI.mask = %LVIF_TEXT
                ListView_SetItem(hCtl, tLVI)
            END IF
        NEXT lCol
    NEXT lRow

    ' Auto size columns.
    FOR lCol = 0 TO lColCnt - 2
        ListView_SetColumnWidth(hCtl, lCol, %LVSCW_AUTOSIZE)
    NEXT lCol
    ListView_SetColumnWidth(hCtl, lColCnt - 1, %LVSCW_AUTOSIZE_USEHEADER)
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Dialogs **
'------------------------------------------------------------------------------
FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    LOCAL lRslt AS LONG

#PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
    LOCAL hDlg  AS DWORD

    DIALOG NEW hParent, "Dialog1", 232, 186, 343, 249, TO hDlg
    CONTROL ADD "SysListView32", hDlg, %IDC_SYSLISTVIEW32_1, _
        "SysListView32_1", 40, 25, 210, 135, %WS_CHILD OR %WS_VISIBLE OR _
        %WS_TABSTOP OR %LVS_REPORT OR %LVS_SHOWSELALWAYS, %WS_EX_LEFT OR _
        %WS_EX_CLIENTEDGE OR %WS_EX_RIGHTSCROLLBAR
    CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Button1", 130, 175, 90, 25
#PBFORMS END DIALOG

    SampleListView hDlg, %IDC_SYSLISTVIEW32_1, 3, 30

    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt

#PBFORMS BEGIN CLEANUP %IDD_DIALOG1
#PBFORMS END CLEANUP

    FUNCTION = lRslt
END FUNCTION
'------------------------------------------------------------------------------
Now, obviously there are work-arounds. Since this is the first column, it would be pretty accurate to get the column width and use that for the r.right size. However, I would really like to know what I am doing wrong. Any thoughts or words of wisdom are appreciated.

Thanks/Danke/Gracias/Merci/Spasiba etc
__________________
Bill Scharf
Reply With Quote
  #2  
Old Aug 26th, 2011, 09:35 AM
Michael Mattias Michael Mattias is offline
Member
 
Join Date: Aug 1998
Location: Racine WI USA
Posts: 36,598
That rect is returned in PIXELS, which may make it "seem" larger than the whole control if you are currently working in dialog units.

MCM
Reply With Quote
  #3  
Old Aug 26th, 2011, 09:49 AM
Bill Scharf Bill Scharf is offline
Member
 
Join Date: Aug 2003
Posts: 123
good point, but...

MM,

Thank you for such a quick response. This is a great point, but it does not explain the odd results. For example, the results for the first column are huge compared to the second column:
first column
r.right = 294
r.left = 0
therefore width= about 294
second column
r.right = 188
r.left = 92
therefore width = about 96
third column
r.right = 294 (yes, the same as the first column?)
r.left=188
therefore width = about 106

I know we cannot always make sense of everything, but I am trying to understand what is going on here and why this result is 294 instead of around 92 (the left coordinate of the the second column). Again, any thoughts are appreciated.
__________________
Bill Scharf
Reply With Quote
  #4  
Old Aug 26th, 2011, 10:07 AM
Michael Mattias Michael Mattias is offline
Member
 
Join Date: Aug 1998
Location: Racine WI USA
Posts: 36,598
Run it again, but take out the autosize stuff. When you get all columns the size at which they were created, you'll know the problem is in your use of that stuff and you can go forward from there. At least that's where I think any problems are.
Reply With Quote
  #5  
Old Aug 26th, 2011, 10:20 AM
Gary Beene Gary Beene is offline
Administrator
 
Join Date: May 2008
Location: Dallas, Tx
Posts: 12,619
Hi Bill,
In this example, the values seems to be correct ... something to compare your own code against.
Code:
'Compilable Example:
 #Compile Exe
 #Dim All
 #Include "win32api.inc"
 #Include "commctrl.inc"
 Global hDlg,hListView As Dword    'main dialog handle
 Function PBMain() As Long
    Dialog New Pixels, 0, "ListView Test",300,300,245,95,%WS_SysMenu, 0 To hDlg
    Control Add Button, hDlg, 200, "Push", 170,10,50,25
    Control Add ListView, hDlg, 100, "", 0,0,150,75   '225
    Control Handle hDlg, 100 To hListView

    'columns               hdlg, id&, col, "test", width, format
    ListView Insert Column hDlg, 100, 1, "test1", 75, 0
    ListView Insert Column hDlg, 100, 2, "test2", 75, 0
    'rows               hdlg, id&, row, image, "text"
    ListView Insert Item hDlg, 100, 1, 1, "one"  'row 1, col1
    ListView Insert Item hDlg, 100, 2, 2, "two"  'row 2, col1
    'items           hdlg, id&, row, col, "text"
    ListView Set Text hDlg, 100, 1,2, "12"    'row1 col2
    ListView Set Text hDlg, 100, 2,2, "22"    'row2 col2
    ListView Set Mode hDlg, 100, 1  '0-icon 1-report 2-small 3-list

    Dialog Show Modal hDlg Call DlgProc
 End Function

 CallBack Function DlgProc() As Long
    Local R As Rect
    If Cb.Msg = %WM_Command And Cb.Ctl = 200 Then
        ListView_GetSubItemRect hListview, 0,0,%LVIR_Bounds, VarPtr(R)
        ? Str$(R.nLeft) + Str$(R.nTop) + Str$(R.nRight) + Str$(R.nBottom)
    End If
 End Function
__________________

Last edited by Gary Beene; Aug 26th, 2011 at 10:24 AM.
Reply With Quote
  #6  
Old Aug 26th, 2011, 10:37 AM
Dave Biggs Dave Biggs is offline
Member
 
Join Date: Feb 2001
Location: Australia
Posts: 2,247
Bill,
This seems to work in your original code..
Code:
                            ListView_getsubItemRect hCtl, 0, 0, %LVIR_LABEL, BYVAL VARPTR(R)
__________________
Rgds, Dave
Reply With Quote
  #7  
Old Aug 26th, 2011, 10:40 AM
Dave Biggs Dave Biggs is offline
Member
 
Join Date: Feb 2001
Location: Australia
Posts: 2,247
Gary,

Did you put your ruler against your results?
__________________
Rgds, Dave
Reply With Quote
  #8  
Old Aug 26th, 2011, 10:48 AM
Bill Scharf Bill Scharf is offline
Member
 
Join Date: Aug 2003
Posts: 123
hmmm

Thank you for your responses. This is VERY interesting. When I use Gary's example, I get a messagebox with "0 17 150 31" in it. That "150" should be "75" I believe. Gary's example (imo) shows the issue more concisely.

Dave's response works (I think)--Using %LVIR_LABEL instead of %LVIR_BOUNDS seems to work.

MS's reference at http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx seems to have thrown me off. Not only does it state that the subitem is 1-based, but it says, "LVIR_LABEL...This is identical to LVIR_BOUNDS." I thought about trying LVIR_LABEL, but I did not because it is supposed to be identical....hmmm.

Many thanks to all of you for your help.
__________________
Bill Scharf
Reply With Quote
  #9  
Old Aug 26th, 2011, 10:49 AM
Michael Mattias Michael Mattias is offline
Member
 
Join Date: Aug 1998
Location: Racine WI USA
Posts: 36,598
>Did you put your ruler against your results

What, you called Gary for a quote instead of calling me?

I'm hurt.
Reply With Quote
  #10  
Old Aug 26th, 2011, 11:33 AM
Dave Biggs Dave Biggs is offline
Member
 
Join Date: Feb 2001
Location: Australia
Posts: 2,247
The results show that LVIR_LABEL is not identical to LVIR_BOUNDS - at least not for SubItem 0 !
Code:
LVIR_BOUNDS                    LVIR_LABEL                    
---------------------------    ---------------------------   
iSubItem    2                  iSubItem    2                 
---------------------------    ---------------------------   
r.right=  294                  r.right=  294                 
r.top=     19                  r.top=     19                 
r.bottom=  33                  r.bottom=  33                 
r.left=   188                  r.Left =  188                 
---------------------------    ---------------------------   
iSubItem    1                  iSubItem    1                 
---------------------------    ---------------------------   
r.right=  188                  r.right=  188                 
r.top=     19                  r.top=     19                 
r.bottom=  33                  r.bottom=  33                 
r.left=    92                  r.left=    92                 
---------------------------    ---------------------------   
iSubItem    0                  iSubItem    0                 
---------------------------    ---------------------------   
r.right=  294                  r.right=   92                 
r.top=     19                  r.top=     19                 
r.bottom=  33                  r.bottom=  33                 
r.left=     0                  r.left=     2                 
---------------------------    ---------------------------
__________________
Rgds, Dave
Reply With Quote
  #11  
Old Aug 26th, 2011, 11:56 AM
Stanley Durham Stanley Durham is offline
Member
 
Join Date: May 2009
Posts: 702
Code:
 
    Listview_GetSubItemRect LVRcdZ_aLvHWin(LvIndex), LvRowNo, LvColNo, %LVIR_BOUNDS, ByVal VarPtr(tRect)
    If LvColNo=0 And LvColCount>1 Then
        Listview_GetSubItemRect LVRcdZ_aLvHWin(LvIndex), LvRowNo, 1, %LVIR_BOUNDS, ByVal VarPtr(tRect2)
        tRect.nRight = tRect2.nLeft-1
    End If
this is old code, so ignore the code
but, the concept is;
getting the rect of the first col returns the whole item (all columns)
so, if the row has more than one column;
1. get the first column (return all columns)
2. get second column
3. subtract second column's left from the first column's right
I don't remember why, but I had a "-1" there - probably for the grid line
__________________
stanthemanstan~gmail
Dead Theory Walking
Range Trie Tree
HLib ~ Free Data Container Lib ~ Arrays, Lists, Stacks, Queues, Deques, Trees, Hashes

Last edited by Stanley Durham; Aug 26th, 2011 at 12:01 PM.
Reply With Quote
  #12  
Old Aug 26th, 2011, 12:09 PM
Stanley Durham Stanley Durham is offline
Member
 
Join Date: May 2009
Posts: 702
I found this code - old code - use with caution
Code:
Function LvColCount( ByVal hDlg As Long, ByVal Id As Long )  As Long
    ' get col count
    Local hHead&
    hHead& = SendMessage(GetDlgItem(hDlg,Id),%LVM_GetHeader,0,0)
    Function = SendMessage( hHead&, %hdm_GetItemCount, 0, 0 )
End Function
Sub LvCellRect( ByVal hDlg As Long, ByVal Id As Long, ByVal LvRowNo As Long, ByVal LvColNo As Long, tRect As RECT )
    Local tRect2 As RECT
    Local hWin, colCount As Long
    'if column=0 and more than one column; then
    '   need to get column 1 rect
    '   column zero tRect.nRight = tRect2.nLeft-1
    '   (column zero rect = whole item (whole row)
    Control Handle hDlg, Id To hWin
    colCount = LvColCount(hDlg, Id)
    Listview_GetSubItemRect hWin, LvRowNo, LvColNo, %LVIR_BOUNDS, ByVal VarPtr(tRect)
    If LvColNo=0 And colCount>1 Then
        Listview_GetSubItemRect hWin, LvRowNo, 1, %LVIR_BOUNDS, ByVal VarPtr(tRect2)
        tRect.nRight = tRect2.nLeft-1
    End If
End Sub
__________________
stanthemanstan~gmail
Dead Theory Walking
Range Trie Tree
HLib ~ Free Data Container Lib ~ Arrays, Lists, Stacks, Queues, Deques, Trees, Hashes
Reply With Quote
  #13  
Old Aug 26th, 2011, 12:52 PM
Michael Mattias Michael Mattias is offline
Member
 
Join Date: Aug 1998
Location: Racine WI USA
Posts: 36,598
Quote:
Listview_GetSubItemRect
...

iItem
Index of the subitem's parent item.
iSubItem
The one-based index of the subitem.
Source: SDK on disk ca. 2003

One based? Hmm, fooled me, too, until I RTFM.
Reply With Quote
  #14  
Old Aug 26th, 2011, 02:25 PM
Gary Beene Gary Beene is offline
Administrator
 
Join Date: May 2008
Location: Dallas, Tx
Posts: 12,619
Gosh, a guy takes a short nap and the world keeps on moving without him!

Dave,

No, just eyeballed it - apparently from too far away!

MCM,
Quote:
What, you called Gary for a quote instead of calling me?
For more money, I'd have worn my eyeglasses!
__________________
Reply With Quote
  #15  
Old Aug 29th, 2011, 03:47 PM
Bill Scharf Bill Scharf is offline
Member
 
Join Date: Aug 2003
Posts: 123
Smile Thanks to all

Thanks to all for your help on this issue. Stanley's solution is what I was using as a work-around. Dave's solution seems to give me the best results, so I am going with that for now. I appreciate both the knowledge and expertise of all of you guys.

I am sure we have all had days when a work-around temporarily covered up a larger problem. I wanted to make sure I did not have that larger problem. I can now rest better at night
__________________
Bill Scharf
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 05:46 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyright 1999-2011 PowerBASIC, Inc. All Rights Reserved.
Error in my_thread_global_end(): 1 threads didn't exit