Link to home
Start Free TrialLog in
Avatar of chaos_59
chaos_59

asked on

columnheader alignment with icon

I am using vb6, listview control in report view. I have several columns left justified and several right justified. Here's the problem. If I add an icon at design time all of the columns align correctly, but if I add or change an icon at run time the affected column becomes left justified regardless of how I set the alignment. I have tried resetting the alignment right after the icon is added but it doesn't work. Is this a bug? or am I doing something wrong?
Avatar of ameba
ameba
Flag of Croatia image

First column can be only left aligned.
>If I add an icon at design time ...
How do you do that? I can only add items at run-time.
Oops, you mean columnheader icon. I thought you were adding listsubitem icons.
It is a bug. Alignment will be reset to left. VB property will still show previous, right aligment, and it will think it doesn't need to change it.
Here is the workaround:

Private Sub Form2_Click()
    Dim savalignment As Integer
    With lvwTest.ColumnHeaders(2)
        savalignment = .Alignment
        .Alignment = lvwColumnLeft
        .Icon = 0
        .Alignment = savalignment ' restore alignment
    End With
End Sub
>Form2_Click
should be Form_Click
Avatar of chaos_59
chaos_59

ASKER

well, this works to reset the alignment, but it also removes the icon. It seems like maybe alignment and icon are mutually exclusive. If you have any other ideas let me know.
           Thanks
By the way, how did you know this was a bug? I assumed it was by how it was behaving, is there some resource where I can look for bugs and stuff?


>but it also removes the icon
Yes in my sample, I also tried
   .Icon = 2
with the same result.

>but if I add or change an icon
I don't see how to test changing columnheader icon, if I don't use that line. Of course, icon will be modified, you wanted this, you said:
>but if I add or change an icon

>how did you know this was a bug?
Bug is if something doesn't work OK. I am not saying this is PUBLISHED BUG.

Bug, how to reproduce:
If second column is right aligned, and column header has an icon, this line
    lvwTest.ColumnHeaders(2).Icon = 0
will also change column alignment to left.

Workaround:
after executing line ".Icon = 0"
we can check column alignment:
  debug.print lvwTest.ColumnHeaders(2).Alignment
the result is 1 (right aligned), but we see it is left aligned.
This means property Alignment, exposed to VB developers, has not been updated, i.e. it shows wrong value. To reset alignment to Right, this single line is not enough:
  lvwTest.ColumnHeaders(2).Alignment = lvwColumnRight
because vb 'thinks' it already is 'right aligned'

So, we have to change alignment twice:
Private Sub Form_Click()
    Dim savalignment As Integer
    With lvwTest.ColumnHeaders(2)
        savalignment = .Alignment
        .Alignment = lvwColumnLeft
        .Icon = 0
        .Alignment = savalignment ' restore alignment
    End With
End Sub

I am 100% sure this is the answer!
I created a test app to try your sample and it doesn't work if you try to set the icon to another icon instead of 0.
here is my code.    
Dim savalignment As Integer
    With lvwtest.ColumnHeaders(2)
        savalignment = .Alignment
        .Alignment = lvwColumnLeft
        .Icon = 2
        .Alignment = savalignment ' restore alignment
    End With

I stepped through the code line by line and when it reaches the ".Alignment = savalignment" statement the icon disappears.
I want my program to be able to toggle the icon between an up arrow and a down arrow depending on if the list is ascending or descending by column.
Sorry, I re-tested what I said and it works only when " .Icon = 0" is used.
It seems I only tested ".Icon = 2" when reproducing the bug.
So, I am withdrawing  my answer.

I'll try to find another workaround (e.g. SendMessage might work).

My examples for changing the columnheader icon when sorting column, all use only left alignment.
I wish I could use left alignment, but when working with numbers it doesn't look right to have them left aligned.
I have something working; this will modify icon in column 2, and make it right aligned

' in form declarations
Private Const LVCF_FMT = &H1
Private Const LVCFMT_LEFT = &H0
Private Const LVCFMT_RIGHT = &H1
Private Const LVCFMT_CENTER = &H2
Private Const LVCFMT_JUSTIFYMASK = &H3
Private Const LVCFMT_IMAGE = &H800
Private Const LVCFMT_BITMAP_ON_RIGHT = &H1000
Private Const LVCFMT_COL_HAS_IMAGES = &H8000&
Private Const LVM_FIRST = &H1000
#If UNICODE Then
Private Const LVM_GETCOLUMN = (LVM_FIRST + 95)
Private Const LVM_SETCOLUMN = (LVM_FIRST + 96)
#Else
Private Const LVM_GETCOLUMN = (LVM_FIRST + 25)
Private Const LVM_SETCOLUMN = (LVM_FIRST + 26)
#End If
Private Type LVCOLUMN
    mask As Long
    fmt As Long
    cx As Long
    pszText As Long
    cchTextMax As Long
    iSubItem As Long
    iImage As Long
    iOrder As Long
End Type
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Function ListViewGetColumn(ahWnd As Long, iCol As Long, pcol As LVCOLUMN) As Boolean
    ListViewGetColumn = SendMessage(ahWnd, LVM_GETCOLUMN, ByVal iCol, pcol)
End Function
Private Function ListViewSetColumn(ahWnd As Long, iCol As Long, pcol As LVCOLUMN) As Boolean
    ListViewSetColumn = SendMessage(ahWnd, LVM_SETCOLUMN, ByVal iCol, pcol)
End Function


' this will modify icon in column colno and make it right-aligned
Private Sub Form_Click()
    Dim newicon As Integer, colno As Long
    newicon = 2
    colno = 2
' ----------------------------------------------------------
    Dim o As ColumnHeader
    Set o = Me.lvVMenn.ColumnHeaders.Item(colno)
    o.Icon = newicon   ' this will also reset column alignment to left
' ----------------------------------------------------------
    Dim lvc As LVCOLUMN, ret As Boolean
    ' read columnformat into lvc.fmt
    lvc.mask = LVCF_FMT
    ret = ListViewGetColumn(Me.lvVMenn.hWnd, colno - 1, lvc)
    Debug.Print "column style: H" & Hex(lvc.fmt)
    ' set columnformat in lvc.fmt
    lvc.fmt = lvc.fmt Or LVCFMT_RIGHT ' make it right aligned
    ret = ListViewSetColumn(Me.lvVMenn.hWnd, colno - 1, lvc)
    Me.lvVMenn.Refresh
' ----------------------------------------------------------
End Sub
'lvVMenn' is listview I used. More to come...
<ping> ;-)
ASKER CERTIFIED SOLUTION
Avatar of ameba
ameba
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks a lot!
Thanks for the points.