本帖最后由 jxqn_liu 于 2012-10-19 16:42:35 编辑

解决方案 »

  1.   

    不同的开发环境会有不同的grid的制作方式和效果,如果想要选中一个项,一般是计算出该项的坐标,再模拟点击事件。毕竟表格非标准win32控件,没有明确的消息处理
      

  2.   

    在网上搜索了API函数,找到一个ChildWindowFromPoint,看这介绍好像是可以获取组合控件上的子控件句柄,但是我怎么也获取不到,是我获取有误还是根本就获取不到?var
      ChildHandle, MainHandle: THandle;
      P: TPoint;
    begin
      P.X := 60;
      P.Y := 30;
      MainHandle := StringGrid1.Handle; //获取StringGrid1的句柄
      //MainHandle := Handle; //获取窗体的句柄  ChildHandle := ChildWindowFromPoint(MainHandle, P);
    end;通过这样的方式获取到的还是StringGrid1的Handle现在这有几个疑问,想请教一下。
      1.MainHandle的值是传主窗体的还是组合控件的句柄。我的理解是:如果想获取StringGrid1的列句柄(假如能获取),那这里传的值应该是StringGrid1的句柄;如果传的是主窗体的句柄的话,我想这获得的句柄是捕捉的应该是主窗体下指定点的第一个子控件,而不是子控件中的其他子控件。  2.P点的位置问题。P点的位置是相对应屏幕的位置或主窗体的下的相对位置或MainHandle对应控件的下的相对位置,获取是其他的位置,这点不明白。来个大神吧
      

  3.   


    问题暂时性的解决了,算是走了一个偏门吧。把方法分享下。
    实现的步骤:
      1、获取表格列的X/Y坐标,X坐标是固定的,Y坐标在起始坐标上加行数*行高
      2、设置控制外部程序前置和表格获取相应的焦点
      3、将鼠标移动到对应的列上
      4、模拟鼠标点击,以表格进入选中状态
      5、将需要设置的值拷贝到剪贴板
      6、根据表格去设置表格列进入输入状态,由于我的当前表格是TStringGrid,需要输入一个字母进入状态,然后删除值
      7、模拟键盘CTRL+V粘帖数据到表格列
      
    以上大概就是我的目前实现步骤,如果各位有啥想法欢迎提供!谢谢
    附上示例源码,提供参考:var
      i, j, iHeight: Integer;
      Str: string; //设置需要输入的表格列值,这里的示例就是一个固定的值
      StrList: TStringList; //这个是存储表格列的所有列的位置
    begin
      iHeight := 0;
      //添加测试表格列的位置
      StrList := TStringList.Create;
      StrList.Add('330');
      StrList.Add('480');
      StrList.Add('550');
      StrList.Add('610');
      StrList.Add('670');
      StrList.Add('730');
      StrList.Add('800');
      StrList.Add('860');
      StrList.Add('920');  //根据句柄设置窗体前置
      SetForegroundWindow(198156);     
      //根据表格句柄设置表格获取焦点
      Windows.SetFocus(67248);  //这里模拟的是3行数据
      for j := 0 to 2 do
      begin
        iHeight := 380 + j * 23; //这里设置的行高是23,每增一行增加相应的高度
        for i := 0 to StrList.Count - 1 do
        begin
          //将鼠标移动到相应的表格列
          SetCursorPos(StrToInt(StrList[i]), iHeight);
          //模拟鼠标左键点击
          mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
          mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);      //设置表格列的数据,这里模拟的是一个固定值
          Str := 'TEST';
          //将值拷贝到剪贴板
          Clipboard.AsText := Str;      //因为我这模拟的是TStringGrid,需要先获取输入状态(试过,模拟鼠标再次点击不能进入输入状态)
          keybd_event(Ord('A')+i, 0, 0, 0);
          keybd_event(Ord('A')+i, 0, KEYEVENTF_KEYUP, 0);
          keybd_event(VK_BACK, 0, 0, 0);
          keybd_event(VK_BACK, 0, KEYEVENTF_KEYUP, 0);      --模拟键盘CTRL+V粘帖数据到表格列
          keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
          keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), 0, 0);
          keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), KEYEVENTF_KEYUP, 0);
          keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);      --等待20毫秒
          Sleep(20);
        end;
      end;
      //清空对象
      FreeAndNil(StrList);  //设置当前自己的程序前置
      SetForegroundWindow(Handle);
    end;
      

  4.   

    stringgrid没有所谓的列句柄,这不是win32标准控件,是DELPHI自己用panel画出来的,整个stringgrid是一个整体,只有一个大句柄
      

  5.   

    这个知道,也不是说STRINGGRID,其他的表格控件也没有。
    后面想了下,表格列不可能有句柄,这样一个表格,多行多列,就算是列有句柄,该列所对应的行也没有,毕竟表格的行列是位置的,所以表格列不允许有句柄。
    后来走了一个偏门,详情在11楼