source: trunk/src/shell32/systray_os2.c@ 21590

Last change on this file since 21590 was 21590, checked in by dmik, 14 years ago

shell32: Shell_NotifyIcon(): Create a copy of the supplied icon because the caller may DestroyIcon() on it at any time (which would cause systray to display an empty rectangle). This matches Windows behavior.

File size: 6.8 KB
Line 
1/*
2 * OS/2 System Tray support. For usage with SysTray/WPS by MadInt
3 * or System Tray widget for XCenter/eCenter.
4 *
5 * author: ErOs2
6 * date: 1 May 2004
7 *
8 * Notes: what's about HAB at lines 113, 118 ?
9 *
10 */
11
12
13#define INCL_WIN
14#include <os2wrap.h>
15
16#include <string.h>
17
18#include <odin.h>
19#include <winconst.h>
20
21
22#define WM_TRAYADDME (WM_USER+1)
23#define WM_TRAYDELME (WM_USER+2)
24#define WM_TRAYICON (WM_USER+3)
25#define WM_TRAYEXIT (0xCD20)
26
27#define SZAPP "SystrayServer"
28#define SZTOPIC "TRAY"
29
30
31BOOL DoWin32PostMessage(HWND, ULONG, MPARAM, MPARAM);
32BOOL DoWin32CharToOem(const char *s, char *t);
33
34static HWND hwndTrayServer = 0;
35
36
37typedef struct _NOTIFYICONDATAA
38{ ULONG cbSize;
39 HWND hWnd;
40 ULONG uID;
41 ULONG uFlags;
42 ULONG uCallbackMessage;
43 HPOINTER hIcon;
44 CHAR szTip[64];
45} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
46
47
48typedef struct SystrayItem {
49 HWND hWndFrame;
50 HWND hWndClient;
51 NOTIFYICONDATAA notifyIcon;
52 struct SystrayItem *nextTrayItem;
53} SystrayItem;
54
55
56
57
58static MRESULT EXPENTRY SYSTRAY_WndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
59{
60 SystrayItem *ptrayItem = (SystrayItem *)WinQueryWindowULong(hWnd, QWL_USER);
61
62 switch ( msg )
63 {
64 case WM_CREATE:
65 WinSetWindowULong(hWnd, QWL_USER, (ULONG)mp1);
66 ptrayItem = (SystrayItem *)mp1;
67 return (MRESULT)FALSE;
68 case WM_DDE_INITIATEACK:
69 hwndTrayServer = (HWND)mp1;
70 if(hwndTrayServer)
71 WinPostMsg(hwndTrayServer,WM_TRAYADDME,(MPARAM)hWnd,(MPARAM)NULL);
72 return (MRESULT)TRUE;
73 case WM_BUTTON1DBLCLK|0x2000:
74 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
75 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_LBUTTONDBLCLK_W);
76 return (MRESULT)FALSE;
77 case WM_BUTTON2DBLCLK|0x2000:
78 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
79 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_RBUTTONDBLCLK_W);
80 return (MRESULT)FALSE;
81 case WM_BUTTON3DBLCLK|0x2000:
82 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
83 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_MBUTTONDBLCLK_W);
84 return (MRESULT)FALSE;
85 case WM_BUTTON1UP|0x2000:
86 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
87 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_LBUTTONUP_W);
88 return (MRESULT)FALSE;
89 case WM_BUTTON2UP|0x2000:
90 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
91 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_RBUTTONUP_W);
92 return (MRESULT)FALSE;
93 case WM_BUTTON3UP|0x2000:
94 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
95 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_MBUTTONUP_W);
96 return (MRESULT)FALSE;
97 case WM_BUTTON1DOWN|0x2000:
98 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
99 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_LBUTTONDOWN_W);
100 return (MRESULT)FALSE;
101 case WM_BUTTON2DOWN|0x2000:
102 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
103 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_RBUTTONDOWN_W);
104 return (MRESULT)FALSE;
105 case WM_BUTTON3DOWN|0x2000:
106 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
107 (MPARAM)ptrayItem->notifyIcon.uID, (MPARAM)WM_MBUTTONDOWN_W);
108 return (MRESULT)FALSE;
109 }
110 return WinDefWindowProc( hWnd , msg , mp1 , mp2 );
111}
112
113//extern HAB hab;
114const char * const systraysupclass = "Odin32SystraySupport";
115
116BOOL SYSTRAY_RegisterClass(void)
117{
118 //WinRegisterClass( hab, systraysupclass, SYSTRAY_WndProc, 0, sizeof(ULONG) );
119 WinRegisterClass(0, systraysupclass, SYSTRAY_WndProc, 0, sizeof(ULONG) );
120 return TRUE;
121}
122
123
124BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
125{
126 ULONG fcf = FCF_TITLEBAR;
127
128 if ( !SYSTRAY_RegisterClass() )
129 {
130 return FALSE;
131 }
132
133
134 memset( ptrayItem, 0, sizeof(SystrayItem) );
135 ptrayItem->hWndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &fcf, NULL,
136 "", 0, NULLHANDLE, 0, NULL );
137 if ( !ptrayItem->hWndFrame ) {
138 return FALSE;
139 }
140 ptrayItem->hWndClient = WinCreateWindow(ptrayItem->hWndFrame, systraysupclass, "",
141 0, 0, 0, 0, 0, ptrayItem->hWndFrame,
142 HWND_TOP, FID_CLIENT, ptrayItem, NULL );
143 if ( !ptrayItem->hWndClient ) {
144 return FALSE;
145 }
146
147 WinDdeInitiate(ptrayItem->hWndClient,SZAPP,SZTOPIC,NULL);
148 if (hwndTrayServer)
149 WinPostMsg(hwndTrayServer,WM_TRAYICON,(MPARAM)ptrayItem->hWndClient,(MPARAM)NULL);
150
151 return (hwndTrayServer!=NULLHANDLE);
152}
153
154void SYSTRAY_ItemTerm(SystrayItem *ptrayItem)
155{
156 HPOINTER hIcon = (HPOINTER)WinSendMsg(ptrayItem->hWndFrame, WM_QUERYICON, NULL, NULL);
157 if (hIcon != NULLHANDLE)
158 WinDestroyPointer(hIcon);
159
160 WinDestroyWindow(ptrayItem->hWndFrame);
161}
162
163
164void SYSTRAY_ItemSetMessage(SystrayItem *ptrayItem, ULONG uCallbackMessage)
165{
166 ptrayItem->notifyIcon.uCallbackMessage = uCallbackMessage;
167}
168
169
170void SYSTRAY_ItemSetIcon(SystrayItem *ptrayItem, HPOINTER hIcon)
171{
172 // Windows seems to make a copy of icons displayed in the tray area. At
173 // least, calling DestroyIcon() after passing the icon handle to
174 // Shell_NotifyIcon() doesn't harm the icon displayed in the tray. Behave
175 // similarly on OS/2 (some applications do call DestroyIcon()). The copy is
176 // deleted in SYSTRAY_ItemTerm().
177
178 POINTERINFO Info;
179 HPOINTER hIcon2 = NULLHANDLE;
180 APIRET arc;
181 arc = WinQueryPointerInfo(hIcon, &Info);
182 if (!arc)
183 return;
184 hIcon2 = WinCreatePointerIndirect(HWND_DESKTOP, &Info);
185 if (hIcon2 == NULLHANDLE)
186 return;
187 hIcon = hIcon2;
188
189 WinSendMsg( ptrayItem->hWndFrame, WM_SETICON, MPFROMLONG( hIcon ), MPVOID );
190 if (hwndTrayServer)
191 WinPostMsg(hwndTrayServer,WM_TRAYICON,(MPARAM)ptrayItem->hWndClient,(MPARAM)NULL);
192}
193
194
195void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
196{
197 char tmp[ 64 ];
198 strncpy(ptrayItem->notifyIcon.szTip, szTip, 64 );
199 ptrayItem->notifyIcon.szTip[ 63 ] = 0;
200 DoWin32CharToOem( ptrayItem->notifyIcon.szTip, tmp );
201 WinSetWindowText( ptrayItem->hWndFrame, tmp );
202 if (hwndTrayServer)
203 WinPostMsg(hwndTrayServer,WM_TRAYICON,(MPARAM)ptrayItem->hWndClient,(MPARAM)NULL);
204}
205
Note: See TracBrowser for help on using the repository browser.