CArray为什么有两个CBitmap*?

dxbh7 2009-05-17 06:24:38
CArray<CBitmap*,CBitmap*>为什么有两个CBitmap*?
...全文
89 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
appleboyecho 2009-05-18
  • 打赏
  • 举报
回复
是这样的,第一个参数是存储的数据类型,而第二个参数是使用这个类时需要传递的数据类型。
码侬 2009-05-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hurryboylqs 的回复:]
第一参数是这个array里存储的数据类型
第二参数是这个array类里的成员函数传递参数时的类型,一般是第一个参数的引用
[/Quote]
很好,学习
mmxqq 2009-05-18
  • 打赏
  • 举报
回复


mark
greatws 2009-05-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 WaistCoat18 的回复:]
模板就是这么设计的,不过一般的写法是:
CArray <CBitmap*,CBitmap&>
[/Quote]

我觉得如果是指针的话,还是这样写比较好CArray <CBitmap*,CBitmap*>,因为返回是TYPE&,返回一个指针的引用,在有些地方编译会报错。
如果是对象,写成CArray <CBitmap,CBitmap&>是可以的
hurryboylqs 2009-05-17
  • 打赏
  • 举报
回复
这个可以看下MFC的实现代码的,下面是CArray的声明:

// CArray<TYPE, ARG_TYPE>

template<class TYPE, class ARG_TYPE = const TYPE&>
class CArray : public CObject
{
public:
// Construction
CArray();

// Attributes
INT_PTR GetSize() const;
INT_PTR GetCount() const;
BOOL IsEmpty() const;
INT_PTR GetUpperBound() const;
void SetSize(INT_PTR nNewSize, INT_PTR nGrowBy = -1);

// Operations
// Clean up
void FreeExtra();
void RemoveAll();

// Accessing elements
const TYPE& GetAt(INT_PTR nIndex) const;
TYPE& GetAt(INT_PTR nIndex);
void SetAt(INT_PTR nIndex, ARG_TYPE newElement);
const TYPE& ElementAt(INT_PTR nIndex) const;
TYPE& ElementAt(INT_PTR nIndex);

// Direct Access to the element data (may return NULL)
const TYPE* GetData() const;
TYPE* GetData();

// Potentially growing the array
void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement);
INT_PTR Add(ARG_TYPE newElement);
INT_PTR Append(const CArray& src);
void Copy(const CArray& src);

// overloaded operator helpers
const TYPE& operator[](INT_PTR nIndex) const;
TYPE& operator[](INT_PTR nIndex);

// Operations that move elements around
void InsertAt(INT_PTR nIndex, ARG_TYPE newElement, INT_PTR nCount = 1);
void RemoveAt(INT_PTR nIndex, INT_PTR nCount = 1);
void InsertAt(INT_PTR nStartIndex, CArray* pNewArray);

// Implementation
protected:
TYPE* m_pData; // the actual array of data
INT_PTR m_nSize; // # of elements (upperBound - 1)
INT_PTR m_nMaxSize; // max allocated
INT_PTR m_nGrowBy; // grow amount

public:
~CArray();
void Serialize(CArchive&);
#ifdef _DEBUG
void Dump(CDumpContext&) const;
void AssertValid() const;
#endif
};
hurryboylqs 2009-05-17
  • 打赏
  • 举报
回复
第一参数是这个array里存储的数据类型
第二参数是这个array类里的成员函数传递参数时的类型,一般是第一个参数的引用
biweilun 2009-05-17
  • 打赏
  • 举报
回复
同意楼上的。一般不会那么写的
WaistCoat18 2009-05-17
  • 打赏
  • 举报
