UCanCode Software

 

产品与方案▼  免费下载  价格与购买▼  技术支持  客户列表  操作视频▼

 

UCanCode.com一起释放Visual C++的巨大能量!
 


028-85354645

VX++跨平台工业C++源码库
100%C++, QT, JAVA源码
 产品特点 
  跨平台工控组态源码
  嵌入式Linux组态源码
  跨平台建模仿真源码
E-Form++可视化图形源码库企业版本
100%C++, VB, C#源码
 产品特点 
  HMI &SCADA源码
 PLC组态编程源码
 CAD设计控件源码
 HMI 报表源码
GIS制图源码
电力系统源码
条码账单源码
工作流程源码
煤炭行业源码
仪器仪表源码
报表打印源码
图形建模源码
电子表单源码
Visio制图源码
工业控制源码
BPM业务流程源码
工业监控源码
流程图控制流源码
组织关系图源码
图形编辑器源码
 Win CE组态源码
UML编辑器源码
地图演示源码
建筑平面制图源码
 关于UCanCode
  开发知识库

Form++开发知识库
 

我们的知识库使用精炼的语言来解决常见的问题。虽然无法与一些大公司的知识库相比,我们会尽力提供更多的信息。知识库将不断更新,增加新的内容。所以希望大家经常关注。

我们的技术支持团队将不断更新和扩充知识库,从一般的编程问题到完整的实例。您可以通过编目、产品类型、或者目录索引来找到您所需的信息。要获取这些信息,您无需注册。

其中的文章回答了很多的用户最常提出的问题。通常情况下,这些文章可以说是超越了版本限制的。您可以类推到你所遇到的情况。

这个页面包含常见的问题和我们的技术支持小组的解答,以及一些常用技巧和提示。
注意:在以下的解答中我们将按如下的简记惯例来描述用户界面操作。组合键按以下方式如:Ctrl+Alt+Delete,意思是你同时按下Control键、Alt键和Delete键不放。菜单的选择将如下描述:File->Open,意思是你打开文件(File)菜单,然后选择打开(Open )项。

E-Form++可视化组件库图形元件的创建与使用方法探讨?
E-Form++可视化组件库图形元件的创建与使用方法探讨?作为全球领先的VC++可视化图形源码组件库,E-Form++在国内国外数百家企业得到了广泛的使用,为那些想要创建工业监管应用用户界面的开发者们提供了包含设计工具和软件开发工具包(SDK Source Code)的一整套服务。这些显示功能提供了高度可自定义的且与潜在实际数据相连接的图表对象。其产品基础架构完全采用VC++开发而成,无论在产品稳定性或者扩展性上都处于全球领先地位,是开发高性能的业务流程、矢量图形处理、工业控制、仿真、监控、可变打印、电子表单等软件产品的首选。使用和扩展E-Form++提供的图形元件是一个非常重要的工作,本文将探讨如何如何创建和使用这些图形元件:一、最基本的图形元件创建方法:直接通过鼠标绘制元件:E-Form++提供了一个绘图工具条,见示例VisioApp, 该工具条显示在画布的右边,选中其中的绘图按钮,然后通过交互操作即可完成绘图。通过工具盒拖拉元件:E-Form++提供了一个类似

阅读全文

页面访问:1 | 聚合访问:0 | 评论:0 
使用E-Form++可视化图形组件库开发工控与仿真方法探讨?
使用E-Form++可视化图形组件库开发工控与仿真方法探讨?开发高质量工控与仿真应用软件是一项非常艰巨的工作,该领域需要非常苛刻的快速实时响应性、稳定性和可靠性。作为全球领先的VC++可视化图形源码组件库,E-Form++在国内国外数百家企业得到了广泛的使用,为那些想要创建工业监管应用用户界面的开发者们提供了包含设计工具和软件开发工具包(SDK Source Code)的一整套服务。这些显示功能提供了高度可自定义的且与潜在实际数据相连接的图表对象。其产品基础架构完全采用VC++开发而成,无论在产品稳定性或者扩展性上都处于全球领先地位,是开发高性能的业务流程、矢量图形处理、工业控制、仿真、监控、可变打印、电子表单等软件产品的首选。经过多年在该领域的实践,为企业节省了超过50%-80%的开发时间,产生了巨大的经济效益:一、为什么要选用E-Form++来构建基础工控与仿真平台?     选择E-Form++可视化图形组件库来开发工控和仿真平台的原因很多,最基本的还是UCanCode的高品质和源码彻底开放原则,在全球很难

阅读全文

页面访问:0 | 聚合访问:0 | 评论:0 
使用E-Form++可视化图形组件库系统隐藏参数的方法探讨?
作为全球领先的VC++可视化图形组件库,E-Form++在国内国外数百家企业得到了广泛的使用,其产品基础架构完全采用VC++开发而成,无论在产品稳定性或者扩展性上都处于领先地位,是开发高性能的业务流程、矢量图形处理、工业控制、仿真、监控、可变打印、电子表单等软件产品的首选。E-Form++产品架构从设计之初就将用户在实际使用中可能需要的定制,系统隐藏着大量没有在帮助系统或者文档中未公开的设置变量,通过这些变量或者函数的调用,将进一步E-Form++开发各种复杂的高性能应用的灵活性发挥到了极致

阅读全文

E-Form++可视化组件库图形元件额外控制点的创建探讨?


E-Form++可视化组件库图形元件额外控制点的创建探讨?

作为全球领先的VC++ / MFC可视化图形源码组件库,E-Form++在国内国外数百家企业得到了广泛的使用,为那些想要创建各种高性能图形可视化显示的开发人员提供了最佳的应用组件选择。使用和扩展E-Form++提供的图形元件是一个非常重要的工作,本文将探讨如何如何为这些图形元件创建额外控制点:

一、什么是额外控制点?
默认情况下,E-Form++已经为画布上的各种图形元件的编辑操作提供了几种标准的控制点:

1、系统默认基本图形编辑控制点,通过这些额外控制点,可以对图形进行缩放,旋转,移动,顶点编辑等等操作。具体包括:

1)、10控制点设计,包括8个顶点编辑控制点,一个旋转控制点,一个中心移动控制点。

2)、直线与曲线顶点编辑控制点。

3)、线段中心切分控制点等。


2、在很多时候,如果需要调整图形的其他独立的几何参数,就需要其他额外控制点来进

阅读全文

 

问题列表:


Q: 我已经安装了Form++,但是我找不到任何DLL或者库(lib)文件,在那里去找?
A:
你需要编译所有的Form++ 类库中的 DLL和 lib文件。从开始菜单->程序->Form++ Library找到类库。你必须为你的平台生成调试(build)和发行(releease)两种版本。

FOENGD40.dll FOENGD40.lib DLL - Win32 Debug
FOENG40.dll FOENG40.lib DLL - Win32 Release
FOStatic40D.lib Static Library - Win32 Debug
FOStatic40.lib Static Library - Win32 Release

注意:如果您使用的是评估版,将只有静态连接库---Win32调试版动态连接文件。您不必生成库。

Back to Top

