/[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 937 - (show annotations)
Fri Jul 1 06:50:52 2005 UTC (18 years, 10 months ago) by astrand
File size: 7487 byte(s)
Indenting with astyle instead of indent

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 PostQuitMessage(0);
119 break;
120 }
121 case ID_WMABOUT: {
122 AboutDlg();
123 break;
124 }
125 }
126 }
127
128 //
129 // manage the main window
130 //
131 LONG WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
132 {
133 switch (uMsg) {
134 case WM_DESTROY: {
135 PostQuitMessage(0);
136 return 0;
137 }
138 case WM_TRAY_NOTIFY: {
139 if (lParam == WM_RBUTTONDOWN)
140 DoContextMenu();
141 return 0;
142 }
143 }
144
145 return DefWindowProc(hWnd, uMsg, wParam, lParam);
146 }
147
148 //
149 //Init window
150 //
151 bool InitWindow()
152 {
153 // register the frame class
154 WNDCLASS wndclass;
155 wndclass.style = 0;
156 wndclass.lpfnWndProc = (WNDPROC) MainWndProc;
157 wndclass.cbClsExtra = 0;
158 wndclass.cbWndExtra = 0;
159 wndclass.hInstance = hAppInstance;
160 wndclass.hIcon = 0;
161 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
162 wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
163 wndclass.lpszMenuName = NULL;
164 wndclass.lpszClassName = szAppName;
165
166 if (!RegisterClass(&wndclass)) {
167 Message("Unable to register the window class.");
168 return false;
169 }
170
171 // create the frame
172 ghWnd = CreateWindow(szAppName, szAppName,
173 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
174 WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 640,
175 480, NULL, NULL, hAppInstance, NULL);
176
177 // make sure window was created
178 if (!ghWnd) {
179 Message("Unable to create the window.");
180 return false;
181 }
182
183 return true;
184 }
185
186 //
187 // init
188 //
189 bool Init(LPSTR lpCmdLine)
190 {
191 // try to load WTSWinClipper.dll
192 if (!WTSWinClipper::Init()) {
193 Message
194 ("Application not installed correctly: Unable to init hookdll.dll.");
195 return false;
196 }
197
198 // check number of instances
199 if (WTSWinClipper::GetInstanceCount() == 1) {
200 // hook in
201 WTSWinClipper::SetCbtHook();
202 return true;
203 } else {
204 // already hooked
205 return false;
206 }
207 }
208
209 //
210 // our main loop
211 //
212 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
213 LPSTR lpCmdLine, int nCmdShow)
214 {
215 hAppInstance = hInstance;
216 if (!Init(lpCmdLine)) {
217 return 0;
218 }
219
220 // if we have been specified an app to launch, we will wait until the app has closed and use that for
221 // our cue to exit
222 if (strlen(lpCmdLine) > 0) {
223 // Because we do not have a explorer.exe we need to make this application the replacement
224 // shell. We do this by calling SystemParametersInfo. If we don't do this, we won't get the WH_SHELL notifications.
225
226 // From MSDN:
227 // Note that custom shell applications do not receive WH_SHELL messages. Therefore, any application that
228 // registers itself as the default shell must call the SystemParametersInfo function with SPI_SETMINIMIZEDMETRICS
229 // before it (or any other application) can receive WH_SHELL messages.
230
231 MINIMIZEDMETRICS mmm;
232 mmm.cbSize = sizeof(MINIMIZEDMETRICS);
233 SystemParametersInfo(SPI_SETMINIMIZEDMETRICS,
234 sizeof(MINIMIZEDMETRICS), &mmm, 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 = { 0 };
243 startupInfo.cb = sizeof(STARTUPINFO);
244 char attr[] = "";
245 LPTSTR process = lpCmdLine;
246 DWORD dwExitCode;
247
248 BOOL m_create =
249 CreateProcess(NULL, process, NULL, NULL, FALSE, 0, NULL, NULL,
250 &startupInfo, &procInfo);
251
252 if (m_create != false) {
253 // A loop to watch the process.
254 GetExitCodeProcess(procInfo.hProcess, &dwExitCode);
255
256 while (dwExitCode == STILL_ACTIVE) {
257 GetExitCodeProcess(procInfo.hProcess, &dwExitCode);
258 Sleep(1000);
259 }
260
261 // Release handles
262 CloseHandle(procInfo.hProcess);
263 CloseHandle(procInfo.hThread);
264 } else {
265 // CreateProcess failed.
266 Message("Unable to launch the requested application");
267 }
268 } else
269 // we are launching without an app, therefore we will show the system tray app and wait for the user to close it
270 {
271 // create a dummy window to receive WM_QUIT message
272 InitWindow();
273
274 // create the tray icon
275 InitTrayIcon();
276
277 // just get and dispatch messages until we're killed
278 MSG msg;
279 while (GetMessage(&msg, 0, 0, 0)) {
280 TranslateMessage(&msg);
281 DispatchMessage(&msg);
282 };
283
284 // remove our tray icon
285 RemoveTrayIcon();
286 }
287
288
289 // remove hook before saying goodbye
290 WTSWinClipper::RemoveCbtHook();
291
292 WTSWinClipper::Done();
293
294 return 1;
295 }

  ViewVC Help
Powered by ViewVC 1.1.26