VirtualBox

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

Last change on this file since 60784 was 58307, checked in by vboxsync, 9 years ago

Additions/WINNT/VBoxGuestInternal.h: Removed empty misnamed file. VBoxGuestInternal.h is the internal header for Additions/common/VBoxGuest, not for the WINNT additions. Very confusing and pointless.

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