选择特殊符号
选择搜索类型
请输入搜索
创建一个窗口的过程如下:
取得程序的实例句柄(hInstance)
注册窗口类,实际上就是为你的窗口指定处理消息的过程,定义光标,窗口风格,颜色等参数
创建窗口
显示窗口
然后进入消息循环,也就是不停地检测有无消息,并把它发送给窗口进程去处理。
创建一个窗口的代码在不同的程序中实际上是几乎一模一样的,所以你编一个新的程序时可以把这一段拷来拷去,稍微修改一下就行,程序的大部分代码实际上是用在窗口过程中,因为这才是不同程序的不同之处。窗口过程的编程要点如下:
从Windows传给窗口过程的参数 uMsg 得到消息类型,并转到不同的分枝去处理。
对自己已经处理的消息,返回 Windows 时必须在eax 中返回0。
自己不处理的消息,必须调用 DefWindowProc 处理,并把返回值传回Windows,否则,Windows会无法显示。
uMsg 参数中指定的消息有280多种,实际上我们需要处理的只有重要的几种,如Windows在创建的时候会发送 WM_CREATE 消息,我们就可以在这时候初始化,分配内存等等,而退出时会发送 WM_CLOSE,我们就可以进行释放内存等清除工作,当Windows上的菜单或按钮被按下时发送 WM_COMMAND 消息等等,具体可以参考 Win32 Programmer's Reference。下面,我们来看一个创建窗口的简单程序。
.386
.model flat, stdcall
option casemap :none ; case sensitive
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib gdi32.lib
IDI_MAIN equ 1000 ;icon
IDM_MAIN equ 4000 ;menu
IDM_EXIT equ 4001
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
szBuffer db 256 dup (?)
.data
szClassName db "Windows Template",0
szCaptionMain db '窗口模板',0
.code
start:
call _WinMain
invoke ExitProcess,NULL
_WinMain proc
local @stWcMain:WNDCLASSEX
local @stMsg:MSG
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadIcon,hInstance,IDI_MAIN
mov hIcon,eax
invoke LoadMenu,hInstance,IDM_MAIN
mov hMenu,eax
;*************** 注册窗口类 *****************************************
invoke LoadCursor,0,IDC_ARROW
mov @stWcMain.hCursor,eax
mov @stWcMain.cbSize,sizeof WNDCLASSEX
mov @stWcMain.hIconSm,0
mov @stWcMain.style,CS_HREDRAW or CS_VREDRAW
mov @stWcMain.lpfnWndProc,offset WndMainProc
mov @stWcMain.cbClsExtra,0
mov @stWcMain.cbWndExtra,0
mov eax,hInstance
mov @stWcMain.hInstance,eax
mov @stWcMain.hIcon,0
mov @stWcMain.hbrBackground,COLOR_WINDOW + 1
mov @stWcMain.lpszClassName,offset szClassName
mov @stWcMain.lpszMenuName,0
invoke RegisterClassEx,addr @stWcMain
;*************** 建立输出窗口 ***************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW OR WS_VSCROLL OR WS_HSCROLL,\
0,0,550,300,\
NULL,hMenu,hInstance,NULL
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;*************** 消息循环 *******************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndMainProc proc uses ebx edi esi, \
hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,uMsg
.if eax == WM_CREATE
mov eax,hWnd
mov hWinMain,eax
call _Init
;********************************************************************
.elseif eax == WM_COMMAND
.if lParam == 0
mov eax,wParam
.if ax == IDM_EXIT
call _Quit
.endif
.endif
;********************************************************************
.elseif eax == WM_CLOSE
call _Quit
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndMainProc endp
_Init proc
invoke SendMessage,hWinMain,WM_SETICON,ICON_SMALL,hIcon
ret
_Init endp
;********************************************************************
_Quit proc
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
ret
_Quit endp
;********************************************************************
end start
让我们来简单分析一下这个程序,首先程序调用 _WinMain,在_WinMain 中定义了两个局部变量 @stMsg 和 @stWinMain,数据类型分别是 MSG 和 WNDCLASSEX结构,在参考手册中,可以看到WNDCLASSEX定义了一个窗口的所有参数,如使用的菜单、光标、颜色、窗口过程等,接下来的一大堆 mov 指令实际上就是在填写这个数据结构,填写完成后,最重要的两句是 mov @stWcMain.lpfnWndProc,offset WndMainProc 定义了处理消息的窗口过程, mov @stWcMain.lpszClassName,offset szClassName 定义了你要创建的类的名称,然后就是使用 RegisterClassEx 注册这个窗口类,注意,这时候窗口并没有创建,你只不过是定义好了一个子类,接下去你要用你定义的类去创建一个窗口。也就是使用 CreateWindowEx 函数去创建它。在手册中,CreateWindowEx 是这样定义的:
HWND CreateWindowEx(
DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu, or child-window identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data );
其中的参数 dwExStyle 是窗口的风格,lpClassName 就是我们自己定义的类的名字。如果大家要创建一个已经定义好的类,如 RichEdit 类等等,只要把 lpClassName 指向 "RichEdit32" 字符串就行了,当然这时就不用 RegisterClass 以及编写自己的窗口过程了。执行 CreateWindowEx 后,得到一个返回值就是窗口句柄,这个值在以后是要经常用到了,所以要先保存下来。这时窗口并没有在屏幕上显示出来,而是处于隐藏状态,我们要用 ShowWindow 来显示出窗口并用UpdateWindow 来绘窗口的内容。
窗口显示出来后,程序就进入一个循环----消息循环,前面我已经说过,作用是不停地接收 Windows 消息并发送给窗口过程去处理。GetMessage 从消息队列中取出一条消息,如果取得的消息不是 WM_QUIT,那么 GetMessage 返回一个非零值,否则返回零,这时候循环结束,程序执行 ExitProcess退回操作系统。TranslateMessage 将消息进行一些键盘转换,用于处理一些快捷键,DispatchMessage 将处理后的消息发回 Windows,由Windows调用窗口进程进行处理,当窗口进程处理完返回后,程序才从 DispatchMessage 返回,从而开始下一个 GetMessage 调用。这些函的参数可以参考手册。
窗口过程有四个参数,hWnd 是本窗口的句柄,和创建窗口时返回的值相同,uMsg 是本次调用的消息类型,wParam 和lParam是消息的参数,其含义和数值根据消息的不同而不同。在本程序中,我们处理 WM_CREATE,WM_COMMAND 和 WM_QUIT 消息,然后返回0,对不处理的消息,使用 invoke DefWindowProc,hWnd,uMsg,wParam,lParam 来处理并直接用 ret 将返回值传回 Windows。在响应 WM_CLOSE 消息时,我们用 DestroyWindow 清除窗口并用PostQuitMessage 产生一条 WM_QUIT 消息,从而使程序在 消息循环调用GetMessage 时返回0,以结束消息循环并结束程序。
让我们先来看看一个最简单的Win32汇编程序:
.386
.model flat, stdcall
option casemap :none ; case sensitive
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
szCaption db 'Win32汇编例子',0
szText db 'Win32汇编,Simple and powerful!',0
.code
start:
invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
invoke ExitProcess,NULL
end start
这就是一个能执行的最简单的Win32汇编程序,下面我简单地介绍一下各部分的作用:
这条语句和Dos下汇编是一样的,是告诉编译器我们要用到80386的指令集,因为32位汇编程序要用到32位的寄存器如eax,ebx等,所以这一句是必须的,当然,你也可以用.486,.586等,当用到特权指令时,还可以用 .386p,.486p等等。
.model告诉编译器程序的模式,编过Dos汇编的人可能知道在Dos程序的模式有tiny,small,...huge 等,它指定了程序内存寻址模式,在huge等模式下,内存寻址和子程序调用将用Far的格式,但在Win32汇编中,你只能使用一个模式即 flat 模式,因为对Win32程序来说,内存是连续的一个4GB的段,无所谓小或大的模式。而stdcall 告诉编译器参数的传递方式,在调用子程序时,参数是通过堆栈传递的,参数的传递方式有三种,stdcall,c 和 pascal,stdcall 指定了参数是从右到左压入堆栈的,比如说对一个Windows API 如 MessageBox,在手册中是如此定义的:
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
那么在汇编中我们就可以这样调用它:
push uType
push lpCaption
push lpText
push hWnd
call MessageBox
大家要注意最右面的参数是最后一个进堆栈的,当然,我们不必这样麻烦的调用一个 API,因为Masm中的一个宏语句不但帮助我们完成了所有的压栈操作,还帮我们检查参数的个数是否正确,那就是 invoke 语句,我们可以把上面的语句换成 invoke MessageBox,hWnd,lpText,lpCaption,uType 就行了。如本程序中代入实际参数就成了 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK。
include 语句包含了一些系统的定义和API函说明,其中所有的Windows 数据结构定义和常量定义包含在 windows.inc 中,而其他 API函数的说明包含在 xxx.inc 中, 如查 Microsoft Win32 Programmer's Reference 知道 ExitProcess包含在kernel32.dll 中,那么我们就要在程序中包括 include kernel32.inc 和 includelib kernel32.lib语句,否则在编译时会出现 API 函数未定义的错误。而 MessageBox 在 user32.dll 中,那么我们就要在程序中包括 include user32.inc 和 includelib user32.lib语句
指明了接下来是数据段,.data 定义了预定义的变量,.data?定义了未初始化的变量,两者的不同之处是 .data? 定义的变量并不占用 .exe 文件的大小,而是在程序执行时动态分配,所以开始是不指定初始值的数据可以放在 .data? 段中,如一个1K大小的缓冲区,放在 .data?中,程序将不会增加一个字节。
指明了接下来是代码段,我们的所有代码都放在这里。最后的一句 start 语句指定了程序开始执行的语句。程序中的 ExitProcess 是一个标准的 Win32 API,对应 Dos汇编中的 int 20h 或 mov ah,4ch/int 21h,也就是程序退出。而 MessageBox 也是一个标准的 API,功能是在屏幕上显示一个消息框,具体的参数上面已经解释过了还有要注意的是 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK 语句中, MB_OK 和 NULL 已经预定义在 Windows.inc 中。
不管在Dos下编程还是在Windows下编程,我们总是要用到除了可执行文件外的很多其他数据,如声音数据,图形数据,文本等等,在Dos下编程,我们可以自己定义这些文件的格式,但这样一来就造成了很多资源共享的问题,大家可能还记的Dos下的很多游戏,它们的图形都是按自己的格式存放的,你无法用标准的看图软件来看。也无法把它另存为其他格式。虽然在Win32编程中,我们仍然可以这样做,但Win32编程给了我们一个方案 ---- 就是格式统一的资源文件,把字符串、图形、对话框包括上面的按钮,文本等定义到一个资源文件中,就可以方便的在不同的文件中使用它,最重要的是,如果我们用自己的文件格式,使用时就要涉及到这些文件的读写操作,比较复杂,但使用资源文件时,Windows提供了一系列的API来装入资源。非常方便。现在,让我们来看一个很简单的资源文件的源文件,它的扩展名是 .rc,当它用资源编译器编译以后产生 .res 文件就可以在 link的时候连入.exe 文件中:
#include <Resource.h>
#define DLG_MAIN 1
DLG_MAIN DIALOGEX 0, 0, 236, 185
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "对话框模板"
FONT 9, "宋体"
BEGIN
DEFPUSHBUTTON "退出",IDOK,177,163,50,14
CONTROL "",-1,"Static",SS_ETCHEDHORZ,7,155,222,1
END
现在我简单解释一下 .rc文件的语法:
#include <resource.h> -- resource.h文件包括资源文件的一些常量定义,如下面的 WS_POPUP,WS_VISIBLE 等窗口的风格等等
#define DLG_MAIN 1 -- 类似于 .asm 文件的 equ 语句,和汇编源程序一样,这些定义是为了程序的可读性。
DLG_MAIN DIALOGEX 0,0,236,185
Windows的.rc文件可以定义 BITMAP(位图),CURSOR(光标),ICON(图标),ACCELERATORS(加速键),DIALOG(对话框),MENU(菜单),STRINGTABLE(字符串表),RCDATA(自定义资源)等8种资源,详细的描述可以参考有关MFC的书籍,在Win32ASM中的资源编译器的语法中,一般格式是这些资源的定义方法是:
位图定义: nameID BITMAP [load-mem] filename
光标定义: nameID CURSOR [load-mem] filename
图标定义: nameID ICON [load-mem] filename
加速键定义:
acctablename ACCELERATORS [optional-statements]
BEGIN event, idvalue, [type] [options]
. . .
END
等等,具体的定义和参数可以参考 Masm32v5 中的 Rc.hlp 帮助文件。(可以在编程工具中下载),我们可以用资源编辑器来所见即所得地编辑资源,也可以在文本编辑器中用上面这些语句自己定义资源。
在程序中,要使用资源之前必须先装如内存,Windows定义了一系列的API来装入资源,如 LoadMenu,LoadString,LoadBitmap 等等,如 LoadBitmap 的定义:
HBITMAP LoadBitmap(
HINSTANCE hInstance, // handle of application instance
LPCTSTR lpBitmapName // address of bitmap resource name
);
这些Load函数的返回值是一个句柄,调用参数中一般至少为两项: hInstance 和 ResouceName,这个 ResouceName(如BitmapName,MenuName)就是在资源文件中的 #define 指定的值,如果你用 #define MY_ICON 10/ MY_ICON ICON "Main.ico" 定义了一个图标,那么在程序中要使用 Main.ico 图标就可以用 LoadIcon(hInstance,10) 来装入已经定义为10号的图标文件。另一个参数 hInstance 是执行文件的句柄,它对应资源所在的文件名,你可以在程序开始执行时用 invoke GetModuleHandle,NULL 获得 hInstance。另外一些资源并不是显式地装入的,如对话框资源,它是在建立对话框的函数中由Windows自己装入的,如下面例子中的 invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0 ,是在屏幕上显示一个资源文件中已经定义好了的对话框,就并不存在 LoadDialogBox 之类的API来先装入对话框。
查看电脑内存最低需4G,重装不行打服务电话
我就遇到过这种情况,处理方法如下
求助官方客服吧4000166166-4-1
悬索桥主缆线形设计与施工计算原理及其Win32软件开发
悬索桥主缆线形设计与施工计算原理及其Win32软件开发
VPN特性
迅博VPN服务器软件(专业版)为WIN32平台服务器软件和NG系列硬件互通,可做为中心点VPN网关使用,集成防火墙,移动VPN客户端个数不限制,支持HUB模式,支持实时用户管理。
其他功能
基本功能包括:
(1)跨平台,支持WIN32、LINUX以及嵌入式平台,与硬件VPN互联互通,支持ARM/MIPS/POWER PC/X86等嵌入式架构。
迅博软件VPN具有完善的产品系列,包括客户端、网关、服务器软件,同时VPN软件支持跨平台环境,无论是Windows XP/2000/20003等WIN32平台还是LINUX平台,都可以运行迅博VPN系列软件,同时迅博VPN软件还支持嵌入式环境,VPN客户端程序及服务器程序可以运行在ARM/MIPS/POWER PC/X86等嵌入式环境,而所需资源较少,效率较高,可以很好的与客户应用集成。
(2)部署简单,使用方便。
迅博软件VPN产品采用策略配置技术,可以方便的将异地的局域网联结在一起,一方面可通过私网IP地址或机器名称访问,还可以通过“网上邻居”直观的看到对方。
(3)多级安全机制,保证信息和网络安全。
除了传统的VPN加密及数据完整性检查,迅博软件VPN支持多级接入认证技术,包括基于PKI体系的X509证书认证方式,以及简单有效的硬件特征认证方式。X509证书认证采用RSA非对称加密算法,密钥长度可达1024位,采用USB KEY存储,使VPN网络具有金融级的安全性。硬件特征认证采用机器的特有标志,使VPN与特定的机器捆绑,是简单而有效的认证方式。
(4)全动态IP地址支持、多种接入方式、实现多种组网结构。
迅博软件VPN不仅支持传统的公网接入方式(ADSL、PSTN、专线),还支持GPRS/CDMA/WLAN/小区宽带等NAT接入方式,并且可以安装在防火墙后,企业组网只需要有一方具备公共IP地址即可。此外,迅博软件VPN产品不仅支持网状结构(mesh)组网,还支持集中星型(hub and spoke)式的组网结构,彻底解决双NAT之间建立VPN隧道问题。同时,迅博软件VPN支持目录服务、WEB代理等寻址技术,可实现全动态VPN网络的组建。
(5)动态负载平衡支持,实现大容量接入。
迅博率先实现实现VPN网关动态负载平衡技术,可以实现上万个并发客户接入,同时,还可实现线路实时备份和带宽捆绑功能,适应于大规模的行业应用及电信级VPN运营。
(6)完备的功能特性,下一代(NGN)VPN产品。
VPN设备类型:服务器软件
VPN特性:主机硬件配置:P4CPU/256M内存/1...
其他功能:WIN32/LINUX平台服务器软件和NG...
协议:TCP/IP
前言
第1章 认识PLC
1.1 概述
1.1.1 PLC简介
1.1.2 PLC的外观、结构及工作原理
1.1.3 PLC的操作方法和步骤
1.1.4 PLC的技术性能指标
1.1.5 PLC的应用领域和发展趋势
1.2 西门子S7-200PLC集成开发环境
1.2.1 STEP7-Micro/WIN32的安装
1.2.2 S7-200PLC的软件开发环境STEP7-Micro/WIN32
1.2.3 PLC程序的生成及运行
1.3 S7-200PLC仿真软件介绍
1.3.1 S7-200PLC仿真软件简介
1.3.2 S7-200PLC仿真软件的使用
思考与练习
第2章 PLC基本指令学习
2.1 S7-200PLC基本指令
2.1.1 概述
2.1.2 S7-200PLC的编程元件和数据存储
2.1.3 基本逻辑指令
2.1.4 定时计数指令
2.1.5 比较指令
2.2 三相电动机启动控制
2.2.1 电动机启保停控制
2.2.2 电动机正反转控制
2.2.3 Y-△减压启动
2.2.4 多点启动控制
2.3 综合编程实例
2.3.1 单速三相异步电动机控制
2.3.2 多速三相异步电动机控制
思考与练习
第3章 步进电动机PLC控制程序设计
3.1 指令学习
3.1.1 移位指令
3.1.2 数据传送指令
3.1.3 中断指令
3.1.4 高速计数器指令
3.1.5 高速脉冲输出指令
3.2 步进电动机及接线
3.2.1 步进电动机的工作原理
3.2.2 步进电动机的通电方式
3.2.3 步进电动机的步距角
3.2.4 步进电动机与PLC的连接方式
3.2.5 步进电动机常用应用及型号
3.3 三相步进电动机控制实例1
3.4 三相步进电动机控制实例2
思考与练习
第4章 液压气动PLC控制程序设计
4.1 液压气动元件基本知识
4.1.1 液压或气动元件
4.1.2 液压气动原理图
4.1.3 动作关系图和电磁阀功能转换表
4.2 程序控制类指令
4.2.1 步进顺序控制指令
4.2.2 循环跳转指令
4.2.3 子程序调用及返回
4.3 气动PLC控制实例
4.3.1 单动缸控制
4.3.2 双动缸控制
4.3.3 PLC与气压过程控制
思考与练习
第5章 PLC数据采集与存储程序设计
5.1 PLC的新角色
5.1.1 PLC作为数据终端的新角色
5.1.2 PLC作为专用数据终端
5.1.3 PLC作为兼用数据终端
5.2 PLC数据保存及访问
5.2.1 S7-200PLC的存储区以及数据保存
5.2.2 S7-200的V区及其访问
5.3 PLC数据采集
5.3.1 PLC的开关量采集
5.3.2 PLC的模拟量采集
5.3.3 PLC的脉冲量采集
5.4 PLC数据存储
5.4.1 PLC进行定时存储
5.4.2 PLC进行事件存储
5.4.3 压缩存储
5.4.4 安全存储
思考与练习
第6章 PLC模拟量控制程序设计
6.1 模拟量控制概述
6.1.1 PLC模拟量控制过程
6.1.2 PLC模拟量控制的目的
6.1.3 PLC模拟量控制的要求
6.2 PLC模拟量简单控制
6.2.1 用开关量ON/OFF比例控制输出
6.2.2 比较设定ON/OFF输出控制
6.3 模拟量PID控制
6.3.1 PID控制概述
6.3.2 PID控制参数及整定
6.3.3 S7-200PLC的PID指令
6.3.4 S7-200PLC的PID指令使用
6.3.5 S7-200PLC的PID指令向导
6.3.6 S7-200PLC的PID整定控制面板
思考与练习
第7章 PLC数据通信与组态
7.1 PLC通信概述
7.1.1 PLC通信联网的意义
7.1.2 PLC通信的类型
7.1.3 S7-200PLC网络通信配置
7.1.4 网络的建立
7.2 PLC通信程序设计
7.2.1 S7-200PLC网络读写指令
7.2.2 S7-200PLC的网络读写指令应用实例
7.2.3 发送和接收指令
7.2.4 S7-200PLC发送和接收指令应用实例
7.3 组态软件简介
7.3.1 组态软件概念
7.3.2 常用组态软件简介
7.3.3 WinCC的简单组态
7.4 人机界面HMI简介
7.4.1 西门子的人机界面
7.4.2 TD200使用简介
思考与练习
第8章 PLC控制实训
8.1 五星彩灯控制系统
8.1.1 实训内容
8.1.2 I/O地址分配
8.1.3 PLC接线图
8.1.4 PLC梯形图控制程序
8.2 交通信号灯控制系统
8.2.1 实训内容
8.2.2 I/O地址分配
8.2.3 PLC接线图
8.2.4 PLC梯形图控制程序
8.3 自动送料控制系统
8.3.1 实训内容
8.3.2 I/O地址分配
8.3.3 PLC接线图
8.3.4 PLC梯形图控制程序
8.4 八层电梯控制系统
8.4.1 实训内容
8.4.2 I/O地址分配
8.4.3 PLC接线图
8.4.4 PLC梯形图控制程序
8.5 组合机床控制系统
8.5.1 实训内容
8.5.2 I/O地址分配表
8.5.3 PLC接线图
8.5.4 PLC控制状态流程图
8.5.5 PLC梯形图控制程序
附录S7-200PLCCPU存储器的范围与特性
参考文献 2100433B