//工程引用此单元就能防止同时出现多个实例
unit MultInst;
interface
uses Windows ,Messages, SysUtils, Classes, Forms;
implementation
const
  STR_UNIQUE    = '{2BE6D96E-827F-4BF9-B33E-8740412CDE96}';
  MI_ACTIVEAPP  = 1;  {激活应用程序}
  MI_GETHANDLE  = 2;  {取得句柄}
var
  iMessageID    : Integer;
  OldWProc      : TFNWndProc;
  MutHandle     : THandle;
  BSMRecipients : DWORD;
function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint): Longint; stdcall;
begin
  Result := 0;
  if Msg = iMessageID then
  begin
    case wParam of
      MI_ACTIVEAPP: {激活应用程序}
        if lParam<>0 then
        begin
          {收到消息的激活前一个实例}
          {为什么要在另一个程序中激活?}
          {因为在同一个进程中SetForegroundWindow并不能把窗体提到最前}
          if IsIconic(lParam) then
            OpenIcon(lParam)
          else
            SetForegroundWindow(lParam);
          Application.Terminate; {终止本实例}
        end;
      MI_GETHANDLE: {取得程序句柄}
        begin
          PostMessage(HWND(lParam), iMessageID, MI_ACTIVEAPP, Application.Handle);
        end;
    end;
  end
  else
    Result := CallWindowProc(OldWProc, Handle, Msg, wParam, lParam);
end;
procedure InitInstance;
begin
  {取代应用程序的消息处理}
  OldWProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc)));
  {打开互斥对象}
  MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, STR_UNIQUE);
  if MutHandle = 0 then
  begin
    {建立互斥对象}
    MutHandle := CreateMutex(nil, False, STR_UNIQUE);
  end
  else
  begin
    Application.ShowMainForm  :=  False;
    {已经有程序实例,广播消息取得实例句柄}
    BSMRecipients := BSM_APPLICATIONS;
    BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE, @BSMRecipients, iMessageID, MI_GETHANDLE,Application.Handle);
  end;
end;
initialization
  {注册消息}
  iMessageID  := RegisterWindowMessage(STR_UNIQUE);
  InitInstance;
finalization
  {还原消息处理过程}
  if OldWProc <> Nil then
    SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldWProc));
  {关闭互斥对象}
  if MutHandle <> 0 then
    CloseHandle(MutHandle);
end.

最新文章

  1. LINUX 根目录说明
  2. SPSS数据分析—二分类Logistic回归模型
  3. HDMI学习
  4. Android Studio导入github下载的工程
  5. Delphi TRichEdit加载word内容
  6. 从assemblyer Instructure deepth understander C principle
  7. windows消息常量值
  8. js实现在新标签页打开页面
  9. 学习任务在继续...css...
  10. linux虚拟机CentOS 7完整安装流程截图
  11. I can do it
  12. Node的安装和进程管理
  13. 看到一个简单的背单词java程序的设计,收藏下
  14. Git-撤销(回退)已经add,commit或push的提交
  15. 机器学习随笔01 - k近邻算法
  16. 原生js实现table的排序
  17. android:3D垂直翻转动画-FlipAnimation
  18. IBM X3650 M4 主板故障
  19. 使用 runtime 实现字符串转方法,并传递参数
  20. bzoj 1004 Cards 组合计数

热门文章

  1. 将序列设置为字段的默认值 - oracle
  2. 3DSlicer源代码编译过程vs2008+windows xp [转]
  3. stl map高效遍历删除的方法 [转]
  4. javac 命令
  5. 窥探EasyMock(2)进阶使用篇
  6. jsonUtil 工具类
  7. insertAfter()
  8. 跨域iframe高度自适应(兼容IE/FF/OP/Chrome)
  9. 数据结构复习:直接插入排序与二分插入排序的C++实现
  10. 使用cwRsync实现windows下文件定时同步【转】