Author: Claudio Hira
How can I receive the WM_WTSSESSION_CHANGE message when a session switch occurs ?
Answer:
Typically, an application does not need to be notified when a session switch
occurs. However, if the application needs to be aware when its desktop is current,
it can register for session switch notifications. Applications that access the
serial port or another shared resource on the computer should check for this. To
register for a notification, use the following function:
1 function WTSRegisterSessionNotification(
2 hWnd: HWND; // Window handle
3 dwFlags: DWORD // Flags
4 ): Bool; // Return value
The registered HWND receives the message WM_WTSSESSION_CHANGE through its
WindowProc function.
In dwFlags you can specify:
NOTIFY_FOR_THIS_SESSION. A window is notified only about the session change events
that affect the session to which window belongs.
NOTIFY_FOR_ALL_SESSIONS. A window is notified for all session change events.
The action happening on the session can be found in wParam code, which may contain
one of the following flags.
WTS_CONSOLE_CONNECT: A session was connected to the console session.
WTS_CONSOLE_DISCONNECT: A session was disconnected from the console session.
WTS_REMOTE_CONNECT: A session was connected to the remote session.
WTS_REMOTE_DISCONNECT: A session was disconnected from the remote session.
WTS_SESSION_LOGON: A user has logged on to the session.
WTS_SESSION_LOGOFF: A user has logged off the session.
WTS_SESSION_LOCK: A session has been locked.
WTS_SESSION_UNLOCK: A session has been unlocked.
WTS_SESSION_REMOTE_CONTROL: A session has changed its remote controlled status.
lParam contains the sessionId for the session affected.
When your process no longer requires these notifications or is terminating, it
should call the following to unregister its notification.
5
6 function WTSUnRegisterSesssionNotification(
7 hWnd: HWND // window handle.
8 ): Boolean; // Result
The HWND values passed to WTSRegisterSessionNotification are reference counted, so
you must call WTSUnRegisterSessionNotification exactly the same number of times
that you call WTSRegisterSessionNotification.
Applications can use the WTS_CONSOLE_CONNECT, WTS_CONSOLE_DISCONNECT,
WTS_REMOTE_CONNECT, WTS_REMOTE_DISCONNECT messages to track their state, as well as
to release and acquire console specific resources.
9
10 {********************************************************************
11 Unit Wtsapi
12 ********************************************************************}
13
14 unit Wtsapi;
15
16 interface
17
18 uses
19 Windows;
20
21 const
22 // The WM_WTSSESSION_CHANGE message notifies applications of changes in session
23 state.
24 WM_WTSSESSION_CHANGE = $2B1;
25
26 // wParam values:
27 WTS_CONSOLE_CONNECT = 1;
28 WTS_CONSOLE_DISCONNECT = 2;
29 WTS_REMOTE_CONNECT = 3;
30 WTS_REMOTE_DISCONNECT = 4;
31 WTS_SESSION_LOGON = 5;
32 WTS_SESSION_LOGOFF = 6;
33 WTS_SESSION_LOCK = 7;
34 WTS_SESSION_UNLOCK = 8;
35 WTS_SESSION_REMOTE_CONTROL = 9;
36
37 // Only session notifications involving the session attached to by the window
38 // identified by the hWnd parameter value are to be received.
39 NOTIFY_FOR_THIS_SESSION = 0;
40 // All session notifications are to be received.
41 NOTIFY_FOR_ALL_SESSIONS = 1;
42
43 function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
44 function UnRegisterSessionNotification(Wnd: HWND): Boolean;
45 function GetCurrentSessionID: Integer;
46
47 implementation
48
49 function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
50 // The RegisterSessionNotification function registers the specified window
51 // to receive session change notifications.
52 // Parameters:
53 // hWnd: Handle of the window to receive session change notifications.
54 // dwFlags: Specifies which session notifications are to be received:
55 // (NOTIFY_FOR_THIS_SESSION, NOTIFY_FOR_ALL_SESSIONS)
56 type
57 TWTSRegisterSessionNotification = function(Wnd: HWND; dwFlags: DWORD): BOOL;
58 stdcall;
59 var
60 hWTSapi32dll: THandle;
61 WTSRegisterSessionNotification: TWTSRegisterSessionNotification;
62 begin
63 Result := False;
64 hWTSAPI32DLL := LoadLibrary('Wtsapi32.dll');
65 if (hWTSAPI32DLL > 0) then
66 begin
67 try
68 @WTSRegisterSessionNotification :=
69 GetProcAddress(hWTSAPI32DLL, 'WTSRegisterSessionNotification');
70 if Assigned(WTSRegisterSessionNotification) then
71 begin
72 Result := WTSRegisterSessionNotification(Wnd, dwFlags);
73 end;
74 finally
75 if hWTSAPI32DLL > 0 then
76 FreeLibrary(hWTSAPI32DLL);
77 end;
78 end;
79 end;
80
81 function UnRegisterSessionNotification(Wnd: HWND): Boolean;
82 // The RegisterSessionNotification function unregisters the specified window
83 // Parameters:
84 // hWnd: Handle to the window
85 type
86 TWTSUnRegisterSessionNotification = function(Wnd: HWND): BOOL; stdcall;
87 var
88 hWTSapi32dll: THandle;
89 WTSUnRegisterSessionNotification: TWTSUnRegisterSessionNotification;
90 begin
91 Result := False;
92 hWTSAPI32DLL := LoadLibrary('Wtsapi32.dll');
93 if (hWTSAPI32DLL > 0) then
94 begin
95 try
96 @WTSUnRegisterSessionNotification :=
97 GetProcAddress(hWTSAPI32DLL, 'WTSUnRegisterSessionNotification');
98 if Assigned(WTSUnRegisterSessionNotification) then
99 begin
100 Result := WTSUnRegisterSessionNotification(Wnd);
101 end;
102 finally
103 if hWTSAPI32DLL > 0 then
104 FreeLibrary(hWTSAPI32DLL);
105 end;
106 end;
107 end;
108
109 function GetCurrentSessionID: Integer;
110 // Getting the session id from the current process
111 type
112 TProcessIdToSessionId = function(dwProcessId: DWORD; pSessionId: DWORD): BOOL;
113 stdcall;
114 var
115 ProcessIdToSessionId: TProcessIdToSessionId;
116 hWTSapi32dll: THandle;
117 Lib: THandle;
118 pSessionId: DWord;
119 begin
120 Result := -1;
121 Lib := GetModuleHandle('kernel32');
122 if Lib <> 0 then
123 begin
124 ProcessIdToSessionId := GetProcAddress(Lib, '1ProcessIdToSessionId');
125 if Assigned(ProcessIdToSessionId) then
126 begin
127 ProcessIdToSessionId(GetCurrentProcessId(), DWORD(@pSessionId));
128 Result := pSessionId;
129 end;
130 end;
131 end;
132
133 end.
134
135 {********************************************************************
136 Example:
137 ********************************************************************}
138
139 unit Unit1;
140
141 interface
142
143 uses
144 Windows, Messages, {...}, Wtsapi;
145
146 type
147 TForm1 = class(TForm)
148 procedure FormCreate(Sender: TObject);
149 procedure FormDestroy(Sender: TObject);
150 private
151 { Private declarations }
152 FRegisteredSessionNotification: Boolean;
153 procedure AppMessage(var Msg: TMSG; var HAndled: Boolean);
154 end;
155
156 var
157 Form1: TForm1;
158
159 implementation
160
161 {$R *.DFM}
162
163 procedure TForm1.AppMessage(var Msg: TMSG; var Handled: Boolean);
164 var
165 strReason: string;
166 begin
167 Handled := False;
168 // Check for WM_WTSSESSION_CHANGE message
169 if Msg.message = WM_WTSSESSION_CHANGE then
170 begin
171 case Msg.wParam of
172 WTS_CONSOLE_CONNECT:
173 strReason := 'WTS_CONSOLE_CONNECT';
174 WTS_CONSOLE_DISCONNECT:
175 strReason := 'WTS_CONSOLE_DISCONNECT';
176 WTS_REMOTE_CONNECT:
177 strReason := 'WTS_REMOTE_CONNECT';
178 WTS_REMOTE_DISCONNECT:
179 strReason := 'WTS_REMOTE_DISCONNECT';
180 WTS_SESSION_LOGON:
181 strReason := 'WTS_SESSION_LOGON';
182 WTS_SESSION_LOGOFF:
183 strReason := 'WTS_SESSION_LOGOFF';
184 WTS_SESSION_LOCK:
185 strReason := 'WTS_SESSION_LOCK';
186 WTS_SESSION_UNLOCK:
187 strReason := 'WTS_SESSION_UNLOCK';
188 WTS_SESSION_REMOTE_CONTROL:
189 begin
190 strReason := 'WTS_SESSION_REMOTE_CONTROL';
191 // GetSystemMetrics(SM_REMOTECONTROL);
192 end;
193 else
194 strReason := 'WTS_Unknown';
195 end;
196 // Write strReason to a Memo
197 Memo1.Lines.Add(strReason + ' ' + IntToStr(msg.Lparam));
198 end;
199 end;
200
201 procedure TForm1.FormCreate(Sender: TObject);
202 begin
203 // register the window to receive session change notifications.
204 FRegisteredSessionNotification := RegisterSessionNotification(Handle,
205 NOTIFY_FOR_THIS_SESSION);
206 Application.OnMessage := AppMessage;
207 end;
208
209 procedure TForm1.FormDestroy(Sender: TObject);
210 begin
211 // unregister session change notifications.
212 if FRegisteredSessionNotification then
213 UnRegisterSessionNotification(Handle);
214 end;
215
216 procedure TForm1.Button1Click(Sender: TObject);
217 begin
218 // retrieve current session ID
219 ShowMessage(Inttostr(GetCurrentSessionID));
220 end;
|