回复
模板就是这么设计的,不过一般的写法是:
CArray <CBitmap*,CBitmap&>
1,01.zipDisplaying a 256 color bitmap在程序中显示256色的位图(6KB)2,02.zipCreating a bitmap object from a BMP file从位图文件中创建位图对象(6KB)3,03.zipAn auto-sizing bitmap picture control一个自适应大小的位图控件(16KB)4,04.zipWriting a bitmap to a BMP file将一个位图写到BMP文件中(11KB)5,05.zipBitmap background in MDI Client在多文档客户程序中增加位图底图(4KB)6,06.zipConverting a bitmap to a region将一个位图转换成一个区域(7KB)7,07.zipConverting a bitmap to a region - memory leak fix 将一个位图转换成一个区域--内存泄露的修正(4KB)8,08.zipTransparent Bitmap实现透明的位图(7KB)9,09.zipCopying a bitmap to clipboard拷贝一个位图到剪贴板(5KB)10,10.zipConverting DDB to DIB将一个设备相关的位图转换成设备无关的位图(6KB)11,11.zipConverting DIB to DDB将一个设备无关的位图转换成设备相关的位图(5KB)12,12.zipCreating a DIB section from a BMP file 从BMP文件中创建一个设备无关的位图(5KB)13,13.zipGetting the dimensions of a bitmap得到一个位图的尺寸(4KB)14,14.zipDraw bitmap with grayed 3D effect画一副3维灰边的位图(6KB)15,15.zipDrawing a bitmap显示位图(7KB)16,16.zipDrawing a bitmap from a BMP file从BMP文件中装入位图并显示(6KB)17,17.zipEBGFX Library 推荐一个强大的EBGFX图形库(15KB)18,18.zipEmboss text and other shape on your bitmap 将文字以浮雕方式嵌入你的位图(7KB)19,19.zipApply a 3D bitmap pattern on text or other shapes将文字上色(3维的位图模板)(6KB)20,20.zipEncapsulated Dib API压缩设备无关位图的API(5KB)21,21.zipAn enhanced DIBLOOK sample 一个增强的DIBLOOK例子(5KB)22,22.zipFade in / Fade out Images using Palette animation使用生动的调色板淡入/淡出位图(8KB)23,23.zipPainting the background for a CFormView derived class在CFromView中画背景图(7KB)24,24.zipGradient Fill 有坡度的填充(5KB)25,25.zipPaint a Gradient Color Background显示渐变的背景(6KB)26,26.zipDrawing an image in grayscale画位图到一个灰色刻度中(5KB)27,27.zipFading from color to grayscale a
定义数据结构如下: typedef struct tagMyNode { Mytype type; //元件类型 MySubtype Subtype; //元件子类型 tagMyNode* input1; //输入端1 tagMyNode* input2; //输入端1 tagMyNode* output1; //输出端1 UINT input1value; //输入端input1的值 UINT input2value; //输入端input2的值 UINT output1value; //输出端output1的值 int inputs; //当前已经有几个输入端有值 int number; //对于输入结点的序号 CPoint Orgpoint; //记录元件左上角位置 int width; //记录元件宽度 int height; //记录元件高度 }MyNode;  元件类型:元件类型Mytype type中Mytype是一个枚举类型定义如下: enum Mytype { Node, //结点 Gate, //门 }; 分为两种类型:Node结点和Gate门。  元件子类型:元件子类型MySubtype Subtype中MySubtype也是一个枚举类 型,定义如下: enum MySubtype { Input, //输入端 Output, //输出端 ANDGate, //与门 ORGate, //或门 NOTGate, //非门 NORGate, //或非门 NANDGate, //与非门 XORGate, //异或门 };  指针连接: tagMyNode* input1; tagMyNode* input2; tagMyNode* output1 是指向此结点的指针。由于元件之间是要相互连接的,于是设置这几个指针用于元件之间的连接。其中特殊情况有: 非门:由于非门只有一个输入端,所以非门不用tagMyNode* input2; 输入结点:输入结点只有一个链接端(这里称之为触点),采用tagMyNode* output1 输出结点:同输入结点,只有一个触点,采用tagMyNode* input1;  保存触点值:由于要进行仿真计算,所以还需保存各个触点的值: UINT input1value; UINT input2value; UINT output1value; 同指针连接,有3种特殊情况: 非门:不用UINT input2value; 输入结点:采用UINT output1value; 输出结点:采用UINT input1value;  进位标志:int inputs; 在进行仿真计算时,要用进位标志辅助计算。如与门只有在两个输入端都有值时,即inputs==2时,才能进位。  输入结点序号:int number; 每个输入结点都有不同的序号,从1开始递增。  元件位置和大小: CPoint Orgpoint; int width; int height; Orgpoint用于记录元件在视图中左上角的坐标 width用于记录元件宽度 height用于记录元件高度  电路图编辑模块 电路图编辑模块又分为两个子模块:鼠标放置元件模块,鼠标连接元件模块 首先在工具栏中可以选择这两种状态,如图4 图4 在按钮上单击可以切换状态。 定义一个枚举类型MyStatus来记录当前状态: enum MyStatus { NONE, //鼠标连接元件状态 ANDGATE, ORGATE, NOTGATE, NORGATE, NANDGATE, XORGATE, NODEINPUT, NODEOUTPUT }; MyStatus Status; 其中:NONE为鼠标连接状态,其他为鼠标放置状态。  鼠标放置元件模块 其算法如图5: 图5  DrawObject函数: 首先根据Status的状态,即六个门,两个端结点。共8种来调用DrawObject函数  引入准备好的八张位图(六个门,两个端) CBitmap MyBitMap; MyBitMap.LoadBitmap (nID);  将引入的位图拷贝入窗体窗户区 BITMAP bmpInfo; MyBitMap.GetBitmap (&bmpInfo); pOldBitmap=dc.SelectObject (&MyBitMap); ClientDC.BitBlt (point.x ,point.y,bmpInfo.bmWidth ,bmpInfo.bmHeight,&dc,0,0,SRCAND); dc.SelectObject (pOldBitmap);  用全局变量bmWidth和bmHeight来保存元件的宽度和高度 bmWidth=bmpInfo.bmWidth ; bmHeight=bmpInfo.bmHeight ;  CreateMyObject函数 函数声明为:CreateMyObject(Mytype type, MySubtype Subtype, CPoint point)  初始化元件 MyNode* pNode=new MyNode; pNode->type =type; pNode->Subtype =Subtype; pNode->input1 =0; pNode->input2 =0; pNode->output1 =0; pNode->output2 =0; pNode->Orgpoint =point; pNode->width =bmWidth; pNode->height =bmHeight; pNode->input1value =0; pNode->input2value =0; pNode->output1value =0; pNode->inputs =0;  如果创建的元件为输入结点,则要创建并画输入结点前的序号,这里 采用一个全局数组CArray numpoint来记录结点前序号。 if(Subtype==Input) { //当创建Input时加入点到numpoint数组中 numpoint.Add (CPoint(point.x-15,point.y)); pNode->number =numpoint.GetSize (); //创建时重绘序号 redrawnum(); } 而redrawnum()函数就是将所有输入结点前的序号重绘。  最后将元件加入到全局链表CList MyList中。 MyList.AddTail (pNode);  鼠标连接元件模块 鼠标连接元件模块分为三个过程模块:鼠标移动模块,鼠标按下模块,鼠标抬起模块。  鼠标移动模块 其算法如图6 图6 代码如下: void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default //此时必然是非画图状态,所以status==NONE; if(Status==NONE) { //当前点在某个物件上吗? 并且 //当前点在该物件触点上吗? if(IsPointInObject(point) && IsPointInPut(point)) { //全局变量pNodeNow是在IsPointInObject()这个函数里面记录的 //circlepoint和put是在IsInInput1() IsInInput2() IsInOutput1() //这三个函数中记录的 //判断此时触点时否己连接非常重要 if(IsPutLinked()) { //如果此时触点己连接,则退出 return; } //此时鼠标移进触点 //当前是连接态吗? if(IsLink) { //连接态画图 LinkStatusDraw(point); } //开启画圆圈态 IsDrawCircle=TRUE; //画圆圈 DrawMyCircle(); } else//此时鼠标移出触点 { //如果此时已画圆圈,则要擦除圆圈 if(IsDrawCircle==TRUE) { EraserMyCircle(); //关闭画圆圈状态 IsDrawCircle=FALSE; //重绘连接线 moveoutredrawline(); //重绘圆圈所在的那个物件,因为擦除圆圈的时候可能擦除了部分物件 //------------------- redrawMyObject(pNodeNow); //如果此时是连接状态,连接态画图 } if(IsLink) { //连接态画图 LinkStatusDraw(point); } } } CView::OnMouseMove(nFlags, point); }  两个关键状态:可连接态IsDrawCircle和正在连接态IsLink  可连接态IsDrawCircle 当且仅当鼠标移动到某个元件上的某个尚未连接的触点上,才开启可连接态IsDrawCircle。之所以取名IsDrawCircle是因为此时会在鼠标停留的尚未连接的触点上画一个黑色小圆圈。 当鼠标移动离开触点,可连接态IsDrawCircle关闭。  正在连接态IsLink 当鼠标按下(见图5)并且此时可连接态IsDrawCircle开启(为TRUE)时正在连接态IsLink开启。  判断当前点是否在某个元件函数:IsPointInObject() 其算法如图7 图7  判断当前点是否在该元件触点上函数:IsPointInPut() 其算法如图8 图8 与门与其它5个门有所不同,与门只有一个输入端,所以要分开来判断 对于输入结点,则判断当前点是否在第一个输出端触点。 对于输出结点,则判断当前点是否在第一个输入端触点。 输入结点和输出结点的这样判断,一眼看上去似乎反了,但实际上有利于整个程序的编写。可以简单地这样分类:总共只有两种端,一种输入,一种输出。 这样,我们就可以将判断触点分为三个函数: IsInInput1() IsInInput2() IsInOutput1() 拿IsInInput1()来分析: centerpoint=GetCirclePoint(Input_1); if(IsInArea(point)) { //说明此时就在触点Input_1,用全局变量put记录下来 put=Input_1; //如果当前点在,则要保存触点中心点 circlepoint=centerpoint; return TRUE; } else { //如果移出触点,肯定不要再保存中心点 return FALSE; } 首先,调用函数GetCirclePoint()来取得当前触点的中心点。然后调用IsInArea(point)函数来判断当前点point是否在以当前触点中心点为中心的矩形区域内。如果是,则用一个全局枚举变量put来记录来前触点是两个输入端和一个输出端中哪一个。 我们看这个枚举类型: enum Myput { Input_1, Input_2, Output_1 }; 接下来用一个全局变量circlepoint来记录当前触点中心点。再返回真。 如果当前点不在以当前触点中心点为中心的矩形区域内,则返回假。这时千万不能记录当前触点中心点。这点不注意会出大错。  判断当前触点是否已连接函数:IsPutLinked() BOOL CMyView::IsPutLinked() { switch(put) { case Input_1: if(pNodeNow->input1 !=0) return TRUE; break; case Input_2: if(pNodeNow->input2 !=0) return TRUE; break; case Output_1: if(pNodeNow->output1 !=0) return TRUE; } return FALSE; } 这里根据全局变量put的类型和全局变量pNodeNow所指向的元件, 就可以判断当前元件的当前触点是否已连接。如果连接相应指针不为0。返回真,否则返回假。  连接态画图函数:LinkStatusDraw() void CMyView::LinkStatusDraw(CPoint point) { CClientDC clientDC(this); CPen whitepen(PS_SOLID,1,RGB(255,255,255)); CPen* pOldPen; pOldPen=clientDC.SelectObject (&whitepen); clientDC.MoveTo (startpoint); clientDC.LineTo (lastpoint); clientDC.SelectObject (pOldPen); CPen redpen(PS_DOT ,1,RGB(255,0,0)); pOldPen=clientDC.SelectObject (&redpen); clientDC.MoveTo (startpoint); clientDC.LineTo (point); clientDC.SelectObject (pOldPen); lastpoint=point; //重绘所有输入结点前的序号 redrawnum(); //重绘连接线 LinkLineRedraw(startpoint,point); //重绘物件 lineRedraw(startpoint,point); } 这里,startpoint是鼠标按下开始连接时起始元件触点中心点坐 标,lastpoint是上一次鼠标移动所停留的点。为了实在连接时鼠标移动 的动画效果,我们要先擦除上一次移动画的线(用白笔),然后再从startpoint到当前点point画线。移动时由于不信的擦除重画,可能将先前已画的元件,输入结点前的序号,和已经连接好的线擦除。于是我们需要重绘。 重绘所有输入结点前的序号 redrawnum(); void CMyView::redrawnum() { CClientDC dc(this); char buffer[20]; CPoint point; //重绘所有Input前的序号 for(int i=0;iCArray numpoint; 而数组的下标加1就为序号。 所以每次重绘为了方便,将所有序号都重绘。 重绘连接线 void CMyView::LinkLineRedraw(CPoint startpoint, CPoint point) { //将起点startpoint到终点point扩充成一个矩形drawrect CRect drawrect(startpoint,point); //rect用于产生连接线最大矩形 CRect rect; //rectInter用于计算两个矩形的相交区域 CRect rectInter; //point1和point2用于产生连接线最大矩形 CPoint point1; CPoint point2; drawrect.NormalizeRect (); drawrect.InflateRect (1,1); //遍历MyPointList链表 POSITION pos=MyPointList.GetHeadPosition (); while(pos!=0) { //pPointArray用于指向点数组对象首址 CArray* pPointArray=MyPointList.GetNext (pos); point1=pPointArray->GetAt (0); switch(pPointArray->GetSize ()) { //分两种情况 :2个点和4,5个点的情况 case 2: //2个点时 point2=pPointArray->GetAt (1); break; default: //4,5个点时 point2=pPointArray->GetAt (3); } //用point1和point2设置矩形rect rect.left =point1.x ; rect.top =point1.y; rect.right =point2.x; rect.bottom =point2.y; rect.NormalizeRect (); rect.InflateRect (1,1); //如果两个矩形相交,则要重绘 if(rectInter.IntersectRect (&drawrect,&rect)) { DrawLinkLine(pPointArray); } } } 主要的算法思想是:将起点startpoint到当前点point扩充成一个矩形drawrect,然后遍历连接线链表,将每根连接线扩充成一个矩形rect,再判断这两个矩形是否相交,若相交,则需要重绘这根连接线。 连接线链表声明如下: CList<CArray*,CArray*> MyPointList; 链表中每个结点是一个数组对象的地址,而这个数组中每个元素是一个点。这样一个数组就表示了一根连接线,而一个链表可以遍历所以连接线。  画提示连接的小圆圈函数:DrawMyCircle() void CMyView::DrawMyCircle() { //此时全局变量circlepoint记录了要画圆圈的 //而pNodeNow指向了当前的物件 //将物件坐标中的circlepoint转换成VIEW中的坐标 int x,y; x=pNodeNow->Orgpoint .x +circlepoint.x; y=pNodeNow->Orgpoint .y +circlepoint.y; CClientDC dc(this); //创建一个黑色的画刷 CBrush brush(RGB(0,0,0)); //创建指针pOldBrush用于保存原来的画刷 CBrush* pOldBrush; //将黑色的画刷选进设备装置DC,并用pOldBrush保存原来的画刷 pOldBrush=dc.SelectObject (&brush); //画一个圆圈,圆心是(x,y) //半径是4 dc.Ellipse (x-4,y-4,x+4,y+4); //将原来的画刷选回 dc.SelectObject (pOldBrush); } 由于全局变量circlepoint保存的是元件内部的相对坐标,需要将它 转换成视图中的坐标 x=pNodeNow->Orgpoint .x +circlepoint.x; y=pNodeNow->Orgpoint .y +circlepoint.y; 以上两句完成坐标的转换。 然后以(x,y)为圆心,4为半径,画一个黑色小圆圈 dc.Ellipse (x-4,y-4,x+4,y+4)  擦除小圆圈函数:EraserMyCircle() void CMyView::EraserMyCircle() { int x,y; x=pNodeNow->Orgpoint .x +circlepoint.x; y=pNodeNow->Orgpoint .y +circlepoint.y; CClientDC dc(this); CPen whitepen(PS_SOLID,1,RGB(255,255,255)); CPen* pOldPen; pOldPen=dc.SelectObject (&whitepen); dc.Ellipse (x-4,y-4,x+4,y+4); dc.SelectObject (pOldPen); } 与画小圆圈不同的是,擦除时要选择白色的笔和白色的画刷(默认) CPen whitepen(PS_SOLID,1,RGB(255,255,255)); CPen* pOldPen; pOldPen=dc.SelectObject (&whitepen); 以上3句选择白色的笔。  鼠标移开触点重绘连接线函数:moveoutredrawline() 为什么需要这个函数,原因是在鼠标称出触点后,此时要擦除刚才画 的小圆圈,而如果此时已经生成了连接线,则会擦除掉连接线的一小部分。于是需要这个函数。 void CMyView::moveoutredrawline() { int x,y; x=pNodeNow->Orgpoint .x +circlepoint.x; y=pNodeNow->Orgpoint .y +circlepoint.y; CPoint point1; CPoint point2; point1.x=x-4; point1.y=y-4; point2.x=x+4; point2.y=y+4; LinkLineRedraw(point1,point2); } 此时pNodeNow指向刚擦除小圆圈的元件,而circlepoint则记录着 触点中心。于是只要将以ciclepoint为中心的半径为4的矩形的左上角点和右下角点为参数调用LinkLineRedraw即可。  重绘元件函数redrawMyObject() void CMyView::redrawMyObject(MyNode* pNode) { switch(pNode->Subtype ) { case ANDGate: DrawObject(pNode->Orgpoint ,IDB_ANDGATE); break; case ORGate: DrawObject(pNode->Orgpoint,IDB_ORGATE); break; case NOTGate: DrawObject(pNode->Orgpoint,IDB_NOTGATE); break; case NORGate: DrawObject(pNode->Orgpoint,IDB_NORGATE); break; case NANDGate: DrawObject(pNode->Orgpoint,IDB_NANDGATE); break; case XORGate: DrawObject(pNode->Orgpoint,IDB_XORGATE); break; case Input: DrawObject(pNode->Orgpoint,IDB_NODEINPUT); break; case Output: DrawObject(pNode->Orgpoint,IDB_NODEOUTPUT); break; } } 该函数参数为指向元件的指针,用于重绘所指向的元件。  鼠标按下模块 如图5 图5 前面已经分析了放置元件状态,现在看连接元件状态中的判断: “当前点是否在某个元件未连接的触点上”其实就是判断“可连接态”IsDrawCircle是否为真。代码如下: if(IsDrawCircle)//当前点在某个元件未连接的触点上 { //全局变量IsLink表示开始连接状态 IsLink=TRUE; //全局变量pNodeStart记录当前物件 pNodeStart=pNodeNow; //全局变量startpoint记录当前触点中心坐标(注,此时要进行坐标转换 startpoint.x=pNodeNow->Orgpoint .x +circlepoint.x; startpoint.y=pNodeNow->Orgpoint .y +circlepoint.y; //全局变量startput记录当前触点类别:Input_1,Input_2,Output_1; startput=put; //lastpoint用于鼠标移动时擦除线效果 lastpoint=startpoint; } 进行连接初始化:首先开启开始连接状态 IsLink=TRUE; 然后用全局变量pNodeStart指向当前元件 pNodeStart=pNodeNow 全局变量startpoint记录当前触点中心坐标(这时要进行坐标的转换) startpoint.x=pNodeNow->Orgpoint .x +circlepoint.x; startpoint.y=pNodeNow->Orgpoint .y +circlepoint.y; 全局变量startput记录当前触点类别 startput=put; 最后lastpoint用于鼠标移动时擦除线效果 lastpoint=startpoint;  鼠标抬起模块 其算法如图9 图9 代码如下: void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(IsLink) { //首先擦除从startpoint到point CClientDC clientDC(this); CClientDC* pDC=&clientDC; CPen whitepen(PS_SOLID,1,RGB(255,255,255)); CPen* pOldPen; pOldPen=clientDC.SelectObject (&whitepen); clientDC.MoveTo (startpoint); clientDC.LineTo (point); clientDC.SelectObject (pOldPen); //重绘所有输入结点前的序号 redrawnum(); //重绘连接线 LinkLineRedraw(startpoint,point); //重绘物件 lineRedraw(startpoint,point); if(IsDrawCircle) { //用全局变量pNodeCurrent记录终点连接的物体 pNodeCurrent=pNodeNow; //用全局变量currentput记录终点连接的触点 currentput=put; //用全局变量currentpoint记录终点触点的中心坐标 currentpoint.x=pNodeNow->Orgpoint .x +circlepoint.x; currentpoint.y=pNodeNow->Orgpoint .y +circlepoint.y; //IsTwoObjectsCanLink()函数判断两个物件是否能连接 if(IsTwoObjectsCanLink()) { //先擦除圆圈 //EraserMyCircle();没有必要,只要鼠标移开时重绘连接线就可 //开始两个物件的画图连接 LineLink(); //开始真正连接:指针连接 RealLink(); } } //关闭连接状态: IsLink=FALSE; } CView::OnLButtonUp(nFlags, point); }  判断两个元件是否可以连接 BOOL CMyView::IsTwoObjectsCanLink() { //判断两个物件是否能连接 //这两个物件分别由pNodeStart和pNodeCurrent指向 //两个触点分别由startput和currentput标识 //若所指同一物件 if(pNodeStart==pNodeCurrent) { MessageBox("连接错误!自身物件不能相互连接"); return FALSE; } //输出直接结输出 if(startput==Output_1 && currentput==Output_1) { MessageBox("连接错误!输出端不能相互连接"); return FALSE; } //输入直接连接输入 if( (startput==Input_1 || startput==Input_2) && (currentput==Input_1||currentput==Input_2) ) { MessageBox("连接错误!输入端不能相互连接"); return FALSE; } //循环连接 if( (startput==Output_1) &&(currentput==Input_1||currentput==Input_2) ) { if(pNodeCurrent->output1 ==pNodeStart) { MessageBox("连接错误!不能循环连接"); return FALSE; } } if( (startput==Input_1||startput==Input_2) &&(currentput==Output_1) ) { if(pNodeStart->output1 ==pNodeCurrent) { MessageBox("连接错误!不能循环连接"); return FALSE; } } //如果以上情况都不发生,表示可以连接 return TRUE; } 用图来表示上述几种错误: 同一元件不能连接 图10 输出端不能连接输出端 图11 输入端不能连接输入端 图12 两个元件不能循环连接 图13  两个元件的画图连接:LineLink() 该函数调用了recordLine() 代码如下: void CMyView::recordLine () { //记录两个物件之间的连接线经过的关键点 //先动态生成一个数组CArray之对象 //记录下连接线的关键点,然后将这个数组对象之地址加入到 //CList<CArray*,CArray*> MyPointList中 int x0,y0,x1,y1,delta_x,delta_y; //(x0,y0)用于记录输出端起始点坐标 //(x1,y1)用于记录输入端终点坐标 //delta_x,delta_y用于记录x和y的偏移量 //一定是从输出端向输入端画线 if(startput==Output_1) { x0=startpoint.x; y0=startpoint.y; x1=currentpoint.x; y1=currentpoint.y; } else { x1=startpoint.x; y1=startpoint.y; x0=currentpoint.x; y0=currentpoint.y; } delta_x=5; //动态生成数组对象 CArray* pPointArray=new CArray; //根据点的位置分为三种情况:2个点,4个点,5个点 if(x0两个点情况 pPointArray->Add (CPoint(x0,y0)); pPointArray->Add (CPoint(x1,y1)); } else { //4个点情况 pPointArray->Add (CPoint(x0,y0)); pPointArray->Add (CPoint(x0+delta_x,y0)); pPointArray->Add (CPoint(x0+delta_x,y1)); pPointArray->Add (CPoint(x1,y1)); } } else if(x0==x1) { //两个点情况 pPointArray->Add (CPoint(x0,y0)); pPointArray->Add (CPoint(x1,y1)); } else //x0>x1 { //5个点情况 if(y0rray->Add (CPoint(x0,y0)); pPointArray->Add (CPoint(x0,y0+delta_y)); pPointArray->Add (CPoint(x1-delta_x,y0+delta_y)); pPointArray->Add (CPoint(x1-delta_x,y1)); pPointArray->Add (CPoint(x1,y1)); } //加入当前数组对象地址到MyPointList MyPointList.AddTail (pPointArray); //用数组中的点画线 DrawLinkLine(pPointArray); } 首先保证从输出端向输入端画线,这样可以统一画线操作。 然后动态生成数组: CArray* pPointArray=new CArray; 用指针pPointArray指向该数组,用于存储连接线的关键点。 连接线根据位置总共有三种线型,如下图所示: (1)两个关键点的连接线: 图14 (2)4个关键点的连接线 图15 (3)5个关键点的连接线 图16  两个元件的指针连接:RealLink(); 其代码如下: void CMyView::RealLink() { //一定是输入连接输出 或 输出连接输入 if(startput==Input_1||startput==Input_2) { //输入连接输出 if(startput==Input_1) { pNodeStart->input1 =pNodeCurrent; } else { pNodeStart->input2 =pNodeCurrent; } pNodeCurrent->output1 =pNodeStart; } else//startput==Output_1 { //输出连接输入 pNodeStart->output1 =pNodeCurrent; if(currentput==Input_1) { pNodeCurrent->input1 =pNodeStart; } else { pNodeCurrent->input2 =pNodeStart; } } } 指针连接只有两种情况:输入连接输出和输出连接输入。可以用下图来表示 输入端连接输出端 图17 输出端连接输入端 图18  元件库模块 代码如下: UINT CMyView::gatefunction(MyNode *pNode) { UINT result; switch(pNode->Subtype ) { case ANDGate: result=pNode->input1value & pNode->input2value ; break; case ORGate: result=pNode->input1value | pNode->input2value ; break; case NOTGate: result=pNode->input1value ; result=1-result; break; case NORGate: result=pNode->input1value | pNode->input2value ; result=1-result; break; case NANDGate: result=pNode->input1value & pNode->input2value ; result=1-result; break; case XORGate: result=pNode->input1value ^ pNode->input2value ; } return result; } 这里pNode是指向当前元件的指针,根据当前元件的类型,及当前元件的输入端的值input1value和input2value(注:非门只有一个输入端)来返回元件的输出端的值。 各个门真值表如下表所示: (1)与门 输入端1 输入端2 输出端 0 0 0 0 1 0 1 0 0 1 1 0 表1 (2)或门 输入端1 输入端2 输出端 0 0 0 0 1 1 1 0 1 1 1 1 表2 (3)非门 输入端 输出端 0 1 1 0 表3 (4)与非门 输入端1 输入端2 输出端 0 0 1 0 1 1 1 0 1 1 1 0 表4 (5)或非门 输入端1 输入端2 输出端 0 0 0 0 1 1 1 0 1 1 1 1 表5 (6)异或门 输入端1 输入端2 输出端 0 0 0 0 1 1 1 0 1 1 1 0 表6  计算结果(仿真)模块 仿真模块在整个仿真器中占有最重要的作用。 当在视图窗体上放置元件,连接元件后。接下工具栏开始按钮 开始计算结果,进行仿真。 其主要算法如图19 图19 代码如下: void CMyView::OnBegin() { //开始计算,输出真值表 // TODO: Add your command handler code here //判断是否能够连接 if(CalculateResult()==-1) { MessageBox("连接线路失败!请检查线路"); } else { //可以连接 //调用函数计算 beginCalculate(); //生成对话框对象 CMyDialog MyDialog; MyDialog.DoModal (); } } 其中判断线路是否正确调用了CalculateResult(),这是仿真中最重要的函数。它的返回值是最终输出结点的值。如果返回-1,说明线路有误。其具体的算法如图20: CalculateResult() 图20 代码如下: int CMyView::CalculateResult() { //用于从输入端开始计算输出端结果 //遍历所有输入结点 MyNode* pNode; MyNode* pNodeNext; POSITION pos=MyList.GetHeadPosition (); while(pos!=0) { pNode=MyList.GetNext (pos); //判断当前结点是否是输入结点 if(pNode->Subtype ==Input) { for(;;) { //判断当前的输入结点的输出端指向的结点是否为空 //如果为空,表示连接失败 if(pNode->output1 ==0) { //连接失败,返回-1 return -1; } //否则不为空 //输出到它指向结点的输入端 //此时要判断输入到哪个输入端:input1 OR input2; pNodeNext=pNode->output1 ; if(pNodeNext->input1 ==pNode) { //如果是输入到input1 pNodeNext->input1value =pNode->output1value ; //输入的值++,如果到了2,就可以计算进位了 pNodeNext->inputs ++; } else { //如果是输入到input2 pNodeNext->input2value =pNode->output1value ; pNodeNext->inputs ++; } //指针跳向下一个结点 pNode=pNodeNext; //判断此时是否是输出结点,如果是返回输出结点的值input1value; if(pNode->Subtype ==Output) { return pNode->input1value ; } //判断是否可以进位,对于非门,只要有一个输入值即可inputs==1 //对于其他门,要两个输入值inputs==2 if(pNode->Subtype==NOTGate) { //非门 if(pNode->inputs==1) { //可以进位 pNode->output1value =gatefunction(pNode); } else { //不能进位 break;//跳出for(;;) } } else { //其他门 if(pNode->inputs ==2) { pNode->output1value =gatefunction(pNode); } else { //不能进位 break;//跳出for(;;) } } //请空输入值个数inputs,以便下次计算 pNode->inputs =0; }//for(;;) }//判断当前结点是否是输入结点 }//while(pos!=0) //遍历完后若没有返回,说明连接失败 return -1; } 其算法主要思想是:遍历每一个输入结点,将输入结点的值送入到它所连接的元件的输入端,若此时该元件可以进位,则调用该元件进位函数gatefunction()计算该元件的输出端的值,再将该输出端的值送入它的下一个连接元件,再判断下一个元件能否进位,如此循环,直到输出结点。若此时不可以进位,则遍历下一个输入结点。 可以用下图来说明: 图21 假设此时输入结点遍历的顺序是1->2->3 (顺序不唯一)。假设此时1,2,3号输入结点取值0,1,0。首先将1号输入结点的值送入它所连接的或门的第一个输入端,即input1value=0。此时或门进位标志inputs= =1。于是不能进位。遍历下一个输入结点2,将2号1号输入结点的值送入它所连接的与门的第一个输入端,同样此时与门进位标志也为inputs= =1,不能进位。最后遍历到输入结点3,将值送入到与门的输入端2。由于此时有两个输入了,即与门进位标志inputs= =2,调用与门函数计算与门输出端output1value.然后将此值送入或门,同样或门进位标志inputs= =2,调用或门函数计算或门输出端值,最后送入输出结点,结束。 计算真值表:beginCalculate() 代码如下: void CMyView::beginCalculate() { //计算输入结点的个数,输出真值表 n=numpoint.GetSize (); //计算要进行循环的次数 int i; x=1; for(i=1;i<=n;i++) { x=x*2; } //动态生成x个字符串保存真值表 //用一个字符串格式化数据 CString str; //用一个数组I[1]~I[n]记录每个输入结点值 UINT* I=new UINT[n+1]; //用数组J[1]~J[n]辅助计算 UINT* J=new UINT[n+1]; //初始化J[1]~J[n] J[1]=1; for(i=2;i<=n;i++) { J[i]=J[i-1]*2; } //进行x次循环,计算真值表 for(i=0;i>(k-1); //将输入端1~n的值加入字符串 str.Format ("%d ",I[k]); // //连接起来 strs[i]=strs[i]+str; } //给输入结点1~n初始化值 POSITION pos=MyList.GetHeadPosition (); MyNode* pNode; while(pos!=0) { pNode=MyList.GetNext (pos); //如果结点是输入结点 if(pNode->Subtype ==Input) { //结点中的pNode->number 记录了结点序号 //给结点初始化值 pNode->output1value =I[pNode->number ]; } } //调用函数计算,将计算结果保存 int result=CalculateResult(); //生成字符串以便输出 str.Format ("%10d",result); strs[i]+=str; } } 代码分析: (1) 首先得到输入结点的个数:n=numpoint.GetSize (); 这里numpoint是记录输入结点前序号位置点的数组,而有多少个这样的点,就有多少个输入结点。 (2)然后计算真值表的行数,因为有n个输入结点,真值表就有2^n行。 x=1; for(i=1;i<=n;i++) { x=x*2; } 这里我们用x来保存真值表的行数。 (3)产生所有的输入结点值的组合。 如果有3个输入结点,它的所有组合如下表 输入3 输入2 输入1 i 0 0 0 0 0 0 1 1 0 1 0 2 0 1 1 3 1 0 0 4 1 0 1 5 1 1 0 6 1 1 1 7 我们可以从表的第四列看出可以用数字i从0到x-1来分解出这些组合。 例如:当i为2时,它在内存中最后3位为:010。 此时 输入3=010 & 100=000,再右移2位即可得到0。 于是我们可以得到:输入1 & 001 再右移0位 输入2 & 010 再右移1位 输入1 & 100 再右移2位 我们用一个数组J[1]~J[n]来记录相与的数字。为1,2,4,......,2^(n-1) 初始化J[1]~J[n] J[1]=1; for(i=2;i<=n;i++) { J[i]=J[i-1]*2; } 用I[1]~I[n]记录输入1~输入n 产生一行输入值: strs.Add (CString()); for(int k=1;k<=n;k++) { I[k]=i & J[k]; //向右移位 I[k]=I[k]>>(k-1); //将输入端1~n的值加入字符串 str.Format ("%d ",I[k]); // //连接起来 strs[i]=strs[i]+str; } 给输入结点1~n初始化值 POSITION pos=MyList.GetHeadPosition (); MyNode* pNode; while(pos!=0) { pNode=MyList.GetNext (pos); //如果结点是输入结点 if(pNode->Subtype ==Input) { //结点中的pNode->number 记录了结点序号 //给结点初始化值 pNode->output1value =I[pNode->number ]; } } 调用函数计算,将计算结果保存 int result=CalculateResult(); 最后生成字符串以便输出 str.Format ("%10d",result); strs[i]+=str; 完成以上操作后,生成一个对话框,然后将字符串数组strs[]加入到列表框内。最终输出整个真值表。 参考文献: 1 Electronics Workbench 5.0 1992-1996 Interactive Image Technologies Ltd 2 MSDN Libary July 2000 Microsoft
BOOL ControlsInitialization(HWND hWnd);//从控件句柄初始化 void ObjectInitialization(CComPtr pDisp);//对象初始化 CString TenToHtmlColor(DWORD CurColor);//将整数型的颜色值转换为网页支持的格式 void WebComplete(HWND hWnd,int Timedelay=0/*单位:毫秒 为空则一直等待*/);//确认网页已经完全载入 HWND GetIesHandle(HWND hWnd);//可以指定父句柄获取IES句柄 BOOL GetAllIesHandle(HWND hParent);//获取所有取已打开的所有网页窗口句柄 CArray m_hWnd;//返回的所有已打开窗口句柄数组 int WebpageNavigate(CString Strurl);//载入某个网址。 int WebpageWriteTextStream(CString StrTextStream);//写超文本流。 CComPtr GetWebpageObject();//取网页对象 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页框架(frame)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页按钮(Button)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int ButGetIndex(CString NameOrID);//按钮取索引返回第一个满足条件的索引值,如果失败返回0 CString GetButName(int i);//获取指定索引按钮元素name(名称) CString GetButId(int i);//获取指定索引按钮元素id int GetButCount();//返回网页内所有按钮的数目 int ButClick(int i);//按钮按索引点击成功返1失败返回0 CString GetButHtml(int i);//获取指定索引按钮元素代码 CString GetButText(int i);//获取指定索引按钮元素文本 CComPtr Object_GetButObject(int i);//获取指定索引按钮对象 CString GetButValue(int i);//获取指定索引按钮标题 CString GetButType(int i);//获取指定索引按钮(Button)的类型(type),“button”、“submit”、“reset” /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页Div~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int GetDivCount();//返回网页内所有Div的数目 CComPtr Object_GetDivObject(int i);//获取指定索引DIV对象 CString GetDivHtml(int i);//获取指定索引Div元素代码 CString GetDivText(int i);//获取指定索引Div元素文本 CString GetDivName(int i);//获取指定索引Div元素name(名称) CString GetDivId(int i);//获取指定索引Div元素id int GetDivIndex(CString NameOrID);////Div取索引返回第一个满足条件的索引值,如果失败返回0 int DivClick(int i);//Div按索引点击成功返1失败返回0 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页隐藏表单(hidden)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int GetHiddenCount();//返回网页内所有隐藏表单的数目 CString GetHiddenName(int i);//获取指定索引隐藏表单元素name(名称) CString GetHiddenId(int i);//获取指定索引隐藏表单元素id CString GetHiddenValue(int i);//获取指定索引隐藏表单元素标题 int GetHiddenIndex(CString NameOrID);////隐藏表单取索引返回第一个满足条件的索引值,如果失败返回0 CComPtr Object_GetHiddenObject(int i);//获取指定索引隐藏表单对象 CString GetHiddenHtml(int i);//获取指定索引隐藏表单元素代码 CString GetHiddenText(int i);//获取指定索引隐藏表单元素文本 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页表格(table)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int GetTableCount();//返回网页内所有表格的数目 CString GetTableName(int i);//获取指定索引表格元素name(名称) CString GetTableId(int i);//获取指定索引表格元素id int GetTableIndex(CString NameOrID);//表格取索引返回第一个满足条件的索引值,如果失败返回0 CString GetTableHtml(int i);//获取指定索引表格元素代码 CString GetTableText(int i);//获取指定索引表格元素文本 int GetTableCellCount(int i);//获取指定索引表格单元格数量 int GetTableRowCount(int i);//获取指定索引表格的行数 CString GetTableDistributionCount(int i);//返回文本格式:“第1行x列,第2行x列,…,第N行x列” CComPtr Object_GetTableCellObject(int i,int row, int j);//获取单元格元素接口(第一个参数指定第几个表格,第二个参数指定第几行,第三个参数指定第几个单元格) CString GetTableCellText(int i,int row, int j);//获取单元格文本(第一个参数指定第几个表格,第二个参数指定第几行,第三个参数指定第几个单元格) CString GetTableCellHtml(int i,int row, int j);//获取单元格源码(第一个参数指定第几个表格,第二个参数指定第几行,第三个参数指定第几个单元格) CComPtr Object_GetTableObject(int i);//获取指定索引表格对象 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页图片~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ CString GetImageName(int i);//获取指定索引图片元素name(名称) CString GetImageId(int i);//获取指定索引图片元素id int ImageClick(int i);//图片按索引点击成功返1失败返回0 int GetImageIndex(CString NameOrID);////图片取索引返回第一个满足条件的索引值,如果失败返回0 int GetImageCount();//返回网页内所有图片的数目 CString GetImageHref(int i);//获取指定索引图片连接地址 CString GetImageSrc(int i);//获取指定索引图片地址 CBitmap *GetImage(int i=NULL, CString vImageIDorName=NULL,int cx=NULL/*图片宽度*/,int cy=NULL/*图片高度*/);//参数1获取指定索引图片如果为NULL请指定参数2的图片Id或Nname /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页单选框(radio)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ BOOL GetRadioChecked(int i);//检查单选框(radio)是否被选中(checked),1为选中,0为未选中 BOOL SetRadioWhetherSelect(int i,int Select);//设置单选框(radio)选中状态,第一个参数填写第几个单选框(radio)第二个添写是否选中(1为选中,0为未选中) CString GetRadioName(int i);//获取指定索引单选框(radio)元素name(名称) CString GetRadioId(int i);//获取指定索引单选框(radio)元素id CString GetRadioValue(int i);//获取指定索引单选框(radio)元素标题 int GetRadioCount();//返回网页内所有单选框(radio)的数目 CComPtr Object_GetRadioObject(int i);//获取指定索引单选框(radio)对象 int GetRadioIndex(CString NameOrID);//单选框(radio)取索引返回第一个满足条件的索引值,如果失败返回0 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页复选框(checkbox)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ BOOL GetCheckboxChecked(int i);//检查复选框(checkbox)是否被选中(checked),1为选中,0为未选中 BOOL SetCheckboxWhetherSelect(int i,int Select);//设置复选框(checkbox)选中状态,第一个参数填写第几个复选框(checkbox)第二个添写是否选中(1为选中,0为未选中) CString GetCheckboxName(int i);//获取指定索引复选框(Checkbox)元素name(名称) CString GetCheckboxId(int i);//获取指定索引复选框(Checkbox)元素id CString GetCheckboxValue(int i);//获取指定索引复选框(Checkbox)元素标题 int GetCheckboxCount();//返回网页内所有复选框(Checkbox)的数目 CComPtr Object_GetCheckboxObject(int i);//获取指定索引复选框(Checkbox)对象 int GetCheckboxIndex(CString NameOrID);//复选框(Checkbox)取索引返回第一个满足条件的索引值,如果失败返回0 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页组合框(Select)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int GetSelectCount();//返回网页内所有组合框(Select)的数目 int GetSelectOptionCount(int i);//取某个组合框(Select)中的选项(option)的数目 int GetSelectItem(int i);//取组合框(select)现行选中项(0为位置1,1为位置2……) int SetSelectItem(int i,int setect);//选中指定名称的组合框(Select)的指定索引的选项(options) CString GetSelectItemText(int i,int j);//取组合框(Select)中某个选项(options)的文本(value)参数一为第几个组合框第二参数为组合框第几项 CString GetSelectName(int i);//取的某个组合框(Select)的名称(name) CString GetSelectId(int i);//取的某个组合框(Select)的Id int GetSelectIndex(CString NameOrID);//组合框(Select)取索引返回第一个满足条件的索引值,如果失败返回0 CComPtr Object_GetSelectObject(int i);//取的某个组合框(Select)的对象(Object) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页表单(Form)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int GetFormIndex(CString NameOrID);//表单(Form)取索引返回第一个满足条件的索引值,如果失败返回0 int GetFormCount();//返回网页内所有表单(Form)的数目 CString GetFormName(int i);//取的某个表单(Form)的名称(name) CString GetFormId(int i);//取的某个表单(Form)的Id void GetFormSubmit(int i);//提交某个表单(Form) CComPtr Object_GetFormObject(int i);//取的某个表单(Form)的对象(Object) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页文本框(Text)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int GetTextboxIndex(CString NameOrID);//文本框(Text)取索引返回第一个满足条件的索引值,如果失败返回0 void SetTextboxText(int i,CString StrTxt);//按索引填写文本框(Text) CString GetTextboxText(int i);//读取某个文本框(Text)内的内容(value) int GetTextboxCount();//返回网页内所有文本框(Text)的数目 CString GetTextboxType(int i);//取得某个文本框(Text)的类型。类型分为“text”、“password”、“file” CString GetTextboxName(int i);//取的某个文本框(Text)的名称(name) CString GetTextboxId(int i);//取的某个文本框(Text)的Id CComPtr Object_GetTextboxObject(int i);//取的某个文本框(Text)的对象(Object) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页多行文本框(TextArea)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ void SetTextAreaText(int i,CString StrTxt);//按索引填写多行文本框(TextArea)索引从1开始 CString GetTextAreaText(int i);//读取某个多行文本框(TextArea)内的内容(value) int GetTextAreaIndex(CString NameOrID);////多行文本框(TextArea)取索引返回第一个满足条件的索引值,如果失败返回0 int GetTextAreaCount();//返回网页内所有多行文本框(TextArea)的数目 CString GetTextAreaName(int i);//取的某个多行文本框(TextArea)的名称(name) CString GetTextAreaId(int i);//取的某个多行文本框(TextArea)的Id CComPtr Object_GetTextAreaObject(int i);//取的某个多行文本框(TextArea)的对象(Object) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页超链结(url)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int LinkClick(int i);//超链结(url)按索引点击成功返1失败返回0 CString GetLinkHref(int i);//获取指定索引超链结(url)地址 int GetLinkCount();//返回网页内所有超链结(url)的数目 int GetLinkIndex(CString NameOrID);//超链结(url)取索引返回第一个满足条件的索引值,如果失败返回0 CString GetLinkHtml(int i);//获取指定索引超链结(url)元素代码 CString GetLinkText(int i);//获取指定索引超链结(url)元素文本 CComPtr Object_GetLinkObject(int i);//取的某个超链结(url)的对象(Object) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页获取对象(Object)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ CComPtr Object_GetObject_Aggregate(CString tag);//获取基于指定元素名称的对象集合(getElementsByTagName),参数1可添写如:“a”、“table”、“div”、“img”. CComPtr Object_GetObject_NameOrID(CString NameOrId, int i);//按名称或ID取网页元素对象,参数1(元素名称或ID)参数2(0=名称(name),1=ID) CComPtr Object_GetObject_Point(int x, int y);//返回指定 x 和 y 坐标的网页元素对象(elementFromPoint) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以下为网页对象(Object)操作~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ void ObjectOperation_ExecutionEvent(CComPtr pDisp,CString Event);//执行某个网页元素相关的脚本方法,事件名称一般是“onclick” void web_RunScript(CString Script,int type);//在当前网页上执行指定的脚本命令,参数1为脚本,参数2(添写1即为:JavaScript 业写2为:VBScript) void web_InsertCode(CString StrCode);//在网页插入网页HTML代码及自定义内容 void Destruction();
MFC类目录及头文件 类 描述 头文件 CAnimateCtrl 自动化通用控件 afxcmn.h CArchive afx.h CArchiveException afx.h CArray afxtempl.h CAsyncMonikerFile 在ActiveX控件中提供对异步标记的支持 afxole.h CAsyncScoket 封装Windows Sockets API,参看CSocket afxsock.h CBitmap afxwin.h CBitmapButton afxext.h CBrush afxwin.h CButton 按钮控件对象 afxwin.h CByteArray afxcoll.h CCachedDataPathProperty 允许一个ActiveX控件异步传输属性数据和缓冲内存中的数据,参考CDataPathProperty afxctl.h CCheckListBox afxwin.h CClientDC afxwin.h CCmdTarget 所有能够接收和响应消息的对象的基类 afxwin.h CCmdUI afxwin.h CColorDialog 颜色选择的通用对话框,提供为显示系统定义的颜色列表 afxdlgs.h CComboBox 组合框对象 afxwin.h CComboBoxEx CComboBox类的派生类,用于支持在组合框控件中的图像列表 afxcmn.h CCommandLineInfo afxwin.h CCommonDialog afxdlgs.h CConnectionPoint afxdisp.h CControlBar afxext.h CCreateContext afxext.h CCriticalSection afxmt.h CCtrlView afxwin.h CDaoDatabase afxdao.h CDaoException afxdao.h CDaoFieldExchange afxdao.h CDaoQueryDef afxdao.h CDaoRecordset 代表选自数据源的记录集。CDaoRecordset对象可用于三种格式:表类型记录集,动态集类型记录集和快照类型记录集 afxdao.h CDaoRecordView 提供表单视图,以在控件中显示数据库记录。表单视图是CDaoRecordset对象的一部分。参考CFormView和CRecordView afxdao.h CDaoTableDef afxdao.h CDaoWorkspace afxdao.h CDatabase afxdb.h CDataExchange afxwin.h CDataPathProperty 实现一个ActiveX控件属性,它能够异步加载其数据。这个类允许ActiveX控件在后台下载属性数据时被激活 afxctl.h CDateTimeCtrl 封装新的日期/时间选取器控件 afxdtctl.h CDBException afxdb.h CDBVariant afxdb.h CDC afxwin.h CDialog 用于包含控件窗口的对话框对象 afxwin.h CDialogBar afxext.h CDocItem afxole.h CDockState afxadv.h CDocObjectServer afxdocob.h CDocObjectServerItem afxdocob.h CDocTemplate afxwin.h CDocument 用于管理程序的数据的类 afxwin.h CDragListBox Windows列表框,允许用户把其中的项拖放到不同的位置 afxcmn.h CDumpContext afx.h CDWordArray afxcoll.h CEdit 用于文本输入的子窗口控件 afxwin.h CEditView 提供Windows编缉控件的功能。因为CEditView派生于Cedit,该对象可同文件和文件模板一同使用 afxext.h CEvent afxmt.h CException afx.h CFieldExchange afxdb.h CFile afx.h CFileDialog 通用文件对话框,提供Open和Save As对话框中的功能 afxdlgs.h CFileException afx.h CFileFind afx.h CFindReplaceDialog afxdlgs.h CFont afxwin.h CFontDialog 通用字体对话框,用于显示当前已装入系统的字体列表 afxdlgs.h CFontHolder afxctl.h CFormView 包含对话框控件的窗口 afxext.h CFrameWnd SDI(单窗口界面)框架窗口 afxwin.h CFtpConnection afxinet.h CFtpFileFind afxinet.h CGdiObject afxwin.h CGopherConnection afxinet.h CGopherFile afxinet.h CGopherFileFind afxinet.h CGopherLocator afxinet.h CHeaderCtrl 标题通用控件 afxcmn.h CHotKeyCtrl 热键通用控件 afxcmn.h CHtmlStream afxisapi.h CHtmlView 实现Web Browser控件的视图类,能够访问当地或Web上的HTML文件。 afxhtml.h CHttpConnection afxinet.h CHttpFile afxinet.h CHttpFilter 创建并处理超文传输协议过滤器对象,该对象用于过滤用于HTTP请求的服务器通知 afxisapi.h CHttpFilterContext afxisapi.h CHttpServer Internet Server API(ISAPI)的包装类 afxisapi.h CHttpServerContext afxisapi.h CImageList afxcmn.h CInternetConnection afxinet.h CInternetException afxinet.h CInternetFile afxinet.h CInternetSession afxinet.h CIPAddressCtrl IP地址控件。类似于编缉框,该控件接收Internet 协议格式的地址 afxcmn.h CList afxtempl.h CListBox 列表框对象 afxwin.h CListCtrl 列表视通用控件 afxcmn.h ClistView 简化CListCtrl的使用,添加了对文件和视图的支持 afxcview.h CLongBinary afxdb_.h CMap afxtempl.h CMapPtrToPtr afxcoll.h CMapPtrToWord afxcoll.h CMapStringToOb afxcoll.h CMapStringToPtr afxcoll.h CMapStringToString afxcoll.h CMapWordToOb afxcoll.h CMapWordToPtr afxcoll.h CMDIChildWnd MDI(多文档界面)子框架窗口 afxwin.h CMDIFrameWnd afxwin.h CMemFile afx.h CMemoryException afx.h CMemoryState CMenu afxwin.h CMetaFileDC afxext.h CMiniFrameWnd 半高的框架窗口,主要用于浮动工具栏。一个小框架窗口没有最小化和最大化按钮,但其他都类似于正常的框架窗口 afxwin.h CMonikerFile afxole.h CMonthCalCtrl 月历控件,用于显示一个用户可选择日期的日历 afxdtctl.h CMultiDocTemplate afxwin.h CMultiLock afxmt.h CMutex afxmt.h CNotSupportedException afx.h CObArray afxcoll.h CObject afx.h CObList afxcoll.h COleBusyDialog afxodlgs.h COleChangeIconDialog afxodlgs.h COleChangeSourceDialog afxodlgs.h COleClientItem afxole.h COleCmdUI afxdocob.h COleControl afxctl.h COleControlModule afxctl.h COleConvertDialog afxodlgs.h COleCurrency afxdisp.h COleDataObject afxole.h COleDataSource afxole.h COleDateTime afxdisp.h COleDateTimeSpan afxdisp.h COleDBRecordView afxoledb.h COleDialog afxodlgs.h COleDispatchDriver afxdisp.h COleDispatchException afxdisp.h COleDocObjectItem afxole.h COleDocument 把一个文件看作为CDocItem对象的一个集合。包容器和服务器都需要这个结构,因为它们的文件必须能够包含OLE项 afxole.h COleDropSource afxole.h COleDropTarget afxole.h COleException afxdisp.h COleInsertDialog afxodlgs.h COleIPFrameWnd afxole.h COleLinkingDoc OLE包容器文件的基类,这些文件支持对它们所包含项的链接 afxole.h COleLinksDialog afxodlgs.h COleMessageFilter afxole.h COleObjectFactory afxdisp.h COlePasteSpecialDialog afxodlgs.h COlePropertiesDialog afxodlgs.h COlePropertyPage afxctl.h COleResizeBar afxole.h COleSafeArray afxdisp.h COleServerDoc OLE服务器文件的基类 afxole.h COleServerItem 为OLE项提供一个服务器界面 afxole.h COleStreamFile afxole.h COleTemplateServer afxdisp.h COleUpdateDialog afxodlgs.h COleVariant afxdisp.h CPageSetupDialog afxdlgs.h CPaintDC afxwin.h CPalette afxwin.h CPen afxwin.h CPictureHolder afxctl.h CPoint atltypes.h CPrintDialog 通用打印对话框,提供Print和Print Setup对话框中的功能 afxdlgs.h CPrintInfo CProgressCtrl 通用进程指示器控件 afxcmn.h CPropertyPage 代表属性表单中的一页 afxdlgs.h CPropertyPageEx CPropertySheet 属性表,也叫做多选项卡对话框。一个属性表由一个CPropertySheet对象和几个CPropertyPage对象组成 afxdlgs.h CPropertySheetEx CPropExchange afxctl.h CPtrArray afxcoll.h CPtrList afxcoll.h CReBar afxext.h CReBarCtrl afxcmn.h CRecentFileList afxadv.h CRecordset 用于访问数据库表或查询的类 afxdb.h CRecordView 包含对话框控件的窗口 afxdb.h CRect atltypes.h CRectTracker afxext.h CResourceException afxwin.h CRgn afxwin.h CRichEditCntrItem afxrich.h CRichEditCtrl 用户能够输入和编缉文本的窗口,提供字符和程序段格式,以及对嵌入OLE项的支持 afxcmn.h CRichEditDoc afxrich.h CRichEditView afxrich.h CRuntimeClass CScrollBar 滚动条对象 afxwin.h CScrollView 可滚动的窗口,派生于CView afxwin.h CSemaphore afxmt.h CSharedFile afxadv.h CSingleDocTemplate afxwin.h CSingleLock afxmt.h CSize atltypes.h CSliderCtrl 提供包含一个滑块和可选的刻度线的窗口 afxcmn.h CSocket Windows Socket API的包装类 afxsock.h CSocketFile afxsock.h CSpinButtonCtrl 提供箭头按钮,用户可单击它,以增加或减少某个控件中的一个值 afxcmn.h CSplitterWnd afxext.h CStatic 用于标识另一个控件或给用户提供消息的简单文本框 afxwin.h CStatusBar afxext.h CStatusBarCtrl 提供一个层次窗口,通常放于父窗口的底部,用于显示关于应用程序的状态信息 afxcmn.h CStdioFile afx.h CString afx.h CStringArray afxcoll.h CStringList afxcoll.h CSyncObject afxmt.h CTabCtrl 允许应用程序在一个窗口或对话框的同一区域显示多个页面 afxcmn.h CTime afx.h CTimeSpan afx.h CToolBar afxext.h CToolBarCtrl 工具栏通用控件 afxcmn.h CToolTipCtrl 提供工具提示控件的功能,它以一个小弹出窗口的样子显示,包含描述某个工具用途的一行文本 afxcmn.h CTreeCtrl 显示项的分层结构列表 afxcmn.h CTreeView 简化CTreeCtrl的用法 afxcview.h CTypedPtrArray afxtempl.h CTypedPtrList afxtempl.h CTypedPtrMap afxtempl.h CUIntArray afxcoll.h CUserException afxwin.h CView 用于显示程序数据的类 afxwin.h CWaitCursor afxwin.h CWinApp afxwin.h CWindowDC afxwin.h CWinThread 代表一个应用程序中的一个线程 afxwin.h CWnd afxwin.h CWordArray afxcoll.h ......

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