This commit is contained in:
恍兮惚兮 2024-05-27 00:17:36 +08:00
parent f12c6fff88
commit 4ad963d9bd
7 changed files with 226 additions and 32 deletions

View File

@ -7,13 +7,13 @@ from PyQt5.QtWidgets import (
QDialog, QDialog,
QDesktopWidget, QDesktopWidget,
) )
from PyQt5.QtGui import QPainter, QPen, QColor from PyQt5.QtGui import QPainter, QPen, QColor, QResizeEvent
from PyQt5.QtCore import Qt, QPoint, QRect, QEvent from PyQt5.QtCore import Qt, QPoint, QRect, QEvent
from myutils.config import _TR from myutils.config import _TR
import gobject import gobject
from myutils.config import globalconfig from myutils.config import globalconfig
from gui.resizeablemainwindow import Mainw from gui.resizeablemainwindow import Mainw
import windows import windows, winsharedutils
class rangeadjust(Mainw): class rangeadjust(Mainw):
@ -131,25 +131,24 @@ class rangeselct(QMainWindow):
Qt.FramelessWindowHint | Qt.Tool Qt.FramelessWindowHint | Qt.Tool
) # |Qt.WindowStaysOnTopHint ) ) # |Qt.WindowStaysOnTopHint )
self.rectlabel = QLabel(self) self.rectlabel = QLabel(self)
self.setAttribute(Qt.WA_TranslucentBackground) # self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowOpacity(0.5)
self.setMouseTracking(True)
self.setCursor(Qt.CrossCursor)
self.reset()
def reset(self): def reset(self):
# screens = QDesktopWidget().screenCount() winsharedutils.maximum_window(int(self.winId()))
# desktop = QDesktopWidget().screenGeometry(0) # desktop = QApplication.primaryScreen().virtualGeometry()
# for i in range(1, screens): # self.setGeometry(desktop)
# desktop = desktop.united(QDesktopWidget().screenGeometry(i))
desktop = QApplication.primaryScreen().virtualGeometry()
self.setGeometry(desktop)
self.rectlabel.setGeometry(desktop)
self.setCursor(Qt.CrossCursor)
self.is_drawing = False self.is_drawing = False
self.setMouseTracking(True)
self.start_point = QPoint() self.start_point = QPoint()
self.end_point = QPoint() self.end_point = QPoint()
self.__start = None self.__start = None
self.__end = None self.__end = None
self.startauto = False self.startauto = False
self.clickrelease = False self.clickrelease = False
self.rectlabel.resize(0, 0)
self.rectlabel.setStyleSheet( self.rectlabel.setStyleSheet(
" border:%spx solid %s; background-color: rgba(0,0,0, 0.01)" " border:%spx solid %s; background-color: rgba(0,0,0, 0.01)"
% (globalconfig["ocrrangewidth"], globalconfig["ocrrangecolor"]) % (globalconfig["ocrrangewidth"], globalconfig["ocrrangecolor"])
@ -246,8 +245,8 @@ def rangeselct_function(parent, callback, clickrelease, startauto):
global screen_shot_ui global screen_shot_ui
if screen_shot_ui is None: if screen_shot_ui is None:
screen_shot_ui = rangeselct(parent) screen_shot_ui = rangeselct(parent)
screen_shot_ui.reset()
screen_shot_ui.show() screen_shot_ui.show()
screen_shot_ui.reset()
screen_shot_ui.callback = callback screen_shot_ui.callback = callback
windows.SetFocus(int(screen_shot_ui.winId())) windows.SetFocus(int(screen_shot_ui.winId()))

View File

@ -252,3 +252,10 @@ def mouseselectwindow(callback):
pass pass
threading.Thread(target=_loop).start() threading.Thread(target=_loop).start()
def screenshot(x1, y1, x2, y2):
bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2)
pixmap = QPixmap()
pixmap.loadFromData(bs)
return pixmap

View File

@ -5,7 +5,7 @@ from PyQt5.QtWidgets import QApplication, QDesktopWidget
from PyQt5.QtGui import QImage from PyQt5.QtGui import QImage
from PyQt5.QtCore import QByteArray, QBuffer from PyQt5.QtCore import QByteArray, QBuffer
from myutils.commonbase import ArgsEmptyExc from myutils.commonbase import ArgsEmptyExc
from myutils.hwnd import dynamic_rate from myutils.hwnd import dynamic_rate, screenshot
from myutils.utils import stringfyerror from myutils.utils import stringfyerror
from traceback import print_exc from traceback import print_exc
import gobject, winsharedutils import gobject, winsharedutils
@ -83,20 +83,9 @@ def imageCut(hwnd, x1, y1, x2, y2, viscompare=True, rawimage=False) -> QImage:
except: except:
print_exc() print_exc()
else: else:
if QDesktopWidget().screenCount() > 1: if QDesktopWidget().screenCount() > 1:
desktop = QApplication.primaryScreen().virtualGeometry() pix = screenshot(x1, y1, x2, y2)
pix = screen.grabWindow(
QApplication.desktop().winId(),
desktop.x(),
desktop.y(),
desktop.width(),
desktop.height(),
)
x1 = x1 - desktop.x()
y1 = y1 - desktop.y()
x2 = x2 - desktop.x()
y2 = y2 - desktop.y()
pix = pix.copy(x1, y1, x2 - x1, y2 - y1)
else: else:
pix = screen.grabWindow( pix = screen.grabWindow(
QApplication.desktop().winId(), x1, y1, x2 - x1, y2 - y1 QApplication.desktop().winId(), x1, y1, x2 - x1, y2 - y1

View File

@ -20,7 +20,7 @@ from ctypes import (
c_double, c_double,
c_char, c_char,
) )
from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT, BYTE
from windows import WINDOWPLACEMENT from windows import WINDOWPLACEMENT
import gobject, csv import gobject, csv
@ -126,7 +126,9 @@ def SAPI_Speak(content, v, voiceid, rate, volume):
return data return data
def distance(s1, s2): # 词典更适合用编辑距离,因为就一两个字符,相似度会很小,预翻译适合用相似度 def distance(
s1, s2
): # 词典更适合用编辑距离,因为就一两个字符,相似度会很小,预翻译适合用相似度
return _levenshtein_distance(len(s1), s1, len(s2), s2) return _levenshtein_distance(len(s1), s1, len(s2), s2)
@ -359,3 +361,24 @@ PlayAudioInMem.restype = c_int
PlayAudioInMem_Stop = utilsdll.PlayAudioInMem_Stop PlayAudioInMem_Stop = utilsdll.PlayAudioInMem_Stop
PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p
_gdi_screenshot = utilsdll.gdi_screenshot
_gdi_screenshot.argtypes = RECT, POINTER(c_size_t)
_gdi_screenshot.restype = POINTER(BYTE)
def gdi_screenshot(x1, y1, x2, y2):
sz = c_size_t()
rect = RECT()
rect.left = x1
rect.top = y1
rect.right = x2
rect.bottom = y2
bf = _gdi_screenshot(rect, pointer(sz))
data = cast(bf, POINTER(c_char))[: sz.value]
c_free(bf)
return data
maximum_window = utilsdll.maximum_window
maximum_window.argtypes = (HWND,)

View File

@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
include(generate_product_version) include(generate_product_version)
set(VERSION_MAJOR 2) set(VERSION_MAJOR 2)
set(VERSION_MINOR 52) set(VERSION_MINOR 53)
set(VERSION_PATCH 8) set(VERSION_PATCH 0)
add_library(pch pch.cpp) add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h) target_precompile_headers(pch PUBLIC pch.h)

