samedi 19 avril 2014

C# Windows Mobile 6.5.3 étendre Winform MainMenu - Stack Overflow


what I want to do is to extend the MainMenu of the Windows Mobile Winforms to have a second menu level. If you tip short on the menu button it will do the event action but if you press it longer a second menu level should pop up. The MainMenu is very deficient in its managed functions so I had to find another way. I archived this by deriving MainMenu and add some SubClassing.


public delegate IntPtr Win32WndProc(IntPtr hWnd, int msg, int wParam, int lParam);

[DllImport("coredll.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);

[DllImport("coredll.dll")]
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

[DllImport("coredll")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);

int GWL_WNDPROC = (-4);
int GW_CHILD = 5;

IntPtr _oldToolbarProc;
IntPtr _oldMenuWorkerProc

void Hookup()
{
//find the window to hook
var hWndHooked = FindWindow("HHTaskbar", IntPtr.Zero);
if (hWndHooked == IntPtr.Zero)
return;

//enable the taskbar, not realy necessary
EnableWindow(hWndHooked, true);

//find the menu_worker window
var menuWorkerWnd = FindWindow("menu_worker", IntPtr.Zero);
if (menuWorkerWnd == IntPtr.Zero)
return;

var toolbarWnd = GetWindow(menuWorkerWnd, GW_CHILD);
if (toolbarWnd == IntPtr.Zero)
return;

Win32WndProc newMenuWorker = MenuWorkerProc;
_oldMenuWorkerProc = SetWindowLong(menuWorkerWnd, GWL_WNDPROC, newMenuWorker);

Win32WndProc newToolbar = ToolbarProc;
_oldToolbarProc = SetWindowLong(newToolbarWnd, GWL_WNDPROC, newToolbar);
}

The toolbar subclassing measures the time between WM_LBUTTONDOWN and WM_LBUTTONUP and depending on the time leaped between these events a context Menu is invoked.


If the context menu is invoked the menu_worker subclassing must suppress the WM_COMMAND of the pressed button.


This works fine for a single window. But if I use it on a second form they will recongize both the same toolbar and menuworker and application crashes.


What I tried is to hook and unhook in the onFocus /onLostFocus events of the parent form. But sadly onFocus is called before the right window is visible and it also gets the wrong window handle :(


What I did now (I know a very bad hack) is to start a time in the onFocus event and wait for 1000ms and hook it up then. This results in a 50:50 change to hook the right window..


Isn't there a better solution for subclassing the right window?



what I want to do is to extend the MainMenu of the Windows Mobile Winforms to have a second menu level. If you tip short on the menu button it will do the event action but if you press it longer a second menu level should pop up. The MainMenu is very deficient in its managed functions so I had to find another way. I archived this by deriving MainMenu and add some SubClassing.


public delegate IntPtr Win32WndProc(IntPtr hWnd, int msg, int wParam, int lParam);

[DllImport("coredll.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);

[DllImport("coredll.dll")]
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

[DllImport("coredll")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);

int GWL_WNDPROC = (-4);
int GW_CHILD = 5;

IntPtr _oldToolbarProc;
IntPtr _oldMenuWorkerProc

void Hookup()
{
//find the window to hook
var hWndHooked = FindWindow("HHTaskbar", IntPtr.Zero);
if (hWndHooked == IntPtr.Zero)
return;

//enable the taskbar, not realy necessary
EnableWindow(hWndHooked, true);

//find the menu_worker window
var menuWorkerWnd = FindWindow("menu_worker", IntPtr.Zero);
if (menuWorkerWnd == IntPtr.Zero)
return;

var toolbarWnd = GetWindow(menuWorkerWnd, GW_CHILD);
if (toolbarWnd == IntPtr.Zero)
return;

Win32WndProc newMenuWorker = MenuWorkerProc;
_oldMenuWorkerProc = SetWindowLong(menuWorkerWnd, GWL_WNDPROC, newMenuWorker);

Win32WndProc newToolbar = ToolbarProc;
_oldToolbarProc = SetWindowLong(newToolbarWnd, GWL_WNDPROC, newToolbar);
}

The toolbar subclassing measures the time between WM_LBUTTONDOWN and WM_LBUTTONUP and depending on the time leaped between these events a context Menu is invoked.


If the context menu is invoked the menu_worker subclassing must suppress the WM_COMMAND of the pressed button.


This works fine for a single window. But if I use it on a second form they will recongize both the same toolbar and menuworker and application crashes.


What I tried is to hook and unhook in the onFocus /onLostFocus events of the parent form. But sadly onFocus is called before the right window is visible and it also gets the wrong window handle :(


What I did now (I know a very bad hack) is to start a time in the onFocus event and wait for 1000ms and hook it up then. This results in a 50:50 change to hook the right window..


Isn't there a better solution for subclassing the right window?


0 commentaires:

Enregistrer un commentaire