31
2019
01

防止程序启动两次的方法CreateMutex()

在工程文件中, WinMain函数里加上以下代码(此代码在BCB6.0下运行):

HANDLE hMutex = CreateMutex(NULL, false, "Process");
       
if (GetLastError() == ERROR_ALREADY_EXISTS)
       
{
           CloseHandle(hMutex);
           MessageBox(Application
->Handle, "程序已经在运行中,不能重复启动!", "提示", MB_OK +MB_ICONWARNING);
           Application
->Terminate();
           
return 0;
        }

        Application
->CreateForm(__classid(TForm1), &Form1);


主要使用到CreateMutex()函数和GetLastError()以及一个常量ERROR_ALREADY_EXISTS.

当然, 你的程序有窗体的话, 还可以使用FindWindow().

void *handle = FindWindow(NULL, WindowName.c_str());
if (handle!=NULL)
   
return 0;


进程的互斥运行

  正常情况下,一个进程的运行一般是不会影响到其他正在运行的进程的。但是对于某些有特殊要求的如以独占方式使用串行口等硬件设备的程序就要求在其进程运行期间不允许其他试图使用此端口设备的程序运行的,而且此类程序通常也不允许运行同一个程序的多个实例。这就引出了进程互斥的问题。

  实现进程互斥的核心思想比较简单:进程在启动时首先检查当前系统是否已经存在有此进程的实例,如果没有,进程将成功创建并设置标识实例已经存在的标记。此后再创建进程时将会通过该标记而知晓其实例已经存在,从而保证进程在系统中只能存在一个实例。具体可以采取内存映射文件、有名事件量、有名互斥量以及全局共享变量等多种方法来实现。下面就分别对其中具有代表性的有名互斥量和全局共享变量这两种方法进行介绍:

// 创建互斥量
HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");
// 检查错误代码
if (GetLastError() == ERROR_ALREADY_EXISTS) {
 
// 如果已有互斥量存在则释放句柄并复位互斥量
 CloseHandle(m_hMutex);
 m_hMutex
= NULL;
 
// 程序退出
 return FALSE;
}


上面这段代码演示了有名互斥量在进程互斥中的用法。代码的核心是CreateMutex()对有名互斥量的创建。CreateMutex()函数可用来创建一个有名或无名的互斥量对象,其函数原型为:

HANDLE CreateMutex(
 LPSECURITY_ATTRIBUTES lpMutexAttributes,
// 指向安全属性的指针
 BOOL bInitialOwner, // 初始化互斥对象的所有者
 LPCTSTR lpName // 指向互斥对象名的指针
);


如果函数成功执行,将返回一个互斥量对象的句柄。如果在CreateMutex()执行前已经存在有相同名字的互斥量,函数将返回这个已经存在互斥量的句柄,并且可以通过GetLastError()得到错误代码ERROR_ALREADY_EXIST。可见,通过对错误代码ERROR_ALREADY_EXIST的检测可以实现CreateMutex()对进程的互斥。

建立互斥体,用来同步。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

参数
lpMutexAttributes
指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。    
bInitialOwner
布尔类型,决定互斥体的创建者是否为拥有者
lpName
指向互斥体名字字符串的指针。互斥体可以有名字。
互斥体的好处是可以在进程间共享

心得体会:
   CreateMutex() 用于有独占要求的程序 (在其进程运行期间不允许其他使用此端口设备的程序运行,或不允许同名程序运行)。如有同名程序运行,则通过 GetLastError()得到错误代码 ERROR_ALREADY_EXIST。

刚才又执行了下得出的结果(程序名samp)
      一般情况下:一进入调试阶段,进程管理器中就出现了samp进程,执行到CreateMutex时返回进程句柄,执行到if(GetLastError() == ERROR_ALREADY_EXISTS ) 进行判断时,跳过不执行if中的内容,所以表示没有互斥。
      调试之前先运行debug中的samp.exe再调试:一进入调试阶段,进程管理器中就出现了两个samp进程,执行到CreateMutex时返回进程句柄,执行到if(GetLastError() == ERROR_ALREADY_EXISTS ) 进行判断时,执行if中的内容,表示有互斥。



