Value does not fall within expected range for dwmapi.dll - c#

"Value does not fall withing expected range" error appears when I run my program with aero glass. I am using the dwmapi.dll. This is the code:
ON Aero.cs
[StructLayout(LayoutKind.Sequential)]
public struct Margins
{
public int Left;
public int Right;
public int Top;
public int Bottom;
}
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref Margins margins);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern bool DwmIsCompositionEnabled();
ON AddStudent.cs
private const int PaddingCounter = 0;
private Aero.Margins _newMargins;
private void SetGlassArea()
{
if (Aero.DwmIsCompositionEnabled())
{
_newMargins.Top = Padding.Top;
_newMargins.Bottom = Padding.Bottom;
_newMargins.Left = Padding.Left;
_newMargins.Right = Padding.Right;
Aero.DwmExtendFrameIntoClientArea(this.Handle, ref _newMargins);
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaint(e);
if (Aero.DwmIsCompositionEnabled())
{
e.Graphics.Clear(Color.Black);
Rectangle clientArea = new Rectangle(_newMargins.Left, _newMargins.Top, this.ClientRectangle.Width - _newMargins.Left -_newMargins.Right,
this.ClientRectangle.Height - _newMargins.Top - _newMargins.Bottom);
Brush b = new SolidBrush(this.BackColor);
e.Graphics.FillRectangle(b, clientArea);
}
}
public void ApplyGlassSurface()
{
this.Padding = new Padding(PaddingCounter);
SetGlassArea();
Invalidate();
}
private void AddStudent_Load(object sender, EventArgs e)
{
ApplyGlassSurface();
webcam = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo videoCaptureDevice in webcam)
{
comboBoxEx1.Items.Add(videoCaptureDevice.Name);
}
comboBoxEx1.SelectedIndex = 0;
}
The error points to:
Aero.DwmExtendFrameIntoClientArea(this.Handle, ref _newMargins);
Can you please tell me what is wrong with it? I know it should work because I've seen a video and it worked for him. Thanks!

Maybe change DwmExtendFrameIntoClientArea PreserveSig to true.
And change Margins to:
[StructLayout(LayoutKind.Sequential)]
public struct Margins
{
public int leftWidth;
public int rightWidth;
public int topHeight;
public int bottomHeight;
}

Related

Border-less winform form shadow

