/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/main.c
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.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1069 - (show annotations)
Thu Mar 9 09:46:30 2006 UTC (18 years, 2 months ago) by ossman_
File MIME type: text/plain
File size: 8331 byte(s)
Use C instead of C++ since we don't depend on any C++ features anyway.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26