VirtualBox

Changeset 3881 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Jul 26, 2007 3:27:15 PM (18 years ago)
Author:
vboxsync
Message:

Check top-level windows in VBoxService itself and not in the event handler of each process.

Location:
trunk/src/VBox/Additions/WINNT
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp

    r3879 r3881  
    1818 *
    1919 */
    20 #define _WIN32_WINNT 0x0500
    2120#include <windows.h>
    2221#include <VBoxHook.h>
    23 #include <VBoxDisplay.h>
    2422#include <stdio.h>
    2523
    26 static HWINEVENTHOOK    hEventHook[2] = {0};
    27 
    28 static void VBoxRecheckVisibleWindows();
     24#pragma data_seg("SHARED")
     25static HWINEVENTHOOK    hEventHook[2]    = {0};
     26static HWND             hwndNotification = 0;
     27#pragma data_seg()
     28#pragma comment(linker, "/section:SHARED,RWS")
    2929
    3030#ifdef DEBUG
     
    3434#define dprintf(a) do {} while (0)
    3535#endif /* DEBUG */
    36 
    37 typedef struct
    38 {
    39     HDC     hdc;
    40     HRGN    hrgn;
    41     RECT    rect;
    42 } VBOX_ENUM_PARAM, *PVBOX_ENUM_PARAM;
    4336
    4437
     
    8679        }
    8780#endif
    88         VBoxRecheckVisibleWindows();
     81        PostMessage(hwndNotification, WM_VBOX_SEAMLESS_UPDATE, 0, 0);
    8982        break;
    9083    }
     
    9285
    9386
    94 BOOL CALLBACK VBoxEnumFunc(HWND hwnd, LPARAM lParam)
    95 {
    96     PVBOX_ENUM_PARAM    lpParam = (PVBOX_ENUM_PARAM)lParam;
    97     DWORD               dwStyle, dwExStyle;
    98     RECT                rectWindow, rectVisible;
    99 
    100     dwStyle   = GetWindowLong(hwnd, GWL_STYLE);
    101     dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
    102     if (   !(dwStyle & WS_VISIBLE)
    103         ||  (dwStyle & WS_CHILD))
    104         return TRUE;
    105 
    106     dprintf(("VBoxEnumFunc %x\n", hwnd));
    107     /* Only visible windows that are present on the desktop are interesting here */
    108     if (    GetWindowRect(hwnd, &rectWindow)
    109         &&  IntersectRect(&rectVisible, &lpParam->rect, &rectWindow))
    110     {
    111         char szWindowText[256];
    112         szWindowText[0] = 0;
    113         GetWindowText(hwnd, szWindowText, sizeof(szWindowText));
    114 
    115         /* Filter out Windows XP shadow windows */
    116         /** @todo still shows inside the guest */
    117         if (   szWindowText[0] == 0
    118             && dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS)
    119             && dwExStyle == (WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_TRANSPARENT|WS_EX_TOPMOST))
    120         {
    121             dprintf(("Filter out shadow window style=%x exstyle=%x\n", dwStyle, dwExStyle));
    122             return TRUE;
    123         }
    124 
    125         /** @todo will this suffice? The Program Manager window covers the whole screen */
    126         if (strcmp(szWindowText, "Program Manager"))
    127         {
    128             dprintf(("Enum hwnd=%x rect (%d,%d) (%d,%d)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
    129             dprintf(("title=%s style=%x\n", szWindowText, dwStyle));
    130 
    131             HRGN hrgn = CreateRectRgn(0,0,0,0);
    132 
    133             int ret = GetWindowRgn(hwnd, hrgn);
    134 
    135             if (ret == ERROR)
    136             {
    137                 dprintf(("GetWindowRgn failed with rc=%d\n", GetLastError()));
    138                 SetRectRgn(hrgn, rectVisible.left, rectVisible.top, rectVisible.right, rectVisible.bottom);
    139             }
    140             else
    141             {
    142                 /* this region is relative to the window origin instead of the desktop origin */
    143                 OffsetRgn(hrgn, rectWindow.left, rectWindow.top);
    144             }
    145             if (lpParam->hrgn)
    146             {
    147                 /* create a union of the current visible region and the visible rectangle of this window. */
    148                 CombineRgn(lpParam->hrgn, lpParam->hrgn, hrgn, RGN_OR);
    149                 DeleteObject(hrgn);
    150             }
    151             else
    152                 lpParam->hrgn = hrgn;
    153         }
    154         else
    155         {
    156             dprintf(("Enum hwnd=%x rect (%d,%d) (%d,%d) (ignored)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
    157             dprintf(("title=%s style=%x\n", szWindowText, dwStyle));
    158         }
    159     }
    160     return TRUE; /* continue enumeration */
    161 }
    162 
    163 void VBoxRecheckVisibleWindows()
    164 {
    165     VBOX_ENUM_PARAM param;
    166 
    167     param.hdc       = GetDC(HWND_DESKTOP);
    168     param.hrgn      = 0;
    169 
    170     GetWindowRect(GetDesktopWindow(), &param.rect);
    171     dprintf(("VBoxRecheckVisibleWindows desktop=%x rect (%d,%d) (%d,%d)\n", GetDesktopWindow(), param.rect.left, param.rect.top, param.rect.right, param.rect.bottom));
    172     EnumWindows(VBoxEnumFunc, (LPARAM)&param);
    173 
    174     if (param.hrgn)
    175     {
    176         DWORD cbSize;
    177 
    178         cbSize = GetRegionData(param.hrgn, 0, NULL);
    179         if (cbSize)
    180         {
    181             LPRGNDATA lpRgnData = (LPRGNDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize);
    182 
    183             if (lpRgnData)
    184             {
    185                 cbSize = GetRegionData(param.hrgn, cbSize, lpRgnData);
    186                 if (cbSize)
    187                 {
    188 #ifdef DEBUG
    189                     RECT *lpRect = (RECT *)&lpRgnData->Buffer[0];
    190                     dprintf(("New visible region: \n"));
    191 
    192                     for (DWORD i=0;i<lpRgnData->rdh.nCount;i++)
    193                     {
    194                         dprintf(("visible rect (%d,%d)(%d,%d)\n", lpRect[i].left, lpRect[i].top, lpRect[i].right, lpRect[i].bottom));
    195                     }
    196 #endif
    197                     /* send to display driver */
    198                     ExtEscape(param.hdc, VBOXESC_SETVISIBLEREGION, cbSize, (LPCSTR)lpRgnData, 0, NULL);
    199                 }
    200                 HeapFree(GetProcessHeap(), 0, lpRgnData);
    201             }
    202         }
    203 
    204         DeleteObject(param.hrgn);
    205     }
    206 
    207     ReleaseDC(HWND_DESKTOP, param.hdc);
    208 }
    209 
    210 
    21187/* Install the global message hook */
    212 BOOL VBoxInstallHook(HMODULE hDll)
     88BOOL VBoxInstallHook(HMODULE hDll, HWND hwndPostWindow)
    21389{
    21490    if (hEventHook[0] || hEventHook[1])
    21591        return TRUE;
    21692
    217     /* Check current visible region state */
    218     VBoxRecheckVisibleWindows();
     93    hwndNotification = hwndPostWindow;
    21994
    22095    CoInitialize(NULL);
  • trunk/src/VBox/Additions/WINNT/VBoxHook/testcase/tstHook.cpp

    r3743 r3881  
    2525{
    2626    printf("Enabling global hook\n");
    27     VBoxInstallHook(GetModuleHandle("VBoxHook.dll"));
     27    VBoxInstallHook(GetModuleHandle("VBoxHook.dll"), 0);
    2828    getchar();
    2929
  • trunk/src/VBox/Additions/WINNT/VBoxService/VBoxSeamless.cpp

    r3877 r3881  
    2121 *
    2222 */
    23 
     23#define _WIN32_WINNT 0x0500
     24#include <windows.h>
    2425#include "VBoxService.h"
    2526#include "VBoxSeamless.h"
    2627#include <VBoxHook.h>
     28#include <VBoxDisplay.h>
    2729#include <VBox/VBoxDev.h>
    2830#include <iprt/assert.h>
     
    3537    HMODULE hModule;
    3638
    37     BOOL (* pfnVBoxInstallHook)(HMODULE hDll);
     39    BOOL (* pfnVBoxInstallHook)(HMODULE hDll, HWND hwndPostWindow);
    3840    BOOL (* pfnVBoxRemoveHook)();
    3941
    4042} VBOXSEAMLESSCONTEXT;
     43
     44typedef struct
     45{
     46    HDC     hdc;
     47    HRGN    hrgn;
     48    RECT    rect;
     49} VBOX_ENUM_PARAM, *PVBOX_ENUM_PARAM;
    4150
    4251static VBOXSEAMLESSCONTEXT gCtx = {0};
     
    111120{
    112121    if (gCtx.pfnVBoxInstallHook)
    113         gCtx.pfnVBoxInstallHook(gCtx.hModule);
     122    {
     123        /* Check current visible region state */
     124        VBoxSeamlessCheckWindows();
     125
     126        gCtx.pfnVBoxInstallHook(gCtx.hModule, gToolWindow);
     127    }
    114128}
    115129
     
    118132    if (gCtx.pfnVBoxRemoveHook)
    119133        gCtx.pfnVBoxRemoveHook();
     134}
     135
     136BOOL CALLBACK VBoxEnumFunc(HWND hwnd, LPARAM lParam)
     137{
     138    PVBOX_ENUM_PARAM    lpParam = (PVBOX_ENUM_PARAM)lParam;
     139    DWORD               dwStyle, dwExStyle;
     140    RECT                rectWindow, rectVisible;
     141
     142    dwStyle   = GetWindowLong(hwnd, GWL_STYLE);
     143    dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
     144    if (   !(dwStyle & WS_VISIBLE)
     145        ||  (dwStyle & WS_CHILD))
     146        return TRUE;
     147
     148    dprintf(("VBoxEnumFunc %x\n", hwnd));
     149    /* Only visible windows that are present on the desktop are interesting here */
     150    if (    GetWindowRect(hwnd, &rectWindow)
     151        &&  IntersectRect(&rectVisible, &lpParam->rect, &rectWindow))
     152    {
     153        char szWindowText[256];
     154        szWindowText[0] = 0;
     155        GetWindowText(hwnd, szWindowText, sizeof(szWindowText));
     156
     157        /* Filter out Windows XP shadow windows */
     158        /** @todo still shows inside the guest */
     159        if (   szWindowText[0] == 0
     160            && dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS)
     161            && dwExStyle == (WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_TRANSPARENT|WS_EX_TOPMOST))
     162        {
     163            dprintf(("Filter out shadow window style=%x exstyle=%x\n", dwStyle, dwExStyle));
     164            return TRUE;
     165        }
     166
     167        /** @todo will this suffice? The Program Manager window covers the whole screen */
     168        if (strcmp(szWindowText, "Program Manager"))
     169        {
     170            dprintf(("Enum hwnd=%x rect (%d,%d) (%d,%d)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
     171            dprintf(("title=%s style=%x\n", szWindowText, dwStyle));
     172
     173            HRGN hrgn = CreateRectRgn(0,0,0,0);
     174
     175            int ret = GetWindowRgn(hwnd, hrgn);
     176
     177            if (ret == ERROR)
     178            {
     179                dprintf(("GetWindowRgn failed with rc=%d\n", GetLastError()));
     180                SetRectRgn(hrgn, rectVisible.left, rectVisible.top, rectVisible.right, rectVisible.bottom);
     181            }
     182            else
     183            {
     184                /* this region is relative to the window origin instead of the desktop origin */
     185                OffsetRgn(hrgn, rectWindow.left, rectWindow.top);
     186            }
     187            if (lpParam->hrgn)
     188            {
     189                /* create a union of the current visible region and the visible rectangle of this window. */
     190                CombineRgn(lpParam->hrgn, lpParam->hrgn, hrgn, RGN_OR);
     191                DeleteObject(hrgn);
     192            }
     193            else
     194                lpParam->hrgn = hrgn;
     195        }
     196        else
     197        {
     198            dprintf(("Enum hwnd=%x rect (%d,%d) (%d,%d) (ignored)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
     199            dprintf(("title=%s style=%x\n", szWindowText, dwStyle));
     200        }
     201    }
     202    return TRUE; /* continue enumeration */
     203}
     204
     205void VBoxSeamlessCheckWindows()
     206{
     207    VBOX_ENUM_PARAM param;
     208
     209    param.hdc       = GetDC(HWND_DESKTOP);
     210    param.hrgn      = 0;
     211
     212    GetWindowRect(GetDesktopWindow(), &param.rect);
     213    dprintf(("VBoxRecheckVisibleWindows desktop=%x rect (%d,%d) (%d,%d)\n", GetDesktopWindow(), param.rect.left, param.rect.top, param.rect.right, param.rect.bottom));
     214    EnumWindows(VBoxEnumFunc, (LPARAM)&param);
     215
     216    if (param.hrgn)
     217    {
     218        DWORD cbSize;
     219
     220        cbSize = GetRegionData(param.hrgn, 0, NULL);
     221        if (cbSize)
     222        {
     223            LPRGNDATA lpRgnData = (LPRGNDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize);
     224
     225            if (lpRgnData)
     226            {
     227                cbSize = GetRegionData(param.hrgn, cbSize, lpRgnData);
     228                if (cbSize)
     229                {
     230#ifdef DEBUG
     231                    RECT *lpRect = (RECT *)&lpRgnData->Buffer[0];
     232                    dprintf(("New visible region: \n"));
     233
     234                    for (DWORD i=0;i<lpRgnData->rdh.nCount;i++)
     235                    {
     236                        dprintf(("visible rect (%d,%d)(%d,%d)\n", lpRect[i].left, lpRect[i].top, lpRect[i].right, lpRect[i].bottom));
     237                    }
     238#endif
     239                    /* send to display driver */
     240                    ExtEscape(param.hdc, VBOXESC_SETVISIBLEREGION, cbSize, (LPCSTR)lpRgnData, 0, NULL);
     241                }
     242                HeapFree(GetProcessHeap(), 0, lpRgnData);
     243            }
     244        }
     245
     246        DeleteObject(param.hrgn);
     247    }
     248
     249    ReleaseDC(HWND_DESKTOP, param.hdc);
    120250}
    121251
     
    203333                            if (fWasScreenSaverActive)
    204334                                dprintf(("Disabling the screensaver\n"));
     335
    205336                            ret = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
    206337                            if (!ret)
     
    259390    return 0;
    260391}
     392
     393
  • trunk/src/VBox/Additions/WINNT/VBoxService/VBoxSeamless.h

    r3812 r3881  
    2929
    3030
    31 /* custom messages as we must install the hook from the main thread */
    32 #define WM_VBOX_INSTALL_SEAMLESS_HOOK               0x2001
    33 #define WM_VBOX_REMOVE_SEAMLESS_HOOK                0x2002
    34 
    3531void VBoxSeamlessInstallHook();
    3632void VBoxSeamlessRemoveHook();
     33void VBoxSeamlessCheckWindows();
    3734
    3835#endif /* __VBOXSERVICESEAMLESS__H */
  • trunk/src/VBox/Additions/WINNT/VBoxService/VBoxService.cpp

    r3813 r3881  
    2222#include "VBoxService.h"
    2323#include "VBoxSeamless.h"
     24#include <VBoxHook.h>
    2425#include "resource.h"
    2526#include <malloc.h>
     
    905906            break;
    906907
     908        case WM_VBOX_SEAMLESS_UPDATE:
     909            VBoxSeamlessCheckWindows();
     910            break;
     911
    907912        default:
    908913            return DefWindowProc(hwnd, msg, wParam, lParam);
Note: See TracChangeset for help on using the changeset viewer.

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