How to detect in which Excel-workbook was clicked ? - excel

Using Excel-2010, Visual-Studio-2013 Professional,
I am trying to find out programatically, in which Excel-Workbook a mouse-click occurrs (or keyboard-shortcut occurs would also be acceptable)? There are several ideas I persuaded, but all of them show the same issue: The Excel-AddIn used does get executed for all open Excel-Workbooks and messes up the needed information in a sense that it does give me the wrong origin of the mouse-click (or keyboard-shortcut click). It does not tell me the desired origin-window but tells me that the click occurred from a window that is not active by all means! I really don't know why the below code-snippets return arbitrary workbook-origins (but never the one I needed, which is the one window I click inside!)...
What is the best way to tell from which window a mouse-click (or keyboard-shortcut) occurrs having several Excel-Workbooks open working with the same Excel-AddIn code ???
Here is what I tried so far:
A) As seen here, a global keyboard-hook was not the solution.
B) GetActiveWindow()
const int nChars = 256;
IntPtr handle1 = GetActiveWindow();
StringBuilder Buff1 = new StringBuilder(nChars);
if (GetWindowText(handle1, Buff1, nChars) > 0) {
MessageBox.Show(Buff1.ToString());
}
C) GetForegroundWindow()
const int nChars = 256;
IntPtr handle2 = GetForegroundWindow();
StringBuilder Buff2 = new StringBuilder(nChars);
if (GetWindowText(handle2, Buff2, nChars) > 0) {
MessageBox.Show(Buff2.ToString());
}
D) ApplicationIsActivated()
public static bool ApplicationIsActivated()
{
var activatedHandle = GetForegroundWindow();
if (activatedHandle == IntPtr.Zero) {
return false; // No window is currently activated
}
var procId = Process.GetCurrentProcess().Id;
int activeProcId;
GetWindowThreadProcessId(activatedHandle, out activeProcId);
MessageBox.Show(activeProcId.ToString());
MessageBox.Show(procId.ToString());
return activeProcId == procId;
}
Needed imports for the above code-snippets:
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
[DllImport("user32.dll")]
static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr GetFocus();
Any idea appreciated!

Related

Avalonia: Is there a way embed Process' Window on Linux

