[置顶] Windows下DLL编程技术及应用

DeskPins——轻量级窗口置顶管理工具实战应用 DeskPins 是一款专为 Windows 系统设计的轻量级窗口置顶工具,通过一个直观的图钉图标实现任意窗口的快速置顶操作。其核心机制基于 Windows API 对窗口层级(Z-Order)的动态调整,用户只需点击目标窗口即可使其始终保持在最前端,适用于多任务并行场景。该工具无需安装、资源占用极低(运行时内存消耗不足 5MB),且兼容所有标准 Win32 窗口,广泛应用于开发调试、文档比对、监控显示等高频切换环境,显著提升工作效率。 阅读详情

 本文转摘自http://linxh.bokee.com/2946294.html    作者: linxh

 

摘 要: 本文介绍了DLL技术在Windows编程中的基本运用方法及应用,给出了直接内存
访问及端口I/O的两个实用DLL的全部源代码。
关键词: DLL Windows编程 内存访问 I/O

一 、引 言
由于Windows为微机提供了前所未有的标准用户界面、图形处理能力和简单灵便的操作,绝大多数程序编制人员都已转向或正在转向Windows编程。在许多用户设计的实际应用系统的编程任务中,常常要实现软件对硬件资源和内存资源的访问,例如端口I/O、DMA、中断、直接内存访问等等 。若是编制DOS程序,这是轻而易举的事情,但要是编制Windows程序,尤其是WindowsNT环境下的程序,就会显得较困难。
因为Windows具有"与设备无关"的特性,不提倡与机器底层的东西打交道,如果直接用Windows的 API函数或I/O读写指令进行访问和操作,程序运行时往往就会产生保护模式错误甚至死机,更严重的情况会导致系统崩溃。那么在Windows下怎样方便地解决上述问题呢?用DLL(Dynamic Link Libraries)技术就是良好途径之一。
DLL是Windows最重要的组成要素,Windows中的许多新功能、新特性都是通过DLL来实现的,因此掌握它、应用它是非常重要的。其实Windows本身就是由许多的DLL组成的,它最基本的三大组成模块Kernel、GDI和User 都是DLL,它所有的库模块也都设计成DLL。凡是以.DLL、.DRV、.FON、.SYS和许多以.EXE为扩展名的系统文件都是DLL,要是打开Windows\System目录,就可以看到许多的DLL模块。尽管DLL在Ring3优先级下运行,仍是实现硬件接口的简便途径。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式,减少了编程设计上的不便;同时,一个DLL在内存中只有一个实例,使之能高效经济地使用内存;DLL实现的代码封装性,使得程序简洁明晰;此外还有一个最大的特点,即DLL的编制与具体的编程语言及编译器无关,只要遵守DLL的开发规范和编程策略,并安排正确的调用接口,不管用何种编程语言编制的DLL都具有通用性。例如在BC31中编制的DLL程序,可用于BC、VC、VB、Delphi等多种语言环境中。笔者在BC31环境下编译了Windows下直接内存访问和端口I/O两个DLL,用在多个自制系统的应用软件中,
运行良好。

二、DLL的建立和调用
DLL的建立及调用方法在许多资料上有详细的介绍,为了节省篇幅,在这里仅作一些
主要的概括。
1.DLL的建立
关于DLL的建立,有如下几个方面的要素是不可缺少和必须掌握的:
?. 入口函数LibMain( )
就象C程序中的WinMain( )一样,Windows每次加载DLL时都要执行LibMain( )函数,主要用来进行一些初始化工作。通常的形式是:



int FAR PASCAL LibMain(HINSTANCE hInstance,WORD wDataSeg,WORD
wHeapSize,LPSTR lpszCmdLine)
{
if(wHeapSize!=0) //使局部堆、数据段可移动
UnlockData(0); //解锁数据段
/*此处可进行一些用户必要的初始化工作*/
return 1; //初始化成功
}
?出口函数WEP( )
Windows从内存中卸载DLL时,调用相应的出口函数WEP( ),主要做一些清理工作,如释放占用的内存资源;丢弃某些字串、位图等资源;关闭打开的文件等等。
?自定义的输出函数
为了让位于不同内存段的应用程序进行远程调用,自定义的输出函数必须定义为远程函数(使用FAR关键字),以防使用近程指针而得到意外的结果;同时,加上PASCAL关键字可加快程序的运行速度,使代码简单高效,提高程序的运行速度。
?输出函数的引出方法
? 在DLL的模块定义文件中(.DEF)由EXPORTS语句对输出函数逐一列出。例如:
EXPORTS WEP @1 residentname //residentname可提高DLL效率和处理速度
PortIn @2
PortOut @3 //通常对所有输出函数附加系列号
? 在每个输出函数定义的说明中使用_export关键字来对其引出。
以上两种方法任选其中的一种即可,不可重复。后面的两个实例分别使用了上述两种不同的引出方式,请留意。

