Esempio n. 1
0
/*************************************************************************
 * NTSHChangeNotifyRegister            [SHELL32.640]
 * NOTES
 *   Idlist is an array of structures and Count specifies how many items in the array.
 *   count should always be one when calling SHChangeNotifyRegister, or
 *   SHChangeNotifyDeregister will not work properly.
 */
EXTERN_C ULONG WINAPI NTSHChangeNotifyRegister(
    HWND hwnd,
    int fSources,
    LONG fEvents,
    UINT msg,
    int count,
    SHChangeNotifyEntry *idlist)
{
    return SHChangeNotifyRegister(hwnd, fSources | SHCNRF_NewDelivery,
                                  fEvents, msg, count, idlist);
}
Esempio n. 2
0
BOOL CPage6::OnInitDialog()
{
	CMFCPropertyPage::OnInitDialog();

	m_wbdShellTree.Expand(m_wbdShellTree.GetRootItem(), TVE_EXPAND);
	m_wbdShellTree.SetRelatedList(&m_wndShellList);

	LPITEMIDLIST ppidl;
	if (SHGetSpecialFolderLocation(GetSafeHwnd(),CSIDL_BITBUCKET, &ppidl) != NOERROR)
	{
		return 0;
	}

	SHChangeNotifyEntry scnIDL;
	scnIDL.pidl = ppidl;
	scnIDL.fRecursive = TRUE;

	m_ulChangeIconNotifyID = SHChangeNotifyRegister(m_hWnd, SHCNF_ACCEPT_INTERRUPTS | SHCNF_ACCEPT_NON_INTERRUPTS, SHCNE_ALLEVENTS,  UWM_CHANGE_SYSTEM_ICON, 1, &scnIDL);

	return TRUE;  // return TRUE unless you set the focus to a control
}
Esempio n. 3
0
/// <summary>
///
/// </summary>
void TileGroup::SetFolder(LPWSTR folder) {
  PIDLIST_ABSOLUTE idList;

  // Just in case we are switching folders, deregister for old notifications
  if (mChangeNotifyUID != 0) {
    SHChangeNotifyDeregister(mChangeNotifyUID);
    mChangeNotifyUID = 0;
  }

  // Get the folder we are interested in
  if (_wcsicmp(folder, L"desktop") == 0) {
    SHGetKnownFolderIDList(FOLDERID_Desktop, 0, nullptr, &idList);
    SHGetDesktopFolder(reinterpret_cast<IShellFolder**>(&mWorkingFolder));
  } else {
    mRootFolder->ParseDisplayName(nullptr, nullptr, folder, nullptr, &idList, nullptr);
    mRootFolder->BindToObject(idList, nullptr, IID_IShellFolder, reinterpret_cast<LPVOID*>(&mWorkingFolder));
  }

  // Enumerate the contents of this folder
  LoadFolderRequest request;
  request.blackList = mHiddenItems;
  request.folder = mWorkingFolder;
  request.targetIconWidth = mTileSettings.mIconSize;
  nCore::LoadFolder(request, this);

  // Register for change notifications
  SHChangeNotifyEntry watchEntries[] = { idList, FALSE };
  mChangeNotifyUID = SHChangeNotifyRegister(
    mWindow->GetWindowHandle(),
    CHANGE_SOURCES,
    CHANGE_EVENTS,
    mChangeNotifyMsg,
    1,
    watchEntries);

  // Let go fo the PIDLists
  CoTaskMemFree(idList);
}
Esempio n. 4
0
void CRecBinViewer::InstallRBinNotify ()
{
	SHChangeNotifyEntry stPIDL;
	LPITEMIDLIST ppidl;
	
	SHGetSpecialFolderLocation(m_hWnd, CSIDL_BITBUCKET, &ppidl);
	
	stPIDL.pidl = ppidl;
	stPIDL.fRecursive = TRUE;

	m_hNotifyRBin = SHChangeNotifyRegister (m_hWnd, 
		SHCNF_ACCEPT_INTERRUPTS | SHCNF_ACCEPT_NON_INTERRUPTS, 
		SHCNE_ALLEVENTS, 
		WM_SHELLNOTIFY,				/* Message that would be sent by the Shell */
		1,
		&stPIDL);
	
	if(NULL == m_hNotifyRBin)
	{
		TRACE(_T("Change Register Failed for RecycleBin"));
	}
	
}
Esempio n. 5
0
LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  XBMC_Event newEvent;
  ZeroMemory(&newEvent, sizeof(newEvent));
  static HDEVNOTIFY hDeviceNotify;

  if (uMsg == WM_CREATE)
  {
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(((LPCREATESTRUCT)lParam)->lpCreateParams));
    DIB_InitOSKeymap();
    g_uQueryCancelAutoPlay = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
    shcne.pidl = NULL;
    shcne.fRecursive = TRUE;
    long fEvents = SHCNE_DRIVEADD | SHCNE_DRIVEREMOVED | SHCNE_MEDIAREMOVED | SHCNE_MEDIAINSERTED;
    SHChangeNotifyRegister(hWnd, SHCNRF_ShellLevel | SHCNRF_NewDelivery, fEvents, WM_MEDIA_CHANGE, 1, &shcne);
    RegisterDeviceInterfaceToHwnd(USB_HID_GUID, hWnd, &hDeviceNotify);
    return 0;
  }

  m_pEventFunc = (PHANDLE_EVENT_FUNC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  if (!m_pEventFunc)
    return DefWindowProc(hWnd, uMsg, wParam, lParam);

  if(g_uQueryCancelAutoPlay != 0 && uMsg == g_uQueryCancelAutoPlay)
    return S_FALSE;

  switch (uMsg)
  {
    case WM_CLOSE:
    case WM_QUIT:
    case WM_DESTROY:
      newEvent.type = XBMC_QUIT;
      m_pEventFunc(newEvent);
      break;
    case WM_SHOWWINDOW:
      {
        bool active = g_application.m_AppActive;
        g_application.m_AppActive = wParam != 0;
        if (g_application.m_AppActive != active)
          g_Windowing.NotifyAppActiveChange(g_application.m_AppActive);
        CLog::Log(LOGDEBUG, __FUNCTION__"Window is %s", g_application.m_AppActive ? "shown" : "hidden");
      }
      break;
    case WM_ACTIVATE:
      {
        bool active = g_application.m_AppActive;
        if (HIWORD(wParam))
        {
          g_application.m_AppActive = false;
        }
        else
        {
          WINDOWPLACEMENT lpwndpl;
          lpwndpl.length = sizeof(lpwndpl);
          if (LOWORD(wParam) != WA_INACTIVE)
          {
            if (GetWindowPlacement(hWnd, &lpwndpl))
              g_application.m_AppActive = lpwndpl.showCmd != SW_HIDE;
          }
          else
          {
            g_application.m_AppActive = g_Windowing.WindowedMode();
          }
        }
        if (g_application.m_AppActive != active)
          g_Windowing.NotifyAppActiveChange(g_application.m_AppActive);
        CLog::Log(LOGDEBUG, __FUNCTION__"Window is %s", g_application.m_AppActive ? "active" : "inactive");
      }
      break;
    case WM_SETFOCUS:
    case WM_KILLFOCUS:
      g_application.m_AppFocused = uMsg == WM_SETFOCUS;
      g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
      if (uMsg == WM_KILLFOCUS)
      {
        CStdString procfile;
        if (CWIN32Util::GetFocussedProcess(procfile))
          CLog::Log(LOGDEBUG, __FUNCTION__": Focus switched to process %s", procfile.c_str());
      }
      break;
    case WM_SYSKEYDOWN:
      switch (wParam)
      {
        case VK_F4: //alt-f4, default event quit.
          return(DefWindowProc(hWnd, uMsg, wParam, lParam));
        case VK_RETURN: //alt-return
          if ((lParam & REPEATED_KEYMASK) == 0)
            g_graphicsContext.ToggleFullScreenRoot();
          return 0;
      }
      //deliberate fallthrough
    case WM_KEYDOWN:
    {
      switch (wParam)
      {
        case VK_CONTROL:
          if ( lParam & EXTENDED_KEYMASK )
            wParam = VK_RCONTROL;
          else
            wParam = VK_LCONTROL;
          break;
        case VK_SHIFT:
          /* EXTENDED trick doesn't work here */
          if (GetKeyState(VK_LSHIFT) & 0x8000)
            wParam = VK_LSHIFT;
          else if (GetKeyState(VK_RSHIFT) & 0x8000)
            wParam = VK_RSHIFT;
          break;
        case VK_MENU:
          if ( lParam & EXTENDED_KEYMASK )
            wParam = VK_RMENU;
          else
            wParam = VK_LMENU;
          break;
      }
      XBMC_keysym keysym;
      TranslateKey(wParam, HIWORD(lParam), &keysym, 1);

      newEvent.type = XBMC_KEYDOWN;
      newEvent.key.keysym = keysym;
      m_pEventFunc(newEvent);
    }
    return(0);

    case WM_SYSKEYUP:
    case WM_KEYUP:
      {
      switch (wParam)
      {
        case VK_CONTROL:
          if ( lParam&EXTENDED_KEYMASK )
            wParam = VK_RCONTROL;
          else
            wParam = VK_LCONTROL;
          break;
        case VK_SHIFT:
          {
            uint32_t scanCodeL = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
            uint32_t scanCodeR = MapVirtualKey(VK_RSHIFT, MAPVK_VK_TO_VSC);
            uint32_t keyCode = (uint32_t)((lParam & 0xFF0000) >> 16);
            if (keyCode == scanCodeL)
              wParam = VK_LSHIFT;
            else if (keyCode == scanCodeR)
              wParam = VK_RSHIFT;
          }
          break;
        case VK_MENU:
          if ( lParam&EXTENDED_KEYMASK )
            wParam = VK_RMENU;
          else
            wParam = VK_LMENU;
          break;
      }
      XBMC_keysym keysym;
      TranslateKey(wParam, HIWORD(lParam), &keysym, 1);

      if (wParam == VK_SNAPSHOT)
        newEvent.type = XBMC_KEYDOWN;
      else
        newEvent.type = XBMC_KEYUP;
      newEvent.key.keysym = keysym;
      m_pEventFunc(newEvent);
    }
    return(0);
    case WM_APPCOMMAND: // MULTIMEDIA keys are mapped to APPCOMMANDS
    {
      CLog::Log(LOGDEBUG, "WinEventsWin32.cpp: APPCOMMAND %d", GET_APPCOMMAND_LPARAM(lParam));
      newEvent.appcommand.type = XBMC_APPCOMMAND;
      newEvent.appcommand.action = GET_APPCOMMAND_LPARAM(lParam);
      if (m_pEventFunc(newEvent))
        return TRUE;
      else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    case WM_GESTURENOTIFY:
    {
      OnGestureNotify(hWnd, lParam);
      return DefWindowProc(hWnd, WM_GESTURENOTIFY, wParam, lParam);
    }
    case WM_GESTURE:
    {
      OnGesture(hWnd, lParam);
      return 0;
    }
    case WM_SYSCHAR:
      if (wParam == VK_RETURN) //stop system beep on alt-return
        return 0;
      break;
    case WM_SETCURSOR:
      if (HTCLIENT != LOWORD(lParam))
        g_Windowing.ShowOSMouse(true);
      break;
    case WM_MOUSEMOVE:
      newEvent.type = XBMC_MOUSEMOTION;
      newEvent.motion.x = GET_X_LPARAM(lParam);
      newEvent.motion.y = GET_Y_LPARAM(lParam);
      newEvent.motion.state = 0;
      m_pEventFunc(newEvent);
      return(0);
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
      newEvent.type = XBMC_MOUSEBUTTONDOWN;
      newEvent.button.state = XBMC_PRESSED;
      newEvent.button.x = GET_X_LPARAM(lParam);
      newEvent.button.y = GET_Y_LPARAM(lParam);
      newEvent.button.button = 0;
      if (uMsg == WM_LBUTTONDOWN) newEvent.button.button = XBMC_BUTTON_LEFT;
      else if (uMsg == WM_MBUTTONDOWN) newEvent.button.button = XBMC_BUTTON_MIDDLE;
      else if (uMsg == WM_RBUTTONDOWN) newEvent.button.button = XBMC_BUTTON_RIGHT;
      m_pEventFunc(newEvent);
      return(0);
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
      newEvent.type = XBMC_MOUSEBUTTONUP;
      newEvent.button.state = XBMC_RELEASED;
      newEvent.button.x = GET_X_LPARAM(lParam);
      newEvent.button.y = GET_Y_LPARAM(lParam);
      newEvent.button.button = 0;
      if (uMsg == WM_LBUTTONUP) newEvent.button.button = XBMC_BUTTON_LEFT;
      else if (uMsg == WM_MBUTTONUP) newEvent.button.button = XBMC_BUTTON_MIDDLE;
      else if (uMsg == WM_RBUTTONUP) newEvent.button.button = XBMC_BUTTON_RIGHT;
      m_pEventFunc(newEvent);
      return(0);
    case WM_MOUSEWHEEL:
      {
        // SDL, which our events system is based off, sends a MOUSEBUTTONDOWN message
        // followed by a MOUSEBUTTONUP message.  As this is a momentary event, we just
        // react on the MOUSEBUTTONUP message, resetting the state after processing.
        newEvent.type = XBMC_MOUSEBUTTONDOWN;
        newEvent.button.state = XBMC_PRESSED;
        // the coordinates in WM_MOUSEWHEEL are screen, not client coordinates
        POINT point;
        point.x = GET_X_LPARAM(lParam);
        point.y = GET_Y_LPARAM(lParam);
        WindowFromScreenCoords(hWnd, &point);
        newEvent.button.x = (uint16_t)point.x;
        newEvent.button.y = (uint16_t)point.y;
        newEvent.button.button = GET_Y_LPARAM(wParam) > 0 ? XBMC_BUTTON_WHEELUP : XBMC_BUTTON_WHEELDOWN;
        m_pEventFunc(newEvent);
        newEvent.type = XBMC_MOUSEBUTTONUP;
        newEvent.button.state = XBMC_RELEASED;
        m_pEventFunc(newEvent);
      }
      return(0);
    case WM_SIZE:
      newEvent.type = XBMC_VIDEORESIZE;
      newEvent.resize.type = XBMC_VIDEORESIZE;
      newEvent.resize.w = GET_X_LPARAM(lParam);
      newEvent.resize.h = GET_Y_LPARAM(lParam);
      if (newEvent.resize.w * newEvent.resize.h)
        m_pEventFunc(newEvent);
      return(0);
    case WM_MEDIA_CHANGE:
      {
        // There may be multiple notifications for one event
        // There are also a few events we're not interested in, but they cause no harm
        // For example SD card reader insertion/removal
        long lEvent;
        PIDLIST_ABSOLUTE *ppidl;
        HANDLE hLock = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &ppidl, &lEvent);

        if (hLock)
        {
          char drivePath[MAX_PATH+1];
          if (!SHGetPathFromIDList(ppidl[0], drivePath))
            break;

          switch(lEvent)
          {
            case SHCNE_DRIVEADD:
            case SHCNE_MEDIAINSERTED:
              CLog::Log(LOGDEBUG, __FUNCTION__": Drive %s Media has arrived.", drivePath);
              if (GetDriveType(drivePath) == DRIVE_CDROM)
                g_application.getApplicationMessenger().OpticalMount(drivePath, true);
              else
                CWin32StorageProvider::SetEvent();
              break;

            case SHCNE_DRIVEREMOVED:
            case SHCNE_MEDIAREMOVED:
              CLog::Log(LOGDEBUG, __FUNCTION__": Drive %s Media was removed.", drivePath);
              if (GetDriveType(drivePath) == DRIVE_CDROM)
                g_application.getApplicationMessenger().OpticalUnMount(drivePath);
              else
                CWin32StorageProvider::SetEvent();
              break;
          }
          SHChangeNotification_Unlock(hLock);
        }
        break;
      }
    case WM_POWERBROADCAST:
      if (wParam==PBT_APMSUSPEND)
      {
        CLog::Log(LOGDEBUG,"WM_POWERBROADCAST: PBT_APMSUSPEND event was sent");
        CWin32PowerSyscall::SetOnSuspend();
      }
      else if(wParam==PBT_APMRESUMEAUTOMATIC)
      {
        CLog::Log(LOGDEBUG,"WM_POWERBROADCAST: PBT_APMRESUMEAUTOMATIC event was sent");
        CWin32PowerSyscall::SetOnResume();
      }
      break;
    case WM_DEVICECHANGE:
      {
        PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) lParam;
        CStdString dbcc_name(b->dbcc_name);
        dbcc_name = CKeymapLoader::ParseWin32HIDName(b->dbcc_name);
        switch (wParam)
        {
          case DBT_DEVICEARRIVAL:
            CKeymapLoader().DeviceAdded(dbcc_name);
            break;
          case DBT_DEVICEREMOVECOMPLETE:
            CKeymapLoader().DeviceRemoved(dbcc_name);
            break;
          case DBT_DEVNODES_CHANGED:
            //CLog::Log(LOGDEBUG, "HID Device Changed");
            //We generally don't care about Change notifications, only need to know if a device is removed or added to rescan the device list
            break;
        }
        break;
      }
    case WM_PAINT:
      //some other app has painted over our window, mark everything as dirty
      g_windowManager.MarkDirty();
      break;
  }
  return(DefWindowProc(hWnd, uMsg, wParam, lParam));
}
Esempio n. 6
0
void CRecBinViewer::InstallShellNotify ()
{
	SHChangeNotifyEntry stPIDL;
	LPITEMIDLIST ppidl;
	
	int				iPos		= 0;
	TCHAR			szPath[MAX_PATH];		
	WIN32_FIND_DATA findData;
	HANDLE			hFindData	= INVALID_HANDLE_VALUE;
	HRESULT			hr			= S_OK;
	
	CDriveArray ar;

	GetDrives (ar);
	for (unsigned int i = 0; i < ar.size (); i++)
	{
		if (ar[i].m_nType != DRIVE_FIXED)	
			continue;
		
		SHQUERYRBINFO qrbi;
		ZeroMemory (&qrbi, sizeof (qrbi));
		qrbi.cbSize = sizeof (qrbi);
		hr = SHQueryRecycleBin (ar[i].m_Path, &qrbi);
		if (SUCCEEDED (hr))
		{
			ZeroMemory (&findData, sizeof (findData));
			wsprintf (szPath, _T("%sRecycler"), static_cast<LPCWSTR>(ar[i].m_Path));
			hFindData = FindFirstFile (szPath, &findData);
			if (INVALID_HANDLE_VALUE != hFindData)
			{
				ppidl = SHSimpleIDListFromPath (szPath);
				stPIDL.pidl = ppidl;
				m_pidlDrives[iPos] = ppidl;
				m_hNotifyDrives[iPos] = SHChangeNotifyRegister (m_hWnd, 
					SHCNF_ACCEPT_INTERRUPTS | SHCNF_ACCEPT_NON_INTERRUPTS, 
					SHCNE_RMDIR | SHCNE_RENAMEFOLDER | SHCNE_DELETE | SHCNE_RENAMEITEM, 
					WM_SHELLNOTIFYRBINDIR,
					1,
					&stPIDL);
				iPos ++;
				FindClose (hFindData);
			}
			else
			{
				ZeroMemory (&findData, sizeof (findData));
				wsprintf (szPath, _T("%sRecycled"), static_cast<LPCWSTR>(ar[i].m_Path));
				hFindData = FindFirstFile (szPath, &findData);
				if (INVALID_HANDLE_VALUE != hFindData)
				{
					ppidl = SHSimpleIDListFromPath (szPath);
					stPIDL.pidl = ppidl;
					m_pidlDrives[iPos] = ppidl;
					m_hNotifyDrives[iPos] = SHChangeNotifyRegister (m_hWnd, 
						SHCNF_ACCEPT_INTERRUPTS | SHCNF_ACCEPT_NON_INTERRUPTS, 
						SHCNE_RMDIR | SHCNE_RENAMEFOLDER | SHCNE_DELETE | SHCNE_RENAMEITEM, 
						WM_SHELLNOTIFYRBINDIR,
						1,
						&stPIDL);
					iPos ++;
					FindClose (hFindData);
				}
			}
		}			
	}
}
Esempio n. 7
0
/// <summary>
/// Handles window messages.
/// </summary>
LRESULT WINAPI TileGroup::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam, LPVOID) {
  if (message == mChangeNotifyMsg) {
    return HandleChangeNotify(HANDLE(wParam), DWORD(lParam));
  }

  if (mContextMenu3) {
    LRESULT result;
    if (SUCCEEDED(mContextMenu3->HandleMenuMsg2(message, wParam, lParam, &result))) {
      return result;
    }
  }

  if (mContextMenu2) {
    if (SUCCEEDED(mContextMenu2->HandleMenuMsg(message, wParam, lParam))) {
      return 0;
    }
  }

  switch (message) {
  case WM_KEYDOWN:
    switch (wParam) {
    case 'A':
      if (GetKeyState(VK_CONTROL) < 0) {
        SelectAll();
      }
      break;

    case 'C':
      if (GetKeyState(VK_CONTROL) < 0) {
        DoCopy(false);
      }
      break;

    case 'V':
      if (GetKeyState(VK_CONTROL) < 0) {
        DoPaste();
      }
      break;

    case 'X':
      if (GetKeyState(VK_CONTROL) < 0) {
        DoCopy(true);
      }
      break;

    case 'Z':
      if (GetKeyState(VK_CONTROL) < 0) {
        DoUndo();
      }
      break;

    case VK_DELETE:
      DeleteSelectedFiles();
      break;

    case VK_RETURN:
      OpenSelectedFiles();
      break;

    case VK_F2:
      RenameSelectedFiles();
      break;

    case VK_F5:
      UpdateAllIcons();
      break;

    case VK_UP:
    case VK_DOWN:
    case VK_LEFT:
    case VK_RIGHT:
      break;
    }
    break;

  case WM_LBUTTONDOWN:
  case WM_RBUTTONDOWN:
    if (!mInRectangleSelection) {
      StartRectangleSelection(D2D1::Point2U(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
    } else {
      EndRectangleSelection(D2D1::Point2U(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
    }
    break;

  case WM_MOUSEMOVE:
    if (mInRectangleSelection) {
      MoveRectangleSelection(D2D1::Point2U(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
    }
    break;

  case WM_LBUTTONUP:
  case WM_RBUTTONUP:
    if (mInRectangleSelection) {
      EndRectangleSelection(D2D1::Point2U(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
    } else if (GetKeyState(VK_CONTROL) >= 0) {
      DeselectAll();
    }
    break;

  case Window::WM_TOPPARENTLOST:
    mChangeNotifyMsg = 0;
    if (mChangeNotifyUID != 0) {
      SHChangeNotifyDeregister(mChangeNotifyUID);
      mChangeNotifyUID = 0;
    }
    break;

  case Window::WM_NEWTOPPARENT:
    {
      // TODO(Erik): This is unacceptable. We have to pick up change notifications while we don't
      // have a top parent.
      IPersistFolder2 *ipsf2;
      LPITEMIDLIST curFolder;
      HRESULT hr;

      mChangeNotifyMsg = mWindow->RegisterUserMessage(this);

      if (SUCCEEDED(hr = mWorkingFolder->QueryInterface(IID_IPersistFolder2, (LPVOID*)&ipsf2))) {
        if (SUCCEEDED(hr = ipsf2->GetCurFolder(&curFolder))) {
          // (Re)Register for change notifications
          SHChangeNotifyEntry watchEntries[] = { curFolder, FALSE };
          mChangeNotifyUID = SHChangeNotifyRegister(
            window,
            CHANGE_SOURCES,
            CHANGE_EVENTS,
            mChangeNotifyMsg,
            1,
            watchEntries);

          // Let go fo the PIDLists
          CoTaskMemFree(curFolder);
        }
        ipsf2->Release();
      }
    }
    break;
  }

  mEventHandler->HandleMessage(window, message, wParam, lParam);
  return DefWindowProc(window, message, wParam, lParam);
}