View previous topic :: View next topic |
Author |
Message |
kbogert
Joined: 18 May 2006 Posts: 5
|
Posted: Wed Jun 21, 2006 9:18 pm Post subject: Balloon Tooltips for NotifyIcon |
|
|
Hello all, here are two patches against version 9.2 to enable the NotifyIcon class to display the balloon popup tooltip we all know and love.
Note that you need to fix a small error in environment.d in order to prevent a stack overflow before using these, see my previous post.
Code: |
--- notifyicon-old.d 2005-07-26 21:46:04.000000000 -0400
+++ notifyicon.d 2006-06-21 23:49:43.000000000 -0400
@@ -2,11 +2,14 @@
private import dfl.winapi, dfl.base, dfl.drawing, dfl.menu;
private import dfl.control, dfl.form, dfl.application;
-private import dfl.event;
+private import dfl.event, dfl.environment;
class NotifyIcon // docmain
{
+
+ const UINT NOTIFYICON_VERSION = 3;
+
final void contextMenu(ContextMenu menu) // setter
{
this.cmenu = menu;
@@ -44,6 +47,9 @@
if(txt.length >= nid.szTip.length)
throw new DflException("Notify icon text too long.");
+ if (!mWin2k && txt.length > 64)
+ throw new DflException("Notify icon text too long.");
+
nid.szTip[txt.length] = 0;
nid.szTip[0 .. txt.length] = txt;
tipLen = txt.length;
@@ -93,7 +99,11 @@
EventHandler click;
- EventHandler doubleClick;
+ EventHandler doubleClick;
+ EventHandler balloonShow;
+ EventHandler balloonHide;
+ EventHandler balloonClick;
+ EventHandler balloonTimeout;
MouseEventHandler mouseDown;
MouseEventHandler mouseUp;
MouseEventHandler mouseMove;
@@ -103,13 +113,18 @@
{
if(!ctrlNotifyIcon)
_init();
-
- nid.cbSize = nid.sizeof;
+
+ if (mWin2k) {
+ nid.cbSize = nid.sizeof;
+ nid.szInfo[0] = '\0';
+ } else
+ nid.cbSize = NOTIFYICONDATA_V1_SIZE;
nid.hWnd = ctrlNotifyIcon.handle;
nid.uID = 0;
nid.uCallbackMessage = WM_NOTIFYICON;
nid.hIcon = null;
- nid.szTip[0] = '\0';
+ nid.szTip[0] = '\0';
+
}
@@ -133,7 +148,40 @@
}
+/
}
-
+
+ void showBalloon(char[] balloonText, char[] balloonTitle, DWORD balloonIconFlag, int balloonTimeout) {
+
+ if (!mWin2k)
+ throw new DflException("Not Supported in this Operating System");
+
+ if (balloonText.length >= nid.szInfo.length)
+ throw new DflException("Balloon text too long.");
+ if(balloonTitle.length >= nid.szInfoTitle.length)
+ throw new DflException("Balloon title too long.");
+
+ if(balloonIconFlag != NIIF_NONE && balloonIconFlag != NIIF_WARNING && balloonIconFlag != NIIF_ERROR && balloonIconFlag != NIIF_INFO)
+ throw new DflException("Balloon icon invalid.");
+
+ if(balloonTimeout < 10 || balloonTimeout > 30)
+ throw new DflException("Balloon timeout invalid.");
+
+ nid.szInfo[balloonText.length] = '\0';
+ nid.szInfo[0 .. balloonText.length] = balloonText;
+
+ nid.szInfoTitle[balloonTitle.length] = '\0';
+ nid.szInfoTitle[0 .. balloonTitle.length] = balloonTitle;
+
+ nid.uTimeout = balloonTimeout * 1000; // convert sec to ms
+ nid.dwInfoFlags = balloonIconFlag;
+
+ if(visible)
+ {
+ nid.uFlags = NIF_INFO;
+ Shell_NotifyIconA(NIM_MODIFY, &nid);
+ nid.szInfo[0] = '\0'; // prevent re-display of the balloon
+ }
+
+ }
// Extra.
void minimize(IWin32Window win)
@@ -209,11 +257,24 @@
ContextMenu cmenu;
Icon _icon;
-
package final void _forceAdd()
{
- nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+ nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+
+ if (mWin2k) {
+ if (nid.szInfo[0] != '\0')
+ nid.uFlags |= NIF_INFO;
+ nid.uTimeout = NOTIFYICON_VERSION;
+ nid.dwState = NIS_SHAREDICON;
+ }
+
Shell_NotifyIconA(NIM_ADD, &nid);
+
+ if (mWin2k) {
+ Shell_NotifyIconA(NIM_SETVERSION, &nid);
+ nid.szInfo[0] = '\0';
+ }
+
}
@@ -303,7 +364,8 @@
NotifyIcon[UINT] allNotifyIcons; // Indexed by ID.
UINT lastId = 1;
NotifyIconControl ctrlNotifyIcon;
-
+LONG windowProc;
+bool mWin2k;
class NotifyIconControl: Control
{
@@ -324,8 +386,20 @@
Application.getInstance(), null);
if(!hwnd)
goto create_err;
+
+// if (mWin2k)
+ // windowProc = SetWindowLongA(hwnd, GWL_WNDPROC, cast(LONG*)&wndProc);
+
}
+ override void destroyHandle()
+ {
+ if (mWin2k && hwnd) {
+ SetWindowLongA(hwnd, GWL_WNDPROC, windowProc);
+ windowProc = 0;
+ }
+ super.destroyHandle();
+ }
protected override void wndProc(inout Message msg)
{
@@ -337,7 +411,7 @@
Point pt;
ni = allNotifyIcons[cast(UINT)msg.wParam];
-
+
switch(cast(UINT)msg.lParam) // msg.
{
case WM_MOUSEMOVE:
@@ -372,8 +446,24 @@
case WM_LBUTTONDBLCLK:
ni.doubleClick(ni, EventArgs.empty);
- break;
-
+ break;
+
+ case NIN_BALLOONSHOW:
+ ni.balloonShow(ni, EventArgs.empty);
+ break;
+
+ case NIN_BALLOONHIDE:
+ ni.balloonHide(ni, EventArgs.empty);
+ break;
+
+ case NIN_BALLOONUSERCLICK:
+ ni.balloonClick(ni, EventArgs.empty);
+ break;
+
+ case NIN_BALLOONTIMEOUT:
+ ni.balloonTimeout(ni, EventArgs.empty);
+ break;
+
default: ;
}
}
@@ -428,6 +518,11 @@
void _init()
{
+ OperatingSystem curOS = Environment.osVersion();
+
+ if ( curOS.ver().major() >= 5 && curOS.platform() == PlatformId.WIN32_NT)
+ mWin2k = true;
+
wmTaskbarCreated = RegisterWindowMessageA("TaskbarCreated");
ctrlNotifyIcon = new NotifyIconControl;
|
Code: |
--- winapi-old.d 2006-01-20 19:46:02.000000000 -0500
+++ winapi.d 2006-06-21 22:59:00.000000000 -0400
@@ -1265,7 +1265,8 @@
{
NIF_MESSAGE = 0x00000001,
NIF_ICON = 0x00000002,
- NIF_TIP = 0x00000004,
+ NIF_TIP = 0x00000004,
+ NIF_INFO = 0x00000010,
}
@@ -1274,6 +1275,7 @@
NIM_ADD = 0x00000000,
NIM_MODIFY = 0x00000001,
NIM_DELETE = 0x00000002,
+ NIM_SETVERSION = 0x00000004,
}
@@ -1527,10 +1529,40 @@
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
- char[64] szTip;
+ char[128] szTip;
+ DWORD dwState;
+ DWORD dwStateMask;
+ char[256] szInfo;
+ UINT uTimeout;
+ char[64] szInfoTitle;
+ DWORD dwInfoFlags;
}
alias NOTIFYICONDATA* PNOTIFYICONDATA;
-
+
+const DWORD NOTIFYICONDATA_V1_SIZE = 88; //pre-5.0 structure size
+// const DWORD NOTIFYICONDATA_V2_SIZE = 488; //pre-6.0 structure size
+
+enum : DWORD
+{
+ NIIF_NONE = 0x0,
+ NIIF_WARNING = 0x2,
+ NIIF_ERROR = 0x3,
+ NIIF_INFO = 0x1,
+}
+
+enum : DWORD
+{
+ NIS_HIDDEN = 1,
+ NIS_SHAREDICON = 2,
+}
+
+enum : UINT
+{
+ NIN_BALLOONSHOW = WM_USER + 2,
+ NIN_BALLOONHIDE = WM_USER + 3,
+ NIN_BALLOONTIMEOUT = WM_USER + 4,
+ NIN_BALLOONUSERCLICK = WM_USER + 5,
+}
// Unaligned!
struct SHITEMID
|
kdb _________________ - kdb |
|
Back to top |
|
|
kbogert
Joined: 18 May 2006 Posts: 5
|
Posted: Thu Jun 22, 2006 3:13 pm Post subject: Remove the DWORD from showBalloon |
|
|
I don't know what I was thinking. C heritage I guess ...
Code: |
--- notifyicon-old2.d 2006-06-22 17:10:01.000000000 -0400
+++ notifyicon.d 2006-06-22 17:09:08.000000000 -0400
@@ -4,6 +4,14 @@
private import dfl.control, dfl.form, dfl.application;
private import dfl.event, dfl.environment;
+
+public enum BalloonIcon : DWORD
+{
+ NONE = NIIF_NONE,
+ INFO = NIIF_INFO,
+ WARNING = NIIF_WARNING,
+ ERROR = NIIF_ERROR,
+}
class NotifyIcon // docmain
{
@@ -149,7 +157,7 @@
+/
}
- void showBalloon(char[] balloonText, char[] balloonTitle, DWORD balloonIconFlag, int balloonTimeout) {
+ void showBalloon(char[] balloonText, char[] balloonTitle, BalloonIcon balloonIconFlag, int balloonTimeout) {
if (!mWin2k)
throw new DflException("Not Supported in this Operating System");
@@ -159,9 +167,6 @@
if(balloonTitle.length >= nid.szInfoTitle.length)
throw new DflException("Balloon title too long.");
- if(balloonIconFlag != NIIF_NONE && balloonIconFlag != NIIF_WARNING && balloonIconFlag != NIIF_ERROR && balloonIconFlag != NIIF_INFO)
- throw new DflException("Balloon icon invalid.");
-
if(balloonTimeout < 10 || balloonTimeout > 30)
throw new DflException("Balloon timeout invalid.");
@@ -387,9 +392,6 @@
if(!hwnd)
goto create_err;
-// if (mWin2k)
- // windowProc = SetWindowLongA(hwnd, GWL_WNDPROC, cast(LONG*)&wndProc);
-
}
override void destroyHandle()
|
That should provide a nice enum for setting the baloon's icon. Apply to the above patch. _________________ - kdb |
|
Back to top |
|
|
Chris Miller
Joined: 27 Mar 2004 Posts: 514 Location: The Internet
|
Posted: Thu Jun 22, 2006 9:47 pm Post subject: Re: Balloon Tooltips for NotifyIcon |
|
|
Cool, I'll take a look at it later. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|