在 F# (PInvoke) 中扩展 Aero Glass
我正在开发 F# 控制台应用程序。在属性中,我将应用程序的输出类型设置为“Windows 应用程序”以隐藏控制台。我还创建了一个表单来代替它运行。目前我只有一个没有控件的简单表单。为了制作表单,我添加了对 System.Windows.Forms 和 System.Drawing 的引用,并将它们与 System.Runtime.InteropServices 一起打开。
我不知道该怎么做的部分是延长航空玻璃。有很多关于如何在 C# 中执行此操作的示例。例如,这里是 API 调用和 MARGINS 结构:
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("dwmapi.dll")]
pubic static extend int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
来自 Form_Load 事件的 API 调用:
MARGINS margins = new MARGINS();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 100;
margins.cyTopHeight = 0;
margins.cyBottomHeight = 0;
int result = DwmExtendFrameIntoClientArea(this.Handle, ref margins);
这是我到目前为止在 F# 中得到的:
API 调用和 MARGINS 结构:
[<StructLayout(LayoutKind.Sequential)>]
type MARGINS =
struct
val cxLeftWidth : int
val cxRightWidth : int
val cyTopHeight : int
val cyBottomHeigh t: int
new(left, right, top, bottom) = { cxLeftWidth = left; cxRightWidth = right; cyTopHeight = top; cyBottomHeigh = bottom } (*Is there any other way to do this?*)
end
[<DllImport("dwmapi.dll")>]
extend int DwmExtendFrameIntoClientArea(IntPtr hWnd, (*I need help here*))
来自 Form_Load 事件的 API 调用:
let margins = new MARGINS(0, 100, 0, 0); (*Is there any other way to do this?*)
let result : int = DwmExtendFrameIntoClientArea(this.Handle, (*I need help here*))
我一直在搜索但我在 F# 中找不到任何有关使用 ref 参数的信息。我知道用 C# 编写会容易得多,但用 int F# 编写表单背后的代码会更容易,因为它是一种函数式编程语言,而且我正在编写的整个程序都是围绕函数进行的。我知道这纯粹是装饰性的,但请帮忙。
I'm working on a F# console application. In the properties I set the output type of application to Windows Application to hide the console. I also created a form to run in its place. Currently I only have a simple form with no controls. To make the form I added referances to System.Windows.Forms
and System.Drawing
and opened them along with System.Runtime.InteropServices
.
The part that I don't know how to do is extending the aero-glass. There are loads of exaples on how to do it in C#. For example, here is the API call and MARGINS structure:
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("dwmapi.dll")]
pubic static extend int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
The API call from Form_Load event:
MARGINS margins = new MARGINS();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 100;
margins.cyTopHeight = 0;
margins.cyBottomHeight = 0;
int result = DwmExtendFrameIntoClientArea(this.Handle, ref margins);
This is what I've got so far in F#:
The API call and MARGINS structure:
[<StructLayout(LayoutKind.Sequential)>]
type MARGINS =
struct
val cxLeftWidth : int
val cxRightWidth : int
val cyTopHeight : int
val cyBottomHeigh t: int
new(left, right, top, bottom) = { cxLeftWidth = left; cxRightWidth = right; cyTopHeight = top; cyBottomHeigh = bottom } (*Is there any other way to do this?*)
end
[<DllImport("dwmapi.dll")>]
extend int DwmExtendFrameIntoClientArea(IntPtr hWnd, (*I need help here*))
The API call from Form_Load event:
let margins = new MARGINS(0, 100, 0, 0); (*Is there any other way to do this?*)
let result : int = DwmExtendFrameIntoClientArea(this.Handle, (*I need help here*))
I have been searching around but I can't find anything about using ref
parameters like this in F#. I know this would be a lot easier to write in C# but the code behind the form will be easier to write int F# because it's a functional programing language and the whole program I'm writing is orientated around functions. I know this is purely decorative but please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一般来说,
extern
(又名这可以是使用方式如下:
请注意,定义
MARGINS
的方式与 C# 定义不太相似。各种val
定义是不可变的,实际上是属性而不是字段(尽管它们由字段支持,所以这可能不是什么大问题)。如果您希望它们成为可变字段,则可以在每个字段的val
之后添加mutable
关键字:(我还使用了
Struct
attribute 而不是 struct ... end,但这只是为了简洁起见)。您可以像在 C# 中那样初始化它,或者使用 F# 的命名参数:In general,
extern
(AKA P/Invoke or platform invoke) definitions in F# use C-like syntax (and note that it'sextern
, notextend
):This can then be used as follows:
Note that the way that you have defined
MARGINS
is not quite analogous to the C# definition. The variousval
definitions are not mutable, and are actually properties rather than fields (though they're backed by fields, so it's probably not a big deal). If you want them to be mutable fields, you can add themutable
keyword afterval
for each field:(I've also used the
Struct
attribute instead ofstruct ... end
, but that's just for brevity). You can initialize this like you do in C#, or using F#'s named arguments: