/[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 933 - (show annotations)
Thu Jun 30 14:46:14 2005 UTC (19 years ago) by astrand
File size: 7544 byte(s)
Fixed indentation, by running indent-all.

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

  ViewVC Help
Powered by ViewVC 1.1.26