Q:开始使用Form++之前,我要做些什么,我怎样设定我的VisualStudio®?
A:
在VisualStudio你必须作以下调整。假设你将Form++ Library 安装在"C:\Program Files\UCanCode Software Inc\Form++ Library V2.0"F目录下。如果你将Form++安装到其他目录下,你需要作一些调整。

  1. 选择"Tools"菜单中的"Options"然后选中"Directories"。.
  2. 设定"Show directories for:"到"Include files".
  3. 增加"C:\Program Files\UCanCode Software Inc\Form++ Library V2.0\Fo20\Include" to the到?/font>
  4. 设定"Show directories for:"到"Library files".
  5. 增加"C:\Program Files\UCanCode Software Inc\Form++ Library V2.0\Lib" to the到列表中 list.
  6. 设定"Show directories for:"到"Source files".
  7. 增加"C:\Program Files\UCanCode Software Inc\Form++ Library V2.0\Fo20\source" to the
  8. 增加"C:\Program Files\UCanCode Software Inc\Form++ Library V2.0\Fo20\Include" to the list.
  9.  现在可以从view菜单选中resource include 项增加Form++的资源到你的程序中,

    在只读目录框中,在最后一行输入以下一行:

    #include "fores.h" 

    Compile-time编译目录框中,输入下面一行:

    #include "fores.rc" 

    单击OK按钮。 会出现一个警告,在按OK 按钮。

你下载和安装Form++类库后,打开工程工作区(见上面的问题,如果是评估版,这是不可用的)。依赖于工作平台,建立调试和发行两种版本的库文件。之后,你打开AppWizard的工作区,编译工程。现在你可以象使用标准的AppWizard产生MFC工程一样使用类向导。做个例子看看工程是什么样。

Back to Top

Q: 怎样使我的程序支持Ole 拖放功能?
A:
要让你的程序支持Ole拖放功能,你必须加入如下代码:

BOOL CCustomSampleApp::InitInstance()

AfxOleInit();

Q: 我怎样使用上Form++资源库?
A:
要在你已有的应用中加入Form++资源,你要在你的stdafx.h文件中加入以下一行,首先你必须在DevStudio的搜索目录下增加了.\lib, .\bin和.\include
目录,且与你安装form++的目录一致。

#include <FO.H> // Form++ Library MFC extensions

Back to Top

Q:  want to prevent resizing of an image but make sure I don't want to lock
the control otherwise I won't be able to move the image. Is there any
function thought which I can enable and disable the control/image resizing?

A: You can use the following method to do it:
void LockWidthAndHeight(const BOOL bLock) it defined in class CFODrawShape

Back to Top

Q: 贵公司在在线帮助中使用复制Basic Shapes.trsForms Shapes.trsindex.dat3个文件到应用程序中的办法来增加组建,试问我自己能编制该文件来增加我自己需要的图形组件吗?如果能,我该怎么做?

A: 如果您自己增加的组件,需要做两个方面的工作:
1
、通过ToolBox来添加新的组件页,并选择另存为菜单保存为新的trs文件,需要同原来的Basic Shapes.trs放置在同一个目录下面。例如:MyShape.trs

2
、需要修改index.dat文件,添加:
3#MyShape.trs
这样在您下一次运行程序的时候,您自己的图形组件页就产生了。

Back to Top

Q: 如何使用单位转换功能?

A: 关于单位转换的类名称为:CFOScaleUint,在新的在线帮助系统中的 <产品介绍>专题中专门有 <单位换算>一节介绍。

Back to Top

Q: 如何在Form++中增加新的命令?

A: 如示例程序所示.

Back to Top

Q: 利用Form++如何生成一个可以旋转任意角度的自定义复合对象?
我发现提供的例子中Basic Shpes中的复合对象可以任意旋转,可是自定义的就不行。
我自定义的过程如下:
画出复合对象,选中并保存为sid文件,建立trs文件,新建对象,装载对象数据(from .sid)
然后拖动此对象到工作区域,可是此对象不能任意旋转。

A: 如果您希望您开发的对象需要旋转属性,您需要在自定义组件的构造函数中调用下面这个函数:
SetOver4ResizeHandles(TRUE);
可以参考示例CustomMSample中的CMyCorsssLineShape
类的定义。

Back to Top

Q: Can U give me a function where I'll pass CFOImageShape pointer and it'll make a list of all links only. Make sure that I won't use GetFormObject() function.

A: Try the following code:

CFODrawShapeList listAllLink;
 if(pObj->IsKindOf(RUNTIME_CLASS(CFOImageShape)))
 {
  CFOImageShape *pComp = (CFOImageShape *)pObj;
  POSITION posport = pComp->GetCompList()->GetHeadPosition();
  CFOPortShape *pPort = NULL;
  while(posport != NULL)
  {
   pPort = (CFOPortShape* )pComp->GetCompList()->GetNext(posport);
   CFODrawShapeList *pLinkList = pPort->GetCompList();
   POSITION poslist = pLinkList->GetHeadPosition();
   while(poslist != NULL)
   {
    listAllLink.AddTail((CFOLinkShape *)pLinkList->GetNext(poslist));
   }
  }
 }

Back to Top

Q: 如何让我的应用程序静态连接到Form++?

A: 在stdafx.h的#include "fo.h"之前添加下面一行代码:

#define _DIAGRAM_STATIC_
#include <FO.H> // Form++ Library MFC extensions

Back to Top

我们将随时增加新的内容!

Q: 如何在Form++中增加新的组件?

A: 下面是增加新组件的基本步骤:

1、您需要利用Form++ Class AddIn程序,从CFODrawPortsShape或者CFODrawShape继承一个新的组件类,例如:CMyComp;

2、为此组件指定一个ID值。

3、在您当前应用程序的Data Model类中修改创建组件代码来创建新的组件。

4、在MyComp代码文件中重载组件绘制代码以及其他控制代码。

 可以参考示例程序CustomMSample以及用户在线文档中相应的描述。

Back to Top

Q:我用Form++ Class AddIn增加的新的类不能在Visual C++的ClassWizard显示出来?

A: To update this change to your project classes, you will need to go to your project folder, find the .clw file and delete it. Then go back to Visual Studio and load the Class Wizard. Visual Studio will then give you an error message and ask you to create a new Class Wizard database. Simply choose the default and you will be able to see all the three new classes in your Class Wizard.

Back to Top

Q:我使用Form++ Class AddIn增加了新的组件类CMyShape,但是我如何才能够判断我当前选择的对象列表中是否包含此组件?

A:您需要调用下面的代码来实现:

CFODrawShape *pObj = GetCurrentSelectShape();
if(pObj != NULL)
{
  if(pObj->IsKindOf(RUNTIME_CLASS(CMyShape)))
  {
    CMyShape *pShape = (CMyShape *)pObj;
  }
}

Back to Top

Q:如何才能够获得当前选中对象的列表?

A:您可以调用下面的代码获得列表:

CFODrawShapeList *GetSelectShapes();

Back to Top

Q:我发现贵公司Basic Shapes.trs中的组件能旋转,矢量性很好,但是有些图形是不能满足我的需要,我能不能修改Basic Shapes.trs中的图形或者增加新的图形,如果能我该怎么做?更好的办法是我也能够做一个像它中的组件盒,其中放置我自己的组件.我能够用两种方法完成这个功能吗?

