I’m trying to use a class named CFindWnd. Unfortunately it’s written in C and I don’t have a clue how to translate it into C# (or any other language that I know). As it is not a very large class, I am hoping to find a helpful soul that is willing to translate it for me.
////////////////////////////////////////////////////////////////
// MSDN Magazine -- August 2003
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET on Windows XP. Tab size=3.
//
// ---
// This class encapsulates the process of finding a window with a given class name
// as a descendant of a given window. To use it, instantiate like so:
//
// CFindWnd fw(hwndParent,classname);
//
// fw.m_hWnd will be the HWND of the desired window, if found.
//
class CFindWnd {
private:
//////////////////
// This private function is used with EnumChildWindows to find the child
// with a given class name. Returns FALSE if found (to stop enumerating).
//
static BOOL CALLBACK FindChildClassHwnd(HWND hwndParent, LPARAM lParam) {
CFindWnd *pfw = (CFindWnd*)lParam;
HWND hwnd = FindWindowEx(hwndParent, NULL, pfw->m_classname, NULL);
if (hwnd) {
pfw->m_hWnd = hwnd; // found: save it
return FALSE; // stop enumerating
}
EnumChildWindows(hwndParent, FindChildClassHwnd, lParam); // recurse
return TRUE; // keep looking
}
public:
LPCSTR m_classname; // class name to look for
HWND m_hWnd; // HWND if found
// ctor does the work--just instantiate and go
CFindWnd(HWND hwndParent, LPCSTR classname)
: m_hWnd(NULL), m_classname(classname)
{
FindChildClassHwnd(hwndParent, (LPARAM)this);
}
};
EDIT:
I have come up with the following. But I have still trouble converting from object to IntPtr and vice versa.
class CFindWnd
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
private static bool FindChildClassHwnd(IntPtr hwndParent, IntPtr lParam)
{
CFindWnd pfw = lParam as CFindWnd; //??? Error: can not be converted
IntPtr hwnd = FindWindowEx(hwndParent, IntPtr.Zero, pfw.m_classname, IntPtr.Zero);
if (!hwnd.Equals(IntPtr.Zero)) //??? not sure if that is correct
{
pfw.m_hWnd = hwnd; // found: save it
return false; // stop enumerating
}
EnumChildWindows(hwndParent, FindChildClassHwnd, lParam); // recurse
return true; // keep looking
}
public string m_classname; // class name to look for
public IntPtr m_hWnd; // HWND if found
// ctor does the work--just instantiate and go
public CFindWnd(IntPtr hwndParent, string classname)
{
m_hWnd = IntPtr.Zero;
m_classname = classname;
FindChildClassHwnd(hwndParent, this); //??? conversion error
}
}
I have solved it. The solution is not quite a direct translation, because the original seems a bit too roundabout.
Usage: Call the static method handle = CFindWnd.FindHandle(parentHandle, classname) to get the handle of a window that is a descendant of parentHandle and has the name classname.
Example: Assuming you have a webbrowser control and want to manipulate the underlying Internet Explorer_Server directly, you can use CFindWnd.FindHandle(webbrowser.Handle, “Internet Explorer_Server”) to get it’s handle.