I have a project where I want to display a combo to show dropdown list of directory listing like dialog boxes does.
there is a Win32 API
int DlgDirListComboBox(
LPTSTR lpPathSpec,
int nIDComboBox,
int nIDStaticPath,
UINT nFileType
);
and its c# version (thanks to pInvoke.net)
[DllImport("user32.dll")]
static extern int DlgDirListComboBox(IntPtr hDlg, StringBuilder lpPathSpec,
int nIDComboBox, int nIDStaticPath, uint uFiletype);
but I can't figure out what value should I pass in for nIDComboBox parameter (I tried and handle do not work here!)
nIDComboBox should be the Win32 Control ID of the combobox. You can get it with another P/Invoke call by passing the control's Handle:
[DllImport("user32.dll")]
static extern int GetDlgCtrlID(IntPtr hWnd);
But you can also list the directories without resorting to P/Invoke by using Directory.GetDirectories
Related
I have a hotkey window application in C# and I want all the text from the focused window of other application on pressing hotkey like notepad, browser, command window(cmd), Turbo c++, Pascal etc.
So Is it possible?
If any one have idea please help me with code example.
I have attach screen shot. I want to read text from this window. On pressing hotkey I want to read text "This is my test text".
There is a GetWindowText() in user32 API,
but if you need to get text from a control in another process, GetWindowText() won't work.
You have to use SendMessage() with WM_GETTEXT instead:
const UInt32 WM_GETTEXT = 0x000D;
const UInt32 WM_GETTEXTLENGTH = 0x000E;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam);
static string GetWindowTextRaw(IntPtr hwnd)
{
// Allocate string length
int length = (int)SendMessage(hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
StringBuilder sb = new StringBuilder(length + 1);
// Get window text
SendMessage(hwnd, WM_GETTEXT, (IntPtr)sb.Capacity, sb);
return sb.ToString();
}
Application that call themselves "Screen Reader" (for visually impaired people) do that kind of things, sort of.
They use the old MSSA (Microsoft Active Accessibility) APIs and/or the new UIAutomation APIs.
With the two APIs, if you have a "Main Window" HWND, you can then browse the tree of the componants making the app. You can then retrieve properties, such as "Text" or "Name" and so on.
If the application doesn't support Accessive technologies, you fall back on case by case solutions, which means eventually awful hacks (as APIs hooking) or more regular methods (as DLL injection and use of the JNI Invocation API in the JAVA case).
Its is not directly possible through C#,
Still microsoft provides with WMI services which can utilized to get at max information on the machine and processes. Kindly check MSDN
You can download WMI tool from here and possible check Win32 classes and methods, you may find useful information for your requirement
I'm writing a super-simple ultra-lite weight .Net wrapper for the LibVLC media library since the only things I need access to are the ability to play, pause and stop media files. I've posted a couple of questions on this and gotten some answers but unfortunately I'm just left with more questions.
We'll start from the top and work down.
The documentation first states I have to initialize VLC with a call to the function with this specification:
libvlc_instance_t* libvlc_new (int argc, const char *const *argv)
for which I have the defined the following method:
[DllImport("libvlc", EntryPoint = "libvlc_new",
CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr NewCore(int argc, IntPtr argv);
And I'm calling the function like this:
private IntPtr Instance;
this.Instance = DGLibVLC.NewCore(0, IntPtr.Zero);
I have tried it several different ways. Initially I did not know about the CallingConvention which was leading to an unbalanced stack which brought me here in the first place. That issue was resolved and the method has gone through several iterations, none of which have proved successful, by which I mean IntPtr is always 0 after the method call. I've tried it like it is above, with the second argument being String[] argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[],
I've tried having it return to a Long (which actually resulted in the Long having a value in it), but nothing so far has worked correctly.
Does anyone know the correct way to call this function from the LibVLC DLL Library?
EDIT: On a suggestion I tried calling the error message function of the library:
Specification:
const char* libvlc_errmsg (void)
Implementation:
[DllImport("libvlc", EntryPoint = "libvlc_errmsg",
CallingConvention = CallingConvention.Cdcel)]
public static extern string GetLastError();
Call:
Console.WriteLine(DGLibVLC.GetLastError());
Result:
Null
The documentation states it will return Null if there is no error. This must indicate that the initial function call NewCore was working correctly but something is still going wrong somehow.
To be cover all bases I checked that the DLLs match the documentation, they do. 2.0.6.0. The documentation I am referencing is here.
EDIT: I can confirm there is no error. When using an initialized to zero long variable to store the result of NewCore I can see it returning something. What I am doing wrong here is where I am trying to store the pointer being returned by the unmanaged function that returns the pointer to the object. How do I store the pointer to the opaque structure reference being passed back?
It doesn't have anything to do with the way you call the function. You cannot get anywhere when you get IntPtr.Zero back from libvlc_new(). It means "there was an error". You'll need to focus on error reporting first, call libvlc_errmsg() to try to get a description for the problem.
So after much looking around and asking questions I've come full circle.
I looked deeply into LibVLC.Net and found how they were importing the DLL functions and adapted what they did to my own wrapper and it worked.
To summarize:
There are some Win32 API functions declared in the code at the start:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetDllDirectory(string lpPathName);
[DllImport("kernel32", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
that handle providing a handle to a dll and setting a directory search path.
I don't know exactly what it all means but when you initialize the LibVLC.Net library (the primary object) it loads pretty much EVERY function like so:
m_libvlc_media_player_new = (libvlc_media_player_new_signature)LoadDelegate<libvlc_media_player_new_signature>("libvlc_media_player_new");
That delegate is defined here like so:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr libvlc_media_player_new_signature(IntPtr p_instance);
//==========================================================================
private readonly libvlc_media_player_new_signature m_libvlc_media_player_new;
//==========================================================================
public IntPtr libvlc_media_player_new(IntPtr p_instance)
{
VerifyAccess();
return m_libvlc_media_player_new(p_instance);
}
And it has a public function that calls the delegate once defined.
I simply stripped down the function that defines the library instance and imported only the functionality I needed.
Thanks very much to everyone who was so patient in helping me along. I likely wouldn't have been able to come to a solution without your help.
EDIT: Okay so it wasn't that. It was the location of the LibVLC Plugin Directory. So it was something stupid -.-;
I recently tried those 2 functions:
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(int hwndParent,int hwndChildAfter,String lpszClass, String lpszWindow);
..so far I received only IntPtrs, I know(at least I think) that this returned int is the process ID of the Window, now I want to get window's control text and click on button, how to do that?
I can't find anything around...
This old stackoverflow post is asking pretty much the same question that I have, however using Spy++ I have obtained the controls handle ID. Now what? :)
I am not sure what this process is called where I can obtain the contents of another applications control from a .net application, therefore I am not having much success with results on the old google machine.
I have an MFC application with a listbox that contains data I need to automate a task using a WPF C# application. I would prefer not to use an external lib and don't think it would be too labour intensive once I have found the process and have my C# app take visibility of the respective list control to do what I need.
Can anyone please point me in the right direction as to what I should be looking up or provide some code to get me started. At this point I'm stuck and my little project relies pretty heavily on this. I don't want to use an OCR either.
Thanks,
Ash
To get text from Win32 ListBox control you have to use messages and functions specially for that control, here is a reference :
http://msdn.microsoft.com/en-us/library/windows/desktop/ff485971%28v=vs.85%29.aspx
In your case you should first see how many items are in the listbox with LB_GETCOUNT, and then for each item get text with LB_GETTEXT.
Here is the method that will return items in a list, parameter is ListBox control window handle :
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);
const int LB_GETCOUNT = 0x018B;
const int LB_GETTEXT = 0x0189;
private List<string> GetListBoxContents(IntPtr listBoxHwnd)
{
int cnt = (int)SendMessage(listBoxHwnd, LB_GETCOUNT, IntPtr.Zero, null);
List<string> listBoxContent = new List<string>();
for (int i = 0; i < cnt; i++)
{
StringBuilder sb = new StringBuilder(256);
IntPtr getText = SendMessage(listBoxHwnd, LB_GETTEXT, (IntPtr)i, sb);
listBoxContent.Add(sb.ToString());
}
return listBoxContent;
}
This question's answer should get you started. Google P/Invoke and FindWindow() / GetWindowText() family of methods.
Hope that helps.
HI all,
I would like to call from my C# code, unamanaged library functions like presented below. There are two options and the both works. In this moment "Beep" function is simple and have no input/output parameters, pointers, references... I am wondering in more complex cases what would be adventages and disadvantage of both approches ?
Thanks,
Milan.
[DllImport("kernel32.dll")]
public static extern bool Beep(uint iFreq, uint iDuration);
public void TestBeep()
{
Beep(300, 3000);
}
internal delegate bool DelegBeep(uint iFreq, uint iDuration);
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(String dllname);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetProcAddress(IntPtr hModule, String procName);
public void BeepIt()
{
IntPtr kernel32 = LoadLibrary("Kernel32.dll");
IntPtr procBeep = GetProcAddress(kernel32, "Beep");
DelegBeep delegBeep = Marshal.GetDelegateForFunctionPointer(procBeep, typeof(DelegBeep)) as DelegBeep;
delegBeep(50, 1000);//Hz,ms
}
Your second one is much more complicated than the first but achieves the same thing in this case.
If the name of the DLL and the name of the function are known at compile time, then stick with the first approach. If you don't know the name of the DLL and/or function until run time then the LoadLibary/GetProcAddress approach is your only option.
The P/Invoke marshaller finds an entrypoint in a DLL by using LoadLibrary() and GetProcAddress(). And knows how to convert a C# declaration to the equivalent of a delegate declaration.
Doing this yourself has no advantage beyond maybe a wee bit of efficiency. Which you'd better measure, it is no slamdunk.