Bug #122351 --> if the shell doesn't support wide string

friendly versions of Shell_NotifyW, then gracefully fall back and
use the older ASCII versions (Shell_Notify).
r=bhuvan
sr=sspitzer
This commit is contained in:
mscott%netscape.com 2002-01-31 07:31:07 +00:00
parent fdf6f6bfee
commit eeaa850c41
2 changed files with 89 additions and 24 deletions

View File

@ -67,6 +67,7 @@
#define XP_SHSetUnreadMailCounts "SHSetUnreadMailCountW"
#define XP_SHEnumerateUnreadMailAccounts "SHEnumerateUnreadMailAccountsW"
#define ShellNotifyWideVersion "Shell_NotifyIconW"
#define UNREADMAILNODEKEY "Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\"
#define SHELL32_DLL "shell32.dll"
#define DOUBLE_QUOTE "\""
@ -96,6 +97,7 @@ nsMessengerWinIntegration::nsMessengerWinIntegration()
mBiffStateAtom = getter_AddRefs(NS_NewAtom("BiffState"));
mBiffIconVisible = PR_FALSE;
mBiffIconInitialized = PR_FALSE;
mUseWideCharBiffIcon = PR_FALSE;
NS_NewISupportsArray(getter_AddRefs(mFoldersWithNewMail));
}
@ -114,11 +116,7 @@ nsMessengerWinIntegration::~nsMessengerWinIntegration()
CRTFREEIF(mInboxURI);
CRTFREEIF(mEmail);
if (mBiffIconData.hIcon)
{
::Shell_NotifyIconW( NIM_DELETE, &mBiffIconData ); // Remove the tray icon.
DestroyIcon(mBiffIconData.hIcon);
}
DestroyBiffIcon();
}
NS_IMPL_ADDREF(nsMessengerWinIntegration);
@ -167,7 +165,15 @@ HWND hwndForDOMWindow( nsISupports *window )
}
// end shameless copying from nsNativeAppSupportWin.cpp
NOTIFYICONDATAW nsMessengerWinIntegration::mBiffIconData = { sizeof(NOTIFYICONDATA),
NOTIFYICONDATA nsMessengerWinIntegration::mAsciiBiffIconData = { sizeof(NOTIFYICONDATA),
0,
2,
NIF_ICON | NIF_MESSAGE | NIF_TIP,
WM_USER,
0,
0 };
NOTIFYICONDATAW nsMessengerWinIntegration::mWideBiffIconData = { sizeof(NOTIFYICONDATAW),
0,
2,
NIF_ICON | NIF_MESSAGE | NIF_TIP,
@ -184,10 +190,18 @@ void nsMessengerWinIntegration::InitializeBiffStatusIcon()
nsCOMPtr<nsIDOMWindowInternal> hiddenWindow;
rv = appService->GetHiddenDOMWindow(getter_AddRefs(hiddenWindow));
mBiffIconData.hWnd = hwndForDOMWindow( hiddenWindow );
mBiffIconData.hIcon = ::LoadIcon( ::GetModuleHandle( "msgbase.dll" ), MAKEINTRESOURCE(IDI_MAILBIFF) );
mBiffIconData.szTip[0] = 0;
if (mUseWideCharBiffIcon)
{
mWideBiffIconData.hWnd = hwndForDOMWindow( hiddenWindow );
mWideBiffIconData.hIcon = ::LoadIcon( ::GetModuleHandle( "msgbase.dll" ), MAKEINTRESOURCE(IDI_MAILBIFF) );
mWideBiffIconData.szTip[0] = 0;
}
else
{
mAsciiBiffIconData.hWnd = hwndForDOMWindow( hiddenWindow );
mAsciiBiffIconData.hIcon = ::LoadIcon( ::GetModuleHandle( "msgbase.dll" ), MAKEINTRESOURCE(IDI_MAILBIFF) );
mAsciiBiffIconData.szTip[0] = 0;
}
mBiffIconInitialized = PR_TRUE;
}
@ -245,6 +259,9 @@ nsMessengerWinIntegration::Init()
if (hModule) {
mSHSetUnreadMailCount = (fnSHSetUnreadMailCount)GetProcAddress(hModule, XP_SHSetUnreadMailCounts);
mSHEnumerateUnreadMailAccounts = (fnSHEnumerateUnreadMailAccounts)GetProcAddress(hModule, XP_SHEnumerateUnreadMailAccounts);
mShellNotifyWideChar = (fnShellNotifyW)GetProcAddress(hModule, ShellNotifyWideVersion);
if (mShellNotifyWideChar)
mUseWideCharBiffIcon = PR_TRUE; // this version of the shell supports I18N friendly ShellNotify routines.
}
// if failed to get either of the process addresses, this is not XP platform
@ -334,6 +351,8 @@ void nsMessengerWinIntegration::FillToolTipInfo()
PRUint32 count = 0;
mFoldersWithNewMail->Count(&count);
PRUint32 maxTooltipSize = GetToolTipSize();
for (PRUint32 index = 0; index < count; index++)
{
supports = getter_AddRefs(mFoldersWithNewMail->ElementAt(index));
@ -367,7 +386,7 @@ void nsMessengerWinIntegration::FillToolTipInfo()
bundle->FormatStringFromName(NS_LITERAL_STRING("biffNotification_messages").get(), formatStrings, 2, getter_Copies(finalText));
// only add this new string if it will fit without truncation....
if ((sizeof mBiffIconData.szTip - 1) >= toolTipText.Length() + finalText.Length() + 2)
if (maxTooltipSize >= toolTipText.Length() + finalText.Length() + 2)
{
if (index > 0)
toolTipText.Append(NS_LITERAL_STRING("\n").get());
@ -377,18 +396,55 @@ void nsMessengerWinIntegration::FillToolTipInfo()
} // if we got a folder
} // for each folder
if (toolTipText.Length())
::wcsncpy( mBiffIconData.szTip, toolTipText.get(), sizeof mBiffIconData.szTip - 1 );
SetToolTipStringOnIconData(toolTipText.get());
// load an icon in the system tray or if it's already there, fire a modified notification so the tooltip
// gets updated.
if (!mBiffIconVisible)
{
::Shell_NotifyIconW( NIM_ADD, &mBiffIconData );
GenericShellNotify(NIM_ADD);
mBiffIconVisible = PR_TRUE;
}
else
::Shell_NotifyIconW( NIM_MODIFY, &mBiffIconData );
GenericShellNotify( NIM_MODIFY);
}
void nsMessengerWinIntegration::DestroyBiffIcon()
{
GenericShellNotify(NIM_DELETE);
if (mUseWideCharBiffIcon && mWideBiffIconData.hIcon)
DestroyIcon(mWideBiffIconData.hIcon);
else if (mAsciiBiffIconData.hIcon)
DestroyIcon(mAsciiBiffIconData.hIcon);
}
PRUint32 nsMessengerWinIntegration::GetToolTipSize()
{
if (mUseWideCharBiffIcon)
return (sizeof mWideBiffIconData.szTip - 1);
else
return (sizeof mAsciiBiffIconData.szTip - 1) * 2;
}
void nsMessengerWinIntegration::SetToolTipStringOnIconData(const PRUnichar * aToolTipString)
{
if (!aToolTipString) return;
if (mUseWideCharBiffIcon)
::wcsncpy( mWideBiffIconData.szTip, aToolTipString, sizeof mWideBiffIconData.szTip - 1 );
else
{
nsCString asciiToolTip;
asciiToolTip.AssignWithConversion(aToolTipString);
::strncpy( mAsciiBiffIconData.szTip, asciiToolTip.get(), sizeof mAsciiBiffIconData.szTip - 1 );
}
}
void nsMessengerWinIntegration::GenericShellNotify(DWORD aMessage)
{
if (mUseWideCharBiffIcon)
mShellNotifyWideChar( aMessage, &mWideBiffIconData );
else
::Shell_NotifyIcon( aMessage, &mAsciiBiffIconData );
}
NS_IMETHODIMP
@ -439,9 +495,9 @@ nsMessengerWinIntegration::OnItemPropertyFlagChanged(nsISupports *item, nsIAtom
// notification.
mFoldersWithNewMail->Clear();
if (mBiffIconVisible)
{
{
mBiffIconVisible = PR_FALSE;
::Shell_NotifyIconW( NIM_DELETE, &mBiffIconData ); // Remove the tray icon.
GenericShellNotify(NIM_DELETE);
}
}
} // if the biff property changed

