中国程序员联盟 正在重新改版中ing 不便之处还请见谅 改版后将内容涉及java delphi .net php
 
  首页 | 数据库开发 | 网络通讯 | 多线程 | 多媒体开发 | 图像处理 | 程序人生 | 系统函数 | 控件开发 | Web服务
 
  当前位置:笨鱼delphi技术网>系统函数>文章内容

delphi 只允许有一个应用程序

来源:国外 关于:Jonas Bilinkevicius 发布时间:2007-07-03   [收藏] [推荐]
Problem/Question/Abstract:
I use Delphi 6 to make an application. Everytime I run the executable, an instance of my application starts up (of course). Is there any way to detect at runtime if another instance of the same application is running and switch control to the original window instead of making a new one?
Answer:
Solve 1:
Include the following unit in your code:
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 procedure}
  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.

Solve 2:
The simplest way to do this is to make the following changes to your dpr where TForm1 is the name of your main form.
program Project1;
uses
  Forms, Windows, Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
  if FindWindow('TForm1', nil) <> 0 then
  begin
    SetForegroundWindow(FindWindow('TForm1', nil));
    Exit;
  end;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

[浏览: 次]   
上一篇:delphi 实时记录事件日志   下一篇:delphi 显示文件属性
[收藏] [推荐] [返回顶部] [打印本页] [关闭窗口]  
    评论加载中…
google adsense热点文章
·delphi Delphi中ShellExecute的妙用
·delphi 如何快速读取文本文件
·delphi 如何判断输入值是否中文
·delphi 在应用层截获键盘消息
·delphi delphi实现服务开启与关闭
·delphi 实时记录事件日志
·delphi 使MEMO自动滚动
·delphi 如何区分键盘两个Enter键
·delphi 切换界面的方法
·delphi 汉字输入法的编程及使用
·delphi Delphi程序输入法自动切换最简
·delphi 消息是由谁来发出又由谁来完成
     delphi技术网 | firefox 下载 | Avant Browser下载 | dedecms 技术网 | drupal 爱好者 | php 技术网
  Copyright@www.delphichm.com,2006-2009.All Rights Reserved.
 
程序员联盟 | delphi Java .net|QQ:707102932