php可以调用windowsapi吗_2.如何调用WindowsApi

2.如何调用WindowsApi

在上一篇章节中 很不专业的介绍了一下WindowsApi 如果你本身就知道 那你也压根不用看 如果你本身就不知道 就算我说的再多 估计你也觉得是多余 所以还是来点实际的

首先 在C#中想要调用那些Api(当然不一定是Windows提供的Api) 你得添加一个引用:

using System.Runtime.InteropServices;

有了这个命名空间 你才能做下一步 这用以MoveWindow函数为例来讲解:

9aa46dce18fdff7baa2f8a37242a85be.png

如上截图 如果拉到底部可以看到 这个函数在user32.dll里面 而上一篇说过这个dll在Window的系统路径下 而MoveWindow函数就在这个dll里面 在调用这个函数前先来看看这个函数的说明 我把chm里面的东西复制出来看:

函数功能:

该函数改变指定窗口的位置和尺寸。对于顶层窗口 位置和尺寸是相对于屏幕的左上角的:

对于子窗口 位置和尺寸是相对于父窗口客户区的左上角坐标的。

函数原型:

BOOL MoveWindow(HWND hWnd.int x.int y,int nWidth,int nHeight,BOOL BRePaint);

参数:

hWnd:窗口句柄。//看不懂不用知道

x:指定窗口的新位置的左边界。

Y:指定窗口的新位置的顶部边界。

nWidth:指定窗口的新的宽度。

nHaight:指定窗口的新的高度。//下面这个看不懂不用看

bRepaint:确定窗口是否被刷新。如果该参数为TRUE 窗口接收一个WM_PAINT消息;

如果参数为FALSE 不发生任何刷新动作。它适用于客户区 非客户区(包括标题栏和滚动条)

及由于移动子窗口而露出的父窗口的区域。如果参数为FALSE

应用程序就必须明确地使窗口无效或重画该窗口和需要刷新的父窗口。

返回值:

如果函数成功 返回值为非零;如果函数失败 返回值为零。若想获得更多错误信息

请调用GetLastError函数。//GetLastError()也是一个函数 在kernel32中

备注://看不懂不用看

如果bRepaint为TRUE 系统在窗口移动后立即给窗口过程发送WM_PAINT消息

(即由MoveWindow函数调用UPdateWindow函数)

如果bRepaint 为FALSE 系统将WM_PAINT消息放在该窗口的消息队列中

消息循环只有在派遣完消息队列中的其他消息时才派遣WM_PAINT消息

MoveWindow给窗口发送WM_WfNOWPOSCHANGING WM_WINDOWPOSCHANGED

WM_MOVE WM_SIZE和WM_NCCALCSIZE消息

速查:

Windows NT:3.1 以上版本:Windows:95 以上版本;Windows CE:1.0 以上版本:

头文件:winuser.h;库文件:user32.lib。

函数签名形式是C++的 淡定习惯就好如果你会C++无所谓 如果不会 没事如果你用多了之后自然什么意思 第一个参数可能有点看不懂HWND 这个是啥?其实全写是HandleWindow 一个窗口的句柄 如果你不知道什么是句柄 那就暂时先别管 暂时先理解为是一个窗体的编号 下一篇来说 中间四个不用说 最后一个应该知道把bool 以后像这样全大写的东西多了去了C++的习惯 这个值简单来说 就是当窗体被移动后 是否刷新窗体

现在知道这个函数要怎么用了 那么 现在怎么才能调用到他?平时写代码的时候 调用函数基本都是自己写的 所以知道怎么调用 但是这个函数在一个系统的dll里面 如果平时用C#写过dll的话你可能会很自然的这样想 难道要引用dll?然后new一个对象 或者类名打点 那个方法就被点出来了?、、这里恐怕有那么一点不一样 平时你用C#写的dll是托管代码是运行在.Net平台受.Net平台管理的 而系统的dll是非托管代码 是不受.Net平台约束的 不然一个没有装.Net平台的电脑 那么那些系统的dll岂不是就运行不了了?、

那到这里估计就郁闷了 又不能添加引用 那要怎么调用到这个函数?话不多说 直接上全部代码上来一看究竟再说

首先随便你搞一个啥工程 然后添加一个button 就像下面这样:

5f77fce6c97a9e3a4d29918c00885efb.png

