c语言如何把菜单内容包裹在矩形内?

cairo_fill(cr); //填充,使用的颜色当然是上面设置的颜色。
  • 第01章 JAVA简介第02章 基础语法第02章 递归补充第03章 面向对象第04章 异常处理第05章 数组第06...

  • 编译时与运行时 编译时: 即编译器对语言的编译阶段,编译时只是对语言进行最基本的检查报错,包括词法分析、语法分析等...

  • 今天是我们这里特殊的日子。有一百对新人在江布拉克风景区旅行大型的婚礼,有很多地方的朋友们都慕名而来。看看这里的水,...

  • 卧室、厨房间、客厅在装修过程中总有一些小细节我们会忽略, 这可能还我们的生活习惯以及专业知识有关系,不过这都不重要...

之间的相互调用 我们最常见就是使用它来调用C#的代码方法或者C#生成的DLL文件的方法 C/C++生成的DLL就要用Node-ffi 因为我是要调用系统的DLL所以主要使用Node-ffi

node-ffi是一个用于使用纯JavaScript加载和调用动态库的Node.js插件。它可以用来在不编写任何C ++代码的情况下创建与本地DLL库的绑定。同时它负责处理跨JavaScript和C的类型转换。

  1. 不要求开发者编写C代码,但是仍要求开发者具有一定C的知识。
  1. 类似其他语言的FFI调试,此方法近似黑盒调用, 查错比较困难。

  • 需要使用系统 API 操作或扩展应用程序;
  • 需要调用第三方的接口API,特别是与硬件设备进行通信,而这些接口 API 基本上都是通过 C++ 动态链接库(DLL)实现的;
  • 需要调用C++实现的一些复杂算法等。

node-ffi通过Buffer类,在C代码和JS代码之间实现了内存共享,类型转换则是通过、、实现。由于node-ffi/ref包含C原生代码,所以安装需要配置Node原生插件编译环境。

// `ffi.Library`用于注册函数,第一个入参为DLL路径,最好为文件绝对路径 // My_Test是dll中定义的函数,两者名称需要一致

C语言中有4种基础数据类型—-整型 浮点型 指针 聚合类型

整型、字符型都有分有符号和无符号两种。

ref库中已经帮我们准备好了基础类型的对应关系。

字符型由char构成,在GBK编码中一个汉字占2个字节,在UTF-8中占用3~4个字节。一个ref.types.char默认一字节。根据所需字符长度创建足够长的内存空间。这时候需要使用ref-array库。

在传递中文字符型时,必须预先得知DLL库的编码方式。node默认使用UTF-8编码。若DLL不为UTF-8编码则需要转码,推荐使用iconv-lite

*设置的返回值,通常返回的文本并不是定长,不会完全使用预分配的空间,末尾则会是无用的值。如果是预初始化的值,一般末尾是一大串的0x00,需要手动做trimEnd,如果不是预初始化的值,则末尾不定值,需要C代码明确返回字符串数组的长度returnValueLength

ffi中内置了一些简写

只建议使用’string’。

字符串虽然在js中被认为是基本类型,但在C语言中是以对象的形式来表示的,所以被认为是引用类型。所以string其实是char* 而不是char

遇到定义为多维数组的基本类型 则需要使用ref-array进行创建

结构体是C中常用的类型,需要用到ref-struct进行创建

指针是一个变量,其值为实际变量的地址,即内存位置的直接地址,有些类似于JS中的引用对象。

C语言中使用*来代表指针

例如 int* a 则就是 整数型a变量的指针 , &用于表示取地址

node-ffi实现指针的原理是借助ref,使用Buffer类在C代码和JS代码之间实现了内存共享,让Buffer成为了C语言当中的指针。

注意,一旦引用ref,会修改Bufferprototype,替换和注入一些方法,请参考文档

要明确一下两个概念 一个是结构类型,一个是指针类型,通过代码来说明。

// 申明一个类的实例
// 结构类型对应的指针类型
 

C的回调函数一般是用作入参传入。


 // 根据结构体类型 开辟一个新的内存空间
 // 开辟一个int 4字节内存空间
 

  1. 通常是传入的DLL路径错误,找不到Dll文件,推荐使用绝对路径。
  2. 如果是在x64的node/electron下引用32位的DLL,也会报这个错,反之亦然。要确保DLL要求的CPU架构和你的运行环境相同。
  3. DLL还有引用其他DLL文件,但是找不到引用的DLL文件,可能是VC依赖库或者多个DLL之间存在依赖关系。

如果你的DLL是多个而且存在相互调用问题,会出现Dynamic Linking Error: Win32 error 126错误3。这是由于默认的进程Path是二进制文件所在目录,即node.exe/electron.exe目录而不是DLL所在目录,导致找不到DLL同目录下的其他引用。可以通过如下方法解决:

//方法二(推荐),设置Path环境环境

实际node-ffi调试的时候,很容易出现内存错误闪崩,甚至会出现断点导致崩溃的情况。这个是往往是因为非法内存访问造成,可以通过Windows日志看到错误信息,但是相信我,那并没有什么用。C的内存差错是不是一件简单的事情。

