使用扩充内存实现 DOS环境下的弹出式图形窗口.docx_第1页
使用扩充内存实现 DOS环境下的弹出式图形窗口.docx_第2页
使用扩充内存实现 DOS环境下的弹出式图形窗口.docx_第3页
使用扩充内存实现 DOS环境下的弹出式图形窗口.docx_第4页
使用扩充内存实现 DOS环境下的弹出式图形窗口.docx_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用扩充内存实现 DOS环境下的弹出式图形窗口 一、 问 题 的 提 出 在DOS 环 境 下, 弹 出 式 图 形 窗 口 的 实 现 方 法 是: 在 窗 口 打 开 时, 存 储 窗 口 将 覆 盖 一 部 分 区 域 的 图 像, 然 后 在 该 区 域 创 建 窗 口 的 内 容; 在 窗 口 关 闭 时, 将 已 存 储 的 图 像 填 回 原 区 域。 一 般 地, 可 将 图 像 存 储 在 常 规 内 存 中。 但 当 打 开 多 个 窗 口 时, 这 样 做 将 占 用 大 量 的 常 规 内 存, 影 响 用 户 程 序 的 执 行。 另 一 种 方 法 是 将 图 像 存 储 在 硬 盘 上, 但 由 于 硬 盘 的 操 作 速 度 太 慢, 在 打 开 或 关 闭 窗 口 时 会 出 现 停 顿 现 象。 如 果 将 图 像 存 入 扩 充 内 存, 就 可 节 省 宝 贵 的 常 规 内 存, 同 时, 扩 充 内 存 的 操 作 速 度 也 很 快, 窗 口 的 打 开 和 关 闭 瞬 间 即 可 完 成。 但 在DOS 环 境 下, 不 能 直 接 存 取 扩 充 内 存, 必 须 通 过 扩 充 内 存 的 驱 动 程 序 来 操 作。 二、 解 决 的 办 法 为 了 解 决 上 述 两 个 问 题, 必 须 先 实 现 对 扩 充 内 存 的 存 取, 然 后 实 现 窗 口 的 打 开 和 关 闭。 笔 者 参 考 有 关 资 料, 编 制 了 有 关 程 序。 为 了 安 全 与 方 便, 已 封 装 成 两 个 类:XMS 及XMSWIN。 类XMS 提 供 了 对 扩 充 内 存 的 检 测 和 存 取 功 能。 读 者 在 程 序 中 用XMS 定 义 一 个 目 标, 就 可 安 全 地 使 用 扩 充 内 存。 类XMSWIN 继 承 了 类XMS 的 特 征 和 功 能, 提 供 了 窗 口 的 快 速 打 开 和 快 速 关 闭 功 能。 下 边 先 说 明 使 用 扩 充 内 存 的 方 法。 使 用 扩 充 内 存 之 前, 必 须 确 认 用 户 的 计 算 机 系 统 中 有 一 定 容 量 的 扩 展 内 存, 并 在CONFIG.SYS 文 件 中 设 置DEVICE=C:DOSHIMEM.SYS。 这 样 扩 展 内 存 就 置 于 扩 充 内 存 驱 动 程 序 的 管 理 之 下。 用 户 通 过 类XMS 使 用 扩 充 内 存 的 具 体 步 骤 如 下: 1. 确 认 扩 充 内 存 驱 动 程 序 已 加 载 在 内 存 中, 并 获 取 驱 动 程 序 的 入 口 地 址。 这 一 步 工 作 由 类XMS 中 的 构 造 函 数 自 动 完 成, 用 户 程 序 无 需 作 任 何 工 作; 2. 在 扩 充 内 存 中 申 请 一 块 相 应 大 小 的 内 存 块。 这 一 步 由 用 户 程 序 调 用XMS 类 的 成 员 函 数halloc 实 现, 如 成 功 则 返 回 这 块 扩 充 内 存 的 句 柄, 否 则 返 回 。 调 用 该 函 数 时 的 参 数 为 以KB 为 单 位 的 需 申 请 的 块 的 长 度; 3. 用 户 在 常 规 内 存 中 申 请 一 块 内 存; 4. 将 需 存 入 扩 充 内 存 的 数 据 存 入 常 规 内 存; 5. 将 常 规 内 存 中 的 数 据 移 入 扩 充 内 存。 这 一 步 由 用 户 程 序 调 用 类XMS 的 成 员 函 数base_to_XMS 实 现, 调 用 该 函 数 的 参 数 如 下; base: 常 规 内 存 的 地 址, 无 类 型 远 程 指 针; handle: 扩 充 内 存 的 句 柄, 无 符 号 整 数; length: 移 入 数 据 的 长 度, 长 整 型 数, 单 位 为Byte; destoffsets: 数 据 在 扩 充 内 存 中 相 对 块 起 点 的 偏 移 量, 长 整 型 数, 单 位 为Byte; 6. 如 有 多 块 数 据 或 大 量 数 据 需 移 入 扩 充 内 存, 可 在 第2 步 中 一 次 申 请 足 够 大 的 扩 充 内 存, 重 复 步 骤3、4、5。 特 别 说 明 一 点, 在 执 行 第 五 步 时, 必 须 改 变 参 数destoffsets 的 值。 这 样, 多 块 数 据 存 入 同 一 块 扩 展 内 存 而 不 会 相 互 覆 盖, 这 块 扩 充 内 存 由 其 句 柄 唯 一 地 标 识。 当 然, 也 可 以 将 一 块 常 规 内 存 移 入 一 块 扩 充 内 存, 占 用 一 个 句 柄。 但 因 为 扩 充 内 存 句 柄 是 非 常 有 限 的 资 源( 一 般 的DOS 机 约 有30 个 句 柄), 在 方 便 的 情 况 下, 尽 量 少 占 用 句 柄; 7. 释 放 常 规 内 存; 8. 在 需 要 使 用 扩 充 内 存 中 的 数 据 时, 先 在 常 规 内 存 中 申 请 相 应 大 小 的 内 存 块; 9. 调 用 成 员 函 数XMS_to_base, 将 扩 充 内 存 中 的 数 据 移 入 常 规 内 存。 调 用 时 的 参 数 与 第5 步 的 相 同; 10. 如 不 再 需 要 扩 充 内 存 中 的 数 据 时, 调 用 成 员 函 数handlefree 释 放 句 柄 对 应 的 扩 充 内 存 块。 如 不 执 行 该 步 骤, 程 序 退 出 执 行, 则 该 块 扩 展 内 存 将 一 直 被 占 用, 直 到 用 户 关 机 为 止。 上 述10 个 步 骤 已 较 完 整 地 说 明 了 类XMS 使 用 扩 充 内 存 的 方 法。 弹 出 式 窗 口 是 由 类XMSWIN 实 现 的, 该 类 继 承 了 类XMS 的 特 征 和 功 能。 在 用 户 程 序 中 用 类XMSWIN 定 义 一 个 目 标, 就 可 方 便 地 打 开 或 关 闭 多 个 窗 口。 具 体 的 步 骤 如 下: 1. 用 类XMSWIN 定 义 一 个 目 标( 例 程 的 主 函 数 中 为WIN, 是 全 程 变 量)。 目 标 中 的 构 造 函 数 自 动 通 过 基 类 的 功 能 检 测XMS 驱 动 程 序 的 安 装 情 况, 获 取 扩 充 内 存 驱 动 程 序 的 入 口 地 址; 2. 用 户 调 用 成 员 函 数Open3dWin 或OpenWin 打 开 一 个 窗 口。 打 开 的 窗 口 已 绘 制 好 窗 口 框 架。 如 果 打 开 的 是 第 一 个 窗 口, 则 函 数 将 自 动 申 请 一 个 扩 充 内 存 句 柄 用 于 存 储 图 像。 同 时, 函 数 自 动 存 储 窗 口, 即 将 覆 盖 的 屏 幕 图 像 和 设 置 予 以 存 储。 存 储 的 设 置 包 括 原 点 坐 标 和 当 前 画 线 颜 色( 限 于 篇 幅, 例 程 中 未 给 出 存 储 设 置 的 源 代 码)。 并 自 动 将 屏 幕 的 视 口 限 定 在 当 前 窗 口 的 范 围 内, 将 原 点 设 置 为 窗 口 左 上 角; 3. 用 户 在 窗 口 内 绘 制 图 形 或 字 符。 因 为 已 将 视 口 限 定 在 窗 口 内, 故 所 有 的 操 作 均 已 限 定 在 窗 口 内, 可 避 免 破 坏 窗 口 外 的 屏 幕; 4. 如 需 要 打 开 多 个 窗 口, 则 重 复 步 骤2、3 即 可; 5. 用 户 调 用CloseWin 关 闭 最 顶 层 的 窗 口, 或 调 用CloseAllWin 关 闭 所 有 窗 口。 在 调 用CloseWin 时, 函 数 会 自 动 将 图 像 由 扩 展 内 存 中 取 出, 并 调 用Putimage 函 数 填 回 到 原 来 的 位 置, 同 时 自 动 释 放 扩 充 内 存 中 的 相 应 数 据。 如 果 关 闭 最 后 一 个 窗 口, 则 函 数 会 自 动 释 放 存 储 图 像 的 扩 展 内 存 的 句 柄。 三、 应 用 效 果 为 了 演 示 上 述 功 能, 例 程 中 的 主 函 数 将 在 屏 幕 打 开 个 随 机 的 立 体 窗 口, 在 每 个 窗 口 中 输 出 一 行 字 符 串, 最 后 关 闭 所 有 窗 口。 类XMS 和XMSWIN 及 例 程 源 程 序 见 下 一 节。 笔 者 在 编 制 一 些 大、 中 型 软 件 时 已 多 次 应 用 类XMS 来 使 用 扩 充 内 存, 应 用 类XMSWIN 来 使 用 弹 出 式 图 形 窗 口。 使 用 方 便 而 安 全, 为 软 件 增 色 不 少。 同 时 也 节 省 了 大 量 的 时 间, 缩 短 了 软 件 的 开 发 周 期。 读 者 可 直 接 把XMS.CPP 或XMSWIN.CPP 两 模 块 加 入 到 自 己 的 工 程 文 件 中, 就 可 方 便 而 安 全 地 应 使 用 扩 充 内 存 或 使 用 弹 出 式 窗 口。 四、 源 程 序 程 序 用Borland C+3.1 编 写, 并 在 其 集 成 环 境 中 用Large 内 存 模 式 编 译 通 过。 /XMS.H 文 件 #ifndef _XMS #define _XMS typedef unsigned int UINT; typedef unsigned long ULONG; typedef unsigned char UCHAR; typedef struct EMBstruct/XMS 内 存 数 据 移 动 结 构 ULONG Count;/ 移 动 的 数 据 长 度( 单 位:Byte) UINT SourceHandle;/ 源 数 据 块 句 柄 ULONG SourceOffset;/ 源 数 据 块 偏 移 量( 单 位:Byte) UINT DestHandle;/ 目 标 数 据 块 句 柄 ULONG DestOffset;/ 目 标 数 据 块 偏 移 量( 单 位:Byte) EMBstruct; typedef class XMS private: int xmsdriver;/XMS 存 在 标 志:1= 有,0= 没 有 void far (*XMS_Control)(void); /XMS 驱 动 程 序 入 口 int init(void);/ 测 试HIMEM.SYS 的 安 装 情 况 public: XMS(void);/ 构 造 函 数 EMBstruct EMB;/XMS 内 存 数 据 移 动 结 构 UINT halloc(UINT kbytes); / 申 请XMS 内 存 成 功: 返 回 句 柄, 失 败: 返 回0 / 参 数kbytes: 欲 申 请 的 大 小( 单 位:kB) int handlefree(UINT handle); / 释 放XMS 内 存, 成 功: 返 回1, 失 败: 返 回0 / 参 数handle: 欲 释 放 的 句 柄 int datamove(void); / 在XMS 内 存 与 常 规 内 存 之 间 移 动 数 据 int base_to_xms(void far * base,UINT handle,ULONG length,ULONG destoffsets); /* 从 常 规 内 存 向XMS 内 存 移 动 数 据, 成 功: 返 回1, 失 败: 返 回0。 参 数:base: 欲 移 动 的 常 规 内 存 的 指 针;handle: 欲 移 动 的XMS 内 存 的 句 柄;length: 欲 移 动 的 数 据 的 长 度( 单 位:Byte);destoffset: 数 据 在XMS 内 存 中 相 对 于 起 点 的 偏 移 量( 单 位:Byte)*/ int xms_to_base(void far * base,UINT handle,ULONG length,ULONG emboffset); / 从XMS 内 存 向 常 规 内 存 移 动 数 据, 成 功: 返 回1, 失 败: / 返 回0; 参 数: 与base_to_xms 相 同 XMS; #endif /XMS.CPP 模 块: #include xms.h #include XMS:XMS(void)xmsdriver=0;init(); int XMS:init(void) union REGS regs; struct SREGS sregs; UINT sav_BX; regs.x.ax = 0x4300; int86(0x2F,®s,®s); if(regs.h.al != 0x80) return 0; regs.x.ax = 0x4310; int86x(0x2F,®s,®s,&sregs); if(regs.x.cflag) return 0; xmsdriver = 1; / OK! HIMEM.SYS Already Installed! XMS_Control=(void far (*)()MK_FP (sregs.es,regs.x.bx); _AH=0x00; XMS_Control(); asm mov sav_BX,bx if(UCHAR)(sav_BX&0x00ff)=0x80) return 0; return 1; UINT XMS:halloc(UINT kbytes) UINT sav_AX,handle; UCHAR sav_BL; _AH=0x9;_ DX=kbytes; XMS_Control(); asm mov sav_AX,ax asm mov handle,dx / if no success then handle = 0 asm mov sav_BL,bl if(sav_AX != 1) return 0; return (handle); / if Success,return EMB_Handler int XMS:handlefree(UINT handle) UINT sav_AX; UCHAR sav_BL; if(!xmsdriver) return(0); _AH=0x0A; _DX=handle; XMS_Control(); asm mov sav_AX,ax asm mov sav_BL,bl if(!sav_AX)return(0);else return(1); int XMS:base_to_xms(void far *base,UINT handle,ULONG length,ULONG emboffset) UINT seg,off; ULONG offset; seg=FP_SEG(base); off=FP_OFF(base); offset=(ULONG)seg)16)+off; EMB.Count =length; EMB.SourceHandle=0; EMB.SourceOffset=offset; EMB.DestHandle =handle; EMB.DestOffset =emboffset; if(!datamove()return(0); else return(1); int XMS:xms_to_base(void far *base,UINT handle,ULONG length,ULONG emboffset) UINT seg,off; ULONG offset; seg=FP_SEG(base); off=FP_OFF(base); offset=(ULONG)seg)16)+off; EMB.Count = length; EMB.SourceHandle = handle; EMB.SourceOffset = emboffset; EMB.DestHandle = 0; EMB.DestOffset = offset; if(!datamove() return(0); else return(1); int XMS:datamove(void) UINT emb_seg,emb_off,sav_AX; UCHAR sav_AH,sav_BL; emb_seg=FP_SEG(&EMB);emb_off=FP_OFF(&EMB); sav_AH=0x0B; asm push ds _AH=sav_AH;_DS=emb_seg;_SI=emb_off; XMS_Control(); asm mov sav_AX,ax asm mov sav_BL,bl asm pop ds if(!sav_AX)return(0);else return(1); /XMSWIN.H 文 件: #ifndef _XMSWIN.H #define _XMSWIN.H #define NUMWINDOWS 100 #include xms.h typedef struct GWin/ 窗 口 数 据 结 构 int l,t,r,b;/ 窗 口 边 界 坐 标 int cpx,cpy;/ 窗 口 打 开 前 的 当 前 点 坐 标 ULONG ms;/ 图 像 数 据 的 大 小( 单 位:Byte) ULONG offset;/ 图 像 数 据 在XMS 内 存 的 偏 移 量( 单 位:KB) int drawcolor;/ 窗 口 打 开 前 的 画 线 颜 色 GWin; typedef class XMSWIN:private XMS private: UINT handle; / 存 储 窗 口 图 像 数 据 的XMS 内 存 句 柄 UINT hlength; / 窗 口 图 像 数 据 的 总 长 度( 单 位:KB) GWin *winstackNUMWINDOWS; / 各 打 开 窗 口 的 窗 口 数 据 结 构 int winnum; / 已 打 开 的 窗 口 数 目 int SaveWin(int l,int t,int r,int b); / 将 图 像 存 入XMS 内 存; 成 功: 返 回1, 失 败: 返 回0 public: XMSWIN(void); XMSWIN(void); int OpenWin(int l,int t,int r,int b,int bt,int bc,int bf,int fc); int Open3dWin(int l,int t,int r,int b,int backfill,int fillcolor); /OpenWin: 打 开 一 个 平 面 式 窗 口 /Open3dWindow: 打 开 一 个 立 体 式 窗 口 / 返 回 值: 成 功1, 失 败0 int CloseWin(void); / 关 闭 当 前 窗 口 int CloseAllWin(void);/ 关 闭 所 有 窗 口 / 返 回 值: 成 功1, 失 败0 XMSWIN; #endif / XMSWIN.CPP 模 块: #include xmswin.h #include xms.h #include XMSWIN:XMSWIN() winnum=0;hlength=0; XMSWIN:XMSWIN()if(handle)handlefree(handle); int XMSWIN:SaveWin(int l,int t,int r,int b) GWin *wp; void far *buf; ULONG ms; UINT newhandle; wp=winstackwinnum;ms=imagesize(l,t,r,b); if(msms=ms;buf=(void far *)(new charms); if(!buf) return(0); getimage(l,t,r,b,buf); if(winnum=0) hlength=(UINT)(ms+1023L)/1024L); handle=halloc(hlength); if(!handle)delete buf;return(0); if(!base_to_xms(buf,handle,ms,0L) delete buf; return(0); wp-offset=0L; else newhandle=halloc(hlength+(UINT)(ms+1023L)/1024L); if(!newhandle)delete buf;return(0); else EMB.Count=hlength*1024L; EMB.SourceHandle=handle; EMB.SourceOffset=0; EMB.DestHandle=newhandle; EMB.DestOffset=0; if(!datamove() handlefree(newhandle); delete buf;return 0; if(!handlefree(handle)delete buf;return 0; handle=newhandle; if(!base_to_xms(buf,handle,ms,hlength*1024L) delete buf;return(0); wp-offset=hlength; hlength+=(UINT)(ms+1023L)/1024L); delete buf;return(1); int XMSWIN:OpenWin(int l,int t,int r,int b,int bt,int bc,int bf,int fc) struct viewporttype oldview; if(winnum=NUMWINDOWS)return(0); if(rgetmaxx() r=getmaxx(); if(bgetmaxy() b=getmaxy(); winstackwinnum=new GWin; if(!(winstackwinnum)return(0); getviewsettings(&oldview); setviewport(0,0,getmaxx(),getmaxy(),1); if(!SaveWin(l,t,r,b) delete(winstackwinnum);return(0); setcolor(bc);setlinestyle(bt,0,NORM_WIDTH); setfillstyle(bf,fc);bar3d(l,t,r,b,0,0); setviewport(l,t,r,b,1); winstackwinnum-l=oldview.left; winstackwinnum-t=oldview.top; winstackwinnum-r=oldview.right; winstackwinnum-b=oldview.bottom; winnum+;return(1); int XMSWIN:Open3dWin(int l,int t,int r,int b,int bf,int fc) if(!OpenWin(l,t,r,b,1,1,bf,fc)return(0); setlinestyle(SOLID_LINE,1,1); setcolor(WHITE); for(int i=0;i2;i+) line(i,i,r-l-i,i); line(i,i,i,b-t-i); setcolor(DARKGRAY);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论