然后cs文件全部代码如下:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace WindowsApplication1

{

public partial class Form1 : Form

{

[DllImport("user32.dll")]//表示下面这个函数在user32.dll中

public static extern bool

MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool bRePaint);

//extern表示外部的 也就是说这个函数在其他地方 而上面的[DllImport(Path)]指定函数的位置

//还有 记得static关键字这个是必须的 没有他 编译都不通过 然后后面该怎么就怎么

public Form1() {

InitializeComponent();

}

private void button1_Click(object sender, EventArgs e) {

MoveWindow(this.Handle/*当前窗体的句柄*/, 100, 100, 200, 200, true);

}

}

}

按照上面方式 就可以调用了 当程序运行的时候点击button然后 窗体就会移动到你指定的坐标和大小 如果你最后一个参数是false的话可能会出现如下效果:

3672fc87c0acc1c6b38af2fbaf3d8b4e.png

因为窗体在桌面上的位置信息发生了变化 但是有没有刷新窗体的后果 当然他不可能一直都是黑的 你把窗体拖出屏幕外 再拖回来 被挡住的地方就会正常 或者最小化再最大化

看到上面的效果可能你不觉的有啥估计你觉得就这个东西 自己也能写一个一样功能的函数啊 干嘛搞的那么麻烦比如:

private void MyMoveWindow(

Form frm, int x, int y, int width, int height, bool bRePaint)

{

frm.Left = x;

frm.Top = y;

frm.Width = width;

frm.Height = height;

if (bRePaint) frm.Refresh();//在这里 其实多余了

}

或许你觉和上面的MoveWindow函数没有区别 在本例中你确实看不到啥明显的区别 不过我告诉你 区别大了你自己写的这个 你能移动你自己程序的窗口 外界程序的 比如IE浏览器 QQ窗体 计算器窗体什么的 你能移动么?、、假设现在桌面上 有一个QQ聊天窗口 叫你写个程序点击button把那个QQ聊天窗体 给我移动到左上角去 这里的MyMoveWindow根本就办不到 所以在MoveWindow中的第一个参数接收的是一个窗口的句柄 而不是.Net中的Form 如果你要移动那个窗体 只需要将指定窗体的句柄传进去就是了 至于什么是句柄下一篇来说 这一篇只是演示一下 怎么调用

要注意的是上面[DllImport(...)]这里面不是只能一个string类型的参数 还有很多可选参数:

1a1ee082019c3df035f16c8b6e10060c.png

见得比较多的就是CharSet EntryPoint SetLastError

[DllImport("user32.dll", EntryPoint = "MoveWindow", CharSet = CharSet.Unicode, SetLastError = true)]

public static extern bool AAA(IntPtr hWnd, int x, int y, int width, int height, bool bRePaint);

比如上面的 如果用了EntryPoint去指定入口的话 那么下面你声明的函数 就可以用其他你喜欢的名字

CharSet表示这个函数中出现的字符串的编码用什么形式 注意很多接收字符串参数的函数是有两个版本的 比如MessageBox有MessageBoxA和messageBoxW两个版本 MessageBox并不是函数的真正名字在C++中是一个宏定义 根据情况决定使用那个版本的函数 如果着这里你把CharSet设置成Unicode那么在调用函数的时候会自己在你定义的函数名上加上W如果是Ansi则会加上A 好像默认不写是Auto来着 根据[Windows核心编程]一书说 Windows NT开始由Unicode构建的 所以就算你调用的是A版本的函数 那么系统内部也会将其转换为Unicode然后进行处理

最后的SetLastError 表示是否设置错误号码 意思就是 并不是每个函数你都能调用成功的有些函数可能因为你参数原因或者其他原因导致函数调用失败 而失败了会产生一个错误号码 这个错误号码可以通过GetLastError()函数获取到 然后根据这个错误号 你可以得到一个错误信息比如:

[DllImport("kernel32.dll",SetLastError = true)]//MoveWindow略

public static extern int GetLastError();

private void button1_Click(object sender, EventArgs e) {

if (!MoveWindow((IntPtr)10086, 100, 100, 10086, 200, false)) {

//MessageBox.Show(new Win32Exception(Marshal.GetLastWin32Error()).Message);

MessageBox.Show(new Win32Exception(GetLastError()).Message);

}

}

