'UpdatelParam proc uses edi
'   LOCAL lvi:LV_ITEM
'
'   Invoke SendMessage, hList, LVM_GETITEMCOUNT, 0, 0
'   mov edi, eax
'   mov lvi.imask, LVIF_PARAM
'   mov lvi.iSubItem, 0
'   mov lvi.iItem, 0
'   .while edi > 0
'     push lvi.iItem
'     pop lvi.lParam
'     invoke SendMessage,hList, LVM_SETITEM,0,addr lvi
'     inc lvi.iItem
'     dec edi
'   .endw
'   ret
'UpdatelParam endp

解决方案 »

  1.   

    该代码的作用是设置项目的附加数据(LV_ITEM.lParam)为顺序编号
    有助于以后排序时确定顺序
      

  2.   

    可是,我看它每次都是在手动排序后(发送LVM_SORTITEMS),用代码确定两个值的大小的办法,
    等排序完成后才用的呀?苦于580个E文词汇量,没看懂它的介绍,好像它说的是LVM_SORTITEMS后的索引值一定需要刷新什么的。事实上也正是我用了LVM_SORTITEMS后,就无法正确定位ListItems的索引了,
    我才想知道,什么叫刷新索引?
      

  3.   

    哦,有点理解,有一点猜测,只是瞎猜哦push是不是存入,pop是不是赋值?那样的话,代码的意思就是把所有项目的lParam值改为Item的编号?(如1、2、3)这样可以吗?不知道VB里面认不认?
    原来LVM_SORTITEMS时的lParam总是很奇怪的值,偶只用来LVM_FINDITEM的,不知道还能改?呵呵,不错,试试去:)
      

  4.   

    这里看过了吗?
    http://vbnet.mvps.org/index.html?code/callback/lvsortcallback.htm
      

  5.   

    谢谢老大,看过了,我用的就是它的办法,排序是可以,但排完后就不能用ListItems了另外,老大能否看看这段代码,我是根据上面的汇编代码,猜测改的:zyl910老大也说要SetItem消息,但是一运行就被退出VB了,郁闷TT就是ListItems.CountDim uItem As LV_ITEM
    Const LVM_SETITEM = LVM_FIRST + 6
    Const LVM_GETITEM = LVM_FIRST + 5
    Dim I As Long,RtV as Long
      For I = 0 To ListView1.ListItems.Count - 1
        With uItem
          .mask = &H4
          .iSubItem = 0
          .iItem = I
          .lParam = I
        End With
        RtV = SendMessage(ListView1.hwnd, LVM_SETITEM, ByVal 0, uItem)
      Next
      

  6.   

    TO rainstormmaster(暴风雨 v2.0)
    另外,那上面的例子好像有问题,返回值好像应该是-1 0 1 而不是0 1 2 
    但实际也可以运行,晕
      

  7.   

    你的uitem初始化不正确,既然指定了.mask为 LVIF_PARAM,就不能设置.lParam
      

  8.   

    LVIF_PARAM:
    The lParam member is valid or must be filled in.
      

  9.   

    //那段汇编到底怎么改成VB版?把你改的那段代码调试通过即可,不出意外的话,把
     .lParam = I
    这句注释掉即可
      

  10.   

    出意外了,还是被Kill了 ,天理何在,555555
      

  11.   

    push是将数值压入栈,pop是将栈中数值弹出
    在汇编中经常结合push、pop实现内存到内存的赋值
    'UpdatelParam proc uses edi
    sub UpdatelParam()    '   LOCAL lvi:LV_ITEM
        dim lvi as LV_ITEM
        dim nCount as long 'edi    '   Invoke SendMessage, hList, LVM_GETITEMCOUNT, 0, 0
        '   mov edi, eax
        nCount = SendMessage(hList, LVM_GETITEMCOUNT, 0, byval 0&)    '   mov lvi.imask, LVIF_PARAM
        lvi.imask = LVIF_PARAM    '   mov lvi.iSubItem, 0
        lvi.iSubItem = 0    '   mov lvi.iItem, 0
        lvi.iItem = 0    '   .while edi > 0
        do while nCount > 0        '     push lvi.iItem
            '     pop lvi.lParam
            lvi.lParam = lvi.iItem        '     invoke SendMessage,hList, LVM_SETITEM,0,addr lvi
            call SendMessage(hList, LVM_SETITEM, 0, lvi)        '     inc lvi.iItem
            lvi.iItem = lvi.iItem + 1        '     dec edi
            nCount = nCount -1    '   .endw
        loop'   ret
    'UpdatelParam endp
    end sub
      

  12.   

    .mask表示使用那些字段,设了LVIF_PARAM才能使用.lParam
      

  13.   

    //出意外了,还是被Kill了 ,天理何在,555555那个ListView是不是自身进程的?
    若是其他进程的ListView,由于存在进程地址空间保护,所以会被系统Kill掉如果是自身进程的
    那可能是VB的ListView控件利用LV_ITEM.lParam存放特殊数据
    现在你修改了LV_ITEM.lParam,破坏了VB的特殊数据,所以VB罢工了
      

  14.   

    //你的uitem初始化不正确,既然指定了.mask为 LVIF_PARAM,就不能设置.lParam这句话不对,我把 LVM_SETITEM看成 LVM_GETITEM了,不好意思:)
      

  15.   

    To rainstormmaster(暴风雨 v2.0) :
    老大也会看错啊,呵呵:)To zyl910(910:分儿,我又来了!) 
    还是老样子!另外,ListView1.hwnd肯定是自身进程啦难道是定义有错?
    Private Type LV_ITEM
      mask As Long
      iItem As Long
      iSubItem As Long
      state As Long
      stateMask As Long
      pszText As String
      cchTextMax As Long
      iImage As Long
      lParam As Long
      iIndent As Long
    End Type最后,To 各位老大,能不能帮帮忙,
    能否找个让VB的ListItems有效的排序方法?
    (当然是能排数字日期,不用格式化改变原数据的那种啦)谢谢!
      

  16.   

    //能否找个让VB的ListItems有效的排序方法?
    VB摆在LV_ITEM.lParam的特殊数据是保密的
    我们没办法维持VB6已被Microsoft宣布放弃技术支持了(被抛弃了)
    Microsoft正在推广VB.Net 2005
    VB6是绝对不管了我早就没用VB的ListView控件了
    都是自己用CreateWindowEx创建ListView控制项我建议你使用vbAccelerator的ListView控件
    比VB那个强太多了
    http://vbaccelerator.com/home/VB/Code/Controls/ListView/article.asp
      

  17.   

    //难道是定义有错?定义没错//老大也会看错啊,呵呵:)呵呵,这几天一直都没休息好,所以,也经常犯些审题不认真的错误:)
    另外,你的listview的版本是什么?其实,如果可能,还是按zyl910说的做吧
      

  18.   

    说实话,俺不是一定想要强大,俺想要的是最大兼容性!
    所以,我一般不用第三方控件,若一定要用到某些功能,如通用对话框,我会尽量用靠近MS的类代码来实现,这样,以后要是不在我的机子上,无法用类源码的话,只要很简单的加上通用控件,把名字改为类名,不用改源码,几乎马上又能用了,实在方便!
    以前觉得vbaccelerator的东东很强,可后来经过多次实践,有时是在98的机子上,有时又是在没有网络的机子上,那时,特讨厌它的SSubTmr.Dll,每个代码都要用它,几乎每个代码都是单独控件,都要一个个注册,有时还注册失败,经常害得整个代码都不能用了,我们要的是编程的结果,那些辅助的控件只是实现的工具而已,如果这时这个工具不能用,而代码又是完全基于这一个工具的话,那时绝对郁闷死:(所以,要用ListView的话,就要以最接近通用控件的方式来用,这样最灵活
    要么就是以纯代码的方式加在工程内部,(像vbaccelerator那样要用14个类模块、6个共用模块、外加SSubTmr.Dll还有两个不知道什么库的方式,绝对不适合合并源码化)(个人很喜欢把子类做在类模块内部的方式,那样可以更接近控件,能让源码近一步通用,只要封装合理,即使转到Net版也是很容易的,很欣赏那句话——同样功能的代码决不要编写两遍)
      

  19.   

    曾经N久以前,看到过一个ListView的源码,(可惜没保存,郁闷)
    好像仅用了一个源码(控件式),就实现了ListView的几乎大部分功能(至少比VB里的强)
    没有多余的共用模块,没有其它的类模块,只用控件源码本身(不过有点大,大于7000行)
    它就绝对适合放在工程内部。俺现在只是很想用ListView而已,暂时还没有自己完整编写它的打算,所以现在使用的办法是,用一个附加功能类模块(千行不到),已实现了22个属性,10几个方法的增强,既能用在CreateWindowEx建立的控件,也能用在现成通用控件上。若要以后自己编写完整控件的话,就可省很多力气,也可少很多差错(现在的代码就在实践中进行检验),是不是很合算?^-^所以,就这一个索引的问题,俺希望能用单独的方法来解决(就是不用建一个完整控件的办法)(诶,只是希望而已,实在不行的话,为了实用结果,只能放弃现在的自定义排序功能,呜乎哀哉!)
      

  20.   

    //曾经N久以前,看到过一个ListView的源码,(可惜没保存,郁闷)
    //好像仅用了一个源码(控件式),就实现了ListView的几乎大部分功能(至少比VB里的强)VB的Microsoft Common Controls 6.0只是对comctl32.dll最基础功能的封装
    随便发几条ListView消息,就可实现用VB的ListView控件接口本身打死也做不到的功能也就说
    那个程序实际上是ListView消息的功能演示而vbAccelerator的ListView控件
    不仅封装了ListView消息
    而且挂上了子类,处理了通知消息
    将ListView本有的许多功能展示了出来至于SSubTmr.Dll
    是专门用来挂接子类的
    这样可以直接在类模块中接受窗口消息
    至于转.Net,只需修改SSubTmr.Dll,不需要修改其他模块(甚至控件都不需要重新编译)
    这体现出作者的软件工程修养vbAccelerator.com唯一的问题是控件很分散,一个控件一个ocx,引用关系很复杂
    其实作者完全可以将它们合并到一个ocx中的,但为什么作者不这样做呢?
    道理其实很容易想通的,作者希望他人是认真学习编程,而不是Copy代码
    既授之于渔,而非授之于鱼
    这体现作者对编程新手的关怀其实任何控件都是对Windows控制项的封装
    vbAccelerator的ListView是告诉我们如何直接使用comctl32.dll提供的ListView控制项以前都是用CreateWindowEx创建控制项子窗口,再发消息控制的(被称为SDK编程)
    而现在为什么流行RAD编程工具呢?
    这是因为:
    1.适应Windows编程环境是需要一定时间的,而RAD窗体设计器可以让你快速入门
    2.编程新手一般很难看出代码的效果,而RAD窗体设计器的图形界面容易理解
    3.Win32 API字符串处理比较麻烦
    4.控件类可以封装控制项的功能,可以减少代码量。但是你也可自己封装控件类,所以这点不算理由其实只要认真地的写三个月SDK程序
    你就会基本适应SDK编程
    这绝对比你使用某种编程工具的时间短(你VB学了几年了?)我记得我在最初学VB时就看SDK编程资料了(我记得我的第一个VB程序就是注册表优化工具,调用注册表API实现的)
    那时VB控件倒是只会最基础的ListBox等
    后来在逛CSDN论坛时才学会常用控件的使用(如VB的ListView控件)
    由于那时Windows编程已有小成
    理解这些控件感觉一点都不难
    而且感觉那些控件封装的太差
    所以那时开始学习界面编程(好象当初就是我推荐dapha.net、vbaccelerator.com这些优秀源码网站的)
      

  21.   

    看了一下你以前的帖子发现你好像是想能显示项目的顺序编号你其实没必要提出那么复杂的界面要求(什么增加一列啊)
    可以放一个标签控件,然后在Click事件中将当前选择的项目的Index值赋给该标签控件
    这样虽然不直观,但是编码简单,可在一定程度上解决问题如果硬要显示顺序编号的话
    可以利用Custom Draw,自己绘制每个项目的顺序编号,而不需要实际上增加一列
    可以使用VB的ListView控件,只需自己处理NM_CUSTOMDRAW消息就行(ListView本身支持Custom Draw,不需要修改窗口风格)
      

  22.   

    谢谢老大指点!:)不过老大误会了,这个帖子不是为了显示编号的,
    这个帖子是为了,自定义数字排序后,能继续使用VB的ListItems集合的。因为要排数字和日期,而又不想用Format修改源数据的办法——实在是太慢了,所以只能使用发送LVM_SORTITEMS消息的办法。直接导致结果——无法再正确使用ListItems了,要想恢复ListItems的使用只能再恢复其Sorted=True,呜呼,白干了。说到底,只是一个快速排序啊,诶,VB真的没办法了吗?如果真的只能用自写完整的ListView控件那7000多行代码才能实现快速排序的话,
    那那今天偶就不排序了,呵呵:)
      

  23.   

    //说到底,只是一个快速排序啊,诶,VB真的没办法了吗?并不是VB这个编程工具办不到
    而是Microsoft Common Control 6.0封装的太差我现在觉得VB的ListView控件的设计思维有问题
    居然是控件自身拥有数据,然后用户在添加项目
    这样的控件虽然使用方便,但是只适合小型数据的显示
    特别是ListView控件的排序功能设计得更差
    使该控件的实用价值很低现在的开发工具
    比如Java
    它们的表格控件
    都是只提供界面交互
    数据源是用户写的类
    虽然用起来有点不习惯
    但是灵活性高、效率高
    归根结底是由于VB6出的太早了
    1998年离现在已经快8年了
    那时的控件、类库设计思维还不够成熟
    这也是Microsoft为什么放弃VB6、MFC而开发.Net框架类的原因(MFC是更古老的东西,90年代早期的作品,该寿终正寝了)对于代码量,我只想说:
    若想实现完美效果,那不要在乎代码量
    若受现实局限,那马马虎虎实现功能就行了
    鱼与熊掌本来就是不可兼得的Microsoft的DOS、Windows的早期版本有很多人说写得差
    但Microsoft坚持了下来,一直在努力
    到了现在的Windows 2000+,已经积累了极其庞大的代码量,拥有了大量的功能,以至于垄断了操作系统行业
    虽然Microsoft的早期作品受现实局限功能薄弱,但毕竟带来了资金收入
    而且Microsoft一直在追求完美,不断的更新,最终呈现今日的辉煌
    (而国内呢,口口声声说现在处于原始积累阶段,出了一个Bug满天飞的版本后就等着收钱,根本没有技术积累的过程,更别提追完美了)
      

  24.   

    看了众多的评语,对本主题来说只得出一个结论:
    想用VB的ListView控件版(还是5。0的呢)要做到快速排序,只有一条路——死路!!!
    算了,不排就不排呗,还有N多事情等着做呢,至少现在正处在饿死的边缘,
    暂时没空去理该死的VB了,吃饭去咯:)