A:作为一套高扩展并包含了完整Source Code的组件库,您提高的要求只是Form++可以非常容易扩展的功能的一部分。事实上,目前我们提供的Basic Shapes.trs以及其他的所有在ToolBox中的组件,均只是Form++组件的一些范例。通过Form++您可以:
1、自由定义新的ToolBox页,您可以根据自己的需要增加新的ToolBox页面,也可以删除不需要的页面。同时您还可以定制ToolBox的外观(如:字体、图标、颜色边框等),我们在ToolBox对应的类(class)中封装了大量的函数,来帮助您完成各种修改。
2、增加新的组件,从大的方面讲,Form++的组件包含两个方面的类型:矢量组件和非矢量组件,非矢量组件目前有图像组件,而其他均为矢量组件。每个矢量组件都拥有旋转、放缩、移动、组合等属性。具体的某个组件需要这其中的哪些属性,均需要调用组件定义class的函数来控制。
3、Form++提供了一套非常完备而且容易的编程工具来帮助您快速的构建属于自己的新的组件,同时也提供了对系统提供的缺省组件的外观以及属性的修改。
4、Form++也提供了对组件具体的属性或者动作的修改功能。例如:您需要增加新的属性,您只需要使用Form++提供的自动代码产生程序,产生一个新的属性class,然后调用增加新属性给组件的函数,就可以在任何需要的时候定制组件的属性。
5、使用Form++增加的每个类型的组件均有一个属于自己的ID,ToolBox能够根据组件的ID来自动识别新的组件,也就是说,一旦您增加了新的组件后,您不需要做额外的工作,在ToolBox就自动具有了拖放的功能。
6、Form++对新增的组件除了能够放置在ToolBox中拖拉进入外,还能够支持通过鼠标直接绘制而成。例如:示例程序中的Rectangle组件。
总之,Form++能够100%的根据您的需要去定制各种功能。

Back to Top

Q:贵公司的组件盒中的组件是需要编程才能够增加,我能否将增加组件的功能增加到我的程序中,实现动态增加组件.我该怎么做?

A:没问题,对于最终用户来讲,他可以根据自己的需要增加属于自己的组件。下面是不需要编程而增加新组件的办法:
1、运行示例程序中的任何一个,比如:CustomMSample.
2、根据自己的需要在画布上,使用Form++提供的各种基本绘制工具,绘制一个复合组件。
3、按下Ctrl+A或者鼠标右键菜单的全部选择菜单。
4、按下Ctrl+C或者工具条上的复制按钮。
5、在ToolBox中按下鼠标右键,选择?#31896;贴?#33756;单。
6、您可以编辑新的组件的图标的外观。
这样您制作的复合组件就增加到了ToolBox中,以后您就可以像ToolBox的其他组件一样通过拖拉的方式拖入画布了。
您也可以参考示例程序FormBuilder的ToolBox的复合组件示例。

Back to Top 

Q:Form++支持什么操作系统?

A:Form++支持所有windows操作系统包括Windows95,Windows98,WindowsNT,Windows 2000,Windows XP

Back to Top

Q:Form++支持什么Visual C++版本?

A:Form++ can be compiled on VC++ versions starting from version 4 all the way to the upcoming VS.Net (with MFC 7) without any problems

Back to Top

Q: Is the Form++ UNICODE?
A:
Yes, Form++5.0 and all of its standard classes fully support UNICODE.

Back to Top

Q: What is one developer license?
A:
Developer license means the software can be installed on one developer's computer.
What does Team 4 and Team 8 stand for?
Team 4 stands for 4 developer licenses e.g. the software can be installed on 4 developer machines. Team 8 stands for 8 developer licenses.

Back to Top

Q: Can I offer component based on a Form++ source code as a competitor product?
A:No. We offer source code at a very special price.You cann't make a competitor product using any party of our source code.

Back to Top

Q: Only ever print inside the CPrintInfo::m_rectDraw area

A:Your printing code should not make assumptions about where it should print on the page, and make proper use of the CPrintInfo::m_rectDraw variable. This ensures that you will not overwrite margins/headers/footers that may be printed outside of your main OnPrint procedure.

pDC->TextOut(pInfo->m_rectDraw.left, pInfo->m_rectDraw.top, 
             "Only draw inside the reported m_rectDraw area") ;

Back to Top

Q: Getting a PrinterDC in OnPreparePrinting()

A:When OnPreparePrinting() is called in your CView derived class, you are generally required to setup the number of pages of output your document will need when printing, unless you are using the CPrintInfo::m_bContinuePrinting method. But it can be difficult to do this if you have no information on the printer resolution or page size. So at this point you need to get hold of the printer DC object that will be used. As the MFC print architecture would not create this until the OnBeginPrinting() function would be called, you have to create one yourself and release it after calculating the number of pages you want to print. To create such a printer DC you can use this code:

CDC dc ;
AfxGetApp()->CreatePrinterDC(dc) ;
    
...

// when finished with the DC, you should delete it
dc.DeleteDC() ;

This will create a printer DC for the default printer selected for you application.

Back to Top

Q: Getting the size of the printable page area

A:The printable area of a page on a printer is normally contained in the CPrintInfo::m_rectDraw member variable. A CPrintInfo object gets passed through to your CView overridden virtual functions. But in some cases, like in OnPreparePrinting(), OnBeginPrinting(), this member variable will not yet have been intialised. So you have to do it yourself.

pInfo->m_rectDraw.SetRect(0, 0, 
                          pDC->GetDeviceCaps(HORZRES), 
                          pDC->GetDeviceCaps(VERTRES)) ;

This gets the printable area of a printers page.

Back to Top

Q: Margins

A:In many cases you may want to have a user programmable margin around a page so that you do not over-print company logo's etc on headed paper, so you can set a user programmable range for you margins in inches. You can then convert these to device units and reserve that space on the page by changing the dimensions of the CPrintInfo::m_rectDraw variable. For example:

double LeftOffset = 0.5 ;       // in imperial inches!
double TopOffset = 0.5 ;        // in imperial inches!
double RightOffset = 0.5 ;      // in imperial inches!
double BottomOffset = 0.5 ;     // in imperial inches!
pInfo->m_rectDraw.DeflateRect(
    (int)(pDC->GetDeviceCaps(LOGPIXELSX) * LeftOffset),
    (int)(pDC->GetDeviceCaps(LOGPIXELSY) * TopOffset),
    (int)(pDC->GetDeviceCaps(LOGPIXELSX) * RightOffset),
    (int)(pDC->GetDeviceCaps(LOGPIXELSY) * BottomOffset)) ;

You will need to apply these changes to the m_rectDraw variable for every page printed, as the rectangle gets reset for every page loop in the MFC stock library code.

Back to Top

Q:Choosing a suitable font size for printing

A:When printing, choosing a font size that is suitable for the resolution of the printer in the past has been a hit and miss affair. I have had code that worked correctly on my development PC/printer setup, only to die horribly on a users PC/printer in Japan (e.g. the text generated was 1 pixel in height). Getting consistent output across printers can be done by selecting the font size based on the resolution reported by the printer:

CFont    font ;
LOGFONT  lf ;

::ZeroMemory(&lf, sizeof(LOGFONT));

// This aims to get a 12-point size font regardless of the 
// printer resolution
lf.lfHeight = -MulDiv(12, pDC->GetDeviceCaps(LOGPIXELSY), 72);
strcpy(lf.lfFaceName, "Arial");    //    with face name "Arial".
// make use of the font....

We set the LOGFONT::lfHeight member to a -ve value as this will get windows to select a good width for us which will give a nice proportional font.

Back to Top

Q:If you do not know how many pages you are going to print use CPrintInfo::m_bContinuePrinting

A:If, when printing your document, you did not know how many pages you were going to print until you actually printed (as calculating the actual page usage can be difficult), you can set the MFC print architecture to continue to request pages to print until you have finished with all your output. To do this, you should not sent a maximum page in your CView::OnPreparePrinting() function.