2.DLL的调用
加载DLL时,Windows寻找相应DLL的次序如下:
?.当前工作盘。
?Windows目录;GetWindowsDirectory( )函数可提供该目录的路径名。
?Windows系统目录,即System子目录;调用GetSystemDiretory( )函数可获得这个目录的路径名。
?DOS的PATH命令中罗列的所有目录。
?网络中映象的目录列表中的全部目录。

DLL模块中输出函数的调用方法:
不论使用何种语言对编译好的DLL进行调用时,基本上都有两种调用方式,即静态调用方式和动态调用方式。静态调用方式由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),简单实用,但不够灵活,只能满足一般要求。动态调用方式是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。具体来说,可用如下的方法调用:
?.在应用程序模块定义文件中,用IMPORTS语句列出所要调用DLL的函数名。如:
IMPORTS MEMORYDLL.MemoryRead
MEMORYDLL.MemoryWrite
?让应用程序运行时与DLL模块动态链接



先用LoadLibrary加载DLL,再用GetProcAddress函数检取其输出函数的地址,获得其指针来调用。如:
HANDLE hLibrary;
FARPROC lpFunc;
int PortValue;
M
hLibrary=LoadLibrary("PORTDLL.DLL"); //加载DLL
if(hLibrary>31) //加载成功
{
lpFunc=GetProcAddress(hLibrary,"PortIn"); //检取PortIn函数地址
if(lpFunc!=(FARPROC)NULL) //检取成功则调用
PortValue=(*lpFunc)(port); //读port端口的值
FreeLibrary(hLibrary); //释放占用的内存
}
M

三、DLL应用实例源程序
1.直接内存访问的DLL源代码
//.DEF文件
LIBRARY MEMORYDLL
DESCRIPTION 'DLL FOR MEMORY_READ_WRITE '
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024 //DLL无自己的堆栈,故没有STACKSIZE语句
EXPORTS WEP @1 residentname
ReadMemory @2
WriteMemory @3

//.CPP文件
#include <windows.h>

int FAR PASCAL LibMain(HINSTANCE hInstance,WORD wDataSeg,WORD
wHeapSize,LPSTR lpszCmdLine)
{
if(wHeapSize!=0)
UnlockData(0);
return 1;
}

int FAR PASCAL MemoryRead(unsigned int DosSeg,unsigned int DosOffset)
{
WORD wDataSelector,wSelector;
char far *pData;
char value;
wDataSelector=HIWORD((DWORD)(WORD FAR *)&wDataSelector);
wSelector=AllocSelector(wDataSelector); //分配选择器
SetSelectorLimit(wSelector,0x2000); //置存取界限
SetSelectorBase(wSelector,(((DWORD)DosSeg)<<4)+(DWORD)DosOffset); //置基地址
pData=(char far *)((DWORD)wSelector<<16);
value=*pData;
FreeSelector(wSelector); //释放选择器
return (value);
}



void FAR PASCAL MemoryWrite(unsigned int DosSeg,unsigned int DosOffset,char Data)
{
WORD wDataSelector,wSelector;
char far *pData;
wDataSelector=HIWORD((DWORD)(WORD FAR *)&wDataSelector);
wSelector=AllocSelector(wDataSelector);
SetSelectorLimit(wSelector,0x2000);
SetSelectorBase(wSelector,(((DWORD)DosSeg)<<4)+(DWORD)DosOffset);
pData=(char far *)((DWORD)wSelector<<16);
*pData=Data;
FreeSelector(wSelector);
}

int FAR PASCAL WEP(int nParam)
{
return 1;
}

2.端口读写I/O的DLL源代码
//.DEF文件
LIBRARY PORTDLL
DESCRIPTION 'DLL FOR PORT_IN_OUT '
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024

//.CPP文件
#include <windows.h>
#include <dos.h>

