Met*_*dja 3 pinvoke f# dllimport
我正在研究一个F#控制台应用程序.在属性中,我将应用程序的输出类型设置为Windows应用程序以隐藏控制台.我还创建了一个在其位置运行的表单.目前我只有一个没有控件的简单表单.为了使形式我添加referances到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);
Run Code Online (Sandbox Code Playgroud)
来自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);
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止在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*))
Run Code Online (Sandbox Code Playgroud)
来自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*))
Run Code Online (Sandbox Code Playgroud)
我一直在寻找,但我找不到任何关于ref在F#中使用这样的参数.我知道用C#写这个会容易得多,但是表格背后的代码更容易编写F#,因为它是一种函数式编程语言,而我正在编写的整个程序都是以函数为导向的.我知道这是纯粹的装饰,但请帮忙.
通常,F#中的extern(AKA P/Invoke或平台调用)定义使用类似C的语法(并注意它extern不是extend):
[<DllImport("dwmapi.dll")>]
extern int DwmExtendFrameIntoClientArea(nativeint hWnd, MARGINS& pMarInset)
Run Code Online (Sandbox Code Playgroud)
然后可以按如下方式使用:
let mutable margin = ...
let result = DwmExtendFrameIntoClientArea(this.Handle, &margin)
Run Code Online (Sandbox Code Playgroud)
请注意,您定义的方式MARGINS与C#定义不太相似.各种val定义不可变,实际上是属性而不是字段(虽然它们是由字段支持的,所以它可能不是什么大问题).如果您希望它们是可变字段,则可以为每个字段添加mutable关键字val:
[<Struct; StructLayout(LayoutKind.Sequential)>]
type MARGINS =
val mutable cxLeftWidth : int
val mutable cxRightWidth : int
val mutable cyTopHeight : int
val mutable cyBottomHeight: int
Run Code Online (Sandbox Code Playgroud)
(我也使用了Struct属性而不是struct ... end,但这只是为了简洁).您可以像在C#中一样初始化它,或者使用F#的命名参数:
let mutable margin = MARGINS(cxRightWidth = 100)
Run Code Online (Sandbox Code Playgroud)