There are 2 places where you can choose to end the printing:

1: In your CView::OnPrepareDC() override

2: At the end of your CView::OnPrint() function when you have printed the last of your output

pInfo->m_bContinuePrinting = FALSE ;

Back to Top

Q:Use DIB's instead of DDB's

A:When printing bitmaps or icons to a printer DC, you should use a DIB (Device Independant Bitmap) rather than a DDB (Device Dependant Bitmap). This is because printer device drivers tend not to support BitBlt. You can end up spending a lot of time wondering why the bitmap appears in Print Preview (because the screen DC supports BitBlt) and not on your printed output (becuase the printer driver does not). So when printing, convert your image to a DIB and use StretchDIBBits to print the image. I have yet to find a printer where this technique would not work.

Here are some helpful functions that I have acquired from the web. I am not the original author of these, but I forget just where I got them from. But they are free source!

// this procedure extracts a single image from an image list into a DIB
HANDLE ImageToDIB( CImageList* pImageList, int iImageNumber, CWnd* pWnd)
{
    // Local Variables
    CBitmap     bitmap;
    CWindowDC    dc( pWnd );

    CDC         memDC;
    CRect        rect;
    CPalette    pal;
    IMAGEINFO   imageInfo;

    if (!pImageList->GetImageInfo( iImageNumber, &imageInfo ))
        {
        // Getting of the Imageinfos failed
        return NULL;
        }

    // Create compatible stuff and select Bitmap
    if (!memDC.CreateCompatibleDC(&dc ))
        {
        // Create failed
        return NULL;
        }

    if (!bitmap.CreateCompatibleBitmap(&dc, 
                                        imageInfo.rcImage.bottom-imageInfo.rcImage.top, 
                                        imageInfo.rcImage.right-imageInfo.rcImage.left))
        {
        // Create failed
        memDC.DeleteDC() ;
        return NULL;
        }

    CBitmap* pOldBitmap = memDC.SelectObject( &bitmap );
    if( NULL == pOldBitmap )
        {
        // Select failed
        memDC.DeleteDC() ;
        return NULL;
        }

    // Local Variables for Draw
    CPoint point( 0, 0);
    UINT nStyle = ILD_NORMAL;

    // Draw Image to the compatible DC
    if(!pImageList->Draw( &memDC, iImageNumber, point, nStyle ))
        {
        // Drawing of the Image failed
        memDC.SelectObject(pOldBitmap) ;
        VERIFY(bitmap.DeleteObject()) ;
        memDC.DeleteDC() ;
        return NULL;
        }

    // Create logical palette if device support a palette
    if( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE )
        {
        UINT        nSize   = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 );
        LOGPALETTE* pLP     = (LOGPALETTE*)new BYTE[nSize];
        pLP->palVersion     = 0x300;
        pLP->palNumEntries = (unsigned short)GetSystemPaletteEntries( dc, 0, 255, 
        pLP->palPalEntry );

        // Create the palette
        pal.CreatePalette( pLP );

        // Free memory
        delete[] pLP;
        }

    memDC.SelectObject( pOldBitmap );
    memDC.DeleteDC() ;

    // Convert the bitmap to a DIB
    HANDLE h = DDBToDIB(bitmap, BI_RGB, &pal );
    VERIFY(bitmap.DeleteObject()) ;
    return h ;
}


// DDBToDIB        - Creates a DIB from a DDB
// bitmap        - Device dependent bitmap
// dwCompression    - Type of compression - see BITMAPINFOHEADER
// pPal            - Logical palette
HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal ) 
{
    BITMAP            bm;
    BITMAPINFOHEADER    bi;
    LPBITMAPINFOHEADER     lpbi;
    DWORD            dwLen;
    HANDLE            hDIB;
    HANDLE            handle;
    HDC             hDC;
    HPALETTE        hPal;


    ASSERT( bitmap.GetSafeHandle() );

    // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS )
        return NULL;

    // If a palette has not been supplied use defaul palette
    hPal = (HPALETTE) pPal->GetSafeHandle();
    if (hPal==NULL)
        hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

    // Get bitmap information
    bitmap.GetObject(sizeof(bm),(LPSTR)&bm);

    // Initialize the bitmapinfoheader
    bi.biSize        = sizeof(BITMAPINFOHEADER);
    bi.biWidth        = bm.bmWidth;
    bi.biHeight         = bm.bmHeight;
    bi.biPlanes         = 1;
    bi.biBitCount        = (unsigned short)(bm.bmPlanes * bm.bmBitsPixel) ;
    bi.biCompression    = dwCompression;
    bi.biSizeImage        = 0;
    bi.biXPelsPerMeter    = 0;
    bi.biYPelsPerMeter    = 0;
    bi.biClrUsed        = 0;
    bi.biClrImportant    = 0;

    // Compute the size of the  infoheader and the color table
    int nColors = 0;
    if(bi.biBitCount <= 8)
        {
        nColors = (1 << bi.biBitCount);
        }
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

    // We need a device context to get the DIB from
    hDC = ::GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC);

    // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

    if (!hDIB){
        SelectPalette(hDC,hPal,FALSE);
        ::ReleaseDC(NULL,hDC);
        return NULL;
    }

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

    *lpbi = bi;

    // Call GetDIBits with a NULL lpBits param, so the device driver 
    // will calculate the biSizeImage field 
    GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
            (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

    bi = *lpbi;

    // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if (bi.biSizeImage == 0){
        bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
                        * bi.biHeight;

        // If a compression scheme is used the result may infact be larger
        // Increase the size to account for this.
        if (dwCompression != BI_RGB)
            bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    }

    // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE) ;
    if (handle != NULL)
        hDIB = handle;
    else
        {
        GlobalFree(hDIB);

        // Reselect the original palette
        SelectPalette(hDC,hPal,FALSE);
        ::ReleaseDC(NULL,hDC);
        return NULL;
        }

    // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER)hDIB;

    // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
                0L,                      // Start scan line
                (DWORD)bi.biHeight,      // # of scan lines
                (LPBYTE)lpbi             // address for bitmap bits
                + (bi.biSize + nColors * sizeof(RGBQUAD)),
                (LPBITMAPINFO)lpbi,      // address of bitmapinfo
                (DWORD)DIB_RGB_COLORS);  // Use RGB for color table

    if( !bGotBits )
    {
        GlobalFree(hDIB);
        
        SelectPalette(hDC,hPal,FALSE);
        ::ReleaseDC(NULL,hDC);
        return NULL;
    }

    SelectPalette(hDC,hPal,FALSE);
    ::ReleaseDC(NULL,hDC);
    return hDIB;
}

To use the above function(s) as an example code may be:

