解决win7截图的BUG,解决Linux开机启动时候输入法BUG

This commit is contained in:
xhm
2025-12-24 12:54:52 +08:00
parent 43313828a7
commit 282fff24dc
6 changed files with 99 additions and 31 deletions

View File

@@ -108,10 +108,10 @@ namespace CPF.Linux
var depth = 32;// (int)x11info.TransparentVisualInfo.depth;
attr.colormap = XCreateColormap(x11info.Display, x11info.RootWindow, x11info.TransparentVisualInfo.visual, 0);
valueMask |= SetWindowValuemask.ColorMap;
size = new PixelSize(300, 200);
position = new PixelPoint(10, 10);
size = new PixelSize(1, 1);
position = new PixelPoint(0, 0);
Handle = XCreateWindow(x11info.Display, x11info.RootWindow, 10, 10, size.Width, size.Height, 0, depth, (int)CreateWindowArgs.InputOutput, x11info.TransparentVisualInfo.visual, new UIntPtr((uint)valueMask), ref attr);
Handle = XCreateWindow(x11info.Display, x11info.RootWindow, position.X, position.Y, size.Width, size.Height, 0, depth, (int)CreateWindowArgs.InputOutput, x11info.TransparentVisualInfo.visual, new UIntPtr((uint)valueMask), ref attr);
// var attributes = new XSetWindowAttributes();
// attributes.background_pixel = XWhitePixel(x11info.Display, x11info.DefaultScreen);
@@ -438,9 +438,9 @@ namespace CPF.Linux
activate = false;
//Console.WriteLine("Deactivated");
Deactivated?.Invoke();
XUnsetICFocus(xic);
if (xic != IntPtr.Zero)
{
XUnsetICFocus(xic);
//if (have_Xutf8ResetIC)
//{
// try

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using CPF.Drawing;
using CPF.Platform;
@@ -60,32 +62,94 @@ namespace CPF.Windows
public override Bitmap Screenshot()
{
var srcDC = GetDC(IntPtr.Zero);
var bounds = Bounds;
IntPtr desktopHwnd = GetDesktopWindow();
IntPtr desktopDc = GetWindowDC(desktopHwnd);
IntPtr memDc = CreateCompatibleDC(desktopDc);
IntPtr memDc = CreateCompatibleDC(srcDC);
BITMAPINFOHEADER info = new BITMAPINFOHEADER();
info.biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
info.biBitCount = 32;
info.biHeight = -(int)bounds.Height;
info.biWidth = (int)bounds.Width;
info.biPlanes = 1;
var hBitmap = CreateDIBSection(memDc, ref info, 0, out var ppvBits, IntPtr.Zero, 0);
var oldBits = SelectObject(memDc, hBitmap);
try
{
// 3. 创建DIBSection (24位真彩色位图)
BITMAPINFOHEADER bmi = new BITMAPINFOHEADER
{
biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER)),
biWidth = (int)Bounds.Width,
biHeight = -(int)Bounds.Height, // 负值表示自顶向下DIB
biPlanes = 1,
biBitCount = 24,
biCompression = 0, // BI_RGB
biSizeImage = (uint)(((int)Bounds.Width * 3 + 3) & ~3) * (uint)Bounds.Height // 行对齐到4字节
}
;
BitBlt(memDc, 0, 0, (int)bounds.Width,
(int)bounds.Height, srcDC, (int)bounds.X, (int)bounds.Y, TernaryRasterOperations.SRCCOPY);
Bitmap temp = new Bitmap((int)bounds.Width, (int)bounds.Height, (int)bounds.Width * 4, PixelFormat.Bgra, ppvBits);
IntPtr hBitmap = CreateDIBSection(desktopDc, ref bmi, 0, out var bitsPtr, IntPtr.Zero, 0);
Bitmap bitmap = (Bitmap)temp.Clone();
temp.Dispose();
// 4. 将屏幕内容复制到位图
IntPtr oldBitmap = SelectObject(memDc, hBitmap);
BitBlt(memDc, 0, 0, (int)Bounds.Width, (int)Bounds.Height, desktopDc, 0, 0, TernaryRasterOperations.SRCCOPY | TernaryRasterOperations.CAPTUREBLT);
SelectObject(memDc, oldBitmap);
SelectObject(memDc, oldBits);
DeleteObject(hBitmap);
DeleteDC(memDc);
// 5. 构造BMP文件
using (MemoryStream ms = new MemoryStream())
{
// 5.1 计算文件大小
uint pixelDataSize = bmi.biSizeImage;
uint fileSize = (uint)(Marshal.SizeOf(typeof(BITMAPFILEHEADER)) +
(Marshal.SizeOf(typeof(BITMAPINFOHEADER))) +
pixelDataSize);
ReleaseDC(IntPtr.Zero, srcDC);
return bitmap;
// 5.2 创建文件头
BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER
{
bfType = 0x4D42, // "BM"
bfSize = fileSize,
bfOffBits = (uint)(Marshal.SizeOf(typeof(BITMAPFILEHEADER)) +
(Marshal.SizeOf(typeof(BITMAPINFOHEADER))))
}
;
// 5.3 写入文件头
byte[] fileHeaderBytes = StructureToBytes(fileHeader);
ms.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);
// 5.4 写入信息头
byte[] infoHeaderBytes = StructureToBytes(bmi);
ms.Write(infoHeaderBytes, 0, infoHeaderBytes.Length);
// 5.5 写入像素数据 (直接从DIBSection内存复制)
byte[] pixelData = new byte[pixelDataSize];
Marshal.Copy(bitsPtr, pixelData, 0, (int)pixelDataSize);
ms.Write(pixelData, 0, pixelData.Length);
ms.Position = 0;
Bitmap bitmap = new Bitmap(ms);
return bitmap;
}
}
finally
{
// 6. 清理资源
ReleaseDC(desktopHwnd, desktopDc);
DeleteDC(memDc);
}
}
// 辅助方法:结构体转字节数组
private static byte[] StructureToBytes<T>(T structure) where T : struct
{
int size = Marshal.SizeOf(typeof(T));
byte[] bytes = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structure, ptr, false);
Marshal.Copy(ptr, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
}
}

