/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/main.cpp
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/seamlessrdp/ServerExe/main.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1065 - (show annotations)
Wed Mar 8 16:12:49 2006 UTC (18 years, 2 months ago) by ossman_
File size: 7767 byte(s)
Run indent-all on the server source.

1 //
2 // Copyright (C) 2004-2005 Martin Wickett
3 //
4
5 #include <windows.h>
6 #include <stdio.h>
7
8 #include "resource.h"
9 #include "HookDll/hook.h"
10
11 #define snprintf _snprintf
12
13 //
14 // some global data
15 //
16 HWND ghWnd;
17 NOTIFYICONDATA nid;
18 HINSTANCE hAppInstance;
19
20 static const UINT WM_TRAY_NOTIFY = ( WM_APP + 1000 );
21 static const char szAppName[] = "SeamlessRDP Shell";
22
23 //
24 // spawn a message box
25 //
26 void Message( const char *message )
27 {
28 MessageBox( GetDesktopWindow(), message, "SeamlessRDP Shell", MB_OK );
29 }
30
31 //
32 // manage the tray icon
33 //
34 bool InitTrayIcon()
35 {
36 nid.cbSize = sizeof( NOTIFYICONDATA );
37 nid.hWnd = ghWnd;
38 nid.uID = 0;
39 nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
40 nid.uCallbackMessage = WM_TRAY_NOTIFY;
41 strcpy( nid.szTip, szAppName );
42 nid.hIcon = ::LoadIcon( hAppInstance, MAKEINTRESOURCE( IDI_TRAY ) );
43
44 if ( Shell_NotifyIcon( NIM_ADD, &nid ) != TRUE ) {
45 Message( "Unable to create tray icon." );
46 return false;
47 }
48
49 return true;
50 }
51
52 //
53 // Remove tray icon
54 //
55 bool RemoveTrayIcon()
56 {
57 if ( Shell_NotifyIcon( NIM_DELETE, &nid ) != TRUE ) {
58 Message( "Unable to remove tray icon." );
59 return false;
60 }
61
62 return true;
63
64 }
65
66 //
67 // manage the about dialog box
68 //
69 BOOL CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam,
70 LPARAM lParam )
71 {
72 if ( uMsg == WM_COMMAND ) {
73 WORD wID = LOWORD( wParam );
74 if ( wID == IDOK )
75 DestroyWindow( hwndDlg );
76 }
77
78 return 0;
79 }
80
81 void AboutDlg()
82 {
83 DialogBox( hAppInstance, MAKEINTRESOURCE( IDD_ABOUT ), NULL, DialogProc );
84 }
85
86 //
87 // manage the context menu
88 //
89 void DoContextMenu()
90 {
91 HMENU hMenu = LoadMenu( hAppInstance, MAKEINTRESOURCE( IDR_TRAY ) );
92 if ( hMenu == NULL ) {
93 Message( "Unable to load menu ressource." );
94 return ;
95 }
96
97 HMENU hSubMenu = GetSubMenu( hMenu, 0 );
98 if ( hSubMenu == NULL ) {
99 Message( "Unable to find popup mennu." );
100 return ;
101 }
102
103 // get the cursor position
104 POINT pt;
105 GetCursorPos( &pt );
106
107 SetForegroundWindow( ghWnd );
108 int cmd = TrackPopupMenu( hSubMenu,
109 TPM_RETURNCMD | TPM_LEFTALIGN | TPM_RIGHTBUTTON,
110 pt.x, pt.y, 0, ghWnd, NULL );
111 DeleteObject( hMenu );
112
113 switch ( cmd ) {
114 case ID_WMEXIT: {
115 PostQuitMessage( 0 );
116 break;
117 }
118 case ID_WMABOUT: {
119 AboutDlg();
120 break;
121 }
122 }
123 }
124
125 //
126 // manage the main window
127 //
128 LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
129 {
130 switch ( uMsg ) {
131 case WM_DESTROY: {
132 PostQuitMessage( 0 );
133 return 0;
134 }
135 case WM_TRAY_NOTIFY: {
136 if ( lParam == WM_RBUTTONDOWN )
137 DoContextMenu();
138 return 0;
139 }
140 }
141
142 return DefWindowProc( hWnd, uMsg, wParam, lParam );
143 }
144
145 //
146 //Init window
147 //
148 bool InitWindow()
149 {
150 // register the frame class
151 WNDCLASS wndclass;
152 wndclass.style = 0;
153 wndclass.lpfnWndProc = ( WNDPROC ) MainWndProc;
154 wndclass.cbClsExtra = 0;
155 wndclass.cbWndExtra = 0;
156 wndclass.hInstance = hAppInstance;
157 wndclass.hIcon = 0;
158 wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
159 wndclass.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 );
160 wndclass.lpszMenuName = NULL;
161 wndclass.lpszClassName = szAppName;
162
163 if ( !RegisterClass( &wndclass ) ) {
164 Message( "Unable to register the window class." );
165 return false;
166 }
167
168 // create the frame
169 ghWnd = CreateWindow( szAppName, szAppName,
170 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
171 WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 640,
172 480, NULL, NULL, hAppInstance, NULL );
173
174 // make sure window was created
175 if ( !ghWnd ) {
176 Message( "Unable to create the window." );
177 return false;
178 }
179
180 return true;
181 }
182
183 //
184 // init
185 //
186 bool Init( LPSTR lpCmdLine )
187 {
188 // try to load WTSWinClipper.dll
189 if ( !WTSWinClipper::Init() ) {
190 Message
191 ( "Application not installed correctly: Unable to init hookdll.dll." );
192 return false;
193 }
194
195 // check number of instances
196 if ( WTSWinClipper::GetInstanceCount() == 1 ) {
197 // hook in
198 WTSWinClipper::SetHooks();
199 return true;
200 } else {
201 // already hooked
202 return false;
203 }
204 }
205
206 //
207 // our main loop
208 //
209 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
210 LPSTR lpCmdLine, int nCmdShow )
211 {
212 hAppInstance = hInstance;
213 if ( !Init( lpCmdLine ) ) {
214 return 0;
215 }
216
217 // if we have been specified an app to launch, we will wait until the app has closed and use that for
218 // our cue to exit
219 if ( strlen( lpCmdLine ) > 0 ) {
220 // Because we do not have a explorer.exe we need to make this application the replacement
221 // shell. We do this by calling SystemParametersInfo. If we don't do this, we won't get the WH_SHELL notifications.
222
223 // From MSDN:
224 // Note that custom shell applications do not receive WH_SHELL messages. Therefore, any application that
225 // registers itself as the default shell must call the SystemParametersInfo function with SPI_SETMINIMIZEDMETRICS
226 // before it (or any other application) can receive WH_SHELL messages.
227
228 MINIMIZEDMETRICS mmm;
229 mmm.cbSize = sizeof( MINIMIZEDMETRICS );
230 SystemParametersInfo( SPI_SETMINIMIZEDMETRICS,
231 sizeof( MINIMIZEDMETRICS ), &mmm, 0 );
232
233 // We require DragFullWindows
234 SystemParametersInfo( SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0 );
235
236 //set the current directory to that of the requested app .exe location
237 //tokenise lpCmdLine. first is the exe path. second (if exists) is the current directory to set.
238 //SetCurrentDirectory ();
239
240 //start process specified from command line arg.
241 PROCESS_INFORMATION procInfo;
242 STARTUPINFO startupInfo = {
243 0
244 };
245 startupInfo.cb = sizeof( STARTUPINFO );
246 char attr[] = "";
247 LPTSTR process = lpCmdLine;
248 DWORD dwExitCode;
249
250 BOOL m_create =
251 CreateProcess( NULL, process, NULL, NULL, FALSE, 0, NULL, NULL,
252 &startupInfo, &procInfo );
253
254 if ( m_create != false ) {
255 // A loop to watch the process.
256 GetExitCodeProcess( procInfo.hProcess, &dwExitCode );
257
258 while ( dwExitCode == STILL_ACTIVE ) {
259 GetExitCodeProcess( procInfo.hProcess, &dwExitCode );
260 Sleep( 1000 );
261 }
262
263 // Release handles
264 CloseHandle( procInfo.hProcess );
265 CloseHandle( procInfo.hThread );
266 } else {
267 // CreateProcess failed.
268 char msg[ 256 ];
269 snprintf( msg, sizeof( msg ), "Unable to launch the requested application:\n%s", process );
270 Message( msg );
271 }
272 } else
273 // we are launching without an app, therefore we will show the system tray app and wait for the user to close it
274 {
275 // create a dummy window to receive WM_QUIT message
276 InitWindow();
277
278 // create the tray icon
279 InitTrayIcon();
280
281 // just get and dispatch messages until we're killed
282 MSG msg;
283 while ( GetMessage( &msg, 0, 0, 0 ) ) {
284 TranslateMessage( &msg );
285 DispatchMessage( &msg );
286 };
287
288 // remove our tray icon
289 RemoveTrayIcon();
290 }
291
292
293 // remove hook before saying goodbye
294 WTSWinClipper::RemoveHooks();
295
296 WTSWinClipper::Done();
297
298 return 1;
299 }

  ViewVC Help
Powered by ViewVC 1.1.26