激活前一个程序(注册全局消息,使用Mutex探测,如果已经占用就广播消息通知第一个程序)

unit MultInst;

interface

const
  MI_QUERYWINDOWHANDLE   = 1;
  MI_RESPONDWINDOWHANDLE = 2;

  MI_ERROR_NONE          = 0;
  MI_ERROR_FAILSUBCLASS  = 1;
  MI_ERROR_CREATINGMUTEX = 2;

// Call this function to determine if error occurred in startup.
// Value will be one or more of the MI_ERROR_* error flags.
function GetMIError: Integer;

implementation

uses Forms, Windows, SysUtils;

const
  UniqueAppStr = ‘DDG.I_am_the_Eggman!‘;

var
  MessageId: Integer;
  WProc: TFNWndProc;
  MutHandle: THandle;
  MIError: Integer;

function GetMIError: Integer;
begin
  Result := MIError;
end;

function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint):
  Longint; stdcall;
begin
  Result := 0;
  // If this is the registered message...
  if Msg = MessageID then
  begin
    case wParam of
      MI_QUERYWINDOWHANDLE:
        // A new instance is asking for main window handle in order
        // to focus the main window, so normalize app and send back
        // message with main window handle.
        begin
          if IsIconic(Application.Handle) then
          begin
            Application.MainForm.WindowState := wsNormal;
            Application.Restore;
          end;
          PostMessage(HWND(lParam), MessageID, MI_RESPONDWINDOWHANDLE,
            Application.MainForm.Handle);
        end;
      MI_RESPONDWINDOWHANDLE:
        // The running instance has returned its main window handle,
        // so we need to focus it and go away.
        begin
          SetForegroundWindow(HWND(lParam));
          Application.Terminate;
        end;
    end;
  end
  // Otherwise, pass message on to old window proc
  else
    Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;

procedure SubClassApplication;
begin
  // We subclass Application window procedure so that
  // Application.OnMessage remains available for user.
  WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
    Longint(@NewWndProc)));
  // Set appropriate error flag if error condition occurred
  if WProc = nil then
    MIError := MIError or MI_ERROR_FAILSUBCLASS;
end;

procedure DoFirstInstance;
// This is called only for the first instance of the application
begin
  // Create the mutex with the (hopefully) unique string
  MutHandle := CreateMutex(nil, False, UniqueAppStr);
  if MutHandle = 0 then
    MIError := MIError or MI_ERROR_CREATINGMUTEX;
end;

procedure BroadcastFocusMessage;
// This is called when there is already an instance running.
var
  BSMRecipients: DWORD;
begin
  // Prevent main form from flashing
  Application.ShowMainForm := False;
  // Post message to try to establish a dialogue with previous instance
  BSMRecipients := BSM_APPLICATIONS;
  BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
    @BSMRecipients, MessageID, MI_QUERYWINDOWHANDLE,
    Application.Handle);
end;

procedure InitInstance;
begin
  SubClassApplication;   // hook application message loop
  MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, UniqueAppStr);
  if MutHandle = 0 then
    // Mutex object has not yet been created, meaning that no previous
    // instance has been created.
    DoFirstInstance
  else
    BroadcastFocusMessage;
end;

initialization
  MessageID := RegisterWindowMessage(UniqueAppStr);
  InitInstance;
finalization
  // Restore old application window procedure
  if WProc <> Nil then
    SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
  if MutHandle <> 0 then CloseHandle(MutHandle);  // Free mutex
end.
时间: 2024-11-10 07:28:32

激活前一个程序(注册全局消息,使用Mutex探测,如果已经占用就广播消息通知第一个程序)的相关文章

激活码方式注册的实现原理述

加密混淆授权 1. 软件授权方式概述 目前,商用软件和共享软件绝大部份都是采用注册码授权的方式来保证软件本身不被盗用,以保证自身的利益.尽管很多常用的许多软件系统的某些版本已经被别人破解,但对于软件特殊行业而言,注册码授权的方式还是一种保护软件系统本身的一种有效的手段. 通常而言,注册码授权方式有以下几种方式: l 安装序列号方式 这是最为常用的方式,Microsoft提供的产品(例如:Windows系列产品.Office系列产品等等)都是采用这种方式.通过一种复杂的算法生成安装序列号,在安装过