I have a border-less windows form that i created a shadow behind it using the code below.
However when I click on the parent form the shadow disappears.
can anyone help me out on how to keep the shadow even when clicking on anther form/parent form?
The shaddow is visable against a diffrent window (chrome for example) but not against it's parent form
(I tried google but couldn't find anything)
Update
I do notice that if i minimize the window and maximize it again the shadow does come back
My Code
private const int CS_DROPSHADOW = 0x00020000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
Thanks in advance
Pls try the below steps and revert back for any errors:
Add the below code to a new code file named DropShadow.cs;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Core
{
public class DropShadow
{
#region Shadowing
#region Fields
private bool _isAeroEnabled = false;
private bool _isDraggingEnabled = false;
private const int WM_NCHITTEST = 0x84;
private const int WS_MINIMIZEBOX = 0x20000;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
private const int CS_DBLCLKS = 0x8;
private const int CS_DROPSHADOW = 0x00020000;
private const int WM_NCPAINT = 0x0085;
private const int WM_ACTIVATEAPP = 0x001C;
#endregion
#region Structures
[EditorBrowsable(EditorBrowsableState.Never)]
public struct MARGINS
{
public int leftWidth;
public int rightWidth;
public int topHeight;
public int bottomHeight;
}
#endregion
#region Methods
#region Public
[DllImport("dwmapi.dll")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
[DllImport("dwmapi.dll")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[DllImport("dwmapi.dll")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool IsCompositionEnabled()
{
if (Environment.OSVersion.Version.Major < 6) return false;
bool enabled;
DwmIsCompositionEnabled(out enabled);
return enabled;
}
#endregion
#region Private
[DllImport("dwmapi.dll")]
private static extern int DwmIsCompositionEnabled(out bool enabled);
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect,
int nWidthEllipse,
int nHeightEllipse
);
private bool CheckIfAeroIsEnabled()
{
if (Environment.OSVersion.Version.Major >= 6)
{
int enabled = 0;
DwmIsCompositionEnabled(ref enabled);
return (enabled == 1) ? true : false;
}
return false;
}
#endregion
#region Overrides
public void ApplyShadows(Form form)
{
var v = 2;
DwmSetWindowAttribute(form.Handle, 2, ref v, 4);
MARGINS margins = new MARGINS()
{
bottomHeight = 1,
leftWidth = 0,
rightWidth = 0,
topHeight = 0
};
DwmExtendFrameIntoClientArea(form.Handle, ref margins);
}
#endregion
#endregion
#endregion
}
}
In your form, add this line below InitializeComponent();
(new Core.DropShadow()).ApplyShadows(this);

C# modify console font, font size at runtime?

I'm in the process of creating a rougelike and to assure my game displays correctly I am wanting to change the console font and font size at runtime.
I am very noob to programming and c# so I'm hoping this can be explained in a way I or anyone else can easily implement.
This resource list the full syntax of the CONSOLE_FONT_INFOEX structure:
typedef struct _CONSOLE_FONT_INFOEX {
ULONG cbSize;
DWORD nFont;
COORD dwFontSize;
UINT FontFamily;
UINT FontWeight;
WCHAR FaceName[LF_FACESIZE];
} CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX;
Specifically I'm wanting to change the console font to NSimSum and font size to 32 at runtime.
EDIT 1: Could I have it explained how to use the SetCurrentConsoleFontEx function from this post. I don't understand what context the function needs to be in. I tried Console.SetCurrentConsoleFontEx but vs gave me no options.
EDIT 2: this forum post seems to detail a simple method of changing font size but is it specific to c++?
void setFontSize(int FontSize)
{
CONSOLE_FONT_INFOEX info = {0};
info.cbSize = sizeof(info);
info.dwFontSize.Y = FontSize; // leave X as zero
info.FontWeight = FW_NORMAL;
wcscpy(info.FaceName, L"Lucida Console");
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), NULL, &info);
}
Another alternative that you might look into is to create a winforms app and use a RichTextBox instead. I guess it depends on how much you need to rely on any built-in console features.
Notice the use of some custom functions to make writing colored text easier.
You can try out something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
RichTextBox console = new RichTextBox();
private void Form1_Load(object sender, EventArgs e)
{
console.Size = this.ClientSize;
console.Top = 0;
console.Left = 0;
console.BackColor = Color.Black;
console.ForeColor = Color.White;
console.WordWrap = false;
console.Font = new Font("Consolas", 12);
this.Controls.Add(console);
this.Resize += Form1_Resize;
DrawDiagram();
}
private void DrawDiagram()
{
WriteLine("The djinni speaks. \"I am in your debt. I will grant one wish!\"--More--\n");
Dot(7);
Diamond(2);
WriteLine("....╔═══════╗..╔═╗");
Dot(8);
Diamond(2);
WriteLine("...║..|....║..║.╠══════╦══════╗");
Dot(9);
Diamond(2);
Write("..║.|.....║..║.║ ║.");
Write('&', Color.DarkRed);
Dot(4);
WriteLine("║");
}
private void Dot(int qty)
{
Write('.', qty);
}
private void WriteLine(string text)
{
Write($"{text}\n");
}
private void Diamond(int qty)
{
Write('♦', qty, Color.Blue);
}
private void Write(char character, Color color)
{
Write(character, 1, color);
}
private void Write(char character, int qty)
{
Write(character, qty, Color.White);
}
private void Write(char character, int qty, Color color)
{
Write(new string(character, qty), color);
}
private void Write(string text)
{
Write(text, Color.White);
}
private void Write(string text, Color color)
{
var originalColor = console.SelectionColor;
console.SelectionColor = color;
console.AppendText(text);
console.SelectionColor = originalColor;
}
private void Form1_Resize(object sender, EventArgs e)
{
console.Size = this.ClientSize;
}
}
Output
Have you tried this
using System;
using System.Runtime.InteropServices;
public class Example
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool GetCurrentConsoleFontEx(
IntPtr consoleOutput,
bool maximumWindow,
ref CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetCurrentConsoleFontEx(
IntPtr consoleOutput,
bool maximumWindow,
CONSOLE_FONT_INFO_EX consoleCurrentFontEx);
private const int STD_OUTPUT_HANDLE = -11;
private const int TMPF_TRUETYPE = 4;
private const int LF_FACESIZE = 32;
private static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
public static unsafe void Main()
{
string fontName = "Lucida Console";
IntPtr hnd = GetStdHandle(STD_OUTPUT_HANDLE);
if (hnd != INVALID_HANDLE_VALUE) {
CONSOLE_FONT_INFO_EX info = new CONSOLE_FONT_INFO_EX();
info.cbSize = (uint) Marshal.SizeOf(info);
bool tt = false;
// First determine whether there's already a TrueType font.
if (GetCurrentConsoleFontEx(hnd, false, ref info)) {
tt = (info.FontFamily & TMPF_TRUETYPE) == TMPF_TRUETYPE;
if (tt) {
Console.WriteLine("The console already is using a TrueType font.");
return;
}
// Set console font to Lucida Console.
CONSOLE_FONT_INFO_EX newInfo = new CONSOLE_FONT_INFO_EX();
newInfo.cbSize = (uint) Marshal.SizeOf(newInfo);
newInfo.FontFamily = TMPF_TRUETYPE;
IntPtr ptr = new IntPtr(newInfo.FaceName);
Marshal.Copy(fontName.ToCharArray(), 0, ptr, fontName.Length);
// Get some settings from current font.
newInfo.dwFontSize = new COORD(info.dwFontSize.X, info.dwFontSize.Y);
newInfo.FontWeight = info.FontWeight;
SetCurrentConsoleFontEx(hnd, false, newInfo);
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct COORD
{
internal short X;
internal short Y;
internal COORD(short x, short y)
{
X = x;
Y = y;
}
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct CONSOLE_FONT_INFO_EX
{
internal uint cbSize;
internal uint nFont;
internal COORD dwFontSize;
internal int FontFamily;
internal int FontWeight;
internal fixed char FaceName[LF_FACESIZE];
}
}
Refer https://msdn.microsoft.com/en-us/library/system.console(v=vs.110).aspx for more details

How to get a constant offset of Adorner in WPF?

I am trying to add drag and drop as a feature to my program. However I am really close at getting it right, but I can't figure out how to set a constant offset of the Adorner I built. It has a way to big offset and as I move the mouse it even changes.
I create the adorner within the following method:
private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point mousePos = e.GetPosition(null);
Vector diff = _startPoint.Value - mousePos;
// Initialize the drag & drop operation
DataObject dragData = new DataObject("foo", foo);
_adorner = new DragAdorner(button, mousePos);
AdornerLayer.GetAdornerLayer(this).Add(_adorner);
DragDrop.DoDragDrop(this, dragData, DragDropEffects.Move);
if (_adorner != null && AdornerLayer.GetAdornerLayer(button) != null)
AdornerLayer.GetAdornerLayer(this).Remove(_adorner);
}
I update the Position with another method:
private void OnGiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (_adorner == null) return;
UIElement lbl = sender as UIElement;
if (lbl == null) return;
var pos = lbl.PointToScreen(Utils.GetCursorPos());
_adorner.UpdatePosition(pos);
}
And the DragAdorner.cs looks like this:
public class DragAdorner : Adorner
{
private Brush _vbrush;
private Point _location;
private Point _offset;
public DragAdorner(UIElement adornedElement, Point offset)
: base(adornedElement)
{
_offset = offset;
IsHitTestVisible = false;
_vbrush = new VisualBrush(AdornedElement) {Opacity = .7};
}
public void UpdatePosition(Point location)
{
_location = location;
InvalidateVisual();
}
public void SetDropable(bool dropable)
{
ReservationButton button = AdornedElement as ReservationButton;
if (button == null) return;
if (dropable)
{
button.Background = Utils.GetReservationColor(button.Reservation.Status);
}
else
{
button.Background = NaramisColors.Yellow;
}
InvalidateVisual();
}
protected override void OnRender(DrawingContext dc)
{
var p = _location;
p.Offset(-_offset.X, -_offset.Y);
dc.DrawRectangle(_vbrush, null, new Rect(p, RenderSize));
}
}
Inside of Utils.cs I wrote the methods to get a Win32Point
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
X = x;
Y = y;
}
}
[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
private static Point ConvertPixelsToUnits(int x, int y)
{
// get the system DPI
IntPtr dDc = GetDC(IntPtr.Zero); // Get desktop DC
int dpi = GetDeviceCaps(dDc, 88);
bool rv = ReleaseDC(IntPtr.Zero, dDc);
// WPF's physical unit size is calculated by taking the
// "Device-Independant Unit Size" (always 1/96)
// and scaling it by the system DPI
double physicalUnitSize = 1d / 96d * dpi;
Point wpfUnits = new Point(x / physicalUnitSize , y / physicalUnitSize);
return wpfUnits;
}
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public enum DeviceCap
{
VERTRES = 10,
DESKTOPVERTRES = 117
}
public static float GetScalingFactor()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int logicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
int physicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
float screenScalingFactor = physicalScreenHeight / (float)logicalScreenHeight;
return screenScalingFactor; // 1.25 = 125%
}
public static Point GetCursorPos()
{
POINT p;
if (GetCursorPos(out p))
{
Point wpfPoint = ConvertPixelsToUnits(p.X, p.Y);
return wpfPoint;
}
return new Point();
}
Also I made a gif to visualize my problem, you can find it here
I'd be really happy if you could help me out with this one, I am working on it for hours now and I just can't find the right solution.

