单实例程序方法

单实例程序


这种情况是打开同类型的文件,然后不想再开一个程序的实例,最好就是让它单实例,然后把同类型文件通过消息传给程序的第一个实例。
办法:
最早看的文章是使用winmain中的参数hPrevInstance,后来在32位中这个参数一直为0,所以不能用了。


好的解决办法是使用mutex互斥。


步骤:
1.首先尝试打开mutex,如果不存在这个mutex,那么就是第一个实例。
2。创建mutex,如果它不存在
3. 在程序返回后,然后释放掉release mutex。
4.如果mutex存在,这表明是程序的第二个实例,终止该实例通过winmain()函数的return。



WINAPI WinMain(
  HINSTANCE, HINSTANCE, LPSTR, int)
{
  try {
    // Try to open the mutex.
    HANDLE hMutex = OpenMutex(
      MUTEX_ALL_ACCESS, 0, "MyApp1.0");


    if (!hMutex)
      // Mutex doesn’t exist. This is
      // the first instance so create
      // the mutex.
      hMutex = 
        CreateMutex(0, 0, "MyApp1.0");
    else
      // The mutex exists so this is the
      // the second instance so return.
      return 0;


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


    // The app is closing so release
    // the mutex.
    ReleaseMutex(hMutex);
  }
  catch (Exception &exception) {
    Application->
      ShowException(&exception);
  }
  return 0;
}







然后将改程序放在前台,然后终止。
if (!hMutex)
  hMutex = CreateMutex(0, 0, "MyApp1.0");
else {
  HWND hWnd = FindWindow(
    0, "File Association Example");
  SetForegroundWindow(hWnd);
  return 0;
}





传数据到初始化实例


解决方法是:使用WM_COPYDATA消息




使用WM_COPYDATA消息
方法是使用WPARAM传入消息,LPARAM传入tagCOPYDATASTRUCT数据结构
typedef struct tagCOPYDATASTRUCT {
  DWORD dwData;
  DWORD cbData;
  PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;






windows为保证消息没被处理之前,数据要保证一直存在,必须使用 SendMessage() 发WM_COPYDATA 消息. 不能用 PostMessage(). 
if (strlen(cmdLine) != 0) {
  COPYDATASTRUCT cds;
  cds.cbData = strlen(cmdLine) + 1;
  cds.lpData = cmdLine;
  SendMessage(hWnd, 
    WM_COPYDATA, 0, (LPARAM)&cds);
}



处理WM_COPYDATA消息

String S = 
  (char*)Message.CopyDataStruct->lpData;


  
  


下边是
BCB代码



#include <vcl.h>
#pragma hdrstop
USERES("FileAssociation.res");
USEFORM("MainU.cpp", Form1);


WINAPI WinMain(
  HINSTANCE, HINSTANCE, LPSTR cmdLine, int)
{
  try {
    // Try to open the mutex.
    HANDLE hMutex = OpenMutex(
      MUTEX_ALL_ACCESS, 0, "MyApp1.0");


    // If hMutex is 0 then the mutex doesn't exist.
    if (!hMutex)
      hMutex = CreateMutex(0, 0, "MyApp1.0");
    else {
      // This is a second instance. Bring the 
      // original instance to the top.
      HWND hWnd = FindWindow(
        0, "File Association Example");
      SetForegroundWindow(hWnd);


      // Command line is not empty. Send the 
      // command line in a WM_COPYDATA message.
      if (strlen(cmdLine) != 0) {
        COPYDATASTRUCT cds;
        cds.cbData = strlen(cmdLine);
        cds.lpData = cmdLine;
        SendMessage(
          hWnd, WM_COPYDATA, 0, (LPARAM)&cds);
      }


      return 0;
    }


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


    ReleaseMutex(hMutex);
  }
  catch (Exception &exception) {
    Application->ShowException(&exception);
  }
  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值