source: trunk/src/shell32/systray_os2ex.c@ 21592

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

shell32: Implemented xsystray support (#16).

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1/*
2 * OS/2 System Tray support.
3 * A better implementaiton using the xsystray XCenter/eCenter widget API.
4 *
5 * Author: Dmitriy Kuminov
6 */
7
8#define INCL_WIN
9#define INCL_DOS
10#define INCL_DOSERRORS
11#include <os2wrap.h>
12
13#include <string.h>
14
15#include <odin.h>
16#include <winconst.h>
17
18// declare function pointers for dynamic linking to xsystray DLL
19#define XSTAPI_FPTRS_STATIC
20#include <xsystray.h>
21
22#include "systray_os2.h"
23
24#define WM_XST_MYNOTIFY (WM_USER + 1000)
25
26static HWND hwndProxy = NULLHANDLE;
27static ULONG hwndProxyRefs = 0;
28
29static PFNWP OldProxyWndProc = NULL;
30
31static MRESULT EXPENTRY ProxyWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
32{
33 switch (msg)
34 {
35 case WM_XST_MYNOTIFY:
36 {
37 USHORT usIconID = SHORT1FROMMP(mp1);
38 USHORT usNotifyCode = SHORT2FROMMP(mp1);
39
40 SystrayItem *ptrayItem = SYSTRAY_FindItem(usIconID);
41 if (!ptrayItem)
42 return (MRESULT)FALSE;
43
44 switch (usNotifyCode)
45 {
46 case XST_IN_MOUSE:
47 {
48 PXSTMOUSEMSG pmmsg = (PXSTMOUSEMSG)mp2;
49 ULONG winMsg = 0;
50
51 switch (pmmsg->ulMouseMsg)
52 {
53 case WM_BUTTON1DBLCLK: winMsg = WM_LBUTTONDBLCLK_W; break;
54 case WM_BUTTON2DBLCLK: winMsg = WM_RBUTTONDBLCLK_W; break;
55 case WM_BUTTON3DBLCLK: winMsg = WM_MBUTTONDBLCLK_W; break;
56 case WM_BUTTON1UP: winMsg = WM_LBUTTONUP_W; break;
57 case WM_BUTTON2UP: winMsg = WM_RBUTTONUP_W; break;
58 case WM_BUTTON3UP: winMsg = WM_MBUTTONUP_W; break;
59 case WM_BUTTON1DOWN: winMsg = WM_LBUTTONDOWN_W; break;
60 case WM_BUTTON2DOWN: winMsg = WM_RBUTTONDOWN_W; break;
61 case WM_BUTTON3DOWN: winMsg = WM_MBUTTONDOWN_W; break;
62 default: break;
63 }
64
65 if (winMsg)
66 {
67 DoWin32PostMessage(ptrayItem->notifyIcon.hWnd,
68 ptrayItem->notifyIcon.uCallbackMessage,
69 (MPARAM)ptrayItem->notifyIcon.uID,
70 (MPARAM)winMsg);
71 }
72
73 return (MRESULT)FALSE;
74 }
75 default:
76 break;
77 }
78 }
79
80 default:
81 break;
82 }
83
84 return OldProxyWndProc(hWnd, msg, mp1, mp2);
85}
86
87static BOOL SYSTRAY_Ex_ItemInit(SystrayItem *ptrayItem)
88{
89 if (hwndProxyRefs == 0)
90 {
91 ULONG fcf = 0;
92 hwndProxy = WinCreateStdWindow(HWND_DESKTOP, 0, &fcf, NULL,
93 NULL, 0, NULLHANDLE, 0, NULL);
94 if (hwndProxy == NULLHANDLE)
95 return FALSE;
96
97 OldProxyWndProc = WinSubclassWindow(hwndProxy, ProxyWndProc);
98 }
99 ++ hwndProxyRefs;
100
101 return TRUE;
102}
103
104static void SYSTRAY_Ex_ItemTerm(SystrayItem *ptrayItem)
105{
106 xstRemoveSysTrayIcon(hwndProxy, ptrayItem->uIdx);
107
108 if (-- hwndProxyRefs == 0)
109 {
110 WinDestroyWindow(hwndProxy);
111 hwndProxy = NULLHANDLE;
112 }
113}
114
115static void SYSTRAY_Ex_ItemUpdate(SystrayItem *ptrayItem, ULONG uFlags)
116{
117 if (uFlags == 0 || (uFlags & (NIF_ICON | NIF_TIP) == NIF_ICON | NIF_TIP))
118 {
119 // uFlags = 0 means it's the first time so add the icon. The other case
120 // is true when a bunch of the parameters is changed at once so use
121 // xstAdd... too to save a few IPC calls.
122 xstAddSysTrayIcon(hwndProxy, ptrayItem->uIdx,
123 ptrayItem->notifyIcon.hIcon,
124 ptrayItem->notifyIcon.szTip,
125 WM_XST_MYNOTIFY,
126 XST_IN_MOUSE | XST_IN_CONTEXT);
127 return;
128 }
129
130 if (uFlags & NIF_ICON)
131 {
132 xstReplaceSysTrayIcon(hwndProxy, ptrayItem->uIdx,
133 ptrayItem->notifyIcon.hIcon);
134 }
135 if (uFlags & NIF_TIP)
136 {
137 xstSetSysTrayIconToolTip(hwndProxy, ptrayItem->uIdx,
138 ptrayItem->notifyIcon.szTip);
139 }
140}
141
142BOOL SYSTRAY_Ex_Init(void)
143{
144 static BOOL tried = FALSE;
145 if (!tried) {
146 char err[CCHMAXPATH];
147 HMODULE hmod;
148
149 tried = TRUE;
150
151 // link to the xsystray DLL at runtime
152 if (DosLoadModule(err, sizeof(err), "XSYSTRAY", &hmod) != NO_ERROR)
153 return FALSE;
154
155 #define R(f) if (DosQueryProcAddr(hmod, 0, #f, (PFN*)&f) != NO_ERROR) return FALSE
156
157 R(xstQuerySysTrayVersion);
158 R(xstAddSysTrayIcon);
159 R(xstReplaceSysTrayIcon);
160 R(xstRemoveSysTrayIcon);
161 R(xstSetSysTrayIconToolTip);
162 R(xstQuerySysTrayIconRect);
163 R(xstGetSysTrayCreatedMsgId);
164 R(xstGetSysTrayMaxTextLen);
165
166 #undef R
167 }
168
169 // check if xsystray is there
170 if (!xstQuerySysTrayVersion(NULL, NULL, NULL))
171 return FALSE;
172
173 SYSTRAY_ItemInit = SYSTRAY_Ex_ItemInit;
174 SYSTRAY_ItemTerm = SYSTRAY_Ex_ItemTerm;
175 SYSTRAY_ItemUpdate = SYSTRAY_Ex_ItemUpdate;
176
177 return TRUE;
178}
179
Note: See TracBrowser for help on using the repository browser.