VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp@ 55628

Last change on this file since 55628 was 55401, checked in by vboxsync, 10 years ago

added a couple of missing Id headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1/* $Id: VBoxHelpers.cpp 55401 2015-04-23 10:03:17Z vboxsync $ */
2/** @file
3 * helpers - Guest Additions Service helper functions
4 */
5
6/*
7 * Copyright (C) 2006-2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <malloc.h>
19#include <windows.h>
20
21#include <iprt/string.h>
22#include <VBox/Log.h>
23#include <VBox/VBoxGuestLib.h>
24
25#include <VBoxGuestInternal.h>
26
27#include "VBoxHelpers.h"
28#include "resource.h"
29
30
31int hlpReportStatus(VBoxGuestFacilityStatus statusCurrent)
32{
33 int rc = VbglR3ReportAdditionsStatus(VBoxGuestFacilityType_VBoxTrayClient,
34 statusCurrent,
35 0 /* Flags */);
36 if (RT_FAILURE(rc))
37 Log(("VBoxTray: Could not report VBoxTray status \"%ld\", rc=%Rrc\n", statusCurrent, rc));
38 return rc;
39}
40
41/**
42 * Attempt to force Windows to reload the cursor image by attaching to the
43 * thread of the window currently under the mouse, hiding the cursor and
44 * showing it again. This could fail to work in any number of ways (no
45 * window under the cursor, the cursor has moved to a different window while
46 * we are processing), but we just accept this, as the cursor will be reloaded
47 * at some point anyway.
48 */
49void hlpReloadCursor(void)
50{
51 POINT mousePos;
52 HWND hWin;
53 DWORD hThread, hCurrentThread;
54
55 GetCursorPos(&mousePos);
56 hWin = WindowFromPoint(mousePos);
57 if (hWin)
58 {
59 hThread = GetWindowThreadProcessId(hWin, NULL);
60 hCurrentThread = GetCurrentThreadId();
61 if (hCurrentThread != hThread)
62 AttachThreadInput(hCurrentThread, hThread, TRUE);
63 }
64 ShowCursor(false);
65 ShowCursor(true);
66 if (hWin && (hCurrentThread != hThread))
67 AttachThreadInput(hCurrentThread, hThread, FALSE);
68}
69
70static unsigned hlpNextAdjacentRectXP(RECTL *paRects, unsigned nRects, unsigned uRect)
71{
72 unsigned i;
73 for (i = 0; i < nRects; i++)
74 {
75 if (paRects[uRect].right == paRects[i].left)
76 return i;
77 }
78 return ~0;
79}
80
81static unsigned hlpNextAdjacentRectXN(RECTL *paRects, unsigned nRects, unsigned uRect)
82{
83 unsigned i;
84 for (i = 0; i < nRects; i++)
85 {
86 if (paRects[uRect].left == paRects[i].right)
87 return i;
88 }
89 return ~0;
90}
91
92static unsigned hlpNextAdjacentRectYP(RECTL *paRects, unsigned nRects, unsigned uRect)
93{
94 unsigned i;
95 for (i = 0; i < nRects; i++)
96 {
97 if (paRects[uRect].bottom == paRects[i].top)
98 return i;
99 }
100 return ~0;
101}
102
103static unsigned hlpNextAdjacentRectYN(RECTL *paRects, unsigned nRects, unsigned uRect)
104{
105 unsigned i;
106 for (i = 0; i < nRects; i++)
107 {
108 if (paRects[uRect].top == paRects[i].bottom)
109 return i;
110 }
111 return ~0;
112}
113
114void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary,
115 unsigned uResized, int iNewWidth, int iNewHeight,
116 int iNewPosX, int iNewPosY)
117{
118 DDCLOG(("nRects %d, iPrimary %d, iResized %d, NewWidth %d, NewHeight %d\n", nRects, uPrimary, uResized, iNewWidth, iNewHeight));
119
120 RECTL *paNewRects = (RECTL *)alloca (sizeof (RECTL) * nRects);
121 memcpy (paNewRects, paRects, sizeof (RECTL) * nRects);
122 paNewRects[uResized].right += iNewWidth - (paNewRects[uResized].right - paNewRects[uResized].left);
123 paNewRects[uResized].bottom += iNewHeight - (paNewRects[uResized].bottom - paNewRects[uResized].top);
124 paNewRects[uResized].right += iNewPosX - paNewRects[uResized].left;
125 paNewRects[uResized].bottom += iNewPosY - paNewRects[uResized].top;
126 paNewRects[uResized].left = iNewPosX;
127 paNewRects[uResized].top = iNewPosY;
128
129 /* Verify all pairs of originally adjacent rectangles for all 4 directions.
130 * If the pair has a "good" delta (that is the first rectangle intersects the second)
131 * at a direction and the second rectangle is not primary one (which can not be moved),
132 * move the second rectangle to make it adjacent to the first one.
133 */
134
135 /* X positive. */
136 unsigned iRect;
137 for (iRect = 0; iRect < nRects; iRect++)
138 {
139 /* Find the next adjacent original rect in x positive direction. */
140 unsigned iNextRect = hlpNextAdjacentRectXP(paRects, nRects, iRect);
141 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
142
143 if (iNextRect == ~0 || iNextRect == uPrimary)
144 {
145 continue;
146 }
147
148 /* Check whether there is an X intersection between these adjacent rects in the new rectangles
149 * and fix the intersection if delta is "good".
150 */
151 int delta = paNewRects[iRect].right - paNewRects[iNextRect].left;
152
153 if (delta != 0)
154 {
155 DDCLOG(("XP intersection right %d left %d, diff %d\n",
156 paNewRects[iRect].right, paNewRects[iNextRect].left,
157 delta));
158
159 paNewRects[iNextRect].left += delta;
160 paNewRects[iNextRect].right += delta;
161 }
162 }
163
164 /* X negative. */
165 for (iRect = 0; iRect < nRects; iRect++)
166 {
167 /* Find the next adjacent original rect in x negative direction. */
168 unsigned iNextRect = hlpNextAdjacentRectXN(paRects, nRects, iRect);
169 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
170
171 if (iNextRect == ~0 || iNextRect == uPrimary)
172 {
173 continue;
174 }
175
176 /* Check whether there is an X intersection between these adjacent rects in the new rectangles
177 * and fix the intersection if delta is "good".
178 */
179 int delta = paNewRects[iRect].left - paNewRects[iNextRect].right;
180
181 if (delta != 0)
182 {
183 DDCLOG(("XN intersection left %d right %d, diff %d\n",
184 paNewRects[iRect].left, paNewRects[iNextRect].right,
185 delta));
186
187 paNewRects[iNextRect].left += delta;
188 paNewRects[iNextRect].right += delta;
189 }
190 }
191
192 /* Y positive (in the computer sense, top->down). */
193 for (iRect = 0; iRect < nRects; iRect++)
194 {
195 /* Find the next adjacent original rect in y positive direction. */
196 unsigned iNextRect = hlpNextAdjacentRectYP(paRects, nRects, iRect);
197 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
198
199 if (iNextRect == ~0 || iNextRect == uPrimary)
200 {
201 continue;
202 }
203
204 /* Check whether there is an Y intersection between these adjacent rects in the new rectangles
205 * and fix the intersection if delta is "good".
206 */
207 int delta = paNewRects[iRect].bottom - paNewRects[iNextRect].top;
208
209 if (delta != 0)
210 {
211 DDCLOG(("YP intersection bottom %d top %d, diff %d\n",
212 paNewRects[iRect].bottom, paNewRects[iNextRect].top,
213 delta));
214
215 paNewRects[iNextRect].top += delta;
216 paNewRects[iNextRect].bottom += delta;
217 }
218 }
219
220 /* Y negative (in the computer sense, down->top). */
221 for (iRect = 0; iRect < nRects; iRect++)
222 {
223 /* Find the next adjacent original rect in x negative direction. */
224 unsigned iNextRect = hlpNextAdjacentRectYN(paRects, nRects, iRect);
225 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
226
227 if (iNextRect == ~0 || iNextRect == uPrimary)
228 {
229 continue;
230 }
231
232 /* Check whether there is an Y intersection between these adjacent rects in the new rectangles
233 * and fix the intersection if delta is "good".
234 */
235 int delta = paNewRects[iRect].top - paNewRects[iNextRect].bottom;
236
237 if (delta != 0)
238 {
239 DDCLOG(("YN intersection top %d bottom %d, diff %d\n",
240 paNewRects[iRect].top, paNewRects[iNextRect].bottom,
241 delta));
242
243 paNewRects[iNextRect].top += delta;
244 paNewRects[iNextRect].bottom += delta;
245 }
246 }
247
248 memcpy (paRects, paNewRects, sizeof (RECTL) * nRects);
249 return;
250}
251
252int hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID,
253 const char *pszMsg, const char *pszTitle,
254 UINT uTimeout, DWORD dwInfoFlags)
255{
256 NOTIFYICONDATA niData;
257 ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
258 niData.cbSize = sizeof(NOTIFYICONDATA);
259 niData.uFlags = NIF_INFO; /* Display a balloon notification. */
260 niData.hWnd = hWnd;
261 niData.uID = uID;
262 /* If not timeout set, set it to 5sec. */
263 if (uTimeout == 0)
264 uTimeout = 5000;
265 niData.uTimeout = uTimeout;
266 /* If no info flag (info, warning, error) set,
267 * set it to info by default. */
268 if (dwInfoFlags == 0)
269 dwInfoFlags = NIIF_INFO;
270 niData.dwInfoFlags = dwInfoFlags;
271
272 /* Do we want to have */
273
274 /* Get running OS version. */
275 OSVERSIONINFO osInfo;
276 osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
277 if (FALSE == GetVersionEx(&osInfo))
278 return RTErrConvertFromWin32(GetLastError());
279
280 /* Is the current OS supported (at least WinXP) for displaying
281 * our own icon and do we actually *want* to display our own stuff? */
282 if ( osInfo.dwMajorVersion >= 5
283 && (dwInfoFlags & NIIF_INFO))
284 {
285 /* Load (or retrieve handle of) the app's icon. */
286 HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_VIRTUALBOX));
287 if (hIcon)
288 niData.dwInfoFlags = NIIF_USER; /* Use an own notification icon. */
289
290 if ( osInfo.dwMajorVersion == 5
291 && osInfo.dwMinorVersion == 1) /* WinXP. */
292 {
293 /* Use an own icon instead of the default one. */
294 niData.hIcon = hIcon;
295 }
296 else if (osInfo.dwMajorVersion == 6) /* Vista and up. */
297 {
298 /* Use an own icon instead of the default one. */
299 niData.dwInfoFlags |= NIIF_LARGE_ICON; /* Use a large icon if available! */
300 niData.hIcon = hIcon;
301 niData.hBalloonIcon = hIcon;
302 }
303 }
304 else
305 {
306 /* This might be a warning, error message or a to old OS. Use the
307 * standard icons provided by Windows (if any). */
308 }
309
310 strcpy(niData.szInfo, pszMsg ? pszMsg : "-");
311 strcpy(niData.szInfoTitle, pszTitle ? pszTitle : "Information");
312
313 if (!Shell_NotifyIcon(NIM_MODIFY, &niData))
314 {
315 DWORD dwErr = GetLastError();
316 return RTErrConvertFromWin32(dwErr);
317 }
318 return VINF_SUCCESS;
319}
320
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette