向专家提问:C#如何改变FontDialog的位置(高分)

时间:2022-11-01 14:35:42
     我做的一个Winform程序中,用到了FontDialog和ColorDialog,他们默认的位置都是在屏幕的中间,我想改变它的位置,让它随着父窗体的位置而改变,显示在父窗体中间。查了下它本身的属性是没发实现的,网上说调用api,但是不能得到句柄,句柄好像只能再窗体fontDialog1.showDialog()后才可以得到,但是fontDialog1.ShowDialog()后,必须关闭后后面的代码才会执行,但是关闭后就无法得到了。不知道该如何实现,所以向专家提问,希望帮我看看。给出思路也行,回答者都有分,问题解决者得高分。

16 个解决方案

#1


该回复于2010-01-19 17:25:00被版主删除

#2


一.获得当前活动窗口的句柄
  用一下的API函数获得
  Declare Function GetForegroundWindow Lib "user32" Alias "GetActiveWindow" () As System.IntPtr
二.重新声明 IWin32Window 接口
    Public Class WindowWrapper
        Implements System.Windows.Forms.IWin32Window
        Private _hwnd As System.IntPtr

        Public Sub New(ByVal handle As System.IntPtr)
            _hwnd = handle
        End Sub

        Private ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _hwnd
            End Get
        End Property
    End Class
三. 把当前活动的句柄转化成IWin32Window 接口,并Show窗体,这样就可以达到两个不
    同线程的窗体粘在一快了。
      Dim IntPart As System.IntPtr
            IntPart = GetForegroundWindow()
            Dim OwinForm As WindowWrapper
            OwinForm = New WindowWrapper(IntPart)
          Form.show(OwinForm ) 

#3


楼上的vb都出来了,汗!

#4


楼上的VB代码改成C#的就行了

#5


看看这个有没有帮助:
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.commondialog.hookproc.aspx
.NET Framework 类库
CommonDialog.HookProc 方法

定义要重写的通用对话框挂钩过程,以便向通用对话框添加特定功能。

[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected virtual IntPtr HookProc(
    IntPtr hWnd,
    int msg,
    IntPtr wparam,
    IntPtr lparam
)


参数
hWnd
类型:System.IntPtr
对话框窗口的句柄。


msg
类型:System.Int32
正在接收的消息。

wparam
类型:System.IntPtr
关于消息的附加信息。

lparam
类型:System.IntPtr
关于消息的附加信息。

#6


引用 2 楼 fengling2001 的回复:
一.获得当前活动窗口的句柄
  用一下的API函数获得
  Declare Function GetForegroundWindow Lib "user32" Alias "GetActiveWindow" () As System.IntPtr
二.重新声明 IWin32Window 接口
    Public Class WindowWrapper
        Implements System.Windows.Forms.IWin32Window
        Private _hwnd As System.IntPtr

        Public Sub New(ByVal handle As System.IntPtr)
            _hwnd = handle
        End Sub

        Private ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _hwnd
            End Get
        End Property
    End Class
三. 把当前活动的句柄转化成IWin32Window 接口,并Show窗体,这样就可以达到两个不
    同线程的窗体粘在一快了。
      Dim IntPart As System.IntPtr
            IntPart = GetForegroundWindow()
            Dim OwinForm As WindowWrapper
            OwinForm = New WindowWrapper(IntPart)
          Form.show(OwinForm )

VB的代码WindowWrapper 类我转换成C#代码好像有问题,谁能帮我看看,c#代码该如何写,谢谢了。

#7


那两个框那么简单,自己用form做一个就可以 了

#8


都是高手,我来瞻仰下

#9


using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class Form1 : Form
{
  Form1()
  {
    Button btn = new Button();
    btn.Parent = this;
    btn.Text   = "Font";
    btn.Click += delegate { new MyFontDialog(50, 80).ShowDialog(); };
  }
  
  [STAThread]
  static void Main()
  {
    Application.Run(new Form1());  
  }
}

class MyFontDialog : FontDialog
{
  const int WM_INITDIALOG = 0x0110;
  const int SWP_NOSIZE    = 0x0001;
  const int SWP_NOZORDER  = 0x0004;

  [DllImport("user32.dll")]
  static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] 
  protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
  {
    SetWindowPos(hWnd, (IntPtr)0, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    return base.HookProc(hWnd, msg, wParam, lParam);
  }
  
  // 窗口的位置
  int Left, Top;
  
  public MyFontDialog(int x, int y)
  {
    Left = x;
    Top  = y;
  }
}

#10


//  一.获得当前活动窗口的句柄
//用一下的API函数获得
[DllImport("user32")]
public static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

//二.重新声明 IWin32Window 接口
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    private System.IntPtr _hwnd;
    
    public WindowWrapper(System.IntPtr handle)
    {
        _hwnd = handle;
    }

    public  System.IntPtr Handle
    {
        get { return _hwnd; }
    }
}

//三. 把当前活动的句柄转化成IWin32Window 接口,并Show窗体,这样就可以达到两个不
 //    同线程的窗体粘在一快了。