微信小程序注册

产品定位及功能介绍 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 小程序注册 注册小程序帐号 在微信公众平台官网首页(mp.weixin.qq.com)点击右上角的“立即注册”按钮. 选择注册的帐号类型 选择“小程序”,点击“查看类型区别”可查看不同类型帐号的区别和优势. 填写邮箱和密码 请填写未注册过公众平台.开放平台.企业号.未绑定个人号的邮箱. 激活邮箱 登录邮箱,查收激活邮件,点击激活链接. 填写主体信息 点击激活链接后,继续下一

Android应用程序注册广播接收器(registerReceiver)的过程分析

前 面我们介绍了Android系统的广播机制,从本质来说,它是一种消息订阅/发布机制,因此,使用这种消息驱动模型的第一步便是订阅消息:而对 Android应用程序来说,订阅消息其实就是注册广播接收器,本文将探讨Android应用程序是如何注册广播接收器以及把广播接收器注册到哪里去的. 在Android的广播机制中,ActivityManagerService扮演着广播中心的角色,负责系统中所有广播的注册和发布操作,因 此,Android应用程序注册广播接收器的过程就把是广播接收器注册到Activ

开机自启动程序 注册表

1 #include "iostream" 2 #include "afx.h" 3 #include "atlbase.h" 4 #include "cstring" 5 using namespace std; 6 7 void main(){ 8 FreeConsole(); 9 HKEY hKey; 10 //找到系统的启动项 11 LPCTSTR lpRun = "Software\\Microsoft\\

小程序基础02:小程序的全局配置

1.配置 我们使用app.json文件来对来微信小程序进行全局配置. 作用:他决定了页面文件的路径,窗口表现,设置网络超时时间,设置多tab等 每一个小程序页面也可以使用 .json 文件来对本页面的窗口进行配置.页面的配置比app.json配置简单得多,只是设置app.json中的window配置项的内容.页面中的配置会覆盖app.json的window中相等的配置项 实例    //pages: String Array 设置页面路径 "pages":[ "pages/i

MySQL-Front 出现“程序注册时间到期 程序将被限制模式下运行”解决方式

MySQL-Front 出现“程序注册时间到期 程序将被限制模式下运行”解决方式 在用mysql-front的时候遇到显示:程序注册时间到期程序将被限制模式下运行.可以在“帮助”菜单下的点“登记”-->把以下的key复制试试,留下以后需要.注意:是整十行一起复制.     gNBpPFgyOw9Rwt/ozsnjgM7tJNo2bhaaAThangemMkaz2tQhq3/f7dZ7Vj29WeGHjuupj/AhYqymjAuokhYiX1T/fG+q1yR22PdcEP39dxU3ovEol

把任意exe程序注册成windows系统服务

某gae代理软件每次开机都需要手动启动,就算添加成开机启动项,在win8.1下权限的管理更加严格,开机时并不能成功启动软件(无人值守时开机),因此在网上搜索把exe注册成系统服务的办法,找到论坛两个帖子,可将代理程序注册成系统服务开机自动启动而不用每次重启系统都要手动启动程序.本经验非原创,内容来自于以上两个帖子. 工具/原料 Instsrv.exe(可以给系统安装和删除服务) Srvany.exe(可以让程序以服务的方式运行) instsrv.exe——来自Windows 2000 Resou

VC++ 在两个程序中 传送字符串等常量值的方法:使用了 WM_COPYDATA 消息(转载)

转载:http://www.cnblogs.com/renyuan/p/5037536.html VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的 消息作用:    在进程间共享数据(内部通过创建内存映射文件) 消息介绍:需要用到的数据结构/类型:typedef struct tagCOPYDATASTRUCT {    ULONG_PTR dwData;    DWORD cbData;    PVOID lpData;} COPYDATASTRUCT,

强化一下概念:程序自己不去取消息,消息不会自己跑过来运行(针对线程消息队列里的消息,也是绝大多数消息)

刚才看这段代码的时候: procedure TControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin if CheckNewSize(AWidth, AHeight) and ((ALeft <> FLeft) or (ATop <> FTop) or (AWidth <> FWidth) or (AHeight <> FHeight)) then begin InvalidateCon