//判断进入哪个游戏房间
function TForm1.GetCanJoinRoom(RoomName: string): boolean;
var
  nIndex,i : Integer;
  sCount : string;
  nCount : integer;
begin
  try
    nIndex := Pos('普通场',RoomName);
    if nIndex > 0 then
    begin
      nIndex := Pos('(',RoomName);
      i := Pos('人',RoomName);
      sCount := Trim(Copy(RoomName,nIndex+1,i-nIndex-1));
      nCount := StrToInt(sCount);
      if nCount < 100 then
        Result := true
      else
        Result := false;
    end
    else
      Result := false;
  except
    Result := false;  
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  vHandle,MainWin,m_hEdit,m_hUserName,m_hBtn:HWND;
  vItemCount: Integer;
  vBuffer: array[0..255] of Char;
  vProcessId: DWORD;
  vProcess: THandle;
  vPointer: Pointer;
  vNumberOfBytesRead: Cardinal;
  I: Integer;
  vItem: TTVItem;
  vTreeItem: HTreeItem;
  bCanJoin : boolean;
  aRect: TRect;
  oldPoint,newPoint:TPOINT;
begin
  MainWin := FindWindow(nil,'面对面视频游戏世界');
  //取得treeviewfun句柄
  treeviewhand := 0;
  EnumChildWindows(MainWin,@EnumTreeViewFunc,0);
  vHandle := treeviewhand;
  GetWindowThreadProcessId(vHandle, @vProcessId); // 获得窗体进程ID
  vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
    PROCESS_VM_WRITE, False, vProcessId);
  vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,
    PAGE_READWRITE);
  try
    vItemCount := TreeView_GetCount(vHandle);
    vTreeItem := TreeView_GetRoot(vHandle);
    for I := 0 to vItemCount - 1 do
    begin
      with vItem do
      begin
        mask := TVIF_TEXT;
        cchTextMax := SizeOf(vBuffer);
        pszText := Pointer(Cardinal(vPointer) + SizeOf(vItem));
        hItem := vTreeItem;
      end;
      WriteProcessMemory(vProcess, vPointer, @vItem,
        SizeOf(vItem), vNumberOfBytesRead);
      SendMessage(vHandle, TVM_GETITEM, 0, lparam(vPointer));
      ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),      
        @vBuffer[0], SizeOf(vBuffer), vNumberOfBytesRead);
      {
      VirtualAllocEx(vProcess,  nil,  sizeof(NewRect),  MEM_COMMIT, PAGE_READWRITE);
      WriteProcessMemory(vProcess, vPointer, @NewRect,SizeOf(NewRect), vNumberOfBytesRead);
      SendMessage(vHandle,LVM_GETITEMRECT,(WPARAM)i,(LPARAM)vPointer);
      }
      bCanJoin := GetCanJoinRoom(vBuffer);//判断是否是可以进入的节点.相应的原则
      if bCanJoin = true then
      begin
        SendMessage(vHandle,TVM_SELECTITEM, TVGN_CARET, Integer(vTreeItem));//选中相应的节点.但是怎么向这个节点发送双击呢?
        //相应的systreeview32在一个非常复杂的动态变化的一个页面里面.
        //DClickItem(vHandle,TreeView_GetSelection(vHandle));
         {
        sleep(100);
        GetCursorPos(oldPoint);   //保存当前鼠标位置。
        TabCtrl_GetItemRect(vHandle,I,aRect);//取坐标,但是这个坐标点拿出来的有问题.
        newPoint.x   :=   aRect.left+(aRect.Right - aRect.Left) div 2;
        newPoint.y   :=   aRect.top + (aRect.Bottom - aRect.Top) div 2;
        Windows.ClientToScreen(vHandle,newPoint);//这一步算出来的也有问题.我想知道到底怎么判断?
        SetCursorPos(newPoint.x,   newPoint.y);
        }
        {
        SendMessage(vHandle,TVM_SELECTITEM, TVGN_CARET, Integer(vTreeItem));
        sleep(300);
        TreeView_GetItemRect(vHandle, vTreeItem, aRect, True);
        }
        {
        SendMessage(vHandle, WM_LBUTTONDOWN, 0,
         (aRect.Left+aRect.Right) div 2 + (aRect.Top+ aRect.Bottom)*$10000 div 2);
        SendMessage(vHandle, WM_LBUTTONUP, 0,
         (aRect.Left+aRect.Right) div 2 + (aRect.Top+ aRect.Bottom)*$10000 div 2);
        }
        break;
      end;
      vTreeItem := TreeNodeGetNext(vHandle, vTreeItem);
    end;
  finally
    VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
    CloseHandle(vProcess);
  end;
end;

解决方案 »

  1.   

    现在的问题是不能双击啊..我现在是根据我的机器硬算的位置.
    procedure TForm1.Button1Click(Sender: TObject);
    var
      vHandle,MainWin,m_hEdit,m_hUserName,m_hBtn:HWND;
      vItemCount: Integer;
      vBuffer: array[0..255] of Char;
      vProcessId: DWORD;
      vProcess: THandle;
      vPointer: Pointer;
      vNumberOfBytesRead: Cardinal;
      I: Integer;
      vItem: TTVItem;
      vTreeItem: HTreeItem;
      bCanJoin : boolean;
      aRect: TRect;
      oldPoint,newPoint:TPOINT;
    begin
      MainWin := FindWindow(nil,'面对面视频游戏世界');
      //取得treeviewfun句柄
      treeviewhand := 0;
      EnumChildWindows(MainWin,@EnumTreeViewFunc,0);
      vHandle := treeviewhand;
      GetWindowThreadProcessId(vHandle, @vProcessId); // 获得窗体进程ID
      vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
        PROCESS_VM_WRITE, False, vProcessId);
      vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,
        PAGE_READWRITE);
      try
        vItemCount := TreeView_GetCount(vHandle);
        vTreeItem := TreeView_GetRoot(vHandle);
        for I := 0 to vItemCount - 1 do
        begin
          with vItem do
          begin
            mask := TVIF_TEXT;
            cchTextMax := SizeOf(vBuffer);
            pszText := Pointer(Cardinal(vPointer) + SizeOf(vItem));
            hItem := vTreeItem;
          end;
          WriteProcessMemory(vProcess, vPointer, @vItem,
            SizeOf(vItem), vNumberOfBytesRead);
          SendMessage(vHandle, TVM_GETITEM, 0, lparam(vPointer));
          ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),      
            @vBuffer[0], SizeOf(vBuffer), vNumberOfBytesRead);
          //计算是否是可以加入该游戏房间即该房间是否是有空位
          bCanJoin := GetCanJoinRoom(vBuffer);
          if bCanJoin = true then
          begin
            SendMessage(vHandle,TVM_SELECTITEM, TVGN_CARET, Integer(vTreeItem));
            sleep(100);
            //鼠标移过去进行双击,虽然也可以实现业务但是这个点是在我机器上的点.而且我要控制的程序一定要在前台.这个实在是有背于我的要求
            SetCursorPos(124,689);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0,0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0,0);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0,0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0,0);        
        
            break;
          end;
          vTreeItem := TreeNodeGetNext(vHandle, vTreeItem);
        end;
      finally
        VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
        CloseHandle(vProcess);
      end;
    end;
      

  2.   

    你可以试试回车键是否能进入游戏尝试一下:发送WM_LBUTTONDBLCLK或者发送回车PostMessage(vHandle, WM_KEYDOWN, VK_RETURN, 0);
    PostMessage(vHandle, WM_KEYUP, VK_RETURN, 0);