int FAR PASCAL LibMain(HINSTANCE hInstance,WORD wDataSeg,WORD
wHeapSize,LPSTR lpszCmdLine)
{
if(wHeapSize!=0)
UnlockData(0);
return 1;
}

int FAR PASCAL _export PortOut(int port,unsigned char value)
{
outp(port,value);
return 1;
}

int FAR PASCAL _export PortIn(int port)
{
int result;
result=inp(port);
return (result);
}

int FAR PASCAL _export WEP(int nParam)
{
return 1;
}


分别将上面两个实例的.DEF文件和.CPP文件各自组成一个.PRJ文件,并进行编译链接成.EXE或.DLL文件就可以在应用程序中对其进行调用。

四、结 束 语
在上面,我们利用DLL技术方便地实现了Windows环境下对内存的直接访问和端口I/O的访问,仿效这两个例子,还可以编制出更多的适合自己应用系统所需的DLL,如用于数据采集卡的端口操作及扩展内存区访问、视频区缓冲区及BIOS数据区操作等许多实际应用的编程任务中。必要时只需直接更新DLL,而用不着对应用程序本身作任何改动就可以对应用程序的功能和用户接口作较大的改善,实现版本升级。因此,掌握好DLL技术对Windows程序开发者很有裨益。

Paypal开发者中心获取“ClientId”和“ClientSecret”参数 正式环境设置 1、登录到 paypal开发者中心 网址:https://developer.paypal.com/developer/ 点击右上角登录按钮登录 2、左侧栏 - 我的应用程序和凭证 - 点击“创建新应用” 新注册的paypal账号,需要进行邮箱验证,验证通过后,需要等待一段时间(或重新登录),才会出现相关设置项位置 验证邮箱通过后,点击创建新应用 3、按提示填写,保存创建应用 4、点击刚创建的应用进入应用详情页 5、应用详情页获得网站开发人员所需要的“ClientId”和“Client 阅读详情

相关推荐

【ISP图像处理】Demosaic去马赛克技术演进与边缘优化策略

本文深入解析了ISP图像处理中的Demosaic(去马赛克)技术。从Bayer阵列原理出发,梳理了从双线性插值、Hamilton-Adams边缘导向算法到利用通道相关性与自相似性的技术演进历程,并重点探讨了针对边缘与纹理伪影的优化策略,为工程实践中的算法选型与硬件协同设计提供了专业指导。

weixin_29091445的博客 388

强制unity 工程 在Win10最前端运行(活动窗口)

强制前端运行,活动窗口,

nynart的博客 1251

Openwifi 开源项目解读(一)

Openwifi wifi 80211 无线网卡 基带 FPGA linux 驱动 开源

2万+

MFC--Extension DLL(扩展DLL)

本文阐述的动态链接库的一种,mfc 扩展动态链接库--MFC Extension DLL.最后以一个程序的启动画面来用实例说明一下这个dll的使用 MFC扩展dll主要是为了实现可重用类,也就是MFC标准类库进行继承,然后通过DLL进行重用,一次开发,多次使用。扩展dll使用MFC的动态连接的库版本生成的。只有使用动态连接库的可执行程序或是regular dll(规则动态链接库)才可以使用扩展d

xinzhiyounizhiyouni的专栏 2851

GBT 27930-2015/2023国标充电协议A类CAN报文ID说明

国标充电CAN的ID,仅供学习参考。

qqq080的博客 7806

2026年紫光同创数字IC笔试试卷带答案

FPGA基础知识与设计要点摘要 本文围绕FPGA与数字IC设计核心概念,通过单选题、波形分析题、多选题和简答题形式,系统梳理了以下关键知识点: FPGA基础架构 查找表(LUT)是实现组合逻辑的基本单元(题1) CLB包含LUT、触发器和进位链,后者加速算术运算(题6,10) 布局布线优化是减少关键路径延迟的核心方法(题7) 时序分析要点 建立时间(时钟沿前数据需稳定)与保持时间(时钟沿后需保持)的定义(题2,简答1) 亚稳态成因及两级同步器处理跨时钟域信号的方法(多选题1,波形题5) 特殊设计技术 异步复

Open 114

如何给自己的程序增加插件功能-用DLL做插件

下载例子源代码原文链接:http://www.vckbase.com/vckbase/vckbase12/vc/nonctrls/atlcomocx_02/1202008.htm现在很多程序都支持外挂插件,插件可以使程序容易扩展。插件一般来说都是要求有标准接口的。我们在这里做个最简单的插件。插件的结构定义如下:这个是插件DLL的输出函数,用于创建插件。 BOOL Plug_CreateObject

