C# Turn off selected monitor - c#

I'm wondering if someone could help me I have been trying to find a way of turning off specific monitors in a basic application, there are a couple of posts on here about turning off all monitors and this works fine. The only topic I can see if this one here:
C# selectively turn off monitor
This does explain how to go about doing this but I'm still learning and not really sure how to expand the example into whats needed.
Turn off all monitors:
public void MonitorOff(IntPtr handle)
{
SendMessage(handle, WmSyscommand, (IntPtr)ScMonitorpower, (IntPtr)MonitorShutoff);
}
private void MonitorOn()
{
mouse_event(MouseeventfMove, 0, 1, 0, UIntPtr.Zero);
Thread.Sleep(40);
mouse_event(MouseeventfMove, 0, -1, 0, UIntPtr.Zero);
}
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern void mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 dwData, UIntPtr dwExtraInfo);
private const int WmSyscommand = 0x0112;
private const int ScMonitorpower = 0xF170;
private const int MonitorShutoff = 2;
private const int MouseeventfMove = 0x0001;
[DllImport("user32")]
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);
private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref Rect pRect, int dwData);
[StructLayout(LayoutKind.Sequential)]
private struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
}
Count Monitors:
public void GetMonitors()
{
int monCount = 0;
//Rect r = new Rect();
MonitorEnumProc callback = (IntPtr hDesktop, IntPtr hdc, ref Rect prect, int d) => ++monCount > 0;
if (EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, 0))
MessageBox.Show("You have " + monCount.ToString() + " monitors", "Windows Hook");
else
MessageBox.Show("An error occured while enumerating monitors");
}
Is anyone able to enplane this or show me the right route to take?, Thank you.

Related

Is it possible to increase size of calendar popup in winform?