if (iImage >= 0)
    {
    HANDLE hDib ;
    hDib = ImageToDIB(&#8465;_list, iImage, this) ; // this is a dialog window in this example
    BITMAPINFOHEADER    *pBMI ;
    pBMI = (BITMAPINFOHEADER*)GlobalLock(hDib) ;
    int nColors = 0;
    if (pBMI->biBitCount <= 8)
        {
        nColors = (1 << pBMI->biBitCount);
        }
    // print the correct image
    ::StretchDIBits(dc.m_hDC,
                        pInfo.m_rectDraw.left, 
                        pInfo.m_rectDraw.top + cs.cy * j, 
                        cs.cy, 
                        cs.cy,
                        0, 
                        0, 
                        pBMI->biWidth,
                        pBMI->biHeight,
                        (LPBYTE)pBMI + (pBMI->biSize + nColors * sizeof(RGBQUAD)),
                        (BITMAPINFO*)pBMI,
                        DIB_RGB_COLORS, 
                        SRCCOPY);
    // free resources
    GlobalUnlock(hDib) ;
    GlobalFree(hDib) ;
    }

Back to Top

Q:请问我在绘制多边形的时候,如何才能够结束绘制!

A:双击鼠标即可!

Back to Top

Q:将form++用在一个实时系统中,关于在此类系统中做动画你们有何建议

A:开发基于动画的应用程序实际上是Form++的主要应用领域之一,在Form++中的所有对象都是矢量对象,比如一个椭圆,Windows的标准椭圆采用2个点来描述,而Form++采用了几十个点来描述,Windows标准椭圆没办法旋转而Form++的椭圆可以选准。此外,Form++封装了专门处理对象移动、放缩、旋转、定点编辑等大量的功能。这些功能将您开发动画系统的时候,只需要考虑对象的基本数据即可,而不用关心如何显示出来。除此之外,Form++还提供了所见及所得的打印功能,您能够在任何时刻,将动画移动的效果直接输出到打印机。当然,Form++大量的Class决不是一下子可以全部描述出来的,但有一点可以肯定,Form++开发动画系统将为您节省大量的宝贵时间。

Back to Top

Q:如何根据某一变量不同的值在画布的同一位置切换不同的Shape 如为0时 三角形  1时 圆形   2时 正方形?

A:每个不同类型的Form++组件Shape,均有自己特定的ID值,如果您需要将一种Shape转换为另外一种Shape,您需要改变ID值,同时如果是复杂组件(比如Tab组件同矩形组件的转换)还需要做相应的数据变换。

Back to Top

Q:如果我使用vc++.net怎样将form++添加到 vc++.net环境中?

A:Form++直接支持.net,您不需要做任何修改。
在连接库文件的时候,您需要指定为连接到Lib70目录。
同时,在运行时也需要将Lib70目录下的dll文件同运行程序的可执行文件放置在一起。
如果要在.net下编译Form++,请直接打开FOLib.dsw文件即可。

Back to Top

Q:We have been delivering about your Form++ product and it suits to our needs, but we have one critical requirement for our project that we haven t seen in it. Our software has to be able to save its drawing, or export it, to a dxf file format, so we would like to know how can we get this functionality in your product or besides it.

A:For default serialization you need to override Serialize() in all of the objects, the view ob, the frame ob and the view/doc to work use this format. For export/import you could just add a SerializeDXF method to all of your objects. Either way is easy, but somewhat laborious since there are a fair number of properties to convert.

We are not working on the .dxf filters. It would be great to have them as a sample though if you wouldn't mind contributing them. That way we would probably maintain them if the Form++-object properties every change

Back to Top

Q:如何在指定位置动态创建一个静态文本组件(CStaticShape)?

A:可以调用下面的代码来完成:

CRect rcTest;
rcTest = CRect(100,100,200,125);
CFOStaticShape *pReturn = new CFOStaticShape;
pReturn->AddRef();
pReturn->Create(rcTest,"");
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
pReturn->RemoveAllPorts();
pReturn->CreateDefaultPort(1,0.5);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:我能够使用已经绘制好的*.wmf和*.emf文件作为我的组件吗?如果能怎样使用?

A:可以调用下面的代码来完成:

CRect rcTest;
rcTest = CRect(100,100,200,125);
CFOWMFShape *pReturn = new CFOWMFShape;
pReturn->AddRef();
pReturn->Create(rcTest,"");
pReturn->LoadImage("c:\\temp\\Arrows1.wmf");
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
pReturn->RemoveAllPorts();
pReturn->CreateDefaultPort(1,0.5);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:如何动态创建一个CFOEllipseShape对象?

A:可以调用下面的代码来完成:

CRect rcTest;
rcTest = CRect(100,100,200,125);
CFOEllipseShape *pReturn = new CFOEllipseShape;
pReturn->AddRef();
pReturn->Create(rcTest,"");
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
pReturn->RemoveAllPorts();
pReturn->CreateDefaultPort(0.5,0.5);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:如何动态创建一个CFOEllipseShape对象?

A:可以调用下面的代码来完成:

CRect rcTest;
rcTest = CRect(100,100,200,125);
CFOEllipseShape *pReturn = new CFOEllipseShape;
pReturn->AddRef();
pReturn->Create(rcTest,"");
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
pReturn->RemoveAllPorts();
pReturn->CreateDefaultPort(0.5,0.5);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:如何动态创建一个CFORectShape对象?

A:可以调用下面的代码来完成:

CRect rcTest;
rcTest = CRect(100,100,200,250);
CFORectShape *pReturn = new CFORectShape;
pReturn->AddRef();
pReturn->Create(rcTest,"");
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
pReturn->RemoveAllPorts();
pReturn->CreateDefaultPort(0.5,0.5);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:如何动态创建一个CFOPolygonShape对象?

A:可以调用下面的代码来完成:

CArray<CPoint,CPoint> ptArray;
ptArray.Add(CPoint(20,20));
ptArray.Add(CPoint(120,90));
ptArray.Add(CPoint(200,40));

CFOPolygonShape *pReturn = new CFOPolygonShape;
pReturn->AddRef();
pReturn->Create(&ptArray);
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:如何动态创建一个CFOLineShape 对象?

A:可以调用下面的代码来完成:

CArray<CPoint,CPoint> ptArray;
ptArray.Add(CPoint(20,20));
ptArray.Add(CPoint(120,90));
ptArray.Add(CPoint(200,40));

CFOLineShape *pReturn = new CFOLineShape;
pReturn->AddRef();
pReturn->Create(&ptArray);
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
GetCurrentModel()->GetFormObjects()->AddTail(pReturn);
pReturn->Release();

InvalidateShape(pReturn);

Back to Top

Q:我想改变画布的大小,但是上次你的解答是改变大小使用的是以像素为单位,我怎样以毫米或者厘米为单位改变画布的大小(因为我使用的图像只知道毫米或厘米大小),我怎样使用厘米或毫米为单位改变画布的大小

A:可以调用下面的代码来完成:

您可以直接调用下面的DataModel的函数来实现:
void SetPageSize(const float &fHorzMMValue,const float &fVertMMValue);
fHorzMMValue为水平毫米数,fVertMMValue为垂直毫米数
GetCurrentModel()->SetPageSize(5.0,6.0);
UpdateScrollSize();

Back to Top

Q:请问Ucancode做报表软件有何优势?如何实现表格的生成?

A:可以调用下面的代码来完成:

作为一个高扩展的C++的Class Library,Form++更重要的是扮演一个Framework的角色,这一点就如同MFC一样(MFC扮演更基础的角色):
问题一、关于报表设计程序?
开发基于报表的应用程序实际上是Form++的主要应用领域之一,一般来讲,如果要开发一个报表打印系统,应该包含两个方面的内容,一是报表设计器,二是报表打印程序,报表设计器将数据库中的字段按照一定的格式在屏幕上完成布局,如果使用Form++来开发报表设计程序,您就有了现成的功能强大的组件布局设计器,在这个设计器的画布上,您可以完成数据库字段的拖拉、移动、按照格式对齐以及按照网格停靠等功能,这些功能不需要您自己去编写任何代码。同时,Form++还提供了完善的打印机页面管理以及所见及所得的打印功能,一旦您在画布上创建好了组件,就可以直接打印出来。虽然一个功能强大的报表设计程序包含很多复杂的内容,但有一点可以肯定,Form++开发报表系统将为您节省大量的宝贵时间。
问题二、表格的生成?
没问题,对于最终用户来讲,他可以根据自己的需要增加属于自己的组件。一般来讲,我们可以使用Form++创建一个新的表格组件,这个组件的每个子对象就是一个静态文本组件或者是其他的一些标准组件,在Form++中直接支持复合组件的创建,比如我们可以将同样大小的静态文本组件排成两行两列就可以构成一个简单的表格。

Back to Top

Q:如何创建一个复合组件?

A:可以调用下面的代码来完成:

void CCustShapeView::OnCreateComposite() 
{
// TODO: Add your command handler code here
CRect rc = CRect(50,50,250,300);
CFOCompositeShape *pReturn = new CFOCompositeShape;
pReturn->AddRef();
pReturn->Create(rc,"");

CFOStaticShape *pText = pReturn->AddText("My home","My Home",CRect(0,0,200,50));
pText->SetBrushType(1);
pText->SetBkColor(RGB(255,0,0));
pText->SetPenStyle(PS_SOLID);
pText->SetNullPen(FALSE);

CFOStaticShape *pText1 = pReturn->AddText("Father","Steven",CRect(0,50,200,100));
pText1->SetBrushType(1);
pText1->SetBkColor(RGB(255,255,255));
pText1->SetPenStyle(PS_SOLID);
pText1->SetNullPen(FALSE);

CFOStaticShape *pText2 = pReturn->AddText("Mather","Cindy",CRect(0,100,200,150));
pText2->SetBrushType(1);
pText2->SetBkColor(RGB(255,255,255));
pText2->SetPenStyle(PS_SOLID);
pText2->SetNullPen(FALSE);

CFOStaticShape *pText3 = pReturn->AddText("Brother0","John",CRect(0,150,200,200));
pText3->SetBrushType(1);
pText3->SetBkColor(RGB(255,255,255));
pText3->SetPenStyle(PS_SOLID);
pText3->SetNullPen(FALSE);

CFOStaticShape *pText4 = pReturn->AddText("Brother1","Jack",CRect(0,200,200,250));
pText4->SetBrushType(1);
pText4->SetBkColor(RGB(255,255,255));
pText4->SetPenStyle(PS_SOLID);
pText4->SetNullPen(FALSE);


pReturn->RemoveAllPorts();
pReturn->CreateDefaultPort(0.5,0.5);
CString strCaption = GetCurrentModel()->GetUniqueCaption(pReturn->GetType());
CString strName = GetCurrentModel()->GetUniqueName(pReturn->GetType());
pReturn->SetObjectCaption(strCaption);
pReturn->SetObjectName(strName);
GetCurrentModel()->InsertShape(pReturn);
pReturn->Release();
pReturn = NULL;
}

Back to Top

Q:如何将选中组件向下移动50个像素?

A:可以调用下面的代码来完成:

void CCustShapeView::OnObjectMoveY50() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() >0)
{
int nMove = 50;
DoMoveAction(&m_listSelectComp, 0, nMove);
}

