Put Button on Top of Process Running in C# Form - c#

I'm running a process in a form and need to cover part of the toolbar with a button. No matter what I do, if I click on the process the button falls behind. Could someone take a look at my code and offer any suggestions? Thanks!
namespace Example
{
public partial class Form1 : Form
{
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
public const int SWP_ASYNCWINDOWPOS = 0x4000;
public const int SWP_DEFERERASE = 0x2000;
public const int SWP_DRAWFRAME = 0x0020;
public const int SWP_FRAMECHANGED = 0x0020;
public const int SWP_HIDEWINDOW = 0x0080;
public const int SWP_NOACTIVATE = 0x0010;
public const int SWP_NOCOPYBITS = 0x0100;
public const int SWP_NOMOVE = 0x0002;
public const int SWP_NOOWNERZORDER = 0x0200;
public const int SWP_NOREDRAW = 0x0008;
public const int SWP_NOREPOSITION = 0x0200;
public const int SWP_NOSENDCHANGING = 0x0400;
public const int SWP_NOSIZE = 0x0001;
public const int SWP_NOZORDER = 0x0004;
public const int SWP_SHOWWINDOW = 0x0040;
public const int HWND_TOP = 0;
public const int HWND_BOTTOM = 1;
public const int HWND_TOPMOST = -1;
public const int HWND_NOTOPMOST = -2;
public Form1() {
InitializeComponent();
openApp();
InitTimer();
}
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hwc, IntPtr hwp);
Panel myPanel = new Panel();
private void openApp() {
FormBorderStyle = FormBorderStyle.FixedToolWindow;
Thread.Sleep(500);
string fullPath = #"Notepad.exe";
ProcessStartInfo stinfo = new ProcessStartInfo();
stinfo.FileName = fullPath;
stinfo.CreateNoWindow = false;
stinfo.UseShellExecute = false;
stinfo.WindowStyle = ProcessWindowStyle.Hidden;
Console.WriteLine("Process started... ");
Process p = Process.Start(stinfo);
Thread.Sleep(500);
SetWindowPos(this.Handle, (IntPtr)HWND_TOPMOST, 0, 0, 275, 488, SWP_NOREPOSITION);
SetWindowPos(p.MainWindowHandle, (IntPtr)HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
Thread.Sleep(500);
SetParent(p.MainWindowHandle, this.Handle);
myPanel.Controls.Add(button1);
myPanel.Width = 275;
myPanel.Height = 30;
myPanel.Top = 0;
this.Controls.Add(myPanel);
myPanel.BringToFront();
SetParent(this.Handle, myPanel.Handle);
SetWindowPos(myPanel.Handle, (IntPtr)HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
}
private void button1_Click(object sender, EventArgs e)
{
}
private void Form1_Layout(object sender, LayoutEventArgs e)
{
myPanel.BringToFront();
}
private System.Timers.Timer timer1;
public void InitTimer()
{
timer1 = new System.Timers.Timer(2000);
timer1.Elapsed += new ElapsedEventHandler(timer1_Tick);
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e) {
button1.BringToFront();
}
}
}

Related

winForm has no border shadow

I want to create a blank border shadow form, and want to keep WS_MINIMIZEBOX | WS_SIZEBOX | WS_CAPTION these three style style window use rise more convenient.
Currently used DwmExtendFrameIntoClientArea to create shaded part. The shadow effect is present when the window is first created
But after minimizing, the shadow effect is gone
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApp1
{
public partial class Form1 : BorderlessForm.FormBase
{
[DllImport("dwmapi.dll")]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
public Form1()
{
InitializeComponent();
}
public enum WindowMessages
{
WM_NULL = 0x0000,
WM_CREATE = 0x0001,
WM_DESTROY = 0x0002,
WM_MOVE = 0x0003,
WM_SIZE = 0x0005,
WM_ACTIVATE = 0x0006,
WM_SETFOCUS = 0x0007,
WM_KILLFOCUS = 0x0008,
WM_ENABLE = 0x000A,
WM_SETREDRAW = 0x000B,
WM_SETTEXT = 0x000C,
WM_GETTEXT = 0x000D,
WM_GETTEXTLENGTH = 0x000E,
WM_PAINT = 0x000F,
WM_CLOSE = 0x0010,
WM_QUIT = 0x0012,
WM_ERASEBKGND = 0x0014,
WM_SYSCOLORCHANGE = 0x0015,
WM_SHOWWINDOW = 0x0018,
WM_ACTIVATEAPP = 0x001C,
WM_SETCURSOR = 0x0020,
WM_MOUSEACTIVATE = 0x0021,
WM_GETMINMAXINFO = 0x24,
WM_WINDOWPOSCHANGING = 0x0046,
WM_WINDOWPOSCHANGED = 0x0047,
WM_CONTEXTMENU = 0x007B,
WM_STYLECHANGING = 0x007C,
WM_STYLECHANGED = 0x007D,
WM_DISPLAYCHANGE = 0x007E,
WM_GETICON = 0x007F,
WM_SETICON = 0x0080,
// non client area
WM_NCCREATE = 0x0081,
WM_NCDESTROY = 0x0082,
WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x84,
WM_NCPAINT = 0x0085,
WM_NCACTIVATE = 0x0086,
WM_GETDLGCODE = 0x0087,
WM_SYNCPAINT = 0x0088,
// non client mouse
WM_NCMOUSEMOVE = 0x00A0,
WM_NCLBUTTONDOWN = 0x00A1,
WM_NCLBUTTONUP = 0x00A2,
WM_NCLBUTTONDBLCLK = 0x00A3,
WM_NCRBUTTONDOWN = 0x00A4,
WM_NCRBUTTONUP = 0x00A5,
WM_NCRBUTTONDBLCLK = 0x00A6,
WM_NCMBUTTONDOWN = 0x00A7,
WM_NCMBUTTONUP = 0x00A8,
WM_NCMBUTTONDBLCLK = 0x00A9,
// keyboard
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
WM_CHAR = 0x0102,
WM_SYSCOMMAND = 0x0112,
// menu
WM_INITMENU = 0x0116,
WM_INITMENUPOPUP = 0x0117,
WM_MENUSELECT = 0x011F,
WM_MENUCHAR = 0x0120,
WM_ENTERIDLE = 0x0121,
WM_MENURBUTTONUP = 0x0122,
WM_MENUDRAG = 0x0123,
WM_MENUGETOBJECT = 0x0124,
WM_UNINITMENUPOPUP = 0x0125,
WM_MENUCOMMAND = 0x0126,
WM_CHANGEUISTATE = 0x0127,
WM_UPDATEUISTATE = 0x0128,
WM_QUERYUISTATE = 0x0129,
// mouse
WM_MOUSEFIRST = 0x0200,
WM_MOUSEMOVE = 0x0200,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_LBUTTONDBLCLK = 0x0203,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205,
WM_RBUTTONDBLCLK = 0x0206,
WM_MBUTTONDOWN = 0x0207,
WM_MBUTTONUP = 0x0208,
WM_MBUTTONDBLCLK = 0x0209,
WM_MOUSEWHEEL = 0x020A,
WM_MOUSELAST = 0x020D,
WM_ENTERMENULOOP = 0x0211,
WM_EXITMENULOOP = 0x0212,
WM_NEXTMENU = 0x0213,
WM_SIZING = 0x0214,
WM_CAPTURECHANGED = 0x0215,
WM_MOVING = 0x0216,
WM_ENTERSIZEMOVE = 0x0231,
WM_EXITSIZEMOVE = 0x0232,
WM_MOUSELEAVE = 0x02A3,
WM_MOUSEHOVER = 0x02A1,
WM_NCMOUSEHOVER = 0x02A0,
WM_NCMOUSELEAVE = 0x02A2,
WM_MDIACTIVATE = 0x0222,
WM_HSCROLL = 0x0114,
WM_VSCROLL = 0x0115,
WM_SYSMENU = 0x313,
WM_PRINT = 0x0317,
WM_PRINTCLIENT = 0x0318,
}
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public static RECT FromXYWH(int x, int y, int width, int height)
{
return new RECT(x,
y,
x + width,
y + height);
}
}
internal struct WINDOWPOS
{
internal IntPtr hwnd;
internal IntPtr hWndInsertAfter;
internal int x;
internal int y;
internal int cx;
internal int cy;
internal uint flags;
}
public struct POINTS
{
public short X;
public short Y;
}
public enum WindowStyle
{
WS_MAXIMIZE = 0x01000000,
WS_MINIMIZE = 0x20000000,
}
public struct APPBARDATA
{
public int cbSize; // initialize this field using: Marshal.SizeOf(typeof(APPBARDATA));
public IntPtr hWnd;
public uint uCallbackMessage;
public uint uEdge;
public RECT rc;
public int lParam;
}
public struct MARGINS
{
public int left;
public int right;
public int top;
public int bottom;
}
public static class NativeMethods
{
[DllImport("user32.dll")]
public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
[DllImport("user32.dll")]
public static extern int GetWindowRgn(IntPtr hWnd, IntPtr hRgn);
[DllImport("gdi32.dll")]
public static extern int GetRgnBox(IntPtr hrgn, out RECT lprc);
[DllImport("user32.dll")]
public static extern Int32 GetWindowLong(IntPtr hWnd, Int32 Offset);
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int smIndex);
[DllImport("shell32.dll")]
public static extern int SHAppBarMessage(uint dwMessage, [In] ref APPBARDATA pData);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObj);
}
public static class NativeConstants
{
public const int SM_CXSIZEFRAME = 32;
public const int SM_CYSIZEFRAME = 33;
public const int SM_CXPADDEDBORDER = 92;
public const int GWL_ID = (-12);
public const int GWL_STYLE = (-16);
public const int GWL_EXSTYLE = (-20);
public const int WM_NCLBUTTONDOWN = 0x00A1;
public const int WM_NCRBUTTONUP = 0x00A5;
public const uint TPM_LEFTBUTTON = 0x0000;
public const uint TPM_RIGHTBUTTON = 0x0002;
public const uint TPM_RETURNCMD = 0x0100;
public static readonly IntPtr TRUE = new IntPtr(1);
public static readonly IntPtr FALSE = new IntPtr(0);
public const uint ABM_GETSTATE = 0x4;
public const int ABS_AUTOHIDE = 0x1;
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case (int)WindowMessages.WM_NCCALCSIZE:
{
WmNCCalcSize(ref m);
break;
}
case (int)WindowMessages.WM_NCACTIVATE:
{
WmNCActivate(ref m);
break;
}
case (int)WindowMessages.WM_WINDOWPOSCHANGED:
{
WmWindowPosChanged(ref m);
break;
}
default:
{
base.WndProc(ref m);
break;
}
}
}
private void SetWindowRegion(IntPtr hwnd, int left, int top, int right, int bottom)
{
var rgn = NativeMethods.CreateRectRgn(0, 0, 0, 0);
var hrg = new HandleRef((object)this, rgn);
var r = NativeMethods.GetWindowRgn(hwnd, hrg.Handle);
RECT box;
NativeMethods.GetRgnBox(hrg.Handle, out box);
if (box.left != left || box.top != top || box.right != right || box.bottom != bottom)
{
var hr = new HandleRef((object)this, NativeMethods.CreateRectRgn(left, top, right, bottom));
NativeMethods.SetWindowRgn(hwnd, hr.Handle, NativeMethods.IsWindowVisible(hwnd));
}
NativeMethods.DeleteObject(rgn);
}
private FormWindowState MinMaxState
{
get
{
var s = NativeMethods.GetWindowLong(Handle, NativeConstants.GWL_STYLE);
var max = (s & (int)WindowStyle.WS_MAXIMIZE) > 0;
if (max) return FormWindowState.Maximized;
var min = (s & (int)WindowStyle.WS_MINIMIZE) > 0;
if (min) return FormWindowState.Minimized;
return FormWindowState.Normal;
}
}
private void WmWindowPosChanged(ref Message m)
{
DefWndProc(ref m);
UpdateBounds();
var pos = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
SetWindowRegion(m.HWnd, 0, 0, pos.cx, pos.cy);
m.Result = NativeConstants.TRUE;
}
private void WmNCCalcSize(ref Message m)
{
var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
var max = MinMaxState == FormWindowState.Maximized;
if (max)
{
var x = NativeMethods.GetSystemMetrics(NativeConstants.SM_CXSIZEFRAME);
var y = NativeMethods.GetSystemMetrics(NativeConstants.SM_CYSIZEFRAME);
var p = NativeMethods.GetSystemMetrics(NativeConstants.SM_CXPADDEDBORDER);
var w = x + p;
var h = y + p;
r.left += w;
r.top += h;
r.right -= w;
r.bottom -= h;
var appBarData = new APPBARDATA();
appBarData.cbSize = Marshal.SizeOf(typeof(APPBARDATA));
var autohide = (NativeMethods.SHAppBarMessage(NativeConstants.ABM_GETSTATE, ref appBarData) & NativeConstants.ABS_AUTOHIDE) != 0;
if (autohide) r.bottom -= 1;
Marshal.StructureToPtr(r, m.LParam, true);
}
m.Result = IntPtr.Zero;
}
private void WmNCActivate(ref Message msg)
{
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowmessages/wm_ncactivate.asp
bool active = (msg.WParam == NativeConstants.TRUE);
if (MinMaxState == FormWindowState.Minimized)
DefWndProc(ref msg);
else
{
// repaint title bar
//PaintNonClientArea(msg.HWnd, (IntPtr)1);
// allow to deactivate window
msg.Result = NativeConstants.TRUE;
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
const int WS_MINIMIZEBOX = 0x00020000;
const int WS_SIZEBOX = 0x00040000;
const int WS_CAPTION = 0x00C00000;
cp.Style = cp.Style | WS_MINIMIZEBOX | WS_SIZEBOX | WS_CAPTION;
return cp;
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (!DesignMode)
SetWindowRegion(Handle, 0, 0, Width, Height);
}
private void DrawShadow(int ShadowWidth)
{
var v = 2;
DwmSetWindowAttribute(Handle, 2, ref v, 4);
var margins = new MARGINS
{
top = ShadowWidth,
left = ShadowWidth,
right = ShadowWidth,
bottom = ShadowWidth
};
DwmExtendFrameIntoClientArea(Handle, ref margins);
}
private void Form1_Load(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.None;
DrawShadow(10);
}
}
}
This is my code, I was hoping you could help me point out the code error or give me an idea
I really want to shadow and WS_SIZEBOX, WS_CAPTION style
How can I get what I want? Thank you again

