public override void Start(int delay, int left, int top, int width, int height, double scale, ProjectInfo project) { base.Start(delay, left, top, width, height, scale, project); _infoHeader = new Native.BitmapInfoHeader(); _infoHeader.biSize = (uint)Marshal.SizeOf(_infoHeader); _infoHeader.biBitCount = 24; //Without alpha channel. _infoHeader.biClrUsed = 0; _infoHeader.biClrImportant = 0; _infoHeader.biCompression = 0; _infoHeader.biHeight = -StartHeight; //Negative, so the Y-axis will be positioned correctly. _infoHeader.biWidth = StartWidth; _infoHeader.biPlanes = 1; //This was working with 32 bits: 3L * Width * Height; _byteLength = (StartWidth * _infoHeader.biBitCount + 31) / 32 * 4 * StartHeight; //Due to a strange behavior with the GetDiBits method while the cursor is IBeam, it's best to use 24 bits, to ignore the alpha values. //This capture mode ignores the alpha value. project.BitDepth = 24; _fileStream = new FileStream(project.CachePath, FileMode.Create, FileAccess.Write, FileShare.None); _bufferedStream = new BufferedStream(_fileStream, UserSettings.All.MemoryCacheSize * 1048576); //Each 1 MB has 1_048_576 bytes. _compressStream = new DeflateStream(_bufferedStream, UserSettings.All.CaptureCompression, true); }
/// <summary> /// Changes the icon of the file to the specified icon. /// </summary> /// <param name="icon">The <see cref="Icon" /> to be applied to the file.</param> public unsafe void ChangeIcon(Icon icon) { Check.FileNotFound(Path); Check.ArgumentNull(icon, nameof(icon)); Native.IconDir iconDir = new Native.IconDir(); List <Native.IconDirEntry> iconEntry = new List <Native.IconDirEntry>(); List <byte[]> iconData = new List <byte[]>(); using (BinaryReader reader = new BinaryReader(new MemoryStream(icon.ToArray()))) { Marshal.Copy(reader.ReadBytes(sizeof(Native.IconDir)), 0, (IntPtr)(&iconDir), sizeof(Native.IconDir)); for (int i = 0; i < iconDir.Count; i++) { Native.IconDirEntry entry = new Native.IconDirEntry(); Marshal.Copy(reader.ReadBytes(sizeof(Native.IconDirEntry)), 0, (IntPtr)(&entry), sizeof(Native.IconDirEntry)); iconEntry.Add(entry); } for (int i = 0; i < iconDir.Count; i++) { iconData.Add(reader.ReadBytes((int)iconEntry[i].BytesInRes)); } } IntPtr update = Native.BeginUpdateResource(Path, false); byte[] data = new byte[sizeof(Native.IconDir) + sizeof(Native.GroupIconDirEntry) * iconDir.Count]; Marshal.Copy((IntPtr)(&iconDir), data, 0, sizeof(Native.IconDir)); for (int i = 0, offset = sizeof(Native.IconDir); i < iconDir.Count; i++, offset += sizeof(Native.GroupIconDirEntry)) { Native.BitmapInfoHeader header = new Native.BitmapInfoHeader(); Marshal.Copy(iconData[i], 0, (IntPtr)(&header), sizeof(Native.BitmapInfoHeader)); Native.GroupIconDirEntry groupEntry = new Native.GroupIconDirEntry { Width = iconEntry[i].Width, Height = iconEntry[i].Height, ColorCount = iconEntry[i].ColorCount, Reserved = iconEntry[i].Reserved, Planes = header.Planes, BitCount = header.BitCount, BytesInRes = iconEntry[i].BytesInRes, Id = (ushort)(i + 10) }; Marshal.Copy((IntPtr)(&groupEntry), data, offset, Marshal.SizeOf(groupEntry)); } Native.UpdateResource(update, (uint)ResourceType.GroupIcon, 1, 0, data, (uint)data.Length); for (int i = 0; i < iconDir.Count; i++) { Native.UpdateResource(update, (uint)ResourceType.Icon, (uint)(10 + i), 0, iconData[i], (uint)iconData[i].Length); } Native.EndUpdateResource(update, false); }
private void CursorCapture(FrameInfo frame) { //if (_justStarted && (CursorShapeBuffer?.Length ?? 0) == 0) { //_justStarted = false; //https://stackoverflow.com/a/6374151/1735672 //Bitmap struct, is used to get the cursor shape when SharpDX fails to do so. var _infoHeader = new Native.BitmapInfoHeader(); _infoHeader.biSize = (uint)Marshal.SizeOf(_infoHeader); _infoHeader.biBitCount = 32; _infoHeader.biClrUsed = 0; _infoHeader.biClrImportant = 0; _infoHeader.biCompression = 0; _infoHeader.biHeight = -Height; //Negative, so the Y-axis will be positioned correctly. _infoHeader.biWidth = Width; _infoHeader.biPlanes = 1; try { var cursorInfo = new Native.CursorInfo(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); if (Native.GetCursorInfo(out cursorInfo)) { if (cursorInfo.flags == Native.CursorShowing) { var hicon = Native.CopyIcon(cursorInfo.hCursor); if (hicon != IntPtr.Zero) { if (Native.GetIconInfo(hicon, out var iconInfo)) { frame.CursorX = cursorInfo.ptScreenPos.X - Left; frame.CursorY = cursorInfo.ptScreenPos.Y - Top; var bitmap = new Native.Bitmap(); var hndl = GCHandle.Alloc(bitmap, GCHandleType.Pinned); var ptrToBitmap = hndl.AddrOfPinnedObject(); Native.GetObject(iconInfo.hbmColor, Marshal.SizeOf <Native.Bitmap>(), ptrToBitmap); bitmap = Marshal.PtrToStructure <Native.Bitmap>(ptrToBitmap); hndl.Free(); //https://microsoft.public.vc.mfc.narkive.com/H1CZeqUk/how-can-i-get-bitmapinfo-object-from-bitmap-or-hbitmap _infoHeader.biHeight = bitmap.bmHeight; _infoHeader.biWidth = bitmap.bmWidth; _infoHeader.biBitCount = (ushort)bitmap.bmBitsPixel; var w = (bitmap.bmWidth * bitmap.bmBitsPixel + 31) / 8; CursorShapeBuffer = new byte[w * bitmap.bmHeight]; var windowDeviceContext = Native.GetWindowDC(IntPtr.Zero); var compatibleBitmap = Native.CreateCompatibleBitmap(windowDeviceContext, Width, Height); Native.GetDIBits(windowDeviceContext, compatibleBitmap, 0, (uint)_infoHeader.biHeight, CursorShapeBuffer, ref _infoHeader, Native.DibColorMode.DibRgbColors); //if (frame.CursorX > 0 && frame.CursorY > 0) // Native.DrawIconEx(_compatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, 0, IntPtr.Zero, 0x0003); //Clean objects here. } Native.DeleteObject(iconInfo.hbmColor); Native.DeleteObject(iconInfo.hbmMask); } Native.DestroyIcon(hicon); } Native.DeleteObject(cursorInfo.hCursor); } } catch (Exception e) { LogWriter.Log(e, "Impossible to get the cursor"); } } }
public void Other() { var hDC = Native.GetWindowDC(IntPtr.Zero); var hMemDC = Native.CreateCompatibleDC(hDC); var bi = new Native.BitmapInfoHeader(); bi.biSize = (uint)Marshal.SizeOf(bi); bi.biBitCount = 24; //Creating RGB bitmap. The following three members don't matter bi.biClrUsed = 0; bi.biClrImportant = 0; bi.biCompression = 0; bi.biHeight = Height; bi.biWidth = Width; bi.biPlanes = 1; var cb = (int)(bi.biHeight * bi.biWidth * bi.biBitCount / 8); //8 is bits per byte. bi.biSizeImage = (uint)(((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight); //bi.biXPelsPerMeter = XPelsPerMeter; //bi.biYPelsPerMeter = YPelsPerMeter; bi.biXPelsPerMeter = 96; bi.biYPelsPerMeter = 96; var pBits = IntPtr.Zero; //Allocate memory for bitmap bits var pBI = Native.LocalAlloc((uint)Native.LocalMemoryFlags.LPTR, new UIntPtr(bi.biSize)); // Not sure if this needed - simply trying to keep marshaller happy Marshal.StructureToPtr(bi, pBI, false); //This will return IntPtr to actual DIB bits in pBits var hBmp = Native.CreateDIBSection(hDC, ref pBI, 0, out pBits, IntPtr.Zero, 0); //Marshall back - now we have BitmapInfoHeader correctly filled in Marshal.PtrToStructure(pBI, bi); var biNew = (Native.BitmapInfoHeader)Marshal.PtrToStructure(pBI, typeof(Native.BitmapInfoHeader)); //Usual stuff var hOldBitmap = Native.SelectObject(hMemDC, hBmp); //Grab bitmap var nRet = Native.BitBlt(hMemDC, 0, 0, bi.biWidth, bi.biHeight, hDC, Left, Top, Native.CopyPixelOperation.SourceCopy | Native.CopyPixelOperation.CaptureBlt); // Allocate memory for a copy of bitmap bits var RealBits = new byte[cb]; // And grab bits from DIBSestion data Marshal.Copy(pBits, RealBits, 0, cb); //This simply creates valid bitmap file header, so it can be saved to disk var bfh = new Native.BitmapFileHeader(); bfh.bfSize = (uint)cb + 0x36; // Size of header + size of Native.BitmapInfoHeader size of bitmap bits bfh.bfType = 0x4d42; //BM bfh.bfOffBits = 0x36; // var HdrSize = 14; var header = new byte[HdrSize]; BitConverter.GetBytes(bfh.bfType).CopyTo(header, 0); BitConverter.GetBytes(bfh.bfSize).CopyTo(header, 2); BitConverter.GetBytes(bfh.bfOffBits).CopyTo(header, 10); //Allocate enough memory for complete bitmap file var data = new byte[cb + bfh.bfOffBits]; //BITMAPFILEHEADER header.CopyTo(data, 0); //BitmapInfoHeader header = new byte[Marshal.SizeOf(bi)]; var pHeader = Native.LocalAlloc((uint)Native.LocalMemoryFlags.LPTR, new UIntPtr((uint)Marshal.SizeOf(bi))); Marshal.StructureToPtr(biNew, pHeader, false); Marshal.Copy(pHeader, header, 0, Marshal.SizeOf(bi)); Native.LocalFree(pHeader); header.CopyTo(data, HdrSize); //Bitmap bits RealBits.CopyTo(data, (int)bfh.bfOffBits); //Native.SelectObject(_compatibleDeviceContext, _oldBitmap); //Native.DeleteObject(_compatibleBitmap); //Native.DeleteDC(_compatibleDeviceContext); //Native.ReleaseDC(_desktopWindow, _windowDeviceContext); Native.SelectObject(hMemDC, hOldBitmap); Native.DeleteObject(hBmp); Native.DeleteDC(hMemDC); Native.ReleaseDC(IntPtr.Zero, hDC); }