Desde hace mucho tiempo me ha llamado la atención la WTL (Windows Template Library), así que decidí crear un pequeño programa utilizando dicha tecnología. Me gusta mucho que el tamaño de los ejecutables de WTL sea mucho más pequeños que los que genera MFC (Microsoft Foundation Classes) y que el código fuente sea abierto para que todo el mundo pueda verlo. Muchos de vosotros pensaréis que no hay mucha diferencia entre WTL y MFC, y en cierto modo es verdad. Son dos herramientas súper potentes para cualquiera que quiera desarrollar programas pequeños y rápidos.
Si a la hora del desarrollo te aparecen errores relacionados con las librerías, puede ser que tengas que instalar los componentes que te detallo más abajo:
- Visual C++ Redistributable para Visual Studio 2015 (https://www.microsoft.com/en-us/download/details.aspx?id=48145)
He testeado el programa en Windows 7 y Windows XP. Realmente no sé qué tal funciona en otras plataformas.
Características
- 1. Capturar pantalla completa
- 2. Capturar ventana
- 3. Capturar zona
- 4. Zoom in
- 5. Zoom out
- 6. Copiar la imagen capturada a Paint
- 7. Favoritos
- 8. Copiar la imagen capturada al portapapeles
- 9. Entorno (atajos)
- 10. Visor de imágenes
Implementación
Enviamos la imagen capturada a Microsoft Paint
//Copy an image to the clipboard. if (OpenClipboard()) { EmptyClipboard(); CBitmap bmpCopy; BITMAP bm; if (GetObject(pImageData->m_bmpOri.m_hBitmap, sizeof(BITMAP), &bm)) bmpCopy = (HBITMAP)CopyImage(pImageData->m_bmpOri.m_hBitmap, IMAGE_BITMAP, 0, 0, 0); ATLASSERT(::GetObjectType(bmpCopy.m_hBitmap) == OBJ_BITMAP); SetClipboardData(CF_BITMAP, bmpCopy.m_hBitmap); CloseClipboard(); } if (IsClipboardFormatAvailable(CF_BITMAP)) { HWND hPaint; STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(STARTUPINFO)); memset(&pi, 0, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); wchar_t szWindowDirector[MAX_PATH] = { 0 }; CString strMspaintLoc; GetSystemDirectory(szWindowDirector, MAX_PATH); strMspaintLoc.Format(L"%s\%s", szWindowDirector, L"mspaint.exe"); if (CreateProcess(strMspaintLoc, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { //HWINEVENTHOOK hook = // SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, // WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT); /*ResumeThread(pi.hThread);*/ //THIS PART NEEDS TO BE FIXED. while (TRUE) { Sleep(100); hPaint = FindWindow(L"MsPaintApp", NULL); ATLTRACE(L"findwindow Handle %Xn", hPaint); if (hPaint) break; } } else { MessageBox(L"Couldn't find mspaint program"); return; } if (OpenClipboard()) { CloseClipboard(); if (SetForegroundWindow(hPaint)) { //Ctrl + V (paste) INPUT ip; ip.type = INPUT_KEYBOARD; ip.ki.wScan = 0; ip.ki.time = 0; ip.ki.dwExtraInfo = 0; // Press the "Ctrl" key ip.ki.wVk = VK_CONTROL; ip.ki.dwFlags = 0; // 0 for key press SendInput(1, &ip, sizeof(INPUT)); // Press the "V" key ip.ki.wVk = 'V'; ip.ki.dwFlags = 0; // 0 for key press SendInput(1, &ip, sizeof(INPUT)); // Release the "V" key ip.ki.wVk = 'V'; ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); // Release the "Ctrl" key ip.ki.wVk = VK_CONTROL; ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } } }
Capturamos pantalla
CRect rc; ShowWindow(SW_MINIMIZE); Sleep(100); // Start to get an Image from the nearest screen (Prepare capture data) CDC dcWindow; dcWindow.CreateDCW(L"DISPLAY", NULL, NULL, NULL); // Get the nearest monitor rect CMonitorInfo::GetMonitorRect(m_hWnd, rc); CBitmap bmp, oldbmp; CDC dcMem; CClientDC dc(m_hWnd); dcMem.CreateCompatibleDC(); bmp.CreateCompatibleBitmap(dcWindow, rc.Width(), rc.Height()); oldbmp = dcMem.SelectBitmap(bmp); dcMem.BitBlt(0, 0, rc.Width(), rc.Height(), dcWindow, rc.left, rc.top, SRCCOPY); SetCaptureImage(&bmp); dcMem.SelectBitmap(oldbmp); ShowWindow(SW_RESTORE);
Capturamos ventana
void CMCFrameWnd::CaptureWindow() { // Get full screen size. CRect rcMonitor; ShowWindow(SW_MINIMIZE); Sleep(100); // Start to get an Image from the nearest screen (Prepare capture data) CDC dcWindow; dcWindow.CreateDCW(L"DISPLAY", NULL, NULL, NULL); // Get the nearest monitor Rect CMonitorInfo::GetMonitorRect(m_hWnd, rcMonitor); CBitmap bmp, oldbmp; CDC dcMem; CClientDC dc(m_hWnd); dcMem.CreateCompatibleDC(); bmp.CreateCompatibleBitmap(dcWindow, rcMonitor.Width(), rcMonitor.Height()); oldbmp = dcMem.SelectBitmap(bmp); dcMem.BitBlt(0, 0, rcMonitor.Width(), rcMonitor.Height(), dcWindow, rcMonitor.left, rcMonitor.top, SRCCOPY); dcMem.SelectBitmap(oldbmp); if (m_pwndTemparyScreenWnd != NULL) delete m_pwndTemparyScreenWnd; m_pwndTemparyScreenWnd = new CTemparyScreenWnd(this); m_pwndTemparyScreenWnd->mode = CTemparyScreenWnd::Mode::TEMPARYSCREEN_WINDOW; m_pwndTemparyScreenWnd->Create(m_hWnd, rcMonitor, 0, WS_POPUP | WS_VISIBLE, WS_EX_TOPMOST); m_pwndTemparyScreenWnd->GetWindowData(); m_pwndTemparyScreenWnd->SetScreenImage(bmp); m_pwndTemparyScreenWnd->ShowMonitorScreen(); SetForegroundWindow(m_pwndTemparyScreenWnd->m_hWnd); }
Si quieres descargarte el proyecto completo, puedes hacerlo desde aquí.
Fuente: Taehoon Kim