Scrollbar reverts to previous position

I am using an auxiliary Scrollbar to do some manual scrolling. I use the GetScrollInfo API to get the track position of the Scrollbar. However, when scrolling ends, the track position reverts to its last set position. So, I use the SetScrollInfo API to set the scroll info after scroll end, but then it only updates visually after a mouse move. What can I do to fix this issue?
ScrollUtility:
public class ScrollUtility
{
[DllImportAttribute("user32.dll")]
[PreserveSigAttribute()]
public static extern int SetScrollInfo(
IntPtr hWnd,
int fnBar,
ref SCROLLINFO si,
bool redraw
);
[DllImport("user32.dll")]
[PreserveSigAttribute()]
public static extern bool GetScrollInfo(
IntPtr hwnd,
int fnBar,
ref SCROLLINFO ScrollInfo
);
}
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct SCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos; // Ignored by setter
public override string ToString()
{
return cbSize + " " + fMask + " " + nMin + " " + nMax + " " + nPage + " " + nPos + " " + nTrackPos;
}
public const int SB_HORZ = 0x0000;
public const int SB_VERT = 0x0001;
public const int WM_HSCROLL = 0x0114;
public const int WM_VSCROLL = 0x0115;
public const int SB_THUMBPOSITION = 4;
public enum ScrollInfoMask : uint
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
}
}
Form1:
public partial class Form1 : Form
{
private bool setOnStartUp = true; // Track position will not update if this is false
private bool setOnEndScroll = true; // Track position reverts to last set position if this is false, but still doesn't update visually if this is true until the mouse moves.
public Form1()
{
InitializeComponent();
if (setOnStartUp)
{
SCROLLINFO info = new SCROLLINFO
{
cbSize = (uint)Marshal.SizeOf(typeof(SCROLLINFO)),
fMask = (uint)SCROLLINFO.ScrollInfoMask.SIF_ALL,
nMax = 1000,
nMin = 0,
nPage = 50,
nPos = 500, // The middle of the scroll bar - just for testing
};
// Am I using the right handle?
ScrollUtility.SetScrollInfo(vScrollBar.Handle, SCROLLINFO.SB_VERT, ref info, true);
}
}
private void vScrollBar_Scroll(object sender, ScrollEventArgs e)
{
SCROLLINFO info = new SCROLLINFO
{
cbSize = (uint)Marshal.SizeOf(typeof(SCROLLINFO)),
fMask = (uint)SCROLLINFO.ScrollInfoMask.SIF_ALL
};
ScrollUtility.GetScrollInfo(vScrollBar.Handle, SCROLLINFO.SB_VERT, ref info);
label.Text = "Track: " + info.nTrackPos;
if (setOnEndScroll)
{
if (e.Type == ScrollEventType.EndScroll)
{
info.nPos = info.nTrackPos;
ScrollUtility.SetScrollInfo(vScrollBar.Handle, SCROLLINFO.SB_VERT, ref info, true);
}
}
}
}

