mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-12-27 06:35:53 +08:00
解决win7截图的BUG,解决Linux开机启动时候输入法BUG
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace CPF.Input
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetFocus(UIElement e)
|
||||
public void SetFocus(UIElement e)
|
||||
{
|
||||
focusedElement = e;
|
||||
//if (focusedElement != null)
|
||||
|
||||
Reference in New Issue
Block a user