systray in desktop mode [unified resend]

Martin Fuchs martin-fuchs at gmx.net
Sat Mar 27 08:17:20 CST 2004


Changelog:
SHELL_NotifyIcon() implementation for Wine's desktop mode


Index: systray.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/systray.c,v
retrieving revision 1.26
diff -u -p -d -r1.26 systray.c
--- systray.c	27 Feb 2004 21:30:16 -0000	1.26
+++ systray.c	27 Mar 2004 14:15:56 -0000
@@ -62,6 +62,15 @@ static BOOL SYSTRAY_Delete(PNOTIFYICONDA
 #define ICON_BORDER  4
 
 
+ /* copy data structure for tray notifications */
+typedef struct TrayNotifyCDS_Dummy {
+  DWORD	cookie;
+  DWORD	notify_code;
+  DWORD	nicon_data[1];	/* placeholder for NOTIFYICONDATA structure */
+} TrayNotifyCDS_Dummy;
+
+static BOOL SHELL_NotifyIconAW(DWORD dwMessage, void* pnid, HWND nid_hwnd, int nid_size, BOOL unicode);
+
 
 static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAA pnid1, PNOTIFYICONDATAA pnid2)
 {
@@ -360,39 +369,83 @@ BOOL SYSTRAY_Init(void)
  * Shell_NotifyIcon			[SHELL32.296]
  * Shell_NotifyIconA			[SHELL32.297]
  */
-BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
+BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
 {
-  BOOL flag=FALSE;
+  BOOL flag = FALSE;
+
   TRACE("enter %p %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
-  switch(dwMessage) {
-  case NIM_ADD:
-    flag = SYSTRAY_Add(pnid);
-    break;
-  case NIM_MODIFY:
-    flag = SYSTRAY_Modify(pnid);
-    break;
-  case NIM_DELETE:
-    flag = SYSTRAY_Delete(pnid);
-    break;
+
+  /* check for desktop mode */
+  if (GetWindowThreadProcessId(GetDesktopWindow(), NULL)) {
+    flag = SHELL_NotifyIconAW(dwMessage, pnid, pnid->hWnd, pnid->cbSize, FALSE);
+  } else {
+    switch(dwMessage) {
+      case NIM_ADD:
+      flag = SYSTRAY_Add(pnid);
+      break;
+    case NIM_MODIFY:
+      flag = SYSTRAY_Modify(pnid);
+      break;
+    case NIM_DELETE:
+      flag = SYSTRAY_Delete(pnid);
+      break;
+    }
   }
+
   TRACE("leave %p %d %ld=%d\n", pnid->hWnd, pnid->uID, dwMessage, flag);
+
   return flag;
 }
 
 /*************************************************************************
  * Shell_NotifyIconW			[SHELL32.298]
  */
-BOOL WINAPI Shell_NotifyIconW (DWORD dwMessage, PNOTIFYICONDATAW pnid )
+BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid)
 {
-	BOOL ret;
+  BOOL ret;
 
-	PNOTIFYICONDATAA p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAA));
-	memcpy(p, pnid, sizeof(NOTIFYICONDATAA));
-        WideCharToMultiByte( CP_ACP, 0, pnid->szTip, -1, p->szTip, sizeof(p->szTip), NULL, NULL );
-        p->szTip[sizeof(p->szTip)-1] = 0;
+  /* check for desktop mode */
+  if (GetWindowThreadProcessId(GetDesktopWindow(), NULL)) {
+    ret = SHELL_NotifyIconAW(dwMessage, pnid, pnid->hWnd, pnid->cbSize, FALSE);
+  } else {
+    PNOTIFYICONDATAA p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAA));
 
-	ret = Shell_NotifyIconA(dwMessage, p );
+    memcpy(p, pnid, sizeof(NOTIFYICONDATAA));
+    WideCharToMultiByte(CP_ACP, 0, pnid->szTip, -1, p->szTip, sizeof(p->szTip), NULL, NULL);
+    p->szTip[sizeof(p->szTip)-1] = 0;
 
-	HeapFree(GetProcessHeap(),0,p);
-	return ret;
+    ret = Shell_NotifyIconA(dwMessage, p);
+
+    HeapFree(GetProcessHeap(),0,p);
+  }
+
+  return ret;
+}
+
+
+/* The only difference between Shell_NotifyIconA and Shell_NotifyIconW is the call to SendMessageA/W. */
+static BOOL SHELL_NotifyIconAW(DWORD dwMessage, void* pnid, HWND nid_hwnd, int nid_size, BOOL unicode)
+{
+  HWND hwnd;
+  COPYDATASTRUCT data;
+  const static WCHAR wszShellTrayClassName[] = {'S','h','e','l','l','_','T','r','a','y','W','n','d','\0'};
+
+  BOOL ret = FALSE;
+  int len = sizeof(TrayNotifyCDS_Dummy)-sizeof(DWORD)+nid_size;
+
+  TrayNotifyCDS_Dummy* pnotify_data = (TrayNotifyCDS_Dummy*) alloca(len);
+
+  pnotify_data->cookie = 1;
+  pnotify_data->notify_code = dwMessage;
+  memcpy(&pnotify_data->nicon_data, pnid, nid_size);
+
+  data.dwData = 1;
+  data.cbData = len;
+  data.lpData = pnotify_data;
+
+  for(hwnd=0; (hwnd=FindWindowExW(0, hwnd, wszShellTrayClassName, NULL)); )
+    if ((unicode?SendMessageW:SendMessageA)(hwnd, WM_COPYDATA, (WPARAM)nid_hwnd, (LPARAM)&data))
+      ret = TRUE;
+
+  return ret;
 }





More information about the wine-patches mailing list