Dreamcode ~ All in AI 4257

JeecgBoot passwordChange 任意用户密码重置漏洞复现

​JeecgBoot 框架passwordChange接口存在任意用户密码重置漏洞,未经身份验证的远程攻击者可以利用此漏洞重置管理员账户密码,从而接管系统后台,造成信息泄露,导致系统处于极不安全的状态。

0xSec 2641

Windows下DLL编程技术及应用

一 、引 言由于Windows为微机提供了前所未有的标准用户界面、图形处理能力和简单灵便的操作,绝大多数程序编制人员都已转向或正在转向Windows编程。在许多用户设计的实际应用系统的编程任务中,常常要实现软件对硬件资源和内存资源的访问,例如端口I/O、DMA、中断、直接内存访问等等 。若是编制DOS程序,这是轻而易举的事情,但要是编制Windows程序,尤其是WindowsNT环境下的程

1341

C# 与欧姆龙 PLC 实战:通过 Ethernet/IP 协议进行设备控制与监控

本文介绍了如何通过C#和Ethernet/IP协议实现与欧姆龙PLC的通信。Ethernet/IP是基于以太网的工业协议,适用于工业设备间的实时数据交换。文章详细讲解了使用EthernetIPSharp库建立连接、读写数据的步骤,并提供了示例代码。此外,还探讨了实时监控、报警系统等高级功能,为工业自动化控制系统开发提供了实用指导。该方法简化了PLC通信开发,提高了系统可靠性和智能化程度。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 813

微信小程序 - request:fail errcode:10011 cronet_error_code:0 error_msg:network change, cancel all task请求报错

微信小程序请求接口,报request:fail errcode:10011是什么原因,uniapp微信小程序request:fail errcode:10011 cronet_error_code:0 error_msg:network change, cancel all task,微信小程序wx.request常规访问接口,有个别用户的接口请求频繁报错,UniApp 微信小程序uni.request请求接口报错:request:fail errcode:10011 的原因分析与解决方案,苹果ios,安卓

🏆 前端领域优质创作者 4567

通过DLL对主程序或其它DLL做扩展的一种方法

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33755649的博客 475

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Unity3D Windows平台窗口置顶全屏

一、效果 在打包后的程序启动过程,无任点击过什么界面,程序启动完后都能显示在窗口最前面,并且全屏无边框显示。 二、思路 主要是对Window编程,引入user32.dll调用window的API对窗口进行操作 三、实现 using System; using System.Collections; using System.Runtime.InteropServices; using ...

YasinXin的博客 3160

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

windows 内核dll

DLL文件说明 后缀 为 .exe是 应用程序, .py 的python的 .rar .zip的是压缩文件 .txt 是文本文档 .dll的是 应用程序扩展 文件 DLL文件为动态链接库 (全称是 Dynamic Link Library),又称应用程序扩展 在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放...

ball4022的博客 619

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

LabVIEW前面板置顶有桌面窗口 官网附件有源码

摘要:本文介绍了如何通过调用Windows系统库User32.dll中的FindWindowA和SetForegroundWindow函数,实现LabVIEW前面板在所有桌面窗口最前端显示的方法。该方法克服了LabVIEW自带IsFrontmost属性只能内部置顶的局限,适用于全版本LabVIEW(Windows系统)。实现步骤包括获取前面板名称、调用系统函数获取窗口句柄并置顶,支持循环持续置顶功能。文中还提供了注意事项,包括窗口标题唯一性要求、权限问题解决方案等,确保该方法在不同LabVIEW版本和Win

bjcyck的博客 1166

C# 窗口置顶

新建一个 WinForm项目,在项目的.cs文件中加入以下代码:1、引入命名空间:2、在窗口类中加入:3、在窗口的Load事件中加入:置顶取消置顶。

#elseif 2450

3大场景突破Windows多任务瓶颈:PinWin窗口置顶工具效率提升指南

在数字化工作环境中,窗口管理效率直接决定多任务处理能力。PinWin作为轻量级窗口置顶工具,通过深度整合Windows API(应用程序接口)技术,为用户提供毫秒级窗口置顶响应,彻底解决传统窗口切换导致的注意力分散问题。本文将从真实工作场景出发,系统解析这款工具如何通过创新操作方法重构你的工作流,实现至少40%的多任务效率提升。 ## 穿透多任务迷雾:三大场景的传统痛点与解决方案 ### 代码

