2011-01-18 59 views
3

我正在开发一个F#控制台应用程序。在属性中,我将应用程序的输出类型设置为Windows应用程序以隐藏控制台。我也创建了一个表单来代替它。目前我只有一个没有控件的简单表单。为了制作表格,我添加了对System.Windows.FormsSystem.Drawing的引用,并将它们与System.Runtime.InteropServices一起打开。在F#中扩展Aero Glass(PInvoke)

我不知道该怎么做的部分是扩展气动玻璃。有很多关于如何在C#中使用Exaples的例子。例如,这里是API调用和利润结构:

[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调用和利润结构:

[<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#代码后面的代码会更容易,因为它是一种功能性编程语言,我正在编写的整个程序都是围绕函数定向的。我知道这是纯粹的装饰,但请帮助。

回答

5

在一般情况下,在F#中使用类似C的语法extern(AKA P/Invoke或平台调用)的定义(请注意,这是extern,不extend):

[<DllImport("dwmapi.dll")>] 
extern int DwmExtendFrameIntoClientArea(nativeint hWnd, MARGINS& pMarInset) 

然后可以使用如下:

let mutable margin = ... 
let result = DwmExtendFrameIntoClientArea(this.Handle, &margin) 

请注意,您定义MARGINS的方式与C#定义不太相似。各种val定义是不可变的,实际上是属性而不是字段(虽然它们由字段支持,所以它可能不是什么大不了的)。如果你想他们是可变的字段,可以val后添加mutable关键字为每个字段:

[<Struct; StructLayout(LayoutKind.Sequential)>] 
type MARGINS = 
    val mutable cxLeftWidth : int   
    val mutable cxRightWidth : int   
    val mutable cyTopHeight : int   
    val mutable cyBottomHeight: int 

(我也用了Struct属性,而不是struct ... end,但是这只是为了简洁)。您可以像在C#中那样初始化,或使用F#的命名参数进行初始化:

let mutable margin = MARGINS(cxRightWidth = 100) 
+0

`[]`从我理解的这是结构的默认设置,是否正确? – 2014-08-08 16:15:57