System.IntPtr IntPart = GetForegroundWindow();
WindowWrapper OwinForm = new WindowWrapper(IntPart);
Form test = new Form();
test.Show(OwinForm);

#11


好东西 mark

#12


using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class FontDialog : System.Windows.Forms.FontDialog
{
  public int   Left     { get { return r.Left    ; } set { r.Left     = value; } }
  public int   Top      { get { return r.Top     ; } set { r.Top      = value; } }
  public int   Width    { get { return r.Width   ; } set { r.Width    = value; } }
  public int   Height   { get { return r.Height  ; } set { r.Height   = value; } }
  public Point Location { get { return r.Location; } set { r.Location = value; } }
  public Size  Size     { get { return r.Size    ; } }

  Rect r;

  const uint SWP_NOSIZE   = 1;
  const uint SWP_NOZORDER = 4;

  [DllImport("user32.dll")]   
  static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);

  [DllImport("user32.dll")]
  static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
  protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
  {
    SetWindowPos(hWnd, (IntPtr)0, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    GetWindowRect(hWnd, ref r);
    return base.HookProc(hWnd, msg, wParam, lParam);
  }
}

class Form1 : Form
{
  Form1()
  {
    Button btn = new Button();
    btn.Parent = this;
    btn.Text   = "&Font";
    btn.Click += delegate
    {
      FontDialog fd = new FontDialog();
      fd.Location = new Point(10, 50);
      fd.ShowDialog();
    };
  }

  static void Main()
  {
    Application.Run(new Form1());
  }
}

[StructLayout(LayoutKind.Sequential)]
public struct Rect 

  public int Left; 
  public int Top; 
  public int Right; 
  public int Bottom;

  public int Width  { get { return Right - Left; } set { Right = Left + value; } }
  public int Height { get { return Bottom - Top; } set { Bottom = Top + value; } }

  public Size Size
  {
    get { return new Size(Width, Height); }
    set { Width = value.Width; Height = value.Height; }
  }

  public Point Location
  {
    get { return new Point(Left, Top); }
    set { Right -= (Left - value.X); Bottom -= (Bottom - value.Y); Left = value.X; Top = value.Y; }
  }

  public override string ToString()
  {
    return string.Format("{{X={0},Y={1},Width={2},Height={3}}}", Left, Top, Width, Height);
  }
}

#13


感谢大家的回复,在你们的帮助下问题解决了。解决办法:*8808,特别感谢。

#14


都是高手,我来瞻仰下

#15


楼主,我仍然遇到这样的问题,我copy代码之后哦发现鼠标移动ColorDialog 出现了很多重贴区域.

#16


12楼的方法可以,只是不能移动,被固定在初始位置,即15楼描述的问题.
 HookProc中第一句和第二句调换位置就可以了.
即:
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
  protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
  {
    GetWindowRect(hWnd, ref r);
    SetWindowPos(hWnd, (IntPtr)0, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);    
    return base.HookProc(hWnd, msg, wParam, lParam);
  }

#1


该回复于2010-01-19 17:25:00被版主删除

#2


一.获得当前活动窗口的句柄
  用一下的API函数获得
  Declare Function GetForegroundWindow Lib "user32" Alias "GetActiveWindow" () As System.IntPtr
二.重新声明 IWin32Window 接口
    Public Class WindowWrapper
        Implements System.Windows.Forms.IWin32Window
        Private _hwnd As System.IntPtr

        Public Sub New(ByVal handle As System.IntPtr)
            _hwnd = handle
        End Sub

        Private ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _hwnd
            End Get
        End Property
    End Class
三. 把当前活动的句柄转化成IWin32Window 接口,并Show窗体,这样就可以达到两个不
    同线程的窗体粘在一快了。
      Dim IntPart As System.IntPtr
            IntPart = GetForegroundWindow()
            Dim OwinForm As WindowWrapper
            OwinForm = New WindowWrapper(IntPart)
          Form.show(OwinForm ) 

#3


楼上的vb都出来了,汗!

#4


楼上的VB代码改成C#的就行了

#5


看看这个有没有帮助:
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.commondialog.hookproc.aspx
.NET Framework 类库
CommonDialog.HookProc 方法

定义要重写的通用对话框挂钩过程,以便向通用对话框添加特定功能。

