This question already has answers here:
Listen for key press in .NET console app
(10 answers)
Closed 7 years ago.
Please could any one help me out, i want to customize my console program to exit only when the user press the Escape key on the keyboard. I appreciate your help.
C# console application.
Try smth like this one
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication
{
[DllImport("user32.dll")]
static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
internal const UInt32 SC_CLOSE = 0xF060;
internal const UInt32 MF_ENABLED = 0x00000000;
internal const UInt32 MF_GRAYED = 0x00000001;
internal const UInt32 MF_DISABLED = 0x00000002;
internal const uint MF_BYCOMMAND = 0x00000000;
static void Main(string[] args)
{
EnableCloseButton(this, false);
}
public static void EnableCloseButton(IWin32Window window, bool bEnabled)
{
IntPtr hSystemMenu = GetSystemMenu(window.Handle, false);
EnableMenuItem(hSystemMenu, SC_CLOSE, (uint)(MF_ENABLED | (bEnabled ? MF_ENABLED : MF_GRAYED)));
}
}
Source
Related
I have a form which I make click-through using the following function calls:
SetWindowLong(Handle, GWL_EXSTYLE, (IntPtr)(GetWindowLong(Handle, GWL_EXSTYLE) ^ WS_EX_LAYERED ^ WS_EX_TRANSPARENT));
SetLayeredWindowAttributes(Handle, 0, 0xFF, LWA_ALPHA);
This works fine, however when I try to fade that window using the System.Windows.Forms.Form.Opacity property I get the following exception:
System.ComponentModel.Win32Exception (0x80004005): The parameter is not valid
at System.Windows.Forms.Form.UpdateLayered()
at System.Windows.Forms.Form.set_Opacity(Double value)
How can I achieve both things at the same time?
The following works on a windows form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication30
{
public partial class Form1 : Form
{
[DllImport("user32.dll", SetLastError = true)]
static extern System.UInt32 GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern int SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte bAlpha, uint dwFlags);
public const int GWL_EXSTYLE = -20;
public const uint WS_EX_LAYERED = 0x80000;
public const uint LWA_ALPHA = 0x2;
public const uint LWA_COLORKEY = 0x1;
public Form1()
{
InitializeComponent();
IntPtr Handle = this.Handle;
UInt32 windowLong = GetWindowLong(Handle, GWL_EXSTYLE);
SetWindowLong32(Handle, GWL_EXSTYLE, (uint)(windowLong ^ WS_EX_LAYERED));
SetLayeredWindowAttributes(Handle, 0, 128, LWA_ALPHA);
}
}
}
I'm trying to emulate some key events by using WinAPI. I want to press a WIN-key, but my code is not working. In example i use VK_F1 for every proc.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication69
{
class Program
{
const UInt32 WM_KEYDOWN = 0x0100;
const UInt32 WM_KEYUP = 0x0101;
const int VK_F1 = 112;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
static void Main(string[] args)
{
Process[] processes = Process.GetProcesses();
foreach (Process proc in processes)
{
SendMessage(proc.MainWindowHandle, WM_KEYDOWN, new IntPtr(VK_F1), IntPtr.Zero);
SendMessage(proc.MainWindowHandle, WM_KEYUP, new IntPtr(VK_F1), IntPtr.Zero);
}
}
}
}
To simulate keyboard input, use SendInput. That's exactly what this API does. "Sending F1 to every window" is not a good idea, because you'll be sending keystrokes to windows that don't have keyboard focus. Who knows how they'll respond.
There are a lot more nuances to keyboard input than you're accounting for; See this question for considerations about emulating keyboard input.
So I used code from this url: SendKeys.Send and Windows Key
And it works fine!
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ConsoleApplication69
{
class Program
{
static void Main(string[] args)
{
KeyboardSend.KeyDown(Keys.LWin);
KeyboardSend.KeyUp(Keys.LWin);
}
}
static class KeyboardSend
{
[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
private const int KEYEVENTF_EXTENDEDKEY = 1;
private const int KEYEVENTF_KEYUP = 2;
public static void KeyDown(Keys vKey)
{
keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
}
public static void KeyUp(Keys vKey)
{
keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}
}
tnx for help everybody!
This question already has an answer here:
how can i disable close button of console window in a visual studio console application?
(1 answer)
Closed 9 years ago.
I need to know if there is an option to cancel the exit key in the console application?
I added an image url describing the button that i want to cancel, surrounded with red color.
http://i44.tinypic.com/2dj18d0.jpg
Thanks!
You can do that using a Windows API.
This code do the trick:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace BlogConsole
{
class API
{
[DllImport("user32.dll")]
static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
internal const UInt32 SC_CLOSE = 0xF060;
internal const UInt32 MF_ENABLED = 0x00000000;
internal const UInt32 MF_GRAYED = 0x00000001;
internal const UInt32 MF_DISABLED = 0x00000002;
internal const uint MF_BYCOMMAND = 0x00000000;
public static void EnableCloseButton(IntPtr handle, bool bEnabled)
{
IntPtr hSystemMenu = GetSystemMenu(handle, false);
EnableMenuItem(hSystemMenu, SC_CLOSE, (uint)(MF_ENABLED | (bEnabled ? MF_ENABLED : MF_GRAYED)));
}
}
}
This is the way you call it:
static void Main(string[] args)
{
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
API.EnableCloseButton(handle, false);
}
I'm using the Sopcast activex plugin (sopocx.ocx) in one of my C# applications.
I would like to retrieve the player status ("Buffering the channel", "Playing the channel", "Channel Offline...") and the buffering percentage. Both of these informationss are displayed on the player (I tried to post a picture but I don't have enough reputation yet).
The problem is the Sopcast activex plugin doesn't provide any methods in order to retrieve these informations.
Does someone has any idea on how this could be done??
GetWindowText results in an empty string...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private void testToolStripMenuItem_Click(object sender, EventArgs e)
{
IntPtr hwnd = sopcast.Handle;
StringBuilder lpString = new StringBuilder(256);
GetWindowText(hwnd, lpString, 256);
MessageBox.Show(lpString.ToString());
}
private void playToolStripMenuItem_Click(object sender, EventArgs e)
{
sopcast.SetSopAddress("sop://broker.sopcast.com:3912/123456789");
sopcast.SetChannelName("Channel");
sopcast.Play();
}
}
}
You can identify Id control and get text with api windows
here a code sample (replace notepad by your application name) the most important for you is to get from your application a way to get ID control of your ocx window
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Security;
namespace Application
{
public class Program
{
public static void Main ( )
{
IntPtr hwnd = UnsafeNativeMethods.FindWindow("Notepad", null);
StringBuilder stringBuilder = new StringBuilder(256);
UnsafeNativeMethods.GetWindowText(hwnd, stringBuilder, stringBuilder.Capacity);
Console.WriteLine(stringBuilder.ToString());
}
}
[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowText ( IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount );
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr FindWindow ( string lpClassName, string lpWindowName );
}
}
I download sopcast and try to get status using spy++:
As you see, caption is status not the channel...
so you can not get it easier
the handle you have catched is for the whole control
Sopcast draws the status text using DrawText (i found out using API Monitor http://www.rohitab.com/apimonitor). So there is no way of getting the text using conventional GetWindowText function or similar. I was able to obtain the text by hooking DrawText function. For .NET EasyHook will enable you to do this.
My scenario:
I have a winforms app that hosts the activex control and i want to obtain the status text.
public class hooklocal : EasyHook.IEntryPoint
{
[DllImport("user32.dll")]
static extern int DrawText(IntPtr hDC, string lpString, int nCount, IntPtr lpRect, uint uFormat);
[UnmanagedFunctionPointer(CallingConvention.StdCall,CharSet = CharSet.Auto,SetLastError = true)]
delegate int DDrawText(IntPtr hDC, string lpString, int nCount, IntPtr lpRect, uint uFormat);
int DrawTextH(IntPtr hDC, string lpString, int nCount, IntPtr lpRect, uint uFormat)
{
//lpString contains the status text
return DrawText(hDC, lpString, nCount, lpRect, uFormat);
}
public hooklocal()
{
try
{
var CreateHook = LocalHook.Create(
LocalHook.GetProcAddress("user32.dll", "DrawTextW"),
new DDrawText(DrawTextH),
this);
CreateHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
}
catch (Exception ExtInfo)
{
Debugger.Break();
}
}
}
To use, instantiate hooklocal class in a new thread at program startup.
EasyHook download
https://easyhook.github.io/downloads.html
This question already has answers here:
Global hotkey in console application
(4 answers)
Closed 8 years ago.
I'm trying to register a hot key, I'm translating this C++ code into C#:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("user32.dll")]
public static extern
bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, int vk);
[DllImport("user32")]
public static extern
bool GetMessage(ref Message lpMsg, IntPtr handle, uint mMsgFilterInMain, uint mMsgFilterMax);
public const int MOD_ALT = 0x0001;
public const int MOD_CONTROL = 0x0002;
public const int MOD_SHIFT = 0x004;
public const int MOD_NOREPEAT = 0x400;
public const int WM_HOTKEY = 0x312;
public const int DSIX = 0x36;
static void Main(string[] args)
{
if (!RegisterHotKey(IntPtr.Zero, 1, MOD_ALT | MOD_NOREPEAT, DSIX))
{
Console.WriteLine("failed key register!");
}
Message msg = new Message();
while (!GetMessage(ref msg, IntPtr.Zero, 0, 0))
{
if (msg.message == WM_HOTKEY)
{
Console.WriteLine("do work..");
}
}
Console.ReadLine();
}
}
public class Message
{
public int message { get; set; }
}
}
but RegisterHotKey() never returns false.
I'm not sure about the arguments passed in the method, IntPtr.Zero should be null, and message class constructor's second argument requires an object. any help is very appreciated!
This might help:
Hotkey in console app
Basically, you have to create a "hidden" form to make it work