| 如果您是使用Microstation中的MDL来开发应用系统,那么加入安装界面将会使人对您的应用程序具有深刻的第一印象。这一篇文章就是叙述通过各种MDL应用程序的连结来建立安装界面资料库界面;此应用程序大致上可以使用任何的bitmap影像,同时设定也相当容易。  在这项目中,有一些基本的设计参数。在图形中几乎任何形式的bitmap影像均可以使用,虽然影像的大小与内容都是考虑的重点,但这并不在这篇文章的讨论范围内,故不在此作探讨。程序之中不应将特定的影像档档名写入程序码中,以免以后无法改变所设定影像档;要注意控制好安装界面显示时间的长短;最后要考虑的一点是当安装界面是INITAPP内之一个设定值时,尽可能让安装界面能显现。  我已经利用这些规则来建立了一个MDL应用程序来显示安装界面,这篇文章中引用它来说明项目,程序码会在转载於此以供参考,亦可在MSM Online Code Archive 中下载。  表1 原始档splash.r中的程序码  /*********************************************************************  * Copyright ( 1998   2001 ) Bentley Systems, Inc., All rights reserved.  *  *  * Description:  *  *  * Modifications:  *=========================================================  *  *  ********************************************************************/  /*----------------------------------------------------------------------+  | |  | Include Files |  | |  +----------------------------------------------------------------------*/  # include < rscdefs.h >  # include < cmdclass.h >  # include < dlogbox.h >  # include < dlogids.h >  # include < keys.h >  # include " splash.ids "  /*----------------------------------------------------------------------+  | |  | 对话方块 |  | |  +----------------------------------------------------------------------*/  DialogBoxRsc DIALOGID_Splash =  {  DIALOGATTR_NORIGHTICONS |  DIALOGATTR_REQUESTBACKINGSTORE |  DIALOGATTR_MUSTSTAYVISIBLE |  DIALOGATTR_UNMOVEABLE |  DIALOGATTR_THINBORDERS |  DIALOGATTR_UNCLOSEABLE,  0, 0,  NOHELP, MHELP,  NOHOOK,  NOPARENTID,  "",  {  {{ 0, 0, 0, 0 }, Generic, GENERICID_SplashFrame, ON, 0, "", ""},  }  };  /*----------------------------------------------------------------------+  | |  | 实体项目 |  | |  +----------------------------------------------------------------------*/  /*----------------------------------------------------------------------+  | |  | 一般的资源项目 |  | |  +----------------------------------------------------------------------*/  DItem_GenericRsc GENERICID_SplashFrame =  {  NOHELP,  MHELP,  HOOKID_GenericItem,  NOARG  };  表2 独立部分的原始档 splash.ids 程序码  /*********************************************************************  * Copyright ( 1998   2001 ) Bentley Systems, Inc., All rights reserved.  *  *  * Description:  *  *  * Modifications:  *==========================================================  *  ********************************************************************/  # if ! defined ( __splashidsH__ )  # define __splashidsH__  /*----------------------------------------------------------------------+  ||  | 定义 |  ||  +----------------------------------------------------------------------*/  /*----------------------------------------------------------------------+  ||  | 资源 ID's |  ||  +----------------------------------------------------------------------*/  /*----------------------------------------------------------------------+  ||  | 对话框 ID's |  ||  +----------------------------------------------------------------------*/  # define DIALOGID_Splash 1000  /*----------------------------------------------------------------------+  ||  | 一般项目 ID's |  ||  +----------------------------------------------------------------------*/  # define GENERICID_SplashFrame 1  # endif /* !defined ( __splashidsH__ ) */  在建立资源的档案中将会产生给这些对话框的资源库(表3),而这个建立的档案将被包含在以下的splash.mke档案之中(参表5)。请注意资源库将不会与任何的物件档案相连结,而连结的部分将由(splash.rl)这个档案在稍後有片段的说明。  表3  包含资源建立的档案splashRsc.mki    #----------------------------------------------------------------------  # Copyright 1996 - 2000, Bentley Systems, Inc.  #  # 这边所授与的最高权限仅限於复制及修正版权资料,而这项版权  # 资料规定所提供的程序码仅能与Bentley所提供的相关产品中使  # 用。此外需注意有关版权资料在任何的复制或修正下,也应该保持  # 程序完整性。  #----------------------------------------------------------------------  rlRscs = $(o) $( appName ).rsc  #----------------------------------------------------------------------  # 以下的部分是建立给应用系统的任何转换资源的模组  #----------------------------------------------------------------------  $(o) $( sAppName ).rsc : $( baseDir ) $( appName ).r \  $( privateInc ) $( appName ).ids  #----------------------------------------------------------------------  # 共用对话框资源的使用  #----------------------------------------------------------------------  $( LibraryOut ) $( sAppName ).rl : $( rlRscs )  $( msg )  > $(o)make.opt  -o$@  $( rlRscs )  <  $( rscLibCmd ) @ $(o)make.opt  ~time  # 建立结束。注意:空白行再对於结束最后的规则时是相当有用的,  # 因为这可以防止与其他的’.mki’档案连结,源自Foreign Language  # Translation Kit的规范。  建立资源库界面  资源库界面是由一个MDL物件与一个资源库物件所组成的,而这些均需连结至你所建立的应用程序,我建立了一个简单的MDL应用程序来说明如何完成这些设定。  安装界面对话方块是在splash.r中定义(参考表1)。这只是关於对话中的一般对话项目来提供bitmap影像。当阅读程序码之时,请注意有许多对话框属性已经有定义了,因为这些定义,所以安装界面的边框可以隐藏起来,并在必要时将它贴上,同时防止当安装界面显示时, 使用者试图控制或修改安装界面的大小。此外也须注意这些对话方块与其所产生的安装界面并没有绝对的座标位置与相关大小,它们会随著所载入影像的大小而作缩放,这些对话方块在这资源中是独立的并在splash.ids(表2)中做定义。  建立资源库界面  下一步所要探讨的是原始码(表4)。所有的操作都是在这里处理。首先来看看显示安装界面界面的公用程序splash_displaySplashWindow,这个界面所需注意的只有时间这一个参数,显示安装界面是以秒为单位,因为这个参数没有任何的检测,所以依照个人需求,适当的设定时间参数。以下的例子是以现有的界面来显示安装界面。首先,一个叫splash_getBMPImageData会抓取点阵影像并将其读进记忆体之中,影像的名称会储存於参数设定档中的变数SPLASH_BMP之中。为了能够使用各种格式的格点影像,利用第四的参数值IMAGEFILE_INKNOWN回传给标准MDL界面mdlImage_readFileToRGB,当参数值回传後,界面即会读进影像的格式来做计算,所以当影像被载入记忆体中,程序即可减少处理有关各类影像的转换的事情。在顺利地取得影像并存入记忆体之后,程序就会重新调整对话项目及对话框的大小以配合影像,执行这些工作的是splash_resizeDialogForBMP。当对话框调整之后,这就做好要显示的准备了。再来就是依照公用界面中所设定的时间以暂停MicroStation数秒钟。  表4  原始码splash.mc  /********************************************************************  * Copyright ( 1998   2001 ) Bentley Systems, Inc., All rights reserved.  *  * Description:  *  * Modifications:  ********************************************************************/  /* Standard Microstation include files */  # include < mdl.h >  # include < msdefs.h >  # include < basetype.h >  # include < global.h >  # include < dlogitem.h >  # include < image.h >  # include < stdlib.h >  # include < string.h >  # include < stdio.h >  /* Function definition files */  # include < mssystem.fdf >  # include < msdialog.fdf >  # include < mswindow.fdf >  # include < msimage.fdf >  /* 特定的表头档案 */  # include "splash.h"  # include "splash.fdf"  # include "splash.ids"  /*----------------------------------------------------------------------+  |  | 本机定义  |  +----------------------------------------------------------------------*/  Point2d rgbImageSize;  BSIRect bmpRectangle;  char *imageBuffer = NULL;  DialogBox *splashDbP = NULL;  /*----------------------------------------------------------------------+  |  | 外部变数  |  +----------------------------------------------------------------------*/  /*==========================================================+  |  | 公用程序的内部演算  |  +==========================================================*/  /*----------------------------------------------------------------------+  ||  | 名称:splash_getBmpName  ||  | 目的:由设定参数回传显示影像的名称  +----------------------------------------------------------------------*/  Private char *splash_getBmpName  (  void  )  {  // get bmp name from CfgVar  return ( mdlSystem_getExpandedCfgVar ( TXT_SPLASH_BMP ));  }  /*----------------------------------------------------------------------+  ||  | 名称:splash_getDialogFontInfo |  ||  | 目的:由对话方块与影像的大小来计算对话文字的大小 |  +----------------------------------------------------------------------*/  Private void splash_getDialogFontInfo  (  DialogBox *dP,  int *fWidth,  int *fHeight,  double *hFactor  )  {  mdlDialog_fontGetInfo ( NULL, fWidth, NULL,  fHeight, dP,  mdlDialog_fontIndexGet ( dP ));  /* The height factor for the dialog is 12 times the font height */  if ( hFactor )  *hFactor = 12.0 / ( double )( *fHeight );  }  /*----------------------------------------------------------------------+  ||  | 名称:splash_getSextentFromRectangle |  ||  | 目的:设定项目的范围为有关对话框内的字体 |  | 与影像的相关项目 |  ||  +----------------------------------------------------------------------*/  Private void splash_getSextentFromRectangle  (  Sextent *extent,  DialogBox *dP,  BSIRect *rectP  )  {  double hFactor;  int fHeight;  splash_getDialogFontInfo ( dP, NULL, &fHeight, &hFactor );  extent -> origin.x = ( double ) rectP -> origin.x * hFactor;  extent -> origin.y = ( double ) rectP -> origin.y * hFactor;  extent -> width = ( double ) ( rectP -> corner.x - rectP->origin.x ) * hFactor;  extent -> height = ( double ) ( rectP -> corner.y - rectP -> origin.y ) * hFactor;  }  /*----------------------------------------------------------------------+  ||  | 名称:splash_resizePhotoGenericItem |  ||  | 目的:重新调整对话方块中的项目以配合影像大小 |  ||  +----------------------------------------------------------------------*/  Private void splash_resizePhotoGenericItem  (  DialogBox *dP,  BSIRect *rectP,  Point2d *imageSize,  int fWidth  )  {  DialogItem *itemP = 0x0;  Sextent extent;  Point2d newPos;  int index;  itemP = mdlDialog_itemGetByTypeAndId ( dP, RTYPE_Generic,  GENERICID_SplashFrame, 0 );  rectP -> origin.y = itemP -> rect.origin.y;  rectP -> origin.x = itemP -> rect.origin.x;  rectP -> corner.x = rectP -> origin.x + imageSize -> x - ( 2*XC );  rectP -> corner.y = rectP -> origin.y + imageSize -> y - ( YC/2 );  splash_getSextentFromRectangle ( &extent, dP, rectP );  mdlDialog_itemSetExtent ( dP, itemP -> itemIndex, &extent, FALSE );  }  /*----------------------------------------------------------------------+  ||  | 名称:splash_resizeDialogForBMP |  ||  | 目的:重新调整对话框以配合影像大小 |  ||  +----------------------------------------------------------------------*/  Private void splash_resizeDialogForBMP  (  DialogBox *dP,  BSIRect *rectP,  Point2d *imageSize  )  {  DialogItem *itemP = 0 x 0;  MSDisplayDescr *displayDescrP = NULL;  Point2d newPos;  Rectangle rect;  int fWidth,  fHeight;  mdlDialog_fontGetInfo ( NULL, &fWidth, NULL, &fHeight, dP,  mdlDialog_fontIndexGet ( dP ));  splash_resizePhotoGenericItem ( dP, rectP, imageSize, fWidth );  itemP = mdlDialog_itemGetByTypeAndId ( dP, RTYPE_Generic,  GENERICID_SplashFrame, 0 );  if ( !itemP )  return  newPos.y = ( itemP -> rect.corner.y > rectP -> corner.y ) ?  itemP -> rect.corner.y : rectP -> corner.y;  newPos.y += ( fHeight / 2 );  newPos.x = rectP -> corner.x + fWidth;  mdlWindow_pointToGlobal ( &newPos, dP, &newPos );  mdlWindow_resize ( dP, CORNER_LOWERRIGHT, &newPos );  displayDescrP = mdlWindow_displayDescrGet ( dP );  if ( displayDescrP )  {  Point2d upperLeftPos;  BSIRect windowRect;  mdlWindow_globalRectGetGlobal ( &windowRect, dP );  upperLeftPos.x = (( displayDescrP -> screenRect.corner.x -  displayDescrP -> screenRect.origin.x ) -  ( windowRect.corner.x - windowRect.origin.x )) / 2;  upperLeftPos.y = (( displayDescrP -> screenRect.corner.y -  displayDescrP -> screenRect.origin.y) -  ( windowRect.corner.y - windowRect.origin.y )) / 2;  mdlWindow_resize ( dP, CORNER_ALL, &upperLeftPos );  }  }  /*----------------------------------------------------------------------+  ||  | 名称:splash_displayBMPData |  ||  | 目的: 将RGB 影像置入对话框中 |  ||  +----------------------------------------------------------------------*/  Private void splash_displayBMPData  (  DialogBox *dP,  BSIRect *rectP,  Point2d *imageSize  )  {  BSIRect rect;  if ( !dP )  return;  memcpy ( &rect, rectP, sizeof ( BSIRect ));  rect.origin.x += 1;  rect.origin.y += 1;  rect.corner.x = rect.origin.x + rgbImageSize.x - 1;  rect.corner.y = rect.origin.y + rgbImageSize.y - 1;  rectP -> corner.x = rect.corner.x;  rectP -> corner.y = rect.corner.y;  mdlWindow_rgbDataDraw ( dP, &rect, 0, imageBuffer, 0, 0, NULL );  mdlDialog_rectDrawBeveled ( dP, rectP, TRUE, TRUE );  }  /*----------------------------------------------------------------------+  ||  | 名称:splash_getBMPImageData |  ||  | 目的:将获得的影像以RGB格式处理, |  | 所以可以在一般的对话项目中显示。 |  ||  +----------------------------------------------------------------------*/  Private int splash_getBMPImageData  (  void  )  {  int fileType;  char *fileNameP = NULL;  int iStatus = ERROR;  char alert [ MAXFILELENGTH ];  if ( imageBuffer != NULL )  {  free ( imageBuffer );  imageBuffer = NULL;  }  fileNameP = splash_getBmpName ( );  if ( fileNameP != NULL )  {  if (( Status = mdlImage_readFileToRGB (&imageBuffer, &rgbImageSize,  fileNameP, IMAGEFILE_UNKNOWN,  NULL, NULL )) != SUCCESS )  {  sprintf ( alert, "Error %d : Unable to convert or retrieve Image : ( %s )", iStatus, fileNameP );  mdlDialog_openAlert ( alert );  }  }  if ( fileNameP )  free ( fileNameP );  return iStatus;  }  /*==========================================================+  ||  | 主要的公用程序部分 |  ||  +==========================================================*/  /*----------------------------------------------------------------------+  ||  | 名称:splash_displaySplashWindow |  |||  +----------------------------------------------------------------------*/  Public void splash_displaySplashWindow  (  int seconds /* Time the dialog is open */  )  {  if ( mdlDialog_find ( DIALOGID_Splash, NULL ) == NULL )  {  /* 获取所需的影像资料 */  if ( SUCCESS == splash_getBMPImageData ( ))  {  /* 开启对话框来抓取影像 */  splashDbP = mdlDialog_open ( NULL, DIALOGID_Splash );  /* 隐藏对话框直到其大小符合影像为止 */  mdlWindow_hide ( splashDbP, FALSE, TRUE );  /* 调整对话内容 */  splash_resizeDialogForBMP ( splashDbP, &bmpRectangle, &rgbImageSize );  /* 对话内容 */  mdlWindow_show ( splashDbP, TRUE );  /* 将影像贴入对话方块中的一般项目 */  splash_displayBMPData ( splashDbP, &bmpRectangle, &rgbImageSize );  /* 等待应用系统定义所需时间 */  mdlSystem_pauseTicks ( 60 * seconds );  /* 关闭对话方块然后继续应用程序 */  mdlWindow_close ( splashDbP, FALSE, TRUE );  }  }  }  表5  建立档案splash.mke  #----------------------------------------------------------------------  #  # Current Revision:  # Copyright 1996, Bentley Systems, Inc.  #  # 这边所授与的最高权限仅限於复制及修正版权资料,而这项版权  # 资料规定所提供的程序码仅能与Bentley所提供的相关产品中使  # 用。此外需注意有关版权资料在任何的复制或修正下,也应该保持  # 程序完整性。  #  #----------------------------------------------------------------------  # 使用的变数如下PROJECT、appName、sAppName与LibraryOut  # 而这些变数的定义包含原始码的目录与输出资料的目录。举例来  # 说,如果project的目录是“ \library ”且应用程序就叫做“splash”,而  # 输出的目录是在library底下的“ bin ”,则原始码的目录将会在  # \library\splash 而输出的目录就会在\library\bin。  # 当变数appName超过8个位元时,就使用变数sAppNam,它是  # 变数appName的简称。如果变数appName等於或少於8个位元时  # 则变数appName与sAppName就都一样了。如果你所使用的是不  # 同的目录,则你就 要改变这些变数去符合你的目录结构。  #------------------------------------------------------------------------  PROJECT = library  appName = splash  sAppName = splash  baseDir = $( PROJECT ) / $( appName ) /  privateInc = $( baseDir )  langSpec = $( baseDir ) english /  LibraryOut = $( PROJECT ) / bin /  % include mdl.mki # Load standard rule definitions.  # --- Default to creating MS95 library ----  # Must specify bmake command line argument "-dMSV5" to build for # # MS Ver 5 #  #----------------------------------------------------------------------  # 以下定义为此应用系统中代码的附属表,包括任何代码  # 的查询系统或物件与此应用系统间的关联性,一般来说  # 这些档案均与一个附档名为’ .map’的档案相连结( Mdl  # 程序模组 )。  #  # 注意:所有包含在.mc 档案中的文字字串应该置於’langSpec’  # 目录下的讯息资源表内,所有的字串在执行时就应要  # 从信息源表中来下载。  #----------------------------------------------------------------------  appObjects = \  $(o) $( sAppName ).mo  #----------------------------------------------------------------------  # 以下定义为此应用系统中任何非使用转换资源的附属表单,  # 一般说来,这些包括了任何指令表单的定义与资源型态的定  # 义,并且这些表单也涵盖了应用系统中代码部分的完整资料  # 。所以一般来说,这些档案资料均置於附档名为’ .mi ’的档  # 案中。( Mdl Intermediate application )  #----------------------------------------------------------------------  #----------------------------------------------------------------------  # 建立输出目录  #----------------------------------------------------------------------  $(o)$( tstdir ) : $(o)$( tstdir )  $( rscObjects )$( tstdir ) : $( rscObjects )$( tstdir )  $( outputDir )$( tstdir ) : $( outputDir )$( tstdir )  $( LibraryOut )$( tstdir ) : $( LibraryOut )$( tstdir )  #--------------------------------------------------------------------------  # 以下的部分是要建立任何应用系统模组所需的程序码  #--------------------------------------------------------------------------  $(o)$( sAppName ).mo : $( baseDir )$( sAppName ).mc \  $( privateInc )splash.fdf \  $( privateInc )splash.h  #---------------------------------------------------------------------------  # 以下的部分会产生MDL 程序模组。  # 这些模将包含所有程序码与应用系统所使用的资源库。  #---------------------------------------------------------------------------  $( LibraryOut )$( appName ).ml : $( appObjects )  $( msg )  > $(o)make.opt  a # create new .ml file  $@  $( appObjects )  <  $( mLibCmd ) @$(o)make.opt  ~time  % include $( baseDir )$( appName )Rsc.mki  表6  表头档splash.h  /**********************************************************  * Copyright ( 1998   2001 ) Bentley Systems, Inc., All rights reserved.  *  * Description:  *  * Modifications:  *==================================================  *  ***********************************************************  # if !defined ( __splashH__ )  # define __splashH__  # define TXT_SPLASH_BMP " SPLASH_BMP " /* hash define for the config variable name */  # endif /* __spalshH__ */  表7  功能定义档splash.fdf  /**********************************************************  * Copyright ( 1998   2001 ) Bentley Systems, Inc., All rights reserved.  *  * Description:  *  * Modifications:  *==================================================  *  ***********************************************************  # if !defined ( _splashFDF_ )  # define _splashFDF_  Public void splash_displaySplashWindow  (  int second /* seconds the dialog is opened */  )   # endif /* _splashFDF_ */  完成的例子  表8所说明的是改变原来的原始档案中的主要功能;表9与表10所要说明的是将其他特定的建立安装界面档案加入应用系统中。  表8  原始档案的变更  /* 包括splash功能定义档案 */  # include “ splash.fdf ”  /* 主要功能 */  int main  (  int argc.  Char **argv  )  {  /* ---------------- 其他程序 -------------------- */  /* 开启splash window五秒钟 */  splash_displaySplashWindow ( 5 );  /* 与一些其他程序码 */  return SUCCESS;  }  表9  原始建立档案的变更  appObjects =\  $(0)$( appName ).mo \  $( mdlLibs )mdllib.ml \  $( LibraryOut )splash.ml \  $( mdlLibs )ditemlib.ml  表10  原始建立档案的变更  maRscs = \  $( rscObjects )$( sAppName )dlg.rsc \  $( LibraryOut )splash.rl \  $( reqdObjs )$( appName ).mi  结论  如果您想要INITAPP应用程序中加入安装界面,且显示的是您客户专有的安装界面并非Microstation 预设的安装界面,这时您就 要在参数设定档中定义参数MS_NOSPLASH,这需要在系统层面上做设定,并不是在Microstation任何的参数设定档中定义此一参数,它的设定并没有任何特定值,只需将此参数值设为1即可。  此外若想在这边提高这个程序的功能,则可以在浮贴资料库中加入按键,以此种方式放入“说明”或 “关于…”的选项目,以及“确定”或“取消”以结束安装界面对话方块。 |
|【路桥隧】
( 湘ICP备16018960号-1 ) QQ群:
GMT+8, 2026-4-2 09:43
Powered by Discuz! X3.2
© 2001-2013 Comsenz Inc.