I am trying to increase calendar popup's size. Increasing font only increases the height of the calendar box and not the pop up. Dates in popup are still small.
Can I do this without using any third party controls etc? If yes how?
There is a CalendarFont property which is responsible to get/set font of the drop-down calendar. But the value will be applied just when the Visual Styles are disabled.
You can handle DropDown event of the DateTimePicker and find the MonthCalendar of the drop-down. Then disable Visual Styles just for that control. Then recalculate the required size of the control and set the size of drop-down based on minimum required size of the calendar.
Then the control will show drop-down using the font which you specified in CalendarFont property:
Code
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class MyDateTimePicker : DateTimePicker
{
private const int SWP_NOMOVE = 0x0002;
private const int DTM_First = 0x1000;
private const int DTM_GETMONTHCAL = DTM_First + 8;
private const int MCM_GETMINREQRECT = DTM_First + 9;
[DllImport("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appName, string idList);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref RECT lParam);
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int X, int Y, int cx, int cy, int uFlags);
[DllImport("User32.dll")]
private static extern IntPtr GetParent(IntPtr hWnd);
[StructLayout(LayoutKind.Sequential)]
private struct RECT { public int L, T, R, B; }
protected override void OnDropDown(EventArgs eventargs)
{
var hwndCalendar = SendMessage(this.Handle, DTM_GETMONTHCAL, 0, 0);
SetWindowTheme(hwndCalendar, string.Empty, string.Empty);
var r = new RECT();
SendMessage(hwndCalendar, MCM_GETMINREQRECT, 0, ref r);
var hwndDropDown = GetParent(hwndCalendar);
SetWindowPos(hwndDropDown, IntPtr.Zero, 0, 0,
r.R - r.L + 6, r.B - r.T + 6, SWP_NOMOVE);
base.OnDropDown(eventargs);
}
}

restore window to specific locaiton on screen c# (console application)

I am wondering how can I restore application window to specific location on the screen.
I did managed to write some code, but somehow I do have a feeling that there must be and easier and more efficient way to do it programaticaly... as my current version is restoring window first and then moving it to required location. I would like to restore it without being forced to move it afterwards.
my code:
public void Send()
{
if (Process.GetProcessesByName("report").Any())
{
Process proc = Process.GetProcessesByName("report").First();
if (proc != null)
{
IntPtr pointer = proc.MainWindowHandle;
SetForegroundWindow(pointer);
SendMessage(pointer, WM_SYSCOMMAND, SC_RESTORE, 0);
Program.MoveWindow(pointer, 0, 0, 100, 100, true);
}
}
// do something
}
of course this is followed with :
[DllImport("user32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
internal static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam);
static Int32 WM_SYSCOMMAND = 0x0112;
static Int32 SC_RESTORE = 0xF120;
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
I would be very grateful for further solutions and explanation.

CreateWindowEx and RegisterClass C#

I want to create a new class and then show a window with the specefied class.
I wrote following codes for that :
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern bool UpdateWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowEx")]
public static extern IntPtr CreateWindowEx(
int dwExStyle,
string lpClassName,
string lpWindowName,
int dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern System.UInt16 RegisterClassW(
[System.Runtime.InteropServices.In] ref WNDCLASSEX lpWndClass
);
struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int style;
public IntPtr lpfnWndProc; // not WndProc
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
public string lpszMenuName;
public string lpszClassName;
public IntPtr hIconSm;
}
[DllImport("user32.dll")]
static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
WNDCLASSEX wind_class = new WNDCLASSEX();
wind_class.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
wind_class.style = 0x00020000;
wind_class.hbrBackground = (IntPtr) 5;
wind_class.cbClsExtra = 0;
wind_class.cbWndExtra = 0;
wind_class.hInstance = Marshal.GetHINSTANCE(GetType().Module);
wind_class.hIcon = this.Icon.Handle;
wind_class.hCursor = IntPtr.Zero;
wind_class.lpszMenuName = string.Empty;
wind_class.lpszClassName = "MyClass";
wind_class.lpfnWndProc = DefWindowProc(IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero);
RegisterClassW(ref wind_class);
IntPtr lolo = CreateWindowEx(0, "MyClass", "MyClass",0,0,0,30,40,IntPtr.Zero,IntPtr.Zero,IntPtr.Zero,IntPtr.Zero);
ShowWindow(lolo, 1);
UpdateWindow(lolo);
}
}
}
But it isn't working correctly.
It doesn't show the window. when i search with Spy++ by my class name , It cant find any results..
I searched in web and do some edits in my code but they didn't work.
Where is my Problem !?
Regards.
Plain-vanilla Win32 is no fun from Win32 C, and it is much less fun from .NET. But anyway, it may be useful in rare cases. Here comes a C# class which should do what you want.
First, a general remarks on your software. In Win32, you should always check the return codes of the system calls, and in case of an error, call GetLastError() to get a more detailed information about the failure. If you had checked the result of the RegisterClass function and it failed, you would have known that it is useless to continue without having fixed that one.
The following is a class which may be used as template for further studies and which should successfully register and create a resizable window. Additionally some simple actions like doubleclick are processed in a custom Window procedure. For some parts of the code credit goes to this site being one of the very few I found in the web presenting something working.
The CreateWindowEx is tricky, because you must NOT put in a string as class name, but the result of the RegisterClassEx. The used constants are found mainly in the C-header file winuser.h. To be able to do something useful with this method, the main painting has to be done "by hand", being a cumbersome and tedious work by manipulationg Device Contexts properly. Of course, all this does not show up in the following example. The "create" method of the class may be called e.g. from a Windows Form button click. The namespace name is of course arbitrarily selected. The WinForm project is x86 32-bit, .NET 4.0.
Have fun!
namespace Win32FromForms
{
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
class Win32Window
{
const UInt32 WS_OVERLAPPEDWINDOW = 0xcf0000;
const UInt32 WS_VISIBLE = 0x10000000;
const UInt32 CS_USEDEFAULT = 0x80000000;
const UInt32 CS_DBLCLKS = 8;
const UInt32 CS_VREDRAW = 1;
const UInt32 CS_HREDRAW = 2;
const UInt32 COLOR_WINDOW = 5;
const UInt32 COLOR_BACKGROUND = 1;
const UInt32 IDC_CROSS = 32515;
const UInt32 WM_DESTROY = 2;
const UInt32 WM_PAINT = 0x0f;
const UInt32 WM_LBUTTONUP = 0x0202;
const UInt32 WM_LBUTTONDBLCLK = 0x0203;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int style;
public IntPtr lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
public string lpszMenuName;
public string lpszClassName;
public IntPtr hIconSm;
}
private WndProc delegWndProc = myWndProc;
[DllImport("user32.dll")]
static extern bool UpdateWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowEx")]
public static extern IntPtr CreateWindowEx(
int dwExStyle,
UInt16 regResult,
//string lpClassName,
string lpWindowName,
UInt32 dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClassEx")]
static extern System.UInt16 RegisterClassEx([In] ref WNDCLASSEX lpWndClass);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("user32.dll")]
static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern void PostQuitMessage(int nExitCode);
//[DllImport("user32.dll")]
//static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin,
// uint wMsgFilterMax);
[DllImport("user32.dll")]
static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
[DllImport("user32.dll")]
static extern bool TranslateMessage([In] ref MSG lpMsg);
[DllImport("user32.dll")]
static extern IntPtr DispatchMessage([In] ref MSG lpmsg);
internal bool create()
{
WNDCLASSEX wind_class = new WNDCLASSEX();
wind_class.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
wind_class.style = (int)(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ) ; //Doubleclicks are active
wind_class.hbrBackground = (IntPtr) COLOR_BACKGROUND +1 ; //Black background, +1 is necessary
wind_class.cbClsExtra = 0;
wind_class.cbWndExtra = 0;
wind_class.hInstance = Marshal.GetHINSTANCE(this.GetType().Module); ;// alternative: Process.GetCurrentProcess().Handle;
wind_class.hIcon = IntPtr.Zero;
wind_class.hCursor = LoadCursor(IntPtr.Zero, (int)IDC_CROSS);// Crosshair cursor;
wind_class.lpszMenuName = null;
wind_class.lpszClassName = "myClass";
wind_class.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(delegWndProc);
wind_class.hIconSm = IntPtr.Zero;
ushort regResult = RegisterClassEx(ref wind_class);
if (regResult == 0)
{
uint error = GetLastError();
return false;
}
string wndClass = wind_class.lpszClassName;
//The next line did NOT work with me! When searching the web, the reason seems to be unclear!
//It resulted in a zero hWnd, but GetLastError resulted in zero (i.e. no error) as well !!??)
//IntPtr hWnd = CreateWindowEx(0, wind_class.lpszClassName, "MyWnd", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 30, 40, IntPtr.Zero, IntPtr.Zero, wind_class.hInstance, IntPtr.Zero);
//This version worked and resulted in a non-zero hWnd
IntPtr hWnd = CreateWindowEx(0, regResult, "Hello Win32", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 300, 400, IntPtr.Zero, IntPtr.Zero, wind_class.hInstance, IntPtr.Zero);
if (hWnd == ((IntPtr)0))
{
uint error = GetLastError();
return false;
}
ShowWindow(hWnd, 1);
UpdateWindow(hWnd);
return true;
//The explicit message pump is not necessary, messages are obviously dispatched by the framework.
//However, if the while loop is implemented, the functions are called... Windows mysteries...
//MSG msg;
//while (GetMessage(out msg, IntPtr.Zero, 0, 0) != 0)
//{
// TranslateMessage(ref msg);
// DispatchMessage(ref msg);
//}
}
private static IntPtr myWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)
{
// All GUI painting must be done here
case WM_PAINT:
break;
case WM_LBUTTONDBLCLK :
MessageBox.Show("Doubleclick");
break;
case WM_DESTROY:
DestroyWindow(hWnd);
//If you want to shutdown the application, call the next function instead of DestroyWindow
//PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
}
The problem is the marshaling of strings to LPStr, if you do it like this then the class name works:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int style;
public IntPtr lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
[MarshalAs(UnmanagedType.LPStr)]
public string lpszMenuName;
[MarshalAs(UnmanagedType.LPStr)]
public string lpszClassName;
public IntPtr hIconSm;
}
[DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowEx")]
public static extern IntPtr CreateWindowEx(
int dwExStyle,
//UInt16 regResult,
[MarshalAs(UnmanagedType.LPStr)]
string lpClassName,
[MarshalAs(UnmanagedType.LPStr)]
string lpWindowName,
UInt32 dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);

Message loop is blocking application

I need to close a download popup in web browser control (disallow user to downloading file).
How i can achieve this?
I found this:
How to block downloads in .NET WebBrowser control?
And i used second answer. It's working but i have problem with it. It's seems that calling GetText of the created object is blocking a whole thread. I don't have any solution for it.
private static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (idObject == 0 && idChild == 0)
{
if(eventType == EVENT_OBJECT_CREATE)
{
string text = GetText(hwnd);
if (text.Contains("File Download"))
SendMessage(hwnd, 0x0010, IntPtr.Zero, IntPtr.Zero); //close window
}
}
}
public static string GetText(IntPtr hWnd)
{
int length = GetWindowTextLength(hWnd); //my app is freezing here - i think it's because i'm calling it from message loop.
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
//edit
Ok, thanks #sgorozco for suggestion. Now i'm using SetWindowsHookEx and WH_CBT. Then in message loop i'm catching HCBT_CREATEWND events. But i have problem with getting CBT_CREATEWND from lparm. I'm getting "Managed Debugging Assistant 'FatalExecutionEngineError'" exception.
Here is my current code:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CREATESTRUCT
{
public IntPtr lpCreateParams;
public IntPtr hInstance;
public IntPtr hMenu;
public IntPtr hwndParent;
public int cy;
public int cx;
public int y;
public int x;
public int style;
public string lpszName;
public string lpszClass;
public int dwExStyle;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CBT_CREATEWND
{
public IntPtr lpcs;
public IntPtr hwndInsertAfter;
}
private static IntPtr MessageLoopFuctnion(int code, IntPtr wParam, IntPtr lParam)
{
if (code < 0)
{
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
if(code == 3)
{
CBT_CREATEWND info;
info = (CBT_CREATEWND)Marshal.PtrToStructure(lParam, typeof(CBT_CREATEWND));
CREATESTRUCT info1;
info1 = (CREATESTRUCT)Marshal.PtrToStructure(info.lpcs, typeof(CREATESTRUCT)); //here exception is throwing
if (info1.lpszName != null && info1.lpszName.Contains("File Download")))
SendMessage(wParam, 0x0010, IntPtr.Zero, IntPtr.Zero); //close popup
//Marshal.FreeHGlobal(info.lpcs); //error, why?
//Marshal.FreeHGlobal((IntPtr)lParam.ToUInt64());
}
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
//set hook
IntPtr hWinEventHook = SetWindowsHookEx(5, myCallbackDelegate, user32DLL, 0);
//edit 2
Here are my definitions:
private delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);
private static HookProc myCallbackDelegate = new HookProc(MessageLoopFuctnion);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetWindowsHookEx(int hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
My myCallbackDelegate is a static field so it's not GC collected for sure.
Temporary i'm enumerating all windows every 500ms and look for dialog which contains text "File Download". But it is an ugly solution.
The reason for the FatalExecutionEngineError are the strings in CREATESTRUCT. Replace these with a IntPtr and you will get no exception.
[StructLayout(LayoutKind.Sequential)]
public struct CREATESTRUCT {
public IntPtr lpCreateParams;
public IntPtr hInstance;
public IntPtr hMenu;
public IntPtr hwndParent;
public int cy;
public int cx;
public int y;
public int x;
public int style;
public IntPtr lpszName;
public IntPtr lpszClass;
public int dwExStyle;
}
(Maybe you can use GetClassName and GetWindowText instead as workaround. not tested)

c#: SetScrollPos (user32.dll)

I want to have 2 (rich)texboxes (vc# 2k8) with same scrolling... so when I scroll tb1 the tb2 scrolls to the same position. I use this functions:
[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);
[DllImport("user32.dll")]
public static extern int GetScrollPos(IntPtr hwnd, int nBar);
That works fine but
int pos = GetScrollPos(tb1.Handle, 1);
SetScrollPos(tb2.Handle, 1, pos, true);
only sets the scrollbar to the same position but down update the text in there.
tb2.Update() oder Refresh won't work...
Please help. Ty
I found answer
[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar,
int nPos, bool bRedraw);
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
public void ScrollTo(int Position) {
SetScrollPos((IntPtr)textBox1.Handle, 0x1, Position, true);
PostMessage((IntPtr)textBox1.Handle, 0x115, 4 + 0x10000 * Position, 0);
}

Categories