Middle button click to scroll

How do I achieve this in a WinForms container control when the scroll bars are visible?
Highlighted here (Google Chrome browser):
EDIT: This cursor is the only one that is visible on a screenshot. I hope it's clear what i mean.
EDIT:
Tried this on my control. Does not work.
const int WM_MBUTTONDOWN = 0x207;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MBUTTONDOWN)
DefWndProc(ref m);
else
base.WndProc(ref m);
}
Here's what I have so far. It exits "reader mode" if I release the middle button, and I haven't implemented scrolling within the control (I used a textbox), but it may give you something to start with.
[DllImport("comctl32.dll", SetLastError=true, EntryPoint="#383")]
static extern void DoReaderMode(ref READERMODEINFO prmi);
public delegate bool TranslateDispatchCallbackDelegate(ref MSG lpmsg);
public delegate bool ReaderScrollCallbackDelegate(ref READERMODEINFO prmi, int dx, int dy);
[StructLayout(LayoutKind.Sequential)]
public struct READERMODEINFO
{
public int cbSize;
public IntPtr hwnd;
public int fFlags;
public IntPtr prc;
public ReaderScrollCallbackDelegate pfnScroll;
public TranslateDispatchCallbackDelegate fFlags2;
public IntPtr lParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public UInt32 message;
public IntPtr wParam;
public IntPtr lParam;
public UInt32 time;
public POINT pt;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int left, top, right, bottom;
}
private bool TranslateDispatchCallback(ref MSG lpMsg)
{
return false;
}
private bool ReaderScrollCallback(ref READERMODEINFO prmi, int dx, int dy)
{
// TODO: Scroll around within your control here
return false;
}
private void EnterReaderMode()
{
READERMODEINFO readerInfo = new READERMODEINFO
{
hwnd = this.textBox1.Handle,
fFlags = 0x00,
prc = IntPtr.Zero,
lParam = IntPtr.Zero,
fFlags2 = new TranslateDispatchCallbackDelegate(this.TranslateDispatchCallback),
pfnScroll = new ReaderScrollCallbackDelegate(this.ReaderScrollCallback)
};
readerInfo.cbSize = Marshal.SizeOf(readerInfo);
DoReaderMode(ref readerInfo);
}
private void textBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Middle)
{
EnterReaderMode();
}
}
The RichTextBox control does it by default when you press the mouse wheel button.
Edit: Sorry I misunderstood and thought you were asking about doing it within a textbox not a container control