25
2018
09

为你的C++ Builder 6 安装FastReport 4

声明:以下教程是从网上copy下来的,权当给自己留一份记录,经测试,可用。

 --------------------- 本文来自 feichangfriend 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/feichangfriend/article/details/9140981?utm_source=copy

以前曾经安装过FastReport数据报表控件,觉得功能不错。现在发现网上已经有4以上的版本下载使用。于是从CCRUN上下载了FastReport V4.7.9进行安装,在下载后发现安装复杂了些,比FastReprot 2.41的版本比较没有自动安装,需要手动编译各部件。于是将安装心得记录给有需要的朋友参考。


一、 卸载旧版本

如果以前未安装过FastReport可以直接跳到下一步。如果安装过以前版本的FastReport在工具栏上会看到FastReport和FR Tools两个选项栏。首先我们要把先前的版本卸载。

01.jpg

打开BCB的菜单"Project"->Option。然后在Packages的标签栏项目下,找到FastReport的所有部件,如下图的FastReport2.4 ADO Components 和 FastReport 2.4 Components。分别点击它们然后点地击“Remove”按钮逐个删除。卸载完成后返回,工具栏上面的FastReport和FR Tools两个选项栏也同时被清除。

02.jpg

二、设定安装目录

选择一个目录进行安装,现在以D:/cb6_control目录为例,将下载的FastReport V4.7.9解压到此目录。

04.jpg

三、生成安装链接文件

1. 执行recomplie文件,执行文件前请先将BCB6退出。否则程序文件出现提示并不能继续安装。

2. 程序运行后出现提示,主要是目录读写权限、C++Builder是否运行、是否有其它程序运行FastReport的部件包,点击“Continue”。

05.jpg

3. 进入到程序界面,选择相应的参数项。

第一项“1. Select the complier”选择程序,选择C++Builer 6。

第二项“2. Select the FastReport version”选择安装FastReport的版本,选择Enterprise。

第三项“3. Select the TeeChart version”,如果不知道的情况下请选择TeeChartStd。

第四项“4.What you want to do”,把“Choose Language to”的选择改为“Chinese”中文版。

完成后点击“Complier”,然后程序将FastReport安装所需要的文件生成到"LibBCB6"目录下。

06.jpg

3. 进入安装目录的/Res/Chinese,执行mk.bat文件生成中文菜单XML文件。并将文件复制到安装目录下的Source目录里面。注意一定要执行这个步聚,否则安装后的FastReport菜单的中文为乱码。


四、编译部件

1. 将刚才生成的LibBCB6的所有文件复制到Source目录下。

2.启动BCB。

3.将Source目录下的文件frx.inc复制到FastQB目录下。

4.编译基本部件,用BCB打开及编译以下部件。

打开FastQB目录下的fqb60.bpk,然后Complie.

打开FastScript目录下的fs6.bpk,然后Complie,编译完成后Install安装.

打开FastScript目录下的fsDB6.bpk,然后Complie,编译完成后Install安装..

打开FastScript目录下的FsADO6.bpk,然后Complie,编译完成后Install安装.

打开FastScript目录下的FsBDE6.bpk,然后Complie,编译完成后Install安装.

5.安装控件。

将LibD10目录下的所有pas文件复制到Source目录。

将Source目录下的所有pas文件复制到C++Builder安装目录的Lib/Release目录里面。

将FastScript目录下的所有pas文件复制到C++Builder安装目录的Lib/Release目录里面。

1) 用BCB打开source目录下的frx6.bpk,然后Complie,编译完成后Install安装。

2) 用BCB打开source目录下的frxDB6.bpk,然后Complie,编译完成后Install安装。

3) 用BCB打开source/ExportPack目录下的frex6.bpk,然后Complie,编译完成后Install安装。

