原文:http://www.vckbase.com/index.php/wv/94
服务程序(Service)一般是不能和用户进行交互的,所以他一般是不能显示窗口的。要和用户进行交互(如显示窗口),我们必须打开用户WinSta0和desktop,下面的这段代码就是打开上述两个,并显示一个dialog:
01.
BOOL
CServiceModule::ShowMsgDlg(
void
)
02.
{
03.
HDESK
hdeskCurrent;
04.
HDESK
hdesk;
05.
HWINSTA
hwinstaCurrent;
06.
HWINSTA
hwinsta;
07.
08.
hwinstaCurrent = GetProcessWindowStation();
09.
if
(hwinstaCurrent == NULL){
10.
LogEvent(_T(
"get window station err"
));
11.
return
FALSE;
12.
}
13.
14.
hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
15.
if
(hdeskCurrent == NULL){
16.
LogEvent(_T(
"get window desktop err"
));
17.
return
FALSE;
18.
}
19.
20.
//打开winsta0
21.
hwinsta = OpenWindowStation(
"winsta0"
, FALSE,
22.
WINSTA_ACCESSCLIPBOARD |
23.
WINSTA_ACCESSGLOBALATOMS |
24.
WINSTA_CREATEDESKTOP |
25.
WINSTA_ENUMDESKTOPS |
26.
WINSTA_ENUMERATE |
27.
WINSTA_EXITWINDOWS |
28.
WINSTA_READATTRIBUTES |
29.
WINSTA_READSCREEN |
30.
WINSTA_WRITEATTRIBUTES);
31.
if
(hwinsta == NULL){
32.
LogEvent(_T(
"open window station err"
));
33.
34.
return
FALSE;
35.
}
36.
37.
if
(!SetProcessWindowStation(hwinsta)){
38.
LogEvent(_T(
"Set window station err"
));
39.
40.
return
FALSE;
41.
}
42.
43.
//打开desktop
44.
hdesk = OpenDesktop(
"default"
, 0, FALSE,
45.
DESKTOP_CREATEMENU |
46.
DESKTOP_CREATEWINDOW |
47.
DESKTOP_ENUMERATE |
48.
DESKTOP_HOOKCONTROL |
49.
DESKTOP_JOURNALPLAYBACK |
50.
DESKTOP_JOURNALRECORD |
51.
DESKTOP_READOBJECTS |
52.
DESKTOP_SWITCHDESKTOP |
53.
DESKTOP_WRITEOBJECTS);
54.
if
(hdesk == NULL){
55.
LogEvent(_T(
"Open desktop err"
));
56.
57.
return
FALSE;
58.
}
59.
60.
SetThreadDesktop(hdesk);
61.
62.
//到这一步,我们获取了和用户交互(如显示窗口)的权利
63.
CMsgDlg dlgMsg;
64.
//显示一个dialog
65.
dlgMsg.DoModal();
66.
67.
if
(!SetProcessWindowStation(hwinstaCurrent))
68.
return
FALSE;
69.
70.
if
(!SetThreadDesktop(hdeskCurrent))
71.
return
FALSE;
72.
73.
if
(!CloseWindowStation(hwinsta))
74.
return
FALSE;
75.
76.
if
(!CloseDesktop(hdesk))
77.
return
FALSE;
78.
79.
return
TRUE;
80.
}