View File

@@ -880,7 +880,11 @@ namespace CPF.Windows
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern int GetDeviceCaps(IntPtr hDC, int nIndex);
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]

View File

@@ -90,10 +90,6 @@ namespace CPF.Windows
{
isLayered = true;
}
if ((v.Major == 6 && v.Minor < 2))
{
touchMsg = RegisterTouchWindow(handle, RegisterTouchFlags.TWF_NONE);
}
_className = "CPFWindow-" + Guid.NewGuid();
// 初始化窗口类结构
wc.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
@@ -113,6 +109,10 @@ namespace CPF.Windows
handle = CreateWindowEx((int)ExStyle, _className, "窗体标题", (uint)Style,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, IntPtr.Zero, IntPtr.Zero, ModuleHandle, null);
if ((v.Major == 6 && v.Minor < 2))
{
touchMsg = RegisterTouchWindow(handle, RegisterTouchFlags.TWF_NONE);
}
//timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1), IsEnabled = true };
//timer.Tick += Timer_Tick;

View File

@@ -276,7 +276,7 @@ namespace CPF.Controls
{
timer = new Threading.DispatcherTimer();
timer.Tick += Timer_Tick;
timer.Interval = TimeSpan.FromMilliseconds(50);
timer.Interval = TimeSpan.FromMilliseconds(25);
}
timer.Start();

View File

@@ -75,7 +75,7 @@ namespace CPF.Input
}
}
internal void SetFocus(UIElement e)
public void SetFocus(UIElement e)
{
focusedElement = e;
//if (focusedElement != null)