gitblog_00883的博客 300

C# WINFORM 强制让窗体获得焦点(可实现单次置顶或持续置顶)

这个是从 这个前辈那里转载来的  传送门: 点击打开链接 //首先要说明的是与TopMost的效果不同,TopMost是属性定义,而且设置True后,如果不设为Flase则一直置顶,效果很差, //以下方法解决了TopMost使用上的不足 //调用API [System.Runtime.InteropServices.DllImport("user32.dll", CharSet

柠檬、别离 6694

unity 实现发布win平台无边框以及窗口置顶

最近需要用到win平台无边框以及窗口置顶,并且可以给用户自己配置窗口大小,多说无益放代码: using System; using System.IO; using System.Runtime.InteropServices; using System.Diagnostics; using UnityEngine; using System.Xml.Serialization; public ...

qq_39676160的博客 2720

WinFrom窗体始终置顶

调用WindowsAPI使窗体始终保持置顶效果,不被其他窗体遮盖: [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, i...

MyNameIsXiaoLai的博客 382

windows将窗口置顶的几种方式

方法一: 使用定时器,然后在定时器响应函数中定时调用,SetWindowPos()函数,第一个参数写HWND_TOPMOST 方法二: 因为2000/XP改变了SetForegroundWindow的执行方式,不允许随便把窗口提前,打扰用户的工作。可以用附加本线程到最前面窗口的线程,从而欺骗windows。 AttachThreadInput(GetWindowThreadProcessI...

chen_daisy的博客 2万+

LabVIEW前面板置顶实战:绕过UIPI与轮询的工业级方案

Windows窗口置顶是GUI开发的基础能力,其核心依赖Z-order层级管理、WS_EX_TOPMOST扩展样式及SetWindowPos等API调用机制。在测试测量与工业控制场景中,LabVIEW前面板因默认不启用顶层窗口属性,常被系统弹窗或第三方应用遮挡,导致人机交互中断。问题本质是权限隔离(UIPI)、窗口类名动态变化与低效轮询三重技术叠加所致。本文基于Windows窗口模型与LabVIEW VI生命周期,提供免轮询、兼容Win10/11 UAC、支持多显示器的稳定置顶方案,并深度整合Front P

weixin_34184158的博客 420

让任务栏永远在线:ExplorerPatcher置顶功能核心实现揭秘

你是否也曾在全屏工作时被突然消失的任务栏打断思路?是否厌烦了反复切换窗口寻找被遮挡的任务栏?本文将带你深入了解ExplorerPatcher如何通过底层Windows API调用,实现任务栏始终置顶的核心技术,让你的工作流从此告别窗口遮挡烦恼。 ## 功能实现概览 ExplorerPatcher的任务栏置顶功能主要通过修改Windows资源管理器(explorer.exe)的窗口属性实现。核心...

gitblog_00560的博客 472

一个开源工具,让任意Windows窗口保持置顶:AlwaysOnTop快速上手指南

如果你经常同时开着好几个应用,一定有过这样的经历:好不容易打开的参考资料,切个窗口就被压到底层;在线听课想边看视频边记笔记,两个窗口来回切换到头昏。Windows系统本身并没有提供"让某个窗口一直显示在最前面"的功能,而市面上的窗口管理软件大多笨重又收费。开源项目 AlwaysOnTop 就是为解决这个具体问题而生的:一个常驻系统托盘的小程序,让你用两次点击,就能把任意 Windows 应用窗口固

gitblog_00305的博客 229

如何让任意窗口永远保持在最前面?AlwaysOnTop窗口置顶工具完全指南

你是否经常需要在多个窗口间频繁切换,却总是找不到需要的那个窗口?或者重要的参考文档总是被其他应用无情遮挡?今天我要介绍一个解决这个问题的神器——AlwaysOnTop。这个轻量级的Windows工具能让你指定的任何窗口"悬浮"在所有其他窗口之上,彻底告别窗口遮挡的烦恼。 ## 为什么你需要窗口置顶功能? 想象一下这些真实的工作场景: - **编程开发时**:API文档被代码编辑器覆盖,需要不

gitblog_00549的博客 227
上一篇: 常用的 js 代码梳理
下一篇: [置顶] EXT/FCKEditor 集成 -- AJAX UI -- 一种web开发的新的思维
许一沐
博客等级 码龄21年 18粉丝 649原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值