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

善缘2022 2009-10-13 01:14:00
我做的一个Winform程序中,用到了FontDialog和ColorDialog,他们默认的位置都是在屏幕的中间,我想改变它的位置,让它随着父窗体的位置而改变,显示在父窗体中间。查了下它本身的属性是没发实现的,网上说调用api,但是不能得到句柄,句柄好像只能再窗体fontDialog1.showDialog()后才可以得到,但是fontDialog1.ShowDialog()后,必须关闭后后面的代码才会执行,但是关闭后就无法得到了。不知道该如何实现,所以向专家提问,希望帮我看看。给出思路也行,回答者都有分,问题解决者得高分。
...全文
635 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
dnfmtzx 2011-10-08
  • 打赏
  • 举报
回复
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);
}
班门弄武 2011-08-29
  • 打赏
  • 举报
回复
楼主,我仍然遇到这样的问题,我copy代码之后哦发现鼠标移动ColorDialog 出现了很多重贴区域.
gtisxgx 2010-03-20
  • 打赏
  • 举报
回复
都是高手,我来瞻仰下
善缘2022 2009-10-17
  • 打赏
  • 举报
回复
感谢大家的回复,在你们的帮助下问题解决了。解决办法:wuyi8808,特别感谢。
mygisforum 2009-10-13
  • 打赏
  • 举报
回复
好东西 mark
yuanhuiqiao 2009-10-13
  • 打赏
  • 举报
回复
//  一.获得当前活动窗口的句柄
//用一下的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);
wuyi8808 2009-10-13
  • 打赏
  • 举报
回复
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;
}
}
ximi82878 2009-10-13
  • 打赏
  • 举报
回复
都是高手,我来瞻仰下
sohighthesky 2009-10-13
  • 打赏
  • 举报
回复
那两个框那么简单,自己用form做一个就可以 了
善缘2022 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 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 )
[/Quote]
VB的代码WindowWrapper 类我转换成C#代码好像有问题,谁能帮我看看,c#代码该如何写,谢谢了。
wuyi8808 2009-10-13
  • 打赏
  • 举报
回复
看看这个有没有帮助:
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
关于消息的附加信息。

sxmonsy 2009-10-13
  • 打赏
  • 举报
回复
楼上的VB代码改成C#的就行了
typeof 2009-10-13
  • 打赏
  • 举报
回复
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);
}
}
Taiyangchen 2009-10-13
  • 打赏
  • 举报
回复
楼上的vb都出来了,汗!
fengling2001 2009-10-13
  • 打赏
  • 举报
回复
一.获得当前活动窗口的句柄
用一下的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 )

110,579

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