C# / WPF: Get icons used by shell

I'm trying to develop an application that can show you the content of directories like the Windows Explorer (with file name and icon). I'm currently using this code:
public class IconManager
{
public static ImageSource GetIcon(string path, bool smallIcon, bool isDirectory)
{
uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
if (smallIcon)
flags |= SHGFI_SMALLICON;
uint attributes = FILE_ATTRIBUTE_NORMAL;
if (isDirectory)
attributes |= FILE_ATTRIBUTE_DIRECTORY;
SHFILEINFO shfi;
if (0 != SHGetFileInfo(path, attributes, out shfi, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), flags))
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
return null;
}
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[DllImport("shell32")]
private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);
private const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040;
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000;
private const uint SHGFI_ICON = 0x000000100;
private const uint SHGFI_DISPLAYNAME = 0x000000200;
private const uint SHGFI_TYPENAME = 0x000000400;
private const uint SHGFI_ATTRIBUTES = 0x000000800;
private const uint SHGFI_ICONLOCATION = 0x000001000;
private const uint SHGFI_EXETYPE = 0x000002000;
private const uint SHGFI_SYSICONINDEX = 0x000004000;
private const uint SHGFI_LINKOVERLAY = 0x000008000;
private const uint SHGFI_SELECTED = 0x000010000;
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000;
private const uint SHGFI_LARGEICON = 0x000000000;
private const uint SHGFI_SMALLICON = 0x000000001;
private const uint SHGFI_OPENICON = 0x000000002;
private const uint SHGFI_SHELLICONSIZE = 0x000000004;
private const uint SHGFI_PIDL = 0x000000008;
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
}
I use this code to get the files and directories with their icons:
foreach (string d in Directory.GetDirectories(Path))
{
string name = "";
foreach (string p in d.Split('\\'))
name = p;
ImageSource icon = IconManager.GetIcon(d + "\\", false, true);
colDesktopItems.Add(new DesktopItem() { ItemName = name, ItemPath = d });
}
foreach (string f in Directory.GetFiles(Path))
{
if (File.GetAttributes(f) != FileAttributes.Hidden && File.GetAttributes(f) != FileAttributes.System)
{
string name = "";
foreach (string p in f.Split('\\'))
if (p.Contains("."))
name = p;
ImageSource icon = IconManager.GetIcon(f, false, false);
if (name != "desktop.ini" && name != "Thumbs.db")
colDesktopItems.Add(new DesktopItem() { ItemName = name.Split('.')[0], ItemPath = f, ItemIcon = icon });
}
}
I also use a DispatcherTimer for automatic refresh (interval = 5 seconds):
private void dpt_Tick(object sender, EventArgs e)
{
if (dPath != null)
{
if (GetContent(dPath).ToString() != diCollection.ToString())
{
diCollection.Clear();
foreach (DesktopItem i in GetContent(dPath))
diCollection.Add(i);
}
}
}
diCollection is the collection that contains the elements to display and dPath is the path of the directory from which the files will be displayed.
But there are two problems:
When I set isDirectory to true, it just returns an empty icon.
After a while, it throws an exception:
The value may not be NULL.
The exception happens in this line:
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
i use the same methodology. Here is how i have mine set up in my personal library.
public static class ImageUtilities
{
public static System.Drawing.Icon GetRegisteredIcon(string filePath)
{
var shinfo = new SHfileInfo();
Win32.SHGetFileInfo(filePath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON);
return System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SHfileInfo
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
internal sealed class Win32
{
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // large
public const uint SHGFI_SMALLICON = 0x1; // small
[System.Runtime.InteropServices.DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHfileInfo psfi, uint cbSizeFileInfo, uint uFlags);
}
Usage:
var icon = ImageUtilites.GetRegisteredIcon(string path)
the Extension method i use to make create an ImageSource for WPF:
public static System.Windows.Media.ImageSource ToImageSource(this System.Drawing.Bitmap bitmap, int width, int height)
{
var hBitmap = bitmap.GetHbitmap();
System.Windows.Media.ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight(width, height));
if (!DeleteObject(hBitmap))
{
throw new System.ComponentModel.Win32Exception();
}
return wpfBitmap;
}
I forgot to add this, I don't know if you are utilizing it..
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);