winapi中,经常通过判断返回的pvoid指针是否存在来判断是否成功,但是在node-ffi中,对FFFFFFFF的内存地址deref()会造成程序闪崩。必须迂回采用指针的指针类型进行特判

  1. 可以查看DLL链接库的所有信息、以及DLL依赖关系的工具,但是很遗憾不支持WIN10。如果你不是WIN10用户,那么你只需要这一个工具即可,下面工具可以跳过。
  2. error错误原因3,可以查看ffi.Libary时的所有IO请求和对应结果,查看缺少了什么DLL

tjfontaine大神提供了一个,可以根据头文件,自动生成node-ffi函数申明,注意这个需要Linux环境,简单用KOA包了一层改成了在线模式,可以丢到VPS中运行。

winapi存在大量的自定义的变量类型,waitingsong大侠的轮子 中完整翻译了全套windef.h中的类型,而且这个项目采用TS来规定FFI的返回Interface,很值得借鉴。

注意!里面的类型不一定都是对的,相信作者也没有完整的测试过所有变量,实际使用中也遇到过里面类型错误的坑。

再运行项目,系统菜单就消失的无影无踪了。

/// 该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。hWnd:设备上下文环境被检索的窗口的句柄 /// 函数释放设备上下文环境(DC)供其他应用程序使用。 /// 该函数返回桌面窗口的句柄。桌面窗口覆盖整个屏幕。 /// 该函数设置指定窗口的显示状态。 /// 通过发送重绘消息 WM_PAINT 给目标窗体来更新目标窗体客户区的无效区域。 /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。 /// 该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z序。 /// 将存放有数据的内存块放入剪切板的资源管理中 /// 在一个矩形中装载指定菜单条目的屏幕坐标信息 /// 该函数获得一个指定子窗口的父窗口句柄。 /// 该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。  /// 该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里 /// 该函数对指定的窗口设置键盘焦点。 /// 该函数在指定的矩形里写入格式化文本,根据指定的方法对文本格式化(扩展的制表符,字符对齐、折行等)。 /// 该函数改变指定子窗口的父窗口。 /// 获取对话框中子窗口控件的句柄 /// 该函数获取窗口客户区的坐标。 /// 该函数向指定的窗体添加一个矩形,然后窗口客户区域的这一部分将被重新绘制。 /// 该函数产生对其他线程的控制,如果一个线程没有其他消息在其消息队列里。 /// 该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。 /// 该函数从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。此函数接收一定范围的消息值。 /// 该函数将虚拟键消息转换为字符消息。 /// 该函数调度一个消息给窗口程序。 /// 该函数从一个与应用事例相关的可执行文件(EXE文件)中载入指定的光标资源. /// 该函数确定光标的形状。 /// 确定当前焦点位于哪个控件上。 /// 该函数从当前线程中的窗口释放鼠标捕获,并恢复通常的鼠标输入处理。捕获鼠标的窗口接收所有的鼠标输入(无论光标的位置在哪里),除非点击鼠标键时,光标热点在另一个线程的窗口中。 /// 准备指定的窗口来重绘并将绘画相关的信息放到一个PAINTSTRUCT结构中。 /// 标记指定窗口的绘画过程结束,每次调用BeginPaint函数之后被请求 /// 该函数返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出。 /// 该函数将指定点的用户坐标转换成屏幕坐标。 /// 当在指定时间内鼠标指针离开或盘旋在一个窗口上时,此函数寄送消息。 /// 该函数检取指定虚拟键的状态。 /// 该函数改变指定窗口的位置和尺寸。对于顶层窗口,位置和尺寸是相对于屏幕的左上角的:对于子窗口,位置和尺寸是相对于父窗口客户区的左上角坐标的。 /// 该函数获得指定窗口所属的类的类名。 /// 该函数改变指定窗口的属性 /// 该函数检索指定窗口客户区域或整个屏幕的显示设备上下文环境的句柄,在随后的GDI函数中可以使用该句柄在设备上下文环境中绘图。 /// 获取整个窗口(包括边框、滚动条、标题栏、菜单等)的设备场景 返回值 Long。 /// 该函数用指定的画刷填充矩形,此函数包括矩形的左上边界,但不包括矩形的右下边界。 /// 该函数返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置。 /// 该函数改变指定窗口的标题栏的文本内容 /// 该函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内。如果指定的窗口是一个控制,则拷贝控制的文本。 /// 用于得到被定义的系统数据或者系统配置信息. /// 该函数设置滚动条参数,包括滚动位置的最大值和最小值,页面大小,滚动按钮的位置。 /// 该函数显示或隐藏所指定的滚动条。 /// 该函数可以激活一个或两个滚动条箭头或是使其失效。 /// 该函数将指定的窗口设置到Z序的顶部。 /// 该函数滚动指定窗体客户区域的目录。 /// 该函数确定给定的窗口句柄是否识别一个已存在的窗口。 /// 该函数将256个虚拟键的状态拷贝到指定的缓冲区中。 /// 该函数将指定的虚拟键码和键盘状态翻译为相应的字符或字符串。该函数使用由给定的键盘布局句柄标识的物理键盘布局和输入语言来翻译代码。

// 枚举窗体返回 false 而且没有错误号时表明获取成功

我要回帖

更多关于 c语言马鞍点 的文章

 

随机推荐