[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected virtual IntPtr HookProc(
    IntPtr hWnd,
    int msg,
    IntPtr wparam,
    IntPtr lparam
)


参数
hWnd
类型:System.IntPtr
对话框窗口的句柄。


msg
类型:System.Int32
正在接收的消息。

wparam
类型:System.IntPtr
关于消息的附加信息。

lparam
类型:System.IntPtr
关于消息的附加信息。

#6


引用 2 楼 fengling2001 的回复:
一.获得当前活动窗口的句柄
  用一下的API函数获得
  Declare Function GetForegroundWindow Lib "user32" Alias "GetActiveWindow" () As System.IntPtr
二.重新声明 IWin32Window 接口
    Public Class WindowWrapper
        Implements System.Windows.Forms.IWin32Window
        Private _hwnd As System.IntPtr

        Public Sub New(ByVal handle As System.IntPtr)
            _hwnd = handle
        End Sub

        Private ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _hwnd
            End Get
        End Property
    End Class
三. 把当前活动的句柄转化成IWin32Window 接口,并Show窗体,这样就可以达到两个不
    同线程的窗体粘在一快了。
      Dim IntPart As System.IntPtr
            IntPart = GetForegroundWindow()
            Dim OwinForm As WindowWrapper
            OwinForm = New WindowWrapper(IntPart)
          Form.show(OwinForm )

VB的代码WindowWrapper 类我转换成C#代码好像有问题,谁能帮我看看,c#代码该如何写,谢谢了。

#7


那两个框那么简单,自己用form做一个就可以 了

#8


都是高手,我来瞻仰下

#9


using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class Form1 : Form
{
  Form1()
  {
    Button btn = new Button();
    btn.Parent = this;
    btn.Text   = "Font";
    btn.Click += delegate { new MyFontDialog(50, 80).ShowDialog(); };
  }
  
  [STAThread]
  static void Main()
  {
    Application.Run(new Form1());  
  }
}

class MyFontDialog : FontDialog
{
  const int WM_INITDIALOG = 0x0110;
  const int SWP_NOSIZE    = 0x0001;
  const int SWP_NOZORDER  = 0x0004;

  [DllImport("user32.dll")]
  static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] 
  protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
  {
    SetWindowPos(hWnd, (IntPtr)0, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    return base.HookProc(hWnd, msg, wParam, lParam);
  }
  
  // 窗口的位置
  int Left, Top;
  
  public MyFontDialog(int x, int y)
  {
    Left = x;
    Top  = y;
  }
}

#10


//  一.获得当前活动窗口的句柄
//用一下的API函数获得
[DllImport("user32")]
public static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

//二.重新声明 IWin32Window 接口
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    private System.IntPtr _hwnd;
    
    public WindowWrapper(System.IntPtr handle)
    {
        _hwnd = handle;
    }

    public  System.IntPtr Handle
    {
        get { return _hwnd; }
    }
}

//三. 把当前活动的句柄转化成IWin32Window 接口,并Show窗体,这样就可以达到两个不
 //    同线程的窗体粘在一快了。
System.IntPtr IntPart = GetForegroundWindow();
WindowWrapper OwinForm = new WindowWrapper(IntPart);
Form test = new Form();
test.Show(OwinForm);

#11


好东西 mark

#12


using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class FontDialog : System.Windows.Forms.FontDialog
{
  public int   Left     { get { return r.Left    ; } set { r.Left     = value; } }
  public int   Top      { get { return r.Top     ; } set { r.Top      = value; } }
  public int   Width    { get { return r.Width   ; } set { r.Width    = value; } }
  public int   Height   { get { return r.Height  ; } set { r.Height   = value; } }
  public Point Location { get { return r.Location; } set { r.Location = value; } }
  public Size  Size     { get { return r.Size    ; } }

  Rect r;

  const uint SWP_NOSIZE   = 1;
  const uint SWP_NOZORDER = 4;

  [DllImport("user32.dll")]   
  static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);

  [DllImport("user32.dll")]
  static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
  protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
  {
    SetWindowPos(hWnd, (IntPtr)0, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    GetWindowRect(hWnd, ref r);
    return base.HookProc(hWnd, msg, wParam, lParam);
  }
}

class Form1 : Form
{
  Form1()
  {
    Button btn = new Button();
    btn.Parent = this;
    btn.Text   = "&Font";
    btn.Click += delegate
    {
      FontDialog fd = new FontDialog();
      fd.Location = new Point(10, 50);
      fd.ShowDialog();
    };
  }

  static void Main()
  {
    Application.Run(new Form1());
  }
}

[StructLayout(LayoutKind.Sequential)]
public struct Rect 

  public int Left; 
  public int Top; 
  public int Right; 
  public int Bottom;

  public int Width  { get { return Right - Left; } set { Right = Left + value; } }
  public int Height { get { return Bottom - Top; } set { Bottom = Top + value; } }

  public Size Size
  {
    get { return new Size(Width, Height); }
    set { Width = value.Width; Height = value.Height; }
  }

  public Point Location
  {
    get { return new Point(Left, Top); }
    set { Right -= (Left - value.X); Bottom -= (Bottom - value.Y); Left = value.X; Top = value.Y; }
  }

  public override string ToString()
  {
    return string.Format("{{X={0},Y={1},Width={2},Height={3}}}", Left, Top, Width, Height);
  }
}

#13


感谢大家的回复,在你们的帮助下问题解决了。解决办法:*8808,特别感谢。

#14


都是高手,我来瞻仰下

#15


楼主,我仍然遇到这样的问题,我copy代码之后哦发现鼠标移动ColorDialog 出现了很多重贴区域.

#16


12楼的方法可以,只是不能移动,被固定在初始位置,即15楼描述的问题.
 HookProc中第一句和第二句调换位置就可以了.
即:
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
  protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
  {
    GetWindowRect(hWnd, ref r);
    SetWindowPos(hWnd, (IntPtr)0, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);    
    return base.HookProc(hWnd, msg, wParam, lParam);
  }