博文
用ATL实现VC插件(1)(2008-03-24 22:14:00)
摘要:用ATL实现VC插件
作者: IUNKNOW 出处: vchelp
4) 选择属性对话框的Names标签,在C++组的Short Name编辑框输入Copyright(如图)
5) 选择DevStudio Add-in标签,在Add-in Features中选择Application Events,选择OK按钮确定
上面的步骤生成基本Add-in框架代码
6) 创建IDE工具条
a) 创建两个Bitmap 文件作为工具条图像资源
IDB_TOOLBAR_LARGE_COPYRIGHT 32 x 32大小
IDB_TOOLBAR_MEDIUM_COPYRIGHT 16 x 16 大小
b) 在Ccopyright 类的OnConnection()函数中加入创建工具条按钮的代码, 详细代码:
HRESULT CCopyright::OnConnection(IApplication* pApp,
VARIANT_BOOL bFirstTime, long dwAddInID, VARIANT_BOOL* bOnConnection)
{
HRESULT hr = S_OK;
m_spApplication = pApp;
m_dwAddInID = dwAddInID;
// Connect up to application event sink
AtlAdvise(pApp, GetUnknown(), IID_IApplicationEvents, &m_dwAppEvents);
hr = pApp->SetAddInInfo((long)_Module.GetModuleInstance(),
static_cast<ICopyright*>(this), IDB_TOOLBAR_MEDIUM_COPYRIGHT,
IDB_TOOLBAR_LARGE_COPYRIGHT, dwAddInID);
// LP......
用ATL实现VC插件(2008-03-24 22:12:00)
摘要:用ATL实现VC插件
作者: IUNKNOW 出处: vchelp
要实现Add-in Object 有三种方法,一种是利用ATL COM Wizard中的ATL对象 Add-in Object来实现,另一种是利用DevStudio Add-in Wizard来实现,第三种就是手工写所有的代码,如果手工写,一定要记住实现IDSAddIn接口,这样才能才能增加新的命令和工具条到VC的IDE环境中去。
我主要是讲解ATL COM Wizard,所以我用第一种方法来实现。在这里我实现了IApplicationEvents 和 IDSAddIn接口,实现IapplicationEvents接口是应为我要对Application 对象进行操作,比如NewDocument()、WorkspaceOpen()等等方法。而实现IDSAddIn接口,是应为要增加新的命令和工具条到VC的IDE环境中去。
示例程序实现的功能:
1)在VC的IDE环境中增加一个工具条(4个按钮),并且能操纵VC的IDE环境,(工具条如下图) 第一个按钮弹出对话框允许修改用户信息,第二个按钮最小化所有打开的窗口,第三个最大化所有的窗口,第四个按钮弹出一个Messagbox。
2)对每一个新建的文档,根据文档类型在文件头自动加上版权信息和相关内容注释。
观看效果:下载源代码,编译后生成Sample_02.dll,然后在VC的环境中,选择菜单tools/customize ,然后选择最后一个Add-ins and Macro Files 标签,选择Browse按钮,选择刚才编译后的Sample_02.dll文件,然后在Add-ins adn Macro列表框中选中Copyright Class ,然后Close Customize对话框,这时VC的IDE环境就会出现一个有四个按钮的工具条(见上图)。大家可以分别点击这几个按钮看看效果,也可分别在VC环境中(新建)New 几种类型的文件(.cpp ,.h .htm 和.txt文件)看看文件头是否加上版权信息.
下面一步步引导大家来实现此例子程序:
1) 用ATL COM Wizard......
Por* C/C++编程思路(2008-03-12 19:33:00)
摘要:Por* C/C++编程思路:
1、包含头文件
与开发C/C++应用程序相同,当编写Por* C/C++应用程序时,首先应该包含头文件。但是要注意,不仅需要包含C/C++的头文件,而且还需要包含Por* C/C++的头文件。当编写Por* C/C++应用程序时,一般需要包含以下C/C++头文件:
stdio.h
iostream.h
stdlib.h
string.h
除了需要包含C/C++头文件,开发人员还需要包含Por* C/C++头文件,其中头文件sqlca.h是必须包含的,并且在某些情况下还需要包含其他头文件,它们的作用如下:
sqlca.h:定义了SQLCA结构,该结构用于与SQL语句执行交互操作
sqlda.h:定义了SQLDA结构,当使用Oracle动态SQL方法四时,必须包含该结构
oci.h:定义了所有OCI函数,当编写LOB应用,对象类型应用、集合类型应用时,必须包 含该结构
sql2oci.h:定义了用于与OCI交互的SQLLIB函数。当嵌入OCI函数时,必须要包含该头文件。
其他
当编写Por* C/C++应用程序时,通过使用C预处理器指令#include可以包含系统(C/C++)头文件和Por* C/C++头文件。示例如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlca.h>
2、定义全局变量(可选)
当编写Por* C/C++程序时,如果要定义所有函数都可以引用的宿主变量,那么要在包含了头文件之后,立即定义这些全局变量。全局宿主变量既可以直接定义,也可以使用定义部分定义。示例如下:
EXEC SQL BEGIN DECLARE SECTION;
char username[10],password[10],server[10];
EXEC SQL END DECLARE SECTION;
3、定义外部函数(可选)
当编写Por* C/C++程序时,有些情况下需要调用SQ......
复杂指针解析[转](2008-01-09 15:55:00)
摘要:右左法则----复杂指针解析
----本文转自http://www.briup.com.cn/export/sites/briup/technology/modules/news/cpp/news_0007.html_410175175.html
因为C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法
则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用
来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:
The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you
encounter parentheses, the direction should be reversed. Once everything in the parentheses has been
parsed, jump out of it. Continue till the whole declaration has been parsed.
这段英文的翻译如下:
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东
西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为
一个声明里面可能有多个标识符,但未定义的标识符只会有一个。
现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:
int (*func)(int *p);
首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指......
FAQ 11:如何避免死锁?(2007-12-29 18:20:00)
摘要:FAQ 11:如何避免死锁?
线程A需要资源X,而线程B需要资源Y,而双方都掌握有对方所要的资源,这种情况称为死锁(deadlock),或死亡拥抱(the deadly embrace)。
任何时候当一段代码需要两个或更多资源时,都有潜在性的死锁阴影。死锁的情况可能非常复杂,许多线程的独立性彼此纠缠在一起。虽然有一些算法可以侦测并仲裁死锁状态,基本上它们仍嫌过于复杂。对大部分程序而言,最好的政策就是找出一种方法以确保死锁不会发生。强迫将资源锁定,使它们成为“all-or-nothing”(不要统统获得,要不统统没有) ,可以阻止死锁的发生。......
FAQ 10:如果线程在critical sections中结束会怎么样? (2007-12-29 18:20:00)
摘要:FAQ 10:如果线程在critical sections中结束会怎么样?
critical section的一个缺点就是,没有办法获知进入critical section中的那个线程是生是死。从另一个角度看,由于critical section不是核心对象,如果进入critical section的那个线程结束了或当掉了,而没有调用LeaveCriticalSection()的话,系统没有办法将该critical section清除。如果你需要那样的机能,你应该0
使用mutex。......
FAQ 09:如果线程在Critical sections中停很久会怎么样?(2007-12-29 18:19:00)
摘要:FAQ 09:如果线程在Critical sections中停很久会怎么样?
如果一直让资源被锁定,你就会阻止其他线程的执行,并把整个程序带到一个完全停止的状态。以critical section来说,当某个线程进入critical section时,该项资源即被琐定。
我们很难定义所谓“长时间”是多长。如果你在网络上进行操作,并且是在一个拨号网络上,长时间可能是指数分钟,如果所处理的是应用程序的一项关键性资源,长时间可能是数个毫秒(milliseconds)。
我能够给你的最牢固而立即的警告是:千万不要在一个critical section之中调用sleep()或任何wait...()API函数。
当你以一个同步机制保护一个资源时,有一点必须记住,那就是:这项资源被使用的频率如何?线程必须多快释放这份资源,才能确保整个程序的运行很平顺?
某些人会关心这样的问题:如果我再也不释放资源(或不离开critical section,或不释放mutex……等等),怎么样?答案是:不会怎么样!!
OS不会当掉。用户不会获得任何错误信息。最坏的情况是,当主线程(一个GUI线程)需要使用这被锁定的资源时,程序会挂在那儿,动也不动。真的,同步机制并没有什么神奇魔法。......
FAQ 08:什么是一个被激发的对象?(2007-12-25 15:16:00)
摘要:FAQ 8:什么是一个被激发的对象?
可被WaitForSingleObject()使用的核心对象有两种状态:激发和未激发。WaitForSingleObject()会
在目标物变成激发状态时返回。事实上我们也几乎是以此作为对象激发与否的操作型定义。
当核心对象被激发时,会导致WaitForSingleObject()醒来。
当线程正在执行时,线程对象处于未激发状态。当线程结束时,线程对象就被激发了。因此,任何线
程如果等待的是一个线程对象,将会在等待对象结束时被调用,因为当时线程对象自动变成激发状态。
......
FAQ 07:我如何得知一个核心对象是否处于激发状态?(2007-12-25 15:15:00)
摘要:FAQ 07:我如何得知一个核心对象是否处于激发状态?
关于time-out,有一个特别重要的用途,但是很少被人注意。设定time-out为0,使你能够检查
handle的状态并立刻返回,没有片刻停留。如果handle已经备妥,那么这个函数成功并传回
WAIT_OBJECT_0。否则,这个函数立刻返回并传回WAIT_TIMEOUT。
另有其他的一些理由使你需要设定time-out参数。最简单的一贯饿理由就是你不希望被粘住,特别是
在调试的时候。如果你所等待的线程进入了一个无穷循环,你或许可以根据此函数的返回值以及time-out
终了与否,获得一些警告。
......
FAQ 06:如果线程还在运行而我的程序结束了会怎么样?(2007-12-25 15:14:00)
摘要:FAQ 08:如果线程还在运行而我的程序结束了会怎么样?
程序启动后就执行的那个线程称为主线程(Primary thread)。主线程有两个特点。第一,它必须负
责GUI(Graphic User Interface)程序中的主消息循环。第二,这一线程的结束(不论是因为返回或因为
调用了ExitThread())会使得程序中的所有线程都逼迫结束,程序也因此而结束。其他线程没有机会做清
理工作。
......