Adding filter boxes to the column headers of a ListView in C# and WinForms

In Windows Explorer (at least in Win7) when you hover the mouse over a column header, a filter box with an arrow appears that lets you filter the results in the ListView, so for example you can only show files starting with "A" or files > 128 MB. Can this feature be enabled in the basic ListView control in C# without subclassing or modifying the ListView?
Here's some code to play with. Add a new class to your project and paste the code shown below. Compile. Drop the new ListViewEx control from the top of the toolbox onto your form. In the form constructor, call the SetHeaderDropdown() method to enable the button. Implement the HeaderDropdown event to return a control to display. For example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
listViewEx1.SetHeaderDropdown(0, true);
listViewEx1.HeaderDropdown += listViewEx1_HeaderDropdown;
}
void listViewEx1_HeaderDropdown(object sender, ListViewEx.HeaderDropdownArgs e) {
e.Control = new UserControl1();
}
}
The below code has a flaw, the popup is displayed in a form. Which can't be too small and takes the focus away from the main form. Check this answer on hints how to implement a control that can be displayed as a toplevel window without needing a form. The code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class ListViewEx : ListView {
public class HeaderDropdownArgs : EventArgs {
public int Column { get; set; }
public Control Control { get; set; }
}
public event EventHandler<HeaderDropdownArgs> HeaderDropdown;
public void SetHeaderDropdown(int column, bool enable) {
if (column < 0 || column >= this.Columns.Count) throw new ArgumentOutOfRangeException("column");
while (HeaderDropdowns.Count < this.Columns.Count) HeaderDropdowns.Add(false);
HeaderDropdowns[column] = enable;
if (this.IsHandleCreated) SetDropdown(column, enable);
}
protected void OnHeaderDropdown(int column) {
var handler = HeaderDropdown;
if (handler == null) return;
var args = new HeaderDropdownArgs() { Column = column };
handler(this, args);
if (args.Control == null) return;
var frm = new Form();
frm.FormBorderStyle = FormBorderStyle.FixedSingle;
frm.ShowInTaskbar = false;
frm.ControlBox = false;
args.Control.Location = Point.Empty;
frm.Controls.Add(args.Control);
frm.Load += delegate { frm.MinimumSize = new Size(1, 1); frm.Size = frm.Controls[0].Size; };
frm.Deactivate += delegate { frm.Dispose(); };
frm.StartPosition = FormStartPosition.Manual;
var rc = GetHeaderRect(column);
frm.Location = this.PointToScreen(new Point(rc.Right - SystemInformation.MenuButtonSize.Width, rc.Bottom));
frm.Show(this.FindForm());
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
if (this.Columns.Count == 0 || Environment.OSVersion.Version.Major < 6 || HeaderDropdowns == null) return;
for (int col = 0; col < HeaderDropdowns.Count; ++col) {
if (HeaderDropdowns[col]) SetDropdown(col, true);
}
}
private Rectangle GetHeaderRect(int column) {
IntPtr hHeader = SendMessage(this.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
RECT rc;
SendMessage(hHeader, HDM_GETITEMRECT, (IntPtr)column, out rc);
return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
}
private void SetDropdown(int column, bool enable) {
LVCOLUMN lvc = new LVCOLUMN();
lvc.mask = LVCF_FMT;
lvc.fmt = enable ? LVCFMT_SPLITBUTTON : 0;
IntPtr res = SendMessage(this.Handle, LVM_SETCOLUMN, (IntPtr)column, ref lvc);
}
protected override void WndProc(ref Message m) {
Console.WriteLine(m);
if (m.Msg == WM_NOTIFY) {
var hdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));
if (hdr.code == LVN_COLUMNDROPDOWN) {
var info = (NMLISTVIEW)Marshal.PtrToStructure(m.LParam, typeof(NMLISTVIEW));
OnHeaderDropdown(info.iSubItem);
return;
}
}
base.WndProc(ref m);
}
private List<bool> HeaderDropdowns = new List<bool>();
// Pinvoke
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, ref LVCOLUMN lvc);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, out RECT rc);
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hParent);
private const int LVM_SETCOLUMN = 0x1000 + 96;
private const int LVCF_FMT = 1;
private const int LVCFMT_SPLITBUTTON = 0x1000000;
private const int WM_NOTIFY = 0x204e;
private const int LVN_COLUMNDROPDOWN = -100 - 64;
private const int LVM_GETHEADER = 0x1000 + 31;
private const int HDM_GETITEMRECT = 0x1200 + 7;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct LVCOLUMN {
public uint mask;
public int fmt;
public int cx;
public string pszText;
public int cchTextMax;
public int iSubItem;
public int iImage;
public int iOrder;
public int cxMin;
public int cxDefault;
public int cxIdeal;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct POINT {
public int x, y;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct RECT {
public int left, top, right, bottom;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct NMHDR {
public IntPtr hwndFrom;
public IntPtr idFrom;
public int code;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct NMLISTVIEW {
public NMHDR hdr;
public int iItem;
public int iSubItem;
public uint uNewState;
public uint uOldState;
public uint uChanged;
public POINT ptAction;
public IntPtr lParam;
}
}
It might be tricky to implement the same type of interface, but you could have your ListView respond to the contents of a TextBox by handling the TextBox's TextChanged event and filtering the list based on the contents. If you put the list in a DataTable then filtering will be easy and you can repopulate your ListView each time the filter changes.
Of course this depends on how many items are in your list.

Categories

Resources