4) 用BCB打开source/Ado目录下的frxADO6.bpk,然后Complie,编译完成后Install安装。

5 用BCB打开source/BDE目录下的frxBDE6.bpk,然后Complie,编译完成后Install安装。(可选安装)

6) 用BCB打开source/DBX目录下的frxDBX6.bpk,然后Complie,编译完成后Install安装。(可选安装)

7) 用BCB打开source目录下的frxTee6.bpk,然后Complie,编译完成后Install安装。(Chart,可选安装)

6.完成以上安装后,BCB的工具栏出现FastReport 4.0 和FR4 tools的标签栏。

08.jpg

五、指定头文件和链接库的目录

1. 点击BCB菜单“Project”->“Options”,选择“Directories/Conditionals”的标签栏。

09.jpg

2. 点击“Include Path”的目录选择按钮“...”,弹出界面后点击“...”选择头文件的目录,即Source目录,本例的路径为“D:/cb6_control/gastReport.v4.7.9/Source”,然后点击“Add”按钮。

11.jpg


3. 按照同样的方法将“Source”目录添加到“Libary Path”链接库选项。

4.点击选择左下角的Default,然后点击“OK”。

12.jpg

5.重新启动BCB,FastReport4正式安装完毕。

20.jpg


27
2017
07

BCB6默认保存项目选项defalut打钩,以后每个新建工程都一样

BCB6默认保存项目选项defalut打钩,以后每个新建工程都一样

BCB6默认保存工程选项.jpg 

 

02
2017
03

Borland InterBase删除

 

在'控制面板->性能和维护->管理工具->服务'中  
  先把Interbase   server和interbase   Guardian停掉

 

13
2017
01

VS自带工具:dumpbin的使用 查看exe和dll的性质

 

有时候我们想查看一个exe引用了哪些动态库,或者我们想看某个动态库包含哪些接口函数,这个时候可以使用dumpbin.exe工具:


1.输入Dumpbin -imports calldll.exe查看它的输入信息,可以看到它加载了***.dll
2.输入dumpbin –exports dlltest.dll,列出导出函数


开始->所有程序->Microsoft Visual Studio 2010->Visual Studio Tools ->“Visual Studio 命令提示(2010)”后,

就像普通的cmd一样的命令行环境,就可以正常使用VS的一些工具,其中就包括dumpbin。


输入如下命令,查看dll信息:

D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>

dumpbin -exports D:\WorkSpace\DLLTutorial\Debug\DLLTutorial.dll


输出如下:

图片1.jpg

 

其中可以看到,我们在DLL中写的两个函数:

 1    0 000110FA Add = @ILT+245(_Add)
 2    1 00011208 Function = @ILT+515(_Function)

 

 

03
2017
01

Delphi中如何使右侧的滚动条自动拖到底端以显示 RichEdit 最新添加的文本

 加在OnChange事件中:

卷屏到光标处 

 SendMessage(RichEdit1.Handle, EM_SCROLLCARET, 0, 0); 
向下卷屏一行 
 SendMessage(RichEdit1.Handle, EM_SCROLL, SB_LINEDOWN, 0) 
向下卷屏到底 
 SendMessage(RichEdit1.Handle, WM_VSCROLL, SB_BOTTOM, 0) 
参见 MSDN 的 WM_VSCROLL

25
2013
04

C++运算符优先级顺序

 在C++中 算法运算符>关系运算符>逻辑运算符>赋值运算符。

算术运算符为  +    -   *    /    %     ++    --。

25
2013
04

C++保留字

 asm  auto  bool  break  case  catch  char
class  const  continue defalut  delete  do  double
else  enum  extern  false  float  for  friend
goto  if  inline  int  long  main  namespace
new  operator private  protected public  register return
short  signed  sizeof  static  struct  switch  template
this  throw  true  try  typedef  typeied  typename
union  unsigned using  virtual  void  volatile while

«1»