Back to Top

Q:如何将选中组件移动点(100,200)?

A:可以调用下面的代码来完成:

void CCustShapeView::OnObjectMoveTo() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() > 0)
{
CRect rcPos = GetCompsMaxRect(&m_listSelectComp);
CPoint ptMove;
ptMove = CPoint(100 - rcPos.TopLeft().x,200 - rcPos.TopLeft().y);
DoMoveAction(&m_listSelectComp, ptMove.x, ptMove.y);
}

Back to Top

Q:如何为直线添加末尾箭头?

A:可以调用下面的代码来完成:

void CCustShapeView::OnObjectRightarrow() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() <= 0)
{
return;
}

CFODrawShapeList lstUpdate;

CFODrawShape *pShape = NULL;
POSITION pos = m_listSelectComp.GetHeadPosition();
while(pos != NULL)
{
pShape = m_listSelectComp.GetNext(pos);
if(pShape != NULL)
{
if(pShape->IsKindOf(RUNTIME_CLASS(CFOLineShape)))
{
CFOLineShape *pLine = (CFOLineShape *)pShape;
int nArrowType = 3;
pLine->SetEndArrowType(nArrowType);
lstUpdate.AddTail(pLine); 
}
}
}
UpdateShapes(&lstUpdate);
}

Back to Top

Q:如何为直线添加开始箭头?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectLeftarrow() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() <= 0)
{
return;
}

CFODrawShapeList lstUpdate;

CFODrawShape *pShape = NULL;
POSITION pos = m_listSelectComp.GetHeadPosition();
while(pos != NULL)
{
pShape = m_listSelectComp.GetNext(pos);
if(pShape != NULL)
{
if(pShape->IsKindOf(RUNTIME_CLASS(CFOLineShape)))
{
CFOLineShape *pLine = (CFOLineShape *)pShape;
int nArrowType = 3;
pLine->SetStartArrowType(nArrowType);
lstUpdate.AddTail(pLine); 
}
}
}
UpdateShapes(&lstUpdate);
}

Back to Top

Q:如何将组件按比例放大2倍?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectEnlarge() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() <= 0)
{
return;
}
DoCompSizeAction(&m_listSelectComp,2.0f, 2.0f, BeCenter);
}

Back to Top

Q:如何将组件按缩小到原来的一半?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectReduce() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() <= 0)
{
return;
}
DoCompSizeAction(&m_listSelectComp,0.5f, 0.5f, BeCenter);
}

Back to Top

Q:如何将组件旋转90度?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectRotate90() 
{
// TODO: Add your command handler code here
int nCount = 0;
CFODrawShapeList lstRotate;
CFODrawShape* pShape;
POSITION pos = m_listSelectComp.GetHeadPosition();
while(pos != NULL)
{
pShape = m_listSelectComp.GetNext(pos);
if(pShape != NULL && !pShape->IsLock())
{
if(pShape->IsOver4ResizeHandles() && 
(!pShape->IsKindOf(RUNTIME_CLASS(CFOLinkShape))) &&
(!pShape->IsKindOf(RUNTIME_CLASS(CFOStaticShape))))
{
lstRotate.AddTail(pShape);
nCount ++;
}
}
}

if(nCount > 0)
{
DoCompRotateAction(&lstRotate,900);
}
}

Back to Top

Q:如何修改选中组件的标题,并且支持UNDO/REDO功能?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectCaption() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() == 1)
{
CFODrawShape *pShape = GetCurrentSelectShape();
if(pShape != NULL)
{
CFOCompProperties *prop = (CFOCompProperties *)pShape->FindProperty(FO_DEFAULT_PROP_ID);
CFOCompProperties *propNew = (CFOCompProperties *)prop->Copy();
CEditCaptionDlg dlg;
dlg.m_strCaption = prop->GetObjectCaption();
if(dlg.DoModal() == IDOK)
{
propNew->SetObjectCaption(dlg.m_strCaption);
DoPropChangeAction(pShape,propNew);

GetCurrentModel()->SetModifiedFlag();
}

}
return;
}
else if(m_listSelectComp.GetCount() >1)
{
CEditCaptionDlg dlg;
if(dlg.DoModal() == IDOK)
{
CFOMultiCompsPropAction* pAction = new CFOMultiCompsPropAction(GetCurrentModel());

CFODrawShape *pShape = NULL;
POSITION pos = m_listSelectComp.GetHeadPosition();
while(pos != NULL)
{
pShape = (CFODrawShape *)m_listSelectComp.GetNext(pos);

CFOCompProperties *prop = (CFOCompProperties *)pShape->FindProperty(FO_DEFAULT_PROP_ID);
CFOCompProperties *propNew = (CFOCompProperties *)prop->Copy();
propNew->SetObjectCaption(dlg.m_strCaption);
pAction->AddShape(pShape,propNew);
}
GetCurrentModel()->Do(pAction);
GetCurrentModel()->SetModifiedFlag();
}
}
}

