Es simple, simplemente inserte este código en su clase de Windows.
Este código usa la interoperabilidad para eliminar los estilos WS_MINIMIZEBOX y WS_MAXIMIZEBOX y agrega el estilo extendido WS_EX_CONTEXTHELP (el signo de interrogación solo aparecerá si elimina los botones minimizar y maximizar).
EDITAR: se agregó detección de clic en el botón de ayuda, esto se hace enganchando en el WndProc usando HwndSource.AddHook y escuchando un mensaje WM_SYSCOMMAND con wParam de SC_CONTEXTHELP.
Cuando se detecta un clic, este código mostrará un cuadro de mensaje, cambiando esto a un evento, evento enrutado o incluso un comando (para aplicaciones MVVM) se deja como un ejercicio para el lector.
private const uint WS_EX_CONTEXTHELP = 0x00000400;
private const uint WS_MINIMIZEBOX = 0x00020000;
private const uint WS_MAXIMIZEBOX = 0x00010000;
private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOMOVE = 0x0002;
private const int SWP_NOZORDER = 0x0004;
private const int SWP_FRAMECHANGED = 0x0020;
private const int WM_SYSCOMMAND = 0x0112;
private const int SC_CONTEXTHELP = 0xF180;
[DllImport("user32.dll")]
private static extern uint GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hwnd, int index, uint newStyle);
[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
uint styles = GetWindowLong(hwnd, GWL_STYLE);
styles &= 0xFFFFFFFF^(WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
SetWindowLong(hwnd, GWL_STYLE, styles);
styles = GetWindowLong(hwnd, GWL_EXSTYLE);
styles |= WS_EX_CONTEXTHELP;
SetWindowLong(hwnd, GWL_EXSTYLE, styles);
SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
((HwndSource)PresentationSource.FromVisual(this)).AddHook(HelpHook);
}
private IntPtr HelpHook(IntPtr hwnd,
int msg,
IntPtr wParam,
IntPtr lParam,
ref bool handled)
{
if (msg == WM_SYSCOMMAND &&
((int)wParam & 0xFFF0) == SC_CONTEXTHELP)
{
MessageBox.Show("help");
handled = true;
}
return IntPtr.Zero;
}
¿Por qué la barra de título? La mayoría de las aplicaciones que veo lo colocan en la barra de menú. –
Lo que pasa es que vamos a usarlo principalmente en ventanas de diálogo, que normalmente no tienen una barra de menú. Al hacer clic en él aparecerá la ayuda contextual para esa ventana. Algo así como en MS Word 2007 en la ventana de diálogo de fuentes. – Carlo