|
我们的知识库使用精炼的语言来解决常见的问题。虽然无法与一些大公司的知识库相比,我们会尽力提供更多的信息。知识库将不断更新,增加新的内容。所以希望大家经常关注。
我们的技术支持团队将不断更新和扩充知识库,从一般的编程问题到完整的实例。您可以通过编目、产品类型、或者目录索引来找到您所需的信息。要获取这些信息,您无需注册。
其中的文章回答了很多的用户最常提出的问题。通常情况下,这些文章可以说是超越了版本限制的。您可以类推到你所遇到的情况。
这个页面包含常见的问题和我们的技术支持小组的解答,以及一些常用技巧和提示。
注意:在以下的解答中我们将按如下的简记惯例来描述用户界面操作。组合键按以下方式如:Ctrl+Alt+Delete,意思是你同时按下Control键、Alt键和Delete键不放。菜单的选择将如下描述:File->Open,意思是你打开文件(File)菜单,然后选择打开(Open
)项。
问题列表:
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++安装到其他目录下,你需要作一些调整。
- 选择"Tools"菜单中的"Options"然后选中"Directories"。.
- 设定"Show directories for:"到"Include
files".
- 增加"C:\Program
Files\UCanCode Software Inc\Form++ Library V2.0\Fo20\Include"
to the到?/font>
- 设定"Show directories for:"到"Library
files".
- 增加"C:\Program
Files\UCanCode Software Inc\Form++ Library V2.0\Lib"
to the到列表中
list.
- 设定"Show directories for:"到"Source
files".
- 增加"C:\Program
Files\UCanCode Software Inc\Form++ Library V2.0\Fo20\source"
to the
- 增加"C:\Program
Files\UCanCode Software Inc\Form++ Library V2.0\Fo20\Include"
to the list.
- 现在可以从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.trs、Forms
Shapes.trs和index.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) ;
...
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 ;
double TopOffset = 0.5 ;
double RightOffset = 0.5 ;
double BottomOffset = 0.5 ;
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));
lf.lfHeight = -MulDiv(12, pDC->GetDeviceCaps(LOGPIXELSY), 72);
strcpy(lf.lfFaceName, "Arial");
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!
HANDLE ImageToDIB( CImageList* pImageList, int iImageNumber, CWnd* pWnd)
{
CBitmap bitmap;
CWindowDC dc( pWnd );
CDC memDC;
CRect rect;
CPalette pal;
IMAGEINFO imageInfo;
if (!pImageList->GetImageInfo( iImageNumber, &imageInfo ))
{
return NULL;
}
if (!memDC.CreateCompatibleDC(&dc ))
{
return NULL;
}
if (!bitmap.CreateCompatibleBitmap(&dc,
imageInfo.rcImage.bottom-imageInfo.rcImage.top,
imageInfo.rcImage.right-imageInfo.rcImage.left))
{
memDC.DeleteDC() ;
return NULL;
}
CBitmap* pOldBitmap = memDC.SelectObject( &bitmap );
if( NULL == pOldBitmap )
{
memDC.DeleteDC() ;
return NULL;
}
CPoint point( 0, 0);
UINT nStyle = ILD_NORMAL;
if(!pImageList->Draw( &memDC, iImageNumber, point, nStyle ))
{
memDC.SelectObject(pOldBitmap) ;
VERIFY(bitmap.DeleteObject()) ;
memDC.DeleteDC() ;
return NULL;
}
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 );
pal.CreatePalette( pLP );
delete[] pLP;
}
memDC.SelectObject( pOldBitmap );
memDC.DeleteDC() ;
HANDLE h = DDBToDIB(bitmap, BI_RGB, &pal );
VERIFY(bitmap.DeleteObject()) ;
return h ;
}
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() );
if( dwCompression == BI_BITFIELDS )
return NULL;
hPal = (HPALETTE) pPal->GetSafeHandle();
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
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;
int nColors = 0;
if(bi.biBitCount <= 8)
{
nColors = (1 << bi.biBitCount);
}
dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
hDC = ::GetDC(NULL);
hPal = SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
if (!hDIB){
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
*lpbi = bi;
GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
if (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
dwLen += bi.biSizeImage;
handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE) ;
if (handle != NULL)
hDIB = handle;
else
{
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)hDIB;
BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
0L,
(DWORD)bi.biHeight,
(LPBYTE)lpbi
+ (bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi,
(DWORD)DIB_RGB_COLORS);
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(ℑ_list, iImage, this) ;
BITMAPINFOHEADER *pBMI ;
pBMI = (BITMAPINFOHEADER*)GlobalLock(hDib) ;
int nColors = 0;
if (pBMI->biBitCount <= 8)
{
nColors = (1 << pBMI->biBitCount);
}
::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);
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(CF | |