http://www.vihome.com.cn/bbs/viewthread.php?tid=4675
Labwindows扫盲+技巧贴,CVI学习必看
1.、
CVI适合什么人使用?
CVI是基于ANSI C的快速 开发环境,适用于有C,C++基础。使用VB,VC,BC运用 控件式组织用户 界面的工程师。 % s# E6 P; {8 X
* w3 X$ e; { P m- y8 P5 y L
2、CVI有几种版本? , T5 C* j' I0 C) z
NI分为labwindows Full development system,labwindows base development system。价格分别为20450,10220RMB。 7 k% h! Q1 m6 |% z9 i5 s1 X8 ~
完整版RMB20450 1 v% /( B7 C5 H# h
基本版RMB10220
- X6 K F" f1 Y9 _
目前最新的是8.11版,下图是CVI的版本历史: - W( k. i ~3 B# `- h* B6 V
, Q, E7 ?. m8 B2 ~
3、CVI开发的程序能否*** 运行?
可以。和所有的开发 工具一样,CVI 编写的程序只要提供CVI运行支持库(CVI runtime)即可。
4、CVI的运行支持库在哪里 下载? $ ?) x' b2 u" T$ `, x
LabWindows/CVI Run-Time Engine 8.1.1 for Windows 2000/Vista x64/Vista x86/XP
http://ftp.ni.com/support/softlib/labwindows/cvi/Run-Time%20Engines/8.1.1/NILWCVIRTE811.exe
J) a- g# s. E6 r$ p, o8 g
5、是否要每次手动安装支持库?
否,CVI程序带有发布 功能。自动生存你项目需要的所有运行库。
菜单Build——distributions下。
/ U( F [$ z' h N1 C6 N
6、 EXE程序的信息在哪里 定义?
菜单Build——Build steps...下可以更改EXE的图标,版权信息等等。 ( z$ Y9 }" G* d: `$ E' e
7、 新手怎么开始学习CVI? b) S2 C' i$ K
新手可以先看看这些书籍和 资料。
http://www.vihome.com.cn/bbs/thread-4658-1-1.html : y9 B4 B7 S/ V2 T
http://www.vihome.com.cn/bbs/thread-3180-1-1.html . y( w K2 _- _5 c( x. O
http://www.vihome.com.cn/bbs/thread-3173-1-1.html
# E) T6 W9 h! T8 S }. u
8、CVI在哪里下载? , W' B3 @ L. S7 W
http://www.vihome.com.cn/bbs/thread-4667-1-1.html , n$ b, C% W4 a I' U
http://www.vihome.com.cn/sq/?uid/4829
9 d# ]) s b! ?/ o& y3 Q# /6 `9 V
9、如何在CVI中获得 系统信息 9 y5 g/ A0 q+ n* Q6 /: A1 Y, y
使用CVI提供的toolbox: " h7 E a4 @+ F
4 J, s3 L" e) i
GetWinOSVersion获得操作系统信息: : ]: y( `1 L7 ?$ y, G( G
GetWindowsDirs获得Windows目录 # }1 o( g! ? A! _
GetDiskSpace得到磁盘空间大小,对于 文件 保存有用,先判断磁盘大小再保存,否则提示。
GetMemoryInfo获得 内存信息。 * S* g# }6 v+ /! O, @0 l8 z, D
GetDiskSpace ("C:", totalBytes64, &freeBytes64);
diskSpaceMB = (double)totalBytes64.hiBytes * 4096. + 7 { _( b, q( O
(double)totalBytes64.loBytes/1048576.; [$ [( T) f/ v, p( i9 K
freeSpaceMB = (double)freeBytes64.hiBytes * 4096. + ; O! A) s# }" |5 v) p8 I
(double)freeBytes64.loBytes/1048576.; # i5 b# v o7 z s" t
9、cvi中如何打开别的 应用程序文件,如Doc,PDF,HLP? / q. z3 l. [( @; U0 M! J4 q
OpenDocumentInDefaultViewer ("c:/aaa.pdf", VAL_NO_ZOOM); 7 [( ~5 v2 x n
z# i1 Y. c1 X1 ]" o5 L0 {
10、怎么在CVI中使用非NI公司的PCI板卡?
其它厂家虽然没有NI这样的FP文件或向导,但都提供 DLL 动态链接库使用。VCBC,CVI通用。
11、如何使用DLL? , S# ]2 i t- Z& a- z/ C5 g% j
需要DLL文件和H头文件,LIB文件。#inlcude "头文件名.h"加入CVI中。将*.lib文件加入工程中。工程右击——add file...即可使用DLL。
12、没有LIB文件如何使用DLL? ) F- l' q1 K% d) [4 D" Q
在CVI菜单中打开DLL相应的.h文件。Option——Generate DLL Import Library 选择DLL文件,即可生存LIB文件。 : w- j, m! y( D/ [8 o6 [0 U! }! N
13、如何根据DLL和.H文件看到C 代码? ^8 ~4 K7 h: |: V" ?
Option——Generate DLL Import source选择DLL文件,即可生存C文件。不过只有 函数定义,源代码就不用想了,现在还没有DLL的破解。
! q" E: o9 ~- V3 a4 t
14、如何创建DLL程序文件? $ z0 J0 D7 N+ X7 L M, /
Build——Target Type——Dynamic Link Library ,即可将当前的工程生存DLL形式。同理Static Library生存Lib形式。
15、运行时窗口的响应慢,显示不及时?
CVI是事件驱动式的运行方法,排队响应个个事件。造成显示滞后。需要强制在函数中加入ProcessSystemEvent()。当然有效的方法是使用CVI或API的多线程 技术。
16、CVI中获取本地计算机的IP地址 " m6 h; ~3 {, e( x4 I7 w
可以调用 GetTCPHostAddr 函数。需要注意的是,该函数获取的是当前程序运行的 电脑的默认IP地址。GetTCPHostAddr 函数会向Windows操作系统获取所有可用的IP地址的列表,但返回的只是其中的第一个。 . x$ a4 k" i v! T2 [- b! j3 `
同样地,如果要获取该电脑的所有IP地址,可以调用GetAllTCPHostAddresses 函数来实现。 ; [$ v0 C) x, }9 b+ G
0 O* |" d- j+ M. Q6 M
17、CVI如何实现右键菜单功能? 9 I1 P0 w( c2 m
调用编辑好的右键菜单可以使用以下两个函数实现: 0 Q. G7 ~" m( s) b; V
menuHandle = LoadMenuBar (0, "popupmenu.uir", MENUBAR); * {( ?. Q$ S- W- v/ C4 b
RunPopupMenu (menuHandle, MENUBAR_MENU1, panel, eventData1, eventData2, 1, 1, 1, 1); : Q; ^; u2 I: V' A4 V
4 {8 q: s H* @* U' s2 R
18、CVI对多线程的如何支持? : k3 k" Y d) z, ?+ h
CVI对多线程的支持(1)概念篇
【 原帖地址: http://easons.blogbus.com/logs/2006/04/2366573.html】 1 l, Q. Q: d( z+ G
多线程对于windows应用程序来说,并不是什么先进的技术,打开你的任务管理器,选择“进程”分页,点击菜单的在“查看”->选择列,在“线程计数”前打勾,确定后你在“进程”分页里头看到现在在运行的绝大多数程序都基于2个以上的线程。 9 Z! y2 h3 p- ?8 Z+ y! A/ g9 N9 u! b
那么进程线程的概念以及他们之间的关系又是什么呢? , K, ?' F l6 U' I
线程技术是指开发架构将应用程序的一部分分离为“线程”,使线程与程序其余部分执行步骤不一致。线程是一种特殊的对象,是操作系统执行多任务的一部分,它允许应用程序的一部分***于其他对象而单独运行,因此也就脱离了应用程序的常规执行顺序。
目前主流的Windows系统都是基于多任务机制,即可同时运行多个应用程序(“应用程序”这个词并不恰当,恰当的说法是“进程”)。当启动应用程序时,系统就会为该应用程序分配所需的内存以及其他资源。内存和资源的物理分离叫做进程。换言之,进程是应用程序的一个运行实例,当然,应用程序可以启动多个进程。每个进程至少有一个基本线程(主线程)。线程与数据一起隔离在某一物理区域,在进程中声明的数据可通过该线程进行访问。
Windows操作系统为抢占式多任务运行机制,即采用 时间片轮换的方式来执行多任务,时间片轮换的基本对象是线程。操作系统为每一个线程分配时间片,让该线程在这个时间段内运行,之后中断该线程的运行,启动另外的线程执行。多线程技术的优势在于将进程分解,在主线程外产生一个或几个辅助线程,用于完成如 数据采集、 网络访问、数据存储等后台工作。
CVI对多线程的支持(2)基本原理
【原帖地址: http://easons.blogbus.com/logs/2006/05/2518754.html】 5 r- T3 F1 g+ n; p/ F6 x6 A
在典型的LabWindws/CVI多线程程序中,使用下线程创建、显示并运行用户界面,在次线程中,运行其它的对时间要求很高的操作[3]。LabWindows/CVI提供了两种 设计辅助线程的机制,分别为线程池(thread pools)和异步定时器(asynchronous timers),线程池适用于需要不连续地执行多次或在循环中执行的任务,而异步定时器适用于在固定时间间隔内执行的任务(只支持一个辅助线程),若要使用多个辅助线程,只能采用线程池技术。
多线程的创建 % u1 ^, D- w( X, A8 t
线程池机制中辅助线程的创建是通过调用实用库(Utility Library)的CmtScheduleThreadPoolFunction Adv函数,把想要在次线程中运行的函数名传递给它,线程池调用这个函数在它的其中一个线程中运行。根据线程池的 设置和当前状态,线程池创建一个新的辅助线程,使用一个已经存在的空闲线程,或等待一个活动的线程空闲来执行需要调度的函数。 ' t" D. s; b D7 e) m
多线程间的数据安全 ) C7 y; Y$ Q; V# b X" [) j
数据保护是在使用辅助线程时必须要 解决的关键问题,防止多个线程同时操作某一 变量,导致逻辑错误,是多线程协调运行的重要内容。在CVI中,系统提供了线程锁(blocked)、线程安全变量(thread safe variables)和线程安全队列(thread safe queues)三种机制来保护共享数据,实现线程间安全的数据传输。其中线程安全队列保护机制传输数据量大;且读取数据和写数据互不影响;数据传输基于事件模式,可以注册读取数据和写数据回调函数在队列数据达到指定数量才被调用。基于多线程监控程序的典型应用为:辅助线程采集处理大量数据并传递给主线程进行显示,线程安全队列机制是最佳的选择。
写入线程把要传送给读出线程的数据 打包后写入到数据队列中,数据队列采用先进先出的工作模式,每写入一个数据包,系统调用在读出线程指定的回调函数来处理数据。选择合适的队列长度后,即使读出线程没有完成上一个数据包的读出,写入线程依然可以安全的写入下一个数据,对数据队列可以同时进行读写操作,线程间的数据传输是安全可靠的。
监视控制辅助线程
监视控制辅助线程的运行,是多线程协调运行的另一个关键问题,CVI提供了CmtGetThreadPoolFunc- tionAttribute函数来监视辅助线程的状态。在多 通道、定时数据采集的监控 软件中,多个辅助线程定时处理某项任务,直到主线程通知其停止。
CVI提供的异步定时器机制可以方便的实现以上功能,但异步定时器机制只能创建一个辅助线程。结合线程池机制和定时器控件成为可行的选择之一。CVI在创建 面板的线程中调用该面板控件的回调函数,即要在辅助线程中运行某一定时器控件的回调函数,则该定时器控件所在的面板必须在辅助线程中创建。这样,主线程就可以通过开关该定时器来控制辅助线程开始或停止某项任务,实现多个辅助线程定时处理某项任务,且每个线程定时可以不同。
6 J7 ~5 y: H# N% y. s) q. |( _
19、如何实现CVI窗体的全屏? " A3 Y1 ]/ t# A n( s! X
GetMonitorFromPanel (Main, monitor);//获得显示器ID
GetMonitorAttribute (monitor, ATTR_HEIGHT, height);//得到高度 ) S, t# Z+ z+ B" H
GetMonitorAttribute (monitor, ATTR_WIDTH, width);//得到宽度
SetPanelSize (Main, height-25,width);//设置窗口高宽度 (高度需要去处任务栏的部分) 6 Q( f$ _% F3 L1 X, u
SetPanelPos (Main, 25, 0);//设置窗口位置 2 o8 P i B. [+ C5 e2 l$ S9 [" R
但仍会看到状态栏,像游戏一样的全屏还没想到。希望网页跟贴解决哦。 ) u0 _7 _; K9 U4 M. E- o. d
* u g! m8 N. b. ~, k
以解决 n7 y% H" m. V ^) o& p5 w
DisableTaskSwitching();
SetPanelAttribute (handle, ATTR_CAN_MINIMIZE, FALSE); ( N/ k$ M' u( ?/ G8 w+ m3 o
SetPanelAttribute (handle, ATTR_CAN_MAXIMIZE, FALSE); 6 q; X% e1 z3 _1 v E G. B5 m0 {
SetPanelAttribute (handle, ATTR_CLOSE_ITEM_VISIBLE, FALSE); $ }! [. p4 T$ a0 e1 b. x
SetPanelAttribute (handle, ATTR_MOVABLE, FALSE);
SetPanelAttribute (handle, ATTR_SIZABLE, FALSE);
SetPanelAttribute (handle, ATTR_SYSTEM_MENU_VISIBLE, FALSE); " B/ /, L7 T* g" P7 ^6 L9 K z( H+ U
SetCtrlAttribute (handle, PANEL_NORMAL_TEXT, ATTR_VISIBLE, FALSE);
SetCtrlAttribute (handle, PANEL_LOCKOUT_TEXT, ATTR_VISIBLE, TRUE);
SetPanelAttribute (handle, ATTR_WINDOW_ZOOM, VAL_MAXIMIZE);
( j. m" U) V+ K1 v V+ M& b0 n
20、如何在LABWINDOWS中调用MATLAB程序?
CVI和Matlab混合编程,必须要先安装Matlab
在CVI中,建立ActiveX控件服务器,选择Matlab Automatin Server Type Library.(Matlab必须在CVI之前安装才能看到这个选项),创建后将生成三个文件,XXX.fp XXX。C和XXX.h,将。C和。H文件包含在CVI工程中就可以了。。C文件中包含着CVi和Matlab的接口函数。
其中就包括打开Matlab函数,运行Matlab函数等。 * B# u/ L8 B1 h! y# f8 q
- A/ q: d9 r1 ?0 w) I3 d
21、如何在CVI中播放Flash影片? 6 Y" G9 ?8 }0 f8 b3 C' r0 N7 w
需要先安装好FLASH PLAYER的IE插件。
实现方法:主要是通过调用ActiveX控件的方式进行。需要在panel上创建一个ActiveX 容器。 8 W, C: q) B; y/ ^* /+ H
第一步:获得ActiveX控件句柄;
errorCode = MD_NO_ERROR; 7 S8 U6 H! e# v2 R2 m _6 `
errorCode = GetObjHandleFromActiveXCtrl (panel, control, movie); L! E3 f6 x4 m% b0 }' |
if(errorCode != 0) * m K4 L& Z$ ~7 }6 F& d* Y: /
goto error; ) P3 d0 T1 R+ A* H3 x+ ^- Y) ^
第二步:设置播放文件路径; 6 t$ R! u; m/ O. P6 _, ~: }
errorCode = ShockwaveFlashObjects_IShockwaveFlashSetMovie(*movie, NULL, path); $ m1 h; e8 S0 H8 L. ?8 a5 M3 _
if(errorCode < 0)
goto error;
第三步:开始播放文件 % g0 W9 u! ~' W) N' K, R
errorCode = ShockwaveFlashObjects_IShockwaveFlashPlay (*movie, NULL);
if(errorCode < 0) 4 W; Y; v5 f7 x' K r+ E: d
goto error; ; H7 {$ X3 S. t* V0 ~% L$ u
第四步:关闭打开的对象句柄; : R0 `. `, i) g) ~! E
errorCode = CA_DiscardObjHandle (movie); $ b" ^( ]% F% V$ R( @ o7 B, ?
$ S+ K1 t$ X7 i" H
22、如何动态调用DLL? ! P4 b7 H( |8 Z5 y# J: L$ |
#include <windows.h>
#include <ansi_c.h> + M. }4 L4 s' `. {% J* @
#include <utility.h> : R) ]7 h( R$ ?
#include <cvirte.h> ) ? ~" D7 E( u$ M. c
根据函数申明进行定义
typedef int(*lpaddfun)(char[], char[]);
int main (int argc, char *argv[])
{ p$ g+ Q9 G; q3 R- H( {7 |- E
void *handle=0; $ R$ i+ @: L! s. b9 u; W
char str1[100],str2[100];
lpaddfun DISKID32; g; f+ /6 v% i4 V3 d6 D6 r
HMODULE DLLhandle;
if (InitCVIRTE (0, argv, 0) == 0) 6 {3 X8 f9 o. j3 _( B* Y2 P D" v4 [# ^
return -1; /* out of memory */ ) X2 Q3 X1 x$ a x5 H
E- i6 `, X; H# r9 U0 Z2 a4 X; S
DLLhandle = LoadLibrary ("d://Customer//diskid32v2.00//DiskID32.dll"); 5 j" X0 W7 w3 A; Q! Y$ ^
DISKID32 = (lpaddfun)GetProcAddress (DLLhandle,"DiskID32");
, h. E- U: X/ p' F6 M
//执行函数
8 s3 /5 N F2 U+ h. X9 i9 V
释放DLL - W; u; ^4 ]8 k" K0 ~7 {
FreeLibrary(DLLhandle);
} 8 O# O- g- |6 G
23、CVI编译器设置 参数的意思?
build options菜单Default calling convention选项中,有两个选项,一个是"cdecl",另一个是"stdcall",
StdCall pascal cdecl 区别:参数传入Stack的顺序有所不同 g! S) g9 g/ |- v4 z
8 h T/ |; Q: ]4 E0 @4 C( ]9 T
Directive Parameter order Clean-up Passes parameters in registers? " J2 w- J+ F8 }" @. F. h" x
register Left-to-right Routine Yes + O$ k. k8 T2 f" Z U H
pascal Left-to-right Routine No 4 /3 p) c ^3 f& S8 A: e
cdecl Right-to-left Caller No
stdcall Right-to-left Routine No
safecall Right-to-left Routine No
! I) f+ u+ |- n) m
_stdcall将参数压栈是按C语言的顺序(从右到左),但与C 语言不同的是它是由被调用者将参数从栈中清除的,所以它的编译文件比_cdecl小。_stdcall是Windows API函数中默认的调用约定,VB、VFP等也采用这个约定。
_cdecl是C语言采用的默认调用方法,它的优点是支持printf这样的可变参数调用。 0 @ e# g# [0 T+ z4 q* {3 M- X
另外,VC++对于两种调用方法的名称转换方法也不同。
24.如何通过编程来新建快捷方式 % ^; b4 D8 U( x1 v
初次接触这个问题,经过查询得知:API提供了一个COM接口调用, IShellLink 将允许你建立一个快捷方式,要在桌面建立一个快捷方式,只要把这个快捷方式保存到桌面目录就可以了。可是这需要了解这个COM接口的调用方法,以及一些API的使用问题,如CreateShortCut,很繁琐,一个小时下来也没有结果。 9 c% f# n; G; J* S/ x
我放弃了上面的想法,开始研究桌面快捷方式,通过对批处理建立的快捷方式的研究,发现当你在桌面建立一个对应的 .url 的文件即可,windows会将其解析为快捷方式。
假设你的目标程序为 D:/IDEasm.exe,下面为其创建桌面快捷方式。 , K; H5 k% S, F% o) V [% ?* f& U
对应的 IDEasm.url 文件内容及 格式如下,(符号 // 后为注释部分,不在文件中) [. D8 p4 e" f1 a ]
---------------------------------------------
[InternetShortcut] //标志
URL=D:/IDEasm.exe //目标程序全路径文件名 8 D4 I6 e. X9 f, x( U6 {+ X
IconFile=D:/IDEasm.exe //以下设置IDEasm.url文件的图标
IconIndex=0 + ~* K, Y7 c# | i1 g7 s
---------------------------------------------
写完后保存,此文件会自动被系统解析成快捷方式的样子。将上面的文件保存在桌面后,就相当于在桌面建立了快捷方式。 ) /2 H2 e; j: ~% i. j: p: R
这样我们只要在程序中用 CreateFile 创建这个 .url 文件就行了,唯一需要改动的只是目标程序的全路径文件名(这可以由程序本身获得)。
1、判断系统盘,可以通过 GetWindowsDirectory 来提取。比如 C:/
2、由上面的结果拼接出桌面的全路径名 'C:/' + 'Documents and Settings/All Users/桌面' 9 b. [5 c, t5 I5 `3 v. o9 V |
综上,在得到桌面的全路径名后,再拼接出我们要建立的 .url文件的全路径文件名即可。最后用 CreateFile 来创建这个文件 (即:C:/Documents and Settings/All Users/桌面/IDEasm.url ),再用WriteFile将上面虚线框中的内容写入此文件即可.
CVI是基于ANSI C的快速 开发环境,适用于有C,C++基础。使用VB,VC,BC运用 控件式组织用户 界面的工程师。 % s# E6 P; {8 X
* w3 X$ e; { P m- y8 P5 y L
2、CVI有几种版本? , T5 C* j' I0 C) z
NI分为labwindows Full development system,labwindows base development system。价格分别为20450,10220RMB。 7 k% h! Q1 m6 |% z9 i5 s1 X8 ~
完整版RMB20450 1 v% /( B7 C5 H# h
- 仪器控制、数据采集和自动化测试的首选
- 完整的分析库,包括曲线拟合和信号处理
- 因特网连接
- 调用Measurement Studio程序
基本版RMB10220
- 集成式开发环境
- 完整的专业用户控件组
- 仪器I/O和DAQ助手
- IVI驱动连接
- .NET和ActiveX支持
- X6 K F" f1 Y9 _
目前最新的是8.11版,下图是CVI的版本历史: - W( k. i ~3 B# `- h* B6 V
, Q, E7 ?. m8 B2 ~
3、CVI开发的程序能否*** 运行?
可以。和所有的开发 工具一样,CVI 编写的程序只要提供CVI运行支持库(CVI runtime)即可。
4、CVI的运行支持库在哪里 下载? $ ?) x' b2 u" T$ `, x
LabWindows/CVI Run-Time Engine 8.1.1 for Windows 2000/Vista x64/Vista x86/XP
http://ftp.ni.com/support/softlib/labwindows/cvi/Run-Time%20Engines/8.1.1/NILWCVIRTE811.exe
J) a- g# s. E6 r$ p, o8 g
5、是否要每次手动安装支持库?
否,CVI程序带有发布 功能。自动生存你项目需要的所有运行库。
菜单Build——distributions下。
/ U( F [$ z' h N1 C6 N
6、 EXE程序的信息在哪里 定义?
菜单Build——Build steps...下可以更改EXE的图标,版权信息等等。 ( z$ Y9 }" G* d: `$ E' e
7、 新手怎么开始学习CVI? b) S2 C' i$ K
新手可以先看看这些书籍和 资料。
http://www.vihome.com.cn/bbs/thread-4658-1-1.html : y9 B4 B7 S/ V2 T
http://www.vihome.com.cn/bbs/thread-3180-1-1.html . y( w K2 _- _5 c( x. O
http://www.vihome.com.cn/bbs/thread-3173-1-1.html
# E) T6 W9 h! T8 S }. u
8、CVI在哪里下载? , W' B3 @ L. S7 W
http://www.vihome.com.cn/bbs/thread-4667-1-1.html , n$ b, C% W4 a I' U
http://www.vihome.com.cn/sq/?uid/4829
9 d# ]) s b! ?/ o& y3 Q# /6 `9 V
9、如何在CVI中获得 系统信息 9 y5 g/ A0 q+ n* Q6 /: A1 Y, y
使用CVI提供的toolbox: " h7 E a4 @+ F
4 J, s3 L" e) i
GetWinOSVersion获得操作系统信息: : ]: y( `1 L7 ?$ y, G( G
GetWindowsDirs获得Windows目录 # }1 o( g! ? A! _
GetDiskSpace得到磁盘空间大小,对于 文件 保存有用,先判断磁盘大小再保存,否则提示。
GetMemoryInfo获得 内存信息。 * S* g# }6 v+ /! O, @0 l8 z, D
GetDiskSpace ("C:", totalBytes64, &freeBytes64);
diskSpaceMB = (double)totalBytes64.hiBytes * 4096. + 7 { _( b, q( O
(double)totalBytes64.loBytes/1048576.; [$ [( T) f/ v, p( i9 K
freeSpaceMB = (double)freeBytes64.hiBytes * 4096. + ; O! A) s# }" |5 v) p8 I
(double)freeBytes64.loBytes/1048576.; # i5 b# v o7 z s" t
9、cvi中如何打开别的 应用程序文件,如Doc,PDF,HLP? / q. z3 l. [( @; U0 M! J4 q
OpenDocumentInDefaultViewer ("c:/aaa.pdf", VAL_NO_ZOOM); 7 [( ~5 v2 x n
z# i1 Y. c1 X1 ]" o5 L0 {
10、怎么在CVI中使用非NI公司的PCI板卡?
其它厂家虽然没有NI这样的FP文件或向导,但都提供 DLL 动态链接库使用。VCBC,CVI通用。
11、如何使用DLL? , S# ]2 i t- Z& a- z/ C5 g% j
需要DLL文件和H头文件,LIB文件。#inlcude "头文件名.h"加入CVI中。将*.lib文件加入工程中。工程右击——add file...即可使用DLL。
12、没有LIB文件如何使用DLL? ) F- l' q1 K% d) [4 D" Q
在CVI菜单中打开DLL相应的.h文件。Option——Generate DLL Import Library 选择DLL文件,即可生存LIB文件。 : w- j, m! y( D/ [8 o6 [0 U! }! N
13、如何根据DLL和.H文件看到C 代码? ^8 ~4 K7 h: |: V" ?
Option——Generate DLL Import source选择DLL文件,即可生存C文件。不过只有 函数定义,源代码就不用想了,现在还没有DLL的破解。
! q" E: o9 ~- V3 a4 t
14、如何创建DLL程序文件? $ z0 J0 D7 N+ X7 L M, /
Build——Target Type——Dynamic Link Library ,即可将当前的工程生存DLL形式。同理Static Library生存Lib形式。
15、运行时窗口的响应慢,显示不及时?
CVI是事件驱动式的运行方法,排队响应个个事件。造成显示滞后。需要强制在函数中加入ProcessSystemEvent()。当然有效的方法是使用CVI或API的多线程 技术。
16、CVI中获取本地计算机的IP地址 " m6 h; ~3 {, e( x4 I7 w
可以调用 GetTCPHostAddr 函数。需要注意的是,该函数获取的是当前程序运行的 电脑的默认IP地址。GetTCPHostAddr 函数会向Windows操作系统获取所有可用的IP地址的列表,但返回的只是其中的第一个。 . x$ a4 k" i v! T2 [- b! j3 `
同样地,如果要获取该电脑的所有IP地址,可以调用GetAllTCPHostAddresses 函数来实现。 ; [$ v0 C) x, }9 b+ G
0 O* |" d- j+ M. Q6 M
17、CVI如何实现右键菜单功能? 9 I1 P0 w( c2 m
调用编辑好的右键菜单可以使用以下两个函数实现: 0 Q. G7 ~" m( s) b; V
menuHandle = LoadMenuBar (0, "popupmenu.uir", MENUBAR); * {( ?. Q$ S- W- v/ C4 b
RunPopupMenu (menuHandle, MENUBAR_MENU1, panel, eventData1, eventData2, 1, 1, 1, 1); : Q; ^; u2 I: V' A4 V
4 {8 q: s H* @* U' s2 R
18、CVI对多线程的如何支持? : k3 k" Y d) z, ?+ h
CVI对多线程的支持(1)概念篇
【 原帖地址: http://easons.blogbus.com/logs/2006/04/2366573.html】 1 l, Q. Q: d( z+ G
多线程对于windows应用程序来说,并不是什么先进的技术,打开你的任务管理器,选择“进程”分页,点击菜单的在“查看”->选择列,在“线程计数”前打勾,确定后你在“进程”分页里头看到现在在运行的绝大多数程序都基于2个以上的线程。 9 Z! y2 h3 p- ?8 Z+ y! A/ g9 N9 u! b
那么进程线程的概念以及他们之间的关系又是什么呢? , K, ?' F l6 U' I
线程技术是指开发架构将应用程序的一部分分离为“线程”,使线程与程序其余部分执行步骤不一致。线程是一种特殊的对象,是操作系统执行多任务的一部分,它允许应用程序的一部分***于其他对象而单独运行,因此也就脱离了应用程序的常规执行顺序。
目前主流的Windows系统都是基于多任务机制,即可同时运行多个应用程序(“应用程序”这个词并不恰当,恰当的说法是“进程”)。当启动应用程序时,系统就会为该应用程序分配所需的内存以及其他资源。内存和资源的物理分离叫做进程。换言之,进程是应用程序的一个运行实例,当然,应用程序可以启动多个进程。每个进程至少有一个基本线程(主线程)。线程与数据一起隔离在某一物理区域,在进程中声明的数据可通过该线程进行访问。
Windows操作系统为抢占式多任务运行机制,即采用 时间片轮换的方式来执行多任务,时间片轮换的基本对象是线程。操作系统为每一个线程分配时间片,让该线程在这个时间段内运行,之后中断该线程的运行,启动另外的线程执行。多线程技术的优势在于将进程分解,在主线程外产生一个或几个辅助线程,用于完成如 数据采集、 网络访问、数据存储等后台工作。
CVI对多线程的支持(2)基本原理
【原帖地址: http://easons.blogbus.com/logs/2006/05/2518754.html】 5 r- T3 F1 g+ n; p/ F6 x6 A
在典型的LabWindws/CVI多线程程序中,使用下线程创建、显示并运行用户界面,在次线程中,运行其它的对时间要求很高的操作[3]。LabWindows/CVI提供了两种 设计辅助线程的机制,分别为线程池(thread pools)和异步定时器(asynchronous timers),线程池适用于需要不连续地执行多次或在循环中执行的任务,而异步定时器适用于在固定时间间隔内执行的任务(只支持一个辅助线程),若要使用多个辅助线程,只能采用线程池技术。
多线程的创建 % u1 ^, D- w( X, A8 t
线程池机制中辅助线程的创建是通过调用实用库(Utility Library)的CmtScheduleThreadPoolFunction Adv函数,把想要在次线程中运行的函数名传递给它,线程池调用这个函数在它的其中一个线程中运行。根据线程池的 设置和当前状态,线程池创建一个新的辅助线程,使用一个已经存在的空闲线程,或等待一个活动的线程空闲来执行需要调度的函数。 ' t" D. s; b D7 e) m
多线程间的数据安全 ) C7 y; Y$ Q; V# b X" [) j
数据保护是在使用辅助线程时必须要 解决的关键问题,防止多个线程同时操作某一 变量,导致逻辑错误,是多线程协调运行的重要内容。在CVI中,系统提供了线程锁(blocked)、线程安全变量(thread safe variables)和线程安全队列(thread safe queues)三种机制来保护共享数据,实现线程间安全的数据传输。其中线程安全队列保护机制传输数据量大;且读取数据和写数据互不影响;数据传输基于事件模式,可以注册读取数据和写数据回调函数在队列数据达到指定数量才被调用。基于多线程监控程序的典型应用为:辅助线程采集处理大量数据并传递给主线程进行显示,线程安全队列机制是最佳的选择。
写入线程把要传送给读出线程的数据 打包后写入到数据队列中,数据队列采用先进先出的工作模式,每写入一个数据包,系统调用在读出线程指定的回调函数来处理数据。选择合适的队列长度后,即使读出线程没有完成上一个数据包的读出,写入线程依然可以安全的写入下一个数据,对数据队列可以同时进行读写操作,线程间的数据传输是安全可靠的。
监视控制辅助线程
监视控制辅助线程的运行,是多线程协调运行的另一个关键问题,CVI提供了CmtGetThreadPoolFunc- tionAttribute函数来监视辅助线程的状态。在多 通道、定时数据采集的监控 软件中,多个辅助线程定时处理某项任务,直到主线程通知其停止。
CVI提供的异步定时器机制可以方便的实现以上功能,但异步定时器机制只能创建一个辅助线程。结合线程池机制和定时器控件成为可行的选择之一。CVI在创建 面板的线程中调用该面板控件的回调函数,即要在辅助线程中运行某一定时器控件的回调函数,则该定时器控件所在的面板必须在辅助线程中创建。这样,主线程就可以通过开关该定时器来控制辅助线程开始或停止某项任务,实现多个辅助线程定时处理某项任务,且每个线程定时可以不同。
6 J7 ~5 y: H# N% y. s) q. |( _
19、如何实现CVI窗体的全屏? " A3 Y1 ]/ t# A n( s! X
GetMonitorFromPanel (Main, monitor);//获得显示器ID
GetMonitorAttribute (monitor, ATTR_HEIGHT, height);//得到高度 ) S, t# Z+ z+ B" H
GetMonitorAttribute (monitor, ATTR_WIDTH, width);//得到宽度
SetPanelSize (Main, height-25,width);//设置窗口高宽度 (高度需要去处任务栏的部分) 6 Q( f$ _% F3 L1 X, u
SetPanelPos (Main, 25, 0);//设置窗口位置 2 o8 P i B. [+ C5 e2 l$ S9 [" R
但仍会看到状态栏,像游戏一样的全屏还没想到。希望网页跟贴解决哦。 ) u0 _7 _; K9 U4 M. E- o. d
* u g! m8 N. b. ~, k
以解决 n7 y% H" m. V ^) o& p5 w
DisableTaskSwitching();
SetPanelAttribute (handle, ATTR_CAN_MINIMIZE, FALSE); ( N/ k$ M' u( ?/ G8 w+ m3 o
SetPanelAttribute (handle, ATTR_CAN_MAXIMIZE, FALSE); 6 q; X% e1 z3 _1 v E G. B5 m0 {
SetPanelAttribute (handle, ATTR_CLOSE_ITEM_VISIBLE, FALSE); $ }! [. p4 T$ a0 e1 b. x
SetPanelAttribute (handle, ATTR_MOVABLE, FALSE);
SetPanelAttribute (handle, ATTR_SIZABLE, FALSE);
SetPanelAttribute (handle, ATTR_SYSTEM_MENU_VISIBLE, FALSE); " B/ /, L7 T* g" P7 ^6 L9 K z( H+ U
SetCtrlAttribute (handle, PANEL_NORMAL_TEXT, ATTR_VISIBLE, FALSE);
SetCtrlAttribute (handle, PANEL_LOCKOUT_TEXT, ATTR_VISIBLE, TRUE);
SetPanelAttribute (handle, ATTR_WINDOW_ZOOM, VAL_MAXIMIZE);
( j. m" U) V+ K1 v V+ M& b0 n
20、如何在LABWINDOWS中调用MATLAB程序?
CVI和Matlab混合编程,必须要先安装Matlab
在CVI中,建立ActiveX控件服务器,选择Matlab Automatin Server Type Library.(Matlab必须在CVI之前安装才能看到这个选项),创建后将生成三个文件,XXX.fp XXX。C和XXX.h,将。C和。H文件包含在CVI工程中就可以了。。C文件中包含着CVi和Matlab的接口函数。
其中就包括打开Matlab函数,运行Matlab函数等。 * B# u/ L8 B1 h! y# f8 q
- A/ q: d9 r1 ?0 w) I3 d
21、如何在CVI中播放Flash影片? 6 Y" G9 ?8 }0 f8 b3 C' r0 N7 w
需要先安装好FLASH PLAYER的IE插件。
实现方法:主要是通过调用ActiveX控件的方式进行。需要在panel上创建一个ActiveX 容器。 8 W, C: q) B; y/ ^* /+ H
第一步:获得ActiveX控件句柄;
errorCode = MD_NO_ERROR; 7 S8 U6 H! e# v2 R2 m _6 `
errorCode = GetObjHandleFromActiveXCtrl (panel, control, movie); L! E3 f6 x4 m% b0 }' |
if(errorCode != 0) * m K4 L& Z$ ~7 }6 F& d* Y: /
goto error; ) P3 d0 T1 R+ A* H3 x+ ^- Y) ^
第二步:设置播放文件路径; 6 t$ R! u; m/ O. P6 _, ~: }
errorCode = ShockwaveFlashObjects_IShockwaveFlashSetMovie(*movie, NULL, path); $ m1 h; e8 S0 H8 L. ?8 a5 M3 _
if(errorCode < 0)
goto error;
第三步:开始播放文件 % g0 W9 u! ~' W) N' K, R
errorCode = ShockwaveFlashObjects_IShockwaveFlashPlay (*movie, NULL);
if(errorCode < 0) 4 W; Y; v5 f7 x' K r+ E: d
goto error; ; H7 {$ X3 S. t* V0 ~% L$ u
第四步:关闭打开的对象句柄; : R0 `. `, i) g) ~! E
errorCode = CA_DiscardObjHandle (movie); $ b" ^( ]% F% V$ R( @ o7 B, ?
$ S+ K1 t$ X7 i" H
22、如何动态调用DLL? ! P4 b7 H( |8 Z5 y# J: L$ |
#include <windows.h>
#include <ansi_c.h> + M. }4 L4 s' `. {% J* @
#include <utility.h> : R) ]7 h( R$ ?
#include <cvirte.h> ) ? ~" D7 E( u$ M. c
根据函数申明进行定义
typedef int(*lpaddfun)(char[], char[]);
int main (int argc, char *argv[])
{ p$ g+ Q9 G; q3 R- H( {7 |- E
void *handle=0; $ R$ i+ @: L! s. b9 u; W
char str1[100],str2[100];
lpaddfun DISKID32; g; f+ /6 v% i4 V3 d6 D6 r
HMODULE DLLhandle;
if (InitCVIRTE (0, argv, 0) == 0) 6 {3 X8 f9 o. j3 _( B* Y2 P D" v4 [# ^
return -1; /* out of memory */ ) X2 Q3 X1 x$ a x5 H
E- i6 `, X; H# r9 U0 Z2 a4 X; S
DLLhandle = LoadLibrary ("d://Customer//diskid32v2.00//DiskID32.dll"); 5 j" X0 W7 w3 A; Q! Y$ ^
DISKID32 = (lpaddfun)GetProcAddress (DLLhandle,"DiskID32");
, h. E- U: X/ p' F6 M
//执行函数
8 s3 /5 N F2 U+ h. X9 i9 V
释放DLL - W; u; ^4 ]8 k" K0 ~7 {
FreeLibrary(DLLhandle);
} 8 O# O- g- |6 G
23、CVI编译器设置 参数的意思?
build options菜单Default calling convention选项中,有两个选项,一个是"cdecl",另一个是"stdcall",
StdCall pascal cdecl 区别:参数传入Stack的顺序有所不同 g! S) g9 g/ |- v4 z
8 h T/ |; Q: ]4 E0 @4 C( ]9 T
Directive Parameter order Clean-up Passes parameters in registers? " J2 w- J+ F8 }" @. F. h" x
register Left-to-right Routine Yes + O$ k. k8 T2 f" Z U H
pascal Left-to-right Routine No 4 /3 p) c ^3 f& S8 A: e
cdecl Right-to-left Caller No
stdcall Right-to-left Routine No
safecall Right-to-left Routine No
! I) f+ u+ |- n) m
_stdcall将参数压栈是按C语言的顺序(从右到左),但与C 语言不同的是它是由被调用者将参数从栈中清除的,所以它的编译文件比_cdecl小。_stdcall是Windows API函数中默认的调用约定,VB、VFP等也采用这个约定。
_cdecl是C语言采用的默认调用方法,它的优点是支持printf这样的可变参数调用。 0 @ e# g# [0 T+ z4 q* {3 M- X
另外,VC++对于两种调用方法的名称转换方法也不同。
24.如何通过编程来新建快捷方式 % ^; b4 D8 U( x1 v
初次接触这个问题,经过查询得知:API提供了一个COM接口调用, IShellLink 将允许你建立一个快捷方式,要在桌面建立一个快捷方式,只要把这个快捷方式保存到桌面目录就可以了。可是这需要了解这个COM接口的调用方法,以及一些API的使用问题,如CreateShortCut,很繁琐,一个小时下来也没有结果。 9 c% f# n; G; J* S/ x
我放弃了上面的想法,开始研究桌面快捷方式,通过对批处理建立的快捷方式的研究,发现当你在桌面建立一个对应的 .url 的文件即可,windows会将其解析为快捷方式。
假设你的目标程序为 D:/IDEasm.exe,下面为其创建桌面快捷方式。 , K; H5 k% S, F% o) V [% ?* f& U
对应的 IDEasm.url 文件内容及 格式如下,(符号 // 后为注释部分,不在文件中) [. D8 p4 e" f1 a ]
---------------------------------------------
[InternetShortcut] //标志
URL=D:/IDEasm.exe //目标程序全路径文件名 8 D4 I6 e. X9 f, x( U6 {+ X
IconFile=D:/IDEasm.exe //以下设置IDEasm.url文件的图标
IconIndex=0 + ~* K, Y7 c# | i1 g7 s
---------------------------------------------
写完后保存,此文件会自动被系统解析成快捷方式的样子。将上面的文件保存在桌面后,就相当于在桌面建立了快捷方式。 ) /2 H2 e; j: ~% i. j: p: R
这样我们只要在程序中用 CreateFile 创建这个 .url 文件就行了,唯一需要改动的只是目标程序的全路径文件名(这可以由程序本身获得)。
1、判断系统盘,可以通过 GetWindowsDirectory 来提取。比如 C:/
2、由上面的结果拼接出桌面的全路径名 'C:/' + 'Documents and Settings/All Users/桌面' 9 b. [5 c, t5 I5 `3 v. o9 V |
综上,在得到桌面的全路径名后,再拼接出我们要建立的 .url文件的全路径文件名即可。最后用 CreateFile 来创建这个文件 (即:C:/Documents and Settings/All Users/桌面/IDEasm.url ),再用WriteFile将上面虚线框中的内容写入此文件即可.