source: trunk/src/shell32/systray_os2ex.c

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

Merge branch gcc-kmk to trunk.

  • Property svn:eol-style set to native
File size: 6.3 KB
RevLine 
[21591]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
[21600]8#define INCL_PM
9#define INCL_DOS
10#define INCL_DOSERRORS
11#include <os2wrap.h> // Odin32 OS/2 api wrappers
[21591]12
[21600]13#include <win32api.h>
14
[21591]15#include <string.h>
16
[21592]17// declare function pointers for dynamic linking to xsystray DLL
18#define XSTAPI_FPTRS_STATIC
[21916]19#include "xsystray.h"
[21591]20
21#include "systray_os2.h"
22
[21600]23#include "dbglog.h"
24
[21592]25#define WM_XST_MYNOTIFY (WM_USER + 1000)
26
[21600]27static ULONG WM_XST_CREATED = 0;
[21602]28static ULONG WM_TASKBARCREATED_W = 0;
[21600]29
[21592]30static HWND hwndProxy = NULLHANDLE;
31static ULONG hwndProxyRefs = 0;
32
33static PFNWP OldProxyWndProc = NULL;
34
35static MRESULT EXPENTRY ProxyWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
36{
37 switch (msg)
38 {
39 case WM_XST_MYNOTIFY:
40 {
41 USHORT usIconID = SHORT1FROMMP(mp1);
42 USHORT usNotifyCode = SHORT2FROMMP(mp1);
43
44 SystrayItem *ptrayItem = SYSTRAY_FindItem(usIconID);
45 if (!ptrayItem)
46 return (MRESULT)FALSE;
47
48 switch (usNotifyCode)
49 {
50 case XST_IN_MOUSE:
51 {
52 PXSTMOUSEMSG pmmsg = (PXSTMOUSEMSG)mp2;
53 ULONG winMsg = 0;
54
55 switch (pmmsg->ulMouseMsg)
56 {
57 case WM_BUTTON1DBLCLK: winMsg = WM_LBUTTONDBLCLK_W; break;
58 case WM_BUTTON2DBLCLK: winMsg = WM_RBUTTONDBLCLK_W; break;
59 case WM_BUTTON3DBLCLK: winMsg = WM_MBUTTONDBLCLK_W; break;
60 case WM_BUTTON1UP: winMsg = WM_LBUTTONUP_W; break;
61 case WM_BUTTON2UP: winMsg = WM_RBUTTONUP_W; break;
62 case WM_BUTTON3UP: winMsg = WM_MBUTTONUP_W; break;
63 case WM_BUTTON1DOWN: winMsg = WM_LBUTTONDOWN_W; break;
64 case WM_BUTTON2DOWN: winMsg = WM_RBUTTONDOWN_W; break;
65 case WM_BUTTON3DOWN: winMsg = WM_MBUTTONDOWN_W; break;
66 default: break;
67 }
68
69 if (winMsg)
70 {
[21602]71 PostMessageA(ptrayItem->notifyIcon.hWnd,
72 ptrayItem->notifyIcon.uCallbackMessage,
73 (WPARAM)ptrayItem->notifyIcon.uID,
74 (LPARAM)winMsg);
[21600]75 return (MRESULT)TRUE;
[21592]76 }
[21600]77 break;
[21592]78 }
[21600]79 case XST_IN_CONTEXT:
80 {
[21602]81 PostMessageA(ptrayItem->notifyIcon.hWnd,
82 ptrayItem->notifyIcon.uCallbackMessage,
83 (WPARAM)ptrayItem->notifyIcon.uID,
84 (LPARAM)WM_CONTEXTMENU_W);
[21600]85 return (MRESULT)TRUE;
86 }
[21592]87 default:
88 break;
89 }
[21600]90
91 return (MRESULT)FALSE;
[21592]92 }
93 default:
[21600]94 {
95 if (msg == WM_XST_CREATED)
96 {
[21602]97 // xCenter was restarted, no icons are shown; remove all items
98 // and broadcast TaskbarCreated to let applications recreate them
99 SYSTRAY_PruneAllItems();
100
101 dprintf(("SHELL32: SYSTRAY: Broadcasting \"TaskbarCreated\" (%x)",
102 WM_TASKBARCREATED_W));
103 PostMessageA(HWND_BROADCAST_W, WM_TASKBARCREATED_W,
104 (WPARAM)0, (LPARAM)0);
[21600]105 return (MRESULT)TRUE;
106 }
[21592]107 break;
108 }
[21600]109 }
[21592]110
[21600]111 return WinDefWindowProc(hWnd, msg, mp1, mp2);
[21592]112}
113
[21591]114static BOOL SYSTRAY_Ex_ItemInit(SystrayItem *ptrayItem)
115{
[21592]116 if (hwndProxyRefs == 0)
117 {
[21600]118 if (!WinRegisterClass(NULLHANDLE, "OdinXSysTrayProxy", ProxyWndProc,
119 0, 0))
120 {
121 dprintf(("SHELL32: SYSTRAY: WinRegisterClass() failed with %x",
122 WinGetLastError(0)));
123 return FALSE;
124 }
125
126 hwndProxy = WinCreateWindow(HWND_DESKTOP, "OdinXSysTrayProxy", NULL,
127 0, 0, 0, 0, 0, NULLHANDLE, HWND_BOTTOM, 0,
128 NULL, NULL);
129
[21592]130 if (hwndProxy == NULLHANDLE)
[21600]131 {
132 dprintf(("SHELL32: SYSTRAY: WinCreateWindow() failed with %x",
133 WinGetLastError(0)));
[21592]134 return FALSE;
[21600]135 }
136 }
[21592]137
138 ++ hwndProxyRefs;
139
[21591]140 return TRUE;
141}
142
143static void SYSTRAY_Ex_ItemTerm(SystrayItem *ptrayItem)
144{
[21592]145 xstRemoveSysTrayIcon(hwndProxy, ptrayItem->uIdx);
[21591]146
[21592]147 if (-- hwndProxyRefs == 0)
148 {
149 WinDestroyWindow(hwndProxy);
150 hwndProxy = NULLHANDLE;
151 }
[21591]152}
153
[21592]154static void SYSTRAY_Ex_ItemUpdate(SystrayItem *ptrayItem, ULONG uFlags)
[21591]155{
[21592]156 if (uFlags == 0 || (uFlags & (NIF_ICON | NIF_TIP) == NIF_ICON | NIF_TIP))
157 {
158 // uFlags = 0 means it's the first time so add the icon. The other case
159 // is true when a bunch of the parameters is changed at once so use
160 // xstAdd... too to save a few IPC calls.
161 xstAddSysTrayIcon(hwndProxy, ptrayItem->uIdx,
162 ptrayItem->notifyIcon.hIcon,
163 ptrayItem->notifyIcon.szTip,
164 WM_XST_MYNOTIFY,
165 XST_IN_MOUSE | XST_IN_CONTEXT);
166 return;
167 }
[21591]168
[21592]169 if (uFlags & NIF_ICON)
170 {
171 xstReplaceSysTrayIcon(hwndProxy, ptrayItem->uIdx,
172 ptrayItem->notifyIcon.hIcon);
173 }
174 if (uFlags & NIF_TIP)
175 {
176 xstSetSysTrayIconToolTip(hwndProxy, ptrayItem->uIdx,
177 ptrayItem->notifyIcon.szTip);
178 }
[21591]179}
180
[21592]181BOOL SYSTRAY_Ex_Init(void)
[21591]182{
[21592]183 static BOOL tried = FALSE;
184 if (!tried) {
185 char err[CCHMAXPATH];
186 HMODULE hmod;
[21591]187
[21592]188 tried = TRUE;
[21591]189
[21592]190 // link to the xsystray DLL at runtime
191 if (DosLoadModule(err, sizeof(err), "XSYSTRAY", &hmod) != NO_ERROR)
192 return FALSE;
[21591]193
[21592]194 #define R(f) if (DosQueryProcAddr(hmod, 0, #f, (PFN*)&f) != NO_ERROR) return FALSE
195
196 R(xstQuerySysTrayVersion);
197 R(xstAddSysTrayIcon);
198 R(xstReplaceSysTrayIcon);
199 R(xstRemoveSysTrayIcon);
200 R(xstSetSysTrayIconToolTip);
201 R(xstQuerySysTrayIconRect);
202 R(xstGetSysTrayCreatedMsgId);
203 R(xstGetSysTrayMaxTextLen);
204
205 #undef R
206 }
207
208 // check if xsystray is there
209 if (!xstQuerySysTrayVersion(NULL, NULL, NULL))
210 return FALSE;
211
[21600]212 // initialize some constants
213 WM_XST_CREATED = xstGetSysTrayCreatedMsgId();
214
[21602]215 WM_TASKBARCREATED_W = RegisterWindowMessageA("TaskbarCreated");
216
[21591]217 SYSTRAY_ItemInit = SYSTRAY_Ex_ItemInit;
218 SYSTRAY_ItemTerm = SYSTRAY_Ex_ItemTerm;
[21592]219 SYSTRAY_ItemUpdate = SYSTRAY_Ex_ItemUpdate;
[21591]220
221 return TRUE;
222}
223
Note: See TracBrowser for help on using the repository browser.