View File

@ -11,7 +11,7 @@ generate_product_version(
VERSION_PATCH ${VERSION_PATCH} VERSION_PATCH ${VERSION_PATCH}
) )
add_library(winsharedutils MODULE audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo}) add_library(winsharedutils MODULE screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo})
target_precompile_headers(winsharedutils REUSE_FROM pch) target_precompile_headers(winsharedutils REUSE_FROM pch)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64") set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64")

View File

@ -0,0 +1,176 @@

#include "define.h"
void GetVirtualDesktopRect(RECT &rect)
{
// 获取虚拟桌面的尺寸和位置
rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rect.right = rect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
rect.bottom = rect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
HBITMAP GetBitmap(RECT &rect, HDC hDC)
{
HDC hMemDC;
int x, y;
int nWidth, nHeight;
HBITMAP hBitmap, hOldBitmap;
hMemDC = CreateCompatibleDC(hDC);
// RECT rect;
// GetVirtualDesktopRect(rect);
hBitmap = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hDC, rect.left, rect.top, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
return hBitmap;
}
int SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName)
{
WORD wBitCount; // 位图中每个像素所占字节数
// 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;
BITMAP Bitmap; // 位图属性结构
BITMAPFILEHEADER bmfHdr; // 位图文件头结构
BITMAPINFOHEADER bi; // 位图信息头结构
HANDLE fh; // 定义文件,分配内存句柄,调色板句柄
LPSTR lpbk, lpmem;
wBitCount = 32;
// 设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight; // 为负,正向的位图;为正,倒向的位图
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
// 创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图信息头
WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
// 获取位图阵列
lpmem = new char[dwBmBitsSize];
lpbk = (LPSTR) new char[dwBmBitsSize];
GetBitmapBits(hBitmap, dwBmBitsSize, lpmem); // 正向的内存图象数据
// 转化为倒向数据(仅在bmHeight为正时需要)
for (int i = 0; i < Bitmap.bmHeight; i++)
{
memcpy(lpbk + Bitmap.bmWidth * i * 4, lpmem + Bitmap.bmWidth * (Bitmap.bmHeight - i - 1) * 4, Bitmap.bmWidth * 4);
}
// 写位图数据
WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);
// 清除
delete[] lpbk;
delete[] lpmem;
CloseHandle(fh);
return TRUE;
}
BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size)
{
WORD wBitCount; // 位图中每个像素所占字节数
// 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;
BITMAP Bitmap; // 位图属性结构
BITMAPFILEHEADER bmfHdr; // 位图文件头结构
BITMAPINFOHEADER bi; // 位图信息头结构
LPSTR lpbk, lpmem;
wBitCount = 32;
// 设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight; // 为负,正向的位图;为正,倒向的位图
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
// 写入位图文件头
// WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图信息头
// WriteFile(fh, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
// 获取位图阵列
lpmem = new char[dwBmBitsSize];
lpbk = (LPSTR) new char[dwBmBitsSize];
GetBitmapBits(hBitmap, dwBmBitsSize, lpmem); // 正向的内存图象数据
for (int i = 0; i < Bitmap.bmHeight; i++)
{
memcpy(lpbk + Bitmap.bmWidth * i * 4, lpmem + Bitmap.bmWidth * (Bitmap.bmHeight - i - 1) * 4, Bitmap.bmWidth * 4);
}
// 写位图数据
// WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL);
auto buffer = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize];
memcpy(buffer, &bmfHdr, sizeof(BITMAPFILEHEADER));
memcpy(buffer + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));
memcpy(buffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER), lpbk, dwBmBitsSize);
*size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
// 清除
delete[] lpbk;
delete[] lpmem;
return buffer;
}
DECLARE BYTE *gdi_screenshot(RECT rect, size_t *size)
{
auto bm = GetBitmap(rect, GetDC(GetDesktopWindow()));
// SaveBitmapToFile(bm, LR"(.\2.bmp)");
auto bf = SaveBitmapToBuffer(bm, size);
DeleteObject(bf);
return bf;
}
DECLARE void maximum_window(HWND hwnd)
{
RECT rect;
GetVirtualDesktopRect(rect);
MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
}