标 题: [合集] 请教如何实现Dialog based apps单实例运行?
发信站: 水木社区 (Sun Dec 3 16:11:26 2006), 站内
☆─────────────────────────────────────☆
rokingphone (鑫森淼焱? ????? ???) 于 (Fri Dec 1 22:19:55 2006) 提到
只允许一个程序运行,第二个运行时使已打开的置顶。
不通过FindWindow,该如何实现?
btw:尝试过用SetWindowsPos 和 SetForegroundWindow 都不能实现。。。
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Fri Dec 1 22:27:06 2006) 提到:
只允许一个:Mutex。
置顶:得到第一个的Handle,然后就好办了。
【 在 rokingphone (鑫森淼焱? ????? ???) 的大作中提到: 】
: 只允许一个程序运行,第二个运行时使已打开的置顶。
: 不通过FindWindow,该如何实现?
: btw:尝试过用SetWindowsPos 和 SetForegroundWindow 都不能实现。。。
: ...................
☆─────────────────────────────────────☆
rokingphone (鑫森淼焱? ????? ???) 于 (Fri Dec 1 22:31:12 2006) 提到
我就是这么做的。
可是一直不能置顶。
部分代码如下:
#pragma data_seg("share")
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:share,RWS")
#define EXCLUSIVE_STRING _T("AFX_OUTPUT__3A93AE06_2751_40E3_8182_6488E146FC7
D")
BOOL COutputApp::InitInstance()
{
// exclusive judgement
m_hOnlyOneInstance = ::CreateMutex(NULL, FALSE, EXCLUSIVE_STRING);
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
if (g_hWnd) //pop up
{
if (IsIconic(g_hWnd))
::ShowWindow(g_hWnd, SW_SHOW);
::SetForegroundWindow(g_hWnd);
//此三句换成
// ::SetWindowPos(g_hWnd, HWND_TOPMOST, NULL, NULL, NULL, NULL, SWP_NOMOVE
|SWP_NOSIZE);
//同样不能置前
}
return FALSE; // terminates the creation
}
COutputDlg dlg;
m_pMainWnd = &dlg;
g_hWnd = m_pMainWnd->m_hWnd;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
if (m_hOnlyOneInstance)
::CloseHandle(m_hOnlyOneInstance);
g_hWnd = NULL;
}
return FALSE;
}
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: 只允许一个:Mutex。
: 置顶:得到第一个的Handle,然后就好办了。
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Fri Dec 1 22:32:38 2006) 提到:
handle是一个进程数据,不能跨进程操作。你可以在这里Sendmessage给已经存在的实例。
【 在 rokingphone (鑫森淼焱? ????? ???) 的大作中提到: 】
: 我就是这么做的。
: 可是一直不能置顶。
: 部分代码如下:
: ...................
☆─────────────────────────────────────☆
rokingphone (鑫森淼焱? ????? ???) 于 (Fri Dec 1 22:34:54 2006) 提到
我的Handle没有跨进程呢。
就一个。在.h里定义的
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: handle是一个进程数据,不能跨进程操作。你可以在这里Sendmessage给已经存在的实例
。
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Fri Dec 1 22:38:15 2006) 提到:
在一个.h跟是否跨进程有啥关系啊。
【 在 rokingphone (鑫森淼焱? ????? ???) 的大作中提到: 】
: 我的Handle没有跨进程呢。
: 就一个。在.h里定义的
☆─────────────────────────────────────☆
rokingphone (鑫森淼焱? ????? ???) 于 (Fri Dec 1 22:40:12 2006) 提到
我怕你认为m_hOnlyOneInstance这个HANDLE跨进程了。
给出的代码也就这个HANDLE
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: 在一个.h跟是否跨进程有啥关系啊。
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Fri Dec 1 22:42:26 2006) 提到:
我的意思是g_hWnd不能跨进程。
【 在 rokingphone (鑫森淼焱? ????? ???) 的大作中提到: 】
: 我怕你认为m_hOnlyOneInstance这个HANDLE跨进程了。
: 给出的代码也就这个HANDLE
☆─────────────────────────────────────☆
rokingphone (鑫森淼焱? ????? ???) 于 (Fri Dec 1 22:46:30 2006) 提到
呵呵。后来看了。HWND也是一个HANDLE。
不过不知道应该Send什么Message
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: 我的意思是g_hWnd不能跨进程。
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Fri Dec 1 22:49:33 2006) 提到:
if (ERROR_ALREADY_EXISTS == GetLastError())
{
hPreApp = FindWindow(....);
if ( hPreApp)
{
::SendMessage( hPreApp, WM_COPYDATA, ......);
}
PostQuitMessage();
}
然后在已经启动的实例的WM_COPYDATA里边激活自己,把自己放在最前边。
【 在 rokingphone (鑫森淼焱? ????? ???) 的大作中提到: 】
: 呵呵。后来看了。HWND也是一个HANDLE。
: 不过不知道应该在哪加SendMessage
☆─────────────────────────────────────☆
hamxj (东操圆梦,电子必胜) 于 (Sat Dec 2 01:30:01 2006) 提到:
赫赫,结果还是回到FindWindow了......
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: if (ERROR_ALREADY_EXISTS == GetLastError())
: {
: hPreApp = FindWindow(....);
: ...................
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Sat Dec 2 01:31:56 2006) 提到:
你还有啥好办法?
【 在 hamxj (东操圆梦,电子必胜) 的大作中提到: 】
: 赫赫,结果还是回到FindWindow了......
☆─────────────────────────────────────☆
hamxj (东操圆梦,电子必胜) 于 (Sat Dec 2 01:33:37 2006) 提到:
没有,俺只能想到FindWindow:(
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: 你还有啥好办法?
☆─────────────────────────────────────☆
hamxj (东操圆梦,电子必胜) 于 (Sat Dec 2 01:58:27 2006) 提到:
忽然想到,这个问题的难点其实就是进程间共享数据
现在能想到的,一个是做一个内存映射文件,第二次启动时把第一次的窗口句柄读出来
然后验证句柄有效后,对句柄进行操作
另一个方法可以把当前句柄存到注册表里面,每次启动就去查那个项,再确认有效性
不过如果非正常关闭,可能会出问题,呵呵
【 在 N95 (做爱做的事 交配交的人) 的大作中提到: 】
: 你还有啥好办法?
☆─────────────────────────────────────☆
N95 (做爱做的事 交配交的人) 于 (Sat Dec 2 02:19:58 2006) 提到:
1.不可行,还是因为句柄不能跨进程使用。
2也勉强了。
【 在 hamxj (东操圆梦,电子必胜) 的大作中提到: 】
: 忽然想到,这个问题的难点其实就是进程间共享数据
: 现在能想到的,一个是做一个内存映射文件,第二次启动时把第一次的窗口句柄读出来
: 然后验证句柄有效后,对句柄进行操作
: ...................
☆─────────────────────────────────────☆
rokingphone (鑫森淼焱? ????? ???) 于 (Sun Dec 3 12:09:40 2006) 提到
可以不用FindWindow()了
因为我做了如下定义:
#pragma data_seg("share")
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:share,RWS")
只是g_hWnd数据没有传好。
现在我在OnInitDialog()把HWND传到g_hWnd,那么第二个实例就不能运行,而且
可以把第一个实例置顶。
也谢谢N95的帮助。掌握了多种方法。呵呵
【 在 hamxj (东操圆梦,电子必胜) 的大作中提到: 】
: 赫赫,结果还是回到FindWindow了......