2011-01-18 38 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