How can I use automation to right-click with a mouse in Windows 7?

I've spent a while getting my mouse to be able to right-click in Windows XP. Here's the code:
public class Mouse
{
[DllImport("user32.dll", SetLastError = true)]
internal static extern uint SendInput(uint numberOfInputs, Input[] inputs, int sizeOfInputStructure);
private const int RightDown = 0x0008;
private const int RightUp = 0x0010;
private const int InputMouse = 0;
public void RightClick<T>(T element) where T: AutomationElementWrapper
{
var point = element.Element.GetClickablePoint();
var processId = element.Element.GetCurrentPropertyValue(AutomationElement.ProcessIdProperty);
var window = AutomationElement.RootElement.FindFirst(
TreeScope.Children,
new PropertyCondition(AutomationElement.ProcessIdProperty,
processId));
window.SetFocus();
var x = (int)point.X;
var y = (int)point.Y;
System.Windows.Forms.Cursor.Position = new System.Drawing.Point(x, y);
SendInput(2, new[] {InputFor(RightDown, x, y), InputFor(RightUp, x, y)}, Marshal.SizeOf(typeof (Input)));
}
private static Input InputFor(uint mouseButtonAction, int x, int y)
{
var input = new Input
{
Dx = x,
Dy = y,
MouseData = 0,
DwFlags = mouseButtonAction,
Time = 0,
DwType = InputMouse,
MouseExtraInfo = new IntPtr()
};
return input;
}
internal struct Input
{
public int DwType;
public int Dx;
public int Dy;
public uint MouseData;
public uint DwFlags;
public uint Time;
public IntPtr MouseExtraInfo;
}
}
This doesn't work in Windows 7. Why not, and how do I fix it?
For more information, I'm using this in an automation tool to bring up a context menu.
Edit: #GSerg's link looks helpful. I'm not sure what goes in the "type" field of the input once you've added the union, though - I left it blank, and now this causes my screensaver to come on. Ah, the joys of Win32. Any help appreciated.
Here's my attempt at a solution - this test program combines the code from the opening question, the pinvoke.net SendInput page, and the oldnewthing 64-bit structure alignment workaround linked to by GSerg.
With this, right-clicking works for me on Win7 x64:
using System;
using System.Runtime.InteropServices;
using System.Windows.Automation;
using WiPFlash;
using WiPFlash.Components;
using WiPFlash.Framework;
using WiPFlash.Util;
using WiPFlash.Exceptions;
using NUnit.Framework;
namespace MouseRightClick
{
class Program
{
static void Main(string[] args)
{
Application application = new ApplicationLauncher(TimeSpan.Parse("00:00:20"))
.LaunchOrRecycle("foo", #"C:\\hg\\wipflash\\Example.PetShop\\bin\\Debug\\Example.PetShop.exe", Assert.Fail);
var window = application.FindWindow("petShopWindow");
var totalLabel = window.Find<Label>("copyPetContextTarget");
Mouse mouse = new Mouse();
mouse.RightClick(totalLabel);
}
}
public class Mouse
{
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
private const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
private const int MOUSEEVENTF_RIGHTUP = 0x0010;
private const int INPUT_MOUSE = 0;
private const int INPUT_KEYBOARD = 1;
private const int INPUT_HARDWARE = 2;
public void RightClick<T>(T element) where T : AutomationElementWrapper
{
var point = element.Element.GetClickablePoint();
var processId = element.Element.GetCurrentPropertyValue(AutomationElement.ProcessIdProperty);
var window = AutomationElement.RootElement.FindFirst(
TreeScope.Children,
new PropertyCondition(AutomationElement.ProcessIdProperty,
processId));
window.SetFocus();
var x = (int)point.X;
var y = (int)point.Y;
System.Windows.Forms.Cursor.Position = new System.Drawing.Point(x, y);
SendInput(2, new[] {
InputFor(MOUSEEVENTF_RIGHTDOWN, x, y),
InputFor(MOUSEEVENTF_RIGHTUP, x, y) },
Marshal.SizeOf(typeof(INPUT)));
}
private static INPUT InputFor(uint mouseButtonAction, int x, int y)
{
var input = new INPUT();
input.type = INPUT_MOUSE;
input.u.mi.dwFlags = mouseButtonAction;
input.u.mi.time = 0;
input.u.mi.dwExtraInfo = IntPtr.Zero;
return input;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
public uint uMsg;
public ushort wParamL;
public ushort wParamH;
}
[StructLayout(LayoutKind.Explicit)]
internal struct INPUT_UNION
{
[FieldOffset(0)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
};
[StructLayout(LayoutKind.Sequential)]
internal struct INPUT
{
public int type;
public INPUT_UNION u;
}
}
}

C# audio recording using winmm.dll native code

Please let me know how could i record and save audio file to my hard drive by using c# code.
I already downloaded code from one of the technical web page.
That may be i don't know enough that it can support recording and saving function as well.
Please let me show you some of my downloaded Code so that you can give me any suggestion how should i do.
[WaveIn.CS]
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace SoundViewer
{
internal class WaveInHelper
{
public static void Try(int err)
{
if (err != WaveNative.MMSYSERR_NOERROR)
throw new Exception(err.ToString());
}
}
public delegate void BufferDoneEventHandler(IntPtr data, int size);
internal class WaveInBuffer : IDisposable
{
public WaveInBuffer NextBuffer;
private AutoResetEvent m_RecordEvent = new AutoResetEvent(false);
private IntPtr m_WaveIn;
private WaveNative.WaveHdr m_Header;
private byte[] m_HeaderData;
private GCHandle m_HeaderHandle;
private GCHandle m_HeaderDataHandle;
private bool m_Recording;
internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WIM_DATA)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveInBuffer buf = (WaveInBuffer)h.Target;
buf.OnCompleted();
}
catch
{
}
}
}
public WaveInBuffer(IntPtr waveInHandle, int size)
{
m_WaveIn = waveInHandle;
m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);
m_HeaderData = new byte[size];
m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned);
m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject();
m_Header.dwBufferLength = size;
WaveInHelper.Try(WaveNative.waveInPrepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)));
}
~WaveInBuffer()
{
Dispose();
}
public void Dispose()
{
if (m_Header.lpData != IntPtr.Zero)
{
WaveNative.waveInUnprepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header));
m_HeaderHandle.Free();
m_Header.lpData = IntPtr.Zero;
}
m_RecordEvent.Close();
if (m_HeaderDataHandle.IsAllocated)
m_HeaderDataHandle.Free();
GC.SuppressFinalize(this);
}
public int Size
{
get { return m_Header.dwBufferLength; }
}
public IntPtr Data
{
get { return m_Header.lpData; }
}
public bool Record()
{
lock(this)
{
m_RecordEvent.Reset();
m_Recording = WaveNative.waveInAddBuffer(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)) == WaveNative.MMSYSERR_NOERROR;
System.Diagnostics.Debug.Write(string.Format("\n m_WaveIn: {0}, m_Header.dwBytesRecorded: {1}", m_WaveIn, m_Header.dwBytesRecorded));
//m_WaveIn.ToPointer();
return m_Recording;
}
}
public void WaitFor()
{
if (m_Recording)
m_Recording = m_RecordEvent.WaitOne();
else
Thread.Sleep(0);
}
private void OnCompleted()
{
m_RecordEvent.Set();
m_Recording = false;
}
}
public class WaveInRecorder : IDisposable
{
private IntPtr m_WaveIn;
private WaveInBuffer m_Buffers; // linked list
private WaveInBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferDoneEventHandler m_DoneProc;
private bool m_Finished;
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc);
public static int DeviceCount
{
get { return WaveNative.waveInGetNumDevs(); }
}
public WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc)
{
m_DoneProc = doneProc;
WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
AllocateBuffers(bufferSize, bufferCount);
for (int i = 0; i < bufferCount; i++)
{
SelectNextBuffer();
m_CurrentBuffer.Record();
}
WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn));
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
}
public void Recording()
{
//int rawsize = Marshal.SizeOf(m_WaveIn);
//byte[] rawdata = new byte[256 * 1024];
////Marshal.Copy(m_WaveIn, rawdata, 0, rawsize);
////System.IO.File.WriteAllBytes(string.Format("C:\\TempImage\\audio_{0}.wav", Guid.NewGuid()), rawdata );
//Marshal.Copy(rawdata, 0, m_WaveIn, rawdata.Length);
////System.IO.File.WriteAllBytes(string.Format("C:\\TempImage\\audio_{0}.wav", Guid.NewGuid()), rawdata);
////Marshal.FreeHGlobal(m_WaveIn);
//System.IO.MemoryStream ms = new System.IO.MemoryStream(
//int elementSize = Marshal.SizeOf(typeof(IntPtr));
//System.Diagnostics.Debug.Print("Reading unmanaged memory:");
//// Print the 10 elements of the C-style unmanagedArray
//for (int i = 0; i < 10; i++)
//{
// System.Diagnostics.Debug.Print(Marshal.ReadIntPtr(m_WaveIn, i * elementSize));
//}
}
~WaveInRecorder()
{
Dispose();
}
public void Dispose()
{
if (m_Thread != null)
try
{
m_Finished = true;
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInReset(m_WaveIn);
WaitForAllBuffers();
m_Thread.Join();
m_DoneProc = null;
FreeBuffers();
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInClose(m_WaveIn);
}
finally
{
m_Thread = null;
m_WaveIn = IntPtr.Zero;
}
GC.SuppressFinalize(this);
}
private void ThreadProc()
{
while (!m_Finished)
{
Advance();
if (m_DoneProc != null && !m_Finished)
m_DoneProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size);
m_CurrentBuffer.Record();
}
}
private void AllocateBuffers(int bufferSize, int bufferCount)
{
FreeBuffers();
if (bufferCount > 0)
{
m_Buffers = new WaveInBuffer(m_WaveIn, bufferSize);
WaveInBuffer Prev = m_Buffers;
try
{
for (int i = 1; i < bufferCount; i++)
{
WaveInBuffer Buf = new WaveInBuffer(m_WaveIn, bufferSize);
Prev.NextBuffer = Buf;
Prev = Buf;
}
}
finally
{
Prev.NextBuffer = m_Buffers;
}
}
}
private void FreeBuffers()
{
m_CurrentBuffer = null;
if (m_Buffers != null)
{
WaveInBuffer First = m_Buffers;
m_Buffers = null;
WaveInBuffer Current = First;
do
{
WaveInBuffer Next = Current.NextBuffer;
Current.Dispose();
Current = Next;
} while(Current != First);
}
}
private void Advance()
{
SelectNextBuffer();
m_CurrentBuffer.WaitFor();
}
private void SelectNextBuffer()
{
m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer;
}
private void WaitForAllBuffers()
{
WaveInBuffer Buf = m_Buffers;
while (Buf.NextBuffer != m_Buffers)
{
Buf.WaitFor();
Buf = Buf.NextBuffer;
}
}
}
}
[WaveNative.cs]
internal class WaveNative
{
// consts
public const int MMSYSERR_NOERROR = 0; // no error
public const int MM_WOM_OPEN = 0x3BB;
public const int MM_WOM_CLOSE = 0x3BC;
public const int MM_WOM_DONE = 0x3BD;
public const int MM_WIM_OPEN = 0x3BE;
public const int MM_WIM_CLOSE = 0x3BF;
public const int MM_WIM_DATA = 0x3C0;
public const int CALLBACK_FUNCTION = 0x00030000; // dwCallback is a FARPROC
public const int TIME_MS = 0x0001; // time in milliseconds
public const int TIME_SAMPLES = 0x0002; // number of wave samples
public const int TIME_BYTES = 0x0004; // current byte offset
// callbacks
public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);
// structs
[StructLayout(LayoutKind.Sequential)] public struct WaveHdr
{
public IntPtr lpData; // pointer to locked data buffer
public int dwBufferLength; // length of data buffer
public int dwBytesRecorded; // used for input only
public IntPtr dwUser; // for client's use
public int dwFlags; // assorted flags (see defines)
public int dwLoops; // loop control counter
public IntPtr lpNext; // PWaveHdr, reserved for driver
public int reserved; // reserved for driver
}
private const string mmdll = "winmm.dll";
// WaveOut calls
[DllImport(mmdll)]
public static extern int waveOutGetNumDevs();
[DllImport(mmdll)]
public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveOutReset(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutClose(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutPause(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutRestart(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
[DllImport(mmdll)]
public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
[DllImport(mmdll)]
public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);
// WaveIn calls
[DllImport(mmdll)]
public static extern int waveInGetNumDevs();
[DllImport(mmdll)]
public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, int cbwh);
[DllImport(mmdll)]
public static extern int waveInClose(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInReset(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStart(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStop(IntPtr hwi);
}

Categories

Resources