如何让一个程序只运行一次,方法很多。可通过发送消息,发送事件,检测窗口等方法。
下面介绍一种查找窗口类名和枚举窗口并且获取窗口属性的方法。
方法一、
通过FindWindow函数,找到指定窗口类名或窗口名的窗口的句柄。给每一个窗口程序都定义一个唯一的类名或者窗口名
1、 查找类名、窗口
在程序开始加入如下代码:
HWND hfind = ::FindWindow(L"MyHello",L”Hello”);// MyHello为类名,Hello为窗口名
if(hfind)
{
::ShowWindow(hfind,SW_SHOW); //窗口存在,显示之前窗口。
return FALSE; //退出这次程序
}
2、如何在定义一个类名呢
A、在win32中,只要在创建窗口时,注册一个窗口类名
wc.lpszClassName = L" MyHello ";
RegisterClass(&wc);
B、在MFC中,往往系统会默认给你“Dialog”类名,如果多个MFC程序,那么他们类名都一样,这个时候我们需要修改默认的类名。
第一步:在工程的InitInstance函数中,修改类名Dialog为MyHello(该名称与第二步保持一致)
BOOL CMyHelloApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
//
//----------------------------------添加---------------------------
WNDCLASS wc;
BOOL bret = ::GetClassInfo(AfxGetInstanceHandle(), L"Dialog", &wc);
wc.lpszClassName = L"MyHello"; //这里于第2步的字符串必须一样
// // Register this class so that MFC can use it。
AfxRegisterClass(&wc);
//----------------------------------结束---------------------------
CMyHelloDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
第二步:打开工程的rc文件
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MYIE_DIALOG DIALOGEX 0, 0, 269, 155
STYLE WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_APPWINDOW | 0x80000000L
CLASS " MyHello "
FONT 8, "System"
BEGIN
END
添加CLASS " MyHello "这一行即可。
这样步骤完成,只要程序在运行,就可以查找到窗口类MyHello,窗口名可用可不用。
方法二、
1、设置窗口属性:
SetProp函数在指定窗口的属性表中增加一个新项
RemoveProp函数指定的窗口的属性表中删除一项
程序启动时添加:
HANDLE g_hValue = (HANDLE)1;//指向要拷贝到属性表中的数据的句柄
SetProp(m_hWnd,g,L”Hello”,g_hValue);
程序退出时:
RemoveProp(m_hWnd,g_szPropName);
2、如何查找改程序是否运行呢。
枚举窗口
HANDLE g_hValue = (HANDLE)1;
BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lParam)
{
HANDLE h = GetProp(hwnd,L” Hello”);
if( h == g_hValue)
{
*(HWND*)lParam = hwnd;
return false;
}
return true;
}
//在InitInstance加入部分代码
BOOL CHelloApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
//----------------------------添加----------------------
HWND oldHWnd = NULL;
EnumWindows(EnumWndProc,(LPARAM)&oldHWnd); //枚举所有运行的窗口
if(oldHWnd != NULL)
{
::ShowWindow(oldHWnd,SW_SHOWNORMAL); //激活找到的前一个程序
::SetForegroundWindow(oldHWnd); //把它设为前景窗口
return false; //退出本次运行
}
//-----------------------------介绍---------------------
CCHelloApp Dlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}