const POINT RandomizeClickLocation(const RECT rect) { POINT p = {0}; // uniform random distribution, yuck! //p.x = ((double) rand() / (double) RAND_MAX) * (rect.right-rect.left) + rect.left; //p.y = ((double) rand() / (double) RAND_MAX) * (rect.bottom-rect.top) + rect.top; // normal random distribution - much better! GetClickPoint(rect.left + (rect.right-rect.left)/2, rect.top + (rect.bottom-rect.top)/2, (rect.right-rect.left)/2, (rect.bottom-rect.top)/2, &p); return p; }
bool Element::IsClickPointInViewPort(const long x, const long y, const long width, const long height) { LOG(TRACE) << "Entering Element::IsClickPointInViewPort"; long click_x, click_y; GetClickPoint(x, y, width, height, &click_x, &click_y); WINDOWINFO window_info; if (!::GetWindowInfo(this->containing_window_handle_, &window_info)) { LOG(WARN) << "Cannot determine size of window, call to GetWindowInfo API failed"; return false; } long window_width = window_info.rcClient.right - window_info.rcClient.left; long window_height = window_info.rcClient.bottom - window_info.rcClient.top; long window_x_border = window_info.cxWindowBorders; long window_y_border = window_info.cyWindowBorders; LOG(DEBUG) << "x border: " << window_x_border << ", y border: " << window_y_border; // Hurrah! Now we know what the visible area of the viewport is // Is the element visible in the X axis? // N.B. There is an n-pixel sized area next to the client area border // where clicks are interpreted as a click on the window border, not // within the client area. We are assuming n == 2, but that's strictly // a wild guess, not based on any research. if (click_x < 0 || click_x >= window_width - 2) { LOG(WARN) << "Click X coordinate is out of element area"; return false; } // And in the Y? if (click_y < 0 || click_y >= window_height - 2) { LOG(WARN) << "Click Y coordinate is out of element area"; return false; } return true; }
int Element::Click(const ELEMENT_SCROLL_BEHAVIOR scroll_behavior) { LOG(TRACE) << "Entering Element::Click"; long x = 0, y = 0, w = 0, h = 0; int status_code = this->GetLocationOnceScrolledIntoView(scroll_behavior, &x, &y, &w, &h); if (status_code == SUCCESS) { long click_x; long click_y; GetClickPoint(x, y, w, h, &click_x, &click_y); // Create a mouse move, mouse down, mouse up OS event LRESULT result = mouseMoveTo(this->containing_window_handle_, /* duration of move in ms = */ 10, x, y, click_x, click_y); if (result != SUCCESS) { LOG(WARN) << "Unable to move mouse, mouseMoveTo returned non-zero value"; return static_cast<int>(result); } result = clickAt(this->containing_window_handle_, click_x, click_y, MOUSEBUTTON_LEFT); if (result != SUCCESS) { LOG(WARN) << "Unable to click at by mouse, clickAt returned non-zero value"; return static_cast<int>(result); } //wait(50); } else { LOG(WARN) << "Unable to get location of clicked element"; } return status_code; }