原文: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.
}