Back to Top

Q:如何修改画布的网格颜色?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectGridColor() 
{
// TODO: Add your command handler code here
COLORREF crColor = GetCurrentModel()->GetGridColor();
CColorDialog dlg(crColor, CC_FULLOPEN | CC_ANYCOLOR);
if(dlg.DoModal() == IDOK)
{
GetCurrentModel()->SetGridColor(dlg.GetColor());
Invalidate(FALSE);
}
}

Back to Top

Q:如何将画布放大到原来的200%?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectZoom300() 
{
// TODO: Add your command handler code here
SetZoomScale(200);
Invalidate(FALSE);
UpdateWindow();
}

Back to Top

Q:如何隐藏选中的组件?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectHideall() 
{
// TODO: Add your command handler code here
if(m_listSelectComp.GetCount() <= 0)
{
return;
}

CFODrawShapeList lstUpdate;

CFODrawShape *pShape = NULL;
POSITION pos = m_listSelectComp.GetHeadPosition();
while(pos != NULL)
{
pShape = m_listSelectComp.GetNext(pos);
if(pShape != NULL)
{
if(pShape->IsVisible())
{
pShape->SetVisible(FALSE);
lstUpdate.AddTail(pShape);
}
}
}
m_listSelectComp.RemoveAll();
UpdateShapes(&lstUpdate);
}

Back to Top

Q:如何显示所有的组件?

A:可以调用下面的代码来完成:


void CCustShapeView::OnObjectShowall() 
{
// TODO: Add your command handler code here
if(GetCurrentModel()->GetFormObjects()->GetCount() <= 0)
{
return;
}

CFODrawShapeList lstUpdate;

CFODrawShape *pShape = NULL;
POSITION pos = GetCurrentModel()->GetFormObjects()->GetHeadPosition();
while(pos != NULL)
{
pShape = GetCurrentModel()->GetFormObjects()->GetNext(pos);
if(pShape != NULL)
{
if(!pShape->IsVisible())
{
pShape->SetVisible(TRUE);
lstUpdate.AddTail(pShape);
}
}
}
UpdateShapes(&lstUpdate);
}

Back to Top

Q:我想绘制一副图像,但是每次放入组件的时候,每个组件的填充属性都为白色,将我的其它组件进行了覆盖,所以要手动的修改每个组件的填充属性为none,能不能将所有的组件的默认填充属性都修改成none,不要每次都修改(特别不方便),有什么好办法吗?

A:可以调用下面的代码来完成:


CFODrawShape *CMyExtDataModel::DoCreateShapeByType(UINT m_drawshape,
CRect &rcCreate,
CString strFileName,
CFOToolBoxItem *pCurItem)
{
CFODrawShape *pReturn = NULL;

pReturn = CFODataModel::DoCreateShapeByType(m_drawshape,rcCreate,strFileName);

pReturn->SetTransparent(TRUE);
pReturn->SetBrushType(0);

return pReturn;

}

Back to Top

Q:我使用From++生成了我的应用程序,使用共享MFC编译成功,但是我使用Static连接库编译是出现如下错误:
--------------------Configuration: gongju - Win32 Release--------------------
Compiling resources...
Compiling...
StdAfx.cpp
自动连接到 Form++ V5.07 试用版本 编译日期 2002年11月1日
Automatically linking with XGLS507.lib (Static,Release,MFC LIB)
Compiling...
ChildFrm.cpp
gongju.cpp
gongjuDoc.cpp
gongjuView.cpp
MainFrm.cpp
MyColorPaletteBar.cpp
MyExtDataModel1.cpp
Generating Code...
Linking...
LINK : fatal error LNK1104: cannot open file "XGLS507.lib"
Error executing link.exe.

gongju.exe - 1 error(s), 0 warning(s)

在本机上搜索XGLS507.lib没有发现,请问是怎么回事?是Form++没有提供还是我没有生成该库?难道我不能使用静态连接库编译?

A:您还没有在您的计算机上编译好Form++静态库,更详细的如何编译请参阅在线帮助系统中的说明。

Back to Top

Q:我使用Form++向导生成的程序,看到工程中有CFODataModel类,而我的CMyExtDataModel 继承CFOTabModelManager当我在CMyExtDataModel类中增加了
virtual CFODrawShape *DoCreateShapeByType(UINT m_drawshape,CRect &rcCreate,CString strFileName = _T(""),CFOToolBoxItem *pCurItem = NULL);
和实现函数时编译出现错误:

-Configuration: gongju - Win32 Release--------------------
Compiling...
MyExtDataModel1.cpp
E:\图形工具\gongju\MyExtDataModel1.cpp(135) : error C2352: 'CFODataModel::DoCreateShapeByType' : illegal call of non-static member function
        c:\PROGRAM FILES\UCANCODE.NET SOFTWARE\FORM++ LIBRARY\FO\INCLUDE\FODataModel.h(167) : see declaration of 'DoCreateShapeByType'
Error executing cl.exe.

MyExtDataModel1.obj - 1 error(s), 0 warning(s)
该函数已经在FODataModel.h中定义过了,怎样解决?


A:在基于Visio样式的多页应用程序中,画布的数据由两个部分的数据来管理,即:DataModel和DataModelManager,因此如果要增加此功能,您必须同时从这两个方面的类继承新类(即CFOTabModel以及CFOTabModelManager)。DoCreateShapeByType(...)只能够添加到CFOTabModel的继承类中。
请参阅这个示例程序中的实现:

TestVisio.zip

Back to Top

Q:函数virtual CFODrawShape *DoCreateShapeByType(UINT m_drawshape,CRect &rcCreate,CString strFileName = _T(""),CFOToolBoxItem *pCurItem = NULL);
中的参数 = _T(""),CFOToolBoxItem *pCurItem = NULL是否能够去掉?如果不去掉,点击函数是会发生找不到函数的错误,去掉后则能找到,而且没有发现运行出错.请问是否是这样?去掉后是否有其它影响?不去掉编译也通过,那么你提供该参数的目的是什么?

A:此函数的另外两个参数在此含书中有非常重要的意义,不能去掉。

Back to Top

Q:1.保存成bitmap,EMF,DIB图像使用程序怎么做?
2.我想改变画布背景,怎么做?
3.我想设置我的画布的网格成黄色的直线,并将画布的网格水平30等分垂直22等分,怎么做?
4.我要将标尺变成厘米显示怎么做?

A:参考下面的解答:

1、调用下面的函数保存为bitmap或者dib图像:
BOOL  ExportAsBmpfile(LPCTSTR lpszFileName);
调用下面函数保存为emf文件:
BOOL  ExportAsMetafile(LPCTSTR lpszFileName);

