win32中preinstance已经没有意义,比较简单的方法思路是,
使用FindWindow函数来查找你的主Form是否已经创建.
FindWindow(  LPCTSTR lpClassName, // pointer to class name // 你的Form的类名TForm1等.
    LPCTSTR lpWindowName  // pointer to window name//可以为空 nil
   );
返回你的Form的handle ,在使用 setwindowpos(handle,....)把你的程序防到最
上面. 但是 在 IDE环境中,此方法不灵,因为Delphi已经打开了你的主Form.
这些判断都放在dpr中.
//另一个方法复杂一些,在你的dpr中 使用临界区,可以创建一个Mutex Objects
具体方法请参看window api的帮助.这时可以判断是否程序已经执行.
然后在使用FindWindow和setwindowpos

解决方案 »

  1.   

    kxy的方法是可行的.不过不总是正确,因为用MainForm的Caption找窗口不总是
    有效的方法.kxy的方法有一个现成的控件,并且能够激活上一个实例.最可靠的办法是建立MapFile,文件映射或者用注册器,关键是一旦运行程序首
    先要将Application的Handle保存起来,而退出后再抹去保存的句柄.第二份实
    例运行时,如果我个句柄存在则读出这个句柄并用Win32API激活.
      

  2.   

    MapFile、文件映射及注册器都不是个好办法, 如果我强行关机怎么办?
    我觉得MemoryMap应该是个好主意. 
      

  3.   

    有好几种方法
    dpr如下:
    var
      HMutex: HWnd;begin
      GlobalMsg:=RegisterWindowMessage(PChar('文正明分机管理器已经运行'));
      HMutex:=CreateMutex(nil,False,PChar('pwzmUsrMgr'));
      if WaitForSingleObject(HMutex,100)=WAIT_TIMEOUT then
        PostMessage(HWND_BROADCAST,GlobalMsg,0,0)
      else
      begin
        Application.Initialize;
        Application.Title := '分机管理器';
        Application.CreateForm(TFrmMainStation, FrmMainStation);
        Application.Run;
        ReleaseMutex(HMutex);
      end;
      CloseHandle(HMutex);
    end.主窗口.pas
    var
      FrmMainStation: TFrmMainStation;
      GlobalMsg: UINT;procedure TFrmMainStation.OnAppMessage(var Msg:TMsg; Var Handled:Boolean);
    begin
      if Msg.message=GlobalMsg then
      begin
        Show;
        WindowState:=wsNormal;
        BringToFront;
        SetFocus;
        Handled:=True;
      end;
    end;procedure TFrmMainStation.FormCreate(Sender: TObject);
    begin
      Application.OnMessage:=OnAppMessage;
    end;
      

  4.   

    有关这个问题的技巧好象大多数有关DELPHI网站上都有讲过,何不自己花点时间去探寻一番呢?