有一个第三方程序(不一定是什么语言开发)的录入界面,上面有一个只读下拉框(就是不能往里面写东西的那种),
里面的数据项是:
品种1
品种2
品种3
品种4
...
...
数据的顺序不定,数据的数量也不定。比如说品种3,它不一定在下拉框的第几项。我现在想通过sendmessage或者postmessage发送一个消息给这个下拉框,让它选中“品种3”
SendMessage(combo1.Hwnd, WM_SETTEXT, 0, '品种3');
但这样不好使,PostMessage也试过,也不行。请教,应该怎样实现我要的效果?

解决方案 »

  1.   

      SendMessage(ComboBox1.Handle, WM_SETTEXT, 0, Integer(PChar('品种3')));
      

  2.   


      SendMessage(ComboBox1.Handle, CB_SETCURSEL, ComboBox1.Items.IndexOf('品种2'), 0);
      

  3.   

    SendMessage(yourHandle,CB_SETCURSEL,0,Integer(PChar('123')));
      

  4.   

    TO:4楼的
    我只是说一下
    blazingfire的第2个方法不成功吧
    从blazingfire回答也学了不少东西我也再学习,呵呵
    仁者见仁,智者见智吧
      

  5.   

    这个肯定是不行的了,因为目标程序是第三方的,我不能获取到ComboBox1控件。
    我能知道的只是它的句柄,和列表中能看到的汉字。
      

  6.   

    var
      Ret: LongInt;
    begin
      Ret := SendMessage(combo1.Hwnd, CB_FINDSTRINGEXACT, -1, LongInt(PChar('品种2')));
      if Ret = -1 then begin
        ShowMessage('没有找到品种2!');
        Exit;
      end;
      SendMessage(combo1.Hwnd,CB_SETCURSEL,Ret,0);
    end;
      

  7.   

    发现僵哥就是高手,一出手就解决问题。
    另外我找到这样也可以:
    SendMessage(combo.Hwnd, CB_SELECTSTRING, 0, Integer(PChar('品种3')));
    -------------------------
    但发现这两个方法,虽然内容都选中了,但却没有激活下拉框的点击事件或者change事件,
    应该如何继续处理呢?
      

  8.   

    一笑而过!
    对于SendMessage(ComboBox1.Handle, WM_SETTEXT, 0, Integer(PChar('品种3'))) 不成功的,不是因为这个方法本身有问题,而是
    因为目标ComboBox的风格的问题
      

  9.   

    这是一个很严重的问题,特别是对于Delphi来说,这应该算是一个BUG。如果该程序是使用VC写的,就不会存在这个问题,因为VC都是基于消息的。但是Delphi就不一样了。
      

  10.   

    应该可以继续编程,去触发下拉框的点击事件以及onchange事件啊
      

  11.   

    那确实不能!鉴于楼主楼主不喜欢别人发同样回复,作一个和他们都不一样的回复吧:procedure ChangeComboBoxTo(hCmbBox: THandle; Searched: string);
    var
      i, Count, Len: integer;
      S: string;
    begin
      Searched := Trim(Searched);
      //取得ComboBox里的项总数
      Count := SendMessage(hCmbBox, CB_GETCOUNT, 0, 0);
      //循环比较每一项,找到与Searched相等的项
      for i := 0 to Count - 1 do
      begin
        Len := SendMessage(hCmbBox, CB_GETLBTEXTLEN, i, 0);
        if Len > 0 then
        begin
          SetLength(S, Len);
          SendMessage(hCmbBox, CB_GETLBTEXT, i, Integer(PChar(S)));
          //取得每一项的内容放入S
          S := Trim(S);
          if SameText(S, Searched) then
          begin
            //设定当前项
            SendMessage(hCmbBox, CB_SETCURSEL, i, 0);
            //如果目标是Delphi程序,让ComoBox触发其OnChange事件
            SendMessage(hCmbBox, CN_COMMAND, MakeLong(0, CBN_SELCHANGE), 0);
            Break;
          end;
        end;
      end;
    end;调用例子:procedure TForm1.Button1Click(Sender: TObject);
    begin
      ChangeComboBoxTo(ComboBox1.Handle, '品种2');
    end;
      

  12.   

    //如果目标是Delphi程序,让ComoBox触发其OnChange事件
            SendMessage(hCmbBox, CN_COMMAND, MakeLong(0, CBN_SELCHANGE), 0);
    为什么必须是Delphi程序呢?如果不是Delphi程序应该怎么办呢?我试了一下,VB的不能触发onclick事件现在最关键的是触发onclick事件另外不是我说的不让发重复的,呵呵,楼上看错了。
    但同样非常感谢。另外没理解,你在循环里判断和unsigned的
    var 
      Ret: LongInt; 
    begin 
      Ret := SendMessage(combo1.Hwnd, CB_FINDSTRINGEXACT, -1, LongInt(PChar('品种2'))); 
      if Ret = -1 then begin 
        ShowMessage('没有找到品种2!'); 
        Exit; 
      end; 
      SendMessage(combo1.Hwnd,CB_SETCURSEL,Ret,0); 
    end;
    这个方法的区别是什么呢?
    是不是用哪个都行呢?
    还有跟
    SendMessage(combo.Hwnd, CB_SELECTSTRING, 0, Integer(PChar('品种3'))); 
    的区别又是什么呢?
    现在有三个方法了,我就不知道用哪个了。
      

  13.   

    呵呵,如果三个方法都行,你就选一个代码最少的一个!至于区别,我看都不大,只是一个是你自己写,一个是调用已经写的API;
    不过自己写要灵活些,能作更多的事情。这个和Delphi响应消息的具体实现有关你到底是要OnClick还是OnChange呢?
      

  14.   

    如果你要的OnChange的话,象这样改造一下可能VB的OnChange事件也能触发。我这里没有VB试,
    我这里用C#写了一个小程序是可以触发OnChange事件了procedure ChangeComboBoxTo(hCmbBox: THandle; Searched: string);
    var
      i, Count, Len: integer;
      S: string;
    begin
      Searched := Trim(Searched);
      //取得ComboBox里的项总数
      Count := SendMessage(hCmbBox, CB_GETCOUNT, 0, 0);
      //循环比较每一项,找到与Searched相等的项
      for i := 0 to Count - 1 do
      begin
        Len := SendMessage(hCmbBox, CB_GETLBTEXTLEN, i, 0);
        if Len > 0 then
        begin
          SetLength(S, Len);
          SendMessage(hCmbBox, CB_GETLBTEXT, i, Integer(PChar(S)));
          //取得每一项的内容放入S
          S := Trim(S);
          if SameText(S, Searched) then
          begin
            //设定当前项
            SendMessage(hCmbBox, CB_SETCURSEL, i, 0);
            //触发OnChange事件,不用CN_COMMAND
            SendMessage(hCmbBox, WM_COMMAND, MakeLong(0, CBN_SELCHANGE), hCmbBox);
            Break;
          end;
        end;
      end;
    end;
      

  15.   

    VB的程序我试了
    用CN_COMMAND的话onclick和onchange都不能触发,
    用WM_COMMAND倒是触发了onclick事件。但看你代码的意思应该是要触发onchange事件。
    怪了。
      

  16.   

    那又该怎么样触发onchange事件呢?
    有的程序的下拉框中,既有onclick事件又有onchange事件。另外我继续追加100分。
      

  17.   

    对呀,我也觉得怪,不知道那个VB是怎么回事。鬼知道VB里面如何处理这个WM_COMMAND消息的!!
    我这里试了C#是不会触发Click事件的,好象只触发了SelectedIndexChanged和
    SelectedValueChanged两个事件