Hello as you know the VLCPlayer not supporting RTSP stream on debian bullseye and pardus21 anymore.
I'm searching a way put native window to Control on Linux for Avalonia.
On windows it's so easy.
[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetWindowPos(IntPtr hWnd, int X, int Y, int cx, int cy, uint flags);
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
...
if (ffProcess.MainWindowHandle != IntPtr.Zero) {
SetParent(ffProcess.MainWindowHandle, ctrl.Handle);
MoveWindow(ffProcess.MainWindowHandle, 0, 0, ctrl.Width, ctrl.Height, true);
}
is there a way embedding process' window for Linux?

SocketCAN in dotnet core

I am writing software for the device on Linux, and which should work with the CAN interface. Ideally, I would like to work with the interface without connecting third-party libraries from c ++. Is it possible?
I solved this problem using native function. Here example to bind socket, can read and write message with native functions write( or aio_write) and read. CanPublisher in UDSim as example
const int Siocgifindex = 0x8933;
private const int PfCan = 29;
private const int SockRaw = 3;
private const int CanRaw = 1;
private const int CanMtu = 16;
[DllImport("libc", SetLastError = true)]
private static extern int socket(int domain, int type, int protocol);
[DllImport("libc", SetLastError = true)]
private static extern int ioctl(int fd, int request, ref Ifreq mtu);
[DllImport("libc", SetLastError = true)]
private static extern int bind(int fd, ref SockaddrCan addr, int addrlen);
[StructLayout(LayoutKind.Sequential)]
struct SockaddrCan
{
public ushort can_family;
public int can_ifindex;
public uint rx_id;
public uint tx_id;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Ifreq
{
public Ifreq(string ifr_name)
{
this.ifr_name = ifr_name;
this.ifr_ifindex = 0; // ifru_ivalue
this.ifru_mtu = 0;
}
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string ifr_name;
public int ifr_ifindex;
public uint ifru_mtu;
}
var addr = new SockaddrCan();
var s = socket(PfCan, SockRaw, CanRaw);
var ifr = new Ifreq("vcan0");
var ret = ioctl(s, Siocgifindex, ref ifr);
addr.can_ifindex = ifr.ifr_ifindex;
addr.can_family = PfCan;
ret = bind(s, ref addr, Marshal.SizeOf(addr));
I have written a .NET managed wrapper library for SocketCAN called SocketCAN# (SocketCANSharp): https://github.com/derek-will/SocketCANSharp
SocketCAN# enables utilizing Raw CAN, ISO-TP, Broadcast Manager, and J1939 sockets in a .NET application on Linux.
Some sample code:
IEnumerable<CanNetworkInterface> collection = CanNetworkInterface.GetAllInterfaces(true);
var iface = collection.FirstOrDefault(i => i.Name.Equals("vcan0"));
using (var rawCanSocket = new RawCanSocket())
{
rawCanSocket.Bind(iface);
int bytesWritten = rawCanSocket.Write(
new CanFrame(0x123, new byte[] { 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }));
}
Underneath the library uses P/Invoke to call the native libc functions and marshal the various types back and fourth between the managed and unmanaged code.
You need to look at the SocketCAN library that is part of Linux.
You can also use candump and cansend to help you develop and also look at the candump.c and cansend.c source files for inspiration.
I see there is a dotnet tag, if you want to use CAN in dotnet I suggest you write a small C library to handle the CAN stuff. Then marshal that to dotnet, once you have access in dotnet you can wrap things in classes and create whatever abstractions you need.

Hiding window in process.start() and moving this window

I wrote this code, but I cannot hide and move the window.
How can I hide the window in Process.Start() and then move it and show it to the user?
[DllImport("USER32.dll")]
//[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("USER32.dll")]
private static extern bool UpdateWindow(IntPtr hWnd);
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = Application.StartupPath + #"\award_star_gold_2.png";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = true;
Process processTemp = new Process();
processTemp.StartInfo = startInfo;
processTemp.EnableRaisingEvents = true;
processTemp.Start();
processTemp.WaitForInputIdle();
IntPtr id = processTemp.MainWindowHandle;
Console.Write(id);
System.Threading.Thread.Sleep(1000);
MoveWindow(processTemp.MainWindowHandle, 10, 200, 200, 300, true);
UpdateWindow(processTemp.MainWindowHandle);
}

How to get the value of a pointer to an int pointer from c++ in c#

How to get array of values from the intptr. how to get vlues pointed by int_ptr_arr into s1[].... mean to say my s1[] should contain 10,100,15
it works for me if it is char** with Marshal.PtrToStringAnsi(), but i want it for int** because i don't have anything like Marshal.ptrint().... etc..
enter code here
Native code:
extern "C" __declspec(dllexport) int** __stdcall Array_hh()
{
int x=10;
int y=100;
int z=15;
static int* myArray[3] = {&x, &y, &z};
return myArray;
}
wrapper:
[DllImport("Native_DLL.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern IntPtr Array_hh();
void some_fun
IntPtr int_ptr_arr = Wrapper.Array_hh();
int k = 0;
int[] s1 = new int[4];

Marshaling char * in .NetcompactFramework(Windows CE)

I have the following signature from c++
IDTECHREADER_EXPORTS void ReadTwoBlocks(char *pathConfig,
char *datablock1, char *datablock2, int timeout, bool &ret )
I was able to Marshal this correctly on the Full .NetFrameWork and it works as below
[DllImport("IDTechReader.dll", EntryPoint = "ReadTwoBlocks" )]
private static extern void _ReadTwoBlocks(
[In][MarshalAs(UnmanagedType.LPStr)] string pathConfig,
[Out][MarshalAs(UnmanagedType.LPStr)] StringBuilder datablock1,
[Out] [MarshalAs(UnmanagedType.LPStr)] StringBuilder datablock2,
int TimeOut,
ref bool result);
However using the same Marshaling as above doesn't work on the NetcompactFramework(Windows CE) it gives an error "NotSupported Exception"
How do we correctly Marshal the above C++ method signature so that it will work correctly on the .NET CompactFramework(windows CE)
any ideas are apperciated...thanks.
The marshaler is probably choking on the MarshalAs(UnmanagedType.LPStr). You're either going to have to change the signature to a fixed size byte[] and do the string conversion in managed code using Encoding.ASCII.GetString(), or you could use an IntPtr type and allocate the memory using Marshal.AllocHGlobal/FreeHGlobal and deal with the string conversion in your code.
I think this might work..
private const int MAX_STRING = 256;
[DllImport("IDTechReader.dll", EntryPoint = "ReadTwoBlocks")]
private static extern void _ReadTwoBlocks(
byte[] pathConfig,
[Out] byte[] datablock1,
[Out] byte[] datablock2,
int TimeOut,
ref bool result);
public void ReadTwoBlocks(string pathConfig,
StringBuilder datablock1,
StringBuilder datablock2,
int TimeOut,
ref bool result)
{
var pathConfigBuff = new byte[MAX_STRING];
var datablock1Buff = new byte[MAX_STRING];
var datablock2Buff = new byte[MAX_STRING];
// Convert unicode string to null terminated single byte charater string
Array.Copy(Encoding.ASCII.GetBytes(pathConfig), pathConfigBuff, pathConfig.Length);
// Call your native method
_ReadTwoBlocks(pathConfigBuff, datablock1Buff, datablock2Buff, TimeOut, ref result);
// If success, copy the datablocks to the StringBuffers
if (result)
{
datablock1.Append(Encoding.ASCII.GetString(datablock1Buff, 0, MAX_STRING).Replace('\0', ' ').Trim());
datablock2.Append(Encoding.ASCII.GetString(datablock2Buff, 0, MAX_STRING).Replace('\0', ' ').Trim());
}
}
It would be something like this:
[DllImport("IDTechReader.dll")]
private static extern void ReadTwoBlocks(IntPtr pathConfig,
IntPtr datablock1, IntPtr datablock2, int timeout, ref bool ret);
and when you use it like this:
string pathConfig = "..\program.ini";
IntPtr ptrPathConfig = IntPtr.Zero;
ptrPathConfig = Marshal.StringToHGlobalAnsi(pathConfig);
IntPtr ptrDatablock1 = IntPtr.Zero;
IntPtr ptrDatablock2 = IntPtr.Zero;
int timeout = 300;
bool ret = false;
ReadTwoBlocks(ptrPathConfig, ptrDatablock1, ptrDatablock2, timeout, ref ret);
string db1 = Marshal.PtrToStringAnsi(ptrDatablock1);
string db2 = Marshal.PtrToStringAnsi(ptrDatablock2);

Resources