• C++Builder使用经验谈(下)


    五、软件封面的实现
        
        现代软件设计的流行做法是,在程序运行完成初始化之前,先调用一幅画面做为封面,通常是1/4屏幕大小,显示一下软件的名称、作者、版本等信息。
        
        要用C++Builder实现这样的功能,方法很简单:
        
        ①自定义一窗体类TSplashForm,将其设置成"透明窗口",即BorderIcons下的所有选项均置成false,BorderStyle=bsNone,FormStyle=fsStayOnTop,Position=poScreenCenter;
        
        ②在TSplashForm窗体上放置一TPanel(相当于图形的镜框);
        
        ③在TPanel上放置一TImage控件,调入所需要的图形;
        
        ④对WinMain函数稍加修改,加入如下所示代码即可。
        
        需要指出的是,这段代码通过函数FindWindow,搜索内存中是否有窗口标题为"Demo"应用程序存在,若存在,则退出程序的运行。该功能可防止程序的再次运行。在某些场合这样设计是必须的。
        
        WINAPIWinMain(HINSTANCE,HINSTANCE,LPSTR,int)
        
        {
        
        try
        
        {
        
        if(FindWindow(NULL,"Demo")!=0)
        
        {
        
        Application->MessageBox
        
        ("程序已经运行!","警告",MB_ICONSTOP);
        
        return0;
        
        }
        
        TSplashForm*splash=newTSplashForm(Application);
        
        splash->Show();
        
        splash->Update();
        
        Application->Initialize();
        
        Application->CreateForm(__classid(TForm1),&Form1);
        
        splash->Close();
        
        deletesplash;
        
        Application->Run();
        
        }
        
        catch(Exception&exception)
        
        {
        
        Application->ShowException(&exception);
        
        }
        
        return0;
        
        }
        
        六、如何永久清除DBF中的已被删除的记录
        
        用table->Delete()删除的DBF记录,并没有真正从DBF数据库中被删除,而仅仅是做上了一个删除标记。如何实现类似dBase中的Pack命令的功能呢?请看下面的代码。
        
        table->Close();
        
        for(;;)
        
        try
        
        {
        
        table->Exclusive=true;
        
        table->Open();
        
        break;
        
        }
        
        catch(…)
        
        {
        
        }
        
        if(DbiPackTable(table->DBHandle,table->
        
        Handle,NULL,szDBASE,true)!=DBIERR_NONE)
        
        Application->MessageBox("不能删除记录",
        
        "错误",
        
        MB_ICONSTOP);

    七、I/O端口读写的实现
        
        细心的读者会发现,C++Builder不再支持如inportb()、outportb()一类I/O端口读写指令了。准确地说,在Windows环境下,BorlandC++仅支持16位应用程序的端口操作,对32位应用程序的端口操作不再支持,而C++Builder开发出来的程序是32位的。我个人以为,这是C++Builder设计者的败笔。因为PC机中,I/O地址空间与内存地址空间从来都是各自独立的。看看Delphi,不就通过Port数组实现了对I/O端口的访问了吗?搞不清楚为什么C++Builder就没有提供类似的机制?下面这几个函数是笔者从网上淘下来的,经过验证,在Windows95环境下,的确可实现对I/O端口的读写。读者可以借鉴使用。
        
        voidoutportb(unsignedshort
        
        intport,unsignedcharvalue)
        
        {
        
        //movedx,*(&port);
        
        __emit__(0x8b,0x95,&port);
        
        //moval,*(&value);
        
        __emit__(0x8a,0x85,&value);
        
        //outdx,al;
        
        __emit__(0x66,0xee);
        
        }
        
        voidoutportw(unsignedshort
        
        intport,unsignedshortintvalue)
        
        {
        
        //movedx,*(&port);
        
        __emit__(0x8b,0x95,&port);
        
        //movax,*(&value);
        
        __emit__(0x66,0x8b,0x85,&value);
        
        //outdx,ax;
        
        __emit__(0xef);
        
        }
        
        unsignedcharinportb(unsignedshortintport)
        
        {
        
        unsignedcharvalue;
        
        //movedx,*(&port);
        
        __emit__(0x8b,0x95,&port);
        
        //inal,dx;
        
        __emit__(0x66,0xec);
        
        //mov*(&value),al;
        
        __emit__(0x88,0x85,&value);
        
        returnvalue;
        
        }
        
        unsignedshortintinportw(unsignedshortintport)
        
        {
        
        unsignedshortintvalue;
        
        //movedx,*(&port);
        
        __emit__(0x8b,0x95,&port);
        
        //inax,dx
        
        __emit__(0xed);
        
        //mov*(&value),ax
        
        __emit__(0x66,0x89,0x85,&value);
        
        returnvalue;
        
        }
        
        八、软件的分发
        
        在Windows下开发的应用程序一般都比较庞大,程序的运行往往离不开一大堆不知名的系统DLL文件。为了生成能脱离C++Builder环境、独立运行的应用程序,读者须对编译器进行一定的设置。方法是:置Project/Option/Packages/Runwithruntimepackages为Disable,置Project/Option/Linker/UsesdynamicRTL为Disable,重新编译一遍程序,这样生成的EXE文件就可以脱离C++Builder环境运行了。但如果你的程序中应用了数据库,仅有上述的操作是不够的--因为,你还得安装BDE(BorlandDatabaseEngineer)。BDE的安装比较麻烦,读者最好是用C++Builder3.0附带的InstallShieldExpress来制作安装盘,把应用程序和BDE打包在一起。如果找不到,也可用Delphi3.0附带的InstallShieldExpress来制作。InstallShield的使用方法,限于篇幅,不再介绍。有条件的读者可上网查到有关资料。


    原文:http://c.chinaitlab.com/ccjq/874278_4.html

  • 相关阅读:
    创建型设计模式之-单例
    设计模式(1、创造型2、结构型、3行为型)
    手写IOC容器和两种注入(构造方法注入和属性注入)
    从依赖倒置原则到IOC控制反转
    自定义HttpHandler可以做什么
    一个用户在浏览器上输入网址怎么走到我们写的.net程序中的,请求到管道处理
    代理Nginx
    .Net Expression表达式目录树(自己动态创建表达式目录树)
    canvas绘制圆环进度条
    城市二级联动
  • 原文地址:https://www.cnblogs.com/phyking/p/4456670.html
Copyright © 2020-2023  润新知