È semplice, basta inserire questo codice nella classe Window.
Questo codice utilizza l'interoperabilità per rimuovere gli stili WS_MINIMIZEBOX e WS_MAXIMIZEBOX e aggiungere lo stile esteso WS_EX_CONTEXTHELP (il punto interrogativo verrà visualizzato solo se si rimuovono i pulsanti di riduzione a icona e ingrandimento).
MODIFICA: aggiunta rilevazione di clic sul pulsante di aiuto, questa operazione viene eseguita collegandosi a WndProc utilizzando HwndSource.AddHook e ascoltando un messaggio WM_SYSCOMMAND con wParam di SC_CONTEXTHELP.
Quando viene rilevato un clic questo codice mostrerà una finestra di messaggio, cambiando questo in un evento, evento indirizzato o anche un comando (per le app MVVM) viene lasciato come esercizio per il lettore.
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;
}
Perché la barra del titolo? La maggior parte delle app che vedo lo metto nella barra dei menu. –
Il problema è che lo useremo principalmente nelle finestre di dialogo, che di solito non hanno una barra dei menu. Facendo clic su di esso verrà visualizzato l'aiuto contestuale per quella finestra. Qualcosa come in MS Word 2007 nella finestra di dialogo dei caratteri. – Carlo