2、调用下面的方法改变画布的背景色:
GetCurrentModel()->SetBkColor(dlg.m_crBK);
GetCurrentModel()->SetModifiedFlag(TRUE);
GetCurrentModel()->NotifyObserver(FO_HINT_UPDATE_WINDOW,NULL);

3、设置网格颜色以及间距距离:
GetCurrentModel()->SetGridColor(dlg.GetColor());
GetCurrentModel()->SetGridX(30);
GetCurrentModel()->SetGridY(22);
Invalidate(FALSE);

4.我要将标尺变成厘米显示怎么做?
Form++标尺的缺省单位是英寸,如果您需要转换成厘米,您需要重新编写标尺的下列函数:
// draw numbers of ruler
 virtual void DrawNumbers(CDC& dc, double dInc, int nTPU);

 // draw divided line
 virtual void DrawDiv(CDC& dc, double dInc, int nLargeDiv, int nLength);

Back to Top

Q:我通过以下程序绘图
CSize szPage = GetCurrentModel()->GetFormSize();
CRect rect= GetFormRect() ;
long h=(long)(rect.right-rect.left)/30 ;
long v=(long)(rect.bottom-rect.top)/22 ;

file://创建画笔
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen* pOldPen=pDC->SelectObject (&pen);
file://绘制黄色网格
for(int i=0;i<31;i++)
{//竖线
pDC->MoveTo(rect.left+h*i,rect.left);
pDC->LineTo(rect.left+h*i,v*22+rect.top);
}
for(int j=0;j<23;j++)
{//横线
pDC->MoveTo(rect.top,v*j+rect.top);
pDC->LineTo(rect.left+h*30,v*j+rect.top);
}
pDC->SelectObject (pOldPen);
但是却画到了画布的外边,请解答.


A:

您需要的功能可以通过下面的方法来实现:
 GetCurrentModel()->SetGridColor(RGB(255,0,0));
 GetCurrentModel()->SetGridX(30);
 GetCurrentModel()->SetGridY(22);
 GetCurrentModel()->SetGridLineType(GRID_RECTANGLE);
 GetCurrentModel()->NotifyObserver(FO_HINT_UPDATE_WINDOW,NULL);

Back to Top

Q:我编写的绘图工具使用程序保存,但是我保存了图形后,退出绘图工具时,总是弹出"将改动保存到 无标题"对话框,怎样设置不弹出提示保存对话框.

A:这只是一个比较简单基本vc编程的问题,您只需要覆盖您当前文档类的
virtual void SetModifiedFlag(BOOL bModified = TRUE);
virtual BOOL IsModified();
两个函数即可。具体可以参考示例程序的编程示范。

TestVisio_Ext.zip

Back to Top

Q:背景组件在Data Model中可以替换掉,代码怎么写?

A:这只是一个比较简单基本vc编程的问题,您只需要调用您当前DataModel类的
SetBackDrawComp(new CMyBackShape);
两个函数即可。具体可以参考示例程序的编程示范。

TestBack.zip

Back to Top

Q:

IN form++5.1中:
"ToolBox增加了一个新的函数专门控制是否显示弹出菜单"
"在Visio风格列表类中增加了是否允许编辑标签控制函数"
请问分别是何?

A:

调用void  EnableEditProp(const BOOL bEnable)来控制是否显示弹出菜单,位置:CFOToolBoxPageWnd
调用void  EnableEditLabel(const BOOL bEnable)来控制是否允许编辑标签控制,位置:CFOTabControlWnd

Back to Top

Q:Form++示例设计中的缺陷

A:Form++在设计示例程序CustomMSample示例程序的时候出现了错误,请参阅下面的修正后的版本:

Form++专业版本:CustomMSample_Pro.zip

Form++基础版本:CustomMSample.zip

Back to Top

Q:在系统自带的三组 shapes 的基础上增加一组自己的shapes,并且是从一个文件中读取的,就如你们自带的 Form Objects.trs!

A:

请参考下面的步骤:
1、打开您当前的应用程序,在ToolBox的标题条上单击右键,选择菜单新建。
2、此时会增加一个新的页面,在新的页面上单击右键,选择?#21478;存为?#65292;将当前页面保存到一个新的trs文件中,例如:test.trs
3、将此test.trs复制到当前应用程序的"Shapes"目录下面。
4、在写字板中打开index.dat(放在shapes目录下面),增加一个新的项:如4#test.trs
然后重新运行程序即可。

Back to Top

Q:

我是FORM++用户,我想改变状态条的以下两个ID号:
ID_FO_INDEX_WIDTH,ID_FO_INDEX_HEIGHT的显示值为厘米,(缺省为象数值),请问对应ID的处理函数在哪里?

A:请参考下面的示例程序中的代码(只适用于Form++基础版本):

CustomTool.zip

Back to Top

Q:遍历所有的画布的所有元素

A:请参考下面的的代码:

CFODrawShape *pObject = NULL;
POSITION pos = GetCurrentModel()->GetFormObjects()->GetHeadPosition();
while (pos != NULL) 
{
pObject = (CFODrawShape*)(GetCurrentModel()->GetFormObjects()->GetNext(pos));
... ...
}

Back to Top

Q.如何在不同的应用程序类中获取其它类的指针?

A:请参考下面的列表:
From this class: You can access this class using:
CWinApp CMainFrame CChildFrame CDocument CView
CWinApp AfxGetMainWnd() or
m_pMainWnd
GetAfxMainWnd()->MDIGetActive() GetAfxMainWnd()->GetActiveView()->GetDocument() GetAfxMainWnd()->GetActiveView()
CMainFrame AfxGetApp() or
theApp
MDIGetActive() or
GetActiveFrame()
SDI: GetActiveView()->GetDocument()
MDI:
MDIGetActive()->GetActiveView()->GetDocument()
SDI: GetActiveView()
MDI:
MDIGetActive()->GetActiveView()
CChildFrame AfxGetApp() or
theApp
GetParentFrame() GetActiveView()->GetDocument() GetActiveView()
CDocument AfxGetApp() or
theApp
AfxGetMainWnd() GetAfxMainWnd()->MDIGetActive() POSITION pos = GetFirstViewPosition();
GetNextView(pos);

(see note below)
CView AfxGetApp() or
theApp
AfxGetMainWnd() GetParentFrame() GetDocument()
any other class AfxGetApp() AfxGetMainWnd() AfxGetMainWnd()->MDIGetActive() or
AfxGetMainWnd()->GetActiveFrame()
SDI: AfxGetMainWnd()->GetActiveView()->GetDocument()
MDI:
AfxGetMainWnd()->MDIGetActive()->GetActiveView()->GetDocument()
SDI: AfxGetMainWnd()->GetActiveView()
MDI:
AfxGetMainWnd()->MDIGetActive()->GetActiveView()
Note: To access only the current view, the document class can call GetAfxMainWnd()->GetActiveView() from a SDI application or GetAfxMainWnd()->MDIGetActive()->GetActiveView() from a MDI application.

Back to Top

 

[ 主页 | 产品 | 新闻 | 下载 | 购买 | 技术支持 | 与我们联系 ]



地址:中国.成都高新区永丰路24号附1号 (邮编:610041)电话: +86-28-85354545 
Copyright ?998-2024 UCanCode Software, ? 版权所有。
其他的产品和公司名称或注册的商标属于其各公司版权所有。

任何问题或者建议请与我们联系:webmaster@ucancode.com