Using Directshow.NET I have developed an application which will record the desktop screen, to get mouse pointer we need to paint mouse pointer by our own. So I added SampleGrabber
adn in BufferCB
I have written below code:
public const Int32 CURSOR_SHOWING = 0x00000001;
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFO
{
public bool fIcon;
public Int32 xHotspot;
public Int32 yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public Int32 x;
public Int32 y;
}
[StructLayout(LayoutKind.Sequential)]
public struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINT ptScreenPos;
}
[DllImport("user32.dll")]
public static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
public static extern IntPtr CopyIcon(IntPtr hIcon);
[DllImport("user32.dll")]
public static extern bool DrawIcon(IntPtr hdc, int x, int y, IntPtr hIcon);
[DllImport("user32.dll")]
public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
{
Graphics g;
Bitmap v;
v = new Bitmap(m_videoWidth, m_videoHeight, m_stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, pBuffer);
g = Graphics.FromImage(v);
CURSORINFO cursorInfo;
cursorInfo.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out cursorInfo))
{
if (cursorInfo.flags == CURSOR_SHOWING)
{
var iconPointer = CopyIcon(cursorInfo.hCursor);
ICONINFO iconInfo;
int iconX, iconY;
if (GetIconInfo(iconPointer, out iconInfo))
{
iconX = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot);
iconY = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot);
DrawIcon(g.GetHdc(), iconX, iconY, cursorInfo.hCursor);
g.ReleaseHdc();
g.Dispose();
v.Dispose();
}
}
}
return 0;
}
This code is painting the mouse cursor but cursor is flipped on Y axis.
It's may be because in BufferCB
if we convert pBuffer
in Bitmap then that frame is flipped on Y axis. To solve this I flipped current frame on Y axis by adding v.RotateFlip(RotateFlipType.RotateNoneFlipY);
inside BufferCB
after this change mouse pointer is not visible in desktop recording video.
How I can flip mouse pointer?
Update #1
I converted icon pointer to Icon
then into Bitmap
using Icon.ToBitmap()
and then flipped on Y axis, here is code (Thanks to @Roman R.):
...
iconX = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot);
iconY = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot);
Icon ic = Icon.FromHandle(iconPointer);
Bitmap icon = ic.ToBitmap();
icon.RotateFlip(RotateFlipType.RotateNoneFlipY);
g.DrawImage(icon, iconX, iconY);
g.Dispose();
v.Dispose();
icon.Dispose();
ic.Dispose();
...
Only one issue I am facing in above modification sometimes I get ArgumentException
at line Bitmap icon = ic.ToBitmap();
System.ArgumentException occurred
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Bitmap.FromHicon(IntPtr hicon)
InnerException:
I disposed all the bitmaps used, still i get this exception.