1
votes

I am working on a C# XNA screensaver kit and so far, everything is in place except for the configuration dialog which must be modal to the Screen Saver Settings dialog provided by windows ("/c:<hwnd>" argument).

My benchmark is Vistas builtin 3D Text screensaver - my code shall provide the same features and regarding the configuration dialog, 3D Text displays fully modal to the Screen Saver Settings dialog and when clicking Screen Saver Settings dialog, the dialogs blink without accepting the click.

I have tried the method of wrapping the HWND with a IWin32Window as suggested by Ryan Farley, but even though my dialog displays on top of the Screen Saver Settings dialog, the controls in Screen Saver Settings dialog still can be clicked.

So do I need some exotic Win32API calls to inform the parent dialog that it has been modalized or does a more clean solution exist?

3

3 Answers

0
votes

Try calling the SetParent API function.

0
votes

Actually, it turned out that the HWND provided by windows to the screensaver is a child of the settings dialog, so by calling GetParent on the HWND, I get an HWND that represents the dialog.

Today is the day that I wrote my first question on stackoverflow.com and answered the first question.

0
votes

I had the same problem. Additionally I was not able to directly hook a dialog to a foreign window with .NET. Therefore I supply a work around to hook a dialog to the parent of a given window handle:

public class CHelpWindow : Form
{ // this class hooks to a foreign window handle and then it starts a
  // modal dialog to this form; .NET seems not to be able to hook a dialog 
  // to a foreign window handle directly: therefore this solution

  // retrieves the parent window of the passed child
  [DllImport("user32.dll")]
  private static extern IntPtr GetParent (IntPtr hWndChild);

  // changes the parent window of the passed child
  [DllImport("user32.dll")]
  private static extern IntPtr SetParent
    (IntPtr hWndChild, IntPtr hWndNewParent);

  // --------------------------------------------------------------------
  public CHelpWindow (long liHandle)
  // this constructor initializes this form and hooks this form to the parent
  // of the passed window handle; then it prepares the call to create the
  // dialog after this form window is first shown in the screen.
  {
    // removing the system title of the window
    FormBorderStyle = FormBorderStyle.None;
    // the dialog will be created when this form is first shown
    Shown += new EventHandler (HelpWindow_Shown);

    // hooking to the parent of the passed handle: that is the control, not
    // the tab of the screen saver dialog
    IntPtr oParent = GetParent (new IntPtr (liHandle));
    SetParent (Handle, oParent);
  }

  // --------------------------------------------------------------------
  private void HelpWindow_Shown (object oSender, EventArgs oEventArgs)
  // this function is called when the form is first shown; now is the right
  // time to start our configuration dialog
  {
    // positioning this window outside the parent area
    Location   = new Point (-100, -100);
    // reducing the size
    Size       = new Size (1, 1);
    ClientSize = new Size (1, 1);
    // creating the dialog
    CKonfiguration oConfiguration = new CKonfiguration ();
    // starting this dialog with the owner of this object; because this
    // form is hooked to the screen saver dialog, the startet dialog is
    // then indirectly hooked to that dialog
    oConfiguration.ShowDialog (this);
    // we don not need this object any longer
    Close ();
  }
}

After extracting your handle from the command line

/c:####

you create your Dialog by

CHelpWindow oHelpWindow = new CHelpWindow (liHandle);
oHelpWindow.ShowDialog ();

Reimer