View File

@ -57,6 +57,7 @@ extern "C"
{
typedef HRESULT (__stdcall *fnSHSetUnreadMailCount)(LPCWSTR pszMailAddress, DWORD dwCount, LPCWSTR pszShellExecuteCommand);
typedef HRESULT (__stdcall *fnSHEnumerateUnreadMailAccounts)(HKEY hKeyUser, DWORD dwIndex, LPCWSTR pszMailAddress, int cchMailAddress);
typedef BOOL (_stdcall *fnShellNotifyW)(DWORD dwMessage, PNOTIFYICONDATAW lpdata);
}
#define NS_MESSENGERWININTEGRATION_CID \
@ -79,15 +80,23 @@ public:
private:
static NOTIFYICONDATAW mBiffIconData; // status bar icon for biff.
static NOTIFYICONDATAW mWideBiffIconData;
static NOTIFYICONDATA mAsciiBiffIconData;
void InitializeBiffStatusIcon();
void FillToolTipInfo();
void GenericShellNotify(DWORD aMessage);
void SetToolTipStringOnIconData(const PRUnichar * aToolTipString);
void DestroyBiffIcon();
PRUint32 GetToolTipSize(); // available space for the tooltip string
nsresult GetStringBundle(nsIStringBundle **aBundle);
nsCOMPtr<nsISupportsArray> mFoldersWithNewMail; // keep track of all the root folders with pending new mail
fnShellNotifyW mShellNotifyWideChar;
nsCOMPtr<nsIAtom> mBiffStateAtom;
PRUint32 mCurrentBiffState;
PRPackedBool mUseWideCharBiffIcon;
PRPackedBool mStoreUnreadCounts; // for windows XP, we do a lot of work to store the last unread count for the inbox
// this flag is set to true when we are doing that
PRPackedBool mBiffIconVisible;