Utilities::Point GetCursorPos() { Utilities::Point pos; CURSORINFO cursorInfo; cursorInfo.cbSize = sizeof(cursorInfo); if(GetCursorInfo(&cursorInfo) == FALSE) { SL_RAT_LOG(Utilities::Logging_Levels::ERROR_log_level, "GetCursorInfo == FALSE"); return pos; } ICONINFOEXA ii = { 0 }; ii.cbSize = sizeof(ii); if(GetIconInfoExA(cursorInfo.hCursor, &ii) == FALSE) { //this tends to fail on hyper-v enviornments generating alot of noise. so lower its level to Info.. SL_RAT_LOG(Utilities::Logging_Levels::INFO_log_level, "GetIconInfoEx == FALSE"); return pos; } auto colorbmp = RAIIHBITMAP(ii.hbmColor); // make sure this is cleaned up properly auto maskbmp = RAIIHBITMAP(ii.hbmMask); // make sure this is cleaned up properly pos.X = cursorInfo.ptScreenPos.x - ii.xHotspot; pos.Y = cursorInfo.ptScreenPos.y - ii.yHotspot; return pos; }
std::shared_ptr<RemoteDesktop::Image> CaptureDesktop(const RemoteDesktop::RAIIHDC_TYPE &desktopGuard, int left, int top) { auto nScreenWidth = GetDeviceCaps(desktopGuard.get(), HORZRES); auto nScreenHeight = GetDeviceCaps(desktopGuard.get(), VERTRES); auto hCaptureDC = RAIIHDC(CreateCompatibleDC(desktopGuard.get())); auto hCaptureBmp = RAIIHBITMAP(CreateCompatibleBitmap(desktopGuard.get(), nScreenWidth, nScreenHeight)); // Selecting an object into the specified DC auto originalBmp = SelectObject(hCaptureDC.get(), hCaptureBmp.get()); if (!BitBlt(hCaptureDC.get(), 0, 0, nScreenWidth, nScreenHeight, desktopGuard.get(), left, top, SRCCOPY | CAPTUREBLT)){ auto p(std::make_shared<RemoteDesktop::Image>(nScreenHeight, nScreenWidth)); memset(p->get_Data(), 1, p->size_in_bytes()); return p; } BITMAPINFOHEADER bi; memset(&bi, 0, sizeof(bi)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = nScreenWidth; bi.biHeight = -nScreenHeight; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; bi.biSizeImage = ((nScreenWidth * bi.biBitCount + 31) / 32) * 4 * nScreenHeight; auto ptr(std::make_shared<RemoteDesktop::Image>(nScreenHeight, nScreenWidth)); GetDIBits(desktopGuard.get(), hCaptureBmp.get(), 0, (UINT)nScreenHeight, ptr->get_Data(), (BITMAPINFO *)&bi, DIB_RGB_COLORS); SelectObject(hCaptureDC.get(), originalBmp); return ptr; }
std::shared_ptr<Utilities::Image> CaptureMouseImage() { auto desktopdc = RAIIHDC(GetDC(NULL)); auto capturedc = RAIIHDC(CreateCompatibleDC(desktopdc.get())); auto capturebmp = RAIIHBITMAP(CreateCompatibleBitmap(desktopdc.get(), 32, 32)); // 32 x 32 is the biggest allowed for windows... if (!desktopdc || !capturedc || !capturebmp) { SL_RAT_LOG(Utilities::Logging_Levels::ERROR_log_level, "Couldnt get Init DC!"); return Utilities::Image::CreateImage(0, 0); } auto originalBmp = SelectObject(capturedc.get(), capturebmp.get()); CURSORINFO cursorInfo; cursorInfo.cbSize = sizeof(cursorInfo); if (GetCursorInfo(&cursorInfo) == FALSE) { SL_RAT_LOG(Utilities::Logging_Levels::ERROR_log_level, "GetCursorInfo == FALSE"); return Utilities::Image::CreateImage(0, 0); } ICONINFOEXA ii = { 0 }; ii.cbSize = sizeof(ii); if (GetIconInfoExA(cursorInfo.hCursor, &ii) == FALSE) { //this tends to fail on hyper-v enviornments generating alot of noise. so lower its level to Info.. SL_RAT_LOG(Utilities::Logging_Levels::INFO_log_level, "GetIconInfoEx == FALSE"); return Utilities::Image::CreateImage(0, 0); } auto colorbmp = RAIIHBITMAP(ii.hbmColor); // make sure this is cleaned up properly auto maskbmp = RAIIHBITMAP(ii.hbmMask); // make sure this is cleaned up properly if (DrawIcon(capturedc.get(), 0, 0, cursorInfo.hCursor) == FALSE) { SL_RAT_LOG(Utilities::Logging_Levels::ERROR_log_level, "DrawIcon == FALSE"); return Utilities::Image::CreateImage(0, 0); } BITMAP bm; int height = 0; int width = 0; if (ii.hbmColor != NULL) { if (GetObject(colorbmp.get(), sizeof(bm), &bm) != NULL) { height = bm.bmHeight; width = bm.bmWidth; } } else if (ii.hbmMask != NULL) { if (GetObject(maskbmp.get(), sizeof(bm), &bm) != NULL) { height = bm.bmHeight / 2; width = bm.bmWidth; } } if (height <= 0 || width <= 0 || height > 32 || width > 32) { SL_RAT_LOG(Utilities::Logging_Levels::ERROR_log_level, "Cursor dimensions are outside normal sizes, could be an error"); return Utilities::Image::CreateImage(0, 0); } BITMAPINFOHEADER bi; memset(&bi, 0, sizeof(bi)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = width; bi.biHeight = -height; bi.biPlanes = 1; bi.biBitCount = 32; // always 32 bits damnit!!! bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; bi.biSizeImage = ((width * bi.biBitCount + 31) / 32) * 4 * height; auto retimg(Utilities::Image::CreateImage(width, height)); GetDIBits(desktopdc.get(), capturebmp.get(), 0, (UINT)height, retimg->data(), (BITMAPINFO*)&bi, DIB_RGB_COLORS); SelectObject(capturedc.get(), originalBmp); if (ii.wResID == 32513) { // when its just the i beam unsigned int* ptr = (unsigned int*)retimg->data(); for (decltype(retimg->size()) i = 0; i < retimg->size() / 4; i++) { if (ptr[i] != 0) { ptr[i] = 0xff000000; } } } else if (ii.hbmMask != nullptr && ii.hbmColor == nullptr) {// just auto ptr = (unsigned int*)retimg->data(); for (decltype(retimg->size()) i = 0; i < retimg->size() / 4; i++) { if (ptr[i] != 0) { ptr[i] = ptr[i] | 0xffffffff; } } } return retimg; }