句柄乱输入一个参数(句柄其实就是一个数字) GetLastError被定义在kernel32中 .Net其实对它有封装在Marshal类中可以直接调用这个函数Win32Exception也是.Net中自己封装的 然后运行程序 你会看到如下效果:

54f5087260d2394e61d6ee70881d9922.png 一个无效的窗体句柄

有时候想知道为什么调用的函数失败 就可以通过GetLastError来获取 别天真的以为 try catch 来捕获 - -!、、try catch 只会捕获throw抛出来的异常 而MoveWindow这些函数都啥时候写的了、、里面没有throw这种前卫的东西的只有设置错误号的代码、、

好吧这一篇就暂时先到这里、、、因为要怎么调用也确实没啥要讲的 引用命名空间 [DllImport(...)] 然后申明函数 然后调用 没啥可以多说的、、、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php获取跳转后url,php获取跳转后真实url的方法

php获取跳转后真实url的方法发布时间:2020-08-01 14:17:56来源:亿速云阅读:68作者:清晨这篇文章主要介绍php获取跳转后真实url的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一…

定界符在php中,php定界符如何使用

定界符给字符串定界的方法使用定界符语法(“<<结束标识符必须从行的第一列开始。同样&#xff0c;标识符也必须遵循 PHP 中其它任何标签的命名规则&#xff1a;只能包含字母数字下划线&#xff0c;而且必须以下划线或非数字字符开始。举个例子&#xff1a;<?php $str…

php protobuf 二进制,PHP环境中使用ProtoBuf数据格式

1、syntax"proto3":表明使用的是proto3格式&#xff0c;如果不指定则为proto22、package test:定义包名为test&#xff0c;生成类时&#xff0c;会产生一个目录为test3、message Person:消息主体内容&#xff0c;里面为各个字段的定义二、生成对应的PHP类定义好Perso…

工具系列:PyCaret介绍_模型训练详细教程

工具系列:PyCaret介绍_模型训练详细教程 PyCaret初始化 setup任务&#xff1a;自动推断数据类型 必需参数默认转换实验记录模型验证GPU支持示例 PyCaret模型训练 compare_models 示例更改排序顺序只比较几个模型返回多个模型设置预算时间设置概率阈值禁用交叉验证在集群上进行…

php怎么调试小程序,教你如何配置微信小程序

这篇文章主要介绍了微信小程序 教程之小程序配置的相关资料,这里对app.json,pages,window等做了详细介绍&#xff0c;对于初学开发微信小程序的朋友&#xff0c;掌握这些还是比较重要的&#xff0c;需要的朋友可以参考下微信小程序——配置以下就是小编对小程序配置的资料进行的…

php中的控制器是什么意思,理解PHP中的MVC编程之控制器_php

简单来讲&#xff0c;控制器的作用就是接受请求。它使用获取的方法&#xff0c;在这里是通过URI&#xff0c;载入一个功能模块来刷新或者提交一个表述层。控制器将使用$_GET自动全局变量来判断载入哪一个模块。一个请求的例子&#xff0c;看起来像这样&#xff1a;http://examp…

GitHub---最简单的使用

大神就不要喷我了&#xff0c;写这个只是希望新人能够对自己写的项目更方便的本地管理。&#xff08;其实我也只会这点东西w&#xff09; 这两天稍微看了看GitHub&#xff0c;之前不是很明白这个版本控制器到底是什么意思&#xff0c;现在略微有了解&#xff0c;这是对项目代码…

php apache配置测试端口,详解安装配置Windows版apache服务器及压力测试

下载Apache1、下载地址&#xff1a;http://httpd.apache.org/download.cgi2、点击链接Files for Microsoft Windows&#xff1a;安装步骤1、先安装apache补丁1)下载地址&#xff1a;https://www.microsoft.com/zh-cn/download/confirmation.aspx?id481452)如果没有安装&#x…

ASCII,Unicode和UTF-8

1. ASCII码 我们知道&#xff0c;在计算机内部&#xff0c;所有的信息最终都表示为一个二进制的字符串。每一个二进制位&#xff08;bit&#xff09;有0和1两种状态&#xff0c;因此八个二进制位就可以组合出256种状态&#xff0c;这被称为一个字节&#xff08;byte&#xff09…

matlab中solve和resolve,resolve和solve的区别

solve和resolve的区别在于&#xff1a;首先solve一般用于解决难题。如solve a problem, solve a riddle, solve an algebra problem。而resolve 是用在解决矛盾&#xff0c;或者是解决大难题&#xff0c;较显示问题的严重性。如resolve a conflict。其他有关slove的词dissolve&…

shell变量详解

1 shell变量基础 shell变量是一种很“弱”的变量&#xff0c;默认情况下&#xff0c;一个变量保存一个串&#xff0c;shell不关心这个串是什么含义。所以若要进行数学运算&#xff0c;必须使用一些命令例如let、declare、expr、双括号等。shell变量可分为两类&#xff1a;局部变…

if和case用法比较

Case语句时并发语句&#xff0c;需要采用并行逻辑来实现&#xff0c;不存在逻辑的优先级别。If……else语句时多级嵌套语句&#xff0c;通常采用逻辑的串联来实现&#xff0c;该结构具有优先级别问题。这两种结构分别如下图所示&#xff1a; Always (a or b or c or d or s[1:…

PHP实训笔记,【学习笔记19】实验吧 让我进去

知识点MD5拓展攻击解题思路打开网站后看到&#xff0c;什么都没有&#xff0c;尝试抓包分析360截图17860604827894.PNGBurp 抓包发现&#xff0c;Cookie有东西。先是把source0改成source1,得到源码。、、、$flag "XXXXXXXXXXXXXXXXXXXXXXX";$secret "XXXXXXXX…

oracle查表占的物理空间,查询Oracle表实际物理使用大小

Oracle中有两种含义的表大小一种是分配给一个表的物理空间数量&#xff0c;而不管空间是否被使用。可以这样查询获得字节数&#xff1a;select segment_name, bytesfrom user_segmentswhere segment_type TABLE;效果如下&#xff1a;或者Select Segment_Name,Sum(bytes)/1024/…

分布模式

Remote Facade远程外观 在OO模型中,存在很多规模小,且有小方法的对象.这些小对象会导致很多的对象间交互.在单一地址空间里,小对象没问题.但是,当在两个进程间做调用时,频繁的跨进程交互会造成性能开销.远程外观,减少远程调用的次数. 建立在大量的细粒度对象之上,提供一个粗粒度…

POJ 2485 Highways(最小生成树 Prim)

Highways大意&#xff1a;给你一个用邻接矩阵形式存储的有n个顶点的无向图&#xff0c;让你求它的最小生成树并求出在这个生成树里面最大的边的权值。 思路&#xff1a;用Prim求&#xff0c;判断条件改一下就行。 PS&#xff1a;dis数组初始化的时候用memset一直RE&#xff0c;…

oracle用户获取datameta权限,Oracle数据库提权(低权限提升至dba)

0x01 Oracle存储过程”缺陷”在 Oracle 的存储过程中&#xff0c;有一个有趣的特点&#xff1a;运行权限。运行权限分为两种&#xff0c;definer 和 invoker。definer 为函数创建者的权限&#xff0c;而 invoker 则是当前调用函数的用户。运行权限在函数创建时就已经被钦定了&a…

linux将文件下载到本地windows,XSHELL下直接下载文件到本地(Windows)

xshell很好用,然后有时候想在windows和linux上传或下载某个文件,其实有个很简单的方法就是rz,sz首先你的Ubuntu需要安装rz.sz(如果没有安装请执行以下命令,安装完的请跳过.其它版本linux请自行安装相应软件)yum install lrzsz安装完毕即可使用rz&#xff0c;sz是便是Linux/Uni…

android远程linux命令,测试可用的Android远程语音识别实例

测试可用的Android远程语音识别实例:代码下载在&#xff1a;相关文件下载在Linux公社的1号FTP服务器里&#xff0c;下载地址&#xff1a;用户名&#xff1a;www.linuxidc.com密码&#xff1a;www.muu.cc在 2011年LinuxIDC.com\10月\10月\测试可用的Android远程语音识别实例pack…

容器set和multiset

一、set和multiset基础 set和multiset会根据特定的排序准则&#xff0c;自动将元素进行排序。不同的是后者允许元素重复而前者不允许。 需要包含头文件&#xff1a; #include <set> set和multiset都是定义在std空间里的类模板